jclic 2.1.21 → 2.1.23

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 (175) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/jclic-node.js +9 -8
  3. package/dist/jclic-node.js.map +1 -1
  4. package/dist/jclic.min.js +2 -2
  5. package/dist/jclic.min.js.map +1 -1
  6. package/package.json +4 -4
  7. package/src/GlobalData.js +1 -1
  8. package/src/JClicPlayer.js +2 -2
  9. package/src/bags/MediaBag.js +6 -5
  10. package/dist/1078.jclic-node.js +0 -282
  11. package/dist/1078.jclic-node.js.map +0 -1
  12. package/dist/1196.jclic-node.js +0 -808
  13. package/dist/1196.jclic-node.js.map +0 -1
  14. package/dist/1253.jclic-node.js +0 -1432
  15. package/dist/1253.jclic-node.js.map +0 -1
  16. package/dist/13.jclic-node.js +0 -103
  17. package/dist/13.jclic-node.js.map +0 -1
  18. package/dist/1567.jclic-node.js +0 -2313
  19. package/dist/1567.jclic-node.js.map +0 -1
  20. package/dist/1588.jclic-node.js +0 -602
  21. package/dist/1588.jclic-node.js.map +0 -1
  22. package/dist/1725.jclic-node.js +0 -836
  23. package/dist/1725.jclic-node.js.map +0 -1
  24. package/dist/1731.jclic-node.js +0 -438
  25. package/dist/1731.jclic-node.js.map +0 -1
  26. package/dist/1842.jclic-node.js +0 -651
  27. package/dist/1842.jclic-node.js.map +0 -1
  28. package/dist/2160.jclic-node.js +0 -1016
  29. package/dist/2160.jclic-node.js.map +0 -1
  30. package/dist/222.jclic-node.js +0 -129
  31. package/dist/222.jclic-node.js.map +0 -1
  32. package/dist/2316.jclic-node.js +0 -949
  33. package/dist/2316.jclic-node.js.map +0 -1
  34. package/dist/2355.jclic-node.js +0 -371
  35. package/dist/2355.jclic-node.js.map +0 -1
  36. package/dist/2366.jclic-node.js +0 -431
  37. package/dist/2366.jclic-node.js.map +0 -1
  38. package/dist/2379.jclic-node.js +0 -202
  39. package/dist/2379.jclic-node.js.map +0 -1
  40. package/dist/2437.jclic-node.js +0 -450
  41. package/dist/2437.jclic-node.js.map +0 -1
  42. package/dist/2531.jclic-node.js +0 -869
  43. package/dist/2531.jclic-node.js.map +0 -1
  44. package/dist/2608.jclic-node.js +0 -160
  45. package/dist/2608.jclic-node.js.map +0 -1
  46. package/dist/2715.jclic-node.js +0 -554
  47. package/dist/2715.jclic-node.js.map +0 -1
  48. package/dist/277.jclic-node.js +0 -22
  49. package/dist/277.jclic-node.js.map +0 -1
  50. package/dist/2921.jclic-node.js +0 -660
  51. package/dist/2921.jclic-node.js.map +0 -1
  52. package/dist/2952.jclic-node.js +0 -101
  53. package/dist/2952.jclic-node.js.map +0 -1
  54. package/dist/3018.jclic-node.js +0 -421
  55. package/dist/3018.jclic-node.js.map +0 -1
  56. package/dist/3019.jclic-node.js +0 -682
  57. package/dist/3019.jclic-node.js.map +0 -1
  58. package/dist/3231.jclic-node.js +0 -274
  59. package/dist/3231.jclic-node.js.map +0 -1
  60. package/dist/331.jclic-node.js +0 -115
  61. package/dist/331.jclic-node.js.map +0 -1
  62. package/dist/3391.jclic-node.js +0 -276
  63. package/dist/3391.jclic-node.js.map +0 -1
  64. package/dist/3502.jclic-node.js +0 -671
  65. package/dist/3502.jclic-node.js.map +0 -1
  66. package/dist/3653.jclic-node.js +0 -982
  67. package/dist/3653.jclic-node.js.map +0 -1
  68. package/dist/371.jclic.min.js +0 -2
  69. package/dist/371.jclic.min.js.map +0 -1
  70. package/dist/3856.jclic-node.js +0 -575
  71. package/dist/3856.jclic-node.js.map +0 -1
  72. package/dist/4112.jclic-node.js +0 -659
  73. package/dist/4112.jclic-node.js.map +0 -1
  74. package/dist/4123.jclic-node.js +0 -910
  75. package/dist/4123.jclic-node.js.map +0 -1
  76. package/dist/427.jclic-node.js +0 -894
  77. package/dist/427.jclic-node.js.map +0 -1
  78. package/dist/4483.jclic-node.js +0 -327
  79. package/dist/4483.jclic-node.js.map +0 -1
  80. package/dist/4548.jclic-node.js +0 -1078
  81. package/dist/4548.jclic-node.js.map +0 -1
  82. package/dist/466.jclic-node.js +0 -99
  83. package/dist/466.jclic-node.js.map +0 -1
  84. package/dist/485.jclic-node.js +0 -783
  85. package/dist/485.jclic-node.js.map +0 -1
  86. package/dist/4921.jclic-node.js +0 -500
  87. package/dist/4921.jclic-node.js.map +0 -1
  88. package/dist/5091.jclic-node.js +0 -239
  89. package/dist/5091.jclic-node.js.map +0 -1
  90. package/dist/520.jclic-node.js +0 -550
  91. package/dist/520.jclic-node.js.map +0 -1
  92. package/dist/5312.jclic-node.js +0 -1126
  93. package/dist/5312.jclic-node.js.map +0 -1
  94. package/dist/5338.jclic-node.js +0 -212
  95. package/dist/5338.jclic-node.js.map +0 -1
  96. package/dist/5344.jclic-node.js +0 -229
  97. package/dist/5344.jclic-node.js.map +0 -1
  98. package/dist/5550.jclic-node.js +0 -238
  99. package/dist/5550.jclic-node.js.map +0 -1
  100. package/dist/5626.jclic-node.js +0 -614
  101. package/dist/5626.jclic-node.js.map +0 -1
  102. package/dist/5977.jclic-node.js +0 -1081
  103. package/dist/5977.jclic-node.js.map +0 -1
  104. package/dist/6148.jclic-node.js +0 -345
  105. package/dist/6148.jclic-node.js.map +0 -1
  106. package/dist/6176.jclic-node.js +0 -481
  107. package/dist/6176.jclic-node.js.map +0 -1
  108. package/dist/6221.jclic-node.js +0 -1072
  109. package/dist/6221.jclic-node.js.map +0 -1
  110. package/dist/6238.jclic-node.js +0 -718
  111. package/dist/6238.jclic-node.js.map +0 -1
  112. package/dist/6454.jclic-node.js +0 -1413
  113. package/dist/6454.jclic-node.js.map +0 -1
  114. package/dist/6565.jclic-node.js +0 -294
  115. package/dist/6565.jclic-node.js.map +0 -1
  116. package/dist/6579.jclic-node.js +0 -719
  117. package/dist/6579.jclic-node.js.map +0 -1
  118. package/dist/6715.jclic-node.js +0 -148
  119. package/dist/6715.jclic-node.js.map +0 -1
  120. package/dist/6777.jclic-node.js +0 -171
  121. package/dist/6777.jclic-node.js.map +0 -1
  122. package/dist/6782.jclic-node.js +0 -1611
  123. package/dist/6782.jclic-node.js.map +0 -1
  124. package/dist/6847.jclic-node.js +0 -601
  125. package/dist/6847.jclic-node.js.map +0 -1
  126. package/dist/6856.jclic-node.js +0 -252
  127. package/dist/6856.jclic-node.js.map +0 -1
  128. package/dist/696.jclic-node.js +0 -1821
  129. package/dist/696.jclic-node.js.map +0 -1
  130. package/dist/698.jclic-node.js +0 -583
  131. package/dist/698.jclic-node.js.map +0 -1
  132. package/dist/704.jclic-node.js +0 -80
  133. package/dist/704.jclic-node.js.map +0 -1
  134. package/dist/7046.jclic-node.js +0 -735
  135. package/dist/7046.jclic-node.js.map +0 -1
  136. package/dist/7220.jclic-node.js +0 -156
  137. package/dist/7220.jclic-node.js.map +0 -1
  138. package/dist/7257.jclic-node.js +0 -931
  139. package/dist/7257.jclic-node.js.map +0 -1
  140. package/dist/743.jclic-node.js +0 -583
  141. package/dist/743.jclic-node.js.map +0 -1
  142. package/dist/757.jclic-node.js +0 -1072
  143. package/dist/757.jclic-node.js.map +0 -1
  144. package/dist/7781.jclic-node.js +0 -202
  145. package/dist/7781.jclic-node.js.map +0 -1
  146. package/dist/7912.jclic-node.js +0 -2103
  147. package/dist/7912.jclic-node.js.map +0 -1
  148. package/dist/827.jclic-node.js +0 -708
  149. package/dist/827.jclic-node.js.map +0 -1
  150. package/dist/8276.jclic-node.js +0 -409
  151. package/dist/8276.jclic-node.js.map +0 -1
  152. package/dist/8322.jclic-node.js +0 -498
  153. package/dist/8322.jclic-node.js.map +0 -1
  154. package/dist/8641.jclic-node.js +0 -360
  155. package/dist/8641.jclic-node.js.map +0 -1
  156. package/dist/8837.jclic-node.js +0 -651
  157. package/dist/8837.jclic-node.js.map +0 -1
  158. package/dist/8895.jclic-node.js +0 -151
  159. package/dist/8895.jclic-node.js.map +0 -1
  160. package/dist/9072.jclic-node.js +0 -1285
  161. package/dist/9072.jclic-node.js.map +0 -1
  162. package/dist/9078.jclic-node.js +0 -935
  163. package/dist/9078.jclic-node.js.map +0 -1
  164. package/dist/9103.jclic-node.js +0 -718
  165. package/dist/9103.jclic-node.js.map +0 -1
  166. package/dist/9359.jclic-node.js +0 -145
  167. package/dist/9359.jclic-node.js.map +0 -1
  168. package/dist/9409.jclic-node.js +0 -921
  169. package/dist/9409.jclic-node.js.map +0 -1
  170. package/dist/9513.jclic-node.js +0 -720
  171. package/dist/9513.jclic-node.js.map +0 -1
  172. package/dist/9704.jclic-node.js +0 -81
  173. package/dist/9704.jclic-node.js.map +0 -1
  174. package/dist/9950.jclic-node.js +0 -827
  175. package/dist/9950.jclic-node.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"1253.jclic-node.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEuB;AACG;AACW;AACI;;AAEzC;AACA;AACA,kDAAkD,yBAAyB;AAC3E,WAAW;AACX;AACO;AACP,GAAG;AACH,OAAO;AACP,YAAY;AACZ;;AAEA;AACA;AACA,WAAW;AACX;AACO;;AAEP;AACA;AACA,WAAW;AACX;AACO;;AAEP;AACA;AACA,UAAU,QAAQ;AACX;AACP;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,uCAAuC,sDAAU;AACjD,6BAA6B,8BAA8B,aAAa,UAAU,SAAS,IAAI;AAC/F,kCAAkC,EAAE,sDAAU;AAC9C;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACO;AACP,0EAA0E,IAAI,gBAAgB,EAAE;AAChG;AACA,SAAS,uBAAuB,EAAE,cAAc,sBAAsB,OAAO,EAAE,cAAc,sBAAsB,OAAO;AAC1H;AACA;;AAEA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,kBAAkB,kBAAkB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ,qCAAqC;AACxD;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,2BAA2B,mEAAmE;AAC9F;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAA0B,EAAE,yBAAyB,EAAE,4CAA4C,EAAE,IAAI;AAClI;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,WAAW,KAAK;AAChB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP,YAAY,sBAAsB;AAClC;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP,aAAa,IAAI;AACjB;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA,YAAY,kBAAkB,EAAE,2BAA2B,EAAE,MAAM;AACnE;;AAEA;AACA;AACA,WAAW,eAAe;AAC1B,aAAa;AACb;AACO;AACP,YAAY,mBAAmB,GAAG,wBAAwB,GAAG,oBAAoB,EAAE,oBAAoB,GAAG,sBAAsB,GAAG,sBAAsB;AACzJ;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,eAAe;AAC5B;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,EAAE,GAAG,EAAE,GAAG,EAAE;AACpD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,YAAY,QAAQ;AACb;;AAEP,YAAY,QAAQ;AACb;;AAEP,YAAY,QAAQ;AACb;;AAEP;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,KAAK;AAChB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,KAAK;AAChB,WAAW,KAAK;AAChB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA,EAAE,6CAAC,0CAA0C,cAAc,kBAAkB,QAAQ;AACrF;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI,QAAQ,aAAa,KAAK,oBAAoB,IAAI,mBAAmB;AACzE,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP,mDAAmD,EAAE,EAAE,IAAI,GAAG,aAAa;AAC3E;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,oCAAoC,GAAG,oCAAoC,GAAG,oCAAoC,GAAG,MAAM;AAC/I;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACO;AACP,SAAS,oDAAQ;AACjB;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA,IAAI,kDAAM;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,UAAU;AACrB;AACA;AACA,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,aAAa,SAAS,sBAAsB;AAC5C;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,UAAU;AACrB;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C,oCAAoC,UAAU;AAC9C,wCAAwC,UAAU;AAClD,uCAAuC,QAAQ;AAC/C;AACA,sCAAsC,QAAQ;AAC9C;AACA;AACA,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA,cAAc,+BAA+B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,IAAI;AACf;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,QAAQ;AACnB,WAAW,KAAK;AAChB,WAAW,UAAU;AACrB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,yBAAyB;AAC/B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B;AACA,WAAW,GAAG;AACd,aAAa;AACb;AACO;AACP;AACA,gBAAgB;AAChB;AACA,kBAAkB,gBAAgB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,WAAW,QAAQ;AACnB,aAAa,KAAK;AAClB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,gBAAgB,qBAAqB,sBAAsB;AACtE;AACA,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,MAAM,SAAS,KAAK;AAC9C,SAAS;AACT,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;AACO;AACP,wBAAwB,6CAAC,iBAAiB,6CAAC,0BAA0B,6CAAC;AACtE,YAAY,6CAAC;AACb,0BAA0B,6CAAC,wBAAwB,mBAAmB;AACtE,0BAA0B,6CAAC,wBAAwB,mBAAmB;AACtE;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA,iDAAiD,MAAM;AACvD;AACA,mDAAmD,OAAO;AAC1D;AACA,yDAAyD,KAAK;AAC9D;AACA;;AAEA;AACA,oCAAoC;AACpC;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP,6BAA6B;AAC7B;;AAEA;AACA;AACA,WAAW,eAAe;AAC1B;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP,qGAAqG,cAAc,QAAQ,IAAI;AAC/H;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ,sEAAsE;AACzF,WAAW,sBAAsB;AACjC,aAAa,QAAQ;AACrB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,sBAAsB;AACjC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,gCAAgC,+CAA+C,iDAAiD;AAC3I,aAAa,2BAA2B;AACxC;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,uBAAuB;AAClC;AACA,WAAW,UAAU;AACrB;AACA;AACO;AACP,kBAAkB,uBAAuB;AACzC;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,gBAAgB;AAC7B;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,8DAA8D;AAClE,IAAI;AACJ,QAAQ;AACR,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+BAA+B;AAC/B,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA,IAAI;AACJ;AACA,2CAA2C,SAAS;AACpD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAoB,sBAAsB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACO;AACP;AACA,WAAW,sDAAU;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,qBAAqB,GAAG;AACjD,8BAA8B,oBAAoB,wEAAwE;;AAE1H;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iEAAe,KAAK,EAAC","sources":["webpack://jclic/./src/Utils.js"],"sourcesContent":["/**\n * File : Utils.js\n * Created : 01/04/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\n/* global Promise, window, document, console, HTMLElement */\n\nimport $ from 'jquery';\nimport JSZip from 'jszip';\nimport JSZipUtils from 'jszip-utils';\nimport GlobalData from './GlobalData.js';\n\n/**\n * Exports third-party NPM packages used by JClic, so they become available to other scripts through\n * the global variable `JClicObject` (defined in {@link module:JClic.JClic})\n * @type: {object}\n */\nexport const pkg = {\n $,\n JSZip,\n JSZipUtils,\n};\n\n/**\n * List of valid verbosity levels\n * @const {string[]}\n */\nexport const LOG_LEVELS = ['none', 'error', 'warn', 'info', 'debug', 'trace', 'all'];\n\n/**\n * Labels printed on logs for each message type\n * @const {string[]}\n */\nexport const LOG_PRINT_LABELS = [' ', 'ERROR', 'WARN ', 'INFO ', 'DEBUG', 'TRACE', 'ALL '];\n\n/**\n * Options of the logging system\n * @type {object} */\nexport const LOG_OPTIONS = {\n level: 2, // warn\n prefix: 'JClic',\n timestamp: true,\n popupOnErrors: false,\n chainTo: null,\n pipeTo: null,\n};\n\n/**\n * Current dictionary of string translations\n */\nlet _messages = {};\n\n/**\n * Initializes the global settings\n * @param {object} options - An object with global settings\n * @param {boolean} [setLog=true] - When `true`, the log level will be set\n * @param {boolean} [setLang=true] - When `true`, the current language will be set\n * @returns {object} The normalized `options` object\n */\nexport function init(options, setLog = true, setLang = true) {\n options = normalizeObject(options);\n if (setLog) {\n if (typeof options.logLevel !== 'undefined')\n setLogLevel(options.logLevel);\n if (typeof options.chainLogTo === 'function')\n LOG_OPTIONS.chainTo = options.chainLogTo;\n if (typeof options.pipeLogTo === 'function')\n LOG_OPTIONS.pipeTo = options.pipeLogTo;\n }\n\n if (setLang) {\n const lngRequested = options.lang;\n const lng = checkPreferredLanguage(GlobalData.languages, 'en', lngRequested);\n log('debug', `Language ${lngRequested ? `requested: \"${lngRequested}\" ` : ''} used: \"${lng}\"`);\n _messages = lng === 'en' ? {} : GlobalData.messages[lng];\n }\n\n return options;\n};\n\n/**\n * Function that will return the translation of the provided key\n * into the current language.\n * @param {string} key - ID of the expression to be translated\n * @returns {string} - The translated text\n */\nexport function getMsg(key) {\n return _messages[key] || key;\n}\n\n/**\n * Converts expressions of type 'pt-br', 'FR', 'ca_es@valencia'... to the format expected by the i18n system:\n * lc[_CC][@variant] where 'lc' is a two or three lowercase letter language code, CC is an optional two uppercase\n * letter country code, followed by an optional 'variant' consisting in letters and/or digits.\n * @param {string} locale - The locale expression to be normalized\n * @returns string - The normalized locale\n */\nexport function normalizeLocale(locale = '') {\n const [, language = null, country = null, variant = null] = /^([a-zA-Z]{2,3})[_-]?([a-zA-Z]{2})?@?([a-zA-Z0-9]*)?$/.exec(locale.trim()) || [];\n return language\n ? `${language.toLowerCase()}${country ? `_${country.toUpperCase()}` : ''}${variant ? `@${variant.toLowerCase()}` : ''}`\n : '';\n};\n\n/**\n * Checks if the language preferred by the user (based on browser and/or specific settings)\n * is in a list of available languages.\n * @param {string[]} availableLangs - Array of available languages. It should contain at least one item.\n * @param {string} [defaultLang=en] - Language to be used by default when not found the selected one\n * @param {string} [requestedLang=''] - Request this specific language\n * @returns {string} - The most suitable language for this request\n */\nexport function checkPreferredLanguage(availableLangs, defaultLang = 'en', requestedLang = '') {\n let result = -1;\n\n // Create an array to store possible values\n let tries = [];\n\n // If \"setLang\" is specified, check it\n if (requestedLang) {\n // Normalize requested locale\n const lang = normalizeLocale(requestedLang);\n if (lang)\n tries.push(lang);\n }\n\n // Add user's preferred languages, if any\n if (window.navigator.languages)\n tries = tries.concat(window.navigator.languages);\n\n // Add the navigator main language, if defined\n if (window.navigator.language)\n tries.push(window.navigator.language);\n\n // Add English as final option\n tries.push(defaultLang);\n\n for (let i = 0; i < tries.length; i++) {\n let match = -1;\n for (let n in availableLangs) {\n if (tries[i].indexOf(availableLangs[n]) === 0) {\n match = n;\n if (tries[i] === availableLangs[n]) {\n result = n;\n break;\n }\n }\n }\n if (result >= 0 || (result = match) >= 0)\n break;\n }\n return availableLangs[result >= 0 ? result : 0];\n};\n\n/**\n * Establishes the current verbosity level of the logging system\n * @param {string} level - One of the valid strings in {@link module:Utils.LOG_LEVELS}\n */\nexport function setLogLevel(level) {\n const log = LOG_LEVELS.indexOf(level);\n if (log >= 0)\n LOG_OPTIONS.level = log;\n};\n\n/**\n * Reports a new message to the logging system\n * @param {string} type - The type of message. Mus be `error`, `warn`, `info`, `debug` or `trace`.\n * @param {string} msg - The main message to be logged. Additional parameters can be added, like\n * in `console.log` (see: {@link https://developer.mozilla.org/en-US/docs/Web/API/Console/log})\n */\nexport function log(type, msg) {\n const level = LOG_LEVELS.indexOf(type);\n const args = Array.prototype.slice.call(arguments);\n\n // Check if message should currently be logged\n if (level < 0 || level <= LOG_OPTIONS.level) {\n if (LOG_OPTIONS.pipeTo)\n LOG_OPTIONS.pipeTo.apply(null, args);\n else {\n const mainMsg = `${LOG_OPTIONS.prefix || ''} ${LOG_PRINT_LABELS[level]} ${LOG_OPTIONS.timestamp ? getDateTime() : ''} ${msg}`;\n console[level === 1 ? 'error' : level === 2 ? 'warn' : 'log'].apply(console, [mainMsg].concat(args.slice(2)));\n // Call chained logger, if anny\n if (LOG_OPTIONS.chainTo)\n LOG_OPTIONS.chainTo.apply(null, args);\n }\n }\n};\n\n/**\n * Gets a boolean value from a textual expression\n * @param {string} val - The value to be parsed (`true` for true, null or otherwise for `false`)\n * @param {boolean} [defaultValue=false] - The default value to return when `val` is false\n * @returns {number}\n */\nexport function getBoolean(val, defaultValue = false) {\n return val === 'true' ? true : val === 'false' ? false : defaultValue;\n};\n\n/**\n * Gets a value from an given expression that can be `null`, `undefined` or empty string ('')\n * @param {any} val - The expression to parse\n * @param {any} [defaultValue=null] - The value to return when `val` is `null`, `''` or `undefined`\n * @returns {any}\n */\nexport function getVal(val, defaultValue = null) {\n return (val === '' || val === null || typeof val === 'undefined') ? defaultValue : val;\n};\n\n/**\n * Gets a number from a string or another number\n * @param {any} val - The expression to parse\n * @param {number} [defaultValue=0] - The default value\n * @returns {number}\n */\nexport function getNumber(val, defaultValue) {\n return Number(getVal(val, defaultValue));\n};\n\n/**\n * Gets the plain percent expression (without decimals) of the given value\n * @param {number} val - The value to be expressed as a percentile\n * @returns {string}\n */\nexport function getPercent(val) {\n return `${Math.round(val * 100)}%`;\n}\n\n/**\n * Returns the two-digits text expression representing the given number (lesser than 100) zero-padded at left\n * Useful for representing hours, minutes and seconds\n * @param {number} val - The number to be processed\n * @returns {string}\n */\nexport function zp(val) {\n return `0${val}`.slice(-2);\n};\n\n/**\n * Returns a given time in [00h 00'00\"] format\n * @param {number} millis - Amount of milliseconds to be processed\n * @returns {string}\n */\nexport function getHMStime(millis) {\n const d = new Date(millis);\n const h = d.getUTCHours(), m = d.getUTCMinutes(), s = d.getUTCSeconds();\n return `${h ? h + 'h ' : ''}${h || m ? zp(m) + '\\'' : ''}${zp(s)}\"`;\n};\n\n/**\n * Returns a formatted string with the provided date and time\n * @param {external:Date} date - The date to be formatted. When `null` or `undefined`, the current date will be used.\n * @returns {string}\n */\nexport function getDateTime(date = new Date()) {\n return `${date.getFullYear()}/${zp(date.getMonth() + 1)}/${zp(date.getDate())} ${zp(date.getHours())}:${zp(date.getMinutes())}:${zp(date.getSeconds())}`;\n};\n\n/**\n * Parse 'date' fields generated by \"JClic Author\" in format d/m/y, with\n * variable number of digits.\n * @param {string} text - The old 'date' field\n * @returns {external:Date} - Always return a Date object (now, if text was invalid)\n */\nexport function parseOldDate(text) {\n let result = null;\n if (text) {\n const elements = text.trim().split('/');\n if (elements.length === 3) {\n let m = parseInt(elements[0]) || 0;\n let d = parseInt(elements[1]) || 0;\n let y = parseInt(elements[2]) || 0;\n if (m > 12 && d <= 12) {\n const t = m;\n m = d;\n d = t;\n }\n if (y < 1980)\n y += (y < 90 ? 2000 : 1900);\n if (d && m && y) {\n result = new Date(Date.parse(`${m}/${d}/${y}`));\n }\n }\n }\n return result || new Date();\n};\n\n/**\n * Extracts just the ISO-639 language code from complex\n * expressions like \"English (en)\", buid by JClic Author.\n * @param {string} text - The expression to parse\n * @returns {string} - The ISO-639 language code, or '--' if none found\n */\nexport function cleanOldLanguageTag(text) {\n if (!text)\n text = '--';\n // Allow only ISO-639-1 and ISO-639-2 language codes\n else if (!text.match(/^[a-z][a-z][a-z]?$/)) {\n const matches = text.match(/\\(([a-z][a-z][a-z]?)\\)/);\n if (matches && matches.length === 2)\n text = matches[1];\n else\n text = '--';\n }\n return text;\n};\n\n/** @const {number} */\nexport const FALSE = 0;\n\n/** @const {number} */\nexport const TRUE = 1;\n\n/** @const {number} */\nexport const DEFAULT = 2;\n\n/**\n * Gets a numeric value (0, 1 or 2) from a set of possible values: `false`, `true` and `default`.\n * @param {string} val - The text to be parsed\n * @param {any} def - An optional default value\n * @returns {number}\n */\nexport function getTriState(val, def = DEFAULT) {\n return val === 'true' ? TRUE : val === 'false' ? FALSE : def;\n};\n\n/**\n * Returns a string with the given `tag` repeated n times\n * @param {string} tag - The tag to be repeated\n * @param {number} repeats - The number of times to repeat the tag\n * @returns {string}\n */\nexport function fillString(tag, repeats = 0) {\n return Array(repeats).fill(tag).join('');\n};\n\n/**\n * Checks if the provided value is 'null' or 'undefined'.\n * @param {any} val - The value to be parsed\n * @returns {boolean}\n */\nexport function isNullOrUndef(val) {\n return typeof val === 'undefined' || val === null;\n};\n\n/**\n * Checks if two expressions are equivalent.\n * Returns `true` when both parameters are `null` or `undefined`, and also when both have\n * equivalent values.\n * @param {any} a\n * @param {any} b\n * @returns {boolean}\n */\nexport function isEquivalent(a, b) {\n return (typeof a === 'undefined' || a === null) && (typeof b === 'undefined' || b === null) || a === b;\n};\n\n/**\n * Reads paragraphs, identified by `<p></p>` elements, inside XML data\n * @param {object} xml - The DOM-XML element to be parsed\n * @returns {string}\n */\nexport function getXmlText(xml) {\n let text = '';\n $(xml).children('p').each((_n, child) => { text += `<p>${child.textContent}</p>`; });\n return text;\n};\n\n/**\n * Parse the provided XML element node, returning a complex object\n * @param {object} xml - The root XML element to parse\n * @param {boolean} [withText=false] - When `true`, any text found inside the XML element is also included in the resulting object.\n * @returns {object}\n */\nexport function parseXmlNode(xml, withText = false) {\n // Initialize the resulting object\n const result = {};\n // Direct copy of root element attributes as object properties\n if (xml.attributes)\n attrForEach(xml.attributes, (name, value) => result[name] = /^-?\\d*$/.test(value) ? Number(value) : value);\n\n const keys = [];\n const children = Array.from(xml.children || xml.childNodes || []);\n\n // If all children is of type 'p', just compile it in a single string\n const paragraphs = children.filter(child => child.nodeName === 'p');\n if (paragraphs.length > 0 && paragraphs.length === children.filter(ch => ch.nodeName !== '#text').length) {\n const text = paragraphs.map(ch => ch.textContent).join('\\n');\n if (xml.attributes) {\n result.text = text;\n return result;\n }\n return text;\n }\n\n // Process children elements\n children.forEach(child => {\n // Avoid extra text content collected by [xmldom](https://www.npmjs.com/package/xmldom)\n if (child.nodeName === '#text' && !withText)\n return;\n\n // Recursive processing of children\n const ch = parseXmlNode(child, withText);\n // Store the result into a temporary object named as the child node name,\n if (!result[child.nodeName]) {\n // Create object and save key for later processing\n result[child.nodeName] = {};\n keys.push(child.nodeName);\n }\n // Use 'id' (or an incremental number if 'id' is not set) as a key\n if (ch.id)\n result[child.nodeName][ch.id] = ch;\n else {\n const n = Object.keys(result[child.nodeName]).length;\n result[child.nodeName][n] = ch;\n }\n });\n // Check temporary objects, converting it to an array, a single object or a complex object\n keys.forEach(k => {\n // Retrieve temporary object from `keys`\n const kx = Object.keys(result[k]);\n // If all keys are numbers, convert object into an array (or leave it as a single object)\n if (!kx.find(kk => isNaN(kk))) {\n if (kx.length === 1)\n // Array with a single element. Leave it as a simple object:\n result[k] = result[k][0];\n else {\n // Object with numeric keys. Convert it to array:\n const arr = [];\n kx.forEach(kk => arr.push(result[k][kk]));\n result[k] = arr;\n }\n }\n });\n // Save text content, if any:\n if (children.length === 0 && xml.textContent)\n result.textContent = xml.textContent;\n return result;\n};\n\n/**\n * Parse the given XML node, known as containing only text elements,\n * and return its content as a string (when possible)\n * @param {object} xml - The XML element to parse\n * @returns {string|object}\n */\nexport function getXmlNodeText(node) {\n const result = parseXmlNode(node);\n return typeof result === 'string' ?\n result :\n result.hasOwnProperty('text') ?\n result.text :\n result.hasOwnProperty('textContent') ?\n result.textContent :\n result;\n};\n\n/**\n * Recursively explore the given object, converting to a string\n * all attributes with a single attribute named 'text'.\n * Example:\n * {a:1, b:{text:\"hello\"}, c:{d:2, text:\"world\"}} => {a:1, b:\"hello\", c:{d:2, text:\"world\"}}\n * @param {object} obj - The object to explore\n * @returns {object} - The same object, with text attributes reduced to strings\n */\nexport function reduceTextsToStrings(obj) {\n if (obj) {\n const keys = Object.keys(obj);\n keys.forEach(k => {\n const attr = obj[k];\n if (typeof attr === 'object') {\n const ko = Object.keys(attr);\n if (ko.length === 1 && ko[0] === 'text')\n obj[k] = attr.text;\n else\n obj[k] = reduceTextsToStrings(attr);\n }\n });\n }\n return obj;\n};\n\n/**\n * Creates a string suitable to be used in the 'style' attribute of HTML tags, filled with the\n * CSS attributes contained in the provided object.\n * @param {object} cssObj\n * @returns {string}\n */\nexport function cssToString(cssObj) {\n return Object.keys(cssObj).reduce((s, key) => `${s}${key}:${cssObj[key]};`, '');\n};\n\n/**\n * Converts java-like color codes (like '0xRRGGBB') to valid CSS values like '#RRGGBB' or 'rgba(r,g,b,a)'\n * @param {string} [color] - A color, as codified in Java\n * @param {string} [defaultColor] - The default color to be used\n * @returns {string}\n */\nexport function checkColor(color, defaultColor = settings.BoxBase.BACK_COLOR) {\n if (typeof color === 'undefined' || color === null)\n color = defaultColor;\n color = color.replace('0x', '#');\n // Check for Alpha value\n if (color.charAt(0) === '#' && color.length > 7) {\n const alpha = fx(parseInt(color.substring(1, 3), 16) / 255.0, 2);\n color = `rgba(${parseInt(color.substring(3, 5), 16)},${parseInt(color.substring(5, 7), 16)},${parseInt(color.substring(7, 9), 16)},${alpha})`;\n }\n return color;\n};\n\n/**\n * Checks if the provided color has an alpha value less than 1\n * @param {string} color - The color to be analyzed\n * @returns {boolean}\n */\nexport function colorHasTransparency(color) {\n if (startsWith(color, 'rgba(')) {\n var alpha = parseInt(color.substring(color.lastIndexOf(',')));\n return typeof alpha === 'number' && alpha < 1.0;\n }\n return false;\n};\n\n/**\n * Clones the provided object\n * See: https://stackoverflow.com/questions/41474986/how-to-clone-a-javascript-es6-class-instance\n * @param {object} obj\n * @returns {object}\n */\n//cloneObject: obj => Object.assign(Object.create(Object.getPrototypeOf(obj)), obj),\nexport function cloneObject(obj) {\n return $.extend(true, Object.create(Object.getPrototypeOf(obj)), obj);\n};\n\n/**\n * Converts string values to number or boolean when needed\n * @param {object} obj - The object to be processed\n * @returns {object} - A new object with normalized content\n */\nexport function normalizeObject(obj) {\n const result = {};\n if (obj)\n $.each(obj, (key, value) => {\n let s;\n if (typeof value === 'string' && (s = value.trim().toLowerCase()) !== '')\n value = s === 'true' ? true : s === 'false' ? false : isNaN(s) ? value : Number(s);\n result[key] = value;\n });\n return result;\n};\n\n/**\n * Returns an partial clone of an object, containing only the own attributes specified in an array of possible keys.\n * When the value of an attribute is of type 'Object' and this object has a method named `getAttributes`, the result of calling\n * this method is returned instead of the crude object.\n * @param {object} obj - The object to be processed\n * @param {string[]} [keys] - An optional array of keys to be included in the resulting object.\n * When null or not set, all keys of `obj` are included. Keys can include a default value separed by '|'.\n * Attributes with default value will be excluded from the resulting object.\n * @returns {object}\n */\nexport function getAttr(obj, keys = null) {\n let result = {};\n keys = keys || Object.keys(obj);\n keys.forEach(key => {\n const [k, d] = key.split('|');\n if (obj.hasOwnProperty(k) && typeof obj[k] !== 'undefined' && obj[k] !== null && obj[k].toString() !== d) {\n const v = getValue(obj[k]);\n if (!isEmpty(v))\n result[k] = v;\n }\n });\n\n // Convert to string objects with only a \"text\" attribute\n keys = Object.keys(result);\n if (keys.length === 1 && keys[0] === 'text')\n result = result.text;\n\n return result;\n};\n\n/**\n * Gets the minimal representation of the given value (object, array, string, number...)\n * @param {any} value - The value to be processed\n * @returns {any}\n */\nexport function getValue(value) {\n return value.getAttributes ?\n value.getAttributes() :\n value instanceof Array ?\n value.map(e => getValue(e)) :\n value instanceof Date ?\n value.toISOString() :\n value instanceof Object ?\n getAttr(value) :\n value;\n};\n\n/**\n * Checks if the given value is an empty object, null or a zero-length string\n * @param {any} v - The value to be checked\n * @returns {boolean} - `true` if `v` is `{}`, `null` or `\"\"`\n */\nexport function isEmpty(v) {\n let result = (typeof v === 'undefined' || v === null);\n if (!result) {\n switch (typeof v) {\n case 'object':\n result = Object.keys(v).length === 0;\n break;\n\n case 'string':\n result = v.length === 0;\n break;\n }\n }\n return result;\n};\n\n/**\n * Fills an object with specific attributes from another data object\n * @param {object} obj - The target object\n * @param {object} data - The data object\n * @param {string[]} attr - The list of attributes to be copied from `data` to `obj`\n * Elements of this list can be:\n * a) Just a string. In this case, the native object will be used as a value\n * b) An object with the following members:\n * - `key`{string} - The attribute name\n * - `fn` {function} - The function to be invoked to build the object\n * - `params` {string[]} - Optional params to be passed to the `setAttributes` method of the created object\n * - `group` {string} - Used when `data` is an object or an array (possible values are `object` and `array`), and multiple results\n * should be aggregated in a resulting object or array with the same keys (or ordering) as data.\n * - `init` {string} - Optional parameter indicating if `fn` should be passed with an additional param. This param can be:\n * - `key` - The member's key\n *\n * @returns {object} - Always returns `obj`\n */\nexport function setAttr(obj, data, attr) {\n attr.forEach(a => {\n if (a.key) {\n const { key, fn, group, init, params } = a;\n // A new object should be built\n if (!isEmpty(data[key])) {\n const dataset = data[key];\n if (group === 'object')\n obj[key] = Object.keys(dataset).reduce((o, k) => {\n o[k] = buildObj(fn, dataset[k], init === 'key' ? k : init, params);\n return o;\n }, {});\n else if (group === 'array')\n obj[key] = dataset.map((element, n) => buildObj(fn, element, init === 'key' ? n : init, params));\n else\n obj[key] = buildObj(fn, dataset, init, params);\n }\n } else if (!isEmpty(data[a]))\n obj[a] = data[a];\n });\n return obj;\n};\n\n/**\n * Builds a new object based on the provided constructor, data and initialization value\n * Objects used with this function should implement `setAttributes`, or an static method named `factory`\n * @param {function} objType - A class or function to be invoked to build the object.\n * @param {object} [data] - An optional object filled with the attributes to be assigned to the newly created object.\n * @param {any} [init] - An optional value to be passed to the function when invoked with `new`\n * @param {object[]} [params=[]] - Optional array of params to be passed when calling `setAttributes` on the final object\n * @returns {object} - The resulting object\n */\nexport function buildObj(objType, data, init, params = []) {\n return objType.factory ? objType.factory(data, init, params) : new objType(init).setAttributes(data, ...params);\n};\n\n/**\n * Check if the given char is a separator\n * @param {string} ch - A string with a single character\n * @returns {boolean}\n */\nexport function isSeparator(ch) {\n return settings.SEPARATORS.includes(ch);\n};\n\n/**\n * Check if the given char is a word delimiter\n * @param {string} ch - A string with a single character\n * @returns {boolean}\n */\nexport function isWordDelimiter(ch) {\n return settings.WORD_DELIMITERS.includes(ch);\n}\n\n/**\n * Converts a string in an array of objects with 'text' and 'sep' attributes, where 'text' are single words and 'sep'\n * are the word separators following each word in the sentence.\n * @example\n * stringToWords(\"Hello, World! That's all\") returns:\n * [\n * {text: \"Hello\", sep: \", \"},\n * {text: \"World\", sep: \"! \"},\n * {text: \"That\", sep: \"'\"},\n * {text: \"s\", sep: \" \"},\n * {text: \"all\", sep: \"\"},\n * ]\n * @param {*} str - The text to be tokenized\n * @returns {object[]}\n */\nexport function stringToWords(str) {\n const result = [];\n let token = { text: '', sep: '' };\n let inWord = true;\n for (let i = 0; i < str.length; i++) {\n const ch = str.charAt(i);\n const delim = isWordDelimiter(ch);\n if (inWord) {\n if (!delim)\n token.text += ch;\n else {\n inWord = false;\n token.sep = ch;\n }\n } else {\n if (delim)\n token.sep += ch;\n else {\n result.push(token);\n token = { text: ch, sep: '' };\n inWord = true;\n }\n }\n }\n result.push(token);\n return result;\n}\n\n/**\n * Rounds `v` to the nearest multiple of `n`\n * @param {number} v\n * @param {number} n - Cannot be zero!\n * @returns {number}\n */\nexport function roundTo(v, n) {\n return Math.round(v / n) * n;\n};\n\n/**\n * Set the maximum number of decimals for a number\n * @param {any} v - The value to be converted to a fixed number of decimals. Can be anything.\n * @param {number} n=4 - the maximum number of decimals\n * @returns {any} - When `v` is a number, a number with fixed decimals is returned. Otherwise, returns `v`\n */\nexport function fx(v, n = 4) {\n return v.toFixed ? Number(v.toFixed(n)) : v;\n};\n\n/**\n * Compares the provided answer against multiple valid options. These valid options are\n * concatenated in a string, separated by pipe chars (`|`). The comparing can be case sensitive.\n * @param {string} answer - The text to check against to\n * @param {string} check - String containing one or multiple options, separated by `|`\n * @param {boolean} [checkCase=false] - When true, the comparing will be case-sensitive\n * @param {boolean} [numeric=false] - When true, we are comparing numeric expressions\n * @returns {boolean}\n */\nexport function compareMultipleOptions(answer, check, checkCase = false, numeric = false) {\n if (answer === null || answer.length === 0 || check === null || check.length === 0)\n return false;\n if (!checkCase && !numeric)\n answer = answer.toUpperCase();\n answer = answer.trim();\n\n // Check for numeric digits in answer!\n numeric = numeric && /\\d/.test(answer);\n\n for (let token of check.split('|')) {\n if (numeric) {\n if (Number.parseFloat(answer.replace(/,/, '.')) === Number.parseFloat(token.replace(/,/, '.')))\n return true;\n }\n else if (answer === (checkCase ? token : token.toUpperCase()).trim())\n return true;\n }\n return false;\n};\n\n/**\n * Checks if the given string ends with the specified expression\n * @param {string} text - The string where to find the expression\n * @param {string} expr - The expression to search for.\n * @param {boolean} [trim] - When `true`, the `text` string will be trimmed before check\n * @returns {boolean}\n */\nexport function endsWith(text = '', expr, trim) {\n return typeof text === 'string' && (trim ? text.trim() : text).endsWith(expr);\n};\n\n/**\n * Checks if the given string starts with the specified expression\n * @param {string} text - The string where to find the expression\n * @param {string} expr - The expression to search for.\n * @param {boolean} [trim] - When `true`, the `text` string will be trimmed before check\n * @returns {boolean}\n */\nexport function startsWith(text = '', expr, trim) {\n return typeof text === 'string' && (trim ? text.trim() : text).indexOf(expr) === 0;\n};\n\n/**\n * Replaces all occurrences of the backslash character (`\\`) by a regular slash (`/`)\n * This is useful to normalize bad path names present in some old JClic projects\n * @param {string} str - The string to be normalized\n * @returns {string}\n */\nexport function nSlash(str) {\n return str ? str.replace(/\\\\/g, '/') : str;\n};\n\n/**\n * Checks if the given expression is an absolute URL\n * @param {string} exp - The expression to be checked\n * @returns {boolean}\n */\nexport function isURL(exp) {\n return /^(filesystem:)?(https?|file|data|ftps?):/i.test(exp);\n};\n\n/**\n * Gets the base path of the given file path (absolute or full URL). This base path always ends\n * with `/`, meaning it can be concatenated with relative paths without adding a separator.\n * @param {string} path - The full path to be parsed\n * @returns {string}\n */\nexport function getBasePath(path) {\n const p = path.lastIndexOf('/');\n return p >= 0 ? path.substring(0, p + 1) : '';\n};\n\n/**\n * Gets the full path of `file` relative to `basePath`\n * @param {string} file - The file name\n * @param {string} [path] - The base path\n * @returns {string}\n */\nexport function getRelativePath(file, path) {\n return (!path || path === '' || file.indexOf(path) !== 0) ? file : file.substring(path.length);\n};\n\n/**\n * Gets the complete path of a relative or absolute URL, using the provided `basePath`\n * @param {string} basePath - The base URL\n * @param {string} path - The filename\n * @returns {string}\n */\nexport function getPath(basePath, path) {\n return isURL(path) ? path : basePath + path;\n};\n\n/**\n * Gets a promise with the complete path of a relative or absolute URL, using the provided `basePath`\n * @param {string} basePath - The base URL\n * @param {string} path - The filename\n * @param {external:JSZip} [zip] - An optional {@link external:JSZip} object where to look\n * for the file\n * @returns {external:Promise}\n */\nexport function getPathPromise(basePath, path, zip) {\n if (zip) {\n const fName = getRelativePath(basePath + path, zip.zipBasePath);\n if (zip.files[fName]) {\n return new Promise((resolve, reject) => {\n zip.file(fName).async('base64').then(data => {\n const ext = path.toLowerCase().split('.').pop();\n const mime = settings.MIME_TYPES[ext] || 'application/octet-stream';\n resolve(`data:${mime};base64,${data}`);\n }).catch(reject);\n });\n }\n }\n return Promise.resolve(getPath(basePath, path));\n};\n\n/**\n * Utility object that provides several methods to build simple and complex DOM objects\n * @type {object}\n */\nexport const $HTML = {\n doubleCell: (a, b) => $('<tr/>').append($('<td/>').html(a)).append($('<td/>').html(b)),\n p: txt => $('<p/>').html(txt),\n td: (txt, className) => $('<td/>', className ? { class: className } : null).html(txt),\n th: (txt, className) => $('<th/>', className ? { class: className } : null).html(txt),\n};\n\n/**\n * Replaces `width`, `height` and `fill` attributes of a simple SVG image\n * with the provided values\n * @param {string} svg - The SVG image as XML string\n * @param {string} [width] - Optional setting for \"width\" property\n * @param {string} [height] - Optional setting for \"height\" property\n * @param {string} [fill] - Optional setting for \"fill\" property\n * @returns {string} - The resulting svg code\n */\nexport function getSvg(svg, width, height, fill) {\n if (width)\n svg = svg.replace(/width=\\\"\\d*\\\"/, `width=\"${width}\"`);\n if (height)\n svg = svg.replace(/height=\\\"\\d*\\\"/, `height=\"${height}\"`);\n if (fill)\n svg = svg.replace(/fill=\\\"[#A-Za-z0-9]*\\\"/, `fill=\"${fill}\"`);\n return svg;\n};\n\n/**\n * Encodes a svg expression into a {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs|data URI}\n * suitable for the `src` property of `img` elements, optionally changing its original size and fill values.\n * @param {string} svg - The SVG image as XML string\n * @param {string} [width] - Optional setting for \"width\" property\n * @param {string} [height] - Optional setting for \"height\" property\n * @param {string} [fill] - Optional setting for \"fill\" property\n * @returns {string} - The resulting Data URI\n */\nexport function svgToURI(svg, width, height, fill) {\n return 'data:image/svg+xml;base64,' + window.btoa(getSvg(svg, width, height, fill));\n};\n\n/**\n * Converts the given expression into a valid value for CSS size values\n * @param {string|number} exp - The expression to be evaluated. Can be a numeric value, `null` or `undefined`.\n * Positive values are in \"px\" units, negative ones are \"%\"\n * @param {object} css - An optional Object where the resulting expression (if any) will be saved\n * @param {string} key - The key under which the result will be stored in `css`\n * @param {string} def - Default value to be used when `exp` is `null` or `undefined`\n * @returns {string} - A valid CSS value, or `null` if it can't be found. Default units are `px`\n */\nexport function toCssSize(exp, css, key, def) {\n const result = typeof exp === 'undefined' || exp === null ? null : isNaN(exp) ? exp : exp < 0 ? `${Math.abs(exp)}%` : `${exp}px`;\n if (css && key && (result || def))\n css[key] = result !== null ? result : def;\n return result;\n};\n\n/**\n * Gets a clip of the give image data, in a URL base64 encoded format\n * @param {object} img - The binary data of the realized image, usually obtained from a {@link module:bads/MediaBagElement.MediaBagElement}\n * @param {module:AWT.Rectangle} rect - A rectangle containing the requested clip\n * @returns {string} - The URL with the image clip, as a PNG file encoded in base64\n */\nexport function getImgClipUrl(img, rect) {\n const canvas = document.createElement('canvas');\n canvas.width = rect.dim.width;\n canvas.height = rect.dim.height;\n const ctx = canvas.getContext('2d');\n let result = '';\n try {\n ctx.drawImage(img, rect.pos.x, rect.pos.y, rect.dim.width, rect.dim.height, 0, 0, rect.dim.width, rect.dim.height);\n result = canvas.toDataURL();\n } catch (err) {\n // catch 'tainted canvases may not be exported' and other errors\n log('error', err);\n }\n return result;\n};\n\n/**\n * Finds the nearest `head` or root node of a given HTMLElement, useful to place `<style/>` elements when\n * the main component of JClic is behind a shadow-root.\n * This method will be replaced by a call to [Node.getRootNode()](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)\n * when fully supported by all major browsers.\n * @param {external:HTMLElement} [el] - The element from which to start the search\n * @returns {external:HTMLElement}\n */\nexport function getRootHead(el) {\n if (el) {\n // Skip HTMLElements\n while (el.parentElement)\n el = el.parentElement;\n // Get the parent node of the last HTMLElement\n if (el instanceof HTMLElement)\n el = el.parentNode || el;\n // If the root node has a `head`, take it\n el = el['head'] || el;\n }\n return el || document.head;\n};\n\n/**\n * Appends a stylesheet element to the `head` or root node nearest to the given `HTMLElement`.\n * @param {string} css - The content of the stylesheet\n * @param {module:JClicPlayer.JClicPlayer} [ps] - An optional `PlayStation` (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used as a base to find the root node\n * @returns {external:HTMLStyleElement} - The appended style element\n */\nexport function appendStyleAtHead(css, ps) {\n const root = getRootHead(ps && ps.$topDiv ? ps.$topDiv[0] : null);\n const style = document.createElement('style');\n style.type = 'text/css';\n style.appendChild(document.createTextNode(css));\n return root.appendChild(style);\n};\n\n/**\n * Traverses all the attributes defined in an Element, calling a function with its name and value as a parameters\n * @param {external:NamedNodeMap} attributes - The [Element.attributes](https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes)\n * object to be traversed\n * @param {function} callback - The function to be called for each [Attr](https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap)\n * object. It should take two parametres: `name` and `value`\n */\nexport function attrForEach(attributes, callback) {\n for (let i = 0; i < attributes.length; i++)\n callback(attributes[i].name, attributes[i].value);\n};\n\n/**\n * Recursive traversal of all nodes of the given object looking for children having the `childName` attribute\n * WARNING: Don't call this method on objects with circular dependencies!\n * @param {object} obj - The object to be analized\n * @param {string} childName - Name of the attribute to search for\n * @returns {object[]} - Array of children having the searched attribute\n */\nexport function findParentsWithChild(obj, childName, _result = []) {\n if (obj[childName])\n _result.push(obj);\n else\n Object.values(obj).forEach(val => {\n if (typeof val === 'object')\n findParentsWithChild(val, childName, _result);\n });\n return _result;\n};\n\n//\n// Functions useful to deal with caret position in `contentEditable` DOM elements\n//\n/**\n * Gets the caret position within the given element. Thanks to\n * {@link http://stackoverflow.com/users/96100/tim-down|Tim Down} answers in:\n * {@link http://stackoverflow.com/questions/4811822/get-a-ranges-start-and-end-offsets-relative-to-its-parent-container}\n * and {@link http://stackoverflow.com/questions/6240139/highlight-text-range-using-javascript/6242538}\n * @param {object} element - A DOM element\n * @returns {number}\n */\nexport function getCaretCharacterOffsetWithin(element) {\n let caretOffset = 0;\n const doc = element.ownerDocument || element.document;\n const win = doc.defaultView || doc.parentWindow;\n let sel;\n if (typeof win.getSelection !== \"undefined\") {\n sel = win.getSelection();\n if (sel.rangeCount > 0) {\n const range = win.getSelection().getRangeAt(0);\n const preCaretRange = range.cloneRange();\n preCaretRange.selectNodeContents(element);\n preCaretRange.setEnd(range.endContainer, range.endOffset);\n caretOffset = preCaretRange.toString().length;\n }\n } else if ((sel = doc.selection) && sel.type !== \"Control\") {\n const textRange = sel.createRange();\n const preCaretTextRange = doc.body.createTextRange();\n preCaretTextRange.moveToElementText(element);\n preCaretTextRange.setEndPoint(\"EndToEnd\", textRange);\n caretOffset = preCaretTextRange.text.length;\n }\n return caretOffset;\n};\n\n/**\n * Utility function called by {@link module:Utils.getCaretCharacterOffsetWithin}\n * @param {object} node - A text node\n * @returns {object[]}\n */\nexport function getTextNodesIn(node) {\n const textNodes = [];\n if (node.nodeType === 3) {\n textNodes.push(node);\n } else {\n const children = node.childNodes;\n for (let i = 0, len = children.length; i < len; ++i) {\n textNodes.push.apply(textNodes, getTextNodesIn(children[i]));\n }\n }\n return textNodes;\n};\n\n/**\n * Sets the selection range (or the cursor position, when `start` and `end` are the same) to a\n * specific position inside a DOM element.\n * @param {object} el - The DOM element where to set the cursor\n * @param {number} start - The start position of the selection (or cursor position)\n * @param {number} end - The end position of the selection. When null or identical to `start`,\n * indicates a cursor position.\n */\nexport function setSelectionRange(el, start, end) {\n if (isNullOrUndef(end))\n end = start;\n if (document.createRange && window.getSelection) {\n const range = document.createRange();\n range.selectNodeContents(el);\n const textNodes = getTextNodesIn(el);\n let foundStart = false;\n let charCount = 0, endCharCount, textNode;\n\n for (let i = 0; i < textNodes.length; i++) {\n textNode = textNodes[i];\n endCharCount = charCount + textNode.length;\n if (!foundStart && start >= charCount &&\n (start < endCharCount ||\n start === endCharCount && i + 1 <= textNodes.length)) {\n range.setStart(textNode, start - charCount);\n foundStart = true;\n }\n if (foundStart && end <= endCharCount) {\n range.setEnd(textNode, end - charCount);\n break;\n }\n charCount = endCharCount;\n }\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n } else if (document.selection && document.body.createTextRange) {\n const textRange = document.body.createTextRange();\n textRange.moveToElementText(el);\n textRange.collapse(true);\n textRange.moveEnd('character', end);\n textRange.moveStart('character', start);\n textRange.select();\n }\n};\n\n/**\n * Performs multiple replacements on the provided string\n * See: https://stackoverflow.com/questions/2501435/replacing-multiple-patterns-in-a-block-of-data\n * @param {Object[]} replacements - Array of pairs formed by an \"expression\" (regexp or string) and a \"value\" (string) to replace the fragments found\n * @param {String} str - The string to be checked for replacements\n * @returns {String} - The original string with the fragments found already replaced\n */\nexport function mReplace(replacements, str) {\n return replacements.reduce((result, [exp, replacement]) => result.replace(exp, replacement), str);\n};\n\n/**\n * Global constants\n * @const\n */\nexport const settings = {\n // JClic.js Version\n VERSION: GlobalData.version,\n // Check if we are running on NodeJS with JSDOM\n NODEJS: typeof window === 'undefined' || window?.navigator?.userAgent?.includes('jsdom'),\n // layout constants\n AB: 0, BA: 1, AUB: 2, BUA: 3,\n LAYOUT_NAMES: ['AB', 'BA', 'AUB', 'BUA'],\n DEFAULT_WIDTH: 400,\n DEFAULT_HEIGHT: 300,\n MINIMUM_WIDTH: 40,\n MINIMUM_HEIGHT: 40,\n DEFAULT_NAME: '---',\n DEFAULT_MARGIN: 8,\n DEFAULT_SHUFFLES: 31,\n DEFAULT_GRID_ELEMENT_SIZE: 20,\n MIN_CELL_SIZE: 10,\n //DEFAULT_BG_COLOR: '#D3D3D3', // LightGray\n DEFAULT_BG_COLOR: '#C0C0C0', // LightGray\n ACTIONS: {\n ACTION_MATCH: 'MATCH', ACTION_PLACE: 'PLACE',\n ACTION_WRITE: 'WRITE', ACTION_SELECT: 'SELECT', ACTION_HELP: 'HELP'\n },\n PREVIOUS: 0, MAIN: 1, END: 2, END_ERROR: 3, NUM_MSG: 4,\n MSG_TYPE: ['previous', 'initial', 'final', 'finalError'],\n RANDOM_CHARS: \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",\n NUM_COUNTERS: 3,\n MAX_RECORD_LENGTH: 180,\n // BoxBase defaults\n BoxBase: {\n REDUCE_FONT_STEP: 1.0,\n MIN_FONT_SIZE: 8,\n STROKE: 1,\n AC_MARGIN: 6,\n //BACK_COLOR: 'lightgray',\n BACK_COLOR: '#C0C0C0',\n TEXT_COLOR: 'black',\n SHADOW_COLOR: 'gray',\n INACTIVE_COLOR: 'gray',\n ALTERNATIVE_COLOR: 'gray',\n BORDER_COLOR: 'black',\n BORDER_STROKE_WIDTH: 0.75,\n MARKER_STROKE_WIDTH: 2.75\n },\n FILE_TYPES: {\n image: 'gif,jpg,png,jpeg,bmp,ico,svg',\n audio: 'wav,mp3,ogg,oga,au,aiff,flac',\n video: 'avi,mov,mpeg,mp4,ogv,m4v,webm',\n font: 'ttf,otf,eot,woff,woff2',\n midi: 'mid,midi',\n anim: 'swf',\n // Used in custom skins\n xml: 'xml'\n },\n MIME_TYPES: {\n xml: 'text/xml',\n gif: 'image/gif',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n bmp: 'image/bmp',\n svg: 'image/svg+xml',\n ico: 'image/x-icon',\n wav: 'audio/wav',\n mp3: 'audio/mpeg',\n mp4: 'video/mp4',\n m4v: 'video/mp4',\n ogg: 'audio/ogg',\n oga: 'audio/ogg',\n ogv: 'video/ogg',\n webm: 'video/webm',\n au: 'audio/basic',\n aiff: 'audio/x-aiff',\n flac: 'audio/flac',\n avi: 'video/avi',\n mov: 'video/quicktime',\n mpeg: 'video/mpeg',\n ttf: 'application/font-sfnt',\n otf: 'application/font-sfnt',\n eot: ' application/vnd.ms-fontobject',\n woff: 'application/font-woff',\n woff2: 'application/font-woff2',\n swf: 'application/x-shockwave-flash',\n mid: 'audio/midi',\n midi: 'audio/midi'\n },\n // Global settings susceptible to be modified\n COMPRESS_IMAGES: true,\n // Keyboard key codes\n VK: {\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40\n },\n // Flag to indicate that we are running on a touch device\n TOUCH_DEVICE: false,\n // Amount of time (in milliseconds) to wait before a media resource is loaded\n LOAD_TIMEOUT: 10000,\n // Number of points to be calculated as polygon vertexs when simplifying bezier curves\n BEZIER_POINTS: 4,\n // Check if canvas accessibility features are enabled\n // See: http://codepen.io/francesc/pen/amwvRp\n // UPDATED May 2020: Detection removed since Canvas HitRegions have been deprecated\n // See: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\n //\n // CANVAS_HITREGIONS: typeof CanvasRenderingContext2D !== 'undefined' && typeof CanvasRenderingContext2D.prototype.addHitRegion === 'function',\n // CANVAS_HITREGIONS_FOCUS: typeof CanvasRenderingContext2D !== 'undefined' && typeof CanvasRenderingContext2D.prototype.drawFocusIfNeeded === 'function',\n //\n CANVAS_DRAW_FOCUS: typeof window !== 'undefined' && typeof window?.CanvasRenderingContext2D?.prototype?.drawFocusIfNeeded === 'function',\n // See: https://emptycharacter.com/\n // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes\n WHITESPACES: ' \\f\\n\\r\\t\\v\\u00a0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u2028\\u2029\\u202f\\u205f\\u3000\\ufeff',\n};\nsettings.SEPARATORS = `${settings.WHITESPACES}.,;-|`;\nsettings.WORD_DELIMITERS = `${settings.SEPARATORS}…_<>\"“”«»'\\xB4\\x60\\u2018\\u2019\\u2022~+\\u2013\\u2014\\u2015=%¿?¡!:/\\\\()[]{}$£€`;\n\n/**\n * Miscellaneous utility functions and constants\n */\nexport const Utils = {\n pkg,\n settings,\n getMsg,\n LOG_LEVELS,\n LOG_PRINT_LABELS,\n LOG_OPTIONS,\n init,\n setLogLevel,\n log,\n getBoolean,\n getVal,\n getNumber,\n getPercent,\n zp,\n getHMStime,\n getDateTime,\n parseOldDate,\n cleanOldLanguageTag,\n FALSE,\n TRUE,\n DEFAULT,\n getTriState,\n fillString,\n isNullOrUndef,\n isEquivalent,\n getXmlText,\n parseXmlNode,\n getXmlNodeText,\n reduceTextsToStrings,\n cssToString,\n checkColor,\n colorHasTransparency,\n cloneObject,\n normalizeObject,\n getAttr,\n getValue,\n isEmpty,\n setAttr,\n buildObj,\n isSeparator,\n isWordDelimiter,\n stringToWords,\n roundTo,\n fx,\n compareMultipleOptions,\n endsWith,\n startsWith,\n nSlash,\n isURL,\n getBasePath,\n getRelativePath,\n getPath,\n getPathPromise,\n $HTML,\n getSvg,\n svgToURI,\n toCssSize,\n getImgClipUrl,\n getRootHead,\n appendStyleAtHead,\n attrForEach,\n findParentsWithChild,\n getCaretCharacterOffsetWithin,\n getTextNodesIn,\n setSelectionRange\n};\n\nexport default Utils;\n"],"names":[],"sourceRoot":""}
@@ -1,103 +0,0 @@
1
- "use strict";
2
- exports.id = 13;
3
- exports.ids = [13];
4
- exports.modules = {
5
-
6
- /***/ 13:
7
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
-
9
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
11
- /* harmony export */ });
12
- /* unused harmony export EmptySkin */
13
- /* harmony import */ var _Skin_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(757);
14
- /* harmony import */ var _boxes_ActiveBox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1725);
15
- /**
16
- * File : skins/EmptySkin.js
17
- * Created : 14/03/2017
18
- * By : Francesc Busquets <francesc@gmail.com>
19
- *
20
- * JClic.js
21
- * An HTML5 player of JClic activities
22
- * https://projectestac.github.io/jclic.js
23
- *
24
- * @source https://github.com/projectestac/jclic.js
25
- *
26
- * @license EUPL-1.2
27
- * @licstart
28
- * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
29
- *
30
- * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
31
- * the European Commission- subsequent versions of the EUPL (the "Licence");
32
- * You may not use this work except in compliance with the Licence.
33
- *
34
- * You may obtain a copy of the Licence at:
35
- * https://joinup.ec.europa.eu/software/page/eupl
36
- *
37
- * Unless required by applicable law or agreed to in writing, software
38
- * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
39
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
40
- * Licence for the specific language governing permissions and limitations
41
- * under the Licence.
42
- * @licend
43
- * @module
44
- */
45
-
46
-
47
-
48
-
49
- /**
50
- * A minimalist {@link module:skins/Skin.Skin Skin} for JClic.js with just the player, without messages, counters nor any button.
51
- * @extends module:skins/Skin.Skin
52
- */
53
- class EmptySkin extends _Skin_js__WEBPACK_IMPORTED_MODULE_0__["default"] {
54
-
55
- /**
56
- * EmptySkin constructor
57
- *
58
- * @param {module:JClicPlayer.JClicPlayer} ps - The PlayStation (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used to load and
59
- * realize the media objects needed tot build the Skin.
60
- * @param {string} [name] - The skin class name
61
- * @param {object} [options] - Optional parameter with additional options
62
- */
63
- constructor(ps, name = null, options = {}) {
64
- // EmptySkin extends [Skin](Skin.html)
65
- super(ps, name, options);
66
- this.msgBox = new _boxes_ActiveBox_js__WEBPACK_IMPORTED_MODULE_1__["default"]();
67
- this.msgBox.role = 'message';
68
- }
69
- /**
70
- * Returns the CSS styles used by this skin. This method should be called only from
71
- * the `Skin` constructor, and overridded by subclasses if needed.
72
- * @param {string} media - A specific media size. Possible values are: 'default', 'half' and 'twoThirds'
73
- * @returns {string}
74
- */
75
- _getStyleSheets(media = 'default') {
76
- return super._getStyleSheets(media) + (media === 'default' ? this.mainCSS : '');
77
- }
78
- }
79
-
80
- Object.assign(EmptySkin.prototype, {
81
- /**
82
- * Class name of this skin. It will be used as a base selector in the definition of all CSS styles.
83
- * @name module:skins/EmptySkin.EmptySkin#skinId
84
- * @override
85
- * @type {string} */
86
- skinId: 'JClicEmptySkin',
87
- /**
88
- * Styles used in this skin
89
- * @name module:skins/EmptySkin.EmptySkin#skinCSS
90
- * @override
91
- * @type {string} */
92
- mainCSS: '.ID .JClicPlayerCnt {margin:0;}'
93
- });
94
-
95
- // Register this class in the list of available skins
96
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_Skin_js__WEBPACK_IMPORTED_MODULE_0__["default"].registerClass('empty', EmptySkin));
97
-
98
-
99
- /***/ })
100
-
101
- };
102
- ;
103
- //# sourceMappingURL=13.jclic-node.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"13.jclic-node.js","mappings":";;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAE6B;AACiB;;AAE9C;AACA,iBAAiB,mCAAmC;AACpD;AACA;AACO,wBAAwB,gDAAI;;AAEnC;AACA;AACA;AACA,aAAa,gCAAgC,mCAAmC,iDAAiD;AACjI;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA,2CAA2C;AAC3C;AACA;AACA,sBAAsB,2DAAS;AAC/B;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,iCAAiC,UAAU;AAC3C,CAAC;;AAED;AACA,iEAAe,gDAAI,kCAAkC,EAAC","sources":["webpack://jclic/./src/skins/EmptySkin.js"],"sourcesContent":["/**\n * File : skins/EmptySkin.js\n * Created : 14/03/2017\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\nimport Skin from './Skin.js';\nimport ActiveBox from '../boxes/ActiveBox.js';\n\n/**\n * A minimalist {@link module:skins/Skin.Skin Skin} for JClic.js with just the player, without messages, counters nor any button.\n * @extends module:skins/Skin.Skin\n */\nexport class EmptySkin extends Skin {\n\n /**\n * EmptySkin constructor\n *\n * @param {module:JClicPlayer.JClicPlayer} ps - The PlayStation (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used to load and\n * realize the media objects needed tot build the Skin.\n * @param {string} [name] - The skin class name\n * @param {object} [options] - Optional parameter with additional options\n */\n constructor(ps, name = null, options = {}) {\n // EmptySkin extends [Skin](Skin.html)\n super(ps, name, options);\n this.msgBox = new ActiveBox();\n this.msgBox.role = 'message';\n }\n /**\n * Returns the CSS styles used by this skin. This method should be called only from\n * the `Skin` constructor, and overridded by subclasses if needed.\n * @param {string} media - A specific media size. Possible values are: 'default', 'half' and 'twoThirds'\n * @returns {string}\n */\n _getStyleSheets(media = 'default') {\n return super._getStyleSheets(media) + (media === 'default' ? this.mainCSS : '');\n }\n}\n\nObject.assign(EmptySkin.prototype, {\n /**\n * Class name of this skin. It will be used as a base selector in the definition of all CSS styles.\n * @name module:skins/EmptySkin.EmptySkin#skinId\n * @override\n * @type {string} */\n skinId: 'JClicEmptySkin',\n /**\n * Styles used in this skin\n * @name module:skins/EmptySkin.EmptySkin#skinCSS\n * @override\n * @type {string} */\n mainCSS: '.ID .JClicPlayerCnt {margin:0;}'\n});\n\n// Register this class in the list of available skins\nexport default Skin.registerClass('empty', EmptySkin);\n"],"names":[],"sourceRoot":""}