@khanacademy/perseus-editor 4.2.8 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -25,7 +25,7 @@ import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
25
25
 
26
26
  // This file is processed by a Rollup plugin (replace) to inject the production
27
27
  const libName = "@khanacademy/perseus-editor";
28
- const libVersion = "4.2.8";
28
+ const libVersion = "4.3.1";
29
29
  addLibraryVersionToPerseusDebug(libName, libVersion);
30
30
 
31
31
  function _extends() {
@@ -22064,7 +22064,7 @@ ArticleEditor.defaultProps = {
22064
22064
  * Renders three buttons: "Phone", "Tablet", and "Desktop".
22065
22065
  */
22066
22066
  const {
22067
- ButtonGroup: ButtonGroup$4,
22067
+ ButtonGroup: ButtonGroup$5,
22068
22068
  InlineIcon: InlineIcon$9
22069
22069
  } = components;
22070
22070
  const {
@@ -22090,7 +22090,7 @@ class ViewportResizer extends React.Component {
22090
22090
  // TODO(david): Allow input of custom viewport sizes.
22091
22091
  return /*#__PURE__*/React.createElement("span", {
22092
22092
  className: "viewport-resizer"
22093
- }, "Viewport:", " ", /*#__PURE__*/React.createElement(ButtonGroup$4, {
22093
+ }, "Viewport:", " ", /*#__PURE__*/React.createElement(ButtonGroup$5, {
22094
22094
  value: this.props.deviceType,
22095
22095
  allowEmpty: false,
22096
22096
  buttons: [{
@@ -22115,8 +22115,6 @@ ViewportResizer.propTypes = {
22115
22115
  onViewportSizeChanged: PropTypes.func.isRequired
22116
22116
  };
22117
22117
 
22118
- var jsdiff$1 = {exports: {}};
22119
-
22120
22118
  /*
22121
22119
  Software License Agreement (BSD License)
22122
22120
 
@@ -22151,382 +22149,374 @@ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISI
22151
22149
  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22152
22150
  */
22153
22151
 
22154
- (function (module) {
22155
- /*
22156
- * Text diff implementation.
22157
- *
22158
- * This library supports the following APIS:
22159
- * JsDiff.diffChars: Character by character diff
22160
- * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
22161
- * JsDiff.diffLines: Line based diff
22162
- *
22163
- * JsDiff.diffCss: Diff targeted at CSS content
22164
- *
22165
- * These methods are based on the implementation proposed in
22166
- * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
22167
- * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
22168
- */
22169
- var JsDiff = function () {
22170
- /*jshint maxparams: 5*/
22171
- function clonePath(path) {
22172
- return {
22173
- newPos: path.newPos,
22174
- components: path.components.slice(0)
22175
- };
22176
- }
22177
- function removeEmpty(array) {
22178
- var ret = [];
22179
- for (var i = 0; i < array.length; i++) {
22180
- if (array[i]) {
22181
- ret.push(array[i]);
22182
- }
22183
- }
22184
- return ret;
22185
- }
22186
- function escapeHTML(s) {
22187
- var n = s;
22188
- n = n.replace(/&/g, '&amp;');
22189
- n = n.replace(/</g, '&lt;');
22190
- n = n.replace(/>/g, '&gt;');
22191
- n = n.replace(/"/g, '&quot;');
22192
- return n;
22193
- }
22194
- var Diff = function Diff(ignoreWhitespace) {
22195
- this.ignoreWhitespace = ignoreWhitespace;
22196
- };
22197
- Diff.prototype = {
22198
- diff: function (oldString, newString) {
22199
- // Handle the identity case (this is due to unrolling editLength == 0
22200
- if (newString === oldString) {
22201
- return [{
22202
- value: newString
22203
- }];
22204
- }
22205
- if (!newString) {
22206
- return [{
22207
- value: oldString,
22208
- removed: true
22209
- }];
22210
- }
22211
- if (!oldString) {
22212
- return [{
22213
- value: newString,
22214
- added: true
22215
- }];
22216
- }
22217
- newString = this.tokenize(newString);
22218
- oldString = this.tokenize(oldString);
22219
- var newLen = newString.length,
22220
- oldLen = oldString.length;
22221
- var maxEditLength = newLen + oldLen;
22222
- var bestPath = [{
22223
- newPos: -1,
22224
- components: []
22225
- }];
22152
+ /*
22153
+ * Text diff implementation.
22154
+ *
22155
+ * This library supports the following APIS:
22156
+ * JsDiff.diffChars: Character by character diff
22157
+ * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
22158
+ * JsDiff.diffLines: Line based diff
22159
+ *
22160
+ * JsDiff.diffCss: Diff targeted at CSS content
22161
+ *
22162
+ * These methods are based on the implementation proposed in
22163
+ * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
22164
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
22165
+ */
22226
22166
 
22227
- // Seed editLength = 0
22228
- var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
22229
- if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
22230
- return bestPath[0].components;
22231
- }
22232
- for (var editLength = 1; editLength <= maxEditLength; editLength++) {
22233
- for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
22234
- var basePath;
22235
- var addPath = bestPath[diagonalPath - 1],
22236
- removePath = bestPath[diagonalPath + 1];
22237
- oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
22238
- if (addPath) {
22239
- // No one else is going to attempt to use this value, clear it
22240
- bestPath[diagonalPath - 1] = undefined;
22241
- }
22242
- var canAdd = addPath && addPath.newPos + 1 < newLen;
22243
- var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
22244
- if (!canAdd && !canRemove) {
22245
- bestPath[diagonalPath] = undefined;
22246
- continue;
22247
- }
22167
+ /*jshint maxparams: 5*/
22168
+ function clonePath(path) {
22169
+ return {
22170
+ newPos: path.newPos,
22171
+ components: path.components.slice(0)
22172
+ };
22173
+ }
22174
+ function removeEmpty(array) {
22175
+ var ret = [];
22176
+ for (var i = 0; i < array.length; i++) {
22177
+ if (array[i]) {
22178
+ ret.push(array[i]);
22179
+ }
22180
+ }
22181
+ return ret;
22182
+ }
22183
+ function escapeHTML(s) {
22184
+ var n = s;
22185
+ n = n.replace(/&/g, '&amp;');
22186
+ n = n.replace(/</g, '&lt;');
22187
+ n = n.replace(/>/g, '&gt;');
22188
+ n = n.replace(/"/g, '&quot;');
22189
+ return n;
22190
+ }
22191
+ var Diff = function Diff(ignoreWhitespace) {
22192
+ this.ignoreWhitespace = ignoreWhitespace;
22193
+ };
22194
+ Diff.prototype = {
22195
+ diff: function (oldString, newString) {
22196
+ // Handle the identity case (this is due to unrolling editLength == 0
22197
+ if (newString === oldString) {
22198
+ return [{
22199
+ value: newString
22200
+ }];
22201
+ }
22202
+ if (!newString) {
22203
+ return [{
22204
+ value: oldString,
22205
+ removed: true
22206
+ }];
22207
+ }
22208
+ if (!oldString) {
22209
+ return [{
22210
+ value: newString,
22211
+ added: true
22212
+ }];
22213
+ }
22214
+ newString = this.tokenize(newString);
22215
+ oldString = this.tokenize(oldString);
22216
+ var newLen = newString.length,
22217
+ oldLen = oldString.length;
22218
+ var maxEditLength = newLen + oldLen;
22219
+ var bestPath = [{
22220
+ newPos: -1,
22221
+ components: []
22222
+ }];
22248
22223
 
22249
- // Select the diagonal that we want to branch from. We select the prior
22250
- // path whose position in the new string is the farthest from the origin
22251
- // and does not pass the bounds of the diff graph
22252
- if (!canAdd || canRemove && addPath.newPos < removePath.newPos) {
22253
- basePath = clonePath(removePath);
22254
- this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
22255
- } else {
22256
- basePath = clonePath(addPath);
22257
- basePath.newPos++;
22258
- this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
22259
- }
22260
- var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
22261
- if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
22262
- return basePath.components;
22263
- } else {
22264
- bestPath[diagonalPath] = basePath;
22265
- }
22266
- }
22267
- }
22268
- },
22269
- pushComponent: function (components, value, added, removed) {
22270
- var last = components[components.length - 1];
22271
- if (last && last.added === added && last.removed === removed) {
22272
- // We need to clone here as the component clone operation is just
22273
- // as shallow array clone
22274
- components[components.length - 1] = {
22275
- value: this.join(last.value, value),
22276
- added: added,
22277
- removed: removed
22278
- };
22279
- } else {
22280
- components.push({
22281
- value: value,
22282
- added: added,
22283
- removed: removed
22284
- });
22285
- }
22286
- },
22287
- extractCommon: function (basePath, newString, oldString, diagonalPath) {
22288
- var newLen = newString.length,
22289
- oldLen = oldString.length,
22290
- newPos = basePath.newPos,
22291
- oldPos = newPos - diagonalPath;
22292
- while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {
22293
- newPos++;
22294
- oldPos++;
22295
- this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
22296
- }
22297
- basePath.newPos = newPos;
22298
- return oldPos;
22299
- },
22300
- equals: function (left, right) {
22301
- var reWhitespace = /\S/;
22302
- if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
22303
- return true;
22304
- } else {
22305
- return left === right;
22306
- }
22307
- },
22308
- join: function (left, right) {
22309
- return left + right;
22310
- },
22311
- tokenize: function (value) {
22312
- return value;
22313
- }
22314
- };
22315
- var CharDiff = new Diff();
22316
- var WordDiff = new Diff(true);
22317
- var WordWithSpaceDiff = new Diff();
22318
- WordDiff.tokenize = WordWithSpaceDiff.tokenize = function (value) {
22319
- return removeEmpty(value.split(/(\s+|\b)/));
22320
- };
22321
- var CssDiff = new Diff(true);
22322
- CssDiff.tokenize = function (value) {
22323
- return removeEmpty(value.split(/([{}:;,]|\s+)/));
22324
- };
22325
- var LineDiff = new Diff();
22326
- LineDiff.tokenize = function (value) {
22327
- var retLines = [],
22328
- lines = value.split(/^/m);
22329
- for (var i = 0; i < lines.length; i++) {
22330
- var line = lines[i],
22331
- lastLine = lines[i - 1];
22332
-
22333
- // Merge lines that may contain windows new lines
22334
- if (line == '\n' && lastLine && lastLine[lastLine.length - 1] === '\r') {
22335
- retLines[retLines.length - 1] += '\n';
22336
- } else if (line) {
22337
- retLines.push(line);
22338
- }
22339
- }
22340
- return retLines;
22341
- };
22342
- return {
22343
- Diff: Diff,
22344
- diffChars: function (oldStr, newStr) {
22345
- return CharDiff.diff(oldStr, newStr);
22346
- },
22347
- diffWords: function (oldStr, newStr) {
22348
- return WordDiff.diff(oldStr, newStr);
22349
- },
22350
- diffWordsWithSpace: function (oldStr, newStr) {
22351
- return WordWithSpaceDiff.diff(oldStr, newStr);
22352
- },
22353
- diffLines: function (oldStr, newStr) {
22354
- return LineDiff.diff(oldStr, newStr);
22355
- },
22356
- diffCss: function (oldStr, newStr) {
22357
- return CssDiff.diff(oldStr, newStr);
22358
- },
22359
- createPatch: function (fileName, oldStr, newStr, oldHeader, newHeader) {
22360
- var ret = [];
22361
- ret.push('Index: ' + fileName);
22362
- ret.push('===================================================================');
22363
- ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
22364
- ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
22365
- var diff = LineDiff.diff(oldStr, newStr);
22366
- if (!diff[diff.length - 1].value) {
22367
- diff.pop(); // Remove trailing newline add
22368
- }
22224
+ // Seed editLength = 0
22225
+ var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
22226
+ if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
22227
+ return bestPath[0].components;
22228
+ }
22229
+ for (var editLength = 1; editLength <= maxEditLength; editLength++) {
22230
+ for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
22231
+ var basePath;
22232
+ var addPath = bestPath[diagonalPath - 1],
22233
+ removePath = bestPath[diagonalPath + 1];
22234
+ oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
22235
+ if (addPath) {
22236
+ // No one else is going to attempt to use this value, clear it
22237
+ bestPath[diagonalPath - 1] = undefined;
22238
+ }
22239
+ var canAdd = addPath && addPath.newPos + 1 < newLen;
22240
+ var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
22241
+ if (!canAdd && !canRemove) {
22242
+ bestPath[diagonalPath] = undefined;
22243
+ continue;
22244
+ }
22369
22245
 
22370
- diff.push({
22371
- value: '',
22372
- lines: []
22373
- }); // Append an empty value to make cleanup easier
22246
+ // Select the diagonal that we want to branch from. We select the prior
22247
+ // path whose position in the new string is the farthest from the origin
22248
+ // and does not pass the bounds of the diff graph
22249
+ if (!canAdd || canRemove && addPath.newPos < removePath.newPos) {
22250
+ basePath = clonePath(removePath);
22251
+ this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
22252
+ } else {
22253
+ basePath = clonePath(addPath);
22254
+ basePath.newPos++;
22255
+ this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
22256
+ }
22257
+ var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
22258
+ if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
22259
+ return basePath.components;
22260
+ } else {
22261
+ bestPath[diagonalPath] = basePath;
22262
+ }
22263
+ }
22264
+ }
22265
+ },
22266
+ pushComponent: function (components, value, added, removed) {
22267
+ var last = components[components.length - 1];
22268
+ if (last && last.added === added && last.removed === removed) {
22269
+ // We need to clone here as the component clone operation is just
22270
+ // as shallow array clone
22271
+ components[components.length - 1] = {
22272
+ value: this.join(last.value, value),
22273
+ added: added,
22274
+ removed: removed
22275
+ };
22276
+ } else {
22277
+ components.push({
22278
+ value: value,
22279
+ added: added,
22280
+ removed: removed
22281
+ });
22282
+ }
22283
+ },
22284
+ extractCommon: function (basePath, newString, oldString, diagonalPath) {
22285
+ var newLen = newString.length,
22286
+ oldLen = oldString.length,
22287
+ newPos = basePath.newPos,
22288
+ oldPos = newPos - diagonalPath;
22289
+ while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) {
22290
+ newPos++;
22291
+ oldPos++;
22292
+ this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
22293
+ }
22294
+ basePath.newPos = newPos;
22295
+ return oldPos;
22296
+ },
22297
+ equals: function (left, right) {
22298
+ var reWhitespace = /\S/;
22299
+ if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
22300
+ return true;
22301
+ } else {
22302
+ return left === right;
22303
+ }
22304
+ },
22305
+ join: function (left, right) {
22306
+ return left + right;
22307
+ },
22308
+ tokenize: function (value) {
22309
+ return value;
22310
+ }
22311
+ };
22312
+ var CharDiff = new Diff();
22313
+ var WordDiff = new Diff(true);
22314
+ var WordWithSpaceDiff = new Diff();
22315
+ WordDiff.tokenize = WordWithSpaceDiff.tokenize = function (value) {
22316
+ return removeEmpty(value.split(/(\s+|\b)/));
22317
+ };
22318
+ var CssDiff = new Diff(true);
22319
+ CssDiff.tokenize = function (value) {
22320
+ return removeEmpty(value.split(/([{}:;,]|\s+)/));
22321
+ };
22322
+ var LineDiff = new Diff();
22323
+ LineDiff.tokenize = function (value) {
22324
+ var retLines = [],
22325
+ lines = value.split(/^/m);
22326
+ for (var i = 0; i < lines.length; i++) {
22327
+ var line = lines[i],
22328
+ lastLine = lines[i - 1];
22329
+
22330
+ // Merge lines that may contain windows new lines
22331
+ if (line == '\n' && lastLine && lastLine[lastLine.length - 1] === '\r') {
22332
+ retLines[retLines.length - 1] += '\n';
22333
+ } else if (line) {
22334
+ retLines.push(line);
22335
+ }
22336
+ }
22337
+ return retLines;
22338
+ };
22339
+ const JSDiff = {
22340
+ Diff: Diff,
22341
+ diffChars: function (oldStr, newStr) {
22342
+ return CharDiff.diff(oldStr, newStr);
22343
+ },
22344
+ diffWords: function (oldStr, newStr) {
22345
+ return WordDiff.diff(oldStr, newStr);
22346
+ },
22347
+ diffWordsWithSpace: function (oldStr, newStr) {
22348
+ return WordWithSpaceDiff.diff(oldStr, newStr);
22349
+ },
22350
+ diffLines: function (oldStr, newStr) {
22351
+ return LineDiff.diff(oldStr, newStr);
22352
+ },
22353
+ diffCss: function (oldStr, newStr) {
22354
+ return CssDiff.diff(oldStr, newStr);
22355
+ },
22356
+ createPatch: function (fileName, oldStr, newStr, oldHeader, newHeader) {
22357
+ var ret = [];
22358
+ ret.push('Index: ' + fileName);
22359
+ ret.push('===================================================================');
22360
+ ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
22361
+ ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));
22362
+ var diff = LineDiff.diff(oldStr, newStr);
22363
+ if (!diff[diff.length - 1].value) {
22364
+ diff.pop(); // Remove trailing newline add
22365
+ }
22374
22366
 
22375
- function contextLines(lines) {
22376
- return lines.map(function (entry) {
22377
- return ' ' + entry;
22378
- });
22379
- }
22380
- function eofNL(curRange, i, current) {
22381
- var last = diff[diff.length - 2],
22382
- isLast = i === diff.length - 2,
22383
- isLastOfType = i === diff.length - 3 && (current.added !== last.added || current.removed !== last.removed);
22384
-
22385
- // Figure out if this is the last line for the given file and missing NL
22386
- if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
22387
- curRange.push('\');
22388
- }
22389
- }
22390
- var oldRangeStart = 0,
22391
- newRangeStart = 0,
22392
- curRange = [],
22393
- oldLine = 1,
22394
- newLine = 1;
22395
- for (var i = 0; i < diff.length; i++) {
22396
- var current = diff[i],
22397
- lines = current.lines || current.value.replace(/\n$/, '').split('\n');
22398
- current.lines = lines;
22399
- if (current.added || current.removed) {
22400
- if (!oldRangeStart) {
22401
- var prev = diff[i - 1];
22402
- oldRangeStart = oldLine;
22403
- newRangeStart = newLine;
22404
- if (prev) {
22405
- curRange = contextLines(prev.lines.slice(-4));
22406
- oldRangeStart -= curRange.length;
22407
- newRangeStart -= curRange.length;
22408
- }
22409
- }
22410
- curRange.push.apply(curRange, lines.map(function (entry) {
22411
- return (current.added ? '+' : '-') + entry;
22412
- }));
22413
- eofNL(curRange, i, current);
22414
- if (current.added) {
22415
- newLine += lines.length;
22416
- } else {
22417
- oldLine += lines.length;
22418
- }
22419
- } else {
22420
- if (oldRangeStart) {
22421
- // Close out any changes that have been output (or join overlapping)
22422
- if (lines.length <= 8 && i < diff.length - 2) {
22423
- // Overlapping
22424
- curRange.push.apply(curRange, contextLines(lines));
22425
- } else {
22426
- // end the range and output
22427
- var contextSize = Math.min(lines.length, 4);
22428
- ret.push('@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) + ' @@');
22429
- ret.push.apply(ret, curRange);
22430
- ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
22431
- if (lines.length <= 4) {
22432
- eofNL(ret, i, current);
22433
- }
22434
- oldRangeStart = 0;
22435
- newRangeStart = 0;
22436
- curRange = [];
22437
- }
22438
- }
22439
- oldLine += lines.length;
22440
- newLine += lines.length;
22441
- }
22442
- }
22443
- return ret.join('\n') + '\n';
22444
- },
22445
- applyPatch: function (oldStr, uniDiff) {
22446
- var diffstr = uniDiff.split('\n');
22447
- var diff = [];
22448
- var remEOFNL = false,
22449
- addEOFNL = false;
22450
- for (var i = diffstr[0][0] === 'I' ? 4 : 0; i < diffstr.length; i++) {
22451
- if (diffstr[i][0] === '@') {
22452
- var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
22453
- diff.unshift({
22454
- start: meh[3],
22455
- oldlength: meh[2],
22456
- oldlines: [],
22457
- newlength: meh[4],
22458
- newlines: []
22459
- });
22460
- } else if (diffstr[i][0] === '+') {
22461
- diff[0].newlines.push(diffstr[i].substr(1));
22462
- } else if (diffstr[i][0] === '-') {
22463
- diff[0].oldlines.push(diffstr[i].substr(1));
22464
- } else if (diffstr[i][0] === ' ') {
22465
- diff[0].newlines.push(diffstr[i].substr(1));
22466
- diff[0].oldlines.push(diffstr[i].substr(1));
22467
- } else if (diffstr[i][0] === '\\') {
22468
- if (diffstr[i - 1][0] === '+') {
22469
- remEOFNL = true;
22470
- } else if (diffstr[i - 1][0] === '-') {
22471
- addEOFNL = true;
22472
- }
22473
- }
22474
- }
22475
- var str = oldStr.split('\n');
22476
- for (var i = diff.length - 1; i >= 0; i--) {
22477
- var d = diff[i];
22478
- for (var j = 0; j < d.oldlength; j++) {
22479
- if (str[d.start - 1 + j] !== d.oldlines[j]) {
22480
- return false;
22481
- }
22482
- }
22483
- Array.prototype.splice.apply(str, [d.start - 1, +d.oldlength].concat(d.newlines));
22484
- }
22485
- if (remEOFNL) {
22486
- while (!str[str.length - 1]) {
22487
- str.pop();
22488
- }
22489
- } else if (addEOFNL) {
22490
- str.push('');
22491
- }
22492
- return str.join('\n');
22493
- },
22494
- convertChangesToXML: function (changes) {
22495
- var ret = [];
22496
- for (var i = 0; i < changes.length; i++) {
22497
- var change = changes[i];
22498
- if (change.added) {
22499
- ret.push('<ins>');
22500
- } else if (change.removed) {
22501
- ret.push('<del>');
22502
- }
22503
- ret.push(escapeHTML(change.value));
22504
- if (change.added) {
22505
- ret.push('</ins>');
22506
- } else if (change.removed) {
22507
- ret.push('</del>');
22508
- }
22509
- }
22510
- return ret.join('');
22511
- },
22512
- // See: http://code.google.com/p/google-diff-match-patch/wiki/API
22513
- convertChangesToDMP: function (changes) {
22514
- var ret = [],
22515
- change;
22516
- for (var i = 0; i < changes.length; i++) {
22517
- change = changes[i];
22518
- ret.push([change.added ? 1 : change.removed ? -1 : 0, change.value]);
22519
- }
22520
- return ret;
22521
- }
22522
- };
22523
- }();
22524
- {
22525
- module.exports = JsDiff;
22526
- }
22527
- } (jsdiff$1));
22367
+ diff.push({
22368
+ value: '',
22369
+ lines: []
22370
+ }); // Append an empty value to make cleanup easier
22528
22371
 
22529
- var jsdiff = jsdiff$1.exports;
22372
+ function contextLines(lines) {
22373
+ return lines.map(function (entry) {
22374
+ return ' ' + entry;
22375
+ });
22376
+ }
22377
+ function eofNL(curRange, i, current) {
22378
+ var last = diff[diff.length - 2],
22379
+ isLast = i === diff.length - 2,
22380
+ isLastOfType = i === diff.length - 3 && (current.added !== last.added || current.removed !== last.removed);
22381
+
22382
+ // Figure out if this is the last line for the given file and missing NL
22383
+ if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
22384
+ curRange.push('\');
22385
+ }
22386
+ }
22387
+ var oldRangeStart = 0,
22388
+ newRangeStart = 0,
22389
+ curRange = [],
22390
+ oldLine = 1,
22391
+ newLine = 1;
22392
+ for (var i = 0; i < diff.length; i++) {
22393
+ var current = diff[i],
22394
+ lines = current.lines || current.value.replace(/\n$/, '').split('\n');
22395
+ current.lines = lines;
22396
+ if (current.added || current.removed) {
22397
+ if (!oldRangeStart) {
22398
+ var prev = diff[i - 1];
22399
+ oldRangeStart = oldLine;
22400
+ newRangeStart = newLine;
22401
+ if (prev) {
22402
+ curRange = contextLines(prev.lines.slice(-4));
22403
+ oldRangeStart -= curRange.length;
22404
+ newRangeStart -= curRange.length;
22405
+ }
22406
+ }
22407
+ curRange.push.apply(curRange, lines.map(function (entry) {
22408
+ return (current.added ? '+' : '-') + entry;
22409
+ }));
22410
+ eofNL(curRange, i, current);
22411
+ if (current.added) {
22412
+ newLine += lines.length;
22413
+ } else {
22414
+ oldLine += lines.length;
22415
+ }
22416
+ } else {
22417
+ if (oldRangeStart) {
22418
+ // Close out any changes that have been output (or join overlapping)
22419
+ if (lines.length <= 8 && i < diff.length - 2) {
22420
+ // Overlapping
22421
+ curRange.push.apply(curRange, contextLines(lines));
22422
+ } else {
22423
+ // end the range and output
22424
+ var contextSize = Math.min(lines.length, 4);
22425
+ ret.push('@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) + ' @@');
22426
+ ret.push.apply(ret, curRange);
22427
+ ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
22428
+ if (lines.length <= 4) {
22429
+ eofNL(ret, i, current);
22430
+ }
22431
+ oldRangeStart = 0;
22432
+ newRangeStart = 0;
22433
+ curRange = [];
22434
+ }
22435
+ }
22436
+ oldLine += lines.length;
22437
+ newLine += lines.length;
22438
+ }
22439
+ }
22440
+ return ret.join('\n') + '\n';
22441
+ },
22442
+ applyPatch: function (oldStr, uniDiff) {
22443
+ var diffstr = uniDiff.split('\n');
22444
+ var diff = [];
22445
+ var remEOFNL = false,
22446
+ addEOFNL = false;
22447
+ for (var i = diffstr[0][0] === 'I' ? 4 : 0; i < diffstr.length; i++) {
22448
+ if (diffstr[i][0] === '@') {
22449
+ var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
22450
+ diff.unshift({
22451
+ start: meh[3],
22452
+ oldlength: meh[2],
22453
+ oldlines: [],
22454
+ newlength: meh[4],
22455
+ newlines: []
22456
+ });
22457
+ } else if (diffstr[i][0] === '+') {
22458
+ diff[0].newlines.push(diffstr[i].substr(1));
22459
+ } else if (diffstr[i][0] === '-') {
22460
+ diff[0].oldlines.push(diffstr[i].substr(1));
22461
+ } else if (diffstr[i][0] === ' ') {
22462
+ diff[0].newlines.push(diffstr[i].substr(1));
22463
+ diff[0].oldlines.push(diffstr[i].substr(1));
22464
+ } else if (diffstr[i][0] === '\\') {
22465
+ if (diffstr[i - 1][0] === '+') {
22466
+ remEOFNL = true;
22467
+ } else if (diffstr[i - 1][0] === '-') {
22468
+ addEOFNL = true;
22469
+ }
22470
+ }
22471
+ }
22472
+ var str = oldStr.split('\n');
22473
+ for (var i = diff.length - 1; i >= 0; i--) {
22474
+ var d = diff[i];
22475
+ for (var j = 0; j < d.oldlength; j++) {
22476
+ if (str[d.start - 1 + j] !== d.oldlines[j]) {
22477
+ return false;
22478
+ }
22479
+ }
22480
+ Array.prototype.splice.apply(str, [d.start - 1, +d.oldlength].concat(d.newlines));
22481
+ }
22482
+ if (remEOFNL) {
22483
+ while (!str[str.length - 1]) {
22484
+ str.pop();
22485
+ }
22486
+ } else if (addEOFNL) {
22487
+ str.push('');
22488
+ }
22489
+ return str.join('\n');
22490
+ },
22491
+ convertChangesToXML: function (changes) {
22492
+ var ret = [];
22493
+ for (var i = 0; i < changes.length; i++) {
22494
+ var change = changes[i];
22495
+ if (change.added) {
22496
+ ret.push('<ins>');
22497
+ } else if (change.removed) {
22498
+ ret.push('<del>');
22499
+ }
22500
+ ret.push(escapeHTML(change.value));
22501
+ if (change.added) {
22502
+ ret.push('</ins>');
22503
+ } else if (change.removed) {
22504
+ ret.push('</del>');
22505
+ }
22506
+ }
22507
+ return ret.join('');
22508
+ },
22509
+ // See: http://code.google.com/p/google-diff-match-patch/wiki/API
22510
+ convertChangesToDMP: function (changes) {
22511
+ var ret = [],
22512
+ change;
22513
+ for (var i = 0; i < changes.length; i++) {
22514
+ change = changes[i];
22515
+ ret.push([change.added ? 1 : change.removed ? -1 : 0, change.value]);
22516
+ }
22517
+ return ret;
22518
+ }
22519
+ };
22530
22520
 
22531
22521
  // Split a word-wise diff generated by jsdiff into multiple lines, for the
22532
22522
  // purpose of breaking up the diffs into lines, so that modified lines can be
@@ -22589,7 +22579,7 @@ const mapcat = function mapcat(lst, fn) {
22589
22579
  // { "value": [2, 3] },
22590
22580
  // { "value": [4],
22591
22581
  // "added": true }]
22592
- const ArrayDiff = new jsdiff.Diff();
22582
+ const ArrayDiff = new JSDiff.Diff();
22593
22583
  ArrayDiff.tokenize = array => _.map(array, elem => [elem]);
22594
22584
  // The default is `+` for string concatenation, which doesn't work for array
22595
22585
  // concatenation.
@@ -22682,7 +22672,7 @@ class TextDiff extends React.Component {
22682
22672
  });
22683
22673
  }
22684
22674
  render() {
22685
- const diffed = jsdiff.diffWords(this.props.before, this.props.after);
22675
+ const diffed = JSDiff.diffWords(this.props.before, this.props.after);
22686
22676
  const lines = splitDiff(diffed);
22687
22677
  const beforeImages = imagesInString(this.props.before);
22688
22678
  const afterImages = imagesInString(this.props.after);
@@ -23450,7 +23440,7 @@ class StructuredItemDiff extends React.Component {
23450
23440
 
23451
23441
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
23452
23442
  const {
23453
- InfoTip: InfoTip$m,
23443
+ InfoTip: InfoTip$n,
23454
23444
  InlineIcon: InlineIcon$8
23455
23445
  } = components;
23456
23446
  const {
@@ -23522,7 +23512,7 @@ class HintEditor extends React.Component {
23522
23512
  type: "button",
23523
23513
  className: this.props.isFirst ? "hidden" : "",
23524
23514
  onClick: _.partial(this.props.onMove, -1)
23525
- }, /*#__PURE__*/React.createElement(InlineIcon$8, iconCircleArrowUp$1)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$m, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23515
+ }, /*#__PURE__*/React.createElement(InlineIcon$8, iconCircleArrowUp$1)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$n, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23526
23516
  type: "checkbox"
23527
23517
  // @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
23528
23518
  ,
@@ -23775,7 +23765,7 @@ CombinedHintsEditor.defaultProps = {
23775
23765
  };
23776
23766
 
23777
23767
  const {
23778
- InfoTip: InfoTip$l
23768
+ InfoTip: InfoTip$m
23779
23769
  } = components;
23780
23770
  class ItemExtrasEditor extends React.Component {
23781
23771
  constructor(...args) {
@@ -23933,7 +23923,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement("div", {
23933
23923
  type: "checkbox",
23934
23924
  checked: props.checked,
23935
23925
  onChange: props.onChange
23936
- })), /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip));
23926
+ })), /*#__PURE__*/React.createElement(InfoTip$m, null, props.infoTip));
23937
23927
 
23938
23928
  const ITEM_DATA_VERSION = itemDataVersion;
23939
23929
  class ItemEditor extends React.Component {
@@ -25619,7 +25609,7 @@ const StatefulEditorPage = createReactClass({
25619
25609
  });
25620
25610
 
25621
25611
  const {
25622
- PropCheckBox: PropCheckBox$c,
25612
+ PropCheckBox: PropCheckBox$d,
25623
25613
  TextListEditor: TextListEditor$4
25624
25614
  } = components;
25625
25615
  const Categorizer = Categorizer$1.widget;
@@ -25636,7 +25626,7 @@ class CategorizerEditor extends React.Component {
25636
25626
  render() {
25637
25627
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
25638
25628
  className: "perseus-widget-row"
25639
- }, /*#__PURE__*/React.createElement(PropCheckBox$c, {
25629
+ }, /*#__PURE__*/React.createElement(PropCheckBox$d, {
25640
25630
  label: "Randomize item order",
25641
25631
  labelAlignment: "right",
25642
25632
  randomizeItems: this.props.randomizeItems,
@@ -25748,8 +25738,8 @@ class BlurInput extends React.Component {
25748
25738
  }
25749
25739
 
25750
25740
  const {
25751
- InfoTip: InfoTip$k,
25752
- PropCheckBox: PropCheckBox$b
25741
+ InfoTip: InfoTip$l,
25742
+ PropCheckBox: PropCheckBox$c
25753
25743
  } = components;
25754
25744
  const DEFAULT_WIDTH = 400;
25755
25745
  const DEFAULT_HEIGHT = 400;
@@ -25905,11 +25895,11 @@ class CSProgramEditor extends React.Component {
25905
25895
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Url or Program ID:", " ", /*#__PURE__*/React.createElement(BlurInput, {
25906
25896
  value: this.props.programID,
25907
25897
  onChange: this._handleProgramIDChange
25908
- })), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
25898
+ })), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$c, {
25909
25899
  label: "Show Editor",
25910
25900
  showEditor: this.props.showEditor,
25911
25901
  onChange: this.props.onChange
25912
- }), /*#__PURE__*/React.createElement(InfoTip$k, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
25902
+ }), /*#__PURE__*/React.createElement(InfoTip$l, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$c, {
25913
25903
  label: "Show Buttons",
25914
25904
  showButtons: this.props.showButtons,
25915
25905
  onChange: this.props.onChange
@@ -25917,7 +25907,7 @@ class CSProgramEditor extends React.Component {
25917
25907
  name: "settings",
25918
25908
  pairs: this.props.settings,
25919
25909
  onChange: this._handleSettingsChange
25920
- }), /*#__PURE__*/React.createElement(InfoTip$k, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
25910
+ }), /*#__PURE__*/React.createElement(InfoTip$l, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
25921
25911
  }
25922
25912
  }
25923
25913
  CSProgramEditor.propTypes = _extends({}, Changeable.propTypes);
@@ -26003,7 +25993,7 @@ DeprecatedStandinEditor.widgetName = "deprecated-standin";
26003
25993
 
26004
25994
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
26005
25995
  const {
26006
- InfoTip: InfoTip$j,
25996
+ InfoTip: InfoTip$k,
26007
25997
  InlineIcon: InlineIcon$6
26008
25998
  } = components;
26009
25999
  const {
@@ -26072,14 +26062,14 @@ class DropdownEditor extends React.Component {
26072
26062
  className: "perseus-widget-dropdown"
26073
26063
  }, /*#__PURE__*/React.createElement("div", {
26074
26064
  className: "dropdown-info"
26075
- }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26065
+ }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26076
26066
  className: "dropdown-placeholder"
26077
26067
  }, /*#__PURE__*/React.createElement("input", {
26078
26068
  type: "text",
26079
26069
  placeholder: "Placeholder value",
26080
26070
  value: this.props.placeholder,
26081
26071
  onChange: this.onPlaceholderChange
26082
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "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."))), /*#__PURE__*/React.createElement("div", {
26072
+ }), /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "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."))), /*#__PURE__*/React.createElement("div", {
26083
26073
  className: "clearfix"
26084
26074
  }), /*#__PURE__*/React.createElement("ul", {
26085
26075
  className: "dropdown-choices"
@@ -26613,8 +26603,8 @@ const SortableItem = createReactClass({
26613
26603
  });
26614
26604
 
26615
26605
  const {
26616
- InfoTip: InfoTip$i,
26617
- PropCheckBox: PropCheckBox$a
26606
+ InfoTip: InfoTip$j,
26607
+ PropCheckBox: PropCheckBox$b
26618
26608
  } = components;
26619
26609
 
26620
26610
  // types for iterables
@@ -26861,16 +26851,16 @@ class ExpressionEditor extends React.Component {
26861
26851
  className: "perseus-widget-expression-editor"
26862
26852
  }, /*#__PURE__*/React.createElement("h3", {
26863
26853
  className: "expression-editor-h3"
26864
- }, "Global Options"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26854
+ }, "Global Options"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$b, {
26865
26855
  times: this.props.times,
26866
26856
  onChange: this.props.onChange,
26867
26857
  labelAlignment: "right",
26868
26858
  label: "Use \xD7 for rendering multiplication instead of a center dot."
26869
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
26859
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
26870
26860
  type: "text",
26871
26861
  defaultValue: this.props.functions.join(" "),
26872
26862
  onChange: this.handleFunctions
26873
- })), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "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\"."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
26863
+ })), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "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\"."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
26874
26864
  className: "expression-editor-h3"
26875
26865
  }, "Answers"), /*#__PURE__*/React.createElement("p", {
26876
26866
  style: {
@@ -26960,19 +26950,19 @@ class AnswerOption extends React.Component {
26960
26950
  className: "answer-expression"
26961
26951
  }, /*#__PURE__*/React.createElement(Expression, this.props.expressionProps))), /*#__PURE__*/React.createElement("div", {
26962
26952
  className: "answer-option"
26963
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26953
+ }, /*#__PURE__*/React.createElement(PropCheckBox$b, {
26964
26954
  form: this.props.form,
26965
26955
  onChange: this.props.onChange,
26966
26956
  labelAlignment: "right",
26967
26957
  label: "Answer expression must have the same form."
26968
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
26958
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
26969
26959
  className: "answer-option"
26970
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26960
+ }, /*#__PURE__*/React.createElement(PropCheckBox$b, {
26971
26961
  simplify: this.props.simplify,
26972
26962
  onChange: this.props.onChange,
26973
26963
  labelAlignment: "right",
26974
26964
  label: "Answer expression must be fully expanded and simplified."
26975
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "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.\""))), /*#__PURE__*/React.createElement("div", {
26965
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "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.\""))), /*#__PURE__*/React.createElement("div", {
26976
26966
  className: "remove-container"
26977
26967
  }, removeButton)));
26978
26968
  }
@@ -27171,20 +27161,17 @@ GradedGroupSetEditor.defaultProps = {
27171
27161
  const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.slice(i + 1)];
27172
27162
 
27173
27163
  const {
27174
- ButtonGroup: ButtonGroup$3,
27175
- InfoTip: InfoTip$h,
27176
- PropCheckBox: PropCheckBox$9,
27177
- RangeInput: RangeInput$5
27164
+ ButtonGroup: ButtonGroup$4,
27165
+ InfoTip: InfoTip$i,
27166
+ PropCheckBox: PropCheckBox$a,
27167
+ RangeInput: RangeInput$6
27178
27168
  } = components;
27179
- const {
27180
- getDependencies: getDependencies$9
27181
- } = Dependencies;
27182
- const defaultBackgroundImage$2 = {
27169
+ const defaultBackgroundImage$3 = {
27183
27170
  url: null,
27184
27171
  width: 0,
27185
27172
  height: 0
27186
27173
  };
27187
- function numSteps(range, step) {
27174
+ function numSteps$1(range, step) {
27188
27175
  return Math.floor((range[1] - range[0]) / step);
27189
27176
  }
27190
27177
  const GraphSettings = createReactClass({
@@ -27216,7 +27203,7 @@ const GraphSettings = createReactClass({
27216
27203
  gridStep: [1, 1],
27217
27204
  snapStep: [1, 1],
27218
27205
  valid: true,
27219
- backgroundImage: defaultBackgroundImage$2,
27206
+ backgroundImage: defaultBackgroundImage$3,
27220
27207
  markings: "graph",
27221
27208
  showProtractor: false,
27222
27209
  showRuler: false,
@@ -27326,7 +27313,7 @@ const GraphSettings = createReactClass({
27326
27313
  if (!_.isFinite(step)) {
27327
27314
  return name + " must be a valid number";
27328
27315
  }
27329
- const nSteps = numSteps(range, step);
27316
+ const nSteps = numSteps$1(range, step);
27330
27317
  if (nSteps < minTicks) {
27331
27318
  return name + " is too large, there must be at least " + minTicks + " ticks.";
27332
27319
  }
@@ -27494,12 +27481,16 @@ const GraphSettings = createReactClass({
27494
27481
  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]))];
27495
27482
  const {
27496
27483
  TeX
27497
- } = getDependencies$9();
27484
+ } = Dependencies.getDependencies();
27485
+ this.props.box; // ?
27498
27486
  return /*#__PURE__*/React.createElement("div", null, _.contains(this.props.editableSettings, "canvas") && /*#__PURE__*/React.createElement("div", {
27499
27487
  className: "graph-settings"
27500
27488
  }, /*#__PURE__*/React.createElement("div", {
27501
27489
  className: "perseus-widget-row"
27502
- }, "Canvas size (x,y pixels)", /*#__PURE__*/React.createElement(RangeInput$5, {
27490
+ }, /*#__PURE__*/React.createElement("label", {
27491
+ htmlFor: "canvas-size"
27492
+ }, "Canvas size (x,y pixels)"), /*#__PURE__*/React.createElement(RangeInput$6, {
27493
+ id: "canvas-size",
27503
27494
  value: this.props.box,
27504
27495
  onChange: box => {
27505
27496
  this.change({
@@ -27514,7 +27505,10 @@ const GraphSettings = createReactClass({
27514
27505
  className: "perseus-widget-row"
27515
27506
  }, /*#__PURE__*/React.createElement("div", {
27516
27507
  className: "perseus-widget-left-col"
27517
- }, " ", "x Label", /*#__PURE__*/React.createElement("input", {
27508
+ }, /*#__PURE__*/React.createElement("label", {
27509
+ htmlFor: "labels-x"
27510
+ }, "x Label"), /*#__PURE__*/React.createElement("input", {
27511
+ id: "labels-x",
27518
27512
  type: "text",
27519
27513
  className: "graph-settings-axis-label"
27520
27514
  // eslint-disable-next-line react/no-string-refs
@@ -27524,7 +27518,10 @@ const GraphSettings = createReactClass({
27524
27518
  value: this.state.labelsTextbox[0] || ""
27525
27519
  })), /*#__PURE__*/React.createElement("div", {
27526
27520
  className: "perseus-widget-right-col"
27527
- }, "y Label", /*#__PURE__*/React.createElement("input", {
27521
+ }, /*#__PURE__*/React.createElement("label", {
27522
+ htmlFor: "labels-y"
27523
+ }, "y Label"), /*#__PURE__*/React.createElement("input", {
27524
+ id: "labels-y",
27528
27525
  type: "text",
27529
27526
  className: "graph-settings-axis-label"
27530
27527
  // eslint-disable-next-line react/no-string-refs
@@ -27536,36 +27533,51 @@ const GraphSettings = createReactClass({
27536
27533
  className: "perseus-widget-row"
27537
27534
  }, /*#__PURE__*/React.createElement("div", {
27538
27535
  className: "perseus-widget-left-col"
27539
- }, "x Range", /*#__PURE__*/React.createElement(RangeInput$5, {
27536
+ }, /*#__PURE__*/React.createElement("label", {
27537
+ htmlFor: "range-x"
27538
+ }, "x Range"), /*#__PURE__*/React.createElement(RangeInput$6, {
27539
+ id: "range-x",
27540
27540
  value: this.state.rangeTextbox[0],
27541
27541
  onChange: vals => this.changeRange(0, vals)
27542
27542
  })), /*#__PURE__*/React.createElement("div", {
27543
27543
  className: "perseus-widget-right-col"
27544
- }, "y Range", /*#__PURE__*/React.createElement(RangeInput$5, {
27544
+ }, /*#__PURE__*/React.createElement("label", {
27545
+ htmlFor: "range-y"
27546
+ }, "y Range"), /*#__PURE__*/React.createElement(RangeInput$6, {
27547
+ id: "range-y",
27545
27548
  value: this.state.rangeTextbox[1],
27546
27549
  onChange: vals => this.changeRange(1, vals)
27547
27550
  }))), /*#__PURE__*/React.createElement("div", {
27548
27551
  className: "perseus-widget-row"
27549
27552
  }, /*#__PURE__*/React.createElement("div", {
27550
27553
  className: "perseus-widget-left-col"
27551
- }, "Tick Step", /*#__PURE__*/React.createElement(RangeInput$5, {
27554
+ }, /*#__PURE__*/React.createElement("label", {
27555
+ htmlFor: "tick-step"
27556
+ }, "Tick Step"), /*#__PURE__*/React.createElement(RangeInput$6, {
27557
+ id: "tick-step",
27552
27558
  value: this.state.stepTextbox,
27553
27559
  onChange: this.changeStep
27554
27560
  })), /*#__PURE__*/React.createElement("div", {
27555
27561
  className: "perseus-widget-right-col"
27556
- }, "Grid Step", /*#__PURE__*/React.createElement(RangeInput$5, {
27562
+ }, /*#__PURE__*/React.createElement("label", {
27563
+ htmlFor: "grid-step"
27564
+ }, "Grid Step"), /*#__PURE__*/React.createElement(RangeInput$6, {
27565
+ id: "grid-step",
27557
27566
  value: this.state.gridStepTextbox,
27558
27567
  onChange: this.changeGridStep
27559
27568
  }))), _.contains(this.props.editableSettings, "snap") && /*#__PURE__*/React.createElement("div", {
27560
27569
  className: "perseus-widget-row"
27561
27570
  }, /*#__PURE__*/React.createElement("div", {
27562
27571
  className: "perseus-widget-left-col"
27563
- }, "Snap Step", /*#__PURE__*/React.createElement(RangeInput$5, {
27572
+ }, /*#__PURE__*/React.createElement("label", {
27573
+ htmlFor: "snap-step"
27574
+ }, "Snap Step"), /*#__PURE__*/React.createElement(RangeInput$6, {
27575
+ id: "snap-step",
27564
27576
  value: this.state.snapStepTextbox,
27565
27577
  onChange: this.changeSnapStep
27566
27578
  }))), /*#__PURE__*/React.createElement("div", {
27567
27579
  className: "perseus-widget-row"
27568
- }, /*#__PURE__*/React.createElement("label", null, "Markings: "), /*#__PURE__*/React.createElement(ButtonGroup$3, {
27580
+ }, /*#__PURE__*/React.createElement("label", null, "Markings: "), /*#__PURE__*/React.createElement(ButtonGroup$4, {
27569
27581
  value: this.props.markings,
27570
27582
  allowEmpty: false,
27571
27583
  buttons: [{
@@ -27581,13 +27593,16 @@ const GraphSettings = createReactClass({
27581
27593
  onChange: this.change("markings")
27582
27594
  })), /*#__PURE__*/React.createElement("div", {
27583
27595
  className: "perseus-widget-left-col"
27584
- }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27596
+ }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27585
27597
  label: "Show tooltips",
27586
27598
  showTooltips: this.props.showTooltips,
27587
27599
  onChange: this.change
27588
27600
  }))), _.contains(this.props.editableSettings, "image") && /*#__PURE__*/React.createElement("div", {
27589
27601
  className: "image-settings"
27590
- }, /*#__PURE__*/React.createElement("div", null, "Background image:"), /*#__PURE__*/React.createElement("div", null, "Url:", " ", /*#__PURE__*/React.createElement("input", {
27602
+ }, /*#__PURE__*/React.createElement("div", null, "Background image:"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
27603
+ htmlFor: "bg-url"
27604
+ }, "Url:"), /*#__PURE__*/React.createElement("input", {
27605
+ id: "bg-url",
27591
27606
  type: "text",
27592
27607
  className: "graph-settings-background-url"
27593
27608
  // eslint-disable-next-line react/no-string-refs
@@ -27603,19 +27618,19 @@ const GraphSettings = createReactClass({
27603
27618
  },
27604
27619
  onKeyPress: this.changeBackgroundUrl,
27605
27620
  onBlur: this.changeBackgroundUrl
27606
- }), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27621
+ }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27607
27622
  className: "misc-settings"
27608
27623
  }, /*#__PURE__*/React.createElement("div", {
27609
27624
  className: "perseus-widget-row"
27610
27625
  }, /*#__PURE__*/React.createElement("div", {
27611
27626
  className: "perseus-widget-left-col"
27612
- }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27627
+ }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27613
27628
  label: "Show ruler",
27614
27629
  showRuler: this.props.showRuler,
27615
27630
  onChange: this.change
27616
27631
  })), /*#__PURE__*/React.createElement("div", {
27617
27632
  className: "perseus-widget-right-col"
27618
- }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27633
+ }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
27619
27634
  label: "Show protractor",
27620
27635
  showProtractor: this.props.showProtractor,
27621
27636
  onChange: this.change
@@ -27640,7 +27655,7 @@ const GraphSettings = createReactClass({
27640
27655
  });
27641
27656
 
27642
27657
  const {
27643
- InfoTip: InfoTip$g,
27658
+ InfoTip: InfoTip$h,
27644
27659
  MultiButtonGroup: MultiButtonGroup$1
27645
27660
  } = components;
27646
27661
  const {
@@ -27723,7 +27738,7 @@ class GrapherEditor extends React.Component {
27723
27738
  className: "perseus-error"
27724
27739
  }, this.props.graph.valid);
27725
27740
  }
27726
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$g, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27741
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27727
27742
  editableSettings: ["graph", "snap", "image"],
27728
27743
  box: getInteractiveBoxFromSizeClass$1(sizeClass),
27729
27744
  range: this.props.graph.range,
@@ -27818,7 +27833,7 @@ GroupEditor.defaultProps = {
27818
27833
  };
27819
27834
 
27820
27835
  const {
27821
- PropCheckBox: PropCheckBox$8
27836
+ PropCheckBox: PropCheckBox$9
27822
27837
  } = components;
27823
27838
  /**
27824
27839
  * This is used for editing a name/value pair.
@@ -27941,11 +27956,11 @@ class IframeEditor extends React.Component {
27941
27956
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
27942
27957
  ,
27943
27958
  onChange: this.change("height")
27944
- })), /*#__PURE__*/React.createElement(PropCheckBox$8, {
27959
+ })), /*#__PURE__*/React.createElement(PropCheckBox$9, {
27945
27960
  label: "Allow full screen",
27946
27961
  allowFullScreen: this.props.allowFullScreen,
27947
27962
  onChange: this.props.onChange
27948
- }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$8, {
27963
+ }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$9, {
27949
27964
  label: "Allow iframe content to redirect the page",
27950
27965
  allowTopNavigation: this.props.allowTopNavigation,
27951
27966
  onChange: this.props.onChange
@@ -27968,13 +27983,13 @@ IframeEditor.defaultProps = {
27968
27983
 
27969
27984
  /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
27970
27985
  const {
27971
- InfoTip: InfoTip$f,
27986
+ InfoTip: InfoTip$g,
27972
27987
  InlineIcon: InlineIcon$4,
27973
- RangeInput: RangeInput$4
27988
+ RangeInput: RangeInput$5
27974
27989
  } = components;
27975
27990
  const defaultBoxSize = 400;
27976
27991
  const defaultRange = [0, 10];
27977
- const defaultBackgroundImage$1 = {
27992
+ const defaultBackgroundImage$2 = {
27978
27993
  url: null,
27979
27994
  width: 0,
27980
27995
  height: 0
@@ -28017,7 +28032,7 @@ class ImageEditor extends React.Component {
28017
28032
  style: {
28018
28033
  width: "100%"
28019
28034
  }
28020
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28035
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$g, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28021
28036
  apiOptions: this.props.apiOptions,
28022
28037
  content: this.props.alt,
28023
28038
  onChange: props => {
@@ -28041,7 +28056,7 @@ class ImageEditor extends React.Component {
28041
28056
  }, this.state.backgroundImageError);
28042
28057
  return /*#__PURE__*/React.createElement("div", {
28043
28058
  className: "perseus-image-editor"
28044
- }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28059
+ }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$g, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28045
28060
  value: backgroundImage.url || "",
28046
28061
  style: {
28047
28062
  width: 332
@@ -28052,7 +28067,7 @@ class ImageEditor extends React.Component {
28052
28067
  _renderRowForLabel(label, i) {
28053
28068
  return /*#__PURE__*/React.createElement("tr", {
28054
28069
  key: i
28055
- }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(RangeInput$4, {
28070
+ }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(RangeInput$5, {
28056
28071
  value: label.coordinates
28057
28072
  // eslint-disable-next-line react/jsx-no-bind
28058
28073
  ,
@@ -28197,7 +28212,7 @@ ImageEditor.defaultProps = {
28197
28212
  title: "",
28198
28213
  range: [defaultRange, defaultRange],
28199
28214
  box: [defaultBoxSize, defaultBoxSize],
28200
- backgroundImage: defaultBackgroundImage$1,
28215
+ backgroundImage: defaultBackgroundImage$2,
28201
28216
  labels: [],
28202
28217
  alt: "",
28203
28218
  caption: ""
@@ -28205,7 +28220,7 @@ ImageEditor.defaultProps = {
28205
28220
 
28206
28221
  /* eslint-disable react/sort-comp */
28207
28222
  const {
28208
- InfoTip: InfoTip$e
28223
+ InfoTip: InfoTip$f
28209
28224
  } = components;
28210
28225
  const answerTypes = {
28211
28226
  number: {
@@ -28291,7 +28306,7 @@ class InputNumberEditor extends React.Component {
28291
28306
  value: "optional"
28292
28307
  }, "will be accepted"), /*#__PURE__*/React.createElement("option", {
28293
28308
  value: "enforced"
28294
- }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "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)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28309
+ }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "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)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28295
28310
  type: "checkbox",
28296
28311
  checked: this.props.inexact,
28297
28312
  onChange: e => {
@@ -28327,7 +28342,7 @@ class InputNumberEditor extends React.Component {
28327
28342
  });
28328
28343
  },
28329
28344
  "aria-label": "Answer type"
28330
- }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28345
+ }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28331
28346
  value: this.props.size,
28332
28347
  onChange: e => {
28333
28348
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
@@ -28339,7 +28354,7 @@ class InputNumberEditor extends React.Component {
28339
28354
  value: "normal"
28340
28355
  }, "Normal (80px)"), /*#__PURE__*/React.createElement("option", {
28341
28356
  value: "small"
28342
- }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "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."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28357
+ }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "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."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28343
28358
  type: "checkbox",
28344
28359
  checked: this.props.rightAlign,
28345
28360
  onChange: e => {
@@ -28615,7 +28630,7 @@ LineEditor.defaultProps = {
28615
28630
  };
28616
28631
 
28617
28632
  const {
28618
- ButtonGroup: ButtonGroup$2,
28633
+ ButtonGroup: ButtonGroup$3,
28619
28634
  NumberInput: NumberInput$f
28620
28635
  } = components;
28621
28636
  class ConstraintEditor extends React.Component {
@@ -28631,7 +28646,7 @@ class ConstraintEditor extends React.Component {
28631
28646
  } = Dependencies.getDependencies();
28632
28647
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
28633
28648
  className: "perseus-widget-row"
28634
- }, "Constraint:", " ", /*#__PURE__*/React.createElement(ButtonGroup$2, {
28649
+ }, "Constraint:", " ", /*#__PURE__*/React.createElement(ButtonGroup$3, {
28635
28650
  value: this.props.constraint,
28636
28651
  allowEmpty: false,
28637
28652
  buttons: [{
@@ -29504,45 +29519,537 @@ const GraphTypeSelector = props => {
29504
29519
  }, "Angle"));
29505
29520
  };
29506
29521
 
29507
- const SegmentCountSelector = ({
29508
- numSegments: _numSegments = 1,
29509
- onChange
29510
- }) => /*#__PURE__*/React.createElement("select", {
29511
- key: "segment-select",
29512
- value: _numSegments,
29513
- onChange: e => {
29514
- const num = +e.target.value;
29515
- onChange(num);
29516
- }
29517
- }, _.range(1, 7).map(n => /*#__PURE__*/React.createElement("option", {
29518
- key: n,
29519
- value: n
29520
- }, `${n} segment${n > 1 ? "s" : ""}`)));
29521
-
29522
29522
  const {
29523
- InfoTip: InfoTip$d
29523
+ ButtonGroup: ButtonGroup$2,
29524
+ InfoTip: InfoTip$e,
29525
+ PropCheckBox: PropCheckBox$8,
29526
+ RangeInput: RangeInput$4
29524
29527
  } = components;
29525
- const {
29526
- containerSizeClass,
29527
- getInteractiveBoxFromSizeClass
29528
- } = SizingUtils;
29529
- const DeprecationMixin = Util.DeprecationMixin;
29530
- const InteractiveGraph = InteractiveGraphWidget.widget;
29531
- const defaultBackgroundImage = {
29532
- url: null
29533
- };
29534
- const deprecatedProps = {
29535
- showGraph: function (props) {
29536
- return {
29537
- markings: props.showGraph ? "graph" : "none"
29538
- };
29539
- }
29528
+ const defaultBackgroundImage$1 = {
29529
+ url: null,
29530
+ width: 0,
29531
+ height: 0
29540
29532
  };
29541
- // [min, max]
29542
- // Renders the given children in a View laid out horizontally.
29543
- const Row = props => {
29544
- const {
29545
- children,
29533
+ function numSteps(range, step) {
29534
+ return Math.floor((range[1] - range[0]) / step);
29535
+ }
29536
+ const InteractiveGraphSettings = createReactClass({
29537
+ displayName: "InteractiveGraphSettings",
29538
+ propTypes: _extends({}, Changeable.propTypes, {
29539
+ editableSettings: PropTypes.arrayOf(PropTypes.oneOf(["canvas", "graph", "snap", "image", "measure"])),
29540
+ box: PropTypes.arrayOf(PropTypes.number),
29541
+ labels: PropTypes.arrayOf(PropTypes.string),
29542
+ range: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),
29543
+ step: PropTypes.arrayOf(PropTypes.number),
29544
+ gridStep: PropTypes.arrayOf(PropTypes.number),
29545
+ snapStep: PropTypes.arrayOf(PropTypes.number),
29546
+ valid: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
29547
+ backgroundImage: PropTypes.object,
29548
+ markings: PropTypes.oneOf(["graph", "grid", "none"]),
29549
+ showProtractor: PropTypes.bool,
29550
+ showRuler: PropTypes.bool,
29551
+ showTooltips: PropTypes.bool,
29552
+ rulerLabel: PropTypes.string,
29553
+ rulerTicks: PropTypes.number
29554
+ }),
29555
+ getDefaultProps: function () {
29556
+ return {
29557
+ editableSettings: ["graph", "snap", "image", "measure"],
29558
+ box: [interactiveSizes.defaultBoxSizeSmall, interactiveSizes.defaultBoxSizeSmall],
29559
+ labels: ["x", "y"],
29560
+ range: [[-10, 10], [-10, 10]],
29561
+ step: [1, 1],
29562
+ gridStep: [1, 1],
29563
+ snapStep: [1, 1],
29564
+ valid: true,
29565
+ backgroundImage: defaultBackgroundImage$1,
29566
+ markings: "graph",
29567
+ showProtractor: false,
29568
+ showRuler: false,
29569
+ showTooltips: false,
29570
+ rulerLabel: "",
29571
+ rulerTicks: 10
29572
+ };
29573
+ },
29574
+ getInitialState: function () {
29575
+ return this.stateFromProps(this.props);
29576
+ },
29577
+ componentDidMount: function () {
29578
+ // TODO(scottgrant): This is a hack to remove the deprecated call to
29579
+ // this.isMounted() but is still considered an anti-pattern.
29580
+ this._isMounted = true;
29581
+ this.changeGraph = _.debounce(this.changeGraph, 300);
29582
+ },
29583
+ UNSAFE_componentWillReceiveProps: function (nextProps) {
29584
+ // Make sure that state updates when switching
29585
+ // between different items in a multi-item editor.
29586
+ 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)) {
29587
+ this.setState(this.stateFromProps(nextProps));
29588
+ }
29589
+ },
29590
+ componentWillUnmount: function () {
29591
+ this._isMounted = false;
29592
+ },
29593
+ stateFromProps: function (props) {
29594
+ return {
29595
+ labelsTextbox: props.labels,
29596
+ gridStepTextbox: props.gridStep,
29597
+ snapStepTextbox: props.snapStep,
29598
+ stepTextbox: props.step,
29599
+ rangeTextbox: props.range,
29600
+ backgroundImage: _.clone(props.backgroundImage)
29601
+ };
29602
+ },
29603
+ change(...args) {
29604
+ return Changeable.change.apply(this, args);
29605
+ },
29606
+ // TODO(aria): Make either a wrapper for standard events to work
29607
+ // with this.change, or make these use some TextInput/NumberInput box
29608
+ changeRulerLabel: function (e) {
29609
+ this.change({
29610
+ rulerLabel: e.target.value
29611
+ });
29612
+ },
29613
+ changeRulerTicks: function (e) {
29614
+ this.change({
29615
+ rulerTicks: +e.target.value
29616
+ });
29617
+ },
29618
+ changeBackgroundUrl: function (e) {
29619
+ // Only continue on blur or "enter"
29620
+ if (e.type === "keypress" && e.key !== "Enter") {
29621
+ return;
29622
+ }
29623
+ const setUrl = (url, width, height) => {
29624
+ const image = _.clone(this.props.backgroundImage);
29625
+ image.url = url;
29626
+ image.width = width;
29627
+ image.height = height;
29628
+ this.setState({
29629
+ backgroundImage: image
29630
+ }, this.changeGraph);
29631
+ };
29632
+
29633
+ // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'value' does not exist on type 'Element | Text'.
29634
+ const url = ReactDOM.findDOMNode(this.refs["bg-url"]).value; // eslint-disable-line react/no-string-refs
29635
+ if (url) {
29636
+ Util.getImageSize(url, (width, height) => {
29637
+ if (this._isMounted) {
29638
+ setUrl(url, width, height);
29639
+ }
29640
+ });
29641
+ } else {
29642
+ setUrl(null, 0, 0);
29643
+ }
29644
+ },
29645
+ renderLabelChoices: function (choices) {
29646
+ return _.map(choices, function (nameAndValue) {
29647
+ return /*#__PURE__*/React.createElement("option", {
29648
+ value: nameAndValue[1]
29649
+ }, nameAndValue[0]);
29650
+ });
29651
+ },
29652
+ validRange: function (range) {
29653
+ const numbers = _.every(range, function (num) {
29654
+ return _.isFinite(num);
29655
+ });
29656
+ if (!numbers) {
29657
+ return "Range must be a valid number";
29658
+ }
29659
+ if (range[0] >= range[1]) {
29660
+ return "Range must have a higher number on the right";
29661
+ }
29662
+ return true;
29663
+ },
29664
+ validateStepValue: function (settings) {
29665
+ const {
29666
+ step,
29667
+ range,
29668
+ name,
29669
+ minTicks,
29670
+ maxTicks
29671
+ } = settings;
29672
+ if (!_.isFinite(step)) {
29673
+ return name + " must be a valid number";
29674
+ }
29675
+ const nSteps = numSteps(range, step);
29676
+ if (nSteps < minTicks) {
29677
+ return name + " is too large, there must be at least " + minTicks + " ticks.";
29678
+ }
29679
+ if (nSteps > maxTicks) {
29680
+ return name + " is too small, there can be at most " + maxTicks + " ticks.";
29681
+ }
29682
+ return true;
29683
+ },
29684
+ validSnapStep: function (step, range) {
29685
+ return this.validateStepValue({
29686
+ step: step,
29687
+ range: range,
29688
+ name: "Snap step",
29689
+ minTicks: 5,
29690
+ maxTicks: 60
29691
+ });
29692
+ },
29693
+ validGridStep: function (step, range) {
29694
+ return this.validateStepValue({
29695
+ step: step,
29696
+ range: range,
29697
+ name: "Grid step",
29698
+ minTicks: 3,
29699
+ maxTicks: 60
29700
+ });
29701
+ },
29702
+ validStep: function (step, range) {
29703
+ return this.validateStepValue({
29704
+ step: step,
29705
+ range: range,
29706
+ name: "Step",
29707
+ minTicks: 3,
29708
+ maxTicks: 20
29709
+ });
29710
+ },
29711
+ validBackgroundImageSize: function (image) {
29712
+ // Ignore empty images
29713
+ if (!image.url) {
29714
+ return true;
29715
+ }
29716
+ const validSize = image.width <= 450 && image.height <= 450;
29717
+ if (!validSize) {
29718
+ return "Image must be smaller than 450px x 450px.";
29719
+ }
29720
+ return true;
29721
+ },
29722
+ validateGraphSettings: function (range, step, gridStep, snapStep, image) {
29723
+ const self = this;
29724
+ let msg;
29725
+ const goodRange = _.every(range, function (range) {
29726
+ msg = self.validRange(range);
29727
+ return msg === true;
29728
+ });
29729
+ if (!goodRange) {
29730
+ return msg;
29731
+ }
29732
+ const goodStep = _.every(step, function (step, i) {
29733
+ msg = self.validStep(step, range[i]);
29734
+ return msg === true;
29735
+ });
29736
+ if (!goodStep) {
29737
+ return msg;
29738
+ }
29739
+ const goodGridStep = _.every(gridStep, function (gridStep, i) {
29740
+ msg = self.validGridStep(gridStep, range[i]);
29741
+ return msg === true;
29742
+ });
29743
+ if (!goodGridStep) {
29744
+ return msg;
29745
+ }
29746
+ const goodSnapStep = _.every(snapStep, function (snapStep, i) {
29747
+ msg = self.validSnapStep(snapStep, range[i]);
29748
+ return msg === true;
29749
+ });
29750
+ if (!goodSnapStep) {
29751
+ return msg;
29752
+ }
29753
+ const goodImageSize = this.validBackgroundImageSize(image);
29754
+ if (goodImageSize !== true) {
29755
+ msg = goodImageSize;
29756
+ return msg;
29757
+ }
29758
+ return true;
29759
+ },
29760
+ changeLabel: function (i, e) {
29761
+ const val = e.target.value;
29762
+ const labels = this.state.labelsTextbox.slice();
29763
+ labels[i] = val;
29764
+ this.setState({
29765
+ labelsTextbox: labels
29766
+ }, this.changeGraph);
29767
+ },
29768
+ changeRange: function (i, values) {
29769
+ const ranges = this.state.rangeTextbox.slice();
29770
+ ranges[i] = values;
29771
+ const step = this.state.stepTextbox.slice();
29772
+ const gridStep = this.state.gridStepTextbox.slice();
29773
+ const snapStep = this.state.snapStepTextbox.slice();
29774
+ const scale = Util.scaleFromExtent(ranges[i], this.props.box[i]);
29775
+ if (this.validRange(ranges[i]) === true) {
29776
+ step[i] = Util.tickStepFromExtent(ranges[i], this.props.box[i]);
29777
+ gridStep[i] = Util.gridStepFromTickStep(step[i], scale);
29778
+ snapStep[i] = gridStep[i] / 2;
29779
+ }
29780
+ this.setState({
29781
+ stepTextbox: step,
29782
+ gridStepTextbox: gridStep,
29783
+ snapStepTextbox: snapStep,
29784
+ rangeTextbox: ranges
29785
+ }, this.changeGraph);
29786
+ },
29787
+ changeStep: function (step) {
29788
+ this.setState({
29789
+ stepTextbox: step
29790
+ }, this.changeGraph);
29791
+ },
29792
+ changeSnapStep: function (snapStep) {
29793
+ this.setState({
29794
+ snapStepTextbox: snapStep
29795
+ }, this.changeGraph);
29796
+ },
29797
+ changeGridStep: function (gridStep) {
29798
+ this.setState({
29799
+ gridStepTextbox: gridStep,
29800
+ snapStepTextbox: _.map(gridStep, function (step) {
29801
+ return step / 2;
29802
+ })
29803
+ }, this.changeGraph);
29804
+ },
29805
+ changeGraph: function () {
29806
+ const labels = this.state.labelsTextbox;
29807
+ const range = _.map(this.state.rangeTextbox, function (range) {
29808
+ return _.map(range, Number);
29809
+ });
29810
+ const step = _.map(this.state.stepTextbox, Number);
29811
+ const gridStep = this.state.gridStepTextbox;
29812
+ const snapStep = this.state.snapStepTextbox;
29813
+ const image = this.state.backgroundImage;
29814
+
29815
+ // validationResult is either:
29816
+ // true -> the settings are valid
29817
+ // a string -> the settings are invalid, and the explanation
29818
+ // is contained in the string
29819
+ // TODO(aria): Refactor this to not be confusing
29820
+ const validationResult = this.validateGraphSettings(range, step, gridStep, snapStep, image);
29821
+ if (validationResult === true) {
29822
+ // either true or a string
29823
+ this.change({
29824
+ valid: true,
29825
+ labels: labels,
29826
+ range: range,
29827
+ step: step,
29828
+ gridStep: gridStep,
29829
+ snapStep: snapStep,
29830
+ backgroundImage: image
29831
+ });
29832
+ } else {
29833
+ this.change({
29834
+ valid: validationResult // a string message, not false
29835
+ });
29836
+ }
29837
+ },
29838
+
29839
+ render: function () {
29840
+ 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]))];
29841
+ const {
29842
+ TeX
29843
+ } = Dependencies.getDependencies();
29844
+ return /*#__PURE__*/React.createElement("div", null, _.contains(this.props.editableSettings, "canvas") && /*#__PURE__*/React.createElement("div", {
29845
+ className: "graph-settings"
29846
+ }, /*#__PURE__*/React.createElement("div", {
29847
+ className: "perseus-widget-row"
29848
+ }, /*#__PURE__*/React.createElement("label", {
29849
+ htmlFor: "canvas-size"
29850
+ }, "Canvas size (x,y pixels)"), /*#__PURE__*/React.createElement(RangeInput$4, {
29851
+ id: "canvas-size",
29852
+ value: this.props.box,
29853
+ onChange: box => {
29854
+ this.change({
29855
+ box: box
29856
+ });
29857
+ }
29858
+ })), /*#__PURE__*/React.createElement("div", {
29859
+ className: "perseus-widget-row"
29860
+ }, "Scale (px per div):", " ", /*#__PURE__*/React.createElement(TeX, null, "(" + scale[0] + ", " + scale[1] + ")"))), _.contains(this.props.editableSettings, "graph") && /*#__PURE__*/React.createElement("div", {
29861
+ className: "graph-settings"
29862
+ }, /*#__PURE__*/React.createElement("div", {
29863
+ className: "perseus-widget-row"
29864
+ }, /*#__PURE__*/React.createElement("div", {
29865
+ className: "perseus-widget-left-col"
29866
+ }, /*#__PURE__*/React.createElement("label", {
29867
+ htmlFor: "labels-x"
29868
+ }, "x Label"), /*#__PURE__*/React.createElement("input", {
29869
+ id: "labels-x",
29870
+ type: "text",
29871
+ className: "graph-settings-axis-label"
29872
+ // eslint-disable-next-line react/no-string-refs
29873
+ ,
29874
+ ref: "labels-0",
29875
+ onChange: e => this.changeLabel(0, e),
29876
+ value: this.state.labelsTextbox[0] || ""
29877
+ })), /*#__PURE__*/React.createElement("div", {
29878
+ className: "perseus-widget-right-col"
29879
+ }, /*#__PURE__*/React.createElement("label", {
29880
+ htmlFor: "labels-y"
29881
+ }, "y Label"), /*#__PURE__*/React.createElement("input", {
29882
+ id: "labels-y",
29883
+ type: "text",
29884
+ className: "graph-settings-axis-label"
29885
+ // eslint-disable-next-line react/no-string-refs
29886
+ ,
29887
+ ref: "labels-1",
29888
+ onChange: e => this.changeLabel(1, e),
29889
+ value: this.state.labelsTextbox[1] || ""
29890
+ }))), /*#__PURE__*/React.createElement("div", {
29891
+ className: "perseus-widget-row"
29892
+ }, /*#__PURE__*/React.createElement("div", {
29893
+ className: "perseus-widget-left-col"
29894
+ }, /*#__PURE__*/React.createElement("label", {
29895
+ htmlFor: "range-x"
29896
+ }, "x Range"), /*#__PURE__*/React.createElement(RangeInput$4, {
29897
+ id: "range-x",
29898
+ value: this.state.rangeTextbox[0],
29899
+ onChange: vals => this.changeRange(0, vals)
29900
+ })), /*#__PURE__*/React.createElement("div", {
29901
+ className: "perseus-widget-right-col"
29902
+ }, /*#__PURE__*/React.createElement("label", {
29903
+ htmlFor: "range-y"
29904
+ }, "y Range"), /*#__PURE__*/React.createElement(RangeInput$4, {
29905
+ id: "range-y",
29906
+ value: this.state.rangeTextbox[1],
29907
+ onChange: vals => this.changeRange(1, vals)
29908
+ }))), /*#__PURE__*/React.createElement("div", {
29909
+ className: "perseus-widget-row"
29910
+ }, /*#__PURE__*/React.createElement("div", {
29911
+ className: "perseus-widget-left-col"
29912
+ }, /*#__PURE__*/React.createElement("label", {
29913
+ htmlFor: "tick-step"
29914
+ }, "Tick Step"), /*#__PURE__*/React.createElement(RangeInput$4, {
29915
+ id: "tick-step",
29916
+ value: this.state.stepTextbox,
29917
+ onChange: this.changeStep
29918
+ })), /*#__PURE__*/React.createElement("div", {
29919
+ className: "perseus-widget-right-col"
29920
+ }, /*#__PURE__*/React.createElement("label", {
29921
+ htmlFor: "grid-step"
29922
+ }, "Grid Step"), /*#__PURE__*/React.createElement(RangeInput$4, {
29923
+ id: "grid-step",
29924
+ value: this.state.gridStepTextbox,
29925
+ onChange: this.changeGridStep
29926
+ }))), _.contains(this.props.editableSettings, "snap") && /*#__PURE__*/React.createElement("div", {
29927
+ className: "perseus-widget-row"
29928
+ }, /*#__PURE__*/React.createElement("div", {
29929
+ className: "perseus-widget-left-col"
29930
+ }, /*#__PURE__*/React.createElement("label", {
29931
+ htmlFor: "snap-step"
29932
+ }, "Snap Step"), /*#__PURE__*/React.createElement(RangeInput$4, {
29933
+ id: "snap-step",
29934
+ value: this.state.snapStepTextbox,
29935
+ onChange: this.changeSnapStep
29936
+ }))), /*#__PURE__*/React.createElement("div", {
29937
+ className: "perseus-widget-row"
29938
+ }, /*#__PURE__*/React.createElement("label", null, "Markings: "), /*#__PURE__*/React.createElement(ButtonGroup$2, {
29939
+ value: this.props.markings,
29940
+ allowEmpty: false,
29941
+ buttons: [{
29942
+ value: "graph",
29943
+ content: "Graph"
29944
+ }, {
29945
+ value: "grid",
29946
+ content: "Grid"
29947
+ }, {
29948
+ value: "none",
29949
+ content: "None"
29950
+ }],
29951
+ onChange: this.change("markings")
29952
+ })), /*#__PURE__*/React.createElement("div", {
29953
+ className: "perseus-widget-left-col"
29954
+ }, /*#__PURE__*/React.createElement(PropCheckBox$8, {
29955
+ label: "Show tooltips",
29956
+ showTooltips: this.props.showTooltips,
29957
+ onChange: this.change
29958
+ }))), _.contains(this.props.editableSettings, "image") && /*#__PURE__*/React.createElement("div", {
29959
+ className: "image-settings"
29960
+ }, /*#__PURE__*/React.createElement("div", null, "Background image:"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
29961
+ htmlFor: "bg-url"
29962
+ }, "Url:"), /*#__PURE__*/React.createElement("input", {
29963
+ id: "bg-url",
29964
+ type: "text",
29965
+ className: "graph-settings-background-url"
29966
+ // eslint-disable-next-line react/no-string-refs
29967
+ ,
29968
+ ref: "bg-url",
29969
+ value: this.state.backgroundImage.url || "",
29970
+ onChange: e => {
29971
+ const image = _.clone(this.props.backgroundImage);
29972
+ image.url = e.target.value;
29973
+ this.setState({
29974
+ backgroundImage: image
29975
+ });
29976
+ },
29977
+ onKeyPress: this.changeBackgroundUrl,
29978
+ onBlur: this.changeBackgroundUrl
29979
+ }), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
29980
+ className: "misc-settings"
29981
+ }, /*#__PURE__*/React.createElement("div", {
29982
+ className: "perseus-widget-row"
29983
+ }, /*#__PURE__*/React.createElement("div", {
29984
+ className: "perseus-widget-left-col"
29985
+ }, /*#__PURE__*/React.createElement(PropCheckBox$8, {
29986
+ label: "Show ruler",
29987
+ showRuler: this.props.showRuler,
29988
+ onChange: this.change
29989
+ })), /*#__PURE__*/React.createElement("div", {
29990
+ className: "perseus-widget-right-col"
29991
+ }, /*#__PURE__*/React.createElement(PropCheckBox$8, {
29992
+ label: "Show protractor",
29993
+ showProtractor: this.props.showProtractor,
29994
+ onChange: this.change
29995
+ }))), this.props.showRuler && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Ruler label:", " ", /*#__PURE__*/React.createElement("select", {
29996
+ onChange: this.changeRulerLabel,
29997
+ value: this.props.rulerLabel
29998
+ }, /*#__PURE__*/React.createElement("option", {
29999
+ value: ""
30000
+ }, "None"), /*#__PURE__*/React.createElement("optgroup", {
30001
+ label: "Metric"
30002
+ }, this.renderLabelChoices([["milimeters", "mm"], ["centimeters", "cm"], ["meters", "m"], ["kilometers", "km"]])), /*#__PURE__*/React.createElement("optgroup", {
30003
+ label: "Imperial"
30004
+ }, this.renderLabelChoices([["inches", "in"], ["feet", "ft"], ["yards", "yd"], ["miles", "mi"]]))))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Ruler ticks:", " ", /*#__PURE__*/React.createElement("select", {
30005
+ onChange: this.changeRulerTicks,
30006
+ value: this.props.rulerTicks
30007
+ }, _.map([1, 2, 4, 8, 10, 16], function (n) {
30008
+ return /*#__PURE__*/React.createElement("option", {
30009
+ value: n
30010
+ }, n);
30011
+ })))))));
30012
+ }
30013
+ });
30014
+
30015
+ const SegmentCountSelector = ({
30016
+ numSegments: _numSegments = 1,
30017
+ onChange
30018
+ }) => /*#__PURE__*/React.createElement("select", {
30019
+ key: "segment-select",
30020
+ value: _numSegments,
30021
+ onChange: e => {
30022
+ const num = +e.target.value;
30023
+ onChange(num);
30024
+ }
30025
+ }, _.range(1, 7).map(n => /*#__PURE__*/React.createElement("option", {
30026
+ key: n,
30027
+ value: n
30028
+ }, `${n} segment${n > 1 ? "s" : ""}`)));
30029
+
30030
+ const {
30031
+ InfoTip: InfoTip$d
30032
+ } = components;
30033
+ const {
30034
+ containerSizeClass,
30035
+ getInteractiveBoxFromSizeClass
30036
+ } = SizingUtils;
30037
+ const DeprecationMixin = Util.DeprecationMixin;
30038
+ const InteractiveGraph = InteractiveGraphWidget.widget;
30039
+ const defaultBackgroundImage = {
30040
+ url: null
30041
+ };
30042
+ const deprecatedProps = {
30043
+ showGraph: function (props) {
30044
+ return {
30045
+ markings: props.showGraph ? "graph" : "none"
30046
+ };
30047
+ }
30048
+ };
30049
+ // Renders the given children in a View laid out horizontally.
30050
+ const Row = props => {
30051
+ const {
30052
+ children,
29546
30053
  style
29547
30054
  } = props;
29548
30055
  return /*#__PURE__*/React.createElement(View, {
@@ -29559,6 +30066,12 @@ const FieldLabel = props => {
29559
30066
  }
29560
30067
  }, props.children);
29561
30068
  };
30069
+ /**
30070
+ * An editor for the InteractiveGraph widget, which allows the user to
30071
+ * specify the graph's properties and the correct answer.
30072
+ *
30073
+ * Used in the exercise editor.
30074
+ */
29562
30075
  class InteractiveGraphEditor extends React.Component {
29563
30076
  constructor(...args) {
29564
30077
  super(...args);
@@ -29738,7 +30251,7 @@ class InteractiveGraphEditor extends React.Component {
29738
30251
  borderStyle: "solid",
29739
30252
  borderWidth: 1
29740
30253
  }
29741
- }, equationString), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React.createElement(GraphSettings, {
30254
+ }, equationString), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React.createElement(InteractiveGraphSettings, {
29742
30255
  box: getInteractiveBoxFromSizeClass(sizeClass),
29743
30256
  range: this.props.range,
29744
30257
  labels: this.props.labels,