@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/index.js CHANGED
@@ -284,7 +284,11 @@ class MathInput extends React__namespace.Component {
284
284
  display: "flex",
285
285
  padding: 1
286
286
  },
287
- onClick: () => {
287
+ onClick: e => {
288
+ // Prevent the click into the input from registering
289
+ // so that the keypad popover doesn't close when
290
+ // switching focus to the input.
291
+ e.stopPropagation();
288
292
  const mathField = this.mathField();
289
293
  if (!mathField) {
290
294
  return;
@@ -3999,10 +4003,10 @@ class FixedToResponsive extends React__namespace.Component {
3999
4003
 
4000
4004
  /* Local helper methods. */
4001
4005
 
4002
- function getKey$1(eventName, id) {
4006
+ function getKey$2(eventName, id) {
4003
4007
  return eventName + ":" + id;
4004
4008
  }
4005
- function getEventName$1(key) {
4009
+ function getEventName$2(key) {
4006
4010
  return key.split(":")[0];
4007
4011
  }
4008
4012
  const MovableHelperMethods = {
@@ -4083,7 +4087,7 @@ const MovableHelperMethods = {
4083
4087
 
4084
4088
  // If there's an existing handler, replace it by using its index in
4085
4089
  // `this.state[eventName]`; otherwise, add this handler to the end
4086
- const key = getKey$1(eventName, id);
4090
+ const key = getKey$2(eventName, id);
4087
4091
  const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
4088
4092
  this.state[eventName][index] = func;
4089
4093
  },
@@ -4095,7 +4099,7 @@ const MovableHelperMethods = {
4095
4099
  */
4096
4100
  unlisten: function (eventName, id) {
4097
4101
  this._listenerMap = this._listenerMap || {};
4098
- const key = getKey$1(eventName, id);
4102
+ const key = getKey$2(eventName, id);
4099
4103
  const index = this._listenerMap[key];
4100
4104
  if (index !== undefined) {
4101
4105
  // Remove handler from list of event handlers and listenerMap
@@ -4105,7 +4109,7 @@ const MovableHelperMethods = {
4105
4109
  // Re-index existing events: if they occur after `index`, decrement
4106
4110
  const keys = ___default["default"].keys(this._listenerMap);
4107
4111
  ___default["default"].each(keys, function (key) {
4108
- if (getEventName$1(key) === eventName &&
4112
+ if (getEventName$2(key) === eventName &&
4109
4113
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
4110
4114
  this._listenerMap[key] > index) {
4111
4115
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
@@ -9546,6 +9550,9 @@ class Graphie$1 {
9546
9550
  getMouseCoord(event) {
9547
9551
  throw new Error("getMouseCoord is a stub, and is not implemented");
9548
9552
  }
9553
+
9554
+ // This is a stub that's overridden in interactive.ts
9555
+ addMouseLayer(options) {}
9549
9556
  }
9550
9557
  const labelDirections = {
9551
9558
  center: [-0.5, -0.5],
@@ -14019,7 +14026,7 @@ class Movable {
14019
14026
 
14020
14027
  // If there's an existing handler, replace it by using its index in
14021
14028
  // `this.state[eventName]`; otherwise, add this handler to the end
14022
- const key = getKey(eventName, id);
14029
+ const key = getKey$1(eventName, id);
14023
14030
  const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
14024
14031
  this.state[eventName][index] = func;
14025
14032
  }
@@ -14032,7 +14039,7 @@ class Movable {
14032
14039
  */
14033
14040
  unlisten(eventName, id) {
14034
14041
  this._listenerMap = this._listenerMap || {};
14035
- const key = getKey(eventName, id);
14042
+ const key = getKey$1(eventName, id);
14036
14043
  const index = this._listenerMap[key];
14037
14044
  if (index !== undefined) {
14038
14045
  // Remove handler from list of event handlers and listenerMap
@@ -14042,7 +14049,7 @@ class Movable {
14042
14049
  // Re-index existing events: if they occur after `index`, decrement
14043
14050
  const keys = ___default["default"].keys(this._listenerMap);
14044
14051
  keys.forEach(key => {
14045
- if (getEventName(key) === eventName && this._listenerMap[key] > index) {
14052
+ if (getEventName$1(key) === eventName && this._listenerMap[key] > index) {
14046
14053
  this._listenerMap[key]--;
14047
14054
  }
14048
14055
  });
@@ -14076,10 +14083,10 @@ class Movable {
14076
14083
  return this.state.mouseTarget;
14077
14084
  }
14078
14085
  }
14079
- function getKey(eventName, id) {
14086
+ function getKey$1(eventName, id) {
14080
14087
  return eventName + ":" + id;
14081
14088
  }
14082
- function getEventName(key) {
14089
+ function getEventName$1(key) {
14083
14090
  return key.split(":")[0];
14084
14091
  }
14085
14092
 
@@ -15032,103 +15039,53 @@ const DEFAULT_STATE$1 = {
15032
15039
  mouseTarget: null,
15033
15040
  touchOffset: null
15034
15041
  };
15042
+ // TODO(benchristel): this is a memory leak. We add items to
15043
+ // tooltipResetFunctions, but never remove them.
15035
15044
  const tooltipResetFunctions = [];
15036
- const MovablePoint$5 = function (graphie, movable, options) {
15037
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
15038
- ___default["default"].extend(this, {
15039
- graphie,
15040
- movable,
15041
- state: {
15042
- // Set here because this must be unique for each instance
15043
- id: ___default["default"].uniqueId("movablePoint")
15044
- }
15045
- });
15046
-
15047
- // We only set DEFAULT_STATE once, here
15048
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
15049
- this.modify(___default["default"].extend({}, DEFAULT_STATE$1, options));
15050
- };
15051
- ___default["default"].extend(MovablePoint$5, MovablePointOptions);
15052
- InteractiveUtil.createGettersFor(MovablePoint$5, ___default["default"].extend({}, DEFAULT_PROPS$1, DEFAULT_STATE$1));
15053
- InteractiveUtil.addMovableHelperMethodsTo(MovablePoint$5);
15054
- ___default["default"].extend(MovablePoint$5.prototype, {
15055
- cloneState: function () {
15056
- return ___default["default"].extend(this.movable.cloneState(), this.state);
15057
- },
15058
- _createDefaultState: function () {
15059
- return ___default["default"].extend({
15060
- id: this.state.id
15061
- }, normalizeOptions$1(
15062
- // Defaults are copied from MovablePointOptions.*.standard
15063
- // These defaults are set here instead of DEFAULT_PROPS/STATE
15064
- // because they:
15065
- // - are objects, not primitives (and need a deeper copy)
15066
- // - they don't need getters created for them
15067
- // TODO(jack): Consider "default" once we es3ify perseus
15068
- objective_.pluck(MovablePointOptions, "standard")
15045
+ class MovablePoint$5 {
15046
+ // @ts-expect-error - TS2564: Property 'prevState' has no initializer and is not definitely assigned in the constructor.
15069
15047
 
15070
- // We only update props here, because we want things on state to
15071
- // be persistent, and updated appropriately in modify()
15072
- ), DEFAULT_PROPS$1);
15073
- },
15074
- /**
15075
- * Resets the object to its state as if it were constructed with
15076
- * `options` originally. state not on DEFAULT_PROPS is maintained.
15077
- *
15078
- * Analogous to React.js's replaceProps
15079
- */
15080
- modify: function (options) {
15048
+ _listenerMap = {};
15049
+ constructor(graphie, movable, options) {
15050
+ this.graphie = graphie;
15051
+ this.movable = movable;
15052
+ // @ts-expect-error - TS2740: Type '{ id: string; }' is missing the following properties from type 'State': add, added, constraints, coord, and 19 more.
15053
+ this.state = {
15054
+ id: ___default["default"].uniqueId("movablePoint")
15055
+ };
15056
+ this.modify({
15057
+ ...DEFAULT_STATE$1,
15058
+ ...options
15059
+ });
15060
+ }
15061
+ modify(options) {
15081
15062
  this.update(___default["default"].extend(this._createDefaultState(), options));
15082
- },
15083
- /**
15084
- * Displays a tooltip above the point, replacing any previous contents. If
15085
- * there is no tooltip initialized, adds the tooltip.
15086
- *
15087
- * If the type of contents is string, the contents will be rendered with
15088
- * KaTeX. Otherwise, the content will be assumed to be a DOM node and will
15089
- * be appended inside the tooltip.
15090
- */
15091
- _showTooltip: function (contents) {
15092
- if (!this._tooltip) {
15093
- this._tooltip = document.createElement("div");
15094
- this._tooltip.className = "tooltip-content";
15095
- this.state.visibleShape.wrapper.className = "tooltip";
15096
- this.state.visibleShape.wrapper.appendChild(this._tooltip);
15063
+ }
15064
+ _createDefaultState() {
15065
+ return {
15066
+ id: this.state.id,
15067
+ ...normalizeOptions$1(
15068
+ // Defaults are copied from MovablePointOptions.*.standard
15069
+ // These defaults are set here instead of DEFAULT_PROPS/STATE
15070
+ // because they:
15071
+ // - are objects, not primitives (and need a deeper copy)
15072
+ // - they don't need getters created for them
15073
+ // TODO(jack): Consider "default" once we es3ify perseus
15074
+ objective_.pluck(MovablePointOptions, "standard")
15075
+ // We only update props here, because we want things on state to
15076
+ // be persistent, and updated appropriately in modify()
15077
+ ),
15097
15078
 
15098
- // Only one tooltip should be displayed at a time, so store a list
15099
- // of all the tooltips initialized.
15100
- tooltipResetFunctions.push(() => {
15101
- if (this.state.added) {
15102
- this._hideTooltip();
15103
- }
15104
- });
15105
- }
15106
- if (this._tooltip.firstChild) {
15107
- this._tooltip.removeChild(this._tooltip.firstChild);
15108
- }
15109
- this.state.visibleShape.wrapper.className = "tooltip visible";
15110
- this._tooltip.appendChild(document.createElement("span"));
15111
- if (typeof contents === "string") {
15112
- processMath(this._tooltip.firstChild, contents, false);
15113
- } else if (typeof contents === "function") {
15114
- contents(this._tooltip.firstChild);
15115
- } else {
15116
- this._tooltip.firstChild.appendChild(contents);
15117
- }
15118
- },
15119
- _hideTooltip: function () {
15120
- if (this._tooltip) {
15121
- // Without the visible class, tooltips have display: none set
15122
- this.state.visibleShape.wrapper.className = "tooltip";
15123
- }
15124
- },
15125
- /**
15126
- * Adjusts constructor parameters without changing previous settings
15127
- * for any option not specified
15128
- *
15129
- * Analogous to React.js's setProps
15130
- */
15131
- update: function (options) {
15079
+ ...DEFAULT_PROPS$1
15080
+ };
15081
+ }
15082
+ cloneState() {
15083
+ return {
15084
+ ...this.movable.cloneState(),
15085
+ ...this.state
15086
+ };
15087
+ }
15088
+ update(options) {
15132
15089
  const self = this;
15133
15090
  const graphie = self.graphie;
15134
15091
  const state = ___default["default"].extend(self.state, normalizeOptions$1(options));
@@ -15278,11 +15235,15 @@ ___default["default"].extend(MovablePoint$5.prototype, {
15278
15235
  showTrashTooltip();
15279
15236
  const content = svgElem.getElementsByClassName("tooltip-content")[0];
15280
15237
  content.style.filter = "none";
15238
+
15239
+ // @ts-expect-error - this._tooltip.firstChild is possibly null
15281
15240
  this._tooltip.firstChild.addEventListener("touchstart", e => {
15282
15241
  // Prevent creation of a new point when the event is
15283
15242
  // propagated up the DOM.
15284
15243
  e.stopPropagation();
15285
15244
  }, true);
15245
+
15246
+ // @ts-expect-error - this._tooltip.firstChild is possibly null
15286
15247
  this._tooltip.firstChild.addEventListener("touchend", e => {
15287
15248
  // Remove the point and prevent creation of a
15288
15249
  // new point.
@@ -15304,6 +15265,7 @@ ___default["default"].extend(MovablePoint$5.prototype, {
15304
15265
 
15305
15266
  // Trigger an add event if this hasn't been added before
15306
15267
  if (!state.added) {
15268
+ // @ts-expect-error - type {} is missing properties from State
15307
15269
  self.prevState = {};
15308
15270
  self._fireEvent(state.add, self.cloneState(), self.prevState);
15309
15271
  state.added = true;
@@ -15315,38 +15277,191 @@ ___default["default"].extend(MovablePoint$5.prototype, {
15315
15277
 
15316
15278
  // Trigger a modify event
15317
15279
  self._fireEvent(state.modify, self.cloneState(), self.prevState);
15318
- },
15319
- remove: function () {
15320
- this.state.added = false;
15321
- this._fireEvent(this.state.remove);
15322
- if (this.movable) {
15323
- this.movable.remove();
15324
- }
15325
- // TODO(jack): This should really be moved off of
15326
- // movablePoint.state and only kept on movable.state
15327
- this.state.mouseTarget = null;
15328
- },
15329
- constrain: function () {
15280
+ }
15281
+ draw() {
15282
+ const currState = this.cloneState();
15283
+ this._fireEvent(this.state.draw, currState, this.prevState);
15284
+ this.prevState = currState;
15285
+ }
15286
+ constrain() {
15330
15287
  const result = this._applyConstraints(this.coord(), this.coord());
15331
15288
  if (kmath.point.is(result)) {
15332
15289
  this.setCoord(result);
15333
15290
  }
15334
15291
  return result !== false;
15335
- },
15336
- setCoord: function (coord) {
15292
+ }
15293
+
15294
+ /**
15295
+ * Fire an onSomething type event to all functions in listeners
15296
+ */
15297
+ _fireEvent(listeners) {
15298
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
15299
+ args[_key - 1] = arguments[_key];
15300
+ }
15301
+ for (const listener of listeners) {
15302
+ listener.call(this, ...args);
15303
+ }
15304
+ }
15305
+
15306
+ /**
15307
+ * Combine the array of constraints functions
15308
+ * Returns either an [x, y] coordinate or false
15309
+ */
15310
+ _applyConstraints(current, previous, extraOptions) {
15311
+ let skipRemaining = false;
15312
+ return this.state.constraints.reduce((memo, constraint) => {
15313
+ // A move that has been cancelled won't be propagated to later
15314
+ // constraints calls
15315
+ if (memo === false) {
15316
+ return false;
15317
+ }
15318
+ if (skipRemaining) {
15319
+ return memo;
15320
+ }
15321
+ const result = constraint.call(this, memo, previous, {
15322
+ onSkipRemaining: () => {
15323
+ skipRemaining = true;
15324
+ },
15325
+ ...extraOptions
15326
+ });
15327
+ if (result === false) {
15328
+ // Returning false cancels the move
15329
+ return false;
15330
+ }
15331
+ if (kmath.point.is(result, 2)) {
15332
+ // Returning a coord from constraints overrides the move
15333
+ return result;
15334
+ }
15335
+ if (result === true || result == null) {
15336
+ // Returning true or undefined allow the move to occur
15337
+ return memo;
15338
+ }
15339
+ // Anything else is an error
15340
+ throw new PerseusError("Constraint returned invalid result: " + result, Errors.Internal);
15341
+ }, current);
15342
+ }
15343
+
15344
+ /**
15345
+ * Displays a tooltip above the point, replacing any previous contents. If
15346
+ * there is no tooltip initialized, adds the tooltip.
15347
+ *
15348
+ * If the type of contents is string, the contents will be rendered with
15349
+ * KaTeX. Otherwise, the content will be assumed to be a DOM node and will
15350
+ * be appended inside the tooltip.
15351
+ */
15352
+ _showTooltip(contents) {
15353
+ if (!this._tooltip) {
15354
+ this._tooltip = document.createElement("div");
15355
+ this._tooltip.className = "tooltip-content";
15356
+ this.state.visibleShape.wrapper.className = "tooltip";
15357
+ this.state.visibleShape.wrapper.appendChild(this._tooltip);
15358
+
15359
+ // Only one tooltip should be displayed at a time, so store a list
15360
+ // of all the tooltips initialized.
15361
+ tooltipResetFunctions.push(() => {
15362
+ if (this.state.added) {
15363
+ this._hideTooltip();
15364
+ }
15365
+ });
15366
+ }
15367
+ if (this._tooltip.firstChild) {
15368
+ this._tooltip.removeChild(this._tooltip.firstChild);
15369
+ }
15370
+ this.state.visibleShape.wrapper.className = "tooltip visible";
15371
+ this._tooltip.appendChild(document.createElement("span"));
15372
+ if (typeof contents === "string") {
15373
+ // @ts-expect-error - this._tooltip.firstChild is possibly 'null'.
15374
+ processMath(this._tooltip.firstChild, contents, false);
15375
+ } else if (typeof contents === "function") {
15376
+ contents(this._tooltip.firstChild);
15377
+ } else {
15378
+ // @ts-expect-error - this._tooltip.firstChild is possibly 'null'.
15379
+ this._tooltip.firstChild.appendChild(contents);
15380
+ }
15381
+ }
15382
+ _hideTooltip() {
15383
+ if (this._tooltip) {
15384
+ // Without the visible class, tooltips have display: none set
15385
+ this.state.visibleShape.wrapper.className = "tooltip";
15386
+ }
15387
+ }
15388
+ coord() {
15389
+ return this.state.coord;
15390
+ }
15391
+ setCoord(coord) {
15337
15392
  assert$6(kmath.point.is(coord, 2));
15338
15393
  this.state.coord = ___default["default"].clone(coord);
15339
15394
  this.draw();
15340
- },
15341
- setCoordConstrained: function (coord) {
15395
+ }
15396
+ setCoordConstrained(coord) {
15342
15397
  assert$6(kmath.point.is(coord, 2));
15343
15398
  const result = this._applyConstraints(coord, this.coord());
15344
15399
  if (result !== false) {
15345
15400
  this.state.coord = ___default["default"].clone(result);
15346
15401
  this.draw();
15347
15402
  }
15348
- },
15349
- moveTo: function (coord) {
15403
+ }
15404
+
15405
+ /**
15406
+ * Add a listener to any event: startMove, constraints, onMove, onMoveEnd,
15407
+ * etc. If a listener is already bound to the given eventName and id, then
15408
+ * it is overwritten by func.
15409
+ *
15410
+ * eventName: the string name of the event to listen to. one of:
15411
+ * "onMoveStart", "onMove", "onMoveEnd", "draw", "remove"
15412
+ *
15413
+ * id: a string id that can be used to remove this event at a later time
15414
+ * note: adding multiple listeners with the same id is undefined behavior
15415
+ *
15416
+ * func: the function to call when the event happens, which is called
15417
+ * with the event's standard parameters [usually (coord, prevCoord) or
15418
+ * (state, prevState)]
15419
+ */
15420
+ // TODO(benchristel): listen() is duplicated in movable.ts
15421
+ listen(eventName, id, func) {
15422
+ this._listenerMap = this._listenerMap || {};
15423
+
15424
+ // If there's an existing handler, replace it by using its index in
15425
+ // `this.state[eventName]`; otherwise, add this handler to the end
15426
+ const key = getKey(eventName, id);
15427
+ const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
15428
+ this.state[eventName][index] = func;
15429
+ }
15430
+
15431
+ /**
15432
+ * Remove a previously added listener, by the id specified in the
15433
+ * corresponding listen() call
15434
+ *
15435
+ * If the given id has not been registered already, this is a no-op
15436
+ */
15437
+ // TODO(benchristel): I don't think unlisten is used. Delete it?
15438
+ // TODO(benchristel): unlisten is duplicated in movable.ts
15439
+ unlisten(eventName, id) {
15440
+ this._listenerMap = this._listenerMap || {};
15441
+ const key = getKey(eventName, id);
15442
+ const index = this._listenerMap[key];
15443
+ if (index !== undefined) {
15444
+ // Remove handler from list of event handlers and listenerMap
15445
+ this.state[eventName].splice(index, 1);
15446
+ delete this._listenerMap[key];
15447
+
15448
+ // Re-index existing events: if they occur after `index`, decrement
15449
+ const keys = ___default["default"].keys(this._listenerMap);
15450
+ ___default["default"].each(keys, key => {
15451
+ if (getEventName(key) === eventName && this._listenerMap[key] > index) {
15452
+ this._listenerMap[key]--;
15453
+ }
15454
+ }, this);
15455
+ }
15456
+ }
15457
+ grab(coord) {
15458
+ // Provide an explicit touchOffset override, so that we track the user's
15459
+ // finger when a point has been grabbed.
15460
+ this.state.touchOffset = [0, 0];
15461
+ this.movable.grab(coord);
15462
+ this.moveTo(coord);
15463
+ }
15464
+ moveTo(coord) {
15350
15465
  // The caller has the option of adding an onMove() method to the
15351
15466
  // movablePoint object we return as a sort of event handler
15352
15467
  // By returning false from onMove(), the move can be vetoed,
@@ -15358,8 +15473,11 @@ ___default["default"].extend(MovablePoint$5.prototype, {
15358
15473
  const result = this._applyConstraints(coord, state.coord, state.onRemove ? {
15359
15474
  onOutOfBounds: () => {
15360
15475
  this.state.outOfBounds = true;
15361
- }
15362
- } : {});
15476
+ },
15477
+ onSkipRemaining: () => {}
15478
+ } : {
15479
+ onSkipRemaining: () => {}
15480
+ });
15363
15481
  if (result === false) {
15364
15482
  return;
15365
15483
  }
@@ -15373,49 +15491,98 @@ ___default["default"].extend(MovablePoint$5.prototype, {
15373
15491
  this._fireEvent(state.onMove, state.coord, prevCoord);
15374
15492
  this.draw();
15375
15493
  }
15376
- },
15377
- // Clone these for use with raphael, which modifies the input
15378
- // style parameters
15379
- normalStyle: function () {
15380
- return ___default["default"].clone(this.state.normalStyle);
15381
- },
15382
- highlightStyle: function () {
15383
- return ___default["default"].clone(this.state.highlightStyle);
15384
- },
15494
+ }
15495
+ remove() {
15496
+ this.state.added = false;
15497
+ this._fireEvent(this.state.remove);
15498
+ if (this.movable) {
15499
+ this.movable.remove();
15500
+ }
15501
+ // TODO(jack): This should really be moved off of
15502
+ // movablePoint.state and only kept on movable.state
15503
+ this.state.mouseTarget = null;
15504
+ }
15505
+ pointSize() {
15506
+ return this.state.pointSize;
15507
+ }
15508
+ static() {
15509
+ return this.state.static;
15510
+ }
15511
+ cursor() {
15512
+ return this.state.cursor;
15513
+ }
15514
+ normalStyle() {
15515
+ return this.state.normalStyle;
15516
+ }
15517
+ highlightStyle() {
15518
+ return this.state.highlightStyle;
15519
+ }
15520
+ shadow() {
15521
+ return this.state.shadow;
15522
+ }
15523
+ tooltip() {
15524
+ return this.state.tooltip;
15525
+ }
15526
+ added() {
15527
+ return this.state.added;
15528
+ }
15529
+ hasMoved() {
15530
+ return this.state.hasMoved;
15531
+ }
15532
+ visibleShape() {
15533
+ return this.state.visibleShape;
15534
+ }
15535
+ outOfBounds() {
15536
+ return this.state.outOfBounds;
15537
+ }
15538
+ mouseTarget() {
15539
+ return this.state.mouseTarget;
15540
+ }
15541
+ touchOffset() {
15542
+ return this.state.touchOffset;
15543
+ }
15544
+
15545
+ /**
15546
+ * Forwarding methods to this.movable:
15547
+ */
15548
+ isHovering() {
15549
+ return this.movable.isHovering();
15550
+ }
15551
+ isDragging() {
15552
+ return this.movable.isDragging();
15553
+ }
15554
+
15385
15555
  // Change z-order to back
15386
- toBack: function () {
15556
+ toBack() {
15387
15557
  this.movable.toBack();
15388
15558
  if (this.state.visibleShape) {
15389
15559
  this.state.visibleShape.toBack();
15390
15560
  }
15391
- },
15561
+ }
15562
+
15392
15563
  // Change z-order to front
15393
- toFront: function () {
15564
+ toFront() {
15394
15565
  if (this.state.visibleShape) {
15395
15566
  this.state.visibleShape.toFront();
15396
15567
  }
15397
15568
  this.movable.toFront();
15398
- },
15399
- /**
15400
- * Forwarding methods to this.movable:
15401
- */
15402
- isHovering: function () {
15403
- return this.movable.isHovering();
15404
- },
15405
- isDragging: function () {
15406
- return this.movable.isDragging();
15407
- },
15408
- mouseTarget: function () {
15409
- return this.movable.mouseTarget();
15410
- },
15411
- grab: function (coord) {
15412
- // Provide an explicit touchOffset override, so that we track the user's
15413
- // finger when a point has been grabbed.
15414
- this.state.touchOffset = [0, 0];
15415
- this.movable.grab(coord);
15416
- this.moveTo(coord);
15417
15569
  }
15418
- });
15570
+ static add = MovablePointOptions.add;
15571
+ static modify = MovablePointOptions.modify;
15572
+ static draw = MovablePointOptions.draw;
15573
+ static remove = MovablePointOptions.remove;
15574
+ static onMoveStart = MovablePointOptions.onMoveStart;
15575
+ static constraints = MovablePointOptions.constraints;
15576
+ static onMove = MovablePointOptions.onMove;
15577
+ static onMoveEnd = MovablePointOptions.onMoveEnd;
15578
+ static onClick = MovablePointOptions.onClick;
15579
+ }
15580
+ function getKey(eventName, id) {
15581
+ return eventName + ":" + id;
15582
+ }
15583
+ function getEventName(key) {
15584
+ return key.split(":")[0];
15585
+ }
15419
15586
 
15420
15587
  /* eslint-disable @babel/no-invalid-this */
15421
15588
  function sum(array) {
@@ -16391,11 +16558,9 @@ class Graphie extends React__namespace.Component {
16391
16558
  });
16392
16559
  // Only add the mouselayer if we actually want one.
16393
16560
  if (this.props.addMouseLayer) {
16394
- // @ts-expect-error - TS2339: Property 'addMouseLayer' does not exist on type 'Graphie'.
16395
16561
  graphie.addMouseLayer({
16396
16562
  onClick: this.props.onClick,
16397
16563
  onMouseDown: this.props.onMouseDown,
16398
- onMouseUp: this.props.onMouseUp,
16399
16564
  onMouseMove: this.props.onMouseMove,
16400
16565
  setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
16401
16566
  });
@@ -26430,11 +26595,7 @@ class FunctionGrapher extends React__namespace.Component {
26430
26595
  key: i,
26431
26596
  coord: coord,
26432
26597
  static: this.props.static,
26433
- constraints: [
26434
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
26435
- Interactive2.MovablePoint.constraints.bound(),
26436
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
26437
- Interactive2.MovablePoint.constraints.snap(), coord => {
26598
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
26438
26599
  // Always enforce that this is a function
26439
26600
  const isFunction = ___default["default"].all(this._coords(), (otherCoord, j) => {
26440
26601
  return i === j || !otherCoord || !kmath.number.equal(coord[0], otherCoord[0]);
@@ -28122,22 +28283,20 @@ class Graph extends React__namespace.Component {
28122
28283
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
28123
28284
  // eslint-disable-next-line @babel/no-invalid-this
28124
28285
  this.props.onMouseDown(coord);
28125
- }, this) : null;
28286
+ }, this) : undefined;
28126
28287
  const onMouseOver = $instructionsWrapper ? function () {
28127
28288
  $instructionsWrapper && $instructionsWrapper.css("opacity", invisible);
28128
- } : null;
28289
+ } : undefined;
28129
28290
  const onMouseOut = $instructionsWrapper ? function () {
28130
28291
  $instructionsWrapper && $instructionsWrapper.css("opacity", visible);
28131
- } : null;
28292
+ } : undefined;
28132
28293
  /* eslint-enable indent */
28133
28294
 
28134
- // @ts-expect-error - Property 'addMouseLayer' does not exist on type 'Graphie'.
28135
28295
  graphie.addMouseLayer({
28136
28296
  onClick: this.props.onClick,
28137
28297
  onMouseDown: onMouseDown,
28138
28298
  onMouseOver: onMouseOver,
28139
28299
  onMouseOut: onMouseOut,
28140
- onMouseUp: this.props.onMouseUp,
28141
28300
  onMouseMove: this.props.onMouseMove,
28142
28301
  allowScratchpad: true,
28143
28302
  setDrawingAreaAvailable: this.props.setDrawingAreaAvailable
@@ -28500,11 +28659,7 @@ class InteractiveGraph extends React__namespace.Component {
28500
28659
  const points = self.points = ___default["default"].map(coords, coord => {
28501
28660
  return Interactive2.addMaybeMobileMovablePoint(this, {
28502
28661
  coord: coord,
28503
- constraints: [
28504
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28505
- Interactive2.MovablePoint.constraints.bound(),
28506
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28507
- Interactive2.MovablePoint.constraints.snap()],
28662
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap()],
28508
28663
  onMove: () => {
28509
28664
  const graph = ___default["default"].extend({}, self.props.graph, {
28510
28665
  coords: ___default["default"].invoke(points, "coord")
@@ -28575,11 +28730,7 @@ class InteractiveGraph extends React__namespace.Component {
28575
28730
  let pointA = null;
28576
28731
  pointA = this.pointA = Interactive2.addMaybeMobileMovablePoint(this, {
28577
28732
  coord: coords[0],
28578
- constraints: [
28579
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28580
- Interactive2.MovablePoint.constraints.bound(),
28581
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28582
- Interactive2.MovablePoint.constraints.snap(), coord => {
28733
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28583
28734
  return !pointA ||
28584
28735
  // @ts-expect-error - TS2531 - Object is possibly 'null'.
28585
28736
  coord[0] !== pointB.coord()[0] &&
@@ -28595,11 +28746,7 @@ class InteractiveGraph extends React__namespace.Component {
28595
28746
  let pointB = null;
28596
28747
  pointB = this.pointB = Interactive2.addMaybeMobileMovablePoint(this, {
28597
28748
  coord: coords[1],
28598
- constraints: [
28599
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28600
- Interactive2.MovablePoint.constraints.bound(),
28601
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28602
- Interactive2.MovablePoint.constraints.snap(), coord => {
28749
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28603
28750
  return !pointB ||
28604
28751
  // @ts-expect-error - TS2531 - Object is possibly 'null'.
28605
28752
  coord[0] !== pointA.coord()[0] &&
@@ -28615,11 +28762,7 @@ class InteractiveGraph extends React__namespace.Component {
28615
28762
  let pointC = null;
28616
28763
  pointC = this.pointC = Interactive2.addMaybeMobileMovablePoint(this, {
28617
28764
  coord: coords[2],
28618
- constraints: [
28619
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28620
- Interactive2.MovablePoint.constraints.bound(),
28621
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28622
- Interactive2.MovablePoint.constraints.snap(), coord => {
28765
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28623
28766
  return !pointC ||
28624
28767
  // @ts-expect-error - TS2531 - Object is possibly 'null'.
28625
28768
  coord[0] !== pointA.coord()[0] &&
@@ -28690,22 +28833,14 @@ class InteractiveGraph extends React__namespace.Component {
28690
28833
  let pointA = null;
28691
28834
  pointA = this.pointA = Interactive2.addMaybeMobileMovablePoint(this, {
28692
28835
  coord: coords[0],
28693
- constraints: [
28694
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28695
- Interactive2.MovablePoint.constraints.bound(),
28696
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28697
- Interactive2.MovablePoint.constraints.snap(), coord => {
28836
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28698
28837
  return !pointA || coord[0] !== pointB.coord()[0];
28699
28838
  }],
28700
28839
  onMove: onMoveHandler
28701
28840
  });
28702
28841
  const pointB = this.pointB = Interactive2.addMaybeMobileMovablePoint(this, {
28703
28842
  coord: coords[1],
28704
- constraints: [
28705
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28706
- Interactive2.MovablePoint.constraints.bound(),
28707
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28708
- Interactive2.MovablePoint.constraints.snap(), coord => {
28843
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28709
28844
  // @ts-expect-error - TS2339 - Property 'coord' does not exist on type 'never'.
28710
28845
  return !pointA || coord[0] !== pointA.coord()[0];
28711
28846
  }],
@@ -28786,11 +28921,7 @@ class InteractiveGraph extends React__namespace.Component {
28786
28921
  const coord = segmentCoords[i];
28787
28922
  segmentPoints.push(Interactive2.addMaybeMobileMovablePoint(this, {
28788
28923
  coord: coord,
28789
- constraints: [
28790
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28791
- Interactive2.MovablePoint.constraints.bound(),
28792
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28793
- Interactive2.MovablePoint.constraints.snap(), coord => {
28924
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
28794
28925
  const otherSegment = segmentPoints[1 - i];
28795
28926
  if (!otherSegment) {
28796
28927
  // segment hasn't been defined yet
@@ -28865,11 +28996,7 @@ class InteractiveGraph extends React__namespace.Component {
28865
28996
  let point = null;
28866
28997
  point = Interactive2.addMaybeMobileMovablePoint(this, {
28867
28998
  coord: coord,
28868
- constraints: [
28869
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28870
- Interactive2.MovablePoint.constraints.bound(),
28871
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
28872
- Interactive2.MovablePoint.constraints.snap(), function (coord) {
28999
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), function (coord) {
28873
29000
  // TODO(jack): There ought to be a
28874
29001
  // MovablePoint.constraints.avoid
28875
29002
  // default that lets you do things like this
@@ -29144,11 +29271,7 @@ class InteractiveGraph extends React__namespace.Component {
29144
29271
  };
29145
29272
  const point = Interactive2.addMaybeMobileMovablePoint(this, {
29146
29273
  coord: coord,
29147
- constraints: [
29148
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
29149
- Interactive2.MovablePoint.constraints.bound(), snapToGrid ?
29150
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
29151
- Interactive2.MovablePoint.constraints.snap() : null, graphConstraint],
29274
+ constraints: [Interactive2.MovablePoint.constraints.bound(), snapToGrid ? Interactive2.MovablePoint.constraints.snap() : null, graphConstraint],
29152
29275
  onMoveStart: () => {
29153
29276
  if (this.isClickToAddPoints()) {
29154
29277
  this.setTrashCanVisibility(1);
@@ -29240,11 +29363,7 @@ class InteractiveGraph extends React__namespace.Component {
29240
29363
  const coord = segment[i];
29241
29364
  points.push(createPoint({
29242
29365
  coord: coord,
29243
- constraints: [
29244
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
29245
- Interactive2.MovablePoint.constraints.bound(),
29246
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
29247
- Interactive2.MovablePoint.constraints.snap(), coord => {
29366
+ constraints: [Interactive2.MovablePoint.constraints.bound(), Interactive2.MovablePoint.constraints.snap(), coord => {
29248
29367
  const otherPoint = points[1 - i];
29249
29368
  if (!otherPoint) {
29250
29369
  // point hasn't been defined yet
@@ -33938,7 +34057,6 @@ const Measurer = createReactClass__default["default"]({
33938
34057
  range: range,
33939
34058
  scale: scale
33940
34059
  });
33941
- // @ts-expect-error - Property 'addMouseLayer' does not exist on type 'Graphie'.
33942
34060
  graphie.addMouseLayer({
33943
34061
  allowScratchpad: true,
33944
34062
  setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
@@ -38481,7 +38599,6 @@ class Plotter extends React__namespace.Component {
38481
38599
  scale: c.scale,
38482
38600
  isMobile: this.props.apiOptions.isMobile
38483
38601
  });
38484
- // @ts-expect-error - Property 'addMouseLayer' does not exist on type 'Graphie'.
38485
38602
  graphie.addMouseLayer({
38486
38603
  allowScratchpad: true,
38487
38604
  setDrawingAreaAvailable: this.props.apiOptions.setDrawingAreaAvailable
@@ -38894,7 +39011,6 @@ class Plotter extends React__namespace.Component {
38894
39011
  if (i > 0) {
38895
39012
  c.graph.lines[i] = Interactive2.addMovableLine(graphie, {
38896
39013
  points: [c.graph.points[i - 1], c.graph.points[i]],
38897
- // @ts-expect-error - TS2339 - Property 'constraints' does not exist on type '(graphie: any, movable: any, options: any) => void'.
38898
39014
  constraints: Interactive2.MovablePoint.constraints.fixed(),
38899
39015
  normalStyle: {
38900
39016
  stroke: KhanColors.BLUE_C,
@@ -41746,7 +41862,7 @@ const init = function (options) {
41746
41862
 
41747
41863
  // This file is processed by a Rollup plugin (replace) to inject the production
41748
41864
  const libName = "@khanacademy/perseus";
41749
- const libVersion = "19.1.6";
41865
+ const libVersion = "19.1.7";
41750
41866
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
41751
41867
 
41752
41868
  const apiVersion = {