@khanacademy/perseus 19.1.6 → 19.1.7

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
@@ -250,7 +250,11 @@ class MathInput extends React.Component {
250
250
  display: "flex",
251
251
  padding: 1
252
252
  },
253
- onClick: () => {
253
+ onClick: e => {
254
+ // Prevent the click into the input from registering
255
+ // so that the keypad popover doesn't close when
256
+ // switching focus to the input.
257
+ e.stopPropagation();
254
258
  const mathField = this.mathField();
255
259
  if (!mathField) {
256
260
  return;
@@ -3975,10 +3979,10 @@ FixedToResponsive.defaultProps = {
3975
3979
 
3976
3980
  /* Local helper methods. */
3977
3981
 
3978
- function getKey$1(eventName, id) {
3982
+ function getKey$2(eventName, id) {
3979
3983
  return eventName + ":" + id;
3980
3984
  }
3981
- function getEventName$1(key) {
3985
+ function getEventName$2(key) {
3982
3986
  return key.split(":")[0];
3983
3987
  }
3984
3988
  const MovableHelperMethods = {
@@ -4055,7 +4059,7 @@ const MovableHelperMethods = {
4055
4059
 
4056
4060
  // If there's an existing handler, replace it by using its index in
4057
4061
  // `this.state[eventName]`; otherwise, add this handler to the end
4058
- const key = getKey$1(eventName, id);
4062
+ const key = getKey$2(eventName, id);
4059
4063
  const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
4060
4064
  this.state[eventName][index] = func;
4061
4065
  },
@@ -4067,7 +4071,7 @@ const MovableHelperMethods = {
4067
4071
  */
4068
4072
  unlisten: function (eventName, id) {
4069
4073
  this._listenerMap = this._listenerMap || {};
4070
- const key = getKey$1(eventName, id);
4074
+ const key = getKey$2(eventName, id);
4071
4075
  const index = this._listenerMap[key];
4072
4076
  if (index !== undefined) {
4073
4077
  // Remove handler from list of event handlers and listenerMap
@@ -4077,7 +4081,7 @@ const MovableHelperMethods = {
4077
4081
  // Re-index existing events: if they occur after `index`, decrement
4078
4082
  const keys = _.keys(this._listenerMap);
4079
4083
  _.each(keys, function (key) {
4080
- if (getEventName$1(key) === eventName &&
4084
+ if (getEventName$2(key) === eventName &&
4081
4085
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
4082
4086
  this._listenerMap[key] > index) {
4083
4087
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
@@ -9535,6 +9539,9 @@ class Graphie$1 {
9535
9539
  getMouseCoord(event) {
9536
9540
  throw new Error("getMouseCoord is a stub, and is not implemented");
9537
9541
  }
9542
+
9543
+ // This is a stub that's overridden in interactive.ts
9544
+ addMouseLayer(options) {}
9538
9545
  }
9539
9546
  const labelDirections = {
9540
9547
  center: [-0.5, -0.5],
@@ -13985,7 +13992,7 @@ class Movable {
13985
13992
 
13986
13993
  // If there's an existing handler, replace it by using its index in
13987
13994
  // `this.state[eventName]`; otherwise, add this handler to the end
13988
- const key = getKey(eventName, id);
13995
+ const key = getKey$1(eventName, id);
13989
13996
  const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
13990
13997
  this.state[eventName][index] = func;
13991
13998
  }
@@ -13998,7 +14005,7 @@ class Movable {
13998
14005
  */
13999
14006
  unlisten(eventName, id) {
14000
14007
  this._listenerMap = this._listenerMap || {};
14001
- const key = getKey(eventName, id);
14008
+ const key = getKey$1(eventName, id);
14002
14009
  const index = this._listenerMap[key];
14003
14010
  if (index !== undefined) {
14004
14011
  // Remove handler from list of event handlers and listenerMap
@@ -14008,7 +14015,7 @@ class Movable {
14008
14015
  // Re-index existing events: if they occur after `index`, decrement
14009
14016
  const keys = _.keys(this._listenerMap);
14010
14017
  keys.forEach(key => {
14011
- if (getEventName(key) === eventName && this._listenerMap[key] > index) {
14018
+ if (getEventName$1(key) === eventName && this._listenerMap[key] > index) {
14012
14019
  this._listenerMap[key]--;
14013
14020
  }
14014
14021
  });
@@ -14042,10 +14049,10 @@ class Movable {
14042
14049
  return this.state.mouseTarget;
14043
14050
  }
14044
14051
  }
14045
- function getKey(eventName, id) {
14052
+ function getKey$1(eventName, id) {
14046
14053
  return eventName + ":" + id;
14047
14054
  }
14048
- function getEventName(key) {
14055
+ function getEventName$1(key) {
14049
14056
  return key.split(":")[0];
14050
14057
  }
14051
14058
 
@@ -14994,31 +15001,31 @@ const DEFAULT_STATE$1 = {
14994
15001
  mouseTarget: null,
14995
15002
  touchOffset: null
14996
15003
  };
15004
+ // TODO(benchristel): this is a memory leak. We add items to
15005
+ // tooltipResetFunctions, but never remove them.
14997
15006
  const tooltipResetFunctions = [];
14998
- const MovablePoint$5 = function MovablePoint(graphie, movable, options) {
14999
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
15000
- _.extend(this, {
15001
- graphie,
15002
- movable,
15003
- state: {
15004
- // Set here because this must be unique for each instance
15007
+ class MovablePoint$5 {
15008
+ constructor(graphie, movable, options) {
15009
+ this.graphie = void 0;
15010
+ this.movable = void 0;
15011
+ this.state = void 0;
15012
+ // @ts-expect-error - TS2564: Property 'prevState' has no initializer and is not definitely assigned in the constructor.
15013
+ this.prevState = void 0;
15014
+ this._tooltip = void 0;
15015
+ this._listenerMap = {};
15016
+ this.graphie = graphie;
15017
+ this.movable = movable;
15018
+ // @ts-expect-error - TS2740: Type '{ id: string; }' is missing the following properties from type 'State': add, added, constraints, coord, and 19 more.
15019
+ this.state = {
15005
15020
  id: _.uniqueId("movablePoint")
15006
- }
15007
- });
15008
-
15009
- // We only set DEFAULT_STATE once, here
15010
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
15011
- this.modify(_.extend({}, DEFAULT_STATE$1, options));
15012
- };
15013
- _.extend(MovablePoint$5, MovablePointOptions);
15014
- InteractiveUtil.createGettersFor(MovablePoint$5, _.extend({}, DEFAULT_PROPS$1, DEFAULT_STATE$1));
15015
- InteractiveUtil.addMovableHelperMethodsTo(MovablePoint$5);
15016
- _.extend(MovablePoint$5.prototype, {
15017
- cloneState: function () {
15018
- return _.extend(this.movable.cloneState(), this.state);
15019
- },
15020
- _createDefaultState: function () {
15021
- return _.extend({
15021
+ };
15022
+ this.modify(_extends({}, DEFAULT_STATE$1, options));
15023
+ }
15024
+ modify(options) {
15025
+ this.update(_.extend(this._createDefaultState(), options));
15026
+ }
15027
+ _createDefaultState() {
15028
+ return _extends({
15022
15029
  id: this.state.id
15023
15030
  }, normalizeOptions$1(
15024
15031
  // Defaults are copied from MovablePointOptions.*.standard
@@ -15028,69 +15035,14 @@ _.extend(MovablePoint$5.prototype, {
15028
15035
  // - they don't need getters created for them
15029
15036
  // TODO(jack): Consider "default" once we es3ify perseus
15030
15037
  objective_.pluck(MovablePointOptions, "standard")
15031
-
15032
15038
  // We only update props here, because we want things on state to
15033
15039
  // be persistent, and updated appropriately in modify()
15034
15040
  ), DEFAULT_PROPS$1);
15035
- },
15036
- /**
15037
- * Resets the object to its state as if it were constructed with
15038
- * `options` originally. state not on DEFAULT_PROPS is maintained.
15039
- *
15040
- * Analogous to React.js's replaceProps
15041
- */
15042
- modify: function (options) {
15043
- this.update(_.extend(this._createDefaultState(), options));
15044
- },
15045
- /**
15046
- * Displays a tooltip above the point, replacing any previous contents. If
15047
- * there is no tooltip initialized, adds the tooltip.
15048
- *
15049
- * If the type of contents is string, the contents will be rendered with
15050
- * KaTeX. Otherwise, the content will be assumed to be a DOM node and will
15051
- * be appended inside the tooltip.
15052
- */
15053
- _showTooltip: function (contents) {
15054
- if (!this._tooltip) {
15055
- this._tooltip = document.createElement("div");
15056
- this._tooltip.className = "tooltip-content";
15057
- this.state.visibleShape.wrapper.className = "tooltip";
15058
- this.state.visibleShape.wrapper.appendChild(this._tooltip);
15059
-
15060
- // Only one tooltip should be displayed at a time, so store a list
15061
- // of all the tooltips initialized.
15062
- tooltipResetFunctions.push(() => {
15063
- if (this.state.added) {
15064
- this._hideTooltip();
15065
- }
15066
- });
15067
- }
15068
- if (this._tooltip.firstChild) {
15069
- this._tooltip.removeChild(this._tooltip.firstChild);
15070
- }
15071
- this.state.visibleShape.wrapper.className = "tooltip visible";
15072
- this._tooltip.appendChild(document.createElement("span"));
15073
- if (typeof contents === "string") {
15074
- processMath(this._tooltip.firstChild, contents, false);
15075
- } else if (typeof contents === "function") {
15076
- contents(this._tooltip.firstChild);
15077
- } else {
15078
- this._tooltip.firstChild.appendChild(contents);
15079
- }
15080
- },
15081
- _hideTooltip: function () {
15082
- if (this._tooltip) {
15083
- // Without the visible class, tooltips have display: none set
15084
- this.state.visibleShape.wrapper.className = "tooltip";
15085
- }
15086
- },
15087
- /**
15088
- * Adjusts constructor parameters without changing previous settings
15089
- * for any option not specified
15090
- *
15091
- * Analogous to React.js's setProps
15092
- */
15093
- update: function (options) {
15041
+ }
15042
+ cloneState() {
15043
+ return _extends({}, this.movable.cloneState(), this.state);
15044
+ }
15045
+ update(options) {
15094
15046
  const self = this;
15095
15047
  const graphie = self.graphie;
15096
15048
  const state = _.extend(self.state, normalizeOptions$1(options));
@@ -15240,11 +15192,15 @@ _.extend(MovablePoint$5.prototype, {
15240
15192
  showTrashTooltip();
15241
15193
  const content = svgElem.getElementsByClassName("tooltip-content")[0];
15242
15194
  content.style.filter = "none";
15195
+
15196
+ // @ts-expect-error - this._tooltip.firstChild is possibly null
15243
15197
  this._tooltip.firstChild.addEventListener("touchstart", e => {
15244
15198
  // Prevent creation of a new point when the event is
15245
15199
  // propagated up the DOM.
15246
15200
  e.stopPropagation();
15247
15201
  }, true);
15202
+
15203
+ // @ts-expect-error - this._tooltip.firstChild is possibly null
15248
15204
  this._tooltip.firstChild.addEventListener("touchend", e => {
15249
15205
  // Remove the point and prevent creation of a
15250
15206
  // new point.
@@ -15266,6 +15222,7 @@ _.extend(MovablePoint$5.prototype, {
15266
15222
 
15267
15223
  // Trigger an add event if this hasn't been added before
15268
15224
  if (!state.added) {
15225
+ // @ts-expect-error - type {} is missing properties from State
15269
15226
  self.prevState = {};
15270
15227
  self._fireEvent(state.add, self.cloneState(), self.prevState);
15271
15228
  state.added = true;
@@ -15277,38 +15234,187 @@ _.extend(MovablePoint$5.prototype, {
15277
15234
 
15278
15235
  // Trigger a modify event
15279
15236
  self._fireEvent(state.modify, self.cloneState(), self.prevState);
15280
- },
15281
- remove: function () {
15282
- this.state.added = false;
15283
- this._fireEvent(this.state.remove);
15284
- if (this.movable) {
15285
- this.movable.remove();
15286
- }
15287
- // TODO(jack): This should really be moved off of
15288
- // movablePoint.state and only kept on movable.state
15289
- this.state.mouseTarget = null;
15290
- },
15291
- constrain: function () {
15237
+ }
15238
+ draw() {
15239
+ const currState = this.cloneState();
15240
+ this._fireEvent(this.state.draw, currState, this.prevState);
15241
+ this.prevState = currState;
15242
+ }
15243
+ constrain() {
15292
15244
  const result = this._applyConstraints(this.coord(), this.coord());
15293
15245
  if (point.is(result)) {
15294
15246
  this.setCoord(result);
15295
15247
  }
15296
15248
  return result !== false;
15297
- },
15298
- setCoord: function (coord) {
15249
+ }
15250
+
15251
+ /**
15252
+ * Fire an onSomething type event to all functions in listeners
15253
+ */
15254
+ _fireEvent(listeners, ...args) {
15255
+ for (const listener of listeners) {
15256
+ listener.call(this, ...args);
15257
+ }
15258
+ }
15259
+
15260
+ /**
15261
+ * Combine the array of constraints functions
15262
+ * Returns either an [x, y] coordinate or false
15263
+ */
15264
+ _applyConstraints(current, previous, extraOptions) {
15265
+ let skipRemaining = false;
15266
+ return this.state.constraints.reduce((memo, constraint) => {
15267
+ // A move that has been cancelled won't be propagated to later
15268
+ // constraints calls
15269
+ if (memo === false) {
15270
+ return false;
15271
+ }
15272
+ if (skipRemaining) {
15273
+ return memo;
15274
+ }
15275
+ const result = constraint.call(this, memo, previous, _extends({
15276
+ onSkipRemaining: () => {
15277
+ skipRemaining = true;
15278
+ }
15279
+ }, extraOptions));
15280
+ if (result === false) {
15281
+ // Returning false cancels the move
15282
+ return false;
15283
+ }
15284
+ if (point.is(result, 2)) {
15285
+ // Returning a coord from constraints overrides the move
15286
+ return result;
15287
+ }
15288
+ if (result === true || result == null) {
15289
+ // Returning true or undefined allow the move to occur
15290
+ return memo;
15291
+ }
15292
+ // Anything else is an error
15293
+ throw new PerseusError("Constraint returned invalid result: " + result, Errors.Internal);
15294
+ }, current);
15295
+ }
15296
+
15297
+ /**
15298
+ * Displays a tooltip above the point, replacing any previous contents. If
15299
+ * there is no tooltip initialized, adds the tooltip.
15300
+ *
15301
+ * If the type of contents is string, the contents will be rendered with
15302
+ * KaTeX. Otherwise, the content will be assumed to be a DOM node and will
15303
+ * be appended inside the tooltip.
15304
+ */
15305
+ _showTooltip(contents) {
15306
+ if (!this._tooltip) {
15307
+ this._tooltip = document.createElement("div");
15308
+ this._tooltip.className = "tooltip-content";
15309
+ this.state.visibleShape.wrapper.className = "tooltip";
15310
+ this.state.visibleShape.wrapper.appendChild(this._tooltip);
15311
+
15312
+ // Only one tooltip should be displayed at a time, so store a list
15313
+ // of all the tooltips initialized.
15314
+ tooltipResetFunctions.push(() => {
15315
+ if (this.state.added) {
15316
+ this._hideTooltip();
15317
+ }
15318
+ });
15319
+ }
15320
+ if (this._tooltip.firstChild) {
15321
+ this._tooltip.removeChild(this._tooltip.firstChild);
15322
+ }
15323
+ this.state.visibleShape.wrapper.className = "tooltip visible";
15324
+ this._tooltip.appendChild(document.createElement("span"));
15325
+ if (typeof contents === "string") {
15326
+ // @ts-expect-error - this._tooltip.firstChild is possibly 'null'.
15327
+ processMath(this._tooltip.firstChild, contents, false);
15328
+ } else if (typeof contents === "function") {
15329
+ contents(this._tooltip.firstChild);
15330
+ } else {
15331
+ // @ts-expect-error - this._tooltip.firstChild is possibly 'null'.
15332
+ this._tooltip.firstChild.appendChild(contents);
15333
+ }
15334
+ }
15335
+ _hideTooltip() {
15336
+ if (this._tooltip) {
15337
+ // Without the visible class, tooltips have display: none set
15338
+ this.state.visibleShape.wrapper.className = "tooltip";
15339
+ }
15340
+ }
15341
+ coord() {
15342
+ return this.state.coord;
15343
+ }
15344
+ setCoord(coord) {
15299
15345
  assert$6(point.is(coord, 2));
15300
15346
  this.state.coord = _.clone(coord);
15301
15347
  this.draw();
15302
- },
15303
- setCoordConstrained: function (coord) {
15348
+ }
15349
+ setCoordConstrained(coord) {
15304
15350
  assert$6(point.is(coord, 2));
15305
15351
  const result = this._applyConstraints(coord, this.coord());
15306
15352
  if (result !== false) {
15307
15353
  this.state.coord = _.clone(result);
15308
15354
  this.draw();
15309
15355
  }
15310
- },
15311
- moveTo: function (coord) {
15356
+ }
15357
+
15358
+ /**
15359
+ * Add a listener to any event: startMove, constraints, onMove, onMoveEnd,
15360
+ * etc. If a listener is already bound to the given eventName and id, then
15361
+ * it is overwritten by func.
15362
+ *
15363
+ * eventName: the string name of the event to listen to. one of:
15364
+ * "onMoveStart", "onMove", "onMoveEnd", "draw", "remove"
15365
+ *
15366
+ * id: a string id that can be used to remove this event at a later time
15367
+ * note: adding multiple listeners with the same id is undefined behavior
15368
+ *
15369
+ * func: the function to call when the event happens, which is called
15370
+ * with the event's standard parameters [usually (coord, prevCoord) or
15371
+ * (state, prevState)]
15372
+ */
15373
+ // TODO(benchristel): listen() is duplicated in movable.ts
15374
+ listen(eventName, id, func) {
15375
+ this._listenerMap = this._listenerMap || {};
15376
+
15377
+ // If there's an existing handler, replace it by using its index in
15378
+ // `this.state[eventName]`; otherwise, add this handler to the end
15379
+ const key = getKey(eventName, id);
15380
+ const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
15381
+ this.state[eventName][index] = func;
15382
+ }
15383
+
15384
+ /**
15385
+ * Remove a previously added listener, by the id specified in the
15386
+ * corresponding listen() call
15387
+ *
15388
+ * If the given id has not been registered already, this is a no-op
15389
+ */
15390
+ // TODO(benchristel): I don't think unlisten is used. Delete it?
15391
+ // TODO(benchristel): unlisten is duplicated in movable.ts
15392
+ unlisten(eventName, id) {
15393
+ this._listenerMap = this._listenerMap || {};
15394
+ const key = getKey(eventName, id);
15395
+ const index = this._listenerMap[key];
15396
+ if (index !== undefined) {
15397
+ // Remove handler from list of event handlers and listenerMap
15398
+ this.state[eventName].splice(index, 1);
15399
+ delete this._listenerMap[key];
15400
+
15401
+ // Re-index existing events: if they occur after `index`, decrement
15402
+ const keys = _.keys(this._listenerMap);
15403
+ _.each(keys, key => {
15404
+ if (getEventName(key) === eventName && this._listenerMap[key] > index) {
15405
+ this._listenerMap[key]--;
15406
+ }
15407
+ }, this);
15408
+ }
15409
+ }
15410
+ grab(coord) {
15411
+ // Provide an explicit touchOffset override, so that we track the user's
15412
+ // finger when a point has been grabbed.
15413
+ this.state.touchOffset = [0, 0];
15414
+ this.movable.grab(coord);
15415
+ this.moveTo(coord);
15416
+ }
15417
+ moveTo(coord) {
15312
15418
  // The caller has the option of adding an onMove() method to the
15313
15419
  // movablePoint object we return as a sort of event handler
15314
15420
  // By returning false from onMove(), the move can be vetoed,
@@ -15320,8 +15426,11 @@ _.extend(MovablePoint$5.prototype, {
15320
15426
  const result = this._applyConstraints(coord, state.coord, state.onRemove ? {
15321
15427
  onOutOfBounds: () => {
15322
15428
  this.state.outOfBounds = true;
15323
- }
15324
- } : {});
15429
+ },
15430
+ onSkipRemaining: () => {}
15431
+ } : {
15432
+ onSkipRemaining: () => {}
15433
+ });
15325
15434
  if (result === false) {
15326
15435
  return;
15327
15436
  }
@@ -15335,49 +15444,98 @@ _.extend(MovablePoint$5.prototype, {
15335
15444
  this._fireEvent(state.onMove, state.coord, prevCoord);
15336
15445
  this.draw();
15337
15446
  }
15338
- },
15339
- // Clone these for use with raphael, which modifies the input
15340
- // style parameters
15341
- normalStyle: function () {
15342
- return _.clone(this.state.normalStyle);
15343
- },
15344
- highlightStyle: function () {
15345
- return _.clone(this.state.highlightStyle);
15346
- },
15447
+ }
15448
+ remove() {
15449
+ this.state.added = false;
15450
+ this._fireEvent(this.state.remove);
15451
+ if (this.movable) {
15452
+ this.movable.remove();
15453
+ }
15454
+ // TODO(jack): This should really be moved off of
15455
+ // movablePoint.state and only kept on movable.state
15456
+ this.state.mouseTarget = null;
15457
+ }
15458
+ pointSize() {
15459
+ return this.state.pointSize;
15460
+ }
15461
+ static() {
15462
+ return this.state.static;
15463
+ }
15464
+ cursor() {
15465
+ return this.state.cursor;
15466
+ }
15467
+ normalStyle() {
15468
+ return this.state.normalStyle;
15469
+ }
15470
+ highlightStyle() {
15471
+ return this.state.highlightStyle;
15472
+ }
15473
+ shadow() {
15474
+ return this.state.shadow;
15475
+ }
15476
+ tooltip() {
15477
+ return this.state.tooltip;
15478
+ }
15479
+ added() {
15480
+ return this.state.added;
15481
+ }
15482
+ hasMoved() {
15483
+ return this.state.hasMoved;
15484
+ }
15485
+ visibleShape() {
15486
+ return this.state.visibleShape;
15487
+ }
15488
+ outOfBounds() {
15489
+ return this.state.outOfBounds;
15490
+ }
15491
+ mouseTarget() {
15492
+ return this.state.mouseTarget;
15493
+ }
15494
+ touchOffset() {
15495
+ return this.state.touchOffset;
15496
+ }
15497
+
15498
+ /**
15499
+ * Forwarding methods to this.movable:
15500
+ */
15501
+ isHovering() {
15502
+ return this.movable.isHovering();
15503
+ }
15504
+ isDragging() {
15505
+ return this.movable.isDragging();
15506
+ }
15507
+
15347
15508
  // Change z-order to back
15348
- toBack: function () {
15509
+ toBack() {
15349
15510
  this.movable.toBack();
15350
15511
  if (this.state.visibleShape) {
15351
15512
  this.state.visibleShape.toBack();
15352
15513
  }
15353
- },
15514
+ }
15515
+
15354
15516
  // Change z-order to front
15355
- toFront: function () {
15517
+ toFront() {
15356
15518
  if (this.state.visibleShape) {
15357
15519
  this.state.visibleShape.toFront();
15358
15520
  }
15359
15521
  this.movable.toFront();
15360
- },
15361
- /**
15362
- * Forwarding methods to this.movable:
15363
- */
15364
- isHovering: function () {
15365
- return this.movable.isHovering();
15366
- },
15367
- isDragging: function () {
15368
- return this.movable.isDragging();
15369
- },
15370
- mouseTarget: function () {
15371
- return this.movable.mouseTarget();
15372
- },
15373
- grab: function (coord) {
15374
- // Provide an explicit touchOffset override, so that we track the user's
15375
- // finger when a point has been grabbed.
15376
- this.state.touchOffset = [0, 0];
15377
- this.movable.grab(coord);
15378
- this.moveTo(coord);
15379
15522
  }
15380
- });
15523
+ }
15524
+ MovablePoint$5.add = MovablePointOptions.add;
15525
+ MovablePoint$5.modify = MovablePointOptions.modify;
15526
+ MovablePoint$5.draw = MovablePointOptions.draw;
15527
+ MovablePoint$5.remove = MovablePointOptions.remove;
15528
+ MovablePoint$5.onMoveStart = MovablePointOptions.onMoveStart;
15529
+ MovablePoint$5.constraints = MovablePointOptions.constraints;
15530
+ MovablePoint$5.onMove = MovablePointOptions.onMove;
15531
+ MovablePoint$5.onMoveEnd = MovablePointOptions.onMoveEnd;
15532
+ MovablePoint$5.onClick = MovablePointOptions.onClick;
15533
+ function getKey(eventName, id) {
15534
+ return eventName + ":" + id;
15535
+ }
15536
+ function getEventName(key) {
15537
+ return key.split(":")[0];
15538
+ }
15381
15539
 
15382
15540
  /* eslint-disable @babel/no-invalid-this */
15383
15541
  function sum(array) {
@@ -16318,11 +16476,9 @@ class Graphie extends React.Component {
16318
16476
  });
16319
16477
  // Only add the mouselayer if we actually want one.
16320
16478
  if (this.props.addMouseLayer) {
16321
- // @ts-expect-error - TS2339: Property 'addMouseLayer' does not exist on type 'Graphie'.
16322
16479
  graphie.addMouseLayer({
16323
16480
  onClick: this.props.onClick,
16324
16481
  onMouseDown: this.props.onMouseDown,
16325
- onMouseUp: this.props.onMouseUp,
16326
16482
  onMouseMove: this.props.onMouseMove,
16327
16483
  setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
16328
16484
  });
@@ -26338,11 +26494,7 @@ class FunctionGrapher extends React.Component {
26338
26494
  key: i,
26339
26495
  coord: coord,
26340
26496
  static: this.props.static,
26341
- constraints: [
26342
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
26343
- Interactive2.MovablePoint.constraints.bound(),
26344
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
26345
- Interactive2.MovablePoint.constraints.snap(), coord => {
26497
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
26346
26498
  // Always enforce that this is a function
26347
26499
  const isFunction = _.all(this._coords(), (otherCoord, j) => {
26348
26500
  return i === j || !otherCoord || !number.equal(coord[0], otherCoord[0]);
@@ -27929,22 +28081,20 @@ class Graph extends React.Component {
27929
28081
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
27930
28082
  // eslint-disable-next-line @babel/no-invalid-this
27931
28083
  this.props.onMouseDown(coord);
27932
- }, this) : null;
28084
+ }, this) : undefined;
27933
28085
  const onMouseOver = $instructionsWrapper ? function () {
27934
28086
  $instructionsWrapper && $instructionsWrapper.css("opacity", invisible);
27935
- } : null;
28087
+ } : undefined;
27936
28088
  const onMouseOut = $instructionsWrapper ? function () {
27937
28089
  $instructionsWrapper && $instructionsWrapper.css("opacity", visible);
27938
- } : null;
28090
+ } : undefined;
27939
28091
  /* eslint-enable indent */
27940
28092
 
27941
- // @ts-expect-error - Property 'addMouseLayer' does not exist on type 'Graphie'.
27942
28093
  graphie.addMouseLayer({
27943
28094
  onClick: this.props.onClick,
27944
28095
  onMouseDown: onMouseDown,
27945
28096
  onMouseOver: onMouseOver,
27946
28097
  onMouseOut: onMouseOut,
27947
- onMouseUp: this.props.onMouseUp,
27948
28098
  onMouseMove: this.props.onMouseMove,
27949
28099
  allowScratchpad: true,
27950
28100
  setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
@@ -28299,11 +28449,7 @@ class InteractiveGraph extends React.Component {
28299
28449
  const points = self.points = _.map(coords, coord => {
28300
28450
  return Interactive2.addMaybeMobileMovablePoint(this, {
28301
28451
  coord: coord,
28302
- constraints: [
28303
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28304
- Interactive2.MovablePoint.constraints.bound(),
28305
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28306
- Interactive2.MovablePoint.constraints.snap()],
28452
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap()],
28307
28453
  onMove: () => {
28308
28454
  const graph = _.extend({}, self.props.graph, {
28309
28455
  coords: _.invoke(points, "coord")
@@ -28374,11 +28520,7 @@ class InteractiveGraph extends React.Component {
28374
28520
  let pointA = null;
28375
28521
  pointA = this.pointA = Interactive2.addMaybeMobileMovablePoint(this, {
28376
28522
  coord: coords[0],
28377
- constraints: [
28378
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28379
- Interactive2.MovablePoint.constraints.bound(),
28380
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28381
- Interactive2.MovablePoint.constraints.snap(), coord => {
28523
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28382
28524
  return !pointA ||
28383
28525
  // @ts-expect-error - TS2531 - Object is possibly 'null'.
28384
28526
  coord[0] !== pointB.coord()[0] &&
@@ -28394,11 +28536,7 @@ class InteractiveGraph extends React.Component {
28394
28536
  let pointB = null;
28395
28537
  pointB = this.pointB = Interactive2.addMaybeMobileMovablePoint(this, {
28396
28538
  coord: coords[1],
28397
- constraints: [
28398
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28399
- Interactive2.MovablePoint.constraints.bound(),
28400
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28401
- Interactive2.MovablePoint.constraints.snap(), coord => {
28539
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28402
28540
  return !pointB ||
28403
28541
  // @ts-expect-error - TS2531 - Object is possibly 'null'.
28404
28542
  coord[0] !== pointA.coord()[0] &&
@@ -28414,11 +28552,7 @@ class InteractiveGraph extends React.Component {
28414
28552
  let pointC = null;
28415
28553
  pointC = this.pointC = Interactive2.addMaybeMobileMovablePoint(this, {
28416
28554
  coord: coords[2],
28417
- constraints: [
28418
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28419
- Interactive2.MovablePoint.constraints.bound(),
28420
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28421
- Interactive2.MovablePoint.constraints.snap(), coord => {
28555
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28422
28556
  return !pointC ||
28423
28557
  // @ts-expect-error - TS2531 - Object is possibly 'null'.
28424
28558
  coord[0] !== pointA.coord()[0] &&
@@ -28491,22 +28625,14 @@ class InteractiveGraph extends React.Component {
28491
28625
  let pointA = null;
28492
28626
  pointA = this.pointA = Interactive2.addMaybeMobileMovablePoint(this, {
28493
28627
  coord: coords[0],
28494
- constraints: [
28495
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28496
- Interactive2.MovablePoint.constraints.bound(),
28497
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28498
- Interactive2.MovablePoint.constraints.snap(), coord => {
28628
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28499
28629
  return !pointA || coord[0] !== pointB.coord()[0];
28500
28630
  }],
28501
28631
  onMove: onMoveHandler
28502
28632
  });
28503
28633
  const pointB = this.pointB = Interactive2.addMaybeMobileMovablePoint(this, {
28504
28634
  coord: coords[1],
28505
- constraints: [
28506
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28507
- Interactive2.MovablePoint.constraints.bound(),
28508
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28509
- Interactive2.MovablePoint.constraints.snap(), coord => {
28635
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28510
28636
  // @ts-expect-error - TS2339 - Property 'coord' does not exist on type 'never'.
28511
28637
  return !pointA || coord[0] !== pointA.coord()[0];
28512
28638
  }],
@@ -28590,11 +28716,7 @@ class InteractiveGraph extends React.Component {
28590
28716
  const coord = segmentCoords[i];
28591
28717
  segmentPoints.push(Interactive2.addMaybeMobileMovablePoint(this, {
28592
28718
  coord: coord,
28593
- constraints: [
28594
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28595
- Interactive2.MovablePoint.constraints.bound(),
28596
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28597
- Interactive2.MovablePoint.constraints.snap(), coord => {
28719
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28598
28720
  const otherSegment = segmentPoints[1 - i];
28599
28721
  if (!otherSegment) {
28600
28722
  // segment hasn't been defined yet
@@ -28669,11 +28791,7 @@ class InteractiveGraph extends React.Component {
28669
28791
  let point$1 = null;
28670
28792
  point$1 = Interactive2.addMaybeMobileMovablePoint(this, _extends({
28671
28793
  coord: coord,
28672
- constraints: [
28673
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28674
- Interactive2.MovablePoint.constraints.bound(),
28675
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28676
- Interactive2.MovablePoint.constraints.snap(), function (coord) {
28794
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), function (coord) {
28677
28795
  // TODO(jack): There ought to be a
28678
28796
  // MovablePoint.constraints.avoid
28679
28797
  // default that lets you do things like this
@@ -28957,11 +29075,7 @@ class InteractiveGraph extends React.Component {
28957
29075
  };
28958
29076
  const point$1 = Interactive2.addMaybeMobileMovablePoint(this, _extends({
28959
29077
  coord: coord,
28960
- constraints: [
28961
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28962
- Interactive2.MovablePoint.constraints.bound(), snapToGrid ?
28963
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28964
- Interactive2.MovablePoint.constraints.snap() : null, graphConstraint],
29078
+ constraints: [Interactive2.MovablePoint.constraints.bound(), snapToGrid ? Interactive2.MovablePoint.constraints.snap() : null, graphConstraint],
28965
29079
  onMoveStart: () => {
28966
29080
  if (this.isClickToAddPoints()) {
28967
29081
  this.setTrashCanVisibility(1);
@@ -29053,11 +29167,7 @@ class InteractiveGraph extends React.Component {
29053
29167
  const coord = segment[_i];
29054
29168
  points.push(createPoint({
29055
29169
  coord: coord,
29056
- constraints: [
29057
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
29058
- Interactive2.MovablePoint.constraints.bound(),
29059
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
29060
- Interactive2.MovablePoint.constraints.snap(), coord => {
29170
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
29061
29171
  const otherPoint = points[1 - _i];
29062
29172
  if (!otherPoint) {
29063
29173
  // point hasn't been defined yet
@@ -33792,7 +33902,6 @@ const Measurer = createReactClass({
33792
33902
  range: range,
33793
33903
  scale: scale
33794
33904
  });
33795
- // @ts-expect-error - Property 'addMouseLayer' does not exist on type 'Graphie'.
33796
33905
  graphie.addMouseLayer({
33797
33906
  allowScratchpad: true,
33798
33907
  setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
@@ -38301,7 +38410,6 @@ class Plotter extends React.Component {
38301
38410
  scale: c.scale,
38302
38411
  isMobile: this.props.apiOptions.isMobile
38303
38412
  });
38304
- // @ts-expect-error - Property 'addMouseLayer' does not exist on type 'Graphie'.
38305
38413
  graphie.addMouseLayer({
38306
38414
  allowScratchpad: true,
38307
38415
  setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
@@ -38710,7 +38818,6 @@ class Plotter extends React.Component {
38710
38818
  if (i > 0) {
38711
38819
  c.graph.lines[i] = Interactive2.addMovableLine(graphie, {
38712
38820
  points: [c.graph.points[i - 1], c.graph.points[i]],
38713
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
38714
38821
  constraints: Interactive2.MovablePoint.constraints.fixed(),
38715
38822
  normalStyle: {
38716
38823
  stroke: KhanColors.BLUE_C,
@@ -41600,7 +41707,7 @@ const init = function init(options) {
41600
41707
 
41601
41708
  // This file is processed by a Rollup plugin (replace) to inject the production
41602
41709
  const libName = "@khanacademy/perseus";
41603
- const libVersion = "19.1.6";
41710
+ const libVersion = "19.1.7";
41604
41711
  addLibraryVersionToPerseusDebug(libName, libVersion);
41605
41712
 
41606
41713
  const apiVersion = {