@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
@@ -8,17 +8,42 @@
8
8
  /** Constructor shape accepted by the mixin functions. */
9
9
  export type Constructor<T = object> = new (...args: any[]) => T;
10
10
 
11
+ /** What a listener receives: the payload, plus the framework's own fields.
12
+ *
13
+ * Kept as an intersection because `fire` merges them into one object — that
14
+ * is what a handler gets. As a side effect it also fixes the `type`
15
+ * clobbering at the type level: intersecting `type: "loaded"` with
16
+ * `type?: string` yields `"loaded"`.
17
+ */
18
+ export type FiredEvent<M, K extends keyof M & string> = M[K] & { type: K; target: unknown };
19
+
11
20
  /** Eventing members provided by the Evented mixin. */
12
- export interface EventedInstance {
13
- on: (type: string, fn: unknown, context?: unknown) => unknown;
14
- off: (type: string, fn: unknown, context?: unknown) => unknown;
15
- fire: (type: string, data?: unknown, target?: unknown) => unknown;
16
- hasEventListeners: (type: string) => boolean;
21
+ export interface EventedInstance<M = Record<string, unknown>> {
22
+ on<K extends keyof M & string>(
23
+ type: K,
24
+ fn: (e: FiredEvent<M, K>) => void,
25
+ context?: unknown,
26
+ ): this;
27
+ off<K extends keyof M & string>(
28
+ type: K,
29
+ fn: (e: FiredEvent<M, K>) => void,
30
+ context?: unknown,
31
+ ): this;
32
+ fire<K extends keyof M & string>(type: K, data?: M[K]): this;
33
+ hasEventListeners<K extends keyof M & string>(type: K): boolean;
17
34
  }
18
35
 
19
- /** Instance contract for DomMixed consumers. */
20
- export interface DomMixedInstance extends EventedInstance {
21
- _el: Record<string, HTMLElement>;
36
+ /**
37
+ * Instance contract for DomMixed consumers.
38
+ *
39
+ * `_el` is deliberately `Record<string, unknown>`: each class declares its
40
+ * own element shape, and several of them hold members that are legitimately
41
+ * null before the component builds them (a slide's call-to-action, a
42
+ * slider's live region). Requiring `Record<string, HTMLElement>` here would
43
+ * force every one of those back into an `{} as HTMLElement` placeholder.
44
+ */
45
+ export interface DomMixedInstance<M = Record<string, unknown>> extends EventedInstance<M> {
46
+ _el: Record<string, unknown>;
22
47
  data?: unknown;
23
48
  }
24
49
 
@@ -28,7 +53,7 @@ export interface DomMixedInstance extends EventedInstance {
28
53
  ================================================== */
29
54
 
30
55
  /** Adds eventing (on/off/fire/hasEventListeners) to a class. */
31
- export function Evented<T extends Constructor>(Base: T) {
56
+ export function Evented<M, T extends Constructor>(Base: T) {
32
57
  return class extends Base {
33
58
  declare "_vco_events"?: Record<string, { action: unknown; context: unknown }[]>;
34
59
 
@@ -62,31 +87,25 @@ export function Evented<T extends Constructor>(Base: T) {
62
87
  string,
63
88
  { action: unknown; context: unknown }[]
64
89
  >;
65
- for (let i = 0, len = events[type].length; i < len; i++) {
66
- if (
67
- events[type][i].action === fn &&
68
- (!context || events[type][i].context === context)
69
- ) {
70
- events[type].splice(i, 1);
71
- return this;
72
- }
90
+ events[type] = events[type].filter(
91
+ (listener) =>
92
+ !(listener.action === fn && (!context || listener.context === context)),
93
+ );
94
+ if (events[type].length === 0) {
95
+ delete events[type];
73
96
  }
74
97
  return this;
75
98
  }
76
99
 
77
- fire(
78
- /*String*/ type: string,
79
- /*(optional) Object*/ data?: unknown,
80
- target?: unknown,
81
- ): this {
100
+ fire(/*String*/ type: string, /*(optional) Object*/ data?: unknown): this {
82
101
  if (!this.hasEventListeners(type)) {
83
102
  return this;
84
103
  }
85
104
 
86
105
  const event = {
87
- type: type,
88
- target: target || this,
89
106
  ...(data as Record<string, unknown> | undefined),
107
+ type,
108
+ target: this,
90
109
  };
91
110
 
92
111
  const listeners = (
@@ -103,7 +122,7 @@ export function Evented<T extends Constructor>(Base: T) {
103
122
  constructor(...args: any[]) {
104
123
  super(...args);
105
124
  }
106
- };
125
+ } as Constructor<EventedInstance<M>> & T;
107
126
  }
108
127
 
109
128
  /* DomMixed
@@ -113,29 +132,41 @@ export function Evented<T extends Constructor>(Base: T) {
113
132
 
114
133
  /** Adds DOM container conveniences (addTo/removeFrom/setPosition/show/hide
115
134
  * and the onAdd/onRemove/onLoaded lifecycle events) to a class. */
116
- export function DomMixed<T extends Constructor<DomMixedInstance>>(Base: T) {
135
+ export function DomMixed<
136
+ M extends { loaded: unknown; added: unknown; removed: unknown },
137
+ T extends Constructor<DomMixedInstance<M>>,
138
+ >(Base: T) {
117
139
  return class extends Base {
140
+ /**
141
+ * The host element. Every DomMixed consumer keeps its root element
142
+ * here, so this narrows the `Record<string, unknown>` element map to
143
+ * something with a style and children.
144
+ */
145
+ container(): HTMLElement {
146
+ return this._el.container as HTMLElement;
147
+ }
148
+
118
149
  /* Adding, Hiding, Showing etc
119
150
  ================================================== */
120
151
  show(animate?: unknown): void {
121
152
  if (!animate) {
122
- this._el.container.style.display = "block";
153
+ this.container().style.display = "block";
123
154
  }
124
155
  // animated show is not implemented
125
156
  }
126
157
 
127
158
  hide(): void {
128
- this._el.container.style.display = "none";
159
+ this.container().style.display = "none";
129
160
  }
130
161
 
131
162
  addTo(container: HTMLElement): this {
132
- container.appendChild(this._el.container);
163
+ container.appendChild(this.container());
133
164
  this.onAdd();
134
165
  return this;
135
166
  }
136
167
 
137
168
  removeFrom(container: HTMLElement): this {
138
- container.removeChild(this._el.container);
169
+ container.removeChild(this.container());
139
170
  this.onRemove();
140
171
  return this;
141
172
  }
@@ -143,7 +174,7 @@ export function DomMixed<T extends Constructor<DomMixedInstance>>(Base: T) {
143
174
  /* Set the Position
144
175
  ================================================== */
145
176
  setPosition(pos: Record<string, number>, el?: HTMLElement): this {
146
- const target = el || this._el.container;
177
+ const target = el || this.container();
147
178
  for (const name of Object.keys(pos)) {
148
179
  (target.style as unknown as Record<string, string>)[name] = pos[name] + "px";
149
180
  }
@@ -151,17 +182,17 @@ export function DomMixed<T extends Constructor<DomMixedInstance>>(Base: T) {
151
182
  }
152
183
 
153
184
  /* Lifecycle events
154
- ================================================== */
185
+ ================================================== */
155
186
  onLoaded(): void {
156
- this.fire("loaded", this.data);
187
+ this.fire("loaded", this.data as M["loaded"]);
157
188
  }
158
189
 
159
190
  onAdd(): void {
160
- this.fire("added", this.data);
191
+ this.fire("added", this.data as M["added"]);
161
192
  }
162
193
 
163
194
  onRemove(): void {
164
- this.fire("removed", this.data);
195
+ this.fire("removed", this.data as M["removed"]);
165
196
  }
166
197
 
167
198
  constructor(...args: any[]) {
@@ -0,0 +1,94 @@
1
+ /**
2
+ * A minimal registry of the viewers alive on this page.
3
+ *
4
+ * This is deliberately *not* a viewer singleton: nothing here owns or replaces
5
+ * a viewer, and the viewer itself holds all of its own state. It exists only
6
+ * so a viewer can answer the one question it cannot answer alone — "given a
7
+ * keypress or a focus change on the document, is this viewer the one that
8
+ * should react?" Two page-wide inputs (the arrow keys and `document.activeElement`)
9
+ * can only be attributed to a single viewer by comparing against the others.
10
+ *
11
+ * Entries are removed in `dispose()`, which is what keeps the registry from
12
+ * outliving the page content it describes.
13
+ */
14
+
15
+ /** What a viewer has to expose to take part in page-wide arbitration. */
16
+ export interface Participant {
17
+ /** The viewer's root element, or null before layout. */
18
+ readonly element: HTMLElement | null;
19
+ /** Higher means more recently interacted. */
20
+ readonly interaction: number;
21
+ }
22
+
23
+ /** Monotonic interaction clock. Shared, but it carries no state of its own. */
24
+ let interactionClock = 0;
25
+
26
+ const participants = new Set<Participant>();
27
+
28
+ /** Stamp an interaction. Returns the new value, for the caller to store. */
29
+ export function markInteraction(): number {
30
+ interactionClock += 1;
31
+ return interactionClock;
32
+ }
33
+
34
+ /** The interaction value currently held by the most recent participant. */
35
+ function latestInteraction(): number {
36
+ let latest = -1;
37
+ for (const participant of participants) {
38
+ if (participant.interaction > latest) {
39
+ latest = participant.interaction;
40
+ }
41
+ }
42
+ return latest;
43
+ }
44
+
45
+ /** Add a viewer. Call from the same place that registers its listeners. */
46
+ export function registerParticipant(participant: Participant): void {
47
+ participants.add(participant);
48
+ }
49
+
50
+ /** Remove a viewer. Call from `dispose()`. */
51
+ export function unregisterParticipant(participant: Participant): void {
52
+ participants.delete(participant);
53
+ }
54
+
55
+ /** The registered viewer whose element contains `node`, if any. */
56
+ export function participantFor(node: Node | null): Participant | null {
57
+ if (!node) {
58
+ return null;
59
+ }
60
+ for (const participant of participants) {
61
+ if (participant.element && participant.element.contains(node)) {
62
+ return participant;
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * The viewer that should react to a page-wide event.
70
+ *
71
+ * Focus wins over recency: if the visitor has focused one viewer, arrow keys
72
+ * belong to it even if they last clicked a different one. With nothing focused
73
+ * — the common case, since clicking a `<div>` does not move focus — the most
74
+ * recently interacted viewer takes it, so the viewer the visitor just used is
75
+ * the one that responds.
76
+ *
77
+ * @param viewer - The viewer asking whether it should react.
78
+ * @returns True if this viewer owns the event.
79
+ */
80
+ export function ownsPageEvent(viewer: Participant): boolean {
81
+ const active = typeof document === "undefined" ? null : document.activeElement;
82
+ // body (or null) means the visitor has focused nothing viewer-specific
83
+ const focused = participantFor(active);
84
+ if (focused) {
85
+ return focused === viewer;
86
+ }
87
+ // no viewer holds focus, so the most recently interacted one responds
88
+ return viewer.interaction === latestInteraction();
89
+ }
90
+
91
+ /** The viewers currently registered. Test helper. */
92
+ export function registeredParticipants(): readonly Participant[] {
93
+ return [...participants];
94
+ }
@@ -16,6 +16,21 @@ export type LegacyEvent = Event & {
16
16
  pageY?: number;
17
17
  };
18
18
 
19
+ /**
20
+ * The wrapper is remembered on the target so `removeListener` can find it
21
+ * again. Keyed by a per-registration counter rather than only by the stamped
22
+ * function: registering the same function twice for the same event used to
23
+ * overwrite the key, leaving the first listener permanently unremovable.
24
+ */
25
+ const registrationCounts = new WeakMap<object, number>();
26
+
27
+ function handlerKey(obj: DomEventTarget, type: string, fn: (e: Event) => void): string {
28
+ const target = obj as object;
29
+ const next = (registrationCounts.get(target) ?? 0) + 1;
30
+ registrationCounts.set(target, next);
31
+ return "_vco_" + type + stamp(fn) + "_" + next;
32
+ }
33
+
19
34
  const DomEvent = {
20
35
  addListener: function (
21
36
  obj: DomEventTarget,
@@ -28,7 +43,7 @@ const DomEvent = {
28
43
  };
29
44
 
30
45
  obj.addEventListener(type, handler, false);
31
- (obj as unknown as Record<string, unknown>)["_vco_" + type + stamp(fn)] = handler;
46
+ (obj as unknown as Record<string, unknown>)[handlerKey(obj, type, fn)] = handler;
32
47
  },
33
48
 
34
49
  removeListener: function (
@@ -37,15 +52,19 @@ const DomEvent = {
37
52
  fn: (e: Event) => void,
38
53
  context?: unknown,
39
54
  ): void {
40
- const key = "_vco_" + type + stamp(fn);
41
- const handler = (obj as unknown as Record<string, unknown>)[key];
42
-
43
- if (!handler) {
55
+ // The most recent registration for this (type, fn) pair is the one the
56
+ // caller means; walk the counter back to find it.
57
+ const target = obj as unknown as Record<string, unknown>;
58
+ for (let n = registrationCounts.get(obj as object) ?? 0; n > 0; n--) {
59
+ const key = "_vco_" + type + stamp(fn) + "_" + n;
60
+ const handler = target[key];
61
+ if (!handler) {
62
+ continue;
63
+ }
64
+ obj.removeEventListener(type, handler as EventListener, false);
65
+ target[key] = null;
44
66
  return;
45
67
  }
46
-
47
- obj.removeEventListener(type, handler as EventListener, false);
48
- (obj as unknown as Record<string, unknown>)[key] = null;
49
68
  },
50
69
 
51
70
  preventDefault: function (e: Event): void {
package/src/globals.d.ts CHANGED
@@ -11,6 +11,14 @@ declare global {
11
11
  const SC: {
12
12
  Widget: (el: HTMLElement) => { pause(): void };
13
13
  };
14
+
15
+ /**
16
+ * The library version, substituted from package.json by the Vite lib build
17
+ * (see the `define` in vite.config.ts). Hard-coded here only so the
18
+ * source type-checks; a dev-server run without the define falls back to
19
+ * "unknown" at runtime via the typeof guard in StoryMap.
20
+ */
21
+ const __STORYMAP_VERSION__: string;
14
22
  }
15
23
 
16
24
  export {};
@@ -1,3 +1,40 @@
1
+ /**
2
+ * UI strings for the active locale.
3
+ *
4
+ * English is the fallback for every missing key (see `getLanguage`), so
5
+ * `messages` and `buttons` are guaranteed to be fully populated once a
6
+ * language has been set — they are typed as required here rather than as
7
+ * `Record<string, string> | undefined` so call sites do not need a null
8
+ * check on every one of the ~30 `Language.messages.*` reads.
9
+ *
10
+ * The locale JSON files themselves are *not* complete: only `en.json` defines
11
+ * every key, and 28 of the 29 bundled locales are missing 8-10 of them
12
+ * (the per-service consent strings and the fullscreen button labels). The
13
+ * runtime falls back to English per key, so this is a translation gap rather
14
+ * than a defect — `npm run check:locales` reports it.
15
+ */
16
+ export interface LanguageEntry {
17
+ /** Display name of the language, e.g. "Deutsch". */
18
+ name?: string;
19
+ /** BCP 47 code, e.g. "de". */
20
+ lang?: string;
21
+ /** Writing direction; drives the `vco-rtl` layout. */
22
+ direction?: "ltr" | "rtl";
23
+ messages: Record<string, string>;
24
+ buttons: Record<string, string>;
25
+ [key: string]: unknown;
26
+ }
27
+
28
+ // The locales are imported statically rather than through `import.meta.glob`
29
+ // on purpose. The viewer reads `Language.messages.*` while it is being
30
+ // constructed — the consent dialog, the RTL class, the swipe hint icon and
31
+ // every button label are all decided synchronously inside `new StoryMap()` —
32
+ // so a locale that has not finished fetching yet would silently render in
33
+ // English. The saving from splitting them is ~6 kB gzip, which is not worth
34
+ // making the language load order-dependent.
35
+ //
36
+ // English remains the fallback for every key a translation is missing (see
37
+ // `getLanguage`), and `npm run check:locales` reports those gaps.
1
38
  import be from "./locale/be.json";
2
39
  import bg from "./locale/bg.json";
3
40
  import cs from "./locale/cs.json";
@@ -28,14 +65,6 @@ import ur from "./locale/ur.json";
28
65
  import zhCn from "./locale/zh-cn.json";
29
66
  import zhTw from "./locale/zh-tw.json";
30
67
 
31
- interface LanguageEntry {
32
- buttons?: Record<string, string>;
33
- messages?: Record<string, string>;
34
- [key: string]: unknown;
35
- }
36
-
37
- // Static locale map: the bundler-agnostic form of what `import.meta.glob`
38
- // with `{ eager: true }` desugars to (works in vite dev and rollup builds).
39
68
  const localeModules: Record<string, { default?: unknown }> = {
40
69
  "./locale/be.json": { default: be },
41
70
  "./locale/bg.json": { default: bg },
@@ -68,40 +97,192 @@ const localeModules: Record<string, { default?: unknown }> = {
68
97
  "./locale/zh-tw.json": { default: zhTw },
69
98
  };
70
99
 
100
+ /** The locale every other language falls back to, per key. */
71
101
  const EN: Record<string, unknown> =
72
102
  (localeModules["./locale/en.json"]?.default as Record<string, unknown> | undefined) || {};
73
103
 
74
- let Language: LanguageEntry = {};
104
+ /** The strings the viewer reads before (or without) a `setLanguage` call. */
105
+ const FALLBACK: LanguageEntry = {
106
+ name: "English",
107
+ lang: "en",
108
+ direction: "ltr",
109
+ messages: (EN.messages as Record<string, string>) ?? {},
110
+ buttons: (EN.buttons as Record<string, string>) ?? {},
111
+ };
75
112
 
76
- function getLanguage(code: string): Record<string, unknown> {
77
- const lang = structuredClone(
78
- (localeModules[`./locale/${code}.json`]?.default as Record<string, unknown> | undefined) ||
79
- {},
113
+ let Language: LanguageEntry = FALLBACK;
114
+
115
+ /**
116
+ * The locale code last passed to `setLanguage`, defaulting to the fallback.
117
+ *
118
+ * Deliberately not derived from `Language.lang`: every bundled locale's `lang`
119
+ * happens to equal its file name today, but a locale like `pt-BR` would make
120
+ * the claim comparison below judge two different identifiers for one locale.
121
+ * Tracking what the caller passed keeps every comparison on one vocabulary.
122
+ */
123
+ let activeLanguageCode = "en";
124
+
125
+ /**
126
+ * Which live viewer owns the page-wide locale.
127
+ *
128
+ * `Language` above is a single module-level binding, and every label read in
129
+ * the viewer goes through it (MenuBar, Message, StorySlider, Consent, Media,
130
+ * ...). That is deliberate — the strings are read synchronously while a viewer
131
+ * is constructed — but it means two viewers on one page cannot show different
132
+ * languages: whichever called `setLanguage` last would win, and the other
133
+ * would silently keep repainting its chrome in the wrong language.
134
+ *
135
+ * Rather than thread a resolved entry down the options chain, the viewer
136
+ * claims the locale it needs and we fail loudly on a conflict. The claim is
137
+ * refcounted, so tearing down one of two viewers set in the same language
138
+ * does not release the page.
139
+ */
140
+ const languageHolders = new Map<symbol, string>();
141
+
142
+ /** Why a claim was rejected, for the thrown error. */
143
+ function languageConflict(claimed: string, requested: string): Error {
144
+ const err = new Error(
145
+ `StoryMapJS: two viewers on this page asked for different languages ` +
146
+ `("${claimed}" and "${requested}"), but the UI strings are a single ` +
147
+ `page-wide setting — the last one set would win and the other viewer ` +
148
+ `would keep rendering its chrome in the wrong language. Pass the same ` +
149
+ `language to every viewer on the page, or call refreshLanguage() on ` +
150
+ `the surviving viewer. See docs/DEVELOPMENT.md, ` +
151
+ `"Multiple instances on one page".`,
80
152
  );
153
+ // the data may carry its own `language`, and a URL-loaded document claims
154
+ // asynchronously, where the constructor cannot throw — the name lets the
155
+ // async load path report the real cause instead of "could not load data"
156
+ err.name = "StoryMapLanguageConflict";
157
+ return err;
158
+ }
159
+
160
+ /** True for the error {@link claimLanguage} throws on a conflicting locale. */
161
+ function isLanguageConflict(err: unknown): boolean {
162
+ return err instanceof Error && err.name === "StoryMapLanguageConflict";
163
+ }
164
+
165
+ /**
166
+ * Claim the page-wide locale for a viewer.
167
+ *
168
+ * @param code - The locale code the viewer is about to render.
169
+ * @param holder - Per-viewer identity; pass the same one to `releaseLanguage`.
170
+ * @throws If a live holder already claimed a different locale.
171
+ */
172
+ function claimLanguage(code: string, holder: symbol): void {
173
+ for (const [existingHolder, existingCode] of languageHolders) {
174
+ if (existingHolder !== holder && existingCode !== code) {
175
+ throw languageConflict(existingCode, code);
176
+ }
177
+ }
178
+ languageHolders.set(holder, code);
179
+ }
180
+
181
+ /**
182
+ * Release a viewer's claim. The page-wide locale is only released once the
183
+ * last holder is gone, so a disposed viewer does not free the locale a
184
+ * sibling is still rendering in.
185
+ *
186
+ * @param holder - The identity passed to `claimLanguage`.
187
+ */
188
+ function releaseLanguage(holder: symbol): void {
189
+ languageHolders.delete(holder);
190
+ }
191
+
192
+ /** The locale currently claimed by a live viewer, or null if there is none. */
193
+ function claimedLanguage(): string | null {
194
+ const codes = new Set(languageHolders.values());
195
+ return codes.size > 0 ? [...codes][0] : null;
196
+ }
197
+
198
+ function getLanguage(code: string): Record<string, unknown> {
199
+ const lang: Record<string, unknown> = {};
200
+ // start from a deep copy of the English defaults, then layer this locale
201
+ // on top: a key the translation is missing keeps its English value
81
202
  for (const k in EN) {
82
- if (lang[k]) {
83
- if (typeof EN[k] == "object" && EN[k] !== null && typeof lang[k] == "object") {
84
- // fresh object: never mutate the shared English default,
85
- // otherwise one setLanguage() call would poison every later
86
- // lookup (and every other language falling back to English)
87
- lang[k] = Object.assign({}, EN[k] as object, lang[k]);
88
- }
203
+ lang[k] = structuredClone(EN[k]);
204
+ }
205
+ const entry = (localeModules[`./locale/${code}.json`]?.default ?? {}) as Record<
206
+ string,
207
+ unknown
208
+ >;
209
+ applyLanguage(lang, entry);
210
+ return lang;
211
+ }
212
+
213
+ /** Merge `entry` over `target`, per key, never mutating the English defaults. */
214
+ function applyLanguage(target: Record<string, unknown>, entry: Record<string, unknown>): void {
215
+ for (const k in entry) {
216
+ if (!entry[k]) {
217
+ continue;
218
+ }
219
+ if (typeof EN[k] === "object" && EN[k] !== null && typeof entry[k] === "object") {
220
+ // fresh object: never mutate the shared English default,
221
+ // otherwise one setLanguage() call would poison every later
222
+ // lookup (and every other language falling back to English)
223
+ target[k] = Object.assign({}, EN[k] as object, entry[k] as object);
89
224
  } else {
90
- lang[k] = structuredClone(EN[k]);
225
+ target[k] = structuredClone(entry[k]);
91
226
  }
92
227
  }
93
- return lang;
94
228
  }
95
229
 
96
230
  /**
97
- * Switch the active UI language.
231
+ * Switch the active UI language. Synchronous: the viewer resolves its labels
232
+ * while it is being constructed.
98
233
  *
99
234
  * @param code - A locale code for which a locale file exists (e.g. `"en"`).
100
235
  * @returns The language entry that is now active.
101
236
  */
102
237
  function setLanguage(code: string): LanguageEntry {
103
- Language = getLanguage(code);
238
+ // recorded before the merge, and unconditionally: a rejected *claim* never
239
+ // reaches here, so a throw cannot leave the page locale half-switched
240
+ activeLanguageCode = code;
241
+ const merged = getLanguage(code);
242
+ Language = {
243
+ ...(merged as Omit<LanguageEntry, "messages" | "buttons">),
244
+ messages: (merged.messages as Record<string, string>) ?? FALLBACK.messages,
245
+ buttons: (merged.buttons as Record<string, string>) ?? FALLBACK.buttons,
246
+ };
247
+ // The page declares the language the viewer actually renders, so
248
+ // assistive tech pronounces chrome correctly. One effective locale per
249
+ // page (a second viewer claiming another throws), so this cannot fight
250
+ // a sibling viewer.
251
+ if (typeof document !== "undefined") {
252
+ document.documentElement.setAttribute("lang", code);
253
+ }
104
254
  return Language;
105
255
  }
106
256
 
107
- export { setLanguage, Language };
257
+ /**
258
+ * The locale code the page is currently set to.
259
+ *
260
+ * A viewer that was not given a `language` adopts this instead of claiming the
261
+ * hardcoded `"en"` default, so a host that called `setLanguage("de")` and then
262
+ * constructed a viewer gets German rather than a conflict with a sibling.
263
+ */
264
+ function currentLanguageCode(): string {
265
+ return activeLanguageCode;
266
+ }
267
+
268
+ /** The active locale's BCP 47 code, for `Intl` formatting. */
269
+ function currentLocale(): string {
270
+ return typeof Language.lang === "string" && Language.lang !== "" ? Language.lang : "en";
271
+ }
272
+
273
+ /** True when the active language is written right-to-left. */
274
+ function isRtl(): boolean {
275
+ return Language.direction === "rtl";
276
+ }
277
+
278
+ export {
279
+ setLanguage,
280
+ Language,
281
+ currentLocale,
282
+ isRtl,
283
+ currentLanguageCode,
284
+ claimLanguage,
285
+ releaseLanguage,
286
+ claimedLanguage,
287
+ isLanguageConflict,
288
+ };