@jackuait/blok 0.16.1 → 0.17.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 (474) hide show
  1. package/dist/blok.cjs +1 -1
  2. package/dist/blok.iife.js +4 -4
  3. package/dist/blok.mjs +2 -2
  4. package/dist/blok.umd.js +4 -4
  5. package/dist/chunks/{blok-DEVVs3xk.cjs → blok-BPd65xOj.cjs} +11 -11
  6. package/dist/chunks/{blok-D1e9swtF.mjs → blok-D4ApwnD7.mjs} +776 -780
  7. package/dist/chunks/constants-C3wBsvmH.cjs +606 -0
  8. package/dist/chunks/{constants-DfGAwzgk.mjs → constants-DObdf8NU.mjs} +274 -274
  9. package/dist/chunks/{i18next-loader-BH_a6G9t.mjs → i18next-loader-BMhspWFn.mjs} +1 -1
  10. package/dist/chunks/{i18next-loader-BID4jAFG.cjs → i18next-loader-CNLosgId.cjs} +1 -1
  11. package/dist/chunks/{lightweight-i18n-Clk37huC.cjs → lightweight-i18n-ByswFbdt.cjs} +1 -1
  12. package/dist/chunks/{lightweight-i18n-B0VO8Rft.mjs → lightweight-i18n-Ck1HlVxq.mjs} +32 -0
  13. package/dist/chunks/{messages-BGoPxZ5n.mjs → messages--uPFKcl3.mjs} +33 -1
  14. package/dist/{messages-BmKhZE7I.mjs → chunks/messages-0ZOxg81Y.mjs} +33 -1
  15. package/dist/chunks/{messages-BxhJFFrR.mjs → messages-1H2SY5H1.mjs} +33 -1
  16. package/dist/chunks/{messages-px_8gpHT.cjs → messages-1bAMgAsO.cjs} +1 -1
  17. package/dist/chunks/{messages-CO_hj1x6.cjs → messages-3B44ZmLZ.cjs} +1 -1
  18. package/dist/chunks/{messages-5tb-mSXS.cjs → messages-3iZ6jJ6e.cjs} +1 -1
  19. package/dist/chunks/{messages-BVuodJIJ.cjs → messages-5Rp1xyL4.cjs} +1 -1
  20. package/dist/chunks/{messages-CgGwGZs22.cjs → messages-5Vbzn-DL2.cjs} +1 -1
  21. package/dist/chunks/{messages-De0Fkl0K.mjs → messages-61uWTg1y.mjs} +33 -1
  22. package/dist/chunks/messages-6lqZ4lhc2.cjs +1 -0
  23. package/dist/chunks/messages-795D2ldP2.cjs +1 -0
  24. package/dist/chunks/{messages-CUxk6xrQ.cjs → messages-79WWudxY.cjs} +1 -1
  25. package/dist/chunks/{messages-B-3_M44j.cjs → messages-8uD5ctYP.cjs} +1 -1
  26. package/dist/{messages-Z8HMjhe9.mjs → chunks/messages-9gvi5jul.mjs} +33 -1
  27. package/dist/chunks/{messages-BDNdC6-X.cjs → messages-B0o3rVBB.cjs} +1 -1
  28. package/dist/chunks/messages-B1h0nDQW.cjs +1 -0
  29. package/dist/chunks/{messages-BPYQEADI.cjs → messages-B37vUkBi.cjs} +1 -1
  30. package/dist/{messages-BrkXHD2D2.mjs → chunks/messages-B4BvJtlu.mjs} +33 -1
  31. package/dist/{messages-CsHwUgSZ.mjs → chunks/messages-BChCPw99.mjs} +33 -1
  32. package/dist/chunks/{messages-DkINYHo4.cjs → messages-BDs_gdD_.cjs} +1 -1
  33. package/dist/chunks/{messages-Cz7AbEFm.cjs → messages-BE6rW2R-.cjs} +1 -1
  34. package/dist/{messages-DFKu1WGX2.mjs → chunks/messages-BFGgLdIA2.mjs} +33 -1
  35. package/dist/{messages-D1jUHOKr.mjs → chunks/messages-BFcq7wsx.mjs} +33 -1
  36. package/dist/{messages-BbFJ2r9p.mjs → chunks/messages-BGaAuDRS.mjs} +33 -1
  37. package/dist/chunks/{messages-Dml6u25s2.cjs → messages-BGoJHXUk2.cjs} +1 -1
  38. package/dist/chunks/{messages-DDnB1EFE2.mjs → messages-BIHeeP7X2.mjs} +33 -1
  39. package/dist/{messages-6RcfJ59a.mjs → chunks/messages-BIQ2VT8X2.mjs} +33 -1
  40. package/dist/chunks/{messages-Bnm45Rmp.mjs → messages-BK32XCpH.mjs} +33 -1
  41. package/dist/{messages-BkNVOuvO2.mjs → chunks/messages-BKSDnjOs.mjs} +33 -1
  42. package/dist/chunks/{messages-CdOX6JHb2.mjs → messages-BMNmXaC8.mjs} +33 -1
  43. package/dist/{messages-Cg3w36Bc.mjs → chunks/messages-BNuGVAEy.mjs} +33 -1
  44. package/dist/chunks/{messages-C62iC79d2.mjs → messages-BQEh67Mi2.mjs} +33 -1
  45. package/dist/chunks/{messages-BG1Tn41d.cjs → messages-BQOx3XGd.cjs} +1 -1
  46. package/dist/{messages-DaoTSrJW.mjs → chunks/messages-BQUzqXIO.mjs} +33 -1
  47. package/dist/chunks/{messages-DuOkV5T_.mjs → messages-BTKPcoLu.mjs} +33 -1
  48. package/dist/chunks/messages-BXgTHDIw.cjs +1 -0
  49. package/dist/chunks/{messages-BItPVbHx.cjs → messages-BXvKhyQH.cjs} +1 -1
  50. package/dist/chunks/{messages-98gouyMa.cjs → messages-BYW-U0iT.cjs} +1 -1
  51. package/dist/chunks/{messages-Bs9JOJDc.cjs → messages-B_lkWkPQ.cjs} +1 -1
  52. package/dist/chunks/{messages-Bq7pLz_h2.mjs → messages-BaWaLwcn2.mjs} +33 -1
  53. package/dist/chunks/{messages-DsWTIuli2.cjs → messages-BeTQxvmX2.cjs} +1 -1
  54. package/dist/chunks/{messages-BSyXBvUi2.cjs → messages-BfWGa4V82.cjs} +1 -1
  55. package/dist/{messages-GUgmAfdB.mjs → chunks/messages-Bgzyr5Lh.mjs} +33 -1
  56. package/dist/chunks/{messages-UoKgx7_8.cjs → messages-BjFB8sow.cjs} +1 -1
  57. package/dist/chunks/messages-Bjmg_8lv2.cjs +1 -0
  58. package/dist/chunks/{messages-CVHSfosB.cjs → messages-BlOVJtaj.cjs} +1 -1
  59. package/dist/{messages-CSVEbRhT.mjs → chunks/messages-BnW_Fwro.mjs} +33 -1
  60. package/dist/chunks/{messages-BdjiMHzU2.cjs → messages-Bpvja9xW2.cjs} +1 -1
  61. package/dist/chunks/{messages-BSxgqWqe.cjs → messages-BtMQ6v_L.cjs} +1 -1
  62. package/dist/chunks/{messages-Cx1kdFH_2.cjs → messages-BvChjyuU2.cjs} +1 -1
  63. package/dist/chunks/{messages-BSstxb1m2.mjs → messages-Bvge__AJ2.mjs} +33 -1
  64. package/dist/chunks/{messages-BhTV7PCN.mjs → messages-BwxzN2q3.mjs} +33 -1
  65. package/dist/chunks/{messages-DubJ63UL.mjs → messages-Byntrl2c.mjs} +33 -1
  66. package/dist/{messages-BfGAGIg-2.mjs → chunks/messages-C3B8l3Hy.mjs} +33 -1
  67. package/dist/chunks/{messages-CZQuqbNz2.cjs → messages-C3fAHxfE2.cjs} +1 -1
  68. package/dist/{messages-BOEP2ly_.mjs → chunks/messages-C56BTPcC.mjs} +33 -1
  69. package/dist/chunks/{messages-BXmg4Rer2.mjs → messages-C6vijVZv2.mjs} +33 -1
  70. package/dist/{messages-zoHZbvbe.mjs → chunks/messages-C79Ef9MU.mjs} +33 -1
  71. package/dist/{messages-CzabNeP5.mjs → chunks/messages-C93gDUHr.mjs} +33 -1
  72. package/dist/chunks/messages-CAix8jdZ.cjs +1 -0
  73. package/dist/chunks/{messages-BHE1mg5A2.mjs → messages-CEUDK26P2.mjs} +33 -1
  74. package/dist/chunks/{messages-D2nTfhRa2.cjs → messages-CEZ528TO2.cjs} +1 -1
  75. package/dist/chunks/{messages-Ced9OY9X.mjs → messages-CHx6m_Bo.mjs} +33 -1
  76. package/dist/chunks/{messages-Ck6jEhXV.cjs → messages-CKiWXTe1.cjs} +1 -1
  77. package/dist/{messages-DfnSbN512.mjs → chunks/messages-CMFcaa9C.mjs} +33 -1
  78. package/dist/chunks/{messages-jAgR8EPP.cjs → messages-CO4J7Nns.cjs} +1 -1
  79. package/dist/chunks/messages-COTP4ZJ_2.cjs +1 -0
  80. package/dist/{messages-TfPmsrxh.mjs → chunks/messages-CV3U2Vsm.mjs} +33 -1
  81. package/dist/chunks/{messages-BClegbPD.mjs → messages-CYOersvL.mjs} +33 -1
  82. package/dist/chunks/{messages-B3xnntgx2.mjs → messages-C_s-wv1r2.mjs} +33 -1
  83. package/dist/{messages-DSmNNjPb.mjs → chunks/messages-CbdaJSfC2.mjs} +33 -1
  84. package/dist/chunks/{messages-CxVi9cnz.mjs → messages-Ccng4hJ2.mjs} +33 -1
  85. package/dist/chunks/{messages-CpJW0LBR.cjs → messages-Cgph4q9d.cjs} +1 -1
  86. package/dist/chunks/{messages-DNYtMplL2.cjs → messages-Cp7wFDrY2.cjs} +1 -1
  87. package/dist/chunks/{messages-Bttb4o0k.cjs → messages-CpZneXUI.cjs} +1 -1
  88. package/dist/chunks/{messages-C2-v6HdR.cjs → messages-CpbireNX.cjs} +1 -1
  89. package/dist/{messages-C5sc4wjR.mjs → chunks/messages-CpcZgGYg.mjs} +33 -1
  90. package/dist/chunks/{messages-Cd-FaIr_2.mjs → messages-CqhQuuRo2.mjs} +33 -1
  91. package/dist/{messages-B8BXCJBA.mjs → chunks/messages-CrFIbrXr2.mjs} +33 -1
  92. package/dist/chunks/{messages-DB6z9ybS.cjs → messages-CrwZs1Gq.cjs} +1 -1
  93. package/dist/chunks/{messages-DQb9YRoO2.mjs → messages-D0_Mxuh62.mjs} +33 -1
  94. package/dist/{messages-2jeEK-EB.mjs → chunks/messages-D1q601Wg.mjs} +33 -1
  95. package/dist/{messages-BCGyLzFB2.mjs → chunks/messages-D3kC7iDa2.mjs} +33 -1
  96. package/dist/chunks/{messages-DwU7qOBO2.mjs → messages-D4UnR6e52.mjs} +33 -1
  97. package/dist/chunks/{messages-f1NcMMTR2.cjs → messages-D5CeQW1e2.cjs} +1 -1
  98. package/dist/chunks/messages-D8UH8jc6.cjs +1 -0
  99. package/dist/chunks/{messages-BJ7clJXu2.cjs → messages-DAmOTPVW2.cjs} +1 -1
  100. package/dist/{messages-DPZsygzY.mjs → chunks/messages-DBPkzBZO2.mjs} +33 -1
  101. package/dist/chunks/{messages-o3omNKfH.cjs → messages-DEduQerF.cjs} +1 -1
  102. package/dist/chunks/{messages-Beh905t72.mjs → messages-DFA5OVrs2.mjs} +33 -1
  103. package/dist/chunks/{messages-poLdFEEs2.cjs → messages-DHah-frn.cjs} +1 -1
  104. package/dist/chunks/messages-DI1ZLPxM.cjs +1 -0
  105. package/dist/chunks/{messages-BqM6l_JM2.mjs → messages-DKJ5CX9h2.mjs} +33 -1
  106. package/dist/chunks/{messages-s9I-JHCa.cjs → messages-DKjhx7Y3.cjs} +1 -1
  107. package/dist/chunks/{messages-GXQbRrHa2.mjs → messages-DR5DyRRY2.mjs} +33 -1
  108. package/dist/chunks/{messages-B94JmzMj.mjs → messages-DWjHAdb3.mjs} +33 -1
  109. package/dist/chunks/{messages-Cn0B5LU1.mjs → messages-DYsO5SIA.mjs} +33 -1
  110. package/dist/chunks/{messages-M2lNlKhI2.mjs → messages-DZwozMZD2.mjs} +33 -1
  111. package/dist/{messages-DGwIRpOH2.mjs → chunks/messages-Db_L5RNl.mjs} +33 -1
  112. package/dist/chunks/{messages-Bi3snvmH2.cjs → messages-DeXUZcFn2.cjs} +1 -1
  113. package/dist/chunks/messages-Dgp7Wk4H.cjs +1 -0
  114. package/dist/chunks/{messages-Cg6qicee.cjs → messages-DhnCZQEY.cjs} +1 -1
  115. package/dist/chunks/{messages-Ckej-nnJ.cjs → messages-DjU1jbKf.cjs} +1 -1
  116. package/dist/{messages-CJsMZvUv.mjs → chunks/messages-DkqiXPS7.mjs} +33 -1
  117. package/dist/chunks/{messages-p5w1kuc5.cjs → messages-Dl6VC9Q9.cjs} +1 -1
  118. package/dist/chunks/{messages-DG8Lmqf52.cjs → messages-Dlc1DdZ22.cjs} +1 -1
  119. package/dist/chunks/{messages-D8qYNZ_T.mjs → messages-Dna-8bQq.mjs} +33 -1
  120. package/dist/chunks/{messages-DgSRzW-Y.mjs → messages-DtTgOx9a.mjs} +33 -1
  121. package/dist/chunks/{messages-h43rfIyt2.mjs → messages-Duj8jpve2.mjs} +33 -1
  122. package/dist/chunks/{messages-XM0y9kXy2.cjs → messages-DvxZjb5g2.cjs} +1 -1
  123. package/dist/chunks/{messages-DWeyV2N3.cjs → messages-Dz8AmvFq.cjs} +1 -1
  124. package/dist/chunks/messages-DzarYc1J2.cjs +1 -0
  125. package/dist/{messages-BXs-Zwhx.mjs → chunks/messages-FIgYAomz2.mjs} +33 -1
  126. package/dist/chunks/{messages-04T5j1ww2.cjs → messages-FM0KHIkQ2.cjs} +1 -1
  127. package/dist/chunks/{messages-BtEDKVO7.cjs → messages-JsmKjXPZ.cjs} +1 -1
  128. package/dist/{messages-DvSC5JGC2.mjs → chunks/messages-LW9Kd-vn.mjs} +33 -1
  129. package/dist/chunks/{messages-LWyC-1ol.mjs → messages-R2RH1RLt.mjs} +33 -1
  130. package/dist/chunks/{messages-0OyEWZDW.cjs → messages-RWVOHsZu.cjs} +1 -1
  131. package/dist/chunks/{messages-DwAl9zoh2.mjs → messages-X90YfYzG2.mjs} +33 -1
  132. package/dist/chunks/{messages-BxRX_hY12.cjs → messages-YhmR1nl02.cjs} +1 -1
  133. package/dist/chunks/{messages-CT025FgD2.cjs → messages-Ywb6VdfO2.cjs} +1 -1
  134. package/dist/{messages-qjir1Zx9.mjs → chunks/messages-ZPOc6IQC.mjs} +33 -1
  135. package/dist/chunks/{messages-C-N1XBvh2.cjs → messages-_ECIn1VC2.cjs} +1 -1
  136. package/dist/chunks/{messages-Cf5mu1AT.cjs → messages-cYjlWqco.cjs} +1 -1
  137. package/dist/{messages-CS6vG53A.mjs → chunks/messages-dp4NwDVM.mjs} +33 -1
  138. package/dist/chunks/{messages-Bz_fTG46.mjs → messages-hhT3Vii-.mjs} +33 -1
  139. package/dist/chunks/messages-iwzDjgrP.cjs +1 -0
  140. package/dist/chunks/{messages-B5eo-pGw.mjs → messages-k4Do3gkF.mjs} +33 -1
  141. package/dist/chunks/{messages-BfYWRC3o.cjs → messages-l0nKmGOV.cjs} +1 -1
  142. package/dist/chunks/{messages-BtevAuQS2.cjs → messages-l7DqwqOu2.cjs} +1 -1
  143. package/dist/{messages-C9XTx39w2.mjs → chunks/messages-oLqnmqJf2.mjs} +33 -1
  144. package/dist/chunks/{messages-Vbqmvxs1.cjs → messages-sLVwrcar.cjs} +1 -1
  145. package/dist/chunks/{messages-DFUn1PHK2.mjs → messages-yGQn67fw2.mjs} +33 -1
  146. package/dist/chunks/{messages-CXlSU8cQ2.cjs → messages-zkunMjZf2.cjs} +1 -1
  147. package/dist/chunks/{tools-vX3wCW3a.mjs → tools-CM6aPuR4.mjs} +3442 -2226
  148. package/dist/chunks/tools-kfoXLTzY.cjs +208 -0
  149. package/dist/chunks/webm-muxer-CC98PYSV.cjs +5 -0
  150. package/dist/chunks/webm-muxer-CUUz719e.mjs +864 -0
  151. package/dist/full.cjs +1 -1
  152. package/dist/full.mjs +13 -13
  153. package/dist/locales.mjs +99 -67
  154. package/dist/{messages-iJKNW8hW2.mjs → messages-1ZSVxDYN2.mjs} +33 -1
  155. package/dist/{chunks/messages-dZdV8VYV.mjs → messages-AK_9q2yu.mjs} +33 -1
  156. package/dist/{messages-eFz25q1T.mjs → messages-B0Gc0lBw.mjs} +33 -1
  157. package/dist/{messages-ChivLKDg2.mjs → messages-B5THTOwb2.mjs} +33 -1
  158. package/dist/{messages-Bd2Q-tnQ.mjs → messages-B5xy5hCa.mjs} +33 -1
  159. package/dist/{chunks/messages-CSc7Lh_3.mjs → messages-B6J8l1aF.mjs} +33 -1
  160. package/dist/{messages-tcfLP2b2.mjs → messages-B7E1zFAv.mjs} +33 -1
  161. package/dist/{messages-gJWgJtGo.mjs → messages-B87GXoqt.mjs} +33 -1
  162. package/dist/{chunks/messages-8vGF8iWb.mjs → messages-B95smO_C.mjs} +33 -1
  163. package/dist/{messages-Dw7P8bMa2.mjs → messages-B9h-mKVO2.mjs} +33 -1
  164. package/dist/{chunks/messages-D1gz17wt.mjs → messages-BBb_hXxm.mjs} +33 -1
  165. package/dist/{messages-kb2GSl-V.mjs → messages-BDJfFuXR.mjs} +33 -1
  166. package/dist/{messages-C1d7I7f_2.mjs → messages-BH5AKf_i2.mjs} +33 -1
  167. package/dist/{chunks/messages-CZ4Jcn6y.mjs → messages-BLslMhf-.mjs} +33 -1
  168. package/dist/{chunks/messages-PtDEkfSR2.mjs → messages-BPsdJnwT.mjs} +33 -1
  169. package/dist/{chunks/messages-BQKWm9xB.mjs → messages-BTrok9K8.mjs} +33 -1
  170. package/dist/{messages-B0n-WDK72.mjs → messages-BctWdAZP2.mjs} +33 -1
  171. package/dist/{messages-CX2ioEBc2.mjs → messages-BhGHyHKC2.mjs} +33 -1
  172. package/dist/{messages-CWdh59uz2.mjs → messages-BlInN8XP2.mjs} +33 -1
  173. package/dist/{chunks/messages-xMrks-Gg.mjs → messages-Bn19MGza.mjs} +33 -1
  174. package/dist/{chunks/messages-Cc56SxY7.mjs → messages-BqFRlEJE2.mjs} +33 -1
  175. package/dist/{messages-DMH0zRig2.mjs → messages-Bt5Sbl952.mjs} +33 -1
  176. package/dist/{chunks/messages-CHizzxUv.mjs → messages-Bumbqs6s.mjs} +33 -1
  177. package/dist/{messages-BytEaMMs.mjs → messages-BvwVDbII.mjs} +33 -1
  178. package/dist/{chunks/messages-DzZZDveu.mjs → messages-Bwese2OQ.mjs} +33 -1
  179. package/dist/{chunks/messages-Vdmc6CaN.mjs → messages-Bx5KWmyJ.mjs} +33 -1
  180. package/dist/{chunks/messages-BzC8TVYC.mjs → messages-ByntluqZ.mjs} +33 -1
  181. package/dist/{messages-C2pz0mJs2.mjs → messages-C-8BMvSp2.mjs} +33 -1
  182. package/dist/{messages-BInBVzW42.mjs → messages-C-ytN6Dz2.mjs} +33 -1
  183. package/dist/{messages-CUsdyCrN2.mjs → messages-C8QB980F2.mjs} +33 -1
  184. package/dist/{chunks/messages-ID7kZQyc.mjs → messages-CCdDP2DE.mjs} +33 -1
  185. package/dist/{chunks/messages-Cx_kyYnf2.mjs → messages-CCgDqF-e.mjs} +33 -1
  186. package/dist/{chunks/messages-DyuKfskv.mjs → messages-CLkbvdRh2.mjs} +33 -1
  187. package/dist/{messages-DPzZM5FG.mjs → messages-CQ6A0zI9.mjs} +33 -1
  188. package/dist/{chunks/messages-DjSuzS2m2.mjs → messages-CQnz6pXD2.mjs} +33 -1
  189. package/dist/{messages-CWWIbebM2.mjs → messages-CQotju8u2.mjs} +33 -1
  190. package/dist/{chunks/messages-C4Wacagz.mjs → messages-CRL2ecWR.mjs} +33 -1
  191. package/dist/{chunks/messages-CkRbSW3z2.mjs → messages-CRhhyqEy2.mjs} +33 -1
  192. package/dist/{chunks/messages-CZfG1cmA2.mjs → messages-CSf1g9n_.mjs} +33 -1
  193. package/dist/{messages-Ck7HWiG_.mjs → messages-CYuTyoK6.mjs} +33 -1
  194. package/dist/{messages-BEnINcno2.mjs → messages-Co2GV7rA2.mjs} +33 -1
  195. package/dist/{chunks/messages-CpC5Cv_s.mjs → messages-CqtZ_gtb.mjs} +33 -1
  196. package/dist/{chunks/messages-Dp5C7vWz.mjs → messages-CxK_Vgra.mjs} +33 -1
  197. package/dist/{messages-2pXizYBd.mjs → messages-D08TSj5Q.mjs} +33 -1
  198. package/dist/{chunks/messages-n1T_9w-Z.mjs → messages-DFDw0nkI.mjs} +33 -1
  199. package/dist/{messages-S8uz2_bw2.mjs → messages-DKoeDmZV2.mjs} +33 -1
  200. package/dist/{chunks/messages-EI0ZLMIG.mjs → messages-DLKTwtBI.mjs} +33 -1
  201. package/dist/{chunks/messages-CcvcAZOt.mjs → messages-DQaDNQat2.mjs} +33 -1
  202. package/dist/{messages-B4cc5O5K.mjs → messages-DZlYqaxx.mjs} +33 -1
  203. package/dist/{messages-CdmaH2dA2.mjs → messages-D_ql7LL-2.mjs} +33 -1
  204. package/dist/{messages-CoSj68Ef2.mjs → messages-Da09byG42.mjs} +33 -1
  205. package/dist/{messages-BXgGBpmY.mjs → messages-DaKjx7Gh.mjs} +33 -1
  206. package/dist/{messages-C-XKbE2c.mjs → messages-Dc1aAz5V.mjs} +33 -1
  207. package/dist/{chunks/messages-CEslBsO62.mjs → messages-DlxBkSUv.mjs} +33 -1
  208. package/dist/{messages-BYyRYlTQ2.mjs → messages-DoahmNMI2.mjs} +33 -1
  209. package/dist/{messages-CGZPFOEr.mjs → messages-DpbHfnge.mjs} +33 -1
  210. package/dist/{chunks/messages-m_zk_AR3.mjs → messages-DrjZz7u9.mjs} +33 -1
  211. package/dist/{chunks/messages-DaqNOQ8p.mjs → messages-DrwEVbKk2.mjs} +33 -1
  212. package/dist/{messages-B_XoP1A3.mjs → messages-DvIPbDsq.mjs} +33 -1
  213. package/dist/{messages-BWzRZ5Un.mjs → messages-Dy3mYP_n.mjs} +33 -1
  214. package/dist/{chunks/messages-Dp5SW9D-.mjs → messages-STUXoPH72.mjs} +33 -1
  215. package/dist/{messages-BCeeFrNO.mjs → messages-Vfl9lWod.mjs} +33 -1
  216. package/dist/{messages-Nbssq1-N.mjs → messages-YPF71WjJ.mjs} +33 -1
  217. package/dist/{chunks/messages-14GzwdH92.mjs → messages-aPBlKHzr.mjs} +33 -1
  218. package/dist/{messages-Bj8K6_bv.mjs → messages-bCZW7LiC.mjs} +33 -1
  219. package/dist/{chunks/messages-Bh3E53-f2.mjs → messages-kjO2WeG-2.mjs} +33 -1
  220. package/dist/{chunks/messages-S_Bmo_Qc.mjs → messages-un7M6YZC2.mjs} +33 -1
  221. package/dist/react.cjs +1 -1
  222. package/dist/react.mjs +1 -1
  223. package/dist/tools.cjs +1 -1
  224. package/dist/tools.mjs +3 -3
  225. package/dist/vendor.LICENSE.txt +35 -0
  226. package/package.json +2 -1
  227. package/src/components/i18n/locales/am/messages.json +33 -1
  228. package/src/components/i18n/locales/ar/messages.json +33 -1
  229. package/src/components/i18n/locales/az/messages.json +33 -1
  230. package/src/components/i18n/locales/bg/messages.json +33 -1
  231. package/src/components/i18n/locales/bn/messages.json +33 -1
  232. package/src/components/i18n/locales/bs/messages.json +33 -1
  233. package/src/components/i18n/locales/cs/messages.json +33 -1
  234. package/src/components/i18n/locales/da/messages.json +33 -1
  235. package/src/components/i18n/locales/de/messages.json +33 -1
  236. package/src/components/i18n/locales/dv/messages.json +33 -1
  237. package/src/components/i18n/locales/el/messages.json +33 -1
  238. package/src/components/i18n/locales/en/messages.json +32 -0
  239. package/src/components/i18n/locales/es/messages.json +33 -1
  240. package/src/components/i18n/locales/et/messages.json +33 -1
  241. package/src/components/i18n/locales/fa/messages.json +33 -1
  242. package/src/components/i18n/locales/fi/messages.json +33 -1
  243. package/src/components/i18n/locales/fil/messages.json +33 -1
  244. package/src/components/i18n/locales/fr/messages.json +33 -1
  245. package/src/components/i18n/locales/gu/messages.json +33 -1
  246. package/src/components/i18n/locales/he/messages.json +33 -1
  247. package/src/components/i18n/locales/hi/messages.json +33 -1
  248. package/src/components/i18n/locales/hr/messages.json +33 -1
  249. package/src/components/i18n/locales/hu/messages.json +33 -1
  250. package/src/components/i18n/locales/hy/messages.json +33 -1
  251. package/src/components/i18n/locales/id/messages.json +33 -1
  252. package/src/components/i18n/locales/it/messages.json +33 -1
  253. package/src/components/i18n/locales/ja/messages.json +33 -1
  254. package/src/components/i18n/locales/ka/messages.json +33 -1
  255. package/src/components/i18n/locales/km/messages.json +33 -1
  256. package/src/components/i18n/locales/kn/messages.json +33 -1
  257. package/src/components/i18n/locales/ko/messages.json +33 -1
  258. package/src/components/i18n/locales/ku/messages.json +33 -1
  259. package/src/components/i18n/locales/lo/messages.json +33 -1
  260. package/src/components/i18n/locales/lt/messages.json +33 -1
  261. package/src/components/i18n/locales/lv/messages.json +33 -1
  262. package/src/components/i18n/locales/mk/messages.json +33 -1
  263. package/src/components/i18n/locales/ml/messages.json +33 -1
  264. package/src/components/i18n/locales/mn/messages.json +33 -1
  265. package/src/components/i18n/locales/mr/messages.json +33 -1
  266. package/src/components/i18n/locales/ms/messages.json +33 -1
  267. package/src/components/i18n/locales/my/messages.json +33 -1
  268. package/src/components/i18n/locales/ne/messages.json +33 -1
  269. package/src/components/i18n/locales/nl/messages.json +33 -1
  270. package/src/components/i18n/locales/no/messages.json +33 -1
  271. package/src/components/i18n/locales/pa/messages.json +33 -1
  272. package/src/components/i18n/locales/pl/messages.json +33 -1
  273. package/src/components/i18n/locales/ps/messages.json +33 -1
  274. package/src/components/i18n/locales/pt/messages.json +33 -1
  275. package/src/components/i18n/locales/ro/messages.json +33 -1
  276. package/src/components/i18n/locales/ru/messages.json +33 -1
  277. package/src/components/i18n/locales/sd/messages.json +33 -1
  278. package/src/components/i18n/locales/si/messages.json +33 -1
  279. package/src/components/i18n/locales/sk/messages.json +33 -1
  280. package/src/components/i18n/locales/sl/messages.json +33 -1
  281. package/src/components/i18n/locales/sq/messages.json +33 -1
  282. package/src/components/i18n/locales/sr/messages.json +33 -1
  283. package/src/components/i18n/locales/sv/messages.json +33 -1
  284. package/src/components/i18n/locales/sw/messages.json +33 -1
  285. package/src/components/i18n/locales/ta/messages.json +33 -1
  286. package/src/components/i18n/locales/te/messages.json +33 -1
  287. package/src/components/i18n/locales/th/messages.json +33 -1
  288. package/src/components/i18n/locales/tr/messages.json +33 -1
  289. package/src/components/i18n/locales/ug/messages.json +33 -1
  290. package/src/components/i18n/locales/uk/messages.json +33 -1
  291. package/src/components/i18n/locales/ur/messages.json +33 -1
  292. package/src/components/i18n/locales/vi/messages.json +33 -1
  293. package/src/components/i18n/locales/yi/messages.json +33 -1
  294. package/src/components/i18n/locales/zh/messages.json +33 -1
  295. package/src/components/icons/index.ts +106 -0
  296. package/src/components/modules/paste/handlers/pattern-handler.ts +4 -7
  297. package/src/components/utils/format-bytes.ts +15 -0
  298. package/src/components/utils/max-size.ts +36 -0
  299. package/src/components/utils/media-empty-state.ts +1 -11
  300. package/src/components/utils/upload-error-message.ts +43 -0
  301. package/src/styles/colors.css +31 -0
  302. package/src/styles/keyframes.css +8 -0
  303. package/src/styles/main.css +2 -0
  304. package/src/styles/resize-cue.css +26 -0
  305. package/src/styles/video.css +1221 -0
  306. package/src/tools/file/constants.ts +3 -0
  307. package/src/tools/file/index.ts +45 -4
  308. package/src/tools/file/uploader.ts +5 -2
  309. package/src/tools/image/constants.ts +1 -1
  310. package/src/tools/image/converted-uploader.ts +30 -0
  311. package/src/tools/image/gif-to-webm.ts +170 -0
  312. package/src/tools/image/index.ts +125 -3
  313. package/src/tools/image/resizer.ts +39 -6
  314. package/src/tools/image/uploader.ts +2 -1
  315. package/src/tools/image/uploading-state.ts +2 -1
  316. package/src/tools/index.ts +2 -0
  317. package/src/tools/video/constants.ts +22 -0
  318. package/src/tools/video/controls.ts +1448 -0
  319. package/src/tools/video/empty-state.ts +45 -0
  320. package/src/tools/video/i18n.ts +13 -0
  321. package/src/tools/video/index.ts +521 -0
  322. package/src/tools/video/ui.ts +83 -0
  323. package/src/tools/video/uploader.ts +75 -0
  324. package/types/configs/blok-config.d.ts +2 -9
  325. package/types/tools/file.d.ts +9 -3
  326. package/types/tools/image.d.ts +11 -2
  327. package/types/tools/max-size.d.ts +12 -0
  328. package/types/tools/video.d.ts +72 -0
  329. package/dist/chunks/constants-B2Lcd7Kk.cjs +0 -539
  330. package/dist/chunks/messages-3iHkF7Vy.cjs +0 -1
  331. package/dist/chunks/messages-BAgSlZpS.cjs +0 -1
  332. package/dist/chunks/messages-Br3ERe172.cjs +0 -1
  333. package/dist/chunks/messages-C6Xc3L-B2.cjs +0 -1
  334. package/dist/chunks/messages-CEquPedm.cjs +0 -1
  335. package/dist/chunks/messages-CFo-pG-t2.cjs +0 -1
  336. package/dist/chunks/messages-Cf8u0aln2.cjs +0 -1
  337. package/dist/chunks/messages-Cgg1HHSo.cjs +0 -1
  338. package/dist/chunks/messages-DOBcfgRF.cjs +0 -1
  339. package/dist/chunks/messages-JLj0J5so.cjs +0 -1
  340. package/dist/chunks/messages-p-1X5oFM2.cjs +0 -1
  341. package/dist/chunks/messages-vdupz5T0.cjs +0 -1
  342. package/dist/chunks/tools-DiTb45BS.cjs +0 -208
  343. /package/dist/chunks/{am-B37aLxvu.cjs → am-BA02TqF9.cjs} +0 -0
  344. /package/dist/chunks/{am-D7yfVqJS.mjs → am-C9_6r8HY.mjs} +0 -0
  345. /package/dist/chunks/{ar-D00SixXA.mjs → ar-BM96nSXF.mjs} +0 -0
  346. /package/dist/chunks/{ar-ySo_KDqd.cjs → ar-CB4IsGCa.cjs} +0 -0
  347. /package/dist/chunks/{az-BmIwKcoq.mjs → az-DnZSY5ok.mjs} +0 -0
  348. /package/dist/chunks/{az-nCoWuGBd.cjs → az-FykE_aDi.cjs} +0 -0
  349. /package/dist/chunks/{bg-BTZaB21W.mjs → bg-BplUvPeX.mjs} +0 -0
  350. /package/dist/chunks/{bg-BKB8_J3v.cjs → bg-D6r90gqH.cjs} +0 -0
  351. /package/dist/chunks/{bn-BQiBKtpR.cjs → bn-B7w2dbK4.cjs} +0 -0
  352. /package/dist/chunks/{bn-BVpf0XL6.mjs → bn-CdP9lnfr.mjs} +0 -0
  353. /package/dist/chunks/{bs-BSz4cPth.mjs → bs-BtX-qLsk.mjs} +0 -0
  354. /package/dist/chunks/{bs-D_lekdEb.cjs → bs-DztHHorM.cjs} +0 -0
  355. /package/dist/chunks/{cs-Dv8Jg_Fa.cjs → cs-CLMsCdIt.cjs} +0 -0
  356. /package/dist/chunks/{cs-p5s4GudH.mjs → cs-NcDYS-aU.mjs} +0 -0
  357. /package/dist/chunks/{da-BqJa8BMd.mjs → da-ANg6gK3-.mjs} +0 -0
  358. /package/dist/chunks/{da-D33rjz-t.cjs → da-sJ7EsHcO.cjs} +0 -0
  359. /package/dist/chunks/{de-BDDktkfI.mjs → de-CTxvRxuE.mjs} +0 -0
  360. /package/dist/chunks/{de-I8YFq0Ej.cjs → de-CxMqLKhy.cjs} +0 -0
  361. /package/dist/chunks/{el-BInM0nQo.cjs → el-Bg6QXLt5.cjs} +0 -0
  362. /package/dist/chunks/{el-R63G08P0.mjs → el-CgOoJaXB.mjs} +0 -0
  363. /package/dist/chunks/{es-Cj_AHhb9.cjs → es-7zUbslPJ.cjs} +0 -0
  364. /package/dist/chunks/{es-BleH_dHg.mjs → es-D5YDFRu-.mjs} +0 -0
  365. /package/dist/chunks/{et-BuISCVFl.mjs → et-57a7ees8.mjs} +0 -0
  366. /package/dist/chunks/{et-BkMzN_qG.cjs → et-D_rhRdDD.cjs} +0 -0
  367. /package/dist/chunks/{fa-CI9f3My0.mjs → fa-Dp_BXnBP.mjs} +0 -0
  368. /package/dist/chunks/{fa-C3VQIfEJ.cjs → fa-JBr2zsfI.cjs} +0 -0
  369. /package/dist/chunks/{fi-p8xxtchQ.cjs → fi-DjbYN6MA.cjs} +0 -0
  370. /package/dist/chunks/{fi-C0_Jyps9.mjs → fi-at45xjOS.mjs} +0 -0
  371. /package/dist/chunks/{fil-BZsJ4YZG.mjs → fil-D_HT2vGt.mjs} +0 -0
  372. /package/dist/chunks/{fil-DC8VTmfd.cjs → fil-dcVBIQoi.cjs} +0 -0
  373. /package/dist/chunks/{fr-BjeioA2N.mjs → fr-ByR9PLTE.mjs} +0 -0
  374. /package/dist/chunks/{fr-Cbstr5ii.cjs → fr-Ch4zj1rM.cjs} +0 -0
  375. /package/dist/chunks/{gu-DpPoUPem.cjs → gu-CoLW5Saq.cjs} +0 -0
  376. /package/dist/chunks/{gu-CNi9WnhQ.mjs → gu-CvfPvH3Y.mjs} +0 -0
  377. /package/dist/chunks/{he-Rlv-PVKK.cjs → he-2wS2DK0D.cjs} +0 -0
  378. /package/dist/chunks/{he-bU_Id5XQ.mjs → he-Bmqypvkq.mjs} +0 -0
  379. /package/dist/chunks/{hi-CYYjJgoQ.mjs → hi-DbcN0x64.mjs} +0 -0
  380. /package/dist/chunks/{hi-CfLaLKZL.cjs → hi-f4gshON3.cjs} +0 -0
  381. /package/dist/chunks/{hr-CerKCstu.mjs → hr-D5mydeyn.mjs} +0 -0
  382. /package/dist/chunks/{hr-B6eFd_4M.cjs → hr-DMExeWwd.cjs} +0 -0
  383. /package/dist/chunks/{hu-DQcisouf.cjs → hu-COmlHkse.cjs} +0 -0
  384. /package/dist/chunks/{hu-DNYoHMic.mjs → hu-DVCPn8un.mjs} +0 -0
  385. /package/dist/chunks/{hy-x9QOWTT6.cjs → hy-BoBSSiJc.cjs} +0 -0
  386. /package/dist/chunks/{hy-N0XBqVv_.mjs → hy-CP6oqcK_.mjs} +0 -0
  387. /package/dist/chunks/{id-dmUIQB07.mjs → id-COwan-Bb.mjs} +0 -0
  388. /package/dist/chunks/{id-G7ASv812.cjs → id-Dk2AQ6-R.cjs} +0 -0
  389. /package/dist/chunks/{it-DXDwm7Aj.cjs → it-BCmU3zOg.cjs} +0 -0
  390. /package/dist/chunks/{it-G9Rg2LaN.mjs → it-DJqN-zLs.mjs} +0 -0
  391. /package/dist/chunks/{ja-C1Nou_k5.mjs → ja-CvoLNAXS.mjs} +0 -0
  392. /package/dist/chunks/{ja-DHMurrnk.cjs → ja-DcMqJvnV.cjs} +0 -0
  393. /package/dist/chunks/{ka-P0_q1_oW.cjs → ka-BdyjQFkv.cjs} +0 -0
  394. /package/dist/chunks/{ka-9rtmTdhq.mjs → ka-BsqbDXqr.mjs} +0 -0
  395. /package/dist/chunks/{km-DedsOdPY.cjs → km-BShH0mB9.cjs} +0 -0
  396. /package/dist/chunks/{km-T8J0lGcC.mjs → km-C9FxSKv0.mjs} +0 -0
  397. /package/dist/chunks/{kn-CMb5Cv2d.mjs → kn-BKTm-E-A.mjs} +0 -0
  398. /package/dist/chunks/{kn-CAGP6H3x.cjs → kn-bNx6e6NK.cjs} +0 -0
  399. /package/dist/chunks/{ko-DulVmkjC.mjs → ko-BLEDr4t_.mjs} +0 -0
  400. /package/dist/chunks/{ko-3D0kPtnu.cjs → ko-LmGjEODJ.cjs} +0 -0
  401. /package/dist/chunks/{ku-BYzD3GnU.cjs → ku-BekLwcHQ.cjs} +0 -0
  402. /package/dist/chunks/{ku-C5mlSVfC.mjs → ku-DGpIv9vX.mjs} +0 -0
  403. /package/dist/chunks/{lo-Cw2hfj84.mjs → lo-C3wsS73b.mjs} +0 -0
  404. /package/dist/chunks/{lo-D9ixPNJD.cjs → lo-YgZPFD63.cjs} +0 -0
  405. /package/dist/chunks/{lt-CzfEJdVd.cjs → lt-CIvBJk2h.cjs} +0 -0
  406. /package/dist/chunks/{lt-Ceg9NAdI.mjs → lt-DWWjfR4Z.mjs} +0 -0
  407. /package/dist/chunks/{lv-DWyBbTHI.cjs → lv-B6Djmvjl.cjs} +0 -0
  408. /package/dist/chunks/{lv-3CXzQoic.mjs → lv-D4nb-9oK.mjs} +0 -0
  409. /package/dist/chunks/{mk-CEbNT0Oe.mjs → mk-BPUvDORf.mjs} +0 -0
  410. /package/dist/chunks/{mk-Anl5AUSU.cjs → mk-Ck56Emvp.cjs} +0 -0
  411. /package/dist/chunks/{ml-B1QmnbTX.cjs → ml-DsibsgSA.cjs} +0 -0
  412. /package/dist/chunks/{ml-DaF_zn1h.mjs → ml-qo0n1JHs.mjs} +0 -0
  413. /package/dist/chunks/{mn-DLpgZmIl.mjs → mn-BAQnLAOv.mjs} +0 -0
  414. /package/dist/chunks/{mn-DM3AWPQI.cjs → mn-Db0fVNYE.cjs} +0 -0
  415. /package/dist/chunks/{mr-CPCMiBsx.cjs → mr-BTz5VL4u.cjs} +0 -0
  416. /package/dist/chunks/{mr-C-d3CWSD.mjs → mr-CFEPrQYy.mjs} +0 -0
  417. /package/dist/chunks/{ms-D3Zil5Dz.mjs → ms-C9p2_6EB.mjs} +0 -0
  418. /package/dist/chunks/{ms-BKg5zJ6g.cjs → ms-ItzWfmiu.cjs} +0 -0
  419. /package/dist/chunks/{my-HzQdQq6H.mjs → my-BQhcHK_d.mjs} +0 -0
  420. /package/dist/chunks/{my-BhrbZPAE.cjs → my-Bq1EPoFX.cjs} +0 -0
  421. /package/dist/chunks/{ne-Dw6kUPkS.mjs → ne-Cf4GpHyI.mjs} +0 -0
  422. /package/dist/chunks/{ne-BsEUv3Vp.cjs → ne-Mog3kAWt.cjs} +0 -0
  423. /package/dist/chunks/{nl-D8QQ6wmJ.mjs → nl-7DE7AKK5.mjs} +0 -0
  424. /package/dist/chunks/{nl-C1jFx32v.cjs → nl-Do9Y1u3F.cjs} +0 -0
  425. /package/dist/chunks/{no-BWEOGeAo.cjs → no-DNuo9wW6.cjs} +0 -0
  426. /package/dist/chunks/{no-Rg2uuKdV.mjs → no-J4jj2fW7.mjs} +0 -0
  427. /package/dist/chunks/{notifier-CEnelp-K.mjs → notifier-BDNwSr07.mjs} +0 -0
  428. /package/dist/chunks/{notifier-BOB8o7IG.cjs → notifier-BW5H3Ctc.cjs} +0 -0
  429. /package/dist/chunks/{pa-BitCteAA.cjs → pa-BVCDv2EV.cjs} +0 -0
  430. /package/dist/chunks/{pa-BSwIZvA0.mjs → pa-DMuUOUxa.mjs} +0 -0
  431. /package/dist/chunks/{pl-CbCrHaA6.cjs → pl-Ct8v4d8V.cjs} +0 -0
  432. /package/dist/chunks/{pl-FhXomIGp.mjs → pl-DIZm5XzV.mjs} +0 -0
  433. /package/dist/chunks/{ps-4sPZuv3g.cjs → ps-DT4DAHOy.cjs} +0 -0
  434. /package/dist/chunks/{ps-BoBtbrB6.mjs → ps-X3--6pS3.mjs} +0 -0
  435. /package/dist/chunks/{pt-BYA5NOw_.mjs → pt-BMT2BIpj.mjs} +0 -0
  436. /package/dist/chunks/{pt-CSzjho-V.cjs → pt-Dwe6Dinw.cjs} +0 -0
  437. /package/dist/chunks/{ro-C9tN3AFF.cjs → ro-CoHEUo3b.cjs} +0 -0
  438. /package/dist/chunks/{ro-mtobtMpD.mjs → ro-Ndh2J4Fv.mjs} +0 -0
  439. /package/dist/chunks/{ru-B791LPq3.mjs → ru-DEoON4H0.mjs} +0 -0
  440. /package/dist/chunks/{ru-BYPO5wNO.cjs → ru-Pmgo28Kt.cjs} +0 -0
  441. /package/dist/chunks/{sd-C8ngG92I.mjs → sd-B46KwBlt.mjs} +0 -0
  442. /package/dist/chunks/{sd-BWuglgs_.cjs → sd-DxSmw84d.cjs} +0 -0
  443. /package/dist/chunks/{si-C_q8DxVt.mjs → si-CEX6-_X4.mjs} +0 -0
  444. /package/dist/chunks/{si-IX2P_DGB.cjs → si-attpuQg-.cjs} +0 -0
  445. /package/dist/chunks/{sk-HJJlM9uq.mjs → sk-Crsvi9aQ.mjs} +0 -0
  446. /package/dist/chunks/{sk-CxtyIOlr.cjs → sk-CvkpO0ti.cjs} +0 -0
  447. /package/dist/chunks/{sl-CPjYG80u.cjs → sl-BT19lhkA.cjs} +0 -0
  448. /package/dist/chunks/{sl-kB1f5rPn.mjs → sl-Cqe1IKhE.mjs} +0 -0
  449. /package/dist/chunks/{sq-CD0W0D6z.mjs → sq-BOQb1hx9.mjs} +0 -0
  450. /package/dist/chunks/{sq-Do6UyHn9.cjs → sq-rY2-arjV.cjs} +0 -0
  451. /package/dist/chunks/{sr-lLJu9TsT.mjs → sr-WVqhi-MV.mjs} +0 -0
  452. /package/dist/chunks/{sr-BcyT-MWS.cjs → sr-jnkxoHkR.cjs} +0 -0
  453. /package/dist/chunks/{sv-Bsz7ersx.cjs → sv-BiWSYdw7.cjs} +0 -0
  454. /package/dist/chunks/{sv-C3GL-a0k.mjs → sv-cjssSK3x.mjs} +0 -0
  455. /package/dist/chunks/{sw-D6-DZ14-.mjs → sw-BNNAgQNn.mjs} +0 -0
  456. /package/dist/chunks/{sw-CUElHZxL.cjs → sw-DFyk62c4.cjs} +0 -0
  457. /package/dist/chunks/{ta-D0DQba-y.cjs → ta-DowDx1bh.cjs} +0 -0
  458. /package/dist/chunks/{ta-BZy78kBk.mjs → ta-jg4mBsL9.mjs} +0 -0
  459. /package/dist/chunks/{te-vigCVKdg.mjs → te-BiLupA2T.mjs} +0 -0
  460. /package/dist/chunks/{te-DPMvJyXg.cjs → te-G0buJU1V.cjs} +0 -0
  461. /package/dist/chunks/{th-DtcrIt9J.cjs → th-DsjA6OWh.cjs} +0 -0
  462. /package/dist/chunks/{th-CGc0RLWB.mjs → th-Dtb_u833.mjs} +0 -0
  463. /package/dist/chunks/{tr-Cgkf5aJo.mjs → tr-01MbT9-l.mjs} +0 -0
  464. /package/dist/chunks/{tr-BrEFaVNA.cjs → tr-DN1xdxQn.cjs} +0 -0
  465. /package/dist/chunks/{ug-BVK7qBs4.mjs → ug-BFlA2VRZ.mjs} +0 -0
  466. /package/dist/chunks/{ug-CqZXfhXi.cjs → ug-DEJ9cNGH.cjs} +0 -0
  467. /package/dist/chunks/{uk-DgReWEge.cjs → uk-Bv6aB1Nd.cjs} +0 -0
  468. /package/dist/chunks/{uk-CSPaCalw.mjs → uk-DY7rBPyo.mjs} +0 -0
  469. /package/dist/chunks/{ur-ByrwJnY1.cjs → ur-C3CFfx9s.cjs} +0 -0
  470. /package/dist/chunks/{ur-VpFFsATs.mjs → ur-DHfULZeF.mjs} +0 -0
  471. /package/dist/chunks/{vi-CWQtvATS.mjs → vi-BFuaq2Tk.mjs} +0 -0
  472. /package/dist/chunks/{vi-lUD3w7gP.cjs → vi-DQrrRkmq.cjs} +0 -0
  473. /package/dist/chunks/{zh-fSp1qOne.cjs → zh-5rdSdLkR.cjs} +0 -0
  474. /package/dist/chunks/{zh-akJj2cdF.mjs → zh-BGpl7x7W.mjs} +0 -0
@@ -16,4 +16,7 @@ export const PASTE_EXTENSIONS = [
16
16
  'mp3', 'wav', 'ogg', 'mp4', 'mov', 'avi', 'mkv',
17
17
  ] as const;
18
18
 
19
+ /** Default upload ceiling (bytes) when the consumer does not configure `maxSize`. */
20
+ export const DEFAULT_MAX_SIZE = 30 * 1024 * 1024; // 30 MiB
21
+
19
22
  export const DEFAULT_CAPTION_PLACEHOLDER = 'Write a caption…';
@@ -11,12 +11,15 @@ import type {
11
11
  import type { MenuConfig } from '../../../types/tools/menu-config';
12
12
  import type { FileConfig, FileData, FileUploadResult } from '../../../types/tools/file';
13
13
  import type { ImageData } from '../../../types/tools/image';
14
+ import type { VideoData } from '../../../types/tools/video';
14
15
  import { IconCaption, IconCopy, IconDownload, IconFile, IconReplace } from '../../components/icons';
15
16
  import { DEFAULT_CAPTION_PLACEHOLDER, PASTE_EXTENSIONS, PASTE_MIME_TYPES } from './constants';
16
17
  import { renderEmptyState, type EmptyStateElement } from './empty-state';
17
18
  import { renderUploadingState, type UploadingStateElement } from './uploading-state';
18
19
  import { renderCaptionRow, renderFileCard } from './ui';
19
20
  import { Uploader } from './uploader';
21
+ import { FileToolError } from './errors';
22
+ import { uploadErrorMessage } from '../../components/utils/upload-error-message';
20
23
  import { safeHttpHref } from './url';
21
24
  import { isPreviewable } from './preview';
22
25
  import { openFilePreview } from './preview-modal';
@@ -26,6 +29,9 @@ type ToolState = 'EMPTY' | 'LOADING' | 'RENDERED' | 'ERROR';
26
29
  /** Image filenames/URLs that should auto-convert the File block into an Image. */
27
30
  const IMAGE_EXTENSION_RE = /\.(png|jpe?g|gif|webp|svg)(?:[?#]|$)/i;
28
31
 
32
+ /** Video filenames/URLs that should auto-convert the File block into a Video. */
33
+ const VIDEO_EXTENSION_RE = /\.(mp4|webm|ogg|mov|m4v)(?:[?#]|$)/i;
34
+
29
35
  export class FileTool implements BlockTool {
30
36
  private readonly api: API;
31
37
  private readonly block: BlockAPI;
@@ -37,9 +43,12 @@ export class FileTool implements BlockTool {
37
43
  private state: ToolState;
38
44
  private uploadingEl: UploadingStateElement | null = null;
39
45
  private lastFileName: string | null = null;
46
+ private errorMessage: string | null = null;
40
47
  private previewTeardown: (() => void) | null = null;
41
48
  /** When the pending upload is an image, the result converts to an Image block. */
42
49
  private pendingImageConversion = false;
50
+ /** When the pending upload is a video, the result converts to a Video block. */
51
+ private pendingVideoConversion = false;
43
52
 
44
53
  constructor(options: BlockToolConstructorOptions<FileData, FileConfig>) {
45
54
  this.api = options.api;
@@ -153,26 +162,29 @@ export class FileTool implements BlockTool {
153
162
  private startUpload(file: File): void {
154
163
  this.lastFileName = file.name;
155
164
  this.pendingImageConversion = file.type.startsWith('image/') || IMAGE_EXTENSION_RE.test(file.name);
165
+ this.pendingVideoConversion = file.type.startsWith('video/') || VIDEO_EXTENSION_RE.test(file.name);
156
166
  this.state = 'LOADING';
157
167
  this.renderState();
158
168
  void this.uploader
159
169
  .handleFile(file, { onProgress: (p) => this.uploadingEl?.setProgress(p) })
160
170
  .then((result) => this.applyResult(result))
161
- .catch(() => this.applyError());
171
+ .catch((err) => this.applyError(err));
162
172
  }
163
173
 
164
174
  private startUrl(url: string): void {
165
175
  this.lastFileName = null;
166
176
  this.pendingImageConversion = IMAGE_EXTENSION_RE.test(url);
177
+ this.pendingVideoConversion = VIDEO_EXTENSION_RE.test(url);
167
178
  this.state = 'LOADING';
168
179
  this.renderState();
169
180
  void this.uploader
170
181
  .handleUrl(url, { onProgress: (p) => this.uploadingEl?.setProgress(p) })
171
182
  .then((result) => this.applyResult(result))
172
- .catch(() => this.applyError());
183
+ .catch((err) => this.applyError(err));
173
184
  }
174
185
 
175
186
  private applyResult(result: FileUploadResult): void {
187
+ this.errorMessage = null;
176
188
  this.data = {
177
189
  ...this.data,
178
190
  url: result.url,
@@ -180,6 +192,9 @@ export class FileTool implements BlockTool {
180
192
  size: result.size ?? this.data.size,
181
193
  mimeType: result.mimeType ?? this.data.mimeType,
182
194
  };
195
+ if (this.pendingVideoConversion && this.convertToVideo()) {
196
+ return;
197
+ }
183
198
  if (this.pendingImageConversion && this.convertToImage()) {
184
199
  return;
185
200
  }
@@ -207,7 +222,33 @@ export class FileTool implements BlockTool {
207
222
  return true;
208
223
  }
209
224
 
210
- private applyError(): void {
225
+ /**
226
+ * Swap this File block for a Video block carrying the just-uploaded url.
227
+ * Mirrors {@link convertToImage}: File and Video declare no conversionConfig,
228
+ * so we replace in place. Returns false (keep the file card) when the block
229
+ * can no longer be located.
230
+ */
231
+ private convertToVideo(): boolean {
232
+ const index = this.api.blocks.getBlockIndex(this.block.id);
233
+ if (index === undefined) {
234
+ return false;
235
+ }
236
+ const videoData: VideoData = { url: this.data.url };
237
+ if (this.data.fileName !== undefined) videoData.fileName = this.data.fileName;
238
+ if (this.data.mimeType !== undefined) videoData.mimeType = this.data.mimeType;
239
+ if ((this.data.caption ?? '') !== '') videoData.caption = this.data.caption;
240
+ if (this.data.captionVisible !== undefined) videoData.captionVisible = this.data.captionVisible;
241
+ this.api.blocks.insert('video', videoData, {}, index, false, true);
242
+ return true;
243
+ }
244
+
245
+ private applyError(err?: unknown): void {
246
+ this.errorMessage = err instanceof FileToolError
247
+ ? uploadErrorMessage(err, (key) => this.api.i18n.t(key), {
248
+ tooLarge: 'tools.file.errorFileTooLarge',
249
+ generic: 'tools.file.errorUploadFailed',
250
+ })
251
+ : null;
211
252
  this.state = 'ERROR';
212
253
  this.renderState();
213
254
  }
@@ -331,7 +372,7 @@ export class FileTool implements BlockTool {
331
372
  wrap.setAttribute('data-role', 'file-error');
332
373
 
333
374
  const message = document.createElement('span');
334
- message.textContent = i18n.t('tools.file.errorUploadFailed');
375
+ message.textContent = this.errorMessage ?? i18n.t('tools.file.errorUploadFailed');
335
376
 
336
377
  const retry = document.createElement('button');
337
378
  retry.type = 'button';
@@ -1,4 +1,6 @@
1
1
  import type { FileConfig, FileUploadResult } from '../../../types/tools/file';
2
+ import { resolveMaxSize } from '../../components/utils/max-size';
3
+ import { DEFAULT_MAX_SIZE } from './constants';
2
4
  import { FileToolError } from './errors';
3
5
 
4
6
  export interface UploadOptions {
@@ -120,12 +122,13 @@ export class Uploader {
120
122
  }
121
123
 
122
124
  private validateFile(file: File): void {
123
- const { types, maxSize } = this.config;
125
+ const { types } = this.config;
126
+ const maxSize = resolveMaxSize(this.config.maxSize, file.type, DEFAULT_MAX_SIZE);
124
127
 
125
128
  if (types !== undefined && !types.includes(file.type)) {
126
129
  throw new FileToolError('UNSUPPORTED_TYPE', file.type || 'unknown');
127
130
  }
128
- if (maxSize !== undefined && file.size > maxSize) {
131
+ if (file.size > maxSize) {
129
132
  throw new FileToolError('FILE_TOO_LARGE', `${file.size} > ${maxSize}`);
130
133
  }
131
134
  }
@@ -6,7 +6,7 @@ export const DEFAULT_MIME_TYPES = [
6
6
  'image/svg+xml',
7
7
  ] as const;
8
8
 
9
- export const DEFAULT_MAX_SIZE = 10 * 1024 * 1024; // 10 MiB
9
+ export const DEFAULT_MAX_SIZE = 30 * 1024 * 1024; // 30 MiB
10
10
 
11
11
  export const DEFAULT_CAPTION_PLACEHOLDER = 'Write a caption…';
12
12
 
@@ -0,0 +1,30 @@
1
+ import type { API } from '../../../types';
2
+ import type { ImageConfig } from '../../../types/tools/image';
3
+
4
+ export type ConvertedUploadFn = (
5
+ file: File,
6
+ ctx?: { onProgress?: (percent: number) => void },
7
+ ) => Promise<{ url: string; fileName?: string }>;
8
+
9
+ interface UploaderHolder { uploader?: { uploadByFile?: ConvertedUploadFn } }
10
+
11
+ function asUploaderHolder(value: unknown): UploaderHolder | undefined {
12
+ return typeof value === 'object' && value !== null ? (value as UploaderHolder) : undefined;
13
+ }
14
+
15
+ /**
16
+ * Resolve which `uploadByFile` to use for a converted WebM file:
17
+ * the video tool's uploader (if registered under the `video` key), else the
18
+ * image tool's own uploader, else undefined (caller uses a blob URL).
19
+ */
20
+ export function resolveConvertedUploader(
21
+ api: API,
22
+ imageConfig: ImageConfig,
23
+ ): ConvertedUploadFn | undefined {
24
+ const videoEntry = asUploaderHolder(api.tools.getToolsConfig().tools?.video);
25
+ // Tool settings carry the config under `.config`; support a flat shape too.
26
+ const videoConfig = asUploaderHolder((videoEntry as { config?: unknown })?.config) ?? videoEntry;
27
+ const videoUpload = videoConfig?.uploader?.uploadByFile;
28
+
29
+ return videoUpload ?? imageConfig.uploader?.uploadByFile;
30
+ }
@@ -0,0 +1,170 @@
1
+ // Minimal structural types for the WebCodecs surface we use (avoids relying on
2
+ // lib.dom types that may not be present in the project's TS target).
3
+ interface DecodedFrame {
4
+ displayWidth: number;
5
+ displayHeight: number;
6
+ duration: number | null;
7
+ timestamp: number;
8
+ close(): void;
9
+ }
10
+
11
+ interface ImageDecoderLike {
12
+ tracks: { ready: Promise<void>; selectedTrack?: { frameCount: number } };
13
+ decode(opts: { frameIndex: number }): Promise<{ image: DecodedFrame; complete: boolean }>;
14
+ close(): void;
15
+ }
16
+
17
+ interface EncodedChunk { type: string; }
18
+
19
+ interface VideoEncoderLike {
20
+ configure(config: Record<string, unknown>): void;
21
+ encode(frame: DecodedFrame, opts?: { keyFrame?: boolean }): void;
22
+ flush(): Promise<void>;
23
+ close(): void;
24
+ }
25
+
26
+ interface VideoEncoderCtor {
27
+ new (init: {
28
+ output: (chunk: EncodedChunk, meta: unknown) => void;
29
+ error: (err: unknown) => void;
30
+ }): VideoEncoderLike;
31
+ isConfigSupported(config: Record<string, unknown>): Promise<{ supported?: boolean }>;
32
+ }
33
+
34
+ const KEYFRAME_INTERVAL = 30;
35
+
36
+ function hasWebCodecs(): boolean {
37
+ const g = globalThis as Record<string, unknown>;
38
+ return typeof g.ImageDecoder !== 'undefined' && typeof g.VideoEncoder !== 'undefined';
39
+ }
40
+
41
+ async function pickCodec(
42
+ Encoder: VideoEncoderCtor,
43
+ width: number,
44
+ height: number,
45
+ ): Promise<{ encoderCodec: string; muxerCodec: 'V_VP9' | 'V_VP8' } | null> {
46
+ const candidates: Array<{ encoderCodec: string; muxerCodec: 'V_VP9' | 'V_VP8' }> = [
47
+ { encoderCodec: 'vp09.00.10.08', muxerCodec: 'V_VP9' },
48
+ { encoderCodec: 'vp8', muxerCodec: 'V_VP8' },
49
+ ];
50
+ for (const c of candidates) {
51
+ const probe = await Encoder.isConfigSupported({ codec: c.encoderCodec, width, height });
52
+ if (probe.supported) return c;
53
+ }
54
+ return null;
55
+ }
56
+
57
+ /**
58
+ * Convert an animated GIF (raw bytes) into a WebM Blob using WebCodecs.
59
+ * Returns null whenever the caller should keep the original GIF: WebCodecs
60
+ * unavailable, a static/single-frame GIF, an unsupported codec, or any error.
61
+ */
62
+ export async function convertGifToWebm(
63
+ data: ArrayBuffer,
64
+ opts: { onProgress?: (percent: number) => void } = {},
65
+ ): Promise<Blob | null> {
66
+ if (!hasWebCodecs()) return null;
67
+
68
+ const g = globalThis as Record<string, unknown>;
69
+ const DecoderCtor = g.ImageDecoder as new (init: { data: ArrayBuffer; type: string }) => ImageDecoderLike;
70
+ const EncoderCtor = g.VideoEncoder as VideoEncoderCtor;
71
+
72
+ const resources: { decoder?: ImageDecoderLike; encoder?: VideoEncoderLike } = {};
73
+ const openFrames: DecodedFrame[] = [];
74
+
75
+ try {
76
+ const decoder = new DecoderCtor({ data, type: 'image/gif' });
77
+ resources.decoder = decoder;
78
+ await decoder.tracks.ready;
79
+ const frameCount = decoder.tracks.selectedTrack?.frameCount ?? 0;
80
+ if (frameCount <= 1) return null;
81
+
82
+ const first = await decoder.decode({ frameIndex: 0 });
83
+ openFrames.push(first.image);
84
+ const width = first.image.displayWidth;
85
+ const height = first.image.displayHeight;
86
+
87
+ const codec = await pickCodec(EncoderCtor, width, height);
88
+ if (!codec) return null;
89
+
90
+ const { Muxer, ArrayBufferTarget } = await import('webm-muxer');
91
+ const target = new ArrayBufferTarget();
92
+ const muxer = new Muxer({
93
+ target,
94
+ video: { codec: codec.muxerCodec, width, height },
95
+ firstTimestampBehavior: 'offset',
96
+ });
97
+
98
+ const encoder = new EncoderCtor({
99
+ output: (chunk, meta) => muxer.addVideoChunk(chunk as never, meta as never),
100
+ error: () => undefined,
101
+ });
102
+ resources.encoder = encoder;
103
+ encoder.configure({
104
+ codec: codec.encoderCodec,
105
+ width,
106
+ height,
107
+ bitrate: Math.max(200_000, width * height * 4),
108
+ });
109
+
110
+ const indices = Array.from({ length: frameCount }, (_unused, i) => i);
111
+ // Running timestamp held in a const cursor so each frame is re-stamped to be
112
+ // monotonic from the accumulated GIF delays (µs) without a mutable `let`.
113
+ const cursor = { timestamp: 0 };
114
+ for (const i of indices) {
115
+ const frame = await getFrame(i, first.image, decoder);
116
+ cursor.timestamp = encodeFrame(encoder, frame, i, cursor.timestamp);
117
+ collectFrame(openFrames, frame, i);
118
+ opts.onProgress?.(Math.round(((i + 1) / frameCount) * 100));
119
+ }
120
+
121
+ await encoder.flush();
122
+ muxer.finalize();
123
+ return new Blob([target.buffer], { type: 'video/webm' });
124
+ } catch {
125
+ return null;
126
+ } finally {
127
+ openFrames.forEach((f) => {
128
+ try { f.close(); } catch { /* already closed */ }
129
+ });
130
+ try { resources.encoder?.close(); } catch { /* noop */ }
131
+ try { resources.decoder?.close(); } catch { /* noop */ }
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Resolve a decoded frame for the given index. Frame 0 reuses the already
137
+ * decoded first image; later frames are decoded on demand.
138
+ */
139
+ async function getFrame(
140
+ index: number,
141
+ first: DecodedFrame,
142
+ decoder: ImageDecoderLike,
143
+ ): Promise<DecodedFrame> {
144
+ if (index === 0) return first;
145
+ return (await decoder.decode({ frameIndex: index })).image;
146
+ }
147
+
148
+ /**
149
+ * Encode one frame at the given timestamp and return the timestamp for the
150
+ * next frame (current + this frame's GIF delay, in µs).
151
+ */
152
+ function encodeFrame(
153
+ encoder: VideoEncoderLike,
154
+ frame: DecodedFrame,
155
+ index: number,
156
+ timestamp: number,
157
+ ): number {
158
+ const stamped = frame as DecodedFrame & { timestamp: number };
159
+ stamped.timestamp = timestamp;
160
+ encoder.encode(frame, { keyFrame: index % KEYFRAME_INTERVAL === 0 });
161
+ return timestamp + (frame.duration ?? 100_000);
162
+ }
163
+
164
+ /**
165
+ * Track later frames so they can be closed in the finally block. Frame 0 is
166
+ * already tracked by the caller.
167
+ */
168
+ function collectFrame(openFrames: DecodedFrame[], frame: DecodedFrame, index: number): void {
169
+ if (index !== 0) openFrames.push(frame);
170
+ }
@@ -33,6 +33,8 @@ import {
33
33
  } from '../../components/icons';
34
34
  import { DEFAULT_CAPTION_PLACEHOLDER, URL_PATTERN } from './constants';
35
35
  import { renderEmptyState, type EmptyStateElement } from './empty-state';
36
+ import { uploadErrorMessage } from '../../components/utils/upload-error-message';
37
+ import { pickDisplayMaxSize } from '../../components/utils/max-size';
36
38
  import { renderErrorState } from './error-state';
37
39
  import { ImageError } from './errors';
38
40
  import { attachResizeHandle, type ResizeEdge } from './resizer';
@@ -50,6 +52,8 @@ import { openAltPopover } from './alt-popover';
50
52
  import { probeImageDimensions } from './probe-dimensions';
51
53
  import { renderUploadingState, type UploadingStateElement } from './uploading-state';
52
54
  import { Uploader, type UploadResult } from './uploader';
55
+ import { convertGifToWebm } from './gif-to-webm';
56
+ import { resolveConvertedUploader } from './converted-uploader';
53
57
 
54
58
  type ToolState = 'EMPTY' | 'LOADING' | 'RENDERED' | 'ERROR';
55
59
 
@@ -83,6 +87,7 @@ export class ImageTool implements BlockTool {
83
87
  private brokenImage = false;
84
88
  private retrying = false;
85
89
  private reloadAttempts = 0;
90
+ private converting = false;
86
91
 
87
92
  constructor(options: BlockToolConstructorOptions<ImageData, ImageConfig>) {
88
93
  this.api = options.api;
@@ -153,7 +158,11 @@ export class ImageTool implements BlockTool {
153
158
  public onPaste(event: PasteEvent): void {
154
159
  if (event.type === 'pattern') {
155
160
  const detail = (event as PatternPasteEvent).detail;
156
- this.applyResult({ url: detail.data });
161
+ if (this.shouldConvertGifUrl(detail.data)) {
162
+ this.startUrl(detail.data);
163
+ } else {
164
+ this.applyResult({ url: detail.data });
165
+ }
157
166
  return;
158
167
  }
159
168
  if (event.type === 'tag') {
@@ -174,6 +183,18 @@ export class ImageTool implements BlockTool {
174
183
  };
175
184
 
176
185
  private startUpload(file: File): void {
186
+ if (this.shouldConvertGif(file.type)) {
187
+ void this.convertGifToVideoBlock(file).then((handled) => {
188
+ if (!handled) this.uploadImageFile(file);
189
+ });
190
+ return;
191
+ }
192
+ this.uploadImageFile(file);
193
+ }
194
+
195
+ /** Existing upload body, extracted verbatim. */
196
+ private uploadImageFile(file: File): void {
197
+ this.converting = false;
177
198
  this.lastFileName = file.name;
178
199
  this.lastSource = { kind: 'file', file };
179
200
  this.state = 'LOADING';
@@ -186,7 +207,67 @@ export class ImageTool implements BlockTool {
186
207
  .catch((err) => this.applyError(err));
187
208
  }
188
209
 
210
+ private shouldConvertGif(mimeType: string): boolean {
211
+ return this.config.convertGifToVideo !== false && mimeType === 'image/gif';
212
+ }
213
+
214
+ /**
215
+ * Try to convert a GIF to a looping WebM video block. Returns true only when
216
+ * the block was swapped; false means the caller should keep the GIF (image).
217
+ */
218
+ private async convertGifToVideoBlock(file: File): Promise<boolean> {
219
+ this.converting = true;
220
+ this.state = 'LOADING';
221
+ this.errorMessage = null;
222
+ this.brokenImage = false;
223
+ this.lastFileName = file.name;
224
+ this.renderState();
225
+ try {
226
+ const blob = await convertGifToWebm(await file.arrayBuffer(), { onProgress: this.reportProgress });
227
+ if (!blob) { this.converting = false; return false; }
228
+ const webm = new File([blob], file.name.replace(/\.gif$/i, '.webm'), { type: 'video/webm' });
229
+ const url = await this.uploadConverted(webm);
230
+ if (url === null) { this.converting = false; return false; }
231
+ this.converting = false;
232
+ return this.swapToVideoBlock(url, webm.name);
233
+ } catch {
234
+ this.converting = false;
235
+ return false;
236
+ }
237
+ }
238
+
239
+ private async uploadConverted(file: File): Promise<string | null> {
240
+ const upload = resolveConvertedUploader(this.api, this.config);
241
+ if (upload) {
242
+ const res = await upload(file, { onProgress: this.reportProgress });
243
+ return res.url;
244
+ }
245
+ return URL.createObjectURL(file);
246
+ }
247
+
248
+ private swapToVideoBlock(url: string, fileName: string): boolean {
249
+ const index = this.api.blocks.getBlockIndex(this.block.id);
250
+ if (index === undefined) return false;
251
+ this.api.blocks.insert(
252
+ 'video',
253
+ { url, autoplay: true, loop: true, mimeType: 'video/webm', fileName },
254
+ {}, index, false, true,
255
+ );
256
+ return true;
257
+ }
258
+
189
259
  private startUrl(url: string): void {
260
+ if (this.shouldConvertGifUrl(url)) {
261
+ void this.convertGifUrlToVideoBlock(url).then((handled) => {
262
+ if (!handled) this.loadImageUrl(url);
263
+ });
264
+ return;
265
+ }
266
+ this.loadImageUrl(url);
267
+ }
268
+
269
+ /** Existing startUrl body, extracted verbatim. */
270
+ private loadImageUrl(url: string): void {
190
271
  this.lastFileName = null;
191
272
  this.lastSource = { kind: 'url', url };
192
273
  this.state = 'LOADING';
@@ -199,6 +280,41 @@ export class ImageTool implements BlockTool {
199
280
  .catch((err) => this.applyError(err));
200
281
  }
201
282
 
283
+ private shouldConvertGifUrl(url: string): boolean {
284
+ return this.config.convertGifToVideo !== false && /\.gif(\?|#|$)/i.test(url);
285
+ }
286
+
287
+ private async convertGifUrlToVideoBlock(url: string): Promise<boolean> {
288
+ const bytes = await this.fetchGifBytes(url);
289
+ if (!bytes) return false;
290
+ this.converting = true;
291
+ this.state = 'LOADING';
292
+ this.errorMessage = null;
293
+ this.renderState();
294
+ try {
295
+ const blob = await convertGifToWebm(bytes, { onProgress: this.reportProgress });
296
+ if (!blob) { this.converting = false; return false; }
297
+ const webm = new File([blob], 'animation.webm', { type: 'video/webm' });
298
+ const uploadedUrl = await this.uploadConverted(webm);
299
+ if (uploadedUrl === null) { this.converting = false; return false; }
300
+ this.converting = false;
301
+ return this.swapToVideoBlock(uploadedUrl, webm.name);
302
+ } catch {
303
+ this.converting = false;
304
+ return false;
305
+ }
306
+ }
307
+
308
+ private async fetchGifBytes(url: string): Promise<ArrayBuffer | null> {
309
+ try {
310
+ const res = await fetch(url);
311
+ if (!res.ok) return null;
312
+ return await res.arrayBuffer();
313
+ } catch {
314
+ return null; // CORS / network → keep the GIF as an image URL
315
+ }
316
+ }
317
+
202
318
  private retryLastSource(): void {
203
319
  const source = this.lastSource;
204
320
  if (!source) {
@@ -231,7 +347,12 @@ export class ImageTool implements BlockTool {
231
347
 
232
348
  private applyError(err: unknown): void {
233
349
  this.state = 'ERROR';
234
- this.errorMessage = err instanceof Error ? err.message : this.api.i18n.t('tools.image.errorUploadFailed');
350
+ this.errorMessage = err instanceof ImageError
351
+ ? uploadErrorMessage(err, (key) => this.api.i18n.t(key), {
352
+ tooLarge: 'tools.image.errorFileTooLarge',
353
+ generic: 'tools.image.errorUploadFailed',
354
+ })
355
+ : this.api.i18n.t('tools.image.errorUploadFailed');
235
356
  this.brokenImage = false;
236
357
  this.retrying = false;
237
358
  this.renderState();
@@ -565,7 +686,7 @@ export class ImageTool implements BlockTool {
565
686
  onFile: (file) => this.startUpload(file),
566
687
  onUrl: (url) => this.startUrl(url),
567
688
  acceptTypes: this.config.types,
568
- maxSize: this.config.maxSize,
689
+ maxSize: pickDisplayMaxSize(this.config.maxSize),
569
690
  i18n: this.api.i18n,
570
691
  });
571
692
  this.emptyStateEl = el;
@@ -578,6 +699,7 @@ export class ImageTool implements BlockTool {
578
699
  fileName: this.lastFileName ?? this.api.i18n.t('tools.image.uploading'),
579
700
  onCancel: () => this.transitionToEmpty(),
580
701
  i18n: this.api.i18n,
702
+ ...(this.converting ? { statusLabel: this.api.i18n.t('tools.image.converting') } : {}),
581
703
  });
582
704
  this.uploadingEl = el;
583
705
  this.root.appendChild(el);
@@ -41,13 +41,26 @@ export function clampPercent(value: number, minPercent: number = MIN_WIDTH_PERCE
41
41
  return value;
42
42
  }
43
43
 
44
+ export interface WidthResult {
45
+ /** The clamped width as a percent of the container. */
46
+ percent: number;
47
+ /**
48
+ * True when the drag wanted to shrink past the lower floor and was pinned
49
+ * there — used to surface a "can't go smaller" cue to the user.
50
+ */
51
+ clampedToMin: boolean;
52
+ }
53
+
44
54
  /**
45
55
  * Pointer follows the dragged edge; width grows around the alignment anchor.
46
56
  * Center (frac 0.5) → both edges move → width delta = 2× pointer delta.
47
57
  * Edge-anchored (frac 0 or 1) → single side grows → width delta = 1× pointer delta.
58
+ *
59
+ * Returns the clamped percent plus whether it hit the lower floor, so callers
60
+ * can animate a resistance cue when the player refuses to shrink further.
48
61
  */
49
- export function computeWidthPercent(input: ComputeWidthInput): number {
50
- if (input.containerWidth <= 0) return clampPercent(0);
62
+ export function computeWidthResult(input: ComputeWidthInput): WidthResult {
63
+ if (input.containerWidth <= 0) return { percent: clampPercent(0), clampedToMin: true };
51
64
  const frac = input.alignFrac ?? 0;
52
65
  const denom = input.edge === 'right' ? 1 - frac : frac;
53
66
  const multiplier = denom === 0 ? 1 : 1 / denom;
@@ -57,9 +70,23 @@ export function computeWidthPercent(input: ComputeWidthInput): number {
57
70
  const minPercent = input.minWidthPx !== undefined
58
71
  ? Math.round((input.minWidthPx / input.containerWidth) * 100)
59
72
  : MIN_WIDTH_PERCENT;
60
- return clampPercent(Math.round((nextWidth / input.containerWidth) * 100), minPercent);
73
+ const floor = Math.min(Math.max(minPercent, MIN_WIDTH_PERCENT), MAX_WIDTH_PERCENT);
74
+ const raw = Math.round((nextWidth / input.containerWidth) * 100);
75
+ return { percent: clampPercent(raw, minPercent), clampedToMin: raw < floor };
61
76
  }
62
77
 
78
+ export function computeWidthPercent(input: ComputeWidthInput): number {
79
+ return computeWidthResult(input).percent;
80
+ }
81
+
82
+ /**
83
+ * Marker set on the figure while a drag is pinned at the lower floor. Shared
84
+ * resize-cue CSS keys off it to recoil the player/image/embed and neutralise
85
+ * the dragged handle, so every resizable tool gets the "can't shrink further"
86
+ * feedback for free.
87
+ */
88
+ export const RESIZE_BLOCKED_ATTR = 'data-resize-blocked';
89
+
63
90
  export interface AttachResizeHandleOptions {
64
91
  handle: HTMLElement;
65
92
  figure: HTMLElement;
@@ -103,7 +130,7 @@ export function attachResizeHandle(opts: AttachResizeHandleOptions): () => void
103
130
 
104
131
  const onMove = (event: PointerEvent): void => {
105
132
  if (!state.active) return;
106
- const next = computeWidthPercent({
133
+ const result = computeWidthResult({
107
134
  edge: opts.edge,
108
135
  containerWidth: state.containerWidth,
109
136
  startWidth: state.startWidth,
@@ -112,13 +139,19 @@ export function attachResizeHandle(opts: AttachResizeHandleOptions): () => void
112
139
  alignFrac,
113
140
  minWidthPx: opts.minWidthPx,
114
141
  });
115
- state.lastPercent = next;
116
- opts.onPreview(next);
142
+ state.lastPercent = result.percent;
143
+ if (result.clampedToMin) {
144
+ opts.figure.setAttribute(RESIZE_BLOCKED_ATTR, 'true');
145
+ } else {
146
+ opts.figure.removeAttribute(RESIZE_BLOCKED_ATTR);
147
+ }
148
+ opts.onPreview(result.percent);
117
149
  };
118
150
 
119
151
  const onUp = (event: PointerEvent): void => {
120
152
  if (!state.active) return;
121
153
  state.active = false;
154
+ opts.figure.removeAttribute(RESIZE_BLOCKED_ATTR);
122
155
  opts.handle.releasePointerCapture(event.pointerId);
123
156
  if (state.lastPercent !== undefined) opts.onCommit(state.lastPercent);
124
157
  };
@@ -1,4 +1,5 @@
1
1
  import type { ImageConfig } from '../../../types/tools/image';
2
+ import { resolveMaxSize } from '../../components/utils/max-size';
2
3
  import { DEFAULT_MAX_SIZE, DEFAULT_MIME_TYPES } from './constants';
3
4
  import { ImageError } from './errors';
4
5
 
@@ -87,7 +88,7 @@ export class Uploader {
87
88
 
88
89
  private validateFile(file: File): void {
89
90
  const types = this.config.types ?? [...DEFAULT_MIME_TYPES];
90
- const maxSize = this.config.maxSize ?? DEFAULT_MAX_SIZE;
91
+ const maxSize = resolveMaxSize(this.config.maxSize, file.type, DEFAULT_MAX_SIZE);
91
92
 
92
93
  if (!types.includes(file.type)) {
93
94
  throw new ImageError('UNSUPPORTED_TYPE', file.type || 'unknown');
@@ -5,6 +5,7 @@ import { tr } from './i18n';
5
5
  export interface UploadingStateOptions {
6
6
  fileName: string;
7
7
  sizeLabel?: string;
8
+ statusLabel?: string;
8
9
  onCancel?(): void;
9
10
  i18n?: I18nInstance;
10
11
  }
@@ -33,7 +34,7 @@ export function renderUploadingState(opts: UploadingStateOptions): UploadingStat
33
34
 
34
35
  const label = document.createElement('span');
35
36
  label.className = 'blok-image-uploading__label';
36
- label.textContent = tr(opts.i18n, 'tools.image.uploadingLabel');
37
+ label.textContent = opts.statusLabel ?? tr(opts.i18n, 'tools.image.uploadingLabel');
37
38
 
38
39
  const name = document.createElement('span');
39
40
  name.className = 'blok-image-uploading__filename';