@khanacademy/perseus 19.1.4 → 19.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @khanacademy/perseus
2
2
 
3
+ ## 19.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#964](https://github.com/Khan/perseus/pull/964) [`d8fbc251`](https://github.com/Khan/perseus/commit/d8fbc25170bd671ad984893553f79f44e3a0d048) Thanks [@benchristel](https://github.com/benchristel)! - Internal: Refactor Movable to be an ES6 class
8
+
9
+ - Updated dependencies [[`d8fbc251`](https://github.com/Khan/perseus/commit/d8fbc25170bd671ad984893553f79f44e3a0d048), [`ba44dd40`](https://github.com/Khan/perseus/commit/ba44dd405272b066615099c8bd30033715305939)]:
10
+ - @khanacademy/kmath@0.1.11
11
+ - @khanacademy/math-input@17.0.4
12
+
3
13
  ## 19.1.4
4
14
 
5
15
  ### Patch Changes
@@ -32,6 +32,9 @@ type DefaultProps = {
32
32
  };
33
33
  interface Movable {
34
34
  remove(): void;
35
+ props: unknown;
36
+ modify(graphie: GraphieDrawingContext): "reordered" | undefined;
37
+ toFront(): void;
35
38
  }
36
39
  declare class Graphie extends React.Component<Props> {
37
40
  graphieDivRef: React.RefObject<HTMLDivElement>;
@@ -56,7 +59,12 @@ declare class Graphie extends React.Component<Props> {
56
59
  _scale: () => Coord;
57
60
  _setupGraphie: () => void;
58
61
  _removeMovables: () => void;
59
- _renderMovables: (children: ReadonlyArray<any>, arg2: any) => React.ReactElement;
62
+ _renderMovables: (children: ReadonlyArray<any>, arg2: {
63
+ nextKey: number;
64
+ graphie: GraphieDrawingContext;
65
+ oldMovables: Record<string, Movable>;
66
+ newMovables: Record<string, Movable>;
67
+ }) => React.ReactElement;
60
68
  _updateMovables: () => void;
61
69
  render(): React.ReactNode;
62
70
  }
package/dist/es/index.js CHANGED
@@ -3975,10 +3975,10 @@ FixedToResponsive.defaultProps = {
3975
3975
 
3976
3976
  /* Local helper methods. */
3977
3977
 
3978
- function getKey(eventName, id) {
3978
+ function getKey$1(eventName, id) {
3979
3979
  return eventName + ":" + id;
3980
3980
  }
3981
- function getEventName(key) {
3981
+ function getEventName$1(key) {
3982
3982
  return key.split(":")[0];
3983
3983
  }
3984
3984
  const MovableHelperMethods = {
@@ -4055,7 +4055,7 @@ const MovableHelperMethods = {
4055
4055
 
4056
4056
  // If there's an existing handler, replace it by using its index in
4057
4057
  // `this.state[eventName]`; otherwise, add this handler to the end
4058
- const key = getKey(eventName, id);
4058
+ const key = getKey$1(eventName, id);
4059
4059
  const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
4060
4060
  this.state[eventName][index] = func;
4061
4061
  },
@@ -4067,7 +4067,7 @@ const MovableHelperMethods = {
4067
4067
  */
4068
4068
  unlisten: function (eventName, id) {
4069
4069
  this._listenerMap = this._listenerMap || {};
4070
- const key = getKey(eventName, id);
4070
+ const key = getKey$1(eventName, id);
4071
4071
  const index = this._listenerMap[key];
4072
4072
  if (index !== undefined) {
4073
4073
  // Remove handler from list of event handlers and listenerMap
@@ -4077,7 +4077,7 @@ const MovableHelperMethods = {
4077
4077
  // Re-index existing events: if they occur after `index`, decrement
4078
4078
  const keys = _.keys(this._listenerMap);
4079
4079
  _.each(keys, function (key) {
4080
- if (getEventName(key) === eventName &&
4080
+ if (getEventName$1(key) === eventName &&
4081
4081
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
4082
4082
  this._listenerMap[key] > index) {
4083
4083
  // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
@@ -8705,6 +8705,10 @@ class Graphie$1 {
8705
8705
  // Refactor to accessor methods that look at this.dimensions.
8706
8706
  this.xpixels = void 0;
8707
8707
  this.ypixels = void 0;
8708
+ // set by Movables
8709
+ // TODO(benchristel): consider putting this state on the Movable instead of
8710
+ // on the Graphie
8711
+ this.isDragging = void 0;
8708
8712
  this.label = (point, text, direction, arg4, arg5) => {
8709
8713
  const style = typeof arg4 === "object" ? arg4 : arg5;
8710
8714
  const latex = typeof arg4 === "boolean" ? arg4 : true;
@@ -9526,6 +9530,11 @@ class Graphie$1 {
9526
9530
  });
9527
9531
  return processed;
9528
9532
  }
9533
+
9534
+ // This is a stub that's overridden in interactive.ts
9535
+ getMouseCoord(event) {
9536
+ throw new Error("getMouseCoord is a stub, and is not implemented");
9537
+ }
9529
9538
  }
9530
9539
  const labelDirections = {
9531
9540
  center: [-0.5, -0.5],
@@ -13722,8 +13731,7 @@ var GraphieClasses = {
13722
13731
  const normalizeOptions$3 = InteractiveUtil.normalizeOptions;
13723
13732
  const assert$8 = InteractiveUtil.assert;
13724
13733
 
13725
- // Default "props" and "state". Both are added to this.state and
13726
- // receive magic getter methods (this.isHovering() etc).
13734
+ // Default "props" and "state". Both are added to this.state.
13727
13735
  // However, properties in DEFAULT_PROPS are updated on `modify()`,
13728
13736
  // while those in DEFAULT_STATE persist and are not updated.
13729
13737
  // Things that the user might want to change should be on "props",
@@ -13738,27 +13746,23 @@ const DEFAULT_STATE$3 = {
13738
13746
  isDragging: false,
13739
13747
  mouseTarget: null
13740
13748
  };
13741
- const Movable = function Movable(graphie, options) {
13742
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
13743
- _.extend(this, {
13744
- graphie,
13745
- state: {
13746
- // Set here because this must be unique for each instance
13749
+ class Movable {
13750
+ constructor(graphie, options) {
13751
+ this.graphie = void 0;
13752
+ this.state = void 0;
13753
+ this.prevState = void 0;
13754
+ // TODO(benchristel): delete _listenerMap; it's unused
13755
+ this._listenerMap = {};
13756
+ this.graphie = graphie;
13757
+ this.state = {
13747
13758
  id: _.uniqueId("movable")
13748
- }
13749
- });
13750
-
13751
- // We only set DEFAULT_STATE once, here
13752
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
13753
- this.modify(_.extend({}, DEFAULT_STATE$3, options));
13754
- };
13755
- InteractiveUtil.createGettersFor(Movable, _.extend({}, DEFAULT_PROPS$3, DEFAULT_STATE$3));
13756
- InteractiveUtil.addMovableHelperMethodsTo(Movable);
13757
- _.extend(Movable.prototype, {
13758
- cloneState: function () {
13759
- return _extends({}, this.state);
13760
- },
13761
- _createDefaultState: function () {
13759
+ };
13760
+ this.modify(_extends({}, DEFAULT_STATE$3, options));
13761
+ }
13762
+ modify(options) {
13763
+ this.update(_extends({}, this._createDefaultState(), options));
13764
+ }
13765
+ _createDefaultState() {
13762
13766
  return _extends({
13763
13767
  id: this.state.id,
13764
13768
  add: [],
@@ -13770,63 +13774,11 @@ _.extend(Movable.prototype, {
13770
13774
  onMoveEnd: [],
13771
13775
  onClick: []
13772
13776
  }, DEFAULT_PROPS$3);
13773
- },
13774
- /**
13775
- * Resets the object to its state as if it were constructed with
13776
- * `options` originally. The only state maintained is `state.id`
13777
- *
13778
- * Analogous to React.js's replaceProps
13779
- */
13780
- modify: function (options) {
13781
- this.update(_extends({}, this._createDefaultState(), options));
13782
- },
13783
- /**
13784
- * Simulates a mouse grab event on the movable object.
13785
- */
13786
- grab: function (coord) {
13787
- assert$8(point.is(coord));
13788
- const self = this;
13789
- const graphie = self.graphie;
13790
- const state = self.state;
13791
- state.isHovering = true;
13792
- state.isDragging = true;
13793
- graphie.isDragging = true;
13794
- const startMouseCoord = coord;
13795
- let prevMouseCoord = startMouseCoord;
13796
- self._fireEvent(state.onMoveStart, startMouseCoord, startMouseCoord);
13797
- const moveHandler = function moveHandler(e) {
13798
- e.preventDefault();
13799
- const mouseCoord = graphie.getMouseCoord(e);
13800
- self._fireEvent(state.onMove, mouseCoord, prevMouseCoord);
13801
- self.draw();
13802
- prevMouseCoord = mouseCoord;
13803
- };
13804
- const upHandler = function upHandler(e) {
13805
- $(document).unbind("vmousemove", moveHandler);
13806
- $(document).unbind("vmouseup", upHandler);
13807
- if (state.isHovering) {
13808
- self._fireEvent(state.onClick, prevMouseCoord, startMouseCoord);
13809
- }
13810
- state.isHovering = self.state.isMouseOver;
13811
- state.isDragging = false;
13812
- graphie.isDragging = false;
13813
- self._fireEvent(state.onMoveEnd, prevMouseCoord, startMouseCoord);
13814
- self.draw();
13815
- };
13816
- $(document).bind("vmousemove", moveHandler);
13817
- $(document).bind("vmouseup", upHandler);
13818
- },
13819
- /**
13820
- * Adjusts constructor parameters without changing previous settings
13821
- * for any option not specified
13822
- *
13823
- * Analogous to React.js's setProps
13824
- */
13825
- update: function (options) {
13826
- const self = this;
13827
- const graphie = self.graphie;
13828
- const prevState = self.cloneState();
13829
- const state = _.extend(self.state, normalizeOptions$3(options));
13777
+ }
13778
+ update(options) {
13779
+ const graphie = this.graphie;
13780
+ const prevState = this.cloneState();
13781
+ const state = Object.assign(this.state, normalizeOptions$3(options));
13830
13782
 
13831
13783
  // the invisible shape in front of the point that gets mouse events
13832
13784
  if (state.mouseTarget && !prevState.mouseTarget) {
@@ -13838,24 +13790,24 @@ _.extend(Movable.prototype, {
13838
13790
  }
13839
13791
  const isMouse = !("ontouchstart" in window);
13840
13792
  if (isMouse) {
13841
- $mouseTarget.on("vmouseover", function () {
13793
+ $mouseTarget.on("vmouseover", () => {
13842
13794
  state.isMouseOver = true;
13843
13795
  if (!graphie.isDragging) {
13844
13796
  state.isHovering = true;
13845
13797
  }
13846
- if (self.state.added) {
13798
+ if (this.state.added) {
13847
13799
  // Avoid drawing if the point has been removed
13848
- self.draw();
13800
+ this.draw();
13849
13801
  }
13850
13802
  });
13851
- $mouseTarget.on("vmouseout", function () {
13803
+ $mouseTarget.on("vmouseout", () => {
13852
13804
  state.isMouseOver = false;
13853
13805
  if (!state.isDragging) {
13854
13806
  state.isHovering = false;
13855
13807
  }
13856
- if (self.state.added) {
13808
+ if (this.state.added) {
13857
13809
  // Avoid drawing if the point has been removed
13858
- self.draw();
13810
+ this.draw();
13859
13811
  }
13860
13812
  });
13861
13813
  }
@@ -13867,13 +13819,13 @@ _.extend(Movable.prototype, {
13867
13819
  }, {
13868
13820
  passive: false
13869
13821
  });
13870
- $mouseTarget.on("vmousedown", function (e) {
13822
+ $mouseTarget.on("vmousedown", e => {
13871
13823
  if (e.which !== 0 && e.which !== 1) {
13872
13824
  return;
13873
13825
  }
13874
13826
  e.preventDefault();
13875
13827
  const mouseCoord = graphie.getMouseCoord(e);
13876
- self.grab(mouseCoord);
13828
+ this.grab(mouseCoord);
13877
13829
  });
13878
13830
  }
13879
13831
  if (state.mouseTarget && state.cursor !== undefined) {
@@ -13890,39 +13842,212 @@ _.extend(Movable.prototype, {
13890
13842
 
13891
13843
  // Trigger an add event if this hasn't been added before
13892
13844
  if (!state.added) {
13893
- self._fireEvent(state.modify, self.cloneState(), {});
13845
+ // TODO(benchristel): No one seems to handle the modify event. Can
13846
+ // we delete this?
13847
+ // @ts-expect-error - TS2345: Argument of type '{}' is not assignable to parameter of type 'State'.
13848
+ this._fireEvent(state.modify, this.cloneState(), {});
13894
13849
  state.added = true;
13895
13850
 
13896
13851
  // Update the state for `added` and in case the add event
13897
13852
  // changed it
13898
- self.prevState = self.cloneState();
13853
+ this.prevState = this.cloneState();
13899
13854
  }
13900
13855
 
13901
13856
  // Trigger a modify event
13902
- self._fireEvent(state.modify, self.cloneState(), self.prevState);
13903
- },
13904
- remove: function () {
13905
- this.state.added = false;
13906
- this._fireEvent(this.state.remove);
13907
- if (this.state.mouseTarget) {
13908
- $(this.state.mouseTarget).off();
13909
- this.state.mouseTarget.remove();
13910
- this.state.mouseTarget = null;
13857
+ this._fireEvent(state.modify, this.cloneState(), this.prevState);
13858
+ }
13859
+ cloneState() {
13860
+ return _extends({}, this.state);
13861
+ }
13862
+
13863
+ /**
13864
+ * Fire an onSomething type event to all functions in listeners
13865
+ */
13866
+ _fireEvent(listeners, ...args) {
13867
+ if (listeners == null) {
13868
+ return;
13911
13869
  }
13912
- },
13870
+ for (const listener of listeners) {
13871
+ listener.call(this, ...args);
13872
+ }
13873
+ }
13874
+
13875
+ /**
13876
+ * Call all draw functions, and update our prevState for the next
13877
+ * draw function
13878
+ */
13879
+ draw() {
13880
+ const currState = this.cloneState();
13881
+ this._fireEvent(this.state.draw, currState, this.prevState);
13882
+ this.prevState = currState;
13883
+ }
13884
+
13885
+ /**
13886
+ * Simulates a mouse grab event on the movable object.
13887
+ */
13888
+ grab(coord) {
13889
+ assert$8(point.is(coord));
13890
+ const graphie = this.graphie;
13891
+ const state = this.state;
13892
+ state.isHovering = true;
13893
+ state.isDragging = true;
13894
+ graphie.isDragging = true;
13895
+ const startMouseCoord = coord;
13896
+ let prevMouseCoord = startMouseCoord;
13897
+ this._fireEvent(state.onMoveStart, startMouseCoord, startMouseCoord);
13898
+ const moveHandler = e => {
13899
+ e.preventDefault();
13900
+ const mouseCoord = graphie.getMouseCoord(e);
13901
+ this._fireEvent(state.onMove, mouseCoord, prevMouseCoord);
13902
+ this.draw();
13903
+ prevMouseCoord = mouseCoord;
13904
+ };
13905
+ const upHandler = () => {
13906
+ $(document).unbind("vmousemove", moveHandler);
13907
+ $(document).unbind("vmouseup", upHandler);
13908
+ if (state.isHovering) {
13909
+ this._fireEvent(state.onClick, prevMouseCoord, startMouseCoord);
13910
+ }
13911
+ state.isHovering = this.state.isMouseOver;
13912
+ state.isDragging = false;
13913
+ graphie.isDragging = false;
13914
+ this._fireEvent(state.onMoveEnd, prevMouseCoord, startMouseCoord);
13915
+ this.draw();
13916
+ };
13917
+ $(document).bind("vmousemove", moveHandler);
13918
+ $(document).bind("vmouseup", upHandler);
13919
+ }
13920
+ _applyConstraints(current, previous, extraOptions) {
13921
+ var _this$state$constrain;
13922
+ let skipRemaining = false;
13923
+ return ((_this$state$constrain = this.state.constraints) != null ? _this$state$constrain : []).reduce((memo, constraint) => {
13924
+ // A move that has been cancelled won't be propagated to later
13925
+ // constraints calls
13926
+ if (memo === false) {
13927
+ return false;
13928
+ }
13929
+ if (skipRemaining) {
13930
+ return memo;
13931
+ }
13932
+ const result = constraint.call(this, memo, previous, _extends({
13933
+ onSkipRemaining: () => {
13934
+ skipRemaining = true;
13935
+ }
13936
+ }, extraOptions));
13937
+ if (result === false) {
13938
+ // Returning false cancels the move
13939
+ return false;
13940
+ }
13941
+ if (point.is(result, 2)) {
13942
+ // Returning a coord from constraints overrides the move
13943
+ return result;
13944
+ }
13945
+ if (result === true || result == null) {
13946
+ // Returning true or undefined allow the move to occur
13947
+ return memo;
13948
+ }
13949
+ // Anything else is an error
13950
+ throw new PerseusError("Constraint returned invalid result: " + result, Errors.Internal);
13951
+ }, current);
13952
+ }
13953
+
13913
13954
  // Change z-order to back
13914
- toBack: function () {
13955
+ toBack() {
13915
13956
  if (this.state.mouseTarget) {
13916
13957
  this.state.mouseTarget.toBack();
13917
13958
  }
13918
- },
13959
+ }
13960
+
13919
13961
  // Change z-order to front
13920
- toFront: function () {
13962
+ toFront() {
13921
13963
  if (this.state.mouseTarget) {
13922
13964
  this.state.mouseTarget.toFront();
13923
13965
  }
13924
13966
  }
13925
- });
13967
+
13968
+ /**
13969
+ * Add a listener to any event: startMove, constraints, onMove, onMoveEnd,
13970
+ * etc. If a listener is already bound to the given eventName and id, then
13971
+ * it is overwritten by func.
13972
+ *
13973
+ * eventName: the string name of the event to listen to. one of:
13974
+ * "onMoveStart", "onMove", "onMoveEnd", "draw", "remove"
13975
+ *
13976
+ * id: a string id that can be used to remove this event at a later time
13977
+ * note: adding multiple listeners with the same id is undefined behavior
13978
+ *
13979
+ * func: the function to call when the event happens, which is called
13980
+ * with the event's standard parameters [usually (coord, prevCoord) or
13981
+ * (state, prevState)]
13982
+ */
13983
+ listen(eventName, id, func) {
13984
+ this._listenerMap = this._listenerMap || {};
13985
+
13986
+ // If there's an existing handler, replace it by using its index in
13987
+ // `this.state[eventName]`; otherwise, add this handler to the end
13988
+ const key = getKey(eventName, id);
13989
+ const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
13990
+ this.state[eventName][index] = func;
13991
+ }
13992
+
13993
+ /**
13994
+ * Remove a previously added listener, by the id specified in the
13995
+ * corresponding listen() call
13996
+ *
13997
+ * If the given id has not been registered already, this is a no-op
13998
+ */
13999
+ unlisten(eventName, id) {
14000
+ this._listenerMap = this._listenerMap || {};
14001
+ const key = getKey(eventName, id);
14002
+ const index = this._listenerMap[key];
14003
+ if (index !== undefined) {
14004
+ // Remove handler from list of event handlers and listenerMap
14005
+ this.state[eventName].splice(index, 1);
14006
+ delete this._listenerMap[key];
14007
+
14008
+ // Re-index existing events: if they occur after `index`, decrement
14009
+ const keys = _.keys(this._listenerMap);
14010
+ keys.forEach(key => {
14011
+ if (getEventName(key) === eventName && this._listenerMap[key] > index) {
14012
+ this._listenerMap[key]--;
14013
+ }
14014
+ });
14015
+ }
14016
+ }
14017
+ remove() {
14018
+ this.state.added = false;
14019
+ this._fireEvent(this.state.remove);
14020
+ if (this.state.mouseTarget) {
14021
+ $(this.state.mouseTarget).off();
14022
+ this.state.mouseTarget.remove();
14023
+ this.state.mouseTarget = null;
14024
+ }
14025
+ }
14026
+ cursor() {
14027
+ return this.state.cursor;
14028
+ }
14029
+ added() {
14030
+ return this.state.added;
14031
+ }
14032
+ isHovering() {
14033
+ return this.state.isHovering;
14034
+ }
14035
+ isMouseOver() {
14036
+ return this.state.isMouseOver;
14037
+ }
14038
+ isDragging() {
14039
+ return this.state.isDragging;
14040
+ }
14041
+ mouseTarget() {
14042
+ return this.state.mouseTarget;
14043
+ }
14044
+ }
14045
+ function getKey(eventName, id) {
14046
+ return eventName + ":" + id;
14047
+ }
14048
+ function getEventName(key) {
14049
+ return key.split(":")[0];
14050
+ }
13926
14051
 
13927
14052
  /* eslint-disable @babel/no-invalid-this */
13928
14053
  /**
@@ -14764,31 +14889,39 @@ const constraints$1 = {
14764
14889
  snap: function (snap) {
14765
14890
  return function (coord) {
14766
14891
  if (snap === null) {
14767
- // NOTE(kevinb): this should probably return the original point
14892
+ // TODO(benchristel), NOTE(kevinb): this should probably return
14893
+ // the original point
14768
14894
  return true;
14769
14895
  }
14770
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
14771
- snap = snap || this.graphie.snap;
14772
- return point.roundTo(coord, snap);
14896
+ // @ts-expect-error - TS2339: Property 'snap' does not exist on type 'Graphie'.
14897
+ return point.roundTo(coord, snap || this.graphie.snap);
14773
14898
  };
14774
14899
  },
14775
- bound: function (range, snap, paddingPx) {
14776
- if (paddingPx === undefined) {
14777
- if (range === undefined) {
14778
- paddingPx = 10;
14900
+ bound: function (range, snap, optionalPaddingPx) {
14901
+ const paddingPx = (() => {
14902
+ if (optionalPaddingPx === undefined) {
14903
+ if (range === undefined) {
14904
+ return 10;
14905
+ } else {
14906
+ return 0;
14907
+ }
14779
14908
  } else {
14780
- paddingPx = 0;
14909
+ return optionalPaddingPx;
14781
14910
  }
14782
- }
14911
+ })();
14783
14912
  return function (coord, prev, options) {
14784
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
14785
14913
  const graphie = this.graphie;
14786
14914
  range = range || graphie.range;
14787
14915
  if (snap === undefined) {
14916
+ // @ts-expect-error - Property 'snap' does not exist on type 'Graphie'.
14788
14917
  snap = graphie.snap;
14789
14918
  }
14790
- let lower = graphie.unscalePoint([paddingPx, graphie.ypixels - paddingPx]);
14791
- let upper = graphie.unscalePoint([graphie.xpixels - paddingPx, paddingPx]);
14919
+ let lower = graphie.unscalePoint([paddingPx,
14920
+ // @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
14921
+ graphie.ypixels - paddingPx]);
14922
+ let upper = graphie.unscalePoint([
14923
+ // @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
14924
+ graphie.xpixels - paddingPx, paddingPx]);
14792
14925
  if (snap) {
14793
14926
  lower = point.ceilTo(lower, snap);
14794
14927
  upper = point.floorTo(upper, snap);
@@ -41467,7 +41600,7 @@ const init = function init(options) {
41467
41600
 
41468
41601
  // This file is processed by a Rollup plugin (replace) to inject the production
41469
41602
  const libName = "@khanacademy/perseus";
41470
- const libVersion = "19.1.4";
41603
+ const libVersion = "19.1.5";
41471
41604
  addLibraryVersionToPerseusDebug(libName, libVersion);
41472
41605
 
41473
41606
  const apiVersion = {