@khanacademy/perseus-editor 33.3.1 → 34.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import React__default, { useState, useId, createElement, useRef, useEffect } from 'react';
4
4
  import { PerseusMarkdown, Util, components, Widgets, excludeDenylistKeys, ApiOptions, Log, preprocessTex, Dependencies, iconTrash, ClassNames, usePerseusI18n, UserInputManager, Renderer, Categorizer as Categorizer$1, Changeable, EditorJsonify, Expression, interactiveSizes, GrapherWidget, GrapherUtil, containerSizeClass, getInteractiveBoxFromSizeClass, iconChevronDown, KhanColors, mathOnlyParser, getLogarithmCoords, getAngleCoords, getPolygonCoords, getPointCoords, getQuadraticCoords, getTangentCoords, getExponentialCoords, getSinusoidCoords, getCircleCoords, getLinearSystemCoords, getSegmentCoords, getVectorCoords, getLineCoords, getAbsoluteValueCoords, InteractiveGraphWidget, MatrixWidget, PlotterWidget, TableWidget, widgets } from '@khanacademy/perseus';
5
5
  export { widgets } from '@khanacademy/perseus';
6
- import { generateImageWidget, generateImageOptions, isSuccess, CoreWidgetRegistry, applyDefaultsToWidget, getWidgetIdsFromContent, PerseusError, Errors, parseAndMigratePerseusArticle, getDefaultAnswerArea, ItemExtras, isFeatureOn, parseAndMigratePerseusItem, categorizerLogic, csProgramLogic, definitionLogic, dropdownLogic, explanationLogic, expressionLogic, deriveExtraKeys, PerseusExpressionAnswerFormConsidered, freeResponseLogic, gradedGroupLogic, gradedGroupSetLogic, grapherLogic, GrapherUtil as GrapherUtil$1, groupLogic, iframeLogic, imageLogic, inputNumberLogic, interactionLogic, lockedFigureColors, lockedFigureColorNames, lockedFigureFillStyles, getDefaultFigureForType, interactiveGraphLogic, labelImageLogic, matcherLogic, matrixLogic, getMatrixSize, measurerLogic, numberLineLogic, numericInputLogic, ordererLogic, phetSimulationLogic, makeSafeUrl, plotterLogic, plotterPlotTypes, pythonProgramLogic, radioLogic, deriveNumCorrect, sorterLogic, tableLogic, videoLogic } from '@khanacademy/perseus-core';
6
+ import { generateImageWidget, generateImageOptions, isSuccess, CoreWidgetRegistry, applyDefaultsToWidget, getWidgetIdsFromContent, PerseusError, Errors, parseAndMigratePerseusArticle, getDefaultAnswerArea, ItemExtras, isFeatureOn, parseAndMigratePerseusItem, categorizerLogic, csProgramLogic, definitionLogic, dropdownLogic, explanationLogic, expressionLogic, deriveExtraKeys, PerseusExpressionAnswerFormConsidered, freeResponseLogic, gradedGroupLogic, gradedGroupSetLogic, grapherLogic, GrapherUtil as GrapherUtil$1, groupLogic, iframeLogic, imageLogic, numericInputLogic, interactionLogic, lockedFigureColors, lockedFigureColorNames, lockedFigureFillStyles, getDefaultFigureForType, interactiveGraphLogic, labelImageLogic, matcherLogic, matrixLogic, getMatrixSize, measurerLogic, numberLineLogic, ordererLogic, phetSimulationLogic, makeSafeUrl, plotterLogic, plotterPlotTypes, pythonProgramLogic, radioLogic, deriveNumCorrect, sorterLogic, tableLogic, videoLogic } from '@khanacademy/perseus-core';
7
7
  import * as PerseusLinter from '@khanacademy/perseus-linter';
8
8
  import Button from '@khanacademy/wonder-blocks-button';
9
9
  import arrowCircleDownIcon from '@phosphor-icons/core/bold/arrow-circle-down-bold.svg';
@@ -44,7 +44,6 @@ import trashIcon$1 from '@phosphor-icons/core/regular/trash.svg';
44
44
  import { KhanMath, angles, vector, number } from '@khanacademy/kmath';
45
45
  import Banner from '@khanacademy/wonder-blocks-banner';
46
46
  import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clockwise-bold.svg';
47
- import { inputNumberAnswerTypes } from '@khanacademy/perseus-score';
48
47
  import Clickable from '@khanacademy/wonder-blocks-clickable';
49
48
  import { StatusBadge, NeutralBadge } from '@khanacademy/wonder-blocks-badge';
50
49
  import pencilCircle from '@phosphor-icons/core/regular/pencil-circle.svg';
@@ -64,7 +63,7 @@ import minusCircle from '@phosphor-icons/core/regular/minus-circle.svg';
64
63
  import checkIcon from '@phosphor-icons/core/bold/check-bold.svg';
65
64
  import minusCircleIcon from '@phosphor-icons/core/bold/minus-circle-bold.svg';
66
65
 
67
- const libName="@khanacademy/perseus-editor";const libVersion="33.3.1";addLibraryVersionToPerseusDebug(libName,libVersion);
66
+ const libName="@khanacademy/perseus-editor";const libVersion="34.1.0";addLibraryVersionToPerseusDebug(libName,libVersion);
68
67
 
69
68
  var jsxRuntime = {exports: {}};
70
69
 
@@ -1440,7 +1439,7 @@ class DragTarget extends React.Component{handleDrop(e){e.stopPropagation();e.pre
1440
1439
 
1441
1440
  function focusWithChromeStickyFocusBugWorkaround(element){element.focus({preventScroll:true});}const alignmentInfoMap={block:"Block - widget is constrained to the width of the article content container.","wrap-left":"Wrap left - widget is 50% width of the article content container, and is left aligned with text wrapping on the right of the widget.","wrap-right":"Wrap right - widget is 50% width of the article content container, and is right aligned with text wrapping on the left of the widget.","full-width":"Full width - widget extends beyond the width of the article content container."};
1442
1441
 
1443
- const{InfoTip: InfoTip$q}=components;function AlignmentSelect({supportedAlignments,widgetInfo,isEditingDisabled,onChange,style}){const labelId=useId();return jsxRuntimeExports.jsxs(View,{style:[{flexDirection:"row",alignItems:"center",gap:sizing.size_080},style],children:[jsxRuntimeExports.jsx(BodyText,{id:labelId,tag:"span",children:"Alignment"}),jsxRuntimeExports.jsx(SingleSelect,{"aria-labelledby":labelId,selectedValue:widgetInfo.alignment??"default",disabled:isEditingDisabled,onChange:value=>{const syntheticEvent={currentTarget:{value}};onChange(syntheticEvent);},placeholder:"Select alignment",style:styles$P.singleSelectShort,children:supportedAlignments.map(alignment=>jsxRuntimeExports.jsx(OptionItem,{value:alignment,label:alignment},alignment))}),jsxRuntimeExports.jsx(InfoTip$q,{children:jsxRuntimeExports.jsx("ul",{children:supportedAlignments.map((alignment,index)=>jsxRuntimeExports.jsx("li",{style:{marginBlockEnd:index<supportedAlignments.length-1?sizing.size_240:0},children:alignmentInfoMap[alignment]},alignment))})})]})}const styles$P=StyleSheet.create({singleSelectShort:{height:sizing.size_260}});
1442
+ const{InfoTip: InfoTip$p}=components;function AlignmentSelect({supportedAlignments,widgetInfo,isEditingDisabled,onChange,style}){const labelId=useId();return jsxRuntimeExports.jsxs(View,{style:[{flexDirection:"row",alignItems:"center",gap:sizing.size_080},style],children:[jsxRuntimeExports.jsx(BodyText,{id:labelId,tag:"span",children:"Alignment"}),jsxRuntimeExports.jsx(SingleSelect,{"aria-labelledby":labelId,selectedValue:widgetInfo.alignment??"default",disabled:isEditingDisabled,onChange:value=>{const syntheticEvent={currentTarget:{value}};onChange(syntheticEvent);},placeholder:"Select alignment",style:styles$P.singleSelectShort,children:supportedAlignments.map(alignment=>jsxRuntimeExports.jsx(OptionItem,{value:alignment,label:alignment},alignment))}),jsxRuntimeExports.jsx(InfoTip$p,{children:jsxRuntimeExports.jsx("ul",{children:supportedAlignments.map((alignment,index)=>jsxRuntimeExports.jsx("li",{style:{marginBlockEnd:index<supportedAlignments.length-1?sizing.size_240:0},children:alignmentInfoMap[alignment]},alignment))})})]})}const styles$P=StyleSheet.create({singleSelectShort:{height:sizing.size_260}});
1444
1443
 
1445
1444
  function WidgetEditorSettings(props){const{bestPractices,supportsStaticMode,isStatic,onStaticChange,supportsGradedToggle,isGraded,onGradedChange,supportedAlignments,widgetInfo,onAlignmentChange,isEditingDisabled}=props;const hasControls=supportsStaticMode||supportsGradedToggle||supportedAlignments.length>1;if(!bestPractices&&!hasControls){return null}return jsxRuntimeExports.jsxs(View,{className:"widget-editor-settings-container",children:[bestPractices&&jsxRuntimeExports.jsx(View,{className:"best-practices-container",children:jsxRuntimeExports.jsx(Link,{href:bestPractices.url,target:"_blank",children:bestPractices.label})}),hasControls&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[supportsStaticMode&&jsxRuntimeExports.jsx(LabeledSwitch,{label:"Static",checked:isStatic,disabled:isEditingDisabled,onChange:onStaticChange,style:{marginBlockEnd:sizing.size_060}}),supportsGradedToggle&&jsxRuntimeExports.jsx(LabeledSwitch,{label:"Interactive but ungraded",checked:!isGraded,disabled:isEditingDisabled,onChange:e=>{onGradedChange(!e);},style:{marginBlockEnd:sizing.size_060}}),supportedAlignments.length>1&&jsxRuntimeExports.jsx(AlignmentSelect,{supportedAlignments:supportedAlignments,widgetInfo:widgetInfo,isEditingDisabled:isEditingDisabled,onChange:onAlignmentChange,style:{marginBlockEnd:sizing.size_060}})]})]})}
1446
1445
 
@@ -1494,9 +1493,9 @@ class AnswerAreaDiff extends React.Component{render(){const{after,before,title}=
1494
1493
 
1495
1494
  class ItemDiff extends React.Component{render(){const{before,after}=this.props;const hintCount=Math.max(before.hints.length,after.hints.length);const question=jsxRuntimeExports.jsx(RendererDiff,{before:before.question,after:after.question,title:"Question",showAlignmentOptions:false,showSeparator:true});const extras=jsxRuntimeExports.jsx(AnswerAreaDiff,{before:before.answerArea?before.answerArea:undefined,after:after.answerArea?after.answerArea:undefined,title:"Question extras"});const hints=_.times(hintCount,function(n){return jsxRuntimeExports.jsx(RendererDiff,{before:n<before.hints.length?before.hints[n]:undefined,after:n<after.hints.length?after.hints[n]:undefined,title:`Hint ${n+1}`,showAlignmentOptions:false,showSeparator:n<hintCount-1},n)});return jsxRuntimeExports.jsx(Dependencies.DependenciesContext.Provider,{value:this.props.dependencies,children:jsxRuntimeExports.jsxs("div",{className:"framework-perseus",children:[question,extras,hints.length>0&&jsxRuntimeExports.jsx("div",{className:"diff-separator"}),hints]})})}}
1496
1495
 
1497
- const{InfoTip: InfoTip$p,InlineIcon: InlineIcon$2}=components;class HintEditor extends React.Component{serialize(){invariant(this.editor.current,"cannot serialize HintEditor with no Editor");return {...this.editor.current.serialize(),replace:this.props.replace??undefined}}render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-hint-editor "+this.props.className,children:[this.props.showTitle&&jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Hint"}),jsxRuntimeExports.jsx(Editor,{ref:this.editor,apiOptions:this.props.apiOptions,widgets:this.props.widgets||undefined,content:this.props.content||undefined,images:this.props.images,placeholder:"Type your hint here...",imageUploader:this.props.imageUploader,onChange:this.props.onChange,widgetIsOpen:this.props.widgetIsOpen},this.props.itemId),jsxRuntimeExports.jsxs("div",{className:"hint-controls-container clearfix",children:[this.props.showMoveButtons&&jsxRuntimeExports.jsxs("span",{className:"reorder-hints",children:[jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isLast?"hidden":"",onClick:_.partial(this.props.onMove,1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowDown})})," ",jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isFirst?"hidden":"",onClick:_.partial(this.props.onMove,-1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowUp})})," ",this.props.isLast&&jsxRuntimeExports.jsx(InfoTip$p,{children:jsxRuntimeExports.jsx("p",{children:"The last hint is automatically bolded."})})]}),jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.replace,onChange:this.handleReplaceChanged}),"Replace previous hint",this.props.showRemoveButton&&jsxRuntimeExports.jsxs("button",{type:"button",className:"remove-hint simple-button orange",onClick:this.props.onRemove,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconTrash}),"Remove this hint"," "]})]})]})}constructor(...args){super(...args),this.editor=React.createRef(),this.handleReplaceChanged=e=>{this.props.onChange({replace:e.target.checked});},this.focus=()=>{this.editor.current?.focus();},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()};}}HintEditor.defaultProps={className:"",content:"",replace:false,showMoveButtons:true,showTitle:true,showRemoveButton:true};class CombinedHintEditor extends React.Component{componentDidMount(){this.updatePreview();}componentDidUpdate(){this.updatePreview();}serialize(){invariant(this.editor.current,"cannot serialize CombinedHintEditor with no HintEditor");return this.editor.current.serialize()}render(){const isMobile=this.props.deviceType==="phone"||this.props.deviceType==="tablet";return jsxRuntimeExports.jsxs("div",{className:"perseus-combined-hint-editor "+"perseus-editor-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(HintEditor,{ref:this.editor,itemId:this.props.itemId,isFirst:this.props.isFirst,isLast:this.props.isLast,widgets:this.props.hint.widgets,content:this.props.hint.content,images:this.props.hint.images,replace:this.props.hint.replace,imageUploader:this.props.imageUploader,onChange:this.props.onChange,onRemove:this.props.onRemove,onMove:this.props.onMove,apiOptions:this.props.apiOptions,widgetIsOpen:this.props.widgetIsOpen})}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell",children:jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.deviceType,nochrome:true,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:this.frame,datasetKey:"mobile",datasetValue:isMobile,seamless:true,url:this.props.previewURL})})})]})}constructor(...args){super(...args),this.editor=React.createRef(),this.frame=React.createRef(),this.updatePreview=()=>{this.frame.current?.sendNewData({type:"hint",data:{hint:this.props.hint,pos:this.props.pos,apiOptions:this.props.apiOptions,linterContext:{contentType:"hint",highlightLint:this.props.highlightLint}}});},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.focus=()=>{this.editor.current?.focus();};}}CombinedHintEditor.defaultProps={highlightLint:false};class CombinedHintsEditor extends React.Component{handleHintChange(i,newProps){const hints=[...this.props.hints];hints[i]=_.extend({},this.serializeHint(i),newProps);this.props.onChange({hints:hints});}handleHintRemove(i){if(!confirm("Are you sure you want to delete this hint?")){return}const hints=[...this.props.hints];hints.splice(i,1);this.props.onChange({hints:hints});}handleHintMove(i,dir){const hints=[...this.props.hints];const hint=hints.splice(i,1)[0];hints.splice(i+dir,0,hint);this.props.onChange({hints:hints});}serialize(){return this.props.hints.map((_,i)=>this.serializeHint(i))}serializeHint(index){return this.refs["hintEditor"+index].serialize()}render(){const{itemId,hints}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const hintElems=_.map(hints,function(hint,i){return jsxRuntimeExports.jsx("fieldset",{disabled:editingDisabled,children:jsxRuntimeExports.jsx(CombinedHintEditor,{ref:"hintEditor"+i,isFirst:i===0,isLast:i+1===hints.length,itemId:itemId,hint:hint,pos:i,imageUploader:this.props.imageUploader,onChange:this.handleHintChange.bind(this,i),onRemove:this.handleHintRemove.bind(this,i),onMove:this.handleHintMove.bind(this,i),deviceType:this.props.deviceType,apiOptions:this.props.apiOptions,highlightLint:this.props.highlightLint,previewURL:this.props.previewURL,widgetIsOpen:this.props.widgetIsOpen})},"hintEditor"+i)},this);return jsxRuntimeExports.jsxs("div",{className:"perseus-hints-editor perseus-editor-table",children:[hintElems,jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsx("div",{className:"add-hint-container perseus-editor-left-cell",children:jsxRuntimeExports.jsxs("button",{type:"button",className:"add-hint simple-button orange",disabled:editingDisabled,onClick:this.addHint,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconPlus})," Add a hint"]})})})]})}constructor(...args){super(...args),this.addHint=()=>{const hint={content:"",images:{},widgets:{}};const hints=[...this.props.hints,hint];this.props.onChange({hints:hints});},this.getSaveWarnings=()=>{return _.chain(this.props.hints).map((hint,i)=>{return _.map(this.refs["hintEditor"+i].getSaveWarnings(),issue=>"Hint "+(i+1)+": "+issue)}).flatten(true).value()};}}CombinedHintsEditor.HintEditor=HintEditor;CombinedHintsEditor.defaultProps={onChange:()=>{},hints:[],highlightLint:false};
1496
+ const{InfoTip: InfoTip$o,InlineIcon: InlineIcon$2}=components;class HintEditor extends React.Component{serialize(){invariant(this.editor.current,"cannot serialize HintEditor with no Editor");return {...this.editor.current.serialize(),replace:this.props.replace??undefined}}render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-hint-editor "+this.props.className,children:[this.props.showTitle&&jsxRuntimeExports.jsx("div",{className:"pod-title",children:"Hint"}),jsxRuntimeExports.jsx(Editor,{ref:this.editor,apiOptions:this.props.apiOptions,widgets:this.props.widgets||undefined,content:this.props.content||undefined,images:this.props.images,placeholder:"Type your hint here...",imageUploader:this.props.imageUploader,onChange:this.props.onChange,widgetIsOpen:this.props.widgetIsOpen},this.props.itemId),jsxRuntimeExports.jsxs("div",{className:"hint-controls-container clearfix",children:[this.props.showMoveButtons&&jsxRuntimeExports.jsxs("span",{className:"reorder-hints",children:[jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isLast?"hidden":"",onClick:_.partial(this.props.onMove,1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowDown})})," ",jsxRuntimeExports.jsx("button",{type:"button",className:this.props.isFirst?"hidden":"",onClick:_.partial(this.props.onMove,-1),children:jsxRuntimeExports.jsx(InlineIcon$2,{...iconCircleArrowUp})})," ",this.props.isLast&&jsxRuntimeExports.jsx(InfoTip$o,{children:jsxRuntimeExports.jsx("p",{children:"The last hint is automatically bolded."})})]}),jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.replace,onChange:this.handleReplaceChanged}),"Replace previous hint",this.props.showRemoveButton&&jsxRuntimeExports.jsxs("button",{type:"button",className:"remove-hint simple-button orange",onClick:this.props.onRemove,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconTrash}),"Remove this hint"," "]})]})]})}constructor(...args){super(...args),this.editor=React.createRef(),this.handleReplaceChanged=e=>{this.props.onChange({replace:e.target.checked});},this.focus=()=>{this.editor.current?.focus();},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()};}}HintEditor.defaultProps={className:"",content:"",replace:false,showMoveButtons:true,showTitle:true,showRemoveButton:true};class CombinedHintEditor extends React.Component{componentDidMount(){this.updatePreview();}componentDidUpdate(){this.updatePreview();}serialize(){invariant(this.editor.current,"cannot serialize CombinedHintEditor with no HintEditor");return this.editor.current.serialize()}render(){const isMobile=this.props.deviceType==="phone"||this.props.deviceType==="tablet";return jsxRuntimeExports.jsxs("div",{className:"perseus-combined-hint-editor "+"perseus-editor-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-editor-left-cell",children:jsxRuntimeExports.jsx(HintEditor,{ref:this.editor,itemId:this.props.itemId,isFirst:this.props.isFirst,isLast:this.props.isLast,widgets:this.props.hint.widgets,content:this.props.hint.content,images:this.props.hint.images,replace:this.props.hint.replace,imageUploader:this.props.imageUploader,onChange:this.props.onChange,onRemove:this.props.onRemove,onMove:this.props.onMove,apiOptions:this.props.apiOptions,widgetIsOpen:this.props.widgetIsOpen})}),jsxRuntimeExports.jsx("div",{className:"perseus-editor-right-cell",children:jsxRuntimeExports.jsx(DeviceFramer,{deviceType:this.props.deviceType,nochrome:true,children:jsxRuntimeExports.jsx(IframeContentRenderer,{ref:this.frame,datasetKey:"mobile",datasetValue:isMobile,seamless:true,url:this.props.previewURL})})})]})}constructor(...args){super(...args),this.editor=React.createRef(),this.frame=React.createRef(),this.updatePreview=()=>{this.frame.current?.sendNewData({type:"hint",data:{hint:this.props.hint,pos:this.props.pos,apiOptions:this.props.apiOptions,linterContext:{contentType:"hint",highlightLint:this.props.highlightLint}}});},this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()},this.focus=()=>{this.editor.current?.focus();};}}CombinedHintEditor.defaultProps={highlightLint:false};class CombinedHintsEditor extends React.Component{handleHintChange(i,newProps){const hints=[...this.props.hints];hints[i]=_.extend({},this.serializeHint(i),newProps);this.props.onChange({hints:hints});}handleHintRemove(i){if(!confirm("Are you sure you want to delete this hint?")){return}const hints=[...this.props.hints];hints.splice(i,1);this.props.onChange({hints:hints});}handleHintMove(i,dir){const hints=[...this.props.hints];const hint=hints.splice(i,1)[0];hints.splice(i+dir,0,hint);this.props.onChange({hints:hints});}serialize(){return this.props.hints.map((_,i)=>this.serializeHint(i))}serializeHint(index){return this.refs["hintEditor"+index].serialize()}render(){const{itemId,hints}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const hintElems=_.map(hints,function(hint,i){return jsxRuntimeExports.jsx("fieldset",{disabled:editingDisabled,children:jsxRuntimeExports.jsx(CombinedHintEditor,{ref:"hintEditor"+i,isFirst:i===0,isLast:i+1===hints.length,itemId:itemId,hint:hint,pos:i,imageUploader:this.props.imageUploader,onChange:this.handleHintChange.bind(this,i),onRemove:this.handleHintRemove.bind(this,i),onMove:this.handleHintMove.bind(this,i),deviceType:this.props.deviceType,apiOptions:this.props.apiOptions,highlightLint:this.props.highlightLint,previewURL:this.props.previewURL,widgetIsOpen:this.props.widgetIsOpen})},"hintEditor"+i)},this);return jsxRuntimeExports.jsxs("div",{className:"perseus-hints-editor perseus-editor-table",children:[hintElems,jsxRuntimeExports.jsx("div",{className:"perseus-editor-row",children:jsxRuntimeExports.jsx("div",{className:"add-hint-container perseus-editor-left-cell",children:jsxRuntimeExports.jsxs("button",{type:"button",className:"add-hint simple-button orange",disabled:editingDisabled,onClick:this.addHint,children:[jsxRuntimeExports.jsx(InlineIcon$2,{...iconPlus})," Add a hint"]})})})]})}constructor(...args){super(...args),this.addHint=()=>{const hint={content:"",images:{},widgets:{}};const hints=[...this.props.hints,hint];this.props.onChange({hints:hints});},this.getSaveWarnings=()=>{return _.chain(this.props.hints).map((hint,i)=>{return _.map(this.refs["hintEditor"+i].getSaveWarnings(),issue=>"Hint "+(i+1)+": "+issue)}).flatten(true).value()};}}CombinedHintsEditor.HintEditor=HintEditor;CombinedHintsEditor.defaultProps={onChange:()=>{},hints:[],highlightLint:false};
1498
1497
 
1499
- const calculatorVariants=[{label:"Scientific calculator",tip:"Provides the student with a scientific calculator.",variant:"scientific"},{label:"Graphing calculator",tip:"Provides the student with a graphing calculator.",variant:"graphing"},{label:"Four-function calculator",tip:"Provides the student with a four-function calculator.",variant:"four_function"}];const{InfoTip: InfoTip$o}=components;class ItemExtrasEditor extends React.Component{shouldShowCalculatorVariants(){return this.props.calculatorVariant!==null}shouldShowFinancialCalculatorOptions(){return this.props.financialCalculatorMonthlyPayment||this.props.financialCalculatorTotalAmount||this.props.financialCalculatorTimeToPayOff}serialize(){const data={...ItemExtrasEditor.defaultProps};for(const key of ItemExtras){data[key]=!!this.props[key];}return data}render(){const{editingDisabled}=this.props;return jsxRuntimeExports.jsx("div",{className:"perseus-answer-editor",children:jsxRuntimeExports.jsxs("div",{className:"perseus-answer-options",children:[jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show calculator",disabled:editingDisabled,infoTip:"Use the calculator when completing difficult calculations is NOT the intent of the question. DON’T use the calculator when testing the student’s ability to complete different types of computations.",checked:this.shouldShowCalculatorVariants(),onChange:newCheckedState=>{this.props.onChange({calculator:newCheckedState,calculatorVariant:newCheckedState?"scientific":null});}}),isFeatureOn(this.props,"desmos-calculator")&&this.shouldShowCalculatorVariants()&&calculatorVariants.map(calcVariant=>jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:calcVariant.label,disabled:editingDisabled,infoTip:calcVariant.tip,checked:this.props.calculatorVariant===calcVariant.variant,onChange:()=>{this.props.onChange({calculatorVariant:calcVariant.variant});},indent:true},calcVariant.variant)),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show financial calculator",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a financial calculator, e.g., for answering financial questions. Once checked, requires at least one of the three options below to be checked.",checked:this.shouldShowFinancialCalculatorOptions(),onChange:newCheckedState=>{this.props.onChange({financialCalculatorMonthlyPayment:newCheckedState,financialCalculatorTotalAmount:newCheckedState,financialCalculatorTimeToPayOff:newCheckedState});}}),this.shouldShowFinancialCalculatorOptions()&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include monthly payment",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a monthly payment calculator; e.g., given a loan amount, interest rate, and term, what is the monthly payment?",checked:this.props.financialCalculatorMonthlyPayment,onChange:newCheckedState=>{this.props.onChange({financialCalculatorMonthlyPayment:newCheckedState});},indent:true}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include total amount",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a total amount calculator; e.g., given a monthly payment, interest rate, and term, what is the total amount to be paid?",checked:this.props.financialCalculatorTotalAmount,onChange:newCheckedState=>{this.props.onChange({financialCalculatorTotalAmount:newCheckedState});},indent:true}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include time-to-pay-off",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a time to pay off calculator; e.g., given a loan amount, interest rate, and monthly payment, how long will it take to pay off the loan?",checked:this.props.financialCalculatorTimeToPayOff,onChange:newCheckedState=>{this.props.onChange({financialCalculatorTimeToPayOff:newCheckedState});},indent:true})]}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show periodic table",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a periodic table of the elements, e.g., for answering chemistry questions.",checked:this.props.periodicTable,onChange:newCheckedState=>{this.props.onChange({periodicTable:newCheckedState,periodicTableWithKey:false});}}),this.props.periodicTable&&jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include key/legend with periodic table",disabled:editingDisabled,infoTip:"Include a key for HS courses; omit for AP chemistry.",checked:this.props.periodicTableWithKey,onChange:newCheckedState=>{this.props.onChange({periodicTableWithKey:newCheckedState});},indent:true})]})})}}ItemExtrasEditor.defaultProps=getDefaultAnswerArea();const ItemExtraCheckbox=props=>jsxRuntimeExports.jsx(View,{style:[styles$O.checkbox,props.indent?styles$O.indented:undefined],children:jsxRuntimeExports.jsx(Checkbox$1,{disabled:props.disabled,label:jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row"},children:[props.label," ",jsxRuntimeExports.jsx(InfoTip$o,{children:props.infoTip})]}),checked:props.checked,onChange:newCheckedState=>props.onChange(newCheckedState)})});const styles$O=StyleSheet.create({indented:{marginInlineStart:spacing.large_24}});
1498
+ const calculatorVariants=[{label:"Scientific calculator",tip:"Provides the student with a scientific calculator.",variant:"scientific"},{label:"Graphing calculator",tip:"Provides the student with a graphing calculator.",variant:"graphing"},{label:"Four-function calculator",tip:"Provides the student with a four-function calculator.",variant:"four_function"}];const{InfoTip: InfoTip$n}=components;class ItemExtrasEditor extends React.Component{shouldShowCalculatorVariants(){return this.props.calculatorVariant!==undefined}shouldShowFinancialCalculatorOptions(){return this.props.financialCalculatorMonthlyPayment||this.props.financialCalculatorTotalAmount||this.props.financialCalculatorTimeToPayOff}serialize(){const data={...ItemExtrasEditor.defaultProps};for(const key of ItemExtras){data[key]=!!this.props[key];}return data}render(){const{editingDisabled}=this.props;return jsxRuntimeExports.jsx("div",{className:"perseus-answer-editor",children:jsxRuntimeExports.jsxs("div",{className:"perseus-answer-options",children:[jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show calculator",disabled:editingDisabled,infoTip:"Use the calculator when completing difficult calculations is NOT the intent of the question. DON’T use the calculator when testing the student’s ability to complete different types of computations.",checked:this.shouldShowCalculatorVariants(),onChange:newCheckedState=>{this.props.onChange({calculator:newCheckedState,calculatorVariant:newCheckedState?"scientific":undefined});}}),isFeatureOn(this.props,"desmos-calculator")&&this.shouldShowCalculatorVariants()&&calculatorVariants.map(calcVariant=>jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:calcVariant.label,disabled:editingDisabled,infoTip:calcVariant.tip,checked:this.props.calculatorVariant===calcVariant.variant,onChange:()=>{this.props.onChange({calculatorVariant:calcVariant.variant});},indent:true},calcVariant.variant)),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show financial calculator",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a financial calculator, e.g., for answering financial questions. Once checked, requires at least one of the three options below to be checked.",checked:this.shouldShowFinancialCalculatorOptions(),onChange:newCheckedState=>{this.props.onChange({financialCalculatorMonthlyPayment:newCheckedState,financialCalculatorTotalAmount:newCheckedState,financialCalculatorTimeToPayOff:newCheckedState});}}),this.shouldShowFinancialCalculatorOptions()&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include monthly payment",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a monthly payment calculator; e.g., given a loan amount, interest rate, and term, what is the monthly payment?",checked:this.props.financialCalculatorMonthlyPayment,onChange:newCheckedState=>{this.props.onChange({financialCalculatorMonthlyPayment:newCheckedState});},indent:true}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include total amount",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a total amount calculator; e.g., given a monthly payment, interest rate, and term, what is the total amount to be paid?",checked:this.props.financialCalculatorTotalAmount,onChange:newCheckedState=>{this.props.onChange({financialCalculatorTotalAmount:newCheckedState});},indent:true}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include time-to-pay-off",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a time to pay off calculator; e.g., given a loan amount, interest rate, and monthly payment, how long will it take to pay off the loan?",checked:this.props.financialCalculatorTimeToPayOff,onChange:newCheckedState=>{this.props.onChange({financialCalculatorTimeToPayOff:newCheckedState});},indent:true})]}),jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Show periodic table",disabled:editingDisabled,infoTip:"This provides the student with the ability to view a periodic table of the elements, e.g., for answering chemistry questions.",checked:this.props.periodicTable,onChange:newCheckedState=>{this.props.onChange({periodicTable:newCheckedState,periodicTableWithKey:false});}}),this.props.periodicTable&&jsxRuntimeExports.jsx(ItemExtraCheckbox,{label:"Include key/legend with periodic table",disabled:editingDisabled,infoTip:"Include a key for HS courses; omit for AP chemistry.",checked:this.props.periodicTableWithKey,onChange:newCheckedState=>{this.props.onChange({periodicTableWithKey:newCheckedState});},indent:true})]})})}}ItemExtrasEditor.defaultProps=getDefaultAnswerArea();const ItemExtraCheckbox=props=>jsxRuntimeExports.jsx(View,{style:[styles$O.checkbox,props.indent?styles$O.indented:undefined],children:jsxRuntimeExports.jsx(Checkbox$1,{disabled:props.disabled,label:jsxRuntimeExports.jsxs(View,{style:{flexDirection:"row"},children:[props.label," ",jsxRuntimeExports.jsx(InfoTip$n,{children:props.infoTip})]}),checked:props.checked,onChange:newCheckedState=>props.onChange(newCheckedState)})});const styles$O=StyleSheet.create({indented:{marginInlineStart:spacing.large_24}});
1500
1499
 
1501
1500
  var issuesList = {"axe-core":{"user-fixable":["aria-input-field-name","aria-meter-name","aria-toggle-field-name","image-alt","input-image-alt","label","link-name","list","role-img-alt","select-name","summary-name","svg-img-alt","video-caption"]}};
1502
1501
 
@@ -1524,22 +1523,22 @@ const{TextListEditor: TextListEditor$4}=components;const Categorizer=Categorizer
1524
1523
 
1525
1524
  class BlurInput extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({value:nextProps.value});}focus(){this.input.current?.focus();}render(){return jsxRuntimeExports.jsx("input",{ref:this.input,className:this.props.className,style:this.props.style,type:"text",value:this.state.value,onChange:this.handleChange,onBlur:this.handleBlur})}constructor(props){super(props),this.input=React.createRef(),this.handleChange=e=>{this.setState({value:e.target.value});},this.handleBlur=e=>{this.props.onChange(e.target.value);};this.state={value:this.props.value};}}
1526
1525
 
1527
- const{InfoTip: InfoTip$n}=components;const DEFAULT_WIDTH=400;const DEFAULT_HEIGHT=400;let PairEditor$1 = class PairEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("fieldset",{className:"pair-editor",children:[jsxRuntimeExports.jsxs("label",{children:["Name:"," ",jsxRuntimeExports.jsx(BlurInput,{value:this.props.name,onChange:this.change("name")})]}),jsxRuntimeExports.jsxs("label",{children:[" ","Value:"," ",jsxRuntimeExports.jsx(BlurInput,{value:this.props.value,onChange:this.change("value")})]})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}};PairEditor$1.propTypes={...Changeable.propTypes,name:PropTypes.string,value:PropTypes.string};PairEditor$1.defaultProps={name:"",value:""};let PairsEditor$1 = class PairsEditor extends React.Component{render(){const editors=_.map(this.props.pairs,(pair,i)=>{return jsxRuntimeExports.jsx(PairEditor$1,{name:pair.name,value:pair.value,onChange:this.handlePairChange.bind(this,i)},i)});return jsxRuntimeExports.jsx("div",{children:editors})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.handlePairChange=(pairIndex,pair)=>{const pairs=this.props.pairs.slice();pairs[pairIndex]=pair;const lastPair=pairs[pairs.length-1];if(lastPair.name&&lastPair.value){pairs.push({name:"",value:""});}this.change("pairs",pairs);},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}};PairsEditor$1.propTypes={...Changeable.propTypes,pairs:PropTypes.arrayOf(PropTypes.shape({name:PropTypes.string,value:PropTypes.string})).isRequired};const KA_PROGRAM_URL=/khanacademy\.org\/computer-programming\/[^/]+\/(\d+)/;function isolateProgramID(programUrl){const match=KA_PROGRAM_URL.exec(programUrl);if(match){programUrl=match[1];}return programUrl}class CSProgramEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Url or Program ID:"," ",jsxRuntimeExports.jsx(BlurInput,{value:this.props.programID,onChange:this._handleProgramIDChange})]}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx(Checkbox$1,{label:"Show Editor",checked:this.props.showEditor,onChange:value=>{this.props.onChange({showEditor:value});}}),jsxRuntimeExports.jsx(InfoTip$n,{children:'If you show the editor, you should use the "full-width" alignment to make room for the width of the editor.'}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx(Checkbox$1,{label:"Show Buttons",checked:this.props.showButtons,onChange:value=>{this.props.onChange({showButtons:value});}}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsxs("label",{children:["Settings:",jsxRuntimeExports.jsx(PairsEditor$1,{name:"settings",pairs:this.props.settings,onChange:this._handleSettingsChange}),jsxRuntimeExports.jsxs(InfoTip$n,{children:["Settings that you add here are available to the program as an object returned by ",jsxRuntimeExports.jsx("code",{children:"Program.settings()"})]})]})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this._handleSettingsChange=settings=>{this.change({settings:settings.pairs});},this._handleProgramIDChange=programID=>{programID=isolateProgramID(programID);const{isDevServer,InitialRequestUrl}=Dependencies.getDependencies();const host=isDevServer?InitialRequestUrl.origin:"https://www.khanacademy.org";const baseUrl=`${host}/api/internal/scratchpads/${programID}`;$.getJSON(baseUrl).done(programInfo=>{const programType=programInfo.userAuthoredContentType;this.change({width:programInfo.width,height:programInfo.height,programID:programID,programType:programType});}).fail((jqxhr,textStatus,error)=>{Log.error("Error retrieving scratchpad info for program ID ",Errors.TransientService,{cause:error,loggedMetadata:{textStatus,programID}});this.change({width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,programID:programID,programType:null});});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}CSProgramEditor.propTypes={...Changeable.propTypes};CSProgramEditor.widgetName="cs-program";CSProgramEditor.defaultProps=csProgramLogic.defaultWidgetOptions;
1526
+ const{InfoTip: InfoTip$m}=components;const DEFAULT_WIDTH=400;const DEFAULT_HEIGHT=400;let PairEditor$1 = class PairEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("fieldset",{className:"pair-editor",children:[jsxRuntimeExports.jsxs("label",{children:["Name:"," ",jsxRuntimeExports.jsx(BlurInput,{value:this.props.name,onChange:this.change("name")})]}),jsxRuntimeExports.jsxs("label",{children:[" ","Value:"," ",jsxRuntimeExports.jsx(BlurInput,{value:this.props.value,onChange:this.change("value")})]})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}};PairEditor$1.propTypes={...Changeable.propTypes,name:PropTypes.string,value:PropTypes.string};PairEditor$1.defaultProps={name:"",value:""};let PairsEditor$1 = class PairsEditor extends React.Component{render(){const editors=_.map(this.props.pairs,(pair,i)=>{return jsxRuntimeExports.jsx(PairEditor$1,{name:pair.name,value:pair.value,onChange:this.handlePairChange.bind(this,i)},i)});return jsxRuntimeExports.jsx("div",{children:editors})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.handlePairChange=(pairIndex,pair)=>{const pairs=this.props.pairs.slice();pairs[pairIndex]=pair;const lastPair=pairs[pairs.length-1];if(lastPair.name&&lastPair.value){pairs.push({name:"",value:""});}this.change("pairs",pairs);},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}};PairsEditor$1.propTypes={...Changeable.propTypes,pairs:PropTypes.arrayOf(PropTypes.shape({name:PropTypes.string,value:PropTypes.string})).isRequired};const KA_PROGRAM_URL=/khanacademy\.org\/computer-programming\/[^/]+\/(\d+)/;function isolateProgramID(programUrl){const match=KA_PROGRAM_URL.exec(programUrl);if(match){programUrl=match[1];}return programUrl}class CSProgramEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Url or Program ID:"," ",jsxRuntimeExports.jsx(BlurInput,{value:this.props.programID,onChange:this._handleProgramIDChange})]}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx(Checkbox$1,{label:"Show Editor",checked:this.props.showEditor,onChange:value=>{this.props.onChange({showEditor:value});}}),jsxRuntimeExports.jsx(InfoTip$m,{children:'If you show the editor, you should use the "full-width" alignment to make room for the width of the editor.'}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx(Checkbox$1,{label:"Show Buttons",checked:this.props.showButtons,onChange:value=>{this.props.onChange({showButtons:value});}}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsxs("label",{children:["Settings:",jsxRuntimeExports.jsx(PairsEditor$1,{name:"settings",pairs:this.props.settings,onChange:this._handleSettingsChange}),jsxRuntimeExports.jsxs(InfoTip$m,{children:["Settings that you add here are available to the program as an object returned by ",jsxRuntimeExports.jsx("code",{children:"Program.settings()"})]})]})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this._handleSettingsChange=settings=>{this.change({settings:settings.pairs});},this._handleProgramIDChange=programID=>{programID=isolateProgramID(programID);const{isDevServer,InitialRequestUrl}=Dependencies.getDependencies();const host=isDevServer?InitialRequestUrl.origin:"https://www.khanacademy.org";const baseUrl=`${host}/api/internal/scratchpads/${programID}`;$.getJSON(baseUrl).done(programInfo=>{const programType=programInfo.userAuthoredContentType;this.change({width:programInfo.width,height:programInfo.height,programID:programID,programType:programType});}).fail((jqxhr,textStatus,error)=>{Log.error("Error retrieving scratchpad info for program ID ",Errors.TransientService,{cause:error,loggedMetadata:{textStatus,programID}});this.change({width:DEFAULT_WIDTH,height:DEFAULT_HEIGHT,programID:programID,programType:null});});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}CSProgramEditor.propTypes={...Changeable.propTypes};CSProgramEditor.widgetName="cs-program";CSProgramEditor.defaultProps=csProgramLogic.defaultWidgetOptions;
1528
1527
 
1529
1528
  const{TextInput: TextInput$6}=components;class DefinitionEditor extends React.Component{static initializeWidgetOptions(params){const defaultWidgetOptions={...definitionLogic.defaultWidgetOptions};if(params.selectedText){defaultWidgetOptions.togglePrompt=params.selectedText;}return defaultWidgetOptions}render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-definition-editor",children:[jsxRuntimeExports.jsx("a",{href:"https://docs.google.com/document/d/1udaPef4imOfTMhmLDlWq4SM0mxL0r3YHFZE-5J1uGfo",target:"_blank",rel:"noreferrer",children:"Definition style guide"}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Word to be defined:"," ",jsxRuntimeExports.jsx(TextInput$6,{value:this.props.togglePrompt,onChange:this.change("togglePrompt"),placeholder:"define me"})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(Editor,{apiOptions:this.props.apiOptions,content:this.props.definition,widgetEnabled:false,placeholder:"definition goes here",onChange:props=>{const newProps={};if(_.has(props,"content")){newProps.definition=props.content;}this.change(newProps);}})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}DefinitionEditor.propTypes={...Changeable.propTypes,togglePrompt:PropTypes.string,definition:PropTypes.string,apiOptions:PropTypes.any};DefinitionEditor.widgetName="definition";DefinitionEditor.defaultProps=definitionLogic.defaultWidgetOptions;
1530
1529
 
1531
1530
  class DeprecatedStandinEditor extends React.Component{serialize(){return EditorJsonify.serialize.call(this)}render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("p",{children:"This widget has been deprecated and removed"}),jsxRuntimeExports.jsx("p",{children:"Learners will see a message and they will not be graded on this part. Please replace this widget with a supported one."})]})}}DeprecatedStandinEditor.widgetName="deprecated-standin";
1532
1531
 
1533
- const{InfoTip: InfoTip$m}=components;class DropdownEditor extends React.Component{render(){const dropdownGroupName=_.uniqueId("perseus_dropdown_");const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-dropdown",children:[jsxRuntimeExports.jsxs("div",{className:"dropdown-info",children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Dropdown"}),jsxRuntimeExports.jsx(InfoTip$m,{children:jsxRuntimeExports.jsxs("p",{children:["The drop down is useful for making inequalities in a custom format. We normally use the symbols ","<",","," ",">",', ≤, ≥ (in that order) which you can copy into the choices. When possible, use the "multiple choice" answer type instead.']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Visible label",jsxRuntimeExports.jsx(TextField,{value:this.props.visibleLabel,onChange:this.onVisibleLabelChange})]}),jsxRuntimeExports.jsx(InfoTip$m,{children:jsxRuntimeExports.jsx("p",{children:"Optional visible label"})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Aria label",jsxRuntimeExports.jsx(TextField,{value:this.props.ariaLabel,onChange:this.onAriaLabelChange,type:"text"})]}),jsxRuntimeExports.jsx(InfoTip$m,{children:jsxRuntimeExports.jsxs("p",{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writing accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})," ",'If left blank, the value will default to "Select an answer".']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Placeholder",jsxRuntimeExports.jsx(TextField,{value:this.props.placeholder,onChange:this.onPlaceholderChange,placeholder:"Placeholder value"})]}),jsxRuntimeExports.jsx(InfoTip$m,{children:jsxRuntimeExports.jsx("p",{children:"This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."})})]}),jsxRuntimeExports.jsx("div",{className:"clearfix"}),jsxRuntimeExports.jsx(BodyText,{children:"Choices"}),jsxRuntimeExports.jsx("ul",{className:"dropdown-choices",children:this.props.choices.map((choice,i)=>{const choiceBackgroundColor=choice.correct?semanticColor.core.background.success.subtle:semanticColor.core.background.critical.subtle;return jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("div",{className:"dropdown-choice",children:[jsxRuntimeExports.jsx("input",{type:"radio",ref:"radio"+i,name:dropdownGroupName,checked:choice.correct,onChange:()=>this.onCorrectChange(i)}),jsxRuntimeExports.jsx(TextField,{value:choice.content,ref:"editor"+i,"aria-label":`Choice ${i+1} content`,disabled:editingDisabled,style:{backgroundColor:choiceBackgroundColor},onChange:newContent=>this.onContentChange(i,newContent)}),jsxRuntimeExports.jsx(IconButton,{icon:trashIcon,"aria-label":"Delete choice",disabled:editingDisabled,kind:"tertiary",size:"small",onClick:()=>this.removeChoice(i)})]})},""+i)},this)}),jsxRuntimeExports.jsx("div",{className:"add-choice-container",children:jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:editingDisabled,onClick:this.addChoice,startIcon:plusIcon,children:"Add a choice"})})]})}constructor(...args){super(...args),this.onVisibleLabelChange=visibleLabel=>{this.props.onChange({visibleLabel});},this.onAriaLabelChange=ariaLabel=>{this.props.onChange({ariaLabel});},this.onPlaceholderChange=placeholder=>{this.props.onChange({placeholder});},this.onCorrectChange=choiceIndex=>{const choices=_.map(this.props.choices,function(choice,i){return _.extend({},choice,{correct:i===choiceIndex})});this.props.onChange({choices:choices});},this.onContentChange=(choiceIndex,newContent)=>{const choices=this.props.choices.slice();const choice=_.clone(choices[choiceIndex]);choice.content=newContent;choices[choiceIndex]=choice;this.props.onChange({choices:choices});},this.addChoice=()=>{const choices=this.props.choices;const blankChoice={content:"",correct:false};this.props.onChange({choices:choices.concat([blankChoice])},this.focus.bind(this,choices.length));},this.removeChoice=choiceIndex=>{const choices=_(this.props.choices).clone();choices.splice(choiceIndex,1);this.props.onChange({choices:choices});},this.focus=i=>{ReactDOM.findDOMNode(this.refs["editor"+i]).focus();return true},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}DropdownEditor.propTypes={choices:PropTypes.arrayOf(PropTypes.shape({content:PropTypes.string,correct:PropTypes.bool})),placeholder:PropTypes.string};DropdownEditor.widgetName="dropdown";DropdownEditor.defaultProps=dropdownLogic.defaultWidgetOptions;
1532
+ const{InfoTip: InfoTip$l}=components;class DropdownEditor extends React.Component{render(){const dropdownGroupName=_.uniqueId("perseus_dropdown_");const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-dropdown",children:[jsxRuntimeExports.jsxs("div",{className:"dropdown-info",children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Dropdown"}),jsxRuntimeExports.jsx(InfoTip$l,{children:jsxRuntimeExports.jsxs("p",{children:["The drop down is useful for making inequalities in a custom format. We normally use the symbols ","<",","," ",">",', ≤, ≥ (in that order) which you can copy into the choices. When possible, use the "multiple choice" answer type instead.']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Visible label",jsxRuntimeExports.jsx(TextField,{value:this.props.visibleLabel,onChange:this.onVisibleLabelChange})]}),jsxRuntimeExports.jsx(InfoTip$l,{children:jsxRuntimeExports.jsx("p",{children:"Optional visible label"})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Aria label",jsxRuntimeExports.jsx(TextField,{value:this.props.ariaLabel,onChange:this.onAriaLabelChange,type:"text"})]}),jsxRuntimeExports.jsx(InfoTip$l,{children:jsxRuntimeExports.jsxs("p",{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writing accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})," ",'If left blank, the value will default to "Select an answer".']})})]}),jsxRuntimeExports.jsxs("div",{className:"dropdown-field",children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",children:["Placeholder",jsxRuntimeExports.jsx(TextField,{value:this.props.placeholder,onChange:this.onPlaceholderChange,placeholder:"Placeholder value"})]}),jsxRuntimeExports.jsx(InfoTip$l,{children:jsxRuntimeExports.jsx("p",{children:"This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."})})]}),jsxRuntimeExports.jsx("div",{className:"clearfix"}),jsxRuntimeExports.jsx(BodyText,{children:"Choices"}),jsxRuntimeExports.jsx("ul",{className:"dropdown-choices",children:this.props.choices.map((choice,i)=>{const choiceBackgroundColor=choice.correct?semanticColor.core.background.success.subtle:semanticColor.core.background.critical.subtle;return jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("div",{className:"dropdown-choice",children:[jsxRuntimeExports.jsx("input",{type:"radio",ref:"radio"+i,name:dropdownGroupName,checked:choice.correct,onChange:()=>this.onCorrectChange(i)}),jsxRuntimeExports.jsx(TextField,{value:choice.content,ref:"editor"+i,"aria-label":`Choice ${i+1} content`,disabled:editingDisabled,style:{backgroundColor:choiceBackgroundColor},onChange:newContent=>this.onContentChange(i,newContent)}),jsxRuntimeExports.jsx(IconButton,{icon:trashIcon,"aria-label":"Delete choice",disabled:editingDisabled,kind:"tertiary",size:"small",onClick:()=>this.removeChoice(i)})]})},""+i)},this)}),jsxRuntimeExports.jsx("div",{className:"add-choice-container",children:jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:editingDisabled,onClick:this.addChoice,startIcon:plusIcon,children:"Add a choice"})})]})}constructor(...args){super(...args),this.onVisibleLabelChange=visibleLabel=>{this.props.onChange({visibleLabel});},this.onAriaLabelChange=ariaLabel=>{this.props.onChange({ariaLabel});},this.onPlaceholderChange=placeholder=>{this.props.onChange({placeholder});},this.onCorrectChange=choiceIndex=>{const choices=_.map(this.props.choices,function(choice,i){return _.extend({},choice,{correct:i===choiceIndex})});this.props.onChange({choices:choices});},this.onContentChange=(choiceIndex,newContent)=>{const choices=this.props.choices.slice();const choice=_.clone(choices[choiceIndex]);choice.content=newContent;choices[choiceIndex]=choice;this.props.onChange({choices:choices});},this.addChoice=()=>{const choices=this.props.choices;const blankChoice={content:"",correct:false};this.props.onChange({choices:choices.concat([blankChoice])},this.focus.bind(this,choices.length));},this.removeChoice=choiceIndex=>{const choices=_(this.props.choices).clone();choices.splice(choiceIndex,1);this.props.onChange({choices:choices});},this.focus=i=>{ReactDOM.findDOMNode(this.refs["editor"+i]).focus();return true},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}DropdownEditor.propTypes={choices:PropTypes.arrayOf(PropTypes.shape({content:PropTypes.string,correct:PropTypes.bool})),placeholder:PropTypes.string};DropdownEditor.widgetName="dropdown";DropdownEditor.defaultProps=dropdownLogic.defaultWidgetOptions;
1534
1533
 
1535
1534
  const{TextInput: TextInput$5}=components;class ExplanationEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-explanation-editor",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Prompt to show explanation:"," ",jsxRuntimeExports.jsx(TextInput$5,{value:this.props.showPrompt,onChange:this.change("showPrompt")})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("label",{children:["Prompt to hide explanation:"," ",jsxRuntimeExports.jsx(TextInput$5,{value:this.props.hidePrompt,onChange:this.change("hidePrompt")})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(Editor,{apiOptions:this.props.apiOptions,content:this.props.explanation,widgets:this.props.widgets,widgetEnabled:true,immutableWidgets:false,onChange:props=>{const newProps={};if(_.has(props,"content")){newProps.explanation=props.content;}if(_.has(props,"widgets")){newProps.widgets=props.widgets;}this.change(newProps);}})})]})}constructor(...args){super(...args),this.state={},this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}ExplanationEditor.propTypes={...Changeable.propTypes,showPrompt:PropTypes.string,hidePrompt:PropTypes.string,explanation:PropTypes.string,widgets:PropTypes.object,apiOptions:PropTypes.any};ExplanationEditor.widgetName="explanation";ExplanationEditor.defaultProps=explanationLogic.defaultWidgetOptions;
1536
1535
 
1537
1536
  var styles$M = {"paddedX":"perseus_xyIPJvSm","paddedY":"perseus_6B-8VzAW","answerOption":"perseus_SHUAvRqo","buttonRow":"perseus_yBc0LCPb","buttonSets":"perseus_h0zeeqNR","answersSubtitle":"perseus_xbG0OWq1","answersGroup":"perseus_XphVr0Eg","answersList":"perseus_-z--eTDm","deleteButton":"perseus_UuEVVICK"};
1538
1537
 
1539
- const{ButtonGroup: ButtonGroup$7,InfoTip: InfoTip$l}=components;const buttonSetsList=["basic","trig","prealgebra","logarithms","scientific","basic relations","advanced relations"];class ExpressionEditor extends React.Component{serialize(){const{answerForms,buttonSets,functions,times,visibleLabel,ariaLabel}=this.props;return {answerForms,buttonSets,functions,times,visibleLabel,ariaLabel,extraKeys:deriveExtraKeys(this.props)}}updateAnswerForm(index,answerFormProps){const answerForms=this.props.answerForms.slice();answerForms[index]=answerFormProps;const{extraKeys:_,...restProps}=this.props;const extraKeys=deriveExtraKeys({...restProps,answerForms});this.props.onChange({answerForms,extraKeys});}changeSimplify(index,simplify){const answerForm={...this.props.answerForms[index],simplify};this.updateAnswerForm(index,answerForm);}changeForm(index,form){const answerForm={...this.props.answerForms[index],form};this.updateAnswerForm(index,answerForm);}changeConsidered(index,considered){const answerForm={...this.props.answerForms[index],considered};this.updateAnswerForm(index,answerForm);}changeTimes(times){this.props.onChange({times:times});}render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;const answerOptions=this.props.answerForms.map((ans,index)=>{const expressionProps={times:this.props.times,functions:this.props.functions,buttonSets:this.props.buttonSets,buttonsVisible:"focused",userInput:ans.value,handleUserInput:input=>this.changeExpressionWidget(index,input),trackInteraction:()=>{},widgetId:this.props.widgetId+"-"+ans.key,visibleLabel:this.props.visibleLabel,ariaLabel:this.props.ariaLabel};return jsxRuntimeExports.jsx(AnswerOption,{considered:ans.considered,editingDisabled:editingDisabled,expressionProps:expressionProps,form:ans.form,simplify:ans.simplify,onDelete:()=>this.handleRemoveForm(index),onChangeSimplify:simplify=>this.changeSimplify(index,simplify),onChangeForm:form=>this.changeForm(index,form),onChangeConsidered:considered=>this.changeConsidered(index,considered)},ans.key)});const buttonSetChoices=buttonSetsList.map(name=>{const isBasic=name==="basic";const checked=this.props.buttonSets.includes(name)||isBasic;return jsxRuntimeExports.jsx(Checkbox$1,{label:name,checked:checked,disabled:isBasic,onChange:()=>this.handleButtonSet(name)},name)});buttonSetChoices.unshift(jsxRuntimeExports.jsx(Checkbox$1,{label:"show ÷ button",checked:this.props.buttonSets.includes("basic+div"),onChange:this.handleToggleDiv},"show ÷ button"));return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(Heading$1,{size:"medium",children:"Global Options"}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Visible label",jsxRuntimeExports.jsx(InfoTip$l,{children:"Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."})]}),value:this.props.visibleLabel||"",onChange:this.handleVisibleLabel})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Aria label",jsxRuntimeExports.jsxs(InfoTip$l,{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writting accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})]})]}),value:this.props.ariaLabel||"",onChange:this.handleAriaLabel})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Function variables",jsxRuntimeExports.jsx(InfoTip$l,{children:'Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means "f of x" and not "f times x".'})]}),value:this.state.functionsInternal,onChange:this.handleFunctions})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Use × instead of ⋅ for multiplication",jsxRuntimeExports.jsx(InfoTip$l,{children:"For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."})]}),checked:this.props.times,onChange:newCheckedState=>{this.changeTimes(newCheckedState);}})}),jsxRuntimeExports.jsxs("div",{className:styles$M.paddedY,children:[jsxRuntimeExports.jsx(Heading$1,{size:"small",className:styles$M.buttonSets,children:"Button Sets"}),buttonSetChoices]}),jsxRuntimeExports.jsx(Heading$1,{size:"medium",children:"Answers"}),jsxRuntimeExports.jsx(BodyText,{size:"small",className:styles$M.answersSubtitle,children:"student responses area matched against these from top to bottom"}),jsxRuntimeExports.jsxs(View,{className:styles$M.answersGroup,children:[jsxRuntimeExports.jsx(View,{className:styles$M.answersList,children:answerOptions}),jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.newAnswer,children:"Add new answer"})]})]})}constructor(props){super(props),this.getSaveWarnings=()=>{const issues=[];if(this.props.answerForms.length===0){issues.push("No answers specified");}else {const hasCorrect=this.props.answerForms.some(form=>{return form.considered==="correct"});if(!hasCorrect){issues.push("No correct answer specified");}_(this.props.answerForms).each((form,ix)=>{if(this.props.value===""){issues.push(`Answer ${ix+1} is empty`);}else {const expression=KAS.parse(form.value,{functions:this.props.functions});if(!expression.parsed){issues.push(`Couldn't parse ${form.value}`);}else if(form.simplify&&!expression.expr.isSimplified()){issues.push(`${form.value} isn't simplified, but is required" +
1540
- " to be`);}}});}return issues},this.newAnswer=()=>{const answerForms=this.props.answerForms.slice();const newKey=crypto.randomUUID();const newAnswerForm={considered:"correct",form:false,key:`${newKey}`,simplify:false,value:""};answerForms.push(newAnswerForm);this.props.onChange({answerForms});},this.handleRemoveForm=i=>{const updatedAnswerForms=this.props.answerForms.slice();updatedAnswerForms.splice(i,1);this.props.onChange({answerForms:updatedAnswerForms});},this.handleButtonSet=changingName=>{const buttonSetNames=buttonSetsList;const buttonSets=buttonSetNames.filter(set=>{return this.props.buttonSets.includes(set)!==(set===changingName)});this.props.onChange({buttonSets});},this.handleToggleDiv=()=>{let keep;let remove;if(this.props.buttonSets.includes("basic+div")){keep="basic";remove="basic+div";}else {keep="basic+div";remove="basic";}const buttonSets=this.props.buttonSets.filter(set=>set!==remove).concat(keep);this.props.onChange({buttonSets});},this.handleTexInsert=str=>{this.refs.expression.insert(str);},this.handleFunctions=value=>{this.setState({functionsInternal:value});const newProps={};newProps.functions=value.split(/[ ,]+/).filter(isTruthy);this.props.onChange(newProps);},this.handleVisibleLabel=visibleLabel=>{this.props.onChange({visibleLabel});},this.handleAriaLabel=ariaLabel=>{this.props.onChange({ariaLabel});},this.changeExpressionWidget=(index,input)=>{const answerForm={...this.props.answerForms[index],value:input};this.updateAnswerForm(index,answerForm);};this.state={functionsInternal:this.props.functions.join(" ")};}}ExpressionEditor.widgetName="expression";ExpressionEditor.defaultProps={...expressionLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};const findNextIn=function(arr,val){let ix=arr.indexOf(val);ix=(ix+1)%arr.length;return arr[ix]};class AnswerOption extends React.Component{render(){const{editingDisabled}=this.props;const removeButton=this.state.deleteFocused?jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleImSure,actionType:"destructive",children:"I'm sure!"}),jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleCancelDelete,kind:"secondary",children:"Cancel"})]}):jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleDelete,actionType:"destructive",kind:"tertiary",className:styles$M.deleteButton,children:"Delete"});return jsxRuntimeExports.jsxs("div",{className:styles$M.answerOption,children:[jsxRuntimeExports.jsx(ButtonGroup$7,{onChange:this.toggleConsidered,allowEmpty:false,disabled:editingDisabled,value:this.props.considered,selectedButtonStyle:consideredButtonStyles[this.props.considered],buttons:PerseusExpressionAnswerFormConsidered.map(c=>({value:c,content:c,title:`This answer will be considered ${c}`}))}),jsxRuntimeExports.jsx(Expression,{...this.props.expressionProps}),jsxRuntimeExports.jsx("div",{className:`${styles$M.paddedY} ${styles$M.paddedX}`,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Answer expression must have the same form.",jsxRuntimeExports.jsx(InfoTip$l,{children:"The student's answer must be in the same form. Commutativity and excess negative signs are ignored."})]}),checked:this.props.form,onChange:this.props.onChangeForm})}),jsxRuntimeExports.jsx("div",{className:`${styles$M.paddedY} ${styles$M.paddedX}`,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Answer expression must be fully expanded and simplified.",jsxRuntimeExports.jsx(InfoTip$l,{children:'The student\'s answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response "Your answer is not fully expanded and simplified."'})]}),checked:this.props.simplify,onChange:this.props.onChangeSimplify})}),jsxRuntimeExports.jsx("div",{className:`${styles$M.buttonRow} ${styles$M.paddedY}`,children:removeButton})]})}constructor(...args){super(...args),this.state={deleteFocused:false},this.handleImSure=()=>{this.props.onDelete();this.handleCancelDelete();},this.handleCancelDelete=()=>{this.setState({deleteFocused:false});},this.handleDelete=()=>{this.setState({deleteFocused:true});},this.toggleConsidered=()=>{const newVal=findNextIn(PerseusExpressionAnswerFormConsidered,this.props.considered);this.props.onChangeConsidered(newVal);};}}const wbStyles$1=StyleSheet.create({answerStatusWrong:{backgroundColor:semanticColor.core.background.critical.subtle},answerStatusCorrect:{backgroundColor:semanticColor.core.background.success.subtle},answerStatusUngraded:{backgroundColor:semanticColor.core.background.instructive.subtle}});const consideredButtonStyles={wrong:wbStyles$1.answerStatusWrong,correct:wbStyles$1.answerStatusCorrect,ungraded:wbStyles$1.answerStatusUngraded};
1538
+ const{ButtonGroup: ButtonGroup$7,InfoTip: InfoTip$k}=components;const buttonSetsList=["basic","trig","prealgebra","logarithms","scientific","basic relations","advanced relations"];class ExpressionEditor extends React.Component{serialize(){const{answerForms,buttonSets,functions,times,visibleLabel,ariaLabel}=this.props;return {answerForms,buttonSets,functions,times,visibleLabel,ariaLabel,extraKeys:deriveExtraKeys(this.props)}}updateAnswerForm(index,answerFormProps){const answerForms=this.props.answerForms.slice();answerForms[index]=answerFormProps;const{extraKeys:_,...restProps}=this.props;const extraKeys=deriveExtraKeys({...restProps,answerForms});this.props.onChange({answerForms,extraKeys});}changeSimplify(index,simplify){const answerForm={...this.props.answerForms[index],simplify};this.updateAnswerForm(index,answerForm);}changeForm(index,form){const answerForm={...this.props.answerForms[index],form};this.updateAnswerForm(index,answerForm);}changeConsidered(index,considered){const answerForm={...this.props.answerForms[index],considered};this.updateAnswerForm(index,answerForm);}changeTimes(times){this.props.onChange({times:times});}render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;const answerOptions=this.props.answerForms.map((ans,index)=>{const expressionProps={times:this.props.times,functions:this.props.functions,buttonSets:this.props.buttonSets,buttonsVisible:"focused",userInput:ans.value,handleUserInput:input=>this.changeExpressionWidget(index,input),trackInteraction:()=>{},widgetId:this.props.widgetId+"-"+ans.key,visibleLabel:this.props.visibleLabel,ariaLabel:this.props.ariaLabel};return jsxRuntimeExports.jsx(AnswerOption,{considered:ans.considered,editingDisabled:editingDisabled,expressionProps:expressionProps,form:ans.form,simplify:ans.simplify,onDelete:()=>this.handleRemoveForm(index),onChangeSimplify:simplify=>this.changeSimplify(index,simplify),onChangeForm:form=>this.changeForm(index,form),onChangeConsidered:considered=>this.changeConsidered(index,considered)},ans.key)});const buttonSetChoices=buttonSetsList.map(name=>{const isBasic=name==="basic";const checked=this.props.buttonSets.includes(name)||isBasic;return jsxRuntimeExports.jsx(Checkbox$1,{label:name,checked:checked,disabled:isBasic,onChange:()=>this.handleButtonSet(name)},name)});buttonSetChoices.unshift(jsxRuntimeExports.jsx(Checkbox$1,{label:"show ÷ button",checked:this.props.buttonSets.includes("basic+div"),onChange:this.handleToggleDiv},"show ÷ button"));return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(Heading$1,{size:"medium",children:"Global Options"}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Visible label",jsxRuntimeExports.jsx(InfoTip$k,{children:"Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."})]}),value:this.props.visibleLabel||"",onChange:this.handleVisibleLabel})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Aria label",jsxRuntimeExports.jsxs(InfoTip$k,{children:["Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writting accessible labels, please see"," ",jsxRuntimeExports.jsx("a",{href:"https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",target:"_blank",rel:"noreferrer",children:"this article."})]})]}),value:this.props.ariaLabel||"",onChange:this.handleAriaLabel})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(LabeledTextField,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Function variables",jsxRuntimeExports.jsx(InfoTip$k,{children:'Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means "f of x" and not "f times x".'})]}),value:this.state.functionsInternal,onChange:this.handleFunctions})}),jsxRuntimeExports.jsx("div",{className:styles$M.paddedY,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Use × instead of ⋅ for multiplication",jsxRuntimeExports.jsx(InfoTip$k,{children:"For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."})]}),checked:this.props.times,onChange:newCheckedState=>{this.changeTimes(newCheckedState);}})}),jsxRuntimeExports.jsxs("div",{className:styles$M.paddedY,children:[jsxRuntimeExports.jsx(Heading$1,{size:"small",className:styles$M.buttonSets,children:"Button Sets"}),buttonSetChoices]}),jsxRuntimeExports.jsx(Heading$1,{size:"medium",children:"Answers"}),jsxRuntimeExports.jsx(BodyText,{size:"small",className:styles$M.answersSubtitle,children:"student responses area matched against these from top to bottom"}),jsxRuntimeExports.jsxs(View,{className:styles$M.answersGroup,children:[jsxRuntimeExports.jsx(View,{className:styles$M.answersList,children:answerOptions}),jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.newAnswer,children:"Add new answer"})]})]})}constructor(props){super(props),this.getSaveWarnings=()=>{const issues=[];if(this.props.answerForms.length===0){issues.push("No answers specified");}else {const hasCorrect=this.props.answerForms.some(form=>{return form.considered==="correct"});if(!hasCorrect){issues.push("No correct answer specified");}_(this.props.answerForms).each((form,ix)=>{if(this.props.value===""){issues.push(`Answer ${ix+1} is empty`);}else {const expression=KAS.parse(form.value,{functions:this.props.functions});if(!expression.parsed){issues.push(`Couldn't parse ${form.value}`);}else if(form.simplify&&!expression.expr.isSimplified()){issues.push(`${form.value} isn't simplified, but is required" +
1539
+ " to be`);}}});}return issues},this.newAnswer=()=>{const answerForms=this.props.answerForms.slice();const newKey=crypto.randomUUID();const newAnswerForm={considered:"correct",form:false,key:`${newKey}`,simplify:false,value:""};answerForms.push(newAnswerForm);this.props.onChange({answerForms});},this.handleRemoveForm=i=>{const updatedAnswerForms=this.props.answerForms.slice();updatedAnswerForms.splice(i,1);this.props.onChange({answerForms:updatedAnswerForms});},this.handleButtonSet=changingName=>{const buttonSetNames=buttonSetsList;const buttonSets=buttonSetNames.filter(set=>{return this.props.buttonSets.includes(set)!==(set===changingName)});this.props.onChange({buttonSets});},this.handleToggleDiv=()=>{let keep;let remove;if(this.props.buttonSets.includes("basic+div")){keep="basic";remove="basic+div";}else {keep="basic+div";remove="basic";}const buttonSets=this.props.buttonSets.filter(set=>set!==remove).concat(keep);this.props.onChange({buttonSets});},this.handleTexInsert=str=>{this.refs.expression.insert(str);},this.handleFunctions=value=>{this.setState({functionsInternal:value});const newProps={};newProps.functions=value.split(/[ ,]+/).filter(isTruthy);this.props.onChange(newProps);},this.handleVisibleLabel=visibleLabel=>{this.props.onChange({visibleLabel});},this.handleAriaLabel=ariaLabel=>{this.props.onChange({ariaLabel});},this.changeExpressionWidget=(index,input)=>{const answerForm={...this.props.answerForms[index],value:input};this.updateAnswerForm(index,answerForm);};this.state={functionsInternal:this.props.functions.join(" ")};}}ExpressionEditor.widgetName="expression";ExpressionEditor.defaultProps={...expressionLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};const findNextIn=function(arr,val){let ix=arr.indexOf(val);ix=(ix+1)%arr.length;return arr[ix]};class AnswerOption extends React.Component{render(){const{editingDisabled}=this.props;const removeButton=this.state.deleteFocused?jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleImSure,actionType:"destructive",children:"I'm sure!"}),jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleCancelDelete,kind:"secondary",children:"Cancel"})]}):jsxRuntimeExports.jsx(Button,{size:"small",disabled:editingDisabled,onClick:this.handleDelete,actionType:"destructive",kind:"tertiary",className:styles$M.deleteButton,children:"Delete"});return jsxRuntimeExports.jsxs("div",{className:styles$M.answerOption,children:[jsxRuntimeExports.jsx(ButtonGroup$7,{onChange:this.toggleConsidered,allowEmpty:false,disabled:editingDisabled,value:this.props.considered,selectedButtonStyle:consideredButtonStyles[this.props.considered],buttons:PerseusExpressionAnswerFormConsidered.map(c=>({value:c,content:c,title:`This answer will be considered ${c}`}))}),jsxRuntimeExports.jsx(Expression,{...this.props.expressionProps}),jsxRuntimeExports.jsx("div",{className:`${styles$M.paddedY} ${styles$M.paddedX}`,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Answer expression must have the same form.",jsxRuntimeExports.jsx(InfoTip$k,{children:"The student's answer must be in the same form. Commutativity and excess negative signs are ignored."})]}),checked:this.props.form,onChange:this.props.onChangeForm})}),jsxRuntimeExports.jsx("div",{className:`${styles$M.paddedY} ${styles$M.paddedX}`,children:jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:["Answer expression must be fully expanded and simplified.",jsxRuntimeExports.jsx(InfoTip$k,{children:'The student\'s answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response "Your answer is not fully expanded and simplified."'})]}),checked:this.props.simplify,onChange:this.props.onChangeSimplify})}),jsxRuntimeExports.jsx("div",{className:`${styles$M.buttonRow} ${styles$M.paddedY}`,children:removeButton})]})}constructor(...args){super(...args),this.state={deleteFocused:false},this.handleImSure=()=>{this.props.onDelete();this.handleCancelDelete();},this.handleCancelDelete=()=>{this.setState({deleteFocused:false});},this.handleDelete=()=>{this.setState({deleteFocused:true});},this.toggleConsidered=()=>{const newVal=findNextIn(PerseusExpressionAnswerFormConsidered,this.props.considered);this.props.onChangeConsidered(newVal);};}}const wbStyles$1=StyleSheet.create({answerStatusWrong:{backgroundColor:semanticColor.core.background.critical.subtle},answerStatusCorrect:{backgroundColor:semanticColor.core.background.success.subtle},answerStatusUngraded:{backgroundColor:semanticColor.core.background.instructive.subtle}});const consideredButtonStyles={wrong:wbStyles$1.answerStatusWrong,correct:wbStyles$1.answerStatusCorrect,ungraded:wbStyles$1.answerStatusUngraded};
1541
1540
 
1542
- class FreeResponseEditor extends React.Component{render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(LabeledField,{label:"Question",field:jsxRuntimeExports.jsx("textarea",{value:this.props.question,onChange:e=>this.props.onChange({question:e.target.value})}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsx(LabeledField,{label:"Placeholder",field:jsxRuntimeExports.jsx("textarea",{value:this.props.placeholder,onChange:e=>this.props.onChange({placeholder:e.target.value})}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsx(LabeledField,{label:"Allow unlimited characters",field:jsxRuntimeExports.jsx(Checkbox$1,{checked:this.props.allowUnlimitedCharacters,onChange:val=>this.props.onChange({allowUnlimitedCharacters:val})}),styles:{root:styles$L.labeledInputField}}),!this.props.allowUnlimitedCharacters&&jsxRuntimeExports.jsx(LabeledField,{label:"Character limit",field:jsxRuntimeExports.jsx("input",{type:"number",min:1,value:this.props.characterLimit,onChange:this.handleUpdateCharacterLimit}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs(View,{style:styles$L.criteriaList,tag:"fieldset",children:[jsxRuntimeExports.jsx(BodyText,{tag:"legend",children:"Scoring criteria"}),this.renderCriteriaList(editingDisabled)]}),jsxRuntimeExports.jsx(View,{children:jsxRuntimeExports.jsx(Button,{onClick:this.handleAddCriterion,startIcon:plusCircle,disabled:editingDisabled,children:"Add an item"})})]})]})}constructor(...args){super(...args),this.serialize=()=>{return {allowUnlimitedCharacters:this.props.allowUnlimitedCharacters,characterLimit:this.props.characterLimit,placeholder:this.props.placeholder,question:this.props.question,scoringCriteria:this.props.scoringCriteria}},this.getSaveWarnings=()=>{const warnings=[];if(!this.props.question){warnings.push("The question is empty");}if(this.props.question.match(Util.rWidgetRule)!=null){warnings.push("The question contains a widget");}return warnings},this.handleUpdateCharacterLimit=e=>{const val=parseInt(e.target.value);if(isNaN(val)){return}this.props.onChange({characterLimit:Math.max(1,val)});},this.handleUpdateCriterion=(index,criterion)=>{const newCriteria=this.props.scoringCriteria.map((c,i)=>{if(i===index){return criterion}return c});this.props.onChange({scoringCriteria:newCriteria});},this.handleDeleteCriterion=index=>{this.props.onChange({scoringCriteria:this.props.scoringCriteria.filter((_,i)=>i!==index)});},this.handleAddCriterion=()=>{this.props.onChange({scoringCriteria:[...this.props.scoringCriteria,{text:""}]});},this.renderCriteriaList=editingDisabled=>{const isDeletable=this.props.scoringCriteria.length>1;return this.props.scoringCriteria.map((criterion,index)=>{return jsxRuntimeExports.jsx(CriterionEditor,{criterion:criterion,index:index,isDeletable:isDeletable,editingDisabled:editingDisabled,onChange:this.handleUpdateCriterion,onDelete:this.handleDeleteCriterion},index)})};}}FreeResponseEditor.defaultProps={...freeResponseLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};FreeResponseEditor.widgetName="free-response";const CriterionEditor=function(props){return jsxRuntimeExports.jsxs(View,{style:styles$L.criterionContainer,children:[jsxRuntimeExports.jsx("textarea",{"aria-label":`Criterion ${props.index+1}`,onChange:e=>props.onChange(props.index,{text:e.target.value}),value:props.criterion.text}),props.isDeletable&&jsxRuntimeExports.jsx(View,{style:styles$L.deleteButtonContainer,children:jsxRuntimeExports.jsx(Button,{"aria-label":`Delete criterion ${props.index+1}`,actionType:"destructive",disabled:!props.isDeletable||props.editingDisabled,kind:"tertiary",onClick:()=>props.onDelete(props.index),size:"small",startIcon:trashIcon$1,children:"Delete"})})]})};const styles$L=StyleSheet.create({criteriaList:{gap:spacing.small_12},criterionContainer:{paddingTop:spacing.xSmall_8,paddingBottom:spacing.xSmall_8,borderBottom:`1px solid ${semanticColor.core.border.neutral.subtle}`,":last-child":{borderBottom:"none"}},deleteButtonContainer:{display:"flex",flexDirection:"row",justifyContent:"flex-end"},labeledInputField:{paddingBottom:spacing.large_24}});
1541
+ class FreeResponseEditor extends React.Component{render(){const editingDisabled=this.props.apiOptions.editingDisabled??false;return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(LabeledField,{label:"Question",field:jsxRuntimeExports.jsx(TextArea,{value:this.props.question,onChange:newValue=>this.props.onChange({question:newValue})}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsx(LabeledField,{label:"Placeholder",field:jsxRuntimeExports.jsx(TextArea,{value:this.props.placeholder,onChange:newValue=>this.props.onChange({placeholder:newValue})}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsx(LabeledField,{label:"Allow unlimited characters",field:jsxRuntimeExports.jsx(Checkbox$1,{checked:this.props.allowUnlimitedCharacters,onChange:val=>this.props.onChange({allowUnlimitedCharacters:val})}),styles:{root:styles$L.labeledInputField}}),!this.props.allowUnlimitedCharacters&&jsxRuntimeExports.jsx(LabeledField,{label:"Character limit",field:jsxRuntimeExports.jsx(TextField,{type:"number",min:1,value:String(this.props.characterLimit),onChange:this.handleUpdateCharacterLimit}),styles:{root:styles$L.labeledInputField}}),jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs(View,{style:styles$L.criteriaList,tag:"fieldset",children:[jsxRuntimeExports.jsx(BodyText,{tag:"legend",children:"Scoring criteria"}),this.renderCriteriaList(editingDisabled)]}),jsxRuntimeExports.jsx(View,{children:jsxRuntimeExports.jsx(Button,{onClick:this.handleAddCriterion,startIcon:plusCircle,disabled:editingDisabled,children:"Add an item"})})]})]})}constructor(...args){super(...args),this.serialize=()=>{return {allowUnlimitedCharacters:this.props.allowUnlimitedCharacters,characterLimit:this.props.characterLimit,placeholder:this.props.placeholder,question:this.props.question,scoringCriteria:this.props.scoringCriteria}},this.getSaveWarnings=()=>{const warnings=[];if(!this.props.question){warnings.push("The question is empty");}if(this.props.question.match(Util.rWidgetRule)!=null){warnings.push("The question contains a widget");}return warnings},this.handleUpdateCharacterLimit=newValue=>{const val=parseInt(newValue);if(isNaN(val)){return}this.props.onChange({characterLimit:Math.max(1,val)});},this.handleUpdateCriterion=(index,criterion)=>{const newCriteria=this.props.scoringCriteria.map((c,i)=>{if(i===index){return criterion}return c});this.props.onChange({scoringCriteria:newCriteria});},this.handleDeleteCriterion=index=>{this.props.onChange({scoringCriteria:this.props.scoringCriteria.filter((_,i)=>i!==index)});},this.handleAddCriterion=()=>{this.props.onChange({scoringCriteria:[...this.props.scoringCriteria,{text:""}]});},this.renderCriteriaList=editingDisabled=>{const isDeletable=this.props.scoringCriteria.length>1;return this.props.scoringCriteria.map((criterion,index)=>{return jsxRuntimeExports.jsx(CriterionEditor,{criterion:criterion,index:index,isDeletable:isDeletable,editingDisabled:editingDisabled,onChange:this.handleUpdateCriterion,onDelete:this.handleDeleteCriterion},index)})};}}FreeResponseEditor.defaultProps={...freeResponseLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};FreeResponseEditor.widgetName="free-response";const CriterionEditor=function(props){return jsxRuntimeExports.jsxs(View,{style:styles$L.criterionContainer,children:[jsxRuntimeExports.jsx("textarea",{"aria-label":`Criterion ${props.index+1}`,onChange:e=>props.onChange(props.index,{text:e.target.value}),value:props.criterion.text}),props.isDeletable&&jsxRuntimeExports.jsx(View,{style:styles$L.deleteButtonContainer,children:jsxRuntimeExports.jsx(Button,{"aria-label":`Delete criterion ${props.index+1}`,actionType:"destructive",disabled:!props.isDeletable||props.editingDisabled,kind:"tertiary",onClick:()=>props.onDelete(props.index),size:"small",startIcon:trashIcon$1,children:"Delete"})})]})};const styles$L=StyleSheet.create({criteriaList:{gap:spacing.small_12},criterionContainer:{paddingTop:spacing.xSmall_8,paddingBottom:spacing.xSmall_8,borderBottom:`1px solid ${semanticColor.core.border.neutral.subtle}`,":last-child":{borderBottom:"none"}},deleteButtonContainer:{display:"flex",flexDirection:"row",justifyContent:"flex-end"},labeledInputField:{paddingBottom:spacing.large_24}});
1543
1542
 
1544
1543
  var styles$K = {"title":"perseus_az1kQinp","input":"perseus_khxW0hEz","hintsTitle":"perseus_UPlDqNry","addHintButton":"perseus_2aajvB7Y"};
1545
1544
 
@@ -1547,9 +1546,9 @@ const{InlineIcon: InlineIcon$1,TextInput: TextInput$4}=components;class GradedGr
1547
1546
 
1548
1547
  class GradedGroupSetEditor extends React.Component{UNSAFE_componentWillMount(){this._editors=[];}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs("div",{className:"perseus-group-editor",children:[this.renderGroups(),jsxRuntimeExports.jsx("button",{onClick:this.addGroup,disabled:editingDisabled,children:"Add group"})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.getSaveWarnings=()=>{return [].concat(...this._editors.map(editor=>editor?editor.getSaveWarnings():[]))},this.serialize=()=>{return {gradedGroups:this.props.gradedGroups}},this.renderGroups=()=>{if(!this.props.gradedGroups){return null}return this.props.gradedGroups.map((group,i)=>jsxRuntimeExports.jsx(GradedGroupEditor,{ref:el=>this._editors[i]=el,...group,apiOptions:this.props.apiOptions,widgetEnabled:true,immutableWidgets:false,onChange:data=>this.change("gradedGroups",setArrayItem(this.props.gradedGroups,i,{...this.props.gradedGroups[i],...data}))},i))},this.addGroup=()=>{const groups=this.props.gradedGroups||[];this.change("gradedGroups",groups.concat([GradedGroupEditor.defaultProps]));};}}GradedGroupSetEditor.propTypes={...Changeable.propTypes,apiOptions:ApiOptions.propTypes,gradedGroups:PropTypes.array,onChange:PropTypes.func.isRequired};GradedGroupSetEditor.widgetName="graded-group-set";GradedGroupSetEditor.defaultProps=gradedGroupSetLogic.defaultWidgetOptions;const setArrayItem=(list,i,value)=>[...list.slice(0,i),value,...list.slice(i+1)];
1549
1548
 
1550
- const{ButtonGroup: ButtonGroup$6,InfoTip: InfoTip$k,RangeInput: RangeInput$5}=components;const defaultBackgroundImage$1={url:null,width:0,height:0};function numSteps$1(range,step){return Math.floor((range[1]-range[0])/step)}class GraphSettings extends React.Component{getInitialState(){return this.stateFromProps(this.props)}componentDidMount(){this._isMounted=true;this.changeGraph=_.debounce(this.changeGraph,300);}UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.labels,nextProps.labels)||!_.isEqual(this.props.gridStep,nextProps.gridStep)||!_.isEqual(this.props.snapStep,nextProps.snapStep)||!_.isEqual(this.props.step,nextProps.step)||!_.isEqual(this.props.range,nextProps.range)||!_.isEqual(this.props.backgroundImage,nextProps.backgroundImage)){this.setState(this.stateFromProps(nextProps));}}componentWillUnmount(){this._isMounted=false;}stateFromProps(props){return {labelsTextbox:props.labels,gridStepTextbox:props.gridStep,snapStepTextbox:props.snapStep,stepTextbox:props.step,rangeTextbox:props.range,backgroundImage:_.clone(props.backgroundImage)}}changeRulerLabel(e){this.props.onChange({rulerLabel:e.target.value});}changeRulerTicks(e){this.props.onChange({rulerTicks:+e.target.value});}changeBackgroundUrl(e){if(e.type==="keypress"&&"key"in e&&e.key!=="Enter"){return}const setUrl=(url,width,height)=>{const image=_.clone(this.props.backgroundImage);image.url=url;image.width=width;image.height=height;this.setState({backgroundImage:image},this.changeGraph);};const url=ReactDOM.findDOMNode(this.refs["bg-url"]).value;if(url){Util.getImageSize(url,(width,height)=>{if(this._isMounted){setUrl(url,width,height);}});}else {setUrl(null,0,0);}}renderLabelChoices(choices){return _.map(choices,function([name,value]){return jsxRuntimeExports.jsx("option",{value:value,children:name},value)})}validRange(range){const numbers=_.every(range,function(num){return _.isFinite(num)});if(!numbers){return "Range must be a valid number"}if(range[0]>=range[1]){return "Range must have a higher number on the right"}return true}validateStepValue(settings){const{step,range,name,minTicks,maxTicks}=settings;if(!_.isFinite(step)){return name+" must be a valid number"}const nSteps=numSteps$1(range,step);if(nSteps<minTicks){return name+" is too large, there must be at least "+minTicks+" ticks."}if(nSteps>maxTicks){return name+" is too small, there can be at most "+maxTicks+" ticks."}return true}validSnapStep(step,range){return this.validateStepValue({step:step,range:range,name:"Snap step",minTicks:5,maxTicks:60})}validGridStep(step,range){return this.validateStepValue({step:step,range:range,name:"Grid step",minTicks:3,maxTicks:60})}validStep(step,range){return this.validateStepValue({step:step,range:range,name:"Step",minTicks:3,maxTicks:20})}validBackgroundImageSize(image){if(!image.url){return true}const validSize=(image.width??0)<=450&&(image.height??0)<=450;if(!validSize){return "Image must be smaller than 450px x 450px."}return true}validateGraphSettings(range,step,gridStep,snapStep,image){const self=this;let msg;const goodRange=_.every(range,function(range){msg=self.validRange(range);return msg===true});if(!goodRange){return msg}const goodStep=_.every(step,function(step,i){msg=self.validStep(step,range[i]);return msg===true});if(!goodStep){return msg}const goodGridStep=_.every(gridStep,function(gridStep,i){msg=self.validGridStep(gridStep,range[i]);return msg===true});if(!goodGridStep){return msg}const goodSnapStep=_.every(snapStep,function(snapStep,i){msg=self.validSnapStep(snapStep,range[i]);return msg===true});if(!goodSnapStep){return msg}const goodImageSize=this.validBackgroundImageSize(image);if(goodImageSize!==true){msg=goodImageSize;return msg}return true}changeLabel(i,e){const val=e.target.value;const labels=this.state.labelsTextbox.slice();labels[i]=val;this.setState({labelsTextbox:labels},this.changeGraph);}changeRange(i,values){const ranges=this.state.rangeTextbox.slice();ranges[i]=values;const step=this.state.stepTextbox.slice();const gridStep=this.state.gridStepTextbox.slice();const snapStep=this.state.snapStepTextbox.slice();const scale=Util.scaleFromExtent(ranges[i],this.props.box[i]);if(this.validRange(ranges[i])===true){step[i]=Util.tickStepFromExtent(ranges[i],this.props.box[i]);gridStep[i]=Util.gridStepFromTickStep(step[i],scale);snapStep[i]=gridStep[i]/2;}this.setState({stepTextbox:step,gridStepTextbox:gridStep,snapStepTextbox:snapStep,rangeTextbox:ranges},this.changeGraph);}changeStep(step){this.setState({stepTextbox:step},this.changeGraph);}changeSnapStep(snapStep){this.setState({snapStepTextbox:snapStep},this.changeGraph);}changeGridStep(gridStep){this.setState({gridStepTextbox:gridStep,snapStepTextbox:_.map(gridStep,function(step){return step/2})},this.changeGraph);}changeGraph(){const labels=this.state.labelsTextbox;const range=this.state.rangeTextbox.map(range=>range.map(Number));const step=_.map(this.state.stepTextbox,Number);const gridStep=this.state.gridStepTextbox;const snapStep=this.state.snapStepTextbox;const image=this.state.backgroundImage;const validationResult=this.validateGraphSettings(range,step,gridStep,snapStep,image);if(validationResult===true){this.props.onChange({valid:true,labels:labels,range:range,step:step,gridStep:gridStep,snapStep:snapStep,backgroundImage:image});}else {this.props.onChange({valid:validationResult});}}render(){const scale=[KhanMath.roundTo(2,Util.scaleFromExtent(this.props.range[0],this.props.box[0])),KhanMath.roundTo(2,Util.scaleFromExtent(this.props.range[1],this.props.box[1]))];const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[_.contains(this.props.editableSettings,"canvas")&&jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("label",{htmlFor:"canvas-size",children:"Canvas size (x,y pixels)"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"canvas-size",value:this.props.box,onChange:box=>{this.props.onChange({box:box});}})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Scale (px per div):"," ",jsxRuntimeExports.jsx(TeX,{children:"("+scale[0]+", "+scale[1]+")"})]})]}),_.contains(this.props.editableSettings,"graph")&&jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"labels-x",children:"x Label"}),jsxRuntimeExports.jsx("input",{id:"labels-x",type:"text",className:"graph-settings-axis-label",ref:"labels-0",onChange:e=>this.changeLabel(0,e),value:this.state.labelsTextbox[0]||""})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"labels-y",children:"y Label"}),jsxRuntimeExports.jsx("input",{id:"labels-y",type:"text",className:"graph-settings-axis-label",ref:"labels-1",onChange:e=>this.changeLabel(1,e),value:this.state.labelsTextbox[1]||""})]})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"range-x",children:"x Range"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"range-x",value:this.state.rangeTextbox[0],onChange:vals=>this.changeRange(0,vals)})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"range-y",children:"y Range"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"range-y",value:this.state.rangeTextbox[1],onChange:vals=>this.changeRange(1,vals)})]})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"tick-step",children:"Tick Step"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"tick-step",value:this.state.stepTextbox,onChange:this.changeStep})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"grid-step",children:"Grid Step"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"grid-step",value:this.state.gridStepTextbox,onChange:this.changeGridStep})]})]}),_.contains(this.props.editableSettings,"snap")&&jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"snap-step",children:"Snap Step"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"snap-step",value:this.state.snapStepTextbox,onChange:this.changeSnapStep})]})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("label",{children:"Markings: "}),jsxRuntimeExports.jsx(ButtonGroup$6,{value:this.props.markings,allowEmpty:false,buttons:[{value:"graph",content:"Graph"},{value:"grid",content:"Grid"},{value:"none",content:"None"}],onChange:value=>this.props.onChange({markings:value})})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.props.onChange({showTooltips:value});}})})]}),_.contains(this.props.editableSettings,"image")&&jsxRuntimeExports.jsxs("div",{className:"image-settings",children:[jsxRuntimeExports.jsx("div",{children:"Background image:"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("label",{htmlFor:"bg-url",children:"Url:"}),jsxRuntimeExports.jsx("input",{id:"bg-url",type:"text",className:"graph-settings-background-url",ref:"bg-url",value:this.state.backgroundImage.url||"",onChange:e=>{const image=_.clone(this.props.backgroundImage);image.url=e.target.value;this.setState({backgroundImage:image});},onKeyPress:this.changeBackgroundUrl,onBlur:this.changeBackgroundUrl}),jsxRuntimeExports.jsx(InfoTip$k,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]})]}),_.contains(this.props.editableSettings,"measure")&&jsxRuntimeExports.jsxs("div",{className:"misc-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show ruler",checked:this.props.showRuler,onChange:value=>{this.props.onChange({showRuler:value});}})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.props.onChange({showProtractor:value});}})})]}),this.props.showRuler&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler label:"," ",jsxRuntimeExports.jsxs("select",{onChange:this.changeRulerLabel,value:this.props.rulerLabel,children:[jsxRuntimeExports.jsx("option",{value:"",children:"None"}),jsxRuntimeExports.jsx("optgroup",{label:"Metric",children:this.renderLabelChoices([["milimeters","mm"],["centimeters","cm"],["meters","m"],["kilometers","km"]])}),jsxRuntimeExports.jsx("optgroup",{label:"Imperial",children:this.renderLabelChoices([["inches","in"],["feet","ft"],["yards","yd"],["miles","mi"]])})]})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler ticks:"," ",jsxRuntimeExports.jsx("select",{onChange:this.changeRulerTicks,value:this.props.rulerTicks,children:_.map([1,2,4,8,10,16],function(n){return jsxRuntimeExports.jsx("option",{value:n,children:n},n)})})]})})]})]})]})}constructor(props){super(props),this._isMounted=false;this.state=this.getInitialState();this.changeBackgroundUrl=this.changeBackgroundUrl.bind(this);this.changeGraph=this.changeGraph.bind(this);this.changeGridStep=this.changeGridStep.bind(this);this.changeLabel=this.changeLabel.bind(this);this.changeRange=this.changeRange.bind(this);this.changeRulerLabel=this.changeRulerLabel.bind(this);this.changeRulerTicks=this.changeRulerTicks.bind(this);this.changeSnapStep=this.changeSnapStep.bind(this);this.changeStep=this.changeStep.bind(this);}}GraphSettings.defaultProps={editableSettings:["graph","snap","image","measure"],box:[interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall],labels:["x","y"],range:[[-10,10],[-10,10]],step:[1,1],gridStep:[1,1],snapStep:[1,1],valid:true,backgroundImage:defaultBackgroundImage$1,markings:"graph",rulerLabel:"",rulerTicks:10,showProtractor:false,showRuler:false,showTooltips:false};
1549
+ const{ButtonGroup: ButtonGroup$6,InfoTip: InfoTip$j,RangeInput: RangeInput$5}=components;const defaultBackgroundImage$1={url:null,width:0,height:0};function numSteps$1(range,step){return Math.floor((range[1]-range[0])/step)}class GraphSettings extends React.Component{getInitialState(){return this.stateFromProps(this.props)}componentDidMount(){this._isMounted=true;this.changeGraph=_.debounce(this.changeGraph,300);}UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.labels,nextProps.labels)||!_.isEqual(this.props.gridStep,nextProps.gridStep)||!_.isEqual(this.props.snapStep,nextProps.snapStep)||!_.isEqual(this.props.step,nextProps.step)||!_.isEqual(this.props.range,nextProps.range)||!_.isEqual(this.props.backgroundImage,nextProps.backgroundImage)){this.setState(this.stateFromProps(nextProps));}}componentWillUnmount(){this._isMounted=false;}stateFromProps(props){return {labelsTextbox:props.labels,gridStepTextbox:props.gridStep,snapStepTextbox:props.snapStep,stepTextbox:props.step,rangeTextbox:props.range,backgroundImage:_.clone(props.backgroundImage)}}changeRulerLabel(e){this.props.onChange({rulerLabel:e.target.value});}changeRulerTicks(e){this.props.onChange({rulerTicks:+e.target.value});}changeBackgroundUrl(e){if(e.type==="keypress"&&"key"in e&&e.key!=="Enter"){return}const setUrl=(url,width,height)=>{const image=_.clone(this.props.backgroundImage);image.url=url;image.width=width;image.height=height;this.setState({backgroundImage:image},this.changeGraph);};const url=ReactDOM.findDOMNode(this.refs["bg-url"]).value;if(url){Util.getImageSize(url,(width,height)=>{if(this._isMounted){setUrl(url,width,height);}});}else {setUrl(null,0,0);}}renderLabelChoices(choices){return _.map(choices,function([name,value]){return jsxRuntimeExports.jsx("option",{value:value,children:name},value)})}validRange(range){const numbers=_.every(range,function(num){return _.isFinite(num)});if(!numbers){return "Range must be a valid number"}if(range[0]>=range[1]){return "Range must have a higher number on the right"}return true}validateStepValue(settings){const{step,range,name,minTicks,maxTicks}=settings;if(!_.isFinite(step)){return name+" must be a valid number"}const nSteps=numSteps$1(range,step);if(nSteps<minTicks){return name+" is too large, there must be at least "+minTicks+" ticks."}if(nSteps>maxTicks){return name+" is too small, there can be at most "+maxTicks+" ticks."}return true}validSnapStep(step,range){return this.validateStepValue({step:step,range:range,name:"Snap step",minTicks:5,maxTicks:60})}validGridStep(step,range){return this.validateStepValue({step:step,range:range,name:"Grid step",minTicks:3,maxTicks:60})}validStep(step,range){return this.validateStepValue({step:step,range:range,name:"Step",minTicks:3,maxTicks:20})}validBackgroundImageSize(image){if(!image.url){return true}const validSize=(image.width??0)<=450&&(image.height??0)<=450;if(!validSize){return "Image must be smaller than 450px x 450px."}return true}validateGraphSettings(range,step,gridStep,snapStep,image){const self=this;let msg;const goodRange=_.every(range,function(range){msg=self.validRange(range);return msg===true});if(!goodRange){return msg}const goodStep=_.every(step,function(step,i){msg=self.validStep(step,range[i]);return msg===true});if(!goodStep){return msg}const goodGridStep=_.every(gridStep,function(gridStep,i){msg=self.validGridStep(gridStep,range[i]);return msg===true});if(!goodGridStep){return msg}const goodSnapStep=_.every(snapStep,function(snapStep,i){msg=self.validSnapStep(snapStep,range[i]);return msg===true});if(!goodSnapStep){return msg}const goodImageSize=this.validBackgroundImageSize(image);if(goodImageSize!==true){msg=goodImageSize;return msg}return true}changeLabel(i,e){const val=e.target.value;const labels=this.state.labelsTextbox.slice();labels[i]=val;this.setState({labelsTextbox:labels},this.changeGraph);}changeRange(i,values){const ranges=this.state.rangeTextbox.slice();ranges[i]=values;const step=this.state.stepTextbox.slice();const gridStep=this.state.gridStepTextbox.slice();const snapStep=this.state.snapStepTextbox.slice();const scale=Util.scaleFromExtent(ranges[i],this.props.box[i]);if(this.validRange(ranges[i])===true){step[i]=Util.tickStepFromExtent(ranges[i],this.props.box[i]);gridStep[i]=Util.gridStepFromTickStep(step[i],scale);snapStep[i]=gridStep[i]/2;}this.setState({stepTextbox:step,gridStepTextbox:gridStep,snapStepTextbox:snapStep,rangeTextbox:ranges},this.changeGraph);}changeStep(step){this.setState({stepTextbox:step},this.changeGraph);}changeSnapStep(snapStep){this.setState({snapStepTextbox:snapStep},this.changeGraph);}changeGridStep(gridStep){this.setState({gridStepTextbox:gridStep,snapStepTextbox:_.map(gridStep,function(step){return step/2})},this.changeGraph);}changeGraph(){const labels=this.state.labelsTextbox;const range=this.state.rangeTextbox.map(range=>range.map(Number));const step=_.map(this.state.stepTextbox,Number);const gridStep=this.state.gridStepTextbox;const snapStep=this.state.snapStepTextbox;const image=this.state.backgroundImage;const validationResult=this.validateGraphSettings(range,step,gridStep,snapStep,image);if(validationResult===true){this.props.onChange({valid:true,labels:labels,range:range,step:step,gridStep:gridStep,snapStep:snapStep,backgroundImage:image});}else {this.props.onChange({valid:validationResult});}}render(){const scale=[KhanMath.roundTo(2,Util.scaleFromExtent(this.props.range[0],this.props.box[0])),KhanMath.roundTo(2,Util.scaleFromExtent(this.props.range[1],this.props.box[1]))];const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[_.contains(this.props.editableSettings,"canvas")&&jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("label",{htmlFor:"canvas-size",children:"Canvas size (x,y pixels)"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"canvas-size",value:this.props.box,onChange:box=>{this.props.onChange({box:box});}})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Scale (px per div):"," ",jsxRuntimeExports.jsx(TeX,{children:"("+scale[0]+", "+scale[1]+")"})]})]}),_.contains(this.props.editableSettings,"graph")&&jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"labels-x",children:"x Label"}),jsxRuntimeExports.jsx("input",{id:"labels-x",type:"text",className:"graph-settings-axis-label",ref:"labels-0",onChange:e=>this.changeLabel(0,e),value:this.state.labelsTextbox[0]||""})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"labels-y",children:"y Label"}),jsxRuntimeExports.jsx("input",{id:"labels-y",type:"text",className:"graph-settings-axis-label",ref:"labels-1",onChange:e=>this.changeLabel(1,e),value:this.state.labelsTextbox[1]||""})]})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"range-x",children:"x Range"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"range-x",value:this.state.rangeTextbox[0],onChange:vals=>this.changeRange(0,vals)})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"range-y",children:"y Range"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"range-y",value:this.state.rangeTextbox[1],onChange:vals=>this.changeRange(1,vals)})]})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"tick-step",children:"Tick Step"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"tick-step",value:this.state.stepTextbox,onChange:this.changeStep})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"grid-step",children:"Grid Step"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"grid-step",value:this.state.gridStepTextbox,onChange:this.changeGridStep})]})]}),_.contains(this.props.editableSettings,"snap")&&jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:[jsxRuntimeExports.jsx("label",{htmlFor:"snap-step",children:"Snap Step"}),jsxRuntimeExports.jsx(RangeInput$5,{id:"snap-step",value:this.state.snapStepTextbox,onChange:this.changeSnapStep})]})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("label",{children:"Markings: "}),jsxRuntimeExports.jsx(ButtonGroup$6,{value:this.props.markings,allowEmpty:false,buttons:[{value:"graph",content:"Graph"},{value:"grid",content:"Grid"},{value:"none",content:"None"}],onChange:value=>this.props.onChange({markings:value})})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.props.onChange({showTooltips:value});}})})]}),_.contains(this.props.editableSettings,"image")&&jsxRuntimeExports.jsxs("div",{className:"image-settings",children:[jsxRuntimeExports.jsx("div",{children:"Background image:"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("label",{htmlFor:"bg-url",children:"Url:"}),jsxRuntimeExports.jsx("input",{id:"bg-url",type:"text",className:"graph-settings-background-url",ref:"bg-url",value:this.state.backgroundImage.url||"",onChange:e=>{const image=_.clone(this.props.backgroundImage);image.url=e.target.value;this.setState({backgroundImage:image});},onKeyPress:this.changeBackgroundUrl,onBlur:this.changeBackgroundUrl}),jsxRuntimeExports.jsx(InfoTip$j,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]})]}),_.contains(this.props.editableSettings,"measure")&&jsxRuntimeExports.jsxs("div",{className:"misc-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show ruler",checked:this.props.showRuler,onChange:value=>{this.props.onChange({showRuler:value});}})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.props.onChange({showProtractor:value});}})})]}),this.props.showRuler&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler label:"," ",jsxRuntimeExports.jsxs("select",{onChange:this.changeRulerLabel,value:this.props.rulerLabel,children:[jsxRuntimeExports.jsx("option",{value:"",children:"None"}),jsxRuntimeExports.jsx("optgroup",{label:"Metric",children:this.renderLabelChoices([["milimeters","mm"],["centimeters","cm"],["meters","m"],["kilometers","km"]])}),jsxRuntimeExports.jsx("optgroup",{label:"Imperial",children:this.renderLabelChoices([["inches","in"],["feet","ft"],["yards","yd"],["miles","mi"]])})]})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler ticks:"," ",jsxRuntimeExports.jsx("select",{onChange:this.changeRulerTicks,value:this.props.rulerTicks,children:_.map([1,2,4,8,10,16],function(n){return jsxRuntimeExports.jsx("option",{value:n,children:n},n)})})]})})]})]})]})}constructor(props){super(props),this._isMounted=false;this.state=this.getInitialState();this.changeBackgroundUrl=this.changeBackgroundUrl.bind(this);this.changeGraph=this.changeGraph.bind(this);this.changeGridStep=this.changeGridStep.bind(this);this.changeLabel=this.changeLabel.bind(this);this.changeRange=this.changeRange.bind(this);this.changeRulerLabel=this.changeRulerLabel.bind(this);this.changeRulerTicks=this.changeRulerTicks.bind(this);this.changeSnapStep=this.changeSnapStep.bind(this);this.changeStep=this.changeStep.bind(this);}}GraphSettings.defaultProps={editableSettings:["graph","snap","image","measure"],box:[interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall],labels:["x","y"],range:[[-10,10],[-10,10]],step:[1,1],gridStep:[1,1],snapStep:[1,1],valid:true,backgroundImage:defaultBackgroundImage$1,markings:"graph",rulerLabel:"",rulerTicks:10,showProtractor:false,showRuler:false,showTooltips:false};
1551
1550
 
1552
- const{InfoTip: InfoTip$j,MultiButtonGroup}=components;const Grapher=GrapherWidget.widget;const{chooseType,defaultPlotProps,getEquationString,typeToButton}=GrapherUtil;class GrapherEditor extends React.Component{render(){const sizeClass=containerSizeClass.SMALL;let equationString;let graph;if(this.props.graph.valid===true){const graphProps={apiOptions:this.props.apiOptions,containerSizeClass:sizeClass,graph:this.props.graph,userInput:this.props.correct,correct:this.props.correct,handleUserInput:userInput=>{let correct=this.props.correct;if(correct.type===userInput?.type){correct=_.extend({},correct,userInput);}else {correct=userInput;}this.props.onChange({correct:correct});},availableTypes:[...this.props.availableTypes],trackInteraction:function(){},static:this.props.apiOptions.editingDisabled};graph=jsxRuntimeExports.jsx(Grapher,{...graphProps});equationString=getEquationString(graphProps.userInput);}else {graph=jsxRuntimeExports.jsx("div",{className:"perseus-error",children:this.props.graph.valid});}return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{children:["Correct answer"," ",jsxRuntimeExports.jsx(InfoTip$j,{children:jsxRuntimeExports.jsx("p",{children:"Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."})})," ",": ",equationString]}),jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["graph","snap","image"],box:getInteractiveBoxFromSizeClass(sizeClass),range:this.props.graph.range,labels:this.props.graph.labels,step:this.props.graph.step,gridStep:this.props.graph.gridStep,snapStep:this.props.graph.snapStep,valid:this.props.graph.valid===true,backgroundImage:this.props.graph.backgroundImage,markings:this.props.graph.markings,rulerLabel:this.props.graph.rulerLabel,rulerTicks:this.props.graph.rulerTicks,showTooltips:this.props.graph.showTooltips,onChange:newProps=>this.props.onChange({graph:{...this.props.graph,...newProps}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("label",{children:"Available functions: "}),jsxRuntimeExports.jsx(MultiButtonGroup,{allowEmpty:false,values:this.props.availableTypes,buttons:_.map(GrapherUtil$1.allTypes,typeToButton),onChange:this.handleAvailableTypesChange})]}),graph]})}constructor(...args){super(...args),this.handleAvailableTypesChange=newAvailableTypes=>{let correct=this.props.correct;if(!_.contains(newAvailableTypes,this.props.correct.type)){const graph=this.props.graph;const newType=chooseType(newAvailableTypes);correct=defaultPlotProps(newType,graph);}this.props.onChange({availableTypes:newAvailableTypes,correct:correct});},this.serialize=()=>{return _.chain(this.props).pick("correct","availableTypes").extend({graph:_.omit(this.props.graph,"box")}).value()};}}GrapherEditor.widgetName="grapher";GrapherEditor.defaultProps=grapherLogic.defaultWidgetOptions;
1551
+ const{InfoTip: InfoTip$i,MultiButtonGroup}=components;const Grapher=GrapherWidget.widget;const{chooseType,defaultPlotProps,getEquationString,typeToButton}=GrapherUtil;class GrapherEditor extends React.Component{render(){const sizeClass=containerSizeClass.SMALL;let equationString;let graph;if(this.props.graph.valid===true){const graphProps={apiOptions:this.props.apiOptions,containerSizeClass:sizeClass,graph:this.props.graph,userInput:this.props.correct,correct:this.props.correct,handleUserInput:userInput=>{let correct=this.props.correct;if(correct.type===userInput?.type){correct=_.extend({},correct,userInput);}else {correct=userInput;}this.props.onChange({correct:correct});},availableTypes:[...this.props.availableTypes],trackInteraction:function(){},static:this.props.apiOptions.editingDisabled};graph=jsxRuntimeExports.jsx(Grapher,{...graphProps});equationString=getEquationString(graphProps.userInput);}else {graph=jsxRuntimeExports.jsx("div",{className:"perseus-error",children:this.props.graph.valid});}return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{children:["Correct answer"," ",jsxRuntimeExports.jsx(InfoTip$i,{children:jsxRuntimeExports.jsx("p",{children:"Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."})})," ",": ",equationString]}),jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["graph","snap","image"],box:getInteractiveBoxFromSizeClass(sizeClass),range:this.props.graph.range,labels:this.props.graph.labels,step:this.props.graph.step,gridStep:this.props.graph.gridStep,snapStep:this.props.graph.snapStep,valid:this.props.graph.valid===true,backgroundImage:this.props.graph.backgroundImage,markings:this.props.graph.markings,rulerLabel:this.props.graph.rulerLabel,rulerTicks:this.props.graph.rulerTicks,showTooltips:this.props.graph.showTooltips,onChange:newProps=>this.props.onChange({graph:{...this.props.graph,...newProps}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("label",{children:"Available functions: "}),jsxRuntimeExports.jsx(MultiButtonGroup,{allowEmpty:false,values:this.props.availableTypes,buttons:_.map(GrapherUtil$1.allTypes,typeToButton),onChange:this.handleAvailableTypesChange})]}),graph]})}constructor(...args){super(...args),this.handleAvailableTypesChange=newAvailableTypes=>{let correct=this.props.correct;if(!_.contains(newAvailableTypes,this.props.correct.type)){const graph=this.props.graph;const newType=chooseType(newAvailableTypes);correct=defaultPlotProps(newType,graph);}this.props.onChange({availableTypes:newAvailableTypes,correct:correct});},this.serialize=()=>{return _.chain(this.props).pick("correct","availableTypes").extend({graph:_.omit(this.props.graph,"box")}).value()};}}GrapherEditor.widgetName="grapher";GrapherEditor.defaultProps=grapherLogic.defaultWidgetOptions;
1553
1552
 
1554
1553
  class GroupEditor extends React.Component{serialize(){invariant(this.editor.current,"cannot serialize GroupEditor without Editor");return {...this.editor.current.serialize()}}render(){return jsxRuntimeExports.jsx("div",{className:"perseus-group-editor",children:jsxRuntimeExports.jsx(Editor,{ref:this.editor,content:this.props.content,widgets:this.props.widgets,apiOptions:this.props.apiOptions,images:this.props.images,widgetEnabled:true,immutableWidgets:false,onChange:this.props.onChange})})}constructor(...args){super(...args),this.editor=React.createRef(),this.getSaveWarnings=()=>{return this.editor.current?.getSaveWarnings()};}}GroupEditor.propTypes={content:PropTypes.string,widgets:PropTypes.object,images:PropTypes.object,apiOptions:ApiOptions.propTypes};GroupEditor.widgetName="group";GroupEditor.defaultProps=groupLogic.defaultWidgetOptions;
1555
1554
 
@@ -1563,7 +1562,7 @@ const wbFieldStyles={root:{marginBlockEnd:sizing.size_080},label:{paddingBlockEn
1563
1562
 
1564
1563
  var styles$I = {"decorativeToggleContainer":"perseus_Z9--Lqsc","flexRow":"perseus_H6OWRNo-"};
1565
1564
 
1566
- const{InfoTip: InfoTip$i}=components;function DecorativeToggle({decorative,hasPopulatedFields,editingDisabled=false,onChange}){function handleDecorativeToggle(newValue){if(!newValue){onChange({decorative:false});return}if(!hasPopulatedFields){onChange({decorative:true});return}const shouldReset=window.confirm("Setting this image as decorative will automatically reset all other fields (title, caption, alt text, and long description). Do you want to continue?");if(shouldReset){onChange({decorative:true,alt:"",caption:undefined,title:undefined,longDescription:undefined});}}return jsxRuntimeExports.jsx("div",{className:styles$I.decorativeToggleContainer,children:jsxRuntimeExports.jsxs("div",{className:styles$I.flexRow,children:[jsxRuntimeExports.jsx(LabeledSwitch,{label:"Decorative",checked:decorative??false,disabled:editingDisabled,onChange:handleDecorativeToggle}),jsxRuntimeExports.jsx(InfoTip$i,{children:jsxRuntimeExports.jsx("p",{children:"Mark this image as decorative and it will not have any alt text, description, title, or caption."})})]})})}
1565
+ const{InfoTip: InfoTip$h}=components;function DecorativeToggle({decorative,hasPopulatedFields,editingDisabled=false,onChange}){function handleDecorativeToggle(newValue){if(!newValue){onChange({decorative:false});return}if(!hasPopulatedFields){onChange({decorative:true});return}const shouldReset=window.confirm("Setting this image as decorative will automatically reset all other fields (title, caption, alt text, and long description). Do you want to continue?");if(shouldReset){onChange({decorative:true,alt:"",caption:undefined,title:undefined,longDescription:undefined});}}return jsxRuntimeExports.jsx("div",{className:styles$I.decorativeToggleContainer,children:jsxRuntimeExports.jsxs("div",{className:styles$I.flexRow,children:[jsxRuntimeExports.jsx(LabeledSwitch,{label:"Decorative",checked:decorative??false,disabled:editingDisabled,onChange:handleDecorativeToggle}),jsxRuntimeExports.jsx(InfoTip$h,{children:jsxRuntimeExports.jsx("p",{children:"Mark this image as decorative and it will not have any alt text, description, title, or caption."})})]})})}
1567
1566
 
1568
1567
  const ScrolllessNumberTextField=props=>{const{value,onChange,...restOfProps}=props;const[focused,setFocused]=React.useState(false);const[wipValue,setWipValue]=React.useState("");const inputRef=React.useRef(null);React.useEffect(()=>{const ref=inputRef.current;const ignoreScroll=e=>{e.stopPropagation();};ref?.addEventListener("wheel",ignoreScroll);return ()=>{ref?.removeEventListener("wheel",ignoreScroll);}},[inputRef]);return jsxRuntimeExports.jsx(TextField,{...restOfProps,type:"number",value:focused?wipValue:value,onChange:newValue=>{setWipValue(newValue);onChange(newValue);},onFocus:e=>{setWipValue(value);setFocused(true);props.onFocus?.(e);},onBlur:e=>{setFocused(false);props.onBlur?.(e);},ref:inputRef})};
1569
1568
 
@@ -1575,7 +1574,17 @@ const INTERNALLY_HOSTED_DOMAINS="("+"ka-.*.s3.amazonaws.com|"+"(fastly|cdn).kast
1575
1574
 
1576
1575
  class ImageEditor extends React.Component{serialize(){return EditorJsonify.serialize.call(this)}render(){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ImageUrlInput,{...this.props}),jsxRuntimeExports.jsx(ImageSettings,{...this.props})]})}}ImageEditor.displayName="ImageEditor";ImageEditor.widgetName="image";ImageEditor.defaultProps=imageLogic.defaultWidgetOptions;
1577
1576
 
1578
- const{InfoTip: InfoTip$h}=components;class InputNumberEditor extends React.Component{render(){const answerTypeOptions=_.map(inputNumberAnswerTypes,function(v,k){return jsxRuntimeExports.jsx("option",{value:k,children:v.name},k)},this);return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Correct answer:"," ",jsxRuntimeExports.jsx(BlurInput,{value:""+this.props.value,onChange:this.handleAnswerChange,ref:this.input})]})}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Unsimplified answers"," ",jsxRuntimeExports.jsxs("select",{value:this.props.simplify,onChange:e=>{this.props.onChange({simplify:e.target.value});},children:[jsxRuntimeExports.jsx("option",{value:"required",children:"will not be graded"}),jsxRuntimeExports.jsx("option",{value:"optional",children:"will be accepted"}),jsxRuntimeExports.jsx("option",{value:"enforced",children:"will be marked wrong"})]})]}),jsxRuntimeExports.jsxs(InfoTip$h,{children:[jsxRuntimeExports.jsx("p",{children:'Normally select "will not be graded". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)'}),jsxRuntimeExports.jsx("p",{children:'Select "will be accepted" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)'}),jsxRuntimeExports.jsx("p",{children:'Select "will be marked wrong" only if we are specifically assessing the ability to simplify.'})]})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.inexact,onChange:e=>{this.props.onChange({inexact:e.target.checked});}})," ","Allow inexact answers"]}),jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"checkbox",style:{visibility:"hidden"}}),"Max error:"," ",jsxRuntimeExports.jsx("input",{type:"text",disabled:!this.props.inexact,defaultValue:this.props.maxError,"aria-label":"Max error",onBlur:e=>{const ans=""+(Util.firstNumericalParse(e.target.value)||0);e.target.value=ans;this.props.onChange({maxError:ans});}})]})]}),jsxRuntimeExports.jsxs("div",{children:["Answer type:"," ",jsxRuntimeExports.jsx("select",{value:this.props.answerType,onChange:e=>{this.props.onChange({answerType:e.target.value});},"aria-label":"Answer type",children:answerTypeOptions}),jsxRuntimeExports.jsx(InfoTip$h,{children:jsxRuntimeExports.jsx("p",{children:'Use the default "Numbers" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions).'})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Width"," ",jsxRuntimeExports.jsxs("select",{value:this.props.size,onChange:e=>{this.props.onChange({size:e.target.value});},children:[jsxRuntimeExports.jsx("option",{value:"normal",children:"Normal (80px)"}),jsxRuntimeExports.jsx("option",{value:"small",children:"Small (40px)"})]})]}),jsxRuntimeExports.jsx(InfoTip$h,{children:jsxRuntimeExports.jsx("p",{children:'Use size "Normal" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.'})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"checkbox",checked:this.props.rightAlign,onChange:e=>{this.props.onChange({rightAlign:e.target.checked});}})," ","Right alignment"]})})]})}constructor(...args){super(...args),this.input=React.createRef(),this.handleAnswerChange=str=>{const value=Util.firstNumericalParse(str)||0;this.props.onChange({value:value});},this.focus=()=>{this.input.current?.focus();return true},this.serialize=()=>({value:this.props.value,simplify:this.props.simplify,size:this.props.size,inexact:this.props.inexact,maxError:this.props.maxError,answerType:this.props.answerType,rightAlign:this.props.rightAlign});}}InputNumberEditor.widgetName="input-number";InputNumberEditor.defaultProps=inputNumberLogic.defaultWidgetOptions;
1577
+ function Heading({title,isOpen,isCollapsible,onToggle}){return jsxRuntimeExports.jsx(Clickable,{style:[styles$H.container,!isCollapsible&&styles$H.notClickable],disabled:!isCollapsible,onClick:()=>isCollapsible&&onToggle?.(!isOpen),children:()=>jsxRuntimeExports.jsxs(View,{style:styles$H.heading,children:[jsxRuntimeExports.jsx(BodyText,{size:"small",weight:"bold",tag:"span",children:title}),isCollapsible&&jsxRuntimeExports.jsx(ToggleableCaret,{isExpanded:isOpen})]})})}const styles$H=StyleSheet.create({container:{marginTop:spacing.small_12,marginInline:-10,backgroundColor:semanticColor.core.background.neutral.subtle,padding:spacing.xSmall_8,width:"calc(100% + 20px)"},heading:{flexDirection:"row",justifyContent:"space-between",userSelect:"none"},notClickable:{color:"inherit",cursor:"default"}});
1578
+
1579
+ var styles$G = {"group":"perseus_Vniq-14O","wrapGroup":"perseus_8W6ltSJv","segment":"perseus_pYpuDydt"};
1580
+
1581
+ function ToggleButton({selected,onClick,disabled=false,role="radio",children,style,"aria-label":ariaLabel}){return jsxRuntimeExports.jsx(Clickable,{role:role,"aria-checked":selected,"aria-label":ariaLabel,disabled:disabled,onClick:onClick,className:styles$G.segment,style:style,children:()=>children})}function SegmentedControl({options,selectedValue,onChange,disabled=false,"aria-label":ariaLabel}){return jsxRuntimeExports.jsx(View,{role:"radiogroup","aria-label":ariaLabel,className:styles$G.group,children:options.map(option=>jsxRuntimeExports.jsx(ToggleButton,{role:"radio",selected:option.value===selectedValue,"aria-label":option.ariaLabel,disabled:disabled,onClick:()=>onChange(option.value),children:option.label},option.value))})}function ToggleButtonGroup({options,selectedValues,onToggle,disabled=false,"aria-label":ariaLabel}){return jsxRuntimeExports.jsx(View,{role:"group","aria-label":ariaLabel,className:styles$G.wrapGroup,children:options.map(option=>jsxRuntimeExports.jsx(ToggleButton,{role:"checkbox",selected:selectedValues.includes(option.value),"aria-label":option.ariaLabel,disabled:disabled,onClick:()=>onToggle(option.value),children:option.label},option.value))})}
1582
+
1583
+ var styles$F = {"field":"perseus_JbwuUF5N","labelRow":"perseus_aHiPdK--","inlineField":"perseus_dNMdOiQI"};
1584
+
1585
+ const{InfoTip: InfoTip$g,NumberInput: NumberInput$c,TextInput: TextInput$3}=components;const{firstNumericalParse}=Util;const answerFormButtons=[{title:"Integers",value:"integer",content:"6"},{title:"Decimals",value:"decimal",content:"0.75"},{title:"Proper fractions",value:"proper",content:"⅗"},{title:"Improper fractions",value:"improper",content:"⁷⁄₄"},{title:"Mixed numbers",value:"mixed",content:"1¾"},{title:"Numbers with π",value:"pi",content:"π"}];const initAnswer=status=>{return {value:null,status:status,message:"",simplify:"required",answerForms:[],strict:false,maxError:null}};class NumericInputEditor extends React.Component{render(){const answers=this.props.answers;const editingDisabled=this.props.apiOptions.editingDisabled;const unsimplifiedAnswers=i=>jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[answers[i]["status"]!=="correct"&&jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Unsimplified answers are irrelevant for this status"}),answers[i]["status"]==="correct"&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$F.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Unsimplified answers are"}),jsxRuntimeExports.jsxs(InfoTip$g,{children:[jsxRuntimeExports.jsx("p",{children:'Normally select "ungraded". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and after)'}),jsxRuntimeExports.jsx("p",{children:'Select "accepted" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)'}),jsxRuntimeExports.jsxs("p",{children:['Select "wrong" ',jsxRuntimeExports.jsx("em",{children:"only"})," if we are specifically assessing the ability to simplify."]})]})]}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Unsimplified answers are",disabled:editingDisabled,selectedValue:answers[i]["simplify"],onChange:value=>this.updateAnswer(i,{simplify:value}),options:[{value:"required",label:"Ungraded"},{value:"optional",label:"Accepted"},{value:"enforced",label:"Wrong"}]})]})]});const suggestedAnswerTypes=i=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$F.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Possible answer formats"}),jsxRuntimeExports.jsxs(InfoTip$g,{children:[jsxRuntimeExports.jsx("p",{children:'Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with π will have format "pi", and values that are fractions will have some subset (mixed will be "mixed" and "proper"; improper/proper will both be "improper" and "proper"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats.'}),jsxRuntimeExports.jsxs("p",{children:["To restrict the answer to ",jsxRuntimeExports.jsx("em",{children:"only"}),' an improper fraction (i.e. 7/4), select the improper fraction and toggle "strict" to true. This ',jsxRuntimeExports.jsx("b",{children:"will not"})," accept 1.75 as an answer."," "]}),jsxRuntimeExports.jsx("p",{children:"Unless you are testing that specific skill, please do not restrict the answer format."})]})]}),jsxRuntimeExports.jsx(ToggleButtonGroup,{"aria-label":"Possible answer formats",disabled:editingDisabled,selectedValues:answers[i]["answerForms"]??[],onToggle:value=>this.onToggleAnswerForm(i,value),options:answerFormButtons.map(format=>({value:format.value,label:format.content,ariaLabel:format.title}))})]}),jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Answer formats are"}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Answer formats are",disabled:editingDisabled,selectedValue:answers[i]["strict"]?"required":"suggested",onChange:value=>this.updateAnswer(i,{strict:value==="required"}),options:[{value:"suggested",label:"Suggested"},{value:"required",label:"Required"}]})]})]});const inputSize=jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$F.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Width"}),jsxRuntimeExports.jsx(InfoTip$g,{children:jsxRuntimeExports.jsx("p",{children:'Use size "Normal" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.'})})]}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Width",disabled:editingDisabled,selectedValue:this.props.size,onChange:value=>this.change("size")(value),options:[{value:"normal",label:"Normal (80px)"},{value:"small",label:"Small (40px)"}]})]});const labelText=jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$F.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Answer Field Aria label"}),jsxRuntimeExports.jsx(InfoTip$g,{children:jsxRuntimeExports.jsx("p",{children:"Text to describe the Answer Field for screenreader users."})})]}),jsxRuntimeExports.jsx(TextInput$3,{labelText:"aria label",value:this.props.labelText,onChange:this.change("labelText")})]});const coefficientCheck=jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$F.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Number style"}),jsxRuntimeExports.jsx(InfoTip$g,{children:jsxRuntimeExports.jsx("p",{children:"A coefficient style number allows the student to use - for -1 and an empty string to mean 1."})})]}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Number style",disabled:editingDisabled,selectedValue:this.props.coefficient?"coefficient":"standard",onChange:value=>this.props.onChange({coefficient:value==="coefficient"}),options:[{value:"standard",label:"Standard"},{value:"coefficient",label:"Coefficient"}]})]});const instructions={wrong:"(address the mistake/misconception)",ungraded:"(explain in detail to avoid confusion)",correct:"(reinforce the user's understanding)"};const generateInputAnswerEditors=()=>answers.map((answer,i)=>{const editor=jsxRuntimeExports.jsx(Editor,{apiOptions:this.props.apiOptions,content:answer.message||"",placeholder:"Why is this answer "+answer.status+"? "+instructions[answer.status],widgetEnabled:false,onChange:newProps=>{if("content"in newProps){this.updateAnswer(i,{message:newProps.content});}}});const statusProper=answer.status.charAt(0).toUpperCase()+answer.status.slice(1);const answerFormat=(answer.answerForms||[]).at(-1);const answerString=KhanMath.toNumericString(answer.value??0,answerFormat);const answerRangeText=answer.maxError?`\xb1 ${KhanMath.toNumericString(answer.maxError,answerFormat)}`:"";const answerHeading=answer.value===null?"New Answer":`${statusProper} answer: ${answerString} ${answerRangeText}`;return jsxRuntimeExports.jsx("div",{className:"perseus-widget-row answer-option",children:jsxRuntimeExports.jsxs(PerseusEditorAccordion,{animated:true,expanded:this.state.showAnswerDetails[i],onToggle:()=>{this.onToggleAnswers(i);},header:jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:answerHeading}),children:[jsxRuntimeExports.jsxs("div",{className:"input-answer-editor-value-container"+(answer.maxError?" with-max-error":""),children:[jsxRuntimeExports.jsxs(View,{tag:"label",className:styles$F.inlineField,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"User input"}),jsxRuntimeExports.jsx(NumberInput$c,{value:answer.value,className:"numeric-input-value",placeholder:"answer",format:_.last(answer.answerForms||[]),onFormatChange:(newValue,format)=>{let forms;if(format==="pi"){forms=["pi"];}else if(format==="mixed"){forms=["proper","mixed"];}else if(format==="proper"||format==="improper"){forms=["proper","improper"];}this.updateAnswer(i,{value:firstNumericalParse(newValue),answerForms:forms});},onChange:newValue=>{this.updateAnswer(i,{value:firstNumericalParse(newValue)});}})]}),jsxRuntimeExports.jsx("span",{className:"max-error-plusmn",children:"±"}),jsxRuntimeExports.jsx(NumberInput$c,{className:"max-error-input-value",placeholder:0,value:answers[i]["maxError"],format:_.last(answer.answerForms||[]),onChange:this.updateAnswer(i,"maxError")})]}),jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Status"}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Status",disabled:editingDisabled,selectedValue:answers[i]["status"],onChange:value=>this.onEvaluationChange(i,value),options:[{value:"correct",label:"Correct"},{value:"wrong",label:"Wrong"},{value:"ungraded",label:"Ungraded"}]})]}),unsimplifiedAnswers(i),jsxRuntimeExports.jsxs(View,{className:styles$F.field,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"(Articles only) Message shown to user"}),editor]}),suggestedAnswerTypes(i),jsxRuntimeExports.jsx(Button,{startIcon:trashIcon,"aria-label":`Delete ${answerHeading}`,className:"delete-item-button",disabled:editingDisabled,onClick:()=>{this.onTrashAnswer(i);},kind:"tertiary",children:"Delete"})]})},i)});return jsxRuntimeExports.jsxs("div",{className:"perseus-input-number-editor",children:[jsxRuntimeExports.jsx(Heading,{title:"General Settings",isCollapsible:true,isOpen:this.state.showSettings,onToggle:this.onToggleHeading("Settings")}),jsxRuntimeExports.jsx("div",{className:`perseus-editor-accordion-container ${this.state.showSettings?"expanded":"collapsed"}`,children:jsxRuntimeExports.jsxs("div",{className:"perseus-editor-accordion-content",children:[inputSize,jsxRuntimeExports.jsxs("label",{children:["Text alignment",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:this.props.textAlign,onChange:value=>{this.props.onChange({textAlign:value});},placeholder:"Select text alignment",children:[jsxRuntimeExports.jsx(OptionItem,{value:"left",label:"Left"}),jsxRuntimeExports.jsx(OptionItem,{value:"center",label:"Center"}),jsxRuntimeExports.jsx(OptionItem,{value:"right",label:"Right"})]})]}),coefficientCheck,labelText]})}),jsxRuntimeExports.jsx(Heading,{title:"Answers",isCollapsible:true,isOpen:this.state.showAnswers,onToggle:this.onToggleHeading("Answers")}),jsxRuntimeExports.jsx("div",{className:`perseus-editor-accordion-container ${this.state.showAnswers?"expanded":"collapsed"}`,children:jsxRuntimeExports.jsxs("div",{className:"perseus-editor-accordion-content",children:[generateInputAnswerEditors(),jsxRuntimeExports.jsx(Button,{kind:"tertiary",disabled:editingDisabled,onClick:this.addAnswer,children:"Add new answer"})]})})]})}constructor(props){super(props),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.onToggleAnswers=answerIndex=>{const showAnswerDetails=this.state.showAnswerDetails.slice();showAnswerDetails[answerIndex]=!showAnswerDetails[answerIndex];this.setState({showAnswerDetails:showAnswerDetails});},this.onToggleAnswerForm=(answerIndex,answerForm)=>{let answerForms=[...this.props.answers[answerIndex]["answerForms"]??[]];const formSelected=answerForms.includes(answerForm);if(!formSelected){answerForms.push(answerForm);}else {answerForms=answerForms.filter(form=>form!==answerForm);}const updateFn=this.updateAnswer(answerIndex,"answerForms");if(updateFn){updateFn(answerForms);}},this.onToggleHeading=accordionName=>{return ()=>{const toggleName=`show${accordionName}`;const newState={...this.state};newState[toggleName]=!newState[toggleName];this.setState(newState);}},this.onTrashAnswer=choiceIndex=>{if(choiceIndex>=0&&choiceIndex<this.props.answers.length){const answers=this.props.answers.slice(0);answers.splice(choiceIndex,1);this.props.onChange({answers:answers});}},this.onSpace=(e,callback,...args)=>{if(e.key===" "){e.preventDefault();callback.apply(this,args);}},this.onStatusChange=choiceIndex=>{const statuses=["wrong","ungraded","correct"];const answers=this.props.answers;const i=statuses.indexOf(answers[choiceIndex].status);const newStatus=statuses[(i+1)%statuses.length];this.updateAnswer(choiceIndex,{status:newStatus,simplify:newStatus==="correct"?"required":"accepted"});},this.onEvaluationChange=(choiceIndex,newStatus)=>{this.updateAnswer(choiceIndex,{status:newStatus,simplify:newStatus==="correct"?"required":"accepted"});},this.updateAnswer=(choiceIndex,update)=>{if(!_.isObject(update)){return _.partial((choiceIndex,key,value)=>{const update={};update[key]=value;this.updateAnswer(choiceIndex,update);},choiceIndex,update)}let answers=[...this.props.answers];if(choiceIndex===answers.length){const lastAnswer=initAnswer(this.state.lastStatus);answers=answers.concat(lastAnswer);}answers[choiceIndex]=_.extend({},answers[choiceIndex],update);this.props.onChange({answers:answers});},this.addAnswer=()=>{const lastAnswer=initAnswer(this.state.lastStatus);const answers=this.props.answers.concat(lastAnswer);const showAnswerDetails=this.state.showAnswerDetails.concat(true);this.setState({showAnswerDetails:showAnswerDetails});this.props.onChange({answers:answers});},this.getSaveWarnings=()=>{const warnings=[];if(_.contains(_.pluck(this.props.answers,"value"),"")){warnings.push("One or more answers is empty");}this.props.answers.forEach((answer,i)=>{const formatError=answer.strict&&(!answer.answerForms||answer.answerForms.length===0);if(formatError){warnings.push(`Answer ${i+1} is set to string format `+"matching, but no format was selected");}});return warnings},this.serialize=()=>{return EditorJsonify.serialize.call(this)};this.state={lastStatus:"wrong",showAnswerDetails:Array(this.props.answers.length).fill(true),showSettings:true,showAnswers:true};}}NumericInputEditor.widgetName="numeric-input";NumericInputEditor.displayName="NumericInputEditor";NumericInputEditor.defaultProps={...numericInputLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};
1586
+
1587
+ class InputNumberEditor extends NumericInputEditor{}InputNumberEditor.widgetName="input-number";
1579
1588
 
1580
1589
  const{InlineIcon}=components;class ElementContainer extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-interaction-element",children:[jsxRuntimeExports.jsxs("a",{href:"#",className:"perseus-interaction-element-title "+(this.state.show?"open":"closed"),onClick:this.toggle,children:[this.state.show?jsxRuntimeExports.jsx(InlineIcon,{...iconChevronDown}):jsxRuntimeExports.jsx(InlineIcon,{...iconChevronRight}),this.props.title]}),jsxRuntimeExports.jsxs("div",{className:"perseus-interaction-element-content "+(this.state.show?"enter":"leave"),children:[this.props.children,(this.props.onUp!=null||this.props.onDown!=null||this.props.onDelete!=null)&&jsxRuntimeExports.jsxs("div",{className:"edit-controls",children:[this.props.onUp!=null&&jsxRuntimeExports.jsx("button",{onClick:this.props.onUp,children:jsxRuntimeExports.jsx(InlineIcon,{...iconCircleArrowUp})}),this.props.onDown!=null&&jsxRuntimeExports.jsx("button",{onClick:this.props.onDown,children:jsxRuntimeExports.jsx(InlineIcon,{...iconCircleArrowDown})}),this.props.onDelete!=null&&jsxRuntimeExports.jsx("button",{onClick:this.props.onDelete,children:jsxRuntimeExports.jsx(InlineIcon,{...iconTrash})})]})]})]})}constructor(props){super(props),this.toggle=e=>{e.preventDefault();this.setState({show:!this.state.show});};this.state={show:props.initiallyVisible};}}ElementContainer.defaultProps={initiallyVisible:false,title:"More"};
1581
1590
 
@@ -1583,23 +1592,23 @@ const{ButtonGroup: ButtonGroup$5}=components;const COLORS=[KhanColors.BLACK,Khan
1583
1592
 
1584
1593
  const{ButtonGroup: ButtonGroup$4}=components;class DashPicker extends React.Component{render(){return jsxRuntimeExports.jsx(ButtonGroup$4,{value:this.props.value,allowEmpty:false,buttons:[{value:"",content:jsxRuntimeExports.jsx("span",{children:"—"})},{value:"-",content:jsxRuntimeExports.jsx("span",{children:"–––"})},{value:"- ",content:jsxRuntimeExports.jsx("span",{children:"–  –"})},{value:".",content:jsxRuntimeExports.jsx("span",{children:"····"})},{value:". ",content:jsxRuntimeExports.jsx("span",{children:"· · ·"})}],onChange:this.props.onChange})}}DashPicker.defaultProps={value:""};
1585
1594
 
1586
- function MathquillInput(props){const mathFieldWrapperRef=useRef(null);const mathFieldInstance=useRef();const{locale,strings}=useMathInputI18n();useEffect(()=>{if(mathFieldWrapperRef.current&&!mathFieldInstance.current){mathFieldInstance.current=createMathField(mathFieldWrapperRef.current,locale,strings,baseConfig=>({...baseConfig,handlers:{edit:mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(props.value!==value){props.onChange(value);}},upOutOf:mathField=>{mathField.typedText("^");}}}));}});return jsxRuntimeExports.jsx(View,{style:styles$H.outerWrapper,children:jsxRuntimeExports.jsx("span",{ref:mathFieldWrapperRef,className:"perseus-math-input mq-editable-field mq-math-mode"})})}const styles$H=StyleSheet.create({outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:semanticColor.core.border.neutral.default,borderRadius:3,background:semanticColor.core.background.base.default}});
1595
+ function MathquillInput(props){const mathFieldWrapperRef=useRef(null);const mathFieldInstance=useRef();const{locale,strings}=useMathInputI18n();useEffect(()=>{if(mathFieldWrapperRef.current&&!mathFieldInstance.current){mathFieldInstance.current=createMathField(mathFieldWrapperRef.current,locale,strings,baseConfig=>({...baseConfig,handlers:{edit:mathField=>{let value=mathField.latex();value=value.replace(/<>/g,"\\ne");if(props.value!==value){props.onChange(value);}},upOutOf:mathField=>{mathField.typedText("^");}}}));}});return jsxRuntimeExports.jsx(View,{style:styles$E.outerWrapper,children:jsxRuntimeExports.jsx("span",{ref:mathFieldWrapperRef,className:"perseus-math-input mq-editable-field mq-math-mode"})})}const styles$E=StyleSheet.create({outerWrapper:{display:"inline-block",borderStyle:"solid",borderWidth:1,borderColor:semanticColor.core.border.neutral.default,borderRadius:3,background:semanticColor.core.background.base.default}});
1587
1596
 
1588
- const{NumberInput: NumberInput$c}=components;const{getDependencies: getDependencies$8}=Dependencies;class FunctionEditor extends React.Component{render(){const{TeX}=getDependencies$8();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:this.props.funcName+"(x)="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.value,onChange:this.change("value")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:this.change("rangeMin")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:this.change("rangeMax")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$c,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}FunctionEditor.defaultProps={value:"x",rangeMin:"-10",rangeMax:"10",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
1597
+ const{NumberInput: NumberInput$b}=components;const{getDependencies: getDependencies$8}=Dependencies;class FunctionEditor extends React.Component{render(){const{TeX}=getDependencies$8();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:this.props.funcName+"(x)="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.value,onChange:this.change("value")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:this.change("rangeMin")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:this.change("rangeMax")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$b,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}FunctionEditor.defaultProps={value:"x",rangeMin:"-10",rangeMax:"10",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
1589
1598
 
1590
- const{TextInput: TextInput$3}=components;const{getDependencies: getDependencies$7}=Dependencies;class LabelEditor extends React.Component{render(){const{TeX}=getDependencies$7();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(TextInput$3,{value:this.props.label,onChange:this.change("label"),style:{width:"100%"}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Location: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.change("coordX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:this.change("coordY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}LabelEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK,label:"\\phi"};
1599
+ const{TextInput: TextInput$2}=components;const{getDependencies: getDependencies$7}=Dependencies;class LabelEditor extends React.Component{render(){const{TeX}=getDependencies$7();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(TextInput$2,{value:this.props.label,onChange:this.change("label"),style:{width:"100%"}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Location: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.change("coordX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:this.change("coordY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}LabelEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK,label:"\\phi"};
1591
1600
 
1592
1601
  const{ButtonGroup: ButtonGroup$3}=components;class ArrowPicker extends React.Component{render(){return jsxRuntimeExports.jsx(ButtonGroup$3,{value:this.props.value,allowEmpty:false,buttons:[{value:"",content:jsxRuntimeExports.jsx("span",{children:"—"})},{value:"->",content:jsxRuntimeExports.jsx("span",{children:"→"})}],onChange:this.props.onChange})}}ArrowPicker.defaultProps={value:""};
1593
1602
 
1594
- const{NumberInput: NumberInput$b}=components;const{getDependencies: getDependencies$6}=Dependencies;class LineEditor extends React.Component{render(){const{TeX}=getDependencies$6();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")}),"   ",jsxRuntimeExports.jsx(ArrowPicker,{value:this.props.arrows,onChange:this.change("arrows")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$b,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}LineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",color:KhanColors.BLACK,strokeDasharray:"",arrows:"",strokeWidth:2};
1603
+ const{NumberInput: NumberInput$a}=components;const{getDependencies: getDependencies$6}=Dependencies;class LineEditor extends React.Component{render(){const{TeX}=getDependencies$6();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")}),"   ",jsxRuntimeExports.jsx(ArrowPicker,{value:this.props.arrows,onChange:this.change("arrows")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$a,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}LineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",color:KhanColors.BLACK,strokeDasharray:"",arrows:"",strokeWidth:2};
1595
1604
 
1596
- const{ButtonGroup: ButtonGroup$2,NumberInput: NumberInput$a}=components;class ConstraintEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Constraint:"," ",jsxRuntimeExports.jsx(ButtonGroup$2,{value:this.props.constraint,allowEmpty:false,buttons:[{value:"none",content:"None"},{value:"snap",content:"Snap"},{value:"x",content:"x="},{value:"y",content:"y="}],onChange:this.change("constraint")})]}),this.props.constraint==="snap"&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Snap:"," ",jsxRuntimeExports.jsx(NumberInput$a,{value:this.props.snap,placeholder:0,onChange:this.change("snap")})]}),this.props.constraint==="x"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:this.change("constraintFn")})]})}),this.props.constraint==="y"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:this.change("constraintFn")})]})}),"Ensure these are set so nothing can be dragged off the canvas:",jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMin,onChange:this.change("constraintXMin")}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMax,onChange:this.change("constraintXMax")})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMin,onChange:this.change("constraintYMin")}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMax,onChange:this.change("constraintYMax")})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})})]})}constructor(...args){super(...args),this.change=propName=>{return Changeable.change.call(this,propName)};}}ConstraintEditor.defaultProps={constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
1605
+ const{ButtonGroup: ButtonGroup$2,NumberInput: NumberInput$9}=components;class ConstraintEditor extends React.Component{render(){const{TeX}=Dependencies.getDependencies();return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Constraint:"," ",jsxRuntimeExports.jsx(ButtonGroup$2,{value:this.props.constraint,allowEmpty:false,buttons:[{value:"none",content:"None"},{value:"snap",content:"Snap"},{value:"x",content:"x="},{value:"y",content:"y="}],onChange:this.change("constraint")})]}),this.props.constraint==="snap"&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Snap:"," ",jsxRuntimeExports.jsx(NumberInput$9,{value:this.props.snap,placeholder:0,onChange:this.change("snap")})]}),this.props.constraint==="x"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:this.change("constraintFn")})]})}),this.props.constraint==="y"&&jsxRuntimeExports.jsx("div",{className:"graph-settings",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintFn,onChange:this.change("constraintFn")})]})}),"Ensure these are set so nothing can be dragged off the canvas:",jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"x \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMin,onChange:this.change("constraintXMin")}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintXMax,onChange:this.change("constraintXMax")})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"y \\in \\Large["})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMin,onChange:this.change("constraintYMin")}),jsxRuntimeExports.jsx(TeX,{children:", "})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.constraintYMax,onChange:this.change("constraintYMax")})," ",jsxRuntimeExports.jsx(TeX,{children:"\\Large]"})]})})]})}constructor(...args){super(...args),this.change=propName=>{return Changeable.change.call(this,propName)};}}ConstraintEditor.defaultProps={constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
1597
1606
 
1598
- const{NumberInput: NumberInput$9}=components;const{getDependencies: getDependencies$5}=Dependencies;class MovableLineEditor extends React.Component{render(){const{TeX}=getDependencies$5();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:["Initial position:",jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="}),jsxRuntimeExports.jsx(NumberInput$9,{value:this.props.startSubscript,placeholder:0,onChange:this.change("startSubscript")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_m, y_m)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"m ="}),jsxRuntimeExports.jsx(NumberInput$9,{value:this.props.endSubscript,placeholder:0,onChange:this.change("endSubscript")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:"All constraints are applied to the start point."}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MovableLineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
1607
+ const{NumberInput: NumberInput$8}=components;const{getDependencies: getDependencies$5}=Dependencies;class MovableLineEditor extends React.Component{render(){const{TeX}=getDependencies$5();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:["Initial position:",jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endX,onChange:this.change("endX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.endY,onChange:this.change("endY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="}),jsxRuntimeExports.jsx(NumberInput$8,{value:this.props.startSubscript,placeholder:0,onChange:this.change("startSubscript")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["End updates ",jsxRuntimeExports.jsx(TeX,{children:"(x_m, y_m)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"m ="}),jsxRuntimeExports.jsx(NumberInput$8,{value:this.props.endSubscript,placeholder:0,onChange:this.change("endSubscript")})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:"All constraints are applied to the start point."}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MovableLineEditor.defaultProps={startX:"-5",startY:"5",endX:"5",endY:"5",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
1599
1608
 
1600
- const{NumberInput: NumberInput$8}=components;const{getDependencies: getDependencies$4}=Dependencies;class MovablePointEditor extends React.Component{render(){const{TeX}=getDependencies$4();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Update ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="})," ",jsxRuntimeExports.jsx(NumberInput$8,{value:this.props.varSubscript,placeholder:0,onChange:this.change("varSubscript")})]}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MovablePointEditor.defaultProps={startX:"0",startY:"0",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
1609
+ const{NumberInput: NumberInput$7}=components;const{getDependencies: getDependencies$4}=Dependencies;class MovablePointEditor extends React.Component{render(){const{TeX}=getDependencies$4();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Start: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startX,onChange:this.change("startX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.startY,onChange:this.change("startY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Update ",jsxRuntimeExports.jsx(TeX,{children:"(x_n, y_n)"})," for ",jsxRuntimeExports.jsx(TeX,{children:"n ="})," ",jsxRuntimeExports.jsx(NumberInput$7,{value:this.props.varSubscript,placeholder:0,onChange:this.change("varSubscript")})]}),jsxRuntimeExports.jsx(ConstraintEditor,{...this.props})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MovablePointEditor.defaultProps={startX:"0",startY:"0",constraint:"none",snap:.5,constraintFn:"0",constraintXMin:"-10",constraintXMax:"10",constraintYMin:"-10",constraintYMax:"10"};
1601
1610
 
1602
- const{NumberInput: NumberInput$7}=components;const{getDependencies: getDependencies$3}=Dependencies;class ParametricEditor extends React.Component{render(){const{TeX}=getDependencies$3();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"X(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.x,onChange:this.change("x")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"Y(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.y,onChange:this.change("y")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:this.change("rangeMin")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:this.change("rangeMax")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$7,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}ParametricEditor.defaultProps={x:"cos(t)",y:"sin(t)",rangeMin:"0",rangeMax:"2\\pi",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
1611
+ const{NumberInput: NumberInput$6}=components;const{getDependencies: getDependencies$3}=Dependencies;class ParametricEditor extends React.Component{render(){const{TeX}=getDependencies$3();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"X(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.x,onChange:this.change("x")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx(TeX,{children:"Y(t) ="})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.y,onChange:this.change("y")})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Range: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMin,onChange:this.change("rangeMin")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.rangeMax,onChange:this.change("rangeMax")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(DashPicker,{value:this.props.strokeDasharray,onChange:this.change("strokeDasharray")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Width:"," ",jsxRuntimeExports.jsx(NumberInput$6,{value:this.props.strokeWidth,placeholder:2,onChange:this.change("strokeWidth")})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}ParametricEditor.defaultProps={x:"cos(t)",y:"sin(t)",rangeMin:"0",rangeMax:"2\\pi",color:KhanColors.BLUE,strokeDasharray:"",strokeWidth:2};
1603
1612
 
1604
1613
  const{getDependencies: getDependencies$2}=Dependencies;class PointEditor extends React.Component{render(){const{TeX}=getDependencies$2();return jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Coordinate: ",jsxRuntimeExports.jsx(TeX,{children:"\\Large("}),jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordX,onChange:this.change("coordX")}),jsxRuntimeExports.jsx(TeX,{children:","})," ",jsxRuntimeExports.jsx(MathquillInput,{value:this.props.coordY,onChange:this.change("coordY")}),jsxRuntimeExports.jsx(TeX,{children:"\\Large)"})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(ColorPicker,{value:this.props.color,onChange:this.change("color")})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}PointEditor.defaultProps={coordX:"0",coordY:"0",color:KhanColors.BLACK};
1605
1614
 
@@ -1607,158 +1616,156 @@ const{getDependencies: getDependencies$1}=Dependencies;class RectangleEditor ext
1607
1616
 
1608
1617
  const{getDependencies}=Dependencies;const{unescapeMathMode}=Util;class InteractionEditor extends React.Component{UNSAFE_componentWillReceiveProps(nextProps){this.setState({usedVarSubscripts:this._getAllVarSubscripts(nextProps.elements),usedFunctionNames:this._getAllFunctionNames(nextProps.elements)});}_getAllVarSubscripts(elements){return _.map(_.where(elements,{type:"movable-point"}),element=>element.options.varSubscript).concat(_.map(_.where(elements,{type:"movable-line"}),element=>element.options.startSubscript)).concat(_.map(_.where(elements,{type:"movable-line"}),element=>element.options.endSubscript))}_getAllFunctionNames(elements){return _.map(_.where(elements,{type:"function"}),element=>element.options.funcName)}render(){const{TeX}=getDependencies();return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-interaction-editor",children:[jsxRuntimeExports.jsxs(ElementContainer,{title:"Grid settings",children:[jsxRuntimeExports.jsx(GraphSettings,{editableSettings:["canvas","graph"],box:this.props.graph.box,labels:this.props.graph.labels,range:this.props.graph.range,step:this.props.graph.tickStep,gridStep:this.props.graph.gridStep,markings:this.props.graph.markings,onChange:this._updateGraphProps}),jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:this.props.graph.valid!==true&&jsxRuntimeExports.jsx("div",{children:this.props.graph.valid})})]}),_.map(this.props.elements,function(element,n){if(element.type==="movable-point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable point"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.varSubscript+"}, y_{"+element.options.varSubscript+"})"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(MovablePointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="movable-line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Movable line"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.startSubscript+"}, y_{"+element.options.startSubscript+"})"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"(x_{"+element.options.endSubscript+"}, y_{"+element.options.endSubscript+"})"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(MovableLineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="point"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Point"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(PointEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="line"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Line"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.startX+", "+element.options.startY+")"})," ","to"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.endX+", "+element.options.endY+")"})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement.bind(this,n),children:jsxRuntimeExports.jsx(LineEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="function"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Function"," ",jsxRuntimeExports.jsx(TeX,{children:element.options.funcName+"(x) = "+element.options.value})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(FunctionEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="parametric"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsx("span",{children:"Parametric"}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(ParametricEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="label"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Label"," ",jsxRuntimeExports.jsx(TeX,{children:unescapeMathMode(element.options.label)})," "]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(LabelEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}if(element.type==="rectangle"){return jsxRuntimeExports.jsx(ElementContainer,{title:jsxRuntimeExports.jsxs("span",{children:["Rectangle"," ",jsxRuntimeExports.jsx(TeX,{children:"("+element.options.coordX+", "+element.options.coordY+")"})," — ",jsxRuntimeExports.jsx(TeX,{children:element.options.width+" \\times "+element.options.height})]}),onUp:n===0?null:this._moveElementUp.bind(this,n),onDown:n===this.props.elements.length-1?null:this._moveElementDown.bind(this,n),onDelete:this._deleteElement,children:jsxRuntimeExports.jsx(RectangleEditor,{...element.options,onChange:newProps=>{const elements=JSON.parse(JSON.stringify(this.props.elements));_.extend(elements[n].options,newProps);this.props.onChange({elements:elements});}})},element.key)}},this),jsxRuntimeExports.jsx("div",{className:"perseus-widget-interaction-editor-select-element",children:jsxRuntimeExports.jsxs("select",{onChange:this._addNewElement,children:[jsxRuntimeExports.jsxs("option",{value:"",children:["Add an element","…"]}),jsxRuntimeExports.jsx("option",{disabled:true,children:"--"}),jsxRuntimeExports.jsx("option",{value:"point",children:"Point"}),jsxRuntimeExports.jsx("option",{value:"line",children:"Line segment"}),jsxRuntimeExports.jsx("option",{value:"function",children:"Function plot"}),jsxRuntimeExports.jsx("option",{value:"parametric",children:"Parametric plot"}),jsxRuntimeExports.jsx("option",{value:"label",children:"Label"}),jsxRuntimeExports.jsx("option",{value:"rectangle",children:"Rectangle"}),jsxRuntimeExports.jsx("option",{value:"movable-point",children:"★ Movable point"}),jsxRuntimeExports.jsx("option",{value:"movable-line",children:"★ Movable line segment"})]})})]})}constructor(...args){super(...args),this.state={usedVarSubscripts:this._getAllVarSubscripts(this.props.elements),usedFunctionNames:this._getAllFunctionNames(this.props.elements)},this._updateGraphProps=newProps=>{this.props.onChange({graph:{...this.props.graph,..._.omit(newProps,"step"),tickStep:newProps.step}});},this._addNewElement=e=>{const elementType=e.target.value;if(elementType===""){return}e.target.value="";const newElement={type:elementType,key:elementType+"-"+(Math.random()*0xffffff<<0).toString(16),options:elementType==="point"?_.clone(PointEditor.defaultProps):elementType==="line"?_.clone(LineEditor.defaultProps):elementType==="movable-point"?_.clone(MovablePointEditor.defaultProps):elementType==="movable-line"?_.clone(MovableLineEditor.defaultProps):elementType==="function"?_.clone(FunctionEditor.defaultProps):elementType==="parametric"?_.clone(ParametricEditor.defaultProps):elementType==="label"?_.clone(LabelEditor.defaultProps):elementType==="rectangle"?_.clone(RectangleEditor.defaultProps):{}};let nextSubscript;if(elementType==="movable-point"){nextSubscript=_.max([_.max(this.state.usedVarSubscripts),-1])+1;newElement.options.varSubscript=nextSubscript;}else if(elementType==="movable-line"){nextSubscript=_.max([_.max(this.state.usedVarSubscripts),-1])+1;newElement.options.startSubscript=nextSubscript;newElement.options.endSubscript=nextSubscript+1;}else if(elementType==="function"){const nextLetter=String.fromCharCode(_.max([_.max(_.map(this.state.usedFunctionNames,function(c){return c.charCodeAt(0)})),"e".charCodeAt(0)])+1);newElement.options.funcName=nextLetter;}this.props.onChange({elements:this.props.elements.concat(newElement)});},this._deleteElement=index=>{const element=this.props.elements[index];this.props.onChange({elements:_.without(this.props.elements,element)});},this._moveElementUp=index=>{const element=this.props.elements[index];const newElements=_.without(this.props.elements,element);newElements.splice(index-1,0,element);this.props.onChange({elements:newElements});},this._moveElementDown=index=>{const element=this.props.elements[index];const newElements=_.without(this.props.elements,element);newElements.splice(index+1,0,element);this.props.onChange({elements:newElements});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}InteractionEditor.widgetName="interaction";InteractionEditor.defaultProps=interactionLogic.defaultWidgetOptions;
1609
1618
 
1610
- var styles$G = {"singleSelectShort":"perseus_wAZzFxEx","row":"perseus_6FquBkGo"};
1619
+ var styles$D = {"singleSelectShort":"perseus_wAZzFxEx","row":"perseus_6FquBkGo"};
1611
1620
 
1612
- const LabeledRow=props=>{const{children,label,labelSide="left",labelSize="small",style}=props;return jsxRuntimeExports.jsx("label",{className:css(styles$F.label),children:jsxRuntimeExports.jsxs(View,{style:[styles$F.row,style],children:[labelSide==="start"||jsxRuntimeExports.jsx(BodyText,{size:labelSize==="small"?"small":undefined,tag:"span",style:styles$F.spaceEnd,children:label}),children,labelSide==="end"&&jsxRuntimeExports.jsx(BodyText,{size:labelSize==="small"?"small":undefined,tag:"span",style:styles$F.spaceStart,children:label})]})})};const styles$F=StyleSheet.create({label:{width:"fit-content"},row:{flexDirection:"row",marginTop:spacing.xSmall_8,alignItems:"center",width:"fit-content"},spaceStart:{marginInlineStart:spacing.xSmall_8},spaceEnd:{marginInlineEnd:spacing.xSmall_8}});
1621
+ const LabeledRow=props=>{const{children,label,labelSide="left",labelSize="small",style}=props;return jsxRuntimeExports.jsx("label",{className:css(styles$C.label),children:jsxRuntimeExports.jsxs(View,{style:[styles$C.row,style],children:[labelSide==="start"||jsxRuntimeExports.jsx(BodyText,{size:labelSize==="small"?"small":undefined,tag:"span",style:styles$C.spaceEnd,children:label}),children,labelSide==="end"&&jsxRuntimeExports.jsx(BodyText,{size:labelSize==="small"?"small":undefined,tag:"span",style:styles$C.spaceStart,children:label})]})})};const styles$C=StyleSheet.create({label:{width:"fit-content"},row:{flexDirection:"row",marginTop:spacing.xSmall_8,alignItems:"center",width:"fit-content"},spaceStart:{marginInlineStart:spacing.xSmall_8},spaceEnd:{marginInlineEnd:spacing.xSmall_8}});
1613
1622
 
1614
- const{InfoTip: InfoTip$g}=components;function AngleAnswerOptions({correct,graph,onChange}){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$G.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Show angle measures"}),checked:!!correct?.showAngles,onChange:newValue=>{if(graph?.type==="angle"){invariant(correct.type==="angle",`Expected graph type to be angle, but got ${correct.type}`);onChange({correct:{...correct,showAngles:newValue},graph:{...graph,showAngles:newValue}});}}}),jsxRuntimeExports.jsx(InfoTip$g,{children:jsxRuntimeExports.jsx("p",{children:"Displays the interior angle measures."})})]}),jsxRuntimeExports.jsxs(View,{className:styles$G.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Allow reflex angles"}),checked:!!correct?.allowReflexAngles,onChange:newValue=>{invariant(correct.type==="angle",`Expected graph type to be angle, but got ${correct.type}`);invariant(graph?.type==="angle",`Expected graph type to be angle, but got ${graph?.type}`);const update={allowReflexAngles:newValue};onChange({correct:{...correct,...update},graph:{...graph,...update}});}}),jsxRuntimeExports.jsx(InfoTip$g,{children:jsxRuntimeExports.jsx("p",{children:"Allow students to be able to create reflex angles."})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Student answer must",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct.match||"exact",onChange:newValue=>{invariant(correct.type==="angle",`Expected graph type to be angle, but got ${correct.type}`);onChange({correct:{...correct,match:newValue}});},placeholder:"",className:styles$G.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"exact",label:"match exactly"}),jsxRuntimeExports.jsx(OptionItem,{value:"congruent",label:"be congruent"})]}),jsxRuntimeExports.jsx(InfoTip$g,{children:jsxRuntimeExports.jsx("p",{children:"Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position."})})]})]})}
1623
+ const{InfoTip: InfoTip$f}=components;function AngleAnswerOptions({correct,graph,onChange}){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$D.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Show angle measures"}),checked:!!correct?.showAngles,onChange:newValue=>{if(graph?.type==="angle"){invariant(correct.type==="angle",`Expected graph type to be angle, but got ${correct.type}`);onChange({correct:{...correct,showAngles:newValue},graph:{...graph,showAngles:newValue}});}}}),jsxRuntimeExports.jsx(InfoTip$f,{children:jsxRuntimeExports.jsx("p",{children:"Displays the interior angle measures."})})]}),jsxRuntimeExports.jsxs(View,{className:styles$D.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Allow reflex angles"}),checked:!!correct?.allowReflexAngles,onChange:newValue=>{invariant(correct.type==="angle",`Expected graph type to be angle, but got ${correct.type}`);invariant(graph?.type==="angle",`Expected graph type to be angle, but got ${graph?.type}`);const update={allowReflexAngles:newValue};onChange({correct:{...correct,...update},graph:{...graph,...update}});}}),jsxRuntimeExports.jsx(InfoTip$f,{children:jsxRuntimeExports.jsx("p",{children:"Allow students to be able to create reflex angles."})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Student answer must",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct.match||"exact",onChange:newValue=>{invariant(correct.type==="angle",`Expected graph type to be angle, but got ${correct.type}`);onChange({correct:{...correct,match:newValue}});},placeholder:"",className:styles$D.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"exact",label:"match exactly"}),jsxRuntimeExports.jsx(OptionItem,{value:"congruent",label:"be congruent"})]}),jsxRuntimeExports.jsx(InfoTip$f,{children:jsxRuntimeExports.jsx("p",{children:"Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position."})})]})]})}
1615
1624
 
1616
1625
  const UNLIMITED="unlimited";const parsePointCount=points=>{const parsed=parseInt(points,10);if(isNaN(parsed)){return UNLIMITED}return parsed===0?UNLIMITED:parsed};
1617
1626
 
1618
- const GraphPointsCountSelector=({correct,graph,onChange})=>{return jsxRuntimeExports.jsx(LabeledRow,{label:"Number of Points:",children:jsxRuntimeExports.jsx(SingleSelect,{selectedValue:`${correct.numPoints??1}`,onChange:newValue=>{const points=parsePointCount(newValue);onChange({correct:{type:"point",numPoints:points},graph:{type:"point",numPoints:points}});},placeholder:"",className:styles$G.singleSelectShort,children:[...[...Array(7).keys()].map(n=>jsxRuntimeExports.jsx(OptionItem,{value:`${n}`,label:`${n} point${n>1?"s":""}`},n)),jsxRuntimeExports.jsx(OptionItem,{value:UNLIMITED,label:"unlimited"},"unlimited")]})})};
1627
+ const GraphPointsCountSelector=({correct,graph,onChange})=>{return jsxRuntimeExports.jsx(LabeledRow,{label:"Number of Points:",children:jsxRuntimeExports.jsx(SingleSelect,{selectedValue:`${correct.numPoints??1}`,onChange:newValue=>{const points=parsePointCount(newValue);onChange({correct:{type:"point",numPoints:points},graph:{type:"point",numPoints:points}});},placeholder:"",className:styles$D.singleSelectShort,children:[...[...Array(7).keys()].map(n=>jsxRuntimeExports.jsx(OptionItem,{value:`${n}`,label:`${n} point${n>1?"s":""}`},n)),jsxRuntimeExports.jsx(OptionItem,{value:UNLIMITED,label:"unlimited"},"unlimited")]})})};
1619
1628
 
1620
- const GraphTypeSelector=props=>{return jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:props.graphType,onChange:props.onChange,placeholder:"Select an answer type",className:styles$G.singleSelectShort,disabled:props.disabled,children:[jsxRuntimeExports.jsx(OptionItem,{value:"none",label:"None"}),jsxRuntimeExports.jsx(OptionItem,{value:"absolute-value",label:"Absolute value function"}),jsxRuntimeExports.jsx(OptionItem,{value:"exponential",label:"Exponential function"}),jsxRuntimeExports.jsx(OptionItem,{value:"linear",label:"Linear function"}),jsxRuntimeExports.jsx(OptionItem,{value:"logarithm",label:"Logarithmic function"}),jsxRuntimeExports.jsx(OptionItem,{value:"quadratic",label:"Quadratic function"}),jsxRuntimeExports.jsx(OptionItem,{value:"sinusoid",label:"Sinusoidal function"}),jsxRuntimeExports.jsx(OptionItem,{value:"tangent",label:"Tangent function"}),jsxRuntimeExports.jsx(OptionItem,{value:"angle",label:"Angle"}),jsxRuntimeExports.jsx(OptionItem,{value:"circle",label:"Circle"}),jsxRuntimeExports.jsx(OptionItem,{value:"linear-system",label:"Linear system"}),jsxRuntimeExports.jsx(OptionItem,{value:"segment",label:"Line segment(s)"}),jsxRuntimeExports.jsx(OptionItem,{value:"point",label:"Point(s)"}),jsxRuntimeExports.jsx(OptionItem,{value:"polygon",label:"Polygon"}),jsxRuntimeExports.jsx(OptionItem,{value:"ray",label:"Ray"}),jsxRuntimeExports.jsx(OptionItem,{value:"vector",label:"Vector"})]})};
1621
-
1622
- function Heading({title,isOpen,isCollapsible,onToggle}){return jsxRuntimeExports.jsx(Clickable,{style:[styles$E.container,!isCollapsible&&styles$E.notClickable],disabled:!isCollapsible,onClick:()=>isCollapsible&&onToggle?.(!isOpen),children:()=>jsxRuntimeExports.jsxs(View,{style:styles$E.heading,children:[jsxRuntimeExports.jsx(BodyText,{size:"small",weight:"bold",tag:"span",children:title}),isCollapsible&&jsxRuntimeExports.jsx(ToggleableCaret,{isExpanded:isOpen})]})})}const styles$E=StyleSheet.create({container:{marginTop:spacing.small_12,marginInline:-10,backgroundColor:semanticColor.core.background.neutral.subtle,padding:spacing.xSmall_8,width:"calc(100% + 20px)"},heading:{flexDirection:"row",justifyContent:"space-between",userSelect:"none"},notClickable:{color:"inherit",cursor:"default"}});
1629
+ const GraphTypeSelector=props=>{return jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:props.graphType,onChange:props.onChange,placeholder:"Select an answer type",className:styles$D.singleSelectShort,disabled:props.disabled,children:[jsxRuntimeExports.jsx(OptionItem,{value:"none",label:"None"}),jsxRuntimeExports.jsx(OptionItem,{value:"absolute-value",label:"Absolute value function"}),jsxRuntimeExports.jsx(OptionItem,{value:"exponential",label:"Exponential function"}),jsxRuntimeExports.jsx(OptionItem,{value:"linear",label:"Linear function"}),jsxRuntimeExports.jsx(OptionItem,{value:"logarithm",label:"Logarithmic function"}),jsxRuntimeExports.jsx(OptionItem,{value:"quadratic",label:"Quadratic function"}),jsxRuntimeExports.jsx(OptionItem,{value:"sinusoid",label:"Sinusoidal function"}),jsxRuntimeExports.jsx(OptionItem,{value:"tangent",label:"Tangent function"}),jsxRuntimeExports.jsx(OptionItem,{value:"angle",label:"Angle"}),jsxRuntimeExports.jsx(OptionItem,{value:"circle",label:"Circle"}),jsxRuntimeExports.jsx(OptionItem,{value:"linear-system",label:"Linear system"}),jsxRuntimeExports.jsx(OptionItem,{value:"segment",label:"Line segment(s)"}),jsxRuntimeExports.jsx(OptionItem,{value:"point",label:"Point(s)"}),jsxRuntimeExports.jsx(OptionItem,{value:"polygon",label:"Polygon"}),jsxRuntimeExports.jsx(OptionItem,{value:"ray",label:"Ray"}),jsxRuntimeExports.jsx(OptionItem,{value:"vector",label:"Vector"})]})};
1623
1630
 
1624
1631
  function InteractiveGraphCorrectAnswer(props){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Correct Answer",isOpen:true,isCollapsible:false}),jsxRuntimeExports.jsxs(View,{id:props.id,children:[jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(BodyText,{size:"xsmall",style:{paddingTop:spacing.xxSmall_6,paddingBottom:spacing.xxSmall_6,color:semanticColor.core.foreground.neutral.subtle},children:"Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."}),jsxRuntimeExports.jsx(BodyMonospace,{style:{fontSize:12,backgroundColor:"#eee",paddingInline:spacing.xxSmall_6,borderColor:"#ccc",borderStyle:"solid",borderWidth:1},children:props.equationString})]}),props.children]})]})}
1625
1632
 
1626
- var styles$D = {"container":"perseus_7paQgL4U","caption":"perseus_DdFGH-ag"};
1633
+ var styles$B = {"container":"perseus_7paQgL4U","caption":"perseus_DdFGH-ag"};
1627
1634
 
1628
- function InteractiveGraphDescription(props){const{ariaLabelValue,ariaDescriptionValue,editingDisabled=false,onChange}=props;const[isOpen,setIsOpen]=React.useState(true);const uniqueId=React.useId();const descriptionTextAreaId=`${uniqueId}-description-textarea`;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Description",isCollapsible:true,isOpen:isOpen,onToggle:setIsOpen}),isOpen&&jsxRuntimeExports.jsxs(View,{className:styles$D.container,children:[jsxRuntimeExports.jsx(BodyText,{size:"xsmall",className:styles$D.caption,children:"Use these fields to describe the graph as a whole. These are used by screen readers to describe content to users who may be visually impaired."}),jsxRuntimeExports.jsx(BodyText,{size:"xsmall",className:styles$D.caption,children:"Aria description required when using locked figures. Locked figures aren't automatically described."}),jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"label",children:["Title",jsxRuntimeExports.jsx(TextField,{value:ariaLabelValue,onChange:newValue=>onChange({fullGraphAriaLabel:newValue||undefined}),disabled:editingDisabled,style:{marginTop:sizing.size_040}})]}),jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"label",htmlFor:descriptionTextAreaId,children:"Description"}),jsxRuntimeExports.jsx(TextArea,{id:descriptionTextAreaId,value:ariaDescriptionValue,onChange:newValue=>onChange({fullGraphAriaDescription:newValue||undefined}),disabled:editingDisabled,autoResize:true})]})]})}
1635
+ function InteractiveGraphDescription(props){const{ariaLabelValue,ariaDescriptionValue,editingDisabled=false,onChange}=props;const[isOpen,setIsOpen]=React.useState(true);const uniqueId=React.useId();const descriptionTextAreaId=`${uniqueId}-description-textarea`;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Description",isCollapsible:true,isOpen:isOpen,onToggle:setIsOpen}),isOpen&&jsxRuntimeExports.jsxs(View,{className:styles$B.container,children:[jsxRuntimeExports.jsx(BodyText,{size:"xsmall",className:styles$B.caption,children:"Use these fields to describe the graph as a whole. These are used by screen readers to describe content to users who may be visually impaired."}),jsxRuntimeExports.jsx(BodyText,{size:"xsmall",className:styles$B.caption,children:"Aria description required when using locked figures. Locked figures aren't automatically described."}),jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"label",children:["Title",jsxRuntimeExports.jsx(TextField,{value:ariaLabelValue,onChange:newValue=>onChange({fullGraphAriaLabel:newValue||undefined}),disabled:editingDisabled,style:{marginTop:sizing.size_040}})]}),jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"label",htmlFor:descriptionTextAreaId,children:"Description"}),jsxRuntimeExports.jsx(TextArea,{id:descriptionTextAreaId,value:ariaDescriptionValue,onChange:newValue=>onChange({fullGraphAriaDescription:newValue||undefined}),disabled:editingDisabled,autoResize:true})]})]})}
1629
1636
 
1630
1637
  function AxisArrowSwitches(props){const{showAxisArrows,onChange,disabled}=props;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(BodyText,{size:"small",children:"Arrows"}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",style:{display:"flex",flexDirection:"row",alignItems:"center",gap:sizing.size_060},children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledSwitch,{label:"x min",labelSide:"start",size:"small",checked:showAxisArrows.xMin,disabled:disabled,onChange:()=>onChange("xMin")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledSwitch,{label:"y min",labelSide:"start",size:"small",checked:showAxisArrows.yMin,disabled:disabled,onChange:()=>onChange("yMin")})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",style:{display:"flex",flexDirection:"row",alignItems:"center",gap:sizing.size_060},children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledSwitch,{label:"x max",labelSide:"start",size:"small",checked:showAxisArrows.xMax,disabled:disabled,onChange:()=>onChange("xMax")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledSwitch,{label:"y max",labelSide:"start",size:"small",checked:showAxisArrows.yMax,disabled:disabled,onChange:()=>onChange("yMax")})})]})]})}
1631
1638
 
1632
1639
  function AxisTickSwitches(props){const{showAxisTicks,onChange,disabled}=props;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(BodyText,{size:"small",children:"Ticks"}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",style:{display:"flex",flexDirection:"row",alignItems:"center",gap:sizing.size_060},children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledSwitch,{label:"x-axis",labelSide:"start",size:"small",checked:showAxisTicks.x,disabled:disabled,onChange:()=>onChange("x")})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledSwitch,{label:"y-axis",labelSide:"start",size:"small",checked:showAxisTicks.y,disabled:disabled,onChange:()=>onChange("y")})})]})]})}
1633
1640
 
1634
- var styles$C = {"backgroundUrlInput":"perseus_so0nIc4z","checkboxRow":"perseus_lfG1X93S","protractorSection":"perseus_thf-SEbO"};
1641
+ var styles$A = {"backgroundUrlInput":"perseus_so0nIc4z","checkboxRow":"perseus_lfG1X93S","protractorSection":"perseus_thf-SEbO"};
1635
1642
 
1636
- const{ButtonGroup: ButtonGroup$1,InfoTip: InfoTip$f,RangeInput: RangeInput$4}=components;const defaultBackgroundImage={url:null,width:0,height:0};function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}class InteractiveGraphSettings extends React.Component{static stateFromProps(props){return {labelsTextbox:props.labels,labelLocation:props.labelLocation,gridStepTextbox:props.gridStep,snapStepTextbox:props.snapStep,stepTextbox:props.step,rangeTextbox:props.range,showAxisArrowsSwitches:props.showAxisArrows,showAxisTicksSwitches:props.showAxisTicks,backgroundImage:{...props.backgroundImage}}}componentDidMount(){this._isMounted=true;this.changeGraph=_.debounce(this.changeGraph,300);}UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.labels,nextProps.labels)||!_.isEqual(this.props.labelLocation,nextProps.labelLocation)||!_.isEqual(this.props.gridStep,nextProps.gridStep)||!_.isEqual(this.props.snapStep,nextProps.snapStep)||!_.isEqual(this.props.step,nextProps.step)||!_.isEqual(this.props.range,nextProps.range)||!_.isEqual(this.props.backgroundImage,nextProps.backgroundImage)){this.setState(InteractiveGraphSettings.stateFromProps(nextProps));}}componentWillUnmount(){this._isMounted=false;}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Common Graph Settings",isOpen:this.state.isExpanded,isCollapsible:true,onToggle:()=>this.setState({isExpanded:!this.state.isExpanded})}),this.state.isExpanded&&jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Label Location",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.labelLocation,allowEmpty:false,buttons:[{value:"onAxis",content:"On Axis"},{value:"alongEdge",content:"Along Graph Edge"}],onChange:this.change("labelLocation"),disabled:editingDisabled})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelXRef,onChange:e=>this.changeLabel(0,e),value:this.state.labelsTextbox[0]||""})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelYRef,onChange:e=>this.changeLabel(1,e),value:this.state.labelsTextbox[1]||""})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[0],onChange:vals=>this.changeRange(0,vals),allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[1],onChange:vals=>this.changeRange(1,vals),allowPiTruncation:true})})})]}),jsxRuntimeExports.jsx(AxisArrowSwitches,{showAxisArrows:this.state.showAxisArrowsSwitches,onChange:this.changeShowAxisArrows,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsx(AxisTickSwitches,{showAxisTicks:this.state.showAxisTicksSwitches,onChange:this.changeShowAxisTicks,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Tick Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.stepTextbox,onChange:this.changeStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Grid Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.gridStepTextbox,onChange:this.changeGridStep,allowPiTruncation:true})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Snap Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.snapStepTextbox,onChange:this.changeSnapStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx(Button,{size:"small",kind:"tertiary",onClick:()=>{this.changeStepsBasedOnRange();},disabled:editingDisabled,children:"Auto-adjust steps"}),jsxRuntimeExports.jsxs(InfoTip$f,{children:[jsxRuntimeExports.jsx("p",{children:'Use the "Auto-adjust" steps button to update the tick step, grid step, and snap step to values that are valid for the current range.'}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("p",{children:"This is useful when the range is changed, and the graph errors due to the step sizes being too large or too small."})]})]})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Markings",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.markings,allowEmpty:false,buttons:[{value:"axes",content:"Axes"},{value:"graph",content:"Graph"},{value:"grid",content:"Grid"},{value:"none",content:"None"}],onChange:this.change("markings"),disabled:editingDisabled})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.change({showTooltips:value});},disabled:editingDisabled})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Background image URL",style:{marginTop:0},children:[jsxRuntimeExports.jsx("input",{type:"text",className:styles$C.backgroundUrlInput,ref:this.bgUrlRef,value:this.state.backgroundImage.url||"",onChange:e=>{const image={...this.props.backgroundImage};image.url=e.target.value;this.setState({backgroundImage:image});},onKeyPress:this.changeBackgroundUrl,onBlur:this.changeBackgroundUrl}),jsxRuntimeExports.jsx(InfoTip$f,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]}),jsxRuntimeExports.jsxs(View,{className:styles$C.protractorSection,children:[jsxRuntimeExports.jsx(View,{className:styles$C.checkboxRow,children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.change({showProtractor:value});},disabled:editingDisabled,style:{marginTop:0}})}),this.props.showProtractor&&jsxRuntimeExports.jsx(Banner,{text:"The protractor is not accessible. Please consider an alternate approach.",kind:"warning"})]})]})]})}constructor(props){super(props),this._isMounted=false,this.bgUrlRef=React.createRef(),this.labelXRef=React.createRef(),this.labelYRef=React.createRef(),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.changeBackgroundUrl=e=>{if(e.type==="keypress"&&e.key!=="Enter"){return}const setUrl=(url,width,height)=>{const image={...this.props.backgroundImage};image.url=url;image.width=width;image.height=height;this.setState({backgroundImage:image},this.changeGraph);};const url=this.bgUrlRef.current?.value;if(url){Util.getImageSize(url,(width,height)=>{if(this._isMounted){setUrl(url,width,height);}});}else {setUrl(null,0,0);}},this.renderLabelChoices=choices=>{return choices.map(nameAndValue=>jsxRuntimeExports.jsx("option",{value:nameAndValue[1],children:nameAndValue[0]},nameAndValue[1]))},this.validRange=range=>{const numbers=_.every(range,function(num){return _.isFinite(num)});if(!numbers){return "Range must be a valid number"}if(range[0]>=range[1]){return "Range must have a higher number on the right"}return true},this.validateStepValue=settings=>{const{step,range,name,minTicks,maxTicks}=settings;const nSteps=numSteps(range,step);if(nSteps<minTicks){return name+" is too large, there must be at least "+minTicks+" ticks."}if(nSteps>maxTicks){return name+" is too small, there can be at most "+maxTicks+" ticks."}return true},this.validSnapStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Snap step",minTicks:5,maxTicks:60})},this.validGridStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Grid step",minTicks:3,maxTicks:60})},this.validStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Step",minTicks:3,maxTicks:20})},this.validBackgroundImageSize=image=>{if(!image.url){return true}const validSize=image.width<=450&&image.height<=450;if(!validSize){return "Image must be smaller than 450px x 450px."}return true},this.validateGraphSettings=(range,step,gridStep,snapStep,image)=>{const self=this;let msg;const goodRange=_.every(range,function(range){msg=self.validRange(range);return msg===true});if(!goodRange){return msg}const goodStep=_.every(step,function(step,i){msg=self.validStep(step,range[i]);return msg===true});if(!goodStep){return msg}const goodGridStep=_.every(gridStep,function(gridStep,i){msg=self.validGridStep(gridStep,range[i]);return msg===true});if(!goodGridStep){return msg}const goodSnapStep=_.every(snapStep,function(snapStep,i){msg=self.validSnapStep(snapStep,range[i]);return msg===true});if(!goodSnapStep){return msg}const goodImageSize=this.validBackgroundImageSize(image);if(goodImageSize!==true){msg=goodImageSize;return msg}return true},this.changeLabel=(i,e)=>{const val=e.target.value;const labels=this.state.labelsTextbox.slice();labels[i]=val;this.setState({labelsTextbox:labels},this.changeGraph);},this.changeRange=(i,values)=>{const ranges=this.state.rangeTextbox.slice();ranges[i]=values;this.setState({rangeTextbox:ranges},this.changeGraph);},this.changeShowAxisArrows=axis=>{const newShowAxisArrows={...this.state.showAxisArrowsSwitches};newShowAxisArrows[axis]=!newShowAxisArrows[axis];this.setState({showAxisArrowsSwitches:newShowAxisArrows},this.changeGraph);},this.changeShowAxisTicks=axis=>{const newShowAxisTicks={...this.state.showAxisTicksSwitches};newShowAxisTicks[axis]=!newShowAxisTicks[axis];this.setState({showAxisTicksSwitches:newShowAxisTicks},this.changeGraph);},this.changeStepsBasedOnRange=()=>{const ranges=this.state.rangeTextbox.slice();const step=this.state.stepTextbox.slice();const gridStep=this.state.gridStepTextbox.slice();const snapStep=this.state.snapStepTextbox.slice();const scaleX=Util.scaleFromExtent(ranges[0],this.props.box[0]);if(this.validRange(ranges[0])===true){step[0]=Util.tickStepFromExtent(ranges[0],this.props.box[0]);const gridStepValue=Util.gridStepFromTickStep(step[0],scaleX);if(gridStepValue){gridStep[0]=gridStepValue;}snapStep[0]=gridStep[0]/2;}const scaleY=Util.scaleFromExtent(ranges[1],this.props.box[1]);if(this.validRange(ranges[1])===true){step[1]=Util.tickStepFromExtent(ranges[1],this.props.box[1]);const gridStepValue=Util.gridStepFromTickStep(step[1],scaleY);if(gridStepValue){gridStep[1]=gridStepValue;}snapStep[1]=gridStep[1]/2;}this.setState({stepTextbox:step,gridStepTextbox:gridStep,snapStepTextbox:snapStep,rangeTextbox:ranges},this.changeGraph);},this.changeStep=step=>{this.setState({stepTextbox:step},this.changeGraph);},this.changeSnapStep=snapStep=>{this.setState({snapStepTextbox:snapStep},this.changeGraph);},this.changeGridStep=gridStep=>{this.setState({gridStepTextbox:gridStep,snapStepTextbox:_.map(gridStep,function(step){return step/2})},this.changeGraph);},this.changeGraph=()=>{const labels=this.state.labelsTextbox;const labelLocation=this.state.labelLocation;const range=this.state.rangeTextbox.map(range=>range.map(value=>Number(value)));const showAxisArrows=this.state.showAxisArrowsSwitches;const showAxisTicks=this.state.showAxisTicksSwitches;const step=this.state.stepTextbox.map(value=>Number(value));const gridStep=this.state.gridStepTextbox;const snapStep=this.state.snapStepTextbox;const image=this.state.backgroundImage;const validationResult=this.validateGraphSettings(range,step,gridStep,snapStep,image);if(validationResult===true){this.change({valid:true,labels:labels,labelLocation:labelLocation,range:range,showAxisArrows:showAxisArrows,showAxisTicks:showAxisTicks,step:step,gridStep:gridStep,snapStep:snapStep,backgroundImage:image});}else {this.change({valid:validationResult});}};this.state={isExpanded:true,...InteractiveGraphSettings.stateFromProps(props)};}}InteractiveGraphSettings.defaultProps={box:[interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall],labels:["$x$","$y$"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],step:[1,1],gridStep:[1,1],snapStep:[1,1],valid:true,backgroundImage:defaultBackgroundImage,markings:"graph",showProtractor:false,showTooltips:false,showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},showAxisTicks:{x:true,y:true}};
1643
+ const{ButtonGroup: ButtonGroup$1,InfoTip: InfoTip$e,RangeInput: RangeInput$4}=components;const defaultBackgroundImage={url:null,width:0,height:0};function numSteps(range,step){return Math.floor((range[1]-range[0])/step)}class InteractiveGraphSettings extends React.Component{static stateFromProps(props){return {labelsTextbox:props.labels,labelLocation:props.labelLocation,gridStepTextbox:props.gridStep,snapStepTextbox:props.snapStep,stepTextbox:props.step,rangeTextbox:props.range,showAxisArrowsSwitches:props.showAxisArrows,showAxisTicksSwitches:props.showAxisTicks,backgroundImage:{...props.backgroundImage}}}componentDidMount(){this._isMounted=true;this.changeGraph=_.debounce(this.changeGraph,300);}UNSAFE_componentWillReceiveProps(nextProps){if(!_.isEqual(this.props.labels,nextProps.labels)||!_.isEqual(this.props.labelLocation,nextProps.labelLocation)||!_.isEqual(this.props.gridStep,nextProps.gridStep)||!_.isEqual(this.props.snapStep,nextProps.snapStep)||!_.isEqual(this.props.step,nextProps.step)||!_.isEqual(this.props.range,nextProps.range)||!_.isEqual(this.props.backgroundImage,nextProps.backgroundImage)){this.setState(InteractiveGraphSettings.stateFromProps(nextProps));}}componentWillUnmount(){this._isMounted=false;}render(){const editingDisabled=this.props.apiOptions?.editingDisabled??false;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Common Graph Settings",isOpen:this.state.isExpanded,isCollapsible:true,onToggle:()=>this.setState({isExpanded:!this.state.isExpanded})}),this.state.isExpanded&&jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsxs("div",{className:"graph-settings",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Label Location",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.labelLocation,allowEmpty:false,buttons:[{value:"onAxis",content:"On Axis"},{value:"alongEdge",content:"Along Graph Edge"}],onChange:this.change("labelLocation"),disabled:editingDisabled})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelXRef,onChange:e=>this.changeLabel(0,e),value:this.state.labelsTextbox[0]||""})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Label",children:jsxRuntimeExports.jsx("input",{type:"text",className:"graph-settings-axis-label",ref:this.labelYRef,onChange:e=>this.changeLabel(1,e),value:this.state.labelsTextbox[1]||""})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"x Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[0],onChange:vals=>this.changeRange(0,vals),allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"y Range",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.rangeTextbox[1],onChange:vals=>this.changeRange(1,vals),allowPiTruncation:true})})})]}),jsxRuntimeExports.jsx(AxisArrowSwitches,{showAxisArrows:this.state.showAxisArrowsSwitches,onChange:this.changeShowAxisArrows,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsx(AxisTickSwitches,{showAxisTicks:this.state.showAxisTicksSwitches,onChange:this.changeShowAxisTicks,disabled:this.props.apiOptions?.editingDisabled??false}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Tick Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.stepTextbox,onChange:this.changeStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Grid Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.gridStepTextbox,onChange:this.changeGridStep,allowPiTruncation:true})})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Snap Step",children:jsxRuntimeExports.jsx(RangeInput$4,{value:this.state.snapStepTextbox,onChange:this.changeSnapStep,allowPiTruncation:true})})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-right-col",children:[jsxRuntimeExports.jsx(Button,{size:"small",kind:"tertiary",onClick:()=>{this.changeStepsBasedOnRange();},disabled:editingDisabled,children:"Auto-adjust steps"}),jsxRuntimeExports.jsxs(InfoTip$e,{children:[jsxRuntimeExports.jsx("p",{children:'Use the "Auto-adjust" steps button to update the tick step, grid step, and snap step to values that are valid for the current range.'}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("p",{children:"This is useful when the range is changed, and the graph errors due to the step sizes being too large or too small."})]})]})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(LabeledRow,{label:"Markings",children:jsxRuntimeExports.jsx(ButtonGroup$1,{value:this.props.markings,allowEmpty:false,buttons:[{value:"axes",content:"Axes"},{value:"graph",content:"Graph"},{value:"grid",content:"Grid"},{value:"none",content:"None"}],onChange:this.change("markings"),disabled:editingDisabled})})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.change({showTooltips:value});},disabled:editingDisabled})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Background image URL",style:{marginTop:0},children:[jsxRuntimeExports.jsx("input",{type:"text",className:styles$A.backgroundUrlInput,ref:this.bgUrlRef,value:this.state.backgroundImage.url||"",onChange:e=>{const image={...this.props.backgroundImage};image.url=e.target.value;this.setState({backgroundImage:image});},onKeyPress:this.changeBackgroundUrl,onBlur:this.changeBackgroundUrl}),jsxRuntimeExports.jsx(InfoTip$e,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]}),jsxRuntimeExports.jsxs(View,{className:styles$A.protractorSection,children:[jsxRuntimeExports.jsx(View,{className:styles$A.checkboxRow,children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.change({showProtractor:value});},disabled:editingDisabled,style:{marginTop:0}})}),this.props.showProtractor&&jsxRuntimeExports.jsx(Banner,{text:"The protractor is not accessible. Please consider an alternate approach.",kind:"warning"})]})]})]})}constructor(props){super(props),this._isMounted=false,this.bgUrlRef=React.createRef(),this.labelXRef=React.createRef(),this.labelYRef=React.createRef(),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.changeBackgroundUrl=e=>{if(e.type==="keypress"&&e.key!=="Enter"){return}const setUrl=(url,width,height)=>{const image={...this.props.backgroundImage};image.url=url;image.width=width;image.height=height;this.setState({backgroundImage:image},this.changeGraph);};const url=this.bgUrlRef.current?.value;if(url){Util.getImageSize(url,(width,height)=>{if(this._isMounted){setUrl(url,width,height);}});}else {setUrl(null,0,0);}},this.renderLabelChoices=choices=>{return choices.map(nameAndValue=>jsxRuntimeExports.jsx("option",{value:nameAndValue[1],children:nameAndValue[0]},nameAndValue[1]))},this.validRange=range=>{const numbers=_.every(range,function(num){return _.isFinite(num)});if(!numbers){return "Range must be a valid number"}if(range[0]>=range[1]){return "Range must have a higher number on the right"}return true},this.validateStepValue=settings=>{const{step,range,name,minTicks,maxTicks}=settings;const nSteps=numSteps(range,step);if(nSteps<minTicks){return name+" is too large, there must be at least "+minTicks+" ticks."}if(nSteps>maxTicks){return name+" is too small, there can be at most "+maxTicks+" ticks."}return true},this.validSnapStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Snap step",minTicks:5,maxTicks:60})},this.validGridStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Grid step",minTicks:3,maxTicks:60})},this.validStep=(step,range)=>{return this.validateStepValue({step:step,range:range,name:"Step",minTicks:3,maxTicks:20})},this.validBackgroundImageSize=image=>{if(!image.url){return true}const validSize=image.width<=450&&image.height<=450;if(!validSize){return "Image must be smaller than 450px x 450px."}return true},this.validateGraphSettings=(range,step,gridStep,snapStep,image)=>{const self=this;let msg;const goodRange=_.every(range,function(range){msg=self.validRange(range);return msg===true});if(!goodRange){return msg}const goodStep=_.every(step,function(step,i){msg=self.validStep(step,range[i]);return msg===true});if(!goodStep){return msg}const goodGridStep=_.every(gridStep,function(gridStep,i){msg=self.validGridStep(gridStep,range[i]);return msg===true});if(!goodGridStep){return msg}const goodSnapStep=_.every(snapStep,function(snapStep,i){msg=self.validSnapStep(snapStep,range[i]);return msg===true});if(!goodSnapStep){return msg}const goodImageSize=this.validBackgroundImageSize(image);if(goodImageSize!==true){msg=goodImageSize;return msg}return true},this.changeLabel=(i,e)=>{const val=e.target.value;const labels=this.state.labelsTextbox.slice();labels[i]=val;this.setState({labelsTextbox:labels},this.changeGraph);},this.changeRange=(i,values)=>{const ranges=this.state.rangeTextbox.slice();ranges[i]=values;this.setState({rangeTextbox:ranges},this.changeGraph);},this.changeShowAxisArrows=axis=>{const newShowAxisArrows={...this.state.showAxisArrowsSwitches};newShowAxisArrows[axis]=!newShowAxisArrows[axis];this.setState({showAxisArrowsSwitches:newShowAxisArrows},this.changeGraph);},this.changeShowAxisTicks=axis=>{const newShowAxisTicks={...this.state.showAxisTicksSwitches};newShowAxisTicks[axis]=!newShowAxisTicks[axis];this.setState({showAxisTicksSwitches:newShowAxisTicks},this.changeGraph);},this.changeStepsBasedOnRange=()=>{const ranges=this.state.rangeTextbox.slice();const step=this.state.stepTextbox.slice();const gridStep=this.state.gridStepTextbox.slice();const snapStep=this.state.snapStepTextbox.slice();const scaleX=Util.scaleFromExtent(ranges[0],this.props.box[0]);if(this.validRange(ranges[0])===true){step[0]=Util.tickStepFromExtent(ranges[0],this.props.box[0]);const gridStepValue=Util.gridStepFromTickStep(step[0],scaleX);if(gridStepValue){gridStep[0]=gridStepValue;}snapStep[0]=gridStep[0]/2;}const scaleY=Util.scaleFromExtent(ranges[1],this.props.box[1]);if(this.validRange(ranges[1])===true){step[1]=Util.tickStepFromExtent(ranges[1],this.props.box[1]);const gridStepValue=Util.gridStepFromTickStep(step[1],scaleY);if(gridStepValue){gridStep[1]=gridStepValue;}snapStep[1]=gridStep[1]/2;}this.setState({stepTextbox:step,gridStepTextbox:gridStep,snapStepTextbox:snapStep,rangeTextbox:ranges},this.changeGraph);},this.changeStep=step=>{this.setState({stepTextbox:step},this.changeGraph);},this.changeSnapStep=snapStep=>{this.setState({snapStepTextbox:snapStep},this.changeGraph);},this.changeGridStep=gridStep=>{this.setState({gridStepTextbox:gridStep,snapStepTextbox:_.map(gridStep,function(step){return step/2})},this.changeGraph);},this.changeGraph=()=>{const labels=this.state.labelsTextbox;const labelLocation=this.state.labelLocation;const range=this.state.rangeTextbox.map(range=>range.map(value=>Number(value)));const showAxisArrows=this.state.showAxisArrowsSwitches;const showAxisTicks=this.state.showAxisTicksSwitches;const step=this.state.stepTextbox.map(value=>Number(value));const gridStep=this.state.gridStepTextbox;const snapStep=this.state.snapStepTextbox;const image=this.state.backgroundImage;const validationResult=this.validateGraphSettings(range,step,gridStep,snapStep,image);if(validationResult===true){this.change({valid:true,labels:labels,labelLocation:labelLocation,range:range,showAxisArrows:showAxisArrows,showAxisTicks:showAxisTicks,step:step,gridStep:gridStep,snapStep:snapStep,backgroundImage:image});}else {this.change({valid:validationResult});}};this.state={isExpanded:true,...InteractiveGraphSettings.stateFromProps(props)};}}InteractiveGraphSettings.defaultProps={box:[interactiveSizes.defaultBoxSizeSmall,interactiveSizes.defaultBoxSizeSmall],labels:["$x$","$y$"],labelLocation:"onAxis",range:[[-10,10],[-10,10]],step:[1,1],gridStep:[1,1],snapStep:[1,1],valid:true,backgroundImage:defaultBackgroundImage,markings:"graph",showProtractor:false,showTooltips:false,showAxisArrows:{xMin:true,xMax:true,yMin:true,yMax:true},showAxisTicks:{x:true,y:true}};
1637
1644
 
1638
- var styles$B = {"treeList":"perseus_dM32KBSs","indentList":"perseus_0LO0xYxg","switchRow":"perseus_T8Wphznm"};
1645
+ var styles$z = {"treeList":"perseus_dM32KBSs","indentList":"perseus_0LO0xYxg","switchRow":"perseus_T8Wphznm"};
1639
1646
 
1640
- const{InfoTip: InfoTip$e}=components;const badgeSpacingStyle={marginInlineEnd:sizing.size_060};const badgeLabelStyle={fontWeight:font.weight.regular};function getAccessibilityAttributes(graphId){const elementArias=[];const container=document.getElementById(graphId);if(!container){return elementArias}container.querySelectorAll("*").forEach(element=>{const elementAttributes=[];const ariaLabel=element.getAttribute("aria-label");const ariaDescribedby=element.getAttribute("aria-describedby");if(ariaLabel){elementAttributes.unshift({name:"label",value:ariaLabel});}if(ariaDescribedby){const descriptions=ariaDescribedby.split(/ +/);for(const description of descriptions){const descriptionString=document.getElementById(description)?.textContent;if(descriptionString){elementAttributes.push({name:"description",value:descriptionString});}}}if(elementAttributes.length>0){elementArias.push({roleOrTag:element.getAttribute("role")||element.tagName.toLowerCase(),className:element.classList[element.classList.length-1]||"",attributes:elementAttributes});}});return elementArias}function SRTree(props){const{elementArias,showTags}=props;return jsxRuntimeExports.jsx("ol",{className:styles$B.treeList,children:elementArias.map((aria,index)=>jsxRuntimeExports.jsxs("li",{children:[showTags&&jsxRuntimeExports.jsx(StatusBadge,{kind:"success",label:aria.roleOrTag,showBorder:false,styles:{root:badgeSpacingStyle,label:badgeLabelStyle}}),aria.className,jsxRuntimeExports.jsx("ul",{className:styles$B.indentList,children:aria.attributes.map((value,index)=>jsxRuntimeExports.jsxs("li",{children:[value.name==="label"?jsxRuntimeExports.jsx(StatusBadge,{kind:"info",label:value.name,showBorder:false,styles:{root:badgeSpacingStyle,label:badgeLabelStyle}}):jsxRuntimeExports.jsx(NeutralBadge,{label:value.name,showBorder:false,styles:{root:badgeSpacingStyle,label:badgeLabelStyle}}),value.value]},index))})]},index))})}function InteractiveGraphSRTree({graphId,correct,fullGraphAriaLabel,fullGraphAriaDescription,lockedFigures,editingDisabled=false}){const[isExpanded,setIsExpanded]=React.useState(true);const[showTags,setShowTags]=React.useState(false);const[elementArias,setElementArias]=React.useState([]);const switchId=React.useId();React.useEffect(()=>{setElementArias(getAccessibilityAttributes(graphId));},[correct,fullGraphAriaLabel,fullGraphAriaDescription,graphId,lockedFigures]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Screen reader tree",isOpen:isExpanded,onToggle:setIsExpanded,isCollapsible:true}),isExpanded&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$B.switchRow,children:[jsxRuntimeExports.jsx(Switch,{id:switchId,checked:showTags,onChange:setShowTags,disabled:editingDisabled}),jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"label",htmlFor:switchId,children:"Show HTML roles/tags"}),jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsx(InfoTip$e,{children:'This screen reader tree shows the ARIA labels and descriptions for elements within the "correct answer" Interactive Graph widget displayed above.'})]}),jsxRuntimeExports.jsx(SRTree,{elementArias:elementArias,showTags:showTags})]})]})}
1647
+ const{InfoTip: InfoTip$d}=components;const badgeSpacingStyle={marginInlineEnd:sizing.size_060};const badgeLabelStyle={fontWeight:font.weight.regular};function getAccessibilityAttributes(graphId){const elementArias=[];const container=document.getElementById(graphId);if(!container){return elementArias}container.querySelectorAll("*").forEach(element=>{const elementAttributes=[];const ariaLabel=element.getAttribute("aria-label");const ariaDescribedby=element.getAttribute("aria-describedby");if(ariaLabel){elementAttributes.unshift({name:"label",value:ariaLabel});}if(ariaDescribedby){const descriptions=ariaDescribedby.split(/ +/);for(const description of descriptions){const descriptionString=document.getElementById(description)?.textContent;if(descriptionString){elementAttributes.push({name:"description",value:descriptionString});}}}if(elementAttributes.length>0){elementArias.push({roleOrTag:element.getAttribute("role")||element.tagName.toLowerCase(),className:element.classList[element.classList.length-1]||"",attributes:elementAttributes});}});return elementArias}function SRTree(props){const{elementArias,showTags}=props;return jsxRuntimeExports.jsx("ol",{className:styles$z.treeList,children:elementArias.map((aria,index)=>jsxRuntimeExports.jsxs("li",{children:[showTags&&jsxRuntimeExports.jsx(StatusBadge,{kind:"success",label:aria.roleOrTag,showBorder:false,styles:{root:badgeSpacingStyle,label:badgeLabelStyle}}),aria.className,jsxRuntimeExports.jsx("ul",{className:styles$z.indentList,children:aria.attributes.map((value,index)=>jsxRuntimeExports.jsxs("li",{children:[value.name==="label"?jsxRuntimeExports.jsx(StatusBadge,{kind:"info",label:value.name,showBorder:false,styles:{root:badgeSpacingStyle,label:badgeLabelStyle}}):jsxRuntimeExports.jsx(NeutralBadge,{label:value.name,showBorder:false,styles:{root:badgeSpacingStyle,label:badgeLabelStyle}}),value.value]},index))})]},index))})}function InteractiveGraphSRTree({graphId,correct,fullGraphAriaLabel,fullGraphAriaDescription,lockedFigures,editingDisabled=false}){const[isExpanded,setIsExpanded]=React.useState(true);const[showTags,setShowTags]=React.useState(false);const[elementArias,setElementArias]=React.useState([]);const switchId=React.useId();React.useEffect(()=>{setElementArias(getAccessibilityAttributes(graphId));},[correct,fullGraphAriaLabel,fullGraphAriaDescription,graphId,lockedFigures]);return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Screen reader tree",isOpen:isExpanded,onToggle:setIsExpanded,isCollapsible:true}),isExpanded&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$z.switchRow,children:[jsxRuntimeExports.jsx(Switch,{id:switchId,checked:showTags,onChange:setShowTags,disabled:editingDisabled}),jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"label",htmlFor:switchId,children:"Show HTML roles/tags"}),jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsx(InfoTip$d,{children:'This screen reader tree shows the ARIA labels and descriptions for elements within the "correct answer" Interactive Graph widget displayed above.'})]}),jsxRuntimeExports.jsx(SRTree,{elementArias:elementArias,showTags:showTags})]})]})}
1641
1648
 
1642
- const{InfoTip: InfoTip$d}=components;const POLYGON_SIDES=_.map(_.range(3,13),function(value){return jsxRuntimeExports.jsx(OptionItem,{value:`${value}`,label:`${value} sides`},`polygon-sides-${value}`)});function PolygonAnswerOptions({correct,graph,onChange}){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(LabeledRow,{label:"Number of sides:",children:jsxRuntimeExports.jsx(SingleSelect,{selectedValue:correct?.numSides?`${correct.numSides}`:"3",placeholder:"",onChange:newValue=>{invariant(graph?.type==="polygon");const updates={numSides:parsePointCount(newValue),coords:undefined,startCoords:undefined,snapTo:"grid"};onChange({correct:{...correct,...updates},graph:{...graph,...updates}});},className:styles$G.singleSelectShort,children:[...POLYGON_SIDES,jsxRuntimeExports.jsx(OptionItem,{value:"unlimited",label:"unlimited sides"},"unlimited")]},"polygon-select")}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Snap to:",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct?.snapTo||"grid",placeholder:"",onChange:newValue=>{invariant(correct.type==="polygon",`Expected correct answer type to be polygon, but got ${correct.type}`);invariant(graph?.type==="polygon",`Expected graph type to be polygon, but got ${graph?.type}`);const updates={snapTo:newValue,coords:null};onChange({correct:{...correct,...updates},graph:{...graph,...updates}});},className:styles$G.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"grid",label:"grid"}),correct?.numSides!=="unlimited"&&jsxRuntimeExports.jsx(OptionItem,{value:"angles",label:"interior angles"}),correct?.numSides!=="unlimited"&&jsxRuntimeExports.jsx(OptionItem,{value:"sides",label:"side measures"})]}),jsxRuntimeExports.jsxs(InfoTip$d,{children:[jsxRuntimeExports.jsx("p",{children:"These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."}),jsxRuntimeExports.jsx("p",{children:"The interior angle and side measure options guide the points to the nearest whole angle or side measure respectively."})]})]}),jsxRuntimeExports.jsxs(View,{className:styles$G.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Show angle measures"}),checked:!!correct?.showAngles,onChange:()=>{if(graph?.type==="polygon"){invariant(correct.type==="polygon",`Expected graph type to be polygon, but got ${correct.type}`);onChange({correct:{...correct,showAngles:!correct.showAngles},graph:{...graph,showAngles:!graph.showAngles}});}}}),jsxRuntimeExports.jsx(InfoTip$d,{children:jsxRuntimeExports.jsx("p",{children:"Displays the interior angle measures."})})]}),jsxRuntimeExports.jsxs(View,{className:styles$G.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Show side measures"}),checked:!!correct?.showSides,onChange:()=>{if(graph?.type==="polygon"&&correct.type==="polygon"){onChange({correct:{...correct,showSides:!correct.showSides},graph:{...graph,showSides:!graph.showSides}});}}}),jsxRuntimeExports.jsx(InfoTip$d,{children:jsxRuntimeExports.jsx("p",{children:"Displays the side lengths."})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Student answer must",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct.match||"exact",onChange:newValue=>{invariant(correct.type==="polygon",`Expected graph type to be polygon, but got ${correct.type}`);const updatedCorrect={...correct,match:newValue};onChange({correct:updatedCorrect});},placeholder:"",className:styles$G.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"exact",label:"match exactly"}),jsxRuntimeExports.jsx(OptionItem,{value:"congruent",label:"be congruent"}),jsxRuntimeExports.jsx(OptionItem,{value:"approx",label:"be approximately congruent"}),jsxRuntimeExports.jsx(OptionItem,{value:"similar",label:"be similar"})]}),jsxRuntimeExports.jsx(InfoTip$d,{children:jsxRuntimeExports.jsxs("ul",{children:[jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Match Exactly:"})," Match exactly in size, orientation, and location on the grid even if it is not shown in the background."]})}),jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Be Congruent:"})," Be congruent in size and shape, but can be located anywhere on the grid."]})}),jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Be Approximately Congruent:"})," Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid."," ",jsxRuntimeExports.jsx("em",{children:"Use this with snapping to angle measure."})]})}),jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Be Similar:"})," Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."]})})]})})]})]})}
1649
+ const{InfoTip: InfoTip$c}=components;const POLYGON_SIDES=_.map(_.range(3,13),function(value){return jsxRuntimeExports.jsx(OptionItem,{value:`${value}`,label:`${value} sides`},`polygon-sides-${value}`)});function PolygonAnswerOptions({correct,graph,onChange}){return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(LabeledRow,{label:"Number of sides:",children:jsxRuntimeExports.jsx(SingleSelect,{selectedValue:correct?.numSides?`${correct.numSides}`:"3",placeholder:"",onChange:newValue=>{invariant(graph?.type==="polygon");const updates={numSides:parsePointCount(newValue),coords:undefined,startCoords:undefined,snapTo:"grid"};onChange({correct:{...correct,...updates},graph:{...graph,...updates}});},className:styles$D.singleSelectShort,children:[...POLYGON_SIDES,jsxRuntimeExports.jsx(OptionItem,{value:"unlimited",label:"unlimited sides"},"unlimited")]},"polygon-select")}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Snap to:",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct?.snapTo||"grid",placeholder:"",onChange:newValue=>{invariant(correct.type==="polygon",`Expected correct answer type to be polygon, but got ${correct.type}`);invariant(graph?.type==="polygon",`Expected graph type to be polygon, but got ${graph?.type}`);const updates={snapTo:newValue,coords:null};onChange({correct:{...correct,...updates},graph:{...graph,...updates}});},className:styles$D.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"grid",label:"grid"}),correct?.numSides!=="unlimited"&&jsxRuntimeExports.jsx(OptionItem,{value:"angles",label:"interior angles"}),correct?.numSides!=="unlimited"&&jsxRuntimeExports.jsx(OptionItem,{value:"sides",label:"side measures"})]}),jsxRuntimeExports.jsxs(InfoTip$c,{children:[jsxRuntimeExports.jsx("p",{children:"These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."}),jsxRuntimeExports.jsx("p",{children:"The interior angle and side measure options guide the points to the nearest whole angle or side measure respectively."})]})]}),jsxRuntimeExports.jsxs(View,{className:styles$D.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Show angle measures"}),checked:!!correct?.showAngles,onChange:()=>{if(graph?.type==="polygon"){invariant(correct.type==="polygon",`Expected graph type to be polygon, but got ${correct.type}`);onChange({correct:{...correct,showAngles:!correct.showAngles},graph:{...graph,showAngles:!graph.showAngles}});}}}),jsxRuntimeExports.jsx(InfoTip$c,{children:jsxRuntimeExports.jsx("p",{children:"Displays the interior angle measures."})})]}),jsxRuntimeExports.jsxs(View,{className:styles$D.row,children:[jsxRuntimeExports.jsx(Checkbox$1,{label:jsxRuntimeExports.jsx(BodyText,{size:"small",tag:"span",children:"Show side measures"}),checked:!!correct?.showSides,onChange:()=>{if(graph?.type==="polygon"&&correct.type==="polygon"){onChange({correct:{...correct,showSides:!correct.showSides},graph:{...graph,showSides:!graph.showSides}});}}}),jsxRuntimeExports.jsx(InfoTip$c,{children:jsxRuntimeExports.jsx("p",{children:"Displays the side lengths."})})]}),jsxRuntimeExports.jsxs(LabeledRow,{label:"Student answer must",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct.match||"exact",onChange:newValue=>{invariant(correct.type==="polygon",`Expected graph type to be polygon, but got ${correct.type}`);const updatedCorrect={...correct,match:newValue};onChange({correct:updatedCorrect});},placeholder:"",className:styles$D.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"exact",label:"match exactly"}),jsxRuntimeExports.jsx(OptionItem,{value:"congruent",label:"be congruent"}),jsxRuntimeExports.jsx(OptionItem,{value:"approx",label:"be approximately congruent"}),jsxRuntimeExports.jsx(OptionItem,{value:"similar",label:"be similar"})]}),jsxRuntimeExports.jsx(InfoTip$c,{children:jsxRuntimeExports.jsxs("ul",{children:[jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Match Exactly:"})," Match exactly in size, orientation, and location on the grid even if it is not shown in the background."]})}),jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Be Congruent:"})," Be congruent in size and shape, but can be located anywhere on the grid."]})}),jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Be Approximately Congruent:"})," Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid."," ",jsxRuntimeExports.jsx("em",{children:"Use this with snapping to angle measure."})]})}),jsxRuntimeExports.jsx("li",{children:jsxRuntimeExports.jsxs("p",{children:[jsxRuntimeExports.jsx("b",{children:"Be Similar:"})," Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."]})})]})})]})]})}
1643
1650
 
1644
- const SegmentCountSelector=({correct,graph,onChange})=>jsxRuntimeExports.jsx(LabeledRow,{label:"Number of segments:",children:jsxRuntimeExports.jsx(SingleSelect,{selectedValue:`${correct.numSegments??1}`,placeholder:"",onChange:newValue=>{const sides=+newValue;onChange({correct:{type:"segment",numSegments:sides,coords:null},graph:{type:"segment",numSegments:sides}});},className:styles$G.singleSelectShort,children:_.range(1,7).map(n=>jsxRuntimeExports.jsx(OptionItem,{value:`${n}`,label:`${n} segment${n>1?"s":""}`},n))},"segment-select")});
1651
+ const SegmentCountSelector=({correct,graph,onChange})=>jsxRuntimeExports.jsx(LabeledRow,{label:"Number of segments:",children:jsxRuntimeExports.jsx(SingleSelect,{selectedValue:`${correct.numSegments??1}`,placeholder:"",onChange:newValue=>{const sides=+newValue;onChange({correct:{type:"segment",numSegments:sides,coords:null},graph:{type:"segment",numSegments:sides}});},className:styles$D.singleSelectShort,children:_.range(1,7).map(n=>jsxRuntimeExports.jsx(OptionItem,{value:`${n}`,label:`${n} segment${n>1?"s":""}`},n))},"segment-select")});
1645
1652
 
1646
- var styles$A = {"switchRow":"perseus_FCU7fslB"};
1653
+ var styles$y = {"switchRow":"perseus_FCU7fslB"};
1647
1654
 
1648
- const{InfoTip: InfoTip$c}=components;function ShowPointLabelsToggle({showPointLabels,pointLabels,onChange}){const labelsPopulated=pointLabels!==undefined&&pointLabels.length>0&&pointLabels.every(label=>label!=="");return jsxRuntimeExports.jsxs(View,{className:styles$A.switchRow,children:[jsxRuntimeExports.jsx(LabeledSwitch,{label:"Show point labels",checked:labelsPopulated&&showPointLabels,disabled:!labelsPopulated,onChange:onChange}),jsxRuntimeExports.jsx(InfoTip$c,{children:"When on, each movable point displays a visible label next to it. Add a name to every point below to enable this option."})]})}
1655
+ const{InfoTip: InfoTip$b}=components;function ShowPointLabelsToggle({showPointLabels,pointLabels,onChange}){const hasAtLeastOneLabel=pointLabels!==undefined&&pointLabels.some(label=>label!=="");return jsxRuntimeExports.jsxs(View,{className:styles$y.switchRow,children:[jsxRuntimeExports.jsx(LabeledSwitch,{label:"Show point labels",checked:hasAtLeastOneLabel&&showPointLabels,disabled:!hasAtLeastOneLabel,onChange:onChange}),jsxRuntimeExports.jsx(InfoTip$b,{children:"When on, each labeled point displays a visible label next to it. Add a name to at least one point below to enable this option."})]})}
1649
1656
 
1650
- const{InfoTip: InfoTip$b}=components;function VectorAnswerOptions({correct,onChange}){return jsxRuntimeExports.jsxs(LabeledRow,{label:"Student answer must",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct.match||"exact",onChange:newValue=>{invariant(correct.type==="vector",`Expected graph type to be vector, but got ${correct.type}`);onChange({correct:{...correct,match:newValue}});},placeholder:"",className:styles$G.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"exact",label:"match exactly"}),jsxRuntimeExports.jsx(OptionItem,{value:"congruent",label:"be congruent"})]}),jsxRuntimeExports.jsx(InfoTip$b,{children:jsxRuntimeExports.jsx("p",{children:"Congruency requires only that the vector has the same direction and magnitude. An exact match implies congruency, but also requires that the tail and tip are in the same position on the grid."})})]})}
1657
+ const{InfoTip: InfoTip$a}=components;function VectorAnswerOptions({correct,onChange}){return jsxRuntimeExports.jsxs(LabeledRow,{label:"Student answer must",children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:correct.match||"exact",onChange:newValue=>{invariant(correct.type==="vector",`Expected graph type to be vector, but got ${correct.type}`);onChange({correct:{...correct,match:newValue}});},placeholder:"",className:styles$D.singleSelectShort,children:[jsxRuntimeExports.jsx(OptionItem,{value:"exact",label:"match exactly"}),jsxRuntimeExports.jsx(OptionItem,{value:"congruent",label:"be congruent"})]}),jsxRuntimeExports.jsx(InfoTip$a,{children:jsxRuntimeExports.jsx("p",{children:"Congruency requires only that the vector has the same direction and magnitude. An exact match implies congruency, but also requires that the tail and tip are in the same position on the grid."})})]})}
1651
1658
 
1652
- var styles$z = {"container":"perseus_UMms5ska","addElementSelect":"perseus_Dz9XA5LM"};
1659
+ var styles$x = {"container":"perseus_UMms5ska","addElementSelect":"perseus_Dz9XA5LM"};
1653
1660
 
1654
- const LockedFigureSelect=props=>{const{id,editingDisabled,onChange}=props;const figureTypes=["point","line","vector","ellipse","polygon","function","label"];return jsxRuntimeExports.jsx(View,{className:styles$z.container,children:jsxRuntimeExports.jsx(ActionMenu,{menuText:"Add locked figure",disabled:editingDisabled,className:styles$z.addElementSelect,children:figureTypes.map(figureType=>jsxRuntimeExports.jsx(ActionItem,{label:figureType,onClick:()=>onChange(figureType)},`${id}-${figureType}`))})})};
1661
+ const LockedFigureSelect=props=>{const{id,editingDisabled,onChange}=props;const figureTypes=["point","line","vector","ellipse","polygon","function","label"];return jsxRuntimeExports.jsx(View,{className:styles$x.container,children:jsxRuntimeExports.jsx(ActionMenu,{menuText:"Add locked figure",disabled:editingDisabled,className:styles$x.addElementSelect,children:figureTypes.map(figureType=>jsxRuntimeExports.jsx(ActionItem,{label:figureType,onClick:()=>onChange(figureType)},`${id}-${figureType}`))})})};
1655
1662
 
1656
- const{convertDegreesToRadians,convertRadiansToDegrees: convertRadiansToDegrees$1}=angles;const AngleInput=props=>{const{angle,onChange}=props;const[angleInput,setAngleInput]=React.useState(convertRadiansToDegrees$1(angle).toString());function handleAngleChange(newValue){setAngleInput(newValue);if(isNaN(+newValue)||newValue===""){return}onChange(convertDegreesToRadians(newValue));}return jsxRuntimeExports.jsxs(BodyText,{tag:"label",style:styles$y.row,children:["angle (degrees)",jsxRuntimeExports.jsx(Strut,{size:spacing.xxSmall_6}),jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:angleInput,onChange:handleAngleChange,style:styles$y.textField}),jsxRuntimeExports.jsx(Strut,{size:spacing.xxSmall_6})]})};const styles$y=StyleSheet.create({row:{display:"flex",flexDirection:"row",alignItems:"center"},textField:{width:spacing.xxxLarge_64}});
1663
+ const{convertDegreesToRadians,convertRadiansToDegrees: convertRadiansToDegrees$1}=angles;const AngleInput=props=>{const{angle,onChange}=props;const[angleInput,setAngleInput]=React.useState(convertRadiansToDegrees$1(angle).toString());function handleAngleChange(newValue){setAngleInput(newValue);if(isNaN(+newValue)||newValue===""){return}onChange(convertDegreesToRadians(newValue));}return jsxRuntimeExports.jsxs(BodyText,{tag:"label",style:styles$w.row,children:["angle (degrees)",jsxRuntimeExports.jsx(Strut,{size:spacing.xxSmall_6}),jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:angleInput,onChange:handleAngleChange,style:styles$w.textField}),jsxRuntimeExports.jsx(Strut,{size:spacing.xxSmall_6})]})};const styles$w=StyleSheet.create({row:{display:"flex",flexDirection:"row",alignItems:"center"},textField:{width:spacing.xxxLarge_64}});
1657
1664
 
1658
- var styles$x = {"container":"perseus_6kPoH3-I","label":"perseus_qYirPY7G"};
1665
+ var styles$v = {"container":"perseus_6kPoH3-I","label":"perseus_qYirPY7G"};
1659
1666
 
1660
- const textFieldStyle={width:sizing.size_640};const errorFieldStyle={borderColor:semanticColor.core.border.critical.default,backgroundColor:semanticColor.core.background.critical.subtle};const CoordinatePairInput=props=>{const{coord,labels,error,style,labelStyle,disabled=false,onChange}=props;const xLabel=labels?labels[0]:"x coord";const yLabel=labels?labels[1]:"y coord";const[coordState,setCoordState]=React.useState([coord[0].toString(),coord[1].toString()]);React.useEffect(()=>{setCoordState([coord[0].toString(),coord[1].toString()]);},[coord]);function handleCoordChange(newValue,coordIndex){const newCoordState=[...coordState];newCoordState[coordIndex]=newValue;setCoordState(newCoordState);if(isNaN(+newValue)||newValue===""){return}const newCoords=[...coord];newCoords[coordIndex]=+newValue;onChange(newCoords);}return jsxRuntimeExports.jsxs(View,{className:styles$x.container,style:style,children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$x.label,children:[labelStyle!=null?jsxRuntimeExports.jsx(View,{style:labelStyle,children:xLabel}):xLabel,jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:coordState[0],disabled:disabled,onChange:newValue=>handleCoordChange(newValue,0),style:[textFieldStyle,error?errorFieldStyle:undefined]})]}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$x.label,children:[labelStyle!=null?jsxRuntimeExports.jsx(View,{style:labelStyle,children:yLabel}):yLabel,jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:coordState[1],disabled:disabled,onChange:newValue=>handleCoordChange(newValue,1),style:[textFieldStyle,error?errorFieldStyle:undefined]})]})]})};
1667
+ const textFieldStyle={width:sizing.size_640};const errorFieldStyle={borderColor:semanticColor.core.border.critical.default,backgroundColor:semanticColor.core.background.critical.subtle};const CoordinatePairInput=props=>{const{coord,labels,error,style,labelStyle,disabled=false,onChange}=props;const xLabel=labels?labels[0]:"x coord";const yLabel=labels?labels[1]:"y coord";const[coordState,setCoordState]=React.useState([coord[0].toString(),coord[1].toString()]);React.useEffect(()=>{setCoordState([coord[0].toString(),coord[1].toString()]);},[coord]);function handleCoordChange(newValue,coordIndex){const newCoordState=[...coordState];newCoordState[coordIndex]=newValue;setCoordState(newCoordState);if(isNaN(+newValue)||newValue===""){return}const newCoords=[...coord];newCoords[coordIndex]=+newValue;onChange(newCoords);}return jsxRuntimeExports.jsxs(View,{className:styles$v.container,style:style,children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$v.label,children:[labelStyle!=null?jsxRuntimeExports.jsx(View,{style:labelStyle,children:xLabel}):xLabel,jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:coordState[0],disabled:disabled,onChange:newValue=>handleCoordChange(newValue,0),style:[textFieldStyle,error?errorFieldStyle:undefined]})]}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$v.label,children:[labelStyle!=null?jsxRuntimeExports.jsx(View,{style:labelStyle,children:yLabel}):yLabel,jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:coordState[1],disabled:disabled,onChange:newValue=>handleCoordChange(newValue,1),style:[textFieldStyle,error?errorFieldStyle:undefined]})]})]})};
1661
1668
 
1662
- var styles$w = {"row":"perseus_v9IBfM--"};
1669
+ var styles$u = {"row":"perseus_v9IBfM--"};
1663
1670
 
1664
- const ColorSwatch=props=>{const{color,filled=true,decorative=false}=props;return jsxRuntimeExports.jsx(View,{"aria-label":!decorative?`${color}, ${filled?"filled":"open"}`:undefined,style:[styles$v.colorSwatch,{border:`4px solid ${lockedFigureColors[color]}`,backgroundColor:filled?lockedFigureColors[color]:semanticColor.core.background.base.default}]})};const styles$v=StyleSheet.create({colorSwatch:{outline:`2px solid ${semanticColor.focus.inner}`,borderRadius:"50%",width:spacing.large_24,height:spacing.large_24}});
1671
+ const ColorSwatch=props=>{const{color,filled=true,decorative=false}=props;return jsxRuntimeExports.jsx(View,{"aria-label":!decorative?`${color}, ${filled?"filled":"open"}`:undefined,style:[styles$t.colorSwatch,{border:`4px solid ${lockedFigureColors[color]}`,backgroundColor:filled?lockedFigureColors[color]:semanticColor.core.background.base.default}]})};const styles$t=StyleSheet.create({colorSwatch:{outline:`2px solid ${semanticColor.focus.inner}`,borderRadius:"50%",width:spacing.large_24,height:spacing.large_24}});
1665
1672
 
1666
- const ColorSelect=props=>{const{selectedValue,style,editingDisabled=false,onChange}=props;return jsxRuntimeExports.jsx(View,{className:styles$w.row,style:style,children:jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$w.row,children:["color",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:selectedValue,disabled:editingDisabled,onChange:onChange,placeholder:"",children:lockedFigureColorNames.map(colorName=>jsxRuntimeExports.jsx(OptionItem,{value:colorName,label:colorName,leftAccessory:jsxRuntimeExports.jsx(ColorSwatch,{color:colorName,decorative:true})},colorName))})]})})};
1673
+ const ColorSelect=props=>{const{selectedValue,style,editingDisabled=false,onChange}=props;return jsxRuntimeExports.jsx(View,{className:styles$u.row,style:style,children:jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$u.row,children:["color",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:selectedValue,disabled:editingDisabled,onChange:onChange,placeholder:"",children:lockedFigureColorNames.map(colorName=>jsxRuntimeExports.jsx(OptionItem,{value:colorName,label:colorName,leftAccessory:jsxRuntimeExports.jsx(ColorSwatch,{color:colorName,decorative:true})},colorName))})]})})};
1667
1674
 
1668
- const EllipseSwatch=props=>{const{color,fillStyle,strokeStyle}=props;return jsxRuntimeExports.jsx(View,{"aria-label":`${color}, stroke ${strokeStyle}, fill ${fillStyle}`,style:[styles$u.container,{border:`4px ${strokeStyle} ${lockedFigureColors[color]}`}],children:jsxRuntimeExports.jsx(View,{style:[styles$u.innerCircle,{backgroundColor:lockedFigureColors[color],opacity:fillStyle==="white"?0:lockedFigureFillStyles[fillStyle]}]})})};const styles$u=StyleSheet.create({container:{outline:`2px solid ${semanticColor.focus.inner}`,borderRadius:"50%",width:spacing.xLarge_32,height:spacing.large_24,backgroundColor:semanticColor.core.background.base.default,alignItems:"center",justifyContent:"center"},innerCircle:{width:28,height:20,borderRadius:"50%"}});
1675
+ const EllipseSwatch=props=>{const{color,fillStyle,strokeStyle}=props;return jsxRuntimeExports.jsx(View,{"aria-label":`${color}, stroke ${strokeStyle}, fill ${fillStyle}`,style:[styles$s.container,{border:`4px ${strokeStyle} ${lockedFigureColors[color]}`}],children:jsxRuntimeExports.jsx(View,{style:[styles$s.innerCircle,{backgroundColor:lockedFigureColors[color],opacity:fillStyle==="white"?0:lockedFigureFillStyles[fillStyle]}]})})};const styles$s=StyleSheet.create({container:{outline:`2px solid ${semanticColor.focus.inner}`,borderRadius:"50%",width:spacing.xLarge_32,height:spacing.large_24,backgroundColor:semanticColor.core.background.base.default,alignItems:"center",justifyContent:"center"},innerCircle:{width:28,height:20,borderRadius:"50%"}});
1669
1676
 
1670
- var styles$t = {"lineStrokeSelect":"perseus_L42pujHE"};
1677
+ var styles$r = {"lineStrokeSelect":"perseus_L42pujHE"};
1671
1678
 
1672
- const LineStrokeSelect=props=>{const{selectedValue,containerStyle,editingDisabled=false,onChange}=props;return jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$t.lineStrokeSelect,style:containerStyle,children:["stroke",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:selectedValue,disabled:editingDisabled,onChange:onChange,placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"solid",label:"solid"}),jsxRuntimeExports.jsx(OptionItem,{value:"dashed",label:"dashed"})]})]})};
1679
+ const LineStrokeSelect=props=>{const{selectedValue,containerStyle,editingDisabled=false,onChange}=props;return jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$r.lineStrokeSelect,style:containerStyle,children:["stroke",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:selectedValue,disabled:editingDisabled,onChange:onChange,placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"solid",label:"solid"}),jsxRuntimeExports.jsx(OptionItem,{value:"dashed",label:"dashed"})]})]})};
1673
1680
 
1674
- var styles$s = {"lineWeightSelect":"perseus_NDL3xmfp"};
1681
+ var styles$q = {"lineWeightSelect":"perseus_NDL3xmfp"};
1675
1682
 
1676
- const LineWeightSelect=props=>{const{selectedValue,containerStyle,editingDisabled=false,onChange}=props;return jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$s.lineWeightSelect,style:containerStyle,children:["weight",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:selectedValue,disabled:editingDisabled,onChange:value=>onChange(value),placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"thin",label:"thin"}),jsxRuntimeExports.jsx(OptionItem,{value:"medium",label:"medium"}),jsxRuntimeExports.jsx(OptionItem,{value:"thick",label:"thick"})]})]})};
1683
+ const LineWeightSelect=props=>{const{selectedValue,containerStyle,editingDisabled=false,onChange}=props;return jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$q.lineWeightSelect,style:containerStyle,children:["weight",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:selectedValue,disabled:editingDisabled,onChange:value=>onChange(value),placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"thin",label:"thin"}),jsxRuntimeExports.jsx(OptionItem,{value:"medium",label:"medium"}),jsxRuntimeExports.jsx(OptionItem,{value:"thick",label:"thick"})]})]})};
1677
1684
 
1678
- var styles$r = {"row":"perseus_mbWJ2QJe","header":"perseus_0eoUQ2Ck","spaceUnder":"perseus_ArAl9ugv","colorRow":"perseus_3tuEF77w","fillLabel":"perseus_mn0Hw09z","truncatedWidth":"perseus_8UEXrB8g","addButton":"perseus_AdQ6tM57","horizontalRule":"perseus_mngqi2xl","sectionTop":"perseus_Nw6aQVGx","dividerTight":"perseus_b5-539TZ"};
1685
+ var styles$p = {"row":"perseus_mbWJ2QJe","header":"perseus_0eoUQ2Ck","spaceUnder":"perseus_ArAl9ugv","colorRow":"perseus_3tuEF77w","fillLabel":"perseus_mn0Hw09z","truncatedWidth":"perseus_8UEXrB8g","addButton":"perseus_AdQ6tM57","horizontalRule":"perseus_mngqi2xl","sectionTop":"perseus_Nw6aQVGx","dividerTight":"perseus_b5-539TZ"};
1679
1686
 
1680
- var styles$q = {"container":"perseus_XtDQYWn5","row":"perseus_B-ZMM2OO","button":"perseus_jRrLESoQ","caption":"perseus_8MnE9qSz"};
1687
+ var styles$o = {"container":"perseus_XtDQYWn5","row":"perseus_B-ZMM2OO","button":"perseus_jRrLESoQ","caption":"perseus_8MnE9qSz"};
1681
1688
 
1682
- const{InfoTip: InfoTip$a}=components;function LockedFigureAria(props){const{ariaLabel,getPrepopulatedAriaLabel,editingDisabled=false,onChangeProps}=props;const id=React.useId();const ariaLabelId=`aria-label-${id}`;const[loading,setLoading]=React.useState(false);return jsxRuntimeExports.jsxs(View,{className:styles$q.container,children:[jsxRuntimeExports.jsxs(View,{className:styles$q.row,children:[jsxRuntimeExports.jsx(BodyText,{tag:"label",htmlFor:ariaLabelId,children:"Aria label"}),jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsxs(InfoTip$a,{children:["Aria label is used by screen readers to describe content to users who may be visually impaired. ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),"Populating this field will make it so that users can use a screen reader to navigate to this point and hear the description.",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),"If you leave this field blank, the point will be hidden from screen readers. Users will not be able to navigate to this point using a screen reader."]})]}),jsxRuntimeExports.jsx(BodyText,{size:"xsmall",className:styles$q.caption,children:"The figure is hidden from screen readers if this field is left blank."}),jsxRuntimeExports.jsx(TextArea,{id:ariaLabelId,value:loading?"Loading...":ariaLabel??"",disabled:editingDisabled,onChange:newValue=>{onChangeProps({ariaLabel:newValue||undefined});},placeholder:"Ex. Point at (x, y)",rows:1,resizeType:"vertical"}),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:pencilCircle,disabled:editingDisabled,className:styles$q.button,onClick:()=>{setLoading(true);getPrepopulatedAriaLabel().then(ariaLabel=>{setLoading(false);onChangeProps({ariaLabel});});},children:"Auto-generate"})]})}
1689
+ const{InfoTip: InfoTip$9}=components;function LockedFigureAria(props){const{ariaLabel,getPrepopulatedAriaLabel,editingDisabled=false,onChangeProps}=props;const id=React.useId();const ariaLabelId=`aria-label-${id}`;const[loading,setLoading]=React.useState(false);return jsxRuntimeExports.jsxs(View,{className:styles$o.container,children:[jsxRuntimeExports.jsxs(View,{className:styles$o.row,children:[jsxRuntimeExports.jsx(BodyText,{tag:"label",htmlFor:ariaLabelId,children:"Aria label"}),jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsxs(InfoTip$9,{children:["Aria label is used by screen readers to describe content to users who may be visually impaired. ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),"Populating this field will make it so that users can use a screen reader to navigate to this point and hear the description.",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),"If you leave this field blank, the point will be hidden from screen readers. Users will not be able to navigate to this point using a screen reader."]})]}),jsxRuntimeExports.jsx(BodyText,{size:"xsmall",className:styles$o.caption,children:"The figure is hidden from screen readers if this field is left blank."}),jsxRuntimeExports.jsx(TextArea,{id:ariaLabelId,value:loading?"Loading...":ariaLabel??"",disabled:editingDisabled,onChange:newValue=>{onChangeProps({ariaLabel:newValue||undefined});},placeholder:"Ex. Point at (x, y)",rows:1,resizeType:"vertical"}),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:pencilCircle,disabled:editingDisabled,className:styles$o.button,onClick:()=>{setLoading(true);getPrepopulatedAriaLabel().then(ariaLabel=>{setLoading(false);onChangeProps({ariaLabel});});},children:"Auto-generate"})]})}
1683
1690
 
1684
- var styles$p = {"container":"perseus_oK9Yeory","deleteButton":"perseus_cNh-Y9Fb"};
1691
+ var styles$n = {"container":"perseus_oK9Yeory","deleteButton":"perseus_cNh-Y9Fb"};
1685
1692
 
1686
- const LockedFigureSettingsActions=props=>{const{figureType,editingDisabled=false,onMove,onRemove}=props;return jsxRuntimeExports.jsxs(View,{className:styles$p.container,children:[jsxRuntimeExports.jsx(Button,{startIcon:trashIcon,"aria-label":`Delete locked ${figureType}`,onClick:onRemove,kind:"tertiary",disabled:editingDisabled,className:styles$p.deleteButton,children:"Delete"}),onMove&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsx(IconButton,{icon:caretDoubleUpIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} to the back`,disabled:editingDisabled,onClick:()=>onMove("back")}),jsxRuntimeExports.jsx(IconButton,{icon:caretUpIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} backward`,disabled:editingDisabled,onClick:()=>onMove("backward")}),jsxRuntimeExports.jsx(IconButton,{icon:caretDownIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} forward`,disabled:editingDisabled,onClick:()=>onMove("forward")}),jsxRuntimeExports.jsx(IconButton,{icon:caretDoubleDownIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} to the front`,disabled:editingDisabled,onClick:()=>onMove("front")})]})]})};
1693
+ const LockedFigureSettingsActions=props=>{const{figureType,editingDisabled=false,onMove,onRemove}=props;return jsxRuntimeExports.jsxs(View,{className:styles$n.container,children:[jsxRuntimeExports.jsx(Button,{startIcon:trashIcon,"aria-label":`Delete locked ${figureType}`,onClick:onRemove,kind:"tertiary",disabled:editingDisabled,className:styles$n.deleteButton,children:"Delete"}),onMove&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsx(IconButton,{icon:caretDoubleUpIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} to the back`,disabled:editingDisabled,onClick:()=>onMove("back")}),jsxRuntimeExports.jsx(IconButton,{icon:caretUpIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} backward`,disabled:editingDisabled,onClick:()=>onMove("backward")}),jsxRuntimeExports.jsx(IconButton,{icon:caretDownIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} forward`,disabled:editingDisabled,onClick:()=>onMove("forward")}),jsxRuntimeExports.jsx(IconButton,{icon:caretDoubleDownIcon,kind:"tertiary",size:"small","aria-label":`Move locked ${figureType} to the front`,disabled:editingDisabled,onClick:()=>onMove("front")})]})]})};
1687
1694
 
1688
- var styles$o = {"accordionHeaderContainer":"perseus_WmxZMpCR","accordionHeader":"perseus_ILzLQ6iO","row":"perseus_UalQRyMJ","header":"perseus_b3CfuxCt","textLabel":"perseus_Bj0ezLvT","colorRow":"perseus_FNd80vCz","sizeLabel":"perseus_V-jCdUIK"};
1695
+ var styles$m = {"accordionHeaderContainer":"perseus_WmxZMpCR","accordionHeader":"perseus_ILzLQ6iO","row":"perseus_UalQRyMJ","header":"perseus_b3CfuxCt","textLabel":"perseus_Bj0ezLvT","colorRow":"perseus_FNd80vCz","sizeLabel":"perseus_V-jCdUIK"};
1689
1696
 
1690
- const{InfoTip: InfoTip$9}=components;const spaceUnderStyle$3={marginBottom:sizing.size_080};function LockedLabelSettings(props){const{type,coord,color,size,text,expanded,editingDisabled=false,onChangeProps,onMove,onRemove,onToggle,containerStyle}=props;return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$o.row} ${styles$o.accordionHeaderContainer} ${styles$o.header}`,children:[jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"span",children:["Label (",coord[0],", ",coord[1],")"]}),text!==""&&jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",className:styles$o.accordionHeader,style:{color:lockedFigureColors[color]},children:text})]}),containerStyle:containerStyle,children:[jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,disabled:editingDisabled,onChange:newCoords=>{onChangeProps({coord:newCoords});},style:spaceUnderStyle$3}),jsxRuntimeExports.jsxs(View,{className:styles$o.row,children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$o.row} ${styles$o.textLabel}`,children:["text",jsxRuntimeExports.jsx(TextField,{value:text,placeholder:"ex. $x^2$ or $\\frac{1}{2}$",disabled:editingDisabled,onChange:newValue=>onChangeProps({text:newValue})})]}),jsxRuntimeExports.jsxs(InfoTip$9,{children:["Surround your text with $ for TeX.",jsxRuntimeExports.jsx("br",{}),"Example: ",`This circle has radius $\\frac{1}{2}$ units.`,jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),'It is important to use TeX when appropriate for accessibility. The above example would be read as "This circle has radius one-half units" by screen readers.']})]}),jsxRuntimeExports.jsxs(View,{className:`${styles$o.row} ${styles$o.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:color,editingDisabled:editingDisabled,onChange:newColor=>{onChangeProps({color:newColor});},style:spaceUnderStyle$3}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$o.row} ${styles$o.sizeLabel}`,children:["size",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:size,disabled:editingDisabled,onChange:newValue=>onChangeProps({size:newValue}),placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"small",label:"small"}),jsxRuntimeExports.jsx(OptionItem,{value:"medium",label:"medium"}),jsxRuntimeExports.jsx(OptionItem,{value:"large",label:"large"})]})]})]}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})}
1697
+ const{InfoTip: InfoTip$8}=components;const spaceUnderStyle$3={marginBottom:sizing.size_080};function LockedLabelSettings(props){const{type,coord,color,size,text,expanded,editingDisabled=false,onChangeProps,onMove,onRemove,onToggle,containerStyle}=props;return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$m.row} ${styles$m.accordionHeaderContainer} ${styles$m.header}`,children:[jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"span",children:["Label (",coord[0],", ",coord[1],")"]}),text!==""&&jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",className:styles$m.accordionHeader,style:{color:lockedFigureColors[color]},children:text})]}),containerStyle:containerStyle,children:[jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,disabled:editingDisabled,onChange:newCoords=>{onChangeProps({coord:newCoords});},style:spaceUnderStyle$3}),jsxRuntimeExports.jsxs(View,{className:styles$m.row,children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$m.row} ${styles$m.textLabel}`,children:["text",jsxRuntimeExports.jsx(TextField,{value:text,placeholder:"ex. $x^2$ or $\\frac{1}{2}$",disabled:editingDisabled,onChange:newValue=>onChangeProps({text:newValue})})]}),jsxRuntimeExports.jsxs(InfoTip$8,{children:["Surround your text with $ for TeX.",jsxRuntimeExports.jsx("br",{}),"Example: ",`This circle has radius $\\frac{1}{2}$ units.`,jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),'It is important to use TeX when appropriate for accessibility. The above example would be read as "This circle has radius one-half units" by screen readers.']})]}),jsxRuntimeExports.jsxs(View,{className:`${styles$m.row} ${styles$m.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:color,editingDisabled:editingDisabled,onChange:newColor=>{onChangeProps({color:newColor});},style:spaceUnderStyle$3}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$m.row} ${styles$m.sizeLabel}`,children:["size",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:size,disabled:editingDisabled,onChange:newValue=>onChangeProps({size:newValue}),placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"small",label:"small"}),jsxRuntimeExports.jsx(OptionItem,{value:"medium",label:"medium"}),jsxRuntimeExports.jsx(OptionItem,{value:"large",label:"large"})]})]})]}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})}
1691
1698
 
1692
1699
  function generateLockedFigureAppearanceDescription(color,strokeStyle="solid",fill,weight="medium"){const convertedColor=color==="grayH"?"gray":color;const weightString=weight==="medium"?"":` ${weight}`;const baseAppearance=`. Appearance${weightString} ${strokeStyle} ${convertedColor}`;switch(fill){case "none":return `${baseAppearance} border, with no fill.`;case "white":return `${baseAppearance} border, with a white fill.`;case "solid":case "translucent":return `${baseAppearance} border, with a ${fill} ${convertedColor} fill.`;case undefined:return `${baseAppearance}.`;default:throw new UnreachableCaseError(fill)}}async function generateSpokenMathDetails(mathString){const engine=await SpeechRuleEngine.setup("en");let convertedSpeech="";const parsedContent=mathOnlyParser(mathString);for(const piece of parsedContent){switch(piece.type){case "math":convertedSpeech+=engine.texToSpeech(piece.content);break;case "specialCharacter":convertedSpeech+=piece.content.length>1?piece.content.slice(1):piece.content;break;default:convertedSpeech+=piece.content;break}}return convertedSpeech}async function joinLabelsAsSpokenMath(labels){if(labels.length===0){return ""}const spokenLabelPromises=labels.map(label=>{return generateSpokenMathDetails(label.text)});const spokenLabels=await Promise.all(spokenLabelPromises);return ` ${spokenLabels.join(", ")}`}
1693
1700
 
1694
- const{convertRadiansToDegrees}=angles;const{InfoTip: InfoTip$8}=components;const spaceUnderStyle$2={marginBottom:sizing.size_080};const labelContainerStyle$3={backgroundColor:semanticColor.core.background.base.default};const LockedEllipseSettings=props=>{const{center,radius,angle,color,labels,ariaLabel,fillStyle,strokeStyle,weight,expanded,editingDisabled=false,onToggle,onChangeProps,onMove,onRemove}=props;async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const spokenCenterX=await generateSpokenMathDetails(`$${center[0]}$`);const spokenCenterY=await generateSpokenMathDetails(`$${center[1]}$`);const spokenRotation=await generateSpokenMathDetails(`$${convertRadiansToDegrees(angle)}$`);const isCircle=radius[0]===radius[1];let str="";if(isCircle){str+=`Circle${visiblelabel} with radius ${radius[0]}`;}else {str+=`Ellipse${visiblelabel} with x radius ${radius[0]} and y radius ${radius[1]}`;}str+=`, centered at ${spokenCenterX} comma ${spokenCenterY}`;if(!isCircle&&angle!==0){str+=`, rotated by ${spokenRotation} degrees`;}const ellipseAppearance=generateLockedFigureAppearanceDescription(color,strokeStyle,fillStyle,weight);str+=ellipseAppearance;return str}function handleCenterChange(newCoord){const xOffset=newCoord[0]-center[0];const yOffset=newCoord[1]-center[1];const newProps={center:newCoord};newProps.labels=labels.map(label=>({...label,coord:[label.coord[0]+xOffset,label.coord[1]+yOffset]}));onChangeProps(newProps);}function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$r.row} ${styles$r.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",tag:"span",weight:"bold",children:`Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`}),jsxRuntimeExports.jsx(EllipseSwatch,{color:props.color,fillStyle:fillStyle,strokeStyle:strokeStyle})]}),children:[jsxRuntimeExports.jsxs(View,{className:styles$r.row,children:[jsxRuntimeExports.jsx(CoordinatePairInput,{coord:center,style:spaceUnderStyle$2,disabled:editingDisabled,onChange:handleCenterChange}),jsxRuntimeExports.jsx(View,{className:styles$r.spaceUnder,children:jsxRuntimeExports.jsx(InfoTip$8,{children:"The coordinates for the center of the ellipse."})})]}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:radius,labels:["x radius","y radius"],style:spaceUnderStyle$2,disabled:editingDisabled,onChange:newCoords=>onChangeProps({radius:newCoords})}),jsxRuntimeExports.jsx(AngleInput,{angle:angle,onChange:newAngle=>onChangeProps({angle:newAngle})}),jsxRuntimeExports.jsxs(View,{className:`${styles$r.row} ${styles$r.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:color,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$r.row} ${styles$r.truncatedWidth} ${styles$r.fillLabel}`,children:["fill",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:fillStyle,disabled:editingDisabled,onChange:value=>onChangeProps({fillStyle:value}),placeholder:"",children:Object.keys(lockedFigureFillStyles).map(option=>jsxRuntimeExports.jsx(OptionItem,{value:option,label:option},option))})]})]}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:strokeStyle,editingDisabled:editingDisabled,onChange:value=>onChangeProps({strokeStyle:value}),containerStyle:{marginBottom:sizing.size_080}}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),jsxRuntimeExports.jsx(View,{className:`${styles$r.horizontalRule} ${styles$r.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$r.horizontalRule} ${styles$r.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$r.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle$3})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[center[0],center[1]-labels.length],color:color};onChangeProps({labels:[...labels,newLabel]});},className:styles$r.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1701
+ const{convertRadiansToDegrees}=angles;const{InfoTip: InfoTip$7}=components;const spaceUnderStyle$2={marginBottom:sizing.size_080};const labelContainerStyle$3={backgroundColor:semanticColor.core.background.base.default};const LockedEllipseSettings=props=>{const{center,radius,angle,color,labels,ariaLabel,fillStyle,strokeStyle,weight,expanded,editingDisabled=false,onToggle,onChangeProps,onMove,onRemove}=props;async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const spokenCenterX=await generateSpokenMathDetails(`$${center[0]}$`);const spokenCenterY=await generateSpokenMathDetails(`$${center[1]}$`);const spokenRotation=await generateSpokenMathDetails(`$${convertRadiansToDegrees(angle)}$`);const isCircle=radius[0]===radius[1];let str="";if(isCircle){str+=`Circle${visiblelabel} with radius ${radius[0]}`;}else {str+=`Ellipse${visiblelabel} with x radius ${radius[0]} and y radius ${radius[1]}`;}str+=`, centered at ${spokenCenterX} comma ${spokenCenterY}`;if(!isCircle&&angle!==0){str+=`, rotated by ${spokenRotation} degrees`;}const ellipseAppearance=generateLockedFigureAppearanceDescription(color,strokeStyle,fillStyle,weight);str+=ellipseAppearance;return str}function handleCenterChange(newCoord){const xOffset=newCoord[0]-center[0];const yOffset=newCoord[1]-center[1];const newProps={center:newCoord};newProps.labels=labels.map(label=>({...label,coord:[label.coord[0]+xOffset,label.coord[1]+yOffset]}));onChangeProps(newProps);}function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$p.row} ${styles$p.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",tag:"span",weight:"bold",children:`Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`}),jsxRuntimeExports.jsx(EllipseSwatch,{color:props.color,fillStyle:fillStyle,strokeStyle:strokeStyle})]}),children:[jsxRuntimeExports.jsxs(View,{className:styles$p.row,children:[jsxRuntimeExports.jsx(CoordinatePairInput,{coord:center,style:spaceUnderStyle$2,disabled:editingDisabled,onChange:handleCenterChange}),jsxRuntimeExports.jsx(View,{className:styles$p.spaceUnder,children:jsxRuntimeExports.jsx(InfoTip$7,{children:"The coordinates for the center of the ellipse."})})]}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:radius,labels:["x radius","y radius"],style:spaceUnderStyle$2,disabled:editingDisabled,onChange:newCoords=>onChangeProps({radius:newCoords})}),jsxRuntimeExports.jsx(AngleInput,{angle:angle,onChange:newAngle=>onChangeProps({angle:newAngle})}),jsxRuntimeExports.jsxs(View,{className:`${styles$p.row} ${styles$p.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:color,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$p.row} ${styles$p.truncatedWidth} ${styles$p.fillLabel}`,children:["fill",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:fillStyle,disabled:editingDisabled,onChange:value=>onChangeProps({fillStyle:value}),placeholder:"",children:Object.keys(lockedFigureFillStyles).map(option=>jsxRuntimeExports.jsx(OptionItem,{value:option,label:option},option))})]})]}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:strokeStyle,editingDisabled:editingDisabled,onChange:value=>onChangeProps({strokeStyle:value}),containerStyle:{marginBottom:sizing.size_080}}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),jsxRuntimeExports.jsx(View,{className:`${styles$p.horizontalRule} ${styles$p.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$p.horizontalRule} ${styles$p.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$p.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle$3})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[center[0],center[1]-labels.length],color:color};onChangeProps({labels:[...labels,newLabel]});},className:styles$p.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1695
1702
 
1696
- const LineSwatch=props=>{const{color,lineStyle}=props;return jsxRuntimeExports.jsx(View,{style:styles$n.container,children:jsxRuntimeExports.jsx(View,{"aria-label":`${color}, ${lineStyle}`,style:[styles$n.lineSwatch,{border:`5px ${lineStyle} ${lockedFigureColors[color]}`}]})})};const styles$n=StyleSheet.create({container:{backgroundColor:semanticColor.core.background.base.default,justifyContent:"center",padding:spacing.xSmall_8,borderRadius:spacing.xxxSmall_4},lineSwatch:{width:40}});
1703
+ const LineSwatch=props=>{const{color,lineStyle}=props;return jsxRuntimeExports.jsx(View,{style:styles$l.container,children:jsxRuntimeExports.jsx(View,{"aria-label":`${color}, ${lineStyle}`,style:[styles$l.lineSwatch,{border:`5px ${lineStyle} ${lockedFigureColors[color]}`}]})})};const styles$l=StyleSheet.create({container:{backgroundColor:semanticColor.core.background.base.default,justifyContent:"center",padding:spacing.xSmall_8,borderRadius:spacing.xxxSmall_4},lineSwatch:{width:40}});
1697
1704
 
1698
1705
  const examples={linear:["x + 5","1/2x - 2"],polynomial:["1/2x^2 + 3x - 4","(1/3)x^3 - 2x^2 + 3x - 4"],trigonometric:["sin(x) * 3","arctan(2x) + 4"]};
1699
1706
 
1700
- var styles$m = {"accordionHeader":"perseus_tXEvWJUz","axisMenu":"perseus_3xCRJZPa","copyPasteButton":"perseus_jQjspEma","domainMin":"perseus_sKC9BNwU","domainMax":"perseus_FKW3Nxnm","dropdownLabel":"perseus_yi6yIVkG","exampleContainer":"perseus_4hIadz5F","exampleContent":"perseus_Im9FqKCL","exampleRow":"perseus_XTGXne8n","rowSpace":"perseus_pLyszuFy","row":"perseus_QcmxeGEV","header":"perseus_n6hVg5Q8","colorRow":"perseus_lTxTG2gH","axisRow":"perseus_-uNx1-Ee","domainRow":"perseus_ledp5RIf","addButton":"perseus_hZeYfTVX","horizontalRule":"perseus_MdlHBO-Z","sectionTop":"perseus_f26X1kQX","dividerTight":"perseus_xD6EJyrU","exampleContentIndent":"perseus_BlYv-O-3"};
1707
+ var styles$k = {"accordionHeader":"perseus_tXEvWJUz","axisMenu":"perseus_3xCRJZPa","copyPasteButton":"perseus_jQjspEma","domainMin":"perseus_sKC9BNwU","domainMax":"perseus_FKW3Nxnm","dropdownLabel":"perseus_yi6yIVkG","exampleContainer":"perseus_4hIadz5F","exampleContent":"perseus_Im9FqKCL","exampleRow":"perseus_XTGXne8n","rowSpace":"perseus_pLyszuFy","row":"perseus_QcmxeGEV","header":"perseus_n6hVg5Q8","colorRow":"perseus_lTxTG2gH","axisRow":"perseus_-uNx1-Ee","domainRow":"perseus_ledp5RIf","addButton":"perseus_hZeYfTVX","horizontalRule":"perseus_MdlHBO-Z","sectionTop":"perseus_f26X1kQX","dividerTight":"perseus_xD6EJyrU","exampleContentIndent":"perseus_BlYv-O-3"};
1701
1708
 
1702
- const LockedFunctionSettings=props=>{const{color:lineColor,strokeStyle,equation,directionalAxis,domain,weight,ariaLabel,editingDisabled=false,onChangeProps,onMove,onRemove}=props;const labels=props.labels;const equationPrefix=directionalAxis==="x"?"y=":"x=";const lineLabel=`Function (${equationPrefix}${equation})`;const getDomainStringValues=domain=>{return [Number.isFinite(domain[0])?domain[0].toString():"",Number.isFinite(domain[1])?domain[1].toString():""]};const[domainEntries,setDomainEntries]=useState(getDomainStringValues(domain));const[exampleCategory,setExampleCategory]=useState("");useEffect(()=>{setDomainEntries(getDomainStringValues(domain));},[domain]);async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);let str=`Function${visiblelabel} with equation ${equationPrefix}${equation}`;if(Number.isFinite(domain[0])||Number.isFinite(domain[1])){str+=`, domain from ${domain[0]} to ${domain[1]}`;}const functionAppearance=generateLockedFigureAppearanceDescription(lineColor,strokeStyle,undefined,weight);str+=functionAppearance;return str}function handlePropChange(property,newValue){const updatedProps={};updatedProps[property]=newValue;onChangeProps(updatedProps);}function handleDomainChange(limitIndex,newValueString){const newDomainEntries=[...domainEntries];newDomainEntries[limitIndex]=newValueString;setDomainEntries(newDomainEntries);const newDomain=[...domain];let newValue=parseFloat(newValueString);if(newValueString===""&&limitIndex===0){newValue=-Infinity;}else if(newValueString===""&&limitIndex===1){newValue=Infinity;}newDomain[limitIndex]=newValue;onChangeProps({domain:newDomain});}const exampleCategories=Object.keys(examples);const exampleCategorySelected=exampleCategory!=="";const exampleContent=exampleCategorySelected?examples[exampleCategory]:["Select category to see example equations"];function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:props.expanded,onToggle:props.onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$m.row} ${styles$m.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",className:styles$m.accordionHeader,children:lineLabel}),jsxRuntimeExports.jsx(LineSwatch,{color:lineColor,lineStyle:strokeStyle})]}),children:[jsxRuntimeExports.jsxs(View,{className:`${styles$m.row} ${styles$m.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:lineColor,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:strokeStyle,editingDisabled:editingDisabled,onChange:newValue=>{handlePropChange("strokeStyle",newValue);}})]}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),jsxRuntimeExports.jsxs(View,{className:`${styles$m.row} ${styles$m.rowSpace} ${styles$m.axisRow}`,children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:directionalAxis,disabled:editingDisabled,onChange:newValue=>{handlePropChange("directionalAxis",newValue);},"aria-label":"equation prefix",className:`${styles$m.dropdownLabel} ${styles$m.axisMenu}`,placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"x",label:"y ="}),jsxRuntimeExports.jsx(OptionItem,{value:"y",label:"x ="})]}),jsxRuntimeExports.jsx(TextField,{type:"text","aria-label":"equation",value:equation,disabled:editingDisabled,onChange:newValue=>{handlePropChange("equation",newValue);},style:{flexGrow:1}})]}),jsxRuntimeExports.jsxs(View,{className:`${styles$m.row} ${styles$m.rowSpace} ${styles$m.domainRow}`,children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$m.dropdownLabel} ${styles$m.domainMin}`,children:["domain min",jsxRuntimeExports.jsx(TextField,{type:"number",style:{width:"calc(100% - 88.7px)"},value:domainEntries[0],disabled:editingDisabled,onChange:newValue=>{handleDomainChange(0,newValue);}})]}),jsxRuntimeExports.jsxs(BodyText,{tag:"label","aria-label":"domain max",className:`${styles$m.dropdownLabel} ${styles$m.domainMax}`,children:["max",jsxRuntimeExports.jsx(TextField,{type:"number",style:{width:"calc(100% - 36.2px)"},value:domainEntries[1],disabled:editingDisabled,onChange:newValue=>{handleDomainChange(1,newValue);}})]})]}),jsxRuntimeExports.jsxs(PerseusEditorAccordion,{header:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Example Functions"}),expanded:false,containerStyle:{background:semanticColor.core.background.base.subtle},panelStyle:{alignItems:"start",paddingBottom:sizing.size_120,flexDirection:"row",flexWrap:"wrap"},children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$m.dropdownLabel,children:["Choose a category",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:exampleCategory,disabled:editingDisabled,onChange:setExampleCategory,placeholder:"examples",children:exampleCategories.map(category=>{return jsxRuntimeExports.jsx(OptionItem,{value:category,label:category},category)})})]}),exampleCategorySelected&&jsxRuntimeExports.jsx("ul",{className:styles$m.exampleContainer,children:exampleContent.map((example,index)=>jsxRuntimeExports.jsx(ExampleItem,{category:exampleCategory,example:example,index:index,editingDisabled:editingDisabled,pasteEquationFn:handlePropChange},index))})]}),jsxRuntimeExports.jsx(View,{className:`${styles$m.horizontalRule} ${styles$m.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$m.horizontalRule} ${styles$m.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$m.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>jsxRuntimeExports.jsx(LockedLabelSettings,{...label,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:{backgroundColor:semanticColor.core.background.base.default}},labelIndex)),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[0,-labels.length],color:lineColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$m.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};const ExampleItem=props=>{const{category,example,index,editingDisabled,pasteEquationFn}=props;const exampleId=useId();return jsxRuntimeExports.jsxs("li",{className:styles$m.exampleRow,children:[jsxRuntimeExports.jsx(IconButton,{icon:autoPasteIcon,kind:"tertiary","aria-label":"paste example","aria-describedby":exampleId,disabled:editingDisabled,onClick:()=>pasteEquationFn("equation",example),size:"medium",className:styles$m.copyPasteButton}),jsxRuntimeExports.jsx(IconButton,{icon:copyIcon,kind:"tertiary","aria-label":"copy example","aria-describedby":exampleId,disabled:editingDisabled,onClick:()=>navigator.clipboard.writeText(example),size:"medium",className:styles$m.copyPasteButton}),jsxRuntimeExports.jsx(View,{className:`${styles$m.exampleContent} ${styles$m.exampleContentIndent}`,id:exampleId,children:example})]},`${category}-${index}`)};
1709
+ const LockedFunctionSettings=props=>{const{color:lineColor,strokeStyle,equation,directionalAxis,domain,weight,ariaLabel,editingDisabled=false,onChangeProps,onMove,onRemove}=props;const labels=props.labels;const equationPrefix=directionalAxis==="x"?"y=":"x=";const lineLabel=`Function (${equationPrefix}${equation})`;const getDomainStringValues=domain=>{return [Number.isFinite(domain[0])?domain[0].toString():"",Number.isFinite(domain[1])?domain[1].toString():""]};const[domainEntries,setDomainEntries]=useState(getDomainStringValues(domain));const[exampleCategory,setExampleCategory]=useState("");useEffect(()=>{setDomainEntries(getDomainStringValues(domain));},[domain]);async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);let str=`Function${visiblelabel} with equation ${equationPrefix}${equation}`;if(Number.isFinite(domain[0])||Number.isFinite(domain[1])){str+=`, domain from ${domain[0]} to ${domain[1]}`;}const functionAppearance=generateLockedFigureAppearanceDescription(lineColor,strokeStyle,undefined,weight);str+=functionAppearance;return str}function handlePropChange(property,newValue){const updatedProps={};updatedProps[property]=newValue;onChangeProps(updatedProps);}function handleDomainChange(limitIndex,newValueString){const newDomainEntries=[...domainEntries];newDomainEntries[limitIndex]=newValueString;setDomainEntries(newDomainEntries);const newDomain=[...domain];let newValue=parseFloat(newValueString);if(newValueString===""&&limitIndex===0){newValue=-Infinity;}else if(newValueString===""&&limitIndex===1){newValue=Infinity;}newDomain[limitIndex]=newValue;onChangeProps({domain:newDomain});}const exampleCategories=Object.keys(examples);const exampleCategorySelected=exampleCategory!=="";const exampleContent=exampleCategorySelected?examples[exampleCategory]:["Select category to see example equations"];function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:props.expanded,onToggle:props.onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$k.row} ${styles$k.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",className:styles$k.accordionHeader,children:lineLabel}),jsxRuntimeExports.jsx(LineSwatch,{color:lineColor,lineStyle:strokeStyle})]}),children:[jsxRuntimeExports.jsxs(View,{className:`${styles$k.row} ${styles$k.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:lineColor,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:strokeStyle,editingDisabled:editingDisabled,onChange:newValue=>{handlePropChange("strokeStyle",newValue);}})]}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),jsxRuntimeExports.jsxs(View,{className:`${styles$k.row} ${styles$k.rowSpace} ${styles$k.axisRow}`,children:[jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:directionalAxis,disabled:editingDisabled,onChange:newValue=>{handlePropChange("directionalAxis",newValue);},"aria-label":"equation prefix",className:`${styles$k.dropdownLabel} ${styles$k.axisMenu}`,placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"x",label:"y ="}),jsxRuntimeExports.jsx(OptionItem,{value:"y",label:"x ="})]}),jsxRuntimeExports.jsx(TextField,{type:"text","aria-label":"equation",value:equation,disabled:editingDisabled,onChange:newValue=>{handlePropChange("equation",newValue);},style:{flexGrow:1}})]}),jsxRuntimeExports.jsxs(View,{className:`${styles$k.row} ${styles$k.rowSpace} ${styles$k.domainRow}`,children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$k.dropdownLabel} ${styles$k.domainMin}`,children:["domain min",jsxRuntimeExports.jsx(TextField,{type:"number",style:{width:"calc(100% - 88.7px)"},value:domainEntries[0],disabled:editingDisabled,onChange:newValue=>{handleDomainChange(0,newValue);}})]}),jsxRuntimeExports.jsxs(BodyText,{tag:"label","aria-label":"domain max",className:`${styles$k.dropdownLabel} ${styles$k.domainMax}`,children:["max",jsxRuntimeExports.jsx(TextField,{type:"number",style:{width:"calc(100% - 36.2px)"},value:domainEntries[1],disabled:editingDisabled,onChange:newValue=>{handleDomainChange(1,newValue);}})]})]}),jsxRuntimeExports.jsxs(PerseusEditorAccordion,{header:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Example Functions"}),expanded:false,containerStyle:{background:semanticColor.core.background.base.subtle},panelStyle:{alignItems:"start",paddingBottom:sizing.size_120,flexDirection:"row",flexWrap:"wrap"},children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$k.dropdownLabel,children:["Choose a category",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:exampleCategory,disabled:editingDisabled,onChange:setExampleCategory,placeholder:"examples",children:exampleCategories.map(category=>{return jsxRuntimeExports.jsx(OptionItem,{value:category,label:category},category)})})]}),exampleCategorySelected&&jsxRuntimeExports.jsx("ul",{className:styles$k.exampleContainer,children:exampleContent.map((example,index)=>jsxRuntimeExports.jsx(ExampleItem,{category:exampleCategory,example:example,index:index,editingDisabled:editingDisabled,pasteEquationFn:handlePropChange},index))})]}),jsxRuntimeExports.jsx(View,{className:`${styles$k.horizontalRule} ${styles$k.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$k.horizontalRule} ${styles$k.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$k.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>jsxRuntimeExports.jsx(LockedLabelSettings,{...label,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:{backgroundColor:semanticColor.core.background.base.default}},labelIndex)),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[0,-labels.length],color:lineColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$k.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};const ExampleItem=props=>{const{category,example,index,editingDisabled,pasteEquationFn}=props;const exampleId=useId();return jsxRuntimeExports.jsxs("li",{className:styles$k.exampleRow,children:[jsxRuntimeExports.jsx(IconButton,{icon:autoPasteIcon,kind:"tertiary","aria-label":"paste example","aria-describedby":exampleId,disabled:editingDisabled,onClick:()=>pasteEquationFn("equation",example),size:"medium",className:styles$k.copyPasteButton}),jsxRuntimeExports.jsx(IconButton,{icon:copyIcon,kind:"tertiary","aria-label":"copy example","aria-describedby":exampleId,disabled:editingDisabled,onClick:()=>navigator.clipboard.writeText(example),size:"medium",className:styles$k.copyPasteButton}),jsxRuntimeExports.jsx(View,{className:`${styles$k.exampleContent} ${styles$k.exampleContentIndent}`,id:exampleId,children:example})]},`${category}-${index}`)};
1703
1710
 
1704
- var styles$l = {"row":"perseus_nBzKD32m","header":"perseus_WNElRLBL","spaceUnder":"perseus_sEXwoqeH","kindLabel":"perseus_MohIPkUC","colorRow":"perseus_WDC67hHF","errorText":"perseus_57zeueK9","addButton":"perseus_se9nOPo3","horizontalRule":"perseus_XnNJefSQ","sectionTop":"perseus_mCvSm-pU","dividerTight":"perseus_34Yfh9Ri"};
1711
+ var styles$j = {"row":"perseus_nBzKD32m","header":"perseus_WNElRLBL","spaceUnder":"perseus_sEXwoqeH","kindLabel":"perseus_MohIPkUC","colorRow":"perseus_WDC67hHF","errorText":"perseus_57zeueK9","addButton":"perseus_se9nOPo3","horizontalRule":"perseus_XnNJefSQ","sectionTop":"perseus_mCvSm-pU","dividerTight":"perseus_34Yfh9Ri"};
1705
1712
 
1706
- var styles$k = {"row":"perseus_PsQTUHiB","addButton":"perseus_DzebTj-c","horizontalRule":"perseus_pxo33u6Q","sectionTop":"perseus_pOW3mBVq","dividerTight":"perseus_iXTo2lsa"};
1713
+ var styles$i = {"row":"perseus_PsQTUHiB","addButton":"perseus_DzebTj-c","horizontalRule":"perseus_pxo33u6Q","sectionTop":"perseus_pOW3mBVq","dividerTight":"perseus_iXTo2lsa"};
1707
1714
 
1708
- const spaceUnderStyle$1={marginBottom:sizing.size_080};const LockedPointSettings=props=>{const{headerLabel,editingDisabled=false,coord,color:pointColor,filled=true,labels,ariaLabel,onChangeProps,onMove,onRemove,showPoint,error,expanded,onTogglePoint,onToggle}=props;const isDefiningPoint=!onMove&&!onRemove;async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const spokenX=await generateSpokenMathDetails(`$${coord[0]}$`);const spokenY=await generateSpokenMathDetails(`$${coord[1]}$`);let str=`Point${visiblelabel} at ${spokenX} comma ${spokenY}`;const pointAppearance=generateLockedFigureAppearanceDescription(pointColor,"solid",filled?undefined:"none");str+=pointAppearance;return str}function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handleCoordChange(newCoord){const xOffset=newCoord[0]-coord[0];const yOffset=newCoord[1]-coord[1];const newProps={coord:newCoord};newProps.labels=labels.map(label=>({...label,coord:[label.coord[0]+xOffset,label.coord[1]+yOffset]}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,containerStyle:isDefiningPoint?{marginTop:sizing.size_080,marginBottom:0,marginLeft:-sizing.size_040,marginRight:-sizing.size_040,backgroundColor:semanticColor.core.background.base.default}:undefined,panelStyle:isDefiningPoint?{paddingBottom:sizing.size_060}:undefined,header:jsxRuntimeExports.jsxs(View,{className:styles$k.row,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`${headerLabel||"Point"} (${coord[0]}, ${coord[1]})`}),jsxRuntimeExports.jsx(ColorSwatch,{color:pointColor,filled:filled})]}),children:[jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,style:spaceUnderStyle$1,disabled:editingDisabled,onChange:handleCoordChange,error:!!error}),onTogglePoint&&jsxRuntimeExports.jsx(LabeledSwitch,{label:"show point on graph",checked:!!showPoint,style:showPoint&&spaceUnderStyle$1,disabled:editingDisabled,onChange:onTogglePoint}),(!isDefiningPoint||showPoint)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:pointColor,onChange:handleColorChange,style:spaceUnderStyle$1,editingDisabled:editingDisabled}),jsxRuntimeExports.jsx(LabeledSwitch,{label:"open point",checked:!filled,disabled:editingDisabled,onChange:newValue=>{onChangeProps({filled:!newValue});}})]}),!isDefiningPoint&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(View,{className:`${styles$k.horizontalRule} ${styles$k.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}})]}),jsxRuntimeExports.jsx(View,{className:`${styles$k.horizontalRule} ${styles$k.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$k.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,containerStyle:!isDefiningPoint&&{backgroundColor:semanticColor.core.background.base.default},expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);}})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[coord[0]+.5,coord[1]-labels.length],color:pointColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$k.addButton,children:"Add visible label"}),onRemove&&jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1715
+ const spaceUnderStyle$1={marginBottom:sizing.size_080};const LockedPointSettings=props=>{const{headerLabel,editingDisabled=false,coord,color:pointColor,filled=true,labels,ariaLabel,onChangeProps,onMove,onRemove,showPoint,error,expanded,onTogglePoint,onToggle}=props;const isDefiningPoint=!onMove&&!onRemove;async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const spokenX=await generateSpokenMathDetails(`$${coord[0]}$`);const spokenY=await generateSpokenMathDetails(`$${coord[1]}$`);let str=`Point${visiblelabel} at ${spokenX} comma ${spokenY}`;const pointAppearance=generateLockedFigureAppearanceDescription(pointColor,"solid",filled?undefined:"none");str+=pointAppearance;return str}function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handleCoordChange(newCoord){const xOffset=newCoord[0]-coord[0];const yOffset=newCoord[1]-coord[1];const newProps={coord:newCoord};newProps.labels=labels.map(label=>({...label,coord:[label.coord[0]+xOffset,label.coord[1]+yOffset]}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,containerStyle:isDefiningPoint?{marginTop:sizing.size_080,marginBottom:0,marginLeft:-sizing.size_040,marginRight:-sizing.size_040,backgroundColor:semanticColor.core.background.base.default}:undefined,panelStyle:isDefiningPoint?{paddingBottom:sizing.size_060}:undefined,header:jsxRuntimeExports.jsxs(View,{className:styles$i.row,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`${headerLabel||"Point"} (${coord[0]}, ${coord[1]})`}),jsxRuntimeExports.jsx(ColorSwatch,{color:pointColor,filled:filled})]}),children:[jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,style:spaceUnderStyle$1,disabled:editingDisabled,onChange:handleCoordChange,error:!!error}),onTogglePoint&&jsxRuntimeExports.jsx(LabeledSwitch,{label:"show point on graph",checked:!!showPoint,style:showPoint&&spaceUnderStyle$1,disabled:editingDisabled,onChange:onTogglePoint}),(!isDefiningPoint||showPoint)&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:pointColor,onChange:handleColorChange,style:spaceUnderStyle$1,editingDisabled:editingDisabled}),jsxRuntimeExports.jsx(LabeledSwitch,{label:"open point",checked:!filled,disabled:editingDisabled,onChange:newValue=>{onChangeProps({filled:!newValue});}})]}),!isDefiningPoint&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(View,{className:`${styles$i.horizontalRule} ${styles$i.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}})]}),jsxRuntimeExports.jsx(View,{className:`${styles$i.horizontalRule} ${styles$i.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$i.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,containerStyle:!isDefiningPoint&&{backgroundColor:semanticColor.core.background.base.default},expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);}})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[coord[0]+.5,coord[1]-labels.length],color:pointColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$i.addButton,children:"Add visible label"}),onRemove&&jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1709
1716
 
1710
1717
  const lengthZeroStr="The line cannot have length 0.";const labelContainerStyle$2={backgroundColor:semanticColor.core.background.base.default};const LockedLineSettings=props=>{const{kind,points,color:lineColor,lineStyle="solid",showPoint1,showPoint2,weight,labels,ariaLabel,editingDisabled=false,onChangeProps,onMove,onRemove}=props;const[point1,point2]=points;const capitalizeKind=kind.charAt(0).toUpperCase()+kind.slice(1);const lineLabel=`${capitalizeKind} (${point1.coord[0]},
1711
- ${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;const isInvalid=vector.equal(point1.coord,point2.coord);async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const point1VisibleLabel=await joinLabelsAsSpokenMath(point1.labels);const point2VisibleLabel=await joinLabelsAsSpokenMath(point2.labels);const spokenPoint1X=await generateSpokenMathDetails(`$${point1.coord[0]}$`);const spokenPoint1Y=await generateSpokenMathDetails(`$${point1.coord[1]}$`);const spokenPoint2X=await generateSpokenMathDetails(`$${point2.coord[0]}$`);const spokenPoint2Y=await generateSpokenMathDetails(`$${point2.coord[1]}$`);let str;switch(kind){case "line":str=`${capitalizeKind}${visiblelabel} through point${point1VisibleLabel} at ${spokenPoint1X} comma ${spokenPoint1Y} and point${point2VisibleLabel} at ${spokenPoint2X} comma ${spokenPoint2Y}`;break;case "ray":str=`${capitalizeKind}${visiblelabel} from point${point1VisibleLabel} at ${spokenPoint1X} comma ${spokenPoint1Y} through point${point2VisibleLabel} at ${spokenPoint2X} comma ${spokenPoint2Y}`;break;case "segment":str=`${capitalizeKind}${visiblelabel} from point${point1VisibleLabel} at ${spokenPoint1X} comma ${spokenPoint1Y} to point${point2VisibleLabel} at ${spokenPoint2X} comma ${spokenPoint2Y}`;break;default:throw new UnreachableCaseError(kind,"Unknown line kind")}const lineAppearance=generateLockedFigureAppearanceDescription(lineColor,lineStyle,undefined,weight);str+=lineAppearance;return str}function handleChangePoint(newPointProps,index){const newPoints=[...points];newPoints[index]={...points[index],...newPointProps};const oldMidpoint=vec.midpoint(points[0].coord,points[1].coord);const newMidpoint=vec.midpoint(newPoints[0].coord,newPoints[1].coord);const offset=[newMidpoint[0]-oldMidpoint[0],newMidpoint[1]-oldMidpoint[1]];const newLabels=labels.map((label,labelIndex)=>({...label,coord:[label.coord[0]+offset[0],label.coord[1]+offset[1]]}));onChangeProps({points:newPoints,labels:newLabels});}function handleColorChange(newColor){const newLabels=labels.map(label=>({...label,color:newColor}));onChangeProps({color:newColor,points:[{...point1,color:newColor,labels:point1.labels.map(label=>({...label,color:newColor}))},{...point2,color:newColor,labels:point2.labels.map(label=>({...label,color:newColor}))}],labels:newLabels});}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:props.expanded,onToggle:props.onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$l.row} ${styles$l.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:lineLabel}),jsxRuntimeExports.jsx(LineSwatch,{color:lineColor,lineStyle:lineStyle})]}),children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$l.row} ${styles$l.spaceUnder} ${styles$l.kindLabel}`,children:["kind",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:kind,disabled:editingDisabled,onChange:value=>onChangeProps({kind:value}),placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"line",label:"line"}),jsxRuntimeExports.jsx(OptionItem,{value:"ray",label:"ray"}),jsxRuntimeExports.jsx(OptionItem,{value:"segment",label:"segment"})]})]}),jsxRuntimeExports.jsxs(View,{className:`${styles$l.row} ${styles$l.spaceUnder} ${styles$l.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:lineColor,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:lineStyle,editingDisabled:editingDisabled,onChange:value=>onChangeProps({lineStyle:value})})]}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),isInvalid&&jsxRuntimeExports.jsx(BodyText,{className:styles$l.errorText,children:lengthZeroStr}),jsxRuntimeExports.jsx(LockedPointSettings,{headerLabel:"Point 1",expanded:true,showPoint:showPoint1,error:isInvalid?lengthZeroStr:null,...point1,editingDisabled:editingDisabled,onTogglePoint:newValue=>onChangeProps({showPoint1:newValue}),onChangeProps:newProps=>handleChangePoint(newProps,0)}),jsxRuntimeExports.jsx(LockedPointSettings,{headerLabel:"Point 2",expanded:true,showPoint:showPoint2,error:isInvalid?lengthZeroStr:null,...point2,editingDisabled:editingDisabled,onTogglePoint:newValue=>onChangeProps({showPoint2:newValue}),onChangeProps:newProps=>handleChangePoint(newProps,1)}),jsxRuntimeExports.jsx(View,{className:`${styles$l.horizontalRule} ${styles$l.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$l.horizontalRule} ${styles$l.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$l.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle$2})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const offsetPerLabel=[0,-1];const labelLocation=vec.add(vec.scale(offsetPerLabel,labels.length),vec.midpoint(points[0].coord,points[1].coord));const newLabel={...getDefaultFigureForType("label"),coord:labelLocation,color:lineColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$l.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1718
+ ${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;const isInvalid=vector.equal(point1.coord,point2.coord);async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const point1VisibleLabel=await joinLabelsAsSpokenMath(point1.labels);const point2VisibleLabel=await joinLabelsAsSpokenMath(point2.labels);const spokenPoint1X=await generateSpokenMathDetails(`$${point1.coord[0]}$`);const spokenPoint1Y=await generateSpokenMathDetails(`$${point1.coord[1]}$`);const spokenPoint2X=await generateSpokenMathDetails(`$${point2.coord[0]}$`);const spokenPoint2Y=await generateSpokenMathDetails(`$${point2.coord[1]}$`);let str;switch(kind){case "line":str=`${capitalizeKind}${visiblelabel} through point${point1VisibleLabel} at ${spokenPoint1X} comma ${spokenPoint1Y} and point${point2VisibleLabel} at ${spokenPoint2X} comma ${spokenPoint2Y}`;break;case "ray":str=`${capitalizeKind}${visiblelabel} from point${point1VisibleLabel} at ${spokenPoint1X} comma ${spokenPoint1Y} through point${point2VisibleLabel} at ${spokenPoint2X} comma ${spokenPoint2Y}`;break;case "segment":str=`${capitalizeKind}${visiblelabel} from point${point1VisibleLabel} at ${spokenPoint1X} comma ${spokenPoint1Y} to point${point2VisibleLabel} at ${spokenPoint2X} comma ${spokenPoint2Y}`;break;default:throw new UnreachableCaseError(kind,"Unknown line kind")}const lineAppearance=generateLockedFigureAppearanceDescription(lineColor,lineStyle,undefined,weight);str+=lineAppearance;return str}function handleChangePoint(newPointProps,index){const newPoints=[...points];newPoints[index]={...points[index],...newPointProps};const oldMidpoint=vec.midpoint(points[0].coord,points[1].coord);const newMidpoint=vec.midpoint(newPoints[0].coord,newPoints[1].coord);const offset=[newMidpoint[0]-oldMidpoint[0],newMidpoint[1]-oldMidpoint[1]];const newLabels=labels.map((label,labelIndex)=>({...label,coord:[label.coord[0]+offset[0],label.coord[1]+offset[1]]}));onChangeProps({points:newPoints,labels:newLabels});}function handleColorChange(newColor){const newLabels=labels.map(label=>({...label,color:newColor}));onChangeProps({color:newColor,points:[{...point1,color:newColor,labels:point1.labels.map(label=>({...label,color:newColor}))},{...point2,color:newColor,labels:point2.labels.map(label=>({...label,color:newColor}))}],labels:newLabels});}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:props.expanded,onToggle:props.onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$j.row} ${styles$j.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:lineLabel}),jsxRuntimeExports.jsx(LineSwatch,{color:lineColor,lineStyle:lineStyle})]}),children:[jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$j.row} ${styles$j.spaceUnder} ${styles$j.kindLabel}`,children:["kind",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:kind,disabled:editingDisabled,onChange:value=>onChangeProps({kind:value}),placeholder:"",children:[jsxRuntimeExports.jsx(OptionItem,{value:"line",label:"line"}),jsxRuntimeExports.jsx(OptionItem,{value:"ray",label:"ray"}),jsxRuntimeExports.jsx(OptionItem,{value:"segment",label:"segment"})]})]}),jsxRuntimeExports.jsxs(View,{className:`${styles$j.row} ${styles$j.spaceUnder} ${styles$j.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:lineColor,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:lineStyle,editingDisabled:editingDisabled,onChange:value=>onChangeProps({lineStyle:value})})]}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),isInvalid&&jsxRuntimeExports.jsx(BodyText,{className:styles$j.errorText,children:lengthZeroStr}),jsxRuntimeExports.jsx(LockedPointSettings,{headerLabel:"Point 1",expanded:true,showPoint:showPoint1,error:isInvalid?lengthZeroStr:null,...point1,editingDisabled:editingDisabled,onTogglePoint:newValue=>onChangeProps({showPoint1:newValue}),onChangeProps:newProps=>handleChangePoint(newProps,0)}),jsxRuntimeExports.jsx(LockedPointSettings,{headerLabel:"Point 2",expanded:true,showPoint:showPoint2,error:isInvalid?lengthZeroStr:null,...point2,editingDisabled:editingDisabled,onTogglePoint:newValue=>onChangeProps({showPoint2:newValue}),onChangeProps:newProps=>handleChangePoint(newProps,1)}),jsxRuntimeExports.jsx(View,{className:`${styles$j.horizontalRule} ${styles$j.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$j.horizontalRule} ${styles$j.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$j.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle$2})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const offsetPerLabel=[0,-1];const labelLocation=vec.add(vec.scale(offsetPerLabel,labels.length),vec.midpoint(points[0].coord,points[1].coord));const newLabel={...getDefaultFigureForType("label"),coord:labelLocation,color:lineColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$j.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1712
1719
 
1713
- var styles$j = {"row":"perseus_7gvpLIxX","header":"perseus_a9dhxydf","spaceUnder":"perseus_FMC5CN4y","colorRow":"perseus_bj3iyVpL","fillLabel":"perseus_gbGj72Hu","icon":"perseus_DYnWU1Yr","polygonActionsContainer":"perseus_YhcLg4qs","movementButtonsContainer":"perseus_DtEDhGzL","truncatedWidth":"perseus_14L-Mr6p","addButton":"perseus_dc8k1hRY","horizontalRule":"perseus_iR-te9L8","sectionTop":"perseus_q3l-Nth6","dividerTight":"perseus_WNA-ZWQ8"};
1720
+ var styles$h = {"row":"perseus_7gvpLIxX","header":"perseus_a9dhxydf","spaceUnder":"perseus_FMC5CN4y","colorRow":"perseus_bj3iyVpL","fillLabel":"perseus_gbGj72Hu","icon":"perseus_DYnWU1Yr","polygonActionsContainer":"perseus_YhcLg4qs","movementButtonsContainer":"perseus_DtEDhGzL","truncatedWidth":"perseus_14L-Mr6p","addButton":"perseus_dc8k1hRY","horizontalRule":"perseus_iR-te9L8","sectionTop":"perseus_q3l-Nth6","dividerTight":"perseus_WNA-ZWQ8"};
1714
1721
 
1715
- const PolygonSwatch=props=>{const{color,fillStyle,strokeStyle}=props;return jsxRuntimeExports.jsx(View,{"aria-label":`${color}, stroke ${strokeStyle}, fill ${fillStyle}`,style:[styles$i.container,{border:`4px ${strokeStyle} ${lockedFigureColors[color]}`}],children:jsxRuntimeExports.jsx(View,{style:[styles$i.innerSquare,{backgroundColor:lockedFigureColors[color],opacity:fillStyle==="white"?0:lockedFigureFillStyles[fillStyle]}]})})};const styles$i=StyleSheet.create({container:{outline:`2px solid ${semanticColor.focus.inner}`,width:spacing.large_24,height:spacing.large_24,backgroundColor:semanticColor.core.background.base.default,alignItems:"center",justifyContent:"center"},innerSquare:{width:20,height:20}});
1722
+ const PolygonSwatch=props=>{const{color,fillStyle,strokeStyle}=props;return jsxRuntimeExports.jsx(View,{"aria-label":`${color}, stroke ${strokeStyle}, fill ${fillStyle}`,style:[styles$g.container,{border:`4px ${strokeStyle} ${lockedFigureColors[color]}`}],children:jsxRuntimeExports.jsx(View,{style:[styles$g.innerSquare,{backgroundColor:lockedFigureColors[color],opacity:fillStyle==="white"?0:lockedFigureFillStyles[fillStyle]}]})})};const styles$g=StyleSheet.create({container:{outline:`2px solid ${semanticColor.focus.inner}`,width:spacing.large_24,height:spacing.large_24,backgroundColor:semanticColor.core.background.base.default,alignItems:"center",justifyContent:"center"},innerSquare:{width:20,height:20}});
1716
1723
 
1717
- const spaceUnderStyle={marginBottom:sizing.size_080};const pointAccordionContainerStyle={backgroundColor:semanticColor.core.background.base.default};const pointAccordionPanelStyle={alignItems:"start"};const labelContainerStyle$1={backgroundColor:semanticColor.core.background.base.default};const LockedPolygonSettings=props=>{const{points,color,showVertices,fillStyle,strokeStyle,weight,labels,ariaLabel,expanded,editingDisabled=false,onToggle,onChangeProps,onMove,onRemove}=props;async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);let str=`Polygon${visiblelabel} with ${points.length} sides, vertices at `;const pointsList=await Promise.all(points.map(async([x,y])=>{const spokenX=await generateSpokenMathDetails(`$${x}$`);const spokenY=await generateSpokenMathDetails(`$${y}$`);return `${spokenX} comma ${spokenY}`}));str+=pointsList.join(", ");const polygonAppearance=generateLockedFigureAppearanceDescription(color,strokeStyle,fillStyle,weight);str+=polygonAppearance;return str}function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handlePolygonMove(movement){switch(movement){case "up":onChangeProps({points:points.map(([x,y])=>[x,y+1]),labels:labels.map(label=>({...label,coord:[label.coord[0],label.coord[1]+1]}))});break;case "down":onChangeProps({points:points.map(([x,y])=>[x,y-1]),labels:labels.map(label=>({...label,coord:[label.coord[0],label.coord[1]-1]}))});break;case "left":onChangeProps({points:points.map(([x,y])=>[x-1,y]),labels:labels.map(label=>({...label,coord:[label.coord[0]-1,label.coord[1]]}))});break;case "right":onChangeProps({points:points.map(([x,y])=>[x+1,y]),labels:labels.map(label=>({...label,coord:[label.coord[0]+1,label.coord[1]]}))});break}}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$j.row} ${styles$j.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`Polygon, ${points.length} sides`}),jsxRuntimeExports.jsx(PolygonSwatch,{color:color,fillStyle:fillStyle,strokeStyle:strokeStyle})]}),children:[jsxRuntimeExports.jsxs(View,{className:`${styles$j.row} ${styles$j.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:color,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$j.row} ${styles$j.truncatedWidth} ${styles$j.fillLabel}`,children:["fill",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:fillStyle,disabled:editingDisabled,onChange:value=>onChangeProps({fillStyle:value}),placeholder:"",children:Object.keys(lockedFigureFillStyles).map(option=>jsxRuntimeExports.jsx(OptionItem,{value:option,label:option},option))})]})]}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:strokeStyle,editingDisabled:editingDisabled,onChange:value=>onChangeProps({strokeStyle:value}),containerStyle:spaceUnderStyle}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value}),containerStyle:spaceUnderStyle}),jsxRuntimeExports.jsx(LabeledSwitch,{label:"show vertices",checked:showVertices,disabled:editingDisabled,onChange:newValue=>onChangeProps({showVertices:newValue}),style:spaceUnderStyle}),jsxRuntimeExports.jsxs(PerseusEditorAccordion,{header:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Points"}),expanded:true,containerStyle:pointAccordionContainerStyle,panelStyle:pointAccordionPanelStyle,children:[points.map((point,index)=>{const pointLabel=String.fromCharCode(65+index);return jsxRuntimeExports.jsxs(View,{className:`${styles$j.row} ${styles$j.spaceUnder}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",children:`${pointLabel}:`}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:point,labels:["x","y"],style:{marginInlineStart:sizing.size_160},disabled:editingDisabled,onChange:newValue=>{const newPoints=[...points];newPoints[index]=newValue;props.onChangeProps({points:newPoints});}}),points.length>3&&jsxRuntimeExports.jsx(IconButton,{"aria-label":`Delete polygon point ${pointLabel}`,icon:minusCircle,kind:"tertiary",actionType:"destructive",disabled:editingDisabled,onClick:()=>{const newPoints=[...points];newPoints.splice(index,1);props.onChangeProps({points:newPoints});},className:styles$j.icon})]},`locked-polygon-point-index-${index}`)}),jsxRuntimeExports.jsxs(View,{className:`${styles$j.row} ${styles$j.polygonActionsContainer}`,children:[jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{props.onChangeProps({points:[...points,[0,0]]});},children:"Add point"}),jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsxs(View,{className:styles$j.movementButtonsContainer,children:[jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon up",size:"small",icon:arrowFatUp,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("up")}),jsxRuntimeExports.jsxs(View,{className:styles$j.row,children:[jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon left",size:"small",icon:arrowFatLeft,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("left")}),jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon down",size:"small",icon:arrowFatDown,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("down")}),jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon right",size:"small",icon:arrowFatRight,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("right")})]})]})]})]}),jsxRuntimeExports.jsx(View,{className:`${styles$j.horizontalRule} ${styles$j.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$j.horizontalRule} ${styles$j.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$j.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle$1})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[points[0][0],points[0][1]-labels.length],color:color};onChangeProps({labels:[...labels,newLabel]});},className:styles$j.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1724
+ const spaceUnderStyle={marginBottom:sizing.size_080};const pointAccordionContainerStyle={backgroundColor:semanticColor.core.background.base.default};const pointAccordionPanelStyle={alignItems:"start"};const labelContainerStyle$1={backgroundColor:semanticColor.core.background.base.default};const LockedPolygonSettings=props=>{const{points,color,showVertices,fillStyle,strokeStyle,weight,labels,ariaLabel,expanded,editingDisabled=false,onToggle,onChangeProps,onMove,onRemove}=props;async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);let str=`Polygon${visiblelabel} with ${points.length} sides, vertices at `;const pointsList=await Promise.all(points.map(async([x,y])=>{const spokenX=await generateSpokenMathDetails(`$${x}$`);const spokenY=await generateSpokenMathDetails(`$${y}$`);return `${spokenX} comma ${spokenY}`}));str+=pointsList.join(", ");const polygonAppearance=generateLockedFigureAppearanceDescription(color,strokeStyle,fillStyle,weight);str+=polygonAppearance;return str}function handleColorChange(newValue){const newProps={color:newValue};newProps.labels=labels.map(label=>({...label,color:newValue}));onChangeProps(newProps);}function handlePolygonMove(movement){switch(movement){case "up":onChangeProps({points:points.map(([x,y])=>[x,y+1]),labels:labels.map(label=>({...label,coord:[label.coord[0],label.coord[1]+1]}))});break;case "down":onChangeProps({points:points.map(([x,y])=>[x,y-1]),labels:labels.map(label=>({...label,coord:[label.coord[0],label.coord[1]-1]}))});break;case "left":onChangeProps({points:points.map(([x,y])=>[x-1,y]),labels:labels.map(label=>({...label,coord:[label.coord[0]-1,label.coord[1]]}))});break;case "right":onChangeProps({points:points.map(([x,y])=>[x+1,y]),labels:labels.map(label=>({...label,coord:[label.coord[0]+1,label.coord[1]]}))});break}}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:expanded,onToggle:onToggle,header:jsxRuntimeExports.jsxs(View,{className:`${styles$h.row} ${styles$h.header}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`Polygon, ${points.length} sides`}),jsxRuntimeExports.jsx(PolygonSwatch,{color:color,fillStyle:fillStyle,strokeStyle:strokeStyle})]}),children:[jsxRuntimeExports.jsxs(View,{className:`${styles$h.row} ${styles$h.colorRow}`,children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:color,editingDisabled:editingDisabled,onChange:handleColorChange}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:`${styles$h.row} ${styles$h.truncatedWidth} ${styles$h.fillLabel}`,children:["fill",jsxRuntimeExports.jsx(SingleSelect,{selectedValue:fillStyle,disabled:editingDisabled,onChange:value=>onChangeProps({fillStyle:value}),placeholder:"",children:Object.keys(lockedFigureFillStyles).map(option=>jsxRuntimeExports.jsx(OptionItem,{value:option,label:option},option))})]})]}),jsxRuntimeExports.jsx(LineStrokeSelect,{selectedValue:strokeStyle,editingDisabled:editingDisabled,onChange:value=>onChangeProps({strokeStyle:value}),containerStyle:spaceUnderStyle}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value}),containerStyle:spaceUnderStyle}),jsxRuntimeExports.jsx(LabeledSwitch,{label:"show vertices",checked:showVertices,disabled:editingDisabled,onChange:newValue=>onChangeProps({showVertices:newValue}),style:spaceUnderStyle}),jsxRuntimeExports.jsxs(PerseusEditorAccordion,{header:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Points"}),expanded:true,containerStyle:pointAccordionContainerStyle,panelStyle:pointAccordionPanelStyle,children:[points.map((point,index)=>{const pointLabel=String.fromCharCode(65+index);return jsxRuntimeExports.jsxs(View,{className:`${styles$h.row} ${styles$h.spaceUnder}`,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",children:`${pointLabel}:`}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:point,labels:["x","y"],style:{marginInlineStart:sizing.size_160},disabled:editingDisabled,onChange:newValue=>{const newPoints=[...points];newPoints[index]=newValue;props.onChangeProps({points:newPoints});}}),points.length>3&&jsxRuntimeExports.jsx(IconButton,{"aria-label":`Delete polygon point ${pointLabel}`,icon:minusCircle,kind:"tertiary",actionType:"destructive",disabled:editingDisabled,onClick:()=>{const newPoints=[...points];newPoints.splice(index,1);props.onChangeProps({points:newPoints});},className:styles$h.icon})]},`locked-polygon-point-index-${index}`)}),jsxRuntimeExports.jsxs(View,{className:`${styles$h.row} ${styles$h.polygonActionsContainer}`,children:[jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{props.onChangeProps({points:[...points,[0,0]]});},children:"Add point"}),jsxRuntimeExports.jsx(Spring,{}),jsxRuntimeExports.jsxs(View,{className:styles$h.movementButtonsContainer,children:[jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon up",size:"small",icon:arrowFatUp,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("up")}),jsxRuntimeExports.jsxs(View,{className:styles$h.row,children:[jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon left",size:"small",icon:arrowFatLeft,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("left")}),jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon down",size:"small",icon:arrowFatDown,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("down")}),jsxRuntimeExports.jsx(IconButton,{"aria-label":"Move polygon right",size:"small",icon:arrowFatRight,kind:"tertiary",disabled:editingDisabled,onClick:()=>handlePolygonMove("right")})]})]})]})]}),jsxRuntimeExports.jsx(View,{className:`${styles$h.horizontalRule} ${styles$h.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$h.horizontalRule} ${styles$h.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$h.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle$1})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const newLabel={...getDefaultFigureForType("label"),coord:[points[0][0],points[0][1]-labels.length],color:color};onChangeProps({labels:[...labels,newLabel]});},className:styles$h.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1718
1725
 
1719
- var styles$h = {"row":"perseus_Ug-lFL8r","errorText":"perseus_6gvwJ939","addButton":"perseus_vcxh5KIo","horizontalRule":"perseus_HRitDKmQ","sectionTop":"perseus_QY6CaDZH","dividerTight":"perseus_QDq7G5V4"};
1726
+ var styles$f = {"row":"perseus_Ug-lFL8r","errorText":"perseus_6gvwJ939","addButton":"perseus_vcxh5KIo","horizontalRule":"perseus_HRitDKmQ","sectionTop":"perseus_QY6CaDZH","dividerTight":"perseus_QDq7G5V4"};
1720
1727
 
1721
- const lengthErrorMessage="The vector cannot have length 0.";const coordsAccordionContainerStyle={marginTop:sizing.size_080,marginBottom:0,marginLeft:-sizing.size_040,marginRight:-sizing.size_040,backgroundColor:semanticColor.core.background.base.default};const coordsAccordionPanelStyle={paddingBottom:sizing.size_160};const labelContainerStyle={backgroundColor:semanticColor.core.background.base.default};const LockedVectorSettings=props=>{const{points,color:lineColor,weight,labels,ariaLabel,editingDisabled=false,onChangeProps,onMove,onRemove}=props;const[tail,tip]=points;const lineLabel=`Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;const isInvalid=vector.equal(tail,tip);async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const spokenTailX=await generateSpokenMathDetails(`$${tail[0]}$`);const spokenTailY=await generateSpokenMathDetails(`$${tail[1]}$`);const spokenTipX=await generateSpokenMathDetails(`$${tip[0]}$`);const spokenTipY=await generateSpokenMathDetails(`$${tip[1]}$`);let str=`Vector${visiblelabel} from ${spokenTailX} comma ${spokenTailY} to ${spokenTipX} comma ${spokenTipY}`;const vectorAppearance=generateLockedFigureAppearanceDescription(lineColor,"solid",undefined,weight);str+=vectorAppearance;return str}function handleChangePoint(newCoord,index){if(typeof newCoord!=="undefined"){const newPoints=[...points];newPoints[index]=[...newCoord];const oldMidpoint=vec.midpoint(tail,tip);const newMidpoint=vec.midpoint(newPoints[0],newPoints[1]);const offset=vec.sub(newMidpoint,oldMidpoint);const newLabels=labels.map(label=>({...label,coord:vec.add(label.coord,offset)}));onChangeProps({points:newPoints,labels:newLabels});}}function handleColorChange(newColor){const newProps={color:newColor};newProps.labels=labels.map(label=>({...label,color:newColor}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:props.expanded,onToggle:props.onToggle,header:jsxRuntimeExports.jsxs(View,{className:styles$h.row,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:lineLabel}),jsxRuntimeExports.jsx(LineSwatch,{color:lineColor,lineStyle:"solid"})]}),children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:lineColor,editingDisabled:editingDisabled,onChange:handleColorChange,style:{marginBottom:sizing.size_080}}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),isInvalid&&jsxRuntimeExports.jsx(BodyText,{className:styles$h.errorText,children:lengthErrorMessage}),jsxRuntimeExports.jsx(PerseusEditorAccordion,{expanded:true,containerStyle:coordsAccordionContainerStyle,panelStyle:coordsAccordionPanelStyle,header:jsxRuntimeExports.jsx(View,{className:styles$h.row,children:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`Tail (${tail[0]}, ${tail[1]})`})}),children:jsxRuntimeExports.jsx(CoordinatePairInput,{coord:tail,error:isInvalid,disabled:editingDisabled,onChange:newProps=>{handleChangePoint(newProps,0);}})}),jsxRuntimeExports.jsx(PerseusEditorAccordion,{expanded:true,containerStyle:coordsAccordionContainerStyle,panelStyle:coordsAccordionPanelStyle,header:jsxRuntimeExports.jsx(View,{className:styles$h.row,children:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`Tip (${tip[0]}, ${tip[1]})`})}),children:jsxRuntimeExports.jsx(CoordinatePairInput,{coord:tip,error:isInvalid,disabled:editingDisabled,onChange:newProps=>{handleChangePoint(newProps,1);}})}),jsxRuntimeExports.jsx(View,{className:`${styles$h.horizontalRule} ${styles$h.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$h.horizontalRule} ${styles$h.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$h.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const offsetPerLabel=[0,-1];const labelLocation=vec.add(vec.scale(offsetPerLabel,labels.length),vec.midpoint(tail,tip));const newLabel={...getDefaultFigureForType("label"),coord:labelLocation,color:lineColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$h.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1728
+ const lengthErrorMessage="The vector cannot have length 0.";const coordsAccordionContainerStyle={marginTop:sizing.size_080,marginBottom:0,marginLeft:-sizing.size_040,marginRight:-sizing.size_040,backgroundColor:semanticColor.core.background.base.default};const coordsAccordionPanelStyle={paddingBottom:sizing.size_160};const labelContainerStyle={backgroundColor:semanticColor.core.background.base.default};const LockedVectorSettings=props=>{const{points,color:lineColor,weight,labels,ariaLabel,editingDisabled=false,onChangeProps,onMove,onRemove}=props;const[tail,tip]=points;const lineLabel=`Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;const isInvalid=vector.equal(tail,tip);async function getPrepopulatedAriaLabel(){const visiblelabel=await joinLabelsAsSpokenMath(labels);const spokenTailX=await generateSpokenMathDetails(`$${tail[0]}$`);const spokenTailY=await generateSpokenMathDetails(`$${tail[1]}$`);const spokenTipX=await generateSpokenMathDetails(`$${tip[0]}$`);const spokenTipY=await generateSpokenMathDetails(`$${tip[1]}$`);let str=`Vector${visiblelabel} from ${spokenTailX} comma ${spokenTailY} to ${spokenTipX} comma ${spokenTipY}`;const vectorAppearance=generateLockedFigureAppearanceDescription(lineColor,"solid",undefined,weight);str+=vectorAppearance;return str}function handleChangePoint(newCoord,index){if(typeof newCoord!=="undefined"){const newPoints=[...points];newPoints[index]=[...newCoord];const oldMidpoint=vec.midpoint(tail,tip);const newMidpoint=vec.midpoint(newPoints[0],newPoints[1]);const offset=vec.sub(newMidpoint,oldMidpoint);const newLabels=labels.map(label=>({...label,coord:vec.add(label.coord,offset)}));onChangeProps({points:newPoints,labels:newLabels});}}function handleColorChange(newColor){const newProps={color:newColor};newProps.labels=labels.map(label=>({...label,color:newColor}));onChangeProps(newProps);}function handleLabelChange(updatedLabel,labelIndex){const updatedLabels=[...labels];updatedLabels[labelIndex]={...labels[labelIndex],...updatedLabel};onChangeProps({labels:updatedLabels});}function handleLabelRemove(labelIndex){const updatedLabels=labels.filter((_,index)=>index!==labelIndex);onChangeProps({labels:updatedLabels});}return jsxRuntimeExports.jsxs(PerseusEditorAccordion,{expanded:props.expanded,onToggle:props.onToggle,header:jsxRuntimeExports.jsxs(View,{className:styles$f.row,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:lineLabel}),jsxRuntimeExports.jsx(LineSwatch,{color:lineColor,lineStyle:"solid"})]}),children:[jsxRuntimeExports.jsx(ColorSelect,{selectedValue:lineColor,editingDisabled:editingDisabled,onChange:handleColorChange,style:{marginBottom:sizing.size_080}}),jsxRuntimeExports.jsx(LineWeightSelect,{selectedValue:weight,editingDisabled:editingDisabled,onChange:value=>onChangeProps({weight:value})}),isInvalid&&jsxRuntimeExports.jsx(BodyText,{className:styles$f.errorText,children:lengthErrorMessage}),jsxRuntimeExports.jsx(PerseusEditorAccordion,{expanded:true,containerStyle:coordsAccordionContainerStyle,panelStyle:coordsAccordionPanelStyle,header:jsxRuntimeExports.jsx(View,{className:styles$f.row,children:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`Tail (${tail[0]}, ${tail[1]})`})}),children:jsxRuntimeExports.jsx(CoordinatePairInput,{coord:tail,error:isInvalid,disabled:editingDisabled,onChange:newProps=>{handleChangePoint(newProps,0);}})}),jsxRuntimeExports.jsx(PerseusEditorAccordion,{expanded:true,containerStyle:coordsAccordionContainerStyle,panelStyle:coordsAccordionPanelStyle,header:jsxRuntimeExports.jsx(View,{className:styles$f.row,children:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`Tip (${tip[0]}, ${tip[1]})`})}),children:jsxRuntimeExports.jsx(CoordinatePairInput,{coord:tip,error:isInvalid,disabled:editingDisabled,onChange:newProps=>{handleChangePoint(newProps,1);}})}),jsxRuntimeExports.jsx(View,{className:`${styles$f.horizontalRule} ${styles$f.sectionTop}`}),jsxRuntimeExports.jsx(LockedFigureAria,{ariaLabel:ariaLabel,getPrepopulatedAriaLabel:getPrepopulatedAriaLabel,editingDisabled:editingDisabled,onChangeProps:newProps=>{onChangeProps(newProps);}}),jsxRuntimeExports.jsx(View,{className:`${styles$f.horizontalRule} ${styles$f.dividerTight}`}),jsxRuntimeExports.jsx(BodyText,{className:styles$f.sectionTop,children:"Visible labels"}),labels.map((label,labelIndex)=>createElement(LockedLabelSettings,{...label,key:labelIndex,editingDisabled:editingDisabled,expanded:true,onChangeProps:newLabel=>{handleLabelChange(newLabel,labelIndex);},onRemove:()=>{handleLabelRemove(labelIndex);},containerStyle:labelContainerStyle})),jsxRuntimeExports.jsx(Button,{kind:"tertiary",startIcon:plusCircle,disabled:editingDisabled,onClick:()=>{const offsetPerLabel=[0,-1];const labelLocation=vec.add(vec.scale(offsetPerLabel,labels.length),vec.midpoint(tail,tip));const newLabel={...getDefaultFigureForType("label"),coord:labelLocation,color:lineColor};onChangeProps({labels:[...labels,newLabel]});},className:styles$f.addButton,children:"Add visible label"}),jsxRuntimeExports.jsx(LockedFigureSettingsActions,{figureType:props.type,editingDisabled:editingDisabled,onMove:onMove,onRemove:onRemove})]})};
1722
1729
 
1723
1730
  const LockedFigureSettings=props=>{switch(props.type){case "point":return jsxRuntimeExports.jsx(LockedPointSettings,{...props});case "line":return jsxRuntimeExports.jsx(LockedLineSettings,{...props});case "vector":return jsxRuntimeExports.jsx(LockedVectorSettings,{...props});case "ellipse":return jsxRuntimeExports.jsx(LockedEllipseSettings,{...props});case "polygon":return jsxRuntimeExports.jsx(LockedPolygonSettings,{...props});case "function":return jsxRuntimeExports.jsx(LockedFunctionSettings,{...props});case "label":return jsxRuntimeExports.jsx(LockedLabelSettings,{...props});default:throw new UnreachableCaseError(props)}};
1724
1731
 
1725
- var styles$g = {"buttonContainer":"perseus_GL9hZba7","button":"perseus_JRXpziEg"};
1732
+ var styles$e = {"buttonContainer":"perseus_GL9hZba7","button":"perseus_JRXpziEg"};
1726
1733
 
1727
- const LockedFiguresSection=props=>{const editingDisabled=props.apiOptions?.editingDisabled??false;const collapsedStateArray=Array((props.figures??[]).length).fill(editingDisabled);const[expandedStates,setExpandedStates]=React.useState(collapsedStateArray);const[isExpanded,setIsExpanded]=React.useState(true);const uniqueId=useId();const{figures,onChange}=props;function addLockedFigure(newFigure){const lockedFigures=figures||[];const newProps={lockedFigures:[...lockedFigures,getDefaultFigureForType(newFigure)]};onChange(newProps);setExpandedStates([...expandedStates,true]);}function moveLockedFigure(index,movement){if(index===0&&(movement==="back"||movement==="backward")){return}if(figures&&index===figures.length-1&&(movement==="front"||movement==="forward")){return}const lockedFigures=figures||[];const newFigures=[...lockedFigures];const newExpandedStates=[...expandedStates];const[removedFigure]=newFigures.splice(index,1);newExpandedStates.splice(index,1);switch(movement){case "back":newFigures.unshift(removedFigure);newExpandedStates.unshift(true);break;case "backward":newFigures.splice(index-1,0,removedFigure);newExpandedStates.splice(index-1,0,true);break;case "forward":newFigures.splice(index+1,0,removedFigure);newExpandedStates.splice(index+1,0,true);break;case "front":newFigures.push(removedFigure);newExpandedStates.push(true);break}onChange({lockedFigures:newFigures});setExpandedStates(newExpandedStates);}function removeLockedFigure(index){if(window.confirm("Are you sure you want to delete this figure?")){const lockedFigures=figures||[];onChange({lockedFigures:[...lockedFigures.slice(0,index),...lockedFigures.slice(index+1)]});const newExpandedStates=[...expandedStates];newExpandedStates.splice(index,1);setExpandedStates(newExpandedStates);}}function changeProps(index,figureProps){const lockedFigures=figures||[];const newFigures={lockedFigures:[...lockedFigures.slice(0,index),{...lockedFigures[index],...figureProps},...lockedFigures.slice(index+1)]};onChange(newFigures);}function toggleExpanded(newValue){setExpandedStates(Array(figures?.length).fill(newValue));}const allCollapsed=expandedStates.every(value=>!value);const buttonLabel=allCollapsed?"Expand all":"Collapse all";const showExpandButton=!!figures?.length;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Locked Figures",isOpen:isExpanded,onToggle:()=>setIsExpanded(!isExpanded),isCollapsible:true}),isExpanded&&jsxRuntimeExports.jsxs(View,{children:[figures?.map((figure,index)=>{return jsxRuntimeExports.jsx(LockedFigureSettings,{expanded:expandedStates[index],onToggle:newValue=>{const newExpanded=[...expandedStates];newExpanded[index]=newValue;setExpandedStates(newExpanded);},...figure,editingDisabled:editingDisabled,onChangeProps:newProps=>changeProps(index,newProps),onMove:movement=>moveLockedFigure(index,movement),onRemove:()=>removeLockedFigure(index)},`${uniqueId}-locked-${figure}-${index}`)}),jsxRuntimeExports.jsxs(View,{className:styles$g.buttonContainer,children:[jsxRuntimeExports.jsx(LockedFigureSelect,{id:`${uniqueId}-select`,editingDisabled:editingDisabled,onChange:addLockedFigure}),showExpandButton&&jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:editingDisabled,onClick:()=>toggleExpanded(allCollapsed),className:styles$g.button,children:buttonLabel})]})]})]})};
1734
+ const LockedFiguresSection=props=>{const editingDisabled=props.apiOptions?.editingDisabled??false;const collapsedStateArray=Array((props.figures??[]).length).fill(editingDisabled);const[expandedStates,setExpandedStates]=React.useState(collapsedStateArray);const[isExpanded,setIsExpanded]=React.useState(true);const uniqueId=useId();const{figures,onChange}=props;function addLockedFigure(newFigure){const lockedFigures=figures||[];const newProps={lockedFigures:[...lockedFigures,getDefaultFigureForType(newFigure)]};onChange(newProps);setExpandedStates([...expandedStates,true]);}function moveLockedFigure(index,movement){if(index===0&&(movement==="back"||movement==="backward")){return}if(figures&&index===figures.length-1&&(movement==="front"||movement==="forward")){return}const lockedFigures=figures||[];const newFigures=[...lockedFigures];const newExpandedStates=[...expandedStates];const[removedFigure]=newFigures.splice(index,1);newExpandedStates.splice(index,1);switch(movement){case "back":newFigures.unshift(removedFigure);newExpandedStates.unshift(true);break;case "backward":newFigures.splice(index-1,0,removedFigure);newExpandedStates.splice(index-1,0,true);break;case "forward":newFigures.splice(index+1,0,removedFigure);newExpandedStates.splice(index+1,0,true);break;case "front":newFigures.push(removedFigure);newExpandedStates.push(true);break}onChange({lockedFigures:newFigures});setExpandedStates(newExpandedStates);}function removeLockedFigure(index){if(window.confirm("Are you sure you want to delete this figure?")){const lockedFigures=figures||[];onChange({lockedFigures:[...lockedFigures.slice(0,index),...lockedFigures.slice(index+1)]});const newExpandedStates=[...expandedStates];newExpandedStates.splice(index,1);setExpandedStates(newExpandedStates);}}function changeProps(index,figureProps){const lockedFigures=figures||[];const newFigures={lockedFigures:[...lockedFigures.slice(0,index),{...lockedFigures[index],...figureProps},...lockedFigures.slice(index+1)]};onChange(newFigures);}function toggleExpanded(newValue){setExpandedStates(Array(figures?.length).fill(newValue));}const allCollapsed=expandedStates.every(value=>!value);const buttonLabel=allCollapsed?"Expand all":"Collapse all";const showExpandButton=!!figures?.length;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(Heading,{title:"Locked Figures",isOpen:isExpanded,onToggle:()=>setIsExpanded(!isExpanded),isCollapsible:true}),isExpanded&&jsxRuntimeExports.jsxs(View,{children:[figures?.map((figure,index)=>{return jsxRuntimeExports.jsx(LockedFigureSettings,{expanded:expandedStates[index],onToggle:newValue=>{const newExpanded=[...expandedStates];newExpanded[index]=newValue;setExpandedStates(newExpanded);},...figure,editingDisabled:editingDisabled,onChangeProps:newProps=>changeProps(index,newProps),onMove:movement=>moveLockedFigure(index,movement),onRemove:()=>removeLockedFigure(index)},`${uniqueId}-locked-${figure}-${index}`)}),jsxRuntimeExports.jsxs(View,{className:styles$e.buttonContainer,children:[jsxRuntimeExports.jsx(LockedFigureSelect,{id:`${uniqueId}-select`,editingDisabled:editingDisabled,onChange:addLockedFigure}),showExpandButton&&jsxRuntimeExports.jsx(Button,{kind:"secondary",disabled:editingDisabled,onClick:()=>toggleExpanded(allCollapsed),className:styles$e.button,children:buttonLabel})]})]})]})};
1728
1735
 
1729
- var styles$f = {"tile":"perseus_9oJAXCGH","tileRow":"perseus_4KcHH9Bl","labelField":"perseus_Ry1WVaFB","labelPrefix":"perseus_aVULDXX8","text-field-wrapper":"perseus_37eFZ7ym","pointLabelField":"perseus_cDLqevTf","equationSection":"perseus_aqjusrqZ","equationBody":"perseus_oT9y-KpN","resetButton":"perseus_sK1-PDYK"};
1736
+ var styles$d = {"tile":"perseus_9oJAXCGH","tileRow":"perseus_4KcHH9Bl","labelField":"perseus_Ry1WVaFB","labelPrefix":"perseus_aVULDXX8","text-field-wrapper":"perseus_37eFZ7ym","pointLabelField":"perseus_cDLqevTf","equationSection":"perseus_aqjusrqZ","equationBody":"perseus_oT9y-KpN","resetButton":"perseus_sK1-PDYK"};
1730
1737
 
1731
- const CoordInput=props=>{const{label,coord,onChange,pointLabel,onPointLabelChange}=props;if(onPointLabelChange){const placeholder=label.match(/\d+$/)?.[0]??label;return jsxRuntimeExports.jsxs(View,{className:styles$f.tile,children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:`${label}:`}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,labels:["x","y"],onChange:onChange,labelStyle:{minWidth:40,textAlign:"right"}}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$f.labelField,children:[jsxRuntimeExports.jsx("span",{className:styles$f.labelPrefix,children:"Label"}),jsxRuntimeExports.jsx(View,{className:styles$f.pointLabelField,children:jsxRuntimeExports.jsx(TextField,{"aria-label":`${label} name`,value:pointLabel??"",placeholder:placeholder,onChange:onPointLabelChange})})]})]})}return jsxRuntimeExports.jsxs(View,{className:styles$f.tileRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:`${label}:`}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,labels:["x","y"],onChange:onChange})]})};
1738
+ const CoordInput=props=>{const{label,coord,onChange,pointLabel,onPointLabelChange}=props;if(onPointLabelChange){const placeholder=label.match(/\d+$/)?.[0]??label;return jsxRuntimeExports.jsxs(View,{className:styles$d.tile,children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:`${label}:`}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,labels:["x","y"],onChange:onChange,labelStyle:{minWidth:40,textAlign:"right"}}),jsxRuntimeExports.jsxs(BodyText,{tag:"label",className:styles$d.labelField,children:[jsxRuntimeExports.jsx("span",{className:styles$d.labelPrefix,children:"Label"}),jsxRuntimeExports.jsx(View,{className:styles$d.pointLabelField,children:jsxRuntimeExports.jsx(TextField,{"aria-label":`${label} name`,value:pointLabel??"",placeholder:placeholder,onChange:onPointLabelChange})})]})]})}return jsxRuntimeExports.jsxs(View,{className:styles$d.tileRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:`${label}:`}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:coord,labels:["x","y"],onChange:onChange})]})};
1732
1739
 
1733
1740
  const StartCoordsAbsoluteValue=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const[vertex,arm]=startCoords;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CoordInput,{label:"Vertex",coord:vertex,onChange:value=>onChange([value,arm]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Arm",coord:arm,onChange:value=>onChange([vertex,value]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)})]})};
1734
1741
 
1735
1742
  const{getClockwiseAngle}=angles;function getStartCoords(graph){if("startCoords"in graph){return graph.startCoords}return undefined}function getDefaultGraphStartCoords(graph,range,step){switch(graph.type){case "absolute-value":return getAbsoluteValueCoords({...graph,startCoords:undefined},range,step);case "linear":case "ray":return getLineCoords({...graph,startCoords:undefined},range,step);case "vector":return getVectorCoords({...graph,startCoords:undefined},range,step);case "segment":return getSegmentCoords({...graph,startCoords:undefined},range,step);case "linear-system":return getLinearSystemCoords({...graph,startCoords:undefined},range,step);case "circle":const startCoords=getCircleCoords({...graph,startCoords:undefined});const radius=vector.length(vector.subtract(startCoords.radiusPoint,startCoords.center));return {center:startCoords.center,radius};case "sinusoid":return getSinusoidCoords({...graph,startCoords:undefined},range,step);case "exponential":{const{coords,asymptote}=getExponentialCoords({...graph,startCoords:undefined},range,step);return {coords,asymptote}}case "tangent":return getTangentCoords({...graph,startCoords:undefined},range,step);case "quadratic":return getQuadraticCoords({...graph,startCoords:undefined},range,step);case "point":return getPointCoords({...graph,startCoords:undefined},range,step);case "polygon":return getPolygonCoords({...graph,startCoords:undefined},range,step);case "angle":return getAngleCoords({graph:{...graph,startCoords:undefined},range,step});case "logarithm":{const{coords,asymptote}=getLogarithmCoords({...graph,startCoords:undefined},range,step);return {coords,asymptote}}default:return undefined}}const getSinusoidEquation=startCoords=>{const p1=startCoords[0];const p2=startCoords[1];const amplitude=p2[1]-p1[1];const angularFrequency=Math.PI/(2*(p2[0]-p1[0]));const phase=p1[0]*angularFrequency;const verticalOffset=p1[1];return "y = "+amplitude.toFixed(3)+"sin("+angularFrequency.toFixed(3)+"x - "+phase.toFixed(3)+") + "+verticalOffset.toFixed(3)};const getTangentEquation=startCoords=>{const p1=startCoords[0];const p2=startCoords[1];const amplitude=p2[1]-p1[1];const angularFrequency=Math.PI/(4*(p2[0]-p1[0]));const phase=p1[0]*angularFrequency;const verticalOffset=p1[1];return "y = "+amplitude.toFixed(3)+"tan("+angularFrequency.toFixed(3)+"x - "+phase.toFixed(3)+") + "+verticalOffset.toFixed(3)};const getQuadraticEquation=startCoords=>{const p1=startCoords[0];const p2=startCoords[1];const p3=startCoords[2];const denom=(p1[0]-p2[0])*(p1[0]-p3[0])*(p2[0]-p3[0]);if(denom===0){return "Division by zero error"}const a=(p3[0]*(p2[1]-p1[1])+p2[0]*(p1[1]-p3[1])+p1[0]*(p3[1]-p2[1]))/denom;const b=(p3[0]*p3[0]*(p1[1]-p2[1])+p2[0]*p2[0]*(p3[1]-p1[1])+p1[0]*p1[0]*(p2[1]-p3[1]))/denom;const c=(p2[0]*p3[0]*(p2[0]-p3[0])*p1[1]+p3[0]*p1[0]*(p3[0]-p1[0])*p2[1]+p1[0]*p2[0]*(p1[0]-p2[0])*p3[1])/denom;return "y = "+a.toFixed(3)+"x^2 + "+b.toFixed(3)+"x + "+c.toFixed(3)};const getLogarithmEquation=(coords,asymptote)=>{const p1=coords[0];const p2=coords[1];if(p1[1]===p2[1]){return "undefined (points share the same y)"}if(p1[0]===asymptote||p2[0]===asymptote){return "undefined (point on asymptote)"}const ratio=(p1[0]-asymptote)/(p2[0]-asymptote);if(ratio<=0){return "undefined (points on opposite sides of asymptote)"}const bExp=Math.log(ratio)/(p1[1]-p2[1]);const aExp=(p1[0]-asymptote)/Math.exp(bExp*p1[1]);if(!isFinite(bExp)||!isFinite(aExp)||aExp===0||bExp===0){return "undefined (invalid coefficients)"}const a=1/bExp;const b=1/aExp;const c=-asymptote/aExp;return "y = "+a.toFixed(3)+"ln("+b.toFixed(3)+"x + "+c.toFixed(3)+")"};const getAngleEquation=(startCoords,allowReflexAngles=false)=>{const vertex=startCoords[1];const roundedAngle=getClockwiseAngle(startCoords,allowReflexAngles).toFixed(0);return `${roundedAngle}\u00B0 angle at (${vertex[0]}, ${vertex[1]})`};const shouldShowStartCoordsUI=(graph,isStatic)=>{if(isStatic){return false}switch(graph.type){case "point":return graph.numPoints!=="unlimited";case "polygon":return graph.numSides!=="unlimited"&&graph.snapTo!=="angles"&&graph.snapTo!=="sides";case "none":return false;case "angle":case "circle":case "exponential":case "linear":case "linear-system":case "tangent":case "quadratic":case "ray":case "segment":case "sinusoid":case "absolute-value":case "logarithm":case "vector":return true;default:throw new UnreachableCaseError(graph)}};
1736
1743
 
1737
- const StartCoordsAngle=props=>{const{startCoords,allowReflexAngles,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??"",index===2?newLabel:pointLabels[2]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{style:styles$e.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{style:styles$e.equationBody,children:getAngleEquation(startCoords,allowReflexAngles)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1],startCoords[2]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Vertex",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value,startCoords[2]]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[2],onChange:value=>onChange([startCoords[0],startCoords[1],value]),pointLabel:pointLabels[2],onPointLabelChange:newLabel=>updatePointLabel(2,newLabel)})]})};const styles$e=StyleSheet.create({equationSection:{marginTop:spacing.small_12},equationBody:{backgroundColor:semanticColor.core.background.neutral.subtle,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,marginTop:spacing.xSmall_8,paddingLeft:spacing.xSmall_8,paddingRight:spacing.xSmall_8,fontSize:font.size.xSmall}});
1744
+ const StartCoordsAngle=props=>{const{startCoords,allowReflexAngles,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??"",index===2?newLabel:pointLabels[2]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{style:styles$c.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{style:styles$c.equationBody,children:getAngleEquation(startCoords,allowReflexAngles)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1],startCoords[2]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Vertex",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value,startCoords[2]]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[2],onChange:value=>onChange([startCoords[0],startCoords[1],value]),pointLabel:pointLabels[2],onPointLabelChange:newLabel=>updatePointLabel(2,newLabel)})]})};const styles$c=StyleSheet.create({equationSection:{marginTop:spacing.small_12},equationBody:{backgroundColor:semanticColor.core.background.neutral.subtle,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,marginTop:spacing.xSmall_8,paddingLeft:spacing.xSmall_8,paddingRight:spacing.xSmall_8,fontSize:font.size.xSmall}});
1738
1745
 
1739
- const StartCoordsCircle=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const[radiusState,setRadiusState]=React.useState(startCoords.radius.toString());React.useEffect(()=>{setRadiusState(startCoords.radius.toString());},[startCoords.radius]);function handleRadiuschange(newValue){setRadiusState(newValue);if(isNaN(+newValue)||newValue===""||+newValue===0){return}onChange({center:startCoords.center,radius:parseFloat(newValue)});}return jsxRuntimeExports.jsxs(View,{style:styles$d.tile,children:[jsxRuntimeExports.jsxs(View,{style:styles$d.row,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Center:"}),jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:startCoords.center,labels:["x","y"],onChange:coord=>onChange({center:coord,radius:startCoords.radius})})]}),jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"label",style:styles$d.row,children:["Radius:",jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:radiusState,onChange:handleRadiuschange,style:styles$d.textField})]}),jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"span",style:styles$d.row,children:["Radius point label:",jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsx(View,{style:styles$d.textField,children:jsxRuntimeExports.jsx(TextField,{"aria-label":"Radius point name",value:pointLabels[0]??"",placeholder:"Radius point",onChange:newLabel=>onChangePointLabels([newLabel])})})]})]})};const styles$d=StyleSheet.create({tile:{backgroundColor:semanticColor.core.background.instructive.subtle,marginTop:spacing.xSmall_8,padding:spacing.small_12,borderRadius:spacing.xSmall_8},row:{display:"flex",flexDirection:"row",alignItems:"center"},textField:{width:spacing.xxxLarge_64}});
1746
+ const StartCoordsCircle=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const[radiusState,setRadiusState]=React.useState(startCoords.radius.toString());React.useEffect(()=>{setRadiusState(startCoords.radius.toString());},[startCoords.radius]);function handleRadiuschange(newValue){setRadiusState(newValue);if(isNaN(+newValue)||newValue===""||+newValue===0){return}onChange({center:startCoords.center,radius:parseFloat(newValue)});}return jsxRuntimeExports.jsxs(View,{style:styles$b.tile,children:[jsxRuntimeExports.jsxs(View,{style:styles$b.row,children:[jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:"Center:"}),jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsx(CoordinatePairInput,{coord:startCoords.center,labels:["x","y"],onChange:coord=>onChange({center:coord,radius:startCoords.radius})})]}),jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"label",style:styles$b.row,children:["Radius:",jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:radiusState,onChange:handleRadiuschange,style:styles$b.textField})]}),jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsxs(BodyText,{size:"medium",weight:"bold",tag:"span",style:styles$b.row,children:["Radius point label:",jsxRuntimeExports.jsx(Strut,{size:spacing.small_12}),jsxRuntimeExports.jsx(View,{style:styles$b.textField,children:jsxRuntimeExports.jsx(TextField,{"aria-label":"Radius point name",value:pointLabels[0]??"",placeholder:"Radius point",onChange:newLabel=>onChangePointLabels([newLabel])})})]})]})};const styles$b=StyleSheet.create({tile:{backgroundColor:semanticColor.core.background.instructive.subtle,marginTop:spacing.xSmall_8,padding:spacing.small_12,borderRadius:spacing.xSmall_8},row:{display:"flex",flexDirection:"row",alignItems:"center"},textField:{width:spacing.xxxLarge_64}});
1740
1747
 
1741
- const AsymptoteInput=props=>{const{axis,value,onChange}=props;const[textState,setTextState]=React.useState(value.toString());React.useEffect(()=>{setTextState(value.toString());},[value]);function handleChange(newValue){setTextState(newValue);if(isNaN(+newValue)||newValue===""){return}onChange(parseFloat(newValue));}return jsxRuntimeExports.jsxs(BodyText,{weight:"bold",tag:"label",className:styles$f.tileRow,children:[`Asymptote ${axis} =`,jsxRuntimeExports.jsx(View,{className:styles$f["text-field-wrapper"],children:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:textState,onChange:handleChange})})]})};
1748
+ const AsymptoteInput=props=>{const{axis,value,onChange}=props;const[textState,setTextState]=React.useState(value.toString());React.useEffect(()=>{setTextState(value.toString());},[value]);function handleChange(newValue){setTextState(newValue);if(isNaN(+newValue)||newValue===""){return}onChange(parseFloat(newValue));}return jsxRuntimeExports.jsxs(BodyText,{weight:"bold",tag:"label",className:styles$d.tileRow,children:[`Asymptote ${axis} =`,jsxRuntimeExports.jsx(View,{className:styles$d["text-field-wrapper"],children:jsxRuntimeExports.jsx(ScrolllessNumberTextField,{value:textState,onChange:handleChange})})]})};
1742
1749
 
1743
1750
  const StartCoordsExponential=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const{coords,asymptote}=startCoords;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:coords[0],onChange:value=>onChange({coords:[value,coords[1]],asymptote}),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:coords[1],onChange:value=>onChange({coords:[coords[0],value],asymptote}),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(AsymptoteInput,{axis:"y",value:asymptote,onChange:newY=>onChange({coords:[coords[0],coords[1]],asymptote:newY})})]})};
1744
1751
 
1745
1752
  const StartCoordsLine=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)})]})};
1746
1753
 
1747
- const StartCoordsLogarithm=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const{coords,asymptote}=startCoords;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$f.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{className:styles$f.equationBody,children:getLogarithmEquation(coords,asymptote)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:coords[0],onChange:value=>onChange({coords:[value,coords[1]],asymptote}),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:coords[1],onChange:value=>onChange({coords:[coords[0],value],asymptote}),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(AsymptoteInput,{axis:"x",value:asymptote,onChange:newX=>onChange({coords:[coords[0],coords[1]],asymptote:newX})})]})};
1754
+ const StartCoordsLogarithm=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const{coords,asymptote}=startCoords;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$d.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{className:styles$d.equationBody,children:getLogarithmEquation(coords,asymptote)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:coords[0],onChange:value=>onChange({coords:[value,coords[1]],asymptote}),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:coords[1],onChange:value=>onChange({coords:[coords[0],value],asymptote}),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(AsymptoteInput,{axis:"x",value:asymptote,onChange:newX=>onChange({coords:[coords[0],coords[1]],asymptote:newX})})]})};
1748
1755
 
1749
1756
  const StartCoordsMultiline=props=>{const{startCoords,type,onChange,pointLabels,onChangePointLabels}=props;const graphName=type==="segment"?"Segment":"Line";const updatePointLabel=(flatIndex,newLabel)=>{const totalPoints=startCoords.length*2;const next=Array.from({length:totalPoints},(_,i)=>i===flatIndex?newLabel:pointLabels[i]??"");onChangePointLabels(next);};return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:startCoords.map((coordPair,i)=>jsxRuntimeExports.jsxs(PerseusEditorAccordion,{header:jsxRuntimeExports.jsx(BodyText,{size:"medium",weight:"bold",tag:"span",children:`${graphName} ${i+1}`}),expanded:true,children:[jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:coordPair[0],onChange:value=>{const newCoords=[...startCoords];newCoords[i]=[value,coordPair[1]];onChange(newCoords);},pointLabel:pointLabels[i*2],onPointLabelChange:newLabel=>updatePointLabel(i*2,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:coordPair[1],onChange:value=>{const newCoords=[...startCoords];newCoords[i]=[coordPair[0],value];onChange(newCoords);},pointLabel:pointLabels[i*2+1],onPointLabelChange:newLabel=>updatePointLabel(i*2+1,newLabel)})]},`segment-${i}-start-coords`))})};
1750
1757
 
1751
1758
  const StartCoordsPoint=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;return jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment,{children:startCoords.map((coord,index)=>jsxRuntimeExports.jsx(CoordInput,{label:`Point ${index+1}`,coord:coord,onChange:newCoord=>{const newStartCoords=[...startCoords];newStartCoords[index]=newCoord;onChange(newStartCoords);},pointLabel:pointLabels?.[index],onPointLabelChange:onChangePointLabels&&(newLabel=>{const next=Array.from({length:startCoords.length},(_,i)=>i===index?newLabel:pointLabels?.[i]??"");onChangePointLabels(next);})},index))})};
1752
1759
 
1753
- const StartCoordsQuadratic=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??"",index===2?newLabel:pointLabels[2]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{style:styles$c.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{style:styles$c.equationBody,children:getQuadraticEquation(startCoords)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1],startCoords[2]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value,startCoords[2]]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 3",coord:startCoords[2],onChange:value=>onChange([startCoords[0],startCoords[1],value]),pointLabel:pointLabels[2],onPointLabelChange:newLabel=>updatePointLabel(2,newLabel)})]})};const styles$c=StyleSheet.create({equationSection:{marginTop:spacing.small_12},equationBody:{backgroundColor:semanticColor.core.background.neutral.subtle,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,marginTop:spacing.xSmall_8,paddingLeft:spacing.xSmall_8,paddingRight:spacing.xSmall_8,fontSize:font.size.xSmall}});
1760
+ const StartCoordsQuadratic=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??"",index===2?newLabel:pointLabels[2]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{style:styles$a.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{style:styles$a.equationBody,children:getQuadraticEquation(startCoords)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1],startCoords[2]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value,startCoords[2]]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 3",coord:startCoords[2],onChange:value=>onChange([startCoords[0],startCoords[1],value]),pointLabel:pointLabels[2],onPointLabelChange:newLabel=>updatePointLabel(2,newLabel)})]})};const styles$a=StyleSheet.create({equationSection:{marginTop:spacing.small_12},equationBody:{backgroundColor:semanticColor.core.background.neutral.subtle,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,marginTop:spacing.xSmall_8,paddingLeft:spacing.xSmall_8,paddingRight:spacing.xSmall_8,fontSize:font.size.xSmall}});
1754
1761
 
1755
- const StartCoordsSinusoid=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{style:styles$b.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{style:styles$b.equationBody,children:getSinusoidEquation(startCoords)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)})]})};const styles$b=StyleSheet.create({equationSection:{marginTop:spacing.small_12},equationBody:{backgroundColor:semanticColor.core.background.neutral.subtle,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,marginTop:spacing.xSmall_8,paddingLeft:spacing.xSmall_8,paddingRight:spacing.xSmall_8,fontSize:font.size.xSmall}});
1762
+ const StartCoordsSinusoid=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{style:styles$9.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{style:styles$9.equationBody,children:getSinusoidEquation(startCoords)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)})]})};const styles$9=StyleSheet.create({equationSection:{marginTop:spacing.small_12},equationBody:{backgroundColor:semanticColor.core.background.neutral.subtle,border:`1px solid ${semanticColor.core.border.neutral.subtle}`,marginTop:spacing.xSmall_8,paddingLeft:spacing.xSmall_8,paddingRight:spacing.xSmall_8,fontSize:font.size.xSmall}});
1756
1763
 
1757
- const StartCoordsTangent=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$f.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{className:styles$f.equationBody,children:getTangentEquation(startCoords)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)})]})};
1764
+ const StartCoordsTangent=props=>{const{startCoords,onChange,pointLabels,onChangePointLabels}=props;const updatePointLabel=(index,newLabel)=>{const next=[index===0?newLabel:pointLabels[0]??"",index===1?newLabel:pointLabels[1]??""];onChangePointLabels(next);};return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$d.equationSection,children:[jsxRuntimeExports.jsx(BodyText,{children:"Starting equation:"}),jsxRuntimeExports.jsx(BodyMonospace,{className:styles$d.equationBody,children:getTangentEquation(startCoords)})]}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1]]),pointLabel:pointLabels[0],onPointLabelChange:newLabel=>updatePointLabel(0,newLabel)}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value]),pointLabel:pointLabels[1],onPointLabelChange:newLabel=>updatePointLabel(1,newLabel)})]})};
1758
1765
 
1759
1766
  const StartCoordsVector=props=>{const{startCoords,onChange}=props;return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(CoordInput,{label:"Point 1",coord:startCoords[0],onChange:value=>onChange([value,startCoords[1]])}),jsxRuntimeExports.jsx(CoordInput,{label:"Point 2",coord:startCoords[1],onChange:value=>onChange([startCoords[0],value])})]})};
1760
1767
 
1761
- const StartCoordsSettingsInner=props=>{const{type,range,step,allowReflexAngles,onChange,onChangePointLabels}=props;switch(type){case "absolute-value":const absoluteValueCoords=getAbsoluteValueCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsAbsoluteValue,{startCoords:absoluteValueCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "linear":case "ray":const linearCoords=getLineCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsLine,{startCoords:linearCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "linear-system":case "segment":const multiLineCoords=type==="segment"?getSegmentCoords(props,range,step):getLinearSystemCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsMultiline,{type:type,startCoords:multiLineCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "circle":const circleCoords=getCircleCoords(props);const radius=vector.length(vector.subtract(circleCoords.radiusPoint,circleCoords.center));return jsxRuntimeExports.jsx(StartCoordsCircle,{startCoords:{center:circleCoords.center,radius},onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "sinusoid":const sinusoidCoords=getSinusoidCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsSinusoid,{startCoords:sinusoidCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "exponential":{const defaultStartCoords=getDefaultGraphStartCoords(props,range,step);const currentStartCoords=props.startCoords??defaultStartCoords;return jsxRuntimeExports.jsx(StartCoordsExponential,{startCoords:currentStartCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels})}case "logarithm":{const defaultLogarithmCoords=getDefaultGraphStartCoords(props,range,step);const currentLogarithmCoords=props.startCoords??defaultLogarithmCoords;return jsxRuntimeExports.jsx(StartCoordsLogarithm,{startCoords:currentLogarithmCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels})}case "vector":{const vectorCoords=getVectorCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsVector,{startCoords:vectorCoords,onChange:onChange})}case "tangent":const tangentCoords=getTangentCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsTangent,{startCoords:tangentCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "quadratic":const quadraticCoords=getQuadraticCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsQuadratic,{startCoords:quadraticCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "point":case "polygon":const pointCoords=type==="point"?getPointCoords(props,range,step):getPolygonCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsPoint,{startCoords:pointCoords,onChange:onChange,pointLabels:props.pointLabels,onChangePointLabels:onChangePointLabels});case "angle":const angleCoords=getAngleCoords({graph:props,range,step});return jsxRuntimeExports.jsx(StartCoordsAngle,{startCoords:angleCoords,allowReflexAngles:allowReflexAngles,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});default:return null}};const StartCoordsSettings=props=>{const{range,step,editingDisabled,onChange}=props;const[isOpen,setIsOpen]=React.useState(true);return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(Heading,{isCollapsible:true,title:"Start coordinates",isOpen:isOpen,onToggle:()=>setIsOpen(!isOpen)}),isOpen&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(StartCoordsSettingsInner,{...props}),jsxRuntimeExports.jsx(View,{className:styles$f.resetButton,children:jsxRuntimeExports.jsx(Button,{startIcon:arrowCounterClockwise,kind:"tertiary",size:"small",disabled:editingDisabled,onClick:()=>{onChange(getDefaultGraphStartCoords(props,range,step));},children:"Use default start coordinates"})})]})]})};
1768
+ const StartCoordsSettingsInner=props=>{const{type,range,step,allowReflexAngles,onChange,onChangePointLabels}=props;switch(type){case "absolute-value":const absoluteValueCoords=getAbsoluteValueCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsAbsoluteValue,{startCoords:absoluteValueCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "linear":case "ray":const linearCoords=getLineCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsLine,{startCoords:linearCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "linear-system":case "segment":const multiLineCoords=type==="segment"?getSegmentCoords(props,range,step):getLinearSystemCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsMultiline,{type:type,startCoords:multiLineCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "circle":const circleCoords=getCircleCoords(props);const radius=vector.length(vector.subtract(circleCoords.radiusPoint,circleCoords.center));return jsxRuntimeExports.jsx(StartCoordsCircle,{startCoords:{center:circleCoords.center,radius},onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "sinusoid":const sinusoidCoords=getSinusoidCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsSinusoid,{startCoords:sinusoidCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "exponential":{const defaultStartCoords=getDefaultGraphStartCoords(props,range,step);const currentStartCoords=props.startCoords??defaultStartCoords;return jsxRuntimeExports.jsx(StartCoordsExponential,{startCoords:currentStartCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels})}case "logarithm":{const defaultLogarithmCoords=getDefaultGraphStartCoords(props,range,step);const currentLogarithmCoords=props.startCoords??defaultLogarithmCoords;return jsxRuntimeExports.jsx(StartCoordsLogarithm,{startCoords:currentLogarithmCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels})}case "vector":{const vectorCoords=getVectorCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsVector,{startCoords:vectorCoords,onChange:onChange})}case "tangent":const tangentCoords=getTangentCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsTangent,{startCoords:tangentCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "quadratic":const quadraticCoords=getQuadraticCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsQuadratic,{startCoords:quadraticCoords,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});case "point":case "polygon":const pointCoords=type==="point"?getPointCoords(props,range,step):getPolygonCoords(props,range,step);return jsxRuntimeExports.jsx(StartCoordsPoint,{startCoords:pointCoords,onChange:onChange,pointLabels:props.pointLabels,onChangePointLabels:onChangePointLabels});case "angle":const angleCoords=getAngleCoords({graph:props,range,step});return jsxRuntimeExports.jsx(StartCoordsAngle,{startCoords:angleCoords,allowReflexAngles:allowReflexAngles,onChange:onChange,pointLabels:props.pointLabels??[],onChangePointLabels:onChangePointLabels});default:return null}};const StartCoordsSettings=props=>{const{range,step,editingDisabled,onChange}=props;const[isOpen,setIsOpen]=React.useState(true);return jsxRuntimeExports.jsxs(View,{children:[jsxRuntimeExports.jsx(Heading,{isCollapsible:true,title:"Start coordinates",isOpen:isOpen,onToggle:()=>setIsOpen(!isOpen)}),isOpen&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsx(StartCoordsSettingsInner,{...props}),jsxRuntimeExports.jsx(View,{className:styles$d.resetButton,children:jsxRuntimeExports.jsx(Button,{startIcon:arrowCounterClockwise,kind:"tertiary",size:"small",disabled:editingDisabled,onClick:()=>{onChange(getDefaultGraphStartCoords(props,range,step));},children:"Use default start coordinates"})})]})]})};
1762
1769
 
1763
1770
  function toTrio(pointLabels){return [pointLabels[0]??"",pointLabels[1]??"",pointLabels[2]??""]}function toPair(pointLabels){return [pointLabels[0]??"",pointLabels[1]??""]}function toArray(pointLabels){return [...pointLabels]}function reshapePointLabelsForGraphType(pointLabels,graph,correct){if(!graph?.type||!correct){return null}let nextGraph;let nextCorrect=correct;switch(graph.type){case "angle":case "quadratic":{const reshaped=toTrio(pointLabels);nextGraph={...graph,pointLabels:reshaped};if(correct.type===graph.type){nextCorrect={...correct,pointLabels:reshaped};}break}case "absolute-value":case "linear":case "ray":{const reshaped=toPair(pointLabels);nextGraph={...graph,pointLabels:reshaped};if(correct.type===graph.type){nextCorrect={...correct,pointLabels:reshaped};}break}case "circle":case "exponential":case "linear-system":case "logarithm":case "point":case "polygon":case "segment":case "sinusoid":case "tangent":{const reshaped=toArray(pointLabels);nextGraph={...graph,pointLabels:reshaped};if(correct.type===graph.type){nextCorrect={...correct,pointLabels:reshaped};}break}case "vector":case "none":return null}return {graph:nextGraph,correct:nextCorrect}}
1764
1771
 
@@ -1766,60 +1773,52 @@ const InteractiveGraph=InteractiveGraphWidget.widget;class InteractiveGraphEdito
1766
1773
 
1767
1774
  const gray98="#FAFAFA";const gray95="#F0F1F2";const gray85="#D6D8DA";const gray76="#BABEC2";const gray68="#888D93";const gray41="#626569";const gray17="#21242C";
1768
1775
 
1769
- class FormWrappedTextField extends React.Component{render(){const{forwardedRef,width,grow,shrink,icon,backgroundColor,focusBorderColor,borderColor,color,onSubmit,leftSideIcon,id,testId,type,labelMediumInputText,...allProps}=this.props;const{focused}=this.state;const extraStyles={};const spanStyle=[styles$a.input,styles$a.container];if(width){extraStyles.width=width;}if(grow){extraStyles.flexGrow=grow===true?1:grow;}if(shrink||shrink===0){extraStyles.flexShrink=shrink===true?0:shrink;}if(backgroundColor){extraStyles.backgroundColor=backgroundColor;}else {spanStyle.push(styles$a.defaultBackground);}if(color){extraStyles.color=color;}const borderColorStyle=focused?focusBorderColor||semanticColor.focus.outer:borderColor||semanticColor.core.border.neutral.subtle;extraStyles.border=`1px solid ${borderColorStyle}`;const wrappedIcon=icon&&jsxRuntimeExports.jsx("span",{className:css(styles$a.icon),children:icon});const inputBase=labelMediumInputText?styles$a.labelMediumInputBase:styles$a.inputBase;return jsxRuntimeExports.jsxs("form",{className:css(...spanStyle),style:extraStyles,onSubmit:onSubmit||this.disableDefault,children:[leftSideIcon&&wrappedIcon,jsxRuntimeExports.jsx("input",{...allProps,onFocus:this.handleFocus,onBlur:this.handleBlur,type:type,className:css(inputBase),ref:forwardedRef,id:id,"data-testid":testId}),!leftSideIcon&&wrappedIcon]})}constructor(...args){super(...args),this.state={focused:false},this.handleBlur=e=>{const{onBlur}=this.props;onBlur?.(e);this.setState({focused:false});},this.handleFocus=e=>{const{onFocus}=this.props;onFocus?.(e);this.setState({focused:true});},this.disableDefault=e=>{e.preventDefault();};}}const styles$a=StyleSheet.create({inputBase:{background:"inherit",border:"none",fontFamily:"inherit",fontSize:15,lineHeight:"22px",outline:"none","::placeholder":{color:gray41},width:"100%",color:"inherit",marginBottom:0,paddingLeft:0,boxShadow:"none",padding:0,margin:0},labelMediumInputBase:{background:"inherit",border:"none",outline:"none","::placeholder":{color:gray41},width:"100%",fontWeight:"normal",fontFamily:"Lato, san-serif",fontSize:"16px",lineHeight:"20px"},input:{height:40,borderRadius:4,boxSizing:"border-box",padding:"8px 10px"},container:{display:"inline-flex",alignItems:"center",marginBottom:0},defaultBackground:{backgroundColor:semanticColor.core.background.base.default},icon:{display:"flex",alignItems:"center",justifyContent:"center"}});var FormWrappedTextField$1 = React.forwardRef((props,ref)=>jsxRuntimeExports.jsx(FormWrappedTextField,{...props,forwardedRef:ref}));
1776
+ class FormWrappedTextField extends React.Component{render(){const{forwardedRef,width,grow,shrink,icon,backgroundColor,focusBorderColor,borderColor,color,onSubmit,leftSideIcon,id,testId,type,labelMediumInputText,...allProps}=this.props;const{focused}=this.state;const extraStyles={};const spanStyle=[styles$8.input,styles$8.container];if(width){extraStyles.width=width;}if(grow){extraStyles.flexGrow=grow===true?1:grow;}if(shrink||shrink===0){extraStyles.flexShrink=shrink===true?0:shrink;}if(backgroundColor){extraStyles.backgroundColor=backgroundColor;}else {spanStyle.push(styles$8.defaultBackground);}if(color){extraStyles.color=color;}const borderColorStyle=focused?focusBorderColor||semanticColor.focus.outer:borderColor||semanticColor.core.border.neutral.subtle;extraStyles.border=`1px solid ${borderColorStyle}`;const wrappedIcon=icon&&jsxRuntimeExports.jsx("span",{className:css(styles$8.icon),children:icon});const inputBase=labelMediumInputText?styles$8.labelMediumInputBase:styles$8.inputBase;return jsxRuntimeExports.jsxs("form",{className:css(...spanStyle),style:extraStyles,onSubmit:onSubmit||this.disableDefault,children:[leftSideIcon&&wrappedIcon,jsxRuntimeExports.jsx("input",{...allProps,onFocus:this.handleFocus,onBlur:this.handleBlur,type:type,className:css(inputBase),ref:forwardedRef,id:id,"data-testid":testId}),!leftSideIcon&&wrappedIcon]})}constructor(...args){super(...args),this.state={focused:false},this.handleBlur=e=>{const{onBlur}=this.props;onBlur?.(e);this.setState({focused:false});},this.handleFocus=e=>{const{onFocus}=this.props;onFocus?.(e);this.setState({focused:true});},this.disableDefault=e=>{e.preventDefault();};}}const styles$8=StyleSheet.create({inputBase:{background:"inherit",border:"none",fontFamily:"inherit",fontSize:15,lineHeight:"22px",outline:"none","::placeholder":{color:gray41},width:"100%",color:"inherit",marginBottom:0,paddingLeft:0,boxShadow:"none",padding:0,margin:0},labelMediumInputBase:{background:"inherit",border:"none",outline:"none","::placeholder":{color:gray41},width:"100%",fontWeight:"normal",fontFamily:"Lato, san-serif",fontSize:"16px",lineHeight:"20px"},input:{height:40,borderRadius:4,boxSizing:"border-box",padding:"8px 10px"},container:{display:"inline-flex",alignItems:"center",marginBottom:0},defaultBackground:{backgroundColor:semanticColor.core.background.base.default},icon:{display:"flex",alignItems:"center",justifyContent:"center"}});var FormWrappedTextField$1 = React.forwardRef((props,ref)=>jsxRuntimeExports.jsx(FormWrappedTextField,{...props,forwardedRef:ref}));
1770
1777
 
1771
- var styles$9 = {"answers":"perseus_DTFHZTRU","answer":"perseus_h6UVAo1f","addAnswerContent":"perseus_bB9KRsBQ","addAnswer":"perseus_be-n-Bce","removeButtonContent":"perseus_JqR-dZ9h","removeButton":"perseus_uYELsWW-"};
1778
+ var styles$7 = {"answers":"perseus_DTFHZTRU","answer":"perseus_h6UVAo1f","addAnswerContent":"perseus_bB9KRsBQ","addAnswer":"perseus_be-n-Bce","removeButtonContent":"perseus_JqR-dZ9h","removeButton":"perseus_uYELsWW-"};
1772
1779
 
1773
- const AddAnswer=({onClick,editingDisabled})=>jsxRuntimeExports.jsx(Clickable,{className:styles$9.addAnswer,disabled:editingDisabled,onClick:onClick,children:()=>jsxRuntimeExports.jsxs("span",{className:styles$9.addAnswerContent,children:[jsxRuntimeExports.jsx(PhosphorIcon,{icon:plusCircle,size:"medium","aria-hidden":true}),jsxRuntimeExports.jsx(BodyText,{tag:"span",size:"medium",weight:"bold",children:"Add an answer choice"})]})});const Answer=({answer,onChange,onRemove,editingDisabled})=>jsxRuntimeExports.jsxs("li",{className:styles$9.answer,children:[jsxRuntimeExports.jsx(Clickable,{className:styles$9.removeButton,"aria-label":"Remove answer",onClick:onRemove,disabled:editingDisabled,children:()=>jsxRuntimeExports.jsx("span",{className:styles$9.removeButtonContent,children:jsxRuntimeExports.jsx(PhosphorIcon,{icon:minusCircle,size:"medium","aria-hidden":true})})}),jsxRuntimeExports.jsx(FormWrappedTextField$1,{grow:1,onChange:e=>onChange(e.target.value),value:answer})]});const AnswerChoices=({choices,editingDisabled,onChange})=>jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Answer Choices"}),jsxRuntimeExports.jsx("ul",{className:styles$9.answers,children:choices.map((answer,index)=>jsxRuntimeExports.jsx(Answer,{answer:answer,editingDisabled:editingDisabled,onChange:answer=>{if(editingDisabled){return}onChange([...choices.slice(0,index),answer,...choices.slice(index+1)]);},onRemove:()=>{if(editingDisabled){return}onChange([...choices.slice(0,index),...choices.slice(index+1)]);}},index))}),jsxRuntimeExports.jsx(AddAnswer,{editingDisabled:editingDisabled,onClick:()=>{if(editingDisabled){return}onChange([...choices,""]);}})]});
1780
+ const AddAnswer=({onClick,editingDisabled})=>jsxRuntimeExports.jsx(Clickable,{className:styles$7.addAnswer,disabled:editingDisabled,onClick:onClick,children:()=>jsxRuntimeExports.jsxs("span",{className:styles$7.addAnswerContent,children:[jsxRuntimeExports.jsx(PhosphorIcon,{icon:plusCircle,size:"medium","aria-hidden":true}),jsxRuntimeExports.jsx(BodyText,{tag:"span",size:"medium",weight:"bold",children:"Add an answer choice"})]})});const Answer=({answer,onChange,onRemove,editingDisabled})=>jsxRuntimeExports.jsxs("li",{className:styles$7.answer,children:[jsxRuntimeExports.jsx(Clickable,{className:styles$7.removeButton,"aria-label":"Remove answer",onClick:onRemove,disabled:editingDisabled,children:()=>jsxRuntimeExports.jsx("span",{className:styles$7.removeButtonContent,children:jsxRuntimeExports.jsx(PhosphorIcon,{icon:minusCircle,size:"medium","aria-hidden":true})})}),jsxRuntimeExports.jsx(FormWrappedTextField$1,{grow:1,onChange:e=>onChange(e.target.value),value:answer})]});const AnswerChoices=({choices,editingDisabled,onChange})=>jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Answer Choices"}),jsxRuntimeExports.jsx("ul",{className:styles$7.answers,children:choices.map((answer,index)=>jsxRuntimeExports.jsx(Answer,{answer:answer,editingDisabled:editingDisabled,onChange:answer=>{if(editingDisabled){return}onChange([...choices.slice(0,index),answer,...choices.slice(index+1)]);},onRemove:()=>{if(editingDisabled){return}onChange([...choices.slice(0,index),...choices.slice(index+1)]);}},index))}),jsxRuntimeExports.jsx(AddAnswer,{editingDisabled:editingDisabled,onClick:()=>{if(editingDisabled){return}onChange([...choices,""]);}})]});
1774
1781
 
1775
1782
  class HoverBehavior extends React.Component{render(){const handlers={onBlur:this.handleBlur,onClick:this.handleClick,onFocus:this.handleFocus,onMouseDown:this.handleMouseDown,onMouseEnter:this.handleMouseEnter,onMouseLeave:this.handleMouseLeave,onTouchStart:this.handleTouchStart,onTouchEnd:this.handleTouchEnd};const{children}=this.props;return children?.(this.state,handlers)||null}constructor(props){super(props),this.handleClick=e=>{if(!this.props.disabled){if(this.props.shouldUpdate()){this.waitingForClick=false;}if(this.props.onClick&&!this.props.disabled){this.props.onClick(e);}}},this.handleMouseEnter=()=>{if(!this.props.disabled&&this.props.shouldUpdate()&&!this.waitingForClick){this.setState({hovered:true});}},this.handleMouseLeave=()=>{if(!this.props.disabled&&this.props.shouldUpdate()&&!this.waitingForClick){this.setState({hovered:false});}},this.handleTouchStart=()=>{if(!this.props.disabled&&this.props.shouldUpdate()){this.setState({hovered:true});}},this.handleTouchEnd=()=>{if(!this.props.disabled&&this.props.shouldUpdate()){this.setState({hovered:false});this.waitingForClick=true;}},this.handleMouseDown=()=>{if(!this.props.disabled&&this.props.shouldUpdate()){this.setState({focused:false});this.focusFlag=true;}},this.handleBlur=()=>{if(!this.props.disabled&&this.props.shouldUpdate()){this.setState({focused:false});}},this.handleFocus=()=>{if(!this.props.disabled&&this.props.shouldUpdate()){if(this.focusFlag){this.focusFlag=false;}else {this.setState({focused:true});}}};this.state={focused:false,hovered:props.startHovered};}}HoverBehavior.defaultProps={startHovered:false,shouldUpdate:()=>true};
1776
1783
 
1777
- const borderRadius=4;const onChangeCheckboxNoop=event=>{};class Checkbox extends React.Component{render(){const{checked,disabled,appearDisabled,onChange,tabIndex,style,dataTestId,id}=this.props;const checkedColor=gray41;return jsxRuntimeExports.jsx(HoverBehavior,{children:({focused},handlers)=>jsxRuntimeExports.jsxs("div",{...handlers,className:css(styles$8.container,focused&&styles$8.focused),style:style,"data-testid":dataTestId,"data-checked":checked,children:[jsxRuntimeExports.jsx("svg",{className:css(styles$8.svg,(disabled||appearDisabled)&&styles$8.disabled),width:sizeWithPadding,height:sizeWithPadding,viewBox:`-${padding} -${padding}
1778
- ${sizeWithPadding} ${sizeWithPadding}`,children:jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[checked&&jsxRuntimeExports.jsxs("g",{children:[jsxRuntimeExports.jsx("rect",{fill:checkedColor,width:size,height:size,x:"0",y:"0",rx:borderRadius}),jsxRuntimeExports.jsx("path",{fill:semanticColor.core.foreground.knockout.default,stroke:semanticColor.core.foreground.knockout.default,d:"M4.98 7.41a0.58.58 0 1 0-0.81.81L6.47 10.53c0.23.23.59.23.81 0l4.55-4.55a0.58.58 0 0 0-0.81-0.81L6.88 9.31 4.98 7.41z"})]}),!checked&&jsxRuntimeExports.jsx("rect",{fill:semanticColor.core.foreground.knockout.default,stroke:gray68,width:size-2*padding,height:size-2*padding,x:padding,y:padding,rx:"4",strokeWidth:borderWidth})]})}),jsxRuntimeExports.jsx("input",{type:"checkbox",id:id,checked:checked,className:css(styles$8.checkbox,disabled&&styles$8.defaultCursor),disabled:disabled,onChange:onChange,tabIndex:tabIndex})]})})}}Checkbox.defaultProps={checked:false,onChange:onChangeCheckboxNoop};const size=16;const padding=.5;const borderWidth=1;const sizeWithPadding=size+2*padding;const styles$8=StyleSheet.create({container:{position:"relative",display:"inline-block",verticalAlign:"middle",lineHeight:0,borderRadius:borderRadius,width:sizeWithPadding,height:sizeWithPadding,flexShrink:0},focused:{"::before":{content:'""',position:"absolute",top:-2,right:-2,bottom:-2,left:-2,borderRadius:borderRadius+2,backgroundColor:"lightblue"}},svg:{position:"absolute",left:0,top:0},checkbox:{appearance:"none",opacity:0,position:"absolute",top:padding,width:size,height:size,margin:0,outline:"none",cursor:"pointer"},disabled:{opacity:.5},defaultCursor:{cursor:"default"}});
1784
+ const borderRadius=4;const onChangeCheckboxNoop=event=>{};class Checkbox extends React.Component{render(){const{checked,disabled,appearDisabled,onChange,tabIndex,style,dataTestId,id}=this.props;const checkedColor=gray41;return jsxRuntimeExports.jsx(HoverBehavior,{children:({focused},handlers)=>jsxRuntimeExports.jsxs("div",{...handlers,className:css(styles$6.container,focused&&styles$6.focused),style:style,"data-testid":dataTestId,"data-checked":checked,children:[jsxRuntimeExports.jsx("svg",{className:css(styles$6.svg,(disabled||appearDisabled)&&styles$6.disabled),width:sizeWithPadding,height:sizeWithPadding,viewBox:`-${padding} -${padding}
1785
+ ${sizeWithPadding} ${sizeWithPadding}`,children:jsxRuntimeExports.jsxs("g",{fill:"none",fillRule:"evenodd",children:[checked&&jsxRuntimeExports.jsxs("g",{children:[jsxRuntimeExports.jsx("rect",{fill:checkedColor,width:size,height:size,x:"0",y:"0",rx:borderRadius}),jsxRuntimeExports.jsx("path",{fill:semanticColor.core.foreground.knockout.default,stroke:semanticColor.core.foreground.knockout.default,d:"M4.98 7.41a0.58.58 0 1 0-0.81.81L6.47 10.53c0.23.23.59.23.81 0l4.55-4.55a0.58.58 0 0 0-0.81-0.81L6.88 9.31 4.98 7.41z"})]}),!checked&&jsxRuntimeExports.jsx("rect",{fill:semanticColor.core.foreground.knockout.default,stroke:gray68,width:size-2*padding,height:size-2*padding,x:padding,y:padding,rx:"4",strokeWidth:borderWidth})]})}),jsxRuntimeExports.jsx("input",{type:"checkbox",id:id,checked:checked,className:css(styles$6.checkbox,disabled&&styles$6.defaultCursor),disabled:disabled,onChange:onChange,tabIndex:tabIndex})]})})}}Checkbox.defaultProps={checked:false,onChange:onChangeCheckboxNoop};const size=16;const padding=.5;const borderWidth=1;const sizeWithPadding=size+2*padding;const styles$6=StyleSheet.create({container:{position:"relative",display:"inline-block",verticalAlign:"middle",lineHeight:0,borderRadius:borderRadius,width:sizeWithPadding,height:sizeWithPadding,flexShrink:0},focused:{"::before":{content:'""',position:"absolute",top:-2,right:-2,bottom:-2,left:-2,borderRadius:borderRadius+2,backgroundColor:"lightblue"}},svg:{position:"absolute",left:0,top:0},checkbox:{appearance:"none",opacity:0,position:"absolute",top:padding,width:size,height:size,margin:0,outline:"none",cursor:"pointer"},disabled:{opacity:.5},defaultCursor:{cursor:"default"}});
1779
1786
 
1780
- var styles$7 = {"optionsList":"perseus_9p2fIJDN","option":"perseus_uz5HIc6B","label":"perseus_nqkpIulz","selectLabel":"perseus_aAJcd7Pn","editor":"perseus_ELq9XmxW"};
1787
+ var styles$5 = {"optionsList":"perseus_9p2fIJDN","option":"perseus_uz5HIc6B","label":"perseus_nqkpIulz","selectLabel":"perseus_aAJcd7Pn","editor":"perseus_ELq9XmxW"};
1781
1788
 
1782
- const Behavior=({multipleAnswers,hideChoicesFromInstructions,preferredPopoverDirection,onChange})=>jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Behavior"}),jsxRuntimeExports.jsxs("ul",{className:styles$7.optionsList,children:[jsxRuntimeExports.jsxs("li",{className:styles$7.option,children:[jsxRuntimeExports.jsx(Checkbox,{checked:multipleAnswers,onChange:()=>onChange({multipleAnswers:!multipleAnswers})}),jsxRuntimeExports.jsx("span",{className:styles$7.label,children:"Allow multiple answers per marker"})]}),jsxRuntimeExports.jsxs("li",{className:styles$7.option,children:[jsxRuntimeExports.jsx(Checkbox,{checked:hideChoicesFromInstructions,onChange:()=>onChange({hideChoicesFromInstructions:!hideChoicesFromInstructions})}),jsxRuntimeExports.jsx("span",{className:styles$7.label,children:"Do not display answer choices in instructions"})]}),jsxRuntimeExports.jsxs("li",{className:styles$7.option,children:[jsxRuntimeExports.jsx("span",{className:[styles$7.label,styles$7.selectLabel].join(" "),children:"Preferred pop-over direction"}),jsxRuntimeExports.jsxs("select",{value:preferredPopoverDirection,onChange:e=>{onChange({preferredPopoverDirection:e.target.value});},children:[jsxRuntimeExports.jsx("option",{value:"NONE",children:" No Preference "}),jsxRuntimeExports.jsx("option",{value:"UP",children:" Up "}),jsxRuntimeExports.jsx("option",{value:"DOWN",children:" Down "}),jsxRuntimeExports.jsx("option",{value:"LEFT",children:" Left "}),jsxRuntimeExports.jsx("option",{value:"RIGHT",children:" Right "})]})]})]})]});
1789
+ const Behavior=({multipleAnswers,hideChoicesFromInstructions,preferredPopoverDirection,onChange})=>jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Behavior"}),jsxRuntimeExports.jsxs("ul",{className:styles$5.optionsList,children:[jsxRuntimeExports.jsxs("li",{className:styles$5.option,children:[jsxRuntimeExports.jsx(Checkbox,{checked:multipleAnswers,onChange:()=>onChange({multipleAnswers:!multipleAnswers})}),jsxRuntimeExports.jsx("span",{className:styles$5.label,children:"Allow multiple answers per marker"})]}),jsxRuntimeExports.jsxs("li",{className:styles$5.option,children:[jsxRuntimeExports.jsx(Checkbox,{checked:hideChoicesFromInstructions,onChange:()=>onChange({hideChoicesFromInstructions:!hideChoicesFromInstructions})}),jsxRuntimeExports.jsx("span",{className:styles$5.label,children:"Do not display answer choices in instructions"})]}),jsxRuntimeExports.jsxs("li",{className:styles$5.option,children:[jsxRuntimeExports.jsx("span",{className:[styles$5.label,styles$5.selectLabel].join(" "),children:"Preferred pop-over direction"}),jsxRuntimeExports.jsxs("select",{value:preferredPopoverDirection,onChange:e=>{onChange({preferredPopoverDirection:e.target.value});},children:[jsxRuntimeExports.jsx("option",{value:"NONE",children:" No Preference "}),jsxRuntimeExports.jsx("option",{value:"UP",children:" Up "}),jsxRuntimeExports.jsx("option",{value:"DOWN",children:" Down "}),jsxRuntimeExports.jsx("option",{value:"LEFT",children:" Left "}),jsxRuntimeExports.jsx("option",{value:"RIGHT",children:" Right "})]})]})]})]});
1783
1790
 
1784
1791
  const{Icon}=components;const findAndFocusElement=component=>{const DOMNode=ReactDOM.findDOMNode(component);const button=DOMNode;if(button.focus){focusWithChromeStickyFocusBugWorkaround(button);}};const check=`M10,3.8C10,4,9.9,4.2,9.8,4.3L5.1,8.9L4.3,9.8C4.2,9.9,4,10,3.8,10
1785
1792
  S3.5,9.9,3.4,9.8L2.5,8.9L0.2,6.6C0.1,6.5,0,6.3,0,6.2s0.1-0.3,0.2-0.4
1786
1793
  l0.9-0.9c0.1-0.1,0.3-0.2,0.4-0.2s0.3,0.1,0.4,0.2l1.9,1.9l4.2-4.2c0.1
1787
1794
  -0.1,0.3-0.2,0.4-0.2c0.2,0,0.3,0.1,0.4,0.2l0.9,0.9C9.9,3.5,10,3.7,
1788
- 10,3.8z`;const optionHeight=30;class Option extends React.Component{handleKeyDown(event){const{onDropdownClose}=this.props;const pressedKey=event.key;const focusedElement=event.currentTarget;if(pressedKey==="ArrowDown"&&focusedElement.nextElementSibling){event.preventDefault();focusedElement.nextElementSibling.focus();}if(pressedKey==="ArrowUp"&&focusedElement.previousElementSibling){event.preventDefault();focusedElement.previousElementSibling.focus();}if(pressedKey==="ArrowUp"&&!focusedElement.previousElementSibling&&onDropdownClose){event.preventDefault();onDropdownClose();}if((pressedKey==="Escape"||pressedKey==="Tab")&&onDropdownClose){onDropdownClose();}}render(){const{selected,value,onClick,children,disabled,hideFocusState,testId,ariaLabel}=this.props;return jsxRuntimeExports.jsx("button",{ref:node=>this.node=node,value:value,role:"menuitemradio","aria-checked":selected,className:css(styles$6.notAButton,disabled&&styles$6.cursorDefault,hideFocusState&&styles$6.noFocus),onClick:value=>{if(!disabled&&onClick){onClick(value);}},onKeyDown:event=>this.handleKeyDown(event),"aria-disabled":disabled,"aria-label":ariaLabel,"data-testid":testId,children:jsxRuntimeExports.jsxs("span",{className:css(styles$6.option,selected&&styles$6.optionSelected,disabled&&styles$6.optionDisabled),children:[children,selected&&jsxRuntimeExports.jsx("span",{className:css(styles$6.check),children:jsxRuntimeExports.jsx(Icon,{icon:check})})]})})}}class OptionGroup extends React.Component{componentDidMount(){if(this.focusedElement){findAndFocusElement(this.focusedElement);}}render(){const{children,onSelected,selectedValues,noMargin,onDropdownClose,hideFocusState}=this.props;return jsxRuntimeExports.jsx("div",{style:{top},className:css(styles$6.optionGroup,noMargin&&styles$6.optionGroupNoMargin),children:React.Children.map(children,(child,index)=>{const selected=selectedValues.includes(child.props.value);const reference=selected||index===0?node=>this.focusedElement=node:null;return React.cloneElement(child,{...child.props,key:index,selected:selected,onClick:()=>onSelected(child.props.value),ref:reference,onDropdownClose:onDropdownClose,hideFocusState:hideFocusState})})})}}const styles$6=StyleSheet.create({optionGroup:{margin:"4px 0"},optionGroupNoMargin:{margin:0},option:{display:"flex",flexDirection:"row",alignItems:"center",paddingLeft:32,paddingRight:32,height:optionHeight,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",color:gray17,userSelect:"none",":hover":{backgroundColor:gray95}},optionSelected:{backgroundColor:gray95,color:"#11ACCD"},optionDisabled:{color:gray76,":hover":{backgroundColor:"transparent"}},check:{position:"absolute",left:11},notAButton:{backgroundColor:"transparent",border:"none",display:"block",padding:0,margin:0,width:"100%",font:"inherit"},noFocus:{outline:"none"},cursorDefault:{cursor:"default"}});
1795
+ 10,3.8z`;const optionHeight=30;class Option extends React.Component{handleKeyDown(event){const{onDropdownClose}=this.props;const pressedKey=event.key;const focusedElement=event.currentTarget;if(pressedKey==="ArrowDown"&&focusedElement.nextElementSibling){event.preventDefault();focusedElement.nextElementSibling.focus();}if(pressedKey==="ArrowUp"&&focusedElement.previousElementSibling){event.preventDefault();focusedElement.previousElementSibling.focus();}if(pressedKey==="ArrowUp"&&!focusedElement.previousElementSibling&&onDropdownClose){event.preventDefault();onDropdownClose();}if((pressedKey==="Escape"||pressedKey==="Tab")&&onDropdownClose){onDropdownClose();}}render(){const{selected,value,onClick,children,disabled,hideFocusState,testId,ariaLabel}=this.props;return jsxRuntimeExports.jsx("button",{ref:node=>this.node=node,value:value,role:"menuitemradio","aria-checked":selected,className:css(styles$4.notAButton,disabled&&styles$4.cursorDefault,hideFocusState&&styles$4.noFocus),onClick:value=>{if(!disabled&&onClick){onClick(value);}},onKeyDown:event=>this.handleKeyDown(event),"aria-disabled":disabled,"aria-label":ariaLabel,"data-testid":testId,children:jsxRuntimeExports.jsxs("span",{className:css(styles$4.option,selected&&styles$4.optionSelected,disabled&&styles$4.optionDisabled),children:[children,selected&&jsxRuntimeExports.jsx("span",{className:css(styles$4.check),children:jsxRuntimeExports.jsx(Icon,{icon:check})})]})})}}class OptionGroup extends React.Component{componentDidMount(){if(this.focusedElement){findAndFocusElement(this.focusedElement);}}render(){const{children,onSelected,selectedValues,noMargin,onDropdownClose,hideFocusState}=this.props;return jsxRuntimeExports.jsx("div",{style:{top},className:css(styles$4.optionGroup,noMargin&&styles$4.optionGroupNoMargin),children:React.Children.map(children,(child,index)=>{const selected=selectedValues.includes(child.props.value);const reference=selected||index===0?node=>this.focusedElement=node:null;return React.cloneElement(child,{...child.props,key:index,selected:selected,onClick:()=>onSelected(child.props.value),ref:reference,onDropdownClose:onDropdownClose,hideFocusState:hideFocusState})})})}}const styles$4=StyleSheet.create({optionGroup:{margin:"4px 0"},optionGroupNoMargin:{margin:0},option:{display:"flex",flexDirection:"row",alignItems:"center",paddingLeft:32,paddingRight:32,height:optionHeight,whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",color:gray17,userSelect:"none",":hover":{backgroundColor:gray95}},optionSelected:{backgroundColor:gray95,color:"#11ACCD"},optionDisabled:{color:gray76,":hover":{backgroundColor:"transparent"}},check:{position:"absolute",left:11},notAButton:{backgroundColor:"transparent",border:"none",display:"block",padding:0,margin:0,width:"100%",font:"inherit"},noFocus:{outline:"none"},cursorDefault:{cursor:"default"}});
1789
1796
 
1790
- class Marker extends React.Component{componentDidMount(){document.addEventListener("click",this.handleClick,true);}UNSAFE_componentWillReceiveProps(nextProps){const{answers}=this.props;const filteredAnswers=answers.filter(answer=>nextProps.choices.includes(answer));if(JSON.stringify(answers)!==JSON.stringify(filteredAnswers)){setTimeout(()=>this.updateAnswers(filteredAnswers));}}componentWillUnmount(){document.removeEventListener("click",this.handleClick,true);}openDropdown(){this.setState({showDropdown:true});}updateAnswers(answers){const{label,onChange,x,y}=this.props;onChange({answers,label,x,y});}updateLabel(label){const{answers,onChange,x,y}=this.props;onChange({answers,label,x,y});}render(){const{answers,choices,label,onRemove,x,y}=this.props;const{showDropdown}=this.state;return jsxRuntimeExports.jsx("div",{className:css(styles$5.marker,answers.length>0&&styles$5.markerWithAnswers,showDropdown&&styles$5.markerSelected),ref:node=>this._marker=node,style:{left:`${x}%`,top:`${y}%`},title:"Click to select marker answers or to delete marker. "+"Repositioning marker is not implemented.",children:showDropdown&&jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("div",{className:css(styles$5.dropdownBody,styles$5.dropdownPositionWithArrow),children:[jsxRuntimeExports.jsx(Option,{value:"",onClick:()=>onRemove(),children:"Delete marker"}),jsxRuntimeExports.jsx("hr",{className:css(styles$5.dividerHorizontal)}),jsxRuntimeExports.jsx(OptionGroup,{onSelected:this.handleSelectAnswer,selectedValues:answers,children:choices.map(choice=>jsxRuntimeExports.jsx(Option,{value:choice,children:choice},choice))}),jsxRuntimeExports.jsx("div",{className:css(styles$5.labelContainer),children:jsxRuntimeExports.jsx(FormWrappedTextField$1,{placeholder:"ARIA label (for screen readers)",onChange:this.handleLabelChange,value:label,width:"100%"})})]})})})}constructor(...args){super(...args),this.state={showDropdown:false},this.handleClick=e=>{const{showDropdown}=this.state;if(this._marker===e.target){this.setState({showDropdown:!showDropdown});}else if(showDropdown){if(this._marker&&e.target instanceof Node&&!this._marker.contains(e.target)){e.stopPropagation();this.setState({showDropdown:false});}}},this.handleLabelChange=e=>{this.updateLabel(e.target.value);},this.handleSelectAnswer=toggleAnswer=>{let{answers}=this.props;if(answers.includes(toggleAnswer)){answers=answers.filter(answer=>answer!==toggleAnswer);}else {answers=[...answers,toggleAnswer];}this.updateAnswers(answers);};}}const styles$5=StyleSheet.create({marker:{position:"absolute",boxSizing:"content-box",width:16,height:16,marginLeft:-8,marginTop:-8,cursor:"pointer",background:"linear-gradient(to bottom, rgba(33, 36, 44, 0.2), rgba(33, 36, 44, 0.5))",border:"solid 2px #ffffff",borderRadius:16,boxShadow:"0 2px 10px 0 rgba(33, 36, 44, 0.1)"},markerSelected:{width:28,height:28,marginLeft:-12,marginTop:-12,border:"none",borderRadius:28,"::before":{content:"''",display:"block",width:20,height:20,marginLeft:2,marginTop:2,border:"solid 2px #ffffff",borderRadius:20}},markerWithAnswers:{background:"#1865f2"},dropdownPositionWithArrow:{left:46,bottom:-12,"::before":{content:"''",display:"block",position:"absolute",width:0,height:0,left:-16,bottom:8,borderRight:`solid 16px ${gray98}`,borderTop:"solid 16px transparent",borderBottom:"solid 16px transparent"}},labelContainer:{padding:4},dividerHorizontal:{height:0,margin:0,border:`solid ${gray85}`,borderWidth:"0 0 1px",boxShadow:"none"},dropdownBody:{position:"absolute",border:"solid 1px rgba(0, 0, 0, 0.1)",zIndex:1e3,color:gray17,backgroundColor:gray98,borderRadius:4,maxHeight:320,cursor:"pointer"}});
1797
+ class Marker extends React.Component{componentDidMount(){document.addEventListener("click",this.handleClick,true);}UNSAFE_componentWillReceiveProps(nextProps){const{answers}=this.props;const filteredAnswers=answers.filter(answer=>nextProps.choices.includes(answer));if(JSON.stringify(answers)!==JSON.stringify(filteredAnswers)){setTimeout(()=>this.updateAnswers(filteredAnswers));}}componentWillUnmount(){document.removeEventListener("click",this.handleClick,true);}openDropdown(){this.setState({showDropdown:true});}updateAnswers(answers){const{label,onChange,x,y}=this.props;onChange({answers,label,x,y});}updateLabel(label){const{answers,onChange,x,y}=this.props;onChange({answers,label,x,y});}render(){const{answers,choices,label,onRemove,x,y}=this.props;const{showDropdown}=this.state;return jsxRuntimeExports.jsx("div",{className:css(styles$3.marker,answers.length>0&&styles$3.markerWithAnswers,showDropdown&&styles$3.markerSelected),ref:node=>this._marker=node,style:{left:`${x}%`,top:`${y}%`},title:"Click to select marker answers or to delete marker. "+"Repositioning marker is not implemented.",children:showDropdown&&jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("div",{className:css(styles$3.dropdownBody,styles$3.dropdownPositionWithArrow),children:[jsxRuntimeExports.jsx(Option,{value:"",onClick:()=>onRemove(),children:"Delete marker"}),jsxRuntimeExports.jsx("hr",{className:css(styles$3.dividerHorizontal)}),jsxRuntimeExports.jsx(OptionGroup,{onSelected:this.handleSelectAnswer,selectedValues:answers,children:choices.map(choice=>jsxRuntimeExports.jsx(Option,{value:choice,children:choice},choice))}),jsxRuntimeExports.jsx("div",{className:css(styles$3.labelContainer),children:jsxRuntimeExports.jsx(FormWrappedTextField$1,{placeholder:"ARIA label (for screen readers)",onChange:this.handleLabelChange,value:label,width:"100%"})})]})})})}constructor(...args){super(...args),this.state={showDropdown:false},this.handleClick=e=>{const{showDropdown}=this.state;if(this._marker===e.target){this.setState({showDropdown:!showDropdown});}else if(showDropdown){if(this._marker&&e.target instanceof Node&&!this._marker.contains(e.target)){e.stopPropagation();this.setState({showDropdown:false});}}},this.handleLabelChange=e=>{this.updateLabel(e.target.value);},this.handleSelectAnswer=toggleAnswer=>{let{answers}=this.props;if(answers.includes(toggleAnswer)){answers=answers.filter(answer=>answer!==toggleAnswer);}else {answers=[...answers,toggleAnswer];}this.updateAnswers(answers);};}}const styles$3=StyleSheet.create({marker:{position:"absolute",boxSizing:"content-box",width:16,height:16,marginLeft:-8,marginTop:-8,cursor:"pointer",background:"linear-gradient(to bottom, rgba(33, 36, 44, 0.2), rgba(33, 36, 44, 0.5))",border:"solid 2px #ffffff",borderRadius:16,boxShadow:"0 2px 10px 0 rgba(33, 36, 44, 0.1)"},markerSelected:{width:28,height:28,marginLeft:-12,marginTop:-12,border:"none",borderRadius:28,"::before":{content:"''",display:"block",width:20,height:20,marginLeft:2,marginTop:2,border:"solid 2px #ffffff",borderRadius:20}},markerWithAnswers:{background:"#1865f2"},dropdownPositionWithArrow:{left:46,bottom:-12,"::before":{content:"''",display:"block",position:"absolute",width:0,height:0,left:-16,bottom:8,borderRight:`solid 16px ${gray98}`,borderTop:"solid 16px transparent",borderBottom:"solid 16px transparent"}},labelContainer:{padding:4},dividerHorizontal:{height:0,margin:0,border:`solid ${gray85}`,borderWidth:"0 0 1px",boxShadow:"none"},dropdownBody:{position:"absolute",border:"solid 1px rgba(0, 0, 0, 0.1)",zIndex:1e3,color:gray17,backgroundColor:gray98,borderRadius:4,maxHeight:320,cursor:"pointer"}});
1791
1798
 
1792
- class QuestionMarkers extends React.Component{openDropdownForMarkerIndices(indices){indices.forEach(index=>{if(this._markers[index]){this._markers[index]?.openDropdown();}});}render(){const{choices,imageUrl,imageWidth,imageHeight,markers,onChange}=this.props;const staticUrl=Dependencies.getDependencies().staticUrl;return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Markers"}),jsxRuntimeExports.jsx("div",{className:css(styles$4.subtitle),children:imageUrl?jsxRuntimeExports.jsxs("span",{children:["Double-click on the image to add a marker.",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),"Markers are read by screen readers in the order that you add them here, so add in a logical order for the learner (e.g. sequentially, clockwise). You can test order by using keyboard tabbing."]}):"Upload an image to place markers."}),imageUrl&&jsxRuntimeExports.jsxs("div",{className:css(styles$4.markersCanvas),style:{maxWidth:imageWidth,maxHeight:imageHeight},children:[jsxRuntimeExports.jsx("img",{alt:"",className:css(styles$4.image),src:staticUrl(Util.getRealImageUrl(imageUrl)),onDoubleClick:this.handleImageDoubleClick}),markers.map((marker,index)=>createElement(Marker,{...marker,choices:choices,key:`${marker.x}.${marker.y}`,onChange:marker=>onChange([...markers.slice(0,index),marker,...markers.slice(index+1)]),onRemove:()=>onChange([...markers.slice(0,index),...markers.slice(index+1)]),ref:node=>this._markers[index]=node}))]})]})}constructor(...args){super(...args),this._markers=[],this.handleImageDoubleClick=e=>{e.preventDefault();if(this.props.editingDisabled){return}const rect=e.currentTarget.getBoundingClientRect();const x=Math.round((e.clientX-rect.left)/rect.width*1e3)/10;const y=Math.round((e.clientY-rect.top)/rect.height*1e3)/10;const{markers,onChange}=this.props;onChange([...markers,{answers:[],label:"",x,y}]);};}}const styles$4=StyleSheet.create({subtitle:{fontFamily:"inherit",fontSize:12,lineHeight:"14px",marginTop:8,marginBottom:12,color:gray68},markersCanvas:{position:"relative",border:"solid 1px rgba(33, 36, 44, 0.16)"},image:{display:"block",maxWidth:"100%"}});
1799
+ class QuestionMarkers extends React.Component{openDropdownForMarkerIndices(indices){indices.forEach(index=>{if(this._markers[index]){this._markers[index]?.openDropdown();}});}render(){const{choices,imageUrl,imageWidth,imageHeight,markers,onChange}=this.props;const staticUrl=Dependencies.getDependencies().staticUrl;return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Markers"}),jsxRuntimeExports.jsx("div",{className:css(styles$2.subtitle),children:imageUrl?jsxRuntimeExports.jsxs("span",{children:["Double-click on the image to add a marker.",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("br",{}),"Markers are read by screen readers in the order that you add them here, so add in a logical order for the learner (e.g. sequentially, clockwise). You can test order by using keyboard tabbing."]}):"Upload an image to place markers."}),imageUrl&&jsxRuntimeExports.jsxs("div",{className:css(styles$2.markersCanvas),style:{maxWidth:imageWidth,maxHeight:imageHeight},children:[jsxRuntimeExports.jsx("img",{alt:"",className:css(styles$2.image),src:staticUrl(Util.getRealImageUrl(imageUrl)),onDoubleClick:this.handleImageDoubleClick}),markers.map((marker,index)=>createElement(Marker,{...marker,choices:choices,key:`${marker.x}.${marker.y}`,onChange:marker=>onChange([...markers.slice(0,index),marker,...markers.slice(index+1)]),onRemove:()=>onChange([...markers.slice(0,index),...markers.slice(index+1)]),ref:node=>this._markers[index]=node}))]})]})}constructor(...args){super(...args),this._markers=[],this.handleImageDoubleClick=e=>{e.preventDefault();if(this.props.editingDisabled){return}const rect=e.currentTarget.getBoundingClientRect();const x=Math.round((e.clientX-rect.left)/rect.width*1e3)/10;const y=Math.round((e.clientY-rect.top)/rect.height*1e3)/10;const{markers,onChange}=this.props;onChange([...markers,{answers:[],label:"",x,y}]);};}}const styles$2=StyleSheet.create({subtitle:{fontFamily:"inherit",fontSize:12,lineHeight:"14px",marginTop:8,marginBottom:12,color:gray68},markersCanvas:{position:"relative",border:"solid 1px rgba(33, 36, 44, 0.16)"},image:{display:"block",maxWidth:"100%"}});
1793
1800
 
1794
- var styles$3 = {"imageRow":"perseus_-XexOs6i"};
1801
+ var styles$1 = {"imageRow":"perseus_-XexOs6i"};
1795
1802
 
1796
- const SelectImage=({onChange,url,editingDisabled=false})=>jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Image"}),jsxRuntimeExports.jsxs("div",{className:styles$3.imageRow,children:[jsxRuntimeExports.jsx(FormWrappedTextField$1,{placeholder:"URL",grow:1,onChange:e=>onChange(e.target.value),value:url}),jsxRuntimeExports.jsx(Button,{disabled:!url||editingDisabled,"aria-label":url?"":"Not implemented. Use the 'Add Image' button in "+"the editor to upload image, then copy the URL here.",onClick:()=>onChange(""),style:{minWidth:90},children:url?"Remove":"Upload"})]})]});
1803
+ const SelectImage=({onChange,url,editingDisabled=false})=>jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:"Image"}),jsxRuntimeExports.jsxs("div",{className:styles$1.imageRow,children:[jsxRuntimeExports.jsx(FormWrappedTextField$1,{placeholder:"URL",grow:1,onChange:e=>onChange(e.target.value),value:url}),jsxRuntimeExports.jsx(Button,{disabled:!url||editingDisabled,"aria-label":url?"":"Not implemented. Use the 'Add Image' button in "+"the editor to upload image, then copy the URL here.",onClick:()=>onChange(""),style:{minWidth:90},children:url?"Remove":"Upload"})]})]});
1797
1804
 
1798
- class LabelImageEditor extends React.Component{componentDidUpdate(prevProps){const coordsToMarkers={};prevProps.markers.forEach(marker=>coordsToMarkers[`${marker.x}.${marker.y}`]=marker);const newIndices=this.props.markers.map((marker,index)=>coordsToMarkers.hasOwnProperty(`${marker.x}.${marker.y}`)?-1:index).filter(index=>index!==-1);if(newIndices.length&&this._questionMarkers){this._questionMarkers.openDropdownForMarkerIndices(newIndices);}}serialize(){return EditorJsonify.serialize.call(this)}render(){const{choices,imageAlt,imageUrl,imageWidth,imageHeight,markers,multipleAnswers,hideChoicesFromInstructions,preferredPopoverDirection}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const imageSelected=imageUrl&&imageWidth>0&&imageHeight>0;return jsxRuntimeExports.jsxs("div",{className:styles$7.editor,children:[jsxRuntimeExports.jsx(SelectImage,{onChange:this.handleImageChange,url:imageUrl,editingDisabled:editingDisabled}),imageSelected&&jsxRuntimeExports.jsx(FormWrappedTextField$1,{placeholder:"Alt text (for screen readers)",onChange:e=>this.handleAltChange(e.target.value),value:imageAlt,width:"100%"}),jsxRuntimeExports.jsx(QuestionMarkers,{editingDisabled:editingDisabled,choices:choices,imageUrl:imageSelected?imageUrl:"",imageWidth:imageWidth,imageHeight:imageHeight,markers:markers,onChange:this.handleMarkersChange,ref:node=>this._questionMarkers=node}),jsxRuntimeExports.jsx(AnswerChoices,{choices:choices,editingDisabled:editingDisabled,onChange:this.handleChoicesChange}),jsxRuntimeExports.jsx(Behavior,{preferredPopoverDirection:preferredPopoverDirection,multipleAnswers:multipleAnswers,hideChoicesFromInstructions:hideChoicesFromInstructions,onChange:this.handleBehaviorChange})]})}constructor(...args){super(...args),this.getSaveWarnings=()=>{const{choices,imageAlt,imageUrl,markers}=this.props;const warnings=[];if(choices.length<2){warnings.push("Question requires at least two answer choices");}if(!imageUrl){warnings.push("Image is not specified for question");}else if(!imageAlt){warnings.push("Question image has no alt text");}if(!markers.length){warnings.push("Question has no markers, to label answers on image");}else {let numNoAnswers=0;let numNoLabels=0;for(const marker of markers){if(!marker.answers.length){numNoAnswers++;}if(!marker.label){numNoLabels++;}}if(numNoAnswers){warnings.push(`Question has ${numNoAnswers} markers with no `+"answers selected");}if(numNoLabels){warnings.push(`Question has ${numNoLabels} markers with no `+"ARIA label");}}return warnings},this.handleImageChange=url=>{this.props.onChange({imageUrl:url,imageWidth:0,imageHeight:0});if(url){Util.getImageSize(url,(width,height)=>{if(this.props.imageUrl===url&&this.props.imageWidth===width&&this.props.imageHeight===height){return}this.props.onChange({imageUrl:url,imageWidth:width,imageHeight:height});});}},this.handleAltChange=alt=>{this.props.onChange({imageAlt:alt});},this.handleChoicesChange=choices=>{this.props.onChange({choices});},this.handleMarkersChange=markers=>{this.props.onChange({markers});},this.handleBehaviorChange=options=>{this.props.onChange(options);};}}LabelImageEditor.defaultProps=labelImageLogic.defaultWidgetOptions;LabelImageEditor.widgetName="label-image";
1805
+ class LabelImageEditor extends React.Component{componentDidUpdate(prevProps){const coordsToMarkers={};prevProps.markers.forEach(marker=>coordsToMarkers[`${marker.x}.${marker.y}`]=marker);const newIndices=this.props.markers.map((marker,index)=>coordsToMarkers.hasOwnProperty(`${marker.x}.${marker.y}`)?-1:index).filter(index=>index!==-1);if(newIndices.length&&this._questionMarkers){this._questionMarkers.openDropdownForMarkerIndices(newIndices);}}serialize(){return EditorJsonify.serialize.call(this)}render(){const{choices,imageAlt,imageUrl,imageWidth,imageHeight,markers,multipleAnswers,hideChoicesFromInstructions,preferredPopoverDirection}=this.props;const editingDisabled=this.props.apiOptions?.editingDisabled??false;const imageSelected=imageUrl&&imageWidth>0&&imageHeight>0;return jsxRuntimeExports.jsxs("div",{className:styles$5.editor,children:[jsxRuntimeExports.jsx(SelectImage,{onChange:this.handleImageChange,url:imageUrl,editingDisabled:editingDisabled}),imageSelected&&jsxRuntimeExports.jsx(FormWrappedTextField$1,{placeholder:"Alt text (for screen readers)",onChange:e=>this.handleAltChange(e.target.value),value:imageAlt,width:"100%"}),jsxRuntimeExports.jsx(QuestionMarkers,{editingDisabled:editingDisabled,choices:choices,imageUrl:imageSelected?imageUrl:"",imageWidth:imageWidth,imageHeight:imageHeight,markers:markers,onChange:this.handleMarkersChange,ref:node=>this._questionMarkers=node}),jsxRuntimeExports.jsx(AnswerChoices,{choices:choices,editingDisabled:editingDisabled,onChange:this.handleChoicesChange}),jsxRuntimeExports.jsx(Behavior,{preferredPopoverDirection:preferredPopoverDirection,multipleAnswers:multipleAnswers,hideChoicesFromInstructions:hideChoicesFromInstructions,onChange:this.handleBehaviorChange})]})}constructor(...args){super(...args),this.getSaveWarnings=()=>{const{choices,imageAlt,imageUrl,markers}=this.props;const warnings=[];if(choices.length<2){warnings.push("Question requires at least two answer choices");}if(!imageUrl){warnings.push("Image is not specified for question");}else if(!imageAlt){warnings.push("Question image has no alt text");}if(!markers.length){warnings.push("Question has no markers, to label answers on image");}else {let numNoAnswers=0;let numNoLabels=0;for(const marker of markers){if(!marker.answers.length){numNoAnswers++;}if(!marker.label){numNoLabels++;}}if(numNoAnswers){warnings.push(`Question has ${numNoAnswers} markers with no `+"answers selected");}if(numNoLabels){warnings.push(`Question has ${numNoLabels} markers with no `+"ARIA label");}}return warnings},this.handleImageChange=url=>{this.props.onChange({imageUrl:url,imageWidth:0,imageHeight:0});if(url){Util.getImageSize(url,(width,height)=>{if(this.props.imageUrl===url&&this.props.imageWidth===width&&this.props.imageHeight===height){return}this.props.onChange({imageUrl:url,imageWidth:width,imageHeight:height});});}},this.handleAltChange=alt=>{this.props.onChange({imageAlt:alt});},this.handleChoicesChange=choices=>{this.props.onChange({choices});},this.handleMarkersChange=markers=>{this.props.onChange({markers});},this.handleBehaviorChange=options=>{this.props.onChange(options);};}}LabelImageEditor.defaultProps=labelImageLogic.defaultWidgetOptions;LabelImageEditor.widgetName="label-image";
1799
1806
 
1800
- const{InfoTip: InfoTip$7,TextListEditor: TextListEditor$3}=components;class MatcherEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-matcher-editor",children:[jsxRuntimeExports.jsxs("div",{children:[" ","Correct answer:"," ",jsxRuntimeExports.jsx(InfoTip$7,{children:jsxRuntimeExports.jsx("p",{children:"Enter the correct answers here. The preview on the right will show the cards in a randomized order, which is how the student will see them."})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-clearfix",children:[jsxRuntimeExports.jsx(TextListEditor$3,{options:this.props.left,onChange:(options,cb)=>{this.props.onChange({left:options},cb);},layout:"vertical"}),jsxRuntimeExports.jsx(TextListEditor$3,{options:this.props.right,onChange:(options,cb)=>{this.props.onChange({right:options},cb);},layout:"vertical"})]}),jsxRuntimeExports.jsxs("span",{children:[" ","Labels:"," ",jsxRuntimeExports.jsx(InfoTip$7,{children:jsxRuntimeExports.jsx("p",{children:"These are entirely optional."})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"text",defaultValue:this.props.labels[0],onChange:this.onLabelChange.bind(this,0)}),jsxRuntimeExports.jsx("input",{type:"text",defaultValue:this.props.labels[1],onChange:this.onLabelChange.bind(this,1)})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(Checkbox$1,{label:"Order of the matched pairs matters:",checked:this.props.orderMatters,onChange:value=>{this.props.onChange({orderMatters:value});}}),jsxRuntimeExports.jsxs(InfoTip$7,{children:[jsxRuntimeExports.jsx("p",{children:"With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."}),jsxRuntimeExports.jsx("p",{children:"If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."})]})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(Checkbox$1,{label:"Padding:",checked:this.props.padding,onChange:value=>{this.props.onChange({padding:value});}}),jsxRuntimeExports.jsx(InfoTip$7,{children:jsxRuntimeExports.jsx("p",{children:"Padding is good for text, but not needed for images."})})]})]})}constructor(...args){super(...args),this.onLabelChange=(index,e)=>{const labels=_.clone(this.props.labels);labels[index]=e.target.value;this.props.onChange({labels:labels});},this.getSaveWarnings=()=>{if(this.props.left.length!==this.props.right.length){return ["The two halves of the matcher have different numbers"+" of cards."]}return []},this.serialize=()=>{return _.pick(this.props,"left","right","labels","orderMatters","padding")};}}MatcherEditor.propTypes={left:PropTypes.array,right:PropTypes.array,labels:PropTypes.array,orderMatters:PropTypes.bool,padding:PropTypes.bool};MatcherEditor.widgetName="matcher";MatcherEditor.defaultProps=matcherLogic.defaultWidgetOptions;
1807
+ const{InfoTip: InfoTip$6,TextListEditor: TextListEditor$3}=components;class MatcherEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-matcher-editor",children:[jsxRuntimeExports.jsxs("div",{children:[" ","Correct answer:"," ",jsxRuntimeExports.jsx(InfoTip$6,{children:jsxRuntimeExports.jsx("p",{children:"Enter the correct answers here. The preview on the right will show the cards in a randomized order, which is how the student will see them."})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-clearfix",children:[jsxRuntimeExports.jsx(TextListEditor$3,{options:this.props.left,onChange:(options,cb)=>{this.props.onChange({left:options},cb);},layout:"vertical"}),jsxRuntimeExports.jsx(TextListEditor$3,{options:this.props.right,onChange:(options,cb)=>{this.props.onChange({right:options},cb);},layout:"vertical"})]}),jsxRuntimeExports.jsxs("span",{children:[" ","Labels:"," ",jsxRuntimeExports.jsx(InfoTip$6,{children:jsxRuntimeExports.jsx("p",{children:"These are entirely optional."})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("input",{type:"text",defaultValue:this.props.labels[0],onChange:this.onLabelChange.bind(this,0)}),jsxRuntimeExports.jsx("input",{type:"text",defaultValue:this.props.labels[1],onChange:this.onLabelChange.bind(this,1)})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(Checkbox$1,{label:"Order of the matched pairs matters:",checked:this.props.orderMatters,onChange:value=>{this.props.onChange({orderMatters:value});}}),jsxRuntimeExports.jsxs(InfoTip$6,{children:[jsxRuntimeExports.jsx("p",{children:"With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."}),jsxRuntimeExports.jsx("p",{children:"If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."})]})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(Checkbox$1,{label:"Padding:",checked:this.props.padding,onChange:value=>{this.props.onChange({padding:value});}}),jsxRuntimeExports.jsx(InfoTip$6,{children:jsxRuntimeExports.jsx("p",{children:"Padding is good for text, but not needed for images."})})]})]})}constructor(...args){super(...args),this.onLabelChange=(index,e)=>{const labels=_.clone(this.props.labels);labels[index]=e.target.value;this.props.onChange({labels:labels});},this.getSaveWarnings=()=>{if(this.props.left.length!==this.props.right.length){return ["The two halves of the matcher have different numbers"+" of cards."]}return []},this.serialize=()=>{return _.pick(this.props,"left","right","labels","orderMatters","padding")};}}MatcherEditor.propTypes={left:PropTypes.array,right:PropTypes.array,labels:PropTypes.array,orderMatters:PropTypes.bool,padding:PropTypes.bool};MatcherEditor.widgetName="matcher";MatcherEditor.defaultProps=matcherLogic.defaultWidgetOptions;
1801
1808
 
1802
1809
  const{RangeInput: RangeInput$3}=components;const Matrix=MatrixWidget.widget;const MAX_BOARD_SIZE=6;class MatrixEditor extends React.Component{render(){const matrixProps={onBlur:()=>{},onFocus:()=>{},trackInteraction:()=>{},userInput:{answers:this.props.answers},handleUserInput:userInput=>{this.change({answers:userInput.answers});},...this.props};return jsxRuntimeExports.jsxs("div",{className:"perseus-matrix-editor",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[" ","Max matrix size:"," ",jsxRuntimeExports.jsx(RangeInput$3,{value:this.props.matrixBoardSize,onChange:this.onMatrixBoardSizeChange,format:this.props.labelStyle,useArrowKeys:true})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsx(Matrix,{...matrixProps})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[" ","Matrix prefix:"," ",jsxRuntimeExports.jsx(Editor,{ref:"prefix",apiOptions:this.props.apiOptions,content:this.props.prefix,widgetEnabled:false,onChange:newProps=>{this.change({prefix:newProps.content});}})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[" ","Matrix suffix:"," ",jsxRuntimeExports.jsx(Editor,{ref:"suffix",apiOptions:this.props.apiOptions,content:this.props.suffix,widgetEnabled:false,onChange:newProps=>{this.change({suffix:newProps.content});}})]})]})}constructor(...args){super(...args),this.change=(...args)=>{if(this.props.apiOptions.editingDisabled){return}return Changeable.change.apply(this,args)},this.onMatrixBoardSizeChange=range=>{const matrixSize=getMatrixSize(this.props.answers);if(range[0]!==null&&range[1]!==null){range=[Math.round(Math.min(Math.max(range[0],1),MAX_BOARD_SIZE)),Math.round(Math.min(Math.max(range[1],1),MAX_BOARD_SIZE))];const answers=_(Math.min(range[0],matrixSize[0])).times(row=>{return _(Math.min(range[1],matrixSize[1])).times(col=>{return this.props.answers[row][col]})});this.props.onChange({matrixBoardSize:range,answers:answers});}},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MatrixEditor.propTypes={...Changeable.propTypes,matrixBoardSize:PropTypes.arrayOf(PropTypes.number).isRequired,answers:PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),prefix:PropTypes.string,suffix:PropTypes.string,cursorPosition:PropTypes.arrayOf(PropTypes.number)};MatrixEditor.widgetName="matrix";MatrixEditor.defaultProps=matrixLogic.defaultWidgetOptions;
1803
1810
 
1804
- const{InfoTip: InfoTip$6,NumberInput: NumberInput$6,RangeInput: RangeInput$2}=components;const defaultImage={url:null,top:0,left:0};class MeasurerEditor extends React.Component{render(){const image=_.extend({},defaultImage,this.props.image);return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-measurer",children:[jsxRuntimeExports.jsx("div",{children:"Image displayed under protractor and/or ruler:"}),jsxRuntimeExports.jsxs("div",{children:["URL:"," ",jsxRuntimeExports.jsx("input",{type:"text",className:"perseus-widget-measurer-url",ref:"image-url",defaultValue:image.url,onChange:this._changeUrl}),jsxRuntimeExports.jsx(InfoTip$6,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]}),image.url&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("label",{className:"perseus-widget-left-col",children:["Pixels from top:"," ",jsxRuntimeExports.jsx(NumberInput$6,{placeholder:0,onChange:this._changeTop,value:image.top,useArrowKeys:true})]}),jsxRuntimeExports.jsxs("label",{className:"perseus-widget-right-col",children:["Pixels from left:"," ",jsxRuntimeExports.jsx(NumberInput$6,{placeholder:0,onChange:this._changeLeft,value:image.left,useArrowKeys:true})]})]}),jsxRuntimeExports.jsxs("div",{children:["Containing area [width, height]:"," ",jsxRuntimeExports.jsx(RangeInput$2,{onChange:this.change("box"),value:this.props.box,useArrowKeys:true})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show ruler",checked:this.props.showRuler,onChange:value=>{this.props.onChange({showRuler:value});}})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.props.onChange({showProtractor:value});}})})]}),this.props.showRuler&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler label:"," ",jsxRuntimeExports.jsxs("select",{onChange:e=>this.change("rulerLabel",e.target.value),value:this.props.rulerLabel,children:[jsxRuntimeExports.jsx("option",{value:"",children:"None"}),jsxRuntimeExports.jsx("optgroup",{label:"Metric",children:this.renderLabelChoices([["milimeters","mm"],["centimeters","cm"],["meters","m"],["kilometers","km"]])}),jsxRuntimeExports.jsx("optgroup",{label:"Imperial",children:this.renderLabelChoices([["inches","in"],["feet","ft"],["yards","yd"],["miles","mi"]])})]})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler ticks:"," ",jsxRuntimeExports.jsx("select",{onChange:e=>this.change("rulerTicks",+e.target.value),value:this.props.rulerTicks,children:_.map([1,2,4,8,10,16],function(n){return jsxRuntimeExports.jsx("option",{value:n,children:n},n)})})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Ruler pixels per unit:"," ",jsxRuntimeExports.jsx(NumberInput$6,{placeholder:40,onChange:this.change("rulerPixels"),value:this.props.rulerPixels,useArrowKeys:true})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Ruler length in units:"," ",jsxRuntimeExports.jsx(NumberInput$6,{placeholder:10,onChange:this.change("rulerLength"),value:this.props.rulerLength,useArrowKeys:true})]})})]})]})}constructor(...args){super(...args),this.className="perseus-widget-measurer",this.change=(...args)=>{return Changeable.change.apply(this,args)},this._changeUrl=e=>{this._changeImage("url",e.target.value);},this._changeTop=newTop=>{this._changeImage("top",newTop);},this._changeLeft=newLeft=>{this._changeImage("left",newLeft);},this._changeImage=(subProp,newValue)=>{const image=_.clone(this.props.image);image[subProp]=newValue;this.change("image",image);},this.renderLabelChoices=choices=>{return _.map(choices,function(nameAndValue){const[name,value]=nameAndValue;return jsxRuntimeExports.jsx("option",{value:value,children:name},value)})},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MeasurerEditor.widgetName="measurer";MeasurerEditor.propTypes={...Changeable.propTypes,box:PropTypes.arrayOf(PropTypes.number),image:PropTypes.shape({url:PropTypes.string,top:PropTypes.number,left:PropTypes.number}),showProtractor:PropTypes.bool,showRuler:PropTypes.bool,rulerLabel:PropTypes.string,rulerTicks:PropTypes.number,rulerPixels:PropTypes.number,rulerLength:PropTypes.number};MeasurerEditor.defaultProps=measurerLogic.defaultWidgetOptions;
1805
-
1806
- const{NumberInput: NumberInput$5,TextInput: TextInput$2}=components;class MoleculeWidgetEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["SMILES: ",jsxRuntimeExports.jsx(TextInput$2,{onChange:this.updateMolecule,value:this.props.smiles})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Rotation (deg): ",jsxRuntimeExports.jsx(NumberInput$5,{onChange:this.updateRotation,value:this.props.rotationAngle})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.updateMolecule=newValue=>{this.change({smiles:newValue});},this.updateRotation=newValue=>{this.change({rotationAngle:newValue});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MoleculeWidgetEditor.propTypes={...Changeable.propTypes,rotationAngle:PropTypes.number,smiles:PropTypes.string};MoleculeWidgetEditor.widgetName="molecule-renderer";
1807
-
1808
- const{ButtonGroup,InfoTip: InfoTip$5,NumberInput: NumberInput$4,RangeInput: RangeInput$1}=components;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";class NumberLineEditor extends React.Component{render(){const range=this.props.range;const labelRange=this.props.labelRange;const divisionRange=this.props.divisionRange;range[0]=+range[0];range[1]=+range[1];const width=range[1]-range[0];const numDivisions=this.props.numDivisions;const snapDivisions=this.props.snapDivisions;const tickStep=this.props.tickStep;const isTickCtrl=this.props.isTickCtrl;let step;if(!isTickCtrl){step=tickStep?tickStep/snapDivisions:width/numDivisions/snapDivisions;}else {step=null;}const labelStyleEditorButtons=[{value:"decimal",content:"0.75",title:"Decimals"},{value:"improper",content:"⁷⁄₄",title:"Improper fractions"},{value:"mixed",content:"1¾",title:"Mixed numbers"},{value:"non-reduced",content:"⁸⁄₄",title:"Non-reduced"}];return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-number-line-editor",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Correct x"," ",jsxRuntimeExports.jsxs("select",{value:this.props.correctRel,onChange:this.onChangeRelation,"aria-label":"Select relationship",children:[jsxRuntimeExports.jsx("option",{value:"eq","aria-label":"Equal",children:"="}),jsxRuntimeExports.jsx("option",{value:"lt","aria-label":"Less than",children:"<"}),jsxRuntimeExports.jsx("option",{value:"gt","aria-label":"Greater than",children:">"}),jsxRuntimeExports.jsx("option",{value:"le","aria-label":"Less than or equal",children:"≤"}),jsxRuntimeExports.jsx("option",{value:"ge","aria-label":"Greater than or equal",children:"≥"})]})," ",jsxRuntimeExports.jsx(NumberInput$4,{value:this.props.correctX,format:this.props.labelStyle,onChange:this.onNumChange.bind(this,"correctX"),checkValidity:val=>val>=range[0]&&val<=range[1]&&(!step||number.isInteger((val-range[0])/step)),placeholder:"answer",size:"normal",useArrowKeys:true}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsx("p",{children:"This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, ≤, ≥)."})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[this.props.static?jsxRuntimeExports.jsx("label",{children:"Range:"}):jsxRuntimeExports.jsxs("label",{children:["Position:"," ",jsxRuntimeExports.jsx(NumberInput$4,{value:this.props.initialX,format:this.props.labelStyle,onChange:this.onNumChange.bind(this,"initialX"),placeholder:range[0],checkValidity:val=>{return val>=range[0]&&val<=range[1]},useArrowKeys:true})," ∈ "]}),jsxRuntimeExports.jsx(RangeInput$1,{value:range,onChange:this.onRangeChange,format:this.props.labelStyle,useArrowKeys:true}),jsxRuntimeExports.jsxs(InfoTip$5,{children:[jsxRuntimeExports.jsxs("p",{children:["This controls the initial position of the point along the number line and the",jsxRuntimeExports.jsx("strong",{children:"range"}),", the position of the endpoints of the number line. Setting the range constrains the position of the answer and the labels."]}),jsxRuntimeExports.jsx("p",{children:"In static mode, the initial position of the point is determined by Correct x instead of position."})]})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Labels:"," ",jsxRuntimeExports.jsx(NumberInput$4,{value:labelRange[0],placeholder:range[0],format:this.props.labelStyle,checkValidity:val=>val>=range[0]&&val<=range[1],onChange:this.onLabelRangeChange.bind(this,0),useArrowKeys:true}),jsxRuntimeExports.jsx("span",{children:" & "}),jsxRuntimeExports.jsx(NumberInput$4,{value:labelRange[1],placeholder:range[1],format:this.props.labelStyle,checkValidity:val=>val>=range[0]&&val<=range[1],onChange:this.onLabelRangeChange.bind(this,1),useArrowKeys:true}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsxs("p",{children:["This controls the position of the left / right labels. By default, the labels are set by the range ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"})," Ensure that the labels line up with the tick marks, or it may be confusing for users."]})})]})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Style:"," ",jsxRuntimeExports.jsx(ButtonGroup,{allowEmpty:false,value:this.props.labelStyle,buttons:labelStyleEditorButtons,onChange:this.onLabelStyleChange}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsx("p",{children:"This controls the styling of the labels for the two main labels as well as all the tick mark labels, if applicable. Your choices are decimal, improper fractions, mixed fractions, and non-reduced fractions."})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[!this.props.static&&jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tick controller",checked:!!this.props.isTickCtrl,onChange:value=>{this.props.onChange({isTickCtrl:value});}})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show label ticks",checked:this.props.labelTicks,onChange:value=>{this.props.onChange({labelTicks:value});}})})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:!this.props.static&&jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.props.onChange({showTooltips:value});}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[isTickCtrl&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:["Start num divisions at"," ",jsxRuntimeExports.jsx(NumberInput$4,{value:this.props.numDivisions||null,format:"decimal",onChange:this.onNumDivisionsChange,checkValidity:val=>{return val>=divisionRange[0]&&val<=divisionRange[1]},placeholder:width/this.props.tickStep,useArrowKeys:true})]}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsxs("p",{children:["This controls the number (and position) of the tick marks. The number of divisions is constrained to"," "+divisionRange[0]+EN_DASH+divisionRange[1],".",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"})," The user will be able to specify the number of divisions in a number input."]})})]}),!isTickCtrl&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:["Num divisions:"," ",jsxRuntimeExports.jsx(NumberInput$4,{value:this.props.numDivisions||null,format:"decimal",onChange:this.onNumDivisionsChange,checkValidity:val=>{return val>=divisionRange[0]&&val<=divisionRange[1]},placeholder:width/this.props.tickStep,useArrowKeys:true})]})," ",jsxRuntimeExports.jsxs("label",{children:["or tick step:"," ",jsxRuntimeExports.jsx(NumberInput$4,{value:this.props.tickStep||null,format:this.props.labelStyle,onChange:this.onTickStepChange,checkValidity:val=>{return val>0&&val<=width},placeholder:width/this.props.numDivisions,useArrowKeys:true})]}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsxs("p",{children:["This controls the number (and position) of the tick marks; you can either set the number of divisions (2 divisions would split the entire range in two halves), or the tick step (the distance between ticks) and the other value will be updated accordingly."," ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"})," There is no check to see if labels coordinate with the tick marks, which may be confusing for users if the blue labels and black ticks are off-step."]})})]})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("label",{children:["Snap increments per tick:"," ",jsxRuntimeExports.jsx(NumberInput$4,{value:snapDivisions,checkValidity:val=>val>0,format:this.props.labelStyle,onChange:this.onNumChange.bind(this,"snapDivisions"),useArrowKeys:true})]}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsxs("p",{children:["This determines the number of different places the point will snap between two adjacent tick marks."," ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"}),"Ensure the required number of snap increments is provided to answer the question."]})})]})]})}constructor(...args){super(...args),this.onRangeChange=range=>{this.props.onChange({range:range});},this.onLabelRangeChange=(i,num)=>{let labelRange=this.props.labelRange.slice();const otherNum=labelRange[1-i];if(num==null||otherNum==null){labelRange[i]=num;}else {labelRange=[Math.min(num,otherNum),Math.max(num,otherNum)];}this.props.onChange({labelRange:labelRange});},this.onDivisionRangeChange=divisionRange=>{let numDivisions=this.props.numDivisions;numDivisions=bound(numDivisions,divisionRange[0],divisionRange[1]);this.props.onChange({divisionRange:divisionRange,numDivisions:numDivisions});},this.onNumChange=(key,value)=>{const opts={};opts[key]=value;this.props.onChange(opts);},this.onNumDivisionsChange=numDivisions=>{const divRange=this.props.divisionRange.slice();numDivisions=_.isFinite(numDivisions)?Math.round(numDivisions):0;numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){numDivisions=Math.min(divRange[1],Math.max(divRange[0],numDivisions));this.props.onChange({tickStep:null,divisionRange:divRange,numDivisions:numDivisions});}},this.onTickStepChange=tickStep=>{this.props.onChange({numDivisions:null,tickStep:tickStep});},this.onChangeRelation=e=>{const value=e.target.value;this.props.onChange({correctRel:value,isInequality:value!=="eq"});},this.onLabelStyleChange=labelStyle=>{this.props.onChange({labelStyle:labelStyle});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}NumberLineEditor.widgetName="number-line";NumberLineEditor.defaultProps=numberLineLogic.defaultWidgetOptions;
1809
-
1810
- var styles$2 = {"group":"perseus_Vniq-14O","wrapGroup":"perseus_8W6ltSJv","segment":"perseus_pYpuDydt"};
1811
-
1812
- function ToggleButton({selected,onClick,disabled=false,role="radio",children,style,"aria-label":ariaLabel}){return jsxRuntimeExports.jsx(Clickable,{role:role,"aria-checked":selected,"aria-label":ariaLabel,disabled:disabled,onClick:onClick,className:styles$2.segment,style:style,children:()=>children})}function SegmentedControl({options,selectedValue,onChange,disabled=false,"aria-label":ariaLabel}){return jsxRuntimeExports.jsx(View,{role:"radiogroup","aria-label":ariaLabel,className:styles$2.group,children:options.map(option=>jsxRuntimeExports.jsx(ToggleButton,{role:"radio",selected:option.value===selectedValue,"aria-label":option.ariaLabel,disabled:disabled,onClick:()=>onChange(option.value),children:option.label},option.value))})}function ToggleButtonGroup({options,selectedValues,onToggle,disabled=false,"aria-label":ariaLabel}){return jsxRuntimeExports.jsx(View,{role:"group","aria-label":ariaLabel,className:styles$2.wrapGroup,children:options.map(option=>jsxRuntimeExports.jsx(ToggleButton,{role:"checkbox",selected:selectedValues.includes(option.value),"aria-label":option.ariaLabel,disabled:disabled,onClick:()=>onToggle(option.value),children:option.label},option.value))})}
1811
+ const{InfoTip: InfoTip$5,NumberInput: NumberInput$5,RangeInput: RangeInput$2}=components;const defaultImage={url:null,top:0,left:0};class MeasurerEditor extends React.Component{render(){const image=_.extend({},defaultImage,this.props.image);return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-measurer",children:[jsxRuntimeExports.jsx("div",{children:"Image displayed under protractor and/or ruler:"}),jsxRuntimeExports.jsxs("div",{children:["URL:"," ",jsxRuntimeExports.jsx("input",{type:"text",className:"perseus-widget-measurer-url",ref:"image-url",defaultValue:image.url,onChange:this._changeUrl}),jsxRuntimeExports.jsx(InfoTip$5,{children:jsxRuntimeExports.jsx("p",{children:'Create an image in graphie, or use the "Add image" function to create a background.'})})]}),image.url&&jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("label",{className:"perseus-widget-left-col",children:["Pixels from top:"," ",jsxRuntimeExports.jsx(NumberInput$5,{placeholder:0,onChange:this._changeTop,value:image.top,useArrowKeys:true})]}),jsxRuntimeExports.jsxs("label",{className:"perseus-widget-right-col",children:["Pixels from left:"," ",jsxRuntimeExports.jsx(NumberInput$5,{placeholder:0,onChange:this._changeLeft,value:image.left,useArrowKeys:true})]})]}),jsxRuntimeExports.jsxs("div",{children:["Containing area [width, height]:"," ",jsxRuntimeExports.jsx(RangeInput$2,{onChange:this.change("box"),value:this.props.box,useArrowKeys:true})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show ruler",checked:this.props.showRuler,onChange:value=>{this.props.onChange({showRuler:value});}})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show protractor",checked:this.props.showProtractor,onChange:value=>{this.props.onChange({showProtractor:value});}})})]}),this.props.showRuler&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler label:"," ",jsxRuntimeExports.jsxs("select",{onChange:e=>this.change("rulerLabel",e.target.value),value:this.props.rulerLabel,children:[jsxRuntimeExports.jsx("option",{value:"",children:"None"}),jsxRuntimeExports.jsx("optgroup",{label:"Metric",children:this.renderLabelChoices([["milimeters","mm"],["centimeters","cm"],["meters","m"],["kilometers","km"]])}),jsxRuntimeExports.jsx("optgroup",{label:"Imperial",children:this.renderLabelChoices([["inches","in"],["feet","ft"],["yards","yd"],["miles","mi"]])})]})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:[" ","Ruler ticks:"," ",jsxRuntimeExports.jsx("select",{onChange:e=>this.change("rulerTicks",+e.target.value),value:this.props.rulerTicks,children:_.map([1,2,4,8,10,16],function(n){return jsxRuntimeExports.jsx("option",{value:n,children:n},n)})})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Ruler pixels per unit:"," ",jsxRuntimeExports.jsx(NumberInput$5,{placeholder:40,onChange:this.change("rulerPixels"),value:this.props.rulerPixels,useArrowKeys:true})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Ruler length in units:"," ",jsxRuntimeExports.jsx(NumberInput$5,{placeholder:10,onChange:this.change("rulerLength"),value:this.props.rulerLength,useArrowKeys:true})]})})]})]})}constructor(...args){super(...args),this.className="perseus-widget-measurer",this.change=(...args)=>{return Changeable.change.apply(this,args)},this._changeUrl=e=>{this._changeImage("url",e.target.value);},this._changeTop=newTop=>{this._changeImage("top",newTop);},this._changeLeft=newLeft=>{this._changeImage("left",newLeft);},this._changeImage=(subProp,newValue)=>{const image=_.clone(this.props.image);image[subProp]=newValue;this.change("image",image);},this.renderLabelChoices=choices=>{return _.map(choices,function(nameAndValue){const[name,value]=nameAndValue;return jsxRuntimeExports.jsx("option",{value:value,children:name},value)})},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MeasurerEditor.widgetName="measurer";MeasurerEditor.propTypes={...Changeable.propTypes,box:PropTypes.arrayOf(PropTypes.number),image:PropTypes.shape({url:PropTypes.string,top:PropTypes.number,left:PropTypes.number}),showProtractor:PropTypes.bool,showRuler:PropTypes.bool,rulerLabel:PropTypes.string,rulerTicks:PropTypes.number,rulerPixels:PropTypes.number,rulerLength:PropTypes.number};MeasurerEditor.defaultProps=measurerLogic.defaultWidgetOptions;
1813
1812
 
1814
- var styles$1 = {"field":"perseus_JbwuUF5N","labelRow":"perseus_aHiPdK--","inlineField":"perseus_dNMdOiQI"};
1813
+ const{NumberInput: NumberInput$4,TextInput: TextInput$1}=components;class MoleculeWidgetEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["SMILES: ",jsxRuntimeExports.jsx(TextInput$1,{onChange:this.updateMolecule,value:this.props.smiles})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Rotation (deg): ",jsxRuntimeExports.jsx(NumberInput$4,{onChange:this.updateRotation,value:this.props.rotationAngle})]})})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.updateMolecule=newValue=>{this.change({smiles:newValue});},this.updateRotation=newValue=>{this.change({rotationAngle:newValue});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}MoleculeWidgetEditor.propTypes={...Changeable.propTypes,rotationAngle:PropTypes.number,smiles:PropTypes.string};MoleculeWidgetEditor.widgetName="molecule-renderer";
1815
1814
 
1816
- const{InfoTip: InfoTip$4,NumberInput: NumberInput$3,TextInput: TextInput$1}=components;const{firstNumericalParse}=Util;const answerFormButtons=[{title:"Integers",value:"integer",content:"6"},{title:"Decimals",value:"decimal",content:"0.75"},{title:"Proper fractions",value:"proper",content:"⅗"},{title:"Improper fractions",value:"improper",content:"⁷⁄₄"},{title:"Mixed numbers",value:"mixed",content:"1¾"},{title:"Numbers with π",value:"pi",content:"π"}];const initAnswer=status=>{return {value:null,status:status,message:"",simplify:"required",answerForms:[],strict:false,maxError:null}};class NumericInputEditor extends React.Component{render(){const answers=this.props.answers;const editingDisabled=this.props.apiOptions.editingDisabled;const unsimplifiedAnswers=i=>jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[answers[i]["status"]!=="correct"&&jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Unsimplified answers are irrelevant for this status"}),answers[i]["status"]==="correct"&&jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$1.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Unsimplified answers are"}),jsxRuntimeExports.jsxs(InfoTip$4,{children:[jsxRuntimeExports.jsx("p",{children:'Normally select "ungraded". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and after)'}),jsxRuntimeExports.jsx("p",{children:'Select "accepted" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)'}),jsxRuntimeExports.jsxs("p",{children:['Select "wrong" ',jsxRuntimeExports.jsx("em",{children:"only"})," if we are specifically assessing the ability to simplify."]})]})]}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Unsimplified answers are",disabled:editingDisabled,selectedValue:answers[i]["simplify"],onChange:value=>this.updateAnswer(i,{simplify:value}),options:[{value:"required",label:"Ungraded"},{value:"optional",label:"Accepted"},{value:"enforced",label:"Wrong"}]})]})]});const suggestedAnswerTypes=i=>jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment,{children:[jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$1.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Possible answer formats"}),jsxRuntimeExports.jsxs(InfoTip$4,{children:[jsxRuntimeExports.jsx("p",{children:'Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with π will have format "pi", and values that are fractions will have some subset (mixed will be "mixed" and "proper"; improper/proper will both be "improper" and "proper"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats.'}),jsxRuntimeExports.jsxs("p",{children:["To restrict the answer to ",jsxRuntimeExports.jsx("em",{children:"only"}),' an improper fraction (i.e. 7/4), select the improper fraction and toggle "strict" to true. This ',jsxRuntimeExports.jsx("b",{children:"will not"})," accept 1.75 as an answer."," "]}),jsxRuntimeExports.jsx("p",{children:"Unless you are testing that specific skill, please do not restrict the answer format."})]})]}),jsxRuntimeExports.jsx(ToggleButtonGroup,{"aria-label":"Possible answer formats",disabled:editingDisabled,selectedValues:answers[i]["answerForms"]??[],onToggle:value=>this.onToggleAnswerForm(i,value),options:answerFormButtons.map(format=>({value:format.value,label:format.content,ariaLabel:format.title}))})]}),jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Answer formats are"}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Answer formats are",disabled:editingDisabled,selectedValue:answers[i]["strict"]?"required":"suggested",onChange:value=>this.updateAnswer(i,{strict:value==="required"}),options:[{value:"suggested",label:"Suggested"},{value:"required",label:"Required"}]})]})]});const inputSize=jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$1.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Width"}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsx("p",{children:'Use size "Normal" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them.'})})]}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Width",disabled:editingDisabled,selectedValue:this.props.size,onChange:value=>this.change("size")(value),options:[{value:"normal",label:"Normal (80px)"},{value:"small",label:"Small (40px)"}]})]});const labelText=jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$1.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Answer Field Aria label"}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsx("p",{children:"Text to describe the Answer Field for screenreader users."})})]}),jsxRuntimeExports.jsx(TextInput$1,{labelText:"aria label",value:this.props.labelText,onChange:this.change("labelText")})]});const coefficientCheck=jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsxs(View,{className:styles$1.labelRow,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Number style"}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsx("p",{children:"A coefficient style number allows the student to use - for -1 and an empty string to mean 1."})})]}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Number style",disabled:editingDisabled,selectedValue:this.props.coefficient?"coefficient":"standard",onChange:value=>this.props.onChange({coefficient:value==="coefficient"}),options:[{value:"standard",label:"Standard"},{value:"coefficient",label:"Coefficient"}]})]});const instructions={wrong:"(address the mistake/misconception)",ungraded:"(explain in detail to avoid confusion)",correct:"(reinforce the user's understanding)"};const generateInputAnswerEditors=()=>answers.map((answer,i)=>{const editor=jsxRuntimeExports.jsx(Editor,{apiOptions:this.props.apiOptions,content:answer.message||"",placeholder:"Why is this answer "+answer.status+"? "+instructions[answer.status],widgetEnabled:false,onChange:newProps=>{if("content"in newProps){this.updateAnswer(i,{message:newProps.content});}}});const statusProper=answer.status.charAt(0).toUpperCase()+answer.status.slice(1);const answerFormat=(answer.answerForms||[]).at(-1);const answerString=KhanMath.toNumericString(answer.value??0,answerFormat);const answerRangeText=answer.maxError?`\xb1 ${KhanMath.toNumericString(answer.maxError,answerFormat)}`:"";const answerHeading=answer.value===null?"New Answer":`${statusProper} answer: ${answerString} ${answerRangeText}`;return jsxRuntimeExports.jsx("div",{className:"perseus-widget-row answer-option",children:jsxRuntimeExports.jsxs(PerseusEditorAccordion,{animated:true,expanded:this.state.showAnswerDetails[i],onToggle:()=>{this.onToggleAnswers(i);},header:jsxRuntimeExports.jsx(BodyText,{weight:"bold",tag:"span",children:answerHeading}),children:[jsxRuntimeExports.jsxs("div",{className:"input-answer-editor-value-container"+(answer.maxError?" with-max-error":""),children:[jsxRuntimeExports.jsxs(View,{tag:"label",className:styles$1.inlineField,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"User input"}),jsxRuntimeExports.jsx(NumberInput$3,{value:answer.value,className:"numeric-input-value",placeholder:"answer",format:_.last(answer.answerForms||[]),onFormatChange:(newValue,format)=>{let forms;if(format==="pi"){forms=["pi"];}else if(format==="mixed"){forms=["proper","mixed"];}else if(format==="proper"||format==="improper"){forms=["proper","improper"];}this.updateAnswer(i,{value:firstNumericalParse(newValue),answerForms:forms});},onChange:newValue=>{this.updateAnswer(i,{value:firstNumericalParse(newValue)});}})]}),jsxRuntimeExports.jsx("span",{className:"max-error-plusmn",children:"±"}),jsxRuntimeExports.jsx(NumberInput$3,{className:"max-error-input-value",placeholder:0,value:answers[i]["maxError"],format:_.last(answer.answerForms||[]),onChange:this.updateAnswer(i,"maxError")})]}),jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"Status"}),jsxRuntimeExports.jsx(SegmentedControl,{"aria-label":"Status",disabled:editingDisabled,selectedValue:answers[i]["status"],onChange:value=>this.onEvaluationChange(i,value),options:[{value:"correct",label:"Correct"},{value:"wrong",label:"Wrong"},{value:"ungraded",label:"Ungraded"}]})]}),unsimplifiedAnswers(i),jsxRuntimeExports.jsxs(View,{className:styles$1.field,children:[jsxRuntimeExports.jsx(BodyText,{weight:"semi",children:"(Articles only) Message shown to user"}),editor]}),suggestedAnswerTypes(i),jsxRuntimeExports.jsx(Button,{startIcon:trashIcon,"aria-label":`Delete ${answerHeading}`,className:"delete-item-button",disabled:editingDisabled,onClick:()=>{this.onTrashAnswer(i);},kind:"tertiary",children:"Delete"})]})},i)});return jsxRuntimeExports.jsxs("div",{className:"perseus-input-number-editor",children:[jsxRuntimeExports.jsx(Heading,{title:"General Settings",isCollapsible:true,isOpen:this.state.showSettings,onToggle:this.onToggleHeading("Settings")}),jsxRuntimeExports.jsx("div",{className:`perseus-editor-accordion-container ${this.state.showSettings?"expanded":"collapsed"}`,children:jsxRuntimeExports.jsxs("div",{className:"perseus-editor-accordion-content",children:[inputSize,jsxRuntimeExports.jsxs("label",{children:["Text alignment",jsxRuntimeExports.jsxs(SingleSelect,{selectedValue:this.props.textAlign,onChange:value=>{this.props.onChange({textAlign:value});},placeholder:"Select text alignment",children:[jsxRuntimeExports.jsx(OptionItem,{value:"left",label:"Left"}),jsxRuntimeExports.jsx(OptionItem,{value:"center",label:"Center"}),jsxRuntimeExports.jsx(OptionItem,{value:"right",label:"Right"})]})]}),coefficientCheck,labelText]})}),jsxRuntimeExports.jsx(Heading,{title:"Answers",isCollapsible:true,isOpen:this.state.showAnswers,onToggle:this.onToggleHeading("Answers")}),jsxRuntimeExports.jsx("div",{className:`perseus-editor-accordion-container ${this.state.showAnswers?"expanded":"collapsed"}`,children:jsxRuntimeExports.jsxs("div",{className:"perseus-editor-accordion-content",children:[generateInputAnswerEditors(),jsxRuntimeExports.jsx(Button,{kind:"tertiary",disabled:editingDisabled,onClick:this.addAnswer,children:"Add new answer"})]})})]})}constructor(props){super(props),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.onToggleAnswers=answerIndex=>{const showAnswerDetails=this.state.showAnswerDetails.slice();showAnswerDetails[answerIndex]=!showAnswerDetails[answerIndex];this.setState({showAnswerDetails:showAnswerDetails});},this.onToggleAnswerForm=(answerIndex,answerForm)=>{let answerForms=[...this.props.answers[answerIndex]["answerForms"]??[]];const formSelected=answerForms.includes(answerForm);if(!formSelected){answerForms.push(answerForm);}else {answerForms=answerForms.filter(form=>form!==answerForm);}const updateFn=this.updateAnswer(answerIndex,"answerForms");if(updateFn){updateFn(answerForms);}},this.onToggleHeading=accordionName=>{return ()=>{const toggleName=`show${accordionName}`;const newState={...this.state};newState[toggleName]=!newState[toggleName];this.setState(newState);}},this.onTrashAnswer=choiceIndex=>{if(choiceIndex>=0&&choiceIndex<this.props.answers.length){const answers=this.props.answers.slice(0);answers.splice(choiceIndex,1);this.props.onChange({answers:answers});}},this.onSpace=(e,callback,...args)=>{if(e.key===" "){e.preventDefault();callback.apply(this,args);}},this.onStatusChange=choiceIndex=>{const statuses=["wrong","ungraded","correct"];const answers=this.props.answers;const i=statuses.indexOf(answers[choiceIndex].status);const newStatus=statuses[(i+1)%statuses.length];this.updateAnswer(choiceIndex,{status:newStatus,simplify:newStatus==="correct"?"required":"accepted"});},this.onEvaluationChange=(choiceIndex,newStatus)=>{this.updateAnswer(choiceIndex,{status:newStatus,simplify:newStatus==="correct"?"required":"accepted"});},this.updateAnswer=(choiceIndex,update)=>{if(!_.isObject(update)){return _.partial((choiceIndex,key,value)=>{const update={};update[key]=value;this.updateAnswer(choiceIndex,update);},choiceIndex,update)}let answers=[...this.props.answers];if(choiceIndex===answers.length){const lastAnswer=initAnswer(this.state.lastStatus);answers=answers.concat(lastAnswer);}answers[choiceIndex]=_.extend({},answers[choiceIndex],update);this.props.onChange({answers:answers});},this.addAnswer=()=>{const lastAnswer=initAnswer(this.state.lastStatus);const answers=this.props.answers.concat(lastAnswer);const showAnswerDetails=this.state.showAnswerDetails.concat(true);this.setState({showAnswerDetails:showAnswerDetails});this.props.onChange({answers:answers});},this.getSaveWarnings=()=>{const warnings=[];if(_.contains(_.pluck(this.props.answers,"value"),"")){warnings.push("One or more answers is empty");}this.props.answers.forEach((answer,i)=>{const formatError=answer.strict&&(!answer.answerForms||answer.answerForms.length===0);if(formatError){warnings.push(`Answer ${i+1} is set to string format `+"matching, but no format was selected");}});return warnings},this.serialize=()=>{return EditorJsonify.serialize.call(this)};this.state={lastStatus:"wrong",showAnswerDetails:Array(this.props.answers.length).fill(true),showSettings:true,showAnswers:true};}}NumericInputEditor.widgetName="numeric-input";NumericInputEditor.displayName="NumericInputEditor";NumericInputEditor.defaultProps={...numericInputLogic.defaultWidgetOptions,apiOptions:ApiOptions.defaults};
1815
+ const{ButtonGroup,InfoTip: InfoTip$4,NumberInput: NumberInput$3,RangeInput: RangeInput$1}=components;const bound=(x,gt,lt)=>Math.min(Math.max(x,gt),lt);const EN_DASH="–";class NumberLineEditor extends React.Component{render(){const range=this.props.range;const labelRange=this.props.labelRange;const divisionRange=this.props.divisionRange;range[0]=+range[0];range[1]=+range[1];const width=range[1]-range[0];const numDivisions=this.props.numDivisions;const snapDivisions=this.props.snapDivisions;const tickStep=this.props.tickStep;const isTickCtrl=this.props.isTickCtrl;let step;if(!isTickCtrl){step=tickStep?tickStep/snapDivisions:width/numDivisions/snapDivisions;}else {step=null;}const labelStyleEditorButtons=[{value:"decimal",content:"0.75",title:"Decimals"},{value:"improper",content:"⁷⁄₄",title:"Improper fractions"},{value:"mixed",content:"1¾",title:"Mixed numbers"},{value:"non-reduced",content:"⁸⁄₄",title:"Non-reduced"}];return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-number-line-editor",children:[jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Correct x"," ",jsxRuntimeExports.jsxs("select",{value:this.props.correctRel,onChange:this.onChangeRelation,"aria-label":"Select relationship",children:[jsxRuntimeExports.jsx("option",{value:"eq","aria-label":"Equal",children:"="}),jsxRuntimeExports.jsx("option",{value:"lt","aria-label":"Less than",children:"<"}),jsxRuntimeExports.jsx("option",{value:"gt","aria-label":"Greater than",children:">"}),jsxRuntimeExports.jsx("option",{value:"le","aria-label":"Less than or equal",children:"≤"}),jsxRuntimeExports.jsx("option",{value:"ge","aria-label":"Greater than or equal",children:"≥"})]})," ",jsxRuntimeExports.jsx(NumberInput$3,{value:this.props.correctX,format:this.props.labelStyle,onChange:this.onNumChange.bind(this,"correctX"),checkValidity:val=>val>=range[0]&&val<=range[1]&&(!step||number.isInteger((val-range[0])/step)),placeholder:"answer",size:"normal",useArrowKeys:true}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsx("p",{children:"This is the correct answer. The answer is validated (as right or wrong) by using only the end position of the point and the relation (=, <, >, ≤, ≥)."})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[this.props.static?jsxRuntimeExports.jsx("label",{children:"Range:"}):jsxRuntimeExports.jsxs("label",{children:["Position:"," ",jsxRuntimeExports.jsx(NumberInput$3,{value:this.props.initialX,format:this.props.labelStyle,onChange:this.onNumChange.bind(this,"initialX"),placeholder:range[0],checkValidity:val=>{return val>=range[0]&&val<=range[1]},useArrowKeys:true})," ∈ "]}),jsxRuntimeExports.jsx(RangeInput$1,{value:range,onChange:this.onRangeChange,format:this.props.labelStyle,useArrowKeys:true}),jsxRuntimeExports.jsxs(InfoTip$4,{children:[jsxRuntimeExports.jsxs("p",{children:["This controls the initial position of the point along the number line and the",jsxRuntimeExports.jsx("strong",{children:"range"}),", the position of the endpoints of the number line. Setting the range constrains the position of the answer and the labels."]}),jsxRuntimeExports.jsx("p",{children:"In static mode, the initial position of the point is determined by Correct x instead of position."})]})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:jsxRuntimeExports.jsxs("div",{className:"perseus-widget-left-col",children:["Labels:"," ",jsxRuntimeExports.jsx(NumberInput$3,{value:labelRange[0],placeholder:range[0],format:this.props.labelStyle,checkValidity:val=>val>=range[0]&&val<=range[1],onChange:this.onLabelRangeChange.bind(this,0),useArrowKeys:true}),jsxRuntimeExports.jsx("span",{children:" & "}),jsxRuntimeExports.jsx(NumberInput$3,{value:labelRange[1],placeholder:range[1],format:this.props.labelStyle,checkValidity:val=>val>=range[0]&&val<=range[1],onChange:this.onLabelRangeChange.bind(this,1),useArrowKeys:true}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsxs("p",{children:["This controls the position of the left / right labels. By default, the labels are set by the range ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"})," Ensure that the labels line up with the tick marks, or it may be confusing for users."]})})]})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:["Style:"," ",jsxRuntimeExports.jsx(ButtonGroup,{allowEmpty:false,value:this.props.labelStyle,buttons:labelStyleEditorButtons,onChange:this.onLabelStyleChange}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsx("p",{children:"This controls the styling of the labels for the two main labels as well as all the tick mark labels, if applicable. Your choices are decimal, improper fractions, mixed fractions, and non-reduced fractions."})})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[!this.props.static&&jsxRuntimeExports.jsx("div",{className:"perseus-widget-left-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tick controller",checked:!!this.props.isTickCtrl,onChange:value=>{this.props.onChange({isTickCtrl:value});}})}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-right-col",children:jsxRuntimeExports.jsx(Checkbox$1,{label:"Show label ticks",checked:this.props.labelTicks,onChange:value=>{this.props.onChange({labelTicks:value});}})})]}),jsxRuntimeExports.jsx("div",{className:"perseus-widget-row",children:!this.props.static&&jsxRuntimeExports.jsx(Checkbox$1,{label:"Show tooltips",checked:this.props.showTooltips,onChange:value=>{this.props.onChange({showTooltips:value});}})}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[isTickCtrl&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:["Start num divisions at"," ",jsxRuntimeExports.jsx(NumberInput$3,{value:this.props.numDivisions||null,format:"decimal",onChange:this.onNumDivisionsChange,checkValidity:val=>{return val>=divisionRange[0]&&val<=divisionRange[1]},placeholder:width/this.props.tickStep,useArrowKeys:true})]}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsxs("p",{children:["This controls the number (and position) of the tick marks. The number of divisions is constrained to"," "+divisionRange[0]+EN_DASH+divisionRange[1],".",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"})," The user will be able to specify the number of divisions in a number input."]})})]}),!isTickCtrl&&jsxRuntimeExports.jsxs("span",{children:[jsxRuntimeExports.jsxs("label",{children:["Num divisions:"," ",jsxRuntimeExports.jsx(NumberInput$3,{value:this.props.numDivisions||null,format:"decimal",onChange:this.onNumDivisionsChange,checkValidity:val=>{return val>=divisionRange[0]&&val<=divisionRange[1]},placeholder:width/this.props.tickStep,useArrowKeys:true})]})," ",jsxRuntimeExports.jsxs("label",{children:["or tick step:"," ",jsxRuntimeExports.jsx(NumberInput$3,{value:this.props.tickStep||null,format:this.props.labelStyle,onChange:this.onTickStepChange,checkValidity:val=>{return val>0&&val<=width},placeholder:width/this.props.numDivisions,useArrowKeys:true})]}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsxs("p",{children:["This controls the number (and position) of the tick marks; you can either set the number of divisions (2 divisions would split the entire range in two halves), or the tick step (the distance between ticks) and the other value will be updated accordingly."," ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"})," There is no check to see if labels coordinate with the tick marks, which may be confusing for users if the blue labels and black ticks are off-step."]})})]})]}),jsxRuntimeExports.jsxs("div",{className:"perseus-widget-row",children:[jsxRuntimeExports.jsxs("label",{children:["Snap increments per tick:"," ",jsxRuntimeExports.jsx(NumberInput$3,{value:snapDivisions,checkValidity:val=>val>0,format:this.props.labelStyle,onChange:this.onNumChange.bind(this,"snapDivisions"),useArrowKeys:true})]}),jsxRuntimeExports.jsx(InfoTip$4,{children:jsxRuntimeExports.jsxs("p",{children:["This determines the number of different places the point will snap between two adjacent tick marks."," ",jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsx("strong",{children:"Note:"}),"Ensure the required number of snap increments is provided to answer the question."]})})]})]})}constructor(...args){super(...args),this.onRangeChange=range=>{this.props.onChange({range:range});},this.onLabelRangeChange=(i,num)=>{let labelRange=this.props.labelRange.slice();const otherNum=labelRange[1-i];if(num==null||otherNum==null){labelRange[i]=num;}else {labelRange=[Math.min(num,otherNum),Math.max(num,otherNum)];}this.props.onChange({labelRange:labelRange});},this.onDivisionRangeChange=divisionRange=>{let numDivisions=this.props.numDivisions;numDivisions=bound(numDivisions,divisionRange[0],divisionRange[1]);this.props.onChange({divisionRange:divisionRange,numDivisions:numDivisions});},this.onNumChange=(key,value)=>{const opts={};opts[key]=value;this.props.onChange(opts);},this.onNumDivisionsChange=numDivisions=>{const divRange=this.props.divisionRange.slice();numDivisions=_.isFinite(numDivisions)?Math.round(numDivisions):0;numDivisions=numDivisions<0?numDivisions*-1:numDivisions;if(numDivisions){numDivisions=Math.min(divRange[1],Math.max(divRange[0],numDivisions));this.props.onChange({tickStep:null,divisionRange:divRange,numDivisions:numDivisions});}},this.onTickStepChange=tickStep=>{this.props.onChange({numDivisions:null,tickStep:tickStep});},this.onChangeRelation=e=>{const value=e.target.value;this.props.onChange({correctRel:value,isInequality:value!=="eq"});},this.onLabelStyleChange=labelStyle=>{this.props.onChange({labelStyle:labelStyle});},this.serialize=()=>{return EditorJsonify.serialize.call(this)};}}NumberLineEditor.widgetName="number-line";NumberLineEditor.defaultProps=numberLineLogic.defaultWidgetOptions;
1817
1816
 
1818
1817
  const{InfoTip: InfoTip$3,TextListEditor: TextListEditor$2}=components;const NORMAL="normal";const AUTO="auto";const HORIZONTAL$1="horizontal";const VERTICAL$1="vertical";const getUpdatedOptions=(correctOptions,otherOptions,whichOptions,options)=>{const props={};if(whichOptions&&options!==undefined){props[whichOptions]=options.map(option=>({content:option}));}const correctOptionsToUse=whichOptions==="correctOptions"?props.correctOptions:correctOptions;const otherOptionsToUse=whichOptions==="otherOptions"?props.otherOptions:otherOptions;const allOptions=[...correctOptionsToUse,...otherOptionsToUse];const updatedOptions=[...new Set(allOptions.map(item=>item.content))].filter(content=>content!=="").sort().sort((a,b)=>{const getCategoryScore=content=>{if(/\d/.test(content)){return 0}if(/^\$?[a-zA-Z]+\$?$/.test(content)){return 2}return 1};return getCategoryScore(a)-getCategoryScore(b)}).map(content=>({content}));return {...props,options:updatedOptions}};class OrdererEditor extends React.Component{render(){return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-orderer",children:[jsxRuntimeExports.jsxs("div",{children:[" ","Correct answer:"," ",jsxRuntimeExports.jsx(InfoTip$3,{children:jsxRuntimeExports.jsx("p",{children:"Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."})})]}),jsxRuntimeExports.jsx(TextListEditor$2,{options:_.pluck(this.props.correctOptions,"content"),onChange:this.onOptionsChange.bind(this,"correctOptions"),layout:this.props.layout}),jsxRuntimeExports.jsxs("div",{children:[" ","Other cards:"," ",jsxRuntimeExports.jsx(InfoTip$3,{children:jsxRuntimeExports.jsx("p",{children:"Create cards that are not part of the answer."})})]}),jsxRuntimeExports.jsx(TextListEditor$2,{options:_.pluck(this.props.otherOptions,"content"),onChange:this.onOptionsChange.bind(this,"otherOptions"),layout:this.props.layout}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:[" ","Layout:"," ",jsxRuntimeExports.jsxs("select",{value:this.props.layout,onChange:this.onLayoutChange,children:[jsxRuntimeExports.jsx("option",{value:HORIZONTAL$1,children:"Horizontal"}),jsxRuntimeExports.jsx("option",{value:VERTICAL$1,children:"Vertical"})]})]}),jsxRuntimeExports.jsx(InfoTip$3,{children:jsxRuntimeExports.jsx("p",{children:"Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:[" ","Height:"," ",jsxRuntimeExports.jsxs("select",{value:this.props.height,onChange:this.onHeightChange,children:[jsxRuntimeExports.jsx("option",{value:NORMAL,children:"Normal"}),jsxRuntimeExports.jsx("option",{value:AUTO,children:"Automatic"})]})]}),jsxRuntimeExports.jsx(InfoTip$3,{children:jsxRuntimeExports.jsx("p",{children:'Use "Normal" for text, "Automatic" for images.'})})]})]})}constructor(...args){super(...args),this.onOptionsChange=(whichOptions,options,cb)=>{const updatedOptions=getUpdatedOptions(this.props.correctOptions||[],this.props.otherOptions||[],whichOptions,options);this.props.onChange(updatedOptions,cb);},this.onLayoutChange=e=>{this.props.onChange({layout:e.target.value});},this.onHeightChange=e=>{this.props.onChange({height:e.target.value});},this.serialize=()=>{const{options}=getUpdatedOptions(this.props.correctOptions||[],this.props.otherOptions||[]);return {options:options,correctOptions:this.props.correctOptions,otherOptions:this.props.otherOptions,height:this.props.height,layout:this.props.layout}};}}OrdererEditor.propTypes={correctOptions:PropTypes.array,otherOptions:PropTypes.array,height:PropTypes.oneOf([NORMAL,AUTO]),layout:PropTypes.oneOf([HORIZONTAL$1,VERTICAL$1]),onChange:PropTypes.func.isRequired};OrdererEditor.widgetName="orderer";OrdererEditor.defaultProps=ordererLogic.defaultWidgetOptions;
1819
1818
 
1820
1819
  class PhetSimulationEditor extends React.Component{serialize(){return {url:this.props.url,description:this.props.description}}render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsx(LabeledTextField,{label:"URL",value:this.props.url,onChange:url=>this.props.onChange({url}),style:{marginBottom:spacing.large_24}}),jsxRuntimeExports.jsx(LabeledTextField,{label:"Description",value:this.props.description,onChange:description=>this.props.onChange({description})})]})}constructor(...args){super(...args),this.getSaveWarnings=()=>{if(makeSafeUrl(this.props.url,"en","https://phet.colorado.edu")===null){return ["Please enter a URL from the PhET domain."]}return []};}}PhetSimulationEditor.defaultProps=phetSimulationLogic.defaultWidgetOptions;PhetSimulationEditor.widgetName="phet-simulation";
1821
1820
 
1822
- const{InfoTip: InfoTip$2,NumberInput: NumberInput$2,RangeInput,TextListEditor: TextListEditor$1}=components;const Plotter=PlotterWidget.widget;const STARTING="starting";const CORRECT="correct";const editingStates=[STARTING,CORRECT];function padArray(array,n,value){const copy=_.clone(array);copy.length=n;for(let i=array.length;i<n;i++){copy[i]=value;}return copy}const editorDefaults={scaleY:1,maxY:10,snapsPerLine:2};const formatNumber=num=>"$"+number.round(num,2)+"$";class PlotterEditor extends React.Component{UNSAFE_componentWillMount(){this.fetchPic(this.props.picUrl);}UNSAFE_componentWillReceiveProps(nextProps){this.fetchPic(nextProps.picUrl);if(nextProps.static){this.setState({editing:"starting"});}}render(){const setFromScale=_.contains(["line","histogram","dotplot"],this.props.type);const canChangeSnaps=!_.contains(["pic","dotplot"],this.props.type);const plotterProps={...this.props,trackInteraction:()=>{},starting:this.props[this.state.editing],onChange:this.handlePlotterChange,userInput:this.props.correct,handleUserInput:userInput=>{this.props.onChange({correct:userInput});}};return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-plotter-editor",children:[jsxRuntimeExports.jsxs("div",{children:["Chart type:"," ",plotterPlotTypes.map(type=>{return jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",name:"chart-type",checked:this.props.type===type,onChange:_.partial(this.changeType,type)}),type]},type)},this)]}),jsxRuntimeExports.jsxs("div",{children:["Labels:"," ",["x","y"].map((axis,i)=>{return jsxRuntimeExports.jsxs("label",{children:[axis+":",jsxRuntimeExports.jsx("input",{type:"text",onChange:_.partial(this.changeLabel,i),defaultValue:this.props.labels[i]})]},axis)},this)]}),setFromScale&&jsxRuntimeExports.jsxs("div",{className:"set-from-scale-box",children:[jsxRuntimeExports.jsx("span",{className:"categories-title",children:"Set Categories From Scale"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Tick Step:"," ",jsxRuntimeExports.jsx(NumberInput$2,{placeholder:1,useArrowKeys:true,value:this.state.tickStep,onChange:this.handleChangeTickStep})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"The difference between adjacent ticks."})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Range:"," ",jsxRuntimeExports.jsx(RangeInput,{placeholder:[0,10],useArrowKeys:true,value:[this.state.minX,this.state.maxX],onChange:this.handleChangeRange})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("button",{onClick:this.setCategoriesFromScale,children:["Set Categories"," "]})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Label Interval:"," ",jsxRuntimeExports.jsx(NumberInput$2,{useArrowKeys:true,value:this.props.labelInterval,onChange:this.changeLabelInterval})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Which ticks to display the labels for. For instance, setting this to "4" will only show every 4th label (plus the last one)'})})]}),this.props.type==="pic"&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Picture:"," ",jsxRuntimeExports.jsx(BlurInput,{className:"pic-url",value:this.props.picUrl,onChange:this.changePicUrl}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Use the default picture of Earth, or insert the URL for a different picture using the "Add image" function.'})})]}),this.state.pic&&this.state.pic.width!==this.state.pic.height&&jsxRuntimeExports.jsxs("p",{className:"warning",children:[jsxRuntimeExports.jsx("b",{children:"Warning"}),": You are using a picture which is not square. This means the image will get distorted. You should probably crop it to be square."]})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Categories:"," ",jsxRuntimeExports.jsx(TextListEditor$1,{ref:"categories",layout:"horizontal",options:this.props.categories,onChange:this.changeCategories})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Scale (y):"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeScale,defaultValue:this.props.scaleY})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Max y:"," ",jsxRuntimeExports.jsx("input",{type:"text",ref:"maxY",onChange:this.changeMax,defaultValue:this.props.maxY})]})}),canChangeSnaps&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Snaps per line:"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeSnaps,defaultValue:this.props.snapsPerLine})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."})})]}),jsxRuntimeExports.jsxs("div",{children:["Editing values:"," ",editingStates.map(editing=>jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",disabled:editing===CORRECT&&this.props.static,checked:this.props.static?editing===STARTING:this.state.editing===editing,onChange:e=>this.changeEditing(editing)}),editing]},editing)),jsxRuntimeExports.jsxs(InfoTip$2,{children:[jsxRuntimeExports.jsx("p",{children:"Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."}),jsxRuntimeExports.jsx("p",{children:"In static mode, the starting values are rendered out to the displayed widget."})]})]}),jsxRuntimeExports.jsx(Plotter,{...plotterProps})]})}constructor(...args){super(...args),this.state={editing:this.props.static?STARTING:CORRECT,pic:null,loadedUrl:null,minX:null,maxX:null,tickStep:null},this.fetchPic=url=>{if(this.state.loadedUrl!==url){const pic=new Image;pic.src=url;pic.onload=()=>{this.setState({pic:pic,loadedUrl:url});};}},this.handleChangeTickStep=value=>{this.setState({tickStep:value});},this.handleChangeRange=newValue=>{this.setState({minX:newValue[0],maxX:newValue[1]});},this.changeLabelInterval=value=>{this.props.onChange({labelInterval:value});},this.handlePlotterChange=newProps=>{const props={};props[this.state.editing]=newProps.values;this.props.onChange(props);},this.changeType=type=>{let categories;if(type==="histogram"){categories=[formatNumber(0)].concat(this.props.categories);this.props.onChange({type:type,categories:categories});}else if(this.props.type==="histogram"){categories=this.props.categories.slice(1);this.props.onChange({type:type,categories:categories});}else {this.props.onChange({type:type});}if(categories){const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");}},this.changeLabel=(i,e)=>{const labels=_.clone(this.props.labels);labels[i]=e.target.value;this.props.onChange({labels:labels});},this.changePicUrl=value=>{const url=Util.getRealImageUrl(value);this.props.onChange({picUrl:url});},this.changeCategories=categories=>{let n=categories.length;if(this.props.type==="histogram"){n--;}const value=this.props.scaleY;this.props.onChange({categories:categories,correct:padArray(this.props.correct,n,value),starting:padArray(this.props.starting,n,value)});},this.changeScale=e=>{const oldScale=this.props.scaleY;const newScale=+e.target.value||editorDefaults.scaleY;const scale=function(value){return value*newScale/oldScale};const maxY=scale(this.props.maxY);this.props.onChange({scaleY:newScale,maxY:maxY,correct:_.map(this.props.correct,scale),starting:_.map(this.props.starting,scale)});ReactDOM.findDOMNode(this.refs.maxY).value=maxY;},this.changeMax=e=>{this.props.onChange({maxY:+e.target.value||editorDefaults.maxY});},this.changeSnaps=e=>{this.props.onChange({snapsPerLine:+e.target.value||editorDefaults.snapsPerLine});},this.changeEditing=editing=>{this.setState({editing:editing});},this.setCategoriesFromScale=()=>{const scale=this.state.tickStep||1;const min=this.state.minX||0;const max=this.state.maxX||0;const length=Math.floor((max-min)/scale)*scale;let categories;if(this.props.type==="histogram"||this.props.type==="dotplot"){categories=_.range(0,length+scale,scale);}else {categories=_.range(scale,length+scale,scale);}categories=_.map(categories,num=>num+min);categories=_.map(categories,formatNumber);this.changeCategories(categories);const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");},this.serialize=()=>{const json=_.pick(this.props,"correct","starting","type","labels","categories","scaleY","maxY","snapsPerLine","labelInterval");if(this.props.type==="pic"){json.picUrl=this.props.picUrl;}return json};}}PlotterEditor.widgetName="plotter";PlotterEditor.defaultProps=plotterLogic.defaultWidgetOptions;
1821
+ const{InfoTip: InfoTip$2,NumberInput: NumberInput$2,RangeInput,TextListEditor: TextListEditor$1}=components;const Plotter=PlotterWidget.widget;const STARTING="starting";const CORRECT="correct";const editingStates=[STARTING,CORRECT];function padArray(array,n,value){const copy=_.clone(array);copy.length=n;for(let i=array.length;i<n;i++){copy[i]=value;}return copy}const editorDefaults={scaleY:1,maxY:10,snapsPerLine:2};const formatNumber=num=>"$"+number.round(num,2)+"$";class PlotterEditor extends React.Component{UNSAFE_componentWillMount(){this.fetchPic(this.props.picUrl);}UNSAFE_componentWillReceiveProps(nextProps){this.fetchPic(nextProps.picUrl);if(nextProps.static){this.setState({editing:"starting"});}}render(){const setFromScale=_.contains(["line","histogram","dotplot"],this.props.type);const canChangeSnaps=!_.contains(["pic","dotplot"],this.props.type);const plotterProps={...this.props,trackInteraction:()=>{},starting:this.props[this.state.editing],onChange:this.handlePlotterChange,userInput:this.props.correct,handleUserInput:userInput=>{this.props.onChange({correct:userInput});}};return jsxRuntimeExports.jsxs("div",{className:"perseus-widget-plotter-editor",children:[jsxRuntimeExports.jsxs("div",{children:["Chart type:"," ",plotterPlotTypes.map(type=>{return jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",name:"chart-type",checked:this.props.type===type,onChange:_.partial(this.changeType,type)}),type]},type)},this)]}),jsxRuntimeExports.jsxs("div",{children:["Labels:"," ",["x","y"].map((axis,i)=>{return jsxRuntimeExports.jsxs("label",{children:[axis+":",jsxRuntimeExports.jsx("input",{type:"text",onChange:_.partial(this.changeLabel,i),defaultValue:this.props.labels[i]})]},axis)},this)]}),setFromScale&&jsxRuntimeExports.jsxs("div",{className:"set-from-scale-box",children:[jsxRuntimeExports.jsx("span",{className:"categories-title",children:"Set Categories From Scale"}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Tick Step:"," ",jsxRuntimeExports.jsx(NumberInput$2,{placeholder:1,useArrowKeys:true,value:this.state.tickStep,onChange:this.handleChangeTickStep})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"The difference between adjacent ticks."})})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Range:"," ",jsxRuntimeExports.jsx(RangeInput,{placeholder:[0,10],useArrowKeys:true,value:[this.state.minX,this.state.maxX],onChange:this.handleChangeRange})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("button",{onClick:this.setCategoriesFromScale,children:["Set Categories"," "]})})]}),jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Label Interval:"," ",jsxRuntimeExports.jsx(NumberInput$2,{useArrowKeys:true,value:this.props.labelInterval,onChange:this.changeLabelInterval})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Which ticks to display the labels for. For instance, setting this to "4" will only show every 4th label (plus the last one)'})})]}),this.props.type==="pic"&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Picture:"," ",jsxRuntimeExports.jsx(BlurInput,{className:"pic-url",value:this.props.picUrl??"",onChange:this.changePicUrl}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:'Use the default picture of Earth, or insert the URL for a different picture using the "Add image" function.'})})]}),this.state.pic&&this.state.pic.width!==this.state.pic.height&&jsxRuntimeExports.jsxs("p",{className:"warning",children:[jsxRuntimeExports.jsx("b",{children:"Warning"}),": You are using a picture which is not square. This means the image will get distorted. You should probably crop it to be square."]})]}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Categories:"," ",jsxRuntimeExports.jsx(TextListEditor$1,{ref:"categories",layout:"horizontal",options:this.props.categories,onChange:this.changeCategories})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Scale (y):"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeScale,defaultValue:this.props.scaleY})]})}),jsxRuntimeExports.jsx("div",{children:jsxRuntimeExports.jsxs("label",{children:["Max y:"," ",jsxRuntimeExports.jsx("input",{type:"text",ref:"maxY",onChange:this.changeMax,defaultValue:this.props.maxY})]})}),canChangeSnaps&&jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["Snaps per line:"," ",jsxRuntimeExports.jsx("input",{type:"text",onChange:this.changeSnaps,defaultValue:this.props.snapsPerLine})]}),jsxRuntimeExports.jsx(InfoTip$2,{children:jsxRuntimeExports.jsx("p",{children:"Creates the specified number of divisions between the horizontal lines. Fewer snaps between lines makes the graph easier for the student to create correctly."})})]}),jsxRuntimeExports.jsxs("div",{children:["Editing values:"," ",editingStates.map(editing=>jsxRuntimeExports.jsxs("label",{children:[jsxRuntimeExports.jsx("input",{type:"radio",disabled:editing===CORRECT&&this.props.static,checked:this.props.static?editing===STARTING:this.state.editing===editing,onChange:e=>this.changeEditing(editing)}),editing]},editing)),jsxRuntimeExports.jsxs(InfoTip$2,{children:[jsxRuntimeExports.jsx("p",{children:"Use this toggle to switch between editing the correct answer (what the student will be graded on) and the starting values (what the student will see plotted when they start the problem). Note: These cannot be the same."}),jsxRuntimeExports.jsx("p",{children:"In static mode, the starting values are rendered out to the displayed widget."})]})]}),jsxRuntimeExports.jsx(Plotter,{...plotterProps})]})}constructor(...args){super(...args),this.state={editing:this.props.static?STARTING:CORRECT,pic:null,loadedUrl:null,minX:null,maxX:null,tickStep:null},this.fetchPic=url=>{if(url==null){if(this.state.pic!==null){this.setState({pic:null,loadedUrl:null});}return}if(this.state.loadedUrl!==url){const pic=new Image;pic.src=url;pic.onload=()=>{this.setState({pic:pic,loadedUrl:url});};}},this.handleChangeTickStep=value=>{this.setState({tickStep:value});},this.handleChangeRange=newValue=>{this.setState({minX:newValue[0],maxX:newValue[1]});},this.changeLabelInterval=value=>{this.props.onChange({labelInterval:value});},this.handlePlotterChange=newProps=>{const props={};props[this.state.editing]=newProps.values;this.props.onChange(props);},this.changeType=type=>{let categories;if(type==="histogram"){categories=[formatNumber(0)].concat(this.props.categories);this.props.onChange({type:type,categories:categories});}else if(this.props.type==="histogram"){categories=this.props.categories.slice(1);this.props.onChange({type:type,categories:categories});}else {this.props.onChange({type:type});}if(categories){const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");}},this.changeLabel=(i,e)=>{const labels=_.clone(this.props.labels);labels[i]=e.target.value;this.props.onChange({labels:labels});},this.changePicUrl=value=>{const url=Util.getRealImageUrl(value);this.props.onChange({picUrl:url});},this.changeCategories=categories=>{let n=categories.length;if(this.props.type==="histogram"){n--;}const value=this.props.scaleY;this.props.onChange({categories:categories,correct:padArray(this.props.correct,n,value),starting:padArray(this.props.starting,n,value)});},this.changeScale=e=>{const oldScale=this.props.scaleY;const newScale=+e.target.value||editorDefaults.scaleY;const scale=function(value){return value*newScale/oldScale};const maxY=scale(this.props.maxY);this.props.onChange({scaleY:newScale,maxY:maxY,correct:_.map(this.props.correct,scale),starting:_.map(this.props.starting,scale)});ReactDOM.findDOMNode(this.refs.maxY).value=maxY;},this.changeMax=e=>{this.props.onChange({maxY:+e.target.value||editorDefaults.maxY});},this.changeSnaps=e=>{this.props.onChange({snapsPerLine:+e.target.value||editorDefaults.snapsPerLine});},this.changeEditing=editing=>{this.setState({editing:editing});},this.setCategoriesFromScale=()=>{const scale=this.state.tickStep||1;const min=this.state.minX||0;const max=this.state.maxX||0;const length=Math.floor((max-min)/scale)*scale;let categories;if(this.props.type==="histogram"||this.props.type==="dotplot"){categories=_.range(0,length+scale,scale);}else {categories=_.range(scale,length+scale,scale);}categories=_.map(categories,num=>num+min);categories=_.map(categories,formatNumber);this.changeCategories(categories);const node=ReactDOM.findDOMNode(this.refs.categories);node.value=categories.join(", ");},this.serialize=()=>{const json=_.pick(this.props,"correct","starting","type","labels","categories","scaleY","maxY","snapsPerLine","labelInterval");if(this.props.type==="pic"){json.picUrl=this.props.picUrl;}return json};}}PlotterEditor.widgetName="plotter";PlotterEditor.defaultProps=plotterLogic.defaultWidgetOptions;
1823
1822
 
1824
1823
  const{NumberInput: NumberInput$1,TextInput}=components;function validateOptions(height,programID){const errors=[];if(programID===""){errors.push("The program ID is required.");}if(!Number.isInteger(height)||height<1){errors.push("The height must be a positive integer.");}return errors}class PythonProgramEditor extends React.Component{serialize(){return {programID:this.props.programID,height:this.props.height}}render(){return jsxRuntimeExports.jsxs("div",{children:[jsxRuntimeExports.jsxs("label",{children:["User Program ID:"," ",jsxRuntimeExports.jsx(TextInput,{value:this.props.programID,onChange:this.change("programID"),placeholder:"123"})]}),jsxRuntimeExports.jsx("br",{}),jsxRuntimeExports.jsxs("label",{children:["Height:"," ",jsxRuntimeExports.jsx(NumberInput$1,{value:this.props.height,onChange:this.change("height"),placeholder:"400"})]})]})}constructor(...args){super(...args),this.change=(...args)=>{return Changeable.change.apply(this,args)},this.getSaveWarnings=()=>{return validateOptions(this.props.height,this.props.programID)};}}PythonProgramEditor.widgetName="python-program";PythonProgramEditor.defaultProps=pythonProgramLogic.defaultWidgetOptions;
1825
1824