@khanacademy/perseus 83.0.1 → 83.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/index.js +30 -30
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +30 -30
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/es/index.js
CHANGED
|
@@ -1414,7 +1414,7 @@ var a11y = StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,mar
|
|
|
1414
1414
|
|
|
1415
1415
|
const debounce=(func,delay)=>{let timer=null;return (...args)=>{if(timer){clearTimeout(timer);}timer=window.setTimeout(()=>{func(...args);},delay);}};
|
|
1416
1416
|
|
|
1417
|
-
class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.value!==this.props.value){if(this.state.focused){return}const field=this.mathField();if(!field){return}const current=field.latex();if(this.props.value!==current){field.latex(this.props.value);}}}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$C.outerWrapper,this.state.focused&&styles$C.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,onClose:()=>this.closeKeypad(),content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{size:"large",id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$C.popoverContent,children:jsxRuntimeExports.jsx(DesktopKeypad,{onAnalyticsEvent:this.props.onAnalyticsEvent,extraKeys:this.props.extraKeys,onClickKey:this.handleKeypadPress,cursorContext:this.state.cursorContext,convertDotToTimes:this.props.convertDotToTimes,...this.props.keypadButtonSets??mapButtonSets(this.props?.buttonSets),showDismiss:true})})]}),children:this.props.buttonsVisible==="never"?jsxRuntimeExports.jsx(MathInputIcon,{hovered:false,focused:false,active:false}):jsxRuntimeExports.jsx(Clickable,{"aria-label":this.state.keypadOpen?this.context.strings.closeKeypad:this.context.strings.openKeypad,role:"button",onClick:()=>this.state.keypadOpen?this.closeKeypad():this.openKeypad(),children:props=>jsxRuntimeExports.jsx(MathInputIcon,{active:this.state.keypadOpen,...props})})})]})})}constructor(...args){super(...args),this.__mathFieldWrapperRef=null,this.__mathField=null,this.state={focused:false,keypadOpen:this.props.buttonsVisible==="always"?true:false,cursorContext:CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...getKeyTranslator(locale,this.context.strings),FRAC:mathQuill=>{const contents=mathQuill.latex();mathQuill.typedText("/");if(mathQuill.latex()===contents){mathQuill.cmd("\\frac");}}};const inputModifier=customKeyTranslator[value];if(inputModifier){inputModifier(input,value);input?.focus();return}if(typeof value==="function"){value(input);}else if(value[0]==="\\"){input?.cmd(value).focus();}else {input?.write(value).focus();}input?.focus();},this.mathField=()=>{if(!this.__mathField&&this.__mathFieldWrapperRef){const{locale}=this.context;this.__mathField=createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathQuillInstance.L];if(left&&left.ctrlSeq==="\\cdot "){mathField.controller().backspace();mathField.cmd("\\times");}}else {value=value.replace(/\\times/g,"\\cdot");}if(this.props.value!==value){this.props.onChange(value);}this.setState({cursorContext:getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){$(this.__mathFieldWrapperRef).submit();}},upOutOf:mathField=>{mathField.typedText("^");}}}));}this.__mathField?.setAriaLabel(this.props.ariaLabel);return this.__mathField},this.focus=()=>{this.mathField()?.focus();this.setState({focused:true});},this.blur=()=>this.setState({focused:false}),this.handleKeypadPress=(key,e)=>{if(key==="DISMISS"){this.closeKeypad();return}const{locale}=this.context;const translator=getKeyTranslator(locale,this.context.strings)[key];const mathField=this.mathField();if(mathField){if(translator){translator(mathField,key);}this.setState({cursorContext:getCursorContext(mathField)});}if(e?.type==="click"){this.focus();}};}}InnerMathInput.contextType=PerseusI18nContext;InnerMathInput.defaultProps={value:"",convertDotToTimes:false};class MathInput extends React.Component{blur(){this.inputRef.current?.blur();}focus(){this.inputRef.current?.focus();}insert(value){this.inputRef.current?.insert(value);}render(){return jsxRuntimeExports.jsx(InnerMathInput,{...this.props,ref:this.inputRef,mathInputStrings:this.context.strings})}constructor(...args){super(...args),this.inputRef=React.createRef();}}MathInput.contextType=MathInputI18nContext;MathInput.defaultProps={ariaLabel:"Math input"};const MathInputIcon=({hovered,focused,active})=>{let fillColor;switch(true){case focused||active:fillColor=semanticColor.action.primary.progressive.default.foreground;break;case hovered:fillColor=semanticColor.action.primary.progressive.hover.background;break;default:fillColor=semanticColor.core.foreground.neutral.strong;break}const dynamicClass=active||focused?styles$C.iconActive:styles$C.iconInactive;return jsxRuntimeExports.jsx(View,{style:[styles$C.iconContainer,dynamicClass],children:jsxRuntimeExports.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",fill:fillColor,viewBox:"0 0 256 256",children:jsxRuntimeExports.jsx("path",{d:"M112,72a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16h64A8,8,0,0,1,112,72Zm-8,104H80V152a8,8,0,0,0-16,0v24H40a8,8,0,0,0,0,16H64v24a8,8,0,0,0,16,0V192h24a8,8,0,0,0,0-16Zm48,0h64a8,8,0,0,0,0-16H152a8,8,0,0,0,0,16Zm64,16H152a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm-61.66-90.34a8,8,0,0,0,11.32,0L184,83.31l18.34,18.35a8,8,0,0,0,11.32-11.32L195.31,72l18.35-18.34a8,8,0,0,0-11.32-11.32L184,60.69,165.66,42.34a8,8,0,0,0-11.32,11.32L172.69,72,154.34,90.34A8,8,0,0,0,154.34,101.66Z"})})})};const mapButtonSets=buttonSets=>{const keypadButtonSets={};if(!buttonSets){return keypadButtonSets}buttonSets.forEach(buttonSet=>{switch(buttonSet){case "advanced relations":keypadButtonSets.advancedRelations=true;break;case "basic relations":keypadButtonSets.basicRelations=true;break;case "basic+div":keypadButtonSets.divisionKey=true;break;case "logarithms":keypadButtonSets.logarithms=true;break;case "prealgebra":keypadButtonSets.preAlgebra=true;break;case "trig":keypadButtonSets.trigonometry=true;break;case "scientific":keypadButtonSets.scientific=true;break;}});return keypadButtonSets};const inputFocused={borderWidth:2,borderColor:semanticColor.core.border.instructive.default,margin:-1};const styles$C=StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:sizing.size_040,borderRadius:1},iconInactive:{border:"2px solid transparent",backgroundColor:semanticColor.core.background.neutral.subtle},iconActive:{border:`2px solid ${semanticColor.core.border.knockout.default}`,backgroundColor:semanticColor.core.background.neutral.default},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:semanticColor.core.border.neutral.default,borderRadius:3,background:semanticColor.core.background.base.default,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,
|
|
1417
|
+
class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.value!==this.props.value){if(this.state.focused){return}const field=this.mathField();if(!field){return}const current=field.latex();if(this.props.value!==current){field.latex(this.props.value);}}}openKeypad(){if(this.props.buttonsVisible==="never"){return}this.setState({keypadOpen:true});}closeKeypad(){this.setState({keypadOpen:false});}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$C.outerWrapper,this.state.focused&&styles$C.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,onClose:()=>this.closeKeypad(),content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{size:"large",id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$C.popoverContent,children:jsxRuntimeExports.jsx(DesktopKeypad,{onAnalyticsEvent:this.props.onAnalyticsEvent,extraKeys:this.props.extraKeys,onClickKey:this.handleKeypadPress,cursorContext:this.state.cursorContext,convertDotToTimes:this.props.convertDotToTimes,...this.props.keypadButtonSets??mapButtonSets(this.props?.buttonSets),showDismiss:true})})]}),children:this.props.buttonsVisible==="never"?jsxRuntimeExports.jsx(MathInputIcon,{hovered:false,focused:false,active:false}):jsxRuntimeExports.jsx(Clickable,{"aria-label":this.state.keypadOpen?this.context.strings.closeKeypad:this.context.strings.openKeypad,role:"button",onClick:()=>this.state.keypadOpen?this.closeKeypad():this.openKeypad(),children:props=>jsxRuntimeExports.jsx(MathInputIcon,{active:this.state.keypadOpen,...props})})})]})})}constructor(...args){super(...args),this.__mathFieldWrapperRef=null,this.__mathField=null,this.state={focused:false,keypadOpen:this.props.buttonsVisible==="always"?true:false,cursorContext:CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...getKeyTranslator(locale,this.context.strings),FRAC:mathQuill=>{const contents=mathQuill.latex();mathQuill.typedText("/");if(mathQuill.latex()===contents){mathQuill.cmd("\\frac");}}};const inputModifier=customKeyTranslator[value];if(inputModifier){inputModifier(input,value);input?.focus();return}if(typeof value==="function"){value(input);}else if(value[0]==="\\"){input?.cmd(value).focus();}else {input?.write(value).focus();}input?.focus();},this.mathField=()=>{if(!this.__mathField&&this.__mathFieldWrapperRef){const{locale}=this.context;this.__mathField=createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathQuillInstance.L];if(left&&left.ctrlSeq==="\\cdot "){mathField.controller().backspace();mathField.cmd("\\times");}}else {value=value.replace(/\\times/g,"\\cdot");}if(this.props.value!==value){this.props.onChange(value);}this.setState({cursorContext:getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){$(this.__mathFieldWrapperRef).submit();}},upOutOf:mathField=>{mathField.typedText("^");}}}));}this.__mathField?.setAriaLabel(this.props.ariaLabel);return this.__mathField},this.focus=()=>{this.mathField()?.focus();this.setState({focused:true});},this.blur=()=>this.setState({focused:false}),this.handleKeypadPress=(key,e)=>{if(key==="DISMISS"){this.closeKeypad();return}const{locale}=this.context;const translator=getKeyTranslator(locale,this.context.strings)[key];const mathField=this.mathField();if(mathField){if(translator){translator(mathField,key);}this.setState({cursorContext:getCursorContext(mathField)});}if(e?.type==="click"){this.focus();}};}}InnerMathInput.contextType=PerseusI18nContext;InnerMathInput.defaultProps={value:"",convertDotToTimes:false};class MathInput extends React.Component{blur(){this.inputRef.current?.blur();}focus(){this.inputRef.current?.focus();}insert(value){this.inputRef.current?.insert(value);}render(){return jsxRuntimeExports.jsx(InnerMathInput,{...this.props,ref:this.inputRef,mathInputStrings:this.context.strings})}constructor(...args){super(...args),this.inputRef=React.createRef();}}MathInput.contextType=MathInputI18nContext;MathInput.defaultProps={ariaLabel:"Math input"};const MathInputIcon=({hovered,focused,active})=>{let fillColor;switch(true){case focused||active:fillColor=semanticColor.action.primary.progressive.default.foreground;break;case hovered:fillColor=semanticColor.action.primary.progressive.hover.background;break;default:fillColor=semanticColor.core.foreground.neutral.strong;break}const dynamicClass=active||focused?styles$C.iconActive:styles$C.iconInactive;return jsxRuntimeExports.jsx(View,{style:[styles$C.iconContainer,dynamicClass],children:jsxRuntimeExports.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",fill:fillColor,viewBox:"0 0 256 256",children:jsxRuntimeExports.jsx("path",{d:"M112,72a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16h64A8,8,0,0,1,112,72Zm-8,104H80V152a8,8,0,0,0-16,0v24H40a8,8,0,0,0,0,16H64v24a8,8,0,0,0,16,0V192h24a8,8,0,0,0,0-16Zm48,0h64a8,8,0,0,0,0-16H152a8,8,0,0,0,0,16Zm64,16H152a8,8,0,0,0,0,16h64a8,8,0,0,0,0-16Zm-61.66-90.34a8,8,0,0,0,11.32,0L184,83.31l18.34,18.35a8,8,0,0,0,11.32-11.32L195.31,72l18.35-18.34a8,8,0,0,0-11.32-11.32L184,60.69,165.66,42.34a8,8,0,0,0-11.32,11.32L172.69,72,154.34,90.34A8,8,0,0,0,154.34,101.66Z"})})})};const mapButtonSets=buttonSets=>{const keypadButtonSets={};if(!buttonSets){return keypadButtonSets}buttonSets.forEach(buttonSet=>{switch(buttonSet){case "advanced relations":keypadButtonSets.advancedRelations=true;break;case "basic relations":keypadButtonSets.basicRelations=true;break;case "basic+div":keypadButtonSets.divisionKey=true;break;case "logarithms":keypadButtonSets.logarithms=true;break;case "prealgebra":keypadButtonSets.preAlgebra=true;break;case "trig":keypadButtonSets.trigonometry=true;break;case "scientific":keypadButtonSets.scientific=true;break;}});return keypadButtonSets};const inputFocused={borderWidth:2,borderColor:semanticColor.core.border.instructive.default,margin:-1};const styles$C=StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:sizing.size_040,borderRadius:1},iconInactive:{border:"2px solid transparent",backgroundColor:semanticColor.core.background.neutral.subtle},iconActive:{border:`2px solid ${semanticColor.core.border.knockout.default}`,backgroundColor:semanticColor.core.background.neutral.default},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:semanticColor.core.border.neutral.default,borderRadius:3,background:semanticColor.core.background.base.default,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,paddingBlockEnd:sizing.size_060,maxInlineSize:"initial"}});
|
|
1418
1418
|
|
|
1419
1419
|
let _dependencies=null;const setDependencies=dependencies=>{_dependencies=dependencies;};const getDependencies=()=>{if(_dependencies){return _dependencies}throw new Error(["Perseus has not been provided required dependencies.","setDependencies(dependencies) must be called first.","Make sure Perseus is being imported from javascript/perseus/perseus.js."].join("\n"))};const DependenciesContext=React.createContext({analytics:{onAnalyticsEvent:async()=>{}},generateUrl:()=>{throw new Error("generateUrl dependency not provided in Perseus dependencies")},useVideo:()=>{throw new Error("useVideo dependency not provided in Perseus dependencies")}});const useDependencies=()=>{const deps=React.useContext(DependenciesContext);return deps};
|
|
1420
1420
|
|
|
@@ -1430,7 +1430,7 @@ const ApiOptions={propTypes:PropTypes.shape({isArticle:PropTypes.bool.isRequired
|
|
|
1430
1430
|
|
|
1431
1431
|
const getPromptJSON$q=(label,userInput)=>{return {type:"expression",label,userInput:{value:userInput}}};
|
|
1432
1432
|
|
|
1433
|
-
const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};const defaultButtonSets=["basic","trig","prealgebra","logarithms"];const defaultOnFocus=()=>{};const defaultOnBlur=()=>{};const KeypadInputWithInterface=React.forwardRef(function KeypadInputWithInterface(props,ref){const keypadInputRef=React.useRef(null);const noopKeypadActivation=_keypadActive=>{};React.useImperativeHandle(ref,()=>({focus:(cb=noopKeypadActivation)=>keypadInputRef.current?.focus(cb),blur:()=>keypadInputRef.current?.blur(),insert:val=>{keypadInputRef.current?.mathField?.pressKey?.(val);}}));return jsxRuntimeExports.jsx(KeypadInput,{ref:keypadInputRef,...props})});const Expression=forwardRef(function Expression({apiOptions=ApiOptions.defaults,buttonSets=defaultButtonSets,times=false,onFocus=defaultOnFocus,onBlur=defaultOnBlur,userInput="",visibleLabel,ariaLabel,keypadElement,extraKeys,handleUserInput,trackInteraction,widgetId,answerForms,...rest},ref){const{strings}=usePerseusI18n();const{analytics}=useDependencies();const{setKeypadActive}=React.useContext(KeypadContext);const textareaId=useId();const inputRef=useRef(null);const rootRef=useRef(null);useEffect(()=>{analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"expression",widgetId}});if(rootRef.current){const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=rootRef.current.querySelector(selector);if(inputElement instanceof HTMLElement){inputElement.setAttribute("id",textareaId);}}},[]);const handleFocus=()=>{analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});onFocus([]);};const handleBlur=()=>{onBlur([]);};const changeAndTrack=(value,cb)=>{const normalized=normalizeTex(value);handleUserInput(normalized,cb);trackInteraction();};const mobileHandleFocus=()=>{keypadElement?.configure(getKeypadConfiguration(),()=>{if(rootRef.current){handleFocus();}});};const getKeypadConfiguration=useCallback(()=>{return {keypadType:"EXPRESSION",extraKeys:extraKeys,times:times}},[extraKeys,times]);const getFocusTarget=useCallback(()=>{if(!rootRef.current){return null}const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const element=rootRef.current.querySelector(selector);return element instanceof HTMLElement?element:null},[apiOptions.customKeypad]);useImperativeHandle(ref,()=>({focus:()=>{const targetBefore=getFocusTarget();inputRef.current?.focus?.(setKeypadActive);const targetAfter=getFocusTarget()??targetBefore??(document.activeElement instanceof HTMLElement?document.activeElement:null);if(!targetAfter){return false}if(document.activeElement!==targetAfter){targetAfter.focus();}return document.activeElement===targetAfter},focusInputPath:path=>{inputRef.current?.focus?.(setKeypadActive);},blurInputPath:path=>{if(typeof inputRef.current?.blur==="function"){inputRef.current?.blur();}},insert:keyPressed=>{inputRef.current?.insert?.(keyPressed);},getInputPaths:()=>[[]],getUserInput:()=>{return normalizeTex(userInput)},getKeypadConfiguration,getPromptJSON:()=>{return getPromptJSON$q(visibleLabel,normalizeTex(userInput))},getSerializedState:()=>{return {...rest,value:userInput,keypadConfiguration:getKeypadConfiguration(),times,buttonSets}}}),[userInput,setKeypadActive,getKeypadConfiguration,getFocusTarget,rest,visibleLabel,buttonSets,times]);const keypadConfiguration=getKeypadConfiguration();if(apiOptions.customKeypad){return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$B.mobileLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx(KeypadInputWithInterface,{ref:inputRef,ariaLabel:ariaLabel||strings.mathInputBox,value:userInput,keypadElement:keypadElement,onChange:changeAndTrack,onFocus:mobileHandleFocus,onBlur:handleBlur})]})}return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$B.desktopLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-expression",children:jsxRuntimeExports.jsx(MathInput,{ref:inputRef,value:userInput,onChange:changeAndTrack,convertDotToTimes:times,buttonSets:buttonSets,onFocus:handleFocus,onBlur:handleBlur,ariaLabel:ariaLabel||strings.mathInputBox,extraKeys:keypadConfiguration.extraKeys,onAnalyticsEvent:analytics?.onAnalyticsEvent??(async()=>{})})})]})});const styles$B=StyleSheet.create({mobileLabelInputWrapper:{
|
|
1433
|
+
const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};const defaultButtonSets=["basic","trig","prealgebra","logarithms"];const defaultOnFocus=()=>{};const defaultOnBlur=()=>{};const KeypadInputWithInterface=React.forwardRef(function KeypadInputWithInterface(props,ref){const keypadInputRef=React.useRef(null);const noopKeypadActivation=_keypadActive=>{};React.useImperativeHandle(ref,()=>({focus:(cb=noopKeypadActivation)=>keypadInputRef.current?.focus(cb),blur:()=>keypadInputRef.current?.blur(),insert:val=>{keypadInputRef.current?.mathField?.pressKey?.(val);}}));return jsxRuntimeExports.jsx(KeypadInput,{ref:keypadInputRef,...props})});const Expression=forwardRef(function Expression({apiOptions=ApiOptions.defaults,buttonSets=defaultButtonSets,times=false,onFocus=defaultOnFocus,onBlur=defaultOnBlur,userInput="",visibleLabel,ariaLabel,keypadElement,extraKeys,handleUserInput,trackInteraction,widgetId,answerForms,...rest},ref){const{strings}=usePerseusI18n();const{analytics}=useDependencies();const{setKeypadActive}=React.useContext(KeypadContext);const textareaId=useId();const inputRef=useRef(null);const rootRef=useRef(null);useEffect(()=>{analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"expression",widgetId}});if(rootRef.current){const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=rootRef.current.querySelector(selector);if(inputElement instanceof HTMLElement){inputElement.setAttribute("id",textareaId);}}},[]);const handleFocus=()=>{analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});onFocus([]);};const handleBlur=()=>{onBlur([]);};const changeAndTrack=(value,cb)=>{const normalized=normalizeTex(value);handleUserInput(normalized,cb);trackInteraction();};const mobileHandleFocus=()=>{keypadElement?.configure(getKeypadConfiguration(),()=>{if(rootRef.current){handleFocus();}});};const getKeypadConfiguration=useCallback(()=>{return {keypadType:"EXPRESSION",extraKeys:extraKeys,times:times}},[extraKeys,times]);const getFocusTarget=useCallback(()=>{if(!rootRef.current){return null}const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const element=rootRef.current.querySelector(selector);return element instanceof HTMLElement?element:null},[apiOptions.customKeypad]);useImperativeHandle(ref,()=>({focus:()=>{const targetBefore=getFocusTarget();inputRef.current?.focus?.(setKeypadActive);const targetAfter=getFocusTarget()??targetBefore??(document.activeElement instanceof HTMLElement?document.activeElement:null);if(!targetAfter){return false}if(document.activeElement!==targetAfter){targetAfter.focus();}return document.activeElement===targetAfter},focusInputPath:path=>{inputRef.current?.focus?.(setKeypadActive);},blurInputPath:path=>{if(typeof inputRef.current?.blur==="function"){inputRef.current?.blur();}},insert:keyPressed=>{inputRef.current?.insert?.(keyPressed);},getInputPaths:()=>[[]],getUserInput:()=>{return normalizeTex(userInput)},getKeypadConfiguration,getPromptJSON:()=>{return getPromptJSON$q(visibleLabel,normalizeTex(userInput))},getSerializedState:()=>{return {...rest,value:userInput,keypadConfiguration:getKeypadConfiguration(),times,buttonSets}}}),[userInput,setKeypadActive,getKeypadConfiguration,getFocusTarget,rest,visibleLabel,buttonSets,times]);const keypadConfiguration=getKeypadConfiguration();if(apiOptions.customKeypad){return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$B.mobileLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx(KeypadInputWithInterface,{ref:inputRef,ariaLabel:ariaLabel||strings.mathInputBox,value:userInput,keypadElement:keypadElement,onChange:changeAndTrack,onFocus:mobileHandleFocus,onBlur:handleBlur})]})}return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$B.desktopLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-expression",children:jsxRuntimeExports.jsx(MathInput,{ref:inputRef,value:userInput,onChange:changeAndTrack,convertDotToTimes:times,buttonSets:buttonSets,onFocus:handleFocus,onBlur:handleBlur,ariaLabel:ariaLabel||strings.mathInputBox,extraKeys:keypadConfiguration.extraKeys,onAnalyticsEvent:analytics?.onAnalyticsEvent??(async()=>{})})})]})});const styles$B=StyleSheet.create({mobileLabelInputWrapper:{paddingBlockStart:"15px",paddingInline:"4px",paddingBlockEnd:"0"},desktopLabelInputWrapper:{marginBlockStart:"5px",marginInline:"5px",marginBlockEnd:"0"}});function getUserInputFromSerializedState$i(serializedState){return normalizeTex(serializedState.value)}function getStartUserInput$i(){return ""}function getOneCorrectAnswerFromRubric$1(rubric){const correctAnswers=(rubric.answerForms||[]).filter(answerForm=>answerForm.considered==="correct");if(correctAnswers.length===0){return}return correctAnswers[0].value}function getCorrectUserInput$9(options){for(const form of options.answerForms){if(form.considered==="correct"){return form.value}}return ""}var Expression$1 = {name:"expression",displayName:"Expression / Equation",widget:Expression,isLintable:true,getOneCorrectAnswerFromRubric: getOneCorrectAnswerFromRubric$1,getStartUserInput: getStartUserInput$i,getCorrectUserInput: getCorrectUserInput$9,getUserInputFromSerializedState: getUserInputFromSerializedState$i};
|
|
1434
1434
|
|
|
1435
1435
|
class SimpleKeypadInput extends React.Component{componentDidMount(){this._isMounted=true;}componentWillUnmount(){this._isMounted=false;}focus(){this.inputRef.current?.focus(this.context.setKeypadActive);}blur(){this.inputRef.current?.blur();}getValue(){return this.props.value}render(){const _this=this;const{keypadElement,onFocus,value,...rest}=_this.props;return jsxRuntimeExports.jsx(KeypadInput,{ref:this.inputRef,keypadElement:keypadElement,onFocus:()=>{if(keypadElement){keypadElement.configure({keypadType:"FRACTION"},()=>{if(_this._isMounted){onFocus?.();}});}else {onFocus?.();}},value:value==null?"":""+value,...rest})}constructor(...args){super(...args),this._isMounted=false,this.inputRef=React.createRef();}}SimpleKeypadInput.contextType=KeypadContext;SimpleKeypadInput.propTypes={keypadElement:keypadElementPropType,onFocus:PropTypes.func,value:PropTypes.oneOfType([PropTypes.string,PropTypes.number])};
|
|
1436
1436
|
|
|
@@ -1479,9 +1479,9 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
1479
1479
|
white: white
|
|
1480
1480
|
});
|
|
1481
1481
|
|
|
1482
|
-
const MIN_VIEWPORT_HEIGHT=480;class FixedToResponsive extends React.Component{componentDidMount(){this._isMounted=true;if(window.innerHeight<MIN_VIEWPORT_HEIGHT){setTimeout(this._cacheViewportSize,800);}else {this._cacheViewportSize();}}componentWillUnmount(){this._isMounted=false;}render(){const aspectRatio=this.props.width/this.props.height;let{width,height}=this.props;if(this.props.constrainHeight&&this.state.viewportHeight){const maxHeight=2/3*this.state.viewportHeight;if(this.props.height>=maxHeight){height=maxHeight;width=maxHeight*aspectRatio;}}const style={maxWidth:width,maxHeight:height,aspectRatio:aspectRatio.toFixed(4)};const className=classNames$2("fixed-to-responsive",this.props.className);const container=jsxRuntimeExports.jsx("div",{className:className,style:style,"data-scale":this.props.scale,children:this.props.children});const shouldFullBleed=this.props.allowFullBleed&&this.state.viewportWidth&&width>=this.state.viewportWidth;if(shouldFullBleed){return jsxRuntimeExports.jsx("div",{style:{
|
|
1482
|
+
const MIN_VIEWPORT_HEIGHT=480;class FixedToResponsive extends React.Component{componentDidMount(){this._isMounted=true;if(window.innerHeight<MIN_VIEWPORT_HEIGHT){setTimeout(this._cacheViewportSize,800);}else {this._cacheViewportSize();}}componentWillUnmount(){this._isMounted=false;}render(){const aspectRatio=this.props.width/this.props.height;let{width,height}=this.props;if(this.props.constrainHeight&&this.state.viewportHeight){const maxHeight=2/3*this.state.viewportHeight;if(this.props.height>=maxHeight){height=maxHeight;width=maxHeight*aspectRatio;}}const style={maxWidth:width,maxHeight:height,aspectRatio:aspectRatio.toFixed(4)};const className=classNames$2("fixed-to-responsive",this.props.className);const container=jsxRuntimeExports.jsx("div",{className:className,style:style,"data-scale":this.props.scale,children:this.props.children});const shouldFullBleed=this.props.allowFullBleed&&this.state.viewportWidth&&width>=this.state.viewportWidth;if(shouldFullBleed){return jsxRuntimeExports.jsx("div",{style:{marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin},children:container})}return container}constructor(...args){super(...args),this._isMounted=false,this.state={viewportHeight:null,viewportWidth:null},this._cacheViewportSize=()=>{if(this._isMounted){this.setState({viewportHeight:Math.max(MIN_VIEWPORT_HEIGHT,window.innerHeight),viewportWidth:window.innerWidth});}};}}FixedToResponsive.defaultProps={className:"",constrainHeight:false,allowFullBleed:false};
|
|
1483
1483
|
|
|
1484
|
-
const GifImage=props=>{const{alt,width,height,scale,isPlaying,onLoop,onLoad,gifFrames}=props;const framesRef=React.useRef([]);const canvasRef=React.useRef(null);const hiddenCanvasRef=React.useRef(null);const animationIdRef=React.useRef(null);const currentFrameIndexRef=React.useRef(0);const lastFrameTimeRef=React.useRef(null);const latestPropsRef=React.useRef({isPlaying,onLoop,onLoad});latestPropsRef.current={isPlaying,onLoop,onLoad};const drawPatch=React.useCallback(index=>{const frames=framesRef.current;const hiddenCtx=hiddenCanvasRef.current?.getContext("2d");const displayCtx=canvasRef.current?.getContext("2d");if(!hiddenCtx||!hiddenCanvasRef.current||!displayCtx||!canvasRef.current||frames.length===0){return}const frame=frames[index];const{dims}=frame;if(index>0){const prev=frames[index-1];if(prev.disposalType===2){displayCtx.clearRect(prev.dims.left,prev.dims.top,prev.dims.width,prev.dims.height);}}hiddenCanvasRef.current.width=dims.width;hiddenCanvasRef.current.height=dims.height;const imageData=new ImageData(new Uint8ClampedArray(frame.patch),dims.width,dims.height);hiddenCtx.putImageData(imageData,0,0);displayCtx.drawImage(hiddenCanvasRef.current,dims.left,dims.top);},[]);const drawFrame=React.useCallback((index=0)=>{const frames=framesRef.current;if(frames.length===0||!canvasRef.current||!hiddenCanvasRef.current){return}const targetIndex=Math.min(index,frames.length-1);currentFrameIndexRef.current=targetIndex;const{width:nativeWidth,height:nativeHeight}=frames[0].dims;canvasRef.current.width=nativeWidth;canvasRef.current.height=nativeHeight;for(let i=0;i<=targetIndex;i++){drawPatch(i);}},[drawPatch]);const pause=React.useCallback(()=>{if(animationIdRef.current!==null){cancelAnimationFrame(animationIdRef.current);animationIdRef.current=null;}},[]);const animate=React.useCallback(timestamp=>{const frames=framesRef.current;if(frames.length===0){return}if(lastFrameTimeRef.current===null){lastFrameTimeRef.current=timestamp;drawPatch(currentFrameIndexRef.current);}const frame=frames[currentFrameIndexRef.current];const delay=frame.delay<=0?10:frame.delay;if(timestamp-lastFrameTimeRef.current>=delay){currentFrameIndexRef.current++;if(currentFrameIndexRef.current>=frames.length){currentFrameIndexRef.current=0;animationIdRef.current=null;latestPropsRef.current.onLoop();return}drawPatch(currentFrameIndexRef.current);lastFrameTimeRef.current=lastFrameTimeRef.current+delay;}animationIdRef.current=requestAnimationFrame(animate);},[drawPatch]);const play=React.useCallback(()=>{if(framesRef.current.length===0){return}lastFrameTimeRef.current=null;animationIdRef.current=requestAnimationFrame(animate);},[animate]);const restart=React.useCallback(()=>{pause();drawFrame(0);},[pause,drawFrame]);React.useEffect(()=>{framesRef.current=gifFrames??[];currentFrameIndexRef.current=0;lastFrameTimeRef.current=null;drawFrame(0);latestPropsRef.current.onLoad?.();if(latestPropsRef.current.isPlaying){play();}return ()=>pause()},[gifFrames]);const prevIsPlayingRef=React.useRef(isPlaying);React.useEffect(()=>{const wasPlaying=prevIsPlayingRef.current;prevIsPlayingRef.current=isPlaying;if(isPlaying&&!wasPlaying){play();}if(!isPlaying&&wasPlaying){if(currentFrameIndexRef.current===0){restart();}else {pause();}}},[isPlaying,restart,play,pause,drawFrame]);const setCanvasRef=React.useCallback(canvas=>{canvasRef.current=canvas;if(canvas&&framesRef.current.length>0){drawFrame(0);}},[drawFrame]);const displayHeight=!width&&height?height*scale:undefined;const aspectRatio=width&&height?`${width} / ${height}`:undefined;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("canvas",{"aria-label":alt,role:"img",ref:setCanvasRef,"data-testid":"gif-canvas",style:{width:width?width*scale:undefined,
|
|
1484
|
+
const GifImage=props=>{const{alt,width,height,scale,isPlaying,onLoop,onLoad,gifFrames}=props;const framesRef=React.useRef([]);const canvasRef=React.useRef(null);const hiddenCanvasRef=React.useRef(null);const animationIdRef=React.useRef(null);const currentFrameIndexRef=React.useRef(0);const lastFrameTimeRef=React.useRef(null);const latestPropsRef=React.useRef({isPlaying,onLoop,onLoad});latestPropsRef.current={isPlaying,onLoop,onLoad};const drawPatch=React.useCallback(index=>{const frames=framesRef.current;const hiddenCtx=hiddenCanvasRef.current?.getContext("2d");const displayCtx=canvasRef.current?.getContext("2d");if(!hiddenCtx||!hiddenCanvasRef.current||!displayCtx||!canvasRef.current||frames.length===0){return}const frame=frames[index];const{dims}=frame;if(index>0){const prev=frames[index-1];if(prev.disposalType===2){displayCtx.clearRect(prev.dims.left,prev.dims.top,prev.dims.width,prev.dims.height);}}hiddenCanvasRef.current.width=dims.width;hiddenCanvasRef.current.height=dims.height;const imageData=new ImageData(new Uint8ClampedArray(frame.patch),dims.width,dims.height);hiddenCtx.putImageData(imageData,0,0);displayCtx.drawImage(hiddenCanvasRef.current,dims.left,dims.top);},[]);const drawFrame=React.useCallback((index=0)=>{const frames=framesRef.current;if(frames.length===0||!canvasRef.current||!hiddenCanvasRef.current){return}const targetIndex=Math.min(index,frames.length-1);currentFrameIndexRef.current=targetIndex;const{width:nativeWidth,height:nativeHeight}=frames[0].dims;canvasRef.current.width=nativeWidth;canvasRef.current.height=nativeHeight;for(let i=0;i<=targetIndex;i++){drawPatch(i);}},[drawPatch]);const pause=React.useCallback(()=>{if(animationIdRef.current!==null){cancelAnimationFrame(animationIdRef.current);animationIdRef.current=null;}},[]);const animate=React.useCallback(timestamp=>{const frames=framesRef.current;if(frames.length===0){return}if(lastFrameTimeRef.current===null){lastFrameTimeRef.current=timestamp;drawPatch(currentFrameIndexRef.current);}const frame=frames[currentFrameIndexRef.current];const delay=frame.delay<=0?10:frame.delay;if(timestamp-lastFrameTimeRef.current>=delay){currentFrameIndexRef.current++;if(currentFrameIndexRef.current>=frames.length){currentFrameIndexRef.current=0;animationIdRef.current=null;latestPropsRef.current.onLoop();return}drawPatch(currentFrameIndexRef.current);lastFrameTimeRef.current=lastFrameTimeRef.current+delay;}animationIdRef.current=requestAnimationFrame(animate);},[drawPatch]);const play=React.useCallback(()=>{if(framesRef.current.length===0){return}lastFrameTimeRef.current=null;animationIdRef.current=requestAnimationFrame(animate);},[animate]);const restart=React.useCallback(()=>{pause();drawFrame(0);},[pause,drawFrame]);React.useEffect(()=>{framesRef.current=gifFrames??[];currentFrameIndexRef.current=0;lastFrameTimeRef.current=null;drawFrame(0);latestPropsRef.current.onLoad?.();if(latestPropsRef.current.isPlaying){play();}return ()=>pause()},[gifFrames]);const prevIsPlayingRef=React.useRef(isPlaying);React.useEffect(()=>{const wasPlaying=prevIsPlayingRef.current;prevIsPlayingRef.current=isPlaying;if(isPlaying&&!wasPlaying){play();}if(!isPlaying&&wasPlaying){if(currentFrameIndexRef.current===0){restart();}else {pause();}}},[isPlaying,restart,play,pause,drawFrame]);const setCanvasRef=React.useCallback(canvas=>{canvasRef.current=canvas;if(canvas&&framesRef.current.length>0){drawFrame(0);}},[drawFrame]);const displayHeight=!width&&height?height*scale:undefined;const aspectRatio=width&&height?`${width} / ${height}`:undefined;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("canvas",{"aria-label":alt,role:"img",ref:setCanvasRef,"data-testid":"gif-canvas",style:{width:width?width*scale:undefined,maxInlineSize:"100%",aspectRatio:aspectRatio,height:displayHeight}}),jsxRuntimeExports.jsx("canvas",{"aria-hidden":true,tabIndex:-1,ref:hiddenCanvasRef,"data-testid":"gif-hidden-canvas",style:{display:"none"}})]})};
|
|
1485
1485
|
|
|
1486
1486
|
function getKey$2(eventName,id){return eventName+":"+id}function getEventName$2(key){return key.split(":")[0]}const MovableHelperMethods={_fireEvent:function(listeners,...args){for(const listener of listeners){listener.call(this,...args);}},_applyConstraints:function(current,previous,extraOptions){let skipRemaining=false;return _.reduce(this.state.constraints,(memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current,this)},draw:function(){const currState=this.cloneState();MovableHelperMethods._fireEvent.call(this,this.state.draw,currState,this.prevState);this.prevState=currState;},listen:function(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey$2(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;},unlisten:function(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey$2(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);_.each(keys,function(key){if(getEventName$2(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}},this);}}};
|
|
1487
1487
|
|
|
@@ -1586,7 +1586,7 @@ const iconCheck={path:`M8.70710678,12.2928932 C8.31658249,11.9023689 7.68341751,
|
|
|
1586
1586
|
|
|
1587
1587
|
const add$1={constrain:function(){this.constrain();}};add$1.standard=[add$1.constrain];const modify$1={draw:function(){this.draw();}};modify$1.standard=[modify$1.draw];const draw$1={basic:function(state,prevState){const graphie=this.graphie;if(!this.state.visibleShape){const radii=[this.pointSize()/graphie.scale[0],this.pointSize()/graphie.scale[1]];const options={maxScale:Math.max(this.highlightStyle().scale,this.normalStyle().scale),padding:10,shadow:state.shadow};this.state.visibleShape=new WrappedEllipse(graphie,this.coord(),radii,options);this.state.visibleShape.attr(_.omit(this.normalStyle(),"scale"));this.state.visibleShape.toFront();if(this.mouseTarget()){this.mouseTarget().toFront();}}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.moveTo(this.coord());if(this.mouseTarget()){this.mouseTarget().moveTo(this.coord());}},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw$1.standard=[draw$1.basic,draw$1.highlight];const remove$1={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();this.state.visibleShape=null;}}};remove$1.standard=remove$1.basic;const constraints$1={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}return point.roundTo(coord,snap||this.graphie.snap)}},bound:function(range,snap,optionalPaddingPx){const paddingPx=(()=>{if(optionalPaddingPx===undefined){if(range===undefined){return 10}else {return 0}}else {return optionalPaddingPx}})();return function(coord,prev,options){const graphie=this.graphie;range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let lower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let upper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){lower=point.ceilTo(lower,snap);upper=point.floorTo(upper,snap);}if(!!options&&!!options.onOutOfBounds){if(coord[0]>upper[0]||coord[0]<lower[0]||coord[1]>upper[1]||coord[1]<lower[1]){options.onSkipRemaining();options.onOutOfBounds();}return coord}const coordX=Math.max(lower[0],Math.min(upper[0],coord[0]));const coordY=Math.max(lower[1],Math.min(upper[1],coord[1]));return [coordX,coordY]}}};constraints$1.standard=null;var MovablePointOptions = {add:add$1,modify:modify$1,draw:draw$1,remove:remove$1,onMoveStart:{standard:null},constraints:constraints$1,onMove:{standard:null},onMoveEnd:{standard:null},onClick:{standard:null}};
|
|
1588
1588
|
|
|
1589
|
-
const assert$4=InteractiveUtil.assert;const normalizeOptions$1=InteractiveUtil.normalizeOptions;const{processMath}=Tex$1;const DEFAULT_PROPS$1={coord:[0,0],pointSize:4,static:false,cursor:"move",normalStyle:null,highlightStyle:null,shadow:false,tooltip:false};const DEFAULT_STATE$1={added:false,hasMoved:false,visibleShape:null,outOfBounds:false,mouseTarget:null,touchOffset:null};const tooltipResetFunctions=[];let MovablePoint$5 = class MovablePoint{modify(options){this.update(_.extend(this._createDefaultState(),options));}_createDefaultState(){return {id:this.state.id,...normalizeOptions$1(pluck(MovablePointOptions,"standard")),...DEFAULT_PROPS$1}}cloneState(){return {...this.movable.cloneState(),...this.state}}update(options){const self=this;const graphie=self.graphie;const state=_.extend(self.state,normalizeOptions$1(options));assert$4(point.is(state.coord));const movableColor=tokenValue(state.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default);state.normalStyle=_.extend({fill:movableColor,stroke:movableColor,scale:1},state.normalStyle);state.highlightStyle=_.extend({fill:movableColor,stroke:movableColor,scale:2},state.highlightStyle);if(!state.static){if(!state.mouseTarget){const center=self.state.coord;const radii=graphie.unscaleVector(24);const options={mouselayer:true,padding:0,interactiveKindForTesting:"movable-point"};state.mouseTarget=new WrappedEllipse(graphie,center,radii,options);state.mouseTarget.attr({fill:"#000",opacity:0});}}const showTrashTooltip=()=>{this._showTooltip(container=>{render(jsxRuntimeExports.jsx("span",{style:{fontSize:"2em"},children:jsxRuntimeExports.jsx(InlineIcon,{...iconTrash,style:{position:"static",color:movableColor,
|
|
1589
|
+
const assert$4=InteractiveUtil.assert;const normalizeOptions$1=InteractiveUtil.normalizeOptions;const{processMath}=Tex$1;const DEFAULT_PROPS$1={coord:[0,0],pointSize:4,static:false,cursor:"move",normalStyle:null,highlightStyle:null,shadow:false,tooltip:false};const DEFAULT_STATE$1={added:false,hasMoved:false,visibleShape:null,outOfBounds:false,mouseTarget:null,touchOffset:null};const tooltipResetFunctions=[];let MovablePoint$5 = class MovablePoint{modify(options){this.update(_.extend(this._createDefaultState(),options));}_createDefaultState(){return {id:this.state.id,...normalizeOptions$1(pluck(MovablePointOptions,"standard")),...DEFAULT_PROPS$1}}cloneState(){return {...this.movable.cloneState(),...this.state}}update(options){const self=this;const graphie=self.graphie;const state=_.extend(self.state,normalizeOptions$1(options));assert$4(point.is(state.coord));const movableColor=tokenValue(state.static?semanticColor.core.foreground.disabled.strong:semanticColor.core.foreground.instructive.default);state.normalStyle=_.extend({fill:movableColor,stroke:movableColor,scale:1},state.normalStyle);state.highlightStyle=_.extend({fill:movableColor,stroke:movableColor,scale:2},state.highlightStyle);if(!state.static){if(!state.mouseTarget){const center=self.state.coord;const radii=graphie.unscaleVector(24);const options={mouselayer:true,padding:0,interactiveKindForTesting:"movable-point"};state.mouseTarget=new WrappedEllipse(graphie,center,radii,options);state.mouseTarget.attr({fill:"#000",opacity:0});}}const showTrashTooltip=()=>{this._showTooltip(container=>{render(jsxRuntimeExports.jsx("span",{style:{fontSize:"2em"},children:jsxRuntimeExports.jsx(InlineIcon,{...iconTrash,style:{position:"static",color:movableColor,marginInlineStart:9,marginInlineEnd:9}})}),container);});};let startCoord=state.coord;self.movable.modify(_.extend({},state,{add:null,modify:null,draw:self.draw.bind(self),remove:null,onMoveStart:startMouseCoord=>{state.hasMoved=false;startCoord=state.coord;if(state.touchOffset==null){const isMouse=!("ontouchstart"in window);state.touchOffset=isMouse?[0,0]:vector$3.subtract(startCoord,startMouseCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter="none";svgElem.style.filter=filter;}if(state.showHairlines){state.showHairlines(state.coord);}tooltipResetFunctions.forEach(f=>f());if(state.tooltip){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}if(state.shadow){const content=svgElem.getElementsByClassName("tooltip-content")[0];const filter="drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";content.style.filter=filter;}}self._fireEvent(state.onMoveStart,startCoord,startCoord);self.draw();},onMove:(mouseCoord,prevMouseCoord)=>{const transformedCoord=vector$3.add(mouseCoord,state.touchOffset);self.moveTo(transformedCoord);if(state.showHairlines){if(!this.state.outOfBounds){state.showHairlines(state.coord);}else {state.hideHairlines();}}if(state.tooltip){if(!this.state.outOfBounds){if(state.xOnlyTooltip){this._showTooltip(`${state.coord[0]}`);}else {this._showTooltip(`(${state.coord[0]}, ${state.coord[1]})`);}}}if(state.onRemove&&this.state.outOfBounds){showTrashTooltip();}},onMoveEnd:()=>{if(self.isHovering()&&!state.hasMoved){self._fireEvent(state.onClick,state.coord,startCoord);}const svgElem=state.visibleShape.wrapper;if(state.shadow){const filter="drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";svgElem.style.filter=filter;}if(state.hideHairlines){state.hideHairlines();}if(state.hasMoved){this._hideTooltip();}else if(state.onRemove){showTrashTooltip();const content=svgElem.getElementsByClassName("tooltip-content")[0];content.style.filter="none";this._tooltip.firstChild.addEventListener("touchstart",e=>{e.stopPropagation();},true);this._tooltip.firstChild.addEventListener("touchend",e=>{state.onRemove();e.stopPropagation();},true);}else if(state.tooltip){this._hideTooltip();}if(state.outOfBounds){state.onRemove();}self._fireEvent(state.onMoveEnd,state.coord,startCoord);state.hasMoved=false;state.touchOffset=null;self.draw();}}));if(!state.added){self.prevState={};self._fireEvent(state.add,self.cloneState(),self.prevState);state.added=true;self.prevState=self.cloneState();}self._fireEvent(state.modify,self.cloneState(),self.prevState);}draw(){const currState=this.cloneState();this._fireEvent(this.state.draw,currState,this.prevState);this.prevState=currState;}constrain(){const result=this._applyConstraints(this.coord(),this.coord());if(point.is(result)){this.setCoord(result);}return result!==false}_fireEvent(listeners,...args){for(const listener of listeners){listener.call(this,...args);}}_applyConstraints(current,previous,extraOptions){let skipRemaining=false;return this.state.constraints.reduce((memo,constraint)=>{if(memo===false){return false}if(skipRemaining){return memo}const result=constraint.call(this,memo,previous,{onSkipRemaining:()=>{skipRemaining=true;},...extraOptions});if(result===false){return false}if(point.is(result,2)){return result}if(result===true||result==null){return memo}throw new PerseusError("Constraint returned invalid result: "+result,Errors.Internal)},current)}_showTooltip(contents){if(!this._tooltip){this._tooltip=document.createElement("div");this._tooltip.className="tooltip-content";this.state.visibleShape.wrapper.className="tooltip";this.state.visibleShape.wrapper.appendChild(this._tooltip);tooltipResetFunctions.push(()=>{if(this.state.added){this._hideTooltip();}});}if(this._tooltip.firstChild){this._tooltip.removeChild(this._tooltip.firstChild);}this.state.visibleShape.wrapper.className="tooltip visible";this._tooltip.appendChild(document.createElement("span"));if(typeof contents==="string"){processMath(this._tooltip.firstChild,contents,false);}else if(typeof contents==="function"){contents(this._tooltip.firstChild);}else {this._tooltip.firstChild.appendChild(contents);}}_hideTooltip(){if(this._tooltip){this.state.visibleShape.wrapper.className="tooltip";}}coord(){return this.state.coord}setCoord(coord){assert$4(point.is(coord,2));this.state.coord=_.clone(coord);this.draw();}setCoordConstrained(coord){assert$4(point.is(coord,2));const result=this._applyConstraints(coord,this.coord());if(result!==false){this.state.coord=_.clone(result);this.draw();}}listen(eventName,id,func){this._listenerMap=this._listenerMap||{};const key=getKey(eventName,id);const index=this._listenerMap[key]=this._listenerMap[key]||this.state[eventName].length;this.state[eventName][index]=func;}unlisten(eventName,id){this._listenerMap=this._listenerMap||{};const key=getKey(eventName,id);const index=this._listenerMap[key];if(index!==undefined){this.state[eventName].splice(index,1);delete this._listenerMap[key];const keys=Object.keys(this._listenerMap);_.each(keys,key=>{if(getEventName(key)===eventName&&this._listenerMap[key]>index){this._listenerMap[key]--;}},this);}}grab(coord){this.state.touchOffset=[0,0];this.movable.grab(coord);this.moveTo(coord);}moveTo(coord){const state=this.state;this.state.outOfBounds=false;const result=this._applyConstraints(coord,state.coord,state.onRemove?{onOutOfBounds:()=>{this.state.outOfBounds=true;},onSkipRemaining:()=>{}}:{onSkipRemaining:()=>{}});if(result===false){return}if(point.is(result)){coord=result;}if(!point.equal(coord,state.coord)){const prevCoord=state.coord;state.coord=coord;state.hasMoved=true;this._fireEvent(state.onMove,state.coord,prevCoord);this.draw();}}remove(){this.state.added=false;this._fireEvent(this.state.remove);if(this.movable){this.movable.remove();}this.state.mouseTarget=null;}pointSize(){return this.state.pointSize}static(){return this.state.static}cursor(){return this.state.cursor}normalStyle(){return this.state.normalStyle}highlightStyle(){return this.state.highlightStyle}shadow(){return this.state.shadow}tooltip(){return this.state.tooltip}added(){return this.state.added}hasMoved(){return this.state.hasMoved}visibleShape(){return this.state.visibleShape}outOfBounds(){return this.state.outOfBounds}mouseTarget(){return this.state.mouseTarget}touchOffset(){return this.state.touchOffset}isHovering(){return this.movable.isHovering()}isDragging(){return this.movable.isDragging()}toBack(){this.movable.toBack();if(this.state.visibleShape){this.state.visibleShape.toBack();}}toFront(){if(this.state.visibleShape){this.state.visibleShape.toFront();}this.movable.toFront();}constructor(graphie,movable,options){this._listenerMap={};this.graphie=graphie;this.movable=movable;this.state={id:_.uniqueId("movablePoint")};this.modify({...DEFAULT_STATE$1,...options});}};MovablePoint$5.add=MovablePointOptions.add;MovablePoint$5.modify=MovablePointOptions.modify;MovablePoint$5.draw=MovablePointOptions.draw;MovablePoint$5.remove=MovablePointOptions.remove;MovablePoint$5.onMoveStart=MovablePointOptions.onMoveStart;MovablePoint$5.constraints=MovablePointOptions.constraints;MovablePoint$5.onMove=MovablePointOptions.onMove;MovablePoint$5.onMoveEnd=MovablePointOptions.onMoveEnd;MovablePoint$5.onClick=MovablePointOptions.onClick;function getKey(eventName,id){return eventName+":"+id}function getEventName(key){return key.split(":")[0]}
|
|
1590
1590
|
|
|
1591
1591
|
function sum(array){return _.reduce(array,function(memo,arg){return memo+arg},0)}function clockwise$2(points){const segments=_.zip(points,points.slice(1).concat(points.slice(0,1)));const areas=segments.map(function(segment){const p1=segment[0];const p2=segment[1];return (p2[0]-p1[0])*(p2[1]+p1[1])});return sum(areas)>0}const add={constrain:function(){this.constrain();},pointsToFront:function(state){_.invoke(state.points,"toFront");}};add.standard=[add.constrain,add.pointsToFront];const modify={draw:function(){this.draw();}};modify.standard=[modify.draw];const draw={basic:function(state,prevState){const graphie=this.graphie;const path=this.path(state);if(!this.state.visibleShape){this.state.visibleShape=graphie.raphael.path(path);this.state.visibleShape.attr(this.normalStyle());}if(state.normalStyle!==prevState.normalStyle&&!_.isEqual(state.normalStyle,prevState.normalStyle)){this.state.visibleShape.attr(this.normalStyle());}this.state.visibleShape.attr({path:path});if(this.mouseTarget()){this.mouseTarget().attr({path:path});}},labels:function(state,prevState){const graphie=this.graphie;const self=this;const coords=_.invoke(state.points,"coord");const isClockwise=clockwise$2(coords);const n=coords.length;if(self.state._labelCache!=null){_.invoke(self.state._labelCache,"remove");}self.state._labelCache=[];if(state.angleLabels.length||state.showRightAngleMarkers.length){if(self.state._labeledAngles==null){self.state._labeledAngles=_.times(Math.max(state.angleLabels.length,state.showRightAngleMarkers.length),function(){return graphie.label([0,0],"","center",state.labelStyle)});}_.each(self.state._labeledAngles,function(label,i){self.state._labelCache.push(graphie.labelAngle({point1:coords[(i-1+n)%n],vertex:coords[i],point3:coords[(i+1)%n],label:label,text:state.angleLabels[i],showRightAngleMarker:state.showRightAngleMarkers[i],numArcs:state.numArcs[i],clockwise:isClockwise,style:state.labelStyle}));});}if(state.sideLabels.length){if(self.state._labeledSides==null){self.state._labeledSides=state.sideLabels.map(function(label){return graphie.label([0,0],"","center",state.labelStyle)});}_.each(self.state._labeledSides,function(label,i){self.state._labelCache.push(graphie.labelSide({point1:coords[i],point2:coords[(i+1)%n],label:label,text:state.sideLabels[i],numArrows:state.numArrows[i],numTicks:state.numTicks[i],clockwise:isClockwise,style:state.labelStyle}));});}if(state.vertexLabels.length){if(self.state._labeledVertices==null){self.state._labeledVertices=state.vertexLabels.map(function(label){return graphie.label([0,0],"","center",state.labelStyle)});}_.each(self.state._labeledVertices,function(label,i){self.state._labelCache.push(graphie.labelVertex({point1:coords[(i-1+n)%n],vertex:coords[i],point3:coords[(i+1)%n],label:label,text:state.vertexLabels[i],clockwise:isClockwise,style:state.labelStyle}));});}self.state._labelCache=_.flatten(self.state._labelCache);},highlight:function(state,prevState){if(state.isHovering&&!prevState.isHovering){state.visibleShape.animate(this.highlightStyle(),50);}else if(!state.isHovering&&prevState.isHovering){state.visibleShape.animate(this.normalStyle(),50);}}};draw.standard=[draw.basic,draw.labels,draw.highlight];const remove={basic:function(){if(this.state.visibleShape){this.state.visibleShape.remove();}},labels:function(){const labels=[this.state._labeledSides,this.state._labeledVertices,this.state._labeledAngles,this.state._labelCache];_.each(labels,function(labelType){if(labelType!=null&&labelType.length){_.invoke(labelType,"remove");}});}};remove.standard=[remove.basic,remove.labels];const constraints={fixed:function(){return function(){return false}},snap:function(snap){return function(coord){if(snap===null){return true}snap=snap||this.graphie.snap;return point.roundTo(coord,snap)}},bound:function(range,snap,paddingPx){if(paddingPx===undefined){if(range===undefined){paddingPx=10;}else {paddingPx=0;}}return function(coord,prevCoord){const graphie=this.graphie;const delta=vector$3.subtract(coord,prevCoord);range=range||graphie.range;if(snap===undefined){snap=graphie.snap;}let absoluteLower=graphie.unscalePoint([paddingPx,graphie.ypixels-paddingPx]);let absoluteUpper=graphie.unscalePoint([graphie.xpixels-paddingPx,paddingPx]);if(snap){absoluteLower=point.ceilTo(absoluteLower,snap);absoluteUpper=point.floorTo(absoluteUpper,snap);}const deltaBounds=this.coords().map(function(coord,i){const max=vector$3.subtract(absoluteUpper,coord);const min=vector$3.subtract(absoluteLower,coord);return [min,max]});const boundedDelta=_.reduce(deltaBounds,function(delta,bound){const lower=bound[0];const upper=bound[1];const deltaX=Math.max(lower[0],Math.min(upper[0],delta[0]));const deltaY=Math.max(lower[1],Math.min(upper[1],delta[1]));return [deltaX,deltaY]},delta);return vector$3.add(prevCoord,boundedDelta)}}};constraints.standard=null;const onMove={updatePoints:function(coord,prevCoord){const actualDelta=vector$3.subtract(coord,prevCoord);_.each(this.state.points,function(point){point.setCoord(vector$3.add(point.coord(),actualDelta));});}};onMove.standard=null;var MovablePolygonOptions = {add:add,modify:modify,draw:draw,remove:remove,onMoveStart:{standard:null},constraints:constraints,onMove:onMove,onMoveEnd:{standard:null},onClick:{standard:null}};
|
|
1592
1592
|
|
|
@@ -1606,11 +1606,11 @@ function isGif(url){return url.endsWith(".gif")}async function decodeGifFrames(s
|
|
|
1606
1606
|
|
|
1607
1607
|
var styles$A = {"contentWrapper":"perseus_NqTCZY3N","imageContainer":"perseus_Ctn3miye"};
|
|
1608
1608
|
|
|
1609
|
-
const WB_MODAL_PADDING_TOTAL=64;const ZoomedImageView=props=>{const i18n=usePerseusI18n();const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const height=props.height;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);const maxAvailableWidth=window.innerWidth-WB_MODAL_PADDING_TOTAL;const maxAvailableHeight=window.innerHeight-WB_MODAL_PADDING_TOTAL;const scaleWidth=maxAvailableWidth/(width*scale);const scaleHeight=maxAvailableHeight/(height*scale);const fitRatio=Math.min(scaleWidth,scaleHeight,1);const constrainedDisplayWidth=width*fitRatio*scale;return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$A.contentWrapper,children:[jsxRuntimeExports.jsx("div",{className:styles$A.imageContainer,style:{width:constrainedDisplayWidth},children:jsxRuntimeExports.jsx("div",{className:"framework-perseus",tabIndex:0,id:initialFocusId,children:jsxRuntimeExports.jsx(SvgImage,{...svgProps,allowZoom:false,width:width,height:height,scale:scale})})}),jsxRuntimeExports.jsx(IconButton,{icon:closeIcon,onClick:onClose,"aria-label":i18n.strings.imageResetZoomAriaLabel,kind:"primary",style:wbStyles$2.closeButton})]})})})};const wbStyles$2=StyleSheet.create({dialog:{width:"auto",height:"auto",margin:sizing.size_320,"@media (max-width: 767px)":{margin:0}},closeButton:{position:"absolute",
|
|
1609
|
+
const WB_MODAL_PADDING_TOTAL=64;const ZoomedImageView=props=>{const i18n=usePerseusI18n();const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const height=props.height;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);const maxAvailableWidth=window.innerWidth-WB_MODAL_PADDING_TOTAL;const maxAvailableHeight=window.innerHeight-WB_MODAL_PADDING_TOTAL;const scaleWidth=maxAvailableWidth/(width*scale);const scaleHeight=maxAvailableHeight/(height*scale);const fitRatio=Math.min(scaleWidth,scaleHeight,1);const constrainedDisplayWidth=width*fitRatio*scale;return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$A.contentWrapper,children:[jsxRuntimeExports.jsx("div",{className:styles$A.imageContainer,style:{width:constrainedDisplayWidth},children:jsxRuntimeExports.jsx("div",{className:"framework-perseus",tabIndex:0,id:initialFocusId,children:jsxRuntimeExports.jsx(SvgImage,{...svgProps,allowZoom:false,width:width,height:height,scale:scale})})}),jsxRuntimeExports.jsx(IconButton,{icon:closeIcon,onClick:onClose,"aria-label":i18n.strings.imageResetZoomAriaLabel,kind:"primary",style:wbStyles$2.closeButton})]})})})};const wbStyles$2=StyleSheet.create({dialog:{width:"auto",height:"auto",margin:sizing.size_320,"@media (max-width: 767px)":{margin:0}},closeButton:{position:"absolute",insetBlockStart:border$1.width.medium,insetInlineEnd:border$1.width.medium,opacity:0,":hover":{opacity:1},":focus":{opacity:1}}});
|
|
1610
1610
|
|
|
1611
1611
|
const ZoomImageButton=props=>{const{imgSrc}=props;const i18n=usePerseusI18n();const uniqueId=React.useId().replace(/:/g,"");const zoomedImageUniqueId=`zoomed-image-${uniqueId}`;const handleClick=(event,openModal)=>{const mouseEvent=event;if(mouseEvent.metaKey||mouseEvent.ctrlKey){window.open(imgSrc,"_blank");}else {openModal();}};return jsxRuntimeExports.jsx(ModalLauncher,{initialFocusId:zoomedImageUniqueId,modal:({closeModal})=>jsxRuntimeExports.jsx(ZoomedImageView,{...props,initialFocusId:zoomedImageUniqueId,onClose:closeModal}),children:({openModal})=>jsxRuntimeExports.jsx(Clickable,{"aria-label":i18n.strings.imageZoomAriaLabel,onClick:event=>handleClick(event,openModal),style:{position:"absolute",width:"100%",height:"100%",overflow:"hidden",cursor:"zoom-in"},children:()=>{return jsxRuntimeExports.jsx(React.Fragment,{})}})})};
|
|
1612
1612
|
|
|
1613
|
-
function isImageProbablyPhotograph(imageUrl){return /\.(jpg|jpeg)$/i.test(imageUrl)}function spinner(){return jsxRuntimeExports.jsx("span",{style:{
|
|
1613
|
+
function isImageProbablyPhotograph(imageUrl){return /\.(jpg|jpeg)$/i.test(imageUrl)}function spinner(){return jsxRuntimeExports.jsx("span",{style:{insetBlockStart:0,insetInlineStart:0,width:"100%",height:"100%",position:"absolute",minInlineSize:"20px",display:"flex",justifyContent:"center",alignContent:"center"},children:jsxRuntimeExports.jsx(CircularSpinner,{size:"medium"})})}class SvgImage extends React.Component{componentDidMount(){this._isMounted=true;if(Util.isLabeledSVG(this.props.src)){this.loadResources();}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.src!==nextProps.src){this._isLoadingGraphie=false;this.setState({imageLoaded:false,dataLoaded:false});}}shouldComponentUpdate(nextProps,nextState){if(!_.isEqual(this.props,nextProps)){return true}const wasLoaded=this.isLoadedInState(this.state);const nextLoaded=this.isLoadedInState(nextState);return wasLoaded!==nextLoaded}componentDidUpdate(prevProps,prevState){const wasLoaded=this.isLoadedInState(prevState);const isLoaded=this.isLoadedInState(this.state);if(Util.isLabeledSVG(this.props.src)&&!isLoaded&&!this._isLoadingGraphie){this.loadResources();}if(!wasLoaded&&isLoaded){this.props.setAssetStatus(this.props.src,true);}}componentWillUnmount(){this._isMounted=false;}isLoadedInState(state){return Util.isLabeledSVG(this.props.src)?state.imageLoaded&&state.dataLoaded:state.imageLoaded}loadResources(){this._isLoadingGraphie=true;loadGraphie(this.props.src,(data,localized)=>{this._isLoadingGraphie=false;if(this._isMounted&&data.labels&&data.range){const labelsRendered={};data.labels.forEach(label=>{labelsRendered[label.content]=false;});this.setState({dataLoaded:true,labelDataIsLocalized:localized,labelsRendered,labels:data.labels,range:data.range});}});}sizeProvided(){return this.props.width!=null&&this.props.height!=null}_tryGetPixels(value){value=value||"";if(!value.endsWith("px")){return null}return parseFloat(value)||null}render(){const imageSrc=this.props.src;const imageProps={alt:this.props.alt,title:this.props.title};const width=this.props.width&&this.props.width*this.props.scale;const height=this.props.height&&this.props.height*this.props.scale;const dimensions={width,height};const responsive=this.props.responsive&&!!(width&&height);let extraGraphie;if(this.props.extraGraphie&&this.props.extraGraphie.labels.length){extraGraphie=jsxRuntimeExports.jsx(Graphie,{box:this.props.extraGraphie.box,range:this.props.extraGraphie.range,options:{labels:this.props.extraGraphie.labels},responsive:true,addMouseLayer:false,setup:this.setupGraphie});}if(!Util.isLabeledSVG(imageSrc)){if(responsive){const isGifControlled=this.props.isGifPlaying!==undefined;const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[!isGifControlled&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,imgProps:imageProps,preloader:spinner,onUpdate:this.handleUpdate}),extraGraphie]}),isGifControlled&&jsxRuntimeExports.jsx(GifImage,{alt:this.props.alt,width:this.props.width,height:this.props.height,scale:this.props.scale,isPlaying:!!this.props.isGifPlaying,onLoop:this.props.onGifLoop??(()=>{}),onLoad:()=>{this.onImageLoad();},gifFrames:this.props.gifFrames})]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,allowFullBleed:this.props.allowFullBleed&&isImageProbablyPhotograph(imageSrc),scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageSrc,width:this.props.width,height:this.props.height})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsx(ImageLoader$1,{src:imageSrc,preloader:spinner,imgProps:imageProps,onUpdate:this.handleUpdate})}const imageUrl=Util.getSvgUrl(imageSrc);let graphie;if(this.isLoadedInState(this.state)){let box;if(this.sizeProvided()){box=[width,height];}else if(this.state.imageDimensions){box=[this.state.imageDimensions[0]*this.props.scale,this.state.imageDimensions[1]*this.props.scale];}else {throw new PerseusError("svg-image has no dimensions",Errors.InvalidInput,{metadata:{src:this.props.src}})}graphie=jsxRuntimeExports.jsx(Graphie,{ref:"graphie",box:box,scale:[40*this.props.scale,40*this.props.scale],range:this.state.range,options:_.pick(this.state,"labels"),responsive:responsive,addMouseLayer:false,setup:this.setupGraphie});}if(responsive){const imageContent=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:spinner,imgProps:imageProps}),graphie,extraGraphie]});return jsxRuntimeExports.jsxs(FixedToResponsive,{className:"svg-image",width:width,height:height,constrainHeight:this.props.constrainHeight,scale:this.props.scale,children:[imageContent,this.props.allowZoom&&jsxRuntimeExports.jsx(ZoomImageButton,{...this.props,imgSrc:imageUrl,width:this.props.width,height:this.props.height})]})}imageProps.style=dimensions;return jsxRuntimeExports.jsxs("div",{className:"unresponsive-svg-image",style:dimensions,children:[jsxRuntimeExports.jsx(ImageLoader$1,{src:imageUrl,onLoad:this.onImageLoad,onUpdate:this.handleUpdate,preloader:spinner,imgProps:imageProps}),graphie]})}constructor(props){super(props),this.onImageLoad=()=>{if(this.sizeProvided()){this.setState({imageLoaded:true});}else {Util.getImageSize(this.props.src,(width,height)=>{if(this._isMounted){this.setState({imageLoaded:true,imageDimensions:[width,height]});}});}},this.setupGraphie=(graphie,options)=>{const newLabelsRendered={};_.map(options.labels,labelData=>{const{JIPT}=getDependencies();if(JIPT.useJIPT&&this.state.labelDataIsLocalized){const elem=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,false);getDependencies().svgImageJiptLabels.addLabel(elem,labelData.typesetAsMath);}else if(labelData.coordinates){const styling=this.props.scale!==1?{"font-size":100*this.props.scale+"%"}:null;const label=graphie.label(labelData.coordinates,labelData.content,labelData.alignment,labelData.typesetAsMath,styling);const labelStyle=label[0].style;let labelTop=this._tryGetPixels(labelStyle.top);let labelLeft=this._tryGetPixels(labelStyle.left);if(labelTop===null||labelLeft===null){const labelPosition=label.position();labelTop=labelPosition.top;labelLeft=labelPosition.left;}const svgHeight=(this.props.height||0)*this.props.scale;const svgWidth=(this.props.width||0)*this.props.scale;label.css({top:labelTop/svgHeight*100+"%",left:labelLeft/svgWidth*100+"%"});_.each(labelData.style,(styleValue,styleName)=>{label.css(styleName,styleValue);});}newLabelsRendered[labelData.content]=true;});this.setState(prev=>({labelsRendered:{...prev.labelsRendered,...newLabelsRendered}}));},this.handleUpdate=status=>{this.props.onUpdate();if(!Util.isLabeledSVG(this.props.src)&&status==="loaded"){this.setState({imageLoaded:true});}};props.setAssetStatus(props.src,false);this._isMounted=false;this._isLoadingGraphie=false;this.state={imageLoaded:false,imageDimensions:null,dataLoaded:false,labelDataIsLocalized:false,labels:[],labelsRendered:{},range:[[0,0],[0,0]]};}}SvgImage.contextType=PerseusI18nContext;SvgImage.defaultProps={constrainHeight:false,onUpdate:()=>{},responsive:true,src:"",scale:1,zoomToFullSizeOnMobile:false,setAssetStatus:(src,status)=>{}};
|
|
1614
1614
|
|
|
1615
1615
|
class Tex extends React.Component{render(){const{TeX:BaseTeX}=getDependencies();return jsxRuntimeExports.jsx(BaseTeX,{onRender:this.handleRender,children:this.props.children})}constructor(props){super(props),this.handleRender=()=>{this.setState({rendered:true});this.props.onRender();if(!this._hasRendered){this._hasRendered=true;this.props.setAssetStatus(this.props.children,true);}};this.props.setAssetStatus(this.props.children,false);this.state={rendered:false};this._hasRendered=false;}}Tex.defaultProps={onRender:()=>{},setAssetStatus:(src,status)=>{}};
|
|
1616
1616
|
|
|
@@ -1630,7 +1630,7 @@ const arrayRules={fence:{match:SimpleMarkdown.defaultRules.fence.match,order:1,p
|
|
|
1630
1630
|
|
|
1631
1631
|
const denylist=["key","ref","containerSizeClass","widgetId","onChange","problemNum","apiOptions","widgetIsOpen","findWidgets","onRemove","id","onBlur","onFocus","trackInteraction","keypadElement","linterContext","handleUserInput","analytics","showSolutions","reviewMode","widgetIndex","graded"];function excludeDenylistKeys(obj){if(obj==null){return obj}const rv={};for(const k of Object.keys(obj)){if(!denylist.includes(k)){rv[k]=obj[k];}}return rv}
|
|
1632
1632
|
|
|
1633
|
-
const exclamationIcon={path:"M6 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1z",height:12,width:12};class Lint extends React.Component{componentDidMount(){this._positionTimeout=window.setTimeout(this.getPosition);}componentWillUnmount(){window.clearTimeout(this._positionTimeout);}render(){const{children,inline,blockHighlight,insideTable}=this.props;if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:css(styles$z.lintContainer,styles$z.lintContainerBlock),children:[this.renderLink(styles$z.radioWidgetHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}if(inline){return jsxRuntimeExports.jsxs("span",{className:css(styles$z.lintContainer),children:[this.renderLink(styles$z.inlineHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}return jsxRuntimeExports.jsxs("div",{className:css(styles$z.lintContainer),children:[this.renderLink(styles$z.hoverTarget),jsxRuntimeExports.jsx("div",{children:children})]})}constructor(...args){super(...args),this.state={tooltipAbove:true},this.getPosition=()=>{const rect=ReactDOM__default.findDOMNode(this).getBoundingClientRect();this.setState({tooltipAbove:rect.top>100});},this.renderLink=style=>{const tooltipAbove=this.state.tooltipAbove;let severityStyle;let warningText;let warningTextStyle;if(this.props.severity===1){severityStyle=styles$z.indicatorError;warningText="Error";warningTextStyle=styles$z.publishBlockingError;}else if(this.props.severity===2){severityStyle=styles$z.indicatorWarning;warningText="Warning";warningTextStyle=styles$z.warning;}else {severityStyle=styles$z.indicatorGuideline;warningText="Recommendation";warningTextStyle=styles$z.warning;}return jsxRuntimeExports.jsxs("a",{href:`https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,target:"lint-help-window",className:css(style),children:[jsxRuntimeExports.jsx("span",{className:css(styles$z.indicator,severityStyle),children:this.props.severity===1&&jsxRuntimeExports.jsx(InlineIcon,{...exclamationIcon})}),jsxRuntimeExports.jsxs("div",{className:css(styles$z.tooltip,tooltipAbove&&styles$z.tooltipAbove),children:[this.props.message.split("\n\n").map((m,i)=>jsxRuntimeExports.jsxs("p",{className:css(styles$z.tooltipParagraph),children:[jsxRuntimeExports.jsxs("span",{className:css(warningTextStyle),children:[warningText,":"," "]}),m]},i)),jsxRuntimeExports.jsx("div",{className:css(styles$z.tail,tooltipAbove&&styles$z.tailAbove)})]})]})};}}const styles$z=StyleSheet.create({lintContainer:{position:"relative"},lintContainerBlock:{display:"block"},hoverTarget:{position:"absolute",
|
|
1633
|
+
const exclamationIcon={path:"M6 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-9a1 1 0 0 1 1 1v4a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1z",height:12,width:12};class Lint extends React.Component{componentDidMount(){this._positionTimeout=window.setTimeout(this.getPosition);}componentWillUnmount(){window.clearTimeout(this._positionTimeout);}render(){const{children,inline,blockHighlight,insideTable}=this.props;if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:css(styles$z.lintContainer,styles$z.lintContainerBlock),children:[this.renderLink(styles$z.radioWidgetHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}if(inline){return jsxRuntimeExports.jsxs("span",{className:css(styles$z.lintContainer),children:[this.renderLink(styles$z.inlineHoverTarget),jsxRuntimeExports.jsx("span",{children:children})]})}return jsxRuntimeExports.jsxs("div",{className:css(styles$z.lintContainer),children:[this.renderLink(styles$z.hoverTarget),jsxRuntimeExports.jsx("div",{children:children})]})}constructor(...args){super(...args),this.state={tooltipAbove:true},this.getPosition=()=>{const rect=ReactDOM__default.findDOMNode(this).getBoundingClientRect();this.setState({tooltipAbove:rect.top>100});},this.renderLink=style=>{const tooltipAbove=this.state.tooltipAbove;let severityStyle;let warningText;let warningTextStyle;if(this.props.severity===1){severityStyle=styles$z.indicatorError;warningText="Error";warningTextStyle=styles$z.publishBlockingError;}else if(this.props.severity===2){severityStyle=styles$z.indicatorWarning;warningText="Warning";warningTextStyle=styles$z.warning;}else {severityStyle=styles$z.indicatorGuideline;warningText="Recommendation";warningTextStyle=styles$z.warning;}return jsxRuntimeExports.jsxs("a",{href:`https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,target:"lint-help-window",className:css(style),children:[jsxRuntimeExports.jsx("span",{className:css(styles$z.indicator,severityStyle),children:this.props.severity===1&&jsxRuntimeExports.jsx(InlineIcon,{...exclamationIcon})}),jsxRuntimeExports.jsxs("div",{className:css(styles$z.tooltip,tooltipAbove&&styles$z.tooltipAbove),children:[this.props.message.split("\n\n").map((m,i)=>jsxRuntimeExports.jsxs("p",{className:css(styles$z.tooltipParagraph),children:[jsxRuntimeExports.jsxs("span",{className:css(warningTextStyle),children:[warningText,":"," "]}),m]},i)),jsxRuntimeExports.jsx("div",{className:css(styles$z.tail,tooltipAbove&&styles$z.tailAbove)})]})]})};}}const styles$z=StyleSheet.create({lintContainer:{position:"relative"},lintContainerBlock:{display:"block"},hoverTarget:{position:"absolute",insetBlockStart:0,insetInlineEnd:-40,display:"block",width:24,height:24,":hover > span":{backgroundColor:warningColorHover},":hover div":{display:"block"},":hover ~ div":{outline:"1px solid "+warningColor},":hover ~ div div[data-lint-inside-table]":{outline:"1px solid "+warningColor},":hover ~ div span[data-lint-inside-table]":{backgroundColor:warningColor,color:white}},inlineHoverTarget:{float:"inline-end",position:"relative",marginInlineEnd:-40,display:"block",width:24,height:24,":hover > span":{backgroundColor:warningColorHover},":hover div":{display:"block"},":hover ~ span":{backgroundColor:warningColor,color:white}},radioWidgetHoverTarget:{position:"absolute",insetInlineStart:-40,display:"block",width:24,height:24,minInlineSize:264,":hover > span":{backgroundColor:warningColorHover},":hover > div":{display:"block",padding:8,width:280},":hover > div > div":{insetInlineStart:8},":hover ~ span":{backgroundColor:warningColor,color:white}},indicator:{alignItems:"center",borderRadius:4,color:"white",display:"flex",fontSize:12,height:8,justifyContent:"center",margin:8,width:8},indicatorError:{backgroundColor:"#be2612",borderRadius:8,height:16,width:16},indicatorWarning:{backgroundColor:"#f86700"},indicatorGuideline:{backgroundColor:"#ffbe26"},tooltip:{position:"absolute",insetInlineEnd:-12,display:"none",zIndex:1e3,color:white,backgroundColor:gray17,opacity:.9,fontFamily:baseFontFamily,fontSize:"12px",lineHeight:"15px",width:"320px",borderRadius:"4px"},tooltipAbove:{insetBlockEnd:32},tail:{position:"absolute",insetBlockStart:-12,insetInlineEnd:16,width:0,height:0,borderInlineStart:"8px solid transparent",borderInlineEnd:"8px solid transparent",borderBlockEnd:"12px solid "+gray17},tailAbove:{insetBlockEnd:-12,borderBlockEnd:"none",borderBlockStart:"12px solid "+gray17,insetBlockStart:"auto"},tooltipParagraph:{margin:12},warning:{color:warningColor,fontFamily:boldFontFamily},publishBlockingError:{color:publishBlockingErrorColor}});
|
|
1634
1634
|
|
|
1635
1635
|
const rules$1={...pureMarkdownRules,columns:{...pureMarkdownRules.columns,react:(node,output,state)=>{return jsxRuntimeExports.jsxs("div",{className:"perseus-two-columns",children:[jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col1,state)})}),jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col2,state)})})]},state.key)}},crowdinId:{...pureMarkdownRules.crowdinId,react:(node,output,state)=>node.id},table:{...pureMarkdownRules.table,react:function(node,output,state){const table=SimpleMarkdown.defaultRules.table.react(node,output,state);if(!state.isMobile){return table}return React.cloneElement(table,{tabIndex:0})}},titledTable:{...pureMarkdownRules.titledTable,react:(node,output,state)=>{let contents;if(!node.table){contents="//invalid table//";}else if(node.table.type==="lint"){if(node.table.content?.type==="table"){contents=rules$1.lint.react({...node.table,content:{...node,table:node.table.content}},output,{...state,unwrapTitledTableContents:true});}else {contents=rules$1.lint.react(node.table,output,state);}}else {const tableOutput=SimpleMarkdown.defaultRules.table.react(node.table,output,state);const caption=jsxRuntimeExports.jsx("caption",{className:"perseus-table-title",children:output(node.title,state)},"caption");contents=React.cloneElement(tableOutput,null,[caption,...tableOutput.props.children]);}if(state.unwrapTitledTableContents){return contents}return jsxRuntimeExports.jsx("div",{className:"perseus-titled-table",children:contents},state.key)}},widget:{...pureMarkdownRules.widget,react:(node,output,state)=>{return jsxRuntimeExports.jsx("em",{children:`[Widget: ${node.id}]`},state.key)}},blockMath:{...pureMarkdownRules.blockMath,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},math:{...pureMarkdownRules.math,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},unescapedDollar:{...pureMarkdownRules.unescapedDollar,react:(node,output,state)=>{return "$"}},link:{...pureMarkdownRules.link,react:function(node,output,state){const link=SimpleMarkdown.defaultRules.link.react(node,output,state);const href=link.props.href;let rel=null;const isKAUrl=href?href.match(/https?:\/\/[^/]*khanacademy.org|^\//):false;if(!isKAUrl){rel="noopener noreferrer";}const newProps={...link.props,target:"_blank",href,rel};if(state.baseElements&&state.baseElements.Link){return state.baseElements.Link(newProps)}return React.cloneElement(link,newProps)}},codeBlock:{...pureMarkdownRules.codeBlock,react:(node,output,state)=>{if(node.lang==="alt"){return jsxRuntimeExports.jsx("div",{className:"perseus-markdown-alt perseus-sr-only",children:output(node.content,state)},state.key)}return SimpleMarkdown.defaultRules.codeBlock.react(node,output,state)}},lint:{...pureMarkdownRules.lint,react:(node,output,state)=>{return jsxRuntimeExports.jsx(Lint,{message:node.message,ruleName:node.ruleName,inline:isInline$1(node.content),blockHighlight:node.blockHighlight,insideTable:node.insideTable,severity:node.severity,children:output(node.content,state)})}},paragraph:{...pureMarkdownRules.paragraph,react:(node,output,state)=>{if(noParagraphForInlineWidget(node)){return output(node.content,state)}else {return jsxRuntimeExports.jsx("p",{children:output(node.content,state)})}}}};function isInline$1(node){return !!(node&&node.type&&inlineNodeTypes$1.hasOwnProperty(node.type))}const inlineNodeTypes$1={text:true,math:true,unescapedDollar:true,link:true,img:true,strong:true,u:true,em:true,del:true,code:true};const builtParser$1=SimpleMarkdown.parserFor(rules$1);const parse$1=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser$1(paragraphedSource,{...state,inline:false})};const inlineParser$1=(source,state)=>{return builtParser$1(source,{...state,inline:true})};const getContent$1=ast=>{if(Array.isArray(ast)){return _.flatten(ast.map(getContent$1))}if(ast.content&&typeof ast.content==="string"){if(ast.type.toLowerCase().indexOf("code")!==-1){return ["",ast.content,""]}return [ast.content.replace(/\s+/g," ")]}const children=_.chain(ast).values().flatten().filter(object=>object!=null&&_.has(object,"type")).value();if(!children.length){return []}const nestedContent=getContent$1(children);if(ast.type==="paragraph"&&nestedContent.length){nestedContent[0]=nestedContent[0].replace(/^\s+/,"");const last=nestedContent.length-1;nestedContent[last]=nestedContent[last].replace(/\s+$/,"");}return nestedContent};const characterCount$1=source=>{const ast=parse$1(source);const content=getContent$1(ast).join("");return content.length};var PerseusMarkdown$1 = {characterCount:characterCount$1,traverseContent:traverseContent,parse:parse$1,parseInline:inlineParser$1,reactFor:SimpleMarkdown.reactFor,ruleOutput:SimpleMarkdown.ruleOutput(rules$1,"react"),basicOutput:SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules$1,"react")),sanitizeUrl:SimpleMarkdown.sanitizeUrl};
|
|
1636
1636
|
|
|
@@ -1728,11 +1728,11 @@ var basicWidgets = [Radio,InputNumber,NumericInput$1,Expression$1];
|
|
|
1728
1728
|
|
|
1729
1729
|
const{pureXsMax,pureSmMax,pureMdMin,pureMdMax,pureLgMin,pureLgMax}=constants;var mediaQueries = {md:`@media screen and (min-width: ${pureMdMin}) and `+`(max-width: ${pureMdMax})`,xsOrSmaller:`@media screen and (max-width: ${pureXsMax})`,smOrSmaller:`@media screen and (max-width: ${pureSmMax})`,mdOrSmaller:`@media screen and (max-width: ${pureMdMax})`,lgOrSmaller:`@media screen and (max-width: ${pureLgMax})`,lgOrLarger:`@media screen and (min-width: ${pureLgMin})`};
|
|
1730
1730
|
|
|
1731
|
-
const{circleSize,radioMarginWidth}=constants;var sharedStyles = StyleSheet.create({blankBackground:{backgroundColor:"#FDFDFD"},perseusSrOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1},responsiveLabel:{[mediaQueries.smOrSmaller]:{fontSize:14,lineHeight:1.3},[mediaQueries.md]:{fontSize:17,lineHeight:1.4},[mediaQueries.lgOrLarger]:{fontSize:20,lineHeight:1.4}},responsiveInput:{display:"inline-block",WebkitAppearance:"none",appearance:"none","::-ms-check":{display:"none"},backgroundColor:"#fff",border:"2px solid #fff",boxShadow:`0 0px 0px ${border$1.width.medium} ${semanticColor.core.border.neutral.subtle}`,outline:"none",boxSizing:"border-box",flexShrink:0,
|
|
1731
|
+
const{circleSize,radioMarginWidth}=constants;var sharedStyles = StyleSheet.create({blankBackground:{backgroundColor:"#FDFDFD"},perseusSrOnly:{border:0,clip:"rect(0,0,0,0)",height:1,margin:-1,overflow:"hidden",padding:0,position:"absolute",width:1},responsiveLabel:{[mediaQueries.smOrSmaller]:{fontSize:14,lineHeight:1.3},[mediaQueries.md]:{fontSize:17,lineHeight:1.4},[mediaQueries.lgOrLarger]:{fontSize:20,lineHeight:1.4}},responsiveInput:{display:"inline-block",WebkitAppearance:"none",appearance:"none","::-ms-check":{display:"none"},backgroundColor:"#fff",border:"2px solid #fff",boxShadow:`0 0px 0px ${border$1.width.medium} ${semanticColor.core.border.neutral.subtle}`,outline:"none",boxSizing:"border-box",flexShrink:0,marginBlockEnd:1,marginInlineStart:1,marginInlineEnd:1,marginBlockStart:1,height:circleSize-2,width:circleSize-2},responsiveRadioInput:{borderRadius:"50%",":checked":{backgroundColor:semanticColor.core.foreground.instructive.default,border:"none",borderRadius:"50%",boxShadow:`inset 0px 0px 0px 2px white, `+`0 0px 0px 2px ${semanticColor.core.foreground.instructive.default}`,marginBlockStart:radioMarginWidth,marginBlockEnd:radioMarginWidth,marginInlineStart:radioMarginWidth,marginInlineEnd:radioMarginWidth,height:circleSize-2*radioMarginWidth,width:circleSize-2*radioMarginWidth}},responsiveRadioInputStatic:{":checked":{backgroundColor:semanticColor.core.foreground.disabled.strong,boxShadow:`inset 0px 0px 0px 2px white, `+`0 0px 0px 2px ${semanticColor.core.foreground.disabled.strong}`}},responsiveRadioInputActive:{backgroundColor:"#fff",border:"2px solid #fff",borderRadius:"50%",boxShadow:`0 0px 0px 2px ${semanticColor.core.border.neutral.strong}`,marginBlockStart:radioMarginWidth,marginBlockEnd:radioMarginWidth,marginInlineStart:radioMarginWidth,marginInlineEnd:radioMarginWidth,height:circleSize-2*radioMarginWidth,width:circleSize-2*radioMarginWidth,":checked":{backgroundColor:"#fff"}},disableTextSelection:{userSelect:"none"}});
|
|
1732
1732
|
|
|
1733
1733
|
const getPromptJSON$n=widgetData=>{return {type:"categorizer",options:{items:widgetData.items,categories:widgetData.categories},userInput:{itemToCategoryMapping:widgetData.userInput.values}}};
|
|
1734
1734
|
|
|
1735
|
-
const Categorizer=forwardRef(function Categorizer(props,ref){const{items,categories,randomizeItems,userInput,problemNum,apiOptions,linterContext,handleUserInput,trackInteraction,dependencies}=props;const{strings}=usePerseusI18n();const idPrefix=useMemo(()=>_.uniqueId("perseus_radio_"),[]);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"categorizer",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$n(props),getSerializedState(){const{userInput,...rest}=props;return {...rest,values:userInput.values}}}));function _handleUserInput(itemNum,catNum){const values=[...userInput.values];values[itemNum]=catNum;handleUserInput({values});trackInteraction();}let indexedItems=items.map((item,n)=>[item,n]);if(randomizeItems){indexedItems=shuffle(indexedItems,problemNum);}const table=jsxRuntimeExports.jsxs("table",{className:"categorizer-table "+css(styles$q.mobileTable),children:[jsxRuntimeExports.jsx("thead",{children:jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{className:css(styles$q.emptyHeaderCell)}),categories.map((category,i)=>{return jsxRuntimeExports.jsx("th",{className:css(styles$q.header),children:jsxRuntimeExports.jsx(Renderer,{content:category,linterContext:linterContext,strings:strings})},i)})]})}),jsxRuntimeExports.jsx("tbody",{children:indexedItems.map(indexedItem=>{const item=indexedItem[0];const itemNum=indexedItem[1];const uniqueId=idPrefix+"_"+itemNum;return jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(Renderer,{content:item,linterContext:linterContext,strings:strings})}),categories.map((catName,catNum)=>{const selected=userInput.values[itemNum]===catNum;return jsxRuntimeExports.jsx("td",{className:"category "+css(styles$q.cell),children:jsxRuntimeExports.jsxs("div",{role:"button","aria-label":catName,onClick:()=>_handleUserInput(itemNum,catNum),children:[apiOptions.isMobile&&jsxRuntimeExports.jsx("input",{type:"radio",name:uniqueId,className:css(sharedStyles.responsiveInput,sharedStyles.responsiveRadioInput,props.static&&sharedStyles.responsiveRadioInputStatic),checked:selected,onChange:()=>_handleUserInput(itemNum,catNum),onClick:e=>e.stopPropagation()}),!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:css(styles$q.radioSpan,selected&&styles$q.checkedRadioSpan,props.static&&selected&&styles$q.staticCheckedRadioSpan),children:selected?jsxRuntimeExports.jsx(InlineIcon,{...iconCircle}):jsxRuntimeExports.jsx(InlineIcon,{...iconCircleThin})})]})},catNum)})]},itemNum)})})]});const extraClassNames=classNames$2({"categorizer-container":true,"static-mode":props.static});const inlineStyles=apiOptions.isMobile?[styles$q.fullBleedContainer]:[];return jsxRuntimeExports.jsx("div",{className:extraClassNames+" "+css(...inlineStyles),children:table})});const styles$q=StyleSheet.create({mobileTable:{[mediaQueries.smOrSmaller]:{
|
|
1735
|
+
const Categorizer=forwardRef(function Categorizer(props,ref){const{items,categories,randomizeItems,userInput,problemNum,apiOptions,linterContext,handleUserInput,trackInteraction,dependencies}=props;const{strings}=usePerseusI18n();const idPrefix=useMemo(()=>_.uniqueId("perseus_radio_"),[]);useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"categorizer",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$n(props),getSerializedState(){const{userInput,...rest}=props;return {...rest,values:userInput.values}}}));function _handleUserInput(itemNum,catNum){const values=[...userInput.values];values[itemNum]=catNum;handleUserInput({values});trackInteraction();}let indexedItems=items.map((item,n)=>[item,n]);if(randomizeItems){indexedItems=shuffle(indexedItems,problemNum);}const table=jsxRuntimeExports.jsxs("table",{className:"categorizer-table "+css(styles$q.mobileTable),children:[jsxRuntimeExports.jsx("thead",{children:jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{className:css(styles$q.emptyHeaderCell)}),categories.map((category,i)=>{return jsxRuntimeExports.jsx("th",{className:css(styles$q.header),children:jsxRuntimeExports.jsx(Renderer,{content:category,linterContext:linterContext,strings:strings})},i)})]})}),jsxRuntimeExports.jsx("tbody",{children:indexedItems.map(indexedItem=>{const item=indexedItem[0];const itemNum=indexedItem[1];const uniqueId=idPrefix+"_"+itemNum;return jsxRuntimeExports.jsxs("tr",{children:[jsxRuntimeExports.jsx("td",{children:jsxRuntimeExports.jsx(Renderer,{content:item,linterContext:linterContext,strings:strings})}),categories.map((catName,catNum)=>{const selected=userInput.values[itemNum]===catNum;return jsxRuntimeExports.jsx("td",{className:"category "+css(styles$q.cell),children:jsxRuntimeExports.jsxs("div",{role:"button","aria-label":catName,onClick:()=>_handleUserInput(itemNum,catNum),children:[apiOptions.isMobile&&jsxRuntimeExports.jsx("input",{type:"radio",name:uniqueId,className:css(sharedStyles.responsiveInput,sharedStyles.responsiveRadioInput,props.static&&sharedStyles.responsiveRadioInputStatic),checked:selected,onChange:()=>_handleUserInput(itemNum,catNum),onClick:e=>e.stopPropagation()}),!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:css(styles$q.radioSpan,selected&&styles$q.checkedRadioSpan,props.static&&selected&&styles$q.staticCheckedRadioSpan),children:selected?jsxRuntimeExports.jsx(InlineIcon,{...iconCircle}):jsxRuntimeExports.jsx(InlineIcon,{...iconCircleThin})})]})},catNum)})]},itemNum)})})]});const extraClassNames=classNames$2({"categorizer-container":true,"static-mode":props.static});const inlineStyles=apiOptions.isMobile?[styles$q.fullBleedContainer]:[];return jsxRuntimeExports.jsx("div",{className:extraClassNames+" "+css(...inlineStyles),children:table})});const styles$q=StyleSheet.create({mobileTable:{[mediaQueries.smOrSmaller]:{minInlineSize:"auto"}},fullBleedContainer:{[mediaQueries.mdOrSmaller]:{marginInlineStart:-16,marginInlineEnd:-16,overflowX:"auto"}},header:{textAlign:"center",verticalAlign:"bottom"},cell:{textAlign:"center",padding:0,color:semanticColor.core.border.neutral.subtle,verticalAlign:"middle"},emptyHeaderCell:{backgroundColor:"inherit",borderBlockEnd:`${border$1.width.medium} solid ${semanticColor.core.border.neutral.subtle}`},radioSpan:{fontSize:sizing.size_280,paddingInlineEnd:3,cursor:"pointer",":hover":{color:semanticColor.core.foreground.instructive.subtle}},checkedRadioSpan:{color:semanticColor.core.foreground.instructive.default},staticCheckedRadioSpan:{color:semanticColor.core.foreground.disabled.strong}});function getUserInputFromSerializedState$e(serializedState){return {values:serializedState.values}}function getCorrectUserInput$7(options){return {values:options.values}}function getStartUserInput$f(){return {values:[]}}const WrappedCategorizer=withDependencies(Categorizer);var Categorizer$1 = {name:"categorizer",displayName:"Categorizer",widget:WrappedCategorizer,getUserInputFromSerializedState: getUserInputFromSerializedState$e,getCorrectUserInput: getCorrectUserInput$7,getStartUserInput: getStartUserInput$f,isLintable:true};
|
|
1736
1736
|
|
|
1737
1737
|
const isFileProtocol=protocol=>{if(protocol&&protocol.toLowerCase()==="file:"){return true}return false};
|
|
1738
1738
|
|
|
@@ -1752,7 +1752,7 @@ const styles$n={tooltipBody:{color:"var(--wb-semanticColor-core-foreground-neutr
|
|
|
1752
1752
|
|
|
1753
1753
|
class Definition extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"definition",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON$l(this.props)}render(){return jsxRuntimeExports.jsx(DefinitionConsumer,{children:({activeDefinitionId,setActiveDefinitionId})=>jsxRuntimeExports.jsx(Popover,{dismissEnabled:true,content:jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$n.tooltipBody,closeButtonVisible:true,children:jsxRuntimeExports.jsx(Renderer,{apiOptions:this.props.apiOptions,content:this.props.definition,widgets:this.props.widgets,strings:this.context.strings})}),opened:activeDefinitionId===this.props.widgetId,onClose:()=>setActiveDefinitionId(null),placement:"top",children:jsxRuntimeExports.jsx(Clickable,{onClick:()=>{this.props.trackInteraction();setActiveDefinitionId(this.props.widgetId);},"aria-label":this.context.strings.definitionIdentifier({word:this.props.togglePrompt}),children:()=>jsxRuntimeExports.jsx("span",{className:styles$o.definition,children:this.props.togglePrompt})})})})}constructor(...args){super(...args),this.isWidget=true;}}Definition.contextType=PerseusI18nContext;Definition.defaultProps={togglePrompt:"define me",definition:"definition goes here"};const WrappedDefinition=withDependencies(Definition);var Definition$1 = {name:"definition",displayName:"Definition",widget:WrappedDefinition};
|
|
1754
1754
|
|
|
1755
|
-
class DeprecatedStandin extends React__default.Component{render(){return jsxRuntimeExports.jsx("div",{style:{
|
|
1755
|
+
class DeprecatedStandin extends React__default.Component{render(){return jsxRuntimeExports.jsx("div",{style:{paddingBlockStart:8,paddingBlockEnd:8},children:jsxRuntimeExports.jsx(Banner,{text:this.context.strings.deprecatedStandin,kind:"info"})})}constructor(...args){super(...args),this.isWidget=true;}}DeprecatedStandin.contextType=PerseusI18nContext;var DeprecatedStandin$1 = {name:"deprecated-standin",displayName:"Deprecated Standin",widget:DeprecatedStandin,hidden:true};
|
|
1756
1756
|
|
|
1757
1757
|
const getPromptJSON$k=widgetData=>{return {type:"dropdown",options:{items:widgetData.choices.map(choice=>choice.content)},userInput:{selectedIndex:widgetData.userInput.value-1}}};
|
|
1758
1758
|
|
|
@@ -1772,15 +1772,15 @@ class FreeResponse extends React.Component{isOverLimit(){return !this.props.allo
|
|
|
1772
1772
|
|
|
1773
1773
|
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}};
|
|
1774
1774
|
|
|
1775
|
-
class GradedGroupAnswerBar extends React.Component{render(){const{apiOptions,answerBarState,onCheckAnswer,onNextQuestion}=this.props;const{keepTrying,tryAgain,check,correctExcited,nextQuestion}=this.context.strings;const answerBarStyle={...styles$j.answerBar,backgroundColor:answerBarState==="CORRECT"?semanticColor.core.background.base.subtle:semanticColor.core.background.base.default,justifyContent:answerBarState==="CORRECT"&&!onNextQuestion?"center":"space-between"};const message=answerBarState==="INCORRECT"?jsxRuntimeExports.jsxs("span",{style:styles$j.text,children:[jsxRuntimeExports.jsx("span",{style:styles$j.tryAgainIcon,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTryAgain})}),jsxRuntimeExports.jsx("span",{style:{
|
|
1775
|
+
class GradedGroupAnswerBar extends React.Component{render(){const{apiOptions,answerBarState,onCheckAnswer,onNextQuestion}=this.props;const{keepTrying,tryAgain,check,correctExcited,nextQuestion}=this.context.strings;const answerBarStyle={...styles$j.answerBar,backgroundColor:answerBarState==="CORRECT"?semanticColor.core.background.base.subtle:semanticColor.core.background.base.default,justifyContent:answerBarState==="CORRECT"&&!onNextQuestion?"center":"space-between"};const message=answerBarState==="INCORRECT"?jsxRuntimeExports.jsxs("span",{style:styles$j.text,children:[jsxRuntimeExports.jsx("span",{style:styles$j.tryAgainIcon,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTryAgain})}),jsxRuntimeExports.jsx("span",{style:{marginInlineStart:8},children:keepTrying})]}):jsxRuntimeExports.jsx("span",{});if(answerBarState!=="CORRECT"){const buttonLabel=answerBarState==="INCORRECT"?tryAgain:check;return jsxRuntimeExports.jsxs("div",{style:answerBarStyle,children:[message,jsxRuntimeExports.jsx(Button,{disabled:apiOptions.readOnly||answerBarState!=="ACTIVE",onClick:onCheckAnswer,children:buttonLabel})]})}return jsxRuntimeExports.jsxs("div",{style:answerBarStyle,children:[jsxRuntimeExports.jsxs("span",{style:styles$j.text,children:[jsxRuntimeExports.jsx("span",{style:{color:semanticColor.core.foreground.success.default},children:jsxRuntimeExports.jsx(InlineIcon,{...iconStar,style:{marginBlockEnd:5}})}),jsxRuntimeExports.jsx("span",{role:"alert","aria-label":correctExcited,style:{marginInlineStart:8},children:correctExcited})]}),onNextQuestion&&jsxRuntimeExports.jsx(Button,{onClick:onNextQuestion,children:nextQuestion})]})}}GradedGroupAnswerBar.contextType=PerseusI18nContext;const styles$j={answerBar:{display:"flex",alignItems:"center",height:68,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,marginBottom:negativePhoneMargin,marginTop:phoneMargin,paddingLeft:phoneMargin,paddingRight:10,borderTop:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.default}`},tryAgainIcon:{color:semanticColor.core.foreground.neutral.subtle,transform:"scale(-1,1) rotate(-268deg)"},text:{display:"flex",flexDirection:"row",alignItems:"center",fontWeight:font.weight.bold,fontSize:font.body.size.medium}};
|
|
1776
1776
|
|
|
1777
|
-
const GRADING_STATUSES={ungraded:"ungraded",correct:"correct",incorrect:"incorrect",invalid:"invalid"};const getNextState=(currentState,answerable)=>{switch(currentState){case "ACTIVE":return !answerable?"INACTIVE":currentState;case "INACTIVE":return answerable?"ACTIVE":currentState;case "INCORRECT":return answerable?"ACTIVE":"INACTIVE";default:return currentState}};class GradedGroup extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group",widgetSubType:"null",widgetId:this.props.widgetId}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}_handleUserInput(_userInput,widgetsEmpty){this.setState({status:GRADING_STATUSES.ungraded,message:""});const answerable=!widgetsEmpty;const answerBarState=this.state.answerBarState;const nextState=getNextState(answerBarState,answerable);this.setState({answerBarState:nextState});}getPromptJSON(){const hint=this.hintRendererRef.current?.getPromptJSON()||{content:this.props.hint?.content||"",widgets:{}};return getPromptJSON$i(this.props.title,this.rendererRef.current?.getPromptJSON(),hint)}render(){const apiOptions=_.extend({},ApiOptions.defaults,this.props.apiOptions,{onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){this.props.onBlur(oldFocus);}if(newFocus){this.props.onFocus(newFocus);}}});let gradeStatus=null;let icon=null;if(this.state.status===GRADING_STATUSES.correct){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconOk,style:{color:semanticColor.core.foreground.success.default}});gradeStatus=this.context.strings.correct;}else if(this.state.status===GRADING_STATUSES.incorrect){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconRemove,style:{color:semanticColor.core.foreground.critical.default}});gradeStatus=this.context.strings.incorrect;}const mobileClass=this.props.inGradedGroupSet?css(styles$i.gradedGroupInSet):css(styles$i.gradedGroup);const classes=classNames$2({[mobileClass]:apiOptions.isMobile,"perseus-graded-group":true,"answer-correct":apiOptions.isMobile?false:this.state.status===GRADING_STATUSES.correct,"answer-incorrect":apiOptions.isMobile?false:this.state.status===GRADING_STATUSES.incorrect});const{answerBarState}=this.state;const isCorrect=answerBarState==="CORRECT";const readOnly=apiOptions.readOnly||apiOptions.isMobile&&isCorrect;const showSolutions=isCorrect?"all":"none";return jsxRuntimeExports.jsxs("div",{className:classes,children:[!!this.props.title&&jsxRuntimeExports.jsx("div",{className:css(styles$i.title),children:this.props.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.widgets,handleUserInput:(userInput,widgetsEmpty)=>this._handleUserInput(userInput,widgetsEmpty),problemNum:0,children:({userInput,handleUserInput})=>jsxRuntimeExports.jsx(Renderer,{content:this.props.content,widgets:this.props.widgets,images:this.props.images,userInput:userInput,handleUserInput:handleUserInput,problemNum:0,ref:this.rendererRef,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,readOnly},showSolutions:showSolutions,linterContext:this.props.linterContext,strings:this.context.strings})}),!apiOptions.isMobile&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[icon!=null&&jsxRuntimeExports.jsx("div",{className:"group-icon",children:icon}),gradeStatus&&jsxRuntimeExports.jsx("div",{className:css(a11y.srOnly),role:"alert","aria-label":gradeStatus,children:gradeStatus}),jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",children:jsxRuntimeExports.jsx(Renderer,{content:this.state.message,strings:this.context.strings})}),jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:this.props.apiOptions.readOnly,onClick:this._checkAnswer,children:this.context.strings.check}),isCorrect&&this.props.onNextQuestion&&jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:this.props.apiOptions.readOnly,onClick:this.props.onNextQuestion,style:{
|
|
1777
|
+
const GRADING_STATUSES={ungraded:"ungraded",correct:"correct",incorrect:"incorrect",invalid:"invalid"};const getNextState=(currentState,answerable)=>{switch(currentState){case "ACTIVE":return !answerable?"INACTIVE":currentState;case "INACTIVE":return answerable?"ACTIVE":currentState;case "INCORRECT":return answerable?"ACTIVE":"INACTIVE";default:return currentState}};class GradedGroup extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group",widgetSubType:"null",widgetId:this.props.widgetId}});}shouldComponentUpdate(nextProps,nextState){return nextProps!==this.props||nextState!==this.state}_handleUserInput(_userInput,widgetsEmpty){this.setState({status:GRADING_STATUSES.ungraded,message:""});const answerable=!widgetsEmpty;const answerBarState=this.state.answerBarState;const nextState=getNextState(answerBarState,answerable);this.setState({answerBarState:nextState});}getPromptJSON(){const hint=this.hintRendererRef.current?.getPromptJSON()||{content:this.props.hint?.content||"",widgets:{}};return getPromptJSON$i(this.props.title,this.rendererRef.current?.getPromptJSON(),hint)}render(){const apiOptions=_.extend({},ApiOptions.defaults,this.props.apiOptions,{onFocusChange:(newFocus,oldFocus)=>{if(oldFocus){this.props.onBlur(oldFocus);}if(newFocus){this.props.onFocus(newFocus);}}});let gradeStatus=null;let icon=null;if(this.state.status===GRADING_STATUSES.correct){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconOk,style:{color:semanticColor.core.foreground.success.default}});gradeStatus=this.context.strings.correct;}else if(this.state.status===GRADING_STATUSES.incorrect){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconRemove,style:{color:semanticColor.core.foreground.critical.default}});gradeStatus=this.context.strings.incorrect;}const mobileClass=this.props.inGradedGroupSet?css(styles$i.gradedGroupInSet):css(styles$i.gradedGroup);const classes=classNames$2({[mobileClass]:apiOptions.isMobile,"perseus-graded-group":true,"answer-correct":apiOptions.isMobile?false:this.state.status===GRADING_STATUSES.correct,"answer-incorrect":apiOptions.isMobile?false:this.state.status===GRADING_STATUSES.incorrect});const{answerBarState}=this.state;const isCorrect=answerBarState==="CORRECT";const readOnly=apiOptions.readOnly||apiOptions.isMobile&&isCorrect;const showSolutions=isCorrect?"all":"none";return jsxRuntimeExports.jsxs("div",{className:classes,children:[!!this.props.title&&jsxRuntimeExports.jsx("div",{className:css(styles$i.title),children:this.props.title}),jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.widgets,handleUserInput:(userInput,widgetsEmpty)=>this._handleUserInput(userInput,widgetsEmpty),problemNum:0,children:({userInput,handleUserInput})=>jsxRuntimeExports.jsx(Renderer,{content:this.props.content,widgets:this.props.widgets,images:this.props.images,userInput:userInput,handleUserInput:handleUserInput,problemNum:0,ref:this.rendererRef,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,readOnly},showSolutions:showSolutions,linterContext:this.props.linterContext,strings:this.context.strings})}),!apiOptions.isMobile&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[icon!=null&&jsxRuntimeExports.jsx("div",{className:"group-icon",children:icon}),gradeStatus&&jsxRuntimeExports.jsx("div",{className:css(a11y.srOnly),role:"alert","aria-label":gradeStatus,children:gradeStatus}),jsxRuntimeExports.jsx("div",{role:"status","aria-live":"polite",children:jsxRuntimeExports.jsx(Renderer,{content:this.state.message,strings:this.context.strings})}),jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:this.props.apiOptions.readOnly,onClick:this._checkAnswer,children:this.context.strings.check}),isCorrect&&this.props.onNextQuestion&&jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:this.props.apiOptions.readOnly,onClick:this.props.onNextQuestion,style:{marginInlineStart:5},children:this.context.strings.nextQuestion})]}),this.props.hint?.content&&(this.state.showHint?jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("button",{tabIndex:"0",className:css(styles$i.explanationTitle),onClick:()=>this.setState({showHint:false}),onKeyPress:e=>{e.preventDefault();this.setState({showHint:false});},children:this.context.strings.hideExplanation}),jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>{const{content,widgets,images}=this.props.hint;return jsxRuntimeExports.jsx(Renderer,{content:content,widgets:widgets,images:images,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:this.hintRendererRef,apiOptions:apiOptions,linterContext:this.props.linterContext,strings:this.context.strings,showSolutions:showSolutions})}})]}):jsxRuntimeExports.jsx("button",{tabIndex:"0",onClick:()=>this.setState({showHint:true}),onKeyPress:e=>{e.preventDefault();this.setState({showHint:true});},className:css(styles$i.showHintLink),children:this.context.strings.explain})),apiOptions.isMobile&&jsxRuntimeExports.jsx(GradedGroupAnswerBar,{apiOptions:apiOptions,answerBarState:answerBarState,onCheckAnswer:this._checkAnswer,onNextQuestion:this.props.onNextQuestion})]})}constructor(...args){super(...args),this.state={status:GRADING_STATUSES.ungraded,showHint:false,message:"",answerBarState:"INACTIVE"},this.rendererRef=React.createRef(),this.hintRendererRef=React.createRef(),this._checkAnswer=()=>{const score=this.rendererRef.current?.score()||{type:"invalid"};const{INVALID_MESSAGE_PREFIX,DEFAULT_INVALID_MESSAGE_1,DEFAULT_INVALID_MESSAGE_2}=this.context.strings;const status=score.type==="points"?score.total===score.earned?GRADING_STATUSES.correct:GRADING_STATUSES.incorrect:GRADING_STATUSES.invalid;const message=score.type==="points"?score.message||"":score.message?`${INVALID_MESSAGE_PREFIX} ${mapErrorToString(score.message,this.context.strings)}`:`${INVALID_MESSAGE_PREFIX} ${DEFAULT_INVALID_MESSAGE_1}${DEFAULT_INVALID_MESSAGE_2}`;this.setState({status:status,message:message,answerBarState:status==="correct"?"CORRECT":"INCORRECT"});this.props.trackInteraction({status:status});},this.getInputPaths=()=>{return this.rendererRef.current?.getInputPaths()||[]},this.focus=()=>{return !!this.rendererRef.current?.focus()},this.focusInputPath=path=>{this.rendererRef.current?.focusPath(path);},this.blurInputPath=path=>{this.rendererRef.current?.blurPath(path);};}}GradedGroup.contextType=PerseusI18nContext;const styles$i=StyleSheet.create({gradedGroupInSet:{marginInlineStart:0,paddingInlineStart:0},gradedGroup:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"},showHintLink:{backgroundColor:"unset",fontSize:font.body.size.small,padding:0,border:"none",marginBlockStart:20,color:semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},explanationTitle:{backgroundColor:"unset",marginBlockStart:20,color:semanticColor.core.foreground.instructive.default,marginBlockEnd:10,cursor:"pointer",fontSize:font.body.size.small,padding:0,border:"none",display:"block",clear:"both"},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8}});const WrappedGradedGroup=withDependencies(GradedGroup);var GradedGroup$1 = {name:"graded-group",displayName:"Graded group (articles only)",widget:WrappedGradedGroup,hidden:false,tracking:"all",isLintable:true};
|
|
1778
1778
|
|
|
1779
1779
|
const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.gradedGroups.length,currentGroup:activeGroupJSON}}};
|
|
1780
1780
|
|
|
1781
|
-
class Indicators extends React.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$h.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>{const isCurrent=i===this.props.currentGroup;return jsxRuntimeExports.jsx("li",{className:css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$h.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$h.indicatorDot,isCurrent&&styles$h.indicatorDotActive,(hovered||focused||pressed)&&styles$h.indicatorDotFocused]})})},i)})})}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.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:this.props.widgetId}});}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: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:css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className: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});}};}}const WrappedGradedGroupSet=withDependencies(GradedGroupSet);var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:WrappedGradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",
|
|
1781
|
+
class Indicators extends React.Component{render(){return jsxRuntimeExports.jsx("ul",{role:"list",className:classNames$2(css(styles$h.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>{const isCurrent=i===this.props.currentGroup;return jsxRuntimeExports.jsx("li",{className:css(styles$h.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":title,"aria-current":isCurrent,style:styles$h.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$h.indicatorDot,isCurrent&&styles$h.indicatorDotActive,(hovered||focused||pressed)&&styles$h.indicatorDotFocused]})})},i)})})}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.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetType:"graded-group-set",widgetSubType:"null",widgetId:this.props.widgetId}});}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: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:css(styles$h.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$h.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$h.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className: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});}};}}const WrappedGradedGroupSet=withDependencies(GradedGroupSet);var GradedGroupSet$1 = {name:"graded-group-set",displayName:"Graded group set (articles only)",widget:WrappedGradedGroupSet,hidden:false,tracking:"all",isLintable:true};const styles$h=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:font.heading.size.small,color:semanticColor.core.foreground.neutral.default,textTransform:"uppercase",marginBlockEnd:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyleType:"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:border$1.radius.radius_full,borderWidth:border$1.width.medium,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{outlineColor:semanticColor.focus.outer,outlineStyle:"solid",outlineWidth:border$1.width.medium,outlineOffset:border$1.width.medium,boxShadow:`0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`},indicatorDotActive:{backgroundColor:semanticColor.core.foreground.instructive.default,borderColor:semanticColor.core.foreground.instructive.default},container:{borderBlockStart:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderBlockEnd:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,backgroundColor:semanticColor.core.background.base.subtle,marginInlineStart:negativePhoneMargin,marginInlineEnd:negativePhoneMargin,paddingBlockEnd:phoneMargin,paddingInlineStart:phoneMargin,paddingInlineEnd:phoneMargin,paddingBlockStart:10,width:"auto"}});
|
|
1782
1782
|
|
|
1783
|
-
class ButtonGroup extends React.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",disabled:this.props.disabled,className:css(styles$g.buttonStyle,button.value===value&&styles$g.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&styles$g.disabledStyle),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=StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",
|
|
1783
|
+
class ButtonGroup extends React.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",disabled:this.props.disabled,className:css(styles$g.buttonStyle,button.value===value&&styles$g.selectedStyle,button.value===value&&this.props.selectedButtonStyle,this.props.disabled&&styles$g.disabledStyle),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=StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",borderInlineStart:"0",cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:"1px solid #ccc",borderStartStartRadius:"3px",borderEndStartRadius:"3px"},":last-child":{borderInlineEnd:"1px solid #ccc",borderStartEndRadius:"3px",borderEndEndRadius:"3px"},":hover":{backgroundColor:"#ccc"},":focus":{zIndex:2}},selectedStyle:{backgroundColor:"#ddd"},disabledStyle:{cursor:"not-allowed",backgroundColor:semanticColor.core.background.disabled.default,color:semanticColor.core.foreground.disabled.strong,":hover":{backgroundColor:semanticColor.core.background.disabled.default}}});
|
|
1784
1784
|
|
|
1785
1785
|
const getPromptJSON$g=widgetData=>{const{userInput}=widgetData;const{type,coords}=userInput;const input={type,coords};if(userInput.type==="logarithm"||userInput.type==="exponential"){input["asymptote"]=userInput.asymptote;}return {type:"grapher",options:{availableTypes:widgetData.availableTypes,range:widgetData.graph.range,labels:widgetData.graph.labels,tickStep:widgetData.graph.step,gridStep:widgetData.graph.gridStep,snapStep:widgetData.graph.snapStep,backgroundImageUrl:widgetData.graph.backgroundImage.url},userInput:input}};
|
|
1786
1786
|
|
|
@@ -1862,11 +1862,11 @@ const GraphBorder=({range,width,height,markings})=>{if(markings!=="graph"&&marki
|
|
|
1862
1862
|
|
|
1863
1863
|
const gridLineOptions=(props,axisIndex)=>{const lines=props.markings==="axes"?false:props.gridStep[axisIndex];return {axis:false,lines:lines,labels:false}};const axisLineOptions=props=>{return {axis:props.markings==="graph"||props.markings==="axes",lines:false,labels:false}};const Grid=props=>{return props.markings==="none"?null:jsxRuntimeExports.jsx(Coordinates.Cartesian,{xAxis:gridLineOptions(props,X),yAxis:gridLineOptions(props,Y)})};const Axes=props=>{return props.markings==="none"?null:jsxRuntimeExports.jsx(Coordinates.Cartesian,{xAxis:axisLineOptions(props),yAxis:axisLineOptions(props)})};
|
|
1864
1864
|
|
|
1865
|
-
const VisibleIcon=()=>jsxRuntimeExports.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",className:css(styles$f.icon),children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsx("path",{id:"a",d:"M7.401 10.035c-1.424.748-2.599 1.905-3.544 "+"3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 "+"12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 "+"1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-"+"3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 "+"0 0 0 0 6z"})}),jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[jsxRuntimeExports.jsx("path",{fill:"none",d:"M0 0h24v24H0z"}),jsxRuntimeExports.jsx("mask",{id:"b",fill:"#fff",children:jsxRuntimeExports.jsx("use",{href:"#a"})}),jsxRuntimeExports.jsx("use",{fill:"#fff",fillRule:"nonzero",href:"#a"}),jsxRuntimeExports.jsx("g",{fill:"#fff",mask:"url(#b)",children:jsxRuntimeExports.jsx("path",{d:"M0 0h24v24H0z"})})]})]});const HiddenIcon=()=>jsxRuntimeExports.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",className:css(styles$f.icon),children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsx("path",{id:"a",d:"M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 "+"7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 "+"1.028c-.945-1.574-2.12-2.73-3.544-3.48.258."+"604.401 1.268.401 1.966 0 1.02-.305 "+"1.967-.828 2.757l2.535 2.536a1 1 0 0 "+"1-1.414 1.414l-12-12a1 1 0 0 1 "+"1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 "+"0-4.001-4.001l4 4.001zM6.072 8.486l2.976 "+"2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 "+"0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 "+"3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 "+"2.363-3.085 3.929-4z"})}),jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[jsxRuntimeExports.jsx("path",{fill:"none",d:"M0 0h24v24H0z"}),jsxRuntimeExports.jsx("mask",{id:"b",fill:"#fff",children:jsxRuntimeExports.jsx("use",{href:"#a"})}),jsxRuntimeExports.jsx("use",{fill:"#fff",fillRule:"nonzero",href:"#a"}),jsxRuntimeExports.jsx("g",{fill:"#fff",mask:"url(#b)",children:jsxRuntimeExports.jsx("path",{d:"M0 0h24v24H0z"})})]})]});const HUD=({message,enabled,onClick,fixedPosition=true})=>{let state;let icon;if(enabled){state=styles$f.enabled;icon=jsxRuntimeExports.jsx(VisibleIcon,{});}else {state=styles$f.disabled;icon=jsxRuntimeExports.jsx(HiddenIcon,{});}return jsxRuntimeExports.jsxs("button",{className:css(styles$f.hud,fixedPosition&&styles$f.hudFixedPosition,state),onClick:e=>{onClick();},children:[icon,message]})};const styles$f=StyleSheet.create({hud:{boxSizing:"border-box",height:36,
|
|
1865
|
+
const VisibleIcon=()=>jsxRuntimeExports.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",className:css(styles$f.icon),children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsx("path",{id:"a",d:"M7.401 10.035c-1.424.748-2.599 1.905-3.544 "+"3.48a1 1 0 0 1-1.714-1.03C4.325 8.849 7.652 7 "+"12 7c4.348 0 7.675 1.848 9.857 5.486a1 1 0 0 "+"1-1.714 1.028c-.945-1.574-2.12-2.73-3.544-"+"3.48a5 5 0 1 1-9.198 0zM12 15a3 3 0 1 0 0-6 3 3 "+"0 0 0 0 6z"})}),jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[jsxRuntimeExports.jsx("path",{fill:"none",d:"M0 0h24v24H0z"}),jsxRuntimeExports.jsx("mask",{id:"b",fill:"#fff",children:jsxRuntimeExports.jsx("use",{href:"#a"})}),jsxRuntimeExports.jsx("use",{fill:"#fff",fillRule:"nonzero",href:"#a"}),jsxRuntimeExports.jsx("g",{fill:"#fff",mask:"url(#b)",children:jsxRuntimeExports.jsx("path",{d:"M0 0h24v24H0z"})})]})]});const HiddenIcon=()=>jsxRuntimeExports.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",className:css(styles$f.icon),children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsx("path",{id:"a",d:"M8.794 7.38C9.791 7.127 10.86 7 12 7c4.348 0 "+"7.675 1.848 9.857 5.486a1 1 0 0 1-1.714 "+"1.028c-.945-1.574-2.12-2.73-3.544-3.48.258."+"604.401 1.268.401 1.966 0 1.02-.305 "+"1.967-.828 2.757l2.535 2.536a1 1 0 0 "+"1-1.414 1.414l-12-12a1 1 0 0 1 "+"1.414-1.414L8.794 7.38zm5.914 5.913a3 3 0 0 "+"0-4.001-4.001l4 4.001zM6.072 8.486l2.976 "+"2.976a3 3 0 0 0 3.49 3.49l1.579 1.58A5 5 0 "+"0 1 7.4 10.035c-1.424.747-2.599 1.904-3.544 "+"3.478a1 1 0 0 1-1.714-1.028c1.049-1.75 "+"2.363-3.085 3.929-4z"})}),jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[jsxRuntimeExports.jsx("path",{fill:"none",d:"M0 0h24v24H0z"}),jsxRuntimeExports.jsx("mask",{id:"b",fill:"#fff",children:jsxRuntimeExports.jsx("use",{href:"#a"})}),jsxRuntimeExports.jsx("use",{fill:"#fff",fillRule:"nonzero",href:"#a"}),jsxRuntimeExports.jsx("g",{fill:"#fff",mask:"url(#b)",children:jsxRuntimeExports.jsx("path",{d:"M0 0h24v24H0z"})})]})]});const HUD=({message,enabled,onClick,fixedPosition=true})=>{let state;let icon;if(enabled){state=styles$f.enabled;icon=jsxRuntimeExports.jsx(VisibleIcon,{});}else {state=styles$f.disabled;icon=jsxRuntimeExports.jsx(HiddenIcon,{});}return jsxRuntimeExports.jsxs("button",{className:css(styles$f.hud,fixedPosition&&styles$f.hudFixedPosition,state),onClick:e=>{onClick();},children:[icon,message]})};const styles$f=StyleSheet.create({hud:{boxSizing:"border-box",height:36,paddingBlock:"9px",paddingInline:"16px",borderRadius:18,fontFamily:boldFontFamily,fontSize:"15px",lineHeight:"18px",color:white,userSelect:"none",borderWidth:0},hudFixedPosition:{insetBlockEnd:20,position:"fixed",insetInlineEnd:20,zIndex:1},icon:{width:24,height:24,marginInlineEnd:8,marginBlockStart:-3,verticalAlign:"middle"},enabled:{backgroundColor:warningColor,":hover":{backgroundColor:warningColorHover},":active":{backgroundColor:warningColorActive}},disabled:{backgroundColor:gray76,":hover":{backgroundColor:"#a1a5a9"},":active":{backgroundColor:gray68}}});
|
|
1866
1866
|
|
|
1867
1867
|
const BASE_ICON_SIZE=10;class Icon extends React.Component{render(){const{color,pathClassName,className,title,style,alt}=this.props;let{icon,size}=this.props;let units="";if(typeof icon==="string"){icon={path:icon,width:BASE_ICON_SIZE,height:BASE_ICON_SIZE};}if(typeof size!=="number"){size=1;units="em";}const height=size;const width=height/icon.height*icon.width;const xMin=0;const yMin=0;const focusable=!!this.props.focusable;return jsxRuntimeExports.jsxs("svg",{role:"img",alt:alt,"aria-label":title,"aria-hidden":title?null:true,className:className,style:style,focusable:focusable.toString(),width:width+units,height:height+units,viewBox:`${xMin} ${yMin} ${icon.width} ${icon.height}`,children:[!!title&&jsxRuntimeExports.jsx("title",{children:title}),jsxRuntimeExports.jsx("path",{className:pathClassName,fill:color,d:icon.path})]})}}Icon.defaultProps={color:"currentColor"};
|
|
1868
1868
|
|
|
1869
|
-
class MultiButtonGroup extends React.Component{focus(){this.buttonContainerRef.current?.focus();return true}render(){const values=this.props.values||[];const buttons=this.props.buttons.map((button,i)=>{const selected=values.indexOf(button.value)>=0;return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",id:""+i,ref:"button"+i,className:css(styles$e.buttonStyle,selected&&styles$e.selectedStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:this.buttonContainerRef,children:buttons})}constructor(...args){super(...args),this.buttonContainerRef=React.createRef(),this.toggleSelect=newValue=>{const values=(this.props.values||[]).slice(0);const allowEmpty=this.props.allowEmpty;if(values.indexOf(newValue)>=0&&(values.length>1||allowEmpty)){values.splice(values.indexOf(newValue),1);}else {if(values.indexOf(newValue)<0){values.push(newValue);}}this.props.onChange(values);};}}MultiButtonGroup.defaultProps={values:[],allowEmpty:true};const styles$e=StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",
|
|
1869
|
+
class MultiButtonGroup extends React.Component{focus(){this.buttonContainerRef.current?.focus();return true}render(){const values=this.props.values||[];const buttons=this.props.buttons.map((button,i)=>{const selected=values.indexOf(button.value)>=0;return jsxRuntimeExports.jsx("button",{title:button.title,type:"button",id:""+i,ref:"button"+i,className:css(styles$e.buttonStyle,selected&&styles$e.selectedStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:this.buttonContainerRef,children:buttons})}constructor(...args){super(...args),this.buttonContainerRef=React.createRef(),this.toggleSelect=newValue=>{const values=(this.props.values||[]).slice(0);const allowEmpty=this.props.allowEmpty;if(values.indexOf(newValue)>=0&&(values.length>1||allowEmpty)){values.splice(values.indexOf(newValue),1);}else {if(values.indexOf(newValue)<0){values.push(newValue);}}this.props.onChange(values);};}}MultiButtonGroup.defaultProps={values:[],allowEmpty:true};const styles$e=StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",borderInlineStart:"0",cursor:"pointer",margin:"0",paddingBlock:"5px",paddingInline:"10px",position:"relative",":first-child":{borderInlineStart:"1px solid #ccc",borderStartStartRadius:"3px",borderEndStartRadius:"3px"},":last-child":{borderInlineEnd:"1px solid #ccc",borderStartEndRadius:"3px",borderEndEndRadius:"3px"},":hover":{backgroundColor:"#ccc"},":focus":{zIndex:2}},selectedStyle:{backgroundColor:"#ddd"}});
|
|
1870
1870
|
|
|
1871
1871
|
function isPiMultiple(value){if(Number.isInteger(value)){return false}return value%Math.PI===0||value%(Math.PI/2)===0||value%(Math.PI/3)===0||value%(Math.PI/4)===0||value%(Math.PI/6)===0}
|
|
1872
1872
|
|
|
@@ -1899,7 +1899,7 @@ function GraphLockedLabelsLayer(props){const{lockedFigures}=props;return lockedF
|
|
|
1899
1899
|
|
|
1900
1900
|
const strokeWeights={thin:1,medium:2,thick:4};function getDashArrayForWeight(weight){const width=strokeWeights[weight];return `${4*width}, ${3*width}`}function dashedStrokeStyle(isDashed,weight){if(!isDashed){return undefined}return {"--mafs-line-stroke-dash-style":getDashArrayForWeight(weight)}}function clampDomain(domain,graphBounds){const normalizedDomain=[domain[0]===null?-Infinity:domain[0],domain[1]===null?Infinity:domain[1]];if(normalizedDomain[0]>normalizedDomain[1]){return graphBounds}if(normalizedDomain[0]<graphBounds[0]&&normalizedDomain[1]<graphBounds[0]||normalizedDomain[0]>graphBounds[1]&&normalizedDomain[1]>graphBounds[1]){return null}const min=Math.max(normalizedDomain[0],graphBounds[0]);const max=Math.min(normalizedDomain[1],graphBounds[1]);return [min,max]}
|
|
1901
1901
|
|
|
1902
|
-
const LockedEllipse=props=>{const{center,radius,angle,color,fillStyle,strokeStyle,weight,ariaLabel}=props;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-ellipse","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:jsxRuntimeExports.jsx(Ellipse,{center:center,radius:radius,angle:angle,fillOpacity:lockedFigureFillStyles[fillStyle],strokeStyle:strokeStyle,color:lockedFigureColors[color],weight:strokeWeights[weight],svgEllipseProps:{style:{fill:fillStyle==="white"?semanticColor.core.background.base.default:lockedFigureColors[color]}}})})};
|
|
1902
|
+
const LockedEllipse=props=>{const{center,radius,angle,color,fillStyle,strokeStyle,weight,ariaLabel}=props;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-ellipse","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:jsxRuntimeExports.jsx(Ellipse,{center:center,radius:radius,angle:angle,fillOpacity:lockedFigureFillStyles[fillStyle],strokeStyle:strokeStyle==="none"?"solid":strokeStyle,color:lockedFigureColors[color],weight:strokeWeights[weight],svgEllipseProps:{style:{fill:fillStyle==="white"?semanticColor.core.background.base.default:lockedFigureColors[color],...strokeStyle==="none"&&{stroke:"none"}}}})})};
|
|
1903
1903
|
|
|
1904
1904
|
const LockedFunction=props=>{const{range}=useGraphConfig();const[equation,setEquation]=useState();const{color,strokeStyle,weight,directionalAxis,domain}=props;const plotProps={color:lockedFigureColors[color],style:strokeStyle,weight:strokeWeights[weight]};const hasAria=!!props.ariaLabel;useEffect(()=>{setEquation(KAS.parse(props.equation).expr);},[props.equation]);if(typeof equation==="undefined"){return null}const clampedDomain=directionalAxis==="x"?clampDomain(domain,range[0]):clampDomain(domain,range[1]);if(clampedDomain===null){return null}return jsxRuntimeExports.jsxs("g",{className:"locked-function","aria-label":hasAria?props.ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:[directionalAxis==="x"&&jsxRuntimeExports.jsx(Plot$2.OfX,{y:x=>equation.eval({x}),domain:clampedDomain,...plotProps}),directionalAxis==="y"&&jsxRuntimeExports.jsx(Plot$2.OfY,{x:y=>equation.eval({y}),domain:clampedDomain,...plotProps})]})};
|
|
1905
1905
|
|
|
@@ -1911,7 +1911,7 @@ const{calculateAngleInDegrees: calculateAngleInDegrees$3}=angles;const LockedLin
|
|
|
1911
1911
|
|
|
1912
1912
|
const LockedPoint=props=>{const{color,coord,filled,ariaLabel}=props;const[x,y]=coord;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-point","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",children:jsxRuntimeExports.jsx(Point$2,{x:x,y:y,svgCircleProps:{style:{fill:filled?lockedFigureColors[color]:semanticColor.core.background.base.default,stroke:lockedFigureColors[color],strokeWidth:spacing.xxxxSmall_2}}})})};
|
|
1913
1913
|
|
|
1914
|
-
const LockedPolygon=props=>{const{points,color,showVertices,fillStyle,strokeStyle,weight}=props;const hasAria=!!props.ariaLabel;return jsxRuntimeExports.jsxs("g",{className:"locked-polygon","aria-label":hasAria?props.ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:[jsxRuntimeExports.jsx(Polygon,{points:[...points],fillOpacity:lockedFigureFillStyles[fillStyle],strokeStyle:strokeStyle,color:lockedFigureColors[color],weight:strokeWeights[weight],svgPolygonProps:{style:{fill:fillStyle==="white"?semanticColor.core.background.base.default:lockedFigureColors[color]}}}),showVertices&&points.map((point,index)=>jsxRuntimeExports.jsx(Point$2,{x:point[X],y:point[Y],color:lockedFigureColors[color]},`locked-polygon-point-${index}`))]})};
|
|
1914
|
+
const LockedPolygon=props=>{const{points,color,showVertices,fillStyle,strokeStyle,weight}=props;const hasAria=!!props.ariaLabel;return jsxRuntimeExports.jsxs("g",{className:"locked-polygon","aria-label":hasAria?props.ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",style:dashedStrokeStyle(strokeStyle==="dashed",weight),children:[jsxRuntimeExports.jsx(Polygon,{points:[...points],fillOpacity:lockedFigureFillStyles[fillStyle],strokeStyle:strokeStyle==="none"?"solid":strokeStyle,color:lockedFigureColors[color],weight:strokeWeights[weight],svgPolygonProps:{style:{fill:fillStyle==="white"?semanticColor.core.background.base.default:lockedFigureColors[color],...strokeStyle==="none"&&{stroke:"none"}}}}),showVertices&&points.map((point,index)=>jsxRuntimeExports.jsx(Point$2,{x:point[X],y:point[Y],color:lockedFigureColors[color]},`locked-polygon-point-${index}`))]})};
|
|
1915
1915
|
|
|
1916
1916
|
const LockedVector=props=>{const{color,points,weight,ariaLabel}=props;const[tail,tip]=points;const hasAria=!!ariaLabel;return jsxRuntimeExports.jsx("g",{className:"locked-vector","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",children:jsxRuntimeExports.jsx(Vector,{tail:tail,tip:tip,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight]})})};
|
|
1917
1917
|
|
|
@@ -2005,7 +2005,7 @@ const{calculateAngleInDegrees,convertDegreesToRadians}=angles;const protractorIm
|
|
|
2005
2005
|
|
|
2006
2006
|
function getLockedFigureClipRuns(lockedFigures){const runs=[];for(const figure of lockedFigures){if(figure.type==="label"){continue}const clipped=figure.type!=="point";const lastRun=runs[runs.length-1];if(lastRun?.clipped===clipped){lastRun.figures.push(figure);}else {runs.push({clipped,figures:[figure]});}}return runs}function handleFocusEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.target.classList.contains("mafs-graph")&&state.interactionMode==="mouse"){dispatch(actions.global.changeKeyboardInvitationVisibility(true));}}}function handleBlurEvent(_event,state,dispatch){if(isUnlimitedGraphState(state)){dispatch(actions.global.changeKeyboardInvitationVisibility(false));}}function handleKeyboardEvent(event,state,dispatch){if(isUnlimitedGraphState(state)){if(event.key==="Backspace"||event.key==="Delete"){if(document.activeElement?.classList.contains("movable-point__focusable-handle")){if(state.type==="point"||state.type==="polygon"&&!state.closedPolygon){dispatch(actions.global.deleteIntent());}}document.activeElement.blur();}else if(event.shiftKey&&event.key==="Enter"){dispatch(actions.global.changeInteractionMode("keyboard"));}else if(state.interactionMode==="keyboard"&&event.key==="a"){dispatch(actions.pointGraph.addPoint([0,0]));}}}function describedByIds(...args){return args.filter(Boolean).join(" ")||undefined}
|
|
2007
2007
|
|
|
2008
|
-
const GRAPH_LEFT_MARGIN=20;const MafsGraph=props=>{const{state,dispatch,labels,labelLocation,readOnly,fullGraphAriaLabel,fullGraphAriaDescription,widgetId,ungradedDescriptionId}=props;const{type}=state;const[width,height]=props.box;const tickStep=props.step;const uniqueId=React.useId();const descriptionId=`interactive-graph-description-${uniqueId}`;const interactiveElementsDescriptionId=`interactive-graph-interactive-elements-description-${uniqueId}`;const unlimitedGraphKeyboardPromptId=`unlimited-graph-keyboard-prompt-${uniqueId}`;const instructionsId=`instructions-${uniqueId}`;const graphRef=React.useRef(null);const[hitboxLayerEl,setHitboxLayerEl]=React.useState(null);const{analytics}=useDependencies();const i18n=usePerseusI18n();const{strings}=i18n;const interactionPrompt=isUnlimitedGraphState(state)&&state.showKeyboardInteractionInvitation;useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:type,widgetType:"interactive-graph",widgetId:widgetId}});});const{graph,interactiveElementsDescription}=renderGraphElements({state,dispatch,i18n,markings:props.markings});const disableInteraction=readOnly||!!props.static;const graphInfo={range:state.range,width,height};const[xAxisLabelLocation,yAxisLabelLocation]=getLabelPosition(graphInfo,labelLocation,tickStep);const needsExtraMargin=labelLocation==="alongEdge"&&yAxisLabelLocation[0]<-14*fontSizeYAxisLabelMultiplier;const marginLabelDiff=GRAPH_LEFT_MARGIN-fontSize*fontSizeYAxisLabelMultiplier;const marginWithExtraOffset=-1*(yAxisLabelLocation[X]-marginLabelDiff);const showsAxisLabels=props.markings==="graph"||props.markings==="axes";const hasXAxisLabel=!!(labels[0]&&labels[0].trim());const graphMarginBottom=getGraphBottomMargin(xAxisLabelLocation[Y],height,hasXAxisLabel,showsAxisLabels);const[[xMin,xMax],[yMin,yMax]]=state.range;const halfStroke=1;const axisClipExpand={left:xMin===0?halfStroke:0,right:xMax===0?halfStroke:0,bottom:yMin===0?halfStroke:0,top:yMax===0?halfStroke:0};const lockedFigureRuns=getLockedFigureClipRuns(props.lockedFigures);return jsxRuntimeExports.jsx(GraphConfigContext.Provider,{value:{range:state.range,snapStep:state.snapStep,markings:props.markings,tickStep:tickStep,gridStep:props.gridStep,showTooltips:!!props.showTooltips,showAxisArrows:props.showAxisArrows,showAxisTicks:props.showAxisTicks,graphDimensionsInPixels:props.box,width,height,labels,labelLocation,disableKeyboardInteraction:disableInteraction,interactiveColor:disableInteraction?"var(--static-gray)":"var(--mafs-blue)"},children:jsxRuntimeExports.jsxs(View,{className:"mafs-graph-container",children:[jsxRuntimeExports.jsxs(View,{className:"mafs-graph",role:"figure",style:{position:"relative",padding:"25px 25px 0 0",boxSizing:"content-box",marginLeft:needsExtraMargin?`${marginWithExtraOffset}px`:`${GRAPH_LEFT_MARGIN}px`,marginBottom:graphMarginBottom,pointerEvents:props.static?"none":"auto",userSelect:"none",width,height},onKeyUp:event=>{handleKeyboardEvent(event,state,dispatch);},"aria-label":fullGraphAriaLabel,"aria-describedby":describedByIds(ungradedDescriptionId,state.type!=="none"&&!disableInteraction&&instructionsId,fullGraphAriaDescription&&descriptionId,interactiveElementsDescription&&interactiveElementsDescriptionId,isUnlimitedGraphState(state)&&unlimitedGraphKeyboardPromptId),ref:graphRef,tabIndex:0,onFocus:event=>{handleFocusEvent(event,state,dispatch);},onBlur:event=>{handleBlurEvent(event,state,dispatch);},children:[state.type!=="none"&&jsxRuntimeExports.jsx(View,{id:instructionsId,tabIndex:-1,className:"mafs-sr-only",children:isUnlimitedGraphState(state)?strings.srUnlimitedGraphInstructions:strings.srGraphInstructions}),fullGraphAriaDescription&&jsxRuntimeExports.jsx(View,{id:descriptionId,tabIndex:-1,className:"mafs-sr-only",children:fullGraphAriaDescription}),interactiveElementsDescription&&jsxRuntimeExports.jsx(View,{id:interactiveElementsDescriptionId,tabIndex:-1,className:"mafs-sr-only",children:interactiveElementsDescription}),jsxRuntimeExports.jsx(LegacyGrid,{box:props.box,backgroundImage:props.backgroundImage}),jsxRuntimeExports.jsxs(View,{style:{position:"absolute",bottom:0,left:0},children:[(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsx(AxisLabels,{i18n:i18n,xAxisLabelLocation:xAxisLabelLocation,yAxisLabelLocation:yAxisLabelLocation})}),jsxRuntimeExports.jsx(View,{"aria-hidden":props.lockedFigures.length===0,children:jsxRuntimeExports.jsxs(Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[jsxRuntimeExports.jsx(SvgDefs,{}),jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Grid,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),jsxRuntimeExports.jsx(GraphBorder,{range:state.range,width:width,height:height,markings:props.markings}),showsAxisLabels&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{expand:axisClipExpand,children:jsxRuntimeExports.jsx(Axes,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),jsxRuntimeExports.jsx(AxisTicks,{}),jsxRuntimeExports.jsx(AxisArrows,{})]}),lockedFigureRuns.map((run,index)=>run.clipped?jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:run.figures,range:state.range})},`locked-figure-run-${index}`):jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:run.figures,range:state.range},`locked-figure-run-${index}`))]})}),jsxRuntimeExports.jsx(GraphLockedLabelsLayer,{lockedFigures:props.lockedFigures}),!props.static&&jsxRuntimeExports.jsx(MovablePointLabelsLayer,{state:state}),jsxRuntimeExports.jsxs(HitboxLayerContext.Provider,{value:hitboxLayerEl,children:[jsxRuntimeExports.jsx(View,{style:{position:"absolute"},children:jsxRuntimeExports.jsxs(Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[props.showProtractor&&jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Protractor,{})}),graph]})}),jsxRuntimeExports.jsx("div",{ref:setHitboxLayerEl,className:"interactive-graph-hitbox-layer",style:{position:"absolute",top:0,left:0,width,height,pointerEvents:"none"}})]})]}),interactionPrompt&&jsxRuntimeExports.jsx(View,{style:{display:interactionPrompt?undefined:"hidden",textAlign:"center",backgroundColor:semanticColor.core.background.base.default,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,padding:"16px 0",boxShadow:boxShadow.mid,top:"50%",transform:"translateY(-50%)"},children:jsxRuntimeExports.jsx(BodyText,{id:unlimitedGraphKeyboardPromptId,children:strings.graphKeyboardPrompt})})]}),renderGraphControls({state,dispatch,width,perseusStrings:strings})]})})};const renderPointGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;return jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.pointGraph.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",tabIndex:-1,style:{width:"100%",marginLeft:"20px",visibility:shouldShowRemoveButton?"visible":"hidden"},onClick:_event=>{props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint})]})};const renderPolygonGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex,closedPolygon,coords}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;const disableCloseButton=getArrayWithoutDuplicates(coords).length<3;const polygonButton=closedPolygon?jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.polygon.openPolygon());},children:perseusStrings.openPolygon}):jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:disableCloseButton,style:{width:"100%",marginLeft:"20px"},tabIndex:disableCloseButton?-1:0,onClick:()=>{props.dispatch(actions.polygon.closePolygon());},children:perseusStrings.closePolygon});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginLeft:"20px"},disabled:closedPolygon,tabIndex:closedPolygon?-1:0,onClick:()=>{props.dispatch(actions.polygon.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",disabled:closedPolygon||!shouldShowRemoveButton,tabIndex:-1,style:{width:"100%",marginLeft:"20px"},onClick:_event=>{props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint}),polygonButton]})})};const renderGraphControls=props=>{const{state,dispatch,width,perseusStrings}=props;const{type}=state;switch(type){case "point":if(state.numPoints==="unlimited"){return renderPointGraphControls({state,dispatch,width,perseusStrings})}return null;case "polygon":if(state.numSides==="unlimited"){return renderPolygonGraphControls({state,dispatch,width,perseusStrings})}return null;default:return null}};const renderGraphElements=props=>{const{state,dispatch,i18n,markings}=props;const{type}=state;switch(type){case "angle":return renderAngleGraph(state,dispatch,i18n);case "segment":return renderSegmentGraph(state,dispatch,i18n);case "linear-system":return renderLinearSystemGraph(state,dispatch,i18n);case "linear":return renderLinearGraph(state,dispatch,i18n);case "ray":return renderRayGraph(state,dispatch,i18n);case "polygon":return renderPolygonGraph(state,dispatch,i18n,markings);case "point":return renderPointGraph(state,dispatch,i18n);case "circle":return renderCircleGraph(state,dispatch,i18n);case "quadratic":return renderQuadraticGraph(state,dispatch,i18n);case "sinusoid":return renderSinusoidGraph(state,dispatch,i18n);case "exponential":return renderExponentialGraph(state,dispatch,i18n);case "none":return {graph:null,interactiveElementsDescription:null};case "absolute-value":return renderAbsoluteValueGraph(state,dispatch,i18n);case "tangent":return renderTangentGraph(state,dispatch,i18n);case "logarithm":return renderLogarithmGraph(state,dispatch,i18n);case "vector":return renderVectorGraph(state,dispatch,i18n);default:throw new UnreachableCaseError(type)}};
|
|
2008
|
+
const GRAPH_LEFT_MARGIN=20;const MafsGraph=props=>{const{state,dispatch,labels,labelLocation,readOnly,fullGraphAriaLabel,fullGraphAriaDescription,widgetId,ungradedDescriptionId}=props;const{type}=state;const[width,height]=props.box;const tickStep=props.step;const uniqueId=React.useId();const descriptionId=`interactive-graph-description-${uniqueId}`;const interactiveElementsDescriptionId=`interactive-graph-interactive-elements-description-${uniqueId}`;const unlimitedGraphKeyboardPromptId=`unlimited-graph-keyboard-prompt-${uniqueId}`;const instructionsId=`instructions-${uniqueId}`;const graphRef=React.useRef(null);const[hitboxLayerEl,setHitboxLayerEl]=React.useState(null);const{analytics}=useDependencies();const i18n=usePerseusI18n();const{strings}=i18n;const interactionPrompt=isUnlimitedGraphState(state)&&state.showKeyboardInteractionInvitation;useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:type,widgetType:"interactive-graph",widgetId:widgetId}});});const{graph,interactiveElementsDescription}=renderGraphElements({state,dispatch,i18n,markings:props.markings});const disableInteraction=readOnly||!!props.static;const graphInfo={range:state.range,width,height};const[xAxisLabelLocation,yAxisLabelLocation]=getLabelPosition(graphInfo,labelLocation,tickStep);const needsExtraMargin=labelLocation==="alongEdge"&&yAxisLabelLocation[0]<-14*fontSizeYAxisLabelMultiplier;const marginLabelDiff=GRAPH_LEFT_MARGIN-fontSize*fontSizeYAxisLabelMultiplier;const marginWithExtraOffset=-1*(yAxisLabelLocation[X]-marginLabelDiff);const showsAxisLabels=props.markings==="graph"||props.markings==="axes";const hasXAxisLabel=!!(labels[0]&&labels[0].trim());const graphMarginBottom=getGraphBottomMargin(xAxisLabelLocation[Y],height,hasXAxisLabel,showsAxisLabels);const[[xMin,xMax],[yMin,yMax]]=state.range;const halfStroke=1;const axisClipExpand={left:xMin===0?halfStroke:0,right:xMax===0?halfStroke:0,bottom:yMin===0?halfStroke:0,top:yMax===0?halfStroke:0};const lockedFigureRuns=getLockedFigureClipRuns(props.lockedFigures);return jsxRuntimeExports.jsx(GraphConfigContext.Provider,{value:{range:state.range,snapStep:state.snapStep,markings:props.markings,tickStep:tickStep,gridStep:props.gridStep,showTooltips:!!props.showTooltips,showAxisArrows:props.showAxisArrows,showAxisTicks:props.showAxisTicks,graphDimensionsInPixels:props.box,width,height,labels,labelLocation,disableKeyboardInteraction:disableInteraction,interactiveColor:disableInteraction?"var(--static-gray)":"var(--mafs-blue)"},children:jsxRuntimeExports.jsxs(View,{className:"mafs-graph-container",children:[jsxRuntimeExports.jsxs(View,{className:"mafs-graph",role:"figure",style:{position:"relative",paddingBlockStart:"25px",paddingInlineEnd:"25px",paddingBlockEnd:"0",paddingInlineStart:"0",boxSizing:"content-box",marginInlineStart:needsExtraMargin?`${marginWithExtraOffset}px`:`${GRAPH_LEFT_MARGIN}px`,marginBlockEnd:graphMarginBottom,pointerEvents:props.static?"none":"auto",userSelect:"none",width,height},onKeyUp:event=>{handleKeyboardEvent(event,state,dispatch);},"aria-label":fullGraphAriaLabel,"aria-describedby":describedByIds(ungradedDescriptionId,state.type!=="none"&&!disableInteraction&&instructionsId,fullGraphAriaDescription&&descriptionId,interactiveElementsDescription&&interactiveElementsDescriptionId,isUnlimitedGraphState(state)&&unlimitedGraphKeyboardPromptId),ref:graphRef,tabIndex:0,onFocus:event=>{handleFocusEvent(event,state,dispatch);},onBlur:event=>{handleBlurEvent(event,state,dispatch);},children:[state.type!=="none"&&jsxRuntimeExports.jsx(View,{id:instructionsId,tabIndex:-1,className:"mafs-sr-only",children:isUnlimitedGraphState(state)?strings.srUnlimitedGraphInstructions:strings.srGraphInstructions}),fullGraphAriaDescription&&jsxRuntimeExports.jsx(View,{id:descriptionId,tabIndex:-1,className:"mafs-sr-only",children:fullGraphAriaDescription}),interactiveElementsDescription&&jsxRuntimeExports.jsx(View,{id:interactiveElementsDescriptionId,tabIndex:-1,className:"mafs-sr-only",children:interactiveElementsDescription}),jsxRuntimeExports.jsx(LegacyGrid,{box:props.box,backgroundImage:props.backgroundImage}),jsxRuntimeExports.jsxs(View,{style:{position:"absolute",bottom:0,left:0},children:[(props.markings==="graph"||props.markings==="axes")&&jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsx(AxisLabels,{i18n:i18n,xAxisLabelLocation:xAxisLabelLocation,yAxisLabelLocation:yAxisLabelLocation})}),jsxRuntimeExports.jsx(View,{"aria-hidden":props.lockedFigures.length===0,children:jsxRuntimeExports.jsxs(Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[jsxRuntimeExports.jsx(SvgDefs,{}),jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Grid,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),jsxRuntimeExports.jsx(GraphBorder,{range:state.range,width:width,height:height,markings:props.markings}),showsAxisLabels&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ClipToGraphBounds,{expand:axisClipExpand,children:jsxRuntimeExports.jsx(Axes,{gridStep:props.gridStep,range:state.range,containerSizeClass:props.containerSizeClass,markings:props.markings,width:width,height:height})}),jsxRuntimeExports.jsx(AxisTicks,{}),jsxRuntimeExports.jsx(AxisArrows,{})]}),lockedFigureRuns.map((run,index)=>run.clipped?jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:run.figures,range:state.range})},`locked-figure-run-${index}`):jsxRuntimeExports.jsx(GraphLockedLayer,{lockedFigures:run.figures,range:state.range},`locked-figure-run-${index}`))]})}),jsxRuntimeExports.jsx(GraphLockedLabelsLayer,{lockedFigures:props.lockedFigures}),!props.static&&jsxRuntimeExports.jsx(MovablePointLabelsLayer,{state:state}),jsxRuntimeExports.jsxs(HitboxLayerContext.Provider,{value:hitboxLayerEl,children:[jsxRuntimeExports.jsx(View,{style:{position:"absolute"},children:jsxRuntimeExports.jsxs(Mafs,{preserveAspectRatio:false,viewBox:{x:state.range[X],y:state.range[Y],padding:0},pan:false,zoom:false,width:width,height:height,children:[props.showProtractor&&jsxRuntimeExports.jsx(ClipToGraphBounds,{children:jsxRuntimeExports.jsx(Protractor,{})}),graph]})}),jsxRuntimeExports.jsx("div",{ref:setHitboxLayerEl,className:"interactive-graph-hitbox-layer",style:{position:"absolute",top:0,left:0,width,height,pointerEvents:"none"}})]})]}),interactionPrompt&&jsxRuntimeExports.jsx(View,{style:{display:interactionPrompt?undefined:"hidden",textAlign:"center",backgroundColor:semanticColor.core.background.base.default,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,paddingBlock:"16px",paddingInline:"0",boxShadow:boxShadow.mid,insetBlockStart:"50%",transform:"translateY(-50%)"},children:jsxRuntimeExports.jsx(BodyText,{id:unlimitedGraphKeyboardPromptId,children:strings.graphKeyboardPrompt})})]}),renderGraphControls({state,dispatch,width,perseusStrings:strings})]})})};const renderPointGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;return jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginInlineStart:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.pointGraph.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",tabIndex:-1,style:{width:"100%",marginInlineStart:"20px",visibility:shouldShowRemoveButton?"visible":"hidden"},onClick:_event=>{props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint})]})};const renderPolygonGraphControls=props=>{const{interactionMode,showRemovePointButton,focusedPointIndex,closedPolygon,coords}=props.state;const{perseusStrings}=props;const shouldShowRemoveButton=showRemovePointButton&&focusedPointIndex!==null;const disableCloseButton=getArrayWithoutDuplicates(coords).length<3;const polygonButton=closedPolygon?jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginInlineStart:"20px"},tabIndex:0,onClick:()=>{props.dispatch(actions.polygon.openPolygon());},children:perseusStrings.openPolygon}):jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:disableCloseButton,style:{width:"100%",marginInlineStart:"20px"},tabIndex:disableCloseButton?-1:0,onClick:()=>{props.dispatch(actions.polygon.closePolygon());},children:perseusStrings.closePolygon});return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row",width:props.width},children:[interactionMode==="keyboard"&&jsxRuntimeExports.jsx(Button,{kind:"secondary",style:{width:"100%",marginInlineStart:"20px"},disabled:closedPolygon,tabIndex:closedPolygon?-1:0,onClick:()=>{props.dispatch(actions.polygon.addPoint([0,0]));},children:perseusStrings.addPoint}),interactionMode==="mouse"&&jsxRuntimeExports.jsx(Button,{id:REMOVE_BUTTON_ID,kind:"secondary",actionType:"destructive",disabled:closedPolygon||!shouldShowRemoveButton,tabIndex:-1,style:{width:"100%",marginInlineStart:"20px"},onClick:_event=>{props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));},children:perseusStrings.removePoint}),polygonButton]})})};const renderGraphControls=props=>{const{state,dispatch,width,perseusStrings}=props;const{type}=state;switch(type){case "point":if(state.numPoints==="unlimited"){return renderPointGraphControls({state,dispatch,width,perseusStrings})}return null;case "polygon":if(state.numSides==="unlimited"){return renderPolygonGraphControls({state,dispatch,width,perseusStrings})}return null;default:return null}};const renderGraphElements=props=>{const{state,dispatch,i18n,markings}=props;const{type}=state;switch(type){case "angle":return renderAngleGraph(state,dispatch,i18n);case "segment":return renderSegmentGraph(state,dispatch,i18n);case "linear-system":return renderLinearSystemGraph(state,dispatch,i18n);case "linear":return renderLinearGraph(state,dispatch,i18n);case "ray":return renderRayGraph(state,dispatch,i18n);case "polygon":return renderPolygonGraph(state,dispatch,i18n,markings);case "point":return renderPointGraph(state,dispatch,i18n);case "circle":return renderCircleGraph(state,dispatch,i18n);case "quadratic":return renderQuadraticGraph(state,dispatch,i18n);case "sinusoid":return renderSinusoidGraph(state,dispatch,i18n);case "exponential":return renderExponentialGraph(state,dispatch,i18n);case "none":return {graph:null,interactiveElementsDescription:null};case "absolute-value":return renderAbsoluteValueGraph(state,dispatch,i18n);case "tangent":return renderTangentGraph(state,dispatch,i18n);case "logarithm":return renderLogarithmGraph(state,dispatch,i18n);case "vector":return renderVectorGraph(state,dispatch,i18n);default:throw new UnreachableCaseError(type)}};
|
|
2009
2009
|
|
|
2010
2010
|
function mafsStateToInteractiveGraph(state,originalGraph){switch(state.type){case "angle":invariant(originalGraph.type==="angle");return {...originalGraph,coords:state.coords};case "quadratic":invariant(originalGraph.type==="quadratic");return {...originalGraph,coords:state.coords};case "circle":invariant(originalGraph.type==="circle");return {...originalGraph,center:state.center,radius:getRadius(state)};case "linear":invariant(originalGraph.type==="linear");return {...originalGraph,coords:state.coords};case "ray":invariant(originalGraph.type==="ray");return {...originalGraph,coords:state.coords};case "sinusoid":invariant(originalGraph.type==="sinusoid");return {...originalGraph,coords:state.coords};case "segment":invariant(originalGraph.type==="segment");return {...originalGraph,coords:state.coords};case "linear-system":invariant(originalGraph.type==="linear-system");return {...originalGraph,coords:state.coords};case "polygon":invariant(originalGraph.type==="polygon");return {...originalGraph,coords:state.coords};case "point":invariant(originalGraph.type==="point");return {...originalGraph,coords:state.coords};case "exponential":invariant(originalGraph.type==="exponential");return {...originalGraph,coords:state.coords,asymptote:state.asymptote};case "none":invariant(originalGraph.type==="none");return {...originalGraph};case "absolute-value":invariant(originalGraph.type==="absolute-value");return {...originalGraph,coords:state.coords};case "tangent":invariant(originalGraph.type==="tangent");return {...originalGraph,coords:state.coords};case "logarithm":invariant(originalGraph.type==="logarithm");return {...originalGraph,coords:state.coords,asymptote:state.asymptote};case "vector":invariant(originalGraph.type==="vector");return {...originalGraph,coords:state.coords};default:throw new UnreachableCaseError(state)}}
|
|
2011
2011
|
|
|
@@ -2043,7 +2043,7 @@ const GifControlsIcon=({isPlaying,onToggle})=>{const strings=usePerseusI18n().st
|
|
|
2043
2043
|
|
|
2044
2044
|
const ImageInfoArea=props=>{const{backgroundImage,caption,longDescription,apiOptions,linterContext,isGifPlaying,setIsGifPlaying,isAnimatedGif,widgetId}=props;const context=React.useContext(PerseusI18nContext);const{analytics}=useDependencies();if(!backgroundImage.url){return null}return jsxRuntimeExports.jsxs("div",{className:styles$d.infoAreaContainer,children:[isAnimatedGif&&jsxRuntimeExports.jsx(GifControlsIcon,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),isAnimatedGif&&longDescription&&jsxRuntimeExports.jsx("div",{className:styles$d.spacerHorizontal}),longDescription&&jsxRuntimeExports.jsx(ModalLauncher,{modal:jsxRuntimeExports.jsx(ExploreImageModal,{...props}),children:({openModal})=>jsxRuntimeExports.jsx(ExploreImageButton,{hasCaption:!!caption,onClick:()=>{analytics.onAnalyticsEvent({type:"perseus:image:explore-modal-opened:ti",payload:{widgetSubType:"null",widgetId}});openModal();}})}),caption&&jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})};
|
|
2045
2045
|
|
|
2046
|
-
const ImageWidget=forwardRef(function ImageWidget(props,ref){const{apiOptions,linterContext,trackInteraction,widgetId}=props;const{alt,backgroundImage,box,caption,longDescription,decorative,labels,range,title}=props;const context=React__default.useContext(PerseusI18nContext);const{analytics}=useDependencies();const[isGifPlaying,setIsGifPlaying]=React__default.useState(false);const[gifFrames,setGifFrames]=React__default.useState(null);const[imageIsGif,setImageGif]=React__default.useState(false);useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$c(props)}));useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React__default.useEffect(()=>{setIsGifPlaying(false);setGifFrames(null);const url=backgroundImage.url;if(!url||!isGif(url)){setImageGif(false);return}setImageGif(true);let mounted=true;decodeGifFrames(url).then(frames=>{if(mounted){setGifFrames(frames);}});return ()=>{mounted=false;}},[backgroundImage.url]);if(!backgroundImage.url){return null}const isAnimatedGif=imageIsGif&&gifFrames!=null&&gifFrames.length>1;let scale=props.scale;if(scale<=0||scale===Infinity||scale===-Infinity){scale=1;}const svgImage=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,apiOptions:apiOptions,width:backgroundImage.width,height:backgroundImage.height,scale:scale,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative&&!imageIsGif,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus,isGifPlaying:imageIsGif?isGifPlaying:undefined,onGifLoop:imageIsGif?()=>setIsGifPlaying(false):undefined,gifFrames:imageIsGif?gifFrames??undefined:undefined})});const maxWidth=backgroundImage.width?backgroundImage.width*scale:undefined;const width=maxWidth?undefined:"fit-content";if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{
|
|
2046
|
+
const ImageWidget=forwardRef(function ImageWidget(props,ref){const{apiOptions,linterContext,trackInteraction,widgetId}=props;const{alt,backgroundImage,box,caption,longDescription,decorative,labels,range,title}=props;const context=React__default.useContext(PerseusI18nContext);const{analytics}=useDependencies();const[isGifPlaying,setIsGifPlaying]=React__default.useState(false);const[gifFrames,setGifFrames]=React__default.useState(null);const[imageIsGif,setImageGif]=React__default.useState(false);useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$c(props)}));useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React__default.useEffect(()=>{setIsGifPlaying(false);setGifFrames(null);const url=backgroundImage.url;if(!url||!isGif(url)){setImageGif(false);return}setImageGif(true);let mounted=true;decodeGifFrames(url).then(frames=>{if(mounted){setGifFrames(frames);}});return ()=>{mounted=false;}},[backgroundImage.url]);if(!backgroundImage.url){return null}const isAnimatedGif=imageIsGif&&gifFrames!=null&&gifFrames.length>1;let scale=props.scale;if(scale<=0||scale===Infinity||scale===-Infinity){scale=1;}const svgImage=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,apiOptions:apiOptions,width:backgroundImage.width,height:backgroundImage.height,scale:scale,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative&&!imageIsGif,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus,isGifPlaying:imageIsGif?isGifPlaying:undefined,onGifLoop:imageIsGif?()=>setIsGifPlaying(false):undefined,gifFrames:imageIsGif?gifFrames??undefined:undefined})});const maxWidth=backgroundImage.width?backgroundImage.width*scale:undefined;const width=maxWidth?undefined:"fit-content";if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{maxInlineSize:maxWidth,width:width},children:svgImage})}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxInlineSize:maxWidth,width:width},children:[title&&jsxRuntimeExports.jsx("div",{className:`perseus-image-title ${styles$d.titleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:title,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),svgImage,(isAnimatedGif||caption||longDescription)&&jsxRuntimeExports.jsx(ImageInfoArea,{isGifPlaying:isGifPlaying,setIsGifPlaying:setIsGifPlaying,isAnimatedGif:isAnimatedGif,...props,apiOptions:apiOptions,linterContext:linterContext,widgetId:widgetId})]})});var Image$1 = {name:"image",displayName:"Image",widget:ImageWidget,isLintable:true};
|
|
2047
2047
|
|
|
2048
2048
|
const getPromptJSON$b=()=>{return getUnsupportedPromptJSON("interaction")};
|
|
2049
2049
|
|
|
@@ -2055,19 +2055,19 @@ const getPromptJSON$a=widgetData=>{const propMarkers=widgetData.markers.map(mark
|
|
|
2055
2055
|
|
|
2056
2056
|
const AnswerChoices=props=>{const{strings}=usePerseusI18n();const onAnswerChange=selected=>{const{choices,onChange}=props;onChange(choices.map(choice=>selected.includes(choice.content)));};const AnswerItems=choices=>choices.map(({content})=>jsxRuntimeExports.jsx(OptionItem,{value:content,label:jsxRuntimeExports.jsx(Renderer,{content:content,strings:strings,inline:true})},content));const selectedValues=props.choices.filter(choice=>choice.checked).map(choice=>choice.content);const{opener,onToggle,disabled}=props;const args={style:{zIndex:"unset"},children:AnswerItems(props.choices),opener,onToggle,disabled};return props.multipleSelect?jsxRuntimeExports.jsx(MultiSelect,{...args,selectedValues:selectedValues,onChange:selected=>onAnswerChange(selected)}):jsxRuntimeExports.jsx(SingleSelect,{...args,selectedValue:selectedValues[0],onChange:selected=>onAnswerChange([selected]),placeholder:props.choices[0].content})};
|
|
2057
2057
|
|
|
2058
|
-
const HideAnswersToggle=props=>{const switchId=useId();const labelId=useId();const{strings}=usePerseusI18n();return jsxRuntimeExports.jsxs(View,{style:styles$c.switchWrapper,children:[jsxRuntimeExports.jsx(Switch,{id:switchId,checked:props.areAnswersHidden,onChange:props.onChange,"aria-labelledby":labelId}),jsxRuntimeExports.jsx(BodyText,{id:labelId,htmlFor:switchId,tag:"label",children:strings.hideAnswersToggleLabel})]})};const styles$c=StyleSheet.create({switchWrapper:{display:"flex",flexDirection:"row",flexWrap:"wrap-reverse",alignItems:"center",gap:"0.5em",
|
|
2058
|
+
const HideAnswersToggle=props=>{const switchId=useId();const labelId=useId();const{strings}=usePerseusI18n();return jsxRuntimeExports.jsxs(View,{style:styles$c.switchWrapper,children:[jsxRuntimeExports.jsx(Switch,{id:switchId,checked:props.areAnswersHidden,onChange:props.onChange,"aria-labelledby":labelId}),jsxRuntimeExports.jsx(BodyText,{id:labelId,htmlFor:switchId,tag:"label",children:strings.hideAnswersToggleLabel})]})};const styles$c=StyleSheet.create({switchWrapper:{display:"flex",flexDirection:"row",flexWrap:"wrap-reverse",alignItems:"center",gap:"0.5em",marginBlockStart:"1em"}});
|
|
2059
2059
|
|
|
2060
2060
|
const BringToFront={boxShadow:`0 8px 8px ${semanticColor.core.border.neutral.default}`,zIndex:1e3};const AnswerPill=props=>{const{selectedAnswers,showCorrectness,markerRef,side,onClick,style,focused,hovered}=props;const pillId=useId();const{strings}=usePerseusI18n();const answerString=selectedAnswers.length>1?strings.answers({num:selectedAnswers.length}):selectedAnswers[0];const correct=showCorrectness==="correct";const incorrect=showCorrectness==="incorrect";return jsxRuntimeExports.jsx(Popper,{placement:side,referenceElement:markerRef,modifiers:[{name:"preventOverflow",options:{rootBoundary:"viewport"}}],children:({ref,style:popperStyle})=>jsxRuntimeExports.jsx(Pill,{size:"large",kind:"accent",id:pillId,onClick:correct?undefined:onClick,ref:ref,style:[style,popperStyle,styles$b.pill,correct&&styles$b.correct,incorrect&&styles$b.incorrect,(focused||hovered)&&BringToFront],children:jsxRuntimeExports.jsx(Renderer,{content:answerString,strings:strings,inline:true})})})};const styles$b=StyleSheet.create({correct:{backgroundColor:semanticColor.core.background.success.strong},incorrect:{backgroundColor:semanticColor.core.background.neutral.default},pill:{height:"auto"}});
|
|
2061
2061
|
|
|
2062
2062
|
function shouldReduceMotion(){if(typeof window.matchMedia!=="function"){return true}const mediaQuery=window.matchMedia("(prefers-reduced-motion: reduce)");return !mediaQuery||mediaQuery.matches}const MARKER_SIZE=24;class Marker extends React.Component{componentDidMount(){this._mounted=true;}componentWillUnmount(){this._mounted=false;}renderIcon(){const{selected,showCorrectness,showSelected,showPulsate}=this.props;const isOpen=showSelected;const selectedAnswers=selected;let iconStyles;const iconNull={path:"",height:1,width:1};let args={size:MARKER_SIZE,color:semanticColor.core.foreground.knockout.default,icon:iconNull};if(showCorrectness){iconStyles=[styles$a.markerGraded,showCorrectness==="correct"?styles$a.markerCorrect:styles$a.markerIncorrect,isOpen&&styles$a.markerSelected];args={...args,icon:showCorrectness==="correct"?iconCheck:iconMinus};}else if(selectedAnswers&&selectedAnswers.length>0){iconStyles=[styles$a.markerFilled,isOpen&&styles$a.markerSelected];}else if(isOpen){iconStyles=[styles$a.markerSelected];args={...args,icon:iconChevronDown,size:8};}else if(showPulsate){iconStyles=[styles$a.markerPulsateBase,this._mounted&&shouldReduceMotion()?showPulsate&&styles$a.markerUnfilledPulsateOnce:showPulsate&&styles$a.markerUnfilledPulsateInfinite];}return jsxRuntimeExports.jsx(View,{style:[styles$a.markerIcon,iconStyles],ref:node=>this._icon=node,children:jsxRuntimeExports.jsx(Icon,{...args})})}render(){const{showCorrectness,selected,showAnswer,answerSide,answerStyles,hovered,focused,label}=this.props;const markerDisabled=showCorrectness==="correct";const active=hovered||focused;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(View,{style:[styles$a.marker,active&&!markerDisabled&&styles$a.markerActive],"aria-label":markerDisabled?this.context.strings.correctExcited:label,children:this.renderIcon()}),!!selected&&showAnswer&&jsxRuntimeExports.jsx(AnswerPill,{selectedAnswers:selected,showCorrectness:showCorrectness,side:answerSide,style:answerStyles,markerRef:this._icon??undefined,hovered:hovered,focused:focused})]})}constructor(...args){super(...args),this._mounted=false;}}Marker.contextType=PerseusI18nContext;Marker.defaultProps={selected:[]};const styles$a=StyleSheet.create({marker:{position:"absolute",backgroundColor:semanticColor.core.background.base.default,borderRadius:MARKER_SIZE,width:MARKER_SIZE,height:MARKER_SIZE,marginLeft:MARKER_SIZE/-2,marginTop:MARKER_SIZE/-2,boxShadow:boxShadow.mid},markerIcon:{display:"flex",alignItems:"center",justifyContent:"center",boxSizing:"border-box",width:MARKER_SIZE,height:MARKER_SIZE,border:`2px solid ${semanticColor.core.border.neutral.default}`,borderRadius:MARKER_SIZE},markerPulsateBase:{animationName:{"0%":{transform:"scale(1)",backgroundColor:semanticColor.core.background.instructive.default},"100%":{transform:"scale(1.3)",backgroundColor:semanticColor.core.background.instructive.default}},animationDirection:"alternate",animationDuration:"0.8s",animationTimingFunction:"ease-in",transformOrigin:"50% 50%",animationIterationCount:"0"},markerUnfilledPulsateInfinite:{animationIterationCount:"infinite"},markerUnfilledPulsateOnce:{animationIterationCount:"2"},markerActive:{outline:`2px solid ${semanticColor.core.border.instructive.default}`,outlineOffset:2},markerSelected:{boxShadow:boxShadow.mid,border:`solid 4px ${semanticColor.core.border.knockout.default}`,backgroundColor:semanticColor.core.background.instructive.default,borderRadius:MARKER_SIZE,transform:"rotate(180deg)"},markerFilled:{backgroundColor:semanticColor.core.background.instructive.subtle,border:`4px solid ${semanticColor.core.border.instructive.default}`},markerGraded:{width:MARKER_SIZE,height:MARKER_SIZE,justifyContent:"center",alignItems:"center",border:`2px solid ${semanticColor.core.border.knockout.default}`},markerCorrect:{background:semanticColor.core.background.success.strong},markerIncorrect:{background:semanticColor.core.background.neutral.default}});
|
|
2063
2063
|
|
|
2064
|
-
function isAnswerful(marker){return marker.answers!=null}function getComputedSelectedState(marker,userInputMarker,reviewMode,showSolutions){const shouldShowFeedback=showSolutions==="all"||reviewMode;if(!shouldShowFeedback){return userInputMarker}if(isAnswerful(marker)){return {...userInputMarker,selected:marker.answers}}else {return {...userInputMarker,selected:undefined}}}class LabelImage extends React.Component{static pointInTriangle(p,a,b,c){const sign=(p1,p2,p3)=>(p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y);const b1=sign(p,a,b)<0;const b2=sign(p,b,c)<0;const b3=sign(p,c,a)<0;return b1===b2&&b2===b3}static imageSideForMarkerPosition(x,y,preferredDirection){if(preferredDirection&&preferredDirection!=="NONE"){if(preferredDirection==="LEFT"&&x>20){return "right"}else if(preferredDirection==="RIGHT"&&x<80){return "left"}else if(preferredDirection==="UP"&&y>20){return "bottom"}else if(preferredDirection==="DOWN"&&y<80){return "top"}}if(x<20){return "left"}if(x>80){return "right"}const tl={x:20,y:0};const tr={x:80,y:0};const br={x:80,y:100};const bl={x:20,y:100};const cp={x:50,y:50};const sides=["top","right","bottom","left"];const triangles={top:[tl,tr,cp],right:[cp,tr,br],bottom:[bl,cp,br],left:[tl,cp,bl]};const p={x,y};for(const side of sides){const corners=triangles[side];if(LabelImage.pointInTriangle(p,...corners)){return side}}return "center"}static navigateToMarkerIndex(navigateDirection,markers,thisIndex){const thisMarker=markers[thisIndex];const sortedMarkers=markers.map((otherMarker,index)=>{const x=otherMarker.x-thisMarker.x;const y=otherMarker.y-thisMarker.y;const dist=Math.sqrt(x**2+y**2);return {index,dist,dir:{x:dist!==0?x/dist:0,y:dist!==0?y/dist:0}}}).filter(marker=>{if(marker.index===thisIndex){return false}return markers[marker.index].showCorrectness!=="correct"}).sort((a,b)=>{const distA=Math.round(a.dist*(navigateDirection.x*a.dir.x+navigateDirection.y*a.dir.y));const distB=Math.round(b.dist*(navigateDirection.x*b.dir.x+navigateDirection.y*b.dir.y));let dirA;let dirB;if(navigateDirection.x>0){dirA=a.dir.x>0&&distA!==0;dirB=b.dir.x>0&&distB!==0;}else if(navigateDirection.x<0){dirA=a.dir.x<0&&distA!==0;dirB=b.dir.x<0&&distB!==0;}else if(navigateDirection.y>0){dirA=a.dir.y>0&&distA!==0;dirB=b.dir.y>0&&distB!==0;}else if(navigateDirection.y<0){dirA=a.dir.y<0&&distA!==0;dirB=b.dir.y<0&&distB!==0;}if(dirA!==dirB){if(dirA){return -1}return 1}return distA-distB});return sortedMarkers.length>0?sortedMarkers[0].index:thisIndex}componentDidMount(){this.props.analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"label-image",widgetId:this.props.widgetId}});this._mounted=true;}componentWillUnmount(){this._mounted=false;}getPromptJSON(){return getPromptJSON$a(this.props)}handleMarkerChange(index,marker){const{userInput,handleUserInput}=this.props;const updatedUserInput=[...userInput.markers.slice(0,index),{label:marker.label,selected:marker.selected},...userInput.markers.slice(index+1)];handleUserInput({markers:updatedUserInput});}activateMarker(index,opened){this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:marker-interacted-with",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:marker-interacted-with:ti",payload:null});const{activeMarkerIndex}=this.state;if(activeMarkerIndex!==index&&opened){this.setState({activeMarkerIndex:index,markersInteracted:true});}else {this.setState({activeMarkerIndex:-1});}}handleMarkerKeyDown(index,e){const{markers}=this.props;if(markers.length<2){return}const directions={ArrowUp:{x:0,y:-1},ArrowRight:{x:1,y:0},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0}};if(!(e.key in directions)){return}const navigateDirection=directions[e.key];e.preventDefault();const marker=this._markers[LabelImage.navigateToMarkerIndex(navigateDirection,markers,index)];if(marker){ReactDOM.findDOMNode(marker).focus();}}handleAnswerChoicesChangeForMarker(index,selection){const{choices,markers}=this.props;const selected=choices.filter((_,index)=>selection[index]);this.handleMarkerChange(index,{...markers[index],selected:selected.length>0?selected:undefined});}renderMarkers(){const{markers,preferredPopoverDirection,userInput}=this.props;const{markersInteracted,activeMarkerIndex}=this.state;const isNarrowPage=this._mounted&&window.matchMedia(mediaQueries.xsOrSmaller.replace("@media ","")).matches;const isWideImage=this.props.imageWidth/2>this.props.imageHeight;return markers.map((marker,index)=>{const userInputMarker=userInput.markers[index];let side;let markerPosition;if(isNarrowPage||isWideImage){side=marker.y>50?"top":"bottom";markerPosition=marker.y>50?"bottom":"top";}else {markerPosition=LabelImage.imageSideForMarkerPosition(marker.x,marker.y,preferredPopoverDirection);if(markerPosition==="center"){markerPosition="bottom";}side=({left:"right",top:"bottom",right:"left",bottom:"top"})[markerPosition];}const computedSelectedState=getComputedSelectedState(marker,userInputMarker,this.props.reviewMode,this.props.showSolutions);let score;if(isAnswerful(marker)){score=scoreLabelImageMarker(computedSelectedState.selected,marker.answers);}else {score={hasAnswers:false,isCorrect:false};}const shouldShowFeedback=this.props.showSolutions==="all"||this.props.reviewMode;const showCorrectness=shouldShowFeedback&&score.isCorrect?"correct":marker.showCorrectness;const disabled=shouldShowFeedback;const isActiveAnswerChoice=activeMarkerIndex===index;const showAnswerChoice=computedSelectedState.selected&&!this.state.hideAnswers&&!isActiveAnswerChoice;const adjustPillDistance={[`margin${markerPosition.charAt(0).toUpperCase()+markerPosition.slice(1)}`]:10};return jsxRuntimeExports.jsx(View,{style:{position:"absolute",left:`${marker.x}%`,top:`${marker.y}%`,zIndex:"unset"},children:jsxRuntimeExports.jsx(AnswerChoices,{choices:this.props.choices.map(choice=>({content:choice,checked:computedSelectedState.selected?computedSelectedState.selected.includes(choice):false})),multipleSelect:this.props.multipleAnswers,onChange:selection=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:choiced-interacted-with",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:choiced-interacted-with:ti",payload:null});this.handleAnswerChoicesChangeForMarker(index,selection);},onToggle:opened=>this.activateMarker(index,opened),disabled:disabled,opener:({opened})=>jsxRuntimeExports.jsx(Clickable,{role:"button","aria-expanded":opened,children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(Marker,{label:marker.label,showCorrectness:showCorrectness,showSelected:opened,showPulsate:!markersInteracted,ref:node=>this._markers[index]=node,showAnswer:showAnswerChoice,answerSide:side,answerStyles:adjustPillDistance,focused:focused||pressed,hovered:hovered,selected:computedSelectedState.selected})},`marker-${marker.x}.${marker.y}`)},`answers-${marker.x}.${marker.y}`)},index)})}renderInstructions(){const{apiOptions:{isMobile},choices,multipleAnswers,hideChoicesFromInstructions:hideChoices}=this.props;const{strings}=this.context;const promptString=isMobile?multipleAnswers?strings.tapMultiple:strings.tapSingle:multipleAnswers?strings.clickMultiple:strings.clickSingle;const choicesString=strings.choices;return jsxRuntimeExports.jsxs("div",{className:classNames$2("perseus-label-image-widget-instructions",css(styles$9.instructions)),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$9.instructionsCaption),children:[promptString," ",!hideChoices&&choicesString]}),!hideChoices&&jsxRuntimeExports.jsx("div",{className:css(styles$9.instructionsChoices),children:choices.map((choice,index)=>jsxRuntimeExports.jsx("div",{className:css(styles$9.instructionsChoice),children:jsxRuntimeExports.jsx(Renderer,{content:choice,strings:strings})},index))})]})}getSerializedState(){const{userInput,markers,...rest}=this.props;return {...rest,markers:markers.map((marker,index)=>({...marker,selected:userInput.markers[index].selected}))}}render(){const{imageAlt,imageUrl,imageWidth,imageHeight}=this.props;const{activeMarkerIndex}=this.state;return jsxRuntimeExports.jsxs("div",{children:[this.renderInstructions(),jsxRuntimeExports.jsxs("div",{className:css(styles$9.markersCanvas),style:{maxWidth:imageWidth,maxHeight:imageHeight},children:[jsxRuntimeExports.jsx("div",{className:css(styles$9.imageContainer,activeMarkerIndex!==-1&&styles$9.imageInteractionDisabled),children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{alt:imageAlt,src:imageUrl,width:imageWidth,height:imageHeight,setAssetStatus:setAssetStatus,allowZoom:true})})}),this.renderMarkers()]}),jsxRuntimeExports.jsx(HideAnswersToggle,{areAnswersHidden:this.state.hideAnswers,onChange:hideAnswers=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:toggle-answers-hidden",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:toggle-answers-hidden:ti",payload:null});this.setState({hideAnswers});}})]})}constructor(props){super(props),this._mounted=false;this._markers=[];this.state={activeMarkerIndex:-1,markersInteracted:false,hideAnswers:false};}}LabelImage.contextType=PerseusI18nContext;const LabelImageWithDependencies=React.forwardRef((props,ref)=>{const deps=useDependencies();return jsxRuntimeExports.jsx(LabelImage,{ref:ref,analytics:deps.analytics,...props})});function getStartUserInput$7(options){return {markers:options.markers.map(m=>({label:m.label}))}}function getUserInputFromSerializedState$7(serializedState){return {markers:serializedState.markers.map(m=>({label:m.label,selected:m.selected}))}}function getCorrectUserInput$3(options){return {markers:options.markers.map(marker=>({label:marker.label,selected:marker.answers}))}}var LabelImage$1 = {name:"label-image",displayName:"Label Image",widget:LabelImageWithDependencies,isLintable:true,getStartUserInput: getStartUserInput$7,getCorrectUserInput: getCorrectUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$7};const styles$9=StyleSheet.create({instructions:{paddingBottom:16},instructionsCaption:{...bodyXsmallBold,paddingBottom:16},instructionsChoices:{display:"flex",flexWrap:"wrap",margin:"-8px 0"},instructionsChoice:{display:"flex",alignItems:"center",margin:"8px 0",":not(:last-child)":{"::after":{content:"''",display:"inline-block",position:"relative",width:2,height:2,marginLeft:5,marginRight:5,background:semanticColor.core.border.neutral.default,borderRadius:2}}},markersCanvas:{position:"relative"},imageContainer:{display:"flex"},imageInteractionDisabled:{pointerEvents:"none"}});
|
|
2064
|
+
function isAnswerful(marker){return marker.answers!=null}function getComputedSelectedState(marker,userInputMarker,reviewMode,showSolutions){const shouldShowFeedback=showSolutions==="all"||reviewMode;if(!shouldShowFeedback){return userInputMarker}if(isAnswerful(marker)){return {...userInputMarker,selected:marker.answers}}else {return {...userInputMarker,selected:undefined}}}class LabelImage extends React.Component{static pointInTriangle(p,a,b,c){const sign=(p1,p2,p3)=>(p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y);const b1=sign(p,a,b)<0;const b2=sign(p,b,c)<0;const b3=sign(p,c,a)<0;return b1===b2&&b2===b3}static imageSideForMarkerPosition(x,y,preferredDirection){if(preferredDirection&&preferredDirection!=="NONE"){if(preferredDirection==="LEFT"&&x>20){return "right"}else if(preferredDirection==="RIGHT"&&x<80){return "left"}else if(preferredDirection==="UP"&&y>20){return "bottom"}else if(preferredDirection==="DOWN"&&y<80){return "top"}}if(x<20){return "left"}if(x>80){return "right"}const tl={x:20,y:0};const tr={x:80,y:0};const br={x:80,y:100};const bl={x:20,y:100};const cp={x:50,y:50};const sides=["top","right","bottom","left"];const triangles={top:[tl,tr,cp],right:[cp,tr,br],bottom:[bl,cp,br],left:[tl,cp,bl]};const p={x,y};for(const side of sides){const corners=triangles[side];if(LabelImage.pointInTriangle(p,...corners)){return side}}return "center"}static navigateToMarkerIndex(navigateDirection,markers,thisIndex){const thisMarker=markers[thisIndex];const sortedMarkers=markers.map((otherMarker,index)=>{const x=otherMarker.x-thisMarker.x;const y=otherMarker.y-thisMarker.y;const dist=Math.sqrt(x**2+y**2);return {index,dist,dir:{x:dist!==0?x/dist:0,y:dist!==0?y/dist:0}}}).filter(marker=>{if(marker.index===thisIndex){return false}return markers[marker.index].showCorrectness!=="correct"}).sort((a,b)=>{const distA=Math.round(a.dist*(navigateDirection.x*a.dir.x+navigateDirection.y*a.dir.y));const distB=Math.round(b.dist*(navigateDirection.x*b.dir.x+navigateDirection.y*b.dir.y));let dirA;let dirB;if(navigateDirection.x>0){dirA=a.dir.x>0&&distA!==0;dirB=b.dir.x>0&&distB!==0;}else if(navigateDirection.x<0){dirA=a.dir.x<0&&distA!==0;dirB=b.dir.x<0&&distB!==0;}else if(navigateDirection.y>0){dirA=a.dir.y>0&&distA!==0;dirB=b.dir.y>0&&distB!==0;}else if(navigateDirection.y<0){dirA=a.dir.y<0&&distA!==0;dirB=b.dir.y<0&&distB!==0;}if(dirA!==dirB){if(dirA){return -1}return 1}return distA-distB});return sortedMarkers.length>0?sortedMarkers[0].index:thisIndex}componentDidMount(){this.props.analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"label-image",widgetId:this.props.widgetId}});this._mounted=true;}componentWillUnmount(){this._mounted=false;}getPromptJSON(){return getPromptJSON$a(this.props)}handleMarkerChange(index,marker){const{userInput,handleUserInput}=this.props;const updatedUserInput=[...userInput.markers.slice(0,index),{label:marker.label,selected:marker.selected},...userInput.markers.slice(index+1)];handleUserInput({markers:updatedUserInput});}activateMarker(index,opened){this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:marker-interacted-with",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:marker-interacted-with:ti",payload:null});const{activeMarkerIndex}=this.state;if(activeMarkerIndex!==index&&opened){this.setState({activeMarkerIndex:index,markersInteracted:true});}else {this.setState({activeMarkerIndex:-1});}}handleMarkerKeyDown(index,e){const{markers}=this.props;if(markers.length<2){return}const directions={ArrowUp:{x:0,y:-1},ArrowRight:{x:1,y:0},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0}};if(!(e.key in directions)){return}const navigateDirection=directions[e.key];e.preventDefault();const marker=this._markers[LabelImage.navigateToMarkerIndex(navigateDirection,markers,index)];if(marker){ReactDOM.findDOMNode(marker).focus();}}handleAnswerChoicesChangeForMarker(index,selection){const{choices,markers}=this.props;const selected=choices.filter((_,index)=>selection[index]);this.handleMarkerChange(index,{...markers[index],selected:selected.length>0?selected:undefined});}renderMarkers(){const{markers,preferredPopoverDirection,userInput}=this.props;const{markersInteracted,activeMarkerIndex}=this.state;const isNarrowPage=this._mounted&&window.matchMedia(mediaQueries.xsOrSmaller.replace("@media ","")).matches;const isWideImage=this.props.imageWidth/2>this.props.imageHeight;return markers.map((marker,index)=>{const userInputMarker=userInput.markers[index];let side;let markerPosition;if(isNarrowPage||isWideImage){side=marker.y>50?"top":"bottom";markerPosition=marker.y>50?"bottom":"top";}else {markerPosition=LabelImage.imageSideForMarkerPosition(marker.x,marker.y,preferredPopoverDirection);if(markerPosition==="center"){markerPosition="bottom";}side=({left:"right",top:"bottom",right:"left",bottom:"top"})[markerPosition];}const computedSelectedState=getComputedSelectedState(marker,userInputMarker,this.props.reviewMode,this.props.showSolutions);let score;if(isAnswerful(marker)){score=scoreLabelImageMarker(computedSelectedState.selected,marker.answers);}else {score={hasAnswers:false,isCorrect:false};}const shouldShowFeedback=this.props.showSolutions==="all"||this.props.reviewMode;const showCorrectness=shouldShowFeedback&&score.isCorrect?"correct":marker.showCorrectness;const disabled=shouldShowFeedback;const isActiveAnswerChoice=activeMarkerIndex===index;const showAnswerChoice=computedSelectedState.selected&&!this.state.hideAnswers&&!isActiveAnswerChoice;const adjustPillDistance={[`margin${markerPosition.charAt(0).toUpperCase()+markerPosition.slice(1)}`]:10};return jsxRuntimeExports.jsx(View,{style:{position:"absolute",left:`${marker.x}%`,top:`${marker.y}%`,zIndex:"unset"},children:jsxRuntimeExports.jsx(AnswerChoices,{choices:this.props.choices.map(choice=>({content:choice,checked:computedSelectedState.selected?computedSelectedState.selected.includes(choice):false})),multipleSelect:this.props.multipleAnswers,onChange:selection=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:choiced-interacted-with",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:choiced-interacted-with:ti",payload:null});this.handleAnswerChoicesChangeForMarker(index,selection);},onToggle:opened=>this.activateMarker(index,opened),disabled:disabled,opener:({opened})=>jsxRuntimeExports.jsx(Clickable,{role:"button","aria-expanded":opened,children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(Marker,{label:marker.label,showCorrectness:showCorrectness,showSelected:opened,showPulsate:!markersInteracted,ref:node=>this._markers[index]=node,showAnswer:showAnswerChoice,answerSide:side,answerStyles:adjustPillDistance,focused:focused||pressed,hovered:hovered,selected:computedSelectedState.selected})},`marker-${marker.x}.${marker.y}`)},`answers-${marker.x}.${marker.y}`)},index)})}renderInstructions(){const{apiOptions:{isMobile},choices,multipleAnswers,hideChoicesFromInstructions:hideChoices}=this.props;const{strings}=this.context;const promptString=isMobile?multipleAnswers?strings.tapMultiple:strings.tapSingle:multipleAnswers?strings.clickMultiple:strings.clickSingle;const choicesString=strings.choices;return jsxRuntimeExports.jsxs("div",{className:classNames$2("perseus-label-image-widget-instructions",css(styles$9.instructions)),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$9.instructionsCaption),children:[promptString," ",!hideChoices&&choicesString]}),!hideChoices&&jsxRuntimeExports.jsx("div",{className:css(styles$9.instructionsChoices),children:choices.map((choice,index)=>jsxRuntimeExports.jsx("div",{className:css(styles$9.instructionsChoice),children:jsxRuntimeExports.jsx(Renderer,{content:choice,strings:strings})},index))})]})}getSerializedState(){const{userInput,markers,...rest}=this.props;return {...rest,markers:markers.map((marker,index)=>({...marker,selected:userInput.markers[index].selected}))}}render(){const{imageAlt,imageUrl,imageWidth,imageHeight}=this.props;const{activeMarkerIndex}=this.state;return jsxRuntimeExports.jsxs("div",{children:[this.renderInstructions(),jsxRuntimeExports.jsxs("div",{className:css(styles$9.markersCanvas),style:{maxInlineSize:imageWidth,maxBlockSize:imageHeight},children:[jsxRuntimeExports.jsx("div",{className:css(styles$9.imageContainer,activeMarkerIndex!==-1&&styles$9.imageInteractionDisabled),children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{alt:imageAlt,src:imageUrl,width:imageWidth,height:imageHeight,setAssetStatus:setAssetStatus,allowZoom:true})})}),this.renderMarkers()]}),jsxRuntimeExports.jsx(HideAnswersToggle,{areAnswersHidden:this.state.hideAnswers,onChange:hideAnswers=>{this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:toggle-answers-hidden",payload:null});this.props.analytics?.onAnalyticsEvent({type:"perseus:label-image:toggle-answers-hidden:ti",payload:null});this.setState({hideAnswers});}})]})}constructor(props){super(props),this._mounted=false;this._markers=[];this.state={activeMarkerIndex:-1,markersInteracted:false,hideAnswers:false};}}LabelImage.contextType=PerseusI18nContext;const LabelImageWithDependencies=React.forwardRef((props,ref)=>{const deps=useDependencies();return jsxRuntimeExports.jsx(LabelImage,{ref:ref,analytics:deps.analytics,...props})});function getStartUserInput$7(options){return {markers:options.markers.map(m=>({label:m.label}))}}function getUserInputFromSerializedState$7(serializedState){return {markers:serializedState.markers.map(m=>({label:m.label,selected:m.selected}))}}function getCorrectUserInput$3(options){return {markers:options.markers.map(marker=>({label:marker.label,selected:marker.answers}))}}var LabelImage$1 = {name:"label-image",displayName:"Label Image",widget:LabelImageWithDependencies,isLintable:true,getStartUserInput: getStartUserInput$7,getCorrectUserInput: getCorrectUserInput$3,getUserInputFromSerializedState: getUserInputFromSerializedState$7};const styles$9=StyleSheet.create({instructions:{paddingBlockEnd:16},instructionsCaption:{...bodyXsmallBold,paddingBlockEnd:16},instructionsChoices:{display:"flex",flexWrap:"wrap",marginBlock:"-8px",marginInline:"0"},instructionsChoice:{display:"flex",alignItems:"center",marginBlock:"8px",marginInline:"0",":not(:last-child)":{"::after":{content:"''",display:"inline-block",position:"relative",width:2,height:2,marginInlineStart:5,marginInlineEnd:5,background:semanticColor.core.border.neutral.default,borderRadius:2}}},markersCanvas:{position:"relative"},imageContainer:{display:"flex"},imageInteractionDisabled:{pointerEvents:"none"}});
|
|
2065
2065
|
|
|
2066
|
-
const addOffsetParentScroll=($el,position)=>{const $offsetParent=$el.offsetParent();return {top:position.top+$offsetParent.scrollTop(),left:position.left+$offsetParent.scrollLeft()}};class Placeholder extends React.Component{render(){const{layout}=this.props;const className=css(styles$8.card,styles$8.placeholder,layout==="horizontal"&&styles$8.horizontalCard);const style={width:this.props.width,height:this.props.height};if(this.props.margin!=null){style.margin=this.props.margin;}return jsxRuntimeExports.jsx("li",{className:className,style:style})}}class Draggable extends React.Component{componentDidMount(){this._mounted=true;this.isMouseMoveUpBound=false;document.addEventListener("touchmove",this.onMouseMove,Util.supportsPassiveEvents()?{passive:false}:false);}componentDidUpdate(prevProps){if(this.props.state===prevProps.state){return}if(this.props.state==="animating"&&this.props.endPosition){const current=this.getCurrentPosition();const duration=15*Math.sqrt(Math.sqrt(Math.pow(this.props.endPosition.left-current.left,2)+Math.pow(this.props.endPosition.top-current.top,2)));$(ReactDOM__default.findDOMNode(this)).animate(this.props.endPosition,{duration:Math.max(duration,1),complete:this.props.onAnimationEnd});}else if(this.props.state==="static"){$(ReactDOM__default.findDOMNode(this)).finish();}}componentWillUnmount(){this._mounted=false;if(this.isMouseMoveUpBound){this.unbindMouseMoveUp();}if(this.animationFrameRequest){cancelAnimationFrame(this.animationFrameRequest);}document.removeEventListener("touchmove",this.onMouseMove);}render(){const{includePadding,layout,state:type}=this.props;let className=css(styles$8.card,styles$8.draggable,layout==="horizontal"&&styles$8.horizontalCard,layout==="vertical"&&styles$8.verticalCard,type==="dragging"&&styles$8.dragging,type==="disabled"&&styles$8.disabled,!includePadding&&styles$8.unpaddedCard)+" "+"perseus-sortable-draggable";if(!includePadding){className+=" perseus-sortable-draggable-unpadded";}const style={position:"static"};if(this.props.state==="dragging"||this.props.state==="animating"){Object.assign(style,{position:"absolute"},this.getCurrentPosition());}if(this.props.width){style.width=this.props.width+1;}if(this.props.height){style.height=this.props.height;}if(this.props.margin!=null){style.margin=this.props.margin;}return jsxRuntimeExports.jsx("li",{className:className,style:style,onMouseDown:this.onMouseDown,onTouchStart:this.onMouseDown,onTouchMove:this.onMouseMove,onTouchEnd:this.onMouseUp,onTouchCancel:this.onMouseUp,children:jsxRuntimeExports.jsx(Renderer,{content:this.props.content,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"draggable"),onRender:this.props.onRender,strings:this.context.strings})})}constructor(...args){super(...args),this.animationFrameRequest=null,this.state={startPosition:{left:0,top:0},startMouse:{left:0,top:0},mouse:{left:0,top:0},dragging:false},this.getCurrentPosition=()=>{return {left:this.state.startPosition.left+this.state.mouse.left-this.state.startMouse.left,top:this.state.startPosition.top+this.state.mouse.top-this.state.startMouse.top}},this.bindMouseMoveUp=()=>{this.isMouseMoveUpBound=true;$(document).on("mousemove",this.onMouseMove);$(document).on("mouseup",this.onMouseUp);},this.unbindMouseMoveUp=()=>{this.isMouseMoveUpBound=false;$(document).off("mousemove",this.onMouseMove);$(document).off("mouseup",this.onMouseUp);},this.onMouseDown=event=>{if(this.props.state!=="static"){return}if(!(event.button===0||event.touches!=null&&event.touches.length===1)){return}event.preventDefault();const loc=Util.extractPointerLocation(event);this.animationFrameRequest=requestAnimationFrame(()=>{const $el=$(ReactDOM__default.findDOMNode(this));const position=$el.position();const startPosition=addOffsetParentScroll($el,position);if(loc&&this._mounted){this.setState({startPosition,startMouse:loc,mouse:loc,dragging:true},function(){this.bindMouseMoveUp();this.props.onMouseDown();});}});},this.onMouseMove=event=>{const notDragging=this.props.state!=="dragging"||!this.state.dragging;if(notDragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.animationFrameRequest=requestAnimationFrame(()=>{this.setState({mouse:loc},this.props.onMouseMove);});}},this.onMouseUp=event=>{const notDragging=this.props.state!=="dragging"||!this.state.dragging;if(notDragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:false});this.unbindMouseMoveUp();this.props.onMouseUp();}};}}Draggable.contextType=PerseusI18nContext;Draggable.defaultProps={includePadding:true,type:"static",linterContext:PerseusLinter.linterContextDefault};class Sortable extends React.Component{static itemsFromProps(props){const state=props.disabled?"disabled":"static";return props.options.map((option,i)=>{return {option:option,key:i,state,width:0,height:0}})}static clearItemMeasurements(items){return items.map(item=>{return {...item,width:0,height:0}})}UNSAFE_componentWillReceiveProps(nextProps){const prevProps=this.props;if(!_.isEqual(nextProps.options,prevProps.options)){this.setState({items:Sortable.itemsFromProps(nextProps)});}else if(nextProps.layout!==prevProps.layout||nextProps.padding!==prevProps.padding||nextProps.disabled!==prevProps.disabled||!_.isEqual(nextProps.constraints,prevProps.constraints)){this.setState({items:Sortable.clearItemMeasurements(this.state.items)});}}componentDidUpdate(){if(this.state.items.length&&!this.state.items[0].width&&!this.state.items[0].height){setTimeout(()=>{this.measureItems();},0);}}measureItems(){let items=[...this.state.items];const $items=items.map(item=>{return $(ReactDOM__default.findDOMNode(this.refs[item.key]))});const widths=_.invoke($items,"outerWidth");const heights=_.invoke($items,"outerHeight");const{constraints,layout}=this.props;let syncWidth=null;if(constraints?.width){syncWidth=Math.max(...widths,constraints.width);}else if(layout==="vertical"){syncWidth=Math.max(...widths);}let syncHeight=null;if(constraints?.height){syncHeight=Math.max(...heights,constraints.height);}else if(layout==="horizontal"){syncHeight=Math.max(...heights);}items=items.map(function(item,i){item.width=syncWidth||widths[i];item.height=syncHeight||heights[i];return item});this.setState({items},()=>{this.props.onMeasure?.({widths:widths,heights:heights});});}onMouseDown(key){const items=this.state.items.map(function(item){if(item.key===key){item.state="dragging";}return item});this.setState({items:items});}moveOptionToIndex(option,index){const{items}=this.state;if(index<0||index>items.length){throw new Error(`index ${index} out of bounds`)}const nextItems=[...items];const item=items.filter(item=>{return item.option===option})[0];if(item==null){throw new Error(`option ${option} not found`)}const currentIndex=items.findIndex(i=>{return i.key===item.key});nextItems.splice(currentIndex,1);nextItems.splice(index,0,item);this.setState({items:nextItems},()=>{this.props.onChange?.({});});}onMouseMove(key){const $draggable=$(ReactDOM__default.findDOMNode(this.refs[key]));const $sortable=$(ReactDOM__default.findDOMNode(this));const items=[...this.state.items];const item=this.state.items.find(item=>item.key===key);const margin=this.props.margin||0;const currentIndex=items.indexOf(item);let newIndex=0;items.splice(currentIndex,1);if(this.props.layout==="horizontal"){const midWidth=$draggable.offset().left-$sortable.offset().left;let sumWidth=0;let cardWidth;items.forEach(function(item){cardWidth=item.width;if(midWidth>sumWidth+cardWidth/2){newIndex+=1;}sumWidth+=cardWidth+margin;});}else {const midHeight=$draggable.offset().top-$sortable.offset().top;let sumHeight=0;let cardHeight;items.forEach(function(item){cardHeight=item.height;if(midHeight>sumHeight+cardHeight/2){newIndex+=1;}sumHeight+=cardHeight+margin;});}if(newIndex!==currentIndex){items.splice(newIndex,0,item);this.setState({items:items});}}onMouseUp(key){const nextAnimationFrame=requestAnimationFrame(()=>{const items=this.state.items.map(item=>{if(item.key===key){item.state="animating";const $placeholder=$(ReactDOM__default.findDOMNode(this.refs["placeholder_"+key]));const position=$placeholder.position();const endPosition=addOffsetParentScroll($placeholder,position);item.endPosition=endPosition;}return item},this);this.setState({items:items},()=>{this.props.onChange?.({});});});this.animationFrameRequest=nextAnimationFrame;}onAnimationEnd(key){const items=this.state.items.map(function(item){if(item.key===key){item.state="static";}return item});this.setState({items:items});}getOptions(){return this.state.items.map(item=>item.option)}render(){if(this.props.waitForTexRendererToLoad&&!this.state.texRendererLoaded){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CircularSpinner,{}),jsxRuntimeExports.jsx("div",{style:{display:"none"},children:jsxRuntimeExports.jsx(TeX,{onRender:()=>this.setState({texRendererLoaded:true}),children:"1"})})]})}const cards=[];const{layout}=this.props;const className=css(styles$8.sortable)+" perseus-sortable";const syncWidth=this.props.constraints?.width||layout==="vertical";const syncHeight=this.props.constraints?.height||layout==="horizontal";this.state.items.forEach((item,i,items)=>{const isLast=i===items.length-1;const isStatic=item.state==="static"||item.state==="disabled";let margin;if(this.props.layout==="horizontal"){margin="0 "+this.props.margin+"px 0 0";}else if(this.props.layout==="vertical"){margin="0 0 "+this.props.margin+"px 0";}cards.push(jsxRuntimeExports.jsx(Draggable,{content:item.option,state:item.state,ref:item.key,width:syncWidth?item.width:undefined,height:syncHeight?item.height:undefined,layout:layout,includePadding:this.props.padding,margin:isLast&&isStatic?0:margin,endPosition:item.endPosition,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"sortable"),onRender:this.remeasureItems,onMouseDown:()=>this.onMouseDown(item.key),onMouseMove:()=>this.onMouseMove(item.key),onMouseUp:()=>this.onMouseUp(item.key),onTouchMove:()=>this.onMouseMove(item.key),onTouchEnd:()=>this.onMouseUp(item.key),onTouchCancel:()=>this.onMouseUp(item.key),onAnimationEnd:()=>this.onAnimationEnd(item.key)},item.key));if(item.state==="dragging"||item.state==="animating"){cards.push(jsxRuntimeExports.jsx(Placeholder,{ref:"placeholder_"+item.key,width:item.width,height:item.height,layout:layout,margin:isLast?0:margin},"placeholder_"+item.key));}},this);return jsxRuntimeExports.jsx("ul",{className:className,children:cards})}constructor(props){super(props),this.remeasureItems=_.debounce(()=>{this.setState({items:Sortable.clearItemMeasurements(this.state.items)});},20);this.state={items:Sortable.itemsFromProps(this.props),texRendererLoaded:false};}}Sortable.defaultProps={layout:"horizontal",padding:true,disabled:false,constraints:{},onMeasure:function(){},margin:5,onChange:function(){},linterContext:PerseusLinter.linterContextDefault,waitForTexRendererToLoad:true};const styles$8=StyleSheet.create({sortable:{boxSizing:"border-box",float:"left",padding:0,margin:0},card:{boxSizing:"border-box",background:semanticColor.core.background.base.default,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderRadius:4,cursor:"pointer",minWidth:25,minHeight:44,padding:10,listStyleType:"none",userSelect:"none",touchAction:"none"},placeholder:{background:semanticColor.core.background.neutral.subtle,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`},draggable:{textAlign:"center"},horizontalCard:{float:"left",cursor:"ew-resize"},verticalCard:{maxWidth:"100%",cursor:"ns-resize"},unpaddedCard:{padding:0},dragging:{background:semanticColor.core.background.instructive.subtle,border:`${border$1.width.thin} solid ${semanticColor.core.border.instructive.default}`,opacity:.8},disabled:{backgroundColor:"inherit",border:`${border$1.width.thin} solid ${semanticColor.core.border.disabled.subtle}`,cursor:"default"}});
|
|
2066
|
+
const addOffsetParentScroll=($el,position)=>{const $offsetParent=$el.offsetParent();return {top:position.top+$offsetParent.scrollTop(),left:position.left+$offsetParent.scrollLeft()}};class Placeholder extends React.Component{render(){const{layout}=this.props;const className=css(styles$8.card,styles$8.placeholder,layout==="horizontal"&&styles$8.horizontalCard);const style={width:this.props.width,height:this.props.height};if(this.props.margin!=null){style.margin=this.props.margin;}return jsxRuntimeExports.jsx("li",{className:className,style:style})}}class Draggable extends React.Component{componentDidMount(){this._mounted=true;this.isMouseMoveUpBound=false;document.addEventListener("touchmove",this.onMouseMove,Util.supportsPassiveEvents()?{passive:false}:false);}componentDidUpdate(prevProps){if(this.props.state===prevProps.state){return}if(this.props.state==="animating"&&this.props.endPosition){const current=this.getCurrentPosition();const duration=15*Math.sqrt(Math.sqrt(Math.pow(this.props.endPosition.left-current.left,2)+Math.pow(this.props.endPosition.top-current.top,2)));$(ReactDOM__default.findDOMNode(this)).animate(this.props.endPosition,{duration:Math.max(duration,1),complete:this.props.onAnimationEnd});}else if(this.props.state==="static"){$(ReactDOM__default.findDOMNode(this)).finish();}}componentWillUnmount(){this._mounted=false;if(this.isMouseMoveUpBound){this.unbindMouseMoveUp();}if(this.animationFrameRequest){cancelAnimationFrame(this.animationFrameRequest);}document.removeEventListener("touchmove",this.onMouseMove);}render(){const{includePadding,layout,state:type}=this.props;let className=css(styles$8.card,styles$8.draggable,layout==="horizontal"&&styles$8.horizontalCard,layout==="vertical"&&styles$8.verticalCard,type==="dragging"&&styles$8.dragging,type==="disabled"&&styles$8.disabled,!includePadding&&styles$8.unpaddedCard)+" "+"perseus-sortable-draggable";if(!includePadding){className+=" perseus-sortable-draggable-unpadded";}const style={position:"static"};if(this.props.state==="dragging"||this.props.state==="animating"){Object.assign(style,{position:"absolute"},this.getCurrentPosition());}if(this.props.width){style.width=this.props.width+1;}if(this.props.height){style.height=this.props.height;}if(this.props.margin!=null){style.margin=this.props.margin;}return jsxRuntimeExports.jsx("li",{className:className,style:style,onMouseDown:this.onMouseDown,onTouchStart:this.onMouseDown,onTouchMove:this.onMouseMove,onTouchEnd:this.onMouseUp,onTouchCancel:this.onMouseUp,children:jsxRuntimeExports.jsx(Renderer,{content:this.props.content,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"draggable"),onRender:this.props.onRender,strings:this.context.strings})})}constructor(...args){super(...args),this.animationFrameRequest=null,this.state={startPosition:{left:0,top:0},startMouse:{left:0,top:0},mouse:{left:0,top:0},dragging:false},this.getCurrentPosition=()=>{return {left:this.state.startPosition.left+this.state.mouse.left-this.state.startMouse.left,top:this.state.startPosition.top+this.state.mouse.top-this.state.startMouse.top}},this.bindMouseMoveUp=()=>{this.isMouseMoveUpBound=true;$(document).on("mousemove",this.onMouseMove);$(document).on("mouseup",this.onMouseUp);},this.unbindMouseMoveUp=()=>{this.isMouseMoveUpBound=false;$(document).off("mousemove",this.onMouseMove);$(document).off("mouseup",this.onMouseUp);},this.onMouseDown=event=>{if(this.props.state!=="static"){return}if(!(event.button===0||event.touches!=null&&event.touches.length===1)){return}event.preventDefault();const loc=Util.extractPointerLocation(event);this.animationFrameRequest=requestAnimationFrame(()=>{const $el=$(ReactDOM__default.findDOMNode(this));const position=$el.position();const startPosition=addOffsetParentScroll($el,position);if(loc&&this._mounted){this.setState({startPosition,startMouse:loc,mouse:loc,dragging:true},function(){this.bindMouseMoveUp();this.props.onMouseDown();});}});},this.onMouseMove=event=>{const notDragging=this.props.state!=="dragging"||!this.state.dragging;if(notDragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.animationFrameRequest=requestAnimationFrame(()=>{this.setState({mouse:loc},this.props.onMouseMove);});}},this.onMouseUp=event=>{const notDragging=this.props.state!=="dragging"||!this.state.dragging;if(notDragging){return}event.preventDefault();const loc=Util.extractPointerLocation(event);if(loc){this.setState({dragging:false});this.unbindMouseMoveUp();this.props.onMouseUp();}};}}Draggable.contextType=PerseusI18nContext;Draggable.defaultProps={includePadding:true,type:"static",linterContext:PerseusLinter.linterContextDefault};class Sortable extends React.Component{static itemsFromProps(props){const state=props.disabled?"disabled":"static";return props.options.map((option,i)=>{return {option:option,key:i,state,width:0,height:0}})}static clearItemMeasurements(items){return items.map(item=>{return {...item,width:0,height:0}})}UNSAFE_componentWillReceiveProps(nextProps){const prevProps=this.props;if(!_.isEqual(nextProps.options,prevProps.options)){this.setState({items:Sortable.itemsFromProps(nextProps)});}else if(nextProps.layout!==prevProps.layout||nextProps.padding!==prevProps.padding||nextProps.disabled!==prevProps.disabled||!_.isEqual(nextProps.constraints,prevProps.constraints)){this.setState({items:Sortable.clearItemMeasurements(this.state.items)});}}componentDidUpdate(){if(this.state.items.length&&!this.state.items[0].width&&!this.state.items[0].height){setTimeout(()=>{this.measureItems();},0);}}measureItems(){let items=[...this.state.items];const $items=items.map(item=>{return $(ReactDOM__default.findDOMNode(this.refs[item.key]))});const widths=_.invoke($items,"outerWidth");const heights=_.invoke($items,"outerHeight");const{constraints,layout}=this.props;let syncWidth=null;if(constraints?.width){syncWidth=Math.max(...widths,constraints.width);}else if(layout==="vertical"){syncWidth=Math.max(...widths);}let syncHeight=null;if(constraints?.height){syncHeight=Math.max(...heights,constraints.height);}else if(layout==="horizontal"){syncHeight=Math.max(...heights);}items=items.map(function(item,i){item.width=syncWidth||widths[i];item.height=syncHeight||heights[i];return item});this.setState({items},()=>{this.props.onMeasure?.({widths:widths,heights:heights});});}onMouseDown(key){const items=this.state.items.map(function(item){if(item.key===key){item.state="dragging";}return item});this.setState({items:items});}moveOptionToIndex(option,index){const{items}=this.state;if(index<0||index>items.length){throw new Error(`index ${index} out of bounds`)}const nextItems=[...items];const item=items.filter(item=>{return item.option===option})[0];if(item==null){throw new Error(`option ${option} not found`)}const currentIndex=items.findIndex(i=>{return i.key===item.key});nextItems.splice(currentIndex,1);nextItems.splice(index,0,item);this.setState({items:nextItems},()=>{this.props.onChange?.({});});}onMouseMove(key){const $draggable=$(ReactDOM__default.findDOMNode(this.refs[key]));const $sortable=$(ReactDOM__default.findDOMNode(this));const items=[...this.state.items];const item=this.state.items.find(item=>item.key===key);const margin=this.props.margin||0;const currentIndex=items.indexOf(item);let newIndex=0;items.splice(currentIndex,1);if(this.props.layout==="horizontal"){const midWidth=$draggable.offset().left-$sortable.offset().left;let sumWidth=0;let cardWidth;items.forEach(function(item){cardWidth=item.width;if(midWidth>sumWidth+cardWidth/2){newIndex+=1;}sumWidth+=cardWidth+margin;});}else {const midHeight=$draggable.offset().top-$sortable.offset().top;let sumHeight=0;let cardHeight;items.forEach(function(item){cardHeight=item.height;if(midHeight>sumHeight+cardHeight/2){newIndex+=1;}sumHeight+=cardHeight+margin;});}if(newIndex!==currentIndex){items.splice(newIndex,0,item);this.setState({items:items});}}onMouseUp(key){const nextAnimationFrame=requestAnimationFrame(()=>{const items=this.state.items.map(item=>{if(item.key===key){item.state="animating";const $placeholder=$(ReactDOM__default.findDOMNode(this.refs["placeholder_"+key]));const position=$placeholder.position();const endPosition=addOffsetParentScroll($placeholder,position);item.endPosition=endPosition;}return item},this);this.setState({items:items},()=>{this.props.onChange?.({});});});this.animationFrameRequest=nextAnimationFrame;}onAnimationEnd(key){const items=this.state.items.map(function(item){if(item.key===key){item.state="static";}return item});this.setState({items:items});}getOptions(){return this.state.items.map(item=>item.option)}render(){if(this.props.waitForTexRendererToLoad&&!this.state.texRendererLoaded){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CircularSpinner,{}),jsxRuntimeExports.jsx("div",{style:{display:"none"},children:jsxRuntimeExports.jsx(TeX,{onRender:()=>this.setState({texRendererLoaded:true}),children:"1"})})]})}const cards=[];const{layout}=this.props;const className=css(styles$8.sortable)+" perseus-sortable";const syncWidth=this.props.constraints?.width||layout==="vertical";const syncHeight=this.props.constraints?.height||layout==="horizontal";this.state.items.forEach((item,i,items)=>{const isLast=i===items.length-1;const isStatic=item.state==="static"||item.state==="disabled";let margin;if(this.props.layout==="horizontal"){margin="0 "+this.props.margin+"px 0 0";}else if(this.props.layout==="vertical"){margin="0 0 "+this.props.margin+"px 0";}cards.push(jsxRuntimeExports.jsx(Draggable,{content:item.option,state:item.state,ref:item.key,width:syncWidth?item.width:undefined,height:syncHeight?item.height:undefined,layout:layout,includePadding:this.props.padding,margin:isLast&&isStatic?0:margin,endPosition:item.endPosition,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"sortable"),onRender:this.remeasureItems,onMouseDown:()=>this.onMouseDown(item.key),onMouseMove:()=>this.onMouseMove(item.key),onMouseUp:()=>this.onMouseUp(item.key),onTouchMove:()=>this.onMouseMove(item.key),onTouchEnd:()=>this.onMouseUp(item.key),onTouchCancel:()=>this.onMouseUp(item.key),onAnimationEnd:()=>this.onAnimationEnd(item.key)},item.key));if(item.state==="dragging"||item.state==="animating"){cards.push(jsxRuntimeExports.jsx(Placeholder,{ref:"placeholder_"+item.key,width:item.width,height:item.height,layout:layout,margin:isLast?0:margin},"placeholder_"+item.key));}},this);return jsxRuntimeExports.jsx("ul",{className:className,children:cards})}constructor(props){super(props),this.remeasureItems=_.debounce(()=>{this.setState({items:Sortable.clearItemMeasurements(this.state.items)});},20);this.state={items:Sortable.itemsFromProps(this.props),texRendererLoaded:false};}}Sortable.defaultProps={layout:"horizontal",padding:true,disabled:false,constraints:{},onMeasure:function(){},margin:5,onChange:function(){},linterContext:PerseusLinter.linterContextDefault,waitForTexRendererToLoad:true};const styles$8=StyleSheet.create({sortable:{boxSizing:"border-box",float:"inline-start",padding:0,margin:0},card:{boxSizing:"border-box",background:semanticColor.core.background.base.default,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`,borderRadius:4,cursor:"pointer",minInlineSize:25,minBlockSize:44,padding:10,listStyleType:"none",userSelect:"none",touchAction:"none"},placeholder:{background:semanticColor.core.background.neutral.subtle,border:`${border$1.width.thin} solid ${semanticColor.core.border.neutral.subtle}`},draggable:{textAlign:"center"},horizontalCard:{float:"inline-start",cursor:"ew-resize"},verticalCard:{maxInlineSize:"100%",cursor:"ns-resize"},unpaddedCard:{padding:0},dragging:{background:semanticColor.core.background.instructive.subtle,border:`${border$1.width.thin} solid ${semanticColor.core.border.instructive.default}`,opacity:.8},disabled:{backgroundColor:"inherit",border:`${border$1.width.thin} solid ${semanticColor.core.border.disabled.subtle}`,cursor:"default"}});
|
|
2067
2067
|
|
|
2068
2068
|
const getPromptJSON$9=widgetData=>{const{userInput}=widgetData;return {type:"matcher",options:{labels:widgetData.labels,left:widgetData.left,right:widgetData.right,orderMatters:widgetData.orderMatters},userInput:{left:userInput.left,right:userInput.right}}};
|
|
2069
2069
|
|
|
2070
|
-
const HACKY_CSS_CLASSNAME="perseus-widget-matcher";const Matcher=forwardRef(function Matcher(props,ref){const{strings}=usePerseusI18n();const leftSortable=useRef(null);const rightSortable=useRef(null);const[leftHeight,setLeftHeight]=useState(0);const[rightHeight,setRightHeight]=useState(0);const[texRendererLoaded,setTexRendererLoaded]=useState(false);useOnMountEffect(()=>{props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"matcher",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$9(props),moveLeftOptionToIndex:(option,index)=>{leftSortable.current?.moveOptionToIndex(option,index);},moveRightOptionToIndex:(option,index)=>{rightSortable.current?.moveOptionToIndex(option,index);}}));function getUserInputFromSortable(){if(!texRendererLoaded){return {left:[],right:[]}}return {left:leftSortable.current?.getOptions()??[],right:rightSortable.current?.getOptions()??[]}}function changeAndTrack(){props.handleUserInput(getUserInputFromSortable());props.trackInteraction();}if(!texRendererLoaded){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CircularSpinner,{}),jsxRuntimeExports.jsx("div",{style:{display:"none"},children:jsxRuntimeExports.jsx(TeX,{onRender:()=>setTexRendererLoaded(true),children:"1"})})]})}const showLabels=props.labels.some(isTruthy);const constraints={height:Math.max(leftHeight,rightHeight)};const cellMarginPx=props.apiOptions.isMobile?8:5;return jsxRuntimeExports.jsx("table",{className:css(styles$7.widget)+" "+HACKY_CSS_CLASSNAME,children:jsxRuntimeExports.jsxs("tbody",{children:[showLabels&&jsxRuntimeExports.jsxs("tr",{className:css(styles$7.row),children:[jsxRuntimeExports.jsx("th",{className:css(styles$7.column,styles$7.columnLabel),children:jsxRuntimeExports.jsx(Renderer,{content:props.labels[0]||"...",linterContext:props.linterContext,strings:strings})}),jsxRuntimeExports.jsx("th",{className:css(styles$7.column,styles$7.columnRight,styles$7.columnLabel),children:jsxRuntimeExports.jsx(Renderer,{content:props.labels[1]||"...",linterContext:props.linterContext,strings:strings})})]}),jsxRuntimeExports.jsxs("tr",{className:css(styles$7.row),children:[jsxRuntimeExports.jsx("td",{className:css(styles$7.column),children:jsxRuntimeExports.jsx(Sortable,{options:props.userInput.left,layout:"vertical",padding:props.padding,disabled:!props.orderMatters,constraints:constraints,onMeasure:dimensions=>setLeftHeight(Math.max(...dimensions.heights)),onChange:changeAndTrack,margin:cellMarginPx,linterContext:props.linterContext,ref:leftSortable})}),jsxRuntimeExports.jsx("td",{className:css(styles$7.column,styles$7.columnRight),children:jsxRuntimeExports.jsx(Sortable,{options:props.userInput.right,layout:"vertical",padding:props.padding,constraints:constraints,onMeasure:dimensions=>setRightHeight(Math.max(...dimensions.heights)),onChange:changeAndTrack,margin:cellMarginPx,linterContext:props.linterContext,ref:rightSortable})})]})]})})});function getStartUserInput$6(options,problemNum){const shuffled=shuffleMatcher(options,problemNum);return shuffled}function getUserInputFromSerializedState$6(serializedState){return {left:serializedState.left,right:serializedState.right}}const WrappedMatcher=withDependencies(Matcher);var Matcher$1 = {name:"matcher",displayName:"Matcher (two column)",hidden:true,widget:WrappedMatcher,isLintable:true,getStartUserInput: getStartUserInput$6,getUserInputFromSerializedState: getUserInputFromSerializedState$6};const padding=5;const border=`var(--wb-border-width-thin) solid var(--wb-semanticColor-core-border-neutral-strong)`;const styles$7=StyleSheet.create({widget:{
|
|
2070
|
+
const HACKY_CSS_CLASSNAME="perseus-widget-matcher";const Matcher=forwardRef(function Matcher(props,ref){const{strings}=usePerseusI18n();const leftSortable=useRef(null);const rightSortable=useRef(null);const[leftHeight,setLeftHeight]=useState(0);const[rightHeight,setRightHeight]=useState(0);const[texRendererLoaded,setTexRendererLoaded]=useState(false);useOnMountEffect(()=>{props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"matcher",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON:()=>getPromptJSON$9(props),moveLeftOptionToIndex:(option,index)=>{leftSortable.current?.moveOptionToIndex(option,index);},moveRightOptionToIndex:(option,index)=>{rightSortable.current?.moveOptionToIndex(option,index);}}));function getUserInputFromSortable(){if(!texRendererLoaded){return {left:[],right:[]}}return {left:leftSortable.current?.getOptions()??[],right:rightSortable.current?.getOptions()??[]}}function changeAndTrack(){props.handleUserInput(getUserInputFromSortable());props.trackInteraction();}if(!texRendererLoaded){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CircularSpinner,{}),jsxRuntimeExports.jsx("div",{style:{display:"none"},children:jsxRuntimeExports.jsx(TeX,{onRender:()=>setTexRendererLoaded(true),children:"1"})})]})}const showLabels=props.labels.some(isTruthy);const constraints={height:Math.max(leftHeight,rightHeight)};const cellMarginPx=props.apiOptions.isMobile?8:5;return jsxRuntimeExports.jsx("table",{className:css(styles$7.widget)+" "+HACKY_CSS_CLASSNAME,children:jsxRuntimeExports.jsxs("tbody",{children:[showLabels&&jsxRuntimeExports.jsxs("tr",{className:css(styles$7.row),children:[jsxRuntimeExports.jsx("th",{className:css(styles$7.column,styles$7.columnLabel),children:jsxRuntimeExports.jsx(Renderer,{content:props.labels[0]||"...",linterContext:props.linterContext,strings:strings})}),jsxRuntimeExports.jsx("th",{className:css(styles$7.column,styles$7.columnRight,styles$7.columnLabel),children:jsxRuntimeExports.jsx(Renderer,{content:props.labels[1]||"...",linterContext:props.linterContext,strings:strings})})]}),jsxRuntimeExports.jsxs("tr",{className:css(styles$7.row),children:[jsxRuntimeExports.jsx("td",{className:css(styles$7.column),children:jsxRuntimeExports.jsx(Sortable,{options:props.userInput.left,layout:"vertical",padding:props.padding,disabled:!props.orderMatters,constraints:constraints,onMeasure:dimensions=>setLeftHeight(Math.max(...dimensions.heights)),onChange:changeAndTrack,margin:cellMarginPx,linterContext:props.linterContext,ref:leftSortable})}),jsxRuntimeExports.jsx("td",{className:css(styles$7.column,styles$7.columnRight),children:jsxRuntimeExports.jsx(Sortable,{options:props.userInput.right,layout:"vertical",padding:props.padding,constraints:constraints,onMeasure:dimensions=>setRightHeight(Math.max(...dimensions.heights)),onChange:changeAndTrack,margin:cellMarginPx,linterContext:props.linterContext,ref:rightSortable})})]})]})})});function getStartUserInput$6(options,problemNum){const shuffled=shuffleMatcher(options,problemNum);return shuffled}function getUserInputFromSerializedState$6(serializedState){return {left:serializedState.left,right:serializedState.right}}const WrappedMatcher=withDependencies(Matcher);var Matcher$1 = {name:"matcher",displayName:"Matcher (two column)",hidden:true,widget:WrappedMatcher,isLintable:true,getStartUserInput: getStartUserInput$6,getUserInputFromSerializedState: getUserInputFromSerializedState$6};const padding=5;const border=`var(--wb-border-width-thin) solid var(--wb-semanticColor-core-border-neutral-strong)`;const styles$7=StyleSheet.create({widget:{paddingBlockStart:padding,maxInlineSize:"100%",minInlineSize:"auto"},row:{border:0},column:{padding:0,border:0},columnRight:{borderInlineStart:border},columnLabel:{fontWeight:"inherit",borderBlockEnd:border,padding:`0 ${padding}px ${padding}px ${padding}px`,textAlign:"center"}});
|
|
2071
2071
|
|
|
2072
2072
|
const getPromptJSON$8=widgetData=>{return {type:"matrix",options:{height:widgetData.matrixBoardSize[0],width:widgetData.matrixBoardSize[1]},userInput:{answerRows:widgetData.userInput.answers}}};
|
|
2073
2073
|
|
|
@@ -2087,7 +2087,7 @@ class PlaceholderCard extends React.Component{render(){return jsxRuntimeExports.
|
|
|
2087
2087
|
|
|
2088
2088
|
const getPromptJSON$4=()=>{return getUnsupportedPromptJSON("phet-simulation")};
|
|
2089
2089
|
|
|
2090
|
-
const isFullscreenApiSupported=()=>{if(typeof document==="undefined"){return false}const doc=document;return Boolean(doc.fullscreenEnabled||doc.webkitFullscreenEnabled)};const MOBILE_APP_BOTTOM_BAR_HEIGHT=66;class PhetSimulation extends React.Component{async componentDidMount(){await this.updateSimState(this.props.url);}async componentDidUpdate(prevProps){if(prevProps.url!==this.props.url){await this.updateSimState(this.props.url);}}getLocale(){switch(this.context.locale){case "pt-pt":return "pt";case "zh-hans":return "zh_CN";case "zh-hant":return "zh_TW";case "fa-af":return "fa_DA";default:return this.context.locale}}getPromptJSON(){return getPromptJSON$4()}async updateSimState(urlString){const url=makeSafeUrl(urlString,this.getLocale(),"https://phet.colorado.edu");if(url===null){this.displayLoadFailure();return}const response=await fetch(url);if(!response.ok){this.displayLoadFailure();return}const showLocaleWarning=await this.showLocaleWarning(url);this.setState({url:url,banner:showLocaleWarning?{message:this.context.strings.simulationLocaleWarning,kind:"warning"}:null});}async showLocaleWarning(url){if(!url){return false}const phetRegex=/https:\/\/phet\.colorado\.edu\/sims\/html\/([a-zA-Z0-9-]+)\/.*/g;const match=phetRegex.exec(url.toString());if(match===null){return false}const simName=match[1];const response=await fetch(`https://phet.colorado.edu/sims/html/${simName}/latest/string-map.json`);if(!response.ok){return false}let responseJson;try{responseJson=await response.json();}catch{return false}const locales=Object.keys(responseJson);const baseLocale=this.getLocale().split("_")[0];for(const l of locales){if(baseLocale===l.split("_")[0]){return false}}return true}renderCornerButton(url,isMobileApp){if(isMobileApp||isFullscreenApiSupported()){return jsxRuntimeExports.jsx(IconButton,{icon:cornersOutIcon,onClick:isMobileApp?this.toggleFullScreen:this.requestIframeFullscreen,kind:"secondary",actionType:"neutral","aria-label":this.context.strings.fullscreen,style:styles$6.cornerButton})}return jsxRuntimeExports.jsx(IconButton,{icon:arrowSquareOutIcon,href:url.toString(),target:"_blank",kind:"secondary",actionType:"neutral","aria-label":this.context.strings.openInNewTab,style:styles$6.cornerButton})}render(){const{isFullScreen,banner,url}=this.state;const{isMobileApp}=this.props.apiOptions;const isMobileAppFullscreen=isFullScreen&&isMobileApp;const containerStyle=isMobileAppFullscreen?{...styles$6.appFullScreenWidgetContainer}:styles$6.widgetContainer;const iframeContainerStyle=isMobileAppFullscreen?styles$6.appFullScreenIframeContainer:styles$6.iframeContainer;const sandboxProperties="allow-same-origin allow-scripts";return jsxRuntimeExports.jsxs(View,{style:containerStyle,children:[banner!==null&&jsxRuntimeExports.jsx(View,{style:{
|
|
2090
|
+
const isFullscreenApiSupported=()=>{if(typeof document==="undefined"){return false}const doc=document;return Boolean(doc.fullscreenEnabled||doc.webkitFullscreenEnabled)};const MOBILE_APP_BOTTOM_BAR_HEIGHT=66;class PhetSimulation extends React.Component{async componentDidMount(){await this.updateSimState(this.props.url);}async componentDidUpdate(prevProps){if(prevProps.url!==this.props.url){await this.updateSimState(this.props.url);}}getLocale(){switch(this.context.locale){case "pt-pt":return "pt";case "zh-hans":return "zh_CN";case "zh-hant":return "zh_TW";case "fa-af":return "fa_DA";default:return this.context.locale}}getPromptJSON(){return getPromptJSON$4()}async updateSimState(urlString){const url=makeSafeUrl(urlString,this.getLocale(),"https://phet.colorado.edu");if(url===null){this.displayLoadFailure();return}const response=await fetch(url);if(!response.ok){this.displayLoadFailure();return}const showLocaleWarning=await this.showLocaleWarning(url);this.setState({url:url,banner:showLocaleWarning?{message:this.context.strings.simulationLocaleWarning,kind:"warning"}:null});}async showLocaleWarning(url){if(!url){return false}const phetRegex=/https:\/\/phet\.colorado\.edu\/sims\/html\/([a-zA-Z0-9-]+)\/.*/g;const match=phetRegex.exec(url.toString());if(match===null){return false}const simName=match[1];const response=await fetch(`https://phet.colorado.edu/sims/html/${simName}/latest/string-map.json`);if(!response.ok){return false}let responseJson;try{responseJson=await response.json();}catch{return false}const locales=Object.keys(responseJson);const baseLocale=this.getLocale().split("_")[0];for(const l of locales){if(baseLocale===l.split("_")[0]){return false}}return true}renderCornerButton(url,isMobileApp){if(isMobileApp||isFullscreenApiSupported()){return jsxRuntimeExports.jsx(IconButton,{icon:cornersOutIcon,onClick:isMobileApp?this.toggleFullScreen:this.requestIframeFullscreen,kind:"secondary",actionType:"neutral","aria-label":this.context.strings.fullscreen,style:styles$6.cornerButton})}return jsxRuntimeExports.jsx(IconButton,{icon:arrowSquareOutIcon,href:url.toString(),target:"_blank",kind:"secondary",actionType:"neutral","aria-label":this.context.strings.openInNewTab,style:styles$6.cornerButton})}render(){const{isFullScreen,banner,url}=this.state;const{isMobileApp}=this.props.apiOptions;const isMobileAppFullscreen=isFullScreen&&isMobileApp;const containerStyle=isMobileAppFullscreen?{...styles$6.appFullScreenWidgetContainer}:styles$6.widgetContainer;const iframeContainerStyle=isMobileAppFullscreen?styles$6.appFullScreenIframeContainer:styles$6.iframeContainer;const sandboxProperties="allow-same-origin allow-scripts";return jsxRuntimeExports.jsxs(View,{style:containerStyle,children:[banner!==null&&jsxRuntimeExports.jsx(View,{style:{marginBlockEnd:phoneMargin},children:jsxRuntimeExports.jsx(Banner,{kind:banner.kind,text:banner.message})}),isMobileAppFullscreen&&jsxRuntimeExports.jsx(View,{style:styles$6.closeButtonContainer,children:jsxRuntimeExports.jsx(IconButton,{icon:xIcon,onClick:this.toggleFullScreen,kind:"secondary",actionType:"neutral","aria-label":this.context.strings.exitFullscreen})}),jsxRuntimeExports.jsx(View,{style:iframeContainerStyle,children:jsxRuntimeExports.jsx("iframe",{ref:this.iframeRef,title:this.props.description,sandbox:sandboxProperties,className:css(styles$6.iframeResponsive),src:url?.toString(),allow:"fullscreen"})}),url!==null&&!isMobileAppFullscreen&&this.renderCornerButton(url,isMobileApp)]})}constructor(...args){super(...args),this.iframeRef=React.createRef(),this.isWidget=true,this.state={url:null,banner:null,isFullScreen:false},this.displayLoadFailure=()=>{this.setState({url:null,banner:{message:this.context.strings.simulationLoadFail,kind:"critical"}});},this.toggleFullScreen=()=>{this.setState(prevState=>({isFullScreen:!prevState.isFullScreen}));},this.requestIframeFullscreen=()=>{const iframe=this.iframeRef.current;if(!iframe){return}if(typeof iframe.requestFullscreen==="function"){iframe.requestFullscreen().catch(()=>{});}else {iframe.webkitRequestFullscreen?.();}};}}PhetSimulation.contextType=PerseusI18nContext;const styles$6=StyleSheet.create({widgetContainer:{borderRadius:border$1.radius.radius_080,borderWidth:border$1.width.thin,borderColor:semanticColor.core.border.neutral.subtle,padding:sizing.size_160,paddingBlockEnd:0},cornerButton:{marginBlockStart:5,marginBlockEnd:5,alignSelf:"flex-end"},iframeContainer:{position:"relative",overflow:"hidden",width:"100%",paddingBlockStart:"56.25%"},iframeResponsive:{borderWidth:border$1.width.none,position:"absolute",insetBlockStart:0,insetInlineStart:0,insetBlockEnd:0,insetInlineEnd:0,width:"100%",height:"100%"},appFullScreenWidgetContainer:{position:"fixed",insetBlockStart:0,insetInlineStart:0,insetInlineEnd:0,insetBlockEnd:MOBILE_APP_BOTTOM_BAR_HEIGHT,width:"100%",height:"auto",zIndex:1e3,backgroundColor:semanticColor.core.background.base.default,display:"flex",flexDirection:"column"},appFullScreenIframeContainer:{position:"relative",overflow:"hidden",width:"100%",flex:1},closeButtonContainer:{position:"absolute",insetBlockStart:sizing.size_080,insetInlineEnd:sizing.size_080,zIndex:1001}});var PhetSimulation$1 = {name:"phet-simulation",displayName:"PhET Simulation",widget:PhetSimulation,isLintable:true};
|
|
2091
2091
|
|
|
2092
2092
|
const getPromptJSON$3=()=>{return getUnsupportedPromptJSON("plotter")};
|
|
2093
2093
|
|
|
@@ -2115,19 +2115,19 @@ var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,D
|
|
|
2115
2115
|
|
|
2116
2116
|
const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
|
|
2117
2117
|
|
|
2118
|
-
const libName="@khanacademy/perseus";const libVersion="83.0
|
|
2118
|
+
const libName="@khanacademy/perseus";const libVersion="83.1.0";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
2119
2119
|
|
|
2120
2120
|
const apiVersion={major:12,minor:0};
|
|
2121
2121
|
|
|
2122
2122
|
class ArticleRenderer extends React.Component{componentDidMount(){this._currentFocus=null;}shouldComponentUpdate(nextProps){return nextProps!==this.props}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,isArticle:true};const classes=classNames$2({"framework-perseus":true,"perseus-article":true,[ClassNames.MOBILE]:apiOptions.isMobile});const sections=this._sections().map((section,sectionIndex)=>{return jsxRuntimeExports.jsx("div",{className:"clearfix",children:jsxRuntimeExports.jsx(UserInputManager,{widgets:section.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>createElement(Renderer,{...section,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,ref:elem=>{if(elem){this.sectionRenderers[sectionIndex]=elem;}},key:sectionIndex,keypadElement:this.props.keypadElement,apiOptions:{...apiOptions,onFocusChange:(newFocusPath,oldFocusPath)=>{this._handleFocusChange(newFocusPath&&[sectionIndex].concat(newFocusPath),oldFocusPath&&[sectionIndex].concat(oldFocusPath));}},linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"article"),legacyPerseusLint:this.props.legacyPerseusLint,strings:this.context.strings})})},sectionIndex)});return jsxRuntimeExports.jsx("div",{className:classes,children:jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:sections})})}constructor(props){super(props),this.sectionRenderers=[],this._handleFocusChange=(newFocusPath,oldFocusPath)=>{if(newFocusPath){this._setCurrentFocus(newFocusPath);}else {this._onRendererBlur(oldFocusPath);}},this._setCurrentFocus=newFocusPath=>{const{keypadElement,apiOptions}=this.props;const{isMobile}=apiOptions;const prevFocusPath=this._currentFocus;this._currentFocus=newFocusPath;let didFocusInput=false;let focusedInput;if(this._currentFocus){const[sectionIndex,...focusPath]=this._currentFocus;const inputPaths=this.sectionRenderers[sectionIndex].getInputPaths();didFocusInput=inputPaths.some(inputPath=>{return Util.inputPathsEqual(inputPath,focusPath)});focusedInput=this.sectionRenderers[sectionIndex].getDOMNodeForPath(focusPath);}const{onFocusChange}=this.props.apiOptions;if(onFocusChange){setTimeout(()=>{const keypadDomNode=keypadElement?.getDOMNode();const keypadHeight=keypadDomNode&&didFocusInput?keypadDomNode.getBoundingClientRect().height:0;onFocusChange(this._currentFocus,prevFocusPath,keypadHeight,didFocusInput?focusedInput:null);},0);}if(keypadElement&&isMobile){if(didFocusInput){keypadElement.activate();}else {keypadElement.dismiss();}}},this._onRendererBlur=blurPath=>{const blurringFocusPath=this._currentFocus;if(!Util.inputPathsEqual(blurPath,blurringFocusPath)){return}setTimeout(()=>{if(Util.inputPathsEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.blur=()=>{if(this._currentFocus){const[sectionIndex,...inputPath]=this._currentFocus;this.sectionRenderers[sectionIndex].blurPath(inputPath);}},this._sections=()=>{const sections=Array.isArray(this.props.json)?this.props.json:[this.props.json];if(getDependencies().JIPT.useJIPT){const paragraphs=[];for(const section of sections){JiptParagraphs.parseToArray(section.content).forEach(paragraph=>{paragraphs.push({...section,content:paragraph});});}return paragraphs}return sections};}}ArticleRenderer.contextType=PerseusI18nContext;ArticleRenderer.defaultProps={apiOptions:ApiOptions.defaults,linterContext:PerseusLinter.linterContextDefault};
|
|
2123
2123
|
|
|
2124
|
-
class HintRenderer extends React.Component{render(){if(this.props.hint.placeholder){return jsxRuntimeExports.jsx("span",{})}const{apiOptions,className,hint,lastHint,lastRendered,pos,totalHints}=this.props;const{isMobile}=apiOptions;const classNames=classNames$2("hint",!isMobile&&"perseus-hint-renderer",isMobile&&css(styles$2.newHint),isMobile&&lastRendered&&css(styles$2.lastRenderedNewHint),lastHint&&"last-hint",lastRendered&&"last-rendered",className);const rendererApiOptions={...apiOptions,customKeypad:false};return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:classNames,tabIndex:"-1",children:[!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:"perseus-sr-only",children:this.context.strings.hintPos({pos:pos+1})}),!apiOptions.isMobile&&totalHints!=null&&pos!=null&&jsxRuntimeExports.jsx("span",{className:"perseus-hint-label",style:{display:"block",color:apiOptions.hintProgressColor},children:`${pos+1} / ${totalHints}`}),jsxRuntimeExports.jsx(UserInputManager,{widgets:hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{ref:this.rendererRef,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,widgets:hint.widgets,content:hint.content||"",images:hint.images,apiOptions:rendererApiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hint"),strings:this.context.strings})})]})})}constructor(...args){super(...args),this.rendererRef=React.createRef(),this.getSerializedState=()=>{return this.rendererRef.current?.getSerializedState()};}}HintRenderer.contextType=PerseusI18nContext;HintRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$2=StyleSheet.create({newHint:{
|
|
2124
|
+
class HintRenderer extends React.Component{render(){if(this.props.hint.placeholder){return jsxRuntimeExports.jsx("span",{})}const{apiOptions,className,hint,lastHint,lastRendered,pos,totalHints}=this.props;const{isMobile}=apiOptions;const classNames=classNames$2("hint",!isMobile&&"perseus-hint-renderer",isMobile&&css(styles$2.newHint),isMobile&&lastRendered&&css(styles$2.lastRenderedNewHint),lastHint&&"last-hint",lastRendered&&"last-rendered",className);const rendererApiOptions={...apiOptions,customKeypad:false};return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:classNames,tabIndex:"-1",children:[!apiOptions.isMobile&&jsxRuntimeExports.jsx("span",{className:"perseus-sr-only",children:this.context.strings.hintPos({pos:pos+1})}),!apiOptions.isMobile&&totalHints!=null&&pos!=null&&jsxRuntimeExports.jsx("span",{className:"perseus-hint-label",style:{display:"block",color:apiOptions.hintProgressColor},children:`${pos+1} / ${totalHints}`}),jsxRuntimeExports.jsx(UserInputManager,{widgets:hint.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>jsxRuntimeExports.jsx(Renderer,{ref:this.rendererRef,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput,widgets:hint.widgets,content:hint.content||"",images:hint.images,apiOptions:rendererApiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hint"),strings:this.context.strings})})]})})}constructor(...args){super(...args),this.rendererRef=React.createRef(),this.getSerializedState=()=>{return this.rendererRef.current?.getSerializedState()};}}HintRenderer.contextType=PerseusI18nContext;HintRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$2=StyleSheet.create({newHint:{marginBlockEnd:sizing.size_240,borderInlineStartColor:semanticColor.core.background.base.subtle,borderInlineStartStyle:"solid",borderInlineStartWidth:hintBorderWidth,[mediaQueries.lgOrSmaller]:{paddingInlineStart:hintPaddingInlineStart},[mediaQueries.smOrSmaller]:{paddingInlineStart:0},":focus":{outline:"none"}},lastRenderedNewHint:{marginBlockEnd:0,borderInlineStartColor:semanticColor.core.border.instructive.default}});
|
|
2125
2125
|
|
|
2126
|
-
class HintsRenderer extends React.Component{componentDidMount(){this._cacheHintImages();}UNSAFE_componentWillReceiveProps(nextProps){if(nextProps.hintsVisible-this.props.hintsVisible>1){this.setState({isFinalHelpPage:true});}}componentDidUpdate(prevProps,prevState){if(!_.isEqual(prevProps.hints,this.props.hints)||prevProps.hintsVisible!==this.props.hintsVisible){this._cacheHintImages();}const prevHintsVisible=prevProps.hintsVisible||0;const nextHintsVisible=this.props.hintsVisible||0;if(prevHintsVisible<nextHintsVisible&&nextHintsVisible<=this.props.hints.length&&nextHintsVisible>=0){const pos=nextHintsVisible-1;const hint=this.props.hints[pos];if(hint?.placeholder){return}try{const ref=this.refs["hintRenderer"+pos];if(ref==null){return}const domNode=ReactDOM__default.findDOMNode(ref);if(domNode&&typeof domNode.focus==="function"){domNode.focus();}}catch(e){}}}render(){const apiOptions=this.getApiOptions();const hintsVisible=this._hintsVisible();const hints=[];const isFinalHelpPage=this.state.isFinalHelpPage;this.props.hints.slice(0,hintsVisible).forEach((hint,i)=>{const lastHint=i===this.props.hints.length-1&&!/\*\*/.test(hint.content);const lastRendered=i===hintsVisible-1;const renderer=jsxRuntimeExports.jsx(HintRenderer,{dependencies:this.props.dependencies,lastHint:lastHint,lastRendered:lastRendered,hint:hint,pos:i,totalHints:this.props.hints.length,ref:"hintRenderer"+i,apiOptions:apiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hints["+i+"]")},"hintRenderer"+i);if(isFinalHelpPage){hints.push(renderer);}else {if(hint.replace&&hints.length>0){hints[hints.length-1]=renderer;}else {hints.push(renderer);}}});const{getAnotherHint}=apiOptions;const showGetAnotherHint=getAnotherHint&&hintsVisible>0&&hintsVisible<this.props.hints.length;const hintRatioCopy=`(${hintsVisible}/${this.props.hints.length})`;const classNames=classNames$2(this.props.className,apiOptions.isMobile&&hintsVisible>0&&css(styles$1.mobileHintStylesHintsRenderer));return jsxRuntimeExports.jsxs("div",{className:classNames,children:[apiOptions.isMobile&&hintsVisible>0&&jsxRuntimeExports.jsx("div",{className:css(styles$1.mobileHintStylesHintTitle,sharedStyles.responsiveLabel),children:this.context.strings.hints}),hints,showGetAnotherHint&&jsxRuntimeExports.jsx(Button,{rel:"button",kind:"tertiary",startIcon:plus,onClick:evt=>{evt.preventDefault();evt.stopPropagation();if(getAnotherHint){getAnotherHint();}},children:this.context.strings.getAnotherHint+" "+hintRatioCopy})]})}constructor(...args){super(...args),this.state={isFinalHelpPage:false},this._hintsVisible=()=>{if(this.props.hintsVisible==null||this.props.hintsVisible===-1){return this.props.hints.length}return this.props.hintsVisible},this._cacheImagesInHint=hint=>{_.each(hint.images,(data,src)=>{const image=new Image;image.src=Util.getRealImageUrl(src);});},this._cacheHintImages=()=>{if(this._hintsVisible()>0){_.each(this.props.hints,this._cacheImagesInHint);}else if(this.props.hints.length>0){this._cacheImagesInHint(this.props.hints[0]);}},this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions,readOnly:false}},this.getSerializedState=()=>{return _.times(this._hintsVisible(),i=>{return this.refs["hintRenderer"+i].getSerializedState()})};}}HintsRenderer.contextType=PerseusI18nContext;HintsRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$1=StyleSheet.create({mobileHintStylesHintsRenderer:{
|
|
2126
|
+
class HintsRenderer extends React.Component{componentDidMount(){this._cacheHintImages();}UNSAFE_componentWillReceiveProps(nextProps){if(nextProps.hintsVisible-this.props.hintsVisible>1){this.setState({isFinalHelpPage:true});}}componentDidUpdate(prevProps,prevState){if(!_.isEqual(prevProps.hints,this.props.hints)||prevProps.hintsVisible!==this.props.hintsVisible){this._cacheHintImages();}const prevHintsVisible=prevProps.hintsVisible||0;const nextHintsVisible=this.props.hintsVisible||0;if(prevHintsVisible<nextHintsVisible&&nextHintsVisible<=this.props.hints.length&&nextHintsVisible>=0){const pos=nextHintsVisible-1;const hint=this.props.hints[pos];if(hint?.placeholder){return}try{const ref=this.refs["hintRenderer"+pos];if(ref==null){return}const domNode=ReactDOM__default.findDOMNode(ref);if(domNode&&typeof domNode.focus==="function"){domNode.focus();}}catch(e){}}}render(){const apiOptions=this.getApiOptions();const hintsVisible=this._hintsVisible();const hints=[];const isFinalHelpPage=this.state.isFinalHelpPage;this.props.hints.slice(0,hintsVisible).forEach((hint,i)=>{const lastHint=i===this.props.hints.length-1&&!/\*\*/.test(hint.content);const lastRendered=i===hintsVisible-1;const renderer=jsxRuntimeExports.jsx(HintRenderer,{dependencies:this.props.dependencies,lastHint:lastHint,lastRendered:lastRendered,hint:hint,pos:i,totalHints:this.props.hints.length,ref:"hintRenderer"+i,apiOptions:apiOptions,findExternalWidgets:this.props.findExternalWidgets,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hints["+i+"]")},"hintRenderer"+i);if(isFinalHelpPage){hints.push(renderer);}else {if(hint.replace&&hints.length>0){hints[hints.length-1]=renderer;}else {hints.push(renderer);}}});const{getAnotherHint}=apiOptions;const showGetAnotherHint=getAnotherHint&&hintsVisible>0&&hintsVisible<this.props.hints.length;const hintRatioCopy=`(${hintsVisible}/${this.props.hints.length})`;const classNames=classNames$2(this.props.className,apiOptions.isMobile&&hintsVisible>0&&css(styles$1.mobileHintStylesHintsRenderer));return jsxRuntimeExports.jsxs("div",{className:classNames,children:[apiOptions.isMobile&&hintsVisible>0&&jsxRuntimeExports.jsx("div",{className:css(styles$1.mobileHintStylesHintTitle,sharedStyles.responsiveLabel),children:this.context.strings.hints}),hints,showGetAnotherHint&&jsxRuntimeExports.jsx(Button,{rel:"button",kind:"tertiary",startIcon:plus,onClick:evt=>{evt.preventDefault();evt.stopPropagation();if(getAnotherHint){getAnotherHint();}},children:this.context.strings.getAnotherHint+" "+hintRatioCopy})]})}constructor(...args){super(...args),this.state={isFinalHelpPage:false},this._hintsVisible=()=>{if(this.props.hintsVisible==null||this.props.hintsVisible===-1){return this.props.hints.length}return this.props.hintsVisible},this._cacheImagesInHint=hint=>{_.each(hint.images,(data,src)=>{const image=new Image;image.src=Util.getRealImageUrl(src);});},this._cacheHintImages=()=>{if(this._hintsVisible()>0){_.each(this.props.hints,this._cacheImagesInHint);}else if(this.props.hints.length>0){this._cacheImagesInHint(this.props.hints[0]);}},this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions,readOnly:false}},this.getSerializedState=()=>{return _.times(this._hintsVisible(),i=>{return this.refs["hintRenderer"+i].getSerializedState()})};}}HintsRenderer.contextType=PerseusI18nContext;HintsRenderer.defaultProps={linterContext:PerseusLinter.linterContextDefault};const styles$1=StyleSheet.create({mobileHintStylesHintsRenderer:{marginBlockStart:sizing.size_640,border:`solid ${semanticColor.core.border.neutral.subtle}`,borderWidth:"1px 0 0 0",position:"relative",":before":{content:'""',display:"table",clear:"both"},":after":{content:'""',display:"table",clear:"both"}},mobileHintStylesHintTitle:{fontWeight:"bold",color:semanticColor.core.foreground.neutral.strong,paddingBlockStart:sizing.size_160,paddingBlockEnd:sizing.size_240,[mediaQueries.lgOrSmaller]:{paddingInlineStart:0},[mediaQueries.smOrSmaller]:{paddingInlineStart:`calc(${hintPaddingInlineStart} + ${hintBorderWidth})`}}});
|
|
2127
2127
|
|
|
2128
2128
|
const defaultContext={onRendered:isRendered=>{}};const context=React.createContext(defaultContext);
|
|
2129
2129
|
|
|
2130
|
-
class ServerItemRenderer extends React.Component{componentDidMount(){this._currentFocus=null;this._fullyRendered=false;this.maybeCallOnRendered();}componentDidUpdate(){this.maybeCallOnRendered();}componentWillUnmount(){if(this.blurTimeoutID!=null){clearTimeout(this.blurTimeoutID);this.blurTimeoutID=null;}}maybeCallOnRendered(){if(!this._fullyRendered){const assetsLoaded=Object.values(this.state.assetStatuses).every(Boolean);if(assetsLoaded){this._fullyRendered=true;this.props.onRendered(true);}}}_setCurrentFocus(newFocus){const{apiOptions:{isMobile,onFocusChange},keypadElement}=this.props;const prevFocus=this._currentFocus;this._currentFocus=newFocus;const inputPaths=this.getInputPaths();const didFocusInput=this._currentFocus&&inputPaths.some(inputPath=>{return Util.inputPathsEqual(inputPath,this._currentFocus)});if(onFocusChange!=null){setTimeout(()=>{const keypadDomNode=keypadElement?.getDOMNode();const keypadHeight=keypadDomNode&&didFocusInput?keypadDomNode.getBoundingClientRect().height:0;onFocusChange(this._currentFocus,prevFocus,keypadHeight,didFocusInput&&this.questionRenderer.getDOMNodeForPath(newFocus));},0);}if(keypadElement&&isMobile){if(didFocusInput){keypadElement.activate();}else {keypadElement.dismiss();}}}_onRendererBlur(blurPath){const blurringFocusPath=this._currentFocus;if(!_.isEqual(blurPath,blurringFocusPath)){return}this.blurTimeoutID=setTimeout(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}},0);}focusPath(path){return this.questionRenderer.focusPath(path)}blurPath(path){return this.questionRenderer.blurPath(path)}getDOMNodeForPath(path){return this.questionRenderer.getDOMNodeForPath(path)}getInputPaths(){const questionAreaInputPaths=this.questionRenderer.getInputPaths();return questionAreaInputPaths}focus(){return this.questionRenderer.focus()}blur(){if(this._currentFocus){this.blurPath(this._currentFocus);}}getNumHints(){return this.props.item.hints.length}getPromptJSON(){return this.questionRenderer.getPromptJSON()}getUserInput(){return this.userInput}getWidgetIds(){return this.questionRenderer.getWidgetIds()}getSerializedState(){return {question:this.questionRenderer.getSerializedState(),hints:this.hintsRenderer.getSerializedState()}}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,onFocusChange:this._handleFocusChange};const contextValue={assetStatuses:this.state.assetStatuses,setAssetStatus:this.setAssetStatus};const questionRenderer=jsxRuntimeExports.jsx(context$1.Provider,{value:contextValue,children:jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.item.question.widgets,problemNum:this.props.problemNum??0,children:({userInput,handleUserInput,initializeUserInput})=>{this.userInput=userInput;return jsxRuntimeExports.jsx(Renderer,{keypadElement:this.props.keypadElement,problemNum:this.props.problemNum,apiOptions:apiOptions,reviewMode:this.props.reviewMode,showSolutions:this.props.showSolutions,ref:elem=>{if(elem!=null){this.questionRenderer=elem;}},content:this.props.item.question.content,widgets:this.props.item.question.widgets,images:this.props.item.question.images,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"question"),strings:this.context.strings,...this.props.dependencies,userInput:userInput,handleUserInput:(id,userInput,widgetsEmpty)=>{handleUserInput(id,userInput,widgetsEmpty);},initializeUserInput:initializeUserInput})}})});const hintsRenderer=jsxRuntimeExports.jsx(HintsRenderer,{dependencies:this.props.dependencies,hints:this.props.item.hints,hintsVisible:this.props.hintsVisible,apiOptions:apiOptions,ref:elem=>this.hintsRenderer=elem,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hints"),strings:this.context.strings});return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:questionRenderer}),jsxRuntimeExports.jsx("div",{className:apiOptions.isMobile?undefined:css(styles.hintsContainer),children:hintsRenderer})]})})}constructor(props){super(props),this._handleFocusChange=(newFocus,oldFocus)=>{if(newFocus!=null){this._setCurrentFocus(newFocus);}else {this._onRendererBlur(oldFocus);}},this.setAssetStatus=(assetKey,status)=>{const assetStatuses={...this.state.assetStatuses,[assetKey]:status};this.setState({assetStatuses});};this.state={assetStatuses:{}};this._fullyRendered=false;this.userInput={};}}ServerItemRenderer.contextType=PerseusI18nContext;ServerItemRenderer.defaultProps={apiOptions:{},linterContext:PerseusLinter.linterContextDefault,onRendered:isRendered=>{}};const styles=StyleSheet.create({hintsContainer:{
|
|
2130
|
+
class ServerItemRenderer extends React.Component{componentDidMount(){this._currentFocus=null;this._fullyRendered=false;this.maybeCallOnRendered();}componentDidUpdate(){this.maybeCallOnRendered();}componentWillUnmount(){if(this.blurTimeoutID!=null){clearTimeout(this.blurTimeoutID);this.blurTimeoutID=null;}}maybeCallOnRendered(){if(!this._fullyRendered){const assetsLoaded=Object.values(this.state.assetStatuses).every(Boolean);if(assetsLoaded){this._fullyRendered=true;this.props.onRendered(true);}}}_setCurrentFocus(newFocus){const{apiOptions:{isMobile,onFocusChange},keypadElement}=this.props;const prevFocus=this._currentFocus;this._currentFocus=newFocus;const inputPaths=this.getInputPaths();const didFocusInput=this._currentFocus&&inputPaths.some(inputPath=>{return Util.inputPathsEqual(inputPath,this._currentFocus)});if(onFocusChange!=null){setTimeout(()=>{const keypadDomNode=keypadElement?.getDOMNode();const keypadHeight=keypadDomNode&&didFocusInput?keypadDomNode.getBoundingClientRect().height:0;onFocusChange(this._currentFocus,prevFocus,keypadHeight,didFocusInput&&this.questionRenderer.getDOMNodeForPath(newFocus));},0);}if(keypadElement&&isMobile){if(didFocusInput){keypadElement.activate();}else {keypadElement.dismiss();}}}_onRendererBlur(blurPath){const blurringFocusPath=this._currentFocus;if(!_.isEqual(blurPath,blurringFocusPath)){return}this.blurTimeoutID=setTimeout(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}},0);}focusPath(path){return this.questionRenderer.focusPath(path)}blurPath(path){return this.questionRenderer.blurPath(path)}getDOMNodeForPath(path){return this.questionRenderer.getDOMNodeForPath(path)}getInputPaths(){const questionAreaInputPaths=this.questionRenderer.getInputPaths();return questionAreaInputPaths}focus(){return this.questionRenderer.focus()}blur(){if(this._currentFocus){this.blurPath(this._currentFocus);}}getNumHints(){return this.props.item.hints.length}getPromptJSON(){return this.questionRenderer.getPromptJSON()}getUserInput(){return this.userInput}getWidgetIds(){return this.questionRenderer.getWidgetIds()}getSerializedState(){return {question:this.questionRenderer.getSerializedState(),hints:this.hintsRenderer.getSerializedState()}}render(){const apiOptions={...ApiOptions.defaults,...this.props.apiOptions,onFocusChange:this._handleFocusChange};const contextValue={assetStatuses:this.state.assetStatuses,setAssetStatus:this.setAssetStatus};const questionRenderer=jsxRuntimeExports.jsx(context$1.Provider,{value:contextValue,children:jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.item.question.widgets,problemNum:this.props.problemNum??0,children:({userInput,handleUserInput,initializeUserInput})=>{this.userInput=userInput;return jsxRuntimeExports.jsx(Renderer,{keypadElement:this.props.keypadElement,problemNum:this.props.problemNum,apiOptions:apiOptions,reviewMode:this.props.reviewMode,showSolutions:this.props.showSolutions,ref:elem=>{if(elem!=null){this.questionRenderer=elem;}},content:this.props.item.question.content,widgets:this.props.item.question.widgets,images:this.props.item.question.images,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"question"),strings:this.context.strings,...this.props.dependencies,userInput:userInput,handleUserInput:(id,userInput,widgetsEmpty)=>{handleUserInput(id,userInput,widgetsEmpty);},initializeUserInput:initializeUserInput})}})});const hintsRenderer=jsxRuntimeExports.jsx(HintsRenderer,{dependencies:this.props.dependencies,hints:this.props.item.hints,hintsVisible:this.props.hintsVisible,apiOptions:apiOptions,ref:elem=>this.hintsRenderer=elem,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"hints"),strings:this.context.strings});return jsxRuntimeExports.jsx(DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:questionRenderer}),jsxRuntimeExports.jsx("div",{className:apiOptions.isMobile?undefined:css(styles.hintsContainer),children:hintsRenderer})]})})}constructor(props){super(props),this._handleFocusChange=(newFocus,oldFocus)=>{if(newFocus!=null){this._setCurrentFocus(newFocus);}else {this._onRendererBlur(oldFocus);}},this.setAssetStatus=(assetKey,status)=>{const assetStatuses={...this.state.assetStatuses,[assetKey]:status};this.setState({assetStatuses});};this.state={assetStatuses:{}};this._fullyRendered=false;this.userInput={};}}ServerItemRenderer.contextType=PerseusI18nContext;ServerItemRenderer.defaultProps={apiOptions:{},linterContext:PerseusLinter.linterContextDefault,onRendered:isRendered=>{}};const styles=StyleSheet.create({hintsContainer:{marginInlineStart:50}});var serverItemRenderer = React.forwardRef(function ServerItemRendererWithRef(props,ref){return jsxRuntimeExports.jsx(context.Consumer,{children:({onRendered})=>jsxRuntimeExports.jsx(ServerItemRenderer,{...props,onRendered:onRendered,ref:ref})})});
|
|
2131
2131
|
|
|
2132
2132
|
var allWidgets = [...basicWidgets,...extraWidgets];
|
|
2133
2133
|
|