@khanacademy/perseus 16.0.0 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/article-renderer.d.ts +1 -2
- package/dist/components.d.ts +0 -1
- package/dist/es/index.css +0 -90
- package/dist/es/index.js +15 -691
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +0 -90
- package/dist/index.d.ts +0 -1
- package/dist/index.js +13 -692
- package/dist/index.js.map +1 -1
- package/dist/server-item-renderer.d.ts +42 -15
- package/dist/strings.js +0 -23
- package/package.json +2 -2
- package/src/__stories__/server-item-renderer.stories.tsx +20 -1
- package/src/__testdata__/server-item-renderer.testdata.ts +173 -0
- package/src/__tests__/server-item-renderer.test.tsx +38 -1
- package/src/article-renderer.tsx +13 -15
- package/src/components.ts +0 -1
- package/src/index.ts +0 -1
- package/src/server-item-renderer.tsx +26 -14
- package/src/styles/khan-exercise.css +0 -24
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/components/tex-buttons.d.ts +0 -25
- package/dist/item-renderer.d.ts +0 -125
- package/dist/mixins/provide-keypad.d.ts +0 -39
- package/src/__stories__/item-renderer.stories.tsx +0 -30
- package/src/__testdata__/item-renderer.testdata.ts +0 -299
- package/src/__tests__/__snapshots__/item-renderer.test.tsx.snap +0 -224
- package/src/__tests__/item-renderer.test.tsx +0 -930
- package/src/components/__stories__/text-buttons.stories.tsx +0 -54
- package/src/components/tex-buttons.tsx +0 -334
- package/src/item-renderer.tsx +0 -529
- package/src/mixins/provide-keypad.tsx +0 -137
package/dist/index.js
CHANGED
|
@@ -10260,7 +10260,7 @@ const pluck = function (table, subKey) {
|
|
|
10260
10260
|
* });
|
|
10261
10261
|
* {a: 2, b: 3}
|
|
10262
10262
|
*/
|
|
10263
|
-
const mapObject$
|
|
10263
|
+
const mapObject$2 = function (obj, lambda) {
|
|
10264
10264
|
const result = {};
|
|
10265
10265
|
___default["default"].each(___default["default"].keys(obj), function (key) {
|
|
10266
10266
|
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'K'.
|
|
@@ -10286,7 +10286,7 @@ const mapObjectFromArray$1 = function (arr, lambda) {
|
|
|
10286
10286
|
};
|
|
10287
10287
|
var objective_ = {
|
|
10288
10288
|
pluck: pluck,
|
|
10289
|
-
mapObject: mapObject$
|
|
10289
|
+
mapObject: mapObject$2,
|
|
10290
10290
|
mapObjectFromArray: mapObjectFromArray$1
|
|
10291
10291
|
};
|
|
10292
10292
|
|
|
@@ -18932,7 +18932,7 @@ class WidgetContainer extends React__namespace.Component {
|
|
|
18932
18932
|
}
|
|
18933
18933
|
|
|
18934
18934
|
const {
|
|
18935
|
-
mapObject: mapObject$
|
|
18935
|
+
mapObject: mapObject$1,
|
|
18936
18936
|
mapObjectFromArray
|
|
18937
18937
|
} = objective_;
|
|
18938
18938
|
const rContainsNonWhitespace = /\S/;
|
|
@@ -19159,7 +19159,7 @@ class Renderer extends React__namespace.Component {
|
|
|
19159
19159
|
// @ts-expect-error - TS2322 - Type '(props: Props) => Partial<Record<string, CategorizerWidget | CSProgramWidget | DefinitionWidget | DropdownWidget | ... 35 more ... | VideoWidget>>' is not assignable to type '(props: Props) => { [key: string]: PerseusWidget; }'.
|
|
19160
19160
|
_getAllWidgetsInfo = props => {
|
|
19161
19161
|
// @ts-expect-error - TS2345 - Argument of type '{ [key: string]: PerseusWidget; }' is not assignable to parameter of type 'Partial<Record<string, CategorizerWidget>>'.
|
|
19162
|
-
return mapObject$
|
|
19162
|
+
return mapObject$1(props.widgets, (widgetInfo, widgetId) => {
|
|
19163
19163
|
if (!widgetInfo.type || !widgetInfo.alignment) {
|
|
19164
19164
|
const newValues = {};
|
|
19165
19165
|
if (!widgetInfo.type) {
|
|
@@ -19175,7 +19175,7 @@ class Renderer extends React__namespace.Component {
|
|
|
19175
19175
|
};
|
|
19176
19176
|
_getAllWidgetsStartProps = (allWidgetInfo, props) => {
|
|
19177
19177
|
// @ts-expect-error - TS2345 - Argument of type '{ [key: string]: PerseusWidget; }' is not assignable to parameter of type 'Partial<Record<string, CategorizerWidget>>'.
|
|
19178
|
-
return mapObject$
|
|
19178
|
+
return mapObject$1(allWidgetInfo, widgetInfo => {
|
|
19179
19179
|
return getRendererPropsForWidgetInfo(widgetInfo, props.problemNum);
|
|
19180
19180
|
});
|
|
19181
19181
|
};
|
|
@@ -19295,7 +19295,7 @@ class Renderer extends React__namespace.Component {
|
|
|
19295
19295
|
* state from that instead of the current widget props.
|
|
19296
19296
|
*/
|
|
19297
19297
|
getSerializedState = widgetProps => {
|
|
19298
|
-
return mapObject$
|
|
19298
|
+
return mapObject$1(widgetProps || this.state.widgetProps, (props, widgetId) => {
|
|
19299
19299
|
const widget = this.getWidgetInstance(widgetId);
|
|
19300
19300
|
if (widget && widget.getSerializedState) {
|
|
19301
19301
|
return widget.getSerializedState();
|
|
@@ -19331,7 +19331,7 @@ class Renderer extends React__namespace.Component {
|
|
|
19331
19331
|
}
|
|
19332
19332
|
};
|
|
19333
19333
|
this.setState({
|
|
19334
|
-
widgetProps: mapObject$
|
|
19334
|
+
widgetProps: mapObject$1(serializedState, (props, widgetId) => {
|
|
19335
19335
|
const widget = this.getWidgetInstance(widgetId);
|
|
19336
19336
|
if (widget && widget.restoreSerializedState) {
|
|
19337
19337
|
// Note that we probably can't call
|
|
@@ -44216,7 +44216,7 @@ const init = function (options) {
|
|
|
44216
44216
|
|
|
44217
44217
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
44218
44218
|
const libName = "@khanacademy/perseus";
|
|
44219
|
-
const libVersion = "
|
|
44219
|
+
const libVersion = "17.0.0";
|
|
44220
44220
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
44221
44221
|
|
|
44222
44222
|
const apiVersion = {
|
|
@@ -44726,454 +44726,6 @@ const styles$4 = aphrodite.StyleSheet.create({
|
|
|
44726
44726
|
}
|
|
44727
44727
|
});
|
|
44728
44728
|
|
|
44729
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
44730
|
-
|
|
44731
|
-
// This represents the shape of any component that uses this ProvideKeypad
|
|
44732
|
-
// mixin.
|
|
44733
|
-
// NOTE: This is not a real component. It's a collection of methods used to
|
|
44734
|
-
// create and manage a Keypad instances.
|
|
44735
|
-
// TODO(LP-10789): replace this with a React Context object to pass information
|
|
44736
|
-
// between Perseus and the Keypad.
|
|
44737
|
-
const ProvideKeypad = {
|
|
44738
|
-
getInitialState() {
|
|
44739
|
-
const _this = this;
|
|
44740
|
-
let keypadElement = null;
|
|
44741
|
-
if (_this.props.apiOptions && _this.props.apiOptions.customKeypad && _this.props.apiOptions.nativeKeypadProxy) {
|
|
44742
|
-
keypadElement = _this.props.apiOptions.nativeKeypadProxy(
|
|
44743
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'. | TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44744
|
-
() => _this.blur && _this.blur());
|
|
44745
|
-
}
|
|
44746
|
-
return {
|
|
44747
|
-
keypadElement
|
|
44748
|
-
};
|
|
44749
|
-
},
|
|
44750
|
-
componentDidMount() {
|
|
44751
|
-
const _this = this;
|
|
44752
|
-
const apiOptions = _this.props.apiOptions;
|
|
44753
|
-
if (apiOptions && apiOptions.customKeypad && !apiOptions.nativeKeypadProxy) {
|
|
44754
|
-
// TODO(charlie): Render this and the wrapped component in the same
|
|
44755
|
-
// React tree. We may also want to add this keypad asynchronously
|
|
44756
|
-
// or on-demand in the future.
|
|
44757
|
-
_this._keypadContainer = document.createElement("div");
|
|
44758
|
-
document.body?.appendChild(_this._keypadContainer);
|
|
44759
|
-
render( /*#__PURE__*/React__namespace.createElement(mathInput.MobileKeypad, {
|
|
44760
|
-
onElementMounted: element => {
|
|
44761
|
-
// NOTE(kevinb): The reason why this setState works is
|
|
44762
|
-
// b/c we're calling it manually from item-renderer.jsx
|
|
44763
|
-
// and we're manually setting the 'this' by using 'call'
|
|
44764
|
-
// @ts-expect-error - TS2339 - Property 'setState' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44765
|
-
_this.setState({
|
|
44766
|
-
keypadElement: element
|
|
44767
|
-
});
|
|
44768
|
-
},
|
|
44769
|
-
onDismiss: () => {
|
|
44770
|
-
// @ts-expect-error - TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'. | TS2339 - Property 'blur' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44771
|
-
_this.blur && _this.blur();
|
|
44772
|
-
}
|
|
44773
|
-
// @ts-expect-error - TS2339 - Property 'props' does not exist on type '{ readonly propTypes: { readonly apiOptions: React.PropType<{ customKeypad?: boolean | undefined; nativeKeypadProxy?: ((...a: readonly any[]) => unknown) | undefined; }>; readonly keypadStyle: Requireable<any>; }; readonly getInitialState: () => { ...; }; readonly componentDidMount: () => void; readonly componentWil...'.
|
|
44774
|
-
,
|
|
44775
|
-
style: _this.props.keypadStyle,
|
|
44776
|
-
onAnalyticsEvent: async () => {
|
|
44777
|
-
// Intentionally left empty. This component is
|
|
44778
|
-
// deprecated and so we don't want/need to instrument
|
|
44779
|
-
// it.
|
|
44780
|
-
}
|
|
44781
|
-
}), _this._keypadContainer);
|
|
44782
|
-
}
|
|
44783
|
-
},
|
|
44784
|
-
componentWillUnmount() {
|
|
44785
|
-
const _this = this;
|
|
44786
|
-
if (_this._keypadContainer) {
|
|
44787
|
-
ReactDOM__default["default"].unmountComponentAtNode(_this._keypadContainer);
|
|
44788
|
-
if (_this._keypadContainer.parentNode) {
|
|
44789
|
-
// Note ChildNode.remove() isn't available in older Android
|
|
44790
|
-
// webviews.
|
|
44791
|
-
_this._keypadContainer.parentNode.removeChild(_this._keypadContainer);
|
|
44792
|
-
}
|
|
44793
|
-
_this._keypadContainer = null;
|
|
44794
|
-
}
|
|
44795
|
-
},
|
|
44796
|
-
keypadElement() {
|
|
44797
|
-
const _this = this;
|
|
44798
|
-
return _this.state.keypadElement;
|
|
44799
|
-
}
|
|
44800
|
-
};
|
|
44801
|
-
|
|
44802
|
-
const {
|
|
44803
|
-
mapObject: mapObject$1
|
|
44804
|
-
} = objective_;
|
|
44805
|
-
/**
|
|
44806
|
-
* @depreciated use ServerItemRenderer
|
|
44807
|
-
*/
|
|
44808
|
-
class ItemRenderer extends React__namespace.Component {
|
|
44809
|
-
// @ts-expect-error - TS2564 - Property 'questionRenderer' has no initializer and is not definitely assigned in the constructor.
|
|
44810
|
-
|
|
44811
|
-
static defaultProps = {
|
|
44812
|
-
apiOptions: ApiOptions.defaults,
|
|
44813
|
-
// defaults are set in `this.update()`
|
|
44814
|
-
controlPeripherals: true,
|
|
44815
|
-
hintsAreaSelector: "#hintsarea",
|
|
44816
|
-
initialHintsVisible: 0,
|
|
44817
|
-
workAreaSelector: "#workarea",
|
|
44818
|
-
reviewMode: false,
|
|
44819
|
-
linterContext: PerseusLinter__namespace.linterContextDefault
|
|
44820
|
-
};
|
|
44821
|
-
constructor(props) {
|
|
44822
|
-
super(props);
|
|
44823
|
-
this.state = {
|
|
44824
|
-
// NOTE: This value is used in provide-keypad.jsx which contains a
|
|
44825
|
-
// "mixin" that this file calls methods on.
|
|
44826
|
-
...ProvideKeypad.getInitialState.call(this),
|
|
44827
|
-
hintsVisible: props.initialHintsVisible || 0,
|
|
44828
|
-
questionCompleted: false,
|
|
44829
|
-
questionHighlightedWidgets: []
|
|
44830
|
-
};
|
|
44831
|
-
}
|
|
44832
|
-
componentDidMount() {
|
|
44833
|
-
ProvideKeypad.componentDidMount.call(this);
|
|
44834
|
-
if (this.props.controlPeripherals && this.props.apiOptions.setDrawingAreaAvailable) {
|
|
44835
|
-
this.props.apiOptions.setDrawingAreaAvailable(true);
|
|
44836
|
-
}
|
|
44837
|
-
this._currentFocus = null;
|
|
44838
|
-
this.update();
|
|
44839
|
-
}
|
|
44840
|
-
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
44841
|
-
this.setState({
|
|
44842
|
-
questionHighlightedWidgets: []
|
|
44843
|
-
});
|
|
44844
|
-
}
|
|
44845
|
-
componentDidUpdate() {
|
|
44846
|
-
this.update();
|
|
44847
|
-
}
|
|
44848
|
-
componentWillUnmount() {
|
|
44849
|
-
ProvideKeypad.componentWillUnmount.call(this);
|
|
44850
|
-
const workArea = document.querySelector(this.props.workAreaSelector);
|
|
44851
|
-
if (workArea != null) {
|
|
44852
|
-
ReactDOM__namespace.unmountComponentAtNode(workArea);
|
|
44853
|
-
}
|
|
44854
|
-
const hintsArea = document.querySelector(this.props.hintsAreaSelector);
|
|
44855
|
-
if (hintsArea != null) {
|
|
44856
|
-
ReactDOM__namespace.unmountComponentAtNode(hintsArea);
|
|
44857
|
-
}
|
|
44858
|
-
if (this.props.controlPeripherals) {
|
|
44859
|
-
const answerArea = this.props.item.answerArea || {};
|
|
44860
|
-
if (answerArea.calculator) {
|
|
44861
|
-
$__default["default"]("#calculator").hide();
|
|
44862
|
-
}
|
|
44863
|
-
if (answerArea.periodicTable) {
|
|
44864
|
-
$__default["default"](".periodic-table-info-box").hide();
|
|
44865
|
-
}
|
|
44866
|
-
if (answerArea.zTable) {
|
|
44867
|
-
$__default["default"](".z-table-info-box").hide();
|
|
44868
|
-
}
|
|
44869
|
-
if (answerArea.tTable) {
|
|
44870
|
-
$__default["default"](".t-table-info-box").hide();
|
|
44871
|
-
}
|
|
44872
|
-
if (answerArea.chi2Table) {
|
|
44873
|
-
$__default["default"](".chi2-table-info-box").hide();
|
|
44874
|
-
}
|
|
44875
|
-
}
|
|
44876
|
-
}
|
|
44877
|
-
keypadElement() {
|
|
44878
|
-
return ProvideKeypad.keypadElement.call(this);
|
|
44879
|
-
}
|
|
44880
|
-
update() {
|
|
44881
|
-
const apiOptions = {
|
|
44882
|
-
...ApiOptions.defaults,
|
|
44883
|
-
...this.props.apiOptions,
|
|
44884
|
-
onFocusChange: this._handleFocusChange
|
|
44885
|
-
};
|
|
44886
|
-
const workArea = document.querySelector(this.props.workAreaSelector);
|
|
44887
|
-
const hintsArea = document.querySelector(this.props.hintsAreaSelector);
|
|
44888
|
-
if (!workArea || !hintsArea) {
|
|
44889
|
-
return;
|
|
44890
|
-
}
|
|
44891
|
-
|
|
44892
|
-
// Since the item renderer works by rendering things into three divs
|
|
44893
|
-
// that have completely different places in the DOM, we have to do this
|
|
44894
|
-
// strangeness instead of relying on React's normal render() method.
|
|
44895
|
-
// TODO(alpert): Figure out how to clean this up somehow
|
|
44896
|
-
render( /*#__PURE__*/React__namespace.createElement(DependenciesContext.Provider, {
|
|
44897
|
-
value: this.props.dependencies
|
|
44898
|
-
}, /*#__PURE__*/React__namespace.createElement(Renderer, _extends({
|
|
44899
|
-
ref: node => {
|
|
44900
|
-
if (!node) {
|
|
44901
|
-
return;
|
|
44902
|
-
}
|
|
44903
|
-
this.questionRenderer = node;
|
|
44904
|
-
|
|
44905
|
-
// NOTE(jeremy): Why don't we just pass this into the
|
|
44906
|
-
// renderer as a prop?
|
|
44907
|
-
const {
|
|
44908
|
-
answerableCallback
|
|
44909
|
-
} = apiOptions;
|
|
44910
|
-
if (answerableCallback) {
|
|
44911
|
-
const isAnswerable = this.questionRenderer.emptyWidgets().length === 0;
|
|
44912
|
-
answerableCallback(isAnswerable);
|
|
44913
|
-
}
|
|
44914
|
-
},
|
|
44915
|
-
keypadElement: this.keypadElement(),
|
|
44916
|
-
problemNum: this.props.problemNum,
|
|
44917
|
-
onInteractWithWidget: this.handleInteractWithWidget,
|
|
44918
|
-
highlightedWidgets: this.state.questionHighlightedWidgets,
|
|
44919
|
-
apiOptions: apiOptions,
|
|
44920
|
-
questionCompleted: this.state.questionCompleted,
|
|
44921
|
-
reviewMode: this.props.reviewMode,
|
|
44922
|
-
savedState: this.props.savedState,
|
|
44923
|
-
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "question")
|
|
44924
|
-
}, this.props.item.question, {
|
|
44925
|
-
legacyPerseusLint: this.props.legacyPerseusLint
|
|
44926
|
-
}))),
|
|
44927
|
-
// @ts-expect-error - TS2345 - Argument of type 'Element' is not assignable to parameter of type 'HTMLElement'.
|
|
44928
|
-
workArea);
|
|
44929
|
-
render( /*#__PURE__*/React__namespace.createElement(DependenciesContext.Provider, {
|
|
44930
|
-
value: this.props.dependencies
|
|
44931
|
-
}, /*#__PURE__*/React__namespace.createElement(HintsRenderer, {
|
|
44932
|
-
ref: node => this.hintsRenderer = node,
|
|
44933
|
-
hints: this.props.item.hints,
|
|
44934
|
-
hintsVisible: this.state.hintsVisible,
|
|
44935
|
-
apiOptions: apiOptions,
|
|
44936
|
-
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "hints")
|
|
44937
|
-
})),
|
|
44938
|
-
// @ts-expect-error - TS2345 - Argument of type 'Element' is not assignable to parameter of type 'HTMLElement'.
|
|
44939
|
-
hintsArea);
|
|
44940
|
-
const answerArea = this.props.item.answerArea || {};
|
|
44941
|
-
if (this.props.controlPeripherals) {
|
|
44942
|
-
$__default["default"]("#calculator").toggle(answerArea.calculator || false);
|
|
44943
|
-
$__default["default"](".periodic-table-info-box").toggle(answerArea.periodicTable || false);
|
|
44944
|
-
$__default["default"](".z-table-info-box").toggle(answerArea.zTable || false);
|
|
44945
|
-
$__default["default"](".t-table-info-box").toggle(answerArea.tTable || false);
|
|
44946
|
-
$__default["default"](".chi2-table-info-box").toggle(answerArea.chi2Table || false);
|
|
44947
|
-
} else {
|
|
44948
|
-
if (answerArea.calculator) {
|
|
44949
|
-
this.props.onShowCalculator && this.props.onShowCalculator();
|
|
44950
|
-
}
|
|
44951
|
-
if (answerArea.periodicTable) {
|
|
44952
|
-
this.props.onShowPeriodicTable && this.props.onShowPeriodicTable({
|
|
44953
|
-
showKey: answerArea.periodicTableWithKey
|
|
44954
|
-
});
|
|
44955
|
-
}
|
|
44956
|
-
if (answerArea.zTable) {
|
|
44957
|
-
this.props.onShowZTable && this.props.onShowZTable();
|
|
44958
|
-
}
|
|
44959
|
-
if (answerArea.tTable) {
|
|
44960
|
-
this.props.onShowTTable && this.props.onShowTTable();
|
|
44961
|
-
}
|
|
44962
|
-
if (answerArea.chi2Table) {
|
|
44963
|
-
this.props.onShowChi2Table && this.props.onShowChi2Table();
|
|
44964
|
-
}
|
|
44965
|
-
}
|
|
44966
|
-
}
|
|
44967
|
-
_handleFocusChange = (newFocus, oldFocus) => {
|
|
44968
|
-
if (newFocus != null) {
|
|
44969
|
-
this._setCurrentFocus(newFocus);
|
|
44970
|
-
} else {
|
|
44971
|
-
this._onRendererBlur(oldFocus);
|
|
44972
|
-
}
|
|
44973
|
-
};
|
|
44974
|
-
|
|
44975
|
-
// Sets the current focus path and element and send an onChangeFocus event
|
|
44976
|
-
// back to our parent.
|
|
44977
|
-
_setCurrentFocus(newFocus) {
|
|
44978
|
-
const keypadElement = this.keypadElement();
|
|
44979
|
-
// By the time this happens, newFocus cannot be a prefix of
|
|
44980
|
-
// prevFocused, since we must have either been called from
|
|
44981
|
-
// an onFocusChange within a renderer, which is only called when
|
|
44982
|
-
// this is not a prefix, or between the question and answer areas,
|
|
44983
|
-
// which can never prefix each other.
|
|
44984
|
-
const prevFocus = this._currentFocus;
|
|
44985
|
-
this._currentFocus = newFocus;
|
|
44986
|
-
|
|
44987
|
-
// Determine whether the newly focused path represents an input.
|
|
44988
|
-
const inputPaths = this.getInputPaths();
|
|
44989
|
-
const didFocusInput = this._currentFocus && inputPaths.some(inputPath => {
|
|
44990
|
-
return Util.inputPathsEqual(inputPath, this._currentFocus);
|
|
44991
|
-
});
|
|
44992
|
-
if (this.props.apiOptions.onFocusChange != null) {
|
|
44993
|
-
this.props.apiOptions.onFocusChange(this._currentFocus, prevFocus, didFocusInput && keypadElement && keypadElement.getDOMNode());
|
|
44994
|
-
}
|
|
44995
|
-
if (keypadElement) {
|
|
44996
|
-
if (didFocusInput) {
|
|
44997
|
-
keypadElement.activate();
|
|
44998
|
-
} else {
|
|
44999
|
-
keypadElement.dismiss();
|
|
45000
|
-
}
|
|
45001
|
-
}
|
|
45002
|
-
}
|
|
45003
|
-
_onRendererBlur(blurPath) {
|
|
45004
|
-
const blurringFocusPath = this._currentFocus;
|
|
45005
|
-
|
|
45006
|
-
// Failsafe: abort if ID is different, because focus probably happened
|
|
45007
|
-
// before blur.
|
|
45008
|
-
if (!Util.inputPathsEqual(blurPath, blurringFocusPath)) {
|
|
45009
|
-
return;
|
|
45010
|
-
}
|
|
45011
|
-
|
|
45012
|
-
// Wait until after any new focus events fire this tick before
|
|
45013
|
-
// declaring that nothing is focused, since if there were a focus change
|
|
45014
|
-
// across Renderers (e.g., from the HintsRenderer to the
|
|
45015
|
-
// QuestionRenderer), we could receive the blur before the focus.
|
|
45016
|
-
// TODO(jeff, CP-3128): Use Wonder Blocks Timing API
|
|
45017
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
45018
|
-
setTimeout(() => {
|
|
45019
|
-
if (Util.inputPathsEqual(this._currentFocus, blurringFocusPath)) {
|
|
45020
|
-
this._setCurrentFocus(null);
|
|
45021
|
-
}
|
|
45022
|
-
});
|
|
45023
|
-
}
|
|
45024
|
-
|
|
45025
|
-
/**
|
|
45026
|
-
* Accepts a question area widgetId, or an answer area widgetId of
|
|
45027
|
-
* the form "answer-input-number 1", or the string "answer-area"
|
|
45028
|
-
* for the whole answer area (if the answer area is a single widget).
|
|
45029
|
-
*/
|
|
45030
|
-
_setWidgetProps(widgetId, newProps, callback) {
|
|
45031
|
-
this.questionRenderer._setWidgetProps(widgetId, newProps, callback);
|
|
45032
|
-
}
|
|
45033
|
-
|
|
45034
|
-
/**
|
|
45035
|
-
* Sets the input value into the widget found at `path`. The `focus`
|
|
45036
|
-
* function provided is called when all affected widgets have been
|
|
45037
|
-
* re-rendered with the new value.
|
|
45038
|
-
*/
|
|
45039
|
-
setInputValue(path, newValue, focus) {
|
|
45040
|
-
return this.questionRenderer.setInputValue(path, newValue, focus);
|
|
45041
|
-
}
|
|
45042
|
-
focusPath(path) {
|
|
45043
|
-
return this.questionRenderer.focusPath(path);
|
|
45044
|
-
}
|
|
45045
|
-
blurPath(path) {
|
|
45046
|
-
return this.questionRenderer.blurPath(path);
|
|
45047
|
-
}
|
|
45048
|
-
getDOMNodeForPath(path) {
|
|
45049
|
-
return this.questionRenderer.getDOMNodeForPath(path);
|
|
45050
|
-
}
|
|
45051
|
-
getGrammarTypeForPath(path) {
|
|
45052
|
-
return this.questionRenderer.getGrammarTypeForPath(path);
|
|
45053
|
-
}
|
|
45054
|
-
getInputPaths() {
|
|
45055
|
-
const questionAreaInputPaths = this.questionRenderer.getInputPaths();
|
|
45056
|
-
return questionAreaInputPaths;
|
|
45057
|
-
}
|
|
45058
|
-
|
|
45059
|
-
// NOTE: this must remain as an arrow function because we pass it Renderer
|
|
45060
|
-
handleInteractWithWidget = widgetId => {
|
|
45061
|
-
const withRemoved = ___default["default"].difference(this.state.questionHighlightedWidgets, [widgetId]);
|
|
45062
|
-
this.setState({
|
|
45063
|
-
questionCompleted: false,
|
|
45064
|
-
questionHighlightedWidgets: withRemoved
|
|
45065
|
-
});
|
|
45066
|
-
if (this.props.apiOptions.interactionCallback) {
|
|
45067
|
-
this.props.apiOptions.interactionCallback();
|
|
45068
|
-
}
|
|
45069
|
-
};
|
|
45070
|
-
focus() {
|
|
45071
|
-
return this.questionRenderer.focus();
|
|
45072
|
-
}
|
|
45073
|
-
blur() {
|
|
45074
|
-
if (this._currentFocus) {
|
|
45075
|
-
this.blurPath(this._currentFocus);
|
|
45076
|
-
}
|
|
45077
|
-
}
|
|
45078
|
-
showHint() {
|
|
45079
|
-
if (this.state.hintsVisible < this.getNumHints()) {
|
|
45080
|
-
this.setState({
|
|
45081
|
-
hintsVisible: this.state.hintsVisible + 1
|
|
45082
|
-
});
|
|
45083
|
-
}
|
|
45084
|
-
}
|
|
45085
|
-
getNumHints() {
|
|
45086
|
-
return this.props.item.hints.length;
|
|
45087
|
-
}
|
|
45088
|
-
|
|
45089
|
-
/**
|
|
45090
|
-
* Grades the item.
|
|
45091
|
-
*
|
|
45092
|
-
* Returns a KE-style score of {
|
|
45093
|
-
* empty: bool,
|
|
45094
|
-
* correct: bool,
|
|
45095
|
-
* message: string|null,
|
|
45096
|
-
* guess: Array
|
|
45097
|
-
* }
|
|
45098
|
-
*/
|
|
45099
|
-
scoreInput() {
|
|
45100
|
-
const guessAndScore = this.questionRenderer.guessAndScore();
|
|
45101
|
-
const guess = guessAndScore[0];
|
|
45102
|
-
const score = guessAndScore[1];
|
|
45103
|
-
|
|
45104
|
-
// Continue to include an empty guess for the now defunct answer area.
|
|
45105
|
-
// TODO(alex): Check whether we rely on the format here for
|
|
45106
|
-
// analyzing ProblemLogs. If not, remove this layer.
|
|
45107
|
-
const maxCompatGuess = [guess, []];
|
|
45108
|
-
const keScore = Util.keScoreFromPerseusScore(score, maxCompatGuess, this.questionRenderer.getSerializedState());
|
|
45109
|
-
const emptyQuestionAreaWidgets = this.questionRenderer.emptyWidgets();
|
|
45110
|
-
this.setState({
|
|
45111
|
-
questionCompleted: keScore.correct,
|
|
45112
|
-
questionHighlightedWidgets: emptyQuestionAreaWidgets
|
|
45113
|
-
});
|
|
45114
|
-
return keScore;
|
|
45115
|
-
}
|
|
45116
|
-
|
|
45117
|
-
/**
|
|
45118
|
-
* Returns an array of all widget IDs in the order they occur in
|
|
45119
|
-
* the question content.
|
|
45120
|
-
*/
|
|
45121
|
-
getWidgetIds() {
|
|
45122
|
-
return this.questionRenderer.getWidgetIds();
|
|
45123
|
-
}
|
|
45124
|
-
|
|
45125
|
-
/**
|
|
45126
|
-
* Returns an object mapping from widget ID to KE-style score.
|
|
45127
|
-
* The keys of this object are the values of the array returned
|
|
45128
|
-
* from `getWidgetIds`.
|
|
45129
|
-
*/
|
|
45130
|
-
scoreWidgets() {
|
|
45131
|
-
const qScore = this.questionRenderer.scoreWidgets();
|
|
45132
|
-
const qGuess = this.questionRenderer.getUserInputForWidgets();
|
|
45133
|
-
const state = this.questionRenderer.getSerializedState();
|
|
45134
|
-
// @ts-expect-error - TS2322 - Type 'Partial<Record<string, KEScore>>' is not assignable to type '{ [id: string]: KEScore; }'. | TS2345 - Argument of type '{ [widgetId: string]: PerseusScore; }' is not assignable to parameter of type 'Partial<Record<string, { type: "invalid"; message?: string | null | undefined; suppressAlmostThere?: boolean | null | undefined; }>>'.
|
|
45135
|
-
return mapObject$1(qScore, (score, id) => {
|
|
45136
|
-
return Util.keScoreFromPerseusScore(score, qGuess[id], state[id]);
|
|
45137
|
-
});
|
|
45138
|
-
}
|
|
45139
|
-
|
|
45140
|
-
/**
|
|
45141
|
-
* Get a representation of the current state of the item.
|
|
45142
|
-
*/
|
|
45143
|
-
getSerializedState() {
|
|
45144
|
-
return {
|
|
45145
|
-
question: this.questionRenderer.getSerializedState(),
|
|
45146
|
-
hints: this.hintsRenderer?.getSerializedState()
|
|
45147
|
-
};
|
|
45148
|
-
}
|
|
45149
|
-
|
|
45150
|
-
// TODO(kevinb): make the type for this state better
|
|
45151
|
-
restoreSerializedState(state, callback) {
|
|
45152
|
-
// We need to wait for both the question renderer and the hints
|
|
45153
|
-
// renderer to finish restoring their states.
|
|
45154
|
-
let numCallbacks = 2;
|
|
45155
|
-
const fireCallback = () => {
|
|
45156
|
-
--numCallbacks;
|
|
45157
|
-
if (callback && numCallbacks === 0) {
|
|
45158
|
-
callback();
|
|
45159
|
-
}
|
|
45160
|
-
};
|
|
45161
|
-
this.questionRenderer.restoreSerializedState(state.question, fireCallback);
|
|
45162
|
-
this.hintsRenderer?.restoreSerializedState(state.hints, fireCallback);
|
|
45163
|
-
}
|
|
45164
|
-
showRationalesForCurrentlySelectedChoices() {
|
|
45165
|
-
this.questionRenderer.showRationalesForCurrentlySelectedChoices();
|
|
45166
|
-
}
|
|
45167
|
-
deselectIncorrectSelectedChoices() {
|
|
45168
|
-
this.questionRenderer.deselectIncorrectSelectedChoices();
|
|
45169
|
-
}
|
|
45170
|
-
render() {
|
|
45171
|
-
return /*#__PURE__*/React__namespace.createElement(DependenciesContext.Provider, {
|
|
45172
|
-
value: this.props.dependencies
|
|
45173
|
-
}, /*#__PURE__*/React__namespace.createElement("div", null));
|
|
45174
|
-
}
|
|
45175
|
-
}
|
|
45176
|
-
|
|
45177
44729
|
/**
|
|
45178
44730
|
* A React context for signaling when all of the components in a Perseus
|
|
45179
44731
|
* renderer is fully rendered. This means that all images and math have
|
|
@@ -45197,6 +44749,7 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
45197
44749
|
static defaultProps = {
|
|
45198
44750
|
apiOptions: {},
|
|
45199
44751
|
// a deep default is done in `this.update()`
|
|
44752
|
+
linterContext: PerseusLinter__namespace.linterContextDefault,
|
|
45200
44753
|
onRendered: isRendered => {}
|
|
45201
44754
|
};
|
|
45202
44755
|
constructor(props) {
|
|
@@ -45475,13 +45028,15 @@ class ServerItemRenderer extends React__namespace.Component {
|
|
|
45475
45028
|
},
|
|
45476
45029
|
content: this.props.item.question.content,
|
|
45477
45030
|
widgets: this.props.item.question.widgets,
|
|
45478
|
-
images: this.props.item.question.images
|
|
45031
|
+
images: this.props.item.question.images,
|
|
45032
|
+
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "question")
|
|
45479
45033
|
}, this.props.dependencies)));
|
|
45480
45034
|
const hintsRenderer = /*#__PURE__*/React__namespace.createElement(HintsRenderer, {
|
|
45481
45035
|
hints: this.props.item.hints,
|
|
45482
45036
|
hintsVisible: this.props.hintsVisible,
|
|
45483
45037
|
apiOptions: apiOptions,
|
|
45484
|
-
ref: elem => this.hintsRenderer = elem
|
|
45038
|
+
ref: elem => this.hintsRenderer = elem,
|
|
45039
|
+
linterContext: PerseusLinter__namespace.pushContextStack(this.props.linterContext, "hints")
|
|
45485
45040
|
});
|
|
45486
45041
|
return /*#__PURE__*/React__namespace.createElement(DependenciesContext.Provider, {
|
|
45487
45042
|
value: this.props.dependencies
|
|
@@ -45946,238 +45501,6 @@ class RangeInput extends React__namespace.Component {
|
|
|
45946
45501
|
};
|
|
45947
45502
|
}
|
|
45948
45503
|
|
|
45949
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
45950
|
-
const prettyBig = {
|
|
45951
|
-
fontSize: "150%"
|
|
45952
|
-
};
|
|
45953
|
-
const slightlyBig = {
|
|
45954
|
-
fontSize: "120%"
|
|
45955
|
-
};
|
|
45956
|
-
const symbStyle = {
|
|
45957
|
-
fontSize: "130%"
|
|
45958
|
-
};
|
|
45959
|
-
// These are functions because we want to generate a new component for each use
|
|
45960
|
-
// on the page rather than reusing an instance (which will cause an error).
|
|
45961
|
-
// Also, it's useful for things which might look different depending on the
|
|
45962
|
-
// props.
|
|
45963
|
-
const basic = [() => [/*#__PURE__*/React__namespace.createElement("span", {
|
|
45964
|
-
key: "plus",
|
|
45965
|
-
style: slightlyBig
|
|
45966
|
-
}, "+"), "PLUS", i18n__namespace._("Plus")], () => [/*#__PURE__*/React__namespace.createElement("span", {
|
|
45967
|
-
key: "minus",
|
|
45968
|
-
style: prettyBig
|
|
45969
|
-
}, "-"), "MINUS", i18n__namespace._("Minus")],
|
|
45970
|
-
// TODO(joel) - display as \cdot when appropriate
|
|
45971
|
-
props => {
|
|
45972
|
-
const {
|
|
45973
|
-
TeX
|
|
45974
|
-
} = getDependencies();
|
|
45975
|
-
if (props.convertDotToTimes) {
|
|
45976
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
45977
|
-
key: "times",
|
|
45978
|
-
style: prettyBig
|
|
45979
|
-
}, i18n__namespace.doNotTranslate("\\times")), "TIMES", i18n__namespace._("Multiply")];
|
|
45980
|
-
}
|
|
45981
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
45982
|
-
key: "times",
|
|
45983
|
-
style: prettyBig
|
|
45984
|
-
}, i18n__namespace.doNotTranslate("\\cdot")), "CDOT", i18n__namespace._("Multiply")];
|
|
45985
|
-
}, () => {
|
|
45986
|
-
const {
|
|
45987
|
-
TeX
|
|
45988
|
-
} = getDependencies();
|
|
45989
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
45990
|
-
key: "frac",
|
|
45991
|
-
style: prettyBig
|
|
45992
|
-
}, i18n__namespace.doNotTranslate("\\frac{x}{y}")), "FRAC", i18n__namespace._("Fraction, excluding the current expression")];
|
|
45993
|
-
}];
|
|
45994
|
-
const buttonSets = {
|
|
45995
|
-
basic,
|
|
45996
|
-
"basic+div": basic.concat([() => {
|
|
45997
|
-
const {
|
|
45998
|
-
TeX
|
|
45999
|
-
} = getDependencies();
|
|
46000
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46001
|
-
key: "div"
|
|
46002
|
-
}, i18n__namespace.doNotTranslate("\\div")), "DIVIDE", i18n__namespace._("Divide")];
|
|
46003
|
-
}]),
|
|
46004
|
-
trig: [() => {
|
|
46005
|
-
const {
|
|
46006
|
-
TeX
|
|
46007
|
-
} = getDependencies();
|
|
46008
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46009
|
-
key: "sin"
|
|
46010
|
-
}, i18n__namespace.doNotTranslate("\\sin")), "SIN", i18n__namespace._("Sine")];
|
|
46011
|
-
}, () => {
|
|
46012
|
-
const {
|
|
46013
|
-
TeX
|
|
46014
|
-
} = getDependencies();
|
|
46015
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46016
|
-
key: "cos"
|
|
46017
|
-
}, i18n__namespace.doNotTranslate("\\cos")), "COS", i18n__namespace._("Cosine")];
|
|
46018
|
-
}, () => {
|
|
46019
|
-
const {
|
|
46020
|
-
TeX
|
|
46021
|
-
} = getDependencies();
|
|
46022
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46023
|
-
key: "tan"
|
|
46024
|
-
}, i18n__namespace.doNotTranslate("\\tan")), "TAN", i18n__namespace._("Tangent")];
|
|
46025
|
-
}, () => {
|
|
46026
|
-
const {
|
|
46027
|
-
TeX
|
|
46028
|
-
} = getDependencies();
|
|
46029
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46030
|
-
key: "theta",
|
|
46031
|
-
style: symbStyle
|
|
46032
|
-
}, i18n__namespace.doNotTranslate("\\theta")), "THETA", i18n__namespace._("Theta")];
|
|
46033
|
-
}, () => {
|
|
46034
|
-
const {
|
|
46035
|
-
TeX
|
|
46036
|
-
} = getDependencies();
|
|
46037
|
-
return [/*#__PURE__*/React__namespace.createElement("span", {
|
|
46038
|
-
key: "phi"
|
|
46039
|
-
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
46040
|
-
className: "perseus-sr-only"
|
|
46041
|
-
}, i18n__namespace.doNotTranslate("phi")), /*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46042
|
-
key: "pi",
|
|
46043
|
-
style: symbStyle
|
|
46044
|
-
}, i18n__namespace.doNotTranslate("\\phi"))), "PHI", i18n__namespace._("Phi")];
|
|
46045
|
-
}],
|
|
46046
|
-
prealgebra: [() => {
|
|
46047
|
-
const {
|
|
46048
|
-
TeX
|
|
46049
|
-
} = getDependencies();
|
|
46050
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46051
|
-
key: "sqrt"
|
|
46052
|
-
}, i18n__namespace.doNotTranslate("\\sqrt{x}")), "SQRT", i18n__namespace._("Square root")];
|
|
46053
|
-
},
|
|
46054
|
-
// TODO(joel) - how does desmos do this?
|
|
46055
|
-
() => {
|
|
46056
|
-
const {
|
|
46057
|
-
TeX
|
|
46058
|
-
} = getDependencies();
|
|
46059
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46060
|
-
key: "nthroot"
|
|
46061
|
-
}, i18n__namespace.doNotTranslate("\\sqrt[3]{x}")), "NTHROOT3", i18n__namespace._("Cube root")];
|
|
46062
|
-
}, () => {
|
|
46063
|
-
const {
|
|
46064
|
-
TeX
|
|
46065
|
-
} = getDependencies();
|
|
46066
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46067
|
-
key: "pow",
|
|
46068
|
-
style: slightlyBig
|
|
46069
|
-
}, i18n__namespace.doNotTranslate("a^b")), "POW", i18n__namespace._("Exponent")];
|
|
46070
|
-
}, () => {
|
|
46071
|
-
const {
|
|
46072
|
-
TeX
|
|
46073
|
-
} = getDependencies();
|
|
46074
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46075
|
-
key: "pi",
|
|
46076
|
-
style: slightlyBig
|
|
46077
|
-
}, i18n__namespace.doNotTranslate("\\pi")), "PI", i18n__namespace._("Pi")];
|
|
46078
|
-
}],
|
|
46079
|
-
logarithms: [() => {
|
|
46080
|
-
const {
|
|
46081
|
-
TeX
|
|
46082
|
-
} = getDependencies();
|
|
46083
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46084
|
-
key: "log"
|
|
46085
|
-
}, i18n__namespace.doNotTranslate("\\log")), "LOG", i18n__namespace._("Logarithm with base 10")];
|
|
46086
|
-
}, () => {
|
|
46087
|
-
const {
|
|
46088
|
-
TeX
|
|
46089
|
-
} = getDependencies();
|
|
46090
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46091
|
-
key: "ln"
|
|
46092
|
-
}, i18n__namespace.doNotTranslate("\\ln")), "LN", i18n__namespace._("Natural logarithm")];
|
|
46093
|
-
}, () => {
|
|
46094
|
-
const {
|
|
46095
|
-
TeX
|
|
46096
|
-
} = getDependencies();
|
|
46097
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46098
|
-
key: "log_b"
|
|
46099
|
-
}, i18n__namespace.doNotTranslate("\\log_b")), "LOG_B", i18n__namespace._("Logarithm with custom base")];
|
|
46100
|
-
}],
|
|
46101
|
-
"basic relations": [() => {
|
|
46102
|
-
const {
|
|
46103
|
-
TeX
|
|
46104
|
-
} = getDependencies();
|
|
46105
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46106
|
-
key: "eq"
|
|
46107
|
-
}, "="), "EQUAL", i18n__namespace._("Equals sign")];
|
|
46108
|
-
}, () => {
|
|
46109
|
-
const {
|
|
46110
|
-
TeX
|
|
46111
|
-
} = getDependencies();
|
|
46112
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46113
|
-
key: "lt"
|
|
46114
|
-
}, i18n__namespace.doNotTranslate("\\lt")), "LT", i18n__namespace._("Less than sign")];
|
|
46115
|
-
}, () => {
|
|
46116
|
-
const {
|
|
46117
|
-
TeX
|
|
46118
|
-
} = getDependencies();
|
|
46119
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46120
|
-
key: "gt"
|
|
46121
|
-
}, i18n__namespace.doNotTranslate("\\gt")), "GT", i18n__namespace._("Greater than sign")];
|
|
46122
|
-
}],
|
|
46123
|
-
"advanced relations": [() => {
|
|
46124
|
-
const {
|
|
46125
|
-
TeX
|
|
46126
|
-
} = getDependencies();
|
|
46127
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46128
|
-
key: "neq"
|
|
46129
|
-
}, i18n__namespace.doNotTranslate("\\neq")), "NEQ", i18n__namespace._("Not-equals sign")];
|
|
46130
|
-
}, () => {
|
|
46131
|
-
const {
|
|
46132
|
-
TeX
|
|
46133
|
-
} = getDependencies();
|
|
46134
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46135
|
-
key: "leq"
|
|
46136
|
-
}, i18n__namespace.doNotTranslate("\\leq")), "LEQ", i18n__namespace._("Less than or equal to sign")];
|
|
46137
|
-
}, () => {
|
|
46138
|
-
const {
|
|
46139
|
-
TeX
|
|
46140
|
-
} = getDependencies();
|
|
46141
|
-
return [/*#__PURE__*/React__namespace.createElement(TeX, {
|
|
46142
|
-
key: "geq"
|
|
46143
|
-
}, i18n__namespace.doNotTranslate("\\geq")), "GEQ", i18n__namespace._("Greater than or equal to sign")];
|
|
46144
|
-
}]
|
|
46145
|
-
};
|
|
46146
|
-
const buttonSetsPropType = PropTypes__default["default"].arrayOf(PropTypes__default["default"].oneOf(___default["default"](buttonSets).keys()));
|
|
46147
|
-
class TexButtons extends React__namespace.Component {
|
|
46148
|
-
static buttonSets = buttonSets;
|
|
46149
|
-
static buttonSetsType = buttonSetsPropType;
|
|
46150
|
-
render() {
|
|
46151
|
-
// Always show buttonSets in the same order. Note: Technically it's ok
|
|
46152
|
-
// for _.keys() to return the keys in an arbitrary order, but in
|
|
46153
|
-
// practice, they will be ordered as listed above.
|
|
46154
|
-
const sortedButtonSets = ___default["default"].sortBy(this.props.sets, setName => ___default["default"].keys(buttonSets).indexOf(setName));
|
|
46155
|
-
const buttons = ___default["default"](sortedButtonSets).map(setName => buttonSets[setName]);
|
|
46156
|
-
const buttonRows = ___default["default"](buttons).map(row => row.map(symbGen => {
|
|
46157
|
-
// create a (component, thing we should send to mathquill) pair
|
|
46158
|
-
const symbol = symbGen(this.props);
|
|
46159
|
-
return /*#__PURE__*/React__namespace.createElement("button", {
|
|
46160
|
-
onClick: () => this.props.onInsert(symbol[1]),
|
|
46161
|
-
className: "tex-button"
|
|
46162
|
-
// @ts-expect-error - TS2533 - Object is possibly 'null' or 'undefined'. | TS2339 - Property 'key' does not exist on type 'boolean | ReactChild | ReactFragment | ReactPortal'.
|
|
46163
|
-
,
|
|
46164
|
-
key: symbol[0].key,
|
|
46165
|
-
type: "button",
|
|
46166
|
-
"aria-label": symbol[2]
|
|
46167
|
-
}, symbol[0]);
|
|
46168
|
-
}));
|
|
46169
|
-
const buttonPopup = ___default["default"](buttonRows).map((row, i) => {
|
|
46170
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
46171
|
-
className: "clearfix tex-button-row",
|
|
46172
|
-
key: this.props.sets[i]
|
|
46173
|
-
}, row);
|
|
46174
|
-
});
|
|
46175
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
46176
|
-
className: `${this.props.className || ""} preview-measure`
|
|
46177
|
-
}, buttonPopup);
|
|
46178
|
-
}
|
|
46179
|
-
}
|
|
46180
|
-
|
|
46181
45504
|
var components = /*#__PURE__*/Object.freeze({
|
|
46182
45505
|
__proto__: null,
|
|
46183
45506
|
ButtonGroup: ButtonGroup,
|
|
@@ -46194,7 +45517,6 @@ var components = /*#__PURE__*/Object.freeze({
|
|
|
46194
45517
|
RangeInput: RangeInput,
|
|
46195
45518
|
SvgImage: SvgImage,
|
|
46196
45519
|
TextInput: TextInput,
|
|
46197
|
-
TexButtons: TexButtons,
|
|
46198
45520
|
TextListEditor: TextListEditor
|
|
46199
45521
|
});
|
|
46200
45522
|
|
|
@@ -47457,7 +46779,6 @@ exports.HintRenderer = HintRenderer;
|
|
|
47457
46779
|
exports.HintsRenderer = HintsRenderer;
|
|
47458
46780
|
exports.InputNumber = InputNumber$1;
|
|
47459
46781
|
exports.InteractiveGraphWidget = InteractiveGraph$1;
|
|
47460
|
-
exports.ItemRenderer = ItemRenderer;
|
|
47461
46782
|
exports.JiptParagraphs = JiptParagraphs;
|
|
47462
46783
|
exports.KhanColors = KhanColors;
|
|
47463
46784
|
exports.KhanMath = KhanMath;
|