@mathscan/geometry-engine 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/README.md +24 -7
  2. package/dist/core.cjs +1 -1
  3. package/dist/core.mjs +4 -4
  4. package/dist/entries/core.d.cts +1 -1
  5. package/dist/entries/core.d.ts +1 -1
  6. package/dist/entries/core.d.ts.map +1 -1
  7. package/dist/exercise.schema-Bma3qN9P.js +251 -0
  8. package/dist/exercise.schema-Bma3qN9P.js.map +1 -0
  9. package/dist/exercise.schema-Oj5ZH-yO.cjs +2 -0
  10. package/dist/exercise.schema-Oj5ZH-yO.cjs.map +1 -0
  11. package/dist/exerciseLoad-Db9Cigxi.cjs +2 -0
  12. package/dist/exerciseLoad-Db9Cigxi.cjs.map +1 -0
  13. package/dist/{geometryAttemptStatus-5L_q6-9l.js → exerciseLoad-DgeDXYbf.js} +84 -71
  14. package/dist/exerciseLoad-DgeDXYbf.js.map +1 -0
  15. package/dist/geometry/entities/angle.d.cts +56 -0
  16. package/dist/geometry/entities/angle.d.ts +57 -0
  17. package/dist/geometry/entities/angle.d.ts.map +1 -0
  18. package/dist/geometry/entities/circle.d.ts.map +1 -1
  19. package/dist/geometry/entities/index.d.cts +8 -4
  20. package/dist/geometry/entities/index.d.ts +8 -4
  21. package/dist/geometry/entities/index.d.ts.map +1 -1
  22. package/dist/geometry/entities/line.d.ts.map +1 -1
  23. package/dist/geometry/entities/point.d.ts.map +1 -1
  24. package/dist/geometry/entities/relations.d.cts +8 -1
  25. package/dist/geometry/entities/relations.d.ts +8 -1
  26. package/dist/geometry/entities/relations.d.ts.map +1 -1
  27. package/dist/geometry/entities/segment.d.ts.map +1 -1
  28. package/dist/geometry/entityModel.d.cts +21 -3
  29. package/dist/geometry/entityModel.d.ts +21 -3
  30. package/dist/geometry/entityModel.d.ts.map +1 -1
  31. package/dist/geometryState.schema-B5ccMKDa.cjs +2 -0
  32. package/dist/geometryState.schema-B5ccMKDa.cjs.map +1 -0
  33. package/dist/geometryState.schema-CKFPlX8j.js +1177 -0
  34. package/dist/geometryState.schema-CKFPlX8j.js.map +1 -0
  35. package/dist/goals-BlSeniyt.js +563 -0
  36. package/dist/goals-BlSeniyt.js.map +1 -0
  37. package/dist/goals-DLbmBZD8.cjs +2 -0
  38. package/dist/goals-DLbmBZD8.cjs.map +1 -0
  39. package/dist/index.cjs +1 -1
  40. package/dist/index.mjs +8 -8
  41. package/dist/measure/angleType.d.cts +2 -0
  42. package/dist/measure/angleType.d.ts +3 -0
  43. package/dist/measure/angleType.d.ts.map +1 -0
  44. package/dist/measure/geometryAdapter.d.cts +3 -0
  45. package/dist/measure/geometryAdapter.d.ts +3 -0
  46. package/dist/measure/geometryAdapter.d.ts.map +1 -1
  47. package/dist/react-B26_e52I.cjs +2 -0
  48. package/dist/react-B26_e52I.cjs.map +1 -0
  49. package/dist/{react-BEcdx1f6.js → react-B5cGaxH8.js} +738 -513
  50. package/dist/react-B5cGaxH8.js.map +1 -0
  51. package/dist/react.cjs +1 -1
  52. package/dist/react.mjs +1 -1
  53. package/dist/renderer/GeometryCanvas.d.ts.map +1 -1
  54. package/dist/renderer/StudentGeometryCanvas.d.ts.map +1 -1
  55. package/dist/renderer/Toolbar.d.ts.map +1 -1
  56. package/dist/renderer/angleMeasure.d.cts +14 -0
  57. package/dist/renderer/angleMeasure.d.ts +15 -0
  58. package/dist/renderer/angleMeasure.d.ts.map +1 -0
  59. package/dist/renderer/deriveRenderableGeometry.d.cts +1 -0
  60. package/dist/renderer/deriveRenderableGeometry.d.ts +1 -0
  61. package/dist/renderer/deriveRenderableGeometry.d.ts.map +1 -1
  62. package/dist/renderer/deriveSemanticScene.d.ts.map +1 -1
  63. package/dist/renderer/dragSnap.d.cts +14 -0
  64. package/dist/renderer/dragSnap.d.ts +15 -0
  65. package/dist/renderer/dragSnap.d.ts.map +1 -0
  66. package/dist/renderer/shapes/AngleShape.d.cts +19 -0
  67. package/dist/renderer/shapes/AngleShape.d.ts +20 -0
  68. package/dist/renderer/shapes/AngleShape.d.ts.map +1 -0
  69. package/dist/renderer/shapes/EntityLabel.d.cts +9 -1
  70. package/dist/renderer/shapes/EntityLabel.d.ts +9 -1
  71. package/dist/renderer/shapes/EntityLabel.d.ts.map +1 -1
  72. package/dist/renderer/shapes/EntityShape.d.cts +2 -1
  73. package/dist/renderer/shapes/EntityShape.d.ts +2 -1
  74. package/dist/renderer/shapes/EntityShape.d.ts.map +1 -1
  75. package/dist/renderer/useConnectionPreview.d.cts +12 -1
  76. package/dist/renderer/useConnectionPreview.d.ts +12 -1
  77. package/dist/renderer/useConnectionPreview.d.ts.map +1 -1
  78. package/dist/renderer/usePointerGestures.d.cts +1 -1
  79. package/dist/renderer/usePointerGestures.d.ts +1 -1
  80. package/dist/renderer/usePointerGestures.d.ts.map +1 -1
  81. package/dist/schemas/entityDefinition.schema.d.cts +7 -0
  82. package/dist/schemas/entityDefinition.schema.d.ts +7 -0
  83. package/dist/schemas/entityDefinition.schema.d.ts.map +1 -1
  84. package/dist/schemas/entityDocument.d.cts +34 -13
  85. package/dist/schemas/entityDocument.d.ts +34 -13
  86. package/dist/schemas/entityDocument.d.ts.map +1 -1
  87. package/dist/schemas/entityPresentation.schema.d.cts +3 -0
  88. package/dist/schemas/entityPresentation.schema.d.ts +3 -0
  89. package/dist/schemas/entityPresentation.schema.d.ts.map +1 -1
  90. package/dist/schemas/exercise.schema.d.cts +80 -2
  91. package/dist/schemas/exercise.schema.d.ts +80 -2
  92. package/dist/schemas/exercise.schema.d.ts.map +1 -1
  93. package/dist/schemas/exerciseV2.schema.d.cts +57 -0
  94. package/dist/schemas/exerciseV2.schema.d.ts +57 -0
  95. package/dist/schemas/exerciseV2.schema.d.ts.map +1 -1
  96. package/dist/schemas/exerciseV4.schema.d.cts +168 -0
  97. package/dist/schemas/exerciseV4.schema.d.ts +169 -0
  98. package/dist/schemas/exerciseV4.schema.d.ts.map +1 -0
  99. package/dist/schemas/geometryState.schema.d.cts +8 -0
  100. package/dist/schemas/geometryState.schema.d.ts +8 -0
  101. package/dist/schemas/geometryState.schema.d.ts.map +1 -1
  102. package/dist/schemas/goals/angleBisectorGoal.schema.d.cts +15 -0
  103. package/dist/schemas/goals/angleBisectorGoal.schema.d.ts +16 -0
  104. package/dist/schemas/goals/angleBisectorGoal.schema.d.ts.map +1 -0
  105. package/dist/schemas/goals/angleCriterion.schema.d.cts +28 -0
  106. package/dist/schemas/goals/angleCriterion.schema.d.ts +29 -0
  107. package/dist/schemas/goals/angleCriterion.schema.d.ts.map +1 -0
  108. package/dist/schemas/goals/angleMeasureGoal.schema.d.cts +26 -0
  109. package/dist/schemas/goals/angleMeasureGoal.schema.d.ts +27 -0
  110. package/dist/schemas/goals/angleMeasureGoal.schema.d.ts.map +1 -0
  111. package/dist/schemas/goals/createGoal.schema.d.cts +1 -0
  112. package/dist/schemas/goals/createGoal.schema.d.ts +1 -0
  113. package/dist/schemas/goals/createGoal.schema.d.ts.map +1 -1
  114. package/dist/schemas/goals/geometryGoal.schema.d.cts +61 -0
  115. package/dist/schemas/goals/geometryGoal.schema.d.ts +61 -0
  116. package/dist/schemas/goals/geometryGoal.schema.d.ts.map +1 -1
  117. package/dist/schemas/goals/givenAngleGoal.schema.d.cts +35 -0
  118. package/dist/schemas/goals/givenAngleGoal.schema.d.ts +36 -0
  119. package/dist/schemas/goals/givenAngleGoal.schema.d.ts.map +1 -0
  120. package/dist/schemas/goals/goalKindDeclaration.d.cts +7 -0
  121. package/dist/schemas/goals/goalKindDeclaration.d.ts +7 -0
  122. package/dist/schemas/goals/goalKindDeclaration.d.ts.map +1 -1
  123. package/dist/schemas/goals/parallelGoal.schema.d.cts +1 -0
  124. package/dist/schemas/goals/parallelGoal.schema.d.ts +1 -0
  125. package/dist/schemas/goals/parallelGoal.schema.d.ts.map +1 -1
  126. package/dist/schemas/goals/perpendicularGoal.schema.d.cts +1 -0
  127. package/dist/schemas/goals/perpendicularGoal.schema.d.ts +1 -0
  128. package/dist/schemas/goals/perpendicularGoal.schema.d.ts.map +1 -1
  129. package/dist/schemas/goals/throughPointsGoal.schema.d.cts +1 -0
  130. package/dist/schemas/goals/throughPointsGoal.schema.d.ts +1 -0
  131. package/dist/schemas/goals/throughPointsGoal.schema.d.ts.map +1 -1
  132. package/dist/schemas/objectTypeName.schema.d.cts +1 -0
  133. package/dist/schemas/objectTypeName.schema.d.ts +1 -0
  134. package/dist/schemas/objectTypeName.schema.d.ts.map +1 -1
  135. package/dist/schemas/v2ToV3.d.cts +15 -1
  136. package/dist/schemas/v2ToV3.d.ts +15 -1
  137. package/dist/schemas/v2ToV3.d.ts.map +1 -1
  138. package/dist/schemas/v3ToV4.d.cts +2 -1
  139. package/dist/schemas/v3ToV4.d.ts +2 -1
  140. package/dist/schemas/v3ToV4.d.ts.map +1 -1
  141. package/dist/schemas/v4ToV5.d.cts +7 -0
  142. package/dist/schemas/v4ToV5.d.ts +8 -0
  143. package/dist/schemas/v4ToV5.d.ts.map +1 -0
  144. package/dist/schemas.cjs +1 -1
  145. package/dist/schemas.mjs +3 -3
  146. package/dist/snapping/computeDragSnap.d.cts +30 -0
  147. package/dist/snapping/computeDragSnap.d.ts +31 -0
  148. package/dist/snapping/computeDragSnap.d.ts.map +1 -0
  149. package/dist/state/geometryContext.d.ts.map +1 -1
  150. package/dist/store/attemptChange.d.cts +1 -1
  151. package/dist/store/attemptChange.d.ts +1 -1
  152. package/dist/store/attemptChange.d.ts.map +1 -1
  153. package/dist/store/constructionCommand.d.cts +14 -2
  154. package/dist/store/constructionCommand.d.ts +14 -2
  155. package/dist/store/constructionCommand.d.ts.map +1 -1
  156. package/dist/store/constructionIdentity.d.cts +9 -0
  157. package/dist/store/constructionIdentity.d.ts +9 -0
  158. package/dist/store/constructionIdentity.d.ts.map +1 -1
  159. package/dist/store/studentStore.d.cts +7 -0
  160. package/dist/store/studentStore.d.ts +7 -0
  161. package/dist/store/studentStore.d.ts.map +1 -1
  162. package/dist/store/teacherStore.d.cts +16 -0
  163. package/dist/store/teacherStore.d.ts +16 -0
  164. package/dist/store/teacherStore.d.ts.map +1 -1
  165. package/dist/{studentStore-CEKTtMCh.js → studentStore-CyYa0N93.js} +502 -370
  166. package/dist/studentStore-CyYa0N93.js.map +1 -0
  167. package/dist/studentStore-ubldy4PJ.cjs +2 -0
  168. package/dist/studentStore-ubldy4PJ.cjs.map +1 -0
  169. package/dist/validation/getGeometryExerciseWarnings.d.cts +3 -2
  170. package/dist/validation/getGeometryExerciseWarnings.d.ts +3 -2
  171. package/dist/validation/getGeometryExerciseWarnings.d.ts.map +1 -1
  172. package/dist/validation/goals/angleBisector.d.cts +3 -0
  173. package/dist/validation/goals/angleBisector.d.ts +4 -0
  174. package/dist/validation/goals/angleBisector.d.ts.map +1 -0
  175. package/dist/validation/goals/angleCriterion.d.cts +12 -0
  176. package/dist/validation/goals/angleCriterion.d.ts +13 -0
  177. package/dist/validation/goals/angleCriterion.d.ts.map +1 -0
  178. package/dist/validation/goals/angleMeasure.d.cts +9 -0
  179. package/dist/validation/goals/angleMeasure.d.ts +10 -0
  180. package/dist/validation/goals/angleMeasure.d.ts.map +1 -0
  181. package/dist/validation/goals/create.d.cts +2 -2
  182. package/dist/validation/goals/create.d.ts +2 -2
  183. package/dist/validation/goals/create.d.ts.map +1 -1
  184. package/dist/validation/goals/givenAngle.d.cts +11 -0
  185. package/dist/validation/goals/givenAngle.d.ts +12 -0
  186. package/dist/validation/goals/givenAngle.d.ts.map +1 -0
  187. package/dist/validation/goals/goalKindHandler.d.cts +38 -1
  188. package/dist/validation/goals/goalKindHandler.d.ts +38 -1
  189. package/dist/validation/goals/goalKindHandler.d.ts.map +1 -1
  190. package/dist/validation/goals/index.d.cts +9 -2
  191. package/dist/validation/goals/index.d.ts +9 -2
  192. package/dist/validation/goals/index.d.ts.map +1 -1
  193. package/dist/validation/goals/midpoint.d.cts +2 -2
  194. package/dist/validation/goals/midpoint.d.ts +2 -2
  195. package/dist/validation/goals/midpoint.d.ts.map +1 -1
  196. package/dist/validation/goals/parallel.d.cts +2 -2
  197. package/dist/validation/goals/parallel.d.ts +2 -2
  198. package/dist/validation/goals/parallel.d.ts.map +1 -1
  199. package/dist/validation/goals/perpendicular.d.cts +2 -2
  200. package/dist/validation/goals/perpendicular.d.ts +2 -2
  201. package/dist/validation/goals/perpendicular.d.ts.map +1 -1
  202. package/dist/validation/goals/segmentLength.d.cts +2 -2
  203. package/dist/validation/goals/segmentLength.d.ts +2 -2
  204. package/dist/validation/goals/segmentLength.d.ts.map +1 -1
  205. package/dist/validation/goals/throughPoints.d.cts +2 -2
  206. package/dist/validation/goals/throughPoints.d.ts +2 -2
  207. package/dist/validation/goals/throughPoints.d.ts.map +1 -1
  208. package/dist/validation/types.d.cts +5 -1
  209. package/dist/validation/types.d.ts +5 -1
  210. package/dist/validation/types.d.ts.map +1 -1
  211. package/dist/validation/validateGeometryState.d.ts.map +1 -1
  212. package/dist/validation/validateGeometryStateInput.d.ts.map +1 -1
  213. package/dist/validation.cjs +1 -1
  214. package/dist/validation.cjs.map +1 -1
  215. package/dist/validation.mjs +106 -85
  216. package/dist/validation.mjs.map +1 -1
  217. package/package.json +1 -1
  218. package/dist/exercise.schema-BV2b7rtN.cjs +0 -2
  219. package/dist/exercise.schema-BV2b7rtN.cjs.map +0 -1
  220. package/dist/exercise.schema-ckVBW9XA.js +0 -212
  221. package/dist/exercise.schema-ckVBW9XA.js.map +0 -1
  222. package/dist/geometryAttemptStatus-5L_q6-9l.js.map +0 -1
  223. package/dist/geometryAttemptStatus-N_XHIkiS.cjs +0 -2
  224. package/dist/geometryAttemptStatus-N_XHIkiS.cjs.map +0 -1
  225. package/dist/geometryState.schema-D0ixyGYE.js +0 -955
  226. package/dist/geometryState.schema-D0ixyGYE.js.map +0 -1
  227. package/dist/geometryState.schema-DKQ-durx.cjs +0 -2
  228. package/dist/geometryState.schema-DKQ-durx.cjs.map +0 -1
  229. package/dist/goals-C3ZwbEh_.js +0 -451
  230. package/dist/goals-C3ZwbEh_.js.map +0 -1
  231. package/dist/goals-CxR5qPDC.cjs +0 -2
  232. package/dist/goals-CxR5qPDC.cjs.map +0 -1
  233. package/dist/react-BEcdx1f6.js.map +0 -1
  234. package/dist/react-Pp_VSk--.cjs +0 -2
  235. package/dist/react-Pp_VSk--.cjs.map +0 -1
  236. package/dist/studentStore-CEKTtMCh.js.map +0 -1
  237. package/dist/studentStore-DLftfFAl.cjs +0 -2
  238. package/dist/studentStore-DLftfFAl.cjs.map +0 -1
@@ -1,12 +1,12 @@
1
- import { I as e, O as t, R as n, k as r } from "./geometryState.schema-D0ixyGYE.js";
2
- import { c as i, d as a, s as o } from "./goals-C3ZwbEh_.js";
3
- import { $ as s, C as c, E as l, H as u, I as d, N as f, O as p, P as m, Q as h, V as g, a as _, at as v, b as y, c as b, ct as x, d as S, f as C, g as w, h as T, i as E, it as D, j as O, k, l as A, m as j, n as M, nt as ee, o as N, ot as P, p as te, r as ne, st as re, t as ie, u as ae, v as F, x as oe, y as se } from "./studentStore-CEKTtMCh.js";
4
- import { c as ce, o as le, r as ue, s as de, t as fe, u as pe } from "./geometryAttemptStatus-5L_q6-9l.js";
5
- import { useEffect as I, useLayoutEffect as L, useMemo as me, useRef as R, useState as z, useSyncExternalStore as he } from "react";
6
- import { Arc as ge, Circle as B, Ellipse as _e, Group as V, Layer as ve, Line as H, Rect as U, Stage as ye, Text as W } from "react-konva";
1
+ import { B as e, G as t, H as n, M as r, N as i, Z as a, q as o, wt as s } from "./geometryState.schema-CKFPlX8j.js";
2
+ import { c, f as l, l as u } from "./goals-BlSeniyt.js";
3
+ import { $ as d, C as f, E as p, H as m, I as h, N as g, O as _, P as v, V as y, a as b, at as x, b as S, c as C, ct as w, d as T, et as E, f as D, g as O, h as k, i as A, j as ee, k as te, l as j, lt as M, m as N, n as ne, o as re, ot as P, p as ie, r as ae, rt as oe, st as F, t as se, u as ce, v as le, x as ue, y as de } from "./studentStore-CyYa0N93.js";
4
+ import { c as fe, i as pe, o as me, s as he, t as ge, u as _e } from "./exerciseLoad-DgeDXYbf.js";
5
+ import { useEffect as I, useLayoutEffect as L, useMemo as ve, useRef as R, useState as z, useSyncExternalStore as ye } from "react";
6
+ import { Arc as be, Circle as B, Ellipse as xe, Group as V, Layer as Se, Line as H, Rect as U, Stage as Ce, Text as W } from "react-konva";
7
7
  import { Fragment as G, jsx as K, jsxs as q } from "react/jsx-runtime";
8
8
  //#region src/geometry/entityCapabilities.ts
9
- var be = {
9
+ var we = {
10
10
  implicit: {
11
11
  rendered: !1,
12
12
  selectable: !1,
@@ -18,13 +18,20 @@ var be = {
18
18
  snapTarget: !0
19
19
  }
20
20
  };
21
- function xe(e) {
22
- return be[e];
21
+ function Te(e) {
22
+ return we[e];
23
+ }
24
+ function Ee(e, t) {
25
+ if (e.presentationOf(t).measureLabel !== "degrees") return;
26
+ let n = e.resolvedOf(t);
27
+ if (n?.kind !== "angle") return;
28
+ let r = Number((n.sweepTurn * 360).toFixed(0));
29
+ return `${(r >= 360 ? 0 : r).toFixed(0)}°`;
23
30
  }
24
31
  //#endregion
25
32
  //#region src/renderer/deriveRenderableGeometry.ts
26
- function Se(e) {
27
- let t = o(e.exercise), n = t.points, r = /* @__PURE__ */ new Map(), i = [];
33
+ function De(e) {
34
+ let t = c(e.exercise), n = t.points, r = /* @__PURE__ */ new Map(), i = [];
28
35
  for (let [t, a] of Object.entries(e.exercise.entities)) {
29
36
  if (a.kind !== "point") {
30
37
  i.push({
@@ -36,117 +43,131 @@ function Se(e) {
36
43
  let e = n.get(t);
37
44
  e && r.set(t, e);
38
45
  }
39
- return we(r, i, t);
46
+ return ke(r, i, t);
40
47
  }
41
- function Ce(e, t) {
42
- let n = a(e, t);
43
- return we(n.points, [...i(e, t).values()], n);
48
+ function Oe(e, t) {
49
+ let n = l(e, t);
50
+ return ke(n.points, [...u(e, t).values()], n);
44
51
  }
45
- function we(e, t, n) {
46
- let r = (e) => xe(n.presentationOf(e).role);
52
+ function ke(e, t, n) {
53
+ let r = (e) => Te(n.presentationOf(e).role), i = (e) => n.presentationOf(e).role === "explicit" ? Ee(n, e) : void 0;
47
54
  return {
48
55
  points: e,
49
56
  objects: t,
50
57
  capabilitiesOf: r,
51
58
  labelOf: (e) => {
52
59
  let t = n.presentationOf(e);
53
- return t.role === "explicit" ? t.label : void 0;
60
+ if (t.role !== "explicit") return;
61
+ let r = i(e);
62
+ return r === void 0 ? t.label : t.label === void 0 ? r : `${t.label} = ${r}`;
54
63
  },
64
+ measureOf: i,
55
65
  isSnapTarget: (e) => r(e).snapTarget
56
66
  };
57
67
  }
58
68
  //#endregion
59
69
  //#region src/renderer/useConnectionPreview.ts
60
- var Te = {
70
+ var Ae = {
61
71
  gestureFrom: null,
62
72
  pointer: null,
63
73
  snap: null
64
74
  };
65
- function Ee({ points: e, viewport: t, canvas: n, pendingObjectType: r, pendingFirstPointId: i, connect: a, pick: o, objects: c = [], isSnapTarget: l, canCreatePoints: u = !1, preserveCreatedPointOrigins: d = !0 }) {
66
- let f = R(null), p = R(null), m = R(null), [g, _] = z(Te), y = r === "segment" || r === "line", b = v(t, n), S = re(32, b), C = {
75
+ function je(t, r, i, a) {
76
+ let o = e({
77
+ kind: "angle",
78
+ parents: [
79
+ r,
80
+ i,
81
+ a
82
+ ]
83
+ }, t);
84
+ return o && n(o);
85
+ }
86
+ function Me({ points: e, viewport: t, canvas: n, pendingObjectType: r, pendingFirstPointId: i, pendingVertexPointId: a = null, connect: o, pick: s, objects: c = [], isSnapTarget: l, canCreatePoints: u = !1, preserveCreatedPointOrigins: f = !0 }) {
87
+ let p = R(null), m = R(null), h = R(null), [g, _] = z(Ae), v = r === "angle", y = v || r === "segment" || r === "line", b = P(t, n), S = w(32, b), C = {
67
88
  points: e,
68
89
  objects: c,
69
90
  viewport: t,
70
91
  isSnapTarget: l
71
- }, w = g.snap?.kind === "point" ? g.snap.targetIds[0] ?? null : null;
72
- function T() {
73
- let e = f.current;
92
+ }, T = g.snap?.kind === "point" ? g.snap.targetIds[0] ?? null : null;
93
+ function D() {
94
+ let e = p.current;
74
95
  _(e ? {
75
96
  gestureFrom: e.fromPoint,
76
97
  pointer: e.pointer,
77
- snap: m.current
98
+ snap: h.current
78
99
  } : {
79
100
  gestureFrom: null,
80
- pointer: p.current,
81
- snap: m.current
101
+ pointer: m.current,
102
+ snap: h.current
82
103
  });
83
104
  }
84
- function E(e) {
85
- return x(e, t, n, b);
105
+ function O(e) {
106
+ return M(e, t, n, b);
86
107
  }
87
- function O(t) {
108
+ function k(t) {
88
109
  return e.has(t) && (!l || l(t));
89
110
  }
90
- function k(e, t) {
91
- return h(E(e), C, {
111
+ function A(e, t) {
112
+ return d(O(e), C, {
92
113
  tolerance: S,
93
114
  exclude: t?.kind === "existing" ? [t.id] : [],
94
- kinds: u ? [
115
+ kinds: u && !v ? [
95
116
  "point",
96
117
  "intersection",
97
118
  "onObject"
98
119
  ] : ["point"]
99
120
  });
100
121
  }
101
- let A = (() => {
102
- let a = g.gestureFrom ?? (i ? e.get(i) ?? null : null), { pointer: o } = g;
103
- if (!y || !a || !o) return null;
104
- let s = g.snap ? P(g.snap.position, t, n) : o;
122
+ let ee = (() => {
123
+ let o = g.gestureFrom ?? (i ? e.get(i) ?? null : null), { pointer: s } = g;
124
+ if (!y || !o || !s || a) return null;
125
+ let c = g.snap ? F(g.snap.position, t, n) : s;
105
126
  if (r !== "line") {
106
- let e = P(a, t, n);
127
+ let e = F(o, t, n);
107
128
  return [
108
129
  e.x,
109
130
  e.y,
110
- s.x,
111
- s.y
131
+ c.x,
132
+ c.y
112
133
  ];
113
134
  }
114
- let c = D(a, E(s), t);
115
- if (!c) return null;
116
- let l = P(c[0], t, n), u = P(c[1], t, n);
135
+ let l = x(o, O(c), t);
136
+ if (!l) return null;
137
+ let u = F(l[0], t, n), d = F(l[1], t, n);
117
138
  return [
118
- l.x,
119
- l.y,
120
139
  u.x,
121
- u.y
140
+ u.y,
141
+ d.x,
142
+ d.y
122
143
  ];
123
- })();
144
+ })(), te = v && i && a && T ? je(e, i, a, T) : null;
124
145
  function j(t, n) {
125
- if (f.current = null, p.current = null, m.current = null, !y) return;
146
+ if (p.current = null, m.current = null, h.current = null, !y) return;
126
147
  if (i) {
127
148
  let n = {
128
149
  kind: "existing",
129
150
  id: i
130
151
  };
131
- f.current = {
152
+ p.current = {
132
153
  from: n,
133
- fromPoint: e.get(i) ?? E(t),
154
+ fromPoint: e.get(i) ?? O(t),
134
155
  completing: !0,
135
156
  pointer: t
136
- }, m.current = k(t, n), T();
157
+ }, h.current = A(t, n), D();
137
158
  return;
138
159
  }
139
- let r = n && O(n) ? n : null, a = E(t), o = null;
140
- if (!r && (!u || (o = h(a, C, {
160
+ let r = n && k(n) ? n : null, a = O(t), o = null;
161
+ if (!r && (!u || (o = d(a, C, {
141
162
  tolerance: S,
142
163
  kinds: [
143
164
  "point",
144
165
  "intersection",
145
166
  "onObject"
146
167
  ]
147
- }), o?.kind === "point" && (r = o.targetIds[0] ?? null, !r || !O(r))))) return;
168
+ }), o?.kind === "point" && (r = o.targetIds[0] ?? null, !r || !k(r))))) return;
148
169
  if (r) {
149
- f.current = {
170
+ p.current = {
150
171
  from: {
151
172
  kind: "existing",
152
173
  id: r
@@ -157,44 +178,45 @@ function Ee({ points: e, viewport: t, canvas: n, pendingObjectType: r, pendingFi
157
178
  };
158
179
  return;
159
180
  }
160
- let c = o?.position ?? a, l = o && d ? s({
161
- position: c,
181
+ if (v) return;
182
+ let s = o?.position ?? a, c = o && f ? E({
183
+ position: s,
162
184
  snap: o
163
185
  }) : null;
164
- f.current = {
186
+ p.current = {
165
187
  from: {
166
188
  kind: "create",
167
- origin: l ?? {
189
+ origin: c ?? {
168
190
  kind: "point",
169
- at: c
191
+ at: s
170
192
  }
171
193
  },
172
- fromPoint: c,
194
+ fromPoint: s,
173
195
  completing: !1,
174
196
  pointer: null
175
197
  };
176
198
  }
177
- function M(e) {
178
- let t = f.current;
179
- t && (m.current = k(e, t.from), f.current = {
199
+ function N(e) {
200
+ let t = p.current;
201
+ !t || v || (h.current = A(e, t.from), p.current = {
180
202
  ...t,
181
203
  pointer: e
182
- }, T());
204
+ }, D());
183
205
  }
184
- function ee(e) {
185
- if (!f.current) {
206
+ function ne(e) {
207
+ if (!p.current) {
186
208
  if (!y || !i || !e) {
187
- if (!p.current && !m.current) return;
188
- p.current = null, m.current = null, T();
209
+ if (!m.current && !h.current) return;
210
+ m.current = null, h.current = null, D();
189
211
  return;
190
212
  }
191
- p.current = e, m.current = k(e, {
213
+ m.current = e, h.current = A(e, {
192
214
  kind: "existing",
193
215
  id: i
194
- }), T();
216
+ }), D();
195
217
  }
196
218
  }
197
- function N(e, t, n) {
219
+ function re(e, t, n) {
198
220
  let r = e ? {
199
221
  kind: "existing",
200
222
  id: e
@@ -214,14 +236,14 @@ function Ee({ points: e, viewport: t, canvas: n, pendingObjectType: r, pendingFi
214
236
  } : r;
215
237
  }
216
238
  if (!u) return r;
217
- if (!d) return {
239
+ if (!f) return {
218
240
  kind: "create",
219
241
  origin: {
220
242
  kind: "point",
221
243
  at: n.position
222
244
  }
223
245
  };
224
- let i = s({
246
+ let i = E({
225
247
  position: n.position,
226
248
  snap: n
227
249
  });
@@ -230,70 +252,72 @@ function Ee({ points: e, viewport: t, canvas: n, pendingObjectType: r, pendingFi
230
252
  origin: i
231
253
  } : r;
232
254
  }
233
- function te(e, t, n) {
234
- let r = f.current;
235
- if (f.current = null, m.current = null, T(), !r || !y) return !1;
236
- let i = t && O(t) ? t : null;
255
+ function ie(e, t, n) {
256
+ let r = p.current;
257
+ if (p.current = null, h.current = null, D(), !r || !y) return !1;
258
+ let i = t && k(t) ? t : null;
237
259
  if (!n) {
238
- let t = r.completing ? i ?? ne(e) : r.from.kind === "existing" ? r.from.id : null;
239
- return t ? (o(t), !0) : !1;
260
+ let t = r.completing ? i ?? ae(e) : r.from.kind === "existing" ? r.from.id : null;
261
+ return t ? (s(t), !0) : !1;
240
262
  }
241
- let s = N(i, E(e), k(e, r.from));
242
- return s && a(r.from, s), !0;
263
+ if (v) return !0;
264
+ let a = re(i, O(e), A(e, r.from));
265
+ return a && o(r.from, a), !0;
243
266
  }
244
- function ne(e) {
245
- let t = h(E(e), C, {
267
+ function ae(e) {
268
+ let t = d(O(e), C, {
246
269
  tolerance: S,
247
270
  kinds: ["point"]
248
271
  }), n = t?.kind === "point" ? t.targetIds[0] : void 0;
249
- return n && O(n) ? n : null;
272
+ return n && k(n) ? n : null;
250
273
  }
251
- function ie() {
252
- !f.current && !p.current && !m.current || (f.current = null, p.current = null, m.current = null, T());
274
+ function oe() {
275
+ !p.current && !m.current && !h.current || (p.current = null, m.current = null, h.current = null, D());
253
276
  }
254
277
  return {
255
278
  connecting: y,
256
- previewPoints: A,
257
- snapTargetId: y ? w : null,
279
+ previewPoints: ee,
280
+ previewAngle: te,
281
+ snapTargetId: y ? T : null,
258
282
  snapPreview: y && g.snap && g.snap.kind !== "point" ? g.snap : null,
259
283
  press: j,
260
- drag: M,
261
- hover: ee,
262
- release: te,
263
- cancel: ie
284
+ drag: N,
285
+ hover: ne,
286
+ release: ie,
287
+ cancel: oe
264
288
  };
265
289
  }
266
290
  //#endregion
267
291
  //#region src/renderer/usePlacementSnap.ts
268
- function De({ points: e, objects: t, viewport: n, canvas: r, showGrid: i, isSnapTarget: a, active: o }) {
269
- let [s, c] = z(null), l = v(n, r), u = {
292
+ function Ne({ points: e, objects: t, viewport: n, canvas: r, showGrid: i, isSnapTarget: a, active: o }) {
293
+ let [s, c] = z(null), l = P(n, r), u = {
270
294
  points: e,
271
295
  objects: t,
272
296
  viewport: n,
273
297
  showGrid: i,
274
298
  isSnapTarget: a
275
- }, d = { tolerance: re(24, l) };
276
- function f(e) {
299
+ }, f = { tolerance: w(24, l) };
300
+ function p(e) {
277
301
  if (!o) {
278
302
  s && c(null);
279
303
  return;
280
304
  }
281
- c(h(x(e, n, r, l), u, d));
305
+ c(d(M(e, n, r, l), u, f));
282
306
  }
283
- function p(e) {
307
+ function m(e) {
284
308
  let t = e.target.getStage()?.getPointerPosition();
285
- t ? f(t) : !o && s && c(null);
309
+ t ? p(t) : !o && s && c(null);
286
310
  }
287
- function m() {
311
+ function h() {
288
312
  s && c(null);
289
313
  }
290
314
  function g(e) {
291
- let t = x(e, n, r, l);
315
+ let t = M(e, n, r, l);
292
316
  if (!o) return {
293
317
  position: t,
294
318
  snap: null
295
319
  };
296
- let i = h(t, u, d);
320
+ let i = d(t, u, f);
297
321
  return {
298
322
  position: i?.position ?? t,
299
323
  snap: i
@@ -301,25 +325,91 @@ function De({ points: e, objects: t, viewport: n, canvas: r, showGrid: i, isSnap
301
325
  }
302
326
  return {
303
327
  snap: o ? s : null,
304
- trackAt: f,
305
- trackPointer: p,
306
- clearPointer: m,
328
+ trackAt: p,
329
+ trackPointer: m,
330
+ clearPointer: h,
307
331
  resolvePlacement: g
308
332
  };
309
333
  }
334
+ function Pe(e) {
335
+ let t = /* @__PURE__ */ new Set();
336
+ for (let n of e) switch (n.type) {
337
+ case "create":
338
+ case "throughPoints":
339
+ case "perpendicular":
340
+ case "parallel":
341
+ case "segmentLength":
342
+ case "midpoint":
343
+ case "angleMeasure":
344
+ case "angleBisector": break;
345
+ case "givenAngle": t.add(n.angleId);
346
+ }
347
+ return t;
348
+ }
349
+ function Fe(t) {
350
+ let { scene: n, pointId: r, pointer: i, start: c, judgedAngleIds: l, isExerciseEntity: u } = t;
351
+ if (!t.free) return i;
352
+ let f = null, p = (e) => (l.has(e) ? 2 : 0) + +!!u(e);
353
+ for (let { id: t, definition: i } of n.objects) {
354
+ if (i.kind !== "angle") continue;
355
+ let [a, o, s] = i.parents;
356
+ if (o === r || a !== r && s !== r) continue;
357
+ if (f) {
358
+ let e = p(t) - p(f.id);
359
+ if (e < 0 || e === 0 && f.id < t) continue;
360
+ }
361
+ let c = e(i, n.points);
362
+ c?.kind === "angle" && (f = {
363
+ id: t,
364
+ definition: i,
365
+ resolved: c
366
+ });
367
+ }
368
+ if (!f) return d(i, n, {
369
+ tolerance: t.tolerance,
370
+ kinds: ["grid"]
371
+ })?.position ?? i;
372
+ let [m, , h] = f.definition.parents, { vertex: g, startTurn: _, sweepTurn: v } = f.resolved, y = o(g, i);
373
+ if (y === null) return null;
374
+ let b = m === r ? y : _, x = h === r ? y : _ + v, S = Math.round(a(b, x) * 360 / 1) * 1 % 360 / 360, C = m === r ? x - S : b + S, w = s(c, g), T = C * 2 * Math.PI;
375
+ return {
376
+ x: g.x + w * Math.cos(T),
377
+ y: g.y + w * Math.sin(T)
378
+ };
379
+ }
380
+ //#endregion
381
+ //#region src/renderer/dragSnap.ts
382
+ function Ie({ exercise: e, attempt: t = {}, points: n, objects: i, canvas: a }, o, s, c) {
383
+ let { viewport: l, entities: u } = e, d = P(l, a), f = r(t, o) ?? r(u, o);
384
+ return Fe({
385
+ scene: {
386
+ points: n,
387
+ objects: i,
388
+ viewport: l,
389
+ showGrid: e.showGrid
390
+ },
391
+ pointId: o,
392
+ pointer: M(s, l, a, d),
393
+ start: M(c, l, a, d),
394
+ free: f?.kind === "point" && "at" in f,
395
+ tolerance: w(24, d),
396
+ judgedAngleIds: Pe(e.goals),
397
+ isExerciseEntity: (e) => r(u, e) !== void 0
398
+ });
399
+ }
310
400
  //#endregion
311
401
  //#region src/renderer/gesturePolicy.ts
312
- function Oe(e, t, n) {
402
+ function Le(e, t, n) {
313
403
  let r = n.width > 0 && t.width / n.width || 1, i = n.height > 0 && t.height / n.height || 1;
314
404
  return {
315
405
  x: (e.x - t.left) / r,
316
406
  y: (e.y - t.top) / i
317
407
  };
318
408
  }
319
- function ke(e) {
409
+ function Re(e) {
320
410
  return e === "touch" ? 8 : 4;
321
411
  }
322
- function Ae(e, t, n) {
412
+ function ze(e, t, n) {
323
413
  return {
324
414
  pointerId: e,
325
415
  pointerType: t,
@@ -328,44 +418,44 @@ function Ae(e, t, n) {
328
418
  dragging: !1
329
419
  };
330
420
  }
331
- function je(e, t) {
421
+ function Be(e, t) {
332
422
  let n = Math.hypot(t.x - e.origin.x, t.y - e.origin.y), r = Math.max(e.maxDisplacement, n);
333
423
  return {
334
424
  ...e,
335
425
  maxDisplacement: r,
336
- dragging: e.dragging || r >= ke(e.pointerType)
426
+ dragging: e.dragging || r >= Re(e.pointerType)
337
427
  };
338
428
  }
339
- function Me(e) {
429
+ function Ve(e) {
340
430
  return e.isPrimary ? e.pointerType !== "mouse" || e.button === 0 : !1;
341
431
  }
342
- var Ne = {
432
+ var He = {
343
433
  touchAction: "none",
344
434
  userSelect: "none",
345
435
  WebkitUserSelect: "none"
346
436
  };
347
- function Pe(e, t) {
437
+ function Ue(e, t) {
348
438
  return e.x >= 0 && e.y >= 0 && e.x <= t.width && e.y <= t.height;
349
439
  }
350
- var Fe = "geometry-point-", Ie = "geometry-object-";
351
- function Le(e) {
352
- return `${Fe}${e}`;
440
+ var We = "geometry-point-", Ge = "geometry-object-";
441
+ function Ke(e) {
442
+ return `${We}${e}`;
353
443
  }
354
- function Re(e) {
355
- return `${Ie}${e}`;
444
+ function qe(e) {
445
+ return `${Ge}${e}`;
356
446
  }
357
- function ze(e) {
358
- return e.startsWith(Fe) ? {
447
+ function Je(e) {
448
+ return e.startsWith(We) ? {
359
449
  kind: "point",
360
450
  id: e.slice(15)
361
- } : e.startsWith(Ie) ? {
451
+ } : e.startsWith(Ge) ? {
362
452
  kind: "object",
363
453
  id: e.slice(16)
364
454
  } : null;
365
455
  }
366
456
  //#endregion
367
457
  //#region src/renderer/usePointerGestures.ts
368
- function Be(e, t, n, r) {
458
+ function Ye(e, t, n, r) {
369
459
  let i = R({
370
460
  handlers: r,
371
461
  canvas: t,
@@ -385,7 +475,7 @@ function Be(e, t, n, r) {
385
475
  let n = t.container();
386
476
  function r(e) {
387
477
  let n = t.content;
388
- return Oe({
478
+ return Le({
389
479
  x: e.clientX,
390
480
  y: e.clientY
391
481
  }, n.getBoundingClientRect(), {
@@ -403,7 +493,7 @@ function Be(e, t, n, r) {
403
493
  function l(e) {
404
494
  let n = t.getIntersection(e);
405
495
  if (!n) return { kind: "stage" };
406
- let r = ze(n.id());
496
+ let r = Je(n.id());
407
497
  return r?.kind === "point" && !i.current.handlers.pointOnScreen(r.id) ? { kind: "foreign" } : r ?? { kind: "foreign" };
408
498
  }
409
499
  function u(e) {
@@ -430,15 +520,15 @@ function Be(e, t, n, r) {
430
520
  return !t || t.pointerId !== e.pointerId ? null : p(t) ? (f("invalidated"), null) : t;
431
521
  }
432
522
  function h(e) {
433
- if (a.current || !Me(e) || c.size > 1) return;
523
+ if (a.current || !Ve(e) || c.size > 1) return;
434
524
  let t = r(e), o = l(t);
435
525
  if (o.kind === "foreign") return;
436
- let { handlers: u, store: d } = i.current, f = u.tool === "segment" || u.tool === "line" ? "connect" : o.kind, p = f === "point" && o.kind === "point" && u.canDragPoint(o.id) ? u.pointOnScreen(o.id) : null, m = !1;
526
+ let { handlers: u, store: d } = i.current, f = u.tool === "segment" || u.tool === "line" || u.tool === "angle" ? "connect" : o.kind, p = f === "point" && o.kind === "point" && u.canDragPoint(o.id) ? u.pointOnScreen(o.id) : null, m = !1;
437
527
  try {
438
528
  n.setPointerCapture(e.pointerId), m = !0;
439
529
  } catch {}
440
530
  a.current = {
441
- ...Ae(e.pointerId, e.pointerType, s(e)),
531
+ ...ze(e.pointerId, e.pointerType, s(e)),
442
532
  store: d,
443
533
  epoch: d.getState().interactionEpoch ?? 0,
444
534
  handlers: u,
@@ -464,24 +554,24 @@ function Be(e, t, n, r) {
464
554
  if (!t) return;
465
555
  let n = r(e), o = {
466
556
  ...t,
467
- ...je(t, s(e))
557
+ ...Be(t, s(e))
468
558
  };
469
559
  if (a.current = o, !o.dragging) return;
470
560
  let { handlers: l } = i.current;
471
561
  o.role === "connect" ? l.connection.drag(n) : o.role === "point" && o.dragFrom ? l.dragPoint(o.target.id, {
472
562
  x: o.dragFrom.x + n.x - o.stageOrigin.x,
473
563
  y: o.dragFrom.y + n.y - o.stageOrigin.y
474
- }) : o.role === "stage" && !t.dragging && l.placement.clearPointer();
564
+ }, o.dragFrom) : o.role === "stage" && !t.dragging && l.placement.clearPointer();
475
565
  }
476
566
  function y(e) {
477
567
  let t = m(e);
478
568
  if (!t) return;
479
569
  let n = r(e);
480
- if (!Pe(n, i.current.canvas)) {
570
+ if (!Ue(n, i.current.canvas)) {
481
571
  f("outside-release");
482
572
  return;
483
573
  }
484
- let { dragging: a } = je(t, s(e));
574
+ let { dragging: a } = Be(t, s(e));
485
575
  d(t);
486
576
  let { handlers: o } = i.current, { target: c } = t;
487
577
  switch (t.role) {
@@ -546,20 +636,20 @@ function Be(e, t, n, r) {
546
636
  }
547
637
  //#endregion
548
638
  //#region src/renderer/shapes/SnapMarker.tsx
549
- var Ve = "#786af5", He = {
639
+ var Xe = "#786af5", Ze = {
550
640
  point: "point",
551
641
  intersection: "intersection",
552
642
  grid: "grid",
553
643
  onObject: "on object"
554
644
  };
555
- function Ue({ snap: e, viewport: t, canvas: n }) {
556
- let r = P(e.position, t, n);
645
+ function Qe({ snap: e, viewport: t, canvas: n }) {
646
+ let r = F(e.position, t, n);
557
647
  return /* @__PURE__ */ q(G, { children: [
558
648
  /* @__PURE__ */ K(B, {
559
649
  x: r.x,
560
650
  y: r.y,
561
651
  radius: 12,
562
- stroke: Ve,
652
+ stroke: Xe,
563
653
  strokeWidth: 2,
564
654
  dash: [4, 3],
565
655
  listening: !1
@@ -568,25 +658,25 @@ function Ue({ snap: e, viewport: t, canvas: n }) {
568
658
  x: r.x,
569
659
  y: r.y,
570
660
  radius: 3.5,
571
- fill: Ve,
661
+ fill: Xe,
572
662
  listening: !1
573
663
  }),
574
664
  /* @__PURE__ */ K(W, {
575
665
  x: r.x + 15,
576
666
  y: r.y + 8,
577
- text: He[e.kind],
667
+ text: Ze[e.kind],
578
668
  fontSize: 13,
579
669
  fontStyle: "bold",
580
- fill: Ve,
670
+ fill: Xe,
581
671
  listening: !1
582
672
  })
583
673
  ] });
584
674
  }
585
675
  //#endregion
586
676
  //#region src/renderer/shapes/PointShape.tsx
587
- var We = 22;
677
+ var $e = 22;
588
678
  function J({ id: e, position: t, viewport: n, canvas: r, selected: i = !1, connectable: a = !1, snapTarget: o = !1, label: s, color: c = "#24304a", feedbackRingColor: l, feedbackRingDashed: u = !1 }) {
589
- let d = P(t, n, r), f = o || i ? 13 : a ? 10 : 9;
679
+ let d = F(t, n, r), f = o || i ? 13 : a ? 10 : 9;
590
680
  return /* @__PURE__ */ q(G, { children: [
591
681
  l && /* @__PURE__ */ K(B, {
592
682
  x: d.x,
@@ -609,14 +699,14 @@ function J({ id: e, position: t, viewport: n, canvas: r, selected: i = !1, conne
609
699
  listening: !1
610
700
  }),
611
701
  /* @__PURE__ */ K(B, {
612
- id: Le(e),
702
+ id: Ke(e),
613
703
  x: d.x,
614
704
  y: d.y,
615
705
  radius: f,
616
706
  fill: o || i ? "#6d5dfc" : c,
617
707
  stroke: a && !i && !o ? "#a69df8" : "#fff",
618
708
  strokeWidth: 3,
619
- hitStrokeWidth: 2 * (We - f),
709
+ hitStrokeWidth: 2 * ($e - f),
620
710
  shadowColor: "#24304a",
621
711
  shadowBlur: i ? 12 : 4
622
712
  }),
@@ -633,10 +723,10 @@ function J({ id: e, position: t, viewport: n, canvas: r, selected: i = !1, conne
633
723
  }
634
724
  //#endregion
635
725
  //#region src/renderer/shapes/StrokedLine.tsx
636
- var Ge = 44;
637
- function Ke({ id: e, a: t, b: n, color: r, strokeWidth: i, dashed: a, selected: o, opacity: s, listening: c }) {
726
+ var et = 44;
727
+ function tt({ id: e, a: t, b: n, color: r, strokeWidth: i, dashed: a, selected: o, opacity: s, listening: c }) {
638
728
  return /* @__PURE__ */ K(H, {
639
- id: Re(e),
729
+ id: qe(e),
640
730
  points: [
641
731
  t.x,
642
732
  t.y,
@@ -647,16 +737,16 @@ function Ke({ id: e, a: t, b: n, color: r, strokeWidth: i, dashed: a, selected:
647
737
  strokeWidth: o ? i + 3 : i,
648
738
  lineCap: "round",
649
739
  dash: a ? [10, 6] : void 0,
650
- hitStrokeWidth: Ge,
740
+ hitStrokeWidth: et,
651
741
  opacity: s,
652
742
  listening: c
653
743
  });
654
744
  }
655
745
  //#endregion
656
746
  //#region src/renderer/shapes/SegmentShape.tsx
657
- function qe({ id: e, from: t, to: n, viewport: r, canvas: i, color: a = "#6d5dfc", strokeWidth: o = 5, dashed: s = !1, selected: c = !1, opacity: l = 1, listening: u = !0 }) {
658
- let d = P(t, r, i), f = P(n, r, i);
659
- return /* @__PURE__ */ K(Ke, {
747
+ function nt({ id: e, from: t, to: n, viewport: r, canvas: i, color: a = "#6d5dfc", strokeWidth: o = 5, dashed: s = !1, selected: c = !1, opacity: l = 1, listening: u = !0 }) {
748
+ let d = F(t, r, i), f = F(n, r, i);
749
+ return /* @__PURE__ */ K(tt, {
660
750
  id: e,
661
751
  a: d,
662
752
  b: f,
@@ -670,11 +760,11 @@ function qe({ id: e, from: t, to: n, viewport: r, canvas: i, color: a = "#6d5dfc
670
760
  }
671
761
  //#endregion
672
762
  //#region src/renderer/shapes/LineShape.tsx
673
- function Je({ id: e, through: t, viewport: n, canvas: r, color: i = "#6d5dfc", strokeWidth: a = 4, dashed: o = !1, selected: s = !1, opacity: c = 1, listening: l = !0 }) {
674
- let u = D(t[0], t[1], n);
763
+ function rt({ id: e, through: t, viewport: n, canvas: r, color: i = "#6d5dfc", strokeWidth: a = 4, dashed: o = !1, selected: s = !1, opacity: c = 1, listening: l = !0 }) {
764
+ let u = x(t[0], t[1], n);
675
765
  if (!u) return null;
676
- let d = P(u[0], n, r), f = P(u[1], n, r);
677
- return /* @__PURE__ */ K(Ke, {
766
+ let d = F(u[0], n, r), f = F(u[1], n, r);
767
+ return /* @__PURE__ */ K(tt, {
678
768
  id: e,
679
769
  a: d,
680
770
  b: f,
@@ -687,12 +777,50 @@ function Je({ id: e, through: t, viewport: n, canvas: r, color: i = "#6d5dfc", s
687
777
  });
688
778
  }
689
779
  //#endregion
780
+ //#region src/renderer/shapes/AngleShape.tsx
781
+ var it = 44, at = 48;
782
+ function ot({ id: e, vertex: n, startTurn: r, sweepTurn: i, radius: a, viewport: o, canvas: s, color: c = "#6d5dfc", strokeWidth: l = 4, dashed: u = !1, selected: d = !1, opacity: f = 1, listening: p = !0 }) {
783
+ let m = [], h = (e) => {
784
+ let t = F(e, o, s);
785
+ m.push(t.x, t.y);
786
+ }, g = (e, t) => ({
787
+ x: t * Math.cos(2 * Math.PI * e),
788
+ y: t * Math.sin(2 * Math.PI * e)
789
+ }), _ = t({
790
+ vertex: n,
791
+ startTurn: r,
792
+ sweepTurn: i,
793
+ markRadius: a
794
+ });
795
+ if (_) _.forEach(h);
796
+ else for (let e = 0; e <= at; e += 1) {
797
+ let t = g(r + i * e / at, a);
798
+ h({
799
+ x: n.x + t.x,
800
+ y: n.y + t.y
801
+ });
802
+ }
803
+ return /* @__PURE__ */ K(H, {
804
+ id: qe(e),
805
+ points: m,
806
+ stroke: c,
807
+ strokeWidth: d ? l + 3 : l,
808
+ dash: u ? [10, 6] : void 0,
809
+ hitStrokeWidth: it,
810
+ opacity: f,
811
+ listening: p,
812
+ lineCap: "round",
813
+ lineJoin: "round",
814
+ closed: !1
815
+ });
816
+ }
817
+ //#endregion
690
818
  //#region src/renderer/shapes/CircleShape.tsx
691
- var Ye = 44;
692
- function Xe({ id: e, center: t, radius: n, viewport: r, canvas: i, color: a = "#6d5dfc", strokeWidth: o = 4, dashed: s = !1, selected: c = !1, opacity: l = 1, listening: u = !0 }) {
693
- let d = v(r, i), f = P(t, r, i, d);
694
- return /* @__PURE__ */ K(_e, {
695
- id: Re(e),
819
+ var st = 44;
820
+ function ct({ id: e, center: t, radius: n, viewport: r, canvas: i, color: a = "#6d5dfc", strokeWidth: o = 4, dashed: s = !1, selected: c = !1, opacity: l = 1, listening: u = !0 }) {
821
+ let d = P(r, i), f = F(t, r, i, d);
822
+ return /* @__PURE__ */ K(xe, {
823
+ id: qe(e),
696
824
  x: f.x,
697
825
  y: f.y,
698
826
  radiusX: n * d.scaleX,
@@ -700,45 +828,72 @@ function Xe({ id: e, center: t, radius: n, viewport: r, canvas: i, color: a = "#
700
828
  stroke: a,
701
829
  strokeWidth: c ? o + 3 : o,
702
830
  dash: s ? [10, 6] : void 0,
703
- hitStrokeWidth: Ye,
831
+ hitStrokeWidth: st,
704
832
  opacity: l,
705
833
  listening: u
706
834
  });
707
835
  }
708
836
  //#endregion
709
837
  //#region src/renderer/shapes/EntityLabel.tsx
710
- var Ze = {
838
+ var lt = {
711
839
  point: () => null,
712
- segment: (e) => et(e.from, e.to),
840
+ segment: (e) => pt(e.from, e.to),
713
841
  line: (e, t) => {
714
- let n = D(e.through[0], e.through[1], t);
715
- return n ? et(n[0], n[1]) : null;
842
+ let n = x(e.through[0], e.through[1], t);
843
+ return n ? pt(n[0], n[1]) : null;
716
844
  },
717
845
  circle: (e) => ({
718
846
  x: e.center.x,
719
847
  y: e.center.y + e.radius
720
- })
848
+ }),
849
+ angle: (e) => {
850
+ let t = 2 * Math.PI * (e.startTurn + e.sweepTurn / 2);
851
+ return {
852
+ x: e.vertex.x + e.radius * Math.cos(t),
853
+ y: e.vertex.y + e.radius * Math.sin(t)
854
+ };
855
+ }
721
856
  };
722
- function Qe(e, t) {
723
- let n = Ze[e.shape];
857
+ function ut(e, t) {
858
+ let n = lt[e.shape];
724
859
  return n(e, t);
725
860
  }
726
- function $e({ text: e, descriptor: t, viewport: n, canvas: r, color: i = "#24304a", opacity: a = 1 }) {
727
- let o = Qe(t, n);
728
- if (!o) return null;
729
- let s = P(o, n, r);
730
- return /* @__PURE__ */ K(W, {
731
- x: s.x + 10,
732
- y: s.y - 24,
861
+ function dt({ text: e, measured: t = !1, descriptor: n, viewport: r, canvas: i, color: a = "#24304a", opacity: o = 1 }) {
862
+ let s = ut(n, r);
863
+ if (!s) return null;
864
+ let c = F(s, r, i), l = {
733
865
  text: e,
734
866
  fontSize: 18,
735
867
  fontStyle: "bold",
736
- fill: i,
737
- opacity: a,
868
+ fill: a,
869
+ opacity: o,
738
870
  listening: !1
871
+ };
872
+ if (t && n.shape === "angle") {
873
+ let e = F(n.vertex, r, i), t = 2 * Math.PI * (n.startTurn + n.sweepTurn / 2), a = F({
874
+ x: n.vertex.x + Math.cos(t),
875
+ y: n.vertex.y + Math.sin(t)
876
+ }, r, i), o = Math.hypot(a.x - e.x, a.y - e.y);
877
+ return /* @__PURE__ */ K(W, {
878
+ ...l,
879
+ x: c.x + (a.x - e.x) / o * 40,
880
+ y: c.y + (a.y - e.y) / o * 40,
881
+ ref: (e) => ft(e)
882
+ });
883
+ }
884
+ return /* @__PURE__ */ K(W, {
885
+ ...l,
886
+ x: c.x + 10,
887
+ y: c.y - 24
888
+ });
889
+ }
890
+ function ft(e) {
891
+ e?.offset({
892
+ x: e.width() / 2,
893
+ y: e.height() / 2
739
894
  });
740
895
  }
741
- function et(e, t) {
896
+ function pt(e, t) {
742
897
  return {
743
898
  x: (e.x + t.x) / 2,
744
899
  y: (e.y + t.y) / 2
@@ -746,47 +901,55 @@ function et(e, t) {
746
901
  }
747
902
  //#endregion
748
903
  //#region src/renderer/shapes/EntityShape.tsx
749
- var tt = {
904
+ var mt = {
750
905
  point: () => null,
751
- segment: (e, t) => /* @__PURE__ */ K(qe, {
906
+ segment: (e, t) => /* @__PURE__ */ K(nt, {
752
907
  ...t,
753
908
  from: e.from,
754
909
  to: e.to
755
910
  }),
756
- line: (e, t) => /* @__PURE__ */ K(Je, {
911
+ line: (e, t) => /* @__PURE__ */ K(rt, {
757
912
  ...t,
758
913
  through: [e.through[0], e.through[1]]
759
914
  }),
760
- circle: (e, t) => /* @__PURE__ */ K(Xe, {
915
+ circle: (e, t) => /* @__PURE__ */ K(ct, {
761
916
  ...t,
762
917
  center: e.center,
763
918
  radius: e.radius
919
+ }),
920
+ angle: (e, t) => /* @__PURE__ */ K(ot, {
921
+ ...t,
922
+ vertex: e.vertex,
923
+ startTurn: e.startTurn,
924
+ sweepTurn: e.sweepTurn,
925
+ radius: e.radius
764
926
  })
765
927
  };
766
- function nt({ descriptor: e, label: t, ...n }) {
767
- let r = tt[e.shape], i = r(e, n);
768
- return !i || t === void 0 ? i : /* @__PURE__ */ q(G, { children: [i, /* @__PURE__ */ K($e, {
928
+ function Y({ descriptor: e, label: t, measured: n, ...r }) {
929
+ let i = mt[e.shape], a = i(e, r);
930
+ return !a || t === void 0 ? a : /* @__PURE__ */ q(G, { children: [a, /* @__PURE__ */ K(dt, {
769
931
  text: t,
932
+ measured: n,
770
933
  descriptor: e,
771
- viewport: n.viewport,
772
- canvas: n.canvas,
773
- color: n.color,
774
- opacity: n.opacity
934
+ viewport: r.viewport,
935
+ canvas: r.canvas,
936
+ color: r.color,
937
+ opacity: r.opacity
775
938
  })] });
776
939
  }
777
940
  //#endregion
778
941
  //#region src/renderer/GeometryGrid.tsx
779
- function rt({ viewport: e, canvas: t, visible: n }) {
780
- let [r, i, a, o] = e, s = v(e, t), c = P({
942
+ function ht({ viewport: e, canvas: t, visible: n }) {
943
+ let [r, i, a, o] = e, s = P(e, t), c = F({
781
944
  x: r,
782
945
  y: o
783
- }, e, t, s), l = P({
946
+ }, e, t, s), l = F({
784
947
  x: a,
785
948
  y: i
786
- }, e, t, s), { x: u, y: d } = ee(e), f = [], p = [];
949
+ }, e, t, s), { x: u, y: d } = oe(e), f = [], p = [];
787
950
  if (n) {
788
951
  for (let n = Math.ceil(r / u) * u; n <= a; n += u) {
789
- let r = P({
952
+ let r = F({
790
953
  x: n,
791
954
  y: 0
792
955
  }, e, t, s);
@@ -803,7 +966,7 @@ function rt({ viewport: e, canvas: t, visible: n }) {
803
966
  }, `grid-x-${n}`));
804
967
  }
805
968
  for (let n = Math.ceil(i / d) * d; n <= o; n += d) {
806
- let r = P({
969
+ let r = F({
807
970
  x: 0,
808
971
  y: n
809
972
  }, e, t, s);
@@ -836,8 +999,8 @@ function rt({ viewport: e, canvas: t, visible: n }) {
836
999
  }
837
1000
  //#endregion
838
1001
  //#region src/renderer/GeometryInstruments.tsx
839
- var Y = "#5b6b82", it = "rgba(211, 225, 242, 0.58)", X = "#6558e8";
840
- function at(e, t) {
1002
+ var X = "#5b6b82", gt = "rgba(211, 225, 242, 0.58)", Z = "#6558e8";
1003
+ function _t(e, t) {
841
1004
  return e === "ruler" ? {
842
1005
  x: t.width * .5,
843
1006
  y: t.height * .72,
@@ -855,7 +1018,7 @@ function at(e, t) {
855
1018
  flipped: !1
856
1019
  };
857
1020
  }
858
- function ot() {
1021
+ function vt() {
859
1022
  let e = Array.from({ length: 21 }, (e, t) => t);
860
1023
  return /* @__PURE__ */ q(V, {
861
1024
  listening: !1,
@@ -866,8 +1029,8 @@ function ot() {
866
1029
  width: 300,
867
1030
  height: 60,
868
1031
  cornerRadius: 5,
869
- fill: it,
870
- stroke: Y,
1032
+ fill: gt,
1033
+ stroke: X,
871
1034
  strokeWidth: 2
872
1035
  }),
873
1036
  e.map((e) => {
@@ -879,7 +1042,7 @@ function ot() {
879
1042
  t,
880
1043
  -29 + (n ? 17 : 10)
881
1044
  ],
882
- stroke: Y,
1045
+ stroke: X,
883
1046
  strokeWidth: n ? 1.5 : 1
884
1047
  }, e);
885
1048
  }),
@@ -890,12 +1053,12 @@ function ot() {
890
1053
  align: "center",
891
1054
  text: String(e / 2),
892
1055
  fontSize: 10,
893
- fill: Y
1056
+ fill: X
894
1057
  }, `label-${e}`))
895
1058
  ]
896
1059
  });
897
1060
  }
898
- function st() {
1061
+ function yt() {
899
1062
  return /* @__PURE__ */ q(V, {
900
1063
  listening: !1,
901
1064
  children: [
@@ -909,8 +1072,8 @@ function st() {
909
1072
  -75
910
1073
  ],
911
1074
  closed: !0,
912
- fill: it,
913
- stroke: Y,
1075
+ fill: gt,
1076
+ stroke: X,
914
1077
  strokeWidth: 2,
915
1078
  lineJoin: "round"
916
1079
  }),
@@ -925,7 +1088,7 @@ function st() {
925
1088
  ],
926
1089
  closed: !0,
927
1090
  fill: "#fbfcff",
928
- stroke: Y,
1091
+ stroke: X,
929
1092
  strokeWidth: 1.5,
930
1093
  lineJoin: "round"
931
1094
  }),
@@ -936,26 +1099,26 @@ function st() {
936
1099
  -91 + t * 18,
937
1100
  t % 5 == 0 ? 54 : 60
938
1101
  ],
939
- stroke: Y,
1102
+ stroke: X,
940
1103
  strokeWidth: 1
941
1104
  }, t))
942
1105
  ]
943
1106
  });
944
1107
  }
945
- function ct() {
1108
+ function bt() {
946
1109
  let e = Array.from({ length: 37 }, (e, t) => t * 5);
947
1110
  return /* @__PURE__ */ q(V, {
948
1111
  listening: !1,
949
1112
  children: [
950
- /* @__PURE__ */ K(ge, {
1113
+ /* @__PURE__ */ K(be, {
951
1114
  x: 0,
952
1115
  y: 0,
953
1116
  innerRadius: 38,
954
1117
  outerRadius: 112,
955
1118
  angle: 180,
956
1119
  rotation: 180,
957
- fill: it,
958
- stroke: Y,
1120
+ fill: gt,
1121
+ stroke: X,
959
1122
  strokeWidth: 2
960
1123
  }),
961
1124
  /* @__PURE__ */ K(H, {
@@ -965,7 +1128,7 @@ function ct() {
965
1128
  112,
966
1129
  0
967
1130
  ],
968
- stroke: Y,
1131
+ stroke: X,
969
1132
  strokeWidth: 2
970
1133
  }),
971
1134
  e.map((e) => {
@@ -977,7 +1140,7 @@ function ct() {
977
1140
  Math.cos(Math.PI - t) * r,
978
1141
  -Math.sin(t) * r
979
1142
  ],
980
- stroke: Y,
1143
+ stroke: X,
981
1144
  strokeWidth: n ? 1.4 : .8
982
1145
  }, e);
983
1146
  }),
@@ -985,22 +1148,22 @@ function ct() {
985
1148
  x: 0,
986
1149
  y: 0,
987
1150
  radius: 3,
988
- fill: Y
1151
+ fill: X
989
1152
  })
990
1153
  ]
991
1154
  });
992
1155
  }
993
- function lt({ tool: e }) {
994
- return K(e === "ruler" ? ot : e === "setSquare" ? st : ct, {});
1156
+ function xt({ tool: e }) {
1157
+ return K(e === "ruler" ? vt : e === "setSquare" ? yt : bt, {});
995
1158
  }
996
- function ut(e, t, n) {
1159
+ function St(e, t, n) {
997
1160
  let r = n * Math.PI / 180;
998
1161
  return {
999
1162
  x: e * Math.cos(r) - t * Math.sin(r),
1000
1163
  y: e * Math.sin(r) + t * Math.cos(r)
1001
1164
  };
1002
1165
  }
1003
- function dt(e, t) {
1166
+ function Ct(e, t) {
1004
1167
  let n = e === "ruler" ? {
1005
1168
  x: 0,
1006
1169
  y: 19
@@ -1016,22 +1179,22 @@ function dt(e, t) {
1016
1179
  y: n.y
1017
1180
  };
1018
1181
  }
1019
- function ft({ tools: e, canvas: t }) {
1020
- let [n, r] = z(() => Object.fromEntries(e.map((e) => [e, at(e, t)]))), [i, a] = z(null), o = i && e.includes(i) ? i : null;
1182
+ function wt({ tools: e, canvas: t }) {
1183
+ let [n, r] = z(() => Object.fromEntries(e.map((e) => [e, _t(e, t)]))), [i, a] = z(null), o = i && e.includes(i) ? i : null;
1021
1184
  function s(e, n) {
1022
1185
  r((r) => ({
1023
1186
  ...r,
1024
1187
  [e]: {
1025
- ...r[e] ?? at(e, t),
1188
+ ...r[e] ?? _t(e, t),
1026
1189
  ...n
1027
1190
  }
1028
1191
  }));
1029
1192
  }
1030
1193
  return /* @__PURE__ */ K(G, { children: e.map((e) => {
1031
- let r = n[e] ?? at(e, t), i = o === e, c = dt(e, r.flipped), l = ut(c.x, c.y, r.rotation), u = {
1194
+ let r = n[e] ?? _t(e, t), i = o === e, c = Ct(e, r.flipped), l = St(c.x, c.y, r.rotation), u = {
1032
1195
  x: r.x + l.x,
1033
1196
  y: r.y + l.y
1034
- }, d = ut(0, -105, r.rotation), f = ut(0, e === "setSquare" ? 96 : e === "ruler" ? 50 : 48, r.rotation);
1197
+ }, d = St(0, -105, r.rotation), f = St(0, e === "setSquare" ? 96 : e === "ruler" ? 50 : 48, r.rotation);
1035
1198
  return /* @__PURE__ */ q(V, { children: [
1036
1199
  /* @__PURE__ */ K(V, {
1037
1200
  x: r.x,
@@ -1039,7 +1202,7 @@ function ft({ tools: e, canvas: t }) {
1039
1202
  rotation: r.rotation,
1040
1203
  scaleX: r.flipped ? -1 : 1,
1041
1204
  listening: !1,
1042
- children: /* @__PURE__ */ K(lt, { tool: e })
1205
+ children: /* @__PURE__ */ K(xt, { tool: e })
1043
1206
  }),
1044
1207
  i && /* @__PURE__ */ q(G, { children: [
1045
1208
  /* @__PURE__ */ K(H, {
@@ -1049,7 +1212,7 @@ function ft({ tools: e, canvas: t }) {
1049
1212
  r.x + d.x,
1050
1213
  r.y + d.y
1051
1214
  ],
1052
- stroke: X,
1215
+ stroke: Z,
1053
1216
  strokeWidth: 1.5,
1054
1217
  dash: [4, 4],
1055
1218
  listening: !1
@@ -1059,7 +1222,7 @@ function ft({ tools: e, canvas: t }) {
1059
1222
  y: r.y + d.y,
1060
1223
  radius: 11,
1061
1224
  fill: "#fff",
1062
- stroke: X,
1225
+ stroke: Z,
1063
1226
  strokeWidth: 2.5,
1064
1227
  draggable: !0,
1065
1228
  onDragMove: (t) => {
@@ -1083,7 +1246,7 @@ function ft({ tools: e, canvas: t }) {
1083
1246
  verticalAlign: "middle",
1084
1247
  fontSize: 14,
1085
1248
  fontStyle: "bold",
1086
- fill: X,
1249
+ fill: Z,
1087
1250
  listening: !1
1088
1251
  }),
1089
1252
  /* @__PURE__ */ K(U, {
@@ -1093,7 +1256,7 @@ function ft({ tools: e, canvas: t }) {
1093
1256
  height: 22,
1094
1257
  cornerRadius: 11,
1095
1258
  fill: "#fff",
1096
- stroke: X,
1259
+ stroke: Z,
1097
1260
  strokeWidth: 1.5,
1098
1261
  onClick: (t) => {
1099
1262
  t.cancelBubble = !0, s(e, { flipped: !r.flipped });
@@ -1112,7 +1275,7 @@ function ft({ tools: e, canvas: t }) {
1112
1275
  verticalAlign: "middle",
1113
1276
  fontSize: 10,
1114
1277
  fontStyle: "600",
1115
- fill: X,
1278
+ fill: Z,
1116
1279
  listening: !1
1117
1280
  })
1118
1281
  ] }),
@@ -1122,7 +1285,7 @@ function ft({ tools: e, canvas: t }) {
1122
1285
  y: u.y,
1123
1286
  radius: i ? 8 : 12,
1124
1287
  fill: i ? "rgba(255, 255, 255, 0.94)" : "rgba(255, 255, 255, 0.01)",
1125
- stroke: X,
1288
+ stroke: Z,
1126
1289
  strokeWidth: i ? 1.5 : 0,
1127
1290
  shadowColor: "#24304a",
1128
1291
  shadowBlur: i ? 2 : 0,
@@ -1161,13 +1324,13 @@ function ft({ tools: e, canvas: t }) {
1161
1324
  verticalAlign: "middle",
1162
1325
  fontSize: 9,
1163
1326
  fontStyle: "bold",
1164
- fill: X,
1327
+ fill: Z,
1165
1328
  listening: !1
1166
1329
  }) : /* @__PURE__ */ K(B, {
1167
1330
  x: u.x,
1168
1331
  y: u.y,
1169
1332
  radius: 2.5,
1170
- fill: Y,
1333
+ fill: X,
1171
1334
  opacity: .65,
1172
1335
  listening: !1
1173
1336
  })
@@ -1176,169 +1339,207 @@ function ft({ tools: e, canvas: t }) {
1176
1339
  }
1177
1340
  //#endregion
1178
1341
  //#region src/store/useStoreState.ts
1179
- function Z(e) {
1180
- return he((t) => e.subscribe(t), () => e.getState());
1342
+ function Q(e) {
1343
+ return ye((t) => e.subscribe(t), () => e.getState());
1181
1344
  }
1182
1345
  //#endregion
1183
1346
  //#region src/renderer/GeometryCanvas.tsx
1184
- function pt({ store: t, size: r, onExerciseChange: i, onGivenSelect: a, highlightedGivenIds: o = [], goalPreviews: h = [] }) {
1185
- let _ = Z(t), { points: v, objects: y, capabilitiesOf: b, labelOf: S, isSnapTarget: C } = Se(_), { viewport: w } = _.exercise, T = R(null), E = Ee({
1186
- points: v,
1187
- viewport: w,
1347
+ function Tt({ store: t, size: r, onExerciseChange: i, onGivenSelect: a, highlightedGivenIds: o = [], goalPreviews: s = [] }) {
1348
+ let c = Q(t), { points: l, objects: u, capabilitiesOf: d, labelOf: b, measureOf: x, isSnapTarget: S } = De(c), { viewport: C } = c.exercise, w = R(null), T = Me({
1349
+ points: l,
1350
+ viewport: C,
1188
1351
  canvas: r,
1189
- pendingObjectType: _.pendingObjectType,
1190
- pendingFirstPointId: _.pendingFirstPointId,
1352
+ pendingObjectType: c.pendingObjectType,
1353
+ pendingFirstPointId: c.pendingFirstPointId,
1354
+ pendingVertexPointId: c.pendingVertexPointId,
1191
1355
  connect: (e, n) => {
1192
- (_.pendingObjectType === "segment" || _.pendingObjectType === "line") && k(t, {
1193
- tool: _.pendingObjectType,
1356
+ (c.pendingObjectType === "segment" || c.pendingObjectType === "line") && te(t, {
1357
+ tool: c.pendingObjectType,
1194
1358
  from: e,
1195
1359
  to: n
1196
1360
  });
1197
1361
  },
1198
1362
  pick: (e) => {
1199
- m(t, e), a?.(e);
1363
+ v(t, e), a?.(e);
1200
1364
  },
1201
- objects: y,
1202
- isSnapTarget: C,
1365
+ objects: u,
1366
+ isSnapTarget: S,
1203
1367
  canCreatePoints: !0,
1204
1368
  preserveCreatedPointOrigins: !1
1205
- }), { connecting: D, previewPoints: A, snapTargetId: j } = E, M = De({
1206
- points: v,
1207
- objects: y,
1208
- viewport: w,
1369
+ }), { connecting: D, previewPoints: O, previewAngle: k, snapTargetId: A } = T, j = Ne({
1370
+ points: l,
1371
+ objects: u,
1372
+ viewport: C,
1209
1373
  canvas: r,
1210
- showGrid: !!_.exercise.showGrid,
1211
- isSnapTarget: C,
1212
- active: _.pendingObjectType === "point"
1374
+ showGrid: !!c.exercise.showGrid,
1375
+ isSnapTarget: S,
1376
+ active: c.pendingObjectType === "point"
1213
1377
  });
1214
1378
  I(() => {
1215
1379
  if (i) return t.subscribe((e) => i(e.exercise));
1216
1380
  }, [t, i]);
1217
- function ee(e) {
1218
- if (_.pendingObjectType !== "point") {
1219
- g(t, null);
1381
+ function M(e) {
1382
+ if (c.pendingObjectType !== "point") {
1383
+ y(t, null);
1220
1384
  return;
1221
1385
  }
1222
- let n = M.resolvePlacement(e);
1386
+ let n = j.resolvePlacement(e);
1223
1387
  if (n.snap?.kind === "point") {
1224
1388
  let e = n.snap.targetIds[0];
1225
- e && d(t, e);
1389
+ e && h(t, e);
1226
1390
  return;
1227
1391
  }
1228
- let r = s(n);
1229
- r && c(t, r, "at" in r);
1392
+ let r = E(n);
1393
+ r && f(t, r, "at" in r);
1230
1394
  }
1231
1395
  function N(e) {
1232
- g(t, e), a?.(e);
1396
+ y(t, e), a?.(e);
1233
1397
  }
1234
- return Be(T, r, t, {
1235
- tool: _.pendingObjectType,
1236
- connection: E,
1237
- placement: M,
1398
+ return Ye(w, r, t, {
1399
+ tool: c.pendingObjectType,
1400
+ connection: T,
1401
+ placement: j,
1238
1402
  pointOnScreen: (e) => {
1239
- let t = v.get(e);
1240
- return t ? P(t, w, r) : null;
1403
+ let t = l.get(e);
1404
+ return t ? F(t, C, r) : null;
1241
1405
  },
1242
- canDragPoint: (e) => O(_, e),
1243
- dragPoint: (e, n) => f(t, e, x(n, w, r)),
1244
- endPointDrag: () => p(t),
1406
+ canDragPoint: (e) => ee(c, e),
1407
+ dragPoint: (e, n, i) => {
1408
+ let a = Ie({
1409
+ exercise: c.exercise,
1410
+ points: l,
1411
+ objects: u,
1412
+ canvas: r
1413
+ }, e, n, i);
1414
+ a && g(t, e, a);
1415
+ },
1416
+ endPointDrag: () => _(t),
1245
1417
  tapPoint: (e) => {
1246
- b(e).selectable && N(e);
1418
+ d(e).selectable && N(e);
1247
1419
  },
1248
1420
  tapObject: N,
1249
- tapStage: ee,
1250
- abandonConstruction: () => l(t),
1251
- disarmTool: () => u(t, null)
1252
- }), /* @__PURE__ */ K(ye, {
1253
- ref: T,
1421
+ tapStage: M,
1422
+ abandonConstruction: () => p(t),
1423
+ disarmTool: () => m(t, null)
1424
+ }), /* @__PURE__ */ K(Ce, {
1425
+ ref: w,
1254
1426
  width: r.width,
1255
1427
  height: r.height,
1256
1428
  style: {
1257
- ...Ne,
1258
- cursor: _.pendingObjectType === "point" || D ? "crosshair" : "default"
1429
+ ...He,
1430
+ cursor: c.pendingObjectType === "point" || D ? "crosshair" : "default"
1259
1431
  },
1260
- children: /* @__PURE__ */ q(ve, { children: [
1432
+ children: /* @__PURE__ */ q(Se, { children: [
1261
1433
  /* @__PURE__ */ K(U, {
1262
1434
  width: r.width,
1263
1435
  height: r.height,
1264
1436
  fill: "#fbfcff",
1265
1437
  listening: !1
1266
1438
  }),
1267
- /* @__PURE__ */ K(rt, {
1268
- viewport: w,
1439
+ /* @__PURE__ */ K(ht, {
1440
+ viewport: C,
1269
1441
  canvas: r,
1270
- visible: !!_.exercise.showGrid
1442
+ visible: !!c.exercise.showGrid
1271
1443
  }),
1272
- A && /* @__PURE__ */ K(H, {
1273
- points: A,
1444
+ O && /* @__PURE__ */ K(H, {
1445
+ points: O,
1274
1446
  stroke: "#786af5",
1275
1447
  strokeWidth: 3,
1276
1448
  dash: [9, 6],
1277
1449
  lineCap: "round",
1278
1450
  listening: !1
1279
1451
  }),
1280
- y.map(({ id: t, definition: i }) => {
1281
- let a = b(t);
1452
+ k && /* @__PURE__ */ K(Y, {
1453
+ id: "angle-preview",
1454
+ descriptor: k,
1455
+ viewport: C,
1456
+ canvas: r,
1457
+ color: "#786af5",
1458
+ dashed: !0,
1459
+ listening: !1
1460
+ }),
1461
+ u.map(({ id: t, definition: i }) => {
1462
+ let a = d(t);
1282
1463
  if (!a.rendered) return null;
1283
- let s = e(i, v);
1284
- return s ? /* @__PURE__ */ K(nt, {
1464
+ let s = e(i, l);
1465
+ return s ? /* @__PURE__ */ K(Y, {
1285
1466
  id: t,
1286
1467
  descriptor: n(s),
1287
- viewport: w,
1468
+ viewport: C,
1288
1469
  canvas: r,
1289
- label: S(t),
1290
- selected: t === _.selectedGivenId || o.includes(t),
1291
- listening: a.selectable && !_.pendingObjectType
1470
+ label: b(t),
1471
+ measured: x(t) !== void 0,
1472
+ selected: t === c.selectedGivenId || o.includes(t),
1473
+ listening: a.selectable && !c.pendingObjectType
1292
1474
  }, t) : null;
1293
1475
  }),
1294
- h.map((e) => e.shape ? e.shape.type === "segment" ? /* @__PURE__ */ K(qe, {
1295
- id: `goal-preview-${e.id}`,
1296
- from: e.shape.from,
1297
- to: e.shape.to,
1298
- viewport: w,
1299
- canvas: r,
1300
- color: "#f59e0b",
1301
- strokeWidth: 4,
1302
- dashed: !0,
1303
- opacity: .72,
1304
- listening: !1
1305
- }, `goal-preview-${e.id}`) : e.shape.type === "point" ? /* @__PURE__ */ K(J, {
1306
- id: `goal-preview-${e.id}`,
1307
- position: e.shape.at,
1308
- viewport: w,
1309
- canvas: r,
1310
- color: "#f59e0b"
1311
- }, `goal-preview-${e.id}`) : /* @__PURE__ */ K(Je, {
1312
- id: `goal-preview-${e.id}`,
1313
- through: e.shape.through,
1314
- viewport: w,
1315
- canvas: r,
1316
- color: "#f59e0b",
1317
- strokeWidth: 3,
1318
- dashed: !0,
1319
- opacity: .72,
1320
- listening: !1
1321
- }, `goal-preview-${e.id}`) : null),
1322
- [...v].map(([e, t]) => {
1323
- let n = b(e);
1476
+ s.map((e) => {
1477
+ if (!e.shape) return null;
1478
+ if (e.shape.type === "segment") return /* @__PURE__ */ K(nt, {
1479
+ id: `goal-preview-${e.id}`,
1480
+ from: e.shape.from,
1481
+ to: e.shape.to,
1482
+ viewport: C,
1483
+ canvas: r,
1484
+ color: "#f59e0b",
1485
+ strokeWidth: 4,
1486
+ dashed: !0,
1487
+ opacity: .72,
1488
+ listening: !1
1489
+ }, `goal-preview-${e.id}`);
1490
+ if (e.shape.type === "angle") {
1491
+ let { vertex: t, arms: n } = e.shape;
1492
+ return n.map((n, i) => /* @__PURE__ */ K(nt, {
1493
+ id: `goal-preview-${e.id}-${i}`,
1494
+ from: t,
1495
+ to: n,
1496
+ viewport: C,
1497
+ canvas: r,
1498
+ color: "#f59e0b",
1499
+ strokeWidth: 4,
1500
+ dashed: !0,
1501
+ opacity: .72,
1502
+ listening: !1
1503
+ }, `goal-preview-${e.id}-${i}`));
1504
+ }
1505
+ return e.shape.type === "point" ? /* @__PURE__ */ K(J, {
1506
+ id: `goal-preview-${e.id}`,
1507
+ position: e.shape.at,
1508
+ viewport: C,
1509
+ canvas: r,
1510
+ color: "#f59e0b"
1511
+ }, `goal-preview-${e.id}`) : /* @__PURE__ */ K(rt, {
1512
+ id: `goal-preview-${e.id}`,
1513
+ through: e.shape.through,
1514
+ viewport: C,
1515
+ canvas: r,
1516
+ color: "#f59e0b",
1517
+ strokeWidth: 3,
1518
+ dashed: !0,
1519
+ opacity: .72,
1520
+ listening: !1
1521
+ }, `goal-preview-${e.id}`);
1522
+ }),
1523
+ [...l].map(([e, t]) => {
1524
+ let n = d(e);
1324
1525
  return n.rendered ? /* @__PURE__ */ K(J, {
1325
1526
  id: e,
1326
1527
  position: t,
1327
- viewport: w,
1528
+ viewport: C,
1328
1529
  canvas: r,
1329
- label: S(e) ?? e,
1330
- selected: e === _.pendingFirstPointId || e === _.selectedGivenId || o.includes(e),
1530
+ label: b(e) ?? e,
1531
+ selected: e === c.pendingFirstPointId || e === c.pendingVertexPointId || e === c.selectedGivenId || o.includes(e),
1331
1532
  connectable: D && n.snapTarget,
1332
- snapTarget: e === j
1533
+ snapTarget: e === A
1333
1534
  }, e) : null;
1334
1535
  }),
1335
- M.snap && /* @__PURE__ */ K(Ue, {
1336
- snap: M.snap,
1337
- viewport: w,
1536
+ j.snap && /* @__PURE__ */ K(Qe, {
1537
+ snap: j.snap,
1538
+ viewport: C,
1338
1539
  canvas: r
1339
1540
  }),
1340
- /* @__PURE__ */ K(ft, {
1341
- tools: _.exercise.tools,
1541
+ /* @__PURE__ */ K(wt, {
1542
+ tools: c.exercise.tools,
1342
1543
  canvas: r
1343
1544
  })
1344
1545
  ] })
@@ -1346,144 +1547,164 @@ function pt({ store: t, size: r, onExerciseChange: i, onGivenSelect: a, highligh
1346
1547
  }
1347
1548
  //#endregion
1348
1549
  //#region src/renderer/entityDisplayName.ts
1349
- var mt = /^student-(.+)-(\d+)$/;
1350
- function Q(e, t, n) {
1550
+ var Et = /^student-(.+)-(\d+)$/;
1551
+ function $(e, t, n) {
1351
1552
  if (t) return t;
1352
1553
  if (n === "given") return e;
1353
- let r = mt.exec(e);
1554
+ let r = Et.exec(e);
1354
1555
  return !r?.[1] || !r[2] ? e : r[1] === "point" ? `P${r[2]}` : `${r[1]} ${r[2]}`;
1355
1556
  }
1356
1557
  //#endregion
1357
1558
  //#region src/renderer/StudentGeometryCanvas.tsx
1358
- var ht = "#1683ff", gt = "#159a68", _t = "#d64555";
1359
- function vt(e) {
1360
- return e === "correct" ? gt : e === "incorrect" ? _t : void 0;
1361
- }
1362
- function yt({ store: r, size: i, validationFeedback: a = null, focusedGoalId: o = null }) {
1363
- let c = Z(r), { exercise: l, geometry: u } = c, { points: d, objects: f, capabilitiesOf: p, labelOf: m, isSnapTarget: h } = Ce(l, u), g = ce(a, u, o), v = R(null), y = Ee({
1364
- points: d,
1365
- viewport: l.viewport,
1559
+ var Dt = "#1683ff", Ot = "#159a68", kt = "#d64555";
1560
+ function At(e) {
1561
+ return e === "correct" ? Ot : e === "incorrect" ? kt : void 0;
1562
+ }
1563
+ function jt({ store: t, size: i, validationFeedback: a = null, focusedGoalId: o = null }) {
1564
+ let s = Q(t), { exercise: c, geometry: l } = s, { points: u, objects: d, capabilitiesOf: f, labelOf: p, measureOf: m, isSnapTarget: h } = Oe(c, l), g = fe(a, l, o), _ = R(null), v = Me({
1565
+ points: u,
1566
+ viewport: c.viewport,
1366
1567
  canvas: i,
1367
- pendingObjectType: c.pendingObjectType,
1368
- pendingFirstPointId: c.pendingFirstPointId,
1369
- connect: (e, t) => {
1370
- (c.pendingObjectType === "segment" || c.pendingObjectType === "line") && N(r, {
1371
- tool: c.pendingObjectType,
1568
+ pendingObjectType: s.pendingObjectType,
1569
+ pendingFirstPointId: s.pendingFirstPointId,
1570
+ pendingVertexPointId: s.pendingVertexPointId,
1571
+ connect: (e, n) => {
1572
+ (s.pendingObjectType === "segment" || s.pendingObjectType === "line") && re(t, {
1573
+ tool: s.pendingObjectType,
1372
1574
  from: e,
1373
- to: t
1575
+ to: n
1374
1576
  });
1375
1577
  },
1376
- pick: (e) => S(r, e),
1377
- objects: f,
1578
+ pick: (e) => T(t, e),
1579
+ objects: d,
1378
1580
  isSnapTarget: h,
1379
1581
  canCreatePoints: !0
1380
- }), { connecting: w, previewPoints: T, snapTargetId: E, snapPreview: D } = y, O = De({
1381
- points: d,
1382
- objects: f,
1383
- viewport: l.viewport,
1582
+ }), { connecting: y, previewPoints: x, previewAngle: S, snapTargetId: w, snapPreview: O } = v, k = Ne({
1583
+ points: u,
1584
+ objects: d,
1585
+ viewport: c.viewport,
1384
1586
  canvas: i,
1385
- showGrid: !!l.showGrid,
1587
+ showGrid: !!c.showGrid,
1386
1588
  isSnapTarget: h,
1387
- active: c.pendingObjectType === "point"
1589
+ active: s.pendingObjectType === "point"
1388
1590
  });
1389
- function k(e) {
1390
- if (c.selectedObjectId && F(r, null), c.pendingObjectType !== "point") return;
1391
- let t = O.resolvePlacement(e);
1392
- if (t.snap?.kind === "point") {
1393
- let e = t.snap.targetIds[0];
1394
- e && C(r, e);
1591
+ function A(e) {
1592
+ if (s.selectedObjectId && le(t, null), s.pendingObjectType !== "point") return;
1593
+ let n = k.resolvePlacement(e);
1594
+ if (n.snap?.kind === "point") {
1595
+ let e = n.snap.targetIds[0];
1596
+ e && D(t, e);
1395
1597
  return;
1396
1598
  }
1397
- let n = s(t);
1398
- n && ie(r, n, !0);
1599
+ let r = E(n);
1600
+ r && se(t, r, !0);
1399
1601
  }
1400
- return Be(v, i, r, {
1401
- tool: c.pendingObjectType,
1402
- connection: y,
1403
- placement: O,
1602
+ return Ye(_, i, t, {
1603
+ tool: s.pendingObjectType,
1604
+ connection: v,
1605
+ placement: k,
1404
1606
  pointOnScreen: (e) => {
1405
- let t = d.get(e);
1406
- return t ? P(t, l.viewport, i) : null;
1607
+ let t = u.get(e);
1608
+ return t ? F(t, c.viewport, i) : null;
1609
+ },
1610
+ canDragPoint: (e) => j(s, e),
1611
+ dragPoint: (e, n, r) => {
1612
+ let a = Ie({
1613
+ exercise: c,
1614
+ attempt: l.entities,
1615
+ points: u,
1616
+ objects: d,
1617
+ canvas: i
1618
+ }, e, n, r);
1619
+ a && ce(t, e, a);
1407
1620
  },
1408
- canDragPoint: (e) => A(c, e),
1409
- dragPoint: (e, t) => ae(r, e, x(t, l.viewport, i)),
1410
- endPointDrag: () => _(r),
1621
+ endPointDrag: () => b(t),
1411
1622
  tapPoint: (e) => {
1412
- let t = p(e).selectable && b(c, e);
1413
- F(r, t ? e : null);
1623
+ let n = f(e).selectable && C(s, e);
1624
+ le(t, n ? e : null);
1414
1625
  },
1415
- tapObject: (e) => F(r, e),
1416
- tapStage: k,
1417
- abandonConstruction: () => M(r),
1418
- disarmTool: () => se(r, null)
1419
- }), /* @__PURE__ */ K(ye, {
1420
- ref: v,
1626
+ tapObject: (e) => le(t, e),
1627
+ tapStage: A,
1628
+ abandonConstruction: () => ne(t),
1629
+ disarmTool: () => de(t, null)
1630
+ }), /* @__PURE__ */ K(Ce, {
1631
+ ref: _,
1421
1632
  width: i.width,
1422
1633
  height: i.height,
1423
- style: Ne,
1424
- children: /* @__PURE__ */ q(ve, { children: [
1634
+ style: He,
1635
+ children: /* @__PURE__ */ q(Se, { children: [
1425
1636
  /* @__PURE__ */ K(U, {
1426
1637
  width: i.width,
1427
1638
  height: i.height,
1428
1639
  fill: "#fbfcff",
1429
1640
  listening: !1
1430
1641
  }),
1431
- /* @__PURE__ */ K(rt, {
1432
- viewport: l.viewport,
1642
+ /* @__PURE__ */ K(ht, {
1643
+ viewport: c.viewport,
1433
1644
  canvas: i,
1434
- visible: !!l.showGrid
1645
+ visible: !!c.showGrid
1435
1646
  }),
1436
- T && /* @__PURE__ */ K(H, {
1437
- points: T,
1647
+ x && /* @__PURE__ */ K(H, {
1648
+ points: x,
1438
1649
  stroke: "#786af5",
1439
1650
  strokeWidth: 3,
1440
1651
  dash: [9, 6],
1441
1652
  lineCap: "round",
1442
1653
  listening: !1
1443
1654
  }),
1444
- f.map(({ id: r, definition: a }) => {
1445
- let o = Object.prototype.hasOwnProperty.call(u.entities, r), s = p(r);
1446
- if (!s.rendered) return null;
1447
- let f = t(g.constructions, r), h = vt(f), _ = e(a, d);
1448
- if (!_) return null;
1449
- let v = s.selectable && o;
1450
- return /* @__PURE__ */ K(nt, {
1451
- id: r,
1452
- descriptor: n(_),
1453
- viewport: l.viewport,
1655
+ S && /* @__PURE__ */ K(Y, {
1656
+ id: "angle-preview",
1657
+ descriptor: S,
1658
+ viewport: c.viewport,
1659
+ canvas: i,
1660
+ color: "#786af5",
1661
+ dashed: !0,
1662
+ listening: !1
1663
+ }),
1664
+ d.map(({ id: t, definition: a }) => {
1665
+ let o = Object.prototype.hasOwnProperty.call(l.entities, t), d = f(t);
1666
+ if (!d.rendered) return null;
1667
+ let h = r(g.constructions, t), _ = At(h), v = e(a, u);
1668
+ if (!v) return null;
1669
+ let y = d.selectable && o;
1670
+ return /* @__PURE__ */ K(Y, {
1671
+ id: t,
1672
+ descriptor: n(v),
1673
+ viewport: c.viewport,
1454
1674
  canvas: i,
1455
- label: m(r),
1456
- color: o ? h ?? ht : void 0,
1457
- dashed: f === "incorrect",
1458
- selected: v && r === c.selectedObjectId,
1459
- listening: v && !c.pendingObjectType
1460
- }, r);
1675
+ label: p(t),
1676
+ measured: m(t) !== void 0,
1677
+ color: o ? _ ?? Dt : void 0,
1678
+ dashed: h === "incorrect",
1679
+ selected: y && t === s.selectedObjectId,
1680
+ listening: y && !s.pendingObjectType
1681
+ }, t);
1461
1682
  }),
1462
- [...d].map(([e, n]) => {
1463
- let r = p(e);
1464
- if (!r.rendered) return null;
1465
- let a = Object.prototype.hasOwnProperty.call(l.entities, e), o = !a, s = t(g.points, e), u = vt(s);
1683
+ [...u].map(([e, t]) => {
1684
+ let n = f(e);
1685
+ if (!n.rendered) return null;
1686
+ let a = Object.prototype.hasOwnProperty.call(c.entities, e), o = !a, l = r(g.points, e), u = At(l);
1466
1687
  return /* @__PURE__ */ K(J, {
1467
1688
  id: e,
1468
- position: n,
1469
- viewport: l.viewport,
1689
+ position: t,
1690
+ viewport: c.viewport,
1470
1691
  canvas: i,
1471
- label: Q(e, m(e), a ? "given" : "student"),
1472
- color: o ? u ?? ht : void 0,
1692
+ label: $(e, p(e), a ? "given" : "student"),
1693
+ color: o ? u ?? Dt : void 0,
1473
1694
  feedbackRingColor: u,
1474
- feedbackRingDashed: s === "incorrect",
1475
- selected: e === c.pendingFirstPointId || e === c.selectedObjectId,
1476
- connectable: w && r.snapTarget,
1477
- snapTarget: e === E
1695
+ feedbackRingDashed: l === "incorrect",
1696
+ selected: e === s.pendingFirstPointId || e === s.pendingVertexPointId || e === s.selectedObjectId,
1697
+ connectable: y && n.snapTarget,
1698
+ snapTarget: e === w
1478
1699
  }, e);
1479
1700
  }),
1480
- (O.snap ?? D) && /* @__PURE__ */ K(Ue, {
1481
- snap: O.snap ?? D,
1482
- viewport: l.viewport,
1701
+ (k.snap ?? O) && /* @__PURE__ */ K(Qe, {
1702
+ snap: k.snap ?? O,
1703
+ viewport: c.viewport,
1483
1704
  canvas: i
1484
1705
  }),
1485
- /* @__PURE__ */ K(ft, {
1486
- tools: l.tools,
1706
+ /* @__PURE__ */ K(wt, {
1707
+ tools: c.tools,
1487
1708
  canvas: i
1488
1709
  })
1489
1710
  ] })
@@ -1491,45 +1712,45 @@ function yt({ store: r, size: i, validationFeedback: a = null, focusedGoalId: o
1491
1712
  }
1492
1713
  //#endregion
1493
1714
  //#region src/renderer/deriveSemanticScene.ts
1494
- function bt(e, n = null, r = null) {
1495
- let { exercise: i, geometry: o } = e, s = a(i, o), c = ce(n, o, r), l = wt(s), u = St(s, s.entityIds, {
1496
- nameOf: l,
1715
+ function Mt(e, t = null, n = null) {
1716
+ let { exercise: i, geometry: a } = e, o = l(i, a), s = fe(t, a, n), c = It(o), u = Pt(o, o.entityIds, {
1717
+ nameOf: c,
1497
1718
  selectedId: e.selectedObjectId,
1498
- isSelectable: (e, t) => t && !s.isGiven(e),
1499
- statusOf: (e, n) => t(n === "point" ? c.points : c.constructions, e) ?? null
1719
+ isSelectable: (e, t) => t && !o.isGiven(e),
1720
+ statusOf: (e, t) => r(t === "point" ? s.points : s.constructions, e) ?? null
1500
1721
  });
1501
1722
  return {
1502
- toolLine: Et(e.pendingObjectType),
1503
- pendingLine: Dt(e.pendingObjectType, e.pendingFirstPointId, l),
1504
- answerLine: Ot(n),
1723
+ toolLine: Rt(e.pendingObjectType),
1724
+ pendingLine: zt(e, c),
1725
+ answerLine: Bt(t),
1505
1726
  entities: u,
1506
1727
  selectedId: e.selectedObjectId
1507
1728
  };
1508
1729
  }
1509
- function xt(e) {
1510
- let t = o(e.exercise), n = wt(t), r = St(t, Object.keys(e.exercise.entities), {
1730
+ function Nt(e) {
1731
+ let t = c(e.exercise), n = It(t), r = Pt(t, Object.keys(e.exercise.entities), {
1511
1732
  nameOf: n,
1512
1733
  selectedId: e.selectedGivenId,
1513
1734
  isSelectable: (e, t) => t,
1514
1735
  statusOf: () => null
1515
1736
  });
1516
1737
  return {
1517
- toolLine: Et(e.pendingObjectType),
1518
- pendingLine: Dt(e.pendingObjectType, e.pendingFirstPointId, n),
1738
+ toolLine: Rt(e.pendingObjectType),
1739
+ pendingLine: zt(e, n),
1519
1740
  answerLine: null,
1520
1741
  entities: r,
1521
1742
  selectedId: e.selectedGivenId
1522
1743
  };
1523
1744
  }
1524
- function St(e, t, n) {
1525
- let i = [];
1745
+ function Pt(e, t, n) {
1746
+ let r = [];
1526
1747
  for (let a of t) {
1527
1748
  let t = e.presentationOf(a);
1528
- if (!xe(t.role).rendered) continue;
1749
+ if (!Te(t.role).rendered) continue;
1529
1750
  let o = e.definitionOf(a), s = e.kindOf(a);
1530
1751
  if (!o || !s) continue;
1531
- let c = e.isGiven(a) ? "given" : "student", l = Q(a, t.label, c), u = r(o, n.nameOf), d = e.resolvedOf(a) !== void 0, f = n.statusOf(a, s);
1532
- i.push({
1752
+ let c = e.isGiven(a) ? "given" : "student", l = $(a, t.label, c), u = i(o, n.nameOf), d = e.resolvedOf(a) !== void 0, f = n.statusOf(a, s);
1753
+ r.push({
1533
1754
  id: a,
1534
1755
  kind: s,
1535
1756
  owner: c,
@@ -1537,41 +1758,43 @@ function St(e, t, n) {
1537
1758
  description: u,
1538
1759
  placed: d,
1539
1760
  selected: a === n.selectedId,
1540
- selectable: n.isSelectable(a, xe(t.role).selectable),
1761
+ selectable: n.isSelectable(a, Te(t.role).selectable),
1541
1762
  status: f,
1542
- text: Ct(l, u, d, f)
1763
+ text: Ft(l, u, Ee(e, a), d, f)
1543
1764
  });
1544
1765
  }
1545
- return i;
1766
+ return r;
1546
1767
  }
1547
- function Ct(e, t, n, r) {
1548
- return `${e}: ${t}${`${n ? "" : ", not on screen"}${r ? `, ${r}` : ""}`}`;
1768
+ function Ft(e, t, n, r, i) {
1769
+ return `${e}: ${t}${`${n ? `, measures ${n}` : ""}${r ? "" : ", not on screen"}${i ? `, ${i}` : ""}`}`;
1549
1770
  }
1550
- function wt(e) {
1551
- return (t) => Q(t, Tt(e, t), e.isGiven(t) ? "given" : "student");
1771
+ function It(e) {
1772
+ return (t) => $(t, Lt(e, t), e.isGiven(t) ? "given" : "student");
1552
1773
  }
1553
- function Tt(e, t) {
1774
+ function Lt(e, t) {
1554
1775
  let n = e.presentationOf(t);
1555
1776
  return n.role === "explicit" ? n.label : void 0;
1556
1777
  }
1557
- function Et(e) {
1778
+ function Rt(e) {
1558
1779
  return `Tool: ${e ?? "none"}`;
1559
1780
  }
1560
- function Dt(e, t, n) {
1561
- return !e || !t ? "Building: nothing" : `Building: ${e} from ${n(t)}`;
1781
+ function zt({ pendingObjectType: e, pendingFirstPointId: t, pendingVertexPointId: n }, r) {
1782
+ if (!e || !t) return "Building: nothing";
1783
+ let i = n ? ` at ${r(n)}` : "";
1784
+ return `Building: ${e} from ${r(t)}${i}`;
1562
1785
  }
1563
- function Ot(e) {
1786
+ function Bt(e) {
1564
1787
  return e ? `Answer: ${e.result.goals.filter((e) => e.status === "correct").length} of ${e.result.goals.length} goals correct` : "Answer: not checked";
1565
1788
  }
1566
- function kt(e, t) {
1789
+ function Vt(e, t) {
1567
1790
  if (!e) return null;
1568
1791
  let n = new Map(e.entities.map((e) => [e.id, e])), r = new Map(t.entities.map((e) => [e.id, e])), i = t.entities.filter((e) => !n.has(e.id)), a = e.entities.filter((e) => !r.has(e.id)), o = [];
1569
1792
  return i.length === 1 && i[0] ? o.push(`Added ${i[0].text}`) : i.length > 1 && o.push(`Added ${i.length} objects`), a.length === 1 && a[0] ? o.push(`Removed ${a[0].text}`) : a.length > 1 && o.push(`Removed ${a.length} objects`), t.answerLine && t.answerLine !== e.answerLine && o.push(t.answerLine), o.length === 0 && t.toolLine !== e.toolLine && o.push(t.toolLine), o.length ? `${o.join(". ")}.` : null;
1570
1793
  }
1571
1794
  //#endregion
1572
1795
  //#region src/renderer/GeometryCompanion.tsx
1573
- function At({ scene: e, onSelect: t, label: n = "Figure contents", className: r }) {
1574
- let i = Nt(e);
1796
+ function Ht({ scene: e, onSelect: t, label: n = "Figure contents", className: r }) {
1797
+ let i = Gt(e);
1575
1798
  return /* @__PURE__ */ q("section", {
1576
1799
  "aria-label": n,
1577
1800
  className: r,
@@ -1597,31 +1820,31 @@ function At({ scene: e, onSelect: t, label: n = "Figure contents", className: r
1597
1820
  ]
1598
1821
  });
1599
1822
  }
1600
- function jt({ store: e, validationFeedback: t = null, focusedGoalId: n = null, label: r, className: i }) {
1601
- let a = bt(Z(e), t, n);
1602
- return /* @__PURE__ */ K(At, {
1823
+ function Ut({ store: e, validationFeedback: t = null, focusedGoalId: n = null, label: r, className: i }) {
1824
+ let a = Mt(Q(e), t, n);
1825
+ return /* @__PURE__ */ K(Ht, {
1603
1826
  scene: a,
1604
- onSelect: (t) => F(e, t),
1827
+ onSelect: (t) => le(e, t),
1605
1828
  label: r,
1606
1829
  className: i
1607
1830
  });
1608
1831
  }
1609
- function Mt({ store: e, label: t, className: n }) {
1610
- let r = xt(Z(e));
1611
- return /* @__PURE__ */ K(At, {
1832
+ function Wt({ store: e, label: t, className: n }) {
1833
+ let r = Nt(Q(e));
1834
+ return /* @__PURE__ */ K(Ht, {
1612
1835
  scene: r,
1613
- onSelect: (t) => g(e, t),
1836
+ onSelect: (t) => y(e, t),
1614
1837
  label: t,
1615
1838
  className: n
1616
1839
  });
1617
1840
  }
1618
- function Nt(e) {
1841
+ function Gt(e) {
1619
1842
  let t = R(null), [n, r] = z({
1620
1843
  message: "",
1621
1844
  tick: 0
1622
1845
  });
1623
1846
  return I(() => {
1624
- let n = kt(t.current, e);
1847
+ let n = Vt(t.current, e);
1625
1848
  t.current = e, n !== null && r((e) => ({
1626
1849
  message: n,
1627
1850
  tick: e.tick + 1
@@ -1630,8 +1853,8 @@ function Nt(e) {
1630
1853
  }
1631
1854
  //#endregion
1632
1855
  //#region src/renderer/studentExerciseSession.ts
1633
- function Pt(e, t) {
1634
- let n = ue(e);
1856
+ function Kt(e, t) {
1857
+ let n = ge(e);
1635
1858
  if (!n.success) return {
1636
1859
  success: !1,
1637
1860
  issues: n.errors.map((e) => ({
@@ -1641,14 +1864,14 @@ function Pt(e, t) {
1641
1864
  };
1642
1865
  let r = t == null ? {
1643
1866
  success: !0,
1644
- data: fe()
1645
- } : pe(t, n.data);
1867
+ data: pe()
1868
+ } : _e(t, n.data);
1646
1869
  return r.success ? {
1647
1870
  success: !0,
1648
1871
  exercise: n.data,
1649
1872
  attempt: r.data,
1650
- exerciseFingerprint: de(n.data),
1651
- attemptFingerprint: le(r.data)
1873
+ exerciseFingerprint: he(n.data),
1874
+ attemptFingerprint: me(r.data)
1652
1875
  } : {
1653
1876
  success: !1,
1654
1877
  issues: r.errors.map((e) => ({
@@ -1657,28 +1880,28 @@ function Pt(e, t) {
1657
1880
  }))
1658
1881
  };
1659
1882
  }
1660
- function Ft(e, t) {
1661
- let n = pe(t, e);
1662
- return n.success ? le(n.data) : null;
1883
+ function qt(e, t) {
1884
+ let n = _e(t, e);
1885
+ return n.success ? me(n.data) : null;
1663
1886
  }
1664
- function It(e) {
1887
+ function Jt(e) {
1665
1888
  return {
1666
- store: ne(e.exercise, e.attempt),
1889
+ store: ae(e.exercise, e.attempt),
1667
1890
  exercise: e.exerciseFingerprint,
1668
1891
  value: e.attemptFingerprint
1669
1892
  };
1670
1893
  }
1671
- function Lt(e, t) {
1894
+ function Yt(e, t) {
1672
1895
  if (t.exerciseFingerprint !== e.exercise) {
1673
- e.exercise = t.exerciseFingerprint, e.value = t.attemptFingerprint, T(e.store, t.exercise, t.attempt);
1896
+ e.exercise = t.exerciseFingerprint, e.value = t.attemptFingerprint, k(e.store, t.exercise, t.attempt);
1674
1897
  return;
1675
1898
  }
1676
1899
  if (t.attemptFingerprint === e.value) return;
1677
1900
  e.value = t.attemptFingerprint;
1678
1901
  let { exercise: n, geometry: r } = e.store.getState();
1679
- Ft(n, r) !== t.attemptFingerprint && j(e.store, t.attempt);
1902
+ qt(n, r) !== t.attemptFingerprint && N(e.store, t.attempt);
1680
1903
  }
1681
- function Rt(e, t) {
1904
+ function Xt(e, t) {
1682
1905
  return e.subscribe((e, n) => {
1683
1906
  let r = e.lastAttemptChange;
1684
1907
  r && r !== n.lastAttemptChange && t().onChange(JSON.parse(JSON.stringify(e.geometry)), {
@@ -1689,27 +1912,29 @@ function Rt(e, t) {
1689
1912
  i && i !== n.constructionNotice && t().onNotice?.(i);
1690
1913
  });
1691
1914
  }
1692
- function zt(e, t, n) {
1693
- return !e?.success || e.fingerprints.exercise !== de(t) ? null : e.fingerprints.attempt === Ft(t, n) ? e.data : null;
1915
+ function Zt(e, t, n) {
1916
+ return !e?.success || e.fingerprints.exercise !== he(t) ? null : e.fingerprints.attempt === qt(t, n) ? e.data : null;
1694
1917
  }
1695
1918
  //#endregion
1696
1919
  //#region src/renderer/Toolbar.tsx
1697
- var Bt = [
1920
+ var Qt = [
1698
1921
  "point",
1699
1922
  "segment",
1700
- "line"
1701
- ], Vt = {
1923
+ "line",
1924
+ "angle"
1925
+ ], $t = {
1702
1926
  minWidth: 44,
1703
1927
  minHeight: 44
1704
1928
  };
1705
- function Ht({ selected: e, onSelect: t, available: n = Bt }) {
1929
+ function en({ selected: e, onSelect: t, available: n = Qt }) {
1930
+ let r = n.filter((e) => Qt.includes(e));
1706
1931
  return /* @__PURE__ */ K("div", {
1707
1932
  role: "toolbar",
1708
1933
  "aria-label": "Geometry tools",
1709
- children: n.map((n) => /* @__PURE__ */ K("button", {
1934
+ children: r.map((n) => /* @__PURE__ */ K("button", {
1710
1935
  type: "button",
1711
1936
  "aria-pressed": e === n,
1712
- style: Vt,
1937
+ style: $t,
1713
1938
  onClick: () => t(e === n ? null : n),
1714
1939
  children: n
1715
1940
  }, n))
@@ -1717,27 +1942,27 @@ function Ht({ selected: e, onSelect: t, available: n = Bt }) {
1717
1942
  }
1718
1943
  //#endregion
1719
1944
  //#region src/renderer/StudentGeometryExercise.tsx
1720
- var $ = {
1945
+ var tn = {
1721
1946
  minWidth: 44,
1722
1947
  minHeight: 44
1723
- }, Ut = {
1948
+ }, nn = {
1724
1949
  border: 0,
1725
1950
  margin: 0,
1726
1951
  padding: 0,
1727
1952
  minWidth: 0
1728
1953
  };
1729
- function Wt(e) {
1730
- let { exercise: t, value: n, readOnly: r = !1, validationFeedback: i = null, focusedGoalId: a = null, controls: o, className: s } = e, c = Pt(t, n), [l, u] = z(null), d = R(e), f = R(null);
1731
- return !l && c.success && u(It(c)), L(() => {
1954
+ function rn(e) {
1955
+ let { exercise: t, value: n, readOnly: r = !1, validationFeedback: i = null, focusedGoalId: a = null, controls: o, className: s } = e, c = Kt(t, n), [l, u] = z(null), d = R(e), f = R(null);
1956
+ return !l && c.success && u(Jt(c)), L(() => {
1732
1957
  d.current = e;
1733
1958
  }), L(() => {
1734
- l && c.success && Lt(l, c);
1735
- }, [c, l]), L(() => l ? Rt(l.store, () => d.current) : void 0, [l]), L(() => {
1736
- l && y(l.store, r);
1959
+ l && c.success && Yt(l, c);
1960
+ }, [c, l]), L(() => l ? Xt(l.store, () => d.current) : void 0, [l]), L(() => {
1961
+ l && S(l.store, r);
1737
1962
  }, [l, r]), L(() => {
1738
1963
  let e = c.success ? null : JSON.stringify(c.issues);
1739
1964
  !c.success && e !== f.current && d.current.onError?.(c.issues), f.current = e;
1740
- }, [c]), c.success ? l ? /* @__PURE__ */ K(Gt, {
1965
+ }, [c]), c.success ? l ? /* @__PURE__ */ K(an, {
1741
1966
  store: l.store,
1742
1967
  validationFeedback: i,
1743
1968
  focusedGoalId: a,
@@ -1749,12 +1974,12 @@ function Wt(e) {
1749
1974
  children: "This exercise cannot be displayed."
1750
1975
  });
1751
1976
  }
1752
- function Gt({ store: e, validationFeedback: n, focusedGoalId: r, controls: i, className: a }) {
1753
- let o = Z(e), { exercise: s, geometry: c, selectedObjectId: l, constructionNotice: u } = o, d = me(() => zt(n, s, c), [
1754
- n,
1977
+ function an({ store: e, validationFeedback: t, focusedGoalId: n, controls: i, className: a }) {
1978
+ let o = Q(e), { exercise: s, geometry: c, selectedObjectId: l, constructionNotice: u } = o, d = ve(() => Zt(t, s, c), [
1979
+ t,
1755
1980
  s,
1756
1981
  c
1757
- ]), f = d ? r : null, p = R(null), [m, h] = z({
1982
+ ]), f = d ? n : null, p = R(null), [m, h] = z({
1758
1983
  width: 0,
1759
1984
  height: 0
1760
1985
  }), [g, _, v, y] = s.viewport;
@@ -1772,43 +1997,43 @@ function Gt({ store: e, validationFeedback: n, focusedGoalId: r, controls: i, cl
1772
1997
  let n = new ResizeObserver(([e]) => e && t(e.contentRect));
1773
1998
  return n.observe(e), () => n.disconnect();
1774
1999
  }, []);
1775
- let b = (e) => i?.[e] !== !1, x = u && `This construction already exists: ${Q(u.entityId, t(c.presentation, u.entityId)?.label, "student")}`;
2000
+ let b = (e) => i?.[e] !== !1, x = u && `This construction already exists: ${$(u.entityId, r(c.presentation, u.entityId)?.label, "student")}`;
1776
2001
  return /* @__PURE__ */ q("div", {
1777
2002
  className: a,
1778
2003
  children: [
1779
2004
  /* @__PURE__ */ q("fieldset", {
1780
2005
  disabled: o.readOnly,
1781
- style: Ut,
2006
+ style: nn,
1782
2007
  children: [
1783
- b("toolbar") && /* @__PURE__ */ K(Ht, {
2008
+ b("toolbar") && /* @__PURE__ */ K(en, {
1784
2009
  selected: o.pendingObjectType,
1785
2010
  available: s.allowedObjects,
1786
- onSelect: (t) => se(e, t)
2011
+ onSelect: (t) => de(e, t)
1787
2012
  }),
1788
2013
  b("history") && /* @__PURE__ */ q(G, { children: [/* @__PURE__ */ K("button", {
1789
2014
  type: "button",
1790
- style: $,
2015
+ style: tn,
1791
2016
  disabled: !o.past.length,
1792
- onClick: () => oe(e),
2017
+ onClick: () => ue(e),
1793
2018
  children: "Undo"
1794
2019
  }), /* @__PURE__ */ K("button", {
1795
2020
  type: "button",
1796
- style: $,
2021
+ style: tn,
1797
2022
  disabled: !o.future.length,
1798
- onClick: () => te(e),
2023
+ onClick: () => ie(e),
1799
2024
  children: "Redo"
1800
2025
  })] }),
1801
2026
  b("delete") && /* @__PURE__ */ K("button", {
1802
2027
  type: "button",
1803
- style: $,
2028
+ style: tn,
1804
2029
  disabled: !l,
1805
- onClick: () => l && E(e, l),
2030
+ onClick: () => l && A(e, l),
1806
2031
  children: "Delete"
1807
2032
  }),
1808
2033
  b("reset") && /* @__PURE__ */ K("button", {
1809
2034
  type: "button",
1810
- style: $,
1811
- onClick: () => w(e),
2035
+ style: tn,
2036
+ onClick: () => O(e),
1812
2037
  children: "Reset"
1813
2038
  })
1814
2039
  ]
@@ -1825,7 +2050,7 @@ function Gt({ store: e, validationFeedback: n, focusedGoalId: r, controls: i, cl
1825
2050
  position: "absolute",
1826
2051
  inset: 0
1827
2052
  },
1828
- children: /* @__PURE__ */ K(yt, {
2053
+ children: /* @__PURE__ */ K(jt, {
1829
2054
  store: e,
1830
2055
  size: m,
1831
2056
  validationFeedback: d,
@@ -1837,7 +2062,7 @@ function Gt({ store: e, validationFeedback: n, focusedGoalId: r, controls: i, cl
1837
2062
  role: "status",
1838
2063
  children: x
1839
2064
  }),
1840
- /* @__PURE__ */ K(jt, {
2065
+ /* @__PURE__ */ K(Ut, {
1841
2066
  store: e,
1842
2067
  validationFeedback: d,
1843
2068
  focusedGoalId: f
@@ -1846,6 +2071,6 @@ function Gt({ store: e, validationFeedback: n, focusedGoalId: r, controls: i, cl
1846
2071
  });
1847
2072
  }
1848
2073
  //#endregion
1849
- export { Ce as C, Se as S, Je as _, Mt as a, Ue as b, xt as c, pt as d, Z as f, Xe as g, nt as h, jt as i, yt as l, rt as m, Ht as n, kt as o, ft as p, At as r, bt as s, Wt as t, Q as u, qe as v, De as x, J as y };
2074
+ export { Oe as C, De as S, rt as _, Wt as a, Qe as b, Nt as c, Tt as d, Q as f, ct as g, Y as h, Ut as i, jt as l, ht as m, en as n, Vt as o, wt as p, Ht as r, Mt as s, rn as t, $ as u, nt as v, Ne as x, J as y };
1850
2075
 
1851
- //# sourceMappingURL=react-BEcdx1f6.js.map
2076
+ //# sourceMappingURL=react-B5cGaxH8.js.map