lido-player 0.0.1 → 0.0.2-alpha-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 (193) hide show
  1. package/dist/cjs/app-col_12.cjs.entry.js +1258 -0
  2. package/dist/cjs/app-col_12.cjs.entry.js.map +1 -0
  3. package/dist/cjs/app-globals-3a1e7e63.js +7 -0
  4. package/dist/cjs/app-globals-3a1e7e63.js.map +1 -0
  5. package/dist/cjs/index-0d28e716.js +1466 -0
  6. package/dist/cjs/index-0d28e716.js.map +1 -0
  7. package/dist/cjs/index.cjs.js +11 -0
  8. package/dist/cjs/index.cjs.js.map +1 -0
  9. package/dist/cjs/lido-player.cjs.js +27 -0
  10. package/dist/cjs/lido-player.cjs.js.map +1 -0
  11. package/dist/cjs/loader.cjs.js +17 -0
  12. package/dist/cjs/loader.cjs.js.map +1 -0
  13. package/dist/cjs/utils-8ac0e3b7.js +597 -0
  14. package/dist/cjs/utils-8ac0e3b7.js.map +1 -0
  15. package/dist/collection/collection-manifest.json +23 -0
  16. package/dist/collection/components/column/AppCol.js +430 -0
  17. package/dist/collection/components/column/AppCol.js.map +1 -0
  18. package/dist/collection/components/column/app-col.css +19 -0
  19. package/dist/collection/components/container/AppContainer.js +495 -0
  20. package/dist/collection/components/container/AppContainer.js.map +1 -0
  21. package/dist/collection/components/container/app-container.css +10 -0
  22. package/dist/collection/components/home/AppHome.js +261 -0
  23. package/dist/collection/components/home/AppHome.js.map +1 -0
  24. package/dist/collection/components/home/app-home.css +48 -0
  25. package/dist/collection/components/image/AppImage.js +431 -0
  26. package/dist/collection/components/image/AppImage.js.map +1 -0
  27. package/dist/collection/components/image/app-image.css +9 -0
  28. package/dist/collection/components/position/AppPos.js +428 -0
  29. package/dist/collection/components/position/AppPos.js.map +1 -0
  30. package/dist/collection/components/position/app-pos.css +16 -0
  31. package/dist/collection/components/random/AppRandom.js +435 -0
  32. package/dist/collection/components/random/AppRandom.js.map +1 -0
  33. package/dist/collection/components/random/app-random.css +10 -0
  34. package/dist/collection/components/root/AppRoot.js +121 -0
  35. package/dist/collection/components/root/AppRoot.js.map +1 -0
  36. package/dist/collection/components/root/assets/Audio/goodJob.mp3 +0 -0
  37. package/dist/collection/components/root/assets/Audio/tryAgain.mp3 +0 -0
  38. package/dist/collection/components/root/assets/Audio/wellDone.mp3 +0 -0
  39. package/dist/collection/components/root/assets/images/HIimage.png +0 -0
  40. package/dist/collection/components/root/assets/images/VIimage.png +0 -0
  41. package/dist/collection/components/root/assets/images/animals/giraffe.png +0 -0
  42. package/dist/collection/components/root/assets/images/animals/leopard.png +0 -0
  43. package/dist/collection/components/root/assets/images/animals/lion.png +0 -0
  44. package/dist/collection/components/root/assets/images/animals/tiger.png +0 -0
  45. package/dist/collection/components/root/assets/images/bodyParts/ear.png +0 -0
  46. package/dist/collection/components/root/assets/images/bodyParts/eyes.png +0 -0
  47. package/dist/collection/components/root/assets/images/bodyParts/nose.png +0 -0
  48. package/dist/collection/components/root/assets/images/girl.png +0 -0
  49. package/dist/collection/components/root/assets/images/icons/access.png +0 -0
  50. package/dist/collection/components/root/assets/images/icons/brightness.png +0 -0
  51. package/dist/collection/components/root/assets/images/icons/cancel.png +0 -0
  52. package/dist/collection/components/root/assets/images/icons/contrast.png +0 -0
  53. package/dist/collection/components/root/assets/images/icons/dropDown.png +0 -0
  54. package/dist/collection/components/root/assets/images/icons/exit.png +0 -0
  55. package/dist/collection/components/root/assets/images/icons/hide.png +0 -0
  56. package/dist/collection/components/root/assets/images/icons/invert.png +0 -0
  57. package/dist/collection/components/root/assets/images/icons/lineSpacing.png +0 -0
  58. package/dist/collection/components/root/assets/images/icons/sound.png +0 -0
  59. package/dist/collection/components/root/assets/images/icons/zoom.png +0 -0
  60. package/dist/collection/components/root/assets/images/truck/blueTruck.png +0 -0
  61. package/dist/collection/components/root/assets/images/truck/dashedBox.png +0 -0
  62. package/dist/collection/components/root/assets/images/truck/face.png +0 -0
  63. package/dist/collection/components/root/assets/images/truck/road.jpg +0 -0
  64. package/dist/collection/components/root/assets/images/truck/seeing.png +0 -0
  65. package/dist/collection/components/root/assets/images/truck/truck.png +0 -0
  66. package/dist/collection/components/root/assets/images/twoColorBg.jpg +0 -0
  67. package/dist/collection/components/root/assets/xmlData.xml +121 -0
  68. package/dist/collection/components/row/AppRow.js +409 -0
  69. package/dist/collection/components/row/AppRow.js.map +1 -0
  70. package/dist/collection/components/row/app-row.css +10 -0
  71. package/dist/collection/components/shape/AppShape.js +446 -0
  72. package/dist/collection/components/shape/AppShape.js.map +1 -0
  73. package/dist/collection/components/shape/app-shape.css +96 -0
  74. package/dist/collection/components/text/AppText.js +521 -0
  75. package/dist/collection/components/text/AppText.js.map +1 -0
  76. package/dist/collection/components/text/app-text.css +16 -0
  77. package/dist/collection/components/trace/app-trace.css +71 -0
  78. package/dist/collection/components/trace/app-trace.js +707 -0
  79. package/dist/collection/components/trace/app-trace.js.map +1 -0
  80. package/dist/collection/components/wrap/AppWrap.js +428 -0
  81. package/dist/collection/components/wrap/AppWrap.js.map +1 -0
  82. package/dist/collection/components/wrap/app-wrap.css +11 -0
  83. package/dist/collection/index.css +6 -0
  84. package/dist/collection/index.js +11 -0
  85. package/dist/collection/index.js.map +1 -0
  86. package/dist/{lido-player/constants-f484fcec.js → collection/utils/constants.js} +4 -7
  87. package/dist/collection/utils/constants.js.map +1 -0
  88. package/dist/collection/utils/css/animation.css +97 -0
  89. package/dist/{lido-player/utils-291495a4.js → collection/utils/utils.js} +6 -10
  90. package/dist/collection/utils/utils.js.map +1 -0
  91. package/dist/components/app-col.js +8 -0
  92. package/dist/components/app-col.js.map +1 -0
  93. package/dist/components/app-container.js +8 -0
  94. package/dist/components/app-container.js.map +1 -0
  95. package/dist/components/app-home.js +8 -0
  96. package/dist/components/app-home.js.map +1 -0
  97. package/dist/components/app-image.js +8 -0
  98. package/dist/components/app-image.js.map +1 -0
  99. package/dist/components/app-pos.js +8 -0
  100. package/dist/components/app-pos.js.map +1 -0
  101. package/dist/components/app-random.js +8 -0
  102. package/dist/components/app-random.js.map +1 -0
  103. package/dist/components/app-root.js +145 -0
  104. package/dist/components/app-root.js.map +1 -0
  105. package/dist/components/app-row.js +8 -0
  106. package/dist/components/app-row.js.map +1 -0
  107. package/dist/components/app-shape.js +8 -0
  108. package/dist/components/app-shape.js.map +1 -0
  109. package/dist/components/app-text.js +8 -0
  110. package/dist/components/app-text.js.map +1 -0
  111. package/dist/components/app-trace.js +8 -0
  112. package/dist/components/app-trace.js.map +1 -0
  113. package/dist/components/app-wrap.js +8 -0
  114. package/dist/components/app-wrap.js.map +1 -0
  115. package/dist/components/index.js +4 -0
  116. package/dist/components/index.js.map +1 -0
  117. package/dist/{lido-player/app-image.entry.js → components/p-34c825bf.js} +48 -11
  118. package/dist/components/p-34c825bf.js.map +1 -0
  119. package/dist/{lido-player/app-wrap.entry.js → components/p-350205d5.js} +48 -11
  120. package/dist/components/p-350205d5.js.map +1 -0
  121. package/dist/components/p-44db2553.js +1295 -0
  122. package/dist/components/p-44db2553.js.map +1 -0
  123. package/dist/components/p-4db699ee.js +591 -0
  124. package/dist/components/p-4db699ee.js.map +1 -0
  125. package/dist/{lido-player/app-shape.entry.js → components/p-639f58cb.js} +49 -11
  126. package/dist/components/p-639f58cb.js.map +1 -0
  127. package/dist/{lido-player/app-pos.entry.js → components/p-8bc122ff.js} +48 -11
  128. package/dist/components/p-8bc122ff.js.map +1 -0
  129. package/dist/{lido-player/app-trace.entry.js → components/p-aa381e73.js} +41 -10
  130. package/dist/components/p-aa381e73.js.map +1 -0
  131. package/dist/{lido-player/app-row.entry.js → components/p-bb0a3ffa.js} +47 -11
  132. package/dist/components/p-bb0a3ffa.js.map +1 -0
  133. package/dist/{lido-player/app-container.entry.js → components/p-c0c3e960.js} +50 -13
  134. package/dist/components/p-c0c3e960.js.map +1 -0
  135. package/dist/{lido-player/app-text.entry.js → components/p-c9a89df3.js} +53 -11
  136. package/dist/components/p-c9a89df3.js.map +1 -0
  137. package/dist/{lido-player/app-home.entry.js → components/p-dee011ef.js} +94 -9
  138. package/dist/components/p-dee011ef.js.map +1 -0
  139. package/dist/{lido-player/app-col.entry.js → components/p-e509500a.js} +48 -11
  140. package/dist/components/p-e509500a.js.map +1 -0
  141. package/dist/{lido-player/app-random.entry.js → components/p-f8bcec19.js} +47 -9
  142. package/dist/components/p-f8bcec19.js.map +1 -0
  143. package/dist/esm/app-col_12.entry.js +1243 -0
  144. package/dist/esm/app-col_12.entry.js.map +1 -0
  145. package/dist/esm/index-00663f21.js +1437 -0
  146. package/dist/esm/index-00663f21.js.map +1 -0
  147. package/dist/esm/index.js +3 -0
  148. package/dist/esm/index.js.map +1 -0
  149. package/dist/esm/lido-player.js +22 -0
  150. package/dist/esm/lido-player.js.map +1 -0
  151. package/dist/esm/loader.js +13 -0
  152. package/dist/esm/loader.js.map +1 -0
  153. package/dist/esm/utils-cbfaa4d8.js +591 -0
  154. package/dist/esm/utils-cbfaa4d8.js.map +1 -0
  155. package/dist/index.cjs.js +1 -0
  156. package/dist/index.js +1 -0
  157. package/dist/lido-player/index.esm.js +1 -13
  158. package/dist/lido-player/index.esm.js.map +1 -1
  159. package/dist/lido-player/lido-player.css +1 -6
  160. package/dist/lido-player/lido-player.esm.js +1 -48
  161. package/dist/lido-player/lido-player.esm.js.map +1 -1
  162. package/dist/lido-player/p-160313d2.js +3 -0
  163. package/dist/lido-player/p-160313d2.js.map +1 -0
  164. package/dist/lido-player/p-4db699ee.js +2 -0
  165. package/dist/lido-player/p-4db699ee.js.map +1 -0
  166. package/dist/lido-player/p-e1255160.js +2 -0
  167. package/dist/lido-player/p-e1255160.js.map +1 -0
  168. package/dist/lido-player/p-ec4f8898.entry.js +2 -0
  169. package/dist/lido-player/p-ec4f8898.entry.js.map +1 -0
  170. package/dist/types/components/root/AppRoot.d.ts +16 -4
  171. package/dist/types/components.d.ts +32 -8
  172. package/package.json +1 -1
  173. package/dist/lido-player/app-col.entry.js.map +0 -1
  174. package/dist/lido-player/app-container.entry.js.map +0 -1
  175. package/dist/lido-player/app-home.entry.js.map +0 -1
  176. package/dist/lido-player/app-image.entry.js.map +0 -1
  177. package/dist/lido-player/app-pos.entry.js.map +0 -1
  178. package/dist/lido-player/app-random.entry.js.map +0 -1
  179. package/dist/lido-player/app-root.entry.js +0 -34
  180. package/dist/lido-player/app-root.entry.js.map +0 -1
  181. package/dist/lido-player/app-row.entry.js.map +0 -1
  182. package/dist/lido-player/app-shape.entry.js.map +0 -1
  183. package/dist/lido-player/app-text.entry.js.map +0 -1
  184. package/dist/lido-player/app-trace.entry.js.map +0 -1
  185. package/dist/lido-player/app-wrap.entry.js.map +0 -1
  186. package/dist/lido-player/constants-f484fcec.js.map +0 -1
  187. package/dist/lido-player/index-9624adf5.js +0 -3013
  188. package/dist/lido-player/index-9624adf5.js.map +0 -1
  189. package/dist/lido-player/shadow-css-7ad5caf8.js +0 -334
  190. package/dist/lido-player/shadow-css-7ad5caf8.js.map +0 -1
  191. package/dist/lido-player/utils-291495a4.js.map +0 -1
  192. /package/dist/{lido-player → esm}/app-globals-0f993ce5.js +0 -0
  193. /package/dist/{lido-player → esm}/app-globals-0f993ce5.js.map +0 -0
@@ -0,0 +1,1258 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-0d28e716.js');
6
+ const utils = require('./utils-8ac0e3b7.js');
7
+
8
+ const appColCss = ".col{top:var(--y, 0);left:var(--x, 0);height:var(--height, 100%);width:var(--width, 100%);background-color:var(--bgColor, #eeeeee);padding:15px;border-radius:10px;display:flex;justify-content:space-around;flex-direction:column;align-items:center}.col>*{}";
9
+ const AppColStyle0 = appColCss;
10
+
11
+ const AppCol = class {
12
+ constructor(hostRef) {
13
+ index.registerInstance(this, hostRef);
14
+ this.id = undefined;
15
+ this.value = undefined;
16
+ this.height = undefined;
17
+ this.width = undefined;
18
+ this.ariaLabel = undefined;
19
+ this.ariaHidden = undefined;
20
+ this.x = undefined;
21
+ this.y = undefined;
22
+ this.z = undefined;
23
+ this.bgColor = undefined;
24
+ this.type = undefined;
25
+ this.tabIndex = undefined;
26
+ this.visible = undefined;
27
+ this.audio = undefined;
28
+ this.onTouch = undefined;
29
+ this.onCorrectTouch = undefined;
30
+ this.onInCorrectTouch = undefined;
31
+ this.onCorrectMatch = undefined;
32
+ this.onMatch = undefined;
33
+ this.onWrong = undefined;
34
+ this.onEntry = undefined;
35
+ }
36
+ /**
37
+ * This lifecycle hook is called after the component is rendered in the DOM.
38
+ * It initializes events for the column based on the provided type.
39
+ */
40
+ componentDidLoad() {
41
+ utils.initEventsForElement(this.el, this.type);
42
+ }
43
+ render() {
44
+ // Inline styles applied to the column, mainly for positioning and background.
45
+ const style = {
46
+ height: this.height,
47
+ width: this.width,
48
+ backgroundColor: this.bgColor,
49
+ top: this.y,
50
+ left: this.x,
51
+ display: this.visible ? 'flex' : 'none',
52
+ zIndex: this.z,
53
+ };
54
+ return (index.h(index.Host, { key: '3cd3b141cf167e7c43132fc0f28fe049765e3e68', id: this.id, class: "col", type: this.type, tabindex: this.tabIndex, value: this.value, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }, index.h("slot", { key: 'fecc9cdf6b7204461c07e89de0ebec35559f8daf' })));
55
+ }
56
+ get el() { return index.getElement(this); }
57
+ };
58
+ AppCol.style = AppColStyle0;
59
+
60
+ const appContainerCss = ".container{position:relative;height:100%;width:100%;background-color:var(--bgColor, #ffffff);display:flex;flex-direction:column;justify-content:center;align-items:center}";
61
+ const AppContainerStyle0 = appContainerCss;
62
+
63
+ const AppContainer = class {
64
+ constructor(hostRef) {
65
+ index.registerInstance(this, hostRef);
66
+ this.id = undefined;
67
+ this.objective = undefined;
68
+ this.value = undefined;
69
+ this.height = undefined;
70
+ this.width = undefined;
71
+ this.ariaLabel = undefined;
72
+ this.ariaHidden = undefined;
73
+ this.x = undefined;
74
+ this.y = undefined;
75
+ this.z = undefined;
76
+ this.bgColor = undefined;
77
+ this.type = undefined;
78
+ this.tabIndex = undefined;
79
+ this.visible = undefined;
80
+ this.audio = undefined;
81
+ this.onTouch = undefined;
82
+ this.onCorrectTouch = undefined;
83
+ this.onCorrectMatch = undefined;
84
+ this.onMatch = undefined;
85
+ this.onWrong = undefined;
86
+ this.onIncorrectTouch = undefined;
87
+ this.onEntry = undefined;
88
+ this.canplay = true;
89
+ }
90
+ /**
91
+ * Scales the container based on the window or screen size, maintaining the aspect ratio.
92
+ * The container scales according to the minimum dimension of the screen.
93
+ *
94
+ * @param container The container element to be scaled.
95
+ */
96
+ scaleContainer(container) {
97
+ var _a;
98
+ const widths = [window.innerWidth];
99
+ if ((_a = window.screen) === null || _a === void 0 ? void 0 : _a.width) {
100
+ widths.push(window.screen.width);
101
+ }
102
+ const width = Math.min(...widths);
103
+ const height = document.documentElement.clientHeight;
104
+ const scaleX = width / 1600; // Scale based on a reference width of 1600px
105
+ const scaleY = height / 900; // Scale based on a reference height of 900px
106
+ const scale = Math.min(scaleX, scaleY);
107
+ // Center the container and apply scaling
108
+ container.style.transform = `translate(-50%, -50%) scale(${scale})`;
109
+ }
110
+ /**
111
+ * Lifecycle hook that runs after the component is loaded.
112
+ * - It scales the container.
113
+ * - It sets the background color of the body.
114
+ * - Adds event listeners for `resize` and `load` to rescale the container on window size changes.
115
+ */
116
+ componentDidLoad() {
117
+ this.scaleContainer(this.el);
118
+ document.body.style.backgroundColor = this.bgColor;
119
+ // Re-scale the container on window resize or load events
120
+ window.addEventListener('resize', () => this.scaleContainer(this.el));
121
+ window.addEventListener('load', () => this.scaleContainer(this.el));
122
+ utils.initEventsForElement(this.el, this.type);
123
+ }
124
+ render() {
125
+ // Define the styles for the container element
126
+ const style = {
127
+ backgroundColor: this.bgColor,
128
+ width: '1600px', // Fixed width of the container
129
+ height: '900px', // Fixed height of the container
130
+ position: 'absolute',
131
+ top: '50%',
132
+ left: '50%',
133
+ transform: 'translate(-50%, -50%)', // Centering the container
134
+ };
135
+ console.log('🚀 ~ AppContainer ~ canplay:', this.canplay);
136
+ return (index.h(index.Host, { key: '3de4da721c5eb3dcdd9b29e01cfcc7968d40a761', id: "container", tabindex: 0, class: "container", objective: this.objective, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onIncorrectTouch: this.onIncorrectTouch, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onEntry: this.onEntry }, index.h("slot", { key: 'bd4abd0fd97b92a6f942554be26a28d3948f7a5d' })));
137
+ }
138
+ get el() { return index.getElement(this); }
139
+ };
140
+ AppContainer.style = AppContainerStyle0;
141
+
142
+ const indexCss = "@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); body{overflow:hidden}";
143
+ const AppHomeStyle0 = indexCss;
144
+
145
+ const animationCss = "@keyframes rightToPlace{from{transform:translateX(2000px)}to{left:0}}@keyframes placeToLeft{from{}to{transform:translateX(-2000px)}}@keyframes shake{0%{transform:translateX(0);color:red;outline:4px solid red}10%{transform:translateX(-5px);color:red;outline:4px solid red}20%{transform:translateX(5px);color:red;outline:4px solid red}30%{transform:translateX(-5px);color:red;outline:4px solid red}40%{transform:translateX(5px);color:red;outline:4px solid red}50%{transform:translateX(-5px);color:red;outline:4px solid red}60%{transform:translateX(5px);color:red;outline:4px solid red}70%{transform:translateX(-5px);color:red;outline:4px solid red}80%{transform:translateX(5px);color:red;outline:4px solid red}90%{transform:translateX(-5px);color:red;outline:4px solid red}100%{transform:translateX(0);color:red;outline:4px solid red}}@keyframes fallAndBounce{0%{transform:translateY(-1000px)}25%{transform:translateY(0px)}50%{transform:translateY(-200px)}75%{transform:translateY(0)}90%{transform:translateY(-100px)}100%{transform:translateY(0)}}";
146
+ const AppHomeStyle1 = animationCss;
147
+
148
+ const appHomeCss = ".snackbar{visibility:visible;min-width:250px;background-color:#333;color:#fff;text-align:center;border-radius:2px;padding:16px;position:fixed;z-index:1;bottom:30px;left:50%;transform:translateX(-50%);font-size:17px}.dot-container{text-align:center;position:fixed;z-index:1;width:fit-content;top:1%;left:50%;transform:translate(-50%)}.dot{height:15px;width:15px;margin:0 4px;background-color:#bbb;border-radius:50%;display:inline-block;transition:background-color 0.3s;cursor:pointer}.dot.completed{background-color:grey}.dot.current{background-color:green}.dot:not(.completed):not(.current){background-color:#bbb}";
149
+ const AppHomeStyle2 = appHomeCss;
150
+
151
+ const AppHome = class {
152
+ constructor(hostRef) {
153
+ index.registerInstance(this, hostRef);
154
+ /**
155
+ * Event handler for transitioning to the next container in the sequence.
156
+ * If the last container is reached, it shows a completion message.
157
+ */
158
+ this.nextContainer = (index) => {
159
+ if (index != undefined && index == this.currentContainerIndex)
160
+ return;
161
+ // Clear selected values from localStorage on container transition
162
+ localStorage.removeItem(utils.SelectedValuesKey);
163
+ localStorage.removeItem(utils.DragSelectedMapKey);
164
+ if (index != undefined && index < this.containers.length) {
165
+ // Move to the next container
166
+ this.currentContainerIndex = index;
167
+ window.dispatchEvent(new CustomEvent('activityChange', { detail: { index: this.currentContainerIndex } }));
168
+ }
169
+ else if (this.currentContainerIndex < this.containers.length - 1) {
170
+ // Move to the next container
171
+ this.currentContainerIndex++;
172
+ window.dispatchEvent(new CustomEvent('activityChange', { detail: { index: this.currentContainerIndex } }));
173
+ }
174
+ else {
175
+ // Show the completion message if all containers have been viewed
176
+ this.showCompletionMessage = true;
177
+ const event = new CustomEvent('gameCompleted');
178
+ window.dispatchEvent(event);
179
+ // Hide the completion message after 3 seconds
180
+ setTimeout(() => {
181
+ this.showCompletionMessage = false;
182
+ }, 3000);
183
+ }
184
+ // Reset the containers array to trigger a re-render
185
+ this.containers = [...this.containers];
186
+ };
187
+ this.xmlData = undefined;
188
+ this.initialIndex = 0;
189
+ this.canplay = true;
190
+ this.currentContainerIndex = this.initialIndex;
191
+ this.showCompletionMessage = false;
192
+ this.containers = [];
193
+ }
194
+ /**
195
+ * Lifecycle method that runs before the component is loaded. It sets up event listeners for transitioning
196
+ * between containers and parses the XML data into containers.
197
+ */
198
+ componentWillLoad() {
199
+ // Listen for 'nextContainer' event to transition between containers
200
+ window.addEventListener('nextContainer', () => {
201
+ this.nextContainer();
202
+ });
203
+ window.addEventListener('changeContainer', (e) => {
204
+ this.nextContainer(e.detail.index);
205
+ });
206
+ // Parse the provided XML data
207
+ this.parseXMLData(this.xmlData);
208
+ // Remove stored values in localStorage when the page is about to be unloaded
209
+ window.addEventListener('beforeunload', () => {
210
+ localStorage.removeItem(utils.SelectedValuesKey);
211
+ localStorage.removeItem(utils.DragSelectedMapKey);
212
+ });
213
+ }
214
+ /**
215
+ * Lifecycle method that cleans up event listeners when the component is removed from the DOM.
216
+ */
217
+ disconnectedCallback() {
218
+ window.removeEventListener('nextContainer', () => {
219
+ this.nextContainer();
220
+ });
221
+ window.removeEventListener('changeContainer', (e) => {
222
+ this.nextContainer(e.detail.index);
223
+ });
224
+ }
225
+ /**
226
+ * Parses the provided XML string into an XML DOM object and extracts the containers from it.
227
+ *
228
+ * @param xmlData - The XML data as a string.
229
+ */
230
+ parseXMLData(xmlData) {
231
+ if (xmlData) {
232
+ const parser = new DOMParser();
233
+ const xmlDoc = parser.parseFromString(xmlData, 'text/xml');
234
+ const rootElement = xmlDoc.documentElement;
235
+ // Parse containers from the root XML element
236
+ this.parseContainers(rootElement);
237
+ }
238
+ }
239
+ /**
240
+ * Recursively parses an XML element and its children, converting them into corresponding Stencil components.
241
+ *
242
+ * @param element - The XML element to parse.
243
+ * @returns The corresponding Stencil component with parsed props and children.
244
+ */
245
+ parseElement(element) {
246
+ const tagName = element.nodeName.toLowerCase();
247
+ const props = {};
248
+ // Extract attributes from the element and map them to props
249
+ Array.from(element.attributes).forEach(attr => {
250
+ props[attr.name] = attr.value;
251
+ });
252
+ // Recursively parse child elements
253
+ const children = Array.from(element.childNodes)
254
+ .map(child => {
255
+ if (child.nodeType === 1) {
256
+ return this.parseElement(child);
257
+ }
258
+ else if (child.nodeType === 3 && child.textContent.trim() !== '') {
259
+ return child.textContent;
260
+ }
261
+ return null;
262
+ })
263
+ .filter(Boolean);
264
+ // Map XML tags to Stencil components
265
+ const componentMapping = {
266
+ 'app-container': (index.h("app-container", Object.assign({}, props, { canplay: this.canplay }), children)),
267
+ 'app-col': index.h("app-col", Object.assign({}, props), children),
268
+ 'app-trace': index.h("app-trace", Object.assign({}, props), children),
269
+ 'app-image': index.h("app-image", Object.assign({}, props), children),
270
+ 'app-row': index.h("app-row", Object.assign({}, props), children),
271
+ 'app-text': index.h("app-text", Object.assign({}, props), children),
272
+ 'app-pos': index.h("app-pos", Object.assign({}, props), children),
273
+ 'app-shape': index.h("app-shape", Object.assign({}, props), children),
274
+ 'app-wrap': index.h("app-wrap", Object.assign({}, props), children),
275
+ 'app-random': index.h("app-random", Object.assign({}, props), children),
276
+ };
277
+ // If the tag is known, return the corresponding Stencil component, otherwise log a warning
278
+ if (componentMapping[tagName]) {
279
+ return componentMapping[tagName];
280
+ }
281
+ else {
282
+ console.warn(`Unknown tag: ${tagName}`);
283
+ return null;
284
+ }
285
+ }
286
+ /**
287
+ * Parses the `app-container` elements from the XML root element and stores them in the `containers` state.
288
+ *
289
+ * @param rootElement - The root element of the parsed XML document.
290
+ */
291
+ parseContainers(rootElement) {
292
+ const containers = [];
293
+ const containerElements = rootElement.querySelectorAll('app-container');
294
+ // Parse each container and add it to the array
295
+ containerElements.forEach(container => {
296
+ const parsedElement = this.parseElement(container);
297
+ if (parsedElement) {
298
+ containers.push(parsedElement);
299
+ }
300
+ });
301
+ this.containers = containers;
302
+ }
303
+ /**
304
+ * Renders navigation dots for each container, indicating the progress of the user.
305
+ * Clicking on a dot allows the user to jump to a specific container.
306
+ */
307
+ renderDots() {
308
+ return (index.h("div", { id: "dot-indicator", class: "dot-container" }, this.containers.map((_, index$1) => (index.h("span", { class: `dot ${index$1 < this.currentContainerIndex ? 'completed' : index$1 === this.currentContainerIndex ? 'current' : ''}`, onClick: () => this.jumpToContainer(index$1) })))));
309
+ }
310
+ /**
311
+ * Jumps to a specific container based on the index of the dot clicked.
312
+ *
313
+ * @param index - The index of the container to jump to.
314
+ */
315
+ jumpToContainer(index) {
316
+ this.nextContainer(index);
317
+ // this.currentContainerIndex = index;
318
+ // this.containers = [...this.containers]; // Trigger re-render
319
+ }
320
+ render() {
321
+ if (!this.xmlData) {
322
+ // If no XML data is provided, prompt the user to provide it
323
+ return index.h("div", null, "Please provide XML data.");
324
+ }
325
+ return (index.h("div", null, index.h("div", { key: this.currentContainerIndex }, this.containers[this.currentContainerIndex]), this.renderDots(), this.showCompletionMessage && index.h("div", { class: "snackbar" }, "All containers have been displayed!")));
326
+ }
327
+ };
328
+ AppHome.style = AppHomeStyle0 + (AppHomeStyle1 + AppHomeStyle2);
329
+
330
+ const appImageCss = ".image{user-select:none;-webkit-user-drag:none;object-fit:contain;max-width:100%;max-height:100%;aspect-ratio:1 / 1;}";
331
+ const AppImageStyle0 = appImageCss;
332
+
333
+ const AppImage = class {
334
+ constructor(hostRef) {
335
+ index.registerInstance(this, hostRef);
336
+ this.value = undefined;
337
+ this.height = undefined;
338
+ this.width = undefined;
339
+ this.ariaLabel = undefined;
340
+ this.ariaHidden = undefined;
341
+ this.x = undefined;
342
+ this.y = undefined;
343
+ this.z = undefined;
344
+ this.bgColor = undefined;
345
+ this.type = undefined;
346
+ this.tabIndex = undefined;
347
+ this.visible = undefined;
348
+ this.audio = undefined;
349
+ this.onTouch = undefined;
350
+ this.onCorrectTouch = undefined;
351
+ this.onInCorrectTouch = undefined;
352
+ this.onCorrectMatch = undefined;
353
+ this.onMatch = undefined;
354
+ this.onWrong = undefined;
355
+ this.onEntry = undefined;
356
+ this.src = undefined;
357
+ }
358
+ /**
359
+ * Lifecycle method that runs after the component has been loaded into the DOM.
360
+ * It initializes custom events based on the `type` of the image component.
361
+ */
362
+ componentDidLoad() {
363
+ utils.initEventsForElement(this.el, this.type);
364
+ }
365
+ render() {
366
+ // Inline styles for the image, including dimensions, positioning, and visibility
367
+ const style = {
368
+ height: this.height,
369
+ width: this.width,
370
+ backgroundColor: this.bgColor,
371
+ top: this.y,
372
+ left: this.x,
373
+ zIndex: this.z,
374
+ display: this.visible ? 'flex' : 'none',
375
+ alignItems: 'center', // Vertically center the image
376
+ justifyContent: 'center', // Horizontally center the image
377
+ };
378
+ return (index.h(index.Host, { key: 'bc0557fa586341933b698df56ecc5929b4185a58', type: this.type, tabindex: this.tabIndex, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, value: this.value, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }, index.h("img", { key: 'fa5cc8aacf12b26625b4bc68a52f19144bc82f99', class: "image", src: this.src, alt: "", style: style })));
379
+ }
380
+ get el() { return index.getElement(this); }
381
+ };
382
+ AppImage.style = AppImageStyle0;
383
+
384
+ const appPosCss = ".pos{top:var(--y, 0);left:var(--x, 0);height:var(--height, 100%);width:var(--width, 100%);background-color:var(--bgColor, #eeeeee);display:flex;justify-content:space-around;flex-direction:column;position:fixed}.pos>*{position:absolute}";
385
+ const AppPosStyle0 = appPosCss;
386
+
387
+ const AppPos = class {
388
+ constructor(hostRef) {
389
+ index.registerInstance(this, hostRef);
390
+ this.id = undefined;
391
+ this.value = undefined;
392
+ this.height = undefined;
393
+ this.width = undefined;
394
+ this.ariaLabel = undefined;
395
+ this.ariaHidden = undefined;
396
+ this.x = undefined;
397
+ this.y = undefined;
398
+ this.z = undefined;
399
+ this.bgColor = undefined;
400
+ this.type = undefined;
401
+ this.tabIndex = undefined;
402
+ this.visible = undefined;
403
+ this.audio = undefined;
404
+ this.onTouch = undefined;
405
+ this.onCorrectTouch = undefined;
406
+ this.onInCorrectTouch = undefined;
407
+ this.onCorrectMatch = undefined;
408
+ this.onMatch = undefined;
409
+ this.onWrong = undefined;
410
+ this.onEntry = undefined;
411
+ }
412
+ /**
413
+ * Lifecycle hook that is called after the component has been rendered in the DOM.
414
+ * It initializes custom events based on the `type` of the component.
415
+ */
416
+ componentDidLoad() {
417
+ utils.initEventsForElement(this.el, this.type);
418
+ }
419
+ render() {
420
+ // Inline styles to position and size the component
421
+ const style = {
422
+ height: this.height,
423
+ width: this.width,
424
+ backgroundColor: this.bgColor,
425
+ top: this.y,
426
+ left: this.x,
427
+ zIndex: this.z,
428
+ display: this.visible ? 'block' : 'none', // Toggle visibility
429
+ };
430
+ return (index.h(index.Host, { key: 'c63889200e5b87ccddf17f236898df959b643aee', id: this.id, class: "pos", type: this.type, tabindex: this.tabIndex, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, value: this.value, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }, index.h("slot", { key: '09b1a03217ffc2c02836f4ac6f61f0887b8445cb' })));
431
+ }
432
+ get el() { return index.getElement(this); }
433
+ };
434
+ AppPos.style = AppPosStyle0;
435
+
436
+ const appRandomCss = ".random{display:flex;justify-content:space-between;align-items:center;position:absolute;}.random>*{position:absolute}";
437
+ const AppRandomStyle0 = appRandomCss;
438
+
439
+ const AppRandom = class {
440
+ constructor(hostRef) {
441
+ index.registerInstance(this, hostRef);
442
+ this.id = undefined;
443
+ this.value = undefined;
444
+ this.height = undefined;
445
+ this.width = undefined;
446
+ this.ariaLabel = undefined;
447
+ this.ariaHidden = undefined;
448
+ this.x = undefined;
449
+ this.y = undefined;
450
+ this.z = undefined;
451
+ this.bgColor = undefined;
452
+ this.type = undefined;
453
+ this.tabIndex = undefined;
454
+ this.visible = undefined;
455
+ this.audio = undefined;
456
+ this.onTouch = undefined;
457
+ this.onCorrectTouch = undefined;
458
+ this.onInCorrectTouch = undefined;
459
+ this.onCorrectMatch = undefined;
460
+ this.onMatch = undefined;
461
+ this.onWrong = undefined;
462
+ this.onEntry = undefined;
463
+ }
464
+ /**
465
+ * Lifecycle hook that runs after the component is rendered in the DOM.
466
+ * It randomly positions all child elements within the container using CSS `top` and `left` percentages.
467
+ */
468
+ componentDidLoad() {
469
+ // Select all direct child elements of the component
470
+ const slotElements = this.el.querySelectorAll('.random > *');
471
+ // Iterate over each child and apply random positions
472
+ slotElements.forEach((child) => {
473
+ const randomTop = Math.random() * 100; // Random value between 0 and 100 for vertical position
474
+ const randomLeft = Math.random() * 100; // Random value between 0 and 100 for horizontal position
475
+ child.style.top = `${randomTop}%`;
476
+ child.style.left = `${randomLeft}%`;
477
+ });
478
+ }
479
+ render() {
480
+ // Inline styles for the container, including dimensions, positioning, and visibility
481
+ const style = {
482
+ height: this.height,
483
+ width: this.width,
484
+ top: this.y,
485
+ left: this.x,
486
+ display: this.visible ? 'block' : 'none', // Toggle visibility
487
+ zIndex: this.z,
488
+ backgroundColor: this.bgColor,
489
+ };
490
+ return (index.h(index.Host, { key: '66b661510df51498d8aaeaa3b8c43d7caf3ab6d1', class: "random", type: this.type, tabindex: this.tabIndex, value: this.value, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }, index.h("slot", { key: '70b2819af97f7d1f85de0ea1161ae95014e427f4' })));
491
+ }
492
+ get el() { return index.getElement(this); }
493
+ };
494
+ AppRandom.style = AppRandomStyle0;
495
+
496
+ const AppRoot = class {
497
+ constructor(hostRef) {
498
+ index.registerInstance(this, hostRef);
499
+ this.xmlPath = undefined;
500
+ this.initialIndex = 0;
501
+ this.canplay = true;
502
+ this.xmlData = undefined;
503
+ }
504
+ /**
505
+ * Lifecycle method that runs before the component is loaded.
506
+ * It fetches the XML data from the specified path or URL and sets it to the component's state.
507
+ */
508
+ async componentWillLoad() {
509
+ // Validate the xmlPath prop
510
+ if (!this.xmlPath) {
511
+ console.error('XML path is not provided.');
512
+ return;
513
+ }
514
+ // Fetch the XML data
515
+ try {
516
+ const resolvedPath = this.xmlPath.startsWith('http')
517
+ ? this.xmlPath // Use the provided URL if it's an HTTP/HTTPS link
518
+ : index.getAssetPath(this.xmlPath); // Otherwise, resolve it as an asset path
519
+ const response = await fetch(resolvedPath);
520
+ if (!response.ok) {
521
+ throw new Error(`Failed to fetch XML data: ${response.statusText}`);
522
+ }
523
+ const data = await response.text();
524
+ // Store the XML data in the component's state
525
+ this.xmlData = data;
526
+ }
527
+ catch (error) {
528
+ console.error('Error fetching XML data:', error);
529
+ this.xmlData = null;
530
+ }
531
+ }
532
+ render() {
533
+ // Show a loading message until the XML data is fetched
534
+ if (this.xmlData === undefined) {
535
+ return index.h("div", null, "Loading...");
536
+ }
537
+ // Show an error message if the XML data could not be fetched
538
+ if (this.xmlData === null) {
539
+ return index.h("div", null, "Error loading XML data. Please check the path or URL.");
540
+ }
541
+ // Once the XML data is loaded, pass it to the `app-home` component
542
+ return index.h("app-home", { initialIndex: this.initialIndex, canplay: this.canplay, xmlData: this.xmlData });
543
+ }
544
+ static get assetsDirs() { return ["assets"]; }
545
+ };
546
+
547
+ const appRowCss = ".row{display:flex;justify-content:space-between;align-items:center;}.row>*{}";
548
+ const AppRowStyle0 = appRowCss;
549
+
550
+ const AppRow = class {
551
+ constructor(hostRef) {
552
+ index.registerInstance(this, hostRef);
553
+ this.value = undefined;
554
+ this.height = undefined;
555
+ this.width = undefined;
556
+ this.ariaLabel = undefined;
557
+ this.ariaHidden = undefined;
558
+ this.x = undefined;
559
+ this.y = undefined;
560
+ this.z = undefined;
561
+ this.bgColor = undefined;
562
+ this.type = undefined;
563
+ this.tabIndex = undefined;
564
+ this.visible = undefined;
565
+ this.audio = undefined;
566
+ this.onTouch = undefined;
567
+ this.onCorrectTouch = undefined;
568
+ this.onInCorrectTouch = undefined;
569
+ this.onCorrectMatch = undefined;
570
+ this.onMatch = undefined;
571
+ this.onWrong = undefined;
572
+ this.onEntry = undefined;
573
+ }
574
+ /**
575
+ * Lifecycle hook that runs after the component is loaded into the DOM.
576
+ * It initializes custom events based on the `type` of the row component.
577
+ */
578
+ componentDidLoad() {
579
+ utils.initEventsForElement(this.el, this.type);
580
+ }
581
+ render() {
582
+ // Inline styles to position and size the row component
583
+ const style = {
584
+ height: this.height,
585
+ width: this.width,
586
+ top: this.y,
587
+ left: this.x,
588
+ display: this.visible ? 'flex' : 'none', // Flexbox for row layout
589
+ zIndex: this.z,
590
+ backgroundColor: this.bgColor, // Apply background color if provided
591
+ };
592
+ return (index.h(index.Host, { key: 'fc3153fcef0ccc98d99afd2e93607e8c71c0a591', class: "row", type: this.type, tabindex: this.tabIndex, value: this.value, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }, index.h("slot", { key: 'b28ce98adfc7ad7c9ac191eae523b974f9bb97f6' })));
593
+ }
594
+ get el() { return index.getElement(this); }
595
+ };
596
+ AppRow.style = AppRowStyle0;
597
+
598
+ const appShapeCss = ".shape{position:absolute;top:var(--y);left:var(--x);display:var(--display);z-index:var(--z)}.rectangle{border-radius:0}.circle{width:var(--width);height:var(--width);border-radius:50%;background-color:var(--bgColor)}.ellipse{width:var(--width);height:var(--height);border-radius:50%;background-color:var(--bgColor)}.triangle{width:var(--triangleWidth);height:var(--triangleHeight);background-color:var(--bgColor);clip-path:polygon(50% 0%, 100% 100%, 0% 100%)}.rightTriangle{width:var(--triangleWidth);height:var(--triangleHeight);background-color:var(--bgColor);clip-path:polygon(100% 0%, 100% 100%, 0% 100%)}.leftTriangle{width:var(--triangleWidth);height:var(--triangleHeight);background-color:var(--triangleBgColor);clip-path:polygon(0% 0%, 100% 100%, 0% 100%)}.parallelogram{width:var(--paralleWidth);height:var(--paralleHeight);transform:skew(20deg)}.star{width:var(--starWidth);height:var(--starHeight);background-color:var(--starBgColor);clip-path:polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)}.pentagon{width:var(--pentagonWidth);height:var(--pentagonHeight);background-color:var(--pentagonBgColor);clip-path:polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%)}.heptagon{width:var(--heptagonWidth);height:var(--heptagonHeight);background-color:var(--heptagonBgColor);clip-path:polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%)}.octagon{width:var(--octagonWidth);height:var(--octagonHeight);background-color:var(--octagonBgColor);clip-path:polygon(25% 0%, 75% 0%, 100% 25%, 100% 75%, 75% 100%, 25% 100%, 0% 75%, 0% 25%)}.rhombus{width:var(--rhombusWidth);height:var(--rhombusHeight);background-color:var(--rhombusBgColor);clip-path:polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)}.heart{height:var(--heartHeight);width:var(--heartWidth);border-image:radial-gradient(var(--heartBgColor) 69%, #0000 70%) 84.5%/50%;clip-path:polygon(-41% 0, 50% 91%, 141% 0)}";
599
+ const AppShapeStyle0 = appShapeCss;
600
+
601
+ const AppShape = class {
602
+ constructor(hostRef) {
603
+ index.registerInstance(this, hostRef);
604
+ this.id = undefined;
605
+ this.value = undefined;
606
+ this.height = undefined;
607
+ this.width = undefined;
608
+ this.ariaLabel = undefined;
609
+ this.ariaHidden = undefined;
610
+ this.x = undefined;
611
+ this.y = undefined;
612
+ this.z = undefined;
613
+ this.bgColor = undefined;
614
+ this.type = undefined;
615
+ this.tabIndex = undefined;
616
+ this.shapeType = undefined;
617
+ this.visible = undefined;
618
+ this.audio = undefined;
619
+ this.onTouch = undefined;
620
+ this.onCorrectTouch = undefined;
621
+ this.onInCorrectTouch = undefined;
622
+ this.onCorrectMatch = undefined;
623
+ this.onMatch = undefined;
624
+ this.onWrong = undefined;
625
+ this.onEntry = undefined;
626
+ }
627
+ /**
628
+ * Lifecycle hook that runs after the component is loaded into the DOM.
629
+ * It initializes custom events based on the `type` of the shape component.
630
+ */
631
+ componentDidLoad() {
632
+ utils.initEventsForElement(this.el, this.type);
633
+ }
634
+ render() {
635
+ // Inline styles to position and size the shape component
636
+ const style = {
637
+ height: this.shapeType !== 'polygon' ? this.height : undefined, // Set height unless it's a polygon
638
+ width: this.shapeType !== 'polygon' ? this.width : undefined, // Set width unless it's a polygon
639
+ top: this.y,
640
+ left: this.x,
641
+ display: this.visible ? 'block' : 'none', // Toggle visibility
642
+ zIndex: this.z,
643
+ backgroundColor: this.shapeType !== 'polygon' ? this.bgColor : 'transparent', // Apply background only if not a polygon
644
+ };
645
+ return (index.h(index.Host, { key: '64db966fc0a1f601fd0002d0f71de3ec3aae241a', class: `shape ${this.shapeType}`, value: this.value, type: this.type, tabindex: this.tabIndex, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }));
646
+ }
647
+ get el() { return index.getElement(this); }
648
+ };
649
+ AppShape.style = AppShapeStyle0;
650
+
651
+ const appTextCss = ".text{background-color:#fff;box-shadow:0 2px 4px rgba(0, 0, 0, 0.1);transition:background-color 0.3s ease;user-select:none;align-items:center;justify-content:center;text-align:center;border-radius:8px;color:#333;cursor:pointer}.text:hover{background-color:#f0f0f0}";
652
+ const AppTextStyle0 = appTextCss;
653
+
654
+ const AppText = class {
655
+ constructor(hostRef) {
656
+ index.registerInstance(this, hostRef);
657
+ this.id = undefined;
658
+ this.value = undefined;
659
+ this.string = undefined;
660
+ this.font = undefined;
661
+ this.fontSize = undefined;
662
+ this.fontColor = undefined;
663
+ this.highlightWhileSpeaking = undefined;
664
+ this.height = undefined;
665
+ this.width = undefined;
666
+ this.ariaLabel = undefined;
667
+ this.ariaHidden = undefined;
668
+ this.x = undefined;
669
+ this.y = undefined;
670
+ this.z = undefined;
671
+ this.bgColor = undefined;
672
+ this.type = undefined;
673
+ this.tabIndex = undefined;
674
+ this.visible = undefined;
675
+ this.audio = undefined;
676
+ this.onTouch = undefined;
677
+ this.onCorrectTouch = undefined;
678
+ this.onInCorrectTouch = undefined;
679
+ this.onCorrectMatch = undefined;
680
+ this.onMatch = undefined;
681
+ this.onWrong = undefined;
682
+ this.onEntry = undefined;
683
+ }
684
+ /**
685
+ * Lifecycle hook that runs after the component is rendered in the DOM.
686
+ * It initializes custom events based on the `type` of the text component.
687
+ */
688
+ componentDidLoad() {
689
+ utils.initEventsForElement(this.el, this.type);
690
+ }
691
+ render() {
692
+ // Inline styles to customize the appearance and positioning of the text component
693
+ const style = {
694
+ height: this.height,
695
+ width: this.width,
696
+ backgroundColor: this.bgColor,
697
+ top: this.y,
698
+ left: this.x,
699
+ zIndex: this.z,
700
+ fontSize: this.fontSize,
701
+ fontFamily: this.font,
702
+ color: this.fontColor,
703
+ display: this.visible ? 'flex' : 'none', // Show or hide based on visibility prop
704
+ };
705
+ return (index.h(index.Host, { key: '06c76433420706301a70a892a9081dfea480167e', class: "text", value: this.value, type: this.type, tabindex: this.tabIndex, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry, id: this.id, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden }, this.string));
706
+ }
707
+ get el() { return index.getElement(this); }
708
+ };
709
+ AppText.style = AppTextStyle0;
710
+
711
+ const appTraceCss = ":host{display:block;position:relative}#svgContainer{position:absolute;top:0;left:0;right:0;bottom:50px;display:flex;justify-content:center;align-items:center;overflow:hidden}svg{width:100%;height:100%;max-height:calc(100vh - 50px);touch-action:none}#draggableCircle{cursor:pointer;fill:red;transition:fill 0.2s, r 0.2s}.blindTracing{stroke:none !important}.blindFreeTrace{stroke:none !important}.hovered{cursor:grab;fill:darkred}#controls{position:fixed;bottom:0;left:0;right:0;display:flex;justify-content:space-between;padding:10px;background-color:#f0f0f0;border-top:1px solid #ccc}button{padding:10px;font-size:16px}@media (max-width: 600px){button{padding:8px;font-size:14px}}.trace-path-green{stroke:green !important}";
712
+ const AppTraceStyle0 = appTraceCss;
713
+
714
+ const AppTrace = class {
715
+ constructor(hostRef) {
716
+ index.registerInstance(this, hostRef);
717
+ this.id = undefined;
718
+ this.svgSource = undefined;
719
+ this.value = undefined;
720
+ this.height = undefined;
721
+ this.width = undefined;
722
+ this.x = undefined;
723
+ this.y = undefined;
724
+ this.z = undefined;
725
+ this.ariaLabel = undefined;
726
+ this.ariaHidden = undefined;
727
+ this.tabIndex = undefined;
728
+ this.mode = undefined;
729
+ this.fileIndex = -1;
730
+ this.isDragging = false;
731
+ this.activePointerId = null;
732
+ }
733
+ // MODES = ['noFlow', 'showFlow', 'freeTrace', 'blindTracing', 'blindFreeTrace'];
734
+ // Handle the pointermove event with optimizations
735
+ // Update the path trace as the red circle moves
736
+ async initializeSVG() {
737
+ let state = {
738
+ fileIndex: -1,
739
+ currentPathIndex: 0,
740
+ lastLength: 0,
741
+ totalPathLength: 0,
742
+ isDragging: false,
743
+ circle: null,
744
+ paths: [],
745
+ svg: null,
746
+ proximityThreshold: 100, // General proximity threshold
747
+ freeTraceProximityThreshold: 50, // Reduced proximity threshold for free trace
748
+ rafId: null,
749
+ pointerMoveEvent: null,
750
+ activePointerId: null,
751
+ mode: this.mode,
752
+ flowMarkers: [],
753
+ freeTraceLines: [],
754
+ };
755
+ await this.loadAnotherSVG(state, true); // Load the first SVG
756
+ }
757
+ componentWillLoad() {
758
+ this.initializeSVG();
759
+ }
760
+ // Fetch the SVG file asynchronously
761
+ async fetchSVG(url) {
762
+ const response = await fetch(url);
763
+ if (!response.ok) {
764
+ throw new Error(`Failed to fetch SVG (${url}): ${response.statusText}`);
765
+ }
766
+ return await response.text();
767
+ }
768
+ // to calculate the bounding box of all paths
769
+ calculateBoundingBox(paths, padding = 22) {
770
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
771
+ paths.forEach(path => {
772
+ const length = path.getTotalLength();
773
+ const numPoints = 100; // Number of points to sample along the path
774
+ for (let i = 0; i <= numPoints; i++) {
775
+ const point = path.getPointAtLength((i / numPoints) * length);
776
+ if (point.x < minX)
777
+ minX = point.x;
778
+ if (point.y < minY)
779
+ minY = point.y;
780
+ if (point.x > maxX)
781
+ maxX = point.x;
782
+ if (point.y > maxY)
783
+ maxY = point.y;
784
+ }
785
+ });
786
+ // Apply padding
787
+ minX -= padding;
788
+ minY -= padding;
789
+ maxX += padding;
790
+ maxY += padding;
791
+ return { minX, minY, maxX, maxY };
792
+ }
793
+ // Insert the fetched SVG into the container and adjust viewBox
794
+ insertSVG(svgText) {
795
+ const svgContainer = document.getElementById('svgContainer');
796
+ svgContainer.innerHTML = svgText;
797
+ // After inserting, get the SVG element
798
+ const svgElement = svgContainer.querySelector('svg');
799
+ // Remove the width and height attributes from the SVG element
800
+ svgElement.removeAttribute('width');
801
+ svgElement.removeAttribute('height');
802
+ // Get all paths
803
+ const paths = svgElement.querySelectorAll('path, line');
804
+ // Calculate bounding box
805
+ const bbox = this.calculateBoundingBox(Array.from(paths));
806
+ // Set the viewBox to the bounding box
807
+ const viewBoxWidth = bbox.maxX - bbox.minX;
808
+ const viewBoxHeight = bbox.maxY - bbox.minY;
809
+ svgElement.setAttribute('viewBox', `${bbox.minX} ${bbox.minY} ${viewBoxWidth} ${viewBoxHeight}`);
810
+ }
811
+ // Retrieve the SVG element from the container
812
+ getSVGElement() {
813
+ const svgContainer = document.getElementById('svgContainer');
814
+ return svgContainer.querySelector('svg');
815
+ }
816
+ // Get all path and line elements from the SVG
817
+ getPaths(svg) {
818
+ return Array.from(svg.querySelectorAll('path, line'));
819
+ }
820
+ // Create flow markers along the path to guide the user
821
+ createFlowMarkersForPath(path, markerCount = 10) {
822
+ var _a;
823
+ const totalLength = path.getTotalLength();
824
+ const interval = totalLength / (markerCount + 1); // Space markers evenly
825
+ const markers = [];
826
+ for (let i = 1; i <= markerCount; i++) {
827
+ const point = path.getPointAtLength(i * interval);
828
+ const nextPoint = path.getPointAtLength((i + 0.5) * interval); // Slightly ahead point for direction
829
+ // Create an arrow marker
830
+ const angle = Math.atan2(nextPoint.y - point.y, nextPoint.x - point.x);
831
+ const arrowMarker = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
832
+ arrowMarker.setAttribute('points', '-5,-5 0,0 -5,5');
833
+ arrowMarker.setAttribute('fill', 'blue');
834
+ arrowMarker.setAttribute('transform', `translate(${point.x},${point.y}) rotate(${(angle * 180) / Math.PI})`);
835
+ arrowMarker.setAttribute('class', 'flow-indicator');
836
+ markers.push(arrowMarker);
837
+ (_a = path.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(arrowMarker); // Append to the same SVG container
838
+ }
839
+ return markers;
840
+ }
841
+ // Show or hide flow indicators based on mode
842
+ updateFlowIndicators(state) {
843
+ const indicators = state.svg.querySelectorAll('.flow-indicator');
844
+ indicators.forEach(indicator => {
845
+ if (state.mode === utils.TraceMode.NoFlow) {
846
+ indicator.style.display = 'none';
847
+ }
848
+ else if (state.mode === utils.TraceMode.ShowFlow) {
849
+ indicator.style.display = 'block';
850
+ }
851
+ });
852
+ }
853
+ // Create a new path element for the drawing effect
854
+ setupDrawingPath(state) {
855
+ state.paths.forEach((path, index) => {
856
+ const pathLength = path.getTotalLength();
857
+ // Create green path for tracing effect
858
+ const greenPath = path.cloneNode();
859
+ greenPath.setAttribute('stroke', 'green');
860
+ greenPath.setAttribute('stroke-width', '13');
861
+ greenPath.setAttribute('stroke-dasharray', pathLength.toString());
862
+ greenPath.setAttribute('stroke-dashoffset', pathLength.toString()); // Hidden initially
863
+ path.parentNode.appendChild(greenPath, path);
864
+ path.setAttribute('class', 'trace-path'); // Add class for easier reference
865
+ greenPath.setAttribute('class', 'trace-path-green'); // Add class for easier reference
866
+ path.greenPath = greenPath;
867
+ path.classList.add(state.mode);
868
+ // Conditionally hide or show the black path based on blind tracing mode
869
+ if (state.mode === utils.TraceMode.BlindTracing || state.mode === utils.TraceMode.BlindFreeTrace) {
870
+ // In blind tracing or blind free trace mode, hide the black path
871
+ path.setAttribute('stroke', 'none');
872
+ }
873
+ else {
874
+ // In other modes, show the black path
875
+ path.setAttribute('stroke', '#000');
876
+ path.setAttribute('stroke-width', '10');
877
+ path.setAttribute('fill', 'none');
878
+ path.setAttribute('stroke-dasharray', pathLength.toString());
879
+ path.setAttribute('stroke-dashoffset', '0'); // Fully visible initially
880
+ }
881
+ // Only create flow markers for the current path in normal modes
882
+ if (index === state.currentPathIndex && state.mode === utils.TraceMode.ShowFlow) {
883
+ state.flowMarkers = this.createFlowMarkersForPath(path);
884
+ }
885
+ });
886
+ state.totalPathLength = state.paths[state.currentPathIndex].getTotalLength();
887
+ }
888
+ // Set up the draggable circle at the start of the first path
889
+ setupDraggableCircle(state) {
890
+ var _a;
891
+ const firstPathStart = state.paths[0].getPointAtLength(0);
892
+ const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
893
+ circle.setAttribute('id', 'draggableCircle');
894
+ circle.setAttribute('cx', firstPathStart.x.toString());
895
+ circle.setAttribute('cy', firstPathStart.y.toString());
896
+ circle.setAttribute('r', '20'); // Radius of the draggable circle
897
+ circle.setAttribute('fill', 'red');
898
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.appendChild(circle);
899
+ state.circle = circle;
900
+ }
901
+ // Add necessary event listeners using Pointer Events
902
+ addEventListeners(state) {
903
+ var _a, _b, _c, _d;
904
+ // Ensure the circle exists before adding events
905
+ if (!state.circle || !state.paths || state.paths.length === 0)
906
+ return;
907
+ // Handle pointerdown on the circle to start dragging
908
+ state.circle.addEventListener('pointerdown', (evt) => {
909
+ evt.preventDefault(); // Prevent default actions like text selection
910
+ const pointerPos = this.getPointerPosition(evt, state.svg);
911
+ const circlePos = {
912
+ x: parseFloat(state.circle.getAttribute('cx')),
913
+ y: parseFloat(state.circle.getAttribute('cy')),
914
+ };
915
+ const distance = this.getDistanceSquared(pointerPos, circlePos);
916
+ if (distance <= state.proximityThreshold * state.proximityThreshold) {
917
+ state.isDragging = true;
918
+ state.activePointerId = evt.pointerId;
919
+ // Capture the pointer to continue receiving events even if it leaves the element
920
+ state.circle.setPointerCapture(evt.pointerId);
921
+ }
922
+ });
923
+ // Handle pointermove on the SVG to update the circle position
924
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.addEventListener('pointermove', (evt) => {
925
+ if (!state.isDragging || evt.pointerId !== state.activePointerId)
926
+ return;
927
+ state.pointerMoveEvent = evt;
928
+ if (!state.rafId) {
929
+ state.rafId = requestAnimationFrame(() => {
930
+ this.handlePointerMove(state);
931
+ state.rafId = null;
932
+ });
933
+ }
934
+ });
935
+ // Handle pointerup and pointercancel on the SVG to stop dragging
936
+ (_b = state.svg) === null || _b === void 0 ? void 0 : _b.addEventListener('pointerup', (evt) => {
937
+ if (evt.pointerId === state.activePointerId) {
938
+ state.isDragging = false;
939
+ state.activePointerId = null;
940
+ }
941
+ });
942
+ (_c = state.svg) === null || _c === void 0 ? void 0 : _c.addEventListener('pointercancel', (evt) => {
943
+ if (evt.pointerId === state.activePointerId) {
944
+ state.isDragging = false;
945
+ state.activePointerId = null;
946
+ }
947
+ });
948
+ // Optional: Prevent context menu on long press
949
+ (_d = state.svg) === null || _d === void 0 ? void 0 : _d.addEventListener('contextmenu', (evt) => {
950
+ evt.preventDefault();
951
+ });
952
+ }
953
+ // Modified handlePointerMove function
954
+ handlePointerMove(state) {
955
+ var _a, _b, _c, _d;
956
+ if (!state.isDragging)
957
+ return;
958
+ if (!state.circle || !state.paths || state.paths.length === 0)
959
+ return;
960
+ const evt = state.pointerMoveEvent;
961
+ const pointerPos = this.getPointerPosition(evt, state.svg);
962
+ const circlePos = {
963
+ x: parseFloat(state.circle.getAttribute('cx')),
964
+ y: parseFloat(state.circle.getAttribute('cy')),
965
+ };
966
+ const currentPath = state.paths[state.currentPathIndex];
967
+ if (!currentPath) {
968
+ console.error('No valid path found at the current index');
969
+ return;
970
+ }
971
+ // Use a reduced proximity threshold for free trace mode
972
+ let proximitySquared;
973
+ if (state.mode === utils.TraceMode.FreeTrace || state.mode === utils.TraceMode.BlindFreeTrace) {
974
+ proximitySquared = state.freeTraceProximityThreshold * state.freeTraceProximityThreshold;
975
+ }
976
+ else {
977
+ proximitySquared = state.proximityThreshold * state.proximityThreshold;
978
+ }
979
+ // Calculate the distance between the pointer and the draggable circle
980
+ const distanceSquared = this.getDistanceSquared(pointerPos, circlePos);
981
+ // If the pointer is outside the proximity threshold, do not proceed with drawing or moving
982
+ if (distanceSquared > proximitySquared) {
983
+ return; // Skip any further actions
984
+ }
985
+ const closestPoint = this.getClosestPointOnPath(currentPath, pointerPos);
986
+ // Ensure drawing happens only within proximity threshold
987
+ const distanceToPathSquared = this.getDistanceSquared(pointerPos, closestPoint);
988
+ if (distanceToPathSquared > proximitySquared) {
989
+ return; // Skip drawing if too far from the path
990
+ }
991
+ // For free trace mode and blind free trace mode, allow free drawing only if within the reduced proximity threshold
992
+ if (state.mode === utils.TraceMode.FreeTrace || state.mode === utils.TraceMode.BlindFreeTrace) {
993
+ // Initialize the currentFreePath array if it's not created
994
+ if (!state.currentFreePath) {
995
+ state.currentFreePath = [];
996
+ }
997
+ // Create a new path element if it's the first trace for the current path index
998
+ if (!state.currentFreePath[state.currentPathIndex]) {
999
+ const newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
1000
+ newPath.setAttribute('stroke', 'green');
1001
+ newPath.setAttribute('stroke-width', '8');
1002
+ newPath.setAttribute('fill', 'none');
1003
+ // Start the new path at the current pointer position
1004
+ newPath.setAttribute('d', `M${pointerPos.x},${pointerPos.y}`);
1005
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.appendChild(newPath);
1006
+ state.currentFreePath[state.currentPathIndex] = newPath;
1007
+ // Reset lastPointerPos for the new path
1008
+ state.lastPointerPos = pointerPos;
1009
+ }
1010
+ // Get the previous position to draw a smooth curve
1011
+ const previousPos = state.lastPointerPos || pointerPos;
1012
+ // Create a quadratic curve from the previous point to the current point
1013
+ const newPathData = state.currentFreePath[state.currentPathIndex].getAttribute('d');
1014
+ const midPointX = (previousPos.x + pointerPos.x) / 2;
1015
+ const midPointY = (previousPos.y + pointerPos.y) / 2;
1016
+ const updatedPathData = `${newPathData} Q ${previousPos.x},${previousPos.y} ${midPointX},${midPointY}`;
1017
+ // Update the path's 'd' attribute with the new curve
1018
+ state.currentFreePath[state.currentPathIndex].setAttribute('d', updatedPathData);
1019
+ // Move the draggable circle with the freehand trace
1020
+ state.circle.setAttribute('cx', pointerPos.x.toString());
1021
+ state.circle.setAttribute('cy', pointerPos.y.toString());
1022
+ // Make sure the red dot (circle) is always on top
1023
+ (_b = state.svg) === null || _b === void 0 ? void 0 : _b.appendChild(state.circle); // This moves the circle to the last child, making it the topmost
1024
+ // Update the last pointer position
1025
+ state.lastPointerPos = pointerPos;
1026
+ const currentPathLength = currentPath.getTotalLength();
1027
+ const distanceToEnd = currentPathLength - closestPoint.length;
1028
+ // If close to the end of the path, move to the next path
1029
+ if (distanceToEnd < 5) {
1030
+ this.moveToNextPath(state);
1031
+ state.currentFreePath[state.currentPathIndex] = null; // Reset free path for next path
1032
+ }
1033
+ return; // Exit early since we're in free trace or blind free trace mode
1034
+ }
1035
+ // In normal modes, allow movement and drawing only within the general proximity threshold
1036
+ if (state.isDragging && closestPoint.length >= state.lastLength) {
1037
+ state.lastLength = closestPoint.length;
1038
+ state.circle.setAttribute('cx', closestPoint.x.toString());
1039
+ state.circle.setAttribute('cy', closestPoint.y.toString());
1040
+ // Make sure the red dot (circle) is always on top
1041
+ (_c = state.svg) === null || _c === void 0 ? void 0 : _c.appendChild(state.circle); // This moves the circle to the last child, making it the topmost
1042
+ (_d = currentPath.greenPath) === null || _d === void 0 ? void 0 : _d.setAttribute('stroke-dashoffset', (state.totalPathLength - state.lastLength).toString());
1043
+ }
1044
+ // Check if the current path is completed
1045
+ if (state.totalPathLength - 1 - state.lastLength < 5 && state.currentPathIndex < state.paths.length - 1) {
1046
+ this.moveToNextPath(state);
1047
+ }
1048
+ else if (state.totalPathLength - 1 - state.lastLength < 5 && state.currentPathIndex === state.paths.length - 1) {
1049
+ // this.loadAnotherSVG(state, true);
1050
+ utils.triggerNextContainer();
1051
+ }
1052
+ }
1053
+ // Get the pointer position relative to the SVG
1054
+ getPointerPosition(evt, svg) {
1055
+ var _a;
1056
+ const svgPoint = svg.createSVGPoint();
1057
+ svgPoint.x = evt.clientX;
1058
+ svgPoint.y = evt.clientY;
1059
+ const ctm = (_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse();
1060
+ return ctm ? svgPoint.matrixTransform(ctm) : { x: evt.clientX, y: evt.clientY };
1061
+ }
1062
+ // Calculate the squared Euclidean distance between two points
1063
+ getDistanceSquared(p1, p2) {
1064
+ const dx = p1.x - p2.x;
1065
+ const dy = p1.y - p2.y;
1066
+ return dx * dx + dy * dy;
1067
+ }
1068
+ // Find the closest point on the given path to the specified point using two-pass sampling
1069
+ getClosestPointOnPath(pathNode, point) {
1070
+ const pathLength = pathNode.getTotalLength();
1071
+ let closestPoint = { x: 0, y: 0, length: 0 };
1072
+ let minDistanceSquared = Infinity;
1073
+ // First pass: coarse sampling
1074
+ const coarseStep = 20; // Increased step for better performance
1075
+ let coarseClosestPoint = { x: 0, y: 0, length: 0 };
1076
+ let coarseMinDistanceSquared = Infinity;
1077
+ for (let i = 0; i <= pathLength; i += coarseStep) {
1078
+ const pointOnPath = pathNode.getPointAtLength(i);
1079
+ const distanceSquared = this.getDistanceSquared(point, pointOnPath);
1080
+ if (distanceSquared < coarseMinDistanceSquared) {
1081
+ coarseMinDistanceSquared = distanceSquared;
1082
+ coarseClosestPoint = {
1083
+ x: pointOnPath.x,
1084
+ y: pointOnPath.y,
1085
+ length: i,
1086
+ };
1087
+ }
1088
+ }
1089
+ // Second pass: fine sampling around coarseClosestPoint
1090
+ const fineStep = 2; // Increased step to reduce computations
1091
+ const searchStart = Math.max(coarseClosestPoint.length - coarseStep, 0);
1092
+ const searchEnd = Math.min(coarseClosestPoint.length + coarseStep, pathLength);
1093
+ for (let i = searchStart; i <= searchEnd; i += fineStep) {
1094
+ const pointOnPath = pathNode.getPointAtLength(i);
1095
+ const distanceSquared = this.getDistanceSquared(point, pointOnPath);
1096
+ if (distanceSquared < minDistanceSquared) {
1097
+ minDistanceSquared = distanceSquared;
1098
+ closestPoint = { x: pointOnPath.x, y: pointOnPath.y, length: i };
1099
+ }
1100
+ }
1101
+ return closestPoint;
1102
+ }
1103
+ // Load the next or previous SVG based on the isNext flag
1104
+ async loadAnotherSVG(state, isNext) {
1105
+ state.isDragging = false;
1106
+ // Update fileIndex based on whether isNext is true or false
1107
+ // if (isNext) {
1108
+ // state.fileIndex++;
1109
+ // if (state.fileIndex >= this.svgFiles.length) {
1110
+ // state.fileIndex = this.svgFiles.length - 1; // Stay at the last file
1111
+ // return;
1112
+ // }
1113
+ // } else {
1114
+ // state.fileIndex--;
1115
+ // if (state.fileIndex < 0) {
1116
+ // state.fileIndex = 0; // Stay at the first file
1117
+ // return;
1118
+ // }
1119
+ // }
1120
+ try {
1121
+ if (state.svg) {
1122
+ this.cleanupPreviousSVG(state);
1123
+ }
1124
+ // const svgText = await this.fetchSVG(this.svgSource ?? this.svgFiles[state.fileIndex]);
1125
+ const svgText = await this.fetchSVG(this.svgSource);
1126
+ this.insertSVG(svgText);
1127
+ state.svg = this.getSVGElement();
1128
+ state.paths = this.getPaths(state.svg);
1129
+ this.setupDrawingPath(state);
1130
+ this.setupDraggableCircle(state);
1131
+ this.addEventListeners(state);
1132
+ }
1133
+ catch (error) {
1134
+ console.error(`Error loading SVG (${this.svgSource}):`, error);
1135
+ }
1136
+ }
1137
+ // Cleanup previous SVG's elements and state
1138
+ cleanupPreviousSVG(state) {
1139
+ var _a, _b;
1140
+ if (state.circle) {
1141
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.removeChild(state.circle);
1142
+ state.circle = null;
1143
+ }
1144
+ const indicators = (_b = state.svg) === null || _b === void 0 ? void 0 : _b.querySelectorAll('.flow-indicator');
1145
+ indicators.forEach(indicator => {
1146
+ indicator.remove(); // Remove all previous flow indicators
1147
+ });
1148
+ state.currentPathIndex = 0;
1149
+ state.lastLength = 0;
1150
+ state.totalPathLength = state.paths[0].getTotalLength();
1151
+ }
1152
+ // Move to the next path in the SVG
1153
+ moveToNextPath(state) {
1154
+ var _a, _b;
1155
+ state.isDragging = false;
1156
+ state.currentPathIndex++;
1157
+ state.lastLength = 0;
1158
+ if (state.currentPathIndex >= state.paths.length) {
1159
+ // this.loadAnotherSVG(state, true);
1160
+ utils.triggerNextContainer();
1161
+ return;
1162
+ }
1163
+ const nextPath = state.paths[state.currentPathIndex];
1164
+ if (!nextPath) {
1165
+ console.error('No valid path found at the next index');
1166
+ return;
1167
+ }
1168
+ state.totalPathLength = nextPath.getTotalLength();
1169
+ const startPoint = nextPath.getPointAtLength(0);
1170
+ (_a = state.circle) === null || _a === void 0 ? void 0 : _a.setAttribute('cx', startPoint.x.toString());
1171
+ (_b = state.circle) === null || _b === void 0 ? void 0 : _b.setAttribute('cy', startPoint.y.toString());
1172
+ if (state.mode === utils.TraceMode.ShowFlow) {
1173
+ state.flowMarkers = this.createFlowMarkersForPath(nextPath);
1174
+ }
1175
+ }
1176
+ render() {
1177
+ const style = {
1178
+ height: this.height,
1179
+ width: this.width,
1180
+ top: this.y,
1181
+ left: this.x,
1182
+ zIndex: this.z,
1183
+ position: 'absolute',
1184
+ };
1185
+ // List of SVG file names to process sequentially
1186
+ // const svgFiles = ['A_test.svg', 'B_test.svg', 'C_test.svg', 'D_test.svg', 'अ_test.svg', 'ट_test.svg', 'क_test.svg', 'ख_test.svg', 'ग_test.svg']; // Add more SVG file names as needed
1187
+ return (index.h(index.Host, { key: 'c957926b2f3e281966de8d1dca6580931af54019', class: "trace", id: this.id, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, tabindex: this.tabIndex }, index.h("div", { key: 'f841bf92fec27ed26594c5ccca937fa20210451f', id: "svgContainer" })));
1188
+ }
1189
+ static get assetsDirs() { return ["svg"]; }
1190
+ };
1191
+ AppTrace.style = AppTraceStyle0;
1192
+
1193
+ const appWrapCss = ".wrap{display:grid;grid-gap:10px;grid-template-columns:repeat(auto-fill, minmax(186px, auto))}.wrap>*{padding:10px;background-color:var(--child-bg-color, #f0f0f0);box-sizing:border-box}";
1194
+ const AppWrapStyle0 = appWrapCss;
1195
+
1196
+ const AppWrap = class {
1197
+ constructor(hostRef) {
1198
+ index.registerInstance(this, hostRef);
1199
+ this.id = undefined;
1200
+ this.value = undefined;
1201
+ this.height = undefined;
1202
+ this.width = undefined;
1203
+ this.ariaLabel = undefined;
1204
+ this.ariaHidden = undefined;
1205
+ this.x = undefined;
1206
+ this.y = undefined;
1207
+ this.z = undefined;
1208
+ this.bgColor = undefined;
1209
+ this.type = undefined;
1210
+ this.tabIndex = undefined;
1211
+ this.visible = undefined;
1212
+ this.audio = undefined;
1213
+ this.onTouch = undefined;
1214
+ this.onCorrectTouch = undefined;
1215
+ this.onInCorrectTouch = undefined;
1216
+ this.onCorrectMatch = undefined;
1217
+ this.onMatch = undefined;
1218
+ this.onWrong = undefined;
1219
+ this.onEntry = undefined;
1220
+ }
1221
+ /**
1222
+ * Lifecycle hook that runs after the component is rendered in the DOM.
1223
+ * It initializes custom events based on the `type` of the wrap container.
1224
+ */
1225
+ componentDidLoad() {
1226
+ utils.initEventsForElement(this.el, this.type);
1227
+ }
1228
+ render() {
1229
+ // Inline styles to position and size the wrap container, with grid layout applied
1230
+ const style = {
1231
+ height: this.height,
1232
+ width: this.width,
1233
+ top: this.y,
1234
+ left: this.x,
1235
+ display: this.visible ? 'grid' : 'none', // Use grid layout
1236
+ zIndex: this.z,
1237
+ backgroundColor: this.bgColor,
1238
+ };
1239
+ return (index.h(index.Host, { key: '7e955c4ff7d20f7138088114ccf344d0fda171d8', class: "wrap", value: this.value, type: this.type, tabindex: this.tabIndex, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onMatch: this.onMatch, onWrong: this.onWrong, onCorrectMatch: this.onCorrectMatch, onCorrectTouch: this.onCorrectTouch, onInCorrectTouch: this.onInCorrectTouch, onEntry: this.onEntry }, index.h("slot", { key: '1ee6b59cfe7cbb8b3bc1c830c51e38e0711e6e62' })));
1240
+ }
1241
+ get el() { return index.getElement(this); }
1242
+ };
1243
+ AppWrap.style = AppWrapStyle0;
1244
+
1245
+ exports.app_col = AppCol;
1246
+ exports.app_container = AppContainer;
1247
+ exports.app_home = AppHome;
1248
+ exports.app_image = AppImage;
1249
+ exports.app_pos = AppPos;
1250
+ exports.app_random = AppRandom;
1251
+ exports.app_root = AppRoot;
1252
+ exports.app_row = AppRow;
1253
+ exports.app_shape = AppShape;
1254
+ exports.app_text = AppText;
1255
+ exports.app_trace = AppTrace;
1256
+ exports.app_wrap = AppWrap;
1257
+
1258
+ //# sourceMappingURL=app-col_12.cjs.entry.js.map