@khanacademy/perseus 91.1.1 → 92.0.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/{chunk-register-all-widgets-for-testing-Q8lpxOOR.js → chunk-register-all-widgets-for-testing-e-q2XfHc.js} +23 -41
- package/dist/chunk-register-all-widgets-for-testing-e-q2XfHc.js.map +1 -0
- package/dist/components/number-input.d.ts +66 -39
- package/dist/components/range-input.d.ts +39 -12
- package/dist/components/unsupported-widget-message.d.ts +14 -0
- package/dist/index.css +2 -2
- package/dist/index.css.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/question-paragraph.d.ts +2 -4
- package/dist/renderer.d.ts +201 -15
- package/dist/strings.d.ts +2 -2
- package/dist/strings.js +1 -1
- package/dist/strings.js.map +1 -1
- package/dist/testing.js +2 -2
- package/dist/testing.js.map +1 -1
- package/dist/util/register-all-widgets-for-testing.d.ts +1 -2
- package/dist/util/widget-enum-utils.d.ts +1 -1
- package/dist/util.d.ts +2 -3
- package/dist/widgets.d.ts +0 -30
- package/package.json +8 -8
- package/dist/chunk-register-all-widgets-for-testing-Q8lpxOOR.js.map +0 -1
- package/dist/perseus-markdown.new.d.ts +0 -11
- package/dist/question-paragraph.new.d.ts +0 -10
- package/dist/renderer.new.d.ts +0 -199
- package/dist/renderer.old.d.ts +0 -210
- package/dist/widget-container.old.d.ts +0 -24
- package/dist/widgets/deprecated-standin/deprecated-standin.d.ts +0 -9
- package/dist/widgets/deprecated-standin/index.d.ts +0 -1
- /package/dist/{widget-container.new.d.ts → widget-container.d.ts} +0 -0
|
@@ -15,7 +15,7 @@ import PropTypes from 'prop-types';
|
|
|
15
15
|
import * as PerseusLinter from '@khanacademy/perseus-linter';
|
|
16
16
|
import { Rule } from '@khanacademy/perseus-linter';
|
|
17
17
|
import Tooltip, { TooltipContent } from '@khanacademy/wonder-blocks-tooltip';
|
|
18
|
-
import { PerseusError, Errors, isLabeledSVG, getDataUrl, getSvgUrl, getBaseUrl, getRealImageUrl, getImageSizeModern, CoreWidgetRegistry, approximateDeepEqual, pluck, getWidgetIdsFromContentByType, Registry, mapObject, excludeDenylistKeys, applyDefaultsToWidgets, splitPerseusItem, getDefaultAnswerArea,
|
|
18
|
+
import { PerseusError, Errors, isLabeledSVG, getDataUrl, getSvgUrl, getBaseUrl, getRealImageUrl, getImageSizeModern, CoreWidgetRegistry, approximateDeepEqual, pluck, getWidgetIdsFromContentByType, Registry, mapObject, excludeDenylistKeys, applyDefaultsToWidgets, splitPerseusItem, getDefaultAnswerArea, shuffle, usesNumCorrect, isFeatureOn, approximateEqual, lockedFigureColors, lockedFigureFillStyles, GrapherUtil, convertGrapherOptionsToInteractiveGraph, convertGrapherUserInputToInteractiveGraph, convertInteractiveGraphUserInputToGrapher, deepClone, shuffleMatcher, getMatrixSize, makeSafeUrl, SORTER_MAX_HORIZONTAL_CARDS, exceedsCardLimit, shuffleSorter } from '@khanacademy/perseus-core';
|
|
19
19
|
import { TextField, TextArea } from '@khanacademy/wonder-blocks-form';
|
|
20
20
|
import { KhanAnswerTypes, emptyWidgetsFunctional, scoreWidgetsFunctional, flattenScores, scoreLabelImageMarker } from '@khanacademy/perseus-score';
|
|
21
21
|
import * as ReactDOM from 'react-dom';
|
|
@@ -34,6 +34,7 @@ import SimpleMarkdown from '@khanacademy/simple-markdown';
|
|
|
34
34
|
import { pureMarkdownRules, traverseContent } from '@khanacademy/pure-markdown';
|
|
35
35
|
import dotOutlineIcon from '@phosphor-icons/core/fill/dot-outline-fill.svg';
|
|
36
36
|
import warningCircleIcon from '@phosphor-icons/core/fill/warning-circle-fill.svg';
|
|
37
|
+
import Banner from '@khanacademy/wonder-blocks-banner';
|
|
37
38
|
import { announceMessage } from '@khanacademy/wonder-blocks-announcer';
|
|
38
39
|
import caretLeftIcon from '@phosphor-icons/core/regular/caret-left.svg';
|
|
39
40
|
import caretRightIcon from '@phosphor-icons/core/regular/caret-right.svg';
|
|
@@ -41,7 +42,6 @@ import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
|
|
|
41
42
|
import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
|
|
42
43
|
import minusIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
|
|
43
44
|
import { useDroppable, useDragOperation } from '@dnd-kit/react';
|
|
44
|
-
import Banner from '@khanacademy/wonder-blocks-banner';
|
|
45
45
|
import { OptionItem, SingleSelect, MultiSelect } from '@khanacademy/wonder-blocks-dropdown';
|
|
46
46
|
import Button from '@khanacademy/wonder-blocks-button';
|
|
47
47
|
import caretDown from '@phosphor-icons/core/regular/caret-down.svg';
|
|
@@ -1416,7 +1416,7 @@ var a11y = StyleSheet.create({srOnly:{border:0,clip:"rect(0,0,0,0)",height:1,mar
|
|
|
1416
1416
|
|
|
1417
1417
|
const debounce=(func,delay)=>{let timer=null;return (...args)=>{if(timer){clearTimeout(timer);}timer=window.setTimeout(()=>{func(...args);},delay);}};
|
|
1418
1418
|
|
|
1419
|
-
class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.ariaRequired!==this.props.ariaRequired){this.updateAriaRequired();}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});}updateAriaRequired(){const textarea=this.__mathFieldWrapperRef?.querySelector("textarea");if(this.props.ariaRequired){textarea?.setAttribute("aria-required","true");}else {textarea?.removeAttribute("aria-required");}}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$
|
|
1419
|
+
class InnerMathInput extends React.Component{componentDidMount(){this.mathField()?.latex(this.props.value);}componentDidUpdate(prevProps){if(prevProps.ariaRequired!==this.props.ariaRequired){this.updateAriaRequired();}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});}updateAriaRequired(){const textarea=this.__mathFieldWrapperRef?.querySelector("textarea");if(this.props.ariaRequired){textarea?.setAttribute("aria-required","true");}else {textarea?.removeAttribute("aria-required");}}render(){let className=classNames$2({"perseus-math-input":true,"mq-editable-field":true,"mq-math-mode":true});const popoverContentUniqueId=v4().slice(0,8);if(this.props.className){className=className+" "+this.props.className;}return jsxRuntimeExports.jsx(View,{style:[styles$z.outerWrapper,this.state.focused&&styles$z.wrapperFocused],children:jsxRuntimeExports.jsxs("div",{style:{display:"flex",alignItems:"center",padding:1},onClick:e=>{e.stopPropagation();const mathField=this.mathField();if(!mathField){return}this.setState({cursorContext:getCursorContext(mathField)});},children:[jsxRuntimeExports.jsx("span",{className:className,ref:ref=>this.__mathFieldWrapperRef=ref,onFocus:()=>this.focus(),onBlur:()=>this.blur()}),jsxRuntimeExports.jsx(Popover,{opened:this.state.keypadOpen,dismissEnabled:true,rootBoundary:"document","aria-label":this.context.strings.mathInputTitle,"aria-describedby":`popover-content-${popoverContentUniqueId}`,onClose:()=>this.closeKeypad(),content:()=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{size:"large",id:`popover-content-${popoverContentUniqueId}`,style:a11y.srOnly,children:this.context.strings.mathInputDescription}),jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$z.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,pressed:false}):jsxRuntimeExports.jsx(Clickable,{"aria-label":this.state.keypadOpen?this.context.strings.closeKeypad:this.context.strings.openKeypad,role:"button",hideDefaultFocusRing:true,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",cursorContext:CursorContext.NONE},this.insert=value=>{const input=this.mathField();const{locale}=this.context;const customKeyTranslator={...getKeyTranslator(locale,this.context.strings),FRAC:mathQuill=>{const contents=mathQuill.latex();mathQuill.typedText("/");if(mathQuill.latex()===contents){mathQuill.cmd("\\frac");}}};const inputModifier=customKeyTranslator[value];if(inputModifier){inputModifier(input,value);input?.focus();return}if(typeof value==="function"){value(input);}else if(value[0]==="\\"){input?.cmd(value).focus();}else {input?.write(value).focus();}input?.focus();},this.mathField=()=>{if(!this.__mathField&&this.__mathFieldWrapperRef){const{locale}=this.context;this.__mathField=createMathField(this.__mathFieldWrapperRef,locale,this.props.mathInputStrings,baseConfig=>({...baseConfig,handlers:{edit:debounce(mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(convertDotToTimesByLocale(locale,this.props.convertDotToTimes)){value=value.replace(/\\cdot/g,"\\times");const left=mathField.cursor()[mathQuillInstance.L];if(left&&left.ctrlSeq==="\\cdot "){mathField.controller().backspace();mathField.cmd("\\times");}}else {value=value.replace(/\\times/g,"\\cdot");}if(this.props.value!==value){this.props.onChange(value);}this.setState({cursorContext:getCursorContext(mathField)});},100),enter:()=>{if(this.__mathFieldWrapperRef){this.__mathFieldWrapperRef.dispatchEvent(new Event("submit",{bubbles:true,cancelable:true}));}},upOutOf:mathField=>{mathField.typedText("^");}}}));}this.__mathField?.setAriaLabel(this.props.ariaLabel);this.updateAriaRequired();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,pressed,active})=>{let fillColor;switch(true){case focused||pressed||active:fillColor=semanticColor.core.foreground.knockout.default;break;case hovered:fillColor=semanticColor.core.foreground.instructive.strong;break;default:fillColor=semanticColor.core.foreground.neutral.default;break}let dynamicClass;switch(true){case focused||pressed:dynamicClass=styles$z.iconActive;break;case active:dynamicClass=styles$z.iconExpanded;break;case hovered:dynamicClass=styles$z.iconHovered;break;default:dynamicClass=styles$z.iconInactive;}return jsxRuntimeExports.jsx(View,{style:[styles$z.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={borderColor:semanticColor.core.border.instructive.default};const styles$z=StyleSheet.create({iconContainer:{display:"flex",justifyContent:"center",height:"100%",padding:sizing.size_060,borderRadius:border$1.radius.radius_040,borderWidth:border$1.width.medium,borderStyle:"solid"},iconInactive:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.subtle},iconActive:{borderColor:semanticColor.focus.outer,boxShadow:`inset 0 0 0 ${border$1.width.medium} ${semanticColor.focus.inner}`,backgroundColor:semanticColor.core.background.neutral.default},iconExpanded:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.default},iconHovered:{borderColor:semanticColor.core.transparent,backgroundColor:semanticColor.core.background.neutral.subtle},outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:border$1.width.thin,borderColor:semanticColor.core.border.neutral.default,borderRadius:border$1.radius.radius_040,background:semanticColor.core.background.base.default,":hover":inputFocused},wrapperFocused:inputFocused,popoverContent:{padding:0,paddingBlockEnd:sizing.size_060,maxInlineSize:"initial"}});
|
|
1420
1420
|
|
|
1421
1421
|
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};
|
|
1422
1422
|
|
|
@@ -1432,7 +1432,7 @@ const ApiOptions={defaults:{isArticle:false,isMobile:false,isMobileApp:false,edi
|
|
|
1432
1432
|
|
|
1433
1433
|
const getPromptJSON$q=(label,userInput)=>{return {type:"expression",label,userInput:{value:userInput}}};
|
|
1434
1434
|
|
|
1435
|
-
const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};const defaultOnFocus=()=>{};const defaultOnBlur=()=>{};const KeypadInputWithInterface=React.forwardRef(function KeypadInputWithInterface(props,ref){const keypadInputRef=React.useRef(null);const noopKeypadActivation=_keypadActive=>{};React.useImperativeHandle(ref,()=>({focus:(cb=noopKeypadActivation)=>keypadInputRef.current?.focus(cb),blur:()=>keypadInputRef.current?.blur(),insert:val=>{keypadInputRef.current?.mathField?.pressKey?.(val);}}));return jsxRuntimeExports.jsx(KeypadInput,{ref:keypadInputRef,...props})});const Expression=forwardRef(function Expression(props,ref){const{apiOptions=ApiOptions.defaults,onFocus=defaultOnFocus,onBlur=defaultOnBlur,userInput="",keypadElement,handleUserInput,trackInteraction,widgetId,options:{buttonSets,times,extraKeys,visibleLabel,ariaLabel,buttonsVisible,functions},...rest}=props;const{strings}=usePerseusI18n();const{analytics}=useDependencies();const isRequired=props.isScorable&&!props.reviewMode&&!props.static&&!apiOptions.readOnly;const{setKeypadActive}=React.useContext(KeypadContext);const textareaId=useId();const inputRef=useRef(null);const rootRef=useRef(null);useEffect(()=>{analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"expression",widgetId}});if(rootRef.current){const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=rootRef.current.querySelector(selector);if(inputElement instanceof HTMLElement){inputElement.setAttribute("id",textareaId);}}},[]);const handleFocus=()=>{analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});onFocus([]);};const handleBlur=()=>{onBlur([]);};const changeAndTrack=(value,cb)=>{const normalized=normalizeTex(value);handleUserInput(normalized,cb);trackInteraction();};const mobileHandleFocus=()=>{keypadElement?.configure(getKeypadConfiguration(),()=>{if(rootRef.current){handleFocus();}});};const getKeypadConfiguration=useCallback(()=>{return {keypadType:"EXPRESSION",extraKeys:extraKeys,times:times}},[extraKeys,times]);const getFocusTarget=useCallback(()=>{if(!rootRef.current){return null}const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const element=rootRef.current.querySelector(selector);return element instanceof HTMLElement?element:null},[apiOptions.customKeypad]);useImperativeHandle(ref,()=>({focus:()=>{const targetBefore=getFocusTarget();inputRef.current?.focus?.(setKeypadActive);const targetAfter=getFocusTarget()??targetBefore??(document.activeElement instanceof HTMLElement?document.activeElement:null);if(!targetAfter){return false}if(document.activeElement!==targetAfter){targetAfter.focus();}return document.activeElement===targetAfter},focusInputPath:path=>{inputRef.current?.focus?.(setKeypadActive);},blurInputPath:path=>{if(typeof inputRef.current?.blur==="function"){inputRef.current?.blur();}},insert:keyPressed=>{inputRef.current?.insert?.(keyPressed);},getInputPaths:()=>[[]],getUserInput:()=>{return normalizeTex(userInput)},getKeypadConfiguration,getPromptJSON:()=>{return getPromptJSON$q(visibleLabel,normalizeTex(userInput))},getSerializedState:()=>{return {...rest,value:userInput,keypadConfiguration:getKeypadConfiguration(),times,buttonSets,buttonsVisible,functions}}}));const keypadConfiguration=getKeypadConfiguration();if(apiOptions.customKeypad){return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$
|
|
1435
|
+
const englishOperators={arctg:"arctan",cosec:"csc",cossec:"csc",cotg:"cot",ctg:"cot",sen:"sin",tg:"tan"};const anglicizeOperators=tex=>{return tex.replace(/\\operatorname{([a-z]+)}/g,(_,op)=>`\\${englishOperators[op]??op} `)};const normalizeTex=tex=>{return anglicizeOperators(tex)};const defaultOnFocus=()=>{};const defaultOnBlur=()=>{};const KeypadInputWithInterface=React.forwardRef(function KeypadInputWithInterface(props,ref){const keypadInputRef=React.useRef(null);const noopKeypadActivation=_keypadActive=>{};React.useImperativeHandle(ref,()=>({focus:(cb=noopKeypadActivation)=>keypadInputRef.current?.focus(cb),blur:()=>keypadInputRef.current?.blur(),insert:val=>{keypadInputRef.current?.mathField?.pressKey?.(val);}}));return jsxRuntimeExports.jsx(KeypadInput,{ref:keypadInputRef,...props})});const Expression=forwardRef(function Expression(props,ref){const{apiOptions=ApiOptions.defaults,onFocus=defaultOnFocus,onBlur=defaultOnBlur,userInput="",keypadElement,handleUserInput,trackInteraction,widgetId,options:{buttonSets,times,extraKeys,visibleLabel,ariaLabel,buttonsVisible,functions},...rest}=props;const{strings}=usePerseusI18n();const{analytics}=useDependencies();const isRequired=props.isScorable&&!props.reviewMode&&!props.static&&!apiOptions.readOnly;const{setKeypadActive}=React.useContext(KeypadContext);const textareaId=useId();const inputRef=useRef(null);const rootRef=useRef(null);useEffect(()=>{analytics?.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"expression",widgetId}});if(rootRef.current){const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const inputElement=rootRef.current.querySelector(selector);if(inputElement instanceof HTMLElement){inputElement.setAttribute("id",textareaId);}}},[]);const handleFocus=()=>{analytics?.onAnalyticsEvent({type:"perseus:expression-focused",payload:null});onFocus([]);};const handleBlur=()=>{onBlur([]);};const changeAndTrack=(value,cb)=>{const normalized=normalizeTex(value);handleUserInput(normalized,cb);trackInteraction();};const mobileHandleFocus=()=>{keypadElement?.configure(getKeypadConfiguration(),()=>{if(rootRef.current){handleFocus();}});};const getKeypadConfiguration=useCallback(()=>{return {keypadType:"EXPRESSION",extraKeys:extraKeys,times:times}},[extraKeys,times]);const getFocusTarget=useCallback(()=>{if(!rootRef.current){return null}const isMobile=apiOptions.customKeypad;const selector=isMobile?".mq-textarea > span":"textarea";const element=rootRef.current.querySelector(selector);return element instanceof HTMLElement?element:null},[apiOptions.customKeypad]);useImperativeHandle(ref,()=>({focus:()=>{const targetBefore=getFocusTarget();inputRef.current?.focus?.(setKeypadActive);const targetAfter=getFocusTarget()??targetBefore??(document.activeElement instanceof HTMLElement?document.activeElement:null);if(!targetAfter){return false}if(document.activeElement!==targetAfter){targetAfter.focus();}return document.activeElement===targetAfter},focusInputPath:path=>{inputRef.current?.focus?.(setKeypadActive);},blurInputPath:path=>{if(typeof inputRef.current?.blur==="function"){inputRef.current?.blur();}},insert:keyPressed=>{inputRef.current?.insert?.(keyPressed);},getInputPaths:()=>[[]],getUserInput:()=>{return normalizeTex(userInput)},getKeypadConfiguration,getPromptJSON:()=>{return getPromptJSON$q(visibleLabel,normalizeTex(userInput))},getSerializedState:()=>{return {...rest,value:userInput,keypadConfiguration:getKeypadConfiguration(),times,buttonSets,buttonsVisible,functions}}}));const keypadConfiguration=getKeypadConfiguration();if(apiOptions.customKeypad){return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$y.mobileLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx(KeypadInputWithInterface,{ref:inputRef,ariaLabel:ariaLabel||strings.mathInputBox,ariaRequired:isRequired,value:userInput,keypadElement:keypadElement,onChange:changeAndTrack,onFocus:mobileHandleFocus,onBlur:handleBlur})]})}return jsxRuntimeExports.jsxs(View,{ref:rootRef,style:styles$y.desktopLabelInputWrapper,children:[!!visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"small",htmlFor:textareaId,tag:"label",children:visibleLabel}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-expression",children:jsxRuntimeExports.jsx(MathInput,{ref:inputRef,value:userInput,onChange:changeAndTrack,convertDotToTimes:times,buttonSets:buttonSets,onFocus:handleFocus,onBlur:handleBlur,ariaLabel:ariaLabel||strings.mathInputBox,ariaRequired:isRequired,extraKeys:keypadConfiguration.extraKeys,onAnalyticsEvent:analytics?.onAnalyticsEvent??(async()=>{})})})]})});const styles$y=StyleSheet.create({mobileLabelInputWrapper:{paddingBlockStart:"15px",paddingInline:"4px",paddingBlockEnd:"0"},desktopLabelInputWrapper:{marginBlockStart:"5px",marginInline:"5px",marginBlockEnd:"0"}});function getUserInputFromSerializedState$i(serializedState){return normalizeTex(serializedState.value)}function getStartUserInput$i(){return ""}function getOneCorrectAnswerFromRubric$1(rubric){const correctAnswers=(rubric.answerForms||[]).filter(answerForm=>answerForm.considered==="correct");if(correctAnswers.length===0){return}return correctAnswers[0].value}function getCorrectUserInput$9(options){for(const form of options.answerForms){if(form.considered==="correct"){return form.value}}return ""}var Expression$1 = {name:"expression",displayName:"Expression / Equation",widget:Expression,isLintable:true,getOneCorrectAnswerFromRubric: getOneCorrectAnswerFromRubric$1,getStartUserInput: getStartUserInput$i,getCorrectUserInput: getCorrectUserInput$9,getUserInputFromSerializedState: getUserInputFromSerializedState$i};
|
|
1436
1436
|
|
|
1437
1437
|
class SimpleKeypadInput extends React.Component{componentDidMount(){this._isMounted=true;}componentWillUnmount(){this._isMounted=false;}focus(){this.inputRef.current?.focus(this.context.setKeypadActive);}blur(){this.inputRef.current?.blur();}getValue(){return this.props.value}render(){const _this=this;const{keypadElement,onFocus,value,...rest}=_this.props;return jsxRuntimeExports.jsx(KeypadInput,{ref:this.inputRef,keypadElement:keypadElement,onFocus:()=>{if(keypadElement){keypadElement.configure({keypadType:"FRACTION"},()=>{if(_this._isMounted){onFocus?.();}});}else {onFocus?.();}},value:value==null?"":""+value,...rest})}constructor(...args){super(...args),this._isMounted=false,this.inputRef=React.createRef();}}SimpleKeypadInput.contextType=KeypadContext;SimpleKeypadInput.propTypes={keypadElement:keypadElementPropType,onFocus:PropTypes.func,value:PropTypes.oneOfType([PropTypes.string,PropTypes.number])};
|
|
1438
1438
|
|
|
@@ -1442,7 +1442,7 @@ let lastId=0;function uniqueIdForInput(prefix="input-"){lastId++;return `${prefi
|
|
|
1442
1442
|
|
|
1443
1443
|
const defaultContext$1={assetStatuses:{},setAssetStatus:(assetKey,loaded)=>{}};const context=React.createContext(defaultContext$1);
|
|
1444
1444
|
|
|
1445
|
-
let supportsPassive=false;const nestedMap$2=function(children,func,context){if(Array.isArray(children)){return children.map(function(child){return nestedMap$2(child,func)})}return func.call(context,children)};function inputPathsEqual(a,b){if(a==null||b==null){return a==null===(b==null)}return a.length===b.length&&a.every((item,index)=>{return b[index]===item})}const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))]]/;const rTypeFromWidgetId=/^([a-z-]+) ([0-9]+)$/;const rWidgetParts=new RegExp(rWidgetRule.source+"$");const snowman="☃";const isBlockWidgetNode=node=>node?.type==="widget"&&!CoreWidgetRegistry.isInlineWidget(node.widgetType);const isParagraphWithBlockWidget=node=>node?.type==="paragraph"&&Array.isArray(node.content)&&node.content.some(isBlockWidgetNode);const inlineWidgetsToExclude=node=>{const widgetsToExclude=["dropdown","explanation","expression"];return node?.type==="widget"&&widgetsToExclude.includes(node.widgetType)};const nodeIsGraphie=node=>{return node.type==="image"&&node.target.startsWith("web+graphie:")};const isContentGraphie=node=>{return Array.isArray(node.content)&&node.content.some(nodeIsGraphie)};const noParagraphForInlineWidget=node=>Array.isArray(node.content)&&node.content.some(inlineWidgetsToExclude);const isWhitespaceOnlyTextNode=node=>node?.type==="text"&&node.content.trim()==="";const trimEdgeWhitespaceNodes=nodes=>{let start=0;let end=nodes.length;while(start<end&&isWhitespaceOnlyTextNode(nodes[start])){start++;}while(end>start&&isWhitespaceOnlyTextNode(nodes[end-1])){end--;}return nodes.slice(start,end)};const mergeInlineNodes=(inlineNodes,blockNodes,referenceNode)=>{const trimmedContentNodes=trimEdgeWhitespaceNodes(inlineNodes);if(trimmedContentNodes.length>0){blockNodes.push({...referenceNode,content:trimmedContentNodes});}};function joinAdjacentTextNodes(ast){if(!Array.isArray(ast)){return ast}const joined=[];for(const node of ast){const lastIndex=joined.length-1;if(node.type==="text"&&joined[lastIndex]?.type==="text"){joined[lastIndex].content+=node.content;}else {joined.push(node);}}return joined}function splitBlockWidgetsFromParagraphs(ast){if(!Array.isArray(ast)){return ast}return ast.flatMap(node=>{if(!isParagraphWithBlockWidget(node)){return node}const blockNodes=[];const inlineNodes=[];node.content.forEach(childNode=>{if(isBlockWidgetNode(childNode)){mergeInlineNodes(inlineNodes,blockNodes,node);blockNodes.push(childNode);inlineNodes.length=0;}else {inlineNodes.push(childNode);}});mergeInlineNodes(inlineNodes,blockNodes,node);return blockNodes})}function firstNumericalParse$1(text){let first;const val=KhanAnswerTypes.predicate.createValidatorFunctional(function(ans){first=ans;return true},{simplify:"optional",inexact:true,forms:"integer, proper, improper, pi, log, mixed, decimal"});val(text);return first}function stringArrayOfSize(size){return Array(size).fill("")}function stringArrayOfSize2D(opt){const{rows,columns}=opt;const rowArr=stringArrayOfSize(rows);return rowArr.map(()=>stringArrayOfSize(columns))}function gridDimensionConfig(absTickStep,extent,dimensionConstraint,gridStep){const scale=scaleFromExtent(extent,dimensionConstraint);const stepPx=absTickStep*scale;const unityLabel=stepPx>30;return {scale:scale,tickStep:absTickStep/gridStep,unityLabel:unityLabel}}function getGridStep(range,step,boxSize){return _(2).times(function(i){const scale=scaleFromExtent(range[i],boxSize);const gridStep=gridStepFromTickStep(step[i],scale);return gridStep})}function snapStepFromGridStep(gridStep){return [gridStep[0]/2,gridStep[1]/2]}function gridStepFromTickStep(tickStep,scale){const tickWidth=tickStep*scale;const x=tickStep;const y=Math.pow(10,Math.floor(Math.log(x)/Math.LN10));const leadingDigit=Math.floor(x/y);if(tickWidth<25){return tickStep}if(tickWidth<50){if(leadingDigit===5){return tickStep}return tickStep/2}if(leadingDigit===1){return tickStep/2}if(leadingDigit===2){return tickStep/4}if(leadingDigit===5){return tickStep/5}}function scaleFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];const scale=dimensionConstraint/span;return scale}function tickStepFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];let tickFactor;if(15<span&&span<=20){tickFactor=23;}else if(span>100||span<5){tickFactor=10;}else {tickFactor=16;}const constraintFactor=dimensionConstraint/500;const desiredNumTicks=tickFactor*constraintFactor;return tickStepFromNumTicks(span,desiredNumTicks)}function tickStepFromNumTicks(span,numTicks){let step=Math.pow(10,Math.floor(Math.log(span/numTicks)/Math.LN10));const err=numTicks/span*step;if(err<=.15){step*=10;}else if(err<=.35){step*=5;}else if(err<=.75){step*=2;}return step}const constrainTickStep=(step,range)=>{const span=range[1]-range[0];const numTicks=span/step;if(numTicks<=10){return step}if(numTicks<=20){return step*2}return tickStepFromNumTicks(span,10)};function constrainedTickStepsFromTickSteps(tickSteps,ranges){return [constrainTickStep(tickSteps[0],ranges[0]),constrainTickStep(tickSteps[1],ranges[1])]}function parseQueryString(query){query=query||window.location.search.substring(1);const urlParams={};const a=/\+/g;const r=/([^&=]+)=?([^&]*)/g;const d=function(s){return decodeURIComponent(s.replace(a," "))};let e;while(e=r.exec(query)){const m=e;urlParams[d(m[1])]=d(m[2]);}return urlParams}function updateQueryString$2(uri,key,value){value=encodeURIComponent(value);const re=new RegExp("([?&])"+key+"=.*?(&|$)","i");const separator=uri.indexOf("?")!==-1?"&":"?";if(uri.match(re)){return uri.replace(re,"$1"+key+"="+value+"$2")}return uri+separator+key+"="+value}function strongEncodeURIComponent(str){return encodeURIComponent(str).replace(/['()!]/g,window.escape).replace(/\*/g,"%2A")}const touchHandlers={pointerDown:false,currentTouchIdentifier:null};function resetTouchHandlers(){Object.assign(touchHandlers,{pointerDown:false,currentTouchIdentifier:null});}function extractPointerLocation(event){let touchOrEvent;if(touchHandlers.pointerDown){if(touchHandlers.currentTouchIdentifier!=null){const len=event.changedTouches?event.changedTouches.length:0;for(let i=0;i<len;i++){if(event.changedTouches[i].identifier===touchHandlers.currentTouchIdentifier){touchOrEvent=event.changedTouches[i];}}}else {touchOrEvent=event;}const isEndish=event.type==="touchend"||event.type==="touchcancel";if(touchOrEvent&&isEndish){touchHandlers.pointerDown=false;touchHandlers.currentTouchIdentifier=null;}}else {touchHandlers.pointerDown=true;if(event.changedTouches){touchOrEvent=event.changedTouches[0];touchHandlers.currentTouchIdentifier=touchOrEvent.identifier;}else {touchOrEvent=event;}}if(touchOrEvent){return {left:touchOrEvent.pageX,top:touchOrEvent.pageY}}}const supportsPassiveEvents=()=>{try{const opts=Object.defineProperty({},"passive",{get:function(){supportsPassive=true;}});window.addEventListener("testPassive",null,opts);window.removeEventListener("testPassive",null,opts);}catch{}return supportsPassive};function captureScratchpadTouchStart$2(e){e.stopPropagation();}function getImageSize(url,callback){const img=new Image;img.onload=function(){if(img.width===0&&img.height===0){document.body?.appendChild(img);_.defer(function(){callback(img.clientWidth,img.clientHeight);document.body?.removeChild(img);});}else {callback(img.width,img.height);}};img.src=getRealImageUrl(url);}function getWordBeforeCursor(textarea){const text=textarea.value;const endPos=textarea.selectionStart-1;const startPos=Math.max(text.lastIndexOf("\n",endPos),text.lastIndexOf(" ",endPos))+1;return {string:text.substring(startPos,endPos+1),pos:{start:startPos,end:endPos}}}function moveCursor(textarea,pos){textarea.selectionStart=pos;textarea.selectionEnd=pos;}const textarea={getWordBeforeCursor,moveCursor};const unescapeMathMode$1=label=>label.startsWith("$")&&label.endsWith("$")?label.slice(1,-1):label;const Util={inputPathsEqual,nestedMap: nestedMap$2,rWidgetRule,rTypeFromWidgetId,rWidgetParts,snowman,splitBlockWidgetsFromParagraphs,firstNumericalParse: firstNumericalParse$1,stringArrayOfSize,stringArrayOfSize2D,gridDimensionConfig,getGridStep,snapStepFromGridStep,scaleFromExtent,tickStepFromExtent,gridStepFromTickStep,tickStepFromNumTicks,constrainedTickStepsFromTickSteps,parseQueryString,updateQueryString: updateQueryString$2,strongEncodeURIComponent,touchHandlers,resetTouchHandlers,extractPointerLocation,supportsPassiveEvents,captureScratchpadTouchStart: captureScratchpadTouchStart$2,getImageSize,getImageSizeModern:getImageSizeModern,getRealImageUrl:getRealImageUrl,isLabeledSVG:isLabeledSVG,getBaseUrl:getBaseUrl,getSvgUrl:getSvgUrl,getDataUrl:getDataUrl,textarea,unescapeMathMode: unescapeMathMode$1,joinAdjacentTextNodes};
|
|
1445
|
+
let supportsPassive=false;const nestedMap$2=function(children,func,context){if(Array.isArray(children)){return children.map(function(child){return nestedMap$2(child,func)})}return func.call(context,children)};function inputPathsEqual(a,b){if(a==null||b==null){return a==null===(b==null)}return a.length===b.length&&a.every((item,index)=>{return b[index]===item})}const rWidgetRule=/^\[\[\u2603 (([a-z-]+) ([0-9]+))]]/;const rTypeFromWidgetId=/^([a-z-]+) ([0-9]+)$/;const rWidgetParts=new RegExp(rWidgetRule.source+"$");const snowman="☃";const isBlockWidgetNode=node=>node?.type==="widget"&&!CoreWidgetRegistry.isInlineWidget(node.widgetType);const isParagraphWithBlockWidget=node=>node?.type==="paragraph"&&Array.isArray(node.content)&&node.content.some(isBlockWidgetNode);const inlineWidgetsToExclude=node=>{const widgetsToExclude=["dropdown","explanation","expression"];return node?.type==="widget"&&widgetsToExclude.includes(node.widgetType)};const nodeIsGraphie=node=>{return node.type==="image"&&node.target.startsWith("web+graphie:")};const isContentGraphie=node=>{return Array.isArray(node.content)&&node.content.some(nodeIsGraphie)};const noParagraphForInlineWidget=node=>Array.isArray(node.content)&&node.content.some(inlineWidgetsToExclude);const isWhitespaceOnlyTextNode=node=>node?.type==="text"&&node.content.trim()==="";const trimEdgeWhitespaceNodes=nodes=>{let start=0;let end=nodes.length;while(start<end&&isWhitespaceOnlyTextNode(nodes[start])){start++;}while(end>start&&isWhitespaceOnlyTextNode(nodes[end-1])){end--;}return nodes.slice(start,end)};const mergeInlineNodes=(inlineNodes,blockNodes,referenceNode)=>{const trimmedContentNodes=trimEdgeWhitespaceNodes(inlineNodes);if(trimmedContentNodes.length>0){blockNodes.push({...referenceNode,content:trimmedContentNodes});}};function joinAdjacentTextNodes(ast){if(!Array.isArray(ast)){return ast}const joined=[];for(const node of ast){const lastIndex=joined.length-1;if(node.type==="text"&&joined[lastIndex]?.type==="text"){joined[lastIndex].content+=node.content;}else {joined.push(node);}}return joined}function splitBlockWidgetsFromParagraphs(ast){if(!Array.isArray(ast)){return ast}return ast.flatMap(node=>{if(!isParagraphWithBlockWidget(node)){return node}const blockNodes=[];const inlineNodes=[];node.content.forEach(childNode=>{if(isBlockWidgetNode(childNode)){mergeInlineNodes(inlineNodes,blockNodes,node);blockNodes.push(childNode);inlineNodes.length=0;}else {inlineNodes.push(childNode);}});mergeInlineNodes(inlineNodes,blockNodes,node);return blockNodes})}function firstNumericalParse$1(text){let first;const val=KhanAnswerTypes.predicate.createValidatorFunctional(function(ans){first=ans;return true},{simplify:"optional",inexact:true,forms:"integer, proper, improper, pi, log, mixed, decimal"});val(String(text));return first}function stringArrayOfSize(size){return Array(size).fill("")}function stringArrayOfSize2D(opt){const{rows,columns}=opt;const rowArr=stringArrayOfSize(rows);return rowArr.map(()=>stringArrayOfSize(columns))}function gridDimensionConfig(absTickStep,extent,dimensionConstraint,gridStep){const scale=scaleFromExtent(extent,dimensionConstraint);const stepPx=absTickStep*scale;const unityLabel=stepPx>30;return {scale:scale,tickStep:absTickStep/gridStep,unityLabel:unityLabel}}function getGridStep(range,step,boxSize){return _(2).times(function(i){const scale=scaleFromExtent(range[i],boxSize);const gridStep=gridStepFromTickStep(step[i],scale);return gridStep})}function snapStepFromGridStep(gridStep){return [gridStep[0]/2,gridStep[1]/2]}function gridStepFromTickStep(tickStep,scale){const tickWidth=tickStep*scale;const x=tickStep;const y=Math.pow(10,Math.floor(Math.log(x)/Math.LN10));const leadingDigit=Math.floor(x/y);if(tickWidth<25){return tickStep}if(tickWidth<50){if(leadingDigit===5){return tickStep}return tickStep/2}if(leadingDigit===1){return tickStep/2}if(leadingDigit===2){return tickStep/4}if(leadingDigit===5){return tickStep/5}}function scaleFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];const scale=dimensionConstraint/span;return scale}function tickStepFromExtent(extent,dimensionConstraint){const span=extent[1]-extent[0];let tickFactor;if(15<span&&span<=20){tickFactor=23;}else if(span>100||span<5){tickFactor=10;}else {tickFactor=16;}const constraintFactor=dimensionConstraint/500;const desiredNumTicks=tickFactor*constraintFactor;return tickStepFromNumTicks(span,desiredNumTicks)}function tickStepFromNumTicks(span,numTicks){let step=Math.pow(10,Math.floor(Math.log(span/numTicks)/Math.LN10));const err=numTicks/span*step;if(err<=.15){step*=10;}else if(err<=.35){step*=5;}else if(err<=.75){step*=2;}return step}const constrainTickStep=(step,range)=>{const span=range[1]-range[0];const numTicks=span/step;if(numTicks<=10){return step}if(numTicks<=20){return step*2}return tickStepFromNumTicks(span,10)};function constrainedTickStepsFromTickSteps(tickSteps,ranges){return [constrainTickStep(tickSteps[0],ranges[0]),constrainTickStep(tickSteps[1],ranges[1])]}function parseQueryString(query){query=query||window.location.search.substring(1);const urlParams={};const a=/\+/g;const r=/([^&=]+)=?([^&]*)/g;const d=function(s){return decodeURIComponent(s.replace(a," "))};let e;while(e=r.exec(query)){const m=e;urlParams[d(m[1])]=d(m[2]);}return urlParams}function updateQueryString$2(uri,key,value){value=encodeURIComponent(value);const re=new RegExp("([?&])"+key+"=.*?(&|$)","i");const separator=uri.indexOf("?")!==-1?"&":"?";if(uri.match(re)){return uri.replace(re,"$1"+key+"="+value+"$2")}return uri+separator+key+"="+value}function strongEncodeURIComponent(str){return encodeURIComponent(str).replace(/['()!]/g,window.escape).replace(/\*/g,"%2A")}const touchHandlers={pointerDown:false,currentTouchIdentifier:null};function resetTouchHandlers(){Object.assign(touchHandlers,{pointerDown:false,currentTouchIdentifier:null});}function extractPointerLocation(event){let touchOrEvent;if(touchHandlers.pointerDown){if(touchHandlers.currentTouchIdentifier!=null){const len=event.changedTouches?event.changedTouches.length:0;for(let i=0;i<len;i++){if(event.changedTouches[i].identifier===touchHandlers.currentTouchIdentifier){touchOrEvent=event.changedTouches[i];}}}else {touchOrEvent=event;}const isEndish=event.type==="touchend"||event.type==="touchcancel";if(touchOrEvent&&isEndish){touchHandlers.pointerDown=false;touchHandlers.currentTouchIdentifier=null;}}else {touchHandlers.pointerDown=true;if(event.changedTouches){touchOrEvent=event.changedTouches[0];touchHandlers.currentTouchIdentifier=touchOrEvent.identifier;}else {touchOrEvent=event;}}if(touchOrEvent){return {left:touchOrEvent.pageX,top:touchOrEvent.pageY}}}const supportsPassiveEvents=()=>{try{const opts=Object.defineProperty({},"passive",{get:function(){supportsPassive=true;}});window.addEventListener("testPassive",null,opts);window.removeEventListener("testPassive",null,opts);}catch{}return supportsPassive};function captureScratchpadTouchStart$2(e){e.stopPropagation();}function getImageSize(url,callback){const img=new Image;img.onload=function(){if(img.width===0&&img.height===0){document.body?.appendChild(img);_.defer(function(){callback(img.clientWidth,img.clientHeight);document.body?.removeChild(img);});}else {callback(img.width,img.height);}};img.src=getRealImageUrl(url);}function getWordBeforeCursor(textarea){const text=textarea.value;const endPos=textarea.selectionStart-1;const startPos=Math.max(text.lastIndexOf("\n",endPos),text.lastIndexOf(" ",endPos))+1;return {string:text.substring(startPos,endPos+1),pos:{start:startPos,end:endPos}}}function moveCursor(textarea,pos){textarea.selectionStart=pos;textarea.selectionEnd=pos;}const textarea={getWordBeforeCursor,moveCursor};const unescapeMathMode$1=label=>label.startsWith("$")&&label.endsWith("$")?label.slice(1,-1):label;const Util={inputPathsEqual,nestedMap: nestedMap$2,rWidgetRule,rTypeFromWidgetId,rWidgetParts,snowman,splitBlockWidgetsFromParagraphs,firstNumericalParse: firstNumericalParse$1,stringArrayOfSize,stringArrayOfSize2D,gridDimensionConfig,getGridStep,snapStepFromGridStep,scaleFromExtent,tickStepFromExtent,gridStepFromTickStep,tickStepFromNumTicks,constrainedTickStepsFromTickSteps,parseQueryString,updateQueryString: updateQueryString$2,strongEncodeURIComponent,touchHandlers,resetTouchHandlers,extractPointerLocation,supportsPassiveEvents,captureScratchpadTouchStart: captureScratchpadTouchStart$2,getImageSize,getImageSizeModern:getImageSizeModern,getRealImageUrl:getRealImageUrl,isLabeledSVG:isLabeledSVG,getBaseUrl:getBaseUrl,getSvgUrl:getSvgUrl,getDataUrl:getDataUrl,textarea,unescapeMathMode: unescapeMathMode$1,joinAdjacentTextNodes};
|
|
1446
1446
|
|
|
1447
1447
|
const KhanColors={BLUE:color.blue,PINK:"#FF00AF",GREEN:color.green,PURPLE:"#9D38BD",RED:"#DF0030",GRAY:"gray",BLACK:"black",LIGHT_BLUE:"#9AB8ED",LIGHT_ORANGE:"#EDD19B",LIGHT_PINK:"#ED9BD3",LIGHT_GREEN:"#9BEDCE",LIGHT_PURPLE:"#DA9BED",LIGHT_RED:"#ED9AAC",GRAY_C:"#E3E5E6",GRAY_G:"#626569",INTERACTING:color.green,INTERACTIVE:color.green,DYNAMIC:color.blue};const getBackgroundColor=elementToInspect=>{const backgroundColor=window.getComputedStyle(elementToInspect).backgroundColor;if(backgroundColor!=="rgba(0, 0, 0, 0)"&&backgroundColor!=="transparent"){return backgroundColor}const parentElement=elementToInspect.parentElement;if(parentElement?.tagName.toLowerCase()==="html"||!parentElement){return "var(--wb-semanticColor-core-background-base-default)"}return getBackgroundColor(parentElement)};const resolveColorCache=new Map;function resolveColor(color){const cached=resolveColorCache.get(color);if(cached!=null){return cached}if(color[0]==="#"){return parseHexColor(color)}const canvas=document.createElement("canvas");const ctx=canvas.getContext("2d");if(!ctx){return {r:0,g:0,b:0}}ctx.fillStyle=color;ctx.fillRect(0,0,1,1);const[r,g,b]=ctx.getImageData(0,0,1,1).data;const resolved={r,g,b};resolveColorCache.set(color,resolved);return resolved}const lightModeHexForMathColor={[semanticColor.learning.math.foreground.blue]:"#3D7586",[semanticColor.learning.math.foreground.gold]:"#946700",[semanticColor.learning.math.foreground.green]:"#447A53",[semanticColor.learning.math.foreground.gray]:"#5D5F66",[semanticColor.learning.math.foreground.grayH]:"#3B3D45",[semanticColor.learning.math.foreground.grayI]:"#21242C",[semanticColor.learning.math.foreground.purple]:"#594094",[semanticColor.learning.math.foreground.purpleD]:"#8351E8",[semanticColor.learning.math.foreground.pink]:"#B25071",[semanticColor.learning.math.foreground.red]:"#D92916"};function toClosestMathColor(target){const targetRGB=resolveColor(target);let closestRGB={r:0,g:0,b:0};let closestCSSVar=semanticColor.core.foreground.neutral.strong;for(const[cssVar,hex]of Object.entries(lightModeHexForMathColor)){const candidate=resolveColor(hex);if(diffColors(targetRGB,candidate)<diffColors(targetRGB,closestRGB)){closestRGB=candidate;closestCSSVar=cssVar;}}return closestCSSVar}function parseHexColor(hex){const threeDigitMatch=hex.match(/^#([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])([0-9A-Fa-f])?$/);if(threeDigitMatch){return {r:parseInt(threeDigitMatch[1],16)*17,g:parseInt(threeDigitMatch[2],16)*17,b:parseInt(threeDigitMatch[3],16)*17}}const sixDigitMatch=hex.match(/^#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})?$/);if(sixDigitMatch){return {r:parseInt(sixDigitMatch[1],16),g:parseInt(sixDigitMatch[2],16),b:parseInt(sixDigitMatch[3],16)}}return {r:0,g:0,b:0}}function diffColors(a,b){const redMean=(a.r+b.r)/2;const redWeight=2+redMean/256;const blueWeight=2+(255-redMean)/256;const greenWeight=4;const dr=a.r-b.r;const dg=a.g-b.g;const db=a.b-b.b;return redWeight*dr*dr+greenWeight*dg*dg+blueWeight*db*db}
|
|
1448
1448
|
|
|
@@ -1561,7 +1561,7 @@ const getClipPoint=function(graph,coord,angle){const xExtent=graph.range[0][1]-g
|
|
|
1561
1561
|
|
|
1562
1562
|
class WrappedDrawing{transform(transformation){const prefixedTransform=InteractiveUtil.getPrefixedTransform();this.wrapper.style[prefixedTransform]=transformation;}toFront(){const parentNode=this.wrapper.parentNode;if(parentNode){parentNode.appendChild(this.wrapper);}}toBack(){const parentNode=this.wrapper.parentNode;if(parentNode!=null&&parentNode.firstChild!==this.wrapper){parentNode.insertBefore(this.wrapper,parentNode.firstChild);}}remove(){this.visibleShape.remove();this.wrapper.remove();}getMouseTarget(){return this.visibleShape[0]}moveTo(point){const delta=vector$3.subtract(this.graphie.scalePoint(point),this.graphie.scalePoint(this.initialPoint));const do3dTransform=InteractiveUtil.getCanUse3dTransform();const transformation="translateX("+delta[0]+"px) "+"translateY("+delta[1]+"px)"+(do3dTransform?" translateZ(0)":"");this.transform(transformation);}hide(){this.visibleShape.hide();}show(){this.visibleShape.show();}attr(...args){this.visibleShape.attr(...args);}animate(...args){this.visibleShape.animate(...args);}constructor(graphie,initialPoint){this.graphie=graphie;this.initialPoint=initialPoint;}}
|
|
1563
1563
|
|
|
1564
|
-
const DEFAULT_OPTIONS$2={center:null,createPath:null,mouselayer:false};class WrappedPath extends WrappedDrawing{constructor(graphie,points,options){const initialPoint=graphie.scalePoint(
|
|
1564
|
+
const DEFAULT_OPTIONS$2={center:null,createPath:null,mouselayer:false};class WrappedPath extends WrappedDrawing{constructor(graphie,points,options){const initialPoint=graphie.scalePoint(points[0]);super(graphie,initialPoint);options={...DEFAULT_OPTIONS$2,...options};const fixedPath=graphie.fixedPath(points,options.center,options.createPath);this.wrapper=fixedPath.wrapper;this.visibleShape=fixedPath.visibleShape;if(options.mouselayer){this.wrapper.style.touchAction="none";this.graphie.addToMouseLayerWrapper(this.wrapper);}else {this.graphie.addToVisibleLayerWrapper(this.wrapper);}}}
|
|
1565
1565
|
|
|
1566
1566
|
let Arrowhead$1 = class Arrowhead extends WrappedPath{toCoordAtAngle(coord,angle){const clipPoint=this.graphie.scalePoint(getClipPoint(this.graphie,coord,angle));this.transform("translateX("+(clipPoint[0]+Arrowhead.scale*this.center[0])+"px) "+"translateY("+(clipPoint[1]+Arrowhead.scale*this.center[1])+"px) "+"translateZ(0) "+"rotate("+(360-KhanMath.bound(angle))+"deg)");}constructor(graphie,style){const center=[.75,0];const points=[[-3,4],[-2.75,2.5],[0,.25],center,[0,-0.25],[-2.75,-2.5],[-3,-4]].map(point=>{const pv=vector$3.subtract(point,center);const pvScaled=vector$3.scale(pv,Arrowhead.scale);return vector$3.add(center,pvScaled)});const unscaledPoints=points.map(graphie.unscalePoint);super(graphie,unscaledPoints,{center:graphie.unscalePoint(center),createPath:createCubicPath});this.center=center;this.attr(_.extend({"stroke-linejoin":"round","stroke-linecap":"round","stroke-dasharray":""},style));}};Arrowhead$1.scale=1.4;const createCubicPath=function(points){let path="M"+points[0][0]+" "+points[0][1];for(let i=1;i<points.length;i+=3){path+="C"+points[i][0]+" "+points[i][1]+" "+points[i+1][0]+" "+points[i+1][1]+" "+points[i+2][0]+" "+points[i+2][1];}return path};
|
|
1567
1567
|
|
|
@@ -1599,9 +1599,9 @@ const Status={PENDING:"pending",LOADING:"loading",LOADED:"loaded",FAILED:"failed
|
|
|
1599
1599
|
|
|
1600
1600
|
function isGif(url){return url.endsWith(".gif")}async function decodeGifFrames(src){const res=await fetch(src);if(!res.ok){return []}const buffer=await res.arrayBuffer();const gif=parseGIF(buffer);return decompressFrames(gif,true)}function isSvg(url){const hasSvgExtension=url.endsWith(".svg");const hasGraphieUrl=isLabeledSVG(url);return hasSvgExtension||hasGraphieUrl}
|
|
1601
1601
|
|
|
1602
|
-
var styles$
|
|
1602
|
+
var styles$x = {"contentWrapper":"perseus_NqTCZY3N","imageContainer":"perseus_Ctn3miye"};
|
|
1603
1603
|
|
|
1604
|
-
const WB_MODAL_PADDING_TOTAL=64;const ZoomedImageView=props=>{const i18n=usePerseusI18n();const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const height=props.height;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);const maxAvailableWidth=window.innerWidth-WB_MODAL_PADDING_TOTAL;const maxAvailableHeight=window.innerHeight-WB_MODAL_PADDING_TOTAL;const scaleWidth=maxAvailableWidth/(width*scale);const scaleHeight=maxAvailableHeight/(height*scale);const fitRatio=Math.min(scaleWidth,scaleHeight,1);const constrainedDisplayWidth=width*fitRatio*scale;return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$
|
|
1604
|
+
const WB_MODAL_PADDING_TOTAL=64;const ZoomedImageView=props=>{const i18n=usePerseusI18n();const{initialFocusId,onClose,...svgProps}=props;const width=props.width;const height=props.height;const contentScale=props.scale;const imageIsSvg=isSvg(props.src);const scale=imageIsSvg?Math.max(contentScale,2):Math.max(contentScale,1);const maxAvailableWidth=window.innerWidth-WB_MODAL_PADDING_TOTAL;const maxAvailableHeight=window.innerHeight-WB_MODAL_PADDING_TOTAL;const scaleWidth=maxAvailableWidth/(width*scale);const scaleHeight=maxAvailableHeight/(height*scale);const fitRatio=Math.min(scaleWidth,scaleHeight,1);const constrainedDisplayWidth=width*fitRatio*scale;return jsxRuntimeExports.jsx(ModalDialog,{"aria-labelledby":"",style:wbStyles$2.dialog,children:jsxRuntimeExports.jsx(ModalPanel,{closeButtonVisible:false,content:jsxRuntimeExports.jsxs("div",{className:styles$x.contentWrapper,children:[jsxRuntimeExports.jsx("div",{className:styles$x.imageContainer,style:{width:constrainedDisplayWidth},children:jsxRuntimeExports.jsx("div",{className:"framework-perseus",tabIndex:0,id:initialFocusId,children:jsxRuntimeExports.jsx(SvgImage,{...svgProps,allowZoom:false,width:width,height:height,scale:scale})})}),jsxRuntimeExports.jsx(IconButton,{icon:closeIcon,onClick:onClose,"aria-label":i18n.strings.imageResetZoomAriaLabel,kind:"primary",style:wbStyles$2.closeButton})]})})})};const wbStyles$2=StyleSheet.create({dialog:{width:"auto",height:"auto",margin:sizing.size_320,"@media (max-width: 767px)":{margin:0}},closeButton:{position:"absolute",insetBlockStart:border$1.width.medium,insetInlineEnd:border$1.width.medium,opacity:0,":hover":{opacity:1},":focus":{opacity:1}}});
|
|
1605
1605
|
|
|
1606
1606
|
const ZoomImageButton=props=>{const{imgSrc}=props;const i18n=usePerseusI18n();const uniqueId=React.useId().replace(/:/g,"");const zoomedImageUniqueId=`zoomed-image-${uniqueId}`;const handleClick=(event,openModal)=>{const mouseEvent=event;if(mouseEvent.metaKey||mouseEvent.ctrlKey){window.open(imgSrc,"_blank");}else {openModal();}};return jsxRuntimeExports.jsx(ModalLauncher,{initialFocusId:zoomedImageUniqueId,modal:({closeModal})=>jsxRuntimeExports.jsx(ZoomedImageView,{...props,initialFocusId:zoomedImageUniqueId,onClose:closeModal}),children:({openModal})=>jsxRuntimeExports.jsx(Clickable,{"aria-label":i18n.strings.imageZoomAriaLabel,onClick:event=>handleClick(event,openModal),style:{position:"absolute",width:"100%",height:"100%",overflow:"hidden",cursor:"zoom-in"},children:()=>{return jsxRuntimeExports.jsx(React.Fragment,{})}})})};
|
|
1607
1607
|
|
|
@@ -1623,13 +1623,13 @@ function _noop(){}class InteractionTracker{constructor(trackApi,widgetType,widge
|
|
|
1623
1623
|
|
|
1624
1624
|
const arrayRules={fence:{match:SimpleMarkdown.defaultRules.fence.match,order:1,parse:(capture,state,parse)=>({type:"codeBlock",lang:capture[2]||undefined,content:capture[3]})},paragraph:{match:SimpleMarkdown.defaultRules.paragraph.match,order:2,parse:(capture,state,parse)=>({content:capture[1]})}};const builtArrayParser=SimpleMarkdown.parserFor(arrayRules);const parseToArray=source=>{const paragraphedSource=source.replace(/^\n\s*\n/,"")+"\n\n";return builtArrayParser(paragraphedSource,{inline:false}).map(c=>{return c["content"]})};const joinFromArray=paragraphs=>paragraphs.join("\n\n");var JiptParagraphs = {parseToArray:parseToArray,joinFromArray:joinFromArray};
|
|
1625
1625
|
|
|
1626
|
-
function LinterLink({message,ruleName,severity,style}){let severityLabel;let severityLabelStyle;if(severity===1){severityLabel="Error";severityLabelStyle=styles$
|
|
1626
|
+
function LinterLink({message,ruleName,severity,style}){let severityLabel;let severityLabelStyle;if(severity===1){severityLabel="Error";severityLabelStyle=styles$w.publishBlockingError;}else if(severity===2){severityLabel="Warning";severityLabelStyle=styles$w.warning;}else {severityLabel="Recommendation";severityLabelStyle=styles$w.warning;}return jsxRuntimeExports.jsx(Tooltip,{placement:"left",forceAnchorFocusivity:false,variant:"strong",content:jsxRuntimeExports.jsx(TooltipContent,{title:jsxRuntimeExports.jsx(BodyText,{weight:"bold",style:severityLabelStyle,children:severityLabel}),children:message.split("\n\n").map((paragraph,i)=>jsxRuntimeExports.jsx(BodyText,{style:styles$w.tooltipParagraph,children:paragraph},i))}),children:jsxRuntimeExports.jsx(IconButton,{size:"small",kind:"tertiary",actionType:"destructive","aria-label":`${severityLabel}: ${ruleName}`,href:`https://khanacademy.org/r/linter-rules#${ruleName}`,icon:severity===1?warningCircleIcon:dotOutlineIcon,style:style,target:"_blank"})})}const tooltipMaxWidth="min(320px, calc(100vw - 120px))";const styles$w=StyleSheet.create({tooltipParagraph:{maxInlineSize:tooltipMaxWidth,":not(:first-child)":{marginBlockStart:sizing.size_080}},warning:{color:semanticColor.status.warning.foreground},publishBlockingError:{color:semanticColor.status.critical.foreground}});
|
|
1627
1627
|
|
|
1628
|
-
function Lint({children,inline,message,ruleName,insideTable,blockHighlight,severity}){const linterLinkProps={message,ruleName,severity};if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:css(styles$
|
|
1628
|
+
function Lint({children,inline,message,ruleName,insideTable,blockHighlight,severity}){const linterLinkProps={message,ruleName,severity};if(insideTable){if(inline){return jsxRuntimeExports.jsx("span",{"data-lint-inside-table":"true",children:children})}return jsxRuntimeExports.jsx("div",{"data-lint-inside-table":"true",children:children})}if(blockHighlight){return jsxRuntimeExports.jsxs("span",{className:css(styles$v.lintContainer,styles$v.lintContainerBlock),children:[jsxRuntimeExports.jsx(LinterLink,{...linterLinkProps,style:styles$v.radioWidgetHoverTarget}),jsxRuntimeExports.jsx("span",{children:children})]})}if(inline){return jsxRuntimeExports.jsxs("span",{className:css(styles$v.lintContainer),children:[jsxRuntimeExports.jsx(LinterLink,{...linterLinkProps,style:styles$v.inlineHoverTarget}),jsxRuntimeExports.jsx("span",{children:children})]})}return jsxRuntimeExports.jsxs("div",{className:css(styles$v.lintContainer),children:[jsxRuntimeExports.jsx(LinterLink,{...linterLinkProps,style:styles$v.hoverTarget}),jsxRuntimeExports.jsx("div",{children:children})]})}const highlightBlockContent={":hover ~ div":{outline:`1px solid ${semanticColor.status.warning.foreground}`},":hover ~ div div[data-lint-inside-table]":{outline:`1px solid ${semanticColor.status.warning.foreground}`},":hover ~ div span[data-lint-inside-table]":{backgroundColor:semanticColor.status.warning.background,color:semanticColor.status.warning.foreground}};const highlightInlineContent={":hover ~ span":{backgroundColor:semanticColor.status.warning.background,color:semanticColor.status.warning.foreground}};const styles$v=StyleSheet.create({lintContainer:{position:"relative"},lintContainerBlock:{display:"block"},hoverTarget:{position:"absolute",insetInlineEnd:-60,...highlightBlockContent},inlineHoverTarget:{float:"inline-end",position:"relative",marginInlineEnd:-60,...highlightInlineContent},radioWidgetHoverTarget:{position:"absolute",insetInlineStart:-60}});
|
|
1629
1629
|
|
|
1630
|
-
const rules
|
|
1630
|
+
const rules={...pureMarkdownRules,columns:{...pureMarkdownRules.columns,react:(node,output,state)=>{return jsxRuntimeExports.jsxs("div",{className:"perseus-two-columns",children:[jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col1,state)})}),jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col2,state)})})]},state.key)}},crowdinId:{...pureMarkdownRules.crowdinId,react:(node,output,state)=>node.id},table:{...pureMarkdownRules.table,react:function(node,output,state){const table=SimpleMarkdown.defaultRules.table.react(node,output,state);if(!state.isMobile){return table}return React.cloneElement(table,{tabIndex:0})}},titledTable:{...pureMarkdownRules.titledTable,react:(node,output,state)=>{let contents;if(!node.table){contents="//invalid table//";}else if(node.table.type==="lint"){if(node.table.content?.type==="table"){contents=rules.lint.react({...node.table,content:{...node,table:node.table.content}},output,{...state,unwrapTitledTableContents:true});}else {contents=rules.lint.react(node.table,output,state);}}else {const tableOutput=SimpleMarkdown.defaultRules.table.react(node.table,output,state);const caption=jsxRuntimeExports.jsx("caption",{className:"perseus-table-title",children:output(node.title,state)},"caption");contents=React.cloneElement(tableOutput,null,[caption,...tableOutput.props.children]);}if(state.unwrapTitledTableContents){return contents}return jsxRuntimeExports.jsx("div",{className:"perseus-titled-table",children:contents},state.key)}},widget:{...pureMarkdownRules.widget,react:(node,output,state)=>{return jsxRuntimeExports.jsx("em",{children:`[Widget: ${node.id}]`},state.key)}},blockMath:{...pureMarkdownRules.blockMath,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},math:{...pureMarkdownRules.math,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},unescapedDollar:{...pureMarkdownRules.unescapedDollar,react:(node,output,state)=>{return "$"}},link:{...pureMarkdownRules.link,react:function(node,output,state){const link=SimpleMarkdown.defaultRules.link.react(node,output,state);const href=link.props.href;let rel=null;const isKAUrl=href?href.match(/https?:\/\/[^/]*khanacademy.org|^\//):false;if(!isKAUrl){rel="noopener noreferrer";}const newProps={...link.props,target:"_blank",href,rel};if(state.baseElements&&state.baseElements.Link){return state.baseElements.Link(newProps)}return React.cloneElement(link,newProps)}},codeBlock:{...pureMarkdownRules.codeBlock,react:(node,output,state)=>{if(node.lang==="alt"){return jsxRuntimeExports.jsx("div",{className:"perseus-markdown-alt perseus-sr-only",children:output(node.content,state)},state.key)}return SimpleMarkdown.defaultRules.codeBlock.react(node,output,state)}},lint:{...pureMarkdownRules.lint,react:(node,output,state)=>{return jsxRuntimeExports.jsx(Lint,{message:node.message,ruleName:node.ruleName,inline:isInline(node.content),blockHighlight:node.blockHighlight,insideTable:node.insideTable,severity:node.severity,children:output(node.content,state)})}}};function isInline(node){if(node?.type==="widget"){return CoreWidgetRegistry.isInlineWidget(node.widgetType)}return !!(node&&node.type&&inlineNodeTypes.hasOwnProperty(node.type))}const inlineNodeTypes={text:true,math:true,unescapedDollar:true,link:true,img:true,strong:true,u:true,em:true,del:true,code:true};const builtParser=SimpleMarkdown.parserFor(rules);const parse=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,{...state,inline:false})};const inlineParser=(source,state)=>{return builtParser(source,{...state,inline:true})};const getContent=ast=>{if(Array.isArray(ast)){return _.flatten(ast.map(getContent))}if(ast.content&&typeof ast.content==="string"){if(ast.type.toLowerCase().indexOf("code")!==-1){return ["",ast.content,""]}return [ast.content.replace(/\s+/g," ")]}const children=_.chain(ast).values().flatten().filter(object=>object!=null&&_.has(object,"type")).value();if(!children.length){return []}const nestedContent=getContent(children);if(ast.type==="paragraph"&&nestedContent.length){nestedContent[0]=nestedContent[0].replace(/^\s+/,"");const last=nestedContent.length-1;nestedContent[last]=nestedContent[last].replace(/\s+$/,"");}return nestedContent};const characterCount=source=>{const ast=parse(source);const content=getContent(ast).join("");return content.length};var PerseusMarkdown = {characterCount:characterCount,traverseContent:traverseContent,parse:parse,parseInline:inlineParser,reactFor:SimpleMarkdown.reactFor,ruleOutput:SimpleMarkdown.ruleOutput(rules,"react"),basicOutput:SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules,"react")),sanitizeUrl:SimpleMarkdown.sanitizeUrl};
|
|
1631
1631
|
|
|
1632
|
-
const QuestionParagraph
|
|
1632
|
+
const QuestionParagraph=props=>{const className=props.className?"deprecated-perseus-container "+props.className:"deprecated-perseus-container";const isJipt=props.translationIndex!=null;if(props.inline&&!props.className&&!isJipt){return props.children}return jsxRuntimeExports.jsx("div",{className:props.inline?props.className??undefined:className,"data-perseus-component-index":isJipt?props.translationIndex:undefined,"data-perseus-paragraph-index":isJipt?props.paragraphIndex:undefined,children:props.children})};
|
|
1633
1633
|
|
|
1634
1634
|
const DEBOUNCE_TIMEOUT=1e3;class TranslationLinter{applyLintErrors(parsedMarkdown,translationLintErrors){if(translationLintErrors.length){const errorText=translationLintErrors.join("\n\n");parsedMarkdown.unshift({content:{type:"text",content:""},insideTable:false,message:errorText,ruleName:"legacy-error",severity:Rule.Severity.ERROR,type:"lint"});}}constructor(){this.previousContent=null;this.runLinter=debounce$1((perseusStr,onLintErrorsGenerated)=>{if(typeof KA==="undefined"){return}if(perseusStr===this.previousContent){return}this.previousContent=perseusStr;if(perseusStr===""){onLintErrorsGenerated([]);return}fetch("/api/internal/translations/lint_poentry?preview=1&lang=en",{headers:{"Content-Type":"application/json"},body:JSON.stringify({msgid:perseusStr,msgstr:perseusStr,format:"perseus_text",filename:""}),method:"POST"}).then(response=>{if(response.status>=400){return {status:"error",message:"Could not run i18n linter."}}return response.json()},rejection=>{return {status:"error",message:"Could not run i18n linter."}}).then(json=>{if(json.status==="error"){onLintErrorsGenerated(["Some part of this text makes it untranslatable. "+"The specific message from the i18n linter was: "+json.message.replace(/\n/g," ")]);}else {onLintErrorsGenerated([]);}});},DEBOUNCE_TIMEOUT);}}
|
|
1635
1635
|
|
|
@@ -1637,43 +1637,29 @@ const{interactiveSizes}=constants;const smMax=articleMaxWidthTableInPx;const mdM
|
|
|
1637
1637
|
|
|
1638
1638
|
var preprocessTex = (texCode=>texCode.replace(/\{align[*]?\}/g,"{aligned}").replace(/[\u00a0]/g," "));
|
|
1639
1639
|
|
|
1640
|
+
function UnsupportedWidgetMessage({widgetType,widgetSubType,widgetId,reason="widget-not-registered"}){const{strings}=usePerseusI18n();const dependencies=useDependencies();useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:unsupported",payload:{widgetType,widgetSubType,widgetId,reason}});});return jsxRuntimeExports.jsx("div",{style:{paddingBlock:sizing.size_080},children:jsxRuntimeExports.jsx(Banner,{text:strings.unsupportedWidget,kind:"info"})})}
|
|
1641
|
+
|
|
1640
1642
|
function getWidgetTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];return widget?.type??null}function getWidgetSubType(widgetType,widgetOptions){switch(widgetType){case "interactive-graph":const graphOptions=widgetOptions;return graphOptions.graph?.type??null;case "radio":const radioOptions=widgetOptions;return radioOptions.multipleSelect?"multiple-select":"single-select";default:return null}}function getWidgetSubTypeByWidgetId(widgetId,widgetMap){const widget=widgetMap[widgetId];if(!widget){return null}return getWidgetSubType(widget.type,widget.options)}function contentHasWidgetType(type,content,widgetMap){return getWidgetIdsFromContentByType(type,content,widgetMap).length>0}function getWidgetFromWidgetMap(widgetId,widgetMap){return widgetMap[widgetId]??null}function getWidgetsFromWidgetMap(widgetIds,widgetMap){const widgets={};widgetIds.forEach(widgetId=>{const widget=getWidgetFromWidgetMap(widgetId,widgetMap);if(widget){widgets[widgetId]=widget;}});return widgets}
|
|
1641
1643
|
|
|
1642
|
-
const DEFAULT_TRACKING="";const DEFAULT_LINTABLE=false;const widgets=new Registry("Perseus widget registry");const
|
|
1644
|
+
const DEFAULT_TRACKING="";const DEFAULT_LINTABLE=false;const widgets=new Registry("Perseus widget registry");const registerWidget=(type,widget)=>{widgets.set(type,widget);};const registerWidgets=widgetArr=>{widgetArr.forEach(widget=>{registerWidget(widget.name,widget);});};const getWidget=type=>{const widget=widgets.get(type);if(widget==null){return null}return widget.widget};const getWidgetExport=type=>{return widgets.get(type)??null};const getPublicWidgets=()=>{return widgets.entries().reduce((acc,[key,value])=>{if(process.env.STORYBOOK||!value.hidden){acc[key]=value;}return acc},{})};const getAllWidgetTypes=()=>{return widgets.keys()};const supportsStaticMode=type=>{const widgetInfo=widgets.get(type);return widgetInfo&&widgetInfo.getCorrectUserInput!=null};const supportsUngraded=type=>{const widgetInfo=widgets.get(type);return widgetInfo?.supportsUngraded===true};const getTracking=type=>{const widgetExport=widgets.get(type);return widgetExport&&widgetExport.tracking||DEFAULT_TRACKING};const isLintable=type=>{const widgetExports=widgets.get(type);return widgetExports&&widgetExports.isLintable||DEFAULT_LINTABLE};
|
|
1643
1645
|
|
|
1644
1646
|
var widgets$1 = /*#__PURE__*/Object.freeze({
|
|
1645
1647
|
__proto__: null,
|
|
1646
1648
|
getAllWidgetTypes: getAllWidgetTypes,
|
|
1647
|
-
getEditor: getEditor,
|
|
1648
1649
|
getPublicWidgets: getPublicWidgets,
|
|
1649
1650
|
getTracking: getTracking,
|
|
1650
1651
|
getWidget: getWidget,
|
|
1651
1652
|
getWidgetExport: getWidgetExport,
|
|
1652
1653
|
isLintable: isLintable,
|
|
1653
|
-
registerEditors: registerEditors,
|
|
1654
1654
|
registerWidget: registerWidget,
|
|
1655
1655
|
registerWidgets: registerWidgets,
|
|
1656
|
-
replaceDeprecatedEditors: replaceDeprecatedEditors,
|
|
1657
|
-
replaceDeprecatedWidgets: replaceDeprecatedWidgets,
|
|
1658
|
-
replaceEditor: replaceEditor,
|
|
1659
|
-
replaceWidget: replaceWidget,
|
|
1660
1656
|
supportsStaticMode: supportsStaticMode,
|
|
1661
1657
|
supportsUngraded: supportsUngraded
|
|
1662
1658
|
});
|
|
1663
1659
|
|
|
1664
|
-
class WidgetContainer extends React.Component{componentDidMount(){if(this.props.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}render(){let className=classNames$2({"perseus-widget-container":true,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;
|
|
1665
|
-
|
|
1666
|
-
const rContainsNonWhitespace$1=/\S/;const rImageURL$1=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender$1=()=>{};const makeContainerId$1=id=>"container:"+id;const isIdPathPrefix$1=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return _.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return _.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion$1(propsA,propsB){function makeItem(props){return splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!_.isEqual(makeItem(propsA),makeItem(propsB))}let Renderer$2 = class Renderer extends React.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion$1(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!_.isEqual(this.state,nextState);const propsChanged=!_.isEqual(this.props,nextProps);return propsChanged||stateChanged}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput&&!_.isEqual(this.props.userInput,prevProps.userInput)){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}_isAnswerable(){if(this.props.userInput){return this.emptyWidgets().length===0}return false}_getWidgetIndexById(id){const widgetIndex=this.widgetIds.indexOf(id);if(widgetIndex<0){Log.error("Unable to get widget index in _getWidgetIndexById",Errors.Internal,{loggedMetadata:{widgets:JSON.stringify(this.props.widgets),widgetId:JSON.stringify(id)}});return 0}return widgetIndex}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetOptions=this.props.widgets[widgetId].options;const widgetInfo=this.state.widgetInfo[widgetId];if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {options:widgetOptions,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,widgetIndex:this._getWidgetIndexById(widgetId),alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,graded:widgetInfo?.graded,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,showSolutions:this.props.showSolutions,onFocus:_.partial(this._onWidgetFocus,widgetId),onBlur:_.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewMode:this.props.reviewMode??false,isScorable:this.props.isScorable??false,containerSizeClass:containerSizeClass.MEDIUM,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"widget"),handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.apiOptions?.interactionCallback?.(updatedUserInput);},trackInteraction:interactionTracker.track}}getSerializedState(){return mapObject(this.props.widgets,(widgetData,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return widgetData.options})}replaceJiptContent(content,paragraphIndex){if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;let parsedMarkdown=this.props.inline?PerseusMarkdown$1.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown$1.parse(content,{isJipt:this.translationIndex!=null});parsedMarkdown=Util.splitBlockWidgetsFromParagraphs(parsedMarkdown);if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(Util.joinAdjacentTextNodes(parsedMarkdown),{baseElements:apiOptions.baseElements});const className=classNames$2({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})})}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo}},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId$1(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,widgetProps:this.getWidgetProps(id)},makeContainerId$1(id))}return null},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId$1(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!Array.isArray(focusPath)){throw new PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!_.isEqual(fullPath,blurringFocusPath)){return}_.defer(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.outputMarkdown=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames$2({"perseus-paragraph-centered":!this._foundTextNodes&&!this.props.inline,"perseus-paragraph-full-width":state.foundFullWidth&&ast.type==="widget"});}return jsxRuntimeExports.jsx(QuestionParagraph$1,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$v.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=_.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{allowZoom:true,setAssetStatus:setAssetStatus,src:PerseusMarkdown$1.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown$1.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace$1.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL$1.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown$1.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$v.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable$1,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown$1.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender$1||oldOnRender!==noopOnRender$1){const node=ReactDOM__default.findDOMNode(this);if(node instanceof Element){node.querySelectorAll("img").forEach(image=>{if(oldOnRender!==noopOnRender$1){image.removeEventListener("load",oldOnRender);}if(onRender!==noopOnRender$1){image.addEventListener("load",onRender);}});}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix$1(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){const container=this._widgetContainers.get(makeContainerId$1(widgetId));if(container){return ReactDOM__default.findDOMNode(container)}return ReactDOM__default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(_.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!_.isEqual(this._currentFocus,path)){return}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],...this._getInitialWidgetState(props)};}};Renderer$2.contextType=PerseusI18nContext;Renderer$2.defaultProps={content:"",widgets:{},images:{},showSolutions:"none",onRender:noopOnRender$1,findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,isScorable:false,linterContext:PerseusLinter.linterContextDefault};const styles$v={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
|
|
1667
|
-
|
|
1668
|
-
const rules={...pureMarkdownRules,columns:{...pureMarkdownRules.columns,react:(node,output,state)=>{return jsxRuntimeExports.jsxs("div",{className:"perseus-two-columns",children:[jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col1,state)})}),jsxRuntimeExports.jsx("div",{className:"perseus-column",children:jsxRuntimeExports.jsx("div",{className:"perseus-column-content",children:output(node.col2,state)})})]},state.key)}},crowdinId:{...pureMarkdownRules.crowdinId,react:(node,output,state)=>node.id},table:{...pureMarkdownRules.table,react:function(node,output,state){const table=SimpleMarkdown.defaultRules.table.react(node,output,state);if(!state.isMobile){return table}return React.cloneElement(table,{tabIndex:0})}},titledTable:{...pureMarkdownRules.titledTable,react:(node,output,state)=>{let contents;if(!node.table){contents="//invalid table//";}else if(node.table.type==="lint"){if(node.table.content?.type==="table"){contents=rules.lint.react({...node.table,content:{...node,table:node.table.content}},output,{...state,unwrapTitledTableContents:true});}else {contents=rules.lint.react(node.table,output,state);}}else {const tableOutput=SimpleMarkdown.defaultRules.table.react(node.table,output,state);const caption=jsxRuntimeExports.jsx("caption",{className:"perseus-table-title",children:output(node.title,state)},"caption");contents=React.cloneElement(tableOutput,null,[caption,...tableOutput.props.children]);}if(state.unwrapTitledTableContents){return contents}return jsxRuntimeExports.jsx("div",{className:"perseus-titled-table",children:contents},state.key)}},widget:{...pureMarkdownRules.widget,react:(node,output,state)=>{return jsxRuntimeExports.jsx("em",{children:`[Widget: ${node.id}]`},state.key)}},blockMath:{...pureMarkdownRules.blockMath,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},math:{...pureMarkdownRules.math,react:(node,output,state)=>{const{TeX}=getDependencies();return jsxRuntimeExports.jsx(TeX,{children:node.content},state.key)}},unescapedDollar:{...pureMarkdownRules.unescapedDollar,react:(node,output,state)=>{return "$"}},link:{...pureMarkdownRules.link,react:function(node,output,state){const link=SimpleMarkdown.defaultRules.link.react(node,output,state);const href=link.props.href;let rel=null;const isKAUrl=href?href.match(/https?:\/\/[^/]*khanacademy.org|^\//):false;if(!isKAUrl){rel="noopener noreferrer";}const newProps={...link.props,target:"_blank",href,rel};if(state.baseElements&&state.baseElements.Link){return state.baseElements.Link(newProps)}return React.cloneElement(link,newProps)}},codeBlock:{...pureMarkdownRules.codeBlock,react:(node,output,state)=>{if(node.lang==="alt"){return jsxRuntimeExports.jsx("div",{className:"perseus-markdown-alt perseus-sr-only",children:output(node.content,state)},state.key)}return SimpleMarkdown.defaultRules.codeBlock.react(node,output,state)}},lint:{...pureMarkdownRules.lint,react:(node,output,state)=>{return jsxRuntimeExports.jsx(Lint,{message:node.message,ruleName:node.ruleName,inline:isInline(node.content),blockHighlight:node.blockHighlight,insideTable:node.insideTable,severity:node.severity,children:output(node.content,state)})}}};function isInline(node){if(node?.type==="widget"){return CoreWidgetRegistry.isInlineWidget(node.widgetType)}return !!(node&&node.type&&inlineNodeTypes.hasOwnProperty(node.type))}const inlineNodeTypes={text:true,math:true,unescapedDollar:true,link:true,img:true,strong:true,u:true,em:true,del:true,code:true};const builtParser=SimpleMarkdown.parserFor(rules);const parse=(source,state)=>{const paragraphedSource=source+"\n\n";return builtParser(paragraphedSource,{...state,inline:false})};const inlineParser=(source,state)=>{return builtParser(source,{...state,inline:true})};const getContent=ast=>{if(Array.isArray(ast)){return _.flatten(ast.map(getContent))}if(ast.content&&typeof ast.content==="string"){if(ast.type.toLowerCase().indexOf("code")!==-1){return ["",ast.content,""]}return [ast.content.replace(/\s+/g," ")]}const children=_.chain(ast).values().flatten().filter(object=>object!=null&&_.has(object,"type")).value();if(!children.length){return []}const nestedContent=getContent(children);if(ast.type==="paragraph"&&nestedContent.length){nestedContent[0]=nestedContent[0].replace(/^\s+/,"");const last=nestedContent.length-1;nestedContent[last]=nestedContent[last].replace(/\s+$/,"");}return nestedContent};const characterCount=source=>{const ast=parse(source);const content=getContent(ast).join("");return content.length};var PerseusMarkdown = {characterCount:characterCount,traverseContent:traverseContent,parse:parse,parseInline:inlineParser,reactFor:SimpleMarkdown.reactFor,ruleOutput:SimpleMarkdown.ruleOutput(rules,"react"),basicOutput:SimpleMarkdown.reactFor(SimpleMarkdown.ruleOutput(rules,"react")),sanitizeUrl:SimpleMarkdown.sanitizeUrl};
|
|
1669
|
-
|
|
1670
|
-
class QuestionParagraph extends React.Component{render(){const className=this.props.className?"paragraph "+this.props.className:"paragraph";return jsxRuntimeExports.jsx("div",{className:this.props.inline?this.props.className??undefined:className,"data-perseus-component-index":this.props.translationIndex,"data-perseus-paragraph-index":this.props.paragraphIndex,children:this.props.children})}}
|
|
1671
|
-
|
|
1672
|
-
class WidgetContainerOld extends React.Component{componentDidMount(){if(this.props.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}render(){let className=classNames$2({"perseus-widget-container":true,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;const WidgetType=getWidget(type);if(WidgetType==null){console.warn(`Widget type '${type}' not found!`);return jsxRuntimeExports.jsx("div",{className:className})}const subType=getWidgetSubType(type,this.props.widgetProps.options)??"null";let alignment=this.props.widgetProps.alignment;if(alignment==null||alignment==="default"){alignment=CoreWidgetRegistry.getDefaultAlignment(type);}className+=CoreWidgetRegistry.getAlignmentClassName(type,alignment);const apiOptions=this.props.widgetProps.apiOptions;const isStatic=this.props.widgetProps.static||apiOptions.readOnly;const staticContainerStyles={position:"relative",overflow:"visible"};const staticOverlayStyles={width:"100%",height:"100%",position:"absolute",top:0,left:0,zIndex:3};const linterContext=isLintable(type)?this.props.widgetProps.linterContext:{...this.props.widgetProps.linterContext,highlightLint:false};return jsxRuntimeExports.jsx("div",{className:className,style:isStatic?staticContainerStyles:{},children:jsxRuntimeExports.jsx(DependenciesContext.Consumer,{children:({analytics})=>jsxRuntimeExports.jsxs(ErrorBoundary,{metadata:{widget_type:type,widget_id:this.props.id},onError:error=>{analytics.onAnalyticsEvent({type:"perseus:widget-rendering-error:ti",payload:{widgetSubType:subType,widgetType:type,widgetId:this.props.id,message:error.message,stack:error.stack??"No stack trace available",userAgent:userAgent}});},children:[jsxRuntimeExports.jsx(WidgetType,{...this.props.widgetProps,linterContext:linterContext,containerSizeClass:this.state.sizeClass,ref:this.widgetRef}),isStatic&&jsxRuntimeExports.jsx("div",{style:staticOverlayStyles})]})})})}constructor(...args){super(...args),this.widgetRef=React.createRef(),this.state={sizeClass:containerSizeClass.MEDIUM},this.getWidget=()=>{return this.widgetRef.current};}}
|
|
1660
|
+
class WidgetContainer extends React.Component{componentDidMount(){if(this.props.widgetProps.apiOptions.isMobile){const containerWidth=ReactDOM__default.findDOMNode(this).offsetWidth;this.setState({sizeClass:getClassFromWidth(containerWidth)});}}UNSAFE_componentWillReceiveProps(nextProps){if(this.props.type!==nextProps.type){throw new Error("WidgetContainer can't change widget type; set a different "+"key instead to recreate the container.")}}render(){let className=classNames$2({"perseus-widget-container":true,"perseus-widget__definition":this.props.type==="definition"});const type=this.props.type;const userAgent=navigator.userAgent;let alignment=this.props.widgetProps.alignment;if(alignment==null||alignment==="default"){alignment=CoreWidgetRegistry.getDefaultAlignment(type);}className+=CoreWidgetRegistry.getAlignmentClassName(type,alignment);const subType=getWidgetSubType(type,this.props.widgetProps.options)??"null";const WidgetType=getWidget(type);if(WidgetType==null){return jsxRuntimeExports.jsx("div",{className:"deprecated-perseus-container",children:jsxRuntimeExports.jsx("div",{className:className,children:jsxRuntimeExports.jsx(UnsupportedWidgetMessage,{widgetType:type,widgetSubType:subType,widgetId:this.props.id})})})}const Container=CoreWidgetRegistry.isInlineWidget(type,alignment)?"span":"div";const apiOptions=this.props.widgetProps.apiOptions;const isStatic=this.props.widgetProps.static||apiOptions.readOnly;const staticContainerStyles={position:"relative",overflow:"visible"};const staticOverlayStyles={width:"100%",height:"100%",position:"absolute",top:0,left:0,zIndex:3};const linterContext=isLintable(type)?this.props.widgetProps.linterContext:{...this.props.widgetProps.linterContext,highlightLint:false};return jsxRuntimeExports.jsx(Container,{className:"deprecated-perseus-container",children:jsxRuntimeExports.jsx(Container,{className:className,style:isStatic?staticContainerStyles:{},children:jsxRuntimeExports.jsx(DependenciesContext.Consumer,{children:({analytics})=>jsxRuntimeExports.jsxs(ErrorBoundary,{metadata:{widget_type:type,widget_id:this.props.id},onError:error=>{analytics.onAnalyticsEvent({type:"perseus:widget-rendering-error:ti",payload:{widgetSubType:subType,widgetType:type,widgetId:this.props.id,message:error.message,stack:error.stack??"No stack trace available",userAgent:userAgent}});},children:[jsxRuntimeExports.jsx(WidgetType,{...this.props.widgetProps,linterContext:linterContext,containerSizeClass:this.state.sizeClass,ref:this.widgetRef}),isStatic&&jsxRuntimeExports.jsx("div",{style:staticOverlayStyles})]})})})})}constructor(...args){super(...args),this.widgetRef=React.createRef(),this.state={sizeClass:containerSizeClass.MEDIUM},this.getWidget=()=>{return this.widgetRef.current};}}
|
|
1673
1661
|
|
|
1674
|
-
const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return _.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return _.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!_.isEqual(makeItem(propsA),makeItem(propsB))}let Renderer$1 = class Renderer extends React.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!_.isEqual(this.state,nextState);const propsChanged=!_.isEqual(this.props,nextProps);return propsChanged||stateChanged}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput&&!_.isEqual(this.props.userInput,prevProps.userInput)){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}_isAnswerable(){if(this.props.userInput){return this.emptyWidgets().length===0}return false}_getWidgetIndexById(id){const widgetIndex=this.widgetIds.indexOf(id);if(widgetIndex<0){Log.error("Unable to get widget index in _getWidgetIndexById",Errors.Internal,{loggedMetadata:{widgets:JSON.stringify(this.props.widgets),widgetId:JSON.stringify(id)}});return 0}return widgetIndex}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetOptions=this.props.widgets[widgetId].options;const widgetInfo=this.state.widgetInfo[widgetId];if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {options:widgetOptions,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,widgetIndex:this._getWidgetIndexById(widgetId),alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,graded:widgetInfo?.graded,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,showSolutions:this.props.showSolutions,onFocus:_.partial(this._onWidgetFocus,widgetId),onBlur:_.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewMode:this.props.reviewMode??false,isScorable:this.props.isScorable??false,containerSizeClass:containerSizeClass.MEDIUM,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"widget"),handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.apiOptions?.interactionCallback?.(updatedUserInput);},trackInteraction:interactionTracker.track}}getSerializedState(){return mapObject(this.props.widgets,(widgetData,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return widgetData.options})}replaceJiptContent(content,paragraphIndex){if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;const parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(parsedMarkdown,{baseElements:apiOptions.baseElements});const className=classNames$2({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})})}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo}},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;return jsxRuntimeExports.jsx(WidgetContainerOld,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,widgetProps:this.getWidgetProps(id)},makeContainerId(id))}return null},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!Array.isArray(focusPath)){throw new PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!_.isEqual(fullPath,blurringFocusPath)){return}_.defer(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.outputMarkdown=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames$2({"perseus-paragraph-centered":!this._foundTextNodes,"perseus-paragraph-full-width":state.foundFullWidth&&ast.content.length===1});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const extraAttrs=_.has(this.props.images,node.target)?this.props.images[node.target]:null;const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{allowZoom:true,setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,...extraAttrs})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable$1,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const node=ReactDOM__default.findDOMNode(this);if(node instanceof Element){node.querySelectorAll("img").forEach(image=>{if(oldOnRender!==noopOnRender){image.removeEventListener("load",oldOnRender);}if(onRender!==noopOnRender){image.addEventListener("load",onRender);}});}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){const container=this._widgetContainers.get(makeContainerId(widgetId));if(container){return ReactDOM__default.findDOMNode(container)}return ReactDOM__default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(_.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!_.isEqual(this._currentFocus,path)){return}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],...this._getInitialWidgetState(props)};}};Renderer$1.contextType=PerseusI18nContext;Renderer$1.defaultProps={content:"",widgets:{},images:{},showSolutions:"none",onRender:noopOnRender,findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,isScorable:false,linterContext:PerseusLinter.linterContextDefault};const styles$u={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
|
|
1675
|
-
|
|
1676
|
-
const Renderer=React.forwardRef(function Renderer(props,ref){const rendererFF=isFeatureOn({apiOptions:props.apiOptions},"perseus-renderer-upgrade");return rendererFF?jsxRuntimeExports.jsx(Renderer$2,{ref:ref,...props}):jsxRuntimeExports.jsx(Renderer$1,{ref:ref,...props})});
|
|
1662
|
+
const rContainsNonWhitespace=/\S/;const rImageURL=/(web\+graphie|https):\/\/[^\s]*/;const noopOnRender=()=>{};const makeContainerId=id=>"container:"+id;const isIdPathPrefix=function(prefixArray,wholeArray){if(prefixArray===null||wholeArray===null){return prefixArray===wholeArray}return _.every(prefixArray,(elem,i)=>{if(wholeArray!=null){return _.isEqual(elem,wholeArray[i])}})};function isDifferentQuestion(propsA,propsB){function makeItem(props){return splitPerseusItem({question:{content:props.content,widgets:props.widgets,images:{}},hints:[],answerArea:getDefaultAnswerArea()})}return propsA.problemNum!==propsB.problemNum||!_.isEqual(makeItem(propsA),makeItem(propsB))}class Renderer extends React.Component{componentDidMount(){this._isMounted=true;this.handleRender({});this._currentFocus=null;this.props.initializeUserInput?.(this.props.widgets,this.props.problemNum??0);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}UNSAFE_componentWillReceiveProps(nextProps){if(isDifferentQuestion(this.props,nextProps)){this.props.initializeUserInput?.(nextProps.widgets,nextProps.problemNum??0);this.setState(this._getInitialWidgetState(nextProps));}}shouldComponentUpdate(nextProps,nextState){if(this.props.alwaysUpdate){return true}const stateChanged=!_.isEqual(this.state,nextState);const propsChanged=!_.isEqual(this.props,nextProps);return propsChanged||stateChanged}componentDidUpdate(prevProps,prevState){this.handleRender(prevProps);if(this.props.linterContext.highlightLint){this._translationLinter.runLinter(this.props.content,this.handletranslationLintErrors);}if(this.props.userInput&&!_.isEqual(this.props.userInput,prevProps.userInput)){this.props.apiOptions?.answerableCallback?.(this._isAnswerable());}}componentWillUnmount(){this.widgetIds=[];if(this.translationIndex!=null){getDependencies().rendererTranslationComponents.removeComponentAtIndex(this.translationIndex);}this._isMounted=false;}_isAnswerable(){if(this.props.userInput){return this.emptyWidgets().length===0}return false}_getWidgetIndexById(id){const widgetIndex=this.widgetIds.indexOf(id);if(widgetIndex<0){Log.error("Unable to get widget index in _getWidgetIndexById",Errors.Internal,{loggedMetadata:{widgets:JSON.stringify(this.props.widgets),widgetId:JSON.stringify(id)}});return 0}return widgetIndex}getWidgetProps(widgetId){const apiOptions=this.getApiOptions();const widgetOptions=this.props.widgets[widgetId].options;const widgetInfo=this.state.widgetInfo[widgetId];if(!this._interactionTrackers){this._interactionTrackers={};}let interactionTracker=this._interactionTrackers[widgetId];if(!interactionTracker){interactionTracker=this._interactionTrackers[widgetId]=new InteractionTracker(apiOptions.trackInteraction,widgetInfo&&widgetInfo.type,widgetId,getTracking(widgetInfo&&widgetInfo.type));}return {options:widgetOptions,userInput:this.props.userInput?.[widgetId],widgetId:widgetId,widgetIndex:this._getWidgetIndexById(widgetId),alignment:widgetInfo&&widgetInfo.alignment,static:widgetInfo?.static,graded:widgetInfo?.graded,problemNum:this.props.problemNum,apiOptions:this.getApiOptions(),keypadElement:this.props.keypadElement,showSolutions:this.props.showSolutions,onFocus:_.partial(this._onWidgetFocus,widgetId),onBlur:_.partial(this._onWidgetBlur,widgetId),findWidgets:this.findWidgets,reviewMode:this.props.reviewMode??false,isScorable:this.props.isScorable??false,containerSizeClass:containerSizeClass.MEDIUM,linterContext:PerseusLinter.pushContextStack(this.props.linterContext,"widget"),handleUserInput:newUserInput=>{const updatedUserInput={...this.props.userInput,[widgetId]:newUserInput};const emptyWidgetIds=emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,updatedUserInput,this.context.locale);const widgetsEmpty=emptyWidgetIds.length>0;this.props.handleUserInput?.(widgetId,newUserInput,widgetsEmpty);this.props.apiOptions?.interactionCallback?.(updatedUserInput);},trackInteraction:interactionTracker.track}}getSerializedState(){return mapObject(this.props.widgets,(widgetData,widgetId)=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getSerializedState){return excludeDenylistKeys(widget.getSerializedState())}return widgetData.options})}replaceJiptContent(content,paragraphIndex){if(paragraphIndex==null){this.setState({jiptContent:content});}else {const codeFenceRegex=/^\s*(`{3,}|~{3,})\s*(\S+)?\s*\n([\s\S]+?)\s*\1\s*$/;if(codeFenceRegex.test(content));else if(/\S\n\s*\n\S/.test(content)){content="$\\large{\\red{\\text{Please translate each "+"paragraph to a single paragraph.}}}$";}else if(/^\s*$/.test(content)){content="$\\large{\\red{\\text{Translated paragraph is "+"currently empty}}}$";}const allContent=this.getContent(this.props,this.state);const paragraphs=JiptParagraphs.parseToArray(allContent);paragraphs[paragraphIndex]=content;this.setState({jiptContent:JiptParagraphs.joinFromArray(paragraphs)});}}emptyWidgets(){if(!this.props.userInput){throw new Error(`emptyWidgets called without providing userInput to Renderer`)}return emptyWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale)}getUserInputMap(){const userInput=this.props.userInput;if(!userInput){throw new Error(`getUserInputMap called without providing userInput to Renderer`)}return userInput}getPromptJSON(){const{content}=this.props;const widgetJSON={};this.widgetIds.forEach(id=>{const widget=this.getWidgetInstance(id);widgetJSON[id]=widget?.getPromptJSON?.()||{};});return {content,widgets:widgetJSON}}score(){if(!this.props.userInput){throw new Error(`score called without providing userInput to Renderer`)}const scores=scoreWidgetsFunctional(this.state.widgetInfo,this.widgetIds,this.props.userInput,this.context.locale);const combinedScore=flattenScores(scores);return combinedScore}render(){const apiOptions=this.getApiOptions();const content=this.getContent(this.props,this.state);this.widgetIds=[];if(this.shouldRenderJiptPlaceholder(this.props,this.state)){if(!this.translationIndex){this.translationIndex=getDependencies().rendererTranslationComponents.addComponent(this);}if(!apiOptions.isArticle){return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{"data-perseus-component-index":this.translationIndex,children:content})})}}this._isTwoColumn=false;let parsedMarkdown=this.props.inline?PerseusMarkdown.parseInline(content,{isJipt:this.translationIndex!=null}):PerseusMarkdown.parse(content,{isJipt:this.translationIndex!=null});parsedMarkdown=Util.splitBlockWidgetsFromParagraphs(parsedMarkdown);if(this.props.linterContext.highlightLint){const fullLinterContext={content:this.props.content,widgets:this.props.widgets,...this.props.linterContext};PerseusLinter.runLinter(parsedMarkdown,fullLinterContext,true);this._translationLinter.applyLintErrors(parsedMarkdown,[...this.state.translationLintErrors,...this.props.legacyPerseusLint||[]]);}const markdownContents=this.outputMarkdown(Util.joinAdjacentTextNodes(parsedMarkdown),{baseElements:apiOptions.baseElements});const className=classNames$2({[ClassNames.RENDERER]:true,[ClassNames.RESPONSIVE_RENDERER]:true,[ClassNames.TWO_COLUMN_RENDERER]:this._isTwoColumn});return jsxRuntimeExports.jsx(DefinitionProvider,{children:jsxRuntimeExports.jsx("div",{className:className,children:markdownContents})})}constructor(props){super(props),this._widgetContainers=new Map,this.getApiOptions=()=>{return {...ApiOptions.defaults,...this.props.apiOptions}},this._getInitialWidgetState=props=>{const allWidgetInfo=applyDefaultsToWidgets(props.widgets);return {widgetInfo:allWidgetInfo}},this._getDefaultWidgetInfo=widgetId=>{const widgetIdParts=Util.rTypeFromWidgetId.exec(widgetId);if(widgetIdParts==null){return {}}return {type:widgetIdParts[1],graded:true,options:{}}},this._getWidgetInfo=widgetId=>{return this.state.widgetInfo[widgetId]||this._getDefaultWidgetInfo(widgetId)},this.renderWidget=(impliedType,id,state)=>{const widgetInfo=this.state.widgetInfo[id];if(widgetInfo&&widgetInfo.alignment==="full-width"){state.foundFullWidth=true;}if(widgetInfo){const type=widgetInfo&&widgetInfo.type||impliedType;return jsxRuntimeExports.jsx(WidgetContainer,{id:id,ref:node=>{const containerId=makeContainerId(id);if(node!=null){this._widgetContainers.set(containerId,node);}else {this._widgetContainers.delete(containerId);}},type:type,widgetProps:this.getWidgetProps(id)},makeContainerId(id))}return null},this.findInternalWidgets=filterCriterion=>{let filterFunc;if(typeof filterCriterion==="string"){if(filterCriterion.indexOf(" ")!==-1){const widgetId=filterCriterion;filterFunc=(id,widgetInfo,widget)=>id===widgetId;}else {const widgetType=filterCriterion;filterFunc=(id,widgetInfo,widget)=>{return widgetInfo.type===widgetType};}}else {filterFunc=filterCriterion;}const results=this.widgetIds.filter(id=>{const widgetInfo=this._getWidgetInfo(id);const widget=this.getWidgetInstance(id);return filterFunc(id,widgetInfo,widget)}).map(this.getWidgetInstance);return results},this.findWidgets=filterCriterion=>{return [...this.findInternalWidgets(filterCriterion),...this.props.findExternalWidgets(filterCriterion)]},this.getWidgetInstance=id=>{const ref=this._widgetContainers.get(makeContainerId(id));if(!ref){return null}return ref.getWidget()},this._onWidgetFocus=(id,focusPath=[])=>{if(!Array.isArray(focusPath)){throw new PerseusError("widget props.onFocus focusPath must be an Array, "+"but was"+JSON.stringify(focusPath),Errors.Internal)}this._setCurrentFocus([id].concat(focusPath));},this._onWidgetBlur=(id,blurPath)=>{const blurringFocusPath=this._currentFocus;const fullPath=[id].concat(blurPath);if(!_.isEqual(fullPath,blurringFocusPath)){return}_.defer(()=>{if(_.isEqual(this._currentFocus,blurringFocusPath)){this._setCurrentFocus(null);}});},this.getContent=(props,state)=>{return state.jiptContent||props.content},this.shouldRenderJiptPlaceholder=(props,state)=>{return getDependencies().JIPT.useJIPT&&state.jiptContent==null&&props.content.indexOf("crwdns")!==-1},this.outputMarkdown=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;state.paragraphIndex=i;const nodeOut=this.outputMarkdown(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}this._foundTextNodes=false;state.foundFullWidth=false;const output=this.outputNested(ast,state);let className;if(this.translationIndex!=null){className=null;}else {className=classNames$2({"perseus-paragraph-centered":!this._foundTextNodes&&!this.props.inline,"perseus-paragraph-full-width":state.foundFullWidth&&ast.type==="widget"});}return jsxRuntimeExports.jsx(QuestionParagraph,{className:className,translationIndex:this.translationIndex,paragraphIndex:state.paragraphIndex,inline:this.props.inline,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:output})},state.key)},this.outputNested=(ast,state)=>{if(Array.isArray(ast)){const oldKey=state.key;const result=[];let lastWasString=false;for(let i=0;i<ast.length;i++){state.key=i;const nodeOut=this.outputNested(ast[i],state);const isString=typeof nodeOut==="string";if(typeof nodeOut==="string"&&lastWasString){result[result.length-1]+=nodeOut;}else {result.push(nodeOut);}lastWasString=isString;}state.key=oldKey;return result}return this.outputNode(ast,this.outputNested,state)},this.outputNode=(node,nestedOutput,state)=>{const apiOptions=this.getApiOptions();const imagePlaceholder=apiOptions.imagePlaceholder;if(node.type==="paragraph"){const content=nestedOutput(node.content,state);if(isContentGraphie(node)||hasResponsiveImage(node,this.props)){return jsxRuntimeExports.jsx("div",{className:"deprecated-perseus-container",children:content})}if(noParagraphForInlineWidget(node)){return content}return jsxRuntimeExports.jsx("p",{className:"deprecated-perseus-container",children:content})}if(node.type==="widget"){const widgetPlaceholder=apiOptions.widgetPlaceholder;if(widgetPlaceholder){return widgetPlaceholder}this._foundTextNodes=true;if(this.widgetIds.includes(node.id)){return jsxRuntimeExports.jsx("span",{className:"renderer-widget-error",children:["Widget [[","☃"," ",node.id,"]] already exists."].join("")},state.key)}this.widgetIds.push(node.id);return this.renderWidget(node.widgetType,node.id,state)}if(node.type==="blockMath"){const content=preprocessTex(node.content);const innerStyle={overflowX:"auto",overflowY:"hidden",paddingTop:10,paddingBottom:10,marginTop:-10,marginBottom:-10};if(apiOptions.isMobile){const margin=16;const outerStyle={marginLeft:-16,marginRight:-16};const horizontalPadding={paddingLeft:margin,paddingRight:margin};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",style:outerStyle,children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:{...mobileInnerStyle,...horizontalPadding},children:jsxRuntimeExports.jsx(ZoomableTeX,{children:content})})})},state.key)}return jsxRuntimeExports.jsx("div",{className:"perseus-block-math",children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx("div",{className:"perseus-block-math-inner",style:innerStyle,children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{setAssetStatus:setAssetStatus,children:content})})})})},state.key)}if(node.type==="math"){const tex=node.content;return jsxRuntimeExports.jsx("span",{style:{whiteSpace:"nowrap"},children:jsxRuntimeExports.jsxs(ErrorBoundary,{children:[jsxRuntimeExports.jsx("span",{}),jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(Tex,{onRender:this.props.onRender,setAssetStatus:setAssetStatus,children:tex})}),jsxRuntimeExports.jsx("span",{})]})},state.key)}if(node.type==="image"){if(imagePlaceholder){return imagePlaceholder}const responsive=!state.inTable;return jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{allowZoom:true,setAssetStatus:setAssetStatus,src:PerseusMarkdown.sanitizeUrl(node.target),alt:node.alt,title:node.title,responsive:responsive,onUpdate:this.props.onRender,...getImageDimensions(node.target,this.props)})})},state.key)}if(node.type==="columns"){this._isTwoColumn=true;return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)}if(node.type==="text"){if(rContainsNonWhitespace.test(node.content)){this._foundTextNodes=true;}if(imagePlaceholder&&rImageURL.test(node.content)){return imagePlaceholder}return node.content}if(node.type==="table"||node.type==="titledTable"){const output=PerseusMarkdown.ruleOutput(node,nestedOutput,{...state,isMobile:apiOptions.isMobile,inTable:true});if(!apiOptions.isMobile){return output}const outerStyle={marginLeft:-16,marginRight:-16};const innerStyle={paddingLeft:0,paddingRight:0};const mobileInnerStyle={...innerStyle,...styles$u.mobileZoomableParentFix};const wrappedOutput=jsxRuntimeExports.jsx("div",{style:{...mobileInnerStyle,overflowX:"auto"},children:jsxRuntimeExports.jsx(ErrorBoundary,{children:jsxRuntimeExports.jsx(Zoomable$1,{animateHeight:true,children:output})})});return jsxRuntimeExports.jsx("div",{style:outerStyle,children:wrappedOutput})}return jsxRuntimeExports.jsx(ErrorBoundary,{children:PerseusMarkdown.ruleOutput(node,nestedOutput,state)},state.key)},this.handleRender=prevProps=>{const onRender=this.props.onRender;const oldOnRender=prevProps.onRender;if(onRender!==noopOnRender||oldOnRender!==noopOnRender){const node=ReactDOM__default.findDOMNode(this);if(node instanceof Element){node.querySelectorAll("img").forEach(image=>{if(oldOnRender!==noopOnRender){image.removeEventListener("load",oldOnRender);}if(onRender!==noopOnRender){image.addEventListener("load",onRender);}});}}onRender();},this._setCurrentFocus=path=>{const apiOptions=this.getApiOptions();if(!isIdPathPrefix(path,this._currentFocus)){const prevFocus=this._currentFocus;if(prevFocus){this.blurPath(prevFocus);}this._currentFocus=path;apiOptions.onFocusChange(this._currentFocus,prevFocus);}},this.focus=()=>{let id;let focusResult;for(let i=0;i<this.widgetIds.length;i++){const widgetId=this.widgetIds[i];const widget=this.getWidgetInstance(widgetId);const widgetFocusResult=widget?.focus?.();if(widgetFocusResult){id=widgetId;focusResult=widgetFocusResult;break}}if(id){let path;if(typeof focusResult==="object"){path=[id].concat(focusResult.path||[]);Log.error("Renderer received a focus result of type 'object' "+"instead of the expected type 'boolean'",Errors.Internal,{loggedMetadata:{focusResult:JSON.stringify(focusResult)}});}else {path=[id];}this._setCurrentFocus(path);return true}},this.getDOMNodeForPath=path=>{const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget?.getDOMNodeForPath){return widget.getDOMNodeForPath(interWidgetPath)}if(interWidgetPath.length===0){const container=this._widgetContainers.get(makeContainerId(widgetId));if(container){return ReactDOM__default.findDOMNode(container)}return ReactDOM__default.findDOMNode(widget)}},this.getInputPaths=()=>{const inputPaths=[];this.widgetIds.forEach(widgetId=>{const widget=this.getWidgetInstance(widgetId);if(widget&&widget.getInputPaths){const widgetInputPaths=widget.getInputPaths();widgetInputPaths.forEach(inputPath=>{const relativeInputPath=[widgetId].concat(inputPath);inputPaths.push(relativeInputPath);});}});return inputPaths},this.focusPath=path=>{if(_.isEqual(this._currentFocus,path)){return}if(this._currentFocus){this.blurPath(this._currentFocus);}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const focusWidget=this.getWidgetInstance(widgetId);focusWidget?.focusInputPath?.(interWidgetPath);},this.blurPath=path=>{if(!_.isEqual(this._currentFocus,path)){return}const widgetId=_.first(path);const interWidgetPath=_.rest(path);const widget=this.getWidgetInstance(widgetId);if(widget){const blurWidget=this.getWidgetInstance(widgetId);blurWidget?.blurInputPath?.(interWidgetPath);}},this.blur=()=>{if(this._currentFocus){this.blurPath(this._currentFocus);}},this.getWidgetIds=()=>{return this.widgetIds},this.handletranslationLintErrors=lintErrors=>{if(!this._isMounted){return}this.setState({translationLintErrors:lintErrors});};this._translationLinter=new TranslationLinter;this.state={jiptContent:null,translationLintErrors:[],...this._getInitialWidgetState(props)};}}Renderer.contextType=PerseusI18nContext;Renderer.defaultProps={content:"",widgets:{},images:{},showSolutions:"none",onRender:noopOnRender,findExternalWidgets:()=>[],alwaysUpdate:false,reviewMode:false,isScorable:false,linterContext:PerseusLinter.linterContextDefault};function getImageDimensions(url,{images}){return _.has(images,url)?images[url]:null}function hasResponsiveImage(node,props){if(Array.isArray(node.content)){return node.content.some(child=>hasResponsiveImage(child,props))}return node.type==="image"&&getImageDimensions(node.target,props)!=null}const styles$u={mobileZoomableParentFix:{transform:"translate3d(0,0,0)"}};
|
|
1677
1663
|
|
|
1678
1664
|
const{captureScratchpadTouchStart: captureScratchpadTouchStart$1}=Util;const InputWithExamples=forwardRef(function InputWithExamples({shouldShowExamples=true,onFocus=()=>{},onBlur=()=>{},disabled=false,required=false,linterContext=PerseusLinter.linterContextDefault,className="",...props},ref){const context=React.useContext(PerseusI18nContext);const inputRef=React.useRef(null);const[inputFocused,setInputFocused]=React.useState(false);const id=useId();const ariaId=`aria-for-${id}`;useImperativeHandle(ref,()=>({current:inputRef.current,focus:()=>{if(inputRef.current){inputRef.current.focus();}},blur:()=>{if(inputRef.current){inputRef.current.blur();}}}));const getInputClassName=()=>{let inputClassName=ClassNames.INPUT;if(inputFocused){inputClassName+=" "+ClassNames.FOCUSED;}if(className){inputClassName+=" "+className;}return inputClassName};const handleFocus=()=>{onFocus();setInputFocused(true);};const handleBlur=()=>{onBlur();setInputFocused(false);};const renderInput=()=>{const examplesAria=shouldShowExamples?`${props.examples[0]}
|
|
1679
1665
|
${props.examples.slice(1).join(", or\n")}`.replace(/\*/g,"").replace(/\$/g,"").replace(/\\ \\text{pi}/g," pi").replace(/\\ /g," and "):"";const inputProps={id:id,"aria-describedby":shouldShowExamples?ariaId:undefined,"aria-required":required,ref:inputRef,className:getInputClassName(),labelText:props.labelText,value:props.value,onFocus:handleFocus,onBlur:handleBlur,disabled:disabled,style:props.style,onChange:props.onChange,onTouchStart:captureScratchpadTouchStart$1,autoCapitalize:"off",autoComplete:"off",autoCorrect:"off",spellCheck:"false"};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(TextInput,{...inputProps}),jsxRuntimeExports.jsx("span",{id:ariaId,style:{display:"none"},children:examplesAria})]})};const renderTooltipContent=()=>{return jsxRuntimeExports.jsx(TooltipContent,{children:jsxRuntimeExports.jsx("div",{id:id,className:"input-with-examples-tooltip perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{content:examplesContent,linterContext:PerseusLinter.pushContextStack(linterContext,"input-with-examples"),strings:context.strings})})})};const examplesContent=props.examples.length<=2?props.examples.join(" "):props.examples.map((example,index)=>{return index===0&&example.startsWith("**")?`${example}
|
|
@@ -1757,8 +1743,6 @@ const styles$j={tooltipBody:{color:"var(--wb-semanticColor-core-foreground-neutr
|
|
|
1757
1743
|
|
|
1758
1744
|
const Definition=forwardRef(function Definition(props,ref){const{strings}=usePerseusI18n();const dependencies=useDependencies();useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"definition",widgetId:props.widgetId}});});useImperativeHandle(ref,()=>({getPromptJSON(){return getPromptJSON$l(props)}}));return jsxRuntimeExports.jsx(DefinitionConsumer,{children:({activeDefinitionId,setActiveDefinitionId})=>jsxRuntimeExports.jsx(Popover,{dismissEnabled:true,content:jsxRuntimeExports.jsx(PopoverContentCore,{style:styles$j.tooltipBody,closeButtonVisible:true,children:jsxRuntimeExports.jsx("div",{className:"perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{apiOptions:props.apiOptions,content:props.options.definition,strings:strings})})}),opened:activeDefinitionId===props.widgetId,onClose:()=>setActiveDefinitionId(null),placement:"top",children:jsxRuntimeExports.jsx(Clickable,{onClick:()=>{props.trackInteraction();setActiveDefinitionId(props.widgetId);},"aria-label":strings.definitionIdentifier({word:props.options.togglePrompt}),children:()=>jsxRuntimeExports.jsx("span",{className:styles$k.definition,children:props.options.togglePrompt})})})})});var Definition$1 = {name:"definition",displayName:"Definition",widget:Definition};
|
|
1759
1745
|
|
|
1760
|
-
const DeprecatedStandin$1=forwardRef(function DeprecatedStandin(){const{strings}=usePerseusI18n();return jsxRuntimeExports.jsx("div",{style:{paddingBlockStart:sizing.size_080,paddingBlockEnd:sizing.size_080},children:jsxRuntimeExports.jsx(Banner,{text:strings.deprecatedStandin,kind:"info"})})});var DeprecatedStandin$2 = {name:"deprecated-standin",displayName:"Deprecated Standin",widget:DeprecatedStandin$1,hidden:true};
|
|
1761
|
-
|
|
1762
1746
|
const getPromptJSON$k=widgetData=>{return {type:"dropdown",options:{items:widgetData.options.choices.map(choice=>choice.content)},userInput:{selectedIndex:widgetData.userInput.value-1}}};
|
|
1763
1747
|
|
|
1764
1748
|
const Dropdown=forwardRef(function Dropdown(props,ref){const{strings}=usePerseusI18n();const dropdownId=useId();const{choices=[],placeholder="",visibleLabel,ariaLabel}=props.options;const{apiOptions=ApiOptions.defaults,userInput={value:0},widgetId,trackInteraction,handleUserInput}=props;const isStatic=props.static??false;const dependencies=useDependencies();const isRequired=props.isScorable&&!props.reviewMode&&!isStatic&&!apiOptions.readOnly;useEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"dropdown",widgetId:widgetId}});},[]);const handleChange=selected=>{trackInteraction();handleUserInput({value:selected});};const rootRef=useRef(null);useImperativeHandle(ref,()=>({focus:()=>{if(apiOptions.readOnly||isStatic){return false}if(!rootRef.current){return false}const button=rootRef.current.querySelector("[role='combobox']");if(!(button instanceof HTMLElement)){return false}if(button instanceof HTMLButtonElement&&button.disabled||button.getAttribute("aria-disabled")==="true"){return false}const previouslyFocused=document.activeElement;button.focus();return document.activeElement===button&&previouslyFocused!==button},getPromptJSON:()=>{return getPromptJSON$k(props)},getSerializedState:()=>{const{userInput,options,...otherProps}=props;const{choices,...otherOptions}=options;return {...otherOptions,...otherProps,choices:choices.map(choice=>choice.content),selected:userInput.value}}}));const children=[jsxRuntimeExports.jsx(OptionItem,{value:"0",disabled:true,label:jsxRuntimeExports.jsx("div",{className:"perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{content:placeholder,strings:strings,apiOptions:{flags:apiOptions.flags}})}),labelAsText:placeholder},"placeholder"),...choices.map((choice,i)=>jsxRuntimeExports.jsx(OptionItem,{value:String(i+1),label:jsxRuntimeExports.jsx("div",{className:"perseus-in-wb-popover",children:jsxRuntimeExports.jsx(Renderer,{content:choice.content,strings:strings,apiOptions:{flags:apiOptions.flags}})}),labelAsText:choice.content},String(i+1)))];return jsxRuntimeExports.jsxs(View,{ref:rootRef,onClick:e=>{e.stopPropagation();},onTouchStart:e=>{e.stopPropagation();},children:[visibleLabel&&jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"label",htmlFor:dropdownId,children:visibleLabel}),jsxRuntimeExports.jsx(SingleSelect,{id:dropdownId,placeholder:"",className:"perseus-dropdown",onChange:value=>handleChange(parseInt(value)),selectedValue:String(userInput.value),disabled:Boolean(apiOptions.readOnly||isStatic),"aria-required":isRequired,"aria-label":ariaLabel||visibleLabel||strings.selectAnAnswer,showOpenerLabelAsText:false,children:children})]})});function getUserInputFromSerializedState$c(serializedState){return {value:serializedState.selected}}function getStartUserInput$d(){return {value:0}}function getCorrectUserInput$6(options){return {value:options.choices.findIndex(c=>c.correct)+1}}var Dropdown$1 = {name:"dropdown",displayName:"Drop down",widget:Dropdown,getStartUserInput: getStartUserInput$d,getCorrectUserInput: getCorrectUserInput$6,getUserInputFromSerializedState: getUserInputFromSerializedState$c};
|
|
@@ -1881,9 +1865,7 @@ class MultiButtonGroup extends React.Component{focus(){this.buttonContainerRef.c
|
|
|
1881
1865
|
|
|
1882
1866
|
function isPiMultiple(value){if(Number.isInteger(value)){return false}return value%Math.PI===0||value%(Math.PI/2)===0||value%(Math.PI/3)===0||value%(Math.PI/4)===0||value%(Math.PI/6)===0}
|
|
1883
1867
|
|
|
1884
|
-
const{firstNumericalParse,captureScratchpadTouchStart}=Util;const toNumericString=KhanMath.toNumericString;const getNumericFormat=KhanMath.getNumericFormat;class NumberInput extends React.Component{componentDidMount(){const value=this.getValue();if(this.props.allowPiTruncation&&value
|
|
1885
|
-
|
|
1886
|
-
const truth=()=>true;class RangeInput extends React.Component{render(){const value=this.props.value;const checkValidity=this.props.checkValidity||truth;return jsxRuntimeExports.jsxs("div",{className:"range-input",children:[jsxRuntimeExports.jsx(NumberInput,{...this.props,value:value[0],checkValidity:val=>checkValidity([val,value[1]]),onChange:this.onChange.bind(this,0),placeholder:this.props.placeholder[0],allowPiTruncation:this.props.allowPiTruncation}),jsxRuntimeExports.jsx(NumberInput,{...this.props,value:value[1],checkValidity:val=>checkValidity([value[0],val]),onChange:this.onChange.bind(this,1),placeholder:this.props.placeholder[1],allowPiTruncation:this.props.allowPiTruncation})]})}constructor(...args){super(...args),this.onChange=(i,newVal)=>{const value=this.props.value;if(i===0){this.props.onChange([newVal,value[1]]);}else {this.props.onChange([value[0],newVal]);}};}}RangeInput.propTypes={value:PropTypes.array.isRequired,onChange:PropTypes.func.isRequired,placeholder:PropTypes.array,checkValidity:PropTypes.func,allowPiTruncation:PropTypes.bool};RangeInput.defaultProps={placeholder:[null,null]};
|
|
1868
|
+
const{firstNumericalParse,captureScratchpadTouchStart}=Util;const toNumericString=KhanMath.toNumericString;const getNumericFormat=KhanMath.getNumericFormat;class NumberInput extends React.Component{componentDidMount(){const value=this.getValue();if(this.props.allowPiTruncation&&value!=null&&value!==0){if(this.state.format!=="pi"&&isPiMultiple(value)){this._setValue(value/Math.PI,"pi");this.setState({format:"pi"});}}}componentDidUpdate(){if(!number.equal(this.getValue(),this.props.value)){this._setValue(this.props.value,this.state.format);}}getValue(){return this.parseInputValue(this._getInput().value)}parseInputValue(value){if(value===""){const placeholder=this.props.placeholder;return _.isFinite(placeholder)?Number(placeholder):null}const result=firstNumericalParse(value);return _.isFinite(result)?result:this.props.value}_checkValidity(value){if(value==null){return true}const val=firstNumericalParse(value);const checkValidity=this.props.checkValidity;return val!=null&&_.isFinite(val)&&checkValidity(val)}_setValue(val,format){this._getInput().value=toNumericString(val,format);}render(){let classes=classNames$2({"number-input":true,"invalid-input":!this._checkValidity(this.props.value),mini:this.props.size==="mini",small:this.props.size==="small",normal:this.props.size==="normal"});if(this.props.className!=null){classes=classes+" "+this.props.className;}const{onFormatChange,checkValidity,useArrowKeys,allowPiTruncation,placeholder,size,...restProps}=this.props;return jsxRuntimeExports.jsx("input",{...restProps,placeholder:placeholder!=null?String(placeholder):undefined,className:classes,type:"text",ref:this.inputRef,onChange:this._handleChange,onFocus:this._handleFocus,onBlur:this._handleBlur,onKeyPress:this._handleBlur,onKeyDown:this._onKeyDown,onTouchStart:captureScratchpadTouchStart,defaultValue:toNumericString(this.props.value,this.state.format),value:undefined})}constructor(...args){super(...args),this.inputRef=React.createRef(),this.state={format:this.props.format??undefined},this._getInput=()=>{if(!this.inputRef.current){throw new PerseusError("Input ref accessed before set",Errors.Internal)}return this.inputRef.current},this.focus=()=>{this._getInput().focus();this._handleFocus();},this.blur=()=>{this._getInput().blur();this._handleBlur();},this._handleChange=e=>{const text=e.target.value;const value=this.parseInputValue(text);if(value==null){return}const format=getNumericFormat(text);this.props.onChange(value);if(format){this.props.onFormatChange?.(value,format);this.setState({format:format});}},this._handleFocus=()=>{if(this.props.onFocus){this.props.onFocus();}},this._handleBlur=e=>{if(e&&e.type==="keypress"&&e.keyCode!==13){return}this._setValue(this.props.value,this.state.format);if(this.props.onBlur){this.props.onBlur();}},this._onKeyDown=e=>{if(!this.props.useArrowKeys||!["ArrowUp","ArrowDown"].includes(e.key)){return}let val=this.getValue();if(val==null||val!==Math.floor(val)){return}if(e.key==="ArrowUp"){val=val+1;}else if(e.key==="ArrowDown"){val=val-1;}if(this._checkValidity(val)){this.props.onChange(val);}};}}NumberInput.defaultProps={value:null,placeholder:null,format:null,checkValidity:()=>true,useArrowKeys:false};
|
|
1887
1869
|
|
|
1888
1870
|
const LegacyGrid=({box,backgroundImage})=>{const{url,width,height}=backgroundImage??{};if(url&&typeof url==="string"){const scale=box[X]/interactiveSizes$1.defaultBoxSize;return jsxRuntimeExports.jsx(View,{style:{position:"absolute",bottom:0,left:0},children:jsxRuntimeExports.jsx(context.Consumer,{children:({setAssetStatus})=>jsxRuntimeExports.jsx(SvgImage,{src:url,allowZoom:false,width:width,height:height,scale:scale,responsive:false,setAssetStatus:setAssetStatus,alt:""})})})}return null};
|
|
1889
1871
|
|
|
@@ -2099,7 +2081,7 @@ function getUrlFromProgramID(programID){return `/python-program/${programID}/emb
|
|
|
2099
2081
|
|
|
2100
2082
|
const getPromptJSON$1=userInput=>{return {type:"sorter",userInput:{values:userInput.options,changed:userInput.changed}}};
|
|
2101
2083
|
|
|
2102
|
-
const
|
|
2084
|
+
const Sorter$1=forwardRef(function Sorter(props,ref){const dependencies=useDependencies();const sortable=useRef(null);const{options,userInput,widgetId,linterContext,apiOptions}=props;const{correct,padding}=options;const layout=correct.length>SORTER_MAX_HORIZONTAL_CARDS?"vertical":options.layout;useOnMountEffect(()=>{dependencies.analytics.onAnalyticsEvent({type:"perseus:widget:rendered:ti",payload:{widgetSubType:"null",widgetType:"sorter",widgetId:widgetId}});});useImperativeHandle(ref,()=>({moveOptionToIndex:(option,index)=>{sortable.current?.moveOptionToIndex(option,index);},getPromptJSON:()=>getPromptJSON$1(props.userInput),getSerializedState:()=>{const{userInput,options,...rest}=props;return {...rest,...options,changed:userInput.changed,options:userInput.options}}}));function handleChange(){props.handleUserInput({options:sortable.current?.getOptions()??[],changed:true});props.trackInteraction();}if(exceedsCardLimit(options.correct)){return jsxRuntimeExports.jsx(UnsupportedWidgetMessage,{widgetType:"sorter",widgetSubType:"null",widgetId:widgetId,reason:"exceeds-card-limit"})}return jsxRuntimeExports.jsx("div",{className:"perseus-clearfix",children:jsxRuntimeExports.jsx(Sortable,{apiOptions:apiOptions,options:userInput.options,layout:layout,margin:apiOptions.isMobile?8:5,padding:padding,onChange:handleChange,linterContext:linterContext,ref:sortable})})});
|
|
2103
2085
|
|
|
2104
2086
|
function getStartUserInput$1(options,problemNum){const shuffled=shuffleSorter(options,problemNum);return {options:shuffled,changed:false}}function getUserInputFromSerializedState$1(serializedState){return {changed:serializedState.changed,options:serializedState.options}}var Sorter = {name:"sorter",displayName:"Sorter",widget:Sorter$1,isLintable:true,getStartUserInput: getStartUserInput$1,getUserInputFromSerializedState: getUserInputFromSerializedState$1};
|
|
2105
2087
|
|
|
@@ -2113,11 +2095,11 @@ var styles = {"perseusVideoWidget":"perseus_gxXDcWBe","perseusVideoFixedToRespon
|
|
|
2113
2095
|
|
|
2114
2096
|
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.options;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.jsx(FixedToResponsive,{className:styles.perseusVideoFixedToResponsive,width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,children:jsxRuntimeExports.jsx("iframe",{title:this.context.strings.videoWrapper,className:styles.perseusVideoWidget,sandbox:"allow-same-origin allow-scripts",width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,src:url,allowFullScreen:true,allow:"autoplay"})},location),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};
|
|
2115
2097
|
|
|
2116
|
-
var extraWidgets = [Blank,CSProgram$1,Categorizer$1,Definition$1,
|
|
2098
|
+
var extraWidgets = [Blank,CSProgram$1,Categorizer$1,Definition$1,Dropdown$1,Explanation$1,FillInTheBlank,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,NumberLine$1,Orderer$1,PhetSimulation$1,Plotter$1,PythonProgram$1,Sorter,Table$1,Video$1];
|
|
2117
2099
|
|
|
2118
2100
|
var allWidgets = [...basicWidgets,...extraWidgets];
|
|
2119
2101
|
|
|
2120
|
-
const registerAllWidgetsForTesting=()=>{registerWidgets(allWidgets);
|
|
2102
|
+
const registerAllWidgetsForTesting=()=>{registerWidgets(allWidgets);};
|
|
2121
2103
|
|
|
2122
|
-
export {
|
|
2123
|
-
//# sourceMappingURL=chunk-register-all-widgets-for-testing-
|
|
2104
|
+
export { MathRenderingContext as $, ApiOptions as A, ButtonGroup as B, ClassNames as C, DependenciesContext as D, Expression as E, Categorizer$1 as F, Graphie as G, HUD as H, Icon as I, JiptParagraphs as J, InteractiveGraph$1 as K, Matrix$1 as L, MathInput as M, NumberInput as N, Table$1 as O, PerseusI18nContext as P, Plotter$1 as Q, Renderer as R, SvgImage as S, TextInput as T, UserInputManager as U, Grapher$1 as V, iconChevronDown as W, iconTrash as X, bodyXsmallBold as Y, dependencies as Z, Log as _, InlineIcon as a, interactiveSizes$1 as a0, PerseusI18nContextProvider as a1, usePerseusI18n as a2, KhanColors as a3, preprocessTex as a4, registerAllWidgetsForTesting as a5, containerSizeClass as a6, getInteractiveBoxFromSizeClass as a7, mathOnlyParser as a8, getWidgetSubTypeByWidgetId as a9, contentHasWidgetType as aa, getWidgetFromWidgetMap as ab, getWidgetsFromWidgetMap as ac, getAbsoluteValueCoords as ad, getCircleCoords as ae, getExponentialCoords as af, getLogarithmCoords as ag, getLineCoords as ah, getLinearSystemCoords as ai, getPointCoords as aj, getPolygonCoords as ak, getSegmentCoords as al, getSinusoidCoords as am, getTangentCoords as an, getVectorCoords as ao, getQuadraticCoords as ap, getAngleCoords as aq, deriveUserInputFromSerializedState as ar, parseDataFromJSONP as as, MultiButtonGroup as b, basicWidgets as c, Util as d, extraWidgets as e, hintBorderWidth as f, getDependencies as g, hintPaddingInlineStart as h, context as i, jsxRuntimeExports as j, getWidgetTypeByWidgetId as k, getWidgetExport as l, mediaQueries as m, PerseusMarkdown as n, getEquationString as o, defaultPlotProps as p, chooseType as q, registerWidgets as r, sharedStyles as s, typeToButton as t, DEFAULT_GRAPHER_PROPS as u, allWidgets as v, widgets$1 as w, InputNumber as x, NumericInput$1 as y, Radio as z };
|
|
2105
|
+
//# sourceMappingURL=chunk-register-all-widgets-for-testing-e-q2XfHc.js.map
|