@projektemacher/storymapjs 0.10.6 → 0.10.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/CHANGELOG +358 -16
  2. package/README.md +43 -9
  3. package/dist/assets/demo-DBpeF31K.js +1 -0
  4. package/dist/assets/harness-Cr0rYpvt.js +1 -0
  5. package/dist/assets/harness-multi-CYHgI0a9.js +1 -0
  6. package/dist/assets/harness-support-Do7sIp2j.js +1 -0
  7. package/dist/assets/index-wHPqGrBS.js +1 -0
  8. package/dist/assets/main-DXalctuR.js +17 -0
  9. package/dist/context.json +12 -9
  10. package/dist/css/fonts/files/amatic-sc-cyrillic-400-normal.woff2 +0 -0
  11. package/dist/css/fonts/files/amatic-sc-cyrillic-700-normal.woff2 +0 -0
  12. package/dist/css/fonts/files/amatic-sc-hebrew-400-normal.woff2 +0 -0
  13. package/dist/css/fonts/files/amatic-sc-hebrew-700-normal.woff2 +0 -0
  14. package/dist/css/fonts/files/amatic-sc-vietnamese-400-normal.woff2 +0 -0
  15. package/dist/css/fonts/files/amatic-sc-vietnamese-700-normal.woff2 +0 -0
  16. package/dist/css/fonts/files/bitter-cyrillic-100-italic.woff2 +0 -0
  17. package/dist/css/fonts/files/bitter-cyrillic-100-normal.woff2 +0 -0
  18. package/dist/css/fonts/files/bitter-cyrillic-200-italic.woff2 +0 -0
  19. package/dist/css/fonts/files/bitter-cyrillic-200-normal.woff2 +0 -0
  20. package/dist/css/fonts/files/bitter-cyrillic-300-italic.woff2 +0 -0
  21. package/dist/css/fonts/files/bitter-cyrillic-300-normal.woff2 +0 -0
  22. package/dist/css/fonts/files/bitter-cyrillic-400-italic.woff2 +0 -0
  23. package/dist/css/fonts/files/bitter-cyrillic-400-normal.woff2 +0 -0
  24. package/dist/css/fonts/files/bitter-cyrillic-500-italic.woff2 +0 -0
  25. package/dist/css/fonts/files/bitter-cyrillic-500-normal.woff2 +0 -0
  26. package/dist/css/fonts/files/bitter-cyrillic-600-italic.woff2 +0 -0
  27. package/dist/css/fonts/files/bitter-cyrillic-600-normal.woff2 +0 -0
  28. package/dist/css/fonts/files/bitter-cyrillic-700-italic.woff2 +0 -0
  29. package/dist/css/fonts/files/bitter-cyrillic-700-normal.woff2 +0 -0
  30. package/dist/css/fonts/files/bitter-cyrillic-800-italic.woff2 +0 -0
  31. package/dist/css/fonts/files/bitter-cyrillic-800-normal.woff2 +0 -0
  32. package/dist/css/fonts/files/bitter-cyrillic-900-italic.woff2 +0 -0
  33. package/dist/css/fonts/files/bitter-cyrillic-900-normal.woff2 +0 -0
  34. package/dist/css/fonts/files/bitter-cyrillic-ext-100-italic.woff2 +0 -0
  35. package/dist/css/fonts/files/bitter-cyrillic-ext-100-normal.woff2 +0 -0
  36. package/dist/css/fonts/files/bitter-cyrillic-ext-200-italic.woff2 +0 -0
  37. package/dist/css/fonts/files/bitter-cyrillic-ext-200-normal.woff2 +0 -0
  38. package/dist/css/fonts/files/bitter-cyrillic-ext-300-italic.woff2 +0 -0
  39. package/dist/css/fonts/files/bitter-cyrillic-ext-300-normal.woff2 +0 -0
  40. package/dist/css/fonts/files/bitter-cyrillic-ext-400-italic.woff2 +0 -0
  41. package/dist/css/fonts/files/bitter-cyrillic-ext-400-normal.woff2 +0 -0
  42. package/dist/css/fonts/files/bitter-cyrillic-ext-500-italic.woff2 +0 -0
  43. package/dist/css/fonts/files/bitter-cyrillic-ext-500-normal.woff2 +0 -0
  44. package/dist/css/fonts/files/bitter-cyrillic-ext-600-italic.woff2 +0 -0
  45. package/dist/css/fonts/files/bitter-cyrillic-ext-600-normal.woff2 +0 -0
  46. package/dist/css/fonts/files/bitter-cyrillic-ext-700-italic.woff2 +0 -0
  47. package/dist/css/fonts/files/bitter-cyrillic-ext-700-normal.woff2 +0 -0
  48. package/dist/css/fonts/files/bitter-cyrillic-ext-800-italic.woff2 +0 -0
  49. package/dist/css/fonts/files/bitter-cyrillic-ext-800-normal.woff2 +0 -0
  50. package/dist/css/fonts/files/bitter-cyrillic-ext-900-italic.woff2 +0 -0
  51. package/dist/css/fonts/files/bitter-cyrillic-ext-900-normal.woff2 +0 -0
  52. package/dist/css/fonts/files/bitter-cyrillic-ext-wght-italic.woff2 +0 -0
  53. package/dist/css/fonts/files/bitter-cyrillic-ext-wght-normal.woff2 +0 -0
  54. package/dist/css/fonts/files/bitter-cyrillic-wght-italic.woff2 +0 -0
  55. package/dist/css/fonts/files/bitter-cyrillic-wght-normal.woff2 +0 -0
  56. package/dist/css/fonts/files/bitter-vietnamese-100-italic.woff2 +0 -0
  57. package/dist/css/fonts/files/bitter-vietnamese-100-normal.woff2 +0 -0
  58. package/dist/css/fonts/files/bitter-vietnamese-200-italic.woff2 +0 -0
  59. package/dist/css/fonts/files/bitter-vietnamese-200-normal.woff2 +0 -0
  60. package/dist/css/fonts/files/bitter-vietnamese-300-italic.woff2 +0 -0
  61. package/dist/css/fonts/files/bitter-vietnamese-300-normal.woff2 +0 -0
  62. package/dist/css/fonts/files/bitter-vietnamese-400-italic.woff2 +0 -0
  63. package/dist/css/fonts/files/bitter-vietnamese-400-normal.woff2 +0 -0
  64. package/dist/css/fonts/files/bitter-vietnamese-500-italic.woff2 +0 -0
  65. package/dist/css/fonts/files/bitter-vietnamese-500-normal.woff2 +0 -0
  66. package/dist/css/fonts/files/bitter-vietnamese-600-italic.woff2 +0 -0
  67. package/dist/css/fonts/files/bitter-vietnamese-600-normal.woff2 +0 -0
  68. package/dist/css/fonts/files/bitter-vietnamese-700-italic.woff2 +0 -0
  69. package/dist/css/fonts/files/bitter-vietnamese-700-normal.woff2 +0 -0
  70. package/dist/css/fonts/files/bitter-vietnamese-800-italic.woff2 +0 -0
  71. package/dist/css/fonts/files/bitter-vietnamese-800-normal.woff2 +0 -0
  72. package/dist/css/fonts/files/bitter-vietnamese-900-italic.woff2 +0 -0
  73. package/dist/css/fonts/files/bitter-vietnamese-900-normal.woff2 +0 -0
  74. package/dist/css/fonts/files/bitter-vietnamese-wght-italic.woff2 +0 -0
  75. package/dist/css/fonts/files/bitter-vietnamese-wght-normal.woff2 +0 -0
  76. package/dist/css/fonts/files/cairo-arabic-200-normal.woff2 +0 -0
  77. package/dist/css/fonts/files/cairo-arabic-300-normal.woff2 +0 -0
  78. package/dist/css/fonts/files/cairo-arabic-400-normal.woff2 +0 -0
  79. package/dist/css/fonts/files/cairo-arabic-500-normal.woff2 +0 -0
  80. package/dist/css/fonts/files/cairo-arabic-600-normal.woff2 +0 -0
  81. package/dist/css/fonts/files/cairo-arabic-700-normal.woff2 +0 -0
  82. package/dist/css/fonts/files/cairo-arabic-800-normal.woff2 +0 -0
  83. package/dist/css/fonts/files/cairo-arabic-900-normal.woff2 +0 -0
  84. package/dist/css/fonts/files/cairo-latin-200-normal.woff2 +0 -0
  85. package/dist/css/fonts/files/cairo-latin-300-normal.woff2 +0 -0
  86. package/dist/css/fonts/files/cairo-latin-400-normal.woff2 +0 -0
  87. package/dist/css/fonts/files/cairo-latin-500-normal.woff2 +0 -0
  88. package/dist/css/fonts/files/cairo-latin-600-normal.woff2 +0 -0
  89. package/dist/css/fonts/files/cairo-latin-700-normal.woff2 +0 -0
  90. package/dist/css/fonts/files/cairo-latin-800-normal.woff2 +0 -0
  91. package/dist/css/fonts/files/cairo-latin-900-normal.woff2 +0 -0
  92. package/dist/css/fonts/files/cairo-latin-ext-200-normal.woff2 +0 -0
  93. package/dist/css/fonts/files/cairo-latin-ext-300-normal.woff2 +0 -0
  94. package/dist/css/fonts/files/cairo-latin-ext-400-normal.woff2 +0 -0
  95. package/dist/css/fonts/files/cairo-latin-ext-500-normal.woff2 +0 -0
  96. package/dist/css/fonts/files/cairo-latin-ext-600-normal.woff2 +0 -0
  97. package/dist/css/fonts/files/cairo-latin-ext-700-normal.woff2 +0 -0
  98. package/dist/css/fonts/files/cairo-latin-ext-800-normal.woff2 +0 -0
  99. package/dist/css/fonts/files/cairo-latin-ext-900-normal.woff2 +0 -0
  100. package/dist/css/fonts/files/dancing-script-vietnamese-wght-normal.woff2 +0 -0
  101. package/dist/css/fonts/files/eb-garamond-cyrillic-ext-wght-italic.woff2 +0 -0
  102. package/dist/css/fonts/files/eb-garamond-cyrillic-ext-wght-normal.woff2 +0 -0
  103. package/dist/css/fonts/files/eb-garamond-cyrillic-wght-italic.woff2 +0 -0
  104. package/dist/css/fonts/files/eb-garamond-cyrillic-wght-normal.woff2 +0 -0
  105. package/dist/css/fonts/files/eb-garamond-greek-ext-wght-italic.woff2 +0 -0
  106. package/dist/css/fonts/files/eb-garamond-greek-ext-wght-normal.woff2 +0 -0
  107. package/dist/css/fonts/files/eb-garamond-greek-wght-italic.woff2 +0 -0
  108. package/dist/css/fonts/files/eb-garamond-greek-wght-normal.woff2 +0 -0
  109. package/dist/css/fonts/files/eb-garamond-vietnamese-wght-italic.woff2 +0 -0
  110. package/dist/css/fonts/files/eb-garamond-vietnamese-wght-normal.woff2 +0 -0
  111. package/dist/css/fonts/files/gentium-book-plus-cyrillic-400-italic.woff2 +0 -0
  112. package/dist/css/fonts/files/gentium-book-plus-cyrillic-400-normal.woff2 +0 -0
  113. package/dist/css/fonts/files/gentium-book-plus-cyrillic-700-italic.woff2 +0 -0
  114. package/dist/css/fonts/files/gentium-book-plus-cyrillic-700-normal.woff2 +0 -0
  115. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-400-italic.woff2 +0 -0
  116. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-400-normal.woff2 +0 -0
  117. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-700-italic.woff2 +0 -0
  118. package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-700-normal.woff2 +0 -0
  119. package/dist/css/fonts/files/gentium-book-plus-greek-400-italic.woff2 +0 -0
  120. package/dist/css/fonts/files/gentium-book-plus-greek-400-normal.woff2 +0 -0
  121. package/dist/css/fonts/files/gentium-book-plus-greek-700-italic.woff2 +0 -0
  122. package/dist/css/fonts/files/gentium-book-plus-greek-700-normal.woff2 +0 -0
  123. package/dist/css/fonts/files/gentium-book-plus-greek-ext-400-italic.woff2 +0 -0
  124. package/dist/css/fonts/files/gentium-book-plus-greek-ext-400-normal.woff2 +0 -0
  125. package/dist/css/fonts/files/gentium-book-plus-greek-ext-700-italic.woff2 +0 -0
  126. package/dist/css/fonts/files/gentium-book-plus-greek-ext-700-normal.woff2 +0 -0
  127. package/dist/css/fonts/files/gentium-book-plus-vietnamese-400-italic.woff2 +0 -0
  128. package/dist/css/fonts/files/gentium-book-plus-vietnamese-400-normal.woff2 +0 -0
  129. package/dist/css/fonts/files/gentium-book-plus-vietnamese-700-italic.woff2 +0 -0
  130. package/dist/css/fonts/files/gentium-book-plus-vietnamese-700-normal.woff2 +0 -0
  131. package/dist/css/fonts/files/old-standard-tt-cyrillic-400-italic.woff2 +0 -0
  132. package/dist/css/fonts/files/old-standard-tt-cyrillic-400-normal.woff2 +0 -0
  133. package/dist/css/fonts/files/old-standard-tt-cyrillic-700-normal.woff2 +0 -0
  134. package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-400-italic.woff2 +0 -0
  135. package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-400-normal.woff2 +0 -0
  136. package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-700-normal.woff2 +0 -0
  137. package/dist/css/fonts/files/old-standard-tt-vietnamese-400-italic.woff2 +0 -0
  138. package/dist/css/fonts/files/old-standard-tt-vietnamese-400-normal.woff2 +0 -0
  139. package/dist/css/fonts/files/old-standard-tt-vietnamese-700-normal.woff2 +0 -0
  140. package/dist/css/fonts/files/open-sans-cyrillic-ext-wght-italic.woff2 +0 -0
  141. package/dist/css/fonts/files/open-sans-cyrillic-ext-wght-normal.woff2 +0 -0
  142. package/dist/css/fonts/files/open-sans-cyrillic-wght-italic.woff2 +0 -0
  143. package/dist/css/fonts/files/open-sans-cyrillic-wght-normal.woff2 +0 -0
  144. package/dist/css/fonts/files/open-sans-greek-ext-wght-italic.woff2 +0 -0
  145. package/dist/css/fonts/files/open-sans-greek-ext-wght-normal.woff2 +0 -0
  146. package/dist/css/fonts/files/open-sans-greek-wght-italic.woff2 +0 -0
  147. package/dist/css/fonts/files/open-sans-greek-wght-normal.woff2 +0 -0
  148. package/dist/css/fonts/files/open-sans-hebrew-wght-italic.woff2 +0 -0
  149. package/dist/css/fonts/files/open-sans-hebrew-wght-normal.woff2 +0 -0
  150. package/dist/css/fonts/files/open-sans-vietnamese-wght-italic.woff2 +0 -0
  151. package/dist/css/fonts/files/open-sans-vietnamese-wght-normal.woff2 +0 -0
  152. package/dist/css/fonts/files/playfair-display-cyrillic-wght-italic.woff2 +0 -0
  153. package/dist/css/fonts/files/playfair-display-cyrillic-wght-normal.woff2 +0 -0
  154. package/dist/css/fonts/files/playfair-display-sc-cyrillic-400-italic.woff2 +0 -0
  155. package/dist/css/fonts/files/playfair-display-sc-cyrillic-400-normal.woff2 +0 -0
  156. package/dist/css/fonts/files/playfair-display-sc-cyrillic-700-italic.woff2 +0 -0
  157. package/dist/css/fonts/files/playfair-display-sc-cyrillic-700-normal.woff2 +0 -0
  158. package/dist/css/fonts/files/playfair-display-sc-cyrillic-900-italic.woff2 +0 -0
  159. package/dist/css/fonts/files/playfair-display-sc-cyrillic-900-normal.woff2 +0 -0
  160. package/dist/css/fonts/files/playfair-display-sc-vietnamese-400-italic.woff2 +0 -0
  161. package/dist/css/fonts/files/playfair-display-sc-vietnamese-400-normal.woff2 +0 -0
  162. package/dist/css/fonts/files/playfair-display-sc-vietnamese-700-italic.woff2 +0 -0
  163. package/dist/css/fonts/files/playfair-display-sc-vietnamese-700-normal.woff2 +0 -0
  164. package/dist/css/fonts/files/playfair-display-sc-vietnamese-900-italic.woff2 +0 -0
  165. package/dist/css/fonts/files/playfair-display-sc-vietnamese-900-normal.woff2 +0 -0
  166. package/dist/css/fonts/files/playfair-display-vietnamese-wght-italic.woff2 +0 -0
  167. package/dist/css/fonts/files/playfair-display-vietnamese-wght-normal.woff2 +0 -0
  168. package/dist/css/fonts/files/pt-sans-cyrillic-400-italic.woff2 +0 -0
  169. package/dist/css/fonts/files/pt-sans-cyrillic-400-normal.woff2 +0 -0
  170. package/dist/css/fonts/files/pt-sans-cyrillic-700-italic.woff2 +0 -0
  171. package/dist/css/fonts/files/pt-sans-cyrillic-700-normal.woff2 +0 -0
  172. package/dist/css/fonts/files/pt-sans-cyrillic-ext-400-italic.woff2 +0 -0
  173. package/dist/css/fonts/files/pt-sans-cyrillic-ext-400-normal.woff2 +0 -0
  174. package/dist/css/fonts/files/pt-sans-cyrillic-ext-700-italic.woff2 +0 -0
  175. package/dist/css/fonts/files/pt-sans-cyrillic-ext-700-normal.woff2 +0 -0
  176. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-400-normal.woff2 +0 -0
  177. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-700-normal.woff2 +0 -0
  178. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-ext-400-normal.woff2 +0 -0
  179. package/dist/css/fonts/files/pt-sans-narrow-cyrillic-ext-700-normal.woff2 +0 -0
  180. package/dist/css/fonts/files/pt-serif-cyrillic-400-italic.woff2 +0 -0
  181. package/dist/css/fonts/files/pt-serif-cyrillic-400-normal.woff2 +0 -0
  182. package/dist/css/fonts/files/pt-serif-cyrillic-700-italic.woff2 +0 -0
  183. package/dist/css/fonts/files/pt-serif-cyrillic-700-normal.woff2 +0 -0
  184. package/dist/css/fonts/files/pt-serif-cyrillic-ext-400-italic.woff2 +0 -0
  185. package/dist/css/fonts/files/pt-serif-cyrillic-ext-400-normal.woff2 +0 -0
  186. package/dist/css/fonts/files/pt-serif-cyrillic-ext-700-italic.woff2 +0 -0
  187. package/dist/css/fonts/files/pt-serif-cyrillic-ext-700-normal.woff2 +0 -0
  188. package/dist/css/fonts/files/raleway-cyrillic-ext-wght-italic.woff2 +0 -0
  189. package/dist/css/fonts/files/raleway-cyrillic-ext-wght-normal.woff2 +0 -0
  190. package/dist/css/fonts/files/raleway-cyrillic-wght-italic.woff2 +0 -0
  191. package/dist/css/fonts/files/raleway-cyrillic-wght-normal.woff2 +0 -0
  192. package/dist/css/fonts/files/raleway-vietnamese-wght-italic.woff2 +0 -0
  193. package/dist/css/fonts/files/raleway-vietnamese-wght-normal.woff2 +0 -0
  194. package/dist/css/fonts/files/roboto-slab-cyrillic-ext-wght-normal.woff2 +0 -0
  195. package/dist/css/fonts/files/roboto-slab-cyrillic-wght-normal.woff2 +0 -0
  196. package/dist/css/fonts/files/roboto-slab-greek-ext-wght-normal.woff2 +0 -0
  197. package/dist/css/fonts/files/roboto-slab-greek-wght-normal.woff2 +0 -0
  198. package/dist/css/fonts/files/roboto-slab-vietnamese-wght-normal.woff2 +0 -0
  199. package/dist/css/fonts/files/ubuntu-cyrillic-300-italic.woff2 +0 -0
  200. package/dist/css/fonts/files/ubuntu-cyrillic-300-normal.woff2 +0 -0
  201. package/dist/css/fonts/files/ubuntu-cyrillic-400-italic.woff2 +0 -0
  202. package/dist/css/fonts/files/ubuntu-cyrillic-400-normal.woff2 +0 -0
  203. package/dist/css/fonts/files/ubuntu-cyrillic-500-italic.woff2 +0 -0
  204. package/dist/css/fonts/files/ubuntu-cyrillic-500-normal.woff2 +0 -0
  205. package/dist/css/fonts/files/ubuntu-cyrillic-700-italic.woff2 +0 -0
  206. package/dist/css/fonts/files/ubuntu-cyrillic-700-normal.woff2 +0 -0
  207. package/dist/css/fonts/files/ubuntu-cyrillic-ext-300-italic.woff2 +0 -0
  208. package/dist/css/fonts/files/ubuntu-cyrillic-ext-300-normal.woff2 +0 -0
  209. package/dist/css/fonts/files/ubuntu-cyrillic-ext-400-italic.woff2 +0 -0
  210. package/dist/css/fonts/files/ubuntu-cyrillic-ext-400-normal.woff2 +0 -0
  211. package/dist/css/fonts/files/ubuntu-cyrillic-ext-500-italic.woff2 +0 -0
  212. package/dist/css/fonts/files/ubuntu-cyrillic-ext-500-normal.woff2 +0 -0
  213. package/dist/css/fonts/files/ubuntu-cyrillic-ext-700-italic.woff2 +0 -0
  214. package/dist/css/fonts/files/ubuntu-cyrillic-ext-700-normal.woff2 +0 -0
  215. package/dist/css/fonts/files/ubuntu-greek-300-italic.woff2 +0 -0
  216. package/dist/css/fonts/files/ubuntu-greek-300-normal.woff2 +0 -0
  217. package/dist/css/fonts/files/ubuntu-greek-400-italic.woff2 +0 -0
  218. package/dist/css/fonts/files/ubuntu-greek-400-normal.woff2 +0 -0
  219. package/dist/css/fonts/files/ubuntu-greek-500-italic.woff2 +0 -0
  220. package/dist/css/fonts/files/ubuntu-greek-500-normal.woff2 +0 -0
  221. package/dist/css/fonts/files/ubuntu-greek-700-italic.woff2 +0 -0
  222. package/dist/css/fonts/files/ubuntu-greek-700-normal.woff2 +0 -0
  223. package/dist/css/fonts/files/ubuntu-greek-ext-300-italic.woff2 +0 -0
  224. package/dist/css/fonts/files/ubuntu-greek-ext-300-normal.woff2 +0 -0
  225. package/dist/css/fonts/files/ubuntu-greek-ext-400-italic.woff2 +0 -0
  226. package/dist/css/fonts/files/ubuntu-greek-ext-400-normal.woff2 +0 -0
  227. package/dist/css/fonts/files/ubuntu-greek-ext-500-italic.woff2 +0 -0
  228. package/dist/css/fonts/files/ubuntu-greek-ext-500-normal.woff2 +0 -0
  229. package/dist/css/fonts/files/ubuntu-greek-ext-700-italic.woff2 +0 -0
  230. package/dist/css/fonts/files/ubuntu-greek-ext-700-normal.woff2 +0 -0
  231. package/dist/css/fonts/files/unica-one-vietnamese-400-normal.woff2 +0 -0
  232. package/dist/css/fonts/files/vollkorn-cyrillic-ext-wght-italic.woff2 +0 -0
  233. package/dist/css/fonts/files/vollkorn-cyrillic-ext-wght-normal.woff2 +0 -0
  234. package/dist/css/fonts/files/vollkorn-cyrillic-wght-italic.woff2 +0 -0
  235. package/dist/css/fonts/files/vollkorn-cyrillic-wght-normal.woff2 +0 -0
  236. package/dist/css/fonts/files/vollkorn-greek-wght-italic.woff2 +0 -0
  237. package/dist/css/fonts/files/vollkorn-greek-wght-normal.woff2 +0 -0
  238. package/dist/css/fonts/files/vollkorn-vietnamese-wght-italic.woff2 +0 -0
  239. package/dist/css/fonts/files/vollkorn-vietnamese-wght-normal.woff2 +0 -0
  240. package/dist/css/fonts/font.abril-droidsans.css +3 -0
  241. package/dist/css/fonts/font.amatic-andika.css +57 -0
  242. package/dist/css/fonts/font.bitter-raleway.css +111 -0
  243. package/dist/css/fonts/font.cairo.css +312 -0
  244. package/dist/css/fonts/font.clicker-garamond.css +93 -0
  245. package/dist/css/fonts/font.dancing-ledger.css +12 -0
  246. package/dist/css/fonts/font.default.css +183 -0
  247. package/dist/css/fonts/font.fjalla-average.css +3 -0
  248. package/dist/css/fonts/font.georgia-helvetica.css +3 -0
  249. package/dist/css/fonts/font.knightlab.css +642 -0
  250. package/dist/css/fonts/font.lustria-lato.css +3 -0
  251. package/dist/css/fonts/font.medula-lato.css +3 -0
  252. package/dist/css/fonts/font.oldstandard.css +101 -21
  253. package/dist/css/fonts/font.opensans-gentiumbook.css +183 -0
  254. package/dist/css/fonts/font.playfair-faunaone.css +39 -0
  255. package/dist/css/fonts/font.playfair.css +147 -0
  256. package/dist/css/fonts/font.pt.css +183 -0
  257. package/dist/css/fonts/font.roboto-megrim.css +3 -0
  258. package/dist/css/fonts/font.rufina-sintony.css +3 -0
  259. package/dist/css/fonts/font.ubuntu.css +291 -0
  260. package/dist/css/fonts/font.unicaone-vollkorn.css +84 -0
  261. package/dist/css/storymap.css +1 -1
  262. package/dist/demo.html +2 -2
  263. package/dist/docs/api/.nojekyll +1 -0
  264. package/dist/docs/api/assets/custom.css +47 -0
  265. package/dist/docs/api/assets/hierarchy.js +1 -0
  266. package/dist/docs/api/assets/highlight.css +57 -0
  267. package/dist/docs/api/assets/icons.js +18 -0
  268. package/dist/docs/api/assets/icons.svg +1 -0
  269. package/dist/docs/api/assets/main.js +60 -0
  270. package/dist/docs/api/assets/navigation.js +1 -0
  271. package/dist/docs/api/assets/search.js +1 -0
  272. package/dist/docs/api/assets/style.css +1648 -0
  273. package/dist/docs/api/classes/StoryMap.html +1604 -0
  274. package/dist/docs/api/functions/MediaType.html +51 -0
  275. package/dist/docs/api/functions/isPresentation3Collection.html +47 -0
  276. package/dist/docs/api/functions/isPresentation3Manifest.html +53 -0
  277. package/dist/docs/api/functions/loadCSS.html +63 -0
  278. package/dist/docs/api/functions/manifestToStorymapData.html +49 -0
  279. package/dist/docs/api/functions/setLanguage.html +54 -0
  280. package/dist/docs/api/functions/storymapToManifest.html +57 -0
  281. package/dist/docs/api/functions/validateStorymap.html +53 -0
  282. package/dist/docs/api/functions/validateStorymapAndReport.html +54 -0
  283. package/dist/docs/api/hierarchy.html +28 -0
  284. package/dist/docs/api/index.html +197 -0
  285. package/dist/docs/api/interfaces/AnimationHandle.html +60 -0
  286. package/dist/docs/api/interfaces/ImagereadyPayload.html +71 -0
  287. package/dist/docs/api/interfaces/LanguageEntry.html +102 -0
  288. package/dist/docs/api/interfaces/LatLngLiteral.html +73 -0
  289. package/dist/docs/api/interfaces/LoadOptions.html +59 -0
  290. package/dist/docs/api/interfaces/OlLayer.html +1400 -0
  291. package/dist/docs/api/interfaces/OlMap.html +1656 -0
  292. package/dist/docs/api/interfaces/OlProjection.html +332 -0
  293. package/dist/docs/api/interfaces/OlSource.html +784 -0
  294. package/dist/docs/api/interfaces/OlTileLayer.html +1497 -0
  295. package/dist/docs/api/interfaces/OlVectorLayer.html +1559 -0
  296. package/dist/docs/api/interfaces/OlView.html +1958 -0
  297. package/dist/docs/api/interfaces/StorymapData.html +71 -0
  298. package/dist/docs/api/interfaces/StorymapDataWrapper.html +60 -0
  299. package/dist/docs/api/interfaces/StorymapDocument.html +68 -0
  300. package/dist/docs/api/interfaces/StorymapError.html +63 -0
  301. package/dist/docs/api/interfaces/StorymapGeoreference.html +93 -0
  302. package/dist/docs/api/interfaces/StorymapGeoreferenceBody.html +74 -0
  303. package/dist/docs/api/interfaces/StorymapGroundControlPoint.html +69 -0
  304. package/dist/docs/api/interfaces/StorymapLanguageMap.html +57 -0
  305. package/dist/docs/api/interfaces/StorymapManifest.html +118 -0
  306. package/dist/docs/api/interfaces/StorymapManifestAnnotation.html +105 -0
  307. package/dist/docs/api/interfaces/StorymapManifestBackground.html +81 -0
  308. package/dist/docs/api/interfaces/StorymapManifestCanvas.html +140 -0
  309. package/dist/docs/api/interfaces/StorymapManifestContentResource.html +97 -0
  310. package/dist/docs/api/interfaces/StorymapManifestFeatureCollection.html +82 -0
  311. package/dist/docs/api/interfaces/StorymapManifestGeoreferencing.html +87 -0
  312. package/dist/docs/api/interfaces/StorymapManifestImageService.html +69 -0
  313. package/dist/docs/api/interfaces/StorymapManifestRange.html +75 -0
  314. package/dist/docs/api/interfaces/StorymapManifestService.html +77 -0
  315. package/dist/docs/api/interfaces/StorymapManifestSpecificResource.html +69 -0
  316. package/dist/docs/api/interfaces/StorymapManifestStatement.html +63 -0
  317. package/dist/docs/api/interfaces/StorymapMapOptions.html +92 -0
  318. package/dist/docs/api/interfaces/StorymapOptions.html +532 -0
  319. package/dist/docs/api/interfaces/StorymapOverlayLayer.html +126 -0
  320. package/dist/docs/api/interfaces/StorymapSlide.html +132 -0
  321. package/dist/docs/api/interfaces/StorymapSlideBackground.html +72 -0
  322. package/dist/docs/api/interfaces/StorymapSlideLocation.html +117 -0
  323. package/dist/docs/api/interfaces/StorymapSlideMarker.html +104 -0
  324. package/dist/docs/api/interfaces/StorymapSlideMedia.html +110 -0
  325. package/dist/docs/api/interfaces/StorymapSlideNarration.html +65 -0
  326. package/dist/docs/api/interfaces/StorymapSlideText.html +72 -0
  327. package/dist/docs/api/interfaces/StorymapTilejson.html +105 -0
  328. package/dist/docs/api/media/es.json +31 -0
  329. package/dist/docs/api/media/migration-from-knightlab.md +359 -0
  330. package/dist/docs/api/modules.html +50 -0
  331. package/dist/docs/api/types/ContentState.html +70 -0
  332. package/dist/docs/api/types/ImagereadyKind.html +34 -0
  333. package/dist/docs/api/types/MediaTypeMatch.html +78 -0
  334. package/dist/docs/api/types/TileSourceFactory.html +53 -0
  335. package/dist/docs/authoring.html +293 -0
  336. package/dist/docs/iiif.html +617 -62
  337. package/dist/docs/migration.html +314 -12
  338. package/dist/docs/readme.html +40 -9
  339. package/dist/embed/index.html +130 -5
  340. package/dist/examples/issue-242-nonlatin.json +55 -0
  341. package/dist/examples/issue-305-start-at-slide-data.json +96 -0
  342. package/dist/examples/issue-358-iframe.json +57 -0
  343. package/dist/examples/issue-iiif-geo.json +32 -0
  344. package/dist/examples/issue-image-alt.json +23 -0
  345. package/dist/examples/issue-image-region.json +42 -0
  346. package/dist/examples/issue-image-srcset.json +24 -0
  347. package/dist/examples/map-area-overlays.json +68 -0
  348. package/dist/examples/no-map.json +44 -0
  349. package/dist/examples-iiif/annotated-image.json +188 -0
  350. package/dist/examples-iiif/bob-boilen.json +11 -5
  351. package/dist/examples-iiif/courbet.json +9 -6
  352. package/dist/examples-iiif/empty.json +8 -4
  353. package/dist/examples-iiif/flickr-drewvigal.json +248 -24
  354. package/dist/examples-iiif/flickr-zach.wise.json +8 -4
  355. package/dist/examples-iiif/georeferenced-layer-unsupported.json +153 -0
  356. package/dist/examples-iiif/georeferenced-layer.json +318 -0
  357. package/dist/examples-iiif/iiif-wellcome.json +9 -6
  358. package/dist/examples-iiif/instagram-chenpamela.json +381 -36
  359. package/dist/examples-iiif/instagram_brentfoster.json +429 -40
  360. package/dist/examples-iiif/instagram_couch.json +261 -26
  361. package/dist/examples-iiif/instagram_joegermuska.json +441 -41
  362. package/dist/examples-iiif/instagram_matteich.json +261 -26
  363. package/dist/examples-iiif/instagram_mirandamulligan.json +261 -26
  364. package/dist/examples-iiif/instagram_raymondmccrea.json +261 -26
  365. package/dist/examples-iiif/instagram_test.json +261 -26
  366. package/dist/examples-iiif/issue-134-no-lines.json +9 -5
  367. package/dist/examples-iiif/issue-177-color-vars.json +9 -5
  368. package/dist/examples-iiif/issue-211-rtl.json +9 -5
  369. package/dist/examples-iiif/issue-242-nonlatin.json +239 -0
  370. package/dist/examples-iiif/issue-272-facebook.json +9 -5
  371. package/dist/examples-iiif/issue-305-start-at-slide-data.json +305 -0
  372. package/dist/examples-iiif/issue-305-start-at-slide.json +9 -5
  373. package/dist/examples-iiif/issue-341-distance.json +9 -5
  374. package/dist/examples-iiif/issue-358-iframe.json +190 -0
  375. package/dist/examples-iiif/issue-360-juxtapose.json +22 -7
  376. package/dist/examples-iiif/issue-368-null-fields.json +9 -5
  377. package/dist/examples-iiif/issue-375-code-lists.json +9 -5
  378. package/dist/examples-iiif/issue-381-dateline.json +9 -5
  379. package/dist/examples-iiif/issue-405-custom-icon.json +203 -0
  380. package/dist/examples-iiif/issue-425-many-slides.json +9 -5
  381. package/dist/examples-iiif/issue-428-background.json +20 -8
  382. package/dist/examples-iiif/issue-435-googlemaps.json +9 -5
  383. package/dist/examples-iiif/issue-437-documentcloud.json +22 -7
  384. package/dist/examples-iiif/issue-451-webp.json +9 -5
  385. package/dist/examples-iiif/issue-455-audio.json +9 -5
  386. package/dist/examples-iiif/issue-480-shorts.json +9 -5
  387. package/dist/examples-iiif/issue-506-marker-sync.json +9 -5
  388. package/dist/examples-iiif/issue-iiif-geo.json +200 -0
  389. package/dist/examples-iiif/issue-image-alt.json +90 -0
  390. package/dist/examples-iiif/issue-image-region.json +203 -0
  391. package/dist/examples-iiif/issue-image-srcset.json +87 -0
  392. package/dist/examples-iiif/jansteen.json +9 -6
  393. package/dist/examples-iiif/katrina.json +197 -41
  394. package/dist/examples-iiif/map-area-overlays.json +289 -0
  395. package/dist/examples-iiif/marktwain.json +255 -58
  396. package/dist/examples-iiif/no-map.json +148 -0
  397. package/dist/examples-iiif/population.json +440 -76
  398. package/dist/examples-iiif/president.json +456 -83
  399. package/dist/examples-iiif/scroll-hint.json +190 -0
  400. package/dist/examples-iiif/seurat.json +113 -22
  401. package/dist/examples-iiif/zoomify-clamp.json +153 -0
  402. package/dist/harness-multi.html +17 -0
  403. package/dist/harness.html +3 -2
  404. package/dist/index.html +33 -10
  405. package/dist/js/storymap.d.ts +1558 -114
  406. package/dist/js/storymap.js +10113 -6490
  407. package/dist/js/storymap.js.map +1 -1
  408. package/dist/navplace-properties.json +40 -0
  409. package/docs/migration-from-knightlab.md +359 -0
  410. package/docs/storymap-as-iiif-manifest.md +934 -0
  411. package/package.json +16 -10
  412. package/schema/storymap.schema.json +431 -78
  413. package/src/animation/easings.ts +25 -0
  414. package/src/animation/tween.ts +186 -0
  415. package/src/core/Browser.ts +20 -0
  416. package/src/core/Load.ts +232 -0
  417. package/src/core/Util.ts +416 -0
  418. package/src/core/mixins.ts +188 -0
  419. package/src/core/viewers.ts +94 -0
  420. package/src/dom/Dom.ts +31 -0
  421. package/src/dom/DomEvent.ts +80 -0
  422. package/src/globals.d.ts +24 -0
  423. package/src/language/Language.ts +281 -0
  424. package/src/language/locale/.expected-gaps.json +86 -0
  425. package/src/language/locale/be.json +31 -0
  426. package/src/language/locale/bg.json +31 -0
  427. package/src/language/locale/cs.json +31 -0
  428. package/src/language/locale/de.json +31 -0
  429. package/src/language/locale/el.json +31 -0
  430. package/src/language/locale/en.json +32 -0
  431. package/src/language/locale/es.json +31 -0
  432. package/src/language/locale/et.json +22 -0
  433. package/src/language/locale/fr.json +31 -0
  434. package/src/language/locale/he.json +31 -0
  435. package/src/language/locale/hu.json +31 -0
  436. package/src/language/locale/is.json +22 -0
  437. package/src/language/locale/it.json +31 -0
  438. package/src/language/locale/jp.json +31 -0
  439. package/src/language/locale/ko.json +31 -0
  440. package/src/language/locale/nl.json +31 -0
  441. package/src/language/locale/nn.json +22 -0
  442. package/src/language/locale/no.json +31 -0
  443. package/src/language/locale/pl.json +31 -0
  444. package/src/language/locale/pt.json +31 -0
  445. package/src/language/locale/ru.json +31 -0
  446. package/src/language/locale/sk.json +31 -0
  447. package/src/language/locale/sr.json +21 -0
  448. package/src/language/locale/sv.json +31 -0
  449. package/src/language/locale/tr.json +31 -0
  450. package/src/language/locale/uk.json +31 -0
  451. package/src/language/locale/ur.json +22 -0
  452. package/src/language/locale/zh-cn.json +31 -0
  453. package/src/language/locale/zh-tw.json +31 -0
  454. package/src/main.ts +143 -0
  455. package/src/map/Map.ts +794 -0
  456. package/src/map/MapMarker.ts +172 -0
  457. package/src/map/georeference.ts +325 -0
  458. package/src/map/openlayers/Map.OpenLayers.ts +2492 -0
  459. package/src/map/openlayers/MapMarker.OpenLayers.ts +400 -0
  460. package/src/map/openlayers/zoomifyTiles.ts +25 -0
  461. package/src/map/types.ts +17 -0
  462. package/src/media/EmbedUtil.ts +452 -0
  463. package/src/media/Media.ts +597 -0
  464. package/src/media/MediaType.ts +163 -0
  465. package/src/media/embedId.ts +104 -0
  466. package/src/media/types/Audio.ts +14 -0
  467. package/src/media/types/Blockquote.ts +39 -0
  468. package/src/media/types/DailyMotion.ts +53 -0
  469. package/src/media/types/DocumentCloud.ts +12 -0
  470. package/src/media/types/Facebook.ts +40 -0
  471. package/src/media/types/Flickr.ts +115 -0
  472. package/src/media/types/GoogleDoc.ts +58 -0
  473. package/src/media/types/HtmlMedia.ts +167 -0
  474. package/src/media/types/IFrame.ts +50 -0
  475. package/src/media/types/Image.ts +115 -0
  476. package/src/media/types/Juxtapose.ts +41 -0
  477. package/src/media/types/SoundCloud.ts +99 -0
  478. package/src/media/types/Text.ts +178 -0
  479. package/src/media/types/Twitter.ts +109 -0
  480. package/src/media/types/Video.ts +14 -0
  481. package/src/media/types/Vimeo.ts +65 -0
  482. package/src/media/types/Website.ts +46 -0
  483. package/src/media/types/Wikipedia.ts +134 -0
  484. package/src/media/types/YouTube.ts +224 -0
  485. package/src/scss/Typography.scss +235 -0
  486. package/src/scss/VCO.StoryMap.Dark.scss +150 -0
  487. package/src/scss/VCO.StoryMap.scss +195 -0
  488. package/src/scss/Variables.Dark.scss +57 -0
  489. package/src/scss/Variables.scss +48 -0
  490. package/src/scss/core/Mixins.scss +54 -0
  491. package/src/scss/core/Reset.scss +206 -0
  492. package/src/scss/fonts/_font.base.scss +113 -0
  493. package/src/scss/fonts/font.abril-droidsans.scss +75 -0
  494. package/src/scss/fonts/font.amatic-andika.scss +76 -0
  495. package/src/scss/fonts/font.bitter-raleway.scss +92 -0
  496. package/src/scss/fonts/font.cairo.scss +79 -0
  497. package/src/scss/fonts/font.clicker-garamond.scss +97 -0
  498. package/src/scss/fonts/font.dancing-ledger.scss +75 -0
  499. package/src/scss/fonts/font.default.scss +9 -0
  500. package/src/scss/fonts/font.fjalla-average.scss +80 -0
  501. package/src/scss/fonts/font.georgia-helvetica.scss +58 -0
  502. package/src/scss/fonts/font.knightlab.scss +111 -0
  503. package/src/scss/fonts/font.lustria-lato.scss +80 -0
  504. package/src/scss/fonts/font.medula-lato.scss +73 -0
  505. package/src/scss/fonts/font.oldstandard.scss +94 -0
  506. package/src/scss/fonts/font.opensans-gentiumbook.scss +85 -0
  507. package/src/scss/fonts/font.playfair-faunaone.scss +88 -0
  508. package/src/scss/fonts/font.playfair.scss +89 -0
  509. package/src/scss/fonts/font.pt.scss +96 -0
  510. package/src/scss/fonts/font.roboto-megrim.scss +73 -0
  511. package/src/scss/fonts/font.rufina-sintony.scss +73 -0
  512. package/src/scss/fonts/font.ubuntu.scss +82 -0
  513. package/src/scss/fonts/font.unicaone-vollkorn.scss +90 -0
  514. package/src/scss/icons/Icons.scss +239 -0
  515. package/src/scss/map/VCO.ImageMarker.scss +23 -0
  516. package/src/scss/map/VCO.Map.scss +21 -0
  517. package/src/scss/map/VCO.MapMarker.scss +242 -0
  518. package/src/scss/map/openlayers/VCO.Map.OpenLayers.scss +126 -0
  519. package/src/scss/media/VCO.Media.scss +219 -0
  520. package/src/scss/media/types/VCO.Media.Blockquote.scss +76 -0
  521. package/src/scss/media/types/VCO.Media.IFrame.scss +11 -0
  522. package/src/scss/media/types/VCO.Media.Image.scss +13 -0
  523. package/src/scss/media/types/VCO.Media.Text.scss +98 -0
  524. package/src/scss/media/types/VCO.Media.Twitter.scss +87 -0
  525. package/src/scss/media/types/VCO.Media.Wikipedia.scss +65 -0
  526. package/src/scss/site/site.scss +748 -0
  527. package/src/scss/slider/VCO.Slide.scss +457 -0
  528. package/src/scss/slider/VCO.SlideNav.scss +332 -0
  529. package/src/scss/slider/VCO.StorySlider.scss +66 -0
  530. package/src/scss/snapmap/VCO.SnapMap.scss +103 -0
  531. package/src/scss/ui/VCO.Consent.scss +121 -0
  532. package/src/scss/ui/VCO.MenuBar.Button.scss +107 -0
  533. package/src/scss/ui/VCO.MenuBar.scss +20 -0
  534. package/src/scss/ui/VCO.Message.scss +101 -0
  535. package/src/site/site.ts +88 -0
  536. package/src/slider/Slide.ts +554 -0
  537. package/src/slider/SlideNav.ts +246 -0
  538. package/src/slider/StorySlider.ts +833 -0
  539. package/src/storymap/Consent.ts +471 -0
  540. package/src/storymap/StoryMap.ts +2118 -0
  541. package/src/storymap/content-state.ts +185 -0
  542. package/src/storymap/iiif.ts +1844 -0
  543. package/src/storymap/to-iiif.ts +921 -0
  544. package/src/storymap/validate.ts +257 -0
  545. package/src/types.ts +494 -0
  546. package/src/ui/MenuBar.ts +376 -0
  547. package/src/ui/Message.ts +127 -0
  548. package/src/ui/Swipable.ts +455 -0
  549. package/dist/assets/demo-CVQ7kFek.js +0 -1
  550. package/dist/assets/harness-C-VZV-ou.js +0 -1
  551. package/dist/assets/index-DDsPBPZA.js +0 -1
  552. package/dist/assets/main-DwbXrrYn.js +0 -17
@@ -0,0 +1,167 @@
1
+ import { Media } from "../Media";
2
+ import Dom from "../../dom/Dom";
3
+ import { Language } from "../../language/Language";
4
+
5
+ /* Media.HtmlMedia
6
+ Shared implementation for the <audio> and <video> types. The two differ
7
+ only in the element name, the CSS class, the fallback text and the
8
+ file extension -> MIME map, so all of that is data here.
9
+ ================================================== */
10
+
11
+ /** The element this media type plays. */
12
+ export type HtmlMediaKind = "audio" | "video";
13
+
14
+ interface HtmlMediaSpec {
15
+ /** The element to create. */
16
+ kind: HtmlMediaKind;
17
+ /** File extension (lowercase, no dot) -> MIME subtype. */
18
+ extensions: Record<string, string>;
19
+ }
20
+
21
+ const AUDIO_DEFAULT: HtmlMediaSpec = { kind: "audio", extensions: { mp3: "mpeg" } };
22
+
23
+ /** MIME subtype for a file extension, or "" when it is not recognised. */
24
+ function mimeSubtype(ext: string, spec: HtmlMediaSpec): string {
25
+ return spec.extensions[ext.toLowerCase()] ?? "";
26
+ }
27
+
28
+ /** The behaviour shared by the audio and video media types. */
29
+ export class HtmlMediaBase extends Media {
30
+ declare "player_element": HTMLMediaElement | null;
31
+ declare "_onCanPlay": (() => void) | null;
32
+ declare "_onEnded": (() => void) | null;
33
+ declare "_onSourceError": (() => void) | null;
34
+
35
+ /**
36
+ * The per-kind differences. Overridden by the Audio/Video subclasses; the
37
+ * base value is never used (an HtmlMediaBase is always subclassed).
38
+ */
39
+ protected spec(): HtmlMediaSpec {
40
+ return AUDIO_DEFAULT;
41
+ }
42
+
43
+ _loadMedia() {
44
+ const spec = this.spec();
45
+ this.loadingMessage();
46
+
47
+ const media_item = Dom.create(
48
+ spec.kind,
49
+ `vco-media-item vco-media-${spec.kind} vco-media-shadow`,
50
+ this._el.content,
51
+ ) as HTMLMediaElement;
52
+ this._el.content_item = media_item;
53
+ media_item.controls = true;
54
+
55
+ const source_item = Dom.create("source", "", media_item) as HTMLSourceElement;
56
+ this._el.source_item = source_item;
57
+
58
+ // Media Loaded Event. The references are kept so dispose() can detach
59
+ // them: an inline arrow function has no other handle.
60
+ this._onEnded = null;
61
+ this._onCanPlay = () => {
62
+ this.onLoaded();
63
+ };
64
+ media_item.addEventListener("canplay", this._onCanPlay);
65
+
66
+ // Load Error Event (the source element fires it, not the media element)
67
+ this._onSourceError = () => {
68
+ this.loadErrorDisplay(Language.messages.error + " " + this.options.media_name);
69
+ };
70
+ source_item.addEventListener("error", this._onSourceError);
71
+
72
+ const url = this._url();
73
+ source_item.src = url;
74
+ const media_type = this._getType(url, spec);
75
+ // An unrecognised extension leaves the type unset so the browser can
76
+ // work it out from the URL — setting a bare "audio/" (as this used to)
77
+ // is not a valid MIME type and makes the source fail outright.
78
+ if (media_type) {
79
+ source_item.type = media_type;
80
+ }
81
+ // Subtitles: a WebVTT track, opt-in via media.subtitles. The element
82
+ // is created before the fallback text node so the fallback stays last.
83
+ if (spec.kind === "video" || spec.kind === "audio") {
84
+ const subtitles = (this.data as { subtitles?: string | null }).subtitles;
85
+ if (typeof subtitles === "string" && subtitles !== "") {
86
+ const track = Dom.create(
87
+ "track",
88
+ "vco-media-track",
89
+ media_item,
90
+ ) as HTMLTrackElement;
91
+ track.kind = "subtitles";
92
+ track.srclang = "en";
93
+ track.label = "Subtitles";
94
+ track.src = subtitles;
95
+ track.default = true;
96
+ }
97
+ }
98
+
99
+ // append as a text node: re-serializing innerHTML would replace the
100
+ // source element and drop its error listener, leaving the loading
101
+ // message on screen forever
102
+ media_item.appendChild(
103
+ document.createTextNode(
104
+ `Your browser doesn't support HTML5 ${spec.kind} with ` + source_item.type,
105
+ ),
106
+ );
107
+
108
+ // `ended` is what autoplay_media waits for instead of its timer; the
109
+ // reference is kept so dispose() can detach it, like the two above
110
+ this._onEnded = () => {
111
+ this.fire("media_ended", this.data);
112
+ };
113
+ media_item.addEventListener("ended", this._onEnded);
114
+
115
+ this.player_element = media_item;
116
+ }
117
+
118
+ // Update Media Display
119
+ _updateMediaDisplay() {
120
+ // the height is CSS-driven; nothing to compute here
121
+ }
122
+
123
+ _stopMedia() {
124
+ this.player_element?.pause();
125
+ }
126
+
127
+ /**
128
+ * Detach the media listeners and release the source, so a disposed audio
129
+ * or video element stops buffering instead of playing into a detached
130
+ * tree. Pausing alone (what `stopMedia()` does per slide change) is not
131
+ * enough for a full teardown.
132
+ */
133
+ _disposeMedia() {
134
+ if (this._onCanPlay) {
135
+ this.player_element?.removeEventListener("canplay", this._onCanPlay);
136
+ this._onCanPlay = null;
137
+ }
138
+ if (this._onEnded) {
139
+ this.player_element?.removeEventListener("ended", this._onEnded);
140
+ this._onEnded = null;
141
+ }
142
+ if (this._onSourceError) {
143
+ this._el.source_item?.removeEventListener("error", this._onSourceError);
144
+ this._onSourceError = null;
145
+ }
146
+ const el = this.player_element;
147
+ if (el) {
148
+ el.pause();
149
+ // dropping the source stops the network fetch immediately
150
+ el.removeAttribute("src");
151
+ el.load();
152
+ }
153
+ this.player_element = null;
154
+
155
+ this._onCanPlay = null;
156
+
157
+ this._onSourceError = null;
158
+ }
159
+
160
+ _getType(url: string, spec: HtmlMediaSpec): string {
161
+ const ext = url.match((this.data.mediatype as { match_str: string | RegExp }).match_str);
162
+ if (!ext) {
163
+ return "";
164
+ }
165
+ return mimeSubtype(ext[1], spec);
166
+ }
167
+ }
@@ -0,0 +1,50 @@
1
+ import { Media } from "../Media";
2
+ import Dom from "../../dom/Dom";
3
+ import { buildIframe } from "../EmbedUtil";
4
+
5
+ /* Media.IFrame
6
+ ================================================== */
7
+
8
+ export default class IFrame extends Media {
9
+ declare "media_id": string;
10
+
11
+ /* Load the media
12
+ ================================================== */
13
+ _loadMedia() {
14
+ // Loading Message
15
+ this.loadingMessage();
16
+
17
+ // Create Dom element
18
+ this._el.content_item = Dom.create(
19
+ "div",
20
+ "vco-media-item vco-media-iframe",
21
+ this._el.content,
22
+ );
23
+
24
+ // Get Media ID
25
+ this.media_id = this._url();
26
+
27
+ // The url field holds a user-pasted embed snippet. Rebuild a
28
+ // clean iframe from its src instead of injecting the raw markup,
29
+ // which would allow stored XSS via the storymap JSON.
30
+ const iframe = buildIframe(this.media_id);
31
+
32
+ if (!iframe) {
33
+ this.loadErrorDisplay(
34
+ "Invalid embed code. Paste an iframe embed code with an http(s) source URL.",
35
+ );
36
+ return;
37
+ }
38
+
39
+ // API Call
40
+ this._el.content_item.appendChild(iframe);
41
+
42
+ // After Loaded
43
+ this.onLoaded();
44
+ }
45
+
46
+ // Update Media Display
47
+ _updateMediaDisplay() {
48
+ this._sizeContentItemToOptionHeight();
49
+ }
50
+ }
@@ -0,0 +1,115 @@
1
+ import { Media } from "../Media";
2
+ import Dom from "../../dom/Dom";
3
+ import { validateWebURL } from "../EmbedUtil";
4
+
5
+ /* IIIF Image API 2/3 URL tail: .../region/size/rotation/quality.format
6
+ (optionally a query string). Used to request container-matched widths
7
+ instead of the full-size image (perf, backwards-compatible). */
8
+ const IIIF_TAIL =
9
+ /\/(full|max|pct:[\d.]+|\d+,?\d*)\/(full|max|pct:[\d.]+|\d+,?\d*)\/(\d+|full)\/(default|color|gray|bitonal)\.(jpg|jpeg|png|webp|gif)(\?.*)?$/i;
10
+
11
+ /**
12
+ * Rewrite an IIIF Image API URL to the given pixel width (`w,` size
13
+ * component, height unconstrained). Returns the URL unchanged when it is
14
+ * not a recognizable IIIF image URL.
15
+ */
16
+ export function iiifSizedUrl(url: string | null, width: number): string | null {
17
+ if (!url || !(width > 0)) {
18
+ return url;
19
+ }
20
+ const match = url.match(IIIF_TAIL);
21
+ if (!match) {
22
+ return url;
23
+ }
24
+ return (
25
+ url.slice(0, match.index) +
26
+ `/${match[1]}/${width},/${match[3]}/${match[4]}.${match[5]}${match[6] ?? ""}`
27
+ );
28
+ }
29
+
30
+ /* Media.Image
31
+ Produces image assets.
32
+ Takes a data object and populates a dom object
33
+ ================================================== */
34
+
35
+ export default class Image extends Media {
36
+ /* Load the media
37
+ ================================================== */
38
+ _loadMedia() {
39
+ // Loading Message
40
+ this.loadingMessage();
41
+
42
+ // Link — protocol-checked: a `javascript:` href in the storymap JSON
43
+ // would be a click-through XSS (see Media._initLayout)
44
+ const link_href = this.data.link ? validateWebURL(this.data.link) : null;
45
+ if (link_href) {
46
+ this._el.content_link = Dom.create("a", "", this._el.content);
47
+ const content_link = this._el.content_link as HTMLAnchorElement;
48
+ content_link.href = link_href;
49
+ content_link.target = "_blank";
50
+ content_link.rel = "noopener noreferrer";
51
+ this._el.content_item = Dom.create(
52
+ "img",
53
+ "vco-media-item vco-media-image vco-media-shadow",
54
+ this._el.content_link,
55
+ );
56
+ } else {
57
+ this._el.content_item = Dom.create(
58
+ "img",
59
+ "vco-media-item vco-media-image vco-media-shadow",
60
+ this._el.content,
61
+ );
62
+ }
63
+
64
+ // Media Loaded Event
65
+ this._el.content_item.addEventListener("load", (e) => {
66
+ this.onMediaLoaded();
67
+ });
68
+
69
+ const img = this._el.content_item as HTMLImageElement;
70
+ // offscreen/preloaded slides stay lazy (the active slide is
71
+ // upgraded to eager on activation, see Slide.setActive); decoding
72
+ // is only a hint — old browsers ignore both attributes
73
+ img.decoding = "async";
74
+ img.loading = this._state.eager ? "eager" : "lazy";
75
+ // responsive sizes (perf): IIIF image URLs request a container-
76
+ // matched width; author-provided srcset/sizes pass through;
77
+ // everything else renders byte-identically
78
+ const media_width = Number(this.options.width) || 0;
79
+ const sized = iiifSizedUrl(this._url(), media_width);
80
+ img.src = sized ?? this._url();
81
+ // accessibility: explicit alt text, falling back to the caption as
82
+ // plain text; an empty string marks a decorative image
83
+ img.alt = this._altText();
84
+ if (this.data.srcset) {
85
+ img.srcset = this.data.srcset as string;
86
+ }
87
+ if (this.data.sizes) {
88
+ img.sizes = this.data.sizes as string;
89
+ }
90
+
91
+ // the element is built and the src is set: hand over to Media so the
92
+ // loading overlay is hidden and credit/caption are rendered. The
93
+ // `load` listener above only fires the separate media_loaded event.
94
+ this.onLoaded();
95
+ }
96
+
97
+ _altText(): string {
98
+ const alt = this.data.alt as string | undefined;
99
+ if (alt !== undefined && alt !== "") {
100
+ return alt;
101
+ }
102
+ const caption = this.data.caption as string | null | undefined;
103
+ if (caption) {
104
+ return caption
105
+ .replace(/<[^>]*>/g, " ")
106
+ .replace(/\s+/g, " ")
107
+ .trim();
108
+ }
109
+ return "";
110
+ }
111
+
112
+ _updateMediaDisplay(layout?: string) {
113
+ // modern browsers size media correctly without engine-specific fixes
114
+ }
115
+ }
@@ -0,0 +1,41 @@
1
+ import { Media } from "../Media";
2
+ import Dom from "../../dom/Dom";
3
+ import { buildIframe } from "../EmbedUtil";
4
+
5
+ /* Media.Juxtapose
6
+ Embeds a JuxtaposeJS before/after slider (issue #360)
7
+ ================================================== */
8
+
9
+ export default class Juxtapose extends Media {
10
+ /* Load the media
11
+ ================================================== */
12
+ _loadMedia() {
13
+ // Loading Message
14
+ this.loadingMessage();
15
+
16
+ // Create Dom element
17
+ this._el.content_item = Dom.create(
18
+ "div",
19
+ "vco-media-item vco-media-iframe vco-media-juxtapose",
20
+ this._el.content,
21
+ );
22
+
23
+ // Built through buildIframe rather than an `<iframe src="${url}">`
24
+ // template string: interpolating a storymap-JSON string into markup
25
+ // is a stored-XSS break-out (`"><img src=x onerror=...>`), and
26
+ // MediaType routes *any* URL containing "juxtapose" here.
27
+ const embed = buildIframe(`<iframe src="${String(this._url() ?? "")}"></iframe>`);
28
+ if (!embed) {
29
+ this.loadErrorDisplay("Invalid URL.");
30
+ return;
31
+ }
32
+ embed.setAttribute("loading", "lazy");
33
+ this._el.content_item.appendChild(embed);
34
+ this.onLoaded();
35
+ }
36
+
37
+ // Update Media Display
38
+ _updateMediaDisplay() {
39
+ this._sizeContentItemToOptionHeight();
40
+ }
41
+ }
@@ -0,0 +1,99 @@
1
+ import { Media } from "../Media";
2
+ import Dom from "../../dom/Dom";
3
+ import { sanitizeSlideText } from "../EmbedUtil";
4
+
5
+ /* Media.SoundCloud
6
+ ================================================== */
7
+
8
+ /* Minimal surface of the SoundCloud widget API used here. */
9
+ interface SoundCloudWidget {
10
+ pause: () => void;
11
+ unbind?: () => void;
12
+ }
13
+
14
+ export default class SoundCloud extends Media {
15
+ declare "media_id": string;
16
+ declare "soundCloudCreated": boolean;
17
+ declare "widget": SoundCloudWidget | null;
18
+
19
+ /* Load the media
20
+ ================================================== */
21
+ async _loadMedia() {
22
+ // Loading Message
23
+ this.loadingMessage();
24
+
25
+ // Create Dom element
26
+ this._el.content_item = Dom.create(
27
+ "div",
28
+ "vco-media-item vco-media-iframe vco-media-soundcloud vco-media-shadow",
29
+ this._el.content,
30
+ );
31
+
32
+ // Get Media ID
33
+ this.media_id = this._url();
34
+
35
+ // API URL
36
+ const api_url = "https://soundcloud.com/oembed?url=" + this.media_id + "&format=json";
37
+
38
+ // API Call
39
+ try {
40
+ const r = await fetch(api_url);
41
+ const d = await r.json();
42
+ await this.loadScript("https://w.soundcloud.com/player/api.js");
43
+ //load soundcloud api for pausing.
44
+ this.createMedia(d);
45
+ } catch (err) {
46
+ // aborted loads stay silent (the visitor navigated away);
47
+ // real failures show the media error display
48
+ if ((err as DOMException)?.name !== "AbortError") {
49
+ this.loadErrorDisplay("Unable to load this track.");
50
+ }
51
+ }
52
+ }
53
+
54
+ createMedia(d: unknown) {
55
+ const data = d as { html: string };
56
+ if (!data?.html) {
57
+ this.loadErrorDisplay("Unable to load this track.");
58
+ return;
59
+ }
60
+ // The oEmbed response is third-party HTML. It is sanitized like any
61
+ // other untrusted markup, which in practice keeps the provider's
62
+ // <iframe> (rebuilt by the sanitizer) and drops its inline script —
63
+ // the widget is created from the iframe below, so the script was never
64
+ // needed in the first place.
65
+ const content_item = this._el.content_item;
66
+ if (!content_item) {
67
+ this.loadErrorDisplay("Unable to load this track.");
68
+ return;
69
+ }
70
+ content_item.appendChild(sanitizeSlideText(data.html));
71
+
72
+ this.soundCloudCreated = true;
73
+
74
+ const sc = SC as { Widget: (iframe: Element | null) => SoundCloudWidget };
75
+ // per-instance widget: a global would be overwritten by every
76
+ // SoundCloud slide and _stopMedia would pause the wrong one
77
+ this.widget = sc.Widget(content_item.querySelector("iframe"));
78
+
79
+ // After Loaded
80
+ this.onLoaded();
81
+ }
82
+
83
+ _stopMedia() {
84
+ if (this.soundCloudCreated) {
85
+ this.widget?.pause();
86
+ }
87
+ }
88
+
89
+ /** Unbind the widget so it stops playing once the slide is gone. */
90
+ _disposeMedia() {
91
+ try {
92
+ this.widget?.unbind?.();
93
+ } catch (err) {
94
+ console.log(err);
95
+ }
96
+ this.widget = null;
97
+ this.soundCloudCreated = false;
98
+ }
99
+ }
@@ -0,0 +1,178 @@
1
+ import { mergeData, htmlify, convertUnixTime } from "../../core/Util";
2
+ import { Evented, type EventedInstance } from "../../core/mixins";
3
+ import Dom from "../../dom/Dom";
4
+ import { sanitizeSlideText } from "../EmbedUtil";
5
+
6
+ interface TextData {
7
+ uniqueid?: string | null;
8
+ headline?: string;
9
+ text?: string;
10
+ text_align?: string;
11
+ date?: { created_time?: string; [key: string]: unknown } | null;
12
+ }
13
+
14
+ interface TextOptions {
15
+ title?: boolean;
16
+ text_align?: string;
17
+ }
18
+
19
+ class TextBase {
20
+ declare "_el": Record<string, HTMLElement>;
21
+ declare "data": TextData;
22
+ declare "options": TextOptions;
23
+ declare "fire": EventedInstance["fire"];
24
+
25
+ /* Constructor
26
+ ================================================== */
27
+ constructor(data: TextData, options?: TextOptions, add_to_container?: HTMLElement) {
28
+ // DOM ELEMENTS
29
+ this._el = {
30
+ container: {} as HTMLElement,
31
+ content_container: {} as HTMLElement,
32
+ content: {} as HTMLElement,
33
+ headline: {} as HTMLElement,
34
+ date: {} as HTMLElement,
35
+ start_btn: {} as HTMLElement,
36
+ };
37
+
38
+ // Data. The placeholders were the literal strings "headline" and
39
+ // "text", which mergeData only overwrites when the key is present — so
40
+ // a slide with body text and no headline rendered an <h2>headline</h2>.
41
+ // The renderer guards both on `!== ""`, so empty is the real default.
42
+ this.data = {
43
+ uniqueid: "",
44
+ headline: "",
45
+ text: "",
46
+ };
47
+
48
+ // Options
49
+ this.options = {
50
+ title: false,
51
+ };
52
+
53
+ mergeData(this.data, data);
54
+
55
+ // Merge Options
56
+ mergeData(this.options, options);
57
+
58
+ this._el.container = Dom.create("div", "vco-text");
59
+ this._el.container.id = this.data.uniqueid ?? "";
60
+
61
+ this._initLayout();
62
+
63
+ if (add_to_container) {
64
+ add_to_container.appendChild(this._el.container);
65
+ }
66
+ }
67
+
68
+ /* Adding, Hiding, Showing etc
69
+ ================================================== */
70
+ show() {}
71
+
72
+ hide() {}
73
+
74
+ addTo(container: HTMLElement) {
75
+ container.appendChild(this._el.container);
76
+ //this.onAdd();
77
+ }
78
+
79
+ removeFrom(container: HTMLElement) {
80
+ container.removeChild(this._el.container);
81
+ }
82
+
83
+ headlineHeight() {
84
+ return this._el.headline.offsetHeight + 40;
85
+ }
86
+
87
+ addDateText(str: string) {
88
+ if (this._el.date) {
89
+ this._el.date.innerHTML = str;
90
+ }
91
+ }
92
+
93
+ /* Events
94
+ ================================================== */
95
+ onLoaded() {
96
+ this.fire("loaded", this.data);
97
+ }
98
+
99
+ onAdd() {
100
+ this.fire("added", this.data);
101
+ }
102
+
103
+ onRemove() {
104
+ this.fire("removed", this.data);
105
+ }
106
+
107
+ /* Private Methods
108
+ ================================================== */
109
+ _initLayout() {
110
+ // Create Layout
111
+ this._el.content_container = Dom.create(
112
+ "div",
113
+ "vco-text-content-container",
114
+ this._el.container,
115
+ );
116
+
117
+ // Text alignment: per-slide override wins, then the storymap option
118
+ // (issue #244)
119
+ const align =
120
+ (this.data.text_align as string | undefined) ??
121
+ (this.options.text_align as string | undefined) ??
122
+ "left";
123
+ if (align === "center" || align === "right") {
124
+ this._el.content_container.classList.add("vco-text-align-" + align);
125
+ }
126
+
127
+ // Date (only rendered when the slide has one; issue #286)
128
+ if (this.data.date && this.data.date.created_time && this.data.date.created_time !== "") {
129
+ this._el.date = Dom.create("h3", "vco-headline-date", this._el.content_container);
130
+ this.addDateText(convertUnixTime(this.data.date.created_time));
131
+ }
132
+
133
+ // Headline (sanitized; issue #358 keeps formatting but drops scripts)
134
+ const headline = this.data.headline ?? "";
135
+ if (headline !== "") {
136
+ let headline_class = "vco-headline";
137
+ if (this.options.title) {
138
+ headline_class = "vco-headline vco-headline-title";
139
+ }
140
+ this._el.headline = Dom.create("h2", headline_class, this._el.content_container);
141
+ this._el.headline.appendChild(sanitizeSlideText(headline));
142
+ }
143
+
144
+ // Text (sanitized; issue #358 allows extra iframe media in the text field)
145
+ const text = this.data.text ?? "";
146
+ if (text !== "") {
147
+ let text_content = "";
148
+
149
+ text_content += htmlify(text);
150
+
151
+ // Date
152
+ if (
153
+ this.data.date &&
154
+ this.data.date.created_time &&
155
+ this.data.date.created_time !== ""
156
+ ) {
157
+ if (this.data.date.created_time.length > 10) {
158
+ text_content +=
159
+ "<div class='vco-text-date'>" +
160
+ convertUnixTime(this.data.date.created_time) +
161
+ "</div>";
162
+ }
163
+ }
164
+
165
+ this._el.content = Dom.create("div", "vco-text-content", this._el.content_container);
166
+ this._el.content.appendChild(sanitizeSlideText(text_content));
167
+ }
168
+
169
+ // Fire event that the slide is loaded
170
+ this.onLoaded();
171
+ }
172
+ }
173
+
174
+ export default class Text extends Evented(TextBase) {
175
+ constructor(...args: ConstructorParameters<typeof TextBase>) {
176
+ super(...args);
177
+ }
178
+ }