@projektemacher/storymapjs 0.10.7 → 0.11.0

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 (587) hide show
  1. package/CHANGELOG +431 -19
  2. package/README.md +168 -17
  3. package/dist/assets/demo-bWnOyfUw.js +1 -0
  4. package/dist/assets/harness-C3JUv5Ii.js +1 -0
  5. package/dist/assets/harness-multi-XZNex3tb.js +1 -0
  6. package/dist/assets/harness-support-CjfZIVeb.js +1 -0
  7. package/dist/assets/index-wHPqGrBS.js +1 -0
  8. package/dist/assets/main-DQ32hWBM.js +17 -0
  9. package/dist/context.json +23 -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 +84 -0
  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 +3 -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 +2112 -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/isSlideshowCollection.html +51 -0
  278. package/dist/docs/api/functions/loadCSS.html +63 -0
  279. package/dist/docs/api/functions/manifestToStorymapData.html +49 -0
  280. package/dist/docs/api/functions/setLanguage.html +54 -0
  281. package/dist/docs/api/functions/slideshowToStorymapData.html +51 -0
  282. package/dist/docs/api/functions/slideshowVersion.html +48 -0
  283. package/dist/docs/api/functions/storymapToManifest.html +57 -0
  284. package/dist/docs/api/functions/validateStorymap.html +53 -0
  285. package/dist/docs/api/functions/validateStorymapAndReport.html +54 -0
  286. package/dist/docs/api/hierarchy.html +28 -0
  287. package/dist/docs/api/index.html +300 -0
  288. package/dist/docs/api/interfaces/AnimationHandle.html +60 -0
  289. package/dist/docs/api/interfaces/ImagereadyPayload.html +71 -0
  290. package/dist/docs/api/interfaces/LanguageEntry.html +102 -0
  291. package/dist/docs/api/interfaces/LatLngLiteral.html +73 -0
  292. package/dist/docs/api/interfaces/LoadOptions.html +59 -0
  293. package/dist/docs/api/interfaces/MapEvents.html +116 -0
  294. package/dist/docs/api/interfaces/MapMarkerEvents.html +66 -0
  295. package/dist/docs/api/interfaces/MarkerEventPayload.html +57 -0
  296. package/dist/docs/api/interfaces/MediaEvents.html +78 -0
  297. package/dist/docs/api/interfaces/MenuBarEvents.html +114 -0
  298. package/dist/docs/api/interfaces/MessageEvents.html +72 -0
  299. package/dist/docs/api/interfaces/OlLayer.html +1400 -0
  300. package/dist/docs/api/interfaces/OlMap.html +1656 -0
  301. package/dist/docs/api/interfaces/OlProjection.html +332 -0
  302. package/dist/docs/api/interfaces/OlSource.html +784 -0
  303. package/dist/docs/api/interfaces/OlTileLayer.html +1497 -0
  304. package/dist/docs/api/interfaces/OlVectorLayer.html +1559 -0
  305. package/dist/docs/api/interfaces/OlView.html +1958 -0
  306. package/dist/docs/api/interfaces/SlideBackgroundState.html +66 -0
  307. package/dist/docs/api/interfaces/SlideEvents.html +78 -0
  308. package/dist/docs/api/interfaces/SlideNavEvents.html +72 -0
  309. package/dist/docs/api/interfaces/SlideshowPlayerSettings.html +182 -0
  310. package/dist/docs/api/interfaces/SlideshowToStorymapResult.html +60 -0
  311. package/dist/docs/api/interfaces/SlideshowTranslatorOptions.html +65 -0
  312. package/dist/docs/api/interfaces/SlideshowWarning.html +72 -0
  313. package/dist/docs/api/interfaces/StoryMapEvents.html +146 -0
  314. package/dist/docs/api/interfaces/StoryMapMarker.html +763 -0
  315. package/dist/docs/api/interfaces/StorySliderEvents.html +102 -0
  316. package/dist/docs/api/interfaces/StorymapBasemap.html +69 -0
  317. package/dist/docs/api/interfaces/StorymapData.html +77 -0
  318. package/dist/docs/api/interfaces/StorymapDataWrapper.html +60 -0
  319. package/dist/docs/api/interfaces/StorymapDocument.html +68 -0
  320. package/dist/docs/api/interfaces/StorymapError.html +63 -0
  321. package/dist/docs/api/interfaces/StorymapGeoreference.html +93 -0
  322. package/dist/docs/api/interfaces/StorymapGeoreferenceBody.html +74 -0
  323. package/dist/docs/api/interfaces/StorymapGroundControlPoint.html +69 -0
  324. package/dist/docs/api/interfaces/StorymapLanguageMap.html +57 -0
  325. package/dist/docs/api/interfaces/StorymapManifest.html +118 -0
  326. package/dist/docs/api/interfaces/StorymapManifestAnnotation.html +137 -0
  327. package/dist/docs/api/interfaces/StorymapManifestBackground.html +81 -0
  328. package/dist/docs/api/interfaces/StorymapManifestCanvas.html +188 -0
  329. package/dist/docs/api/interfaces/StorymapManifestContentResource.html +97 -0
  330. package/dist/docs/api/interfaces/StorymapManifestFeatureCollection.html +82 -0
  331. package/dist/docs/api/interfaces/StorymapManifestGeoreferencing.html +87 -0
  332. package/dist/docs/api/interfaces/StorymapManifestImageService.html +69 -0
  333. package/dist/docs/api/interfaces/StorymapManifestRange.html +75 -0
  334. package/dist/docs/api/interfaces/StorymapManifestService.html +77 -0
  335. package/dist/docs/api/interfaces/StorymapManifestSpecificResource.html +69 -0
  336. package/dist/docs/api/interfaces/StorymapManifestStatement.html +63 -0
  337. package/dist/docs/api/interfaces/StorymapMapOptions.html +92 -0
  338. package/dist/docs/api/interfaces/StorymapOptions.html +734 -0
  339. package/dist/docs/api/interfaces/StorymapOverlayLayer.html +157 -0
  340. package/dist/docs/api/interfaces/StorymapSlide.html +186 -0
  341. package/dist/docs/api/interfaces/StorymapSlideBackground.html +72 -0
  342. package/dist/docs/api/interfaces/StorymapSlideLocation.html +161 -0
  343. package/dist/docs/api/interfaces/StorymapSlideMarker.html +103 -0
  344. package/dist/docs/api/interfaces/StorymapSlideMedia.html +149 -0
  345. package/dist/docs/api/interfaces/StorymapSlideNarration.html +117 -0
  346. package/dist/docs/api/interfaces/StorymapSlideText.html +72 -0
  347. package/dist/docs/api/interfaces/StorymapTilejson.html +105 -0
  348. package/dist/docs/api/interfaces/SwipableEvents.html +102 -0
  349. package/dist/docs/api/interfaces/TextEvents.html +66 -0
  350. package/dist/docs/api/media/es.json +31 -0
  351. package/dist/docs/api/media/events.md +66 -0
  352. package/dist/docs/api/media/migration-from-knightlab.md +399 -0
  353. package/dist/docs/api/media/slideshow.md +109 -0
  354. package/dist/docs/api/media/storymap-as-iiif-manifest.md +1007 -0
  355. package/dist/docs/api/modules.html +50 -0
  356. package/dist/docs/api/types/ContentState.html +70 -0
  357. package/dist/docs/api/types/FiredEvent.html +43 -0
  358. package/dist/docs/api/types/ImagereadyKind.html +34 -0
  359. package/dist/docs/api/types/MediaTypeMatch.html +78 -0
  360. package/dist/docs/api/types/SwipeDirection.html +36 -0
  361. package/dist/docs/api/types/TileSourceFactory.html +53 -0
  362. package/dist/docs/authoring.html +306 -0
  363. package/dist/docs/events.html +263 -0
  364. package/dist/docs/iiif.html +738 -69
  365. package/dist/docs/migration.html +360 -11
  366. package/dist/docs/readme.html +149 -17
  367. package/dist/embed/index.html +8 -1
  368. package/dist/examples/font-css-false.json +33 -0
  369. package/dist/examples/issue-242-nonlatin.json +55 -0
  370. package/dist/examples/issue-305-start-at-slide-data.json +96 -0
  371. package/dist/examples/issue-358-iframe.json +57 -0
  372. package/dist/examples/issue-iiif-geo.json +32 -0
  373. package/dist/examples/issue-image-alt.json +23 -0
  374. package/dist/examples/issue-image-region.json +42 -0
  375. package/dist/examples/issue-image-srcset.json +24 -0
  376. package/dist/examples/layers-control.json +60 -0
  377. package/dist/examples/map-area-overlays.json +68 -0
  378. package/dist/examples/map-template-provider.json +36 -0
  379. package/dist/examples/multi-media.json +71 -0
  380. package/dist/examples/no-map.json +44 -0
  381. package/dist/examples-iiif/annotated-image.json +204 -0
  382. package/dist/examples-iiif/bob-boilen.json +11 -5
  383. package/dist/examples-iiif/courbet.json +9 -6
  384. package/dist/examples-iiif/empty.json +8 -4
  385. package/dist/examples-iiif/flickr-drewvigal.json +248 -24
  386. package/dist/examples-iiif/flickr-zach.wise.json +8 -4
  387. package/dist/examples-iiif/font-css-false.json +114 -0
  388. package/dist/examples-iiif/georeferenced-layer-unsupported.json +153 -0
  389. package/dist/examples-iiif/georeferenced-layer.json +318 -0
  390. package/dist/examples-iiif/iiif-wellcome.json +9 -6
  391. package/dist/examples-iiif/instagram-chenpamela.json +381 -36
  392. package/dist/examples-iiif/instagram_brentfoster.json +429 -40
  393. package/dist/examples-iiif/instagram_couch.json +261 -26
  394. package/dist/examples-iiif/instagram_joegermuska.json +441 -41
  395. package/dist/examples-iiif/instagram_matteich.json +261 -26
  396. package/dist/examples-iiif/instagram_mirandamulligan.json +261 -26
  397. package/dist/examples-iiif/instagram_raymondmccrea.json +261 -26
  398. package/dist/examples-iiif/instagram_test.json +261 -26
  399. package/dist/examples-iiif/issue-134-no-lines.json +9 -5
  400. package/dist/examples-iiif/issue-177-color-vars.json +9 -5
  401. package/dist/examples-iiif/issue-211-rtl.json +9 -5
  402. package/dist/examples-iiif/issue-242-nonlatin.json +239 -0
  403. package/dist/examples-iiif/issue-272-facebook.json +9 -5
  404. package/dist/examples-iiif/issue-305-start-at-slide-data.json +305 -0
  405. package/dist/examples-iiif/issue-305-start-at-slide.json +9 -5
  406. package/dist/examples-iiif/issue-341-distance.json +9 -5
  407. package/dist/examples-iiif/issue-358-iframe.json +190 -0
  408. package/dist/examples-iiif/issue-360-juxtapose.json +22 -7
  409. package/dist/examples-iiif/issue-368-null-fields.json +9 -5
  410. package/dist/examples-iiif/issue-375-code-lists.json +9 -5
  411. package/dist/examples-iiif/issue-381-dateline.json +9 -5
  412. package/dist/examples-iiif/issue-405-custom-icon.json +203 -0
  413. package/dist/examples-iiif/issue-425-many-slides.json +9 -5
  414. package/dist/examples-iiif/issue-428-background.json +20 -8
  415. package/dist/examples-iiif/issue-435-googlemaps.json +9 -5
  416. package/dist/examples-iiif/issue-437-documentcloud.json +22 -7
  417. package/dist/examples-iiif/issue-451-webp.json +9 -5
  418. package/dist/examples-iiif/issue-455-audio.json +9 -5
  419. package/dist/examples-iiif/issue-480-shorts.json +9 -5
  420. package/dist/examples-iiif/issue-506-marker-sync.json +9 -5
  421. package/dist/examples-iiif/issue-iiif-geo.json +200 -0
  422. package/dist/examples-iiif/issue-image-alt.json +90 -0
  423. package/dist/examples-iiif/issue-image-region.json +203 -0
  424. package/dist/examples-iiif/issue-image-srcset.json +87 -0
  425. package/dist/examples-iiif/jansteen.json +9 -6
  426. package/dist/examples-iiif/katrina.json +197 -41
  427. package/dist/examples-iiif/layers-control.json +226 -0
  428. package/dist/examples-iiif/map-area-overlays.json +289 -0
  429. package/dist/examples-iiif/map-template-provider.json +133 -0
  430. package/dist/examples-iiif/marktwain.json +255 -58
  431. package/dist/examples-iiif/multi-media.json +237 -0
  432. package/dist/examples-iiif/no-map.json +148 -0
  433. package/dist/examples-iiif/population.json +440 -76
  434. package/dist/examples-iiif/president.json +456 -83
  435. package/dist/examples-iiif/scroll-hint.json +190 -0
  436. package/dist/examples-iiif/seurat.json +113 -22
  437. package/dist/examples-iiif/zoomify-clamp.json +153 -0
  438. package/dist/examples-slideshow/single.json +79 -0
  439. package/dist/examples-slideshow/static/pixel.png +0 -0
  440. package/dist/examples-slideshow/static.json +44 -0
  441. package/dist/harness-multi.html +17 -0
  442. package/dist/harness.html +4 -2
  443. package/dist/index.html +19 -12
  444. package/dist/js/storymap.d.ts +2669 -307
  445. package/dist/js/storymap.js +10820 -6196
  446. package/dist/js/storymap.js.map +1 -1
  447. package/dist/navplace-properties.json +54 -0
  448. package/dist/site.css +54 -36
  449. package/docs/migration-from-knightlab.md +279 -19
  450. package/docs/storymap-as-iiif-manifest.md +633 -136
  451. package/package.json +12 -7
  452. package/schema/storymap.schema.json +733 -80
  453. package/src/animation/easings.ts +8 -1
  454. package/src/animation/tween.ts +186 -0
  455. package/src/core/Browser.ts +6 -5
  456. package/src/core/Load.ts +54 -2
  457. package/src/core/Util.ts +257 -193
  458. package/src/core/mixins.ts +66 -35
  459. package/src/core/viewers.ts +94 -0
  460. package/src/dom/DomEvent.ts +27 -8
  461. package/src/globals.d.ts +8 -0
  462. package/src/language/Language.ts +206 -25
  463. package/src/language/locale/.expected-gaps.json +346 -0
  464. package/src/language/locale/be.json +15 -2
  465. package/src/language/locale/bg.json +15 -2
  466. package/src/language/locale/cs.json +15 -2
  467. package/src/language/locale/de.json +23 -2
  468. package/src/language/locale/el.json +15 -2
  469. package/src/language/locale/en.json +17 -3
  470. package/src/language/locale/es.json +15 -2
  471. package/src/language/locale/et.json +5 -1
  472. package/src/language/locale/fr.json +15 -2
  473. package/src/language/locale/he.json +16 -3
  474. package/src/language/locale/hu.json +15 -2
  475. package/src/language/locale/is.json +5 -1
  476. package/src/language/locale/it.json +15 -2
  477. package/src/language/locale/jp.json +15 -2
  478. package/src/language/locale/ko.json +15 -2
  479. package/src/language/locale/nl.json +15 -2
  480. package/src/language/locale/nn.json +5 -1
  481. package/src/language/locale/no.json +15 -2
  482. package/src/language/locale/pl.json +15 -2
  483. package/src/language/locale/pt.json +15 -2
  484. package/src/language/locale/ru.json +15 -2
  485. package/src/language/locale/sk.json +15 -2
  486. package/src/language/locale/sr.json +5 -1
  487. package/src/language/locale/sv.json +15 -2
  488. package/src/language/locale/tr.json +15 -2
  489. package/src/language/locale/uk.json +15 -2
  490. package/src/language/locale/ur.json +5 -1
  491. package/src/language/locale/zh-cn.json +15 -2
  492. package/src/language/locale/zh-tw.json +15 -2
  493. package/src/main.ts +143 -0
  494. package/src/map/Map.ts +227 -112
  495. package/src/map/MapMarker.ts +44 -8
  496. package/src/map/georeference.ts +325 -0
  497. package/src/map/openlayers/Map.OpenLayers.ts +1601 -263
  498. package/src/map/openlayers/MapMarker.OpenLayers.ts +348 -24
  499. package/src/map/openlayers/zoomifyTiles.ts +1 -4
  500. package/src/map/slideView.ts +149 -0
  501. package/src/map/types.ts +2 -0
  502. package/src/media/EmbedUtil.ts +333 -24
  503. package/src/media/Media.ts +270 -59
  504. package/src/media/embedId.ts +110 -0
  505. package/src/media/types/Audio.ts +9 -82
  506. package/src/media/types/Blockquote.ts +2 -3
  507. package/src/media/types/DailyMotion.ts +5 -10
  508. package/src/media/types/DocumentCloud.ts +6 -35
  509. package/src/media/types/Facebook.ts +3 -4
  510. package/src/media/types/Flickr.ts +23 -12
  511. package/src/media/types/GoogleDoc.ts +3 -4
  512. package/src/media/types/HtmlMedia.ts +233 -0
  513. package/src/media/types/IFrame.ts +3 -4
  514. package/src/media/types/Image.ts +87 -9
  515. package/src/media/types/Juxtapose.ts +14 -5
  516. package/src/media/types/SoundCloud.ts +28 -6
  517. package/src/media/types/Text.ts +46 -21
  518. package/src/media/types/Twitter.ts +35 -20
  519. package/src/media/types/Video.ts +9 -79
  520. package/src/media/types/Vimeo.ts +11 -11
  521. package/src/media/types/Website.ts +23 -13
  522. package/src/media/types/Wikipedia.ts +18 -8
  523. package/src/media/types/YouTube.ts +72 -40
  524. package/src/scss/Typography.scss +16 -18
  525. package/src/scss/VCO.StoryMap.scss +208 -12
  526. package/src/scss/Variables.scss +3 -2
  527. package/src/scss/core/Mixins.scss +5 -63
  528. package/src/scss/core/Reset.scss +5 -18
  529. package/src/scss/fonts/font.amatic-andika.scss +3 -0
  530. package/src/scss/fonts/font.bitter-raleway.scss +6 -0
  531. package/src/scss/fonts/font.cairo.scss +79 -0
  532. package/src/scss/fonts/font.clicker-garamond.scss +5 -0
  533. package/src/scss/fonts/font.dancing-ledger.scss +1 -0
  534. package/src/scss/fonts/font.knightlab.scss +14 -0
  535. package/src/scss/fonts/font.oldstandard.scss +6 -0
  536. package/src/scss/fonts/font.opensans-gentiumbook.scss +5 -0
  537. package/src/scss/fonts/font.playfair-faunaone.scss +2 -0
  538. package/src/scss/fonts/font.playfair.scss +4 -0
  539. package/src/scss/fonts/font.pt.scss +6 -0
  540. package/src/scss/fonts/font.ubuntu.scss +4 -0
  541. package/src/scss/fonts/font.unicaone-vollkorn.scss +5 -0
  542. package/src/scss/map/VCO.Map.scss +1 -1
  543. package/src/scss/map/VCO.MapMarker.scss +114 -8
  544. package/src/scss/map/openlayers/VCO.Map.OpenLayers.scss +7 -4
  545. package/src/scss/media/VCO.Media.scss +14 -17
  546. package/src/scss/media/types/VCO.Media.Blockquote.scss +1 -1
  547. package/src/scss/media/types/VCO.Media.Text.scss +13 -5
  548. package/src/scss/media/types/VCO.Media.Twitter.scss +4 -4
  549. package/src/scss/media/types/VCO.Media.Wikipedia.scss +3 -19
  550. package/src/scss/site/site.scss +55 -36
  551. package/src/scss/slider/VCO.Slide.scss +61 -13
  552. package/src/scss/slider/VCO.SlideNav.scss +34 -24
  553. package/src/scss/slider/VCO.StorySlider.scss +53 -1
  554. package/src/scss/snapmap/VCO.SnapMap.scss +3 -3
  555. package/src/scss/ui/VCO.Consent.scss +63 -13
  556. package/src/scss/ui/VCO.Layers.scss +119 -0
  557. package/src/scss/ui/VCO.MenuBar.Button.scss +143 -14
  558. package/src/scss/ui/VCO.MenuBar.scss +9 -2
  559. package/src/scss/ui/VCO.Message.scss +16 -5
  560. package/src/site/site.ts +2 -1
  561. package/src/slider/Slide.ts +326 -74
  562. package/src/slider/SlideNav.ts +54 -9
  563. package/src/slider/StorySlider.ts +352 -60
  564. package/src/storymap/Consent.ts +429 -82
  565. package/src/storymap/StoryMap.ts +2163 -340
  566. package/src/storymap/content-state.ts +180 -0
  567. package/src/storymap/font-css.ts +72 -0
  568. package/src/storymap/from-slideshow.ts +785 -0
  569. package/src/storymap/iiif-shared.ts +228 -0
  570. package/src/storymap/iiif.ts +1742 -95
  571. package/src/storymap/to-iiif.ts +1008 -0
  572. package/src/storymap/validate.ts +80 -7
  573. package/src/types.ts +591 -29
  574. package/src/ui/LayersControl.ts +302 -0
  575. package/src/ui/MenuBar.ts +325 -61
  576. package/src/ui/Message.ts +44 -2
  577. package/src/ui/Swipable.ts +170 -85
  578. package/dist/assets/demo-D6cTmzn6.js +0 -1
  579. package/dist/assets/harness-BPFlzutp.js +0 -1
  580. package/dist/assets/index-DDsPBPZA.js +0 -1
  581. package/dist/assets/main-Y-MYUSJ4.js +0 -17
  582. package/src/animation/morpheus.d.ts +0 -41
  583. package/src/scss/VCO.StoryMap.Dark.scss +0 -138
  584. package/src/scss/Variables.Dark.scss +0 -56
  585. package/src/scss/media/types/VCO.Media.Instagram.scss +0 -7
  586. package/src/scss/media/types/VCO.Media.Profile.scss +0 -5
  587. package/src/ui/Draggable.ts +0 -374
@@ -1,6 +1,31 @@
1
1
  import { Media } from "../Media";
2
2
  import Dom from "../../dom/Dom";
3
- import { Language } from "../../language/Language";
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
+ }
4
29
 
5
30
  /* Media.Image
6
31
  Produces image assets.
@@ -8,18 +33,24 @@ import { Language } from "../../language/Language";
8
33
  ================================================== */
9
34
 
10
35
  export default class Image extends Media {
36
+ /** The `load` handler on the image, stored so dispose() can detach it. */
37
+ declare "_onLoad": (() => void) | null;
38
+
11
39
  /* Load the media
12
40
  ================================================== */
13
41
  _loadMedia() {
14
42
  // Loading Message
15
- this.message.updateMessage(Language.messages.loading + " " + this.options.media_name);
43
+ this.loadingMessage();
16
44
 
17
- // Link
18
- if (this.data.link) {
45
+ // Link — protocol-checked: a `javascript:` href in the storymap JSON
46
+ // would be a click-through XSS (see Media._initLayout)
47
+ const link_href = this.data.link ? validateWebURL(this.data.link) : null;
48
+ if (link_href) {
19
49
  this._el.content_link = Dom.create("a", "", this._el.content);
20
50
  const content_link = this._el.content_link as HTMLAnchorElement;
21
- content_link.href = this.data.link;
51
+ content_link.href = link_href;
22
52
  content_link.target = "_blank";
53
+ content_link.rel = "noopener noreferrer";
23
54
  this._el.content_item = Dom.create(
24
55
  "img",
25
56
  "vco-media-item vco-media-image vco-media-shadow",
@@ -33,17 +64,64 @@ export default class Image extends Media {
33
64
  );
34
65
  }
35
66
 
36
- // Media Loaded Event
37
- this._el.content_item.addEventListener("load", (e) => {
67
+ // Media Loaded Event. The reference is kept so dispose() can detach
68
+ // it: an inline arrow function has no other handle.
69
+ this._onLoad = () => {
38
70
  this.onMediaLoaded();
39
- });
71
+ };
72
+ this._el.content_item.addEventListener("load", this._onLoad);
40
73
 
41
- (this._el.content_item as HTMLImageElement).src = this.data.url;
74
+ const img = this._el.content_item as HTMLImageElement;
75
+ // offscreen/preloaded slides stay lazy (the active slide is
76
+ // upgraded to eager on activation, see Slide.setActive); decoding
77
+ // is only a hint — old browsers ignore both attributes
78
+ img.decoding = "async";
79
+ img.loading = this._state.eager ? "eager" : "lazy";
80
+ // responsive sizes (perf): IIIF image URLs request a container-
81
+ // matched width; author-provided srcset/sizes pass through;
82
+ // everything else renders byte-identically
83
+ const media_width = Number(this.options.width) || 0;
84
+ const sized = iiifSizedUrl(this._url(), media_width);
85
+ img.src = sized ?? this._url();
86
+ // accessibility: explicit alt text, falling back to the caption as
87
+ // plain text; an empty string marks a decorative image
88
+ img.alt = this._altText();
89
+ if (this.data.srcset) {
90
+ img.srcset = this.data.srcset as string;
91
+ }
92
+ if (this.data.sizes) {
93
+ img.sizes = this.data.sizes as string;
94
+ }
42
95
 
96
+ // the element is built and the src is set: hand over to Media so the
97
+ // loading overlay is hidden and credit/caption are rendered. The
98
+ // `load` listener above only fires the separate media_loaded event.
43
99
  this.onLoaded();
44
100
  }
45
101
 
102
+ _altText(): string {
103
+ const alt = this.data.alt as string | undefined;
104
+ if (alt !== undefined && alt !== "") {
105
+ return alt;
106
+ }
107
+ const caption = this.data.caption as string | null | undefined;
108
+ if (caption) {
109
+ return caption
110
+ .replace(/<[^>]*>/g, " ")
111
+ .replace(/\s+/g, " ")
112
+ .trim();
113
+ }
114
+ return "";
115
+ }
116
+
46
117
  _updateMediaDisplay(layout?: string) {
47
118
  // modern browsers size media correctly without engine-specific fixes
48
119
  }
120
+
121
+ _disposeMedia(): void {
122
+ if (this._onLoad) {
123
+ this._el.content_item?.removeEventListener("load", this._onLoad);
124
+ this._onLoad = null;
125
+ }
126
+ }
49
127
  }
@@ -1,6 +1,6 @@
1
1
  import { Media } from "../Media";
2
2
  import Dom from "../../dom/Dom";
3
- import { Language } from "../../language/Language";
3
+ import { buildIframe } from "../EmbedUtil";
4
4
 
5
5
  /* Media.Juxtapose
6
6
  Embeds a JuxtaposeJS before/after slider (issue #360)
@@ -11,7 +11,7 @@ export default class Juxtapose extends Media {
11
11
  ================================================== */
12
12
  _loadMedia() {
13
13
  // Loading Message
14
- this.message.updateMessage(Language.messages.loading + " " + this.options.media_name);
14
+ this.loadingMessage();
15
15
 
16
16
  // Create Dom element
17
17
  this._el.content_item = Dom.create(
@@ -20,13 +20,22 @@ export default class Juxtapose extends Media {
20
20
  this._el.content,
21
21
  );
22
22
 
23
- // published Juxtapose URLs are iframe-ready embeds
24
- this._el.content_item.innerHTML = `<iframe src="${this.data.url}" />`;
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);
25
34
  this.onLoaded();
26
35
  }
27
36
 
28
37
  // Update Media Display
29
38
  _updateMediaDisplay() {
30
- this._el.content_item.style.height = this.options.height + "px";
39
+ this._sizeContentItemToOptionHeight();
31
40
  }
32
41
  }
@@ -1,6 +1,6 @@
1
1
  import { Media } from "../Media";
2
2
  import Dom from "../../dom/Dom";
3
- import { Language } from "../../language/Language";
3
+ import { sanitizeSlideText } from "../EmbedUtil";
4
4
 
5
5
  /* Media.SoundCloud
6
6
  ================================================== */
@@ -8,18 +8,19 @@ import { Language } from "../../language/Language";
8
8
  /* Minimal surface of the SoundCloud widget API used here. */
9
9
  interface SoundCloudWidget {
10
10
  pause: () => void;
11
+ unbind?: () => void;
11
12
  }
12
13
 
13
14
  export default class SoundCloud extends Media {
14
15
  declare "media_id": string;
15
16
  declare "soundCloudCreated": boolean;
16
- declare "widget": SoundCloudWidget;
17
+ declare "widget": SoundCloudWidget | null;
17
18
 
18
19
  /* Load the media
19
20
  ================================================== */
20
21
  async _loadMedia() {
21
22
  // Loading Message
22
- this.message.updateMessage(Language.messages.loading + " " + this.options.media_name);
23
+ this.loadingMessage();
23
24
 
24
25
  // Create Dom element
25
26
  this._el.content_item = Dom.create(
@@ -29,7 +30,7 @@ export default class SoundCloud extends Media {
29
30
  );
30
31
 
31
32
  // Get Media ID
32
- this.media_id = this.data.url;
33
+ this.media_id = this._url();
33
34
 
34
35
  // API URL
35
36
  const api_url = "https://soundcloud.com/oembed?url=" + this.media_id + "&format=json";
@@ -56,14 +57,24 @@ export default class SoundCloud extends Media {
56
57
  this.loadErrorDisplay("Unable to load this track.");
57
58
  return;
58
59
  }
59
- this._el.content_item.innerHTML = data.html;
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));
60
71
 
61
72
  this.soundCloudCreated = true;
62
73
 
63
74
  const sc = SC as { Widget: (iframe: Element | null) => SoundCloudWidget };
64
75
  // per-instance widget: a global would be overwritten by every
65
76
  // SoundCloud slide and _stopMedia would pause the wrong one
66
- this.widget = sc.Widget(this._el.content_item.querySelector("iframe"));
77
+ this.widget = sc.Widget(content_item.querySelector("iframe"));
67
78
 
68
79
  // After Loaded
69
80
  this.onLoaded();
@@ -74,4 +85,15 @@ export default class SoundCloud extends Media {
74
85
  this.widget?.pause();
75
86
  }
76
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.warn("StoryMapJS: error unbinding SoundCloud widget.", err);
95
+ }
96
+ this.widget = null;
97
+ this.soundCloudCreated = false;
98
+ }
77
99
  }
@@ -1,6 +1,7 @@
1
- import { mergeData, setData, htmlify, convertUnixTime } from "../../core/Util";
1
+ import { mergeData, htmlify, convertUnixTime } from "../../core/Util";
2
2
  import { Evented, type EventedInstance } from "../../core/mixins";
3
3
  import Dom from "../../dom/Dom";
4
+ import { sanitizeSlideText } from "../EmbedUtil";
4
5
 
5
6
  interface TextData {
6
7
  uniqueid?: string | null;
@@ -13,13 +14,21 @@ interface TextData {
13
14
  interface TextOptions {
14
15
  title?: boolean;
15
16
  text_align?: string;
17
+ /** BCP 47 tag for the slide text (from `StorymapSlide.language`). */
18
+ language?: string;
19
+ }
20
+
21
+ export interface TextEvents {
22
+ loaded: TextData;
23
+ added: TextData;
24
+ removed: TextData;
16
25
  }
17
26
 
18
27
  class TextBase {
19
28
  declare "_el": Record<string, HTMLElement>;
20
29
  declare "data": TextData;
21
30
  declare "options": TextOptions;
22
- declare "fire": EventedInstance["fire"];
31
+ declare "fire": EventedInstance<TextEvents>["fire"];
23
32
 
24
33
  /* Constructor
25
34
  ================================================== */
@@ -34,11 +43,14 @@ class TextBase {
34
43
  start_btn: {} as HTMLElement,
35
44
  };
36
45
 
37
- // Data
46
+ // Data. The placeholders were the literal strings "headline" and
47
+ // "text", which mergeData only overwrites when the key is present — so
48
+ // a slide with body text and no headline rendered an <h2>headline</h2>.
49
+ // The renderer guards both on `!== ""`, so empty is the real default.
38
50
  this.data = {
39
51
  uniqueid: "",
40
- headline: "headline",
41
- text: "text",
52
+ headline: "",
53
+ text: "",
42
54
  };
43
55
 
44
56
  // Options
@@ -46,13 +58,22 @@ class TextBase {
46
58
  title: false,
47
59
  };
48
60
 
49
- setData(this, data);
61
+ mergeData(this.data, data);
50
62
 
51
63
  // Merge Options
52
64
  mergeData(this.options, options);
53
65
 
54
66
  this._el.container = Dom.create("div", "vco-text");
55
- this._el.container.id = this.data.uniqueid;
67
+ this._el.container.id = this.data.uniqueid ?? "";
68
+ // Pronounce mixed-language slides correctly: the reader reports
69
+ // which language map it picked, and the DOM should say so too.
70
+ if (
71
+ typeof this.options.language === "string" &&
72
+ this.options.language !== "" &&
73
+ this.options.language !== "none"
74
+ ) {
75
+ this._el.container.setAttribute("lang", this.options.language);
76
+ }
56
77
 
57
78
  this._initLayout();
58
79
 
@@ -120,27 +141,31 @@ class TextBase {
120
141
  this._el.content_container.classList.add("vco-text-align-" + align);
121
142
  }
122
143
 
123
- // Date (only rendered when the slide has one; issue #286)
124
- if (this.data.date && this.data.date.created_time && this.data.date.created_time !== "") {
125
- this._el.date = Dom.create("h3", "vco-headline-date", this._el.content_container);
126
- this.addDateText(convertUnixTime(this.data.date.created_time));
127
- }
128
-
129
- // Headline
130
- if (this.data.headline !== "") {
144
+ // Headline (sanitized; issue #358 keeps formatting but drops scripts)
145
+ const headline = this.data.headline ?? "";
146
+ if (headline !== "") {
131
147
  let headline_class = "vco-headline";
132
148
  if (this.options.title) {
133
149
  headline_class = "vco-headline vco-headline-title";
134
150
  }
135
151
  this._el.headline = Dom.create("h2", headline_class, this._el.content_container);
136
- this._el.headline.innerHTML = this.data.headline;
152
+ this._el.headline.appendChild(sanitizeSlideText(headline));
153
+ }
154
+
155
+ // Date (only rendered when the slide has one; issue #286). Emitted
156
+ // after the headline and as a <p> (issue #385 wave): an <h3> before
157
+ // the <h2> was a heading-order skip
158
+ if (this.data.date && this.data.date.created_time && this.data.date.created_time !== "") {
159
+ this._el.date = Dom.create("p", "vco-headline-date", this._el.content_container);
160
+ this.addDateText(convertUnixTime(this.data.date.created_time));
137
161
  }
138
162
 
139
- // Text
140
- if (this.data.text !== "") {
163
+ // Text (sanitized; issue #358 allows extra iframe media in the text field)
164
+ const text = this.data.text ?? "";
165
+ if (text !== "") {
141
166
  let text_content = "";
142
167
 
143
- text_content += htmlify(this.data.text);
168
+ text_content += htmlify(text);
144
169
 
145
170
  // Date
146
171
  if (
@@ -157,7 +182,7 @@ class TextBase {
157
182
  }
158
183
 
159
184
  this._el.content = Dom.create("div", "vco-text-content", this._el.content_container);
160
- this._el.content.innerHTML = text_content;
185
+ this._el.content.appendChild(sanitizeSlideText(text_content));
161
186
  }
162
187
 
163
188
  // Fire event that the slide is loaded
@@ -165,7 +190,7 @@ class TextBase {
165
190
  }
166
191
  }
167
192
 
168
- export default class Text extends Evented(TextBase) {
193
+ export default class Text extends Evented<TextEvents, typeof TextBase>(TextBase) {
169
194
  constructor(...args: ConstructorParameters<typeof TextBase>) {
170
195
  super(...args);
171
196
  }
@@ -1,6 +1,7 @@
1
1
  import { Media } from "../Media";
2
2
  import Dom from "../../dom/Dom";
3
- import { Language } from "../../language/Language";
3
+ import { sanitizeSlideText } from "../EmbedUtil";
4
+ import { tweetAuthor, tweetId } from "../embedId";
4
5
  import { loadJSONP, uniqueGlobalName } from "../../core/Load";
5
6
 
6
7
  /* Media.Twitter
@@ -15,18 +16,21 @@ export default class Twitter extends Media {
15
16
  ================================================== */
16
17
  _loadMedia() {
17
18
  // Loading Message
18
- this.message.updateMessage(Language.messages.loading + " " + this.options.media_name);
19
+ this.loadingMessage();
19
20
 
20
21
  // Create Dom element
21
22
  this._el.content_item = Dom.create("div", "vco-media-twitter", this._el.content);
22
23
 
23
- // Get Media ID
24
-
25
- const r = /(?:twitter\.com|x\.com)\/(.+?)\/status\/(\d+)/;
26
- const match = r.exec(this.data.url);
27
- if (match) {
28
- this.user_id = match[1];
29
- this.media_id = match[2];
24
+ // Get Media ID — routed here by MediaType, extracted by the shared
25
+ // helpers so the accepted shapes cannot diverge again. The id stays
26
+ // numeric-only, as before: anything else is not a status URL.
27
+ const media_id = tweetId(this._url());
28
+ const user_id = tweetAuthor(this._url());
29
+ if (media_id && user_id && /^\d+$/.test(media_id)) {
30
+ this.user_id = user_id;
31
+ this.media_id = media_id;
32
+ } else {
33
+ throw new Error("Invalid Twitter URL");
30
34
  }
31
35
  const callbackName = uniqueGlobalName(`twitterCallback_${this.media_id}`);
32
36
  const api_url = `https://api.twitter.com/1/statuses/oembed.json?id=${this.media_id}&include_entities=true&callback=${callbackName}`;
@@ -43,17 +47,22 @@ export default class Twitter extends Media {
43
47
 
44
48
  createMedia(d: unknown) {
45
49
  const data = d as { html: string; author_url: string; author_name: string };
46
- let tweet = "",
47
- tweet_text;
48
-
50
+ if (!data?.html) {
51
+ this.loadErrorDisplay("Unable to load this post.");
52
+ return;
53
+ }
54
+ // The oEmbed markup is positional: the date link follows the tweet text
55
+ // after a "&mdash;" separator. Every step below is optional so a markup
56
+ // change upstream degrades to a missing date/link rather than throwing.
57
+ const afterText = data.html.split("</p>&mdash;")[1] ?? "";
58
+ const tweetuser = data.author_url.split(/twitter\.com|x\.com\//)[1] ?? "";
59
+ const statusLink = afterText.split('<a href="')[1] ?? "";
60
+ const tweet_status_url = statusLink.split('">')[0] ?? "";
61
+ const tweet_status_date = (statusLink.split('">')[1] ?? "").split("</a>")[0] ?? "";
62
+
63
+ let tweet = "";
49
64
  // TWEET CONTENT
50
- tweet_text = data.html.split("</p>&mdash;")[0] + "</p></blockquote>";
51
- // the oembed endpoint returns x.com URLs since the rebrand — parse both
52
- const tweetuser = data.author_url.split(/twitter\.com|x\.com\//)[1];
53
- const tweet_status_temp = data.html.split("</p>&mdash;")[1].split('<a href="')[1];
54
- const tweet_status_url = tweet_status_temp.split('">')[0];
55
- const tweet_status_date = tweet_status_temp.split('">')[1].split("</a>")[0];
56
-
65
+ let tweet_text = afterText ? data.html.split("</p>&mdash;")[0] + "</p></blockquote>" : "";
57
66
  // Open links in new window
58
67
  tweet_text = tweet_text.replace(/<a href/gi, '<a target="_blank" href');
59
68
 
@@ -84,7 +93,13 @@ export default class Twitter extends Media {
84
93
  tweet += "</div>";
85
94
 
86
95
  // Add to DOM
87
- this._el.content_item.innerHTML = tweet;
96
+ // The whole tweet is assembled from the oEmbed response's own HTML
97
+ // plus five string-concatenated fields, and that API does not escape
98
+ // HTML — so the result is untrusted third-party markup and goes
99
+ // through the sanitizer. It also repairs the four unguarded
100
+ // positional splits above: a markup change upstream now degrades to a
101
+ // missing date instead of throwing.
102
+ this._el.content_item?.appendChild(sanitizeSlideText(tweet));
88
103
 
89
104
  // After Loaded
90
105
  this.onLoaded();
@@ -1,84 +1,14 @@
1
- import { Media } from "../Media";
2
- import Dom from "../../dom/Dom";
3
- import { Language } from "../../language/Language";
1
+ import { HtmlMediaBase, type HtmlMediaKind } from "./HtmlMedia";
4
2
 
5
- /* Media.Vimeo
3
+ /* Media.Video
4
+ A <video> element with a single <source> child.
6
5
  ================================================== */
7
6
 
8
- export default class Video extends Media {
9
- declare "player_element": HTMLMediaElement;
10
-
11
- /* Load the media
12
- ================================================== */
13
- _loadMedia() {
14
- // Loading Message
15
- this.message.updateMessage(Language.messages.loading + " " + this.options.media_name);
16
-
17
- // Create Dom element
18
- this._el.content_item = Dom.create(
19
- "video",
20
- "vco-media-item vco-media-video vco-media-shadow",
21
- this._el.content,
22
- );
23
- const media_item = this._el.content_item as HTMLMediaElement;
24
- media_item.controls = true;
25
- this._el.source_item = Dom.create("source", "", this._el.content_item);
26
- const source_item = this._el.source_item as HTMLSourceElement;
27
-
28
- // Media Loaded Event
29
- media_item.addEventListener("canplay", () => {
30
- this.onLoaded();
31
- });
32
-
33
- // Load Error Event (the source element fires it, not the media element)
34
- source_item.addEventListener("error", () => {
35
- this.loadErrorDisplay(Language.messages.error + " " + this.options.media_name);
36
- });
37
-
38
- source_item.src = this.data.url;
39
- const media_type = this._getType(this.data.url, this.data.mediatype.match_str);
40
- if (media_type) {
41
- source_item.type = media_type;
42
- }
43
- // append as a text node: re-serializing innerHTML would replace the
44
- // source element and drop its error listener, leaving the loading
45
- // message on screen forever
46
- media_item.appendChild(
47
- document.createTextNode(
48
- "Your browser doesn't support HTML5 video with " + source_item.type,
49
- ),
50
- );
51
- this.player_element = media_item;
52
- }
53
-
54
- // Update Media Display
55
- _updateMediaDisplay() {
56
- // video height is CSS-driven; nothing to compute here
57
- }
58
-
59
- _stopMedia() {
60
- if (this.player_element) {
61
- this.player_element.pause();
62
- }
63
- }
64
-
65
- _getType(url: string, reg: string | RegExp) {
66
- const ext = url.match(reg);
67
- let type = "video/";
68
- if (!ext) {
69
- return type;
70
- }
71
- switch (ext[1]) {
72
- case "mp4":
73
- type += "mp4";
74
- break;
75
- case "webm":
76
- type += "webm";
77
- break;
78
- default:
79
- type = "";
80
- break;
81
- }
82
- return type;
7
+ export default class Video extends HtmlMediaBase {
8
+ protected spec() {
9
+ return {
10
+ kind: "video" as HtmlMediaKind,
11
+ extensions: { mp4: "mp4", webm: "webm" },
12
+ };
83
13
  }
84
14
  }
@@ -1,7 +1,6 @@
1
+ import { vimeoId } from "../embedId";
1
2
  import { Media } from "../Media";
2
3
  import Dom from "../../dom/Dom";
3
- import { Language } from "../../language/Language";
4
- import { ratio } from "../../core/Util";
5
4
 
6
5
  /* Media.Vimeo
7
6
  ================================================== */
@@ -14,7 +13,7 @@ export default class Vimeo extends Media {
14
13
  ================================================== */
15
14
  _loadMedia() {
16
15
  // Loading Message
17
- this.message.updateMessage(Language.messages.loading + " " + this.options.media_name);
16
+ this.loadingMessage();
18
17
 
19
18
  // Create Dom element
20
19
  this._el.content_item = Dom.create(
@@ -24,17 +23,19 @@ export default class Vimeo extends Media {
24
23
  );
25
24
 
26
25
  // Get Media ID
27
- const parts = this.data.url.split(/video\/|\/\/vimeo\.com\//);
28
- if (!parts[1]) {
26
+ this.media_id = vimeoId(this._url()) ?? "";
27
+ if (!this.media_id) {
29
28
  throw new Error("Invalid Vimeo URL");
30
29
  }
31
- this.media_id = parts[1].split(/[?&]/)[0];
32
30
 
33
- // API URL
31
+ // API URL — plain `&` separators. The HTML entity `&amp;` is correct
32
+ // inside markup but is not decoded in a URL property, so Vimeo was
33
+ // receiving params literally named `amp;byline` / `amp;color` and
34
+ // ignoring them.
34
35
  const api_url =
35
36
  "https://player.vimeo.com/video/" +
36
37
  this.media_id +
37
- "?api=1&title=0&amp;byline=0&amp;portrait=0&amp;color=ffffff";
38
+ "?api=1&title=0&byline=0&portrait=0&color=ffffff";
38
39
 
39
40
  this.player = Dom.create("iframe", "", this._el.content_item) as HTMLIFrameElement;
40
41
  this.player.width = "100%";
@@ -48,8 +49,7 @@ export default class Vimeo extends Media {
48
49
 
49
50
  // Update Media Display
50
51
  _updateMediaDisplay() {
51
- this._el.content_item.style.height =
52
- ratio.r16_9({ w: this._el.content_item.offsetWidth }) + "px";
52
+ this._sizeContentItemTo16x9();
53
53
  }
54
54
 
55
55
  _stopMedia() {
@@ -59,7 +59,7 @@ export default class Vimeo extends Media {
59
59
  "https://player.vimeo.com",
60
60
  );
61
61
  } catch (err) {
62
- console.log(err);
62
+ console.warn("StoryMapJS: error pausing Vimeo player.", err);
63
63
  }
64
64
  }
65
65
  }