@khanacademy/perseus 75.3.0 → 75.4.1
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 +24 -24
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/dist/server-item-renderer.d.ts +1 -1
- package/dist/testing/feature-flags-util.d.ts +2 -0
- package/dist/testing/item-renderer-hooks.d.ts +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/util.d.ts +6 -7
- package/dist/widgets/cs-program/cs-program.d.ts +3 -0
- package/dist/widgets/dropdown/dropdown.d.ts +1 -1
- package/dist/widgets/expression/expression.d.ts +2 -2
- package/dist/widgets/iframe/iframe.d.ts +3 -0
- package/dist/widgets/image/image.class.d.ts +2 -0
- package/dist/widgets/interactive-graphs/interactive-graph.d.ts +2 -2
- package/dist/widgets/label-image/label-image.d.ts +1 -1
- package/dist/widgets/mock-widgets/mock-widget.d.ts +1 -1
- package/dist/widgets/numeric-input/numeric-input.class.d.ts +1 -1
- package/dist/widgets/numeric-input/numeric-input.d.ts +2 -2
- package/dist/widgets/phet-simulation/phet-simulation.d.ts +1 -3
- package/dist/widgets/radio/multiple-choice-widget.d.ts +1 -1
- package/dist/widgets/radio/radio.ff.d.ts +1 -1
- package/dist/widgets/table/table.d.ts +1 -1
- package/package.json +45 -45
package/dist/es/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { HeadingMedium, LabelSmall, LabelLarge, Body, LabelMedium } from '@khana
|
|
|
8
8
|
import { StyleSheet, css } from 'aphrodite';
|
|
9
9
|
import Clickable from '@khanacademy/wonder-blocks-clickable';
|
|
10
10
|
import { Popover, PopoverContentCore } from '@khanacademy/wonder-blocks-popover';
|
|
11
|
-
import { semanticColor, sizing, color, spacing, font } from '@khanacademy/wonder-blocks-tokens';
|
|
11
|
+
import { semanticColor, sizing, color, spacing, font, boxShadow } from '@khanacademy/wonder-blocks-tokens';
|
|
12
12
|
import classNames$1 from 'classnames';
|
|
13
13
|
import $ from 'jquery';
|
|
14
14
|
import _, { debounce as debounce$1 } from 'underscore';
|
|
@@ -1413,7 +1413,7 @@ var a11y = StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,mar
|
|
|
1413
1413
|
|
|
1414
1414
|
const debounce=(func,delay)=>{let timer=null;return (...args)=>{if(timer){clearTimeout(timer);}timer=window.setTimeout(()=>{func(...args);},delay);}};
|
|
1415
1415
|
|
|
1416
|
-
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$1({"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$D.outerWrapper,this.state.focused&&styles$D.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(HeadingMedium,{id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$D.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(_(value).isFunction()){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$D.iconActive:styles$D.iconInactive;return jsxRuntimeExports.jsx(View,{style:[styles$D.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$D=StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:sizing.size_040,borderRadius:1},iconInactive:{border:"2px solid transparent",backgroundColor:
|
|
1416
|
+
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$1({"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$D.outerWrapper,this.state.focused&&styles$D.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(HeadingMedium,{id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$D.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(_(value).isFunction()){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$D.iconActive:styles$D.iconInactive;return jsxRuntimeExports.jsx(View,{style:[styles$D.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$D=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,paddingBottom:sizing.size_060,maxWidth:"initial"}});
|
|
1417
1417
|
|
|
1418
1418
|
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};
|
|
1419
1419
|
|
|
@@ -1722,7 +1722,7 @@ const getUnsupportedPromptJSON=(widgetType,message="")=>{return {type:widgetType
|
|
|
1722
1722
|
|
|
1723
1723
|
const getPromptJSON$m=()=>{return getUnsupportedPromptJSON("cs-program")};
|
|
1724
1724
|
|
|
1725
|
-
const{updateQueryString: updateQueryString$1}=Util;function getUrlFromProgramID$1(programID){const{InitialRequestUrl}=getDependencies();const path="/computer-programming/program/"+`${programID}/embedded?embed=yes&author=no`;if(isFileProtocol(InitialRequestUrl.protocol)){return `https://khanacademy.org${path}`}return toAbsoluteUrl(path)}class CSProgram extends React.Component{componentDidMount(){$(window).on("message",this.handleMessageEvent);}componentWillUnmount(){$(window).off("message",this.handleMessageEvent);}getPromptJSON(){return getPromptJSON$m()}getSerializedState(){const{userInput:_,alignment:__,...rest}=this.props;return {...rest,programType:rest.programType||null}}render(){if(!this.props.programID){return jsxRuntimeExports.jsx("div",{})}let styleContainer=false;let url=getUrlFromProgramID$1(this.props.programID);let className;const style={height:this.props.height,width:"100%"};if(this.props.showEditor){url+="&editor=yes";className="perseus-scratchpad-editor";}else {url+=`&editor=no&width=${articleMaxWidthInPx}`;className="perseus-scratchpad";if(this.props.programType!=="webpage"){styleContainer=true;}}if(this.props.showButtons){url+="&buttons=yes";style.height+=67;}else {url+="&buttons=no";}if(this.props.settings){const settings={};_.each(this.props.settings,function(setting){if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString$1(url,"settings",JSON.stringify(settings));}const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx("div",{className:css(styleContainer&&styles$q.container),children:jsxRuntimeExports.jsx("iframe",{sandbox:sandboxOptions,src:url,style:style,className:className,allowFullScreen:true})})}constructor(...args){super(...args),this.handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.originalEvent.data);}catch{return}if(_.isUndefined(data.testsPassed)){return}const status=data.testsPassed?"correct":"incorrect";this.props.handleUserInput({status:status,message:data.message});};}}CSProgram.defaultProps={showEditor:false,showButtons:false,userInput:{status:"incomplete",message:null}};const styles$q=StyleSheet.create({container:{margin:"auto"}});function getUserInputFromSerializedState$d(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$e(){return {status:"incomplete",message:null}}var CSProgram$1 = {name:"cs-program",displayName:"CS Program",widget:CSProgram,hidden:true,getStartUserInput: getStartUserInput$e,getUserInputFromSerializedState: getUserInputFromSerializedState$d};
|
|
1725
|
+
const{updateQueryString: updateQueryString$1}=Util;function getUrlFromProgramID$1(programID){const{InitialRequestUrl}=getDependencies();const path="/computer-programming/program/"+`${programID}/embedded?embed=yes&author=no`;if(isFileProtocol(InitialRequestUrl.protocol)){return `https://khanacademy.org${path}`}return toAbsoluteUrl(path)}class CSProgram extends React.Component{componentDidMount(){$(window).on("message",this.handleMessageEvent);}componentWillUnmount(){$(window).off("message",this.handleMessageEvent);}getPromptJSON(){return getPromptJSON$m()}getSerializedState(){const{userInput:_,alignment:__,...rest}=this.props;return {...rest,programType:rest.programType||null}}render(){if(!this.props.programID){return jsxRuntimeExports.jsx("div",{})}let styleContainer=false;let url=getUrlFromProgramID$1(this.props.programID);let className;const style={height:this.props.height,width:"100%"};if(this.props.showEditor){url+="&editor=yes";className="perseus-scratchpad-editor";}else {url+=`&editor=no&width=${articleMaxWidthInPx}`;className="perseus-scratchpad";if(this.props.programType!=="webpage"){styleContainer=true;}}if(this.props.showButtons){url+="&buttons=yes";style.height+=67;}else {url+="&buttons=no";}if(this.props.settings){const settings={};_.each(this.props.settings,function(setting){if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString$1(url,"settings",JSON.stringify(settings));}if(this.context?.locale){url=updateQueryString$1(url,"lang",this.context.locale);}const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx("div",{className:css(styleContainer&&styles$q.container),children:jsxRuntimeExports.jsx("iframe",{sandbox:sandboxOptions,src:url,style:style,className:className,allowFullScreen:true})})}constructor(...args){super(...args),this.handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.originalEvent.data);}catch{return}if(_.isUndefined(data.testsPassed)){return}const status=data.testsPassed?"correct":"incorrect";this.props.handleUserInput({status:status,message:data.message});};}}CSProgram.contextType=PerseusI18nContext;CSProgram.defaultProps={showEditor:false,showButtons:false,userInput:{status:"incomplete",message:null}};const styles$q=StyleSheet.create({container:{margin:"auto"}});function getUserInputFromSerializedState$d(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$e(){return {status:"incomplete",message:null}}var CSProgram$1 = {name:"cs-program",displayName:"CS Program",widget:CSProgram,hidden:true,getStartUserInput: getStartUserInput$e,getUserInputFromSerializedState: getUserInputFromSerializedState$d};
|
|
1726
1726
|
|
|
1727
1727
|
const getPromptJSON$l=widgetData=>{return {type:"definition",definition:widgetData.definition,togglePrompt:widgetData.togglePrompt}};
|
|
1728
1728
|
|
|
@@ -1750,17 +1750,17 @@ const styles$m={buttonStyleOverrides:{height:"auto",lineHeight:"inherit",marginL
|
|
|
1750
1750
|
|
|
1751
1751
|
function mediaQueryIsMatched(mediaQuery){if(typeof window.matchMedia!=="function"){return false}return window.matchMedia(mediaQuery).matches}class Explanation extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"explanation",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON$j(this.props)}render(){const promptText=this.state.expanded?this.props.hidePrompt:this.props.showPrompt;const caretIcon=this.state.expanded?caretUp:caretDown;const legacyContentStyling=[styles$m.content,this.state.expanded?styles$m.contentExpanded:styles$m.contentCollapsed,mediaQueryIsMatched("(prefers-reduced-motion: no-preference)")&&(this.state.expanded?styles$m.transitionExpanded:styles$m.transitionCollapsed)];const contentClasses=[styles$n.content,this.state.expanded?styles$n.contentExpanded:styles$n.contentCollapsed,this.state.expanded?styles$n.transitionExpanded:styles$n.transitionCollapsed];return jsxRuntimeExports.jsx(Id,{children:contentId=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button,{"aria-expanded":this.state.expanded,"aria-controls":contentId,endIcon:caretIcon,kind:"tertiary",labelStyle:styles$m.labelStyle,onClick:this._onClick,size:"small",style:styles$m.buttonStyleOverrides,children:promptText}),jsxRuntimeExports.jsx(View,{id:contentId,style:legacyContentStyling,className:contentClasses.join(" "),"aria-hidden":!this.state.expanded,testId:"content-container",children:jsxRuntimeExports.jsx(View,{className:styles$n.contentWrapper,style:styles$m.contentWrapper,children:jsxRuntimeExports.jsx(UserInputManager,{widgets:this.props.widgets,problemNum:0,children:({userInput,handleUserInput,initializeUserInput})=>{return jsxRuntimeExports.jsx(Renderer,{apiOptions:this.props.apiOptions,content:this.props.explanation,widgets:this.props.widgets,linterContext:this.props.linterContext,strings:this.context.strings,userInput:userInput,handleUserInput:handleUserInput,initializeUserInput:initializeUserInput})}})})})]})})}constructor(...args){super(...args),this.isWidget=true,this.state={expanded:false},this._onClick=()=>{this.setState({expanded:!this.state.expanded});this.props.trackInteraction();};}}Explanation.contextType=PerseusI18nContext;Explanation.defaultProps={showPrompt:"Explain",hidePrompt:"Hide explanation",explanation:"explanation goes here\n\nmore explanation",widgets:{},linterContext:linterContextDefault};const WrappedExplanation=withDependencies(Explanation);var Explanation$1 = {name:"explanation",displayName:"Explanation",widget:WrappedExplanation,isLintable:true};
|
|
1752
1752
|
|
|
1753
|
-
class FreeResponse extends React.Component{isOverLimit(){return !this.props.allowUnlimitedCharacters&&this.characterCount()>this.props.characterLimit}renderCharacterCount(){if(this.props.allowUnlimitedCharacters){return null}const characterCountText=this.context.strings.characterCount({used:this.characterCount(),num:this.props.characterLimit});return jsxRuntimeExports.jsx(View,{children:jsxRuntimeExports.jsxs(Text$1,{role:"status",style:[styles$l.characterCountText,this.isOverLimit()?styles$l.overCharacterLimit:undefined],children:[this.isOverLimit()&&jsxRuntimeExports.jsx(PhosphorIcon,{icon:warningCircleIcon,size:"small",style:styles$l.warningCircleIcon}),characterCountText]})})}render(){return jsxRuntimeExports.jsxs(View,{style:styles$l.container,className:"free-response",children:[jsxRuntimeExports.jsx(LabeledField,{label:jsxRuntimeExports.jsx(View,{className:"free-response-question",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.question,strings:this.context.strings})}),field:jsxRuntimeExports.jsx(TextArea,{error:this.isOverLimit(),onChange:this._handleUserInput,placeholder:this.props.placeholder,style:styles$l.textarea,value:this.props.userInput.currentValue})}),this.renderCharacterCount()]})}constructor(...args){super(...args),this.isWidget=true,this.characterCount=()=>{return this.props.userInput.currentValue.replace(/\n/g,"").length},this._handleUserInput=newValue=>{this.props.handleUserInput({currentValue:newValue});};}}FreeResponse.contextType=PerseusI18nContext;FreeResponse.defaultProps={userInput:{currentValue:""}};function getStartUserInput$c(){return {currentValue:""}}var FreeResponse$1 = {name:"free-response",accessible:true,displayName:"Free Response (Assessments only)",widget:FreeResponse,hidden:false,getUserInputFromSerializedState:getStartUserInput$c,getStartUserInput: getStartUserInput$c};const styles$l=StyleSheet.create({container:{gap:spacing.xSmall_8},characterCountText:{color:semanticColor.core.foreground.neutral.default,fontSize:font.size.small},overCharacterLimit:{color:
|
|
1753
|
+
class FreeResponse extends React.Component{isOverLimit(){return !this.props.allowUnlimitedCharacters&&this.characterCount()>this.props.characterLimit}renderCharacterCount(){if(this.props.allowUnlimitedCharacters){return null}const characterCountText=this.context.strings.characterCount({used:this.characterCount(),num:this.props.characterLimit});return jsxRuntimeExports.jsx(View,{children:jsxRuntimeExports.jsxs(Text$1,{role:"status",style:[styles$l.characterCountText,this.isOverLimit()?styles$l.overCharacterLimit:undefined],children:[this.isOverLimit()&&jsxRuntimeExports.jsx(PhosphorIcon,{icon:warningCircleIcon,size:"small",style:styles$l.warningCircleIcon}),characterCountText]})})}render(){return jsxRuntimeExports.jsxs(View,{style:styles$l.container,className:"free-response",children:[jsxRuntimeExports.jsx(LabeledField,{label:jsxRuntimeExports.jsx(View,{className:"free-response-question",children:jsxRuntimeExports.jsx(Renderer,{content:this.props.question,strings:this.context.strings})}),field:jsxRuntimeExports.jsx(TextArea,{error:this.isOverLimit(),onChange:this._handleUserInput,placeholder:this.props.placeholder,style:styles$l.textarea,value:this.props.userInput.currentValue})}),this.renderCharacterCount()]})}constructor(...args){super(...args),this.isWidget=true,this.characterCount=()=>{return this.props.userInput.currentValue.replace(/\n/g,"").length},this._handleUserInput=newValue=>{this.props.handleUserInput({currentValue:newValue});};}}FreeResponse.contextType=PerseusI18nContext;FreeResponse.defaultProps={userInput:{currentValue:""}};function getStartUserInput$c(){return {currentValue:""}}var FreeResponse$1 = {name:"free-response",accessible:true,displayName:"Free Response (Assessments only)",widget:FreeResponse,hidden:false,getUserInputFromSerializedState:getStartUserInput$c,getStartUserInput: getStartUserInput$c};const styles$l=StyleSheet.create({container:{gap:spacing.xSmall_8},characterCountText:{color:semanticColor.core.foreground.neutral.default,fontSize:font.size.small},overCharacterLimit:{color:semanticColor.core.foreground.critical.default},textarea:{padding:spacing.medium_16},warningCircleIcon:{marginInlineEnd:spacing.xSmall_8}});
|
|
1754
1754
|
|
|
1755
1755
|
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}};
|
|
1756
1756
|
|
|
1757
|
-
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$k.answerBar,backgroundColor:answerBarState==="CORRECT"?
|
|
1757
|
+
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$k.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$k.text,children:[jsxRuntimeExports.jsx("span",{style:styles$k.tryAgainIcon,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTryAgain})}),jsxRuntimeExports.jsx("span",{style:{marginLeft: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$k.text,children:[jsxRuntimeExports.jsx("span",{style:{fontSize:28,color:semanticColor.core.foreground.success.default},children:jsxRuntimeExports.jsx(InlineIcon,{...iconStar,style:{marginBottom:5}})}),jsxRuntimeExports.jsx("span",{role:"alert","aria-label":correctExcited,style:{marginLeft:8},children:correctExcited})]}),onNextQuestion&&jsxRuntimeExports.jsx(Button,{onClick:onNextQuestion,children:nextQuestion})]})}}GradedGroupAnswerBar.contextType=PerseusI18nContext;const fontSize$1=17;const styles$k={answerBar:{display:"flex",alignItems:"center",height:68,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,marginBottom:negativePhoneMargin,marginTop:phoneMargin,paddingLeft:phoneMargin,paddingRight:10,borderTop:`1px solid ${semanticColor.core.border.neutral.default}`},tryAgainIcon:{fontSize:28,color:"#63D9EA",transform:"scale(-1,1) rotate(-268deg)"},text:{display:"flex",flexDirection:"row",alignItems:"center",fontWeight:"bold",fontSize:fontSize$1}};
|
|
1758
1758
|
|
|
1759
|
-
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:"#526f03"}});gradeStatus=this.context.strings.correct;}else if(this.state.status===GRADING_STATUSES.incorrect){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconRemove,style:{color:"#ff5454"}});gradeStatus=this.context.strings.incorrect;}const mobileClass=this.props.inGradedGroupSet?css(styles$j.gradedGroupInSet):css(styles$j.gradedGroup);const classes=classNames$1({[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$j.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("p",{role:"status","aria-live":"polite",children:this.state.message}),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:{marginLeft: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$j.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$j.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;GradedGroup.defaultProps={title:"",content:"",widgets:{},images:{},hint:null,hasHint:false,linterContext:linterContextDefault};const styles$j=StyleSheet.create({gradedGroupInSet:{marginLeft:0,paddingLeft:0},gradedGroup:{borderTop:`1px solid ${gray76}`,borderBottom:`1px solid ${gray76}`,backgroundColor:tableBackgroundAccent,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"},showHintLink:{backgroundColor:"unset",fontSize:14,padding:0,border:"none",marginTop:20,color:
|
|
1759
|
+
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:"#526f03"}});gradeStatus=this.context.strings.correct;}else if(this.state.status===GRADING_STATUSES.incorrect){icon=jsxRuntimeExports.jsx(InlineIcon,{...iconRemove,style:{color:"#ff5454"}});gradeStatus=this.context.strings.incorrect;}const mobileClass=this.props.inGradedGroupSet?css(styles$j.gradedGroupInSet):css(styles$j.gradedGroup);const classes=classNames$1({[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$j.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("p",{role:"status","aria-live":"polite",children:this.state.message}),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:{marginLeft: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$j.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$j.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;GradedGroup.defaultProps={title:"",content:"",widgets:{},images:{},hint:null,hasHint:false,linterContext:linterContextDefault};const styles$j=StyleSheet.create({gradedGroupInSet:{marginLeft:0,paddingLeft:0},gradedGroup:{borderTop:`1px solid ${gray76}`,borderBottom:`1px solid ${gray76}`,backgroundColor:tableBackgroundAccent,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"},showHintLink:{backgroundColor:"unset",fontSize:14,padding:0,border:"none",marginTop:20,color:semanticColor.core.foreground.instructive.default,cursor:"pointer",display:"block",clear:"both"},explanationTitle:{backgroundColor:"unset",marginTop:20,color:semanticColor.core.foreground.instructive.default,marginBottom:10,cursor:"pointer",fontSize:14,padding:0,border:"none",display:"block",clear:"both"},title:{fontSize:12,color:gray68,textTransform:"uppercase",marginBottom: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};
|
|
1760
1760
|
|
|
1761
1761
|
const getPromptJSON$h=(widgetData,activeGroupJSON)=>{return {type:"graded-group-set",options:{groupCount:widgetData.gradedGroups.length,currentGroup:activeGroupJSON}}};
|
|
1762
1762
|
|
|
1763
|
-
class Indicators extends React.Component{render(){return jsxRuntimeExports.jsx("ul",{className:classNames$1(css(styles$i.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>jsxRuntimeExports.jsx("li",{className:css(styles$i.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":this.context.strings.skipToTitle({title}),style:styles$i.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$i.indicatorDot,(hovered||focused||pressed)&&styles$i.indicatorDotFocused],children:i===this.props.currentGroup&&jsxRuntimeExports.jsx(View,{style:styles$i.indicatorDotActive,children:jsxRuntimeExports.jsx("span",{className:css(a11y.srOnly),children:this.context.strings.current})})})})},title))})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React.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$i.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$i.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$i.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$i.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$i.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:this.props.gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,...currentGroup,inGradedGroupSet:true,title:null,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}GradedGroupSet.defaultProps={gradedGroups:[],linterContext:linterContextDefault};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$i=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:12,color:
|
|
1763
|
+
class Indicators extends React.Component{render(){return jsxRuntimeExports.jsx("ul",{className:classNames$1(css(styles$i.indicatorContainer),"indicatorContainer"),children:this.props.gradedGroups.map(({title},i)=>jsxRuntimeExports.jsx("li",{className:css(styles$i.indicator),children:jsxRuntimeExports.jsx(Clickable,{role:"button","aria-label":this.context.strings.skipToTitle({title}),style:styles$i.indicatorButton,onClick:()=>this.props.onChangeCurrentGroup(i),onKeyDown:e=>this.handleKeyDown(e,i),children:({hovered,focused,pressed})=>jsxRuntimeExports.jsx(View,{style:[styles$i.indicatorDot,(hovered||focused||pressed)&&styles$i.indicatorDotFocused],children:i===this.props.currentGroup&&jsxRuntimeExports.jsx(View,{style:styles$i.indicatorDotActive,children:jsxRuntimeExports.jsx("span",{className:css(a11y.srOnly),children:this.context.strings.current})})})})},title))})}constructor(...args){super(...args),this.handleKeyDown=(e,i)=>{if(e.key==="Enter"||e.key===" "){this.props.onChangeCurrentGroup(i);}};}}Indicators.contextType=PerseusI18nContext;class GradedGroupSet extends React.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$i.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$i.container),children:[jsxRuntimeExports.jsxs("div",{className:css(styles$i.top),children:[jsxRuntimeExports.jsx("div",{className:css(styles$i.title),children:currentGroup.title}),jsxRuntimeExports.jsx("div",{className:css(styles$i.spacer)}),jsxRuntimeExports.jsx(Indicators,{currentGroup:this.state.currentGroup,gradedGroups:this.props.gradedGroups,onChangeCurrentGroup:currentGroup=>this.setState({currentGroup})})]}),jsxRuntimeExports.jsx(GradedGroup,{ref:comp=>this._childGroup=comp,...this.props,...currentGroup,inGradedGroupSet:true,title:null,onNextQuestion:handleNextQuestion,linterContext:this.props.linterContext},this.state.currentGroup)]})}constructor(...args){super(...args),this.state={currentGroup:0},this.getInputPaths=()=>{return this._childGroup.getInputPaths()},this.focus=()=>{return this._childGroup.focus()},this.focusInputPath=path=>{this._childGroup.focusInputPath(path);},this.blurInputPath=path=>{this._childGroup.blurInputPath(path);},this.handleNextQuestion=()=>{const{currentGroup}=this.state;const numGroups=this.props.gradedGroups.length;if(currentGroup<numGroups-1){this.setState({currentGroup:currentGroup+1});}};}}GradedGroupSet.defaultProps={gradedGroups:[],linterContext:linterContextDefault};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$i=StyleSheet.create({top:{display:"flex",flexDirection:"row"},spacer:{flex:1},title:{fontSize:12,color:semanticColor.core.foreground.neutral.subtle,textTransform:"uppercase",marginBottom:11,letterSpacing:.8},indicatorContainer:{display:"flex",flexDirection:"row",listStyle:"none",margin:"unset",paddingInlineStart:"unset",flexWrap:"wrap"},indicator:{width:24,height:24},indicatorButton:{width:"100%",height:"100%",display:"flex",flexWrap:"wrap",placeContent:"center",cursor:"pointer",":focus":{outline:"none"}},indicatorDot:{boxSizing:"content-box",width:10,height:10,borderRadius:"100%",borderWidth:2,borderColor:semanticColor.core.border.instructive.default,borderStyle:"solid"},indicatorDotFocused:{borderWidth:5,borderStyle:"double"},indicatorDotActive:{backgroundColor:semanticColor.core.background.instructive.default,width:"100%",height:"100%"},container:{borderTop:`1px solid ${gray76}`,borderBottom:`1px solid ${gray76}`,backgroundColor:tableBackgroundAccent,marginLeft:negativePhoneMargin,marginRight:negativePhoneMargin,paddingBottom:phoneMargin,paddingLeft:phoneMargin,paddingRight:phoneMargin,paddingTop:10,width:"auto"}});
|
|
1764
1764
|
|
|
1765
1765
|
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",ref:"button"+i,className:css(styles$h.buttonStyle,button.value===value&&styles$h.selectedStyle,button.value===value&&this.props.selectedButtonStyle),onClick:()=>this.toggleSelect(button.value),children:button.content||""+button.value},""+i)});const outerStyle={display:"inline-block"};return jsxRuntimeExports.jsx("div",{style:outerStyle,ref:node=>this.container=node,children:buttons})}}ButtonGroup.defaultProps={value:null,allowEmpty:true};const styles$h=StyleSheet.create({buttonStyle:{backgroundColor:"white",border:"1px solid #ccc",borderLeft:"0",cursor:"pointer",margin:"0",padding:"5px 10px",position:"relative",":first-child":{borderLeft:"1px solid #ccc",borderTopLeftRadius:"3px",borderBottomLeftRadius:"3px"},":last-child":{borderRight:"1px solid #ccc",borderTopRightRadius:"3px",borderBottomRightRadius:"3px"},":hover":{backgroundColor:"#ccc"},":focus":{zIndex:2}},selectedStyle:{backgroundColor:"#ddd"}});
|
|
1766
1766
|
|
|
@@ -1776,7 +1776,7 @@ class Group extends React.Component{componentDidMount(){this.forceUpdate();}getP
|
|
|
1776
1776
|
|
|
1777
1777
|
const getPromptJSON$e=()=>{return getUnsupportedPromptJSON("iframe")};
|
|
1778
1778
|
|
|
1779
|
-
const{updateQueryString}=Util;class Iframe extends React.Component{componentDidMount(){$(window).on("message",this.handleMessageEvent);}componentWillUnmount(){$(window).off("message",this.handleMessageEvent);}getPromptJSON(){return getPromptJSON$e()}getSerializedState(){const{userInput:_,alignment:__,...rest}=this.props;return rest}render(){const style={width:String(this.props.width),height:String(this.props.height)};const{InitialRequestUrl}=getDependencies();Object.entries(style).forEach(([key,value])=>{if(!value.endsWith("%")&&!value.endsWith("px")){style[key]=value+"px";}});let url=this.props.url;if(url&&url.length&&url.indexOf("http")!==0){url="https://www.khanacademy.org/computer-programming/program/"+url+"/embedded?buttons=no&embed=yes&editor=no&author=no";url=updateQueryString(url,"width",`${this.props.width}`);url=updateQueryString(url,"height",`${this.props.height}`);url=updateQueryString(url,"origin",InitialRequestUrl.origin);}if(this.props.settings){const settings={};this.props.settings.forEach(setting=>{if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString(url,"settings",JSON.stringify(settings));}let sandboxProperties="allow-same-origin allow-scripts";sandboxProperties+=" allow-top-navigation";return jsxRuntimeExports.jsx("iframe",{sandbox:sandboxProperties,style:style,src:url,allowFullScreen:this.props.allowFullScreen})}constructor(...args){super(...args),this.handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.originalEvent.data);}catch{return}if(data.testsPassed===undefined){return}const status=data.testsPassed?"correct":"incorrect";this.props.handleUserInput({status:status,message:data.message});};}}Iframe.defaultProps={allowFullScreen:false,allowTopNavigation:false,userInput:{status:"incomplete",message:null}};function getUserInputFromSerializedState$9(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$9(){return {status:"incomplete",message:null}}var Iframe$1 = {name:"iframe",displayName:"Iframe (deprecated)",widget:Iframe,hidden:true,getStartUserInput: getStartUserInput$9,getUserInputFromSerializedState: getUserInputFromSerializedState$9};
|
|
1779
|
+
const{updateQueryString}=Util;class Iframe extends React.Component{componentDidMount(){$(window).on("message",this.handleMessageEvent);}componentWillUnmount(){$(window).off("message",this.handleMessageEvent);}getPromptJSON(){return getPromptJSON$e()}getSerializedState(){const{userInput:_,alignment:__,...rest}=this.props;return rest}render(){const style={width:String(this.props.width),height:String(this.props.height)};const{InitialRequestUrl}=getDependencies();Object.entries(style).forEach(([key,value])=>{if(!value.endsWith("%")&&!value.endsWith("px")){style[key]=value+"px";}});let url=this.props.url;if(url&&url.length&&url.indexOf("http")!==0){url="https://www.khanacademy.org/computer-programming/program/"+url+"/embedded?buttons=no&embed=yes&editor=no&author=no";url=updateQueryString(url,"width",`${this.props.width}`);url=updateQueryString(url,"height",`${this.props.height}`);url=updateQueryString(url,"origin",InitialRequestUrl.origin);}if(this.context?.locale&&url?.includes("khanacademy.org")){url=updateQueryString(url,"lang",this.context.locale);}if(this.props.settings){const settings={};this.props.settings.forEach(setting=>{if(setting.name&&setting.value){settings[setting.name]=setting.value;}});url=updateQueryString(url,"settings",JSON.stringify(settings));}let sandboxProperties="allow-same-origin allow-scripts";sandboxProperties+=" allow-top-navigation";return jsxRuntimeExports.jsx("iframe",{sandbox:sandboxProperties,style:style,src:url,allowFullScreen:this.props.allowFullScreen})}constructor(...args){super(...args),this.handleMessageEvent=e=>{let data={};try{data=JSON.parse(e.originalEvent.data);}catch{return}if(data.testsPassed===undefined){return}const status=data.testsPassed?"correct":"incorrect";this.props.handleUserInput({status:status,message:data.message});};}}Iframe.contextType=PerseusI18nContext;Iframe.defaultProps={allowFullScreen:false,allowTopNavigation:false,userInput:{status:"incomplete",message:null}};function getUserInputFromSerializedState$9(serializedState){return {status:serializedState.status,message:serializedState.message}}function getStartUserInput$9(){return {status:"incomplete",message:null}}var Iframe$1 = {name:"iframe",displayName:"Iframe (deprecated)",widget:Iframe,hidden:true,getStartUserInput: getStartUserInput$9,getUserInputFromSerializedState: getUserInputFromSerializedState$9};
|
|
1780
1780
|
|
|
1781
1781
|
const getPromptJSON$d=widgetData=>{return {type:"image",options:{altText:widgetData.alt,title:widgetData.title,caption:widgetData.caption,imageUrl:widgetData.backgroundImage.url}}};
|
|
1782
1782
|
|
|
@@ -1823,17 +1823,17 @@ var components = /*#__PURE__*/Object.freeze({
|
|
|
1823
1823
|
|
|
1824
1824
|
const GifControlsButton=({isPlaying,onToggle})=>{const strings=usePerseusI18n().strings;return jsxRuntimeExports.jsx(Button,{kind:"secondary",startIcon:isPlaying?pauseIcon:playIcon,onClick:onToggle,style:{width:"fit-content"},children:isPlaying?strings.gifPauseButton:strings.gifPlayButton})};
|
|
1825
1825
|
|
|
1826
|
-
const MODAL_HEIGHT=568;function ExploreImageModalContent({backgroundImage,caption,alt,longDescription,linterContext,apiOptions,box,labels,range,zoomSize,isGifPlaying,setIsGifPlaying}){const context=React.useContext(PerseusI18nContext);const[zoomWidth,zoomHeight]=zoomSize;const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");if(!backgroundImage.height||!backgroundImage.width||!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);
|
|
1826
|
+
const MODAL_HEIGHT=568;function ExploreImageModalContent({backgroundImage,caption,alt,longDescription,linterContext,apiOptions,box,labels,range,zoomSize,isGifPlaying,setIsGifPlaying}){const context=React.useContext(PerseusI18nContext);const scaleFF=isFeatureOn({apiOptions},"image-widget-upgrade-scale");const[zoomWidth,zoomHeight]=zoomSize;const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");if(!backgroundImage.height||!backgroundImage.width||!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);let modalImageHeight=Math.min(MODAL_HEIGHT,zoomHeight);let width=zoomWidth/zoomHeight*modalImageHeight;if(scaleFF){modalImageHeight=Math.min(MODAL_HEIGHT,backgroundImage.height);width=backgroundImage.width/backgroundImage.height*modalImageHeight;}return jsxRuntimeExports.jsxs("div",{className:styles$g.modalPanelContainer,children:[jsxRuntimeExports.jsx("div",{className:styles$g.modalImageContainer,children:jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,allowZoom:false,alt:caption===alt?"":alt,width:width,height:modalImageHeight,preloader:apiOptions.imagePreloader,extraGraphie:{box:box,range:range,labels:labels??[]},zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,setAssetStatus:setAssetStatus})})}),jsxRuntimeExports.jsxs("div",{className:`perseus-image-modal-description ${styles$g.modalDescriptionContainer}`,children:[gifControlsFF&&imageIsGif&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(GifControlsButton,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),jsxRuntimeExports.jsx("div",{className:styles$g.spacerVertical})]}),caption&&jsxRuntimeExports.jsx("div",{className:styles$g.modalCaptionContainer,children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),jsxRuntimeExports.jsx(HeadingMedium,{tag:"h2",style:wbStyles$1.descriptionHeading,children:context.strings.imageDescriptionLabel}),jsxRuntimeExports.jsx(Renderer,{content:longDescription,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})]})]})}const wbStyles$1={descriptionHeading:{marginBlockEnd:sizing.size_160}};
|
|
1827
1827
|
|
|
1828
1828
|
const ExploreImageModal=props=>{const context=React__default.useContext(PerseusI18nContext);const titleText=props.title||context.strings.imageAlternativeTitle;const title=jsxRuntimeExports.jsx("h1",{className:`perseus-image-modal-title ${styles$g.modalTitleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:titleText,apiOptions:props.apiOptions,linterContext:props.linterContext,strings:context.strings})});return jsxRuntimeExports.jsx("div",{className:`framework-perseus ${styles$g.modalContainer}`,children:jsxRuntimeExports.jsx(FlexibleDialog,{title:title,content:jsxRuntimeExports.jsx(ExploreImageModalContent,{...props}),styles:{root:wbStyles.root}})})};const wbStyles={root:{borderRadius:sizing.size_120,maxWidth:"100%"}};
|
|
1829
1829
|
|
|
1830
1830
|
const GifControlsIcon=({isPlaying,onToggle})=>{const strings=usePerseusI18n().strings;return jsxRuntimeExports.jsx(IconButton,{icon:isPlaying?pauseIcon:playIcon,kind:"secondary","aria-label":isPlaying?strings.gifPauseAriaLabel:strings.gifPlayAriaLabel,onClick:onToggle,style:{flexShrink:0}})};
|
|
1831
1831
|
|
|
1832
|
-
const ImageInfoArea=props=>{const{backgroundImage,caption,longDescription,apiOptions,linterContext,zoomSize,isGifPlaying,setIsGifPlaying}=props;const[zoomWidth,_]=zoomSize;const context=React.useContext(PerseusI18nContext);const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);return jsxRuntimeExports.jsxs("div",{className:styles$g.infoAreaContainer,children:[gifControlsFF&&imageIsGif&&jsxRuntimeExports.jsx(GifControlsIcon,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),gifControlsFF&&imageIsGif&&longDescription&&jsxRuntimeExports.jsx("div",{className:styles$g.spacerHorizontal}),longDescription&&jsxRuntimeExports.jsx(ModalLauncher,{modal:jsxRuntimeExports.jsx(ExploreImageModal,{...props}),children:({openModal})=>jsxRuntimeExports.jsx(ExploreImageButton,{hasCaption:!!caption,onClick:openModal})}),caption&&jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",style:{maxWidth:zoomWidth},children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})};
|
|
1832
|
+
const ImageInfoArea=props=>{const{backgroundImage,caption,longDescription,apiOptions,linterContext,zoomSize,isGifPlaying,setIsGifPlaying}=props;const[zoomWidth,_]=zoomSize;const context=React.useContext(PerseusI18nContext);const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");const scaleFF=isFeatureOn({apiOptions},"image-widget-upgrade-scale");if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);return jsxRuntimeExports.jsxs("div",{className:styles$g.infoAreaContainer,children:[gifControlsFF&&imageIsGif&&jsxRuntimeExports.jsx(GifControlsIcon,{isPlaying:isGifPlaying,onToggle:()=>setIsGifPlaying(!isGifPlaying)}),gifControlsFF&&imageIsGif&&longDescription&&jsxRuntimeExports.jsx("div",{className:styles$g.spacerHorizontal}),longDescription&&jsxRuntimeExports.jsx(ModalLauncher,{modal:jsxRuntimeExports.jsx(ExploreImageModal,{...props}),children:({openModal})=>jsxRuntimeExports.jsx(ExploreImageButton,{hasCaption:!!caption,onClick:openModal})}),caption&&jsxRuntimeExports.jsx("figcaption",{className:"perseus-image-caption",style:{maxWidth:scaleFF?backgroundImage.width:zoomWidth},children:jsxRuntimeExports.jsx(Renderer,{content:caption,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})})]})};
|
|
1833
1833
|
|
|
1834
|
-
const ImageComponent=props=>{const{apiOptions,alt,backgroundImage,box,caption,longDescription,decorative,linterContext,labels,range,title,trackInteraction,widgetId}=props;const context=React.useContext(PerseusI18nContext);const{analytics}=useDependencies();const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");const[zoomSize,setZoomSize]=React.useState([backgroundImage.width||0,backgroundImage.height||0]);const[isGifPlaying,setIsGifPlaying]=React.useState(false);const[zoomWidth,zoomHeight]=zoomSize;const ignoreResultsRef=React.useRef(false);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React.useEffect(()=>{ignoreResultsRef.current=false;Util.getImageSizeModern(backgroundImage.url).then(naturalSize=>{if(ignoreResultsRef.current){return}const[naturalWidth,naturalHeight]=naturalSize;const[savedWidth,savedHeight]=[backgroundImage.width||0,backgroundImage.height||0];if(naturalWidth>savedWidth){setZoomSize([naturalWidth,naturalHeight]);}else {setZoomSize([savedWidth,savedHeight]);}});return ()=>{ignoreResultsRef.current=true;}},[backgroundImage.url,backgroundImage.width,backgroundImage.height]);if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);const svgImage=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,width:zoomWidth,height:zoomHeight,preloader:apiOptions.imagePreloader,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus})});if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{maxWidth:
|
|
1834
|
+
const ImageComponent=props=>{const{apiOptions,alt,backgroundImage,box,caption,longDescription,decorative,linterContext,labels,range,title,trackInteraction,widgetId}=props;const context=React.useContext(PerseusI18nContext);const{analytics}=useDependencies();const gifControlsFF=isFeatureOn({apiOptions},"image-widget-upgrade-gif-controls");const scaleFF=isFeatureOn({apiOptions},"image-widget-upgrade-scale");const[zoomSize,setZoomSize]=React.useState([backgroundImage.width||0,backgroundImage.height||0]);const[isGifPlaying,setIsGifPlaying]=React.useState(false);const[zoomWidth,zoomHeight]=zoomSize;const ignoreResultsRef=React.useRef(false);useOnMountEffect(()=>{analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"image",widgetId:widgetId}});});React.useEffect(()=>{ignoreResultsRef.current=false;Util.getImageSizeModern(backgroundImage.url).then(naturalSize=>{if(ignoreResultsRef.current){return}const[naturalWidth,naturalHeight]=naturalSize;const[savedWidth,savedHeight]=[backgroundImage.width||0,backgroundImage.height||0];if(naturalWidth>savedWidth){setZoomSize([naturalWidth,naturalHeight]);}else {setZoomSize([savedWidth,savedHeight]);}});return ()=>{ignoreResultsRef.current=true;}},[backgroundImage.url,backgroundImage.width,backgroundImage.height]);if(!backgroundImage.url){return null}const imageIsGif=isGif(backgroundImage.url);let scale=props.scale;if(!scaleFF||scale<=0||scale===Infinity||scale===-Infinity){scale=1;}const svgImage=jsxRuntimeExports.jsx(context$1.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:backgroundImage.url,width:scaleFF?backgroundImage.width:zoomWidth,height:scaleFF?backgroundImage.height:zoomHeight,scale:scale,preloader:apiOptions.imagePreloader,extraGraphie:{box:box,range:range,labels:labels},trackInteraction:trackInteraction,zoomToFullSizeOnMobile:apiOptions.isMobile,constrainHeight:apiOptions.isMobile,allowFullBleed:apiOptions.isMobile,allowZoom:!decorative,alt:decorative||caption===alt?"":alt,setAssetStatus:setAssetStatus})});const maxWidth=(backgroundImage.width??0)*scale;if(decorative){return jsxRuntimeExports.jsx("figure",{className:"perseus-image-widget",style:{maxWidth:maxWidth},children:svgImage})}return jsxRuntimeExports.jsxs("figure",{className:"perseus-image-widget",style:{maxWidth:maxWidth},children:[title&&jsxRuntimeExports.jsx("div",{className:`perseus-image-title ${styles$g.titleContainer}`,children:jsxRuntimeExports.jsx(Renderer,{content:title,apiOptions:apiOptions,linterContext:linterContext,strings:context.strings})}),svgImage,(gifControlsFF&&imageIsGif||caption||longDescription)&&jsxRuntimeExports.jsx(ImageInfoArea,{zoomSize:zoomSize,isGifPlaying:isGifPlaying,setIsGifPlaying:setIsGifPlaying,...props})]})};
|
|
1835
1835
|
|
|
1836
|
-
const defaultBoxSize=400;const defaultRange=[0,10];const defaultBackgroundImage$1={url:null,width:0,height:0};class ImageWidget extends React.Component{getPromptJSON(){return getPromptJSON$d(this.props)}render(){return jsxRuntimeExports.jsx(ImageComponent,{...this.props})}constructor(...args){super(...args),this.isWidget=true;}}ImageWidget.contextType=PerseusI18nContext;ImageWidget.defaultProps={alignment:"block",title:"",range:[defaultRange,defaultRange],box:[defaultBoxSize,defaultBoxSize],backgroundImage:defaultBackgroundImage$1,labels:[],alt:"",longDescription:"",decorative:false,caption:"",linterContext:linterContextDefault};var Image$1 = {name:"image",displayName:"Image",widget:ImageWidget,isLintable:true};
|
|
1836
|
+
const defaultBoxSize=400;const defaultRange=[0,10];const defaultBackgroundImage$1={url:null,width:0,height:0};class ImageWidget extends React.Component{getPromptJSON(){return getPromptJSON$d(this.props)}render(){return jsxRuntimeExports.jsx(ImageComponent,{...this.props})}constructor(...args){super(...args),this.isWidget=true;}}ImageWidget.contextType=PerseusI18nContext;ImageWidget.defaultProps={alignment:"block",title:"",range:[defaultRange,defaultRange],box:[defaultBoxSize,defaultBoxSize],backgroundImage:defaultBackgroundImage$1,scale:1,labels:[],alt:"",longDescription:"",decorative:false,caption:"",linterContext:linterContextDefault};var Image$1 = {name:"image",displayName:"Image",widget:ImageWidget,isLintable:true};
|
|
1837
1837
|
|
|
1838
1838
|
const getPromptJSON$c=()=>{return getUnsupportedPromptJSON("interaction")};
|
|
1839
1839
|
|
|
@@ -1883,7 +1883,7 @@ function GraphLockedLabelsLayer(props){const{lockedFigures}=props;return lockedF
|
|
|
1883
1883
|
|
|
1884
1884
|
const strokeWeights={thin:1,medium:2,thick:4};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]}
|
|
1885
1885
|
|
|
1886
|
-
const LockedEllipse=props=>{const{center,radius,angle,color
|
|
1886
|
+
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",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]}}})})};
|
|
1887
1887
|
|
|
1888
1888
|
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",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})]})};
|
|
1889
1889
|
|
|
@@ -1895,11 +1895,11 @@ function srFormatNumber(a,locale,maximumFractionDigits){const piBasedNumber=getP
|
|
|
1895
1895
|
|
|
1896
1896
|
const getIntersectionOfRayWithBox=(initialPoint,throughPoint,box)=>{const[[xMin,xMax],[yMin,yMax]]=box;const[aX,aY]=initialPoint;const[bX,bY]=throughPoint;const yDiff=bY-aY;const xDiff=bX-aX;const slope=yDiff/xDiff;const inverseSlope=1/slope;const xExtreme=xDiff<0?xMin:xMax;const yExtreme=yDiff<0?yMin:yMax;const yAtXExtreme=aY+(xExtreme-aX)*slope;const xAtYExtreme=aX+(yExtreme-aY)*inverseSlope;switch(true){case isBetween(yAtXExtreme,yMin,yMax):return [xExtreme,yAtXExtreme];case isBetween(xAtYExtreme,xMin,xMax):return [xAtYExtreme,yExtreme];default:return [xExtreme,yExtreme]}};function isBetween(x,low,high){return x>=low&&x<=high}function getArrayWithoutDuplicates(array){const returnArray=[];for(const coordPair of array){if(!returnArray.some(([x,y])=>x===coordPair[0]&&y===coordPair[1])){returnArray.push(coordPair);}}return returnArray}function getSlopeStringForLine(line,strings){const slope=(line[1][1]-line[0][1])/(line[1][0]-line[0][0]);if(!Number.isFinite(slope)){return strings.srLinearGraphSlopeVertical}if(slope===0){return strings.srLinearGraphSlopeHorizontal}return slope>0?strings.srLinearGraphSlopeIncreasing:strings.srLinearGraphSlopeDecreasing}function getInterceptStringForLine(line,strings,locale){const slope=(line[1][1]-line[0][1])/(line[1][0]-line[0][0]);const xIntercept=(0-line[0][1])/slope+line[0][0];const yIntercept=line[0][1]-slope*line[0][0];const overlapsXAxis=line[0][1]===0&&line[1][1]===0;const overlapsYAxis=line[0][0]===0&&line[1][0]===0;const hasXIntercept=Number.isFinite(xIntercept)&&!overlapsXAxis;const hasYIntercept=Number.isFinite(yIntercept)&&!overlapsYAxis;if(hasXIntercept&&hasYIntercept){return xIntercept===0&&yIntercept===0?strings.srLinearGraphOriginIntercept:strings.srLinearGraphBothIntercepts({xIntercept:srFormatNumber(xIntercept,locale),yIntercept:srFormatNumber(yIntercept,locale)})}return hasXIntercept?strings.srLinearGraphXOnlyIntercept({xIntercept:srFormatNumber(xIntercept,locale)}):strings.srLinearGraphYOnlyIntercept({yIntercept:srFormatNumber(yIntercept,locale)})}function getCoordQuadrant(coord){const[unroundedX,unroundedY]=coord;const x=Number(unroundedX.toFixed(3));const y=Number(unroundedY.toFixed(3));if(x===0&&y===0){return "origin"}if(y===0){return "x-axis"}if(x===0){return "y-axis"}if(x>0&&y>0){return 1}if(x<0&&y>0){return 2}if(x<0&&y<0){return 3}return 4}function getQuadraticVertexString(vertex,strings){const location=getCoordQuadrant(vertex);switch(location){case "origin":return strings.srQuadraticGraphVertexOrigin;case "x-axis":return strings.srQuadraticGraphVertexXAxis;case "y-axis":return strings.srQuadraticGraphVertexYAxis;default:return strings.srQuadraticGraphVertexQuadrant({quadrant:location})}}function getQuadraticPointString(pointNumber,coord,strings,locale){const location=getCoordQuadrant(coord);const[x,y]=coord;switch(location){case "origin":return strings.srQuadraticPointOrigin({pointNumber:pointNumber});case "x-axis":case "y-axis":return strings.srQuadraticPointAxis({pointNumber:pointNumber,x:srFormatNumber(x,locale),y:srFormatNumber(y,locale)});default:return strings.srQuadraticPointQuadrant({pointNumber:pointNumber,quadrant:location,x:srFormatNumber(x,locale),y:srFormatNumber(y,locale)})}}function getQuadraticXIntercepts(a,b,c){if(a===0){if(b===0){return []}return [-c/b]}const discriminant=b*b-4*a*c;if(discriminant<0){return []}const x1=(-b+Math.sqrt(discriminant))/(2*a);const x2=(-b-Math.sqrt(discriminant))/(2*a);if(x1===x2){return [x1]}return [x1,x2]}function getAngleFromPoints(points,i){if(i<0||i>=points.length||!Number.isInteger(i)){return null}if(points.length<3){return null}const point=points.at(i);const pt1=points.at(i-1);const pt2=points[(i+1)%points.length];if(!point||!pt1||!pt2){return null}const a=vec.dist(point,pt1);const b=vec.dist(point,pt2);const c=vec.dist(pt1,pt2);let lawOfCosinesRadicand=(a**2+b**2-c**2)/(2*a*b);if(lawOfCosinesRadicand<-1||lawOfCosinesRadicand>1){lawOfCosinesRadicand=Math.round(lawOfCosinesRadicand);}const angle=Math.acos(lawOfCosinesRadicand);return angle}function getSideLengthsFromPoints(points,i,isPolygonOpen){if(i<0||i>=points.length||!Number.isInteger(i)){return []}if(points.length<2){return []}const returnArray=[];const point=points[i];const point1Index=i===0?points.length-1:i-1;const point1=points[point1Index];const side1=i!==point1Index?vec.dist(point,point1):null;if(side1&&!(isPolygonOpen&&i===0)){returnArray.push({pointIndex:point1Index,sideLength:side1});}const point2Index=(i+1)%points.length;const point2=points[point2Index];const side2=i!==point2Index&&point2Index!==point1Index?vec.dist(point,point2):null;if(side2&&!(isPolygonOpen&&i===points.length-1)){returnArray.push({pointIndex:point2Index,sideLength:side2});}return returnArray}function getPolygonSideString(sideLength,pointIndex,strings,locale){return Number.isInteger(sideLength)?strings.srPolygonSideLength({pointNum:pointIndex+1,length:`${sideLength}`}):strings.srPolygonSideLengthApprox({pointNum:pointIndex+1,length:srFormatNumber(sideLength,locale,1)})}function calculateScaledRadius(range){const[[xMin,xMax],[yMin,yMax]]=range;const xSpan=xMax-xMin;const ySpan=yMax-yMin;const minSpan=Math.min(xSpan,ySpan);return minSpan*.06}
|
|
1897
1897
|
|
|
1898
|
-
const{calculateAngleInDegrees: calculateAngleInDegrees$2}=angles;const LockedLine=props=>{const{color
|
|
1898
|
+
const{calculateAngleInDegrees: calculateAngleInDegrees$2}=angles;const LockedLine=props=>{const{color,lineStyle,kind,points,showPoint1,showPoint2,weight,ariaLabel,range}=props;const[point1,point2]=points;const hasAria=!!ariaLabel;let line;if(kind==="ray"){const extendedPoint=getIntersectionOfRayWithBox(point1.coord,point2.coord,range);line=jsxRuntimeExports.jsx(Vector,{tail:point1.coord,tip:extendedPoint,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight],style:{strokeDasharray:lineStyle==="dashed"?"var(--mafs-line-stroke-dash-style)":undefined}});}else {const LineType=kind==="segment"?Line$4.Segment:Line$4.ThroughPoints;let arrowTip=kind==="segment"?point2.coord:getIntersectionOfRayWithBox(point1.coord,point2.coord,range);const[tailPx,tipPx]=useTransformVectorsToPixels(point2.coord,point1.coord);const direction=vec.sub(tailPx,tipPx);let angle=calculateAngleInDegrees$2(direction);const startArrowHead=kind!=="segment"&&jsxRuntimeExports.jsx(Arrowhead,{angle:angle,tip:arrowTip,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight]});arrowTip=kind==="segment"?point1.coord:getIntersectionOfRayWithBox(point2.coord,point1.coord,range);angle=angle>180?angle-180:angle+180;const endArrowHead=kind!=="segment"&&jsxRuntimeExports.jsx(Arrowhead,{angle:angle,tip:arrowTip,color:lockedFigureColors[color],strokeWidth:strokeWeights[weight]});line=jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[startArrowHead,jsxRuntimeExports.jsx(LineType,{point1:point1.coord,point2:point2.coord,color:lockedFigureColors[color],weight:strokeWeights[weight],style:lineStyle}),endArrowHead]});}return jsxRuntimeExports.jsxs("g",{className:kind==="ray"?"locked-ray":"locked-line","aria-label":hasAria?ariaLabel:undefined,"aria-hidden":!hasAria,role:"img",children:[line,showPoint1&&jsxRuntimeExports.jsx(Point$2,{x:point1.coord[X],y:point1.coord[Y],svgCircleProps:{style:{fill:point1.filled?lockedFigureColors[point1.color]:semanticColor.core.background.base.default,stroke:lockedFigureColors[point1.color],strokeWidth:spacing.xxxxSmall_2}}}),showPoint2&&jsxRuntimeExports.jsx(Point$2,{x:point2.coord[X],y:point2.coord[Y],svgCircleProps:{style:{fill:point2.filled?lockedFigureColors[point2.color]:semanticColor.core.background.base.default,stroke:lockedFigureColors[point2.color],strokeWidth:spacing.xxxxSmall_2}}})]})};
|
|
1899
1899
|
|
|
1900
|
-
const LockedPoint=props=>{const{color
|
|
1900
|
+
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}}})})};
|
|
1901
1901
|
|
|
1902
|
-
const LockedPolygon=props=>{const{points,color
|
|
1902
|
+
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",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}`))]})};
|
|
1903
1903
|
|
|
1904
1904
|
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]})})};
|
|
1905
1905
|
|
|
@@ -1911,11 +1911,11 @@ const MafsCssTransformWrapper=({children})=>jsxRuntimeExports.jsx("g",{style:{tr
|
|
|
1911
1911
|
|
|
1912
1912
|
const TextLabel=({children,...rest})=>jsxRuntimeExports.jsx(Text$2,{size:16,svgTextProps:{filter:"url(#background)",fontWeight:"bold"},...rest,children:children});const SvgDefs=()=>jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:"#FFF",floodOpacity:"0.64"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})});
|
|
1913
1913
|
|
|
1914
|
-
const{clockwise: clockwise$1}=geometry;const{getAngleFromVertex: getAngleFromVertex$1}=angles;const PolygonAngle=({centerPoint,endPoints,showAngles,snapTo,areEndPointsClockwise})=>{const{range}=useGraphConfig();const[centerX,centerY]=centerPoint;const[[startX,startY],[endX,endY]]=areEndPointsClockwise?endPoints:endPoints.reverse();const radius=calculateScaledRadius(range);const a=vec.dist(centerPoint,endPoints[0]);const b=vec.dist(centerPoint,endPoints[1]);const c=vec.dist(endPoints[0],endPoints[1]);let lawOfCosinesRadicand=(a**2+b**2-c**2)/(2*a*b);if(lawOfCosinesRadicand<-1||lawOfCosinesRadicand>1){lawOfCosinesRadicand=Math.round(lawOfCosinesRadicand);}const angle=Math.acos(lawOfCosinesRadicand);const y1=centerY+(startY-centerY)/a*radius;const x2=centerX+(endX-centerX)/b*radius;const x1=centerX+(startX-centerX)/a*radius;const y2=centerY+(endY-centerY)/b*radius;const[x3,y3]=vec.add(centerPoint,vec.add(vec.sub([x1,y1],centerPoint),vec.sub([x2,y2],centerPoint)));if(!showAngles){return isRightPolygonAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],nonScalingStroke:true}):null}const isConcave=isConcavePolygonVertex(centerPoint,endPoints);const largeArcFlag=isConcave?1:0;const arc=`M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}`;let angleInDegrees=angle*(180/Math.PI);if(isConcave){angleInDegrees=360-angleInDegrees;}const angleLabelNumber=parseFloat(angleInDegrees.toFixed(snapTo==="angles"?0:1));const angleLabel=Number.isInteger(angleLabelNumber)?angleLabelNumber:"≈ "+angleLabelNumber;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:"#FFF",floodOpacity:"0.5"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})}),!isConcave&&isRightPolygonAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],nonScalingStroke:true}):jsxRuntimeExports.jsx(Arc,{arc:arc,nonScalingStroke:true}),jsxRuntimeExports.jsxs(TextLabel,{x:x3,y:y3,attach:y3-centerY>0?"s":"n",attachDistance:Math.abs(y3-centerY)<.2||vec.dist([x3,y3],centerPoint)<.3?20:10,children:[angleLabel,"°"]})]})};const Angle=({vertex,coords,showAngles,allowReflexAngles,range})=>{const areClockwise=clockwise$1([...coords,vertex]);const shouldReverseCoords=areClockwise&&!allowReflexAngles;const clockwiseCoords=shouldReverseCoords?coords:coords.reverse();const startAngle=getAngleFromVertex$1(clockwiseCoords[0],vertex);const endAngle=getAngleFromVertex$1(clockwiseCoords[1],vertex);const angle=(startAngle+360-endAngle)%360;const isReflexive=angle>180;const[centerX,centerY]=vertex;const[point1,point2]=clockwiseCoords;const[startX,startY]=point1;const[endX,endY]=point2;const a=vec.dist(vertex,point1);const b=vec.dist(vertex,point2);const radius=2;const y1=centerY+(startY-centerY)/a*radius;const x2=centerX+(endX-centerX)/b*radius;const x1=centerX+(startX-centerX)/a*radius;const y2=centerY+(endY-centerY)/b*radius;const[x3,y3]=vec.add(vertex,vec.add(vec.sub([x1,y1],vertex),vec.sub([x2,y2],vertex)));const isOutside=shouldDrawArcOutside([x3,y3],vertex,range,[[vertex,point1],[vertex,point2]]);const largeArcFlag=isOutside||isReflexive?1:0;const sweepFlag=isOutside&&isReflexive?1:0;const arc=`M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;const angleLabel=parseFloat(angle.toFixed(0));const[textX,textY]=calculateBisectorPoint(point1,point2,vertex,isReflexive,allowReflexAngles,radius);const{disableKeyboardInteraction}=useGraphConfig();const arcClassName=disableKeyboardInteraction?"angle-arc-static":"angle-arc-interactive";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:"#FFF",floodOpacity:"0.5"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})}),isRightAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],className:arcClassName}):jsxRuntimeExports.jsx(Arc,{arc:arc,className:arcClassName}),showAngles&&jsxRuntimeExports.jsxs(TextLabel,{x:textX,y:textY,color:
|
|
1914
|
+
const{clockwise: clockwise$1}=geometry;const{getAngleFromVertex: getAngleFromVertex$1}=angles;const PolygonAngle=({centerPoint,endPoints,showAngles,snapTo,areEndPointsClockwise})=>{const{range}=useGraphConfig();const[centerX,centerY]=centerPoint;const[[startX,startY],[endX,endY]]=areEndPointsClockwise?endPoints:endPoints.reverse();const radius=calculateScaledRadius(range);const a=vec.dist(centerPoint,endPoints[0]);const b=vec.dist(centerPoint,endPoints[1]);const c=vec.dist(endPoints[0],endPoints[1]);let lawOfCosinesRadicand=(a**2+b**2-c**2)/(2*a*b);if(lawOfCosinesRadicand<-1||lawOfCosinesRadicand>1){lawOfCosinesRadicand=Math.round(lawOfCosinesRadicand);}const angle=Math.acos(lawOfCosinesRadicand);const y1=centerY+(startY-centerY)/a*radius;const x2=centerX+(endX-centerX)/b*radius;const x1=centerX+(startX-centerX)/a*radius;const y2=centerY+(endY-centerY)/b*radius;const[x3,y3]=vec.add(centerPoint,vec.add(vec.sub([x1,y1],centerPoint),vec.sub([x2,y2],centerPoint)));if(!showAngles){return isRightPolygonAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],nonScalingStroke:true}):null}const isConcave=isConcavePolygonVertex(centerPoint,endPoints);const largeArcFlag=isConcave?1:0;const arc=`M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2}`;let angleInDegrees=angle*(180/Math.PI);if(isConcave){angleInDegrees=360-angleInDegrees;}const angleLabelNumber=parseFloat(angleInDegrees.toFixed(snapTo==="angles"?0:1));const angleLabel=Number.isInteger(angleLabelNumber)?angleLabelNumber:"≈ "+angleLabelNumber;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:"#FFF",floodOpacity:"0.5"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})}),!isConcave&&isRightPolygonAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],nonScalingStroke:true}):jsxRuntimeExports.jsx(Arc,{arc:arc,nonScalingStroke:true}),jsxRuntimeExports.jsxs(TextLabel,{x:x3,y:y3,attach:y3-centerY>0?"s":"n",attachDistance:Math.abs(y3-centerY)<.2||vec.dist([x3,y3],centerPoint)<.3?20:10,children:[angleLabel,"°"]})]})};const Angle=({vertex,coords,showAngles,allowReflexAngles,range})=>{const areClockwise=clockwise$1([...coords,vertex]);const shouldReverseCoords=areClockwise&&!allowReflexAngles;const clockwiseCoords=shouldReverseCoords?coords:coords.reverse();const startAngle=getAngleFromVertex$1(clockwiseCoords[0],vertex);const endAngle=getAngleFromVertex$1(clockwiseCoords[1],vertex);const angle=(startAngle+360-endAngle)%360;const isReflexive=angle>180;const[centerX,centerY]=vertex;const[point1,point2]=clockwiseCoords;const[startX,startY]=point1;const[endX,endY]=point2;const a=vec.dist(vertex,point1);const b=vec.dist(vertex,point2);const radius=2;const y1=centerY+(startY-centerY)/a*radius;const x2=centerX+(endX-centerX)/b*radius;const x1=centerX+(startX-centerX)/a*radius;const y2=centerY+(endY-centerY)/b*radius;const[x3,y3]=vec.add(vertex,vec.add(vec.sub([x1,y1],vertex),vec.sub([x2,y2],vertex)));const isOutside=shouldDrawArcOutside([x3,y3],vertex,range,[[vertex,point1],[vertex,point2]]);const largeArcFlag=isOutside||isReflexive?1:0;const sweepFlag=isOutside&&isReflexive?1:0;const arc=`M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;const angleLabel=parseFloat(angle.toFixed(0));const[textX,textY]=calculateBisectorPoint(point1,point2,vertex,isReflexive,allowReflexAngles,radius);const{disableKeyboardInteraction}=useGraphConfig();const arcClassName=disableKeyboardInteraction?"angle-arc-static":"angle-arc-interactive";return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx("defs",{children:jsxRuntimeExports.jsxs("filter",{id:"background",x:"-5%",width:"110%",y:"0%",height:"100%",children:[jsxRuntimeExports.jsx("feFlood",{floodColor:"#FFF",floodOpacity:"0.5"}),jsxRuntimeExports.jsx("feComposite",{operator:"over",in:"SourceGraphic"})]})}),isRightAngle(angle)?jsxRuntimeExports.jsx(RightAngleSquare,{start:[x1,y1],vertex:[x2,y2],end:[x3,y3],className:arcClassName}):jsxRuntimeExports.jsx(Arc,{arc:arc,className:arcClassName}),showAngles&&jsxRuntimeExports.jsxs(TextLabel,{x:textX,y:textY,color:semanticColor.core.foreground.instructive.default,children:[angleLabel,"°"]})]})};const RightAngleSquare=({start:[x1,y1],vertex:[x2,y2],end:[x3,y3],className,nonScalingStroke})=>jsxRuntimeExports.jsx(MafsCssTransformWrapper,{children:jsxRuntimeExports.jsx("path",{"aria-hidden":true,d:`M ${x1} ${y1} L ${x3} ${y3} M ${x3} ${y3} L ${x2} ${y2}`,strokeWidth:1,fill:"none",className:className,"data-testid":"angle-indicators__right-angle",vectorEffect:nonScalingStroke?"non-scaling-stroke":"none"})});const Arc=({arc,className,nonScalingStroke})=>{return jsxRuntimeExports.jsx(MafsCssTransformWrapper,{children:jsxRuntimeExports.jsx("path",{"aria-hidden":true,d:arc,strokeWidth:1,fill:"none",className:className,"data-testid":"angle-indicators__arc",vectorEffect:nonScalingStroke?"non-scaling-stroke":"none"})})};const isRightPolygonAngle=angle=>Math.abs(angle-Math.PI/2)<.01;const isRightAngle=angle=>Math.round(angle)===90;const shouldDrawArcOutside=(midpoint,vertex,range,polygonLines)=>{const rangeIntersectionPoint=getIntersectionOfRayWithBox(midpoint,vertex,range);let lineIntersectionCount=0;polygonLines.forEach(line=>segmentsIntersect([vertex,rangeIntersectionPoint],line)&&lineIntersectionCount++);return !isEven(lineIntersectionCount)};const isEven=n=>n%2===0;function isConcavePolygonVertex(centerPoint,clockwiseEndpoints){const v1=vec.sub(clockwiseEndpoints[1],centerPoint);const v2=vec.sub(clockwiseEndpoints[0],centerPoint);const crossProduct=v1[0]*v2[1]-v1[1]*v2[0];return crossProduct>0}function calculateBisectorPoint(point1,point2,vertex,isReflex,allowReflex,arcRadius){const[originX,originY]=vertex;const[x1,y1]=point1;const[x2,y2]=point2;const vectorA=[x1-originX,y1-originY];const vectorB=[x2-originX,y2-originY];const angleA=Math.atan2(vectorA[1],vectorA[0]);const angleB=Math.atan2(vectorB[1],vectorB[0]);let averageAngle=(angleA+angleB)/2;const angleRadians=Math.abs(angleA-angleB);if(allowReflex){if(angleRadians<=Math.PI&&isReflex||angleB>angleA){averageAngle+=Math.PI;}}else {if(angleRadians>Math.PI){averageAngle-=Math.PI;}}const sum=[Math.cos(averageAngle),Math.sin(averageAngle)];const sumMagnitude=Math.sqrt(sum[0]**2+sum[1]**2);const bisectorDirection=[sum[0]/sumMagnitude,sum[1]/sumMagnitude];const initialDistance=Math.sqrt(bisectorDirection[0]**2+bisectorDirection[1]**2);const requiredDistance=arcRadius*1.75;let radius=requiredDistance/initialDistance;if(initialDistance>=requiredDistance){radius=1;}const bisectorPoint=[bisectorDirection[0]*radius,bisectorDirection[1]*radius];const scaledBisector=vec.add(bisectorPoint,vertex);return scaledBisector}
|
|
1915
1915
|
|
|
1916
1916
|
function useDraggable(args){const{gestureTarget:target,onMove,onDragEnd,point,constrainKeyboardMovement}=args;const[dragging,setDragging]=React.useState(false);const{xSpan,ySpan}=useSpanContext();const{viewTransform,userTransform}=useTransformContext();const inverseViewTransform=vec.matrixInvert(viewTransform);invariant(inverseViewTransform,"The view transform must be invertible.");const inverseTransform=React.useMemo(()=>getInverseTransform(userTransform),[userTransform]);const pickup=React.useRef([0,0]);useDrag(state=>{const{type,event}=state;event?.stopPropagation();const isKeyboard=type.includes("key");if(isKeyboard){invariant(event instanceof KeyboardEvent);event?.preventDefault();if(type==="keyup"){return}if(typeof constrainKeyboardMovement==="object"){const destination=constrainKeyboardMovement[directionForKey[event.key]];onMove(destination??point);return}const{direction:yDownDirection,altKey,ctrlKey,metaKey,shiftKey}=state;const direction=[yDownDirection[X],-yDownDirection[Y]];const span=Math.abs(direction[X])?xSpan:ySpan;let divisions=50;if(altKey||metaKey){divisions=200;}if(shiftKey&&!ctrlKey){divisions=10;}const min=span/(divisions*2);const tests=range(span/divisions,span/2,span/divisions);for(const dx of tests){const testMovement=vec.scale(direction,dx);const testPoint=constrainKeyboardMovement(vec.transform(vec.add(vec.transform(point,userTransform),testMovement),inverseTransform));if(vec.dist(testPoint,point)>min){onMove(testPoint);break}}}else {const{last,movement:pixelMovement,first}=state;setDragging(!last);if(last&&onDragEnd){onDragEnd();}if(first){pickup.current=vec.transform(point,userTransform);}if(vec.mag(pixelMovement)===0){return}const zoomFactor=target.current?getCSSZoomFactor(target.current):1;const unzoomedPixelMovement=vec.scale(pixelMovement,1/zoomFactor);const movement=vec.transform(unzoomedPixelMovement,inverseViewTransform);onMove(vec.transform(vec.add(pickup.current,movement),inverseTransform));}},{target,eventOptions:{passive:false}});return {dragging}}const directionForKey={ArrowLeft:"left",ArrowRight:"right",ArrowUp:"up",ArrowDown:"down"};function getInverseTransform(transform){const invert=vec.matrixInvert(transform);invariant(invert!==null,"Could not invert transform matrix. A parent transformation matrix might be degenerative (mapping 2D space to a line).");return invert}function useSpanContext(){const{range:[[xMin,xMax],[yMin,yMax]]}=useGraphConfig();const xSpan=xMax-xMin;const ySpan=yMax-yMin;return {xSpan,ySpan}}function range(min,max,step=1){const result=[];for(let i=min;i<max-step/2;i+=step){result.push(i);}const computedMax=result[result.length-1]+step;if(Math.abs(max-computedMax)<step/1e-6){result.push(max);}else {result.push(computedMax);}return result}
|
|
1917
1917
|
|
|
1918
|
-
function Hairlines(props){const{point}=props;const{range}=useGraphConfig();const[[xMin,xMax],[yMin,yMax]]=range;const[[x,y]]=useTransformVectorsToPixels(point);const[[verticalStartX]]=useTransformVectorsToPixels([xMin,0]);const[[verticalEndX]]=useTransformVectorsToPixels([xMax,0]);const[[_,horizontalStartY]]=useTransformVectorsToPixels([0,yMin]);const[[__,horizontalEndY]]=useTransformVectorsToPixels([0,yMax]);return jsxRuntimeExports.jsxs("g",{"aria-hidden":true,children:[jsxRuntimeExports.jsx("line",{x1:verticalStartX,y1:y,x2:verticalEndX,y2:y,stroke:
|
|
1918
|
+
function Hairlines(props){const{point}=props;const{range}=useGraphConfig();const[[xMin,xMax],[yMin,yMax]]=range;const[[x,y]]=useTransformVectorsToPixels(point);const[[verticalStartX]]=useTransformVectorsToPixels([xMin,0]);const[[verticalEndX]]=useTransformVectorsToPixels([xMax,0]);const[[_,horizontalStartY]]=useTransformVectorsToPixels([0,yMin]);const[[__,horizontalEndY]]=useTransformVectorsToPixels([0,yMax]);return jsxRuntimeExports.jsxs("g",{"aria-hidden":true,children:[jsxRuntimeExports.jsx("line",{x1:verticalStartX,y1:y,x2:verticalEndX,y2:y,stroke:semanticColor.core.border.instructive.default}),jsxRuntimeExports.jsx("line",{x1:x,y1:horizontalStartY,x2:x,y2:horizontalEndY,stroke:semanticColor.core.border.instructive.default})]})}
|
|
1919
1919
|
|
|
1920
1920
|
const hitboxSizePx=48;const MovablePointView=forwardRef(function MovablePointViewWithRef(props,hitboxRef){const{markings,showTooltips,interactiveColor,disableKeyboardInteraction,snapStep}=useGraphConfig();const{point,dragging,focused,cursor,showFocusRing,onClick=()=>{}}=props;const wbColorName=disableKeyboardInteraction?"fadedOffBlack64":"blue";const pointClasses=classNames("movable-point",dragging&&"movable-point--dragging",showFocusRing&&"movable-point--focus");const[[x,y]]=useTransformVectorsToPixels(point);const showHairlines=(dragging||focused)&&markings!=="none";const xSigFigs=countSignificantDecimals(snapStep[X]);const ySigFigs=countSignificantDecimals(snapStep[Y]);const xTickLabel=point[X].toFixed(xSigFigs);const yTickLabel=point[Y].toFixed(ySigFigs);const pointTooltipContent=`(${xTickLabel}, ${yTickLabel})`;const svgForPoint=jsxRuntimeExports.jsxs("g",{"aria-hidden":true,ref:hitboxRef,className:pointClasses,style:{"--movable-point-color":interactiveColor,cursor},"data-testid":"movable-point",onClick:onClick,children:[jsxRuntimeExports.jsx("circle",{className:"movable-point-hitbox",r:hitboxSizePx/2,cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-halo",cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-ring",cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-focus-outline",cx:x,cy:y}),jsxRuntimeExports.jsx("circle",{className:"movable-point-center",cx:x,cy:y,style:{fill:interactiveColor},"data-testid":"movable-point__center"})]});return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[showHairlines&&jsxRuntimeExports.jsx(Hairlines,{point:point}),showTooltips?jsxRuntimeExports.jsx(Tooltip,{autoUpdate:true,opened:true,backgroundColor:wbColorName,content:pointTooltipContent,contentStyle:{color:"white"},children:svgForPoint}):svgForPoint]})});function classNames(...names){return names.filter(Boolean).join(" ")}
|
|
1921
1921
|
|
|
@@ -1971,9 +1971,9 @@ const AnswerChoices=props=>{const{strings}=usePerseusI18n();const onAnswerChange
|
|
|
1971
1971
|
|
|
1972
1972
|
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(LabelMedium,{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",marginTop:"1em"}});
|
|
1973
1973
|
|
|
1974
|
-
const BringToFront={boxShadow:`0 8px 8px ${
|
|
1974
|
+
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:"#00880b"},incorrect:{backgroundColor:semanticColor.core.background.neutral.default},pill:{height:"auto"}});
|
|
1975
1975
|
|
|
1976
|
-
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:
|
|
1976
|
+
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:"#ECF3FE",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:"#00880b"},markerIncorrect:{background:semanticColor.core.background.neutral.default}});
|
|
1977
1977
|
|
|
1978
1978
|
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$1("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:"rgba(33, 36, 44, 0.32)",borderRadius:2}}},markersCanvas:{position:"relative"},imageContainer:{display:"flex"},imageInteractionDisabled:{pointerEvents:"none"}});
|
|
1979
1979
|
|
|
@@ -2009,7 +2009,7 @@ class PlaceholderCard extends React.Component{render(){return jsxRuntimeExports.
|
|
|
2009
2009
|
|
|
2010
2010
|
const getPromptJSON$4=()=>{return getUnsupportedPromptJSON("phet-simulation")};
|
|
2011
2011
|
|
|
2012
|
-
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);}}getPromptJSON(){return getPromptJSON$4()}async updateSimState(urlString){const url=makeSafeUrl(urlString,this.
|
|
2012
|
+
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}render(){const{isFullScreen,banner,url}=this.state;const{isMobileApp}=this.props.apiOptions;const isMobileAppFullscreen=isFullScreen&&isMobileApp;const containerStyle=isMobileAppFullscreen?{...styles$5.appFullScreenWidgetContainer}:styles$5.widgetContainer;const iframeContainerStyle=isMobileAppFullscreen?styles$5.appFullScreenIframeContainer:styles$5.iframeContainer;const sandboxProperties="allow-same-origin allow-scripts";return jsxRuntimeExports.jsxs(View,{style:containerStyle,children:[banner!==null&&jsxRuntimeExports.jsx(View,{style:{marginBottom:phoneMargin},children:jsxRuntimeExports.jsx(Banner,{kind:banner.kind,text:banner.message})}),isMobileAppFullscreen&&jsxRuntimeExports.jsx(View,{style:styles$5.closeButtonContainer,children:jsxRuntimeExports.jsx(IconButton,{icon:xIcon,onClick:this.toggleFullScreen,kind:"tertiary",actionType:"neutral","aria-label":"Exit fullscreen",style:styles$5.closeButton})}),jsxRuntimeExports.jsx(View,{style:iframeContainerStyle,children:jsxRuntimeExports.jsx("iframe",{ref:this.iframeRef,title:this.props.description,sandbox:sandboxProperties,className:css(styles$5.iframeResponsive),src:url?.toString(),allow:"fullscreen"})}),url!==null&&!isMobileAppFullscreen&&jsxRuntimeExports.jsx(IconButton,{icon:cornersOutIcon,onClick:isMobileApp?this.toggleFullScreen:()=>{this.iframeRef.current?.requestFullscreen();},kind:"tertiary",actionType:"neutral","aria-label":"Fullscreen",style:{marginTop:5,marginBottom:5,alignSelf:"flex-end"}})]})}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}));};}}PhetSimulation.contextType=PerseusI18nContext;const styles$5=StyleSheet.create({widgetContainer:{borderRadius:6,borderWidth:1,borderColor:"#CCC",padding:spacing.medium_16,paddingBottom:0},iframeContainer:{position:"relative",overflow:"hidden",width:"100%",paddingTop:"56.25%"},iframeResponsive:{borderWidth:0,position:"absolute",top:0,left:0,bottom:0,right:0,width:"100%",height:"100%"},appFullScreenWidgetContainer:{position:"fixed",top:0,left:0,right:0,bottom:MOBILE_APP_BOTTOM_BAR_HEIGHT,width:"100%",height:"auto",zIndex:1e3,backgroundColor:"white",display:"flex",flexDirection:"column"},appFullScreenIframeContainer:{position:"relative",overflow:"hidden",width:"100%",flex:1},closeButtonContainer:{position:"absolute",top:spacing.xSmall_8,right:spacing.xSmall_8,zIndex:1001},closeButton:{backgroundColor:"rgba(255, 255, 255, 0.8)",borderRadius:"50%"}});var PhetSimulation$1 = {name:"phet-simulation",displayName:"PhET Simulation",widget:PhetSimulation,isLintable:true};
|
|
2013
2013
|
|
|
2014
2014
|
const getPromptJSON$3=()=>{return getUnsupportedPromptJSON("plotter")};
|
|
2015
2015
|
|
|
@@ -2017,7 +2017,7 @@ const plotterDefaults=CoreWidgetRegistry.getDefaultWidgetOptions("plotter");clas
|
|
|
2017
2017
|
|
|
2018
2018
|
const getPromptJSON$2=()=>{return getUnsupportedPromptJSON("python-program")};
|
|
2019
2019
|
|
|
2020
|
-
function getUrlFromProgramID(programID){return `/python-program/${programID}/embedded`}class PythonProgram extends React.Component{getPromptJSON(){return getPromptJSON$2()}render(){let url=getUrlFromProgramID(this.props.programID);url=this.props.dependencies.generateUrl({url,context:"python_program:program_url"});const iframeStyle={height:this.props.height,width:"100%"};const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx(View,{style:styles$4.container,children:jsxRuntimeExports.jsx("iframe",{sandbox:sandboxOptions,src:url,style:iframeStyle,allowFullScreen:true})})}}PythonProgram.defaultProps={height:400};const styles$4=StyleSheet.create({container:{margin:"auto",width:"100%"}});const WrappedPythonProgram=withDependencies(PythonProgram);var PythonProgram$1 = {name:"python-program",displayName:"Python Program",widget:WrappedPythonProgram};
|
|
2020
|
+
function getUrlFromProgramID(programID){return `/python-program/${programID}/embedded`}class PythonProgram extends React.Component{getPromptJSON(){return getPromptJSON$2()}render(){let url=getUrlFromProgramID(this.props.programID);url=this.props.dependencies.generateUrl({url,context:"python_program:program_url",kaLocale:this.context?.locale});const iframeStyle={height:this.props.height,width:"100%"};const sandboxOptions=["allow-popups","allow-same-origin","allow-scripts","allow-top-navigation"].join(" ");return jsxRuntimeExports.jsx(View,{style:styles$4.container,children:jsxRuntimeExports.jsx("iframe",{sandbox:sandboxOptions,src:url,style:iframeStyle,allowFullScreen:true})})}}PythonProgram.contextType=PerseusI18nContext;PythonProgram.defaultProps={height:400};const styles$4=StyleSheet.create({container:{margin:"auto",width:"100%"}});const WrappedPythonProgram=withDependencies(PythonProgram);var PythonProgram$1 = {name:"python-program",displayName:"Python Program",widget:WrappedPythonProgram};
|
|
2021
2021
|
|
|
2022
2022
|
const getPromptJSON$1=userInput=>{return {type:"sorter",userInput:{values:userInput.options,changed:userInput.changed}}};
|
|
2023
2023
|
|
|
@@ -2029,13 +2029,13 @@ const getPromptJSON=()=>{return getUnsupportedPromptJSON("video")};
|
|
|
2029
2029
|
|
|
2030
2030
|
const IS_URL$1=/^https?:\/\//;const getYoutubeId=url=>{const regExp=/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;const match=url.match(regExp);if(match&&match[7].length===11){return match[7]}return "videoNotFound"};const VideoTranscriptLink=props=>{const{location}=props;const{useVideo}=useDependencies();const[id,kind]=IS_URL$1.test(location)?[getYoutubeId(location),"YOUTUBE_ID"]:[location,"READABLE_ID"];const result=useVideo(id,kind);const{strings}=usePerseusI18n();switch(result.status){case "loading":return jsxRuntimeExports.jsx(View,{children:strings.loading});case "success":{const video=result.data?.video;return jsxRuntimeExports.jsxs(View,{style:styles$3.transcriptLink,children:[jsxRuntimeExports.jsx(Text$1,{children:video?.title}),jsxRuntimeExports.jsx(Strut,{size:10}),jsxRuntimeExports.jsx(Link,{href:"/transcript/"+(video?.contentId||"videoNotFound"),target:"_blank",className:"visited-no-recolor",children:strings.videoTranscript})]})}case "error":return jsxRuntimeExports.jsx(View,{children:strings.somethingWrong});case "aborted":return jsxRuntimeExports.jsx(View,{children:strings.somethingWrong});default:return jsxRuntimeExports.jsx(View,{children:strings.somethingWrong})}};const styles$3=StyleSheet.create({transcriptLink:{flexDirection:"row",width:"100%",justifyContent:"center"}});
|
|
2031
2031
|
|
|
2032
|
-
const DEFAULT_WIDTH=1280;const DEFAULT_HEIGHT=720;const KA_EMBED="{host}/embed_video?slug={slug}"+"&internal_video_only=1";const IS_URL=/^https?:\/\//;const IS_KA_SITE=/(khanacademy\.org|localhost)/;const IS_VIMEO=/(vimeo\.com)/;class Video extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"video",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON()}render(){const{InitialRequestUrl}=getDependencies();const location=this.props.location;if(!location){return jsxRuntimeExports.jsx("div",{})}let url;if(IS_URL.test(location)){url=location;if(IS_VIMEO.test(url)){if(url.indexOf("?")===-1){url+="?dnt=1";}else {url+="&dnt=1";}}}else {url=KA_EMBED.replace("{slug}",location);let embedHostname="https://www.khanacademy.org";if(IS_KA_SITE.test(InitialRequestUrl.host)){embedHostname=InitialRequestUrl.origin;}url=url.replace("{host}",embedHostname);}url=this.props.dependencies.generateUrl({url,context:"video:video_url"});return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs(FixedToResponsive,{width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:[jsxRuntimeExports.jsx(View,{style:a11y.srOnly,children:this.context.strings.videoWrapper}),jsxRuntimeExports.jsx("iframe",{className:"perseus-video-widget",sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true,allow:"autoplay"})]},location+this.props.alignment),jsxRuntimeExports.jsx(VideoTranscriptLink,{location:location})]})}constructor(...args){super(...args),this.isWidget=true;}}Video.contextType=PerseusI18nContext;const WrappedVideo=withDependencies(Video);var Video$1 = {name:"video",displayName:"Video",widget:WrappedVideo};
|
|
2032
|
+
const DEFAULT_WIDTH=1280;const DEFAULT_HEIGHT=720;const KA_EMBED="{host}/embed_video?slug={slug}"+"&internal_video_only=1";const IS_URL=/^https?:\/\//;const IS_KA_SITE=/(khanacademy\.org|localhost)/;const IS_VIMEO=/(vimeo\.com)/;class Video extends React.Component{componentDidMount(){this.props.dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"video",widgetId:this.props.widgetId}});}getPromptJSON(){return getPromptJSON()}render(){const{InitialRequestUrl}=getDependencies();const location=this.props.location;if(!location){return jsxRuntimeExports.jsx("div",{})}let url;if(IS_URL.test(location)){url=location;if(IS_VIMEO.test(url)){if(url.indexOf("?")===-1){url+="?dnt=1";}else {url+="&dnt=1";}}}else {url=KA_EMBED.replace("{slug}",location);let embedHostname="https://www.khanacademy.org";if(IS_KA_SITE.test(InitialRequestUrl.host)){embedHostname=InitialRequestUrl.origin;}url=url.replace("{host}",embedHostname);}url=this.props.dependencies.generateUrl({url,context:"video:video_url",kaLocale:this.context.locale});return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs(FixedToResponsive,{width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:[jsxRuntimeExports.jsx(View,{style:a11y.srOnly,children:this.context.strings.videoWrapper}),jsxRuntimeExports.jsx("iframe",{className:"perseus-video-widget",sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true,allow:"autoplay"})]},location+this.props.alignment),jsxRuntimeExports.jsx(VideoTranscriptLink,{location:location})]})}constructor(...args){super(...args),this.isWidget=true;}}Video.contextType=PerseusI18nContext;const WrappedVideo=withDependencies(Video);var Video$1 = {name:"video",displayName:"Video",widget:WrappedVideo};
|
|
2033
2033
|
|
|
2034
2034
|
var extraWidgets = [CSProgram$1,Categorizer$1,Definition$1,DeprecatedStandin$1,Dropdown$1,Explanation$1,FreeResponse$1,GradedGroup$1,GradedGroupSet$1,Grapher$1,Group$1,Iframe$1,Image$1,Interactive,InteractiveGraph$1,LabelImage$1,Matcher$1,Matrix$1,Measurer$1,Molecule$1,NumberLine$1,Orderer$1,PhetSimulation$1,Plotter$1,PythonProgram$1,Sorter$1,Table$1,Video$1];
|
|
2035
2035
|
|
|
2036
2036
|
const init=function(){registerWidgets(basicWidgets);registerWidgets(extraWidgets);replaceDeprecatedWidgets();};
|
|
2037
2037
|
|
|
2038
|
-
const libName="@khanacademy/perseus";const libVersion="75.
|
|
2038
|
+
const libName="@khanacademy/perseus";const libVersion="75.4.1";addLibraryVersionToPerseusDebug(libName,libVersion);
|
|
2039
2039
|
|
|
2040
2040
|
const apiVersion={major:12,minor:0};
|
|
2041
2041
|
|