j1-template 2024.3.16 → 2024.3.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (621) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/content_generator_collection.html +1 -1
  3. data/_includes/themes/j1/layouts/content_generator_news_panel_posts.html +1 -1
  4. data/_includes/themes/j1/layouts/content_generator_page.html +1 -1
  5. data/_includes/themes/j1/layouts/content_generator_post.html +1 -1
  6. data/_includes/themes/j1/layouts/content_generator_raw.html +1 -1
  7. data/_includes/themes/j1/layouts/layout_metadata_generator.html +1 -1
  8. data/_includes/themes/j1/layouts/layout_module_generator.html +1 -1
  9. data/_includes/themes/j1/layouts/layout_resource_generator.html +1 -1
  10. data/_includes/themes/j1/modules/attics/generator.html +1 -1
  11. data/_includes/themes/j1/modules/navigator/generator.html +1 -1
  12. data/_includes/themes/j1/modules/searcher/generator.html +1 -1
  13. data/_includes/themes/j1/modules/searcher/procedures/topsearch.proc +1 -1
  14. data/_includes/themes/j1/procedures/blocks/footer/boxes/about_box.proc +1 -1
  15. data/_includes/themes/j1/procedures/blocks/footer/boxes/contacts_box.proc +1 -1
  16. data/_includes/themes/j1/procedures/blocks/footer/boxes/issue.proc +1 -1
  17. data/_includes/themes/j1/procedures/blocks/footer/boxes/legal_statements.proc +1 -1
  18. data/_includes/themes/j1/procedures/blocks/footer/boxes/links_box.proc +1 -1
  19. data/_includes/themes/j1/procedures/blocks/footer/boxes/news_box.proc +1 -1
  20. data/_includes/themes/j1/procedures/blocks/footer/boxes/social_media_icons.proc +1 -1
  21. data/_includes/themes/j1/procedures/blocks/get_wave.proc +1 -1
  22. data/_includes/themes/j1/procedures/collections/create_collection_article_preview.proc +1 -1
  23. data/_includes/themes/j1/procedures/collections/pager.proc +1 -1
  24. data/_includes/themes/j1/procedures/global/attributes_loader.proc +1 -1
  25. data/_includes/themes/j1/procedures/global/collect_frontmatter_options.proc +1 -1
  26. data/_includes/themes/j1/procedures/global/collect_page_options.proc +1 -1
  27. data/_includes/themes/j1/procedures/global/create_bs_button.proc +1 -1
  28. data/_includes/themes/j1/procedures/global/create_word_cloud.proc +1 -1
  29. data/_includes/themes/j1/procedures/global/date-german.proc +1 -1
  30. data/_includes/themes/j1/procedures/global/get_category.proc +1 -1
  31. data/_includes/themes/j1/procedures/global/get_category_item.proc +1 -1
  32. data/_includes/themes/j1/procedures/global/get_documents_dir.proc +1 -1
  33. data/_includes/themes/j1/procedures/global/get_page_path.proc +1 -1
  34. data/_includes/themes/j1/procedures/global/get_page_url.proc +1 -1
  35. data/_includes/themes/j1/procedures/global/select_color.proc +1 -1
  36. data/_includes/themes/j1/procedures/global/select_font_size.proc +1 -1
  37. data/_includes/themes/j1/procedures/global/select_icon_size.proc +1 -1
  38. data/_includes/themes/j1/procedures/global/select_location.proc +1 -1
  39. data/_includes/themes/j1/procedures/global/set_base_vars_folders.proc +1 -1
  40. data/_includes/themes/j1/procedures/global/set_env_entry_document.proc +1 -1
  41. data/_includes/themes/j1/procedures/global/set_image_block.proc +1 -1
  42. data/_includes/themes/j1/procedures/global/setup.proc +1 -1
  43. data/_includes/themes/j1/procedures/layouts/content_writer.proc +1 -1
  44. data/_includes/themes/j1/procedures/layouts/default_writer.proc +1 -1
  45. data/_includes/themes/j1/procedures/layouts/module_writer.proc +1 -1
  46. data/_includes/themes/j1/procedures/layouts/resource_writer.proc +1 -1
  47. data/_includes/themes/j1/procedures/posts/collate_calendar.proc +1 -1
  48. data/_includes/themes/j1/procedures/posts/collate_list.proc +1 -1
  49. data/_includes/themes/j1/procedures/posts/collate_timeline.proc +1 -1
  50. data/_includes/themes/j1/procedures/posts/create_ad_block.proc +1 -1
  51. data/_includes/themes/j1/procedures/posts/create_series_header.proc +1 -1
  52. data/_includes/themes/j1/procedures/posts/pager.proc +1 -1
  53. data/_layouts/autopage_category.html +1 -1
  54. data/_layouts/autopage_collection.html +1 -1
  55. data/_layouts/autopage_collections_tags.html +1 -1
  56. data/_layouts/autopage_tags.html +1 -1
  57. data/_layouts/collection.html +1 -1
  58. data/_layouts/compress.html +1 -1
  59. data/_layouts/default.html +1 -1
  60. data/_layouts/home.html +1 -1
  61. data/_layouts/news_panel_posts.html +1 -1
  62. data/_layouts/page.html +1 -1
  63. data/_layouts/post.html +1 -1
  64. data/_layouts/raw.html +1 -1
  65. data/apps/public/cc/cc.yml +1 -1
  66. data/assets/data/amplitude.html +137 -66
  67. data/assets/data/authclient.html +1 -1
  68. data/assets/data/banner.html +2 -2
  69. data/assets/data/carousel.json +1 -1
  70. data/assets/data/cookieconsent.html +2 -2
  71. data/assets/data/docsearch.html +2 -2
  72. data/assets/data/fab.html +2 -2
  73. data/assets/data/footer.html +2 -2
  74. data/assets/data/galeries.html +2 -2
  75. data/assets/data/gallery_customizer.html +2 -2
  76. data/assets/data/gemini-ui.html +2 -2
  77. data/assets/data/iframes.html +2 -2
  78. data/assets/data/iso-3166-country-codes.json +1 -1
  79. data/assets/data/iso-639-language-codes.json +1 -1
  80. data/assets/data/j1_config.json +1 -1
  81. data/assets/data/masonry.html +2 -2
  82. data/assets/data/masterslider.html +2 -2
  83. data/assets/data/mdi_icons.json +1 -1
  84. data/assets/data/mdil_icons.json +1 -1
  85. data/assets/data/menu.html +2 -2
  86. data/assets/data/mmenu.html +2 -2
  87. data/assets/data/mmenu_sidebar.html +2 -2
  88. data/assets/data/mmenu_toc.html +2 -2
  89. data/assets/data/panel.html +2 -2
  90. data/assets/data/particles.yml +1 -1
  91. data/assets/data/private.json +1 -1
  92. data/assets/data/quicklinks.html +2 -2
  93. data/assets/data/rtext_resizer.html +2 -2
  94. data/assets/data/slick.html +2 -2
  95. data/assets/data/speak2me.html +2 -2
  96. data/assets/data/swiper.html +244 -0
  97. data/assets/data/swiper.json +84 -0
  98. data/assets/data/themes.bootswatch.json +1 -1
  99. data/assets/data/themes.json +1 -1
  100. data/assets/data/translator.html +1 -1
  101. data/assets/error_pages/HTTP204.html +1 -1
  102. data/assets/error_pages/HTTP400.html +1 -1
  103. data/assets/error_pages/HTTP401.html +1 -1
  104. data/assets/error_pages/HTTP403.html +1 -1
  105. data/assets/error_pages/HTTP404.html +1 -1
  106. data/assets/error_pages/HTTP444.html +1 -1
  107. data/assets/error_pages/HTTP445.html +1 -1
  108. data/assets/error_pages/HTTP446.html +1 -1
  109. data/assets/error_pages/HTTP447.html +1 -1
  110. data/assets/error_pages/HTTP448.html +1 -1
  111. data/assets/error_pages/HTTP500.html +1 -1
  112. data/assets/error_pages/HTTP501.html +1 -1
  113. data/assets/error_pages/HTTP502.html +1 -1
  114. data/assets/error_pages/HTTP503.html +1 -1
  115. data/assets/theme/j1/adapter/js/advertising.js +2 -2
  116. data/assets/theme/j1/adapter/js/algolia.js +2 -2
  117. data/assets/theme/j1/adapter/js/amplitude.30.js +1177 -0
  118. data/assets/theme/j1/adapter/js/amplitude.js +165 -132
  119. data/assets/theme/j1/adapter/js/analytics.js +2 -2
  120. data/assets/theme/j1/adapter/js/asciidoctor.js +2 -2
  121. data/assets/theme/j1/adapter/js/attic.js +2 -2
  122. data/assets/theme/j1/adapter/js/bmd.js +2 -2
  123. data/assets/theme/j1/adapter/js/carousel.js +2 -2
  124. data/assets/theme/j1/adapter/js/chatbot.js +2 -2
  125. data/assets/theme/j1/adapter/js/clipboard.js +2 -2
  126. data/assets/theme/j1/adapter/js/comments.js +2 -2
  127. data/assets/theme/j1/adapter/js/cookieConsent.js +2 -2
  128. data/assets/theme/j1/adapter/js/customFunctions.js +2 -2
  129. data/assets/theme/j1/adapter/js/customModule.js +2 -2
  130. data/assets/theme/j1/adapter/js/docsearch.js +2 -2
  131. data/assets/theme/j1/adapter/js/dropdowns.js +2 -2
  132. data/assets/theme/j1/adapter/js/fab.js +2 -2
  133. data/assets/theme/j1/adapter/js/gallery.js +2 -2
  134. data/assets/theme/j1/adapter/js/gemini.js +2 -2
  135. data/assets/theme/j1/adapter/js/iconPicker.js +2 -2
  136. data/assets/theme/j1/adapter/js/iconPickerPage.js +2 -2
  137. data/assets/theme/j1/adapter/js/iframer.js +2 -2
  138. data/assets/theme/j1/adapter/js/j1.js +5 -5
  139. data/assets/theme/j1/adapter/js/lazyLoader.js +2 -2
  140. data/assets/theme/j1/adapter/js/lightbox.js +2 -2
  141. data/assets/theme/j1/adapter/js/logger.js +2 -2
  142. data/assets/theme/j1/adapter/js/lunr.js +2 -2
  143. data/assets/theme/j1/adapter/js/masonry.js +2 -2
  144. data/assets/theme/j1/adapter/js/masterslider.js +4 -3
  145. data/assets/theme/j1/adapter/js/mmenu.js +2 -2
  146. data/assets/theme/j1/adapter/js/navigator.js +2 -2
  147. data/assets/theme/j1/adapter/js/particles.js +2 -2
  148. data/assets/theme/j1/adapter/js/rangeSlider.js +2 -2
  149. data/assets/theme/j1/adapter/js/rouge.js +2 -2
  150. data/assets/theme/j1/adapter/js/rtable.js +2 -2
  151. data/assets/theme/j1/adapter/js/rtextResizer.js +2 -2
  152. data/assets/theme/j1/adapter/js/scroller.js +2 -2
  153. data/assets/theme/j1/adapter/js/slick.js +2 -2
  154. data/assets/theme/j1/adapter/js/slimSelect.js +2 -2
  155. data/assets/theme/j1/adapter/js/speak2me.js +2 -2
  156. data/assets/theme/j1/adapter/js/swiper.js +503 -0
  157. data/assets/theme/j1/adapter/js/themeToggler.js +2 -2
  158. data/assets/theme/j1/adapter/js/themes.js +2 -2
  159. data/assets/theme/j1/adapter/js/toccer.js +2 -2
  160. data/assets/theme/j1/adapter/js/translator.js +2 -2
  161. data/assets/theme/j1/adapter/js/videojs.js +2 -2
  162. data/assets/theme/j1/adapter/js/waves.js +2 -2
  163. data/assets/theme/j1/core/country-flags/css/theme/uno.css +1 -1
  164. data/assets/theme/j1/core/country-flags/css/theme/uno.min.css +1 -1
  165. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.css +14 -4
  166. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/amplitude.min.css +2 -2
  167. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.css +1 -1
  168. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/compact.min.css +1 -1
  169. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.css +54 -7
  170. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/large.min.css +3 -2
  171. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/mini.css +1 -1
  172. data/assets/theme/j1/modules/amplitudejs/css/theme/uno/dark/player/mini.min.css +1 -1
  173. data/assets/theme/j1/modules/amplitudejs/js/amplitude.js +1 -1
  174. data/assets/theme/j1/modules/amplitudejs/js/amplitude.map +1 -1
  175. data/assets/theme/j1/modules/amplitudejs/js/amplitude.min.js +1 -1
  176. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.js +1621 -90
  177. data/assets/theme/j1/modules/amplitudejs/js/tech/ytp.min.js +14 -0
  178. data/assets/theme/j1/modules/amplitudejs/js/visualizations/bar.js +2 -2
  179. data/assets/theme/j1/modules/amplitudejs/js/visualizations/bar.min.js +1 -1
  180. data/assets/theme/j1/modules/amplitudejs/js/visualizations/circular-equalizer.js +32 -2
  181. data/assets/theme/j1/modules/amplitudejs/js/visualizations/circular-equalizer.min.js +1 -1
  182. data/assets/theme/j1/modules/amplitudejs/js/visualizations/frequency-analyzer.js +2 -2
  183. data/assets/theme/j1/modules/amplitudejs/js/visualizations/frequency-analyzer.min.js +1 -1
  184. data/assets/theme/j1/modules/amplitudejs/js/visualizations/michael-bromley.js +2 -2
  185. data/assets/theme/j1/modules/amplitudejs/js/visualizations/michael-bromley.min.js +1 -1
  186. data/assets/theme/j1/modules/amplitudejs/js/visualizations/template.js +2 -2
  187. data/assets/theme/j1/modules/amplitudejs/js/visualizations/template.min.js +1 -1
  188. data/assets/theme/j1/modules/amplitudejs/scss/theme/uno/dark/amplitude.scss +1 -1
  189. data/assets/theme/j1/modules/amplitudejs/scss/theme/uno/dark/player/compact.scss +1 -1
  190. data/assets/theme/j1/modules/amplitudejs/scss/theme/uno/dark/player/large.scss +1 -1
  191. data/assets/theme/j1/modules/amplitudejs/scss/theme/uno/dark/player/mini.scss +1 -1
  192. data/assets/theme/j1/modules/backstretch/js/backstretch.js +1 -1
  193. data/assets/theme/j1/modules/backstretch/js/backstretch.min.js +1 -1
  194. data/assets/theme/j1/modules/bmd/js/bmd.js +1 -1
  195. data/assets/theme/j1/modules/bmd/js/bmd.min.js +1 -1
  196. data/assets/theme/j1/modules/carousel/css/carousel.css +1 -1
  197. data/assets/theme/j1/modules/carousel/css/carousel.min.css +1 -1
  198. data/assets/theme/j1/modules/carousel/css/carousel_transitions.css +1 -1
  199. data/assets/theme/j1/modules/carousel/css/carousel_transitions.min.css +1 -1
  200. data/assets/theme/j1/modules/carousel/css/theme/uno.css +1 -1
  201. data/assets/theme/j1/modules/carousel/css/theme/uno.min.css +1 -1
  202. data/assets/theme/j1/modules/chatbot/css/theme/uno.css +1 -1
  203. data/assets/theme/j1/modules/chatbot/css/theme/uno.min.css +1 -1
  204. data/assets/theme/j1/modules/clipboard/css/theme/uno.css +1 -1
  205. data/assets/theme/j1/modules/clipboard/css/theme/uno.min.css +1 -1
  206. data/assets/theme/j1/modules/cookieConsent/js/cookieConsent.js +1 -1
  207. data/assets/theme/j1/modules/cookieConsent/js/cookieConsent.min.js +1 -1
  208. data/assets/theme/j1/modules/dropdowns/css/theme/uno/dropdowns.css +1 -1
  209. data/assets/theme/j1/modules/dropdowns/css/theme/uno/dropdowns.min.css +1 -1
  210. data/assets/theme/j1/modules/dropdowns/js/cash.js +1 -1
  211. data/assets/theme/j1/modules/dropdowns/js/cash.min.js +1 -1
  212. data/assets/theme/j1/modules/dropdowns/js/dropdowns.js +1 -1
  213. data/assets/theme/j1/modules/dropdowns/js/dropdowns.min.js +1 -1
  214. data/assets/theme/j1/modules/fab/js/cash.js +1 -1
  215. data/assets/theme/j1/modules/fab/js/cash.min.js +1 -1
  216. data/assets/theme/j1/modules/fab/js/fab.js +1 -1
  217. data/assets/theme/j1/modules/fab/js/fab.min.js +1 -1
  218. data/assets/theme/j1/modules/gemini/css/theme/uno.css +1 -1
  219. data/assets/theme/j1/modules/gemini/css/theme/uno.min.css +1 -1
  220. data/assets/theme/j1/modules/gemini/js/gemini.js +1 -1
  221. data/assets/theme/j1/modules/gemini/js/gemini.min.js +1 -1
  222. data/assets/theme/j1/modules/iconPicker/css/theme/uno.css +1 -1
  223. data/assets/theme/j1/modules/iconPicker/css/theme/uno.min.css +1 -1
  224. data/assets/theme/j1/modules/iconPicker/css/universal-icon-picker.css +1 -1
  225. data/assets/theme/j1/modules/iconPicker/css/universal-icon-picker.min.css +1 -1
  226. data/assets/theme/j1/modules/iconPicker/js/universal-icon-picker.js +1 -1
  227. data/assets/theme/j1/modules/iconPicker/js/universal-icon-picker.min.js +1 -1
  228. data/assets/theme/j1/modules/j1LazyLoader/LICENSE +1 -1
  229. data/assets/theme/j1/modules/jquery/js/extensions/hasClass.js +1 -1
  230. data/assets/theme/j1/modules/jquery/js/extensions/hasClass.min.js +1 -1
  231. data/assets/theme/j1/modules/jquery/js/extensions/removeClass.js +1 -1
  232. data/assets/theme/j1/modules/jquery/js/extensions/removeClass.min.js +1 -1
  233. data/assets/theme/j1/modules/justifiedGallery/css/justifiedGallery.css +1 -1
  234. data/assets/theme/j1/modules/justifiedGallery/css/justifiedGallery.min.css +1 -1
  235. data/assets/theme/j1/modules/justifiedGallery/css/theme/uno.css +1 -1
  236. data/assets/theme/j1/modules/justifiedGallery/css/theme/uno.min.css +1 -1
  237. data/assets/theme/j1/modules/lazyCssLoader/js/main.0.js +1 -1
  238. data/assets/theme/j1/modules/lazyCssLoader/js/main.1.js +1 -1
  239. data/assets/theme/j1/modules/lazyCssLoader/js/main.js +1 -1
  240. data/assets/theme/j1/modules/lightGallery/css/lg-transitions.css +1 -1
  241. data/assets/theme/j1/modules/lightGallery/css/lg-transitions.min.css +1 -1
  242. data/assets/theme/j1/modules/lightGallery/css/lightgallery-bundle.css +1 -1
  243. data/assets/theme/j1/modules/lightGallery/css/lightgallery-bundle.min.css +1 -1
  244. data/assets/theme/j1/modules/lightGallery/css/themes/uno/uno.css +1 -1
  245. data/assets/theme/j1/modules/lightGallery/css/themes/uno/uno.min.css +1 -1
  246. data/assets/theme/j1/modules/lightGallery/js/lightgallery.js +1 -1
  247. data/assets/theme/j1/modules/lightGallery/js/lightgallery.min.js +1 -1
  248. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/j1-video.js +1 -1
  249. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/j1-video.min.js +1 -1
  250. data/assets/theme/j1/modules/lightGallery/js/plugins/j1/lg-video.1.js +1 -1
  251. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-autoplay.js +1 -1
  252. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-autoplay.min.js +1 -1
  253. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-comment.js +1 -1
  254. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-comment.min.js +1 -1
  255. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-fullscreen.js +1 -1
  256. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-fullscreen.min.js +1 -1
  257. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-hash.js +1 -1
  258. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-hash.min.js +1 -1
  259. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-medium-zoom.js +1 -1
  260. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-medium-zoom.min.js +1 -1
  261. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-pager.js +1 -1
  262. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-pager.min.js +1 -1
  263. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-rotate.js +1 -1
  264. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-rotate.min.js +1 -1
  265. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-share.js +1 -1
  266. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-share.min.js +1 -1
  267. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-thumbnail.js +1 -1
  268. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-thumbnail.min.js +1 -1
  269. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.js +1 -1
  270. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-video.min.js +1 -1
  271. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-vimeo-thumbnail.js +1 -1
  272. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-vimeo-thumbnail.min.js +1 -1
  273. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-zoom.js +1 -1
  274. data/assets/theme/j1/modules/lightGallery/js/plugins/lg-zoom.min.js +1 -1
  275. data/assets/theme/j1/modules/lightbox/css/lightbox.css +1 -1
  276. data/assets/theme/j1/modules/lightbox/css/lightbox.min.css +1 -1
  277. data/assets/theme/j1/modules/lightbox/css/theme/uno.css +1 -1
  278. data/assets/theme/j1/modules/lightbox/css/theme/uno.min.css +1 -1
  279. data/assets/theme/j1/modules/lightbox/js/lightbox.js +1 -1
  280. data/assets/theme/j1/modules/lightbox/js/lightbox.min.js +1 -1
  281. data/assets/theme/j1/modules/lunr/css/theme/uno.css +1 -1
  282. data/assets/theme/j1/modules/lunr/css/theme/uno.min.css +1 -1
  283. data/assets/theme/j1/modules/lunr/js/j1.js +1 -1
  284. data/assets/theme/j1/modules/lunr/js/j1.min.js +1 -1
  285. data/assets/theme/j1/modules/masterslider/css/theme/uno.css +1 -1
  286. data/assets/theme/j1/modules/masterslider/css/theme/uno.min.css +1 -1
  287. data/assets/theme/j1/modules/mmenuLight/css/mmenu-light.css +1 -1
  288. data/assets/theme/j1/modules/mmenuLight/css/mmenu-light.min.css +1 -1
  289. data/assets/theme/j1/modules/mmenuLight/css/theme/uno/mmenu.css +1 -1
  290. data/assets/theme/j1/modules/mmenuLight/css/theme/uno/mmenu.min.css +1 -1
  291. data/assets/theme/j1/modules/mmenuLight/js/mmenu.js +1 -1
  292. data/assets/theme/j1/modules/mmenuLight/js/mmenu.min.js +1 -1
  293. data/assets/theme/j1/modules/msDropdown/css/flags.css +1 -1
  294. data/assets/theme/j1/modules/msDropdown/css/flags.min.css +1 -1
  295. data/assets/theme/j1/modules/msDropdown/css/msDropdown.css +1 -1
  296. data/assets/theme/j1/modules/msDropdown/css/msDropdown.min.css +1 -1
  297. data/assets/theme/j1/modules/msDropdown/css/themes/uno/msDropdown.css +1 -1
  298. data/assets/theme/j1/modules/msDropdown/css/themes/uno/msDropdown.min.css +1 -1
  299. data/assets/theme/j1/modules/msDropdown/js/msDropdown.js +1 -1
  300. data/assets/theme/j1/modules/msDropdown/js/msDropdown.min.js +1 -1
  301. data/assets/theme/j1/modules/photoswipe/LICENSE +21 -0
  302. data/assets/theme/j1/modules/photoswipe/README.md +32 -0
  303. data/assets/theme/j1/modules/photoswipe/_info/.version_5.4.4 +6 -0
  304. data/assets/theme/j1/modules/photoswipe/_info/example/photoswipe-caption-plugin.html +237 -0
  305. data/assets/theme/j1/modules/photoswipe/_info/example/test-gallery.html +36 -0
  306. data/assets/theme/j1/modules/photoswipe/css/photoswipe-caption-plugin.css +69 -0
  307. data/assets/theme/j1/modules/photoswipe/css/photoswipe-caption-plugin.min.css +16 -0
  308. data/assets/theme/j1/modules/photoswipe/css/photoswipe.css +376 -0
  309. data/assets/theme/j1/modules/photoswipe/css/photoswipe.min.css +17 -0
  310. data/assets/theme/j1/modules/photoswipe/js/_info/README.md +43 -0
  311. data/assets/theme/j1/modules/photoswipe/js/photoswipe-caption-plugin.js +428 -0
  312. data/assets/theme/j1/modules/photoswipe/js/photoswipe-caption-plugin.min.js +18 -0
  313. data/assets/theme/j1/modules/photoswipe/js/photoswipe-core.js +7102 -0
  314. data/assets/theme/j1/modules/photoswipe/js/photoswipe-core.min.js +18 -0
  315. data/assets/theme/j1/modules/photoswipe/js/photoswipe-lightbox.1.js +1990 -0
  316. data/assets/theme/j1/modules/photoswipe/js/photoswipe-lightbox.js +1981 -0
  317. data/assets/theme/j1/modules/photoswipe/js/photoswipe-lightbox.min.js +18 -0
  318. data/assets/theme/j1/modules/rangeSlider/css/theme/uno/nouislider.css +1 -1
  319. data/assets/theme/j1/modules/rangeSlider/css/theme/uno/nouislider.min.css +1 -1
  320. data/assets/theme/j1/modules/rouge/css/base16/theme.css +1 -1
  321. data/assets/theme/j1/modules/rouge/css/base16/theme.min.css +1 -1
  322. data/assets/theme/j1/modules/rouge/css/base16.dark/theme.css +1 -1
  323. data/assets/theme/j1/modules/rouge/css/base16.dark/theme.min.css +1 -1
  324. data/assets/theme/j1/modules/rouge/css/base16.light/theme.css +1 -1
  325. data/assets/theme/j1/modules/rouge/css/base16.light/theme.min.css +1 -1
  326. data/assets/theme/j1/modules/rouge/css/base16.monokai/theme.css +1 -1
  327. data/assets/theme/j1/modules/rouge/css/base16.monokai/theme.min.css +1 -1
  328. data/assets/theme/j1/modules/rouge/css/base16.monokai.dark/theme.css +1 -1
  329. data/assets/theme/j1/modules/rouge/css/base16.monokai.dark/theme.min.css +1 -1
  330. data/assets/theme/j1/modules/rouge/css/base16.monokai.light/theme.css +1 -1
  331. data/assets/theme/j1/modules/rouge/css/base16.monokai.light/theme.min.css +1 -1
  332. data/assets/theme/j1/modules/rouge/css/base16.solarized/theme.css +1 -1
  333. data/assets/theme/j1/modules/rouge/css/base16.solarized/theme.min.css +1 -1
  334. data/assets/theme/j1/modules/rouge/css/base16.solarized.dark/theme.css +1 -1
  335. data/assets/theme/j1/modules/rouge/css/base16.solarized.dark/theme.min.css +1 -1
  336. data/assets/theme/j1/modules/rouge/css/base16.solarized.light/theme.css +1 -1
  337. data/assets/theme/j1/modules/rouge/css/base16.solarized.light/theme.min.css +1 -1
  338. data/assets/theme/j1/modules/rouge/css/colorful/theme.css +1 -1
  339. data/assets/theme/j1/modules/rouge/css/colorful/theme.min.css +1 -1
  340. data/assets/theme/j1/modules/rouge/css/github/theme.css +1 -1
  341. data/assets/theme/j1/modules/rouge/css/github/theme.min.css +1 -1
  342. data/assets/theme/j1/modules/rouge/css/gruvbox/theme.css +1 -1
  343. data/assets/theme/j1/modules/rouge/css/gruvbox/theme.min.css +1 -1
  344. data/assets/theme/j1/modules/rouge/css/gruvbox.dark/theme.css +1 -1
  345. data/assets/theme/j1/modules/rouge/css/gruvbox.dark/theme.min.css +1 -1
  346. data/assets/theme/j1/modules/rouge/css/gruvbox.light/theme.css +1 -1
  347. data/assets/theme/j1/modules/rouge/css/gruvbox.light/theme.min.css +1 -1
  348. data/assets/theme/j1/modules/rouge/css/igorpro/theme.css +1 -1
  349. data/assets/theme/j1/modules/rouge/css/igorpro/theme.min.css +1 -1
  350. data/assets/theme/j1/modules/rouge/css/molokai/theme.css +1 -1
  351. data/assets/theme/j1/modules/rouge/css/molokai/theme.min.css +1 -1
  352. data/assets/theme/j1/modules/rouge/css/monokai/theme.css +1 -1
  353. data/assets/theme/j1/modules/rouge/css/monokai/theme.min.css +1 -1
  354. data/assets/theme/j1/modules/rouge/css/monokai.sublime/theme.css +1 -1
  355. data/assets/theme/j1/modules/rouge/css/monokai.sublime/theme.min.css +1 -1
  356. data/assets/theme/j1/modules/rouge/css/pastie/theme.css +1 -1
  357. data/assets/theme/j1/modules/rouge/css/pastie/theme.min.css +1 -1
  358. data/assets/theme/j1/modules/rouge/css/thankful_eyes/theme.css +1 -1
  359. data/assets/theme/j1/modules/rouge/css/thankful_eyes/theme.min.css +1 -1
  360. data/assets/theme/j1/modules/rouge/css/themes.txt +1 -1
  361. data/assets/theme/j1/modules/rouge/css/tulip/theme.css +1 -1
  362. data/assets/theme/j1/modules/rouge/css/tulip/theme.min.css +1 -1
  363. data/assets/theme/j1/modules/rouge/css/uno.dark/theme.css +1 -1
  364. data/assets/theme/j1/modules/rouge/css/uno.dark/theme.min.css +1 -1
  365. data/assets/theme/j1/modules/rouge/css/uno.light/theme.css +1 -1
  366. data/assets/theme/j1/modules/rouge/css/uno.light/theme.min.css +1 -1
  367. data/assets/theme/j1/modules/rouge/js/select.js +1 -1
  368. data/assets/theme/j1/modules/rtable/css/theme/uno/rtable.css +1 -1
  369. data/assets/theme/j1/modules/rtable/css/theme/uno/rtable.min.css +1 -1
  370. data/assets/theme/j1/modules/rtable/js/rtable.js +1 -1
  371. data/assets/theme/j1/modules/rtable/js/rtable.min.js +1 -1
  372. data/assets/theme/j1/modules/scroller/css/theme/uno.css +1 -1
  373. data/assets/theme/j1/modules/scroller/css/theme/uno.min.css +1 -1
  374. data/assets/theme/j1/modules/scroller/js/scroller.min.js +1 -1
  375. data/assets/theme/j1/modules/slick/lightbox/css/theme/uno.css +1 -1
  376. data/assets/theme/j1/modules/slick/lightbox/css/theme/uno.min.css +1 -1
  377. data/assets/theme/j1/modules/slick/slider/css/theme/uno.css +1 -1
  378. data/assets/theme/j1/modules/slick/slider/css/theme/uno.min.css +1 -1
  379. data/assets/theme/j1/modules/spinner/css/spin.css +1 -1
  380. data/assets/theme/j1/modules/spinner/css/spin.min.css +1 -1
  381. data/assets/theme/j1/modules/spinner/js/spin.js +1 -1
  382. data/assets/theme/j1/modules/spinner/js/spin.min.js +1 -1
  383. data/assets/theme/j1/modules/swiper/LICENSE +20 -0
  384. data/assets/theme/j1/modules/swiper/README.md +95 -0
  385. data/assets/theme/j1/modules/swiper/_info/.version_1.2.0 +15 -0
  386. data/assets/theme/j1/modules/swiper/_info/swiperjs.com-demos.url +2 -0
  387. data/assets/theme/j1/modules/swiper/css/modules/effectNeighbor.css +53 -0
  388. data/assets/theme/j1/modules/swiper/css/modules/effectNeighbor.min.css +17 -0
  389. data/assets/theme/j1/modules/swiper/css/modules/effectPanorama.css +26 -0
  390. data/assets/theme/j1/modules/swiper/css/modules/effectPanorama.min.css +17 -0
  391. data/assets/theme/j1/modules/swiper/css/modules/effectThumbs.css +44 -0
  392. data/assets/theme/j1/modules/swiper/css/modules/effectThumbs.min.css +44 -0
  393. data/assets/theme/j1/modules/swiper/css/swiper-bundle.css +746 -0
  394. data/assets/theme/j1/modules/swiper/css/swiper-bundle.min..css +23 -0
  395. data/assets/theme/j1/modules/swiper/css/theme/uno.css +229 -0
  396. data/assets/theme/j1/modules/swiper/css/theme/uno.min.css +144 -0
  397. data/assets/theme/j1/modules/swiper/js/modules/!readme +3 -0
  398. data/assets/theme/j1/modules/swiper/js/modules/effectNeighbor.js +33 -0
  399. data/assets/theme/j1/modules/swiper/js/modules/effectNeighbor.min.js +33 -0
  400. data/assets/theme/j1/modules/swiper/js/modules/effectPanorama.js +93 -0
  401. data/assets/theme/j1/modules/swiper/js/modules/effectPanorama.min.js +17 -0
  402. data/assets/theme/j1/modules/swiper/js/modules/effectThumbs.js +113 -0
  403. data/assets/theme/j1/modules/swiper/js/modules/effectThumbs.min.js +33 -0
  404. data/assets/theme/j1/modules/swiper/js/swiper-bundle.js +9791 -0
  405. data/assets/theme/j1/modules/swiper/js/swiper-bundle.min.js +23 -0
  406. data/assets/theme/j1/modules/themeSwitcher/js/switcher.js +1 -1
  407. data/assets/theme/j1/modules/themeSwitcher/js/switcher.min.js +1 -1
  408. data/assets/theme/j1/modules/translator/css/translator.css +1 -1
  409. data/assets/theme/j1/modules/translator/css/translator.min.css +1 -1
  410. data/assets/theme/j1/modules/translator/js/translator.js +1 -1
  411. data/assets/theme/j1/modules/translator/js/translator.min.js +1 -1
  412. data/assets/theme/j1/modules/videoPlayer/vimeo/js/player.min.js +1 -1
  413. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.0.css +1 -1
  414. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.1.css +1 -1
  415. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.css +1 -1
  416. data/assets/theme/j1/modules/videojs/css/plugins/controls/skipbuttons.min.css +1 -1
  417. data/assets/theme/j1/modules/videojs/css/plugins/controls/zoom.css +1 -1
  418. data/assets/theme/j1/modules/videojs/css/plugins/controls/zoom.min.css +1 -1
  419. data/assets/theme/j1/modules/videojs/css/themes/uno.css +1 -1
  420. data/assets/theme/j1/modules/videojs/css/themes/uno.min.css +1 -1
  421. data/assets/theme/j1/modules/videojs/js/plugins/controls/autocaption/autocaption.js +1 -1
  422. data/assets/theme/j1/modules/videojs/js/plugins/controls/autocaption/autocaption.min.js +1 -1
  423. data/assets/theme/j1/modules/videojs/js/plugins/controls/hotkeys/hotkeys.js +1 -1
  424. data/assets/theme/j1/modules/videojs/js/plugins/controls/hotkeys/hotkeys.min.js +1 -1
  425. data/assets/theme/j1/modules/videojs/js/plugins/controls/skipbuttons/skipbuttons.js +1 -1
  426. data/assets/theme/j1/modules/videojs/js/plugins/controls/skipbuttons/skipbuttons.min.js +1 -1
  427. data/assets/theme/j1/modules/videojs/js/plugins/controls/zoom/zoom.js +1 -1
  428. data/assets/theme/j1/modules/videojs/js/plugins/controls/zoom/zoom.min.js +1 -1
  429. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/api/dailymotion.sdk.js +1 -1
  430. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/api/dailymotion.sdk.min.js +1 -1
  431. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/dailymotion.js +1 -1
  432. data/assets/theme/j1/modules/videojs/js/plugins/players/dm/dailymotion.min.js +1 -1
  433. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/api/vimeo.js +1 -1
  434. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/api/vimeo.min.js +1 -1
  435. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/vimeo.js +1 -1
  436. data/assets/theme/j1/modules/videojs/js/plugins/players/vm/vimeo.min.js +1 -1
  437. data/assets/theme/j1/modules/videojs/js/plugins/players/wt/wistia.js +1 -1
  438. data/assets/theme/j1/modules/videojs/js/plugins/players/wt/wistia.min.js +1 -1
  439. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/api/youtube.min.js +1 -1
  440. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/v3.0.0/youtube.js +1 -1
  441. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/v3.0.0/youtube.min.js +1 -1
  442. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.js +1 -1
  443. data/assets/theme/j1/modules/videojs/js/plugins/players/yt/youtube.min.js +1 -1
  444. data/lib/j1/version.rb +1 -1
  445. data/lib/starter_web/Gemfile +1 -1
  446. data/lib/starter_web/README.md +5 -5
  447. data/lib/starter_web/_config.yml +2 -2
  448. data/lib/starter_web/_data/j1_config.yml +1 -1
  449. data/lib/starter_web/_data/modules/amplitude_players.yml +352 -0
  450. data/lib/starter_web/_data/modules/{amplitude.yml → amplitude_playlists.yml} +257 -239
  451. data/lib/starter_web/_data/modules/authentication.yml +1 -1
  452. data/lib/starter_web/_data/modules/defaults/amplitude.yml +60 -35
  453. data/lib/starter_web/_data/modules/defaults/slick.yml +1 -1
  454. data/lib/starter_web/_data/modules/defaults/swiper.yml +175 -0
  455. data/lib/starter_web/_data/modules/log4javascript.yml +1 -1
  456. data/lib/starter_web/_data/modules/navigator.yml +1 -1
  457. data/lib/starter_web/_data/modules/navigator_menu.yml +1 -1
  458. data/lib/starter_web/_data/modules/swiper.yml +655 -0
  459. data/lib/starter_web/_data/modules/swiper_playlists.yml +480 -0
  460. data/lib/starter_web/_data/private.yml +1 -1
  461. data/lib/starter_web/_data/resources.yml +272 -158
  462. data/lib/starter_web/_data/templates/feed.xml +1 -1
  463. data/lib/starter_web/_includes/custom/static/bs5_accordion.html +1 -1
  464. data/lib/starter_web/_includes/custom/templates/bs5_accordion.html +1 -1
  465. data/lib/starter_web/_includes/custom/templates/collection_panel.html +1 -1
  466. data/lib/starter_web/_includes/custom/templates/custom_header.html +1 -1
  467. data/lib/starter_web/_includes/custom/templates/people_panel.html +1 -1
  468. data/lib/starter_web/_includes/google/static/google_ad__your-slot-id.html +1 -1
  469. data/lib/starter_web/_includes/google/templates/google_ads.html +1 -1
  470. data/lib/starter_web/_plugins/asciidoctor/admonition-block-answer.rb +1 -1
  471. data/lib/starter_web/_plugins/asciidoctor/admonition-block-question.rb +1 -1
  472. data/lib/starter_web/_plugins/asciidoctor/amplitude-block.rb +2 -1
  473. data/lib/starter_web/_plugins/asciidoctor/banner.rb +1 -1
  474. data/lib/starter_web/_plugins/asciidoctor/callout.rb +1 -1
  475. data/lib/starter_web/_plugins/asciidoctor/carousel-block.rb +1 -1
  476. data/lib/starter_web/_plugins/asciidoctor/conum.rb +1 -1
  477. data/lib/starter_web/_plugins/asciidoctor/dailymotion-block.rb +1 -1
  478. data/lib/starter_web/_plugins/asciidoctor/fab-icon-inline.rb +1 -1
  479. data/lib/starter_web/_plugins/asciidoctor/fas-icon-inline.rb +1 -1
  480. data/lib/starter_web/_plugins/asciidoctor/flag-icon-inline.rb +1 -1
  481. data/lib/starter_web/_plugins/asciidoctor/gallery-block.rb +1 -1
  482. data/lib/starter_web/_plugins/asciidoctor/gemini-ui-block.rb +1 -1
  483. data/lib/starter_web/_plugins/asciidoctor/gist-block.rb +1 -1
  484. data/lib/starter_web/_plugins/asciidoctor/google-ad-block.rb +1 -1
  485. data/lib/starter_web/_plugins/asciidoctor/iconify-icon-inline.rb +1 -1
  486. data/lib/starter_web/_plugins/asciidoctor/iframe-block.rb +1 -1
  487. data/lib/starter_web/_plugins/asciidoctor/lightbox-block.rb +1 -1
  488. data/lib/starter_web/_plugins/asciidoctor/lorem_inline.rb +1 -1
  489. data/lib/starter_web/_plugins/asciidoctor/masonry-block.rb +1 -1
  490. data/lib/starter_web/_plugins/asciidoctor/masterslider-block.rb +1 -1
  491. data/lib/starter_web/_plugins/asciidoctor/mdi-icon-inline.rb +1 -1
  492. data/lib/starter_web/_plugins/asciidoctor/mdib-icon-inline.rb +1 -1
  493. data/lib/starter_web/_plugins/asciidoctor/mdil-icon-inline.rb +1 -1
  494. data/lib/starter_web/_plugins/asciidoctor/panel.rb +1 -1
  495. data/lib/starter_web/_plugins/asciidoctor/placeholder-inline.rb +1 -1
  496. data/lib/starter_web/_plugins/asciidoctor/range-slider-block.rb +1 -1
  497. data/lib/starter_web/_plugins/asciidoctor/shout-block.rb +1 -1
  498. data/lib/starter_web/_plugins/asciidoctor/slick-block.rb +1 -1
  499. data/lib/starter_web/_plugins/asciidoctor/slim-select-block.rb +1 -1
  500. data/lib/starter_web/_plugins/asciidoctor/swiper-block.rb +55 -0
  501. data/lib/starter_web/_plugins/asciidoctor/textbook-block.rb +1 -1
  502. data/lib/starter_web/_plugins/asciidoctor/twitter-emoji-inline.rb +1 -1
  503. data/lib/starter_web/_plugins/asciidoctor/videojs-block.rb +1 -5
  504. data/lib/starter_web/_plugins/asciidoctor/vimeo-block.rb +1 -1
  505. data/lib/starter_web/_plugins/asciidoctor/wistia-block.rb +1 -1
  506. data/lib/starter_web/_plugins/asciidoctor/youtube-block.rb +1 -1
  507. data/lib/starter_web/_plugins/filter/debug.rb +1 -1
  508. data/lib/starter_web/_plugins/filter/encodeBase64.rb +1 -1
  509. data/lib/starter_web/_plugins/filter/encryptAES.rb +1 -1
  510. data/lib/starter_web/_plugins/filter/filters.rb +32 -1
  511. data/lib/starter_web/_plugins/filter/liquify.rb +1 -1
  512. data/lib/starter_web/_plugins/filter/minifyJS.rb +1 -1
  513. data/lib/starter_web/_plugins/filter/minifyJSON.rb +1 -1
  514. data/lib/starter_web/_plugins/filter/prettify.rb +1 -1
  515. data/lib/starter_web/_plugins/filter/xml_prettify.rb +1 -1
  516. data/lib/starter_web/_plugins/helper/symlink_watcher.rb +1 -1
  517. data/lib/starter_web/_plugins/i18n/date.rb +1 -1
  518. data/lib/starter_web/_plugins/index/lunr.rb +2 -2
  519. data/lib/starter_web/_plugins/seo/j1-feed.rb +1 -1
  520. data/lib/starter_web/_plugins/seo/j1-seo-tags.rb +1 -1
  521. data/lib/starter_web/_plugins/seo/j1-sitemap.rb +1 -1
  522. data/lib/starter_web/assets/image/icons/tv/Index of -tv-logos-.url +2 -0
  523. data/lib/starter_web/assets/image/icons/tv/TV from Germany - LyngSat Logo.url +2 -0
  524. data/lib/starter_web/assets/image/icons/tv/Zeichnung.svg +47 -0
  525. data/lib/starter_web/assets/image/icons/tv/ard-icon-16x16.ico +0 -0
  526. data/lib/starter_web/assets/image/icons/tv/ard-icon-24x24.png +0 -0
  527. data/lib/starter_web/assets/image/icons/tv/ard-icon-512x512.png +0 -0
  528. data/lib/starter_web/assets/image/icons/tv/ard-icon.jpg +0 -0
  529. data/lib/starter_web/assets/image/icons/tv/ard-icon.jpg (353/303/227353).url" +2 -0
  530. data/lib/starter_web/assets/image/icons/tv/ard-icon.png +0 -0
  531. data/lib/starter_web/assets/image/icons/tv/ard-logo-png_seeklogo-428343.png +0 -0
  532. data/lib/starter_web/assets/image/icons/tv/cytec-tvlogos- collection of mostly german tv channel logos.url +2 -0
  533. data/lib/starter_web/assets/image/icons/tv/output_image.jpg +0 -0
  534. data/lib/starter_web/assets/image/icons/tv/pang.ping +0 -0
  535. data/lib/starter_web/assets/image/icons/tv/tv-logos-countries-germany-0_all_logos_mosaic.md at main /302/267 tv-logo-tv-logos.url" +2 -0
  536. data/lib/starter_web/assets/image/modules/attics/1920x1280/tiny_desk.jpg +0 -0
  537. data/lib/starter_web/assets/image/modules/attics/alice-donovan-rouse-2.jpg +0 -0
  538. data/lib/starter_web/assets/image/modules/gallery/free_animals/free-animals-1.jpg +0 -0
  539. data/lib/starter_web/assets/image/modules/gallery/free_animals/free-animals-2.jpg +0 -0
  540. data/lib/starter_web/assets/image/modules/gallery/free_animals/free-animals-3.jpg +0 -0
  541. data/lib/starter_web/assets/image/modules/gallery/free_animals/free-animals-4.jpg +0 -0
  542. data/lib/starter_web/assets/image/modules/gallery/free_animals/free-animals-5.jpg +0 -0
  543. data/lib/starter_web/assets/image/modules/gallery/free_animals/free-animals-6.jpg +0 -0
  544. data/lib/starter_web/assets/image/modules/gallery/mega_cities/295683517.jpg +0 -0
  545. data/lib/starter_web/assets/image/modules/gallery/mega_cities/chicago-us.jpg +0 -0
  546. data/lib/starter_web/assets/image/modules/gallery/mega_cities/denys-nevozhai-1_b.jpg +0 -0
  547. data/lib/starter_web/assets/image/modules/gallery/mega_cities/denys-nevozhai-1_c.jpg +0 -0
  548. data/lib/starter_web/assets/image/modules/gallery/mega_cities/denys-nevozhai-3_b.jpg +0 -0
  549. data/lib/starter_web/assets/image/modules/gallery/mega_cities/emmad-mazhari_c.jpg +0 -0
  550. data/lib/starter_web/assets/image/modules/gallery/mega_cities/federico-rizzarelli_b.jpg +0 -0
  551. data/lib/starter_web/assets/image/modules/gallery/mega_cities/federico-rizzarelli_c.jpg +0 -0
  552. data/lib/starter_web/assets/image/modules/gallery/mega_cities/jakarta_indonesia.jpg +0 -0
  553. data/lib/starter_web/assets/image/modules/gallery/mega_cities/jakarta_indonesia_2.jpg +0 -0
  554. data/lib/starter_web/assets/image/modules/gallery/mega_cities/melbourne_australia.jpg +0 -0
  555. data/lib/starter_web/assets/image/modules/gallery/mega_cities/melbourne_australia.webp +0 -0
  556. data/lib/starter_web/assets/image/modules/gallery/mega_cities/queen_bees_at_eureka_tower.jpg +0 -0
  557. data/lib/starter_web/assets/image/modules/gallery/mega_cities/shanghai_china.jpg +0 -0
  558. data/lib/starter_web/assets/image/modules/gallery/mega_cities/thomas-tucker_b.jpg +0 -0
  559. data/lib/starter_web/assets/image/modules/gallery/mega_cities/tokyo_japan.jpg +0 -0
  560. data/lib/starter_web/assets/image/modules/gallery/neighbor_slider/guardians-of-the-galaxy.jpg +0 -0
  561. data/lib/starter_web/assets/image/modules/gallery/neighbor_slider/justice-league.jpg +0 -0
  562. data/lib/starter_web/assets/image/modules/gallery/neighbor_slider/spider-man.jpg +0 -0
  563. data/lib/starter_web/assets/image/modules/gallery/neighbor_slider/suicide-squad.jpg +0 -0
  564. data/lib/starter_web/assets/image/modules/gallery/neighbor_slider/thor-ragnarok.jpg +0 -0
  565. data/lib/starter_web/assets/image/modules/gallery/panorama/1.jpg +0 -0
  566. data/lib/starter_web/assets/image/modules/gallery/panorama/10.jpg +0 -0
  567. data/lib/starter_web/assets/image/modules/gallery/panorama/11.jpg +0 -0
  568. data/lib/starter_web/assets/image/modules/gallery/panorama/12.jpg +0 -0
  569. data/lib/starter_web/assets/image/modules/gallery/panorama/2.jpg +0 -0
  570. data/lib/starter_web/assets/image/modules/gallery/panorama/3.jpg +0 -0
  571. data/lib/starter_web/assets/image/modules/gallery/panorama/4.jpg +0 -0
  572. data/lib/starter_web/assets/image/modules/gallery/panorama/5.jpg +0 -0
  573. data/lib/starter_web/assets/image/modules/gallery/panorama/6.jpg +0 -0
  574. data/lib/starter_web/assets/image/modules/gallery/panorama/7.jpg +0 -0
  575. data/lib/starter_web/assets/image/modules/gallery/panorama/8.jpg +0 -0
  576. data/lib/starter_web/assets/image/modules/gallery/panorama/9.jpg +0 -0
  577. data/lib/starter_web/assets/video/poster/youtube/faelle_des_bnd/der_unverzichtbare_feind.jpg +0 -0
  578. data/lib/starter_web/assets/video/poster/youtube/faelle_des_bnd/ein_diener_vieler_herren.jpg +0 -0
  579. data/lib/starter_web/assets/video/poster/youtube/the_piano/the-piano.jpg +0 -0
  580. data/lib/starter_web/config.ru +1 -1
  581. data/lib/starter_web/dot.gitattributes +1 -1
  582. data/lib/starter_web/dot.nojekyll +1 -1
  583. data/lib/starter_web/package.json +1 -1
  584. data/lib/starter_web/pages/public/{manuals/integrations/google/gemini/_includes → _includes}/attributes.asciidoc +5 -7
  585. data/lib/starter_web/pages/public/_includes/documents/photoswipe/200_photoswipe_parameters.asciidoc +529 -0
  586. data/lib/starter_web/pages/public/_includes/documents/photoswipe/210_photoswipe_lightbox_parameters.asciidoc +105 -0
  587. data/lib/starter_web/pages/public/_includes/documents/photoswipe/300_caption_plugin_for_photoSwipe.asciidoc +324 -0
  588. data/lib/starter_web/pages/public/_includes/documents/swiper/100_swiper_features.asciidoc +50 -0
  589. data/lib/starter_web/pages/public/_includes/documents/swiper/100_swiper_html_layout.asciidoc +122 -0
  590. data/lib/starter_web/pages/public/_includes/documents/swiper/100_swiper_initialization.asciidoc +53 -0
  591. data/lib/starter_web/pages/public/_includes/documents/swiper/110_swiper_common_options.asciidoc +118 -0
  592. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_a_k.asciidoc +1094 -0
  593. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_l_o.asciidoc +537 -0
  594. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_p_s.asciidoc +757 -0
  595. data/lib/starter_web/pages/public/_includes/documents/swiper/200_swiper_parameters_t_z.asciidoc +451 -0
  596. data/lib/starter_web/pages/public/_includes/documents/swiper/300_swiper_instance_properties.asciidoc +873 -0
  597. data/lib/starter_web/pages/public/_includes/documents/swiper/400_swiper_modules.asciidoc +3445 -0
  598. data/lib/starter_web/pages/public/_includes/documents/swiper/500_swiper_methods.asciidoc +989 -0
  599. data/lib/starter_web/pages/public/_includes/documents/swiper/600_swiper_events.asciidoc +1534 -0
  600. data/lib/starter_web/pages/public/{amplitude_yt_tester.adoc → tools/tester/amplitude_yt_tester.adoc} +81 -67
  601. data/lib/starter_web/pages/public/tools/tester/swiper_tester.adoc +796 -0
  602. data/lib/starter_web/pages/public/tour/modal_extentions.adoc +12 -5
  603. data/lib/starter_web/pages/public/tour/play_audio.adoc +60 -5
  604. data/lib/starter_web/pages/public/tour/play_video.adoc +30 -0
  605. data/lib/starter_web/pages/public/tour/present_images.adoc +24 -22
  606. metadata +128 -20
  607. data/assets/theme/j1/modules/amplitudejs/js/tech/youtube_example.js +0 -211
  608. data/lib/starter_web/assets/image/modules/gallery/mega_cities/thomas-tucker-bw.jpg +0 -0
  609. data/lib/starter_web/pages/public/lazy_loader_tester.adoc +0 -402
  610. data/lib/starter_web/pages/public/manuals/integrations/amplitudejs/_includes/attributes.asciidoc +0 -69
  611. data/lib/starter_web/pages/public/manuals/integrations/amplitudejs/_includes/documents/readme +0 -0
  612. data/lib/starter_web/pages/public/manuals/integrations/amplitudejs/amplitudejs-api.adoc +0 -2260
  613. data/lib/starter_web/pages/public/manuals/integrations/google/gemini/_includes/documents/preview_google_adsense.asciidoc +0 -448
  614. data/lib/starter_web/pages/public/manuals/integrations/google/gemini/_includes/documents/readme +0 -0
  615. data/lib/starter_web/pages/public/manuals/integrations/google/gemini/_includes/tables/readme +0 -0
  616. data/lib/starter_web/pages/public/manuals/integrations/google/gemini/gemini.adoc +0 -525
  617. data/lib/starter_web/pages/public/manuals/integrations/google/gemini/security.asccidoc +0 -274
  618. data/lib/starter_web/pages/public/manuals/integrations/google/gemini/security.hrml +0 -560
  619. data/lib/starter_web/pages/public/manuals/integrations/videojs/youtube-api.adoc +0 -1638
  620. data/lib/starter_web/pages/public/manuals/ytdl/man.adoc +0 -3020
  621. data/lib/starter_web/pages/public/manuals/ytdl/man.md +0 -2378
@@ -1,12 +1,72 @@
1
+ ---
2
+ regenerate: true
3
+ ---
4
+
5
+ {%- capture cache -%}
6
+
7
+ {% comment %}
8
+ # -----------------------------------------------------------------------------
9
+ # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.js
10
+ # AmplitudeJS V5 Plugin|Tech for J1 Template
11
+ #
12
+ # Product/Info:
13
+ # https://jekyll.one
14
+ #
15
+ # Copyright (C) 2023-2025 Juergen Adams
16
+ #
17
+ # J1 Template is licensed under the MIT License.
18
+ # See: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE
19
+ # -----------------------------------------------------------------------------
20
+ # Test data:
21
+ # {{ liquid_var | debug }}
22
+ # amplitude_options: {{ amplitude_options | debug }}
23
+ # -----------------------------------------------------------------------------
24
+ {% endcomment %}
25
+
26
+ {% comment %} Liquid procedures
27
+ -------------------------------------------------------------------------------- {% endcomment %}
28
+
29
+ {% comment %} Set global settings
30
+ -------------------------------------------------------------------------------- {% endcomment %}
31
+ {% assign environment = site.environment %}
32
+ {% assign asset_path = "/assets/theme/j1" %}
33
+
34
+ {% comment %} Process YML config data
35
+ ================================================================================ {% endcomment %}
36
+
37
+ {% comment %} Set config files
38
+ -------------------------------------------------------------------------------- {% endcomment %}
39
+ {% assign template_config = site.data.j1_config %}
40
+ {% assign blocks = site.data.blocks %}
41
+ {% assign modules = site.data.modules %}
42
+
43
+ {% comment %} Set config data (settings only)
44
+ -------------------------------------------------------------------------------- {% endcomment %}
45
+ {% assign amplitude_defaults = modules.defaults.amplitude.defaults %}
46
+ {% assign amplitude_players = modules.amplitude_players.settings %}
47
+ {% assign amplitude_playlists = modules.amplitude_playlists.settings %}
48
+
49
+ {% comment %} Set config options (settings only)
50
+ -------------------------------------------------------------------------------- {% endcomment %}
51
+ {% assign amplitude_options = amplitude_defaults | merge: amplitude_players %}
52
+ {% assign amplitude_options = amplitude_options | merge: amplitude_playlists %}
53
+
54
+ {% comment %} Detect prod mode
55
+ -------------------------------------------------------------------------------- {% endcomment %}
56
+ {% assign production = false %}
57
+ {% if environment == 'prod' or environment == 'production' %}
58
+ {% assign production = true %}
59
+ {% endif %}
60
+
1
61
  /*
2
62
  # -----------------------------------------------------------------------------
3
- # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/youtube.js
63
+ # ~/assets/theme/j1/modules/amplitudejs/js/plugins/tech/ytp.js
4
64
  # AmplitudeJS V5 Plugin|Tech for J1 Template
5
65
  #
6
66
  # Product/Info:
7
67
  # https://jekyll.one
8
68
  #
9
- # Copyright (C) 2023, 2024 Juergen Adams
69
+ # Copyright (C) 2023-2025 Juergen Adams
10
70
  #
11
71
  # J1 Template is licensed under the MIT License.
12
72
  # See: https://github.com/jekyll-one-org/j1-template/blob/main/LICENSE
@@ -14,100 +74,1571 @@
14
74
  */
15
75
  "use strict";
16
76
 
17
- var ytPlayer;
18
- var ytPlayerReady = false;
19
- var ytApiIReady = false;
20
- var logger = log4javascript.getLogger('j1.adapter.amplitude.tech');
21
- var ytpSettings = {
22
- ytpVideoID: "qEhzpBJpUq0",
23
- ytpAutoPlay: 0,
24
- ytpLoop: 1
25
- };
26
-
27
77
  // date|time monitoring
28
- //---------------------
78
+ //------------------------------------------------------------------------------
29
79
  var startTime;
30
80
  var endTime;
31
81
  var startTimeModule;
32
82
  var endTimeModule;
33
83
  var timeSeconds;
34
84
 
35
- startTimeModule = Date.now();
36
-
37
- logger.info('\n' + 'Initialize YouTube IframeAPI: started');
85
+ // YT API settings
86
+ // -----------------------------------------------------------------------------
87
+ var YT_PLAYER_STATE = {
88
+ UNSTARTED: -1,
89
+ ENDED: 0,
90
+ PLAYING: 1,
91
+ PAUSED: 2,
92
+ BUFFERING: 3,
93
+ CUED: 5
94
+ };
38
95
 
39
- // load the IFrame Player API code asynchronously
40
- //
41
96
  var firstScriptTag;
42
- var tag = document.createElement('script');
43
- tag.id = 'iframe_api';
44
- tag.src = '//youtube.com/iframe_api';
45
- firstScriptTag = document.getElementsByTagName('script')[0];
46
-
47
- firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
48
-
49
- // Create an <iframe> (and the YouTube player) after the YT API code
50
- // has been downloaded
51
- function onYouTubeytApiIReady() {
52
- ytApiIReady = true;
53
-
54
- // logger.info('\n' + 'AJS YouTube IframeAPI: ready');
55
-
56
- // var ytCtrl = document.getElementById("youtube_player_container");
57
- // ytCtrl.innerHTML = '<img id="youtube-icon1 src=""/> <div id="ytPlayer"></div>';
58
- // ytCtrl.style.cssText = 'width:150px;margin:2em auto;cursor:pointer;cursor:hand;display:none';
59
- // ytCtrl.onclick = toggleAudio1;
60
-
61
- ytPlayer = new YT.Player('ytPlayer', {
62
- height: 0,
63
- width: 0,
64
- videoId: ytpSettings.ytpVideoID,
65
- playerVars: {
66
- autoplay: ytpSettings.ytpAutoPlay,
67
- loop: ytpSettings.ytpLoop
68
- },
69
- events: {
70
- onReady: onPlayerReady,
71
- onStateChange: onPlayerStateChange
72
- }
73
- });
74
-
75
- // save player reference for later use
76
- j1.adapter.amplitude['ytPlayer'] = ytPlayer;
77
- j1.adapter.amplitude['ytApiIReady'] = ytApiIReady;
78
-
79
- logger.info('\n' + 'Initialize YouTube API: finished');
80
- endTimeModule = Date.now();
81
- logger.info('\n' + 'YouTube API initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
82
-
83
- } // END onYouTubeytApiIReady
84
-
85
- function onPlayerReady(event) {
86
- logger.info('\n' + 'YouTube Player: ready');
87
- ytPlayer.setPlaybackQuality("small");
88
- j1.adapter.amplitude['ytPlayerReady'] = true;
89
-
90
- // document.getElementById("youtube-audio").style.display = "block";
91
- // togglePlayButton1(ytPlayer.getPlayerState() !== 5);
92
- } // END event onPlayerReady
93
-
94
- function onPlayerStateChange(event) {
95
- if (event.data === 0) {
96
- var bla = 'blupp'
97
- // togglePlayButton1(false);
98
- }
99
- } // END event onPlayerStateChange
100
-
101
- // Create a new div element
102
- const ytpContainer = document.createElement('div');
103
-
104
- // Set attributes for the div container
105
- ytpContainer.id = 'youtube_player_container';
106
- // ytpContainer.className = 'container';
107
- // ytpContainer.setAttribute("data-video", "WxcWO9O4DSM");
108
- // ytpContainer.setAttribute("data-autoplay", "0");
109
- // ytpContainer.setAttribute("data-loop", "1");
110
- // ytpContainer.innerHTML = 'data-video="WxcWO9O4DSM" data-autoplay="0" data-loop="1"';
111
-
112
- // Append the div container to the end of the body
113
- document.body.appendChild(ytpContainer);
97
+ var ytPlayer;
98
+ var ytPlayerReady = false;
99
+ var ytApiReady = false;
100
+ var logger = log4javascript.getLogger('j1.adapter.amplitude.tech');
101
+
102
+ // YT Player settings data (created dynamically)
103
+ // -----------------------------------------------------------------------------
104
+ // var ytPlayers = {};
105
+ // var ytPlayersMap = new Map();
106
+
107
+ // AmplitudeJS API settings
108
+ // -----------------------------------------------------------------------------
109
+
110
+ var dependency;
111
+ var playerCounter = 0;
112
+ var load_dependencies = {};
113
+
114
+ // set default song index to FIRST item
115
+ var songIndex = 0;
116
+ var ytpSongIndex = 0;
117
+
118
+ var ytpAutoPlay = false;
119
+ var ytpLoop = true;
120
+ var playLists = {};
121
+ var playersUILoaded = { state: false };
122
+ var apiInitialized = { state: false };
123
+
124
+ var amplitudeDefaults = $.extend({}, {{amplitude_defaults | replace: 'nil', 'null' | replace: '=>', ':' }});
125
+ var amplitudePlayers = $.extend({}, {{amplitude_players | replace: 'nil', 'null' | replace: '=>', ':' }});
126
+ var amplitudePlaylists = $.extend({}, {{amplitude_playlists | replace: 'nil', 'null' | replace: '=>', ':' }});
127
+ var amplitudeOptions = $.extend(true, {}, amplitudeDefaults, amplitudePlayers, amplitudePlaylists);
128
+
129
+ var playerExistsInPage = false;
130
+ var ytpContainer = null;
131
+ var playerProperties = {};
132
+ var playList;
133
+ var playerProperties;
134
+ var playerID;
135
+ var playerType;
136
+ var playListTitle;
137
+ var playListName;
138
+ var amplitudePlayerState;
139
+ var ytPlayer;
140
+ var ytpPlaybackRate
141
+
142
+ var songs;
143
+ var songMetaData;
144
+ var songURL;
145
+
146
+ var progress;
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Base YT functions and events
150
+ // ---------------------------------------------------------------------------
151
+
152
+ // Recursive function to MERGE objects
153
+ var mergeObject = function() {
154
+ mergeObject = Object.assign || function mergeObject(t) {
155
+ for (var s, i=1, n=arguments.length; i<n; i++) {
156
+ s = arguments[i];
157
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
158
+ }
159
+ return t;
160
+ };
161
+ return mergeObject.apply(this, arguments);
162
+ };
163
+
164
+ // Add property path dynamically to an existing object
165
+ // Example: addNestedProperty(j1.adapter.amplitude.data, 'playlist.profile.name', 'Max Mustermann')
166
+ function addNestedProperty(obj, path, value) {
167
+ let current = obj;
168
+ const properties = path.split('.');
169
+
170
+ properties.forEach((property, index) => {
171
+ if (index === properties.length - 1) {
172
+ current[property] = value;
173
+ } else {
174
+ if (!current[property]) {
175
+ current[property] = {};
176
+ }
177
+ current = current[property];
178
+ }
179
+ });
180
+ }
181
+
182
+ function setNestedProperty(obj, path, value) {
183
+ const keys = path.split('.');
184
+
185
+ // Basisfall: Wenn nur noch ein Schlüssel übrig ist, setzen wir den Wert direkt
186
+ if (keys.length === 1) {
187
+ obj[keys[0]] = value;
188
+ return;
189
+ }
190
+
191
+ // Rekursiver Fall: Wir erstellen das Objekt für den nächsten Schlüssel, falls es noch nicht existiert
192
+ let current = obj[keys[0]];
193
+ if (typeof current !== 'object') {
194
+ current = obj[keys[0]] = {};
195
+ }
196
+
197
+ // Rekursiver Aufruf für den Rest des Pfades
198
+ setNestedProperty(current, keys.slice(1).join('.'), value);
199
+ }
200
+
201
+ // Add (nested) object dynamically to an existing object
202
+ // Example: createNestedObject(myObject, ['level1', 'arrayProperty', 0], 'element1');
203
+ function addNestedObject(obj, path, value) {
204
+ const lastKey = path[path.length - 1];
205
+ let current = obj;
206
+
207
+ path.slice(0, -1).forEach(key => {
208
+ current[key] = current[key] || {};
209
+ current = current[key];
210
+ });
211
+
212
+ current[lastKey] = value;
213
+ }
214
+
215
+ // load YT Iframe player API
216
+ function initYtAPI() {
217
+ startTimeModule = Date.now();
218
+
219
+ logger.info('\n' + 'Initialize plugin|tech (ytp) : started');
220
+
221
+ // Load YT IFrame Player API asynchronously
222
+ // -------------------------------------------------------------------------
223
+ var tag = document.createElement('script');
224
+ tag.src = "//youtube.com/iframe_api";
225
+ firstScriptTag = document.getElementsByTagName('script')[0];
226
+
227
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
228
+ }
229
+
230
+ // setup YTPlayerUiEvents for AJS players
231
+ function initUiEventsForAJS() {
232
+
233
+ var dependencies_ytp_ready = setInterval (() => {
234
+ var ytApiReady = (j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] !== undefined) ? j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] : false;
235
+ var ytPlayerReady = (j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] !== undefined) ? j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] : false;
236
+
237
+ if (ytApiReady && ytPlayerReady) {
238
+
239
+ {% for player in amplitude_players.players %}{% if player.enabled %}
240
+
241
+ {% if player.source == empty %}
242
+ {% assign player_source = amplitude_defaults.player.source %}
243
+ {% else %}
244
+ {% assign player_source = player.source %}
245
+ {% endif %}
246
+
247
+ {% if player_source == 'video' %}
248
+ var playerID = '{{player.id}}';
249
+ mimikYTPlayerUiEventsForAJS(playerID);
250
+ {% endif %}
251
+
252
+ {% endif %}{% endfor %}
253
+
254
+ clearInterval(dependencies_ytp_ready);
255
+ logger.info('\n' + 'Initialize APIPlayers : ready');
256
+ } // END if ready
257
+
258
+ }, 10); // END dependencies_ytp_ready
259
+ } // END initUiEventsForAJS()
260
+
261
+ // Create a player after Iframe player API is ready to use
262
+ // ---------------------------------------------------------------------------
263
+ function onYouTubeIframeAPIReady() {
264
+ // var currentOptions;
265
+ var playerSource;
266
+
267
+ ytApiReady = true;
268
+ // currentOptions = $.extend({}, {{amplitude_options | replace: 'nil', 'null' | replace: '=>', ':' }});
269
+
270
+ {% for player in amplitude_options.players %}{% if player.enabled %}
271
+ {% capture xhr_container_id %}{{player.id}}_parent{% endcapture %}
272
+
273
+ playerSource = '{{player.source}}';
274
+
275
+ {% if player.source == empty %}
276
+ {% assign player_source = amplitude_defaults.player.source %}
277
+ {% else %}
278
+ {% assign player_source = player.source %}
279
+ {% endif %}
280
+
281
+ {% if player_source != 'video' %}
282
+ {% continue %}
283
+ {% else %}
284
+ // load players of type 'video' configured in current page
285
+ //
286
+ playerExistsInPage = ($('#' + '{{xhr_container_id}}')[0] !== undefined) ? true : false;
287
+ if (playerExistsInPage) {
288
+ var playerSettings = $.extend({}, {{player | replace: 'nil', 'null' | replace: '=>', ':' }});
289
+ var songs = Amplitude.getSongsStatePlaylist(playerSettings.playlist.name);
290
+ var activeSongMetadata = songs[0];
291
+ var playerType = playerSettings.type
292
+
293
+ // increase number of found players in page by one
294
+ playerCounter++;
295
+
296
+ // load individual player settings (to manage multiple players in page)
297
+ //
298
+ var ytpVideoID = activeSongMetadata.url.split('=')[1];
299
+ var ytpAutoPlay = ('{{player.yt_player.autoplay}}'.length > 0) ? '{{player.yt_player.autoplay}}' : '{{amplitude_defaults.player.yt_player.autoplay}}';
300
+ var ytpLoop = ('{{player.yt_player.loop}}'.length > 0) ? '{{player.yt_player.loop}}' : '{{amplitude_defaults.player.yt_player.loop}}';
301
+ var ytpHeight = ('{{player.yt_player.height}}'.length > 0) ? '{{player.yt_player.height}}' : '{{amplitude_defaults.player.yt_player.height}}';
302
+ var ytpWidth = ('{{player.yt_player.width}}'.length > 0) ? '{{player.yt_player.width}}' : '{{amplitude_defaults.player.yt_player.width}}';
303
+
304
+ logger.info('\n' + 'AJS YouTube iFrame API: ready');
305
+ logger.info('\n' + 'configure player on ID: #{{player.id}}');
306
+
307
+ // create a hidden YT Player iFrame container
308
+ //
309
+ ytpContainer = document.getElementById('{{player.id}}_video');
310
+ ytpContainer.innerHTML = '<div id="iframe_{{player.id}}"></div>';
311
+ ytpContainer.style.cssText = 'display:none';
312
+
313
+ ytPlayer = new YT.Player('iframe_{{player.id}}', {
314
+ height: ytpHeight,
315
+ width: ytpWidth,
316
+ videoId: ytpVideoID,
317
+ playerVars: {
318
+ autoplay: ytpAutoPlay,
319
+ loop: ytpLoop
320
+ },
321
+ events: {
322
+ 'onReady': {{player.id}}OnPlayerReady,
323
+ 'onStateChange': {{player.id}}OnPlayerStateChange
324
+ }
325
+ });
326
+
327
+ // remove EMPTY properties
328
+ delete playerSettings.player;
329
+
330
+ // save YT player properties for later use
331
+ playerProperties = {
332
+ "playerDefaults": amplitudeDefaults.player,
333
+ "playerSettings": playerSettings,
334
+ "player": ytPlayer,
335
+ "playerReady": false,
336
+ "playerType": playerType,
337
+ "playerID": "{{player.id}}",
338
+ "videoID": ytpVideoID,
339
+ "songs": songs,
340
+ "activeIndex": 0,
341
+ };
342
+
343
+ // store player properties for later use
344
+ addNestedProperty(j1.adapter.amplitude.data.ytPlayers, '{{player.id}}', playerProperties);
345
+
346
+ // save YT player data for later use (e.g. events)
347
+ // j1.adapter.amplitude.data.ytpGlobals['ytVideoID'] = ytpVideoID;
348
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerDefaults'] = amplitudeDefaults.player;
349
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerSettings'] = playerSettings;
350
+ j1.adapter.amplitude.data.ytpGlobals['ytApiReady'] = ytApiReady;
351
+
352
+
353
+ // reset current player
354
+ playerExistsInPage = false;
355
+
356
+ } // END if playerExistsInPage()
357
+
358
+ // run AJS YouTube Player initialization
359
+ // ---------------------------------------------------------------------
360
+ function {{player.id}}OnPlayerReady(event) {
361
+ var hours, minutes, seconds;
362
+ var ytPlayer = event.target;
363
+ var ytPlayerReady = true;
364
+
365
+ logger.info('\n' + 'AJS YouTube Player on ID {{player.id}}: ready');
366
+
367
+ // save YT player data for later use (e.g. events)
368
+ j1.adapter.amplitude.data.ytpGlobals['ytPlayerReady'] = ytPlayerReady;
369
+ j1.adapter.amplitude.data.ytPlayers.{{player.id}}.playerReady = ytPlayerReady;
370
+
371
+ // setInterval(updateCurrentTimeContainerYTP, 1000);
372
+ // setInterval(updateProgressBarsYTP, 1000)
373
+
374
+ // get duration hours (if configured)
375
+ if ({{player.display_hours}} ) {
376
+ hours = ytpGetDurationHours (ytPlayer);
377
+ }
378
+
379
+ // get duration minutes|seconds
380
+ minutes = ytpGetDurationMinutes (ytPlayer);
381
+ seconds = ytpGetDurationSeconds (ytPlayer);
382
+
383
+ // set duration time values for current video
384
+ // -------------------------------------------------------------------
385
+
386
+ // set duration|hours
387
+ if ({{player.display_hours}} ) {
388
+ var durationHours = document.getElementsByClassName("amplitude-duration-hours");
389
+ durationHours[0].innerHTML = hours;
390
+ }
391
+
392
+ // set duration|minutes
393
+ var durationMinutes = document.getElementsByClassName("amplitude-duration-minutes");
394
+ durationMinutes[0].innerHTML = minutes;
395
+
396
+ // set duration|seconds
397
+ var durationSeconds = document.getElementsByClassName("amplitude-duration-seconds");
398
+ durationSeconds[0].innerHTML = seconds;
399
+
400
+ // final message
401
+ // -------------------------------------------------------------------
402
+ endTimeModule = Date.now();
403
+
404
+ logger.info('\n' + 'Initialize plugin|tech (ytp) : finished');
405
+
406
+ if (playerCounter > 0) {
407
+ logger.info('\n' + 'Found players of type video (YTP) in page: ' + playerCounter);
408
+ } else {
409
+ logger.warn('\n' + 'Found NO players of type video (YTP) in page');
410
+ }
411
+
412
+ logger.info('\n' + 'plugin|tech initializing time: ' + (endTimeModule-startTimeModule) + 'ms');
413
+
414
+ } // END onPlayerReady()
415
+
416
+ // update YT player elements on state change (playing)
417
+ // ---------------------------------------------------------------------
418
+ function {{player.id}}OnPlayerStateChange(event) {
419
+ var playlist = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.playerSettings.playlist.name;
420
+ var playerID = playlist + '_large';
421
+ var ytPlayer = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player;
422
+ var songs = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.songs;
423
+ // var activeIndex = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.activeIndex;
424
+
425
+ // set active ytPlayer
426
+ j1.adapter.amplitude.data.ytpGlobals['activePlayer'] = ytPlayer;
427
+
428
+ // save YT player data for later use (e.g. events)
429
+ // j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player = ytPlayer;
430
+
431
+ resetCurrentTimeContainerYTP();
432
+ updateDurationTimeContainerYTP(ytPlayer);
433
+
434
+ // setInterval(updateCurrentTimeContainerYTP, 1000);
435
+ // setInterval(updateProgressBarsYTP('{{player.id}}'), 1000)
436
+
437
+ // Set the index of the active song (index starts by 0)
438
+ // ytpSetActiveIndex({{player.id}}, activeIndex);
439
+
440
+ if (event.data === YT_PLAYER_STATE.PLAYING || event.data === YT_PLAYER_STATE.BUFFERING) {
441
+ setInterval(updateCurrentTimeContainerYTP, 1000);
442
+ setInterval(updateProgressBarsYTP, 1000);
443
+
444
+ // j1.adapter.amplitude.data.ytpGlobals['activePlayer'] = ytPlayer;
445
+ }
446
+
447
+ // play next video
448
+ if (event.data === YT_PLAYER_STATE.ENDED) {
449
+
450
+ // var ytPlayer = j1.adapter.amplitude.data.ytpGlobals['ytPlayer'];
451
+ // var ytPlayer = j1.adapter.amplitude.data.ytPlayers.{{player.id}}.player;
452
+ // var songs = j1.adapter.amplitude.data.ytpGlobals['ytPlayerSongs'];
453
+ // var songIndex = parseInt(j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex']) + 1;
454
+
455
+ var songIndex;
456
+ songIndex = ytpSongIndex;
457
+ songIndex++;
458
+ ytpSongIndex = songIndex;
459
+
460
+ // var songIndex = j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex
461
+ // songIndex++
462
+
463
+ // update activeIndex
464
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
465
+
466
+ if (songIndex < songs.length) {
467
+ var songMetaData = songs[songIndex];
468
+ var songURL = songMetaData.url;
469
+ var ytpVideoID = songURL.split('=')[1];
470
+
471
+ // continue on next video
472
+ ytPlayer.loadVideoById(ytpVideoID);
473
+
474
+ // reset|update time settings
475
+ resetCurrentTimeContainerYTP();
476
+ updateDurationTimeContainerYTP(ytPlayer);
477
+
478
+ // update global song index for next video
479
+ ytpSongIndex = songIndex;
480
+ // ytpSetActiveIndex({{player.id}}, songIndex);
481
+
482
+ // save YT player data for later use (e.g. events)
483
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
484
+
485
+ // load cover image for next video
486
+ var coverImage;
487
+ var selector = ".cover-image-" + playlist;
488
+ coverImage = document.querySelector(selector);
489
+ coverImage.src = songMetaData.cover_art_url;
490
+
491
+ // replace song name in meta-containers for next video
492
+ var songName = document.getElementsByClassName("song-name");
493
+ songName[0].innerHTML = songMetaData.name; // player-bottom
494
+ songName[1].innerHTML = songMetaData.name; // playlist-screen-controls
495
+
496
+ // replace song rating (playlist-screen|meta-container)
497
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
498
+ if (largetPlayerSongAudioRating.length) {
499
+ if (songMetaData.rating) {
500
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
501
+ } else {
502
+ largetPlayerSongAudioRating[0].innerHTML = '';
503
+ }
504
+ } // END if largetPlayerSongAudioRating
505
+
506
+ // replace artist name in meta-containers for next video
507
+ var artistName = document.getElementsByClassName("artist");
508
+ artistName[0].innerHTML = songMetaData.artist;
509
+
510
+ // replace album name in meta-containers for next video
511
+ var albumName = document.getElementsByClassName("album");
512
+ albumName[0].innerHTML = songMetaData.album;
513
+
514
+ // set song active in playlist
515
+ // setSongPlayed(songIndex);
516
+ setSongPlayed(playerID, songIndex);
517
+ } else {
518
+ // select FIRST video
519
+ songIndex = 0;
520
+ var songMetaData = songs[songIndex];
521
+ var songURL = songMetaData.url;
522
+ var ytpVideoID = songURL.split('=')[1];
523
+
524
+ // ytpSetActiveIndex({{player.id}}, songIndex);
525
+
526
+ // continue (paused) on FIRST video
527
+ ytPlayer.loadVideoById(ytpVideoID);
528
+ // wait some time to make sure video is loaded|active
529
+ setTimeout(() => {
530
+ ytPlayer.pauseVideo();
531
+ // reset|update time settings
532
+ resetCurrentTimeContainerYTP();
533
+ updateDurationTimeContainerYTP(ytPlayer);
534
+
535
+ // update AJS play_pause button
536
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
537
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
538
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
539
+ }, 300);
540
+
541
+ // update global song index for first video
542
+ ytpSongIndex = songIndex;
543
+
544
+ // save YT player data for later use (e.g. events)
545
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
546
+
547
+ // load cover image for first video
548
+ var coverImage;
549
+ var selector = ".cover-image-" + playlist;
550
+ coverImage = document.querySelector(selector);
551
+ coverImage.src = songMetaData.cover_art_url;
552
+
553
+ // replace name in meta-containers for first video
554
+ var songName = document.getElementsByClassName("song-name");
555
+ songName[0].innerHTML = songMetaData.name; // player-bottom
556
+ songName[1].innerHTML = songMetaData.name; // playlist-screen-controls
557
+
558
+ // replace song rating (playlist-screen|meta-container)
559
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
560
+ if (largetPlayerSongAudioRating.length) {
561
+ if (songMetaData.rating) {
562
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
563
+ } else {
564
+ largetPlayerSongAudioRating[0].innerHTML = '';
565
+ }
566
+ } // END if largetPlayerSongAudioRating
567
+
568
+ // replace artist name in meta-containers for next video
569
+ var artistName = document.getElementsByClassName("artist");
570
+ artistName.innerHTML = songMetaData.artist;
571
+
572
+ // replace album name in meta-containers for next video
573
+ var albumName = document.getElementsByClassName("album");
574
+ albumName.innerHTML = songMetaData.album;
575
+
576
+ // update AJS play_pause button
577
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
578
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
579
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
580
+
581
+ // set song (video) active in playlist
582
+ // setSongPlayed(songIndex);
583
+ setSongPlayed(playerID, songIndex);
584
+ }
585
+ } // END if YT_PLAYER_STATE.ENDED
586
+
587
+ } // END {{player.id}}OnPlayerStateChange
588
+
589
+ {% endif %}
590
+ {% endif %}{% endfor %}
591
+
592
+ } // END onYouTubeIframeAPIReady ()
593
+
594
+
595
+ // ---------------------------------------------------------------------------
596
+ // main (plugin)
597
+ // ---------------------------------------------------------------------------
598
+ // load|initialize YT Iframe player API
599
+ //
600
+ initYtAPI();
601
+
602
+ // setup YTPlayerUiEvents for AJS players
603
+ //
604
+ initUiEventsForAJS();
605
+
606
+
607
+ // ---------------------------------------------------------------------------
608
+ // Base AJS Player functions
609
+ // ---------------------------------------------------------------------------
610
+
611
+ // ---------------------------------------------------------------------------
612
+ // Returns the index of the current video (song) in the songs array
613
+ // that is currently playing (starts by 0)
614
+ // ---------------------------------------------------------------------------
615
+ //
616
+ function getSongPlayed() {
617
+ var index = -1;
618
+ var songContainers = document.getElementsByClassName("amplitude-active-song-container");
619
+
620
+ if (songContainers.length) {
621
+ for (var i=0; i<songContainers.length; i++) {
622
+ index = parseInt(songContainers[i].getAttribute('data-amplitude-song-index'));
623
+ if (index >= 0) {
624
+ break;
625
+ }
626
+ }
627
+ }
628
+
629
+ return index;
630
+ } // END getSongPlayed
631
+
632
+ // ---------------------------------------------------------------------------
633
+ // Add class 'amplitude-active-song-container' to the element containing
634
+ // visual information for the active song.
635
+ //
636
+ // NOTE: We then don't care if shuffle is on or not.
637
+ // ---------------------------------------------------------------------------
638
+ //
639
+ function setSongPlayed(playerID, index) {
640
+ var direct;
641
+
642
+ // Specify if it was a (direct) click on the song container
643
+ direct = true;
644
+
645
+ // Get all song container elements
646
+ var songContainers = document.getElementsByClassName("amplitude-song-container");
647
+
648
+ // Clear all active song containrs
649
+ for (var i = 0; i < songContainers.length; i++) {
650
+ songContainers[i].classList.remove("amplitude-active-song-container");
651
+ }
652
+
653
+ // Find the active index and add the active song container to the element
654
+ // that represents the song at the index.
655
+ //
656
+ if (Amplitude.getActivePlaylist() == "" || Amplitude.getActivePlaylist() == null) {
657
+ var activeIndex = "";
658
+
659
+ // If we click directly on the song element, we ignore
660
+ // whether it's in shuffle or not.
661
+ //
662
+ if (direct) {
663
+ // activeIndex = Amplitude.getActiveIndex();
664
+ activeIndex = index;
665
+ } else {
666
+ if (Amplitude.getConfig().shuffle_on) {
667
+ // activeIndex = Amplitude.getConfig().shuffle_list[Amplitude.getActiveIndex()];
668
+ } else {
669
+ // activeIndex = Amplitude.getActiveIndex();
670
+ activeIndex = index;
671
+ }
672
+ }
673
+
674
+ // activate playlist container
675
+ if (document.querySelectorAll('.amplitude-song-container[data-amplitude-song-index="' + activeIndex + '"]')) {
676
+ var _songContainers = document.querySelectorAll('.amplitude-song-container[data-amplitude-song-index="' + activeIndex + '"]');
677
+ for (var _i = 0; _i < _songContainers.length; _i++) {
678
+ if (_songContainers[_i].hasAttribute("data-amplitude-playlist")) {
679
+ var _playerID = _songContainers[_i].getAttribute("data-amplitude-playlist") + '_large';
680
+ if (_playerID === playerID) {
681
+ _songContainers[_i].classList.add("amplitude-active-song-container");
682
+ }
683
+ }
684
+ }
685
+ }
686
+ } else {
687
+ // If we have an active playlist or the action took place directly on the
688
+ // song element, we ignore the shuffle.
689
+ //
690
+ if (Amplitude.getActivePlaylist() != null && Amplitude.getActivePlaylist() != "" || direct) {
691
+ var activePlaylistIndex = Amplitude.getActiveIndex();
692
+ } else {
693
+ var activePlaylistIndex = "";
694
+
695
+ if (Amplitude.getActivePlaylist().shuffle) {
696
+ activePlaylistIndex = Amplitude.getActiveIndex();
697
+ } else {
698
+ activePlaylistIndex = Amplitude.getActiveIndex();
699
+ }
700
+ } // END if
701
+ } // END if
702
+ } // END setSongPlayed
703
+
704
+ // Returns the position as a percentage the user clicked in player progressbar
705
+ // NOTE: The percentage is out of [0.00 .. 1.00]
706
+ // ---------------------------------------------------------------------------
707
+ function getProgressBarSelectedPositionPercentage (event, progessBar) {
708
+ var offset = progessBar.getBoundingClientRect();
709
+ var xpos = event.pageX - offset.left;
710
+ var percentage = (parseFloat(xpos) / parseFloat(progessBar.offsetWidth)).toFixed(2);
711
+
712
+ return percentage;
713
+ }
714
+
715
+ // Returns the time in seconds calculated from a percentage value
716
+ // NOTE: The percentage is out of [0.00 .. 1.00]
717
+ // ---------------------------------------------------------------------------
718
+ function getTimeFromPercentage (player, percentage) {
719
+ var videoDuration = ytpGetDuration(player);
720
+ var time = parseFloat((videoDuration * percentage).toFixed(2));
721
+
722
+ return time;
723
+ }
724
+
725
+ // Update YTP specific progress data
726
+ // ---------------------------------------------------------------------------
727
+ function updateProgressBarsYTP() {
728
+ var progress;
729
+ var activePlayer = j1.adapter.amplitude.data.ytpGlobals['activePlayer'];
730
+ var progressBars = document.getElementsByClassName("large-player-progress");
731
+
732
+ for (var i=0; i<progressBars.length; i++) {
733
+ if (activePlayer !== undefined) {
734
+ // calc procent value (float, 2 decimals [0.00 .. 1.00])
735
+ progress = parseFloat((activePlayer.getCurrentTime() / activePlayer.getDuration()).toFixed(2));
736
+
737
+ // set current progess value if valid
738
+ if (isFinite(progress)) {
739
+ progressBars[i].value = progress;
740
+ }
741
+ }
742
+ } // END for
743
+
744
+ // calc procent value (float, 2 decimals [0.00 .. 1.00])
745
+ // progress = parseFloat((ytPlayer.getCurrentTime() / ytPlayer.getDuration()).toFixed(2));
746
+
747
+ // // jadams, 2024-12-07: added check on finite value
748
+ // if (!isFinite(progress)) {
749
+ // // TODO: check why progress value may NOT finite
750
+ // progressBar.value = 0;
751
+ // } else if (progress === 1) {
752
+ // // reset progress value for next video
753
+ // progressBar.value = 0;
754
+ // } else {
755
+ // // calculate current progress
756
+ // progress = parseFloat((ytPlayer.getCurrentTime() / ytPlayer.getDuration()).toFixed(2));
757
+ // progressBar.value = progress;
758
+
759
+ // save YT player progress data for later use (e.g. events)
760
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerProgress'] = progress;
761
+ //}
762
+ }
763
+
764
+ // Update YTP specific duration time data
765
+ // ---------------------------------------------------------------------------
766
+ function updateDurationTimeContainerYTP(player) {
767
+ var hours, minutes, seconds;
768
+ var durationHours, durationMinutes, durationSeconds;
769
+
770
+ // get current hours|minutes|seconds
771
+ hours = ytpGetDurationHours(player);
772
+ minutes = ytpGetDurationMinutes(player);
773
+ seconds = ytpGetDurationSeconds(player);
774
+
775
+ // update time container values for current video
776
+ // -------------------------------------------------------------------------
777
+
778
+ // update current duration|hours
779
+ durationHours = document.getElementsByClassName("amplitude-duration-hours");
780
+ if (durationHours.length && !isNaN(hours)) {
781
+ durationHours[0].innerHTML = hours;
782
+ }
783
+
784
+ // update current duration|minutes
785
+ durationMinutes = document.getElementsByClassName("amplitude-duration-minutes");
786
+ if (durationMinutes.length && !isNaN(minutes)) {
787
+ durationMinutes[0].innerHTML = minutes;
788
+ }
789
+
790
+ // update duration|seconds
791
+ durationSeconds = document.getElementsByClassName("amplitude-duration-seconds");
792
+ if (durationSeconds.length && !isNaN(seconds)) {
793
+ durationSeconds[0].innerHTML = seconds;
794
+ }
795
+ }
796
+
797
+ // Update YTP specific CURRENT time data
798
+ // ---------------------------------------------------------------------------
799
+ function updateCurrentTimeContainerYTP() {
800
+ var hours, minutes, seconds;
801
+ var currentHours, currentMinutes, currentSeconds;
802
+
803
+ // get current hours|minutes|seconds
804
+ hours = ytpGetCurrentHours(ytPlayer);
805
+ minutes = ytpGetCurrentMinutes(ytPlayer);
806
+ seconds = ytpGetCurrentSeconds(ytPlayer);
807
+
808
+ // update time container values for current video
809
+ // -------------------------------------------------------------------------
810
+
811
+ // update current duration|hours
812
+ if (hours !== '00') {
813
+ currentHours = document.getElementsByClassName("amplitude-current-hours");
814
+ currentHours[0].innerHTML = hours;
815
+ }
816
+
817
+ // update current duration|minutes
818
+ currentMinutes = document.getElementsByClassName("amplitude-current-minutes");
819
+ currentMinutes[0].innerHTML = minutes;
820
+
821
+ // update duration|seconds
822
+ currentSeconds = document.getElementsByClassName("amplitude-current-seconds");
823
+ currentSeconds[0].innerHTML = seconds;
824
+ }
825
+
826
+ // Reset YTP specific progress data
827
+ // ---------------------------------------------------------------------------
828
+ function resetProgressBarYTP(playerID) {
829
+ if (playerID !== undefined) {
830
+ var progressBar = j1.adapter.amplitude.data.ytPlayers[playerID].progressBar;
831
+ progressBar.value = 0;
832
+ }
833
+ }
834
+
835
+ // Reset YTP specific CURRENT time data
836
+ // ---------------------------------------------------------------------------
837
+ function resetCurrentTimeContainerYTP() {
838
+
839
+ // reset duration|hours
840
+ var currentHours = document.getElementsByClassName("amplitude-current-hours");
841
+ if (currentHours.length) {
842
+ currentHours[0].innerHTML = '00';
843
+ }
844
+
845
+ // reset duration|minutes
846
+ var currentMinutes = document.getElementsByClassName("amplitude-current-minutes");
847
+ currentMinutes[0].innerHTML = '00';
848
+
849
+ // reset duration|seconds
850
+ var currentSeconds = document.getElementsByClassName("amplitude-current-seconds");
851
+ currentSeconds[0].innerHTML = '00';
852
+ }
853
+
854
+
855
+ // ---------------------------------------------------------------------------
856
+ // Mimik Base AJS API functions
857
+ // ---------------------------------------------------------------------------
858
+
859
+ // Seek (skip) video to time specified
860
+ // ---------------------------------------------------------------------------
861
+ function ytpSeekTo(player, time) {
862
+ player.seekTo(time, true);
863
+ } // END ytpSeekTo
864
+
865
+ // Returns the buffered percentage of the playing video
866
+ // ---------------------------------------------------------------------------
867
+ function ytpGetBuffered(player) {
868
+ // to be defined
869
+ }
870
+
871
+ // Returns the active song index (in the songs array, starts by 0)
872
+ // ---------------------------------------------------------------------------
873
+ function ytpGetActiveIndex(playerID) {
874
+ var activeIndex = -1;
875
+
876
+ if (j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex !== undefined) {
877
+ activeIndex = parseInt(j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex);
878
+ }
879
+
880
+ return activeIndex;
881
+ } // END ytpGetActiveIndex
882
+
883
+ // Set the index of the active song (index starts by 0)
884
+ // ---------------------------------------------------------------------------
885
+ function ytpSetActiveIndex(playerID, idx) {
886
+ var success = false;
887
+ var index = parseInt(idx);
888
+
889
+ if (j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex !== undefined) {
890
+ j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = index;
891
+ success = true;
892
+ }
893
+
894
+ return success;
895
+ } // END ytpSetActiveIndex
896
+
897
+ // Returns the percentage of the video played
898
+ // ---------------------------------------------------------------------------
899
+ function ytpGetPlayedPercentage(player) {
900
+ // to be defined
901
+ }
902
+
903
+ // Returns the actual video element
904
+ // ---------------------------------------------------------------------------
905
+ function ytpGetAudio(player) {
906
+ // to be defined
907
+ }
908
+
909
+ // Returns available playback speeds for the player
910
+ // ---------------------------------------------------------------------------
911
+ function ytpGetPlaybackSpeeds(player) {
912
+ // to be defined
913
+ }
914
+
915
+ // Returns the current playback speed for the player
916
+ // ---------------------------------------------------------------------------
917
+ function ytpGetPlaybackSpeed(player) {
918
+ }
919
+
920
+ // Returns the current state of the player
921
+ // ---------------------------------------------------------------------------
922
+ function ytpGetPlayerState(player) {
923
+ // to be defined
924
+ }
925
+
926
+ // Returns the duration of the video
927
+ // ---------------------------------------------------------------------------
928
+ function ytpGetDuration(player) {
929
+ var playerState, duration;
930
+
931
+ playerState = player.getPlayerState();
932
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.BUFFERING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
933
+ duration = player.getDuration();
934
+
935
+ return duration;
936
+ } else {
937
+ return 0;
938
+ }
939
+ } // END ytpGetDuration
940
+
941
+ // Returns the current time of the video played
942
+ // ---------------------------------------------------------------------------
943
+ function ytpGetCurrentTime(player) {
944
+ var currentTime, playerState;
945
+
946
+ if (player !== undefined && player.getPlayerState !== undefined) {
947
+ playerState = player.getPlayerState();
948
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
949
+ currentTime = player.getCurrentTime();
950
+
951
+ return currentTime;
952
+ } else {
953
+ return 0;
954
+ }
955
+ }
956
+ } // END ytpGetCurrentTime
957
+
958
+ // Returns the duration hours of the video
959
+ // ---------------------------------------------------------------------------
960
+ function ytpGetDurationHours(player) {
961
+ var playerState, duration, hours, d, h;
962
+
963
+ if (player !== undefined && player.getPlayerState !== undefined) {
964
+ playerState = player.getPlayerState();
965
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
966
+ duration = ytpGetDuration(player);
967
+ d = Number(duration);
968
+ h = Math.floor(d / 3600);
969
+ hours = h.toString().padStart(2, '0');
970
+
971
+ return hours;
972
+ } else {
973
+ return '00';
974
+ }
975
+ }
976
+ } // END ytpGetDurationHours
977
+
978
+ // Returns the duration minutes of the video
979
+ // ---------------------------------------------------------------------------
980
+ function ytpGetDurationMinutes(player) {
981
+ var playerState, duration, minutes, d, m;
982
+
983
+ if (player !== undefined && player.getPlayerState !== undefined) {
984
+ playerState = player.getPlayerState();
985
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
986
+ duration = ytpGetDuration(player);
987
+ d = Number(duration);
988
+ m = Math.floor(d % 3600 / 60);
989
+ minutes = m.toString().padStart(2, '0');
990
+
991
+ return minutes;
992
+ } else {
993
+ return '00';
994
+ }
995
+ }
996
+ } // END ytpGetDurationMinutes
997
+
998
+ // Returns the duration seconds of the video
999
+ // ---------------------------------------------------------------------------
1000
+ function ytpGetDurationSeconds(player) {
1001
+ var playerState, duration, seconds, d, s;
1002
+
1003
+ if (player !== undefined && player.getPlayerState !== undefined) {
1004
+ playerState = player.getPlayerState();
1005
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
1006
+ duration = ytpGetDuration(player);
1007
+ d = Number(duration);
1008
+ s = Math.floor(d % 60);
1009
+ seconds = s.toString().padStart(2, '0');
1010
+
1011
+ return seconds;
1012
+ } else {
1013
+ return '00';
1014
+ }
1015
+ }
1016
+ } // END ytpGetDurationSeconds
1017
+
1018
+ // Returns the current hours the user is into the video
1019
+ // ---------------------------------------------------------------------------
1020
+ function ytpGetCurrentHours(player) {
1021
+ var playerState, currentTime, hours, d, h;
1022
+
1023
+ if (player !== undefined && player.getPlayerState !== undefined) {
1024
+ playerState = player.getPlayerState();
1025
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1026
+ currentTime = ytpGetCurrentTime(player);
1027
+ d = Number(currentTime);
1028
+ h = Math.floor(d / 3600);
1029
+ hours = h.toString().padStart(2, '0');
1030
+
1031
+ return hours;
1032
+ } else {
1033
+ return '00';
1034
+ }
1035
+ }
1036
+ } // END ytpGetCurrentHours
1037
+
1038
+ // Returns the current minutes the user is into the video
1039
+ // ---------------------------------------------------------------------------
1040
+ function ytpGetCurrentMinutes (player) {
1041
+ var playerState, currentTime, minutes, d, m;
1042
+
1043
+ if (player !== undefined && player.getPlayerState !== undefined) {
1044
+ playerState = player.getPlayerState();
1045
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED) {
1046
+ currentTime = ytpGetCurrentTime(player);
1047
+ d = Number(currentTime);
1048
+ m = Math.floor(d % 3600 / 60);
1049
+ minutes = m.toString().padStart(2, '0');
1050
+
1051
+ return minutes;
1052
+ } else {
1053
+ return '00';
1054
+ }
1055
+ }
1056
+ } // END ytpGetCurrentMinutes
1057
+
1058
+ // Returns the current seconds the user is into the video
1059
+ // ---------------------------------------------------------------------------
1060
+ function ytpGetCurrentSeconds(player) {
1061
+ var playerState, currentTime, seconds, d, s;
1062
+
1063
+ if (player !== undefined && player.getPlayerState !== undefined) {
1064
+ playerState = player.getPlayerState();
1065
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED || playerState === YT_PLAYER_STATE.CUED ) {
1066
+ currentTime = ytpGetCurrentTime(player);
1067
+ d = Number(currentTime);
1068
+ s = Math.floor(d % 60);
1069
+ seconds = s.toString().padStart(2, '0');
1070
+
1071
+ return seconds;
1072
+ } else {
1073
+ return '00';
1074
+ }
1075
+ }
1076
+ } // END ytpGetCurrentSeconds
1077
+
1078
+ // ---------------------------------------------------------------------------
1079
+ // mimikYTPlayerUiEventsForAJS()
1080
+ // Mimik AJS button events for YT video
1081
+ // ---------------------------------------------------------------------------
1082
+ function mimikYTPlayerUiEventsForAJS(ytPlayerID) {
1083
+ if (j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID] !== undefined) {
1084
+ var playerDefaults = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].playerDefaults;
1085
+ var playerSettings = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].playerSettings;
1086
+ var playerButton = `large-player-play-pause-${ytPlayerID}`;
1087
+
1088
+ // -----------------------------------------------------------------------
1089
+ // Large AJS players
1090
+ //
1091
+ if (j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].playerSettings.type === 'large') {
1092
+
1093
+ // Overload AJS play_pause button for YT
1094
+ //
1095
+ var largePlayerPlayPauseButton = document.getElementsByClassName(playerButton);
1096
+ for (var i=0; i<largePlayerPlayPauseButton.length; i++) {
1097
+ var classArray = [].slice.call(largePlayerPlayPauseButton[i].classList, 0);
1098
+ var classString = classArray.toString();
1099
+
1100
+ if (classString.includes(ytPlayerID)) {
1101
+ largePlayerPlayPauseButton[i].addEventListener('click', function(event) {
1102
+ var playlist = this.getAttribute("data-amplitude-playlist");
1103
+ var playerID = playlist + '_large';
1104
+ var ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][playerID]['player'];
1105
+ var songs = j1.adapter.amplitude['data']['ytPlayers'][playerID]['songs'];
1106
+ var activeIndex = parseInt(j1.adapter.amplitude['data']['ytPlayers'][playerID]['activeIndex']);
1107
+ var songMetaData = songs[songIndex];
1108
+ var playPauseButton = `large-player-play-pause-${ytPlayerID}`;
1109
+
1110
+ // toggle YT play|pause video
1111
+ if (ytPlayer.getPlayerState() === YT_PLAYER_STATE.PLAYING || ytPlayer.getPlayerState() === YT_PLAYER_STATE.BUFFERING) {
1112
+ ytPlayer.pauseVideo();
1113
+ } else {
1114
+ ytPlayer.playVideo();
1115
+ }
1116
+
1117
+ // toggle AJS PlayPauseButton
1118
+ var largePlayerPlayPauseButton = document.getElementsByClassName(playPauseButton);
1119
+ if (largePlayerPlayPauseButton[0].classList.contains('amplitude-paused')) {
1120
+ largePlayerPlayPauseButton[0].classList.remove('amplitude-paused');
1121
+ largePlayerPlayPauseButton[0].classList.add('amplitude-playing');
1122
+ } else {
1123
+ largePlayerPlayPauseButton[0].classList.remove('amplitude-playing');
1124
+ largePlayerPlayPauseButton[0].classList.add('amplitude-paused');
1125
+ }
1126
+
1127
+ // don't activate playlist item on FIRST || LAST song
1128
+ // if (songIndex !== 0 && songIndex !== songs.length - 1) {
1129
+ if (songIndex !== songs.length - 1) {
1130
+ // set song active in playlist
1131
+ //setSongPlayed(songIndex);
1132
+ setSongPlayed(playerID, songIndex);
1133
+ }
1134
+
1135
+ // event.preventDefault();
1136
+ event.stopImmediatePropagation(); // deactivate AJS events
1137
+ }); // END EventListener largePlayerPlayPauseButton 'click'
1138
+ } // END if largePlayerPlayPauseButton
1139
+ } // END for largePlayerPlayPauseButton
1140
+
1141
+ // Overload AJS largePlayerSkipBackward button for YT
1142
+ //
1143
+ var largePlayerSkipForwardButtons = document.getElementsByClassName("large-player-skip-forward");
1144
+ for (var i=0; i<largePlayerSkipForwardButtons.length; i++) {
1145
+ var classArray = [].slice.call(largePlayerSkipForwardButtons[i].classList, 0);
1146
+ var classString = classArray.toString();
1147
+
1148
+ // load player settings
1149
+ var playerForwardBackwardSkipSeconds = (playerSettings.forward_backward_skip_seconds === undefined) ? playerDefaults.forward_backward_skip_seconds : playerSettings.forward_backward_skip_seconds;
1150
+
1151
+ // if (largePlayerSkipForwardButtons[i].id === 'skip-forward_' + ytPlayerID) {
1152
+ // if (classString.includes(ytPlayerID)) && largePlayerSkipForwardButtons[i].id === 'skip-forkward_' + ytPlayerID) {
1153
+ if (classString.includes(ytPlayerID)) {
1154
+ largePlayerSkipForwardButtons[i].addEventListener('click', function(event) {
1155
+ var currentTime, playerState, skipOffset, ytPlayer;
1156
+
1157
+ skipOffset = parseFloat(playerForwardBackwardSkipSeconds);
1158
+ ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].player;
1159
+ playerState = ytPlayer.getPlayerState();
1160
+ currentTime = ytPlayer.getCurrentTime();
1161
+
1162
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) {
1163
+ ytPlayer.seekTo(currentTime + skipOffset, true);
1164
+ }
1165
+
1166
+ // deactivate AJS events (if any)
1167
+ event.stopImmediatePropagation();
1168
+ }); // END Listener 'click'
1169
+ } // END if skip-forward button
1170
+ } // END for
1171
+
1172
+ // Overload AJS largePlayerSkipBackward button for YT
1173
+ //
1174
+ var largePlayerSkipBackwardButtons = document.getElementsByClassName("large-player-skip-backward");
1175
+ for (var i=0; i<largePlayerSkipBackwardButtons.length; i++) {
1176
+ var classArray = [].slice.call(largePlayerSkipBackwardButtons[i].classList, 0);
1177
+ var classString = classArray.toString();
1178
+
1179
+ // load player settings
1180
+ var playerForwardBackwardSkipSeconds = (playerSettings.forward_backward_skip_seconds === undefined) ? playerDefaults.forward_backward_skip_seconds : playerSettings.forward_backward_skip_seconds;
1181
+
1182
+ if (classString.includes(ytPlayerID)) {
1183
+ largePlayerSkipBackwardButtons[i].addEventListener('click', function(event) {
1184
+ var currentTime, playerState, skipOffset, ytPlayer;
1185
+
1186
+ skipOffset = parseFloat(playerForwardBackwardSkipSeconds);
1187
+ ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][ytPlayerID].player;
1188
+ playerState = ytPlayer.getPlayerState();
1189
+ currentTime = ytPlayer.getCurrentTime();
1190
+
1191
+ if (playerState === YT_PLAYER_STATE.PLAYING || playerState === YT_PLAYER_STATE.PAUSED) {
1192
+ ytPlayer.seekTo(currentTime - skipOffset, true);
1193
+ }
1194
+
1195
+ // deactivate AJS events (if any)
1196
+ event.stopImmediatePropagation();
1197
+ }); // END Listener 'click'
1198
+ } // END if skip-backward button
1199
+ } // END for
1200
+
1201
+ // click on (player) next button
1202
+ // TODO: Fix for multiple players in page
1203
+ // --------------------------------------------------------------------
1204
+
1205
+ // Overload AJS largePlayerNext button for YT
1206
+ //
1207
+ var largePlayerNextButton = document.getElementsByClassName("large-player-next");
1208
+ for (var i=0; i<largePlayerNextButton.length; i++) {
1209
+ var classArray = [].slice.call(largePlayerNextButton[i].classList, 0);
1210
+ var classString = classArray.toString();
1211
+
1212
+ if (classString.includes(ytPlayerID)) {
1213
+ largePlayerNextButton[i].addEventListener('click', function(event) {
1214
+ var ytpVideoID;
1215
+ var playlist = this.getAttribute("data-amplitude-playlist");
1216
+ var playerID = playlist + '_large';
1217
+ // var songIndex = parseInt(j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex);
1218
+ var songIndex = ytpSongIndex;
1219
+ var songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
1220
+ var ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
1221
+
1222
+ // var songs = j1.adapter.amplitude['data']['ytPlayers'][playerID].songs
1223
+ // var ytPlayer = j1.adapter.amplitude['data']['ytPlayers'][playerID].player;
1224
+
1225
+ // if (songIndex < songs.length) {
1226
+ if (songIndex < songs.length-1) {
1227
+ // set song on next item
1228
+ songIndex++;
1229
+ ytpSongIndex = songIndex;
1230
+
1231
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1232
+ }
1233
+ // else {
1234
+ // songIndex--;
1235
+ // }
1236
+
1237
+ // collect (next) song data
1238
+ // if (songIndex < songs.length) {
1239
+ if (songIndex < songs.length-1) {
1240
+ songMetaData = songs[songIndex];
1241
+ songURL = songMetaData.url;
1242
+ ytpVideoID = songURL.split('=')[1];
1243
+ } else {
1244
+ songIndex = 0;
1245
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1246
+ songMetaData = songs[songIndex];
1247
+ songURL = songMetaData.url;
1248
+ ytpVideoID = songURL.split('=')[1];
1249
+ }
1250
+
1251
+ // pause song (video) if FIRST item reached
1252
+ // TODO: handle on player|shuffle different (do play)
1253
+ if (songMetaData.index === 0) {
1254
+
1255
+ // continue (paused) on FIRST video
1256
+ if (ytPlayer !== undefined) {
1257
+ ytPlayer.loadVideoById(ytpVideoID);
1258
+
1259
+ // wait some time to make sure video is loaded|active
1260
+ setTimeout(() => {
1261
+ ytPlayer.pauseVideo();
1262
+ // reset|update time settings
1263
+ resetCurrentTimeContainerYTP();
1264
+ updateDurationTimeContainerYTP(ytPlayer);
1265
+ // resetProgressBarYTP(playerID);
1266
+
1267
+ // update AJS play_pause button
1268
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1269
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1270
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1271
+ }, 300);
1272
+ }
1273
+ } else {
1274
+ // load NEXT video if available
1275
+ if (ytPlayer !== undefined) {
1276
+ ytPlayer.loadVideoById(ytpVideoID);
1277
+
1278
+ // update AJS play_pause button (set playing)
1279
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1280
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1281
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1282
+ } else {
1283
+ // update AJS play_pause button (set paused)
1284
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1285
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1286
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1287
+ }
1288
+ }
1289
+
1290
+ // reset|update current time settings
1291
+ resetCurrentTimeContainerYTP();
1292
+ updateDurationTimeContainerYTP(ytPlayer);
1293
+
1294
+ // load cover image for next video
1295
+ var coverImage;
1296
+ var selector = ".cover-image-" + playlist;
1297
+ coverImage = document.querySelector(selector);
1298
+ coverImage.src = songMetaData.cover_art_url;
1299
+
1300
+ // replace new song name (meta-container)
1301
+ var songName = document.getElementsByClassName("song-name");
1302
+ songName[0].innerHTML = songMetaData.name; // player-bottom
1303
+ songName[1].innerHTML = songMetaData.name; // playlist-screen
1304
+
1305
+ // replace song rating (playlist-screen|meta-container)
1306
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
1307
+ if (largetPlayerSongAudioRating.length) {
1308
+ if (songMetaData.rating) {
1309
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
1310
+ } else {
1311
+ largetPlayerSongAudioRating[0].innerHTML = '';
1312
+ }
1313
+ } // END if largetPlayerSongAudioRating
1314
+
1315
+ // replace artist name in meta-containers for next video
1316
+ var artistName = document.getElementsByClassName("artist");
1317
+ artistName[0].innerHTML = songMetaData.artist;
1318
+
1319
+ // replace album name in meta-containers for next video
1320
+ var albumName = document.getElementsByClassName("album");
1321
+ albumName[0].innerHTML = songMetaData.album;
1322
+
1323
+ // update AJS play_pause button
1324
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1325
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1326
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1327
+
1328
+ // if (songIndex < songs.length) {
1329
+ if (songIndex < songs.length-1) {
1330
+ // set song active in playlist
1331
+ // setSongPlayed(songIndex);
1332
+ setSongPlayed(playerID, songIndex);
1333
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1334
+ }
1335
+
1336
+ // deactivate AJS events (if any)
1337
+ event.stopImmediatePropagation();
1338
+ }); // END EventListener 'click' next button
1339
+ } // END if
1340
+ } // END for largePlayerNextButton
1341
+
1342
+ // click on (player) previous button
1343
+ // TODO: Fix for multiple players in page
1344
+ // -----------------------------------------------------------------------
1345
+
1346
+ // Overload AJS largePlayerPrevious button for YT
1347
+ //
1348
+ var largePlayePreviousButton = document.getElementsByClassName("large-player-previous");
1349
+ for (var i=0; i<largePlayePreviousButton.length; i++) {
1350
+ var classArray = [].slice.call(largePlayerNextButton[i].classList, 0);
1351
+ var classString = classArray.toString();
1352
+
1353
+ if (classString.includes(ytPlayerID)) {
1354
+ largePlayePreviousButton[i].addEventListener('click', function(event) {
1355
+ var ytpVideoID;
1356
+ var playlist = this.getAttribute("data-amplitude-playlist");
1357
+ var playerID = playlist + '_large';
1358
+ // var songIndex = parseInt(j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex);
1359
+ var songIndex = ytpSongIndex;
1360
+ var songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
1361
+ var ytPlayer = j1.adapter.amplitude.data.ytPlayers[playerID].player;
1362
+
1363
+ if (songIndex < songs.length-1) {
1364
+ // set song on previous item
1365
+ songIndex--;
1366
+ ytpSongIndex = songIndex;
1367
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1368
+ }
1369
+
1370
+ // collect (next) song data
1371
+ if (songIndex > 0 && songIndex < songs.length) {
1372
+ songMetaData = songs[songIndex];
1373
+ songIndex = songMetaData.index;
1374
+ songURL = songMetaData.url;
1375
+ ytpSongIndex = songMetaData.index;
1376
+ ytpVideoID = songURL.split('=')[1];
1377
+ } else {
1378
+ songIndex = 0;
1379
+ ytpSongIndex = 0;
1380
+ // j1.adapter.amplitude.data.ytPlayers[playerID].activeIndex = songIndex;
1381
+ songMetaData = songs[songIndex];
1382
+ songURL = songMetaData.url;
1383
+ ytpSongIndex = songIndex;
1384
+ ytpVideoID = songURL.split('=')[1];
1385
+ }
1386
+
1387
+ // save YT player data for later use (e.g. events)
1388
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
1389
+
1390
+ // pause song (video) if FIRST item reached
1391
+ // TODO: handle on player|shuffle different (do play)
1392
+ if (songMetaData.index === 0) {
1393
+ ytpSongIndex = 0;
1394
+
1395
+ // continue (paused) on FIRST video
1396
+ if (ytPlayer !== undefined) {
1397
+ ytPlayer.loadVideoById(ytpVideoID);
1398
+
1399
+ // wait some time to make sure video is loaded|active
1400
+ setTimeout(() => {
1401
+ ytPlayer.pauseVideo();
1402
+ // reset|update time settings
1403
+ resetCurrentTimeContainerYTP();
1404
+ updateDurationTimeContainerYTP(ytPlayer);
1405
+ resetProgressBarYTP(playerID);
1406
+
1407
+ // update AJS play_pause button
1408
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1409
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1410
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1411
+ }, 300);
1412
+ }
1413
+ } else {
1414
+ // load NEXT video if available
1415
+ if (ytPlayer !== undefined) {
1416
+ ytPlayer.loadVideoById(ytpVideoID);
1417
+
1418
+ // update AJS play_pause button (set playing)
1419
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1420
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1421
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1422
+ } else {
1423
+ // update AJS play_pause button (set paused)
1424
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1425
+ largePlayerPlayPauseButton.classList.remove('amplitude-playing');
1426
+ largePlayerPlayPauseButton.classList.add('amplitude-paused');
1427
+ }
1428
+ }
1429
+
1430
+ // reset|update current time settings
1431
+ resetCurrentTimeContainerYTP();
1432
+ updateDurationTimeContainerYTP(ytPlayer);
1433
+
1434
+ // replace new song name (meta-container)
1435
+ var songName = document.getElementsByClassName("song-name");
1436
+ songName[0].innerHTML = songMetaData.name; // player-bottom
1437
+ songName[1].innerHTML = songMetaData.name; // playlist-screen
1438
+
1439
+ // load cover image for next video
1440
+ var coverImage;
1441
+ var selector = ".cover-image-" + playlist;
1442
+ coverImage = document.querySelector(selector);
1443
+ coverImage.src = songMetaData.cover_art_url;
1444
+
1445
+ // replace song rating (playlist-screen|meta-container)
1446
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
1447
+ if (largetPlayerSongAudioRating.length) {
1448
+ if (songMetaData.rating) {
1449
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
1450
+ } else {
1451
+ largetPlayerSongAudioRating[0].innerHTML = '';
1452
+ }
1453
+ } // END if largetPlayerSongAudioRating
1454
+
1455
+ // replace artist name in meta-containers for next video
1456
+ var artistName = document.getElementsByClassName("artist");
1457
+ artistName[0].innerHTML = songMetaData.artist;
1458
+
1459
+ // replace album name in meta-containers for next video
1460
+ var albumName = document.getElementsByClassName("album");
1461
+ albumName[0].innerHTML = songMetaData.album;
1462
+
1463
+ // update AJS play_pause button
1464
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1465
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1466
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1467
+
1468
+ // on LAST item, don't activate item in playlist
1469
+ if (songIndex !== songs.length - 1) {
1470
+ // set song active in playlist
1471
+ // setSongPlayed(songIndex);
1472
+ setSongPlayed(playerID, songIndex);
1473
+ }
1474
+
1475
+ // set song active in playlist
1476
+ // setSongPlayed(songIndex);
1477
+ // setSongPlayed(playerID, songIndex);
1478
+
1479
+ // deactivate AJS events (if any)
1480
+ event.stopImmediatePropagation();
1481
+ }); // END EventListener 'click' previous button
1482
+ } // END if
1483
+ } // END for
1484
+
1485
+ // click on song container
1486
+ // TODO: Fix for multiple players in page
1487
+ // ---------------------------------------------------------------------
1488
+ var largetPlayerSongContainer = document.getElementsByClassName("amplitude-song-container");
1489
+ for (var i=0; i<largetPlayerSongContainer.length; i++) {
1490
+ var classArray = [].slice.call(largetPlayerSongContainer[i].classList, 0);
1491
+ var classString = classArray.toString();
1492
+
1493
+ if (classString.includes(ytPlayerID)) {
1494
+ largetPlayerSongContainer[i].addEventListener('click', function(event) {
1495
+ var ytpVideoID;
1496
+ var activeSongIndex;
1497
+ var success;
1498
+
1499
+ var playlist = this.getAttribute("data-amplitude-playlist");
1500
+ var playerID = playlist + '_large';
1501
+ // var ytpSongIndex = parseInt(this.getAttribute("data-amplitude-song-index"));
1502
+ var songs = j1.adapter.amplitude.data.ytPlayers[playerID].songs;
1503
+
1504
+ // update global song index
1505
+ ytpSongIndex = parseInt(this.getAttribute("data-amplitude-song-index"));
1506
+
1507
+ // get active song index if video (song) is playing
1508
+ activeSongIndex = getSongPlayed();
1509
+
1510
+ // if (activeSongIndex >= 0) {
1511
+ // success = ytpSetActiveIndex(playerID, activeSongIndex);
1512
+ // } else {
1513
+ // success = ytpSetActiveIndex(playerID, ytpSongIndex);
1514
+ // }
1515
+
1516
+ // save YT player data for later use (e.g. events)
1517
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerSongs'] = songs;
1518
+ // j1.adapter.amplitude.data.ytpGlobals['ytpSongIndex'] = ytpSongIndex;
1519
+
1520
+ var playerState = ytPlayer.getPlayerState();
1521
+ if (playerState === YT_PLAYER_STATE.PLAYING && ytpSongIndex === activeSongIndex) {
1522
+ // do NOT interupt current video (song) is playing
1523
+ return;
1524
+ } else {
1525
+ // set (current) song data
1526
+ songMetaData = songs[ytpSongIndex];
1527
+ songIndex = songMetaData.index;
1528
+ songURL = songMetaData.url;
1529
+ ytpSongIndex = songIndex;
1530
+ ytpVideoID = songURL.split('=')[1];
1531
+ // load new video
1532
+ ytPlayer.loadVideoById(ytpVideoID);
1533
+ }
1534
+
1535
+ // reset|update current time settings
1536
+ resetCurrentTimeContainerYTP();
1537
+ updateDurationTimeContainerYTP(ytPlayer);
1538
+
1539
+ // load cover image for next video
1540
+ var coverImage;
1541
+ var selector = ".cover-image-" + playlist;
1542
+ coverImage = document.querySelector(selector);
1543
+ coverImage.src = songMetaData.cover_art_url;
1544
+
1545
+ // replace new song name (meta-container)
1546
+ var songName = document.getElementsByClassName("song-name");
1547
+ songName[0].innerHTML = songMetaData.name; // player-bottom
1548
+ songName[1].innerHTML = songMetaData.name; // playlist-screen
1549
+
1550
+ // replace song info URL (playlist-screen|meta-container)
1551
+ var largetPlayerSongInfoLink = document.getElementsByClassName("audio-info-link");
1552
+ if (largetPlayerSongInfoLink.length) {
1553
+ if (songMetaData.audio_info) {
1554
+ largetPlayerSongInfoLink[0].href = songMetaData.audio_info;
1555
+ } else {
1556
+ largetPlayerSongInfoLink[0].href = songURL;
1557
+ }
1558
+ } // END if largetPlayerSongInfoLink
1559
+
1560
+ // replace song rating (playlist-screen|meta-container)
1561
+ var largetPlayerSongAudioRating = document.getElementsByClassName("audio-rating");
1562
+ if (largetPlayerSongAudioRating.length) {
1563
+ if (songMetaData.rating) {
1564
+ largetPlayerSongAudioRating[0].innerHTML = songMetaData.rating + ' <i class="mdib mdib-star md-gray-400 mdib-18px"></i>';
1565
+ } else {
1566
+ largetPlayerSongAudioRating[0].innerHTML = '';
1567
+ }
1568
+ } // END if largetPlayerSongAudioRating
1569
+
1570
+ // update AJS play_pause button
1571
+ var largePlayerPlayPauseButton = document.getElementById('large_player_play_pause');
1572
+ largePlayerPlayPauseButton.classList.remove('amplitude-paused');
1573
+ largePlayerPlayPauseButton.classList.add('amplitude-playing');
1574
+
1575
+ // set song active in playlist
1576
+ // if (event.currentTarget.className.includes(ytPlayerID)) {
1577
+ // setSongPlayed(songIndex);
1578
+ // }
1579
+
1580
+ // set song active in playlist
1581
+ setSongPlayed(ytPlayerID, songIndex);
1582
+
1583
+ // do NOT bubble up
1584
+ event.stopPropagation();
1585
+
1586
+ // deactivate AJS events (if any)
1587
+ event.stopImmediatePropagation();
1588
+ }); // END EventListener 'click' SongContainer
1589
+ } // END if
1590
+ } // END for
1591
+
1592
+ // add listeners to all progress bars found
1593
+ // TODO: Fix for multiple players in page
1594
+ // ---------------------------------------------------------------------
1595
+ var progressBars = document.getElementsByClassName("large-player-progress");
1596
+ if (progressBars.length) {
1597
+ for (var i=0; i<progressBars.length; i++) {
1598
+ var progressBar = progressBars[i];
1599
+ // var id = bar.id.split('large-player-progress_')[0];
1600
+ // var progressId = progressBars[i].id.split('large-player-progress_')[0];
1601
+ var progressId = progressBars[i].id;
1602
+ var playerId = progressId.split('large_player_progress_')[1];
1603
+
1604
+ // save YT player data for later use (e.g. events)
1605
+ // j1.adapter.amplitude.data.ytpGlobals['ytPlayerProgressBar'] = progressBars[i];
1606
+ // j1.adapter.amplitude.data.ytPlayers[playerId].progressBar = progressId;
1607
+ j1.adapter.amplitude.data.ytPlayers[playerId].progressBar = progressBar;
1608
+
1609
+ progressBars[i].addEventListener('click', function(event) {
1610
+ // if (ytPlayer.getPlayerState() === YT_PLAYER_STATE.PLAYING) {
1611
+ if (ytPlayer !== undefined) {
1612
+ var progressBar, percentage, time;
1613
+ progressBar = this;
1614
+ percentage = getProgressBarSelectedPositionPercentage(event, progressBar);
1615
+ time = getTimeFromPercentage(ytPlayer, percentage);
1616
+
1617
+ // seek video to current time
1618
+ ytpSeekTo(ytPlayer, time);
1619
+
1620
+ // set current progess value if valid
1621
+ if (isFinite(percentage)) {
1622
+ progressBar.value = percentage;
1623
+ }
1624
+ } // END if ytPlayer
1625
+
1626
+ // deactivate AJS events (if any)
1627
+ event.stopImmediatePropagation();
1628
+ }); // END EventListener 'click'
1629
+ } // END for
1630
+ } // END if progressBars
1631
+
1632
+ } // END if playerType large'
1633
+ }
1634
+ } // END mimikYTPlayerUiEventsForAJS
1635
+
1636
+ {%- endcapture -%}
1637
+
1638
+ {%- if production -%}
1639
+ {{ cache|minifyJS }}
1640
+ {%- else -%}
1641
+ {{ cache|strip_empty_lines }}
1642
+ {%- endif -%}
1643
+
1644
+ {%- assign cache = false -%}