lido-player 0.0.1 → 0.0.2-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 +1256 -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 +83 -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 +141 -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 +1241 -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-c87e2f20.entry.js +2 -0
  167. package/dist/lido-player/p-c87e2f20.entry.js.map +1 -0
  168. package/dist/lido-player/p-e1255160.js +2 -0
  169. package/dist/lido-player/p-e1255160.js.map +1 -0
  170. package/dist/types/components/root/AppRoot.d.ts +8 -4
  171. package/dist/types/components.d.ts +16 -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,1256 @@
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.xmlData = undefined;
501
+ }
502
+ /**
503
+ * Lifecycle method that runs before the component is loaded.
504
+ * It fetches the XML data from the specified path or URL and sets it to the component's state.
505
+ */
506
+ async componentWillLoad() {
507
+ // Validate the xmlPath prop
508
+ if (!this.xmlPath) {
509
+ console.error('XML path is not provided.');
510
+ return;
511
+ }
512
+ // Fetch the XML data
513
+ try {
514
+ const resolvedPath = this.xmlPath.startsWith('http')
515
+ ? this.xmlPath // Use the provided URL if it's an HTTP/HTTPS link
516
+ : index.getAssetPath(this.xmlPath); // Otherwise, resolve it as an asset path
517
+ const response = await fetch(resolvedPath);
518
+ if (!response.ok) {
519
+ throw new Error(`Failed to fetch XML data: ${response.statusText}`);
520
+ }
521
+ const data = await response.text();
522
+ // Store the XML data in the component's state
523
+ this.xmlData = data;
524
+ }
525
+ catch (error) {
526
+ console.error('Error fetching XML data:', error);
527
+ this.xmlData = null;
528
+ }
529
+ }
530
+ render() {
531
+ // Show a loading message until the XML data is fetched
532
+ if (this.xmlData === undefined) {
533
+ return index.h("div", null, "Loading...");
534
+ }
535
+ // Show an error message if the XML data could not be fetched
536
+ if (this.xmlData === null) {
537
+ return index.h("div", null, "Error loading XML data. Please check the path or URL.");
538
+ }
539
+ // Once the XML data is loaded, pass it to the `app-home` component
540
+ return index.h("app-home", { initialIndex: 0, canplay: true, xmlData: this.xmlData });
541
+ }
542
+ static get assetsDirs() { return ["assets"]; }
543
+ };
544
+
545
+ const appRowCss = ".row{display:flex;justify-content:space-between;align-items:center;}.row>*{}";
546
+ const AppRowStyle0 = appRowCss;
547
+
548
+ const AppRow = class {
549
+ constructor(hostRef) {
550
+ index.registerInstance(this, hostRef);
551
+ this.value = undefined;
552
+ this.height = undefined;
553
+ this.width = undefined;
554
+ this.ariaLabel = undefined;
555
+ this.ariaHidden = undefined;
556
+ this.x = undefined;
557
+ this.y = undefined;
558
+ this.z = undefined;
559
+ this.bgColor = undefined;
560
+ this.type = undefined;
561
+ this.tabIndex = undefined;
562
+ this.visible = undefined;
563
+ this.audio = undefined;
564
+ this.onTouch = undefined;
565
+ this.onCorrectTouch = undefined;
566
+ this.onInCorrectTouch = undefined;
567
+ this.onCorrectMatch = undefined;
568
+ this.onMatch = undefined;
569
+ this.onWrong = undefined;
570
+ this.onEntry = undefined;
571
+ }
572
+ /**
573
+ * Lifecycle hook that runs after the component is loaded into the DOM.
574
+ * It initializes custom events based on the `type` of the row component.
575
+ */
576
+ componentDidLoad() {
577
+ utils.initEventsForElement(this.el, this.type);
578
+ }
579
+ render() {
580
+ // Inline styles to position and size the row component
581
+ const style = {
582
+ height: this.height,
583
+ width: this.width,
584
+ top: this.y,
585
+ left: this.x,
586
+ display: this.visible ? 'flex' : 'none', // Flexbox for row layout
587
+ zIndex: this.z,
588
+ backgroundColor: this.bgColor, // Apply background color if provided
589
+ };
590
+ 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' })));
591
+ }
592
+ get el() { return index.getElement(this); }
593
+ };
594
+ AppRow.style = AppRowStyle0;
595
+
596
+ 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)}";
597
+ const AppShapeStyle0 = appShapeCss;
598
+
599
+ const AppShape = class {
600
+ constructor(hostRef) {
601
+ index.registerInstance(this, hostRef);
602
+ this.id = undefined;
603
+ this.value = undefined;
604
+ this.height = undefined;
605
+ this.width = undefined;
606
+ this.ariaLabel = undefined;
607
+ this.ariaHidden = undefined;
608
+ this.x = undefined;
609
+ this.y = undefined;
610
+ this.z = undefined;
611
+ this.bgColor = undefined;
612
+ this.type = undefined;
613
+ this.tabIndex = undefined;
614
+ this.shapeType = undefined;
615
+ this.visible = undefined;
616
+ this.audio = undefined;
617
+ this.onTouch = undefined;
618
+ this.onCorrectTouch = undefined;
619
+ this.onInCorrectTouch = undefined;
620
+ this.onCorrectMatch = undefined;
621
+ this.onMatch = undefined;
622
+ this.onWrong = undefined;
623
+ this.onEntry = undefined;
624
+ }
625
+ /**
626
+ * Lifecycle hook that runs after the component is loaded into the DOM.
627
+ * It initializes custom events based on the `type` of the shape component.
628
+ */
629
+ componentDidLoad() {
630
+ utils.initEventsForElement(this.el, this.type);
631
+ }
632
+ render() {
633
+ // Inline styles to position and size the shape component
634
+ const style = {
635
+ height: this.shapeType !== 'polygon' ? this.height : undefined, // Set height unless it's a polygon
636
+ width: this.shapeType !== 'polygon' ? this.width : undefined, // Set width unless it's a polygon
637
+ top: this.y,
638
+ left: this.x,
639
+ display: this.visible ? 'block' : 'none', // Toggle visibility
640
+ zIndex: this.z,
641
+ backgroundColor: this.shapeType !== 'polygon' ? this.bgColor : 'transparent', // Apply background only if not a polygon
642
+ };
643
+ 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 }));
644
+ }
645
+ get el() { return index.getElement(this); }
646
+ };
647
+ AppShape.style = AppShapeStyle0;
648
+
649
+ 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}";
650
+ const AppTextStyle0 = appTextCss;
651
+
652
+ const AppText = class {
653
+ constructor(hostRef) {
654
+ index.registerInstance(this, hostRef);
655
+ this.id = undefined;
656
+ this.value = undefined;
657
+ this.string = undefined;
658
+ this.font = undefined;
659
+ this.fontSize = undefined;
660
+ this.fontColor = undefined;
661
+ this.highlightWhileSpeaking = undefined;
662
+ this.height = undefined;
663
+ this.width = undefined;
664
+ this.ariaLabel = undefined;
665
+ this.ariaHidden = undefined;
666
+ this.x = undefined;
667
+ this.y = undefined;
668
+ this.z = undefined;
669
+ this.bgColor = undefined;
670
+ this.type = undefined;
671
+ this.tabIndex = undefined;
672
+ this.visible = undefined;
673
+ this.audio = undefined;
674
+ this.onTouch = undefined;
675
+ this.onCorrectTouch = undefined;
676
+ this.onInCorrectTouch = undefined;
677
+ this.onCorrectMatch = undefined;
678
+ this.onMatch = undefined;
679
+ this.onWrong = undefined;
680
+ this.onEntry = undefined;
681
+ }
682
+ /**
683
+ * Lifecycle hook that runs after the component is rendered in the DOM.
684
+ * It initializes custom events based on the `type` of the text component.
685
+ */
686
+ componentDidLoad() {
687
+ utils.initEventsForElement(this.el, this.type);
688
+ }
689
+ render() {
690
+ // Inline styles to customize the appearance and positioning of the text component
691
+ const style = {
692
+ height: this.height,
693
+ width: this.width,
694
+ backgroundColor: this.bgColor,
695
+ top: this.y,
696
+ left: this.x,
697
+ zIndex: this.z,
698
+ fontSize: this.fontSize,
699
+ fontFamily: this.font,
700
+ color: this.fontColor,
701
+ display: this.visible ? 'flex' : 'none', // Show or hide based on visibility prop
702
+ };
703
+ 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));
704
+ }
705
+ get el() { return index.getElement(this); }
706
+ };
707
+ AppText.style = AppTextStyle0;
708
+
709
+ 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}";
710
+ const AppTraceStyle0 = appTraceCss;
711
+
712
+ const AppTrace = class {
713
+ constructor(hostRef) {
714
+ index.registerInstance(this, hostRef);
715
+ this.id = undefined;
716
+ this.svgSource = undefined;
717
+ this.value = undefined;
718
+ this.height = undefined;
719
+ this.width = undefined;
720
+ this.x = undefined;
721
+ this.y = undefined;
722
+ this.z = undefined;
723
+ this.ariaLabel = undefined;
724
+ this.ariaHidden = undefined;
725
+ this.tabIndex = undefined;
726
+ this.mode = undefined;
727
+ this.fileIndex = -1;
728
+ this.isDragging = false;
729
+ this.activePointerId = null;
730
+ }
731
+ // MODES = ['noFlow', 'showFlow', 'freeTrace', 'blindTracing', 'blindFreeTrace'];
732
+ // Handle the pointermove event with optimizations
733
+ // Update the path trace as the red circle moves
734
+ async initializeSVG() {
735
+ let state = {
736
+ fileIndex: -1,
737
+ currentPathIndex: 0,
738
+ lastLength: 0,
739
+ totalPathLength: 0,
740
+ isDragging: false,
741
+ circle: null,
742
+ paths: [],
743
+ svg: null,
744
+ proximityThreshold: 100, // General proximity threshold
745
+ freeTraceProximityThreshold: 50, // Reduced proximity threshold for free trace
746
+ rafId: null,
747
+ pointerMoveEvent: null,
748
+ activePointerId: null,
749
+ mode: this.mode,
750
+ flowMarkers: [],
751
+ freeTraceLines: [],
752
+ };
753
+ await this.loadAnotherSVG(state, true); // Load the first SVG
754
+ }
755
+ componentWillLoad() {
756
+ this.initializeSVG();
757
+ }
758
+ // Fetch the SVG file asynchronously
759
+ async fetchSVG(url) {
760
+ const response = await fetch(url);
761
+ if (!response.ok) {
762
+ throw new Error(`Failed to fetch SVG (${url}): ${response.statusText}`);
763
+ }
764
+ return await response.text();
765
+ }
766
+ // to calculate the bounding box of all paths
767
+ calculateBoundingBox(paths, padding = 22) {
768
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
769
+ paths.forEach(path => {
770
+ const length = path.getTotalLength();
771
+ const numPoints = 100; // Number of points to sample along the path
772
+ for (let i = 0; i <= numPoints; i++) {
773
+ const point = path.getPointAtLength((i / numPoints) * length);
774
+ if (point.x < minX)
775
+ minX = point.x;
776
+ if (point.y < minY)
777
+ minY = point.y;
778
+ if (point.x > maxX)
779
+ maxX = point.x;
780
+ if (point.y > maxY)
781
+ maxY = point.y;
782
+ }
783
+ });
784
+ // Apply padding
785
+ minX -= padding;
786
+ minY -= padding;
787
+ maxX += padding;
788
+ maxY += padding;
789
+ return { minX, minY, maxX, maxY };
790
+ }
791
+ // Insert the fetched SVG into the container and adjust viewBox
792
+ insertSVG(svgText) {
793
+ const svgContainer = document.getElementById('svgContainer');
794
+ svgContainer.innerHTML = svgText;
795
+ // After inserting, get the SVG element
796
+ const svgElement = svgContainer.querySelector('svg');
797
+ // Remove the width and height attributes from the SVG element
798
+ svgElement.removeAttribute('width');
799
+ svgElement.removeAttribute('height');
800
+ // Get all paths
801
+ const paths = svgElement.querySelectorAll('path, line');
802
+ // Calculate bounding box
803
+ const bbox = this.calculateBoundingBox(Array.from(paths));
804
+ // Set the viewBox to the bounding box
805
+ const viewBoxWidth = bbox.maxX - bbox.minX;
806
+ const viewBoxHeight = bbox.maxY - bbox.minY;
807
+ svgElement.setAttribute('viewBox', `${bbox.minX} ${bbox.minY} ${viewBoxWidth} ${viewBoxHeight}`);
808
+ }
809
+ // Retrieve the SVG element from the container
810
+ getSVGElement() {
811
+ const svgContainer = document.getElementById('svgContainer');
812
+ return svgContainer.querySelector('svg');
813
+ }
814
+ // Get all path and line elements from the SVG
815
+ getPaths(svg) {
816
+ return Array.from(svg.querySelectorAll('path, line'));
817
+ }
818
+ // Create flow markers along the path to guide the user
819
+ createFlowMarkersForPath(path, markerCount = 10) {
820
+ var _a;
821
+ const totalLength = path.getTotalLength();
822
+ const interval = totalLength / (markerCount + 1); // Space markers evenly
823
+ const markers = [];
824
+ for (let i = 1; i <= markerCount; i++) {
825
+ const point = path.getPointAtLength(i * interval);
826
+ const nextPoint = path.getPointAtLength((i + 0.5) * interval); // Slightly ahead point for direction
827
+ // Create an arrow marker
828
+ const angle = Math.atan2(nextPoint.y - point.y, nextPoint.x - point.x);
829
+ const arrowMarker = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
830
+ arrowMarker.setAttribute('points', '-5,-5 0,0 -5,5');
831
+ arrowMarker.setAttribute('fill', 'blue');
832
+ arrowMarker.setAttribute('transform', `translate(${point.x},${point.y}) rotate(${(angle * 180) / Math.PI})`);
833
+ arrowMarker.setAttribute('class', 'flow-indicator');
834
+ markers.push(arrowMarker);
835
+ (_a = path.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(arrowMarker); // Append to the same SVG container
836
+ }
837
+ return markers;
838
+ }
839
+ // Show or hide flow indicators based on mode
840
+ updateFlowIndicators(state) {
841
+ const indicators = state.svg.querySelectorAll('.flow-indicator');
842
+ indicators.forEach(indicator => {
843
+ if (state.mode === utils.TraceMode.NoFlow) {
844
+ indicator.style.display = 'none';
845
+ }
846
+ else if (state.mode === utils.TraceMode.ShowFlow) {
847
+ indicator.style.display = 'block';
848
+ }
849
+ });
850
+ }
851
+ // Create a new path element for the drawing effect
852
+ setupDrawingPath(state) {
853
+ state.paths.forEach((path, index) => {
854
+ const pathLength = path.getTotalLength();
855
+ // Create green path for tracing effect
856
+ const greenPath = path.cloneNode();
857
+ greenPath.setAttribute('stroke', 'green');
858
+ greenPath.setAttribute('stroke-width', '13');
859
+ greenPath.setAttribute('stroke-dasharray', pathLength.toString());
860
+ greenPath.setAttribute('stroke-dashoffset', pathLength.toString()); // Hidden initially
861
+ path.parentNode.appendChild(greenPath, path);
862
+ path.setAttribute('class', 'trace-path'); // Add class for easier reference
863
+ greenPath.setAttribute('class', 'trace-path-green'); // Add class for easier reference
864
+ path.greenPath = greenPath;
865
+ path.classList.add(state.mode);
866
+ // Conditionally hide or show the black path based on blind tracing mode
867
+ if (state.mode === utils.TraceMode.BlindTracing || state.mode === utils.TraceMode.BlindFreeTrace) {
868
+ // In blind tracing or blind free trace mode, hide the black path
869
+ path.setAttribute('stroke', 'none');
870
+ }
871
+ else {
872
+ // In other modes, show the black path
873
+ path.setAttribute('stroke', '#000');
874
+ path.setAttribute('stroke-width', '10');
875
+ path.setAttribute('fill', 'none');
876
+ path.setAttribute('stroke-dasharray', pathLength.toString());
877
+ path.setAttribute('stroke-dashoffset', '0'); // Fully visible initially
878
+ }
879
+ // Only create flow markers for the current path in normal modes
880
+ if (index === state.currentPathIndex && state.mode === utils.TraceMode.ShowFlow) {
881
+ state.flowMarkers = this.createFlowMarkersForPath(path);
882
+ }
883
+ });
884
+ state.totalPathLength = state.paths[state.currentPathIndex].getTotalLength();
885
+ }
886
+ // Set up the draggable circle at the start of the first path
887
+ setupDraggableCircle(state) {
888
+ var _a;
889
+ const firstPathStart = state.paths[0].getPointAtLength(0);
890
+ const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
891
+ circle.setAttribute('id', 'draggableCircle');
892
+ circle.setAttribute('cx', firstPathStart.x.toString());
893
+ circle.setAttribute('cy', firstPathStart.y.toString());
894
+ circle.setAttribute('r', '20'); // Radius of the draggable circle
895
+ circle.setAttribute('fill', 'red');
896
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.appendChild(circle);
897
+ state.circle = circle;
898
+ }
899
+ // Add necessary event listeners using Pointer Events
900
+ addEventListeners(state) {
901
+ var _a, _b, _c, _d;
902
+ // Ensure the circle exists before adding events
903
+ if (!state.circle || !state.paths || state.paths.length === 0)
904
+ return;
905
+ // Handle pointerdown on the circle to start dragging
906
+ state.circle.addEventListener('pointerdown', (evt) => {
907
+ evt.preventDefault(); // Prevent default actions like text selection
908
+ const pointerPos = this.getPointerPosition(evt, state.svg);
909
+ const circlePos = {
910
+ x: parseFloat(state.circle.getAttribute('cx')),
911
+ y: parseFloat(state.circle.getAttribute('cy')),
912
+ };
913
+ const distance = this.getDistanceSquared(pointerPos, circlePos);
914
+ if (distance <= state.proximityThreshold * state.proximityThreshold) {
915
+ state.isDragging = true;
916
+ state.activePointerId = evt.pointerId;
917
+ // Capture the pointer to continue receiving events even if it leaves the element
918
+ state.circle.setPointerCapture(evt.pointerId);
919
+ }
920
+ });
921
+ // Handle pointermove on the SVG to update the circle position
922
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.addEventListener('pointermove', (evt) => {
923
+ if (!state.isDragging || evt.pointerId !== state.activePointerId)
924
+ return;
925
+ state.pointerMoveEvent = evt;
926
+ if (!state.rafId) {
927
+ state.rafId = requestAnimationFrame(() => {
928
+ this.handlePointerMove(state);
929
+ state.rafId = null;
930
+ });
931
+ }
932
+ });
933
+ // Handle pointerup and pointercancel on the SVG to stop dragging
934
+ (_b = state.svg) === null || _b === void 0 ? void 0 : _b.addEventListener('pointerup', (evt) => {
935
+ if (evt.pointerId === state.activePointerId) {
936
+ state.isDragging = false;
937
+ state.activePointerId = null;
938
+ }
939
+ });
940
+ (_c = state.svg) === null || _c === void 0 ? void 0 : _c.addEventListener('pointercancel', (evt) => {
941
+ if (evt.pointerId === state.activePointerId) {
942
+ state.isDragging = false;
943
+ state.activePointerId = null;
944
+ }
945
+ });
946
+ // Optional: Prevent context menu on long press
947
+ (_d = state.svg) === null || _d === void 0 ? void 0 : _d.addEventListener('contextmenu', (evt) => {
948
+ evt.preventDefault();
949
+ });
950
+ }
951
+ // Modified handlePointerMove function
952
+ handlePointerMove(state) {
953
+ var _a, _b, _c, _d;
954
+ if (!state.isDragging)
955
+ return;
956
+ if (!state.circle || !state.paths || state.paths.length === 0)
957
+ return;
958
+ const evt = state.pointerMoveEvent;
959
+ const pointerPos = this.getPointerPosition(evt, state.svg);
960
+ const circlePos = {
961
+ x: parseFloat(state.circle.getAttribute('cx')),
962
+ y: parseFloat(state.circle.getAttribute('cy')),
963
+ };
964
+ const currentPath = state.paths[state.currentPathIndex];
965
+ if (!currentPath) {
966
+ console.error('No valid path found at the current index');
967
+ return;
968
+ }
969
+ // Use a reduced proximity threshold for free trace mode
970
+ let proximitySquared;
971
+ if (state.mode === utils.TraceMode.FreeTrace || state.mode === utils.TraceMode.BlindFreeTrace) {
972
+ proximitySquared = state.freeTraceProximityThreshold * state.freeTraceProximityThreshold;
973
+ }
974
+ else {
975
+ proximitySquared = state.proximityThreshold * state.proximityThreshold;
976
+ }
977
+ // Calculate the distance between the pointer and the draggable circle
978
+ const distanceSquared = this.getDistanceSquared(pointerPos, circlePos);
979
+ // If the pointer is outside the proximity threshold, do not proceed with drawing or moving
980
+ if (distanceSquared > proximitySquared) {
981
+ return; // Skip any further actions
982
+ }
983
+ const closestPoint = this.getClosestPointOnPath(currentPath, pointerPos);
984
+ // Ensure drawing happens only within proximity threshold
985
+ const distanceToPathSquared = this.getDistanceSquared(pointerPos, closestPoint);
986
+ if (distanceToPathSquared > proximitySquared) {
987
+ return; // Skip drawing if too far from the path
988
+ }
989
+ // For free trace mode and blind free trace mode, allow free drawing only if within the reduced proximity threshold
990
+ if (state.mode === utils.TraceMode.FreeTrace || state.mode === utils.TraceMode.BlindFreeTrace) {
991
+ // Initialize the currentFreePath array if it's not created
992
+ if (!state.currentFreePath) {
993
+ state.currentFreePath = [];
994
+ }
995
+ // Create a new path element if it's the first trace for the current path index
996
+ if (!state.currentFreePath[state.currentPathIndex]) {
997
+ const newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
998
+ newPath.setAttribute('stroke', 'green');
999
+ newPath.setAttribute('stroke-width', '8');
1000
+ newPath.setAttribute('fill', 'none');
1001
+ // Start the new path at the current pointer position
1002
+ newPath.setAttribute('d', `M${pointerPos.x},${pointerPos.y}`);
1003
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.appendChild(newPath);
1004
+ state.currentFreePath[state.currentPathIndex] = newPath;
1005
+ // Reset lastPointerPos for the new path
1006
+ state.lastPointerPos = pointerPos;
1007
+ }
1008
+ // Get the previous position to draw a smooth curve
1009
+ const previousPos = state.lastPointerPos || pointerPos;
1010
+ // Create a quadratic curve from the previous point to the current point
1011
+ const newPathData = state.currentFreePath[state.currentPathIndex].getAttribute('d');
1012
+ const midPointX = (previousPos.x + pointerPos.x) / 2;
1013
+ const midPointY = (previousPos.y + pointerPos.y) / 2;
1014
+ const updatedPathData = `${newPathData} Q ${previousPos.x},${previousPos.y} ${midPointX},${midPointY}`;
1015
+ // Update the path's 'd' attribute with the new curve
1016
+ state.currentFreePath[state.currentPathIndex].setAttribute('d', updatedPathData);
1017
+ // Move the draggable circle with the freehand trace
1018
+ state.circle.setAttribute('cx', pointerPos.x.toString());
1019
+ state.circle.setAttribute('cy', pointerPos.y.toString());
1020
+ // Make sure the red dot (circle) is always on top
1021
+ (_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
1022
+ // Update the last pointer position
1023
+ state.lastPointerPos = pointerPos;
1024
+ const currentPathLength = currentPath.getTotalLength();
1025
+ const distanceToEnd = currentPathLength - closestPoint.length;
1026
+ // If close to the end of the path, move to the next path
1027
+ if (distanceToEnd < 5) {
1028
+ this.moveToNextPath(state);
1029
+ state.currentFreePath[state.currentPathIndex] = null; // Reset free path for next path
1030
+ }
1031
+ return; // Exit early since we're in free trace or blind free trace mode
1032
+ }
1033
+ // In normal modes, allow movement and drawing only within the general proximity threshold
1034
+ if (state.isDragging && closestPoint.length >= state.lastLength) {
1035
+ state.lastLength = closestPoint.length;
1036
+ state.circle.setAttribute('cx', closestPoint.x.toString());
1037
+ state.circle.setAttribute('cy', closestPoint.y.toString());
1038
+ // Make sure the red dot (circle) is always on top
1039
+ (_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
1040
+ (_d = currentPath.greenPath) === null || _d === void 0 ? void 0 : _d.setAttribute('stroke-dashoffset', (state.totalPathLength - state.lastLength).toString());
1041
+ }
1042
+ // Check if the current path is completed
1043
+ if (state.totalPathLength - 1 - state.lastLength < 5 && state.currentPathIndex < state.paths.length - 1) {
1044
+ this.moveToNextPath(state);
1045
+ }
1046
+ else if (state.totalPathLength - 1 - state.lastLength < 5 && state.currentPathIndex === state.paths.length - 1) {
1047
+ // this.loadAnotherSVG(state, true);
1048
+ utils.triggerNextContainer();
1049
+ }
1050
+ }
1051
+ // Get the pointer position relative to the SVG
1052
+ getPointerPosition(evt, svg) {
1053
+ var _a;
1054
+ const svgPoint = svg.createSVGPoint();
1055
+ svgPoint.x = evt.clientX;
1056
+ svgPoint.y = evt.clientY;
1057
+ const ctm = (_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse();
1058
+ return ctm ? svgPoint.matrixTransform(ctm) : { x: evt.clientX, y: evt.clientY };
1059
+ }
1060
+ // Calculate the squared Euclidean distance between two points
1061
+ getDistanceSquared(p1, p2) {
1062
+ const dx = p1.x - p2.x;
1063
+ const dy = p1.y - p2.y;
1064
+ return dx * dx + dy * dy;
1065
+ }
1066
+ // Find the closest point on the given path to the specified point using two-pass sampling
1067
+ getClosestPointOnPath(pathNode, point) {
1068
+ const pathLength = pathNode.getTotalLength();
1069
+ let closestPoint = { x: 0, y: 0, length: 0 };
1070
+ let minDistanceSquared = Infinity;
1071
+ // First pass: coarse sampling
1072
+ const coarseStep = 20; // Increased step for better performance
1073
+ let coarseClosestPoint = { x: 0, y: 0, length: 0 };
1074
+ let coarseMinDistanceSquared = Infinity;
1075
+ for (let i = 0; i <= pathLength; i += coarseStep) {
1076
+ const pointOnPath = pathNode.getPointAtLength(i);
1077
+ const distanceSquared = this.getDistanceSquared(point, pointOnPath);
1078
+ if (distanceSquared < coarseMinDistanceSquared) {
1079
+ coarseMinDistanceSquared = distanceSquared;
1080
+ coarseClosestPoint = {
1081
+ x: pointOnPath.x,
1082
+ y: pointOnPath.y,
1083
+ length: i,
1084
+ };
1085
+ }
1086
+ }
1087
+ // Second pass: fine sampling around coarseClosestPoint
1088
+ const fineStep = 2; // Increased step to reduce computations
1089
+ const searchStart = Math.max(coarseClosestPoint.length - coarseStep, 0);
1090
+ const searchEnd = Math.min(coarseClosestPoint.length + coarseStep, pathLength);
1091
+ for (let i = searchStart; i <= searchEnd; i += fineStep) {
1092
+ const pointOnPath = pathNode.getPointAtLength(i);
1093
+ const distanceSquared = this.getDistanceSquared(point, pointOnPath);
1094
+ if (distanceSquared < minDistanceSquared) {
1095
+ minDistanceSquared = distanceSquared;
1096
+ closestPoint = { x: pointOnPath.x, y: pointOnPath.y, length: i };
1097
+ }
1098
+ }
1099
+ return closestPoint;
1100
+ }
1101
+ // Load the next or previous SVG based on the isNext flag
1102
+ async loadAnotherSVG(state, isNext) {
1103
+ state.isDragging = false;
1104
+ // Update fileIndex based on whether isNext is true or false
1105
+ // if (isNext) {
1106
+ // state.fileIndex++;
1107
+ // if (state.fileIndex >= this.svgFiles.length) {
1108
+ // state.fileIndex = this.svgFiles.length - 1; // Stay at the last file
1109
+ // return;
1110
+ // }
1111
+ // } else {
1112
+ // state.fileIndex--;
1113
+ // if (state.fileIndex < 0) {
1114
+ // state.fileIndex = 0; // Stay at the first file
1115
+ // return;
1116
+ // }
1117
+ // }
1118
+ try {
1119
+ if (state.svg) {
1120
+ this.cleanupPreviousSVG(state);
1121
+ }
1122
+ // const svgText = await this.fetchSVG(this.svgSource ?? this.svgFiles[state.fileIndex]);
1123
+ const svgText = await this.fetchSVG(this.svgSource);
1124
+ this.insertSVG(svgText);
1125
+ state.svg = this.getSVGElement();
1126
+ state.paths = this.getPaths(state.svg);
1127
+ this.setupDrawingPath(state);
1128
+ this.setupDraggableCircle(state);
1129
+ this.addEventListeners(state);
1130
+ }
1131
+ catch (error) {
1132
+ console.error(`Error loading SVG (${this.svgSource}):`, error);
1133
+ }
1134
+ }
1135
+ // Cleanup previous SVG's elements and state
1136
+ cleanupPreviousSVG(state) {
1137
+ var _a, _b;
1138
+ if (state.circle) {
1139
+ (_a = state.svg) === null || _a === void 0 ? void 0 : _a.removeChild(state.circle);
1140
+ state.circle = null;
1141
+ }
1142
+ const indicators = (_b = state.svg) === null || _b === void 0 ? void 0 : _b.querySelectorAll('.flow-indicator');
1143
+ indicators.forEach(indicator => {
1144
+ indicator.remove(); // Remove all previous flow indicators
1145
+ });
1146
+ state.currentPathIndex = 0;
1147
+ state.lastLength = 0;
1148
+ state.totalPathLength = state.paths[0].getTotalLength();
1149
+ }
1150
+ // Move to the next path in the SVG
1151
+ moveToNextPath(state) {
1152
+ var _a, _b;
1153
+ state.isDragging = false;
1154
+ state.currentPathIndex++;
1155
+ state.lastLength = 0;
1156
+ if (state.currentPathIndex >= state.paths.length) {
1157
+ // this.loadAnotherSVG(state, true);
1158
+ utils.triggerNextContainer();
1159
+ return;
1160
+ }
1161
+ const nextPath = state.paths[state.currentPathIndex];
1162
+ if (!nextPath) {
1163
+ console.error('No valid path found at the next index');
1164
+ return;
1165
+ }
1166
+ state.totalPathLength = nextPath.getTotalLength();
1167
+ const startPoint = nextPath.getPointAtLength(0);
1168
+ (_a = state.circle) === null || _a === void 0 ? void 0 : _a.setAttribute('cx', startPoint.x.toString());
1169
+ (_b = state.circle) === null || _b === void 0 ? void 0 : _b.setAttribute('cy', startPoint.y.toString());
1170
+ if (state.mode === utils.TraceMode.ShowFlow) {
1171
+ state.flowMarkers = this.createFlowMarkersForPath(nextPath);
1172
+ }
1173
+ }
1174
+ render() {
1175
+ const style = {
1176
+ height: this.height,
1177
+ width: this.width,
1178
+ top: this.y,
1179
+ left: this.x,
1180
+ zIndex: this.z,
1181
+ position: 'absolute',
1182
+ };
1183
+ // List of SVG file names to process sequentially
1184
+ // 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
1185
+ 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" })));
1186
+ }
1187
+ static get assetsDirs() { return ["svg"]; }
1188
+ };
1189
+ AppTrace.style = AppTraceStyle0;
1190
+
1191
+ 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}";
1192
+ const AppWrapStyle0 = appWrapCss;
1193
+
1194
+ const AppWrap = class {
1195
+ constructor(hostRef) {
1196
+ index.registerInstance(this, hostRef);
1197
+ this.id = undefined;
1198
+ this.value = undefined;
1199
+ this.height = undefined;
1200
+ this.width = undefined;
1201
+ this.ariaLabel = undefined;
1202
+ this.ariaHidden = undefined;
1203
+ this.x = undefined;
1204
+ this.y = undefined;
1205
+ this.z = undefined;
1206
+ this.bgColor = undefined;
1207
+ this.type = undefined;
1208
+ this.tabIndex = undefined;
1209
+ this.visible = undefined;
1210
+ this.audio = undefined;
1211
+ this.onTouch = undefined;
1212
+ this.onCorrectTouch = undefined;
1213
+ this.onInCorrectTouch = undefined;
1214
+ this.onCorrectMatch = undefined;
1215
+ this.onMatch = undefined;
1216
+ this.onWrong = undefined;
1217
+ this.onEntry = undefined;
1218
+ }
1219
+ /**
1220
+ * Lifecycle hook that runs after the component is rendered in the DOM.
1221
+ * It initializes custom events based on the `type` of the wrap container.
1222
+ */
1223
+ componentDidLoad() {
1224
+ utils.initEventsForElement(this.el, this.type);
1225
+ }
1226
+ render() {
1227
+ // Inline styles to position and size the wrap container, with grid layout applied
1228
+ const style = {
1229
+ height: this.height,
1230
+ width: this.width,
1231
+ top: this.y,
1232
+ left: this.x,
1233
+ display: this.visible ? 'grid' : 'none', // Use grid layout
1234
+ zIndex: this.z,
1235
+ backgroundColor: this.bgColor,
1236
+ };
1237
+ 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' })));
1238
+ }
1239
+ get el() { return index.getElement(this); }
1240
+ };
1241
+ AppWrap.style = AppWrapStyle0;
1242
+
1243
+ exports.app_col = AppCol;
1244
+ exports.app_container = AppContainer;
1245
+ exports.app_home = AppHome;
1246
+ exports.app_image = AppImage;
1247
+ exports.app_pos = AppPos;
1248
+ exports.app_random = AppRandom;
1249
+ exports.app_root = AppRoot;
1250
+ exports.app_row = AppRow;
1251
+ exports.app_shape = AppShape;
1252
+ exports.app_text = AppText;
1253
+ exports.app_trace = AppTrace;
1254
+ exports.app_wrap = AppWrap;
1255
+
1256
+ //# sourceMappingURL=app-col_12.cjs.entry.js.map