@templatical/editor 0.19.0 → 0.21.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 (189) hide show
  1. package/README.md +1 -0
  2. package/dist/{AiChatSidebar-DAQTFuvi.js → AiChatSidebar-K_AehWc-.js} +9 -9
  3. package/dist/{AiFeatureMenu-aFSO20PR.js → AiFeatureMenu-CPdNpHpZ.js} +6 -6
  4. package/dist/{BlockIssueBadge-BQmq1bxn.js → BlockIssueBadge-Dmj9rVra.js} +4 -4
  5. package/dist/{CloudEditor-D0K-m1GA.js → CloudEditor-3a7mqMhe.js} +263 -315
  6. package/dist/{CollaboratorBar-CJO3l6Dt.js → CollaboratorBar-Ds0YZWzV.js} +3 -3
  7. package/dist/{ColorPicker-BsgpTJqK.js → ColorPicker-s9GHXjZs.js} +4 -4
  8. package/dist/CommentsSidebar-DvNEdugN.js +435 -0
  9. package/dist/{CountdownBlock-Bn5w7C-p.js → CountdownBlock-BUHYIAe9.js} +1 -1
  10. package/dist/{CountdownToolbar-PJI3ffi1.js → CountdownToolbar-DPRcv3Fu.js} +3 -4
  11. package/dist/{DesignReferenceSidebar-QfAV8XT9.js → DesignReferenceSidebar-DNmK3dxp.js} +8 -8
  12. package/dist/{IssuesPanel-CTjRgz8w.js → IssuesPanel-CEnEGFtd.js} +7 -7
  13. package/dist/{MergeTagSuggestion-DCuaSOPQ.js → MergeTagSuggestion-DMe4rqn0.js} +2 -2
  14. package/dist/NumberWithSuffix-CCPN_oCh.js +121 -0
  15. package/dist/{ParagraphEditor-Cf75UfSo.js → ParagraphEditor-CkwBirNl.js} +47 -47
  16. package/dist/{RichTextEditorContent-MdaLz6Q3.js → RichTextEditorContent-FbnWsh46.js} +6 -6
  17. package/dist/SaveBlockDialog-Cc5BSUBx.js +264 -0
  18. package/dist/SavedBlockPreviewCanvas-ubttfmKr.js +109 -0
  19. package/dist/SavedBlocksBrowserModal-LkY_U3lY.js +323 -0
  20. package/dist/SavedBlocksPanels-CET0zvH6.js +36 -0
  21. package/dist/SavedBlocksPickBar-poGS4PoI.js +52 -0
  22. package/dist/{SnapshotHistory-C_Y1LzAY.js → SnapshotHistory-BvF5IXn1.js} +8 -8
  23. package/dist/{TemplateScoringPanel-DikuKc6i.js → TemplateScoringPanel-ifGGGWs5.js} +14 -14
  24. package/dist/{TestEmailModal-BW8aTtzf.js → TestEmailModal-BRaM_eko.js} +4 -4
  25. package/dist/{TitleEditor-CCUkbRN0.js → TitleEditor-Bhgzh-iQ.js} +11 -11
  26. package/dist/{TplModal-DoOwUKlT.js → TplModal-BA-Zsg0O.js} +3 -3
  27. package/dist/{blockTypeIcons-BlPKjD7M.js → blockTypeIcons-B1-Yzp-a.js} +6 -6
  28. package/dist/bundle-stats.json +8 -8
  29. package/dist/{ca-DbWoy4rG.js → ca-BBgad6y5.js} +50 -3
  30. package/dist/cdn/chunks/{AiFeatureMenu-RwJiaPXZ.js → AiFeatureMenu--PdArSnv.js} +7 -7
  31. package/dist/cdn/chunks/{AiFeatureMenu-RwJiaPXZ.js.map → AiFeatureMenu--PdArSnv.js.map} +1 -1
  32. package/dist/cdn/chunks/{BlockIssueBadge-DM-TDKbr.js → BlockIssueBadge-DMSd0SIl.js} +4 -4
  33. package/dist/cdn/chunks/{BlockIssueBadge-DM-TDKbr.js.map → BlockIssueBadge-DMSd0SIl.js.map} +1 -1
  34. package/dist/cdn/chunks/{CloudEditor-Dufl354p.js → CloudEditor-DnTfI5GU.js} +273 -325
  35. package/dist/cdn/chunks/CloudEditor-DnTfI5GU.js.map +1 -0
  36. package/dist/cdn/chunks/{CollaboratorBar-xsU20iPl.js → CollaboratorBar-CBqd7ldq.js} +3 -3
  37. package/dist/cdn/chunks/{CollaboratorBar-xsU20iPl.js.map → CollaboratorBar-CBqd7ldq.js.map} +1 -1
  38. package/dist/cdn/chunks/{ColorPicker-y_obnw4o.js → ColorPicker-DCdWP8YB.js} +99 -99
  39. package/dist/cdn/chunks/ColorPicker-DCdWP8YB.js.map +1 -0
  40. package/dist/cdn/chunks/{CountdownBlock-sHsRMe1q.js → CountdownBlock-BDnWMAME.js} +2 -2
  41. package/dist/cdn/chunks/{CountdownBlock-sHsRMe1q.js.map → CountdownBlock-BDnWMAME.js.map} +1 -1
  42. package/dist/cdn/chunks/{CountdownToolbar-Ckc_jEi-.js → CountdownToolbar-BbLoo22S.js} +4 -5
  43. package/dist/cdn/chunks/{CountdownToolbar-Ckc_jEi-.js.map → CountdownToolbar-BbLoo22S.js.map} +1 -1
  44. package/dist/cdn/chunks/{IssuesPanel-DF5Ajuna.js → IssuesPanel-CfudrI3T.js} +7 -7
  45. package/dist/cdn/chunks/{IssuesPanel-DF5Ajuna.js.map → IssuesPanel-CfudrI3T.js.map} +1 -1
  46. package/dist/cdn/chunks/{MergeTagSuggestion-BmMmdcRg.js → MergeTagSuggestion-D7TsECll.js} +2 -2
  47. package/dist/cdn/chunks/{MergeTagSuggestion-BmMmdcRg.js.map → MergeTagSuggestion-D7TsECll.js.map} +1 -1
  48. package/dist/cdn/chunks/NumberWithSuffix-BmMx9_n_.js +123 -0
  49. package/dist/cdn/chunks/NumberWithSuffix-BmMx9_n_.js.map +1 -0
  50. package/dist/cdn/chunks/{ParagraphEditor-BkafKSju.js → ParagraphEditor-DPCUSXpx.js} +82 -82
  51. package/dist/cdn/chunks/{ParagraphEditor-BkafKSju.js.map → ParagraphEditor-DPCUSXpx.js.map} +1 -1
  52. package/dist/cdn/chunks/{RichTextEditorContent-BthhzOZS.js → RichTextEditorContent-B8dOiv_D.js} +5 -5
  53. package/dist/cdn/chunks/{RichTextEditorContent-BthhzOZS.js.map → RichTextEditorContent-B8dOiv_D.js.map} +1 -1
  54. package/dist/cdn/chunks/SaveBlockDialog-BY3SMnNV.js +259 -0
  55. package/dist/cdn/chunks/SaveBlockDialog-BY3SMnNV.js.map +1 -0
  56. package/dist/cdn/chunks/SavedBlockPreviewCanvas-LpaOcusq.js +110 -0
  57. package/dist/cdn/chunks/SavedBlockPreviewCanvas-LpaOcusq.js.map +1 -0
  58. package/dist/cdn/chunks/SavedBlocksBrowserModal-CfIcmyzF.js +318 -0
  59. package/dist/cdn/chunks/SavedBlocksBrowserModal-CfIcmyzF.js.map +1 -0
  60. package/dist/cdn/chunks/SavedBlocksPanels-kIowCfh_.js +38 -0
  61. package/dist/cdn/chunks/SavedBlocksPanels-kIowCfh_.js.map +1 -0
  62. package/dist/cdn/chunks/SavedBlocksPickBar-WSGe1GiZ.js +52 -0
  63. package/dist/cdn/chunks/SavedBlocksPickBar-WSGe1GiZ.js.map +1 -0
  64. package/dist/cdn/chunks/{TitleEditor-DLv9cXba.js → TitleEditor-iwd-O9sO.js} +11 -11
  65. package/dist/cdn/chunks/{TitleEditor-DLv9cXba.js.map → TitleEditor-iwd-O9sO.js.map} +1 -1
  66. package/dist/cdn/chunks/{blockTypeIcons-B0uibGX7.js → blockTypeIcons-BYz0fgLz.js} +7 -7
  67. package/dist/cdn/chunks/{blockTypeIcons-B0uibGX7.js.map → blockTypeIcons-BYz0fgLz.js.map} +1 -1
  68. package/dist/cdn/chunks/{ca-DbWoy4rG.js → ca-BBgad6y5.js} +51 -4
  69. package/dist/cdn/chunks/ca-BBgad6y5.js.map +1 -0
  70. package/dist/{de-CTYXVU9v.js → cdn/chunks/de-Bw6fB5JU.js} +2 -24
  71. package/dist/cdn/chunks/{de-CTYXVU9v.js.map → de-Bw6fB5JU.js.map} +1 -1
  72. package/dist/cdn/chunks/{de-CgGOnerg.js → de-D7WbpFBR.js} +50 -3
  73. package/dist/cdn/chunks/de-D7WbpFBR.js.map +1 -0
  74. package/dist/{en-DrUV9xth.js → cdn/chunks/en-BrZ0uGK2.js} +51 -2
  75. package/dist/cdn/chunks/en-BrZ0uGK2.js.map +1 -0
  76. package/dist/{en-BtmIaJeb.js → cdn/chunks/en-DAdHJz7h.js} +2 -24
  77. package/dist/cdn/chunks/{en-BtmIaJeb.js.map → en-DAdHJz7h.js.map} +1 -1
  78. package/dist/{es-DwbKjU7q.js → cdn/chunks/es-tLSLysPs.js} +51 -2
  79. package/dist/cdn/chunks/es-tLSLysPs.js.map +1 -0
  80. package/dist/cdn/chunks/{extensions-DLHvZ0UH.js → extensions-DeJh3E9b.js} +29 -29
  81. package/dist/cdn/chunks/{extensions-DLHvZ0UH.js.map → extensions-DeJh3E9b.js.map} +1 -1
  82. package/dist/cdn/chunks/{features-Cnfv4QAY.js → features-pLfGJWIB.js} +1802 -1603
  83. package/dist/cdn/chunks/features-pLfGJWIB.js.map +1 -0
  84. package/dist/cdn/chunks/{icons-DbcM69bb.js → icons-FLemooQz.js} +16 -16
  85. package/dist/cdn/chunks/{icons-DbcM69bb.js.map → icons-FLemooQz.js.map} +1 -1
  86. package/dist/cdn/chunks/{media-library-DpSMwHd4.js → media-library-mCCZieYO.js} +163 -163
  87. package/dist/cdn/chunks/{media-library-DpSMwHd4.js.map → media-library-mCCZieYO.js.map} +1 -1
  88. package/dist/cdn/chunks/{pt-BR-Bcc5Tjed.js → pt-BR-BWFokdTU.js} +50 -3
  89. package/dist/cdn/chunks/pt-BR-BWFokdTU.js.map +1 -0
  90. package/dist/{pt-BR-B2ZvFlRL.js → cdn/chunks/pt-BR-w2sGzHNX.js} +2 -24
  91. package/dist/cdn/chunks/{pt-BR-B2ZvFlRL.js.map → pt-BR-w2sGzHNX.js.map} +1 -1
  92. package/dist/cdn/chunks/{pusher-CIwiKF8H.js → pusher-R0v5p99W.js} +27 -22
  93. package/dist/cdn/chunks/pusher-R0v5p99W.js.map +1 -0
  94. package/dist/cdn/chunks/{quality-D9QqkRcU.js → quality-BRbHtAk1.js} +460 -460
  95. package/dist/cdn/chunks/{quality-D9QqkRcU.js.map → quality-BRbHtAk1.js.map} +1 -1
  96. package/dist/cdn/chunks/{renderer-BsLQZNXU.js → renderer-Yg1XhsBN.js} +18 -18
  97. package/dist/cdn/chunks/{renderer-BsLQZNXU.js.map → renderer-Yg1XhsBN.js.map} +1 -1
  98. package/dist/cdn/chunks/{src-zu1ehVNN.js → src-BDJeYiVE.js} +33 -33
  99. package/dist/cdn/chunks/{src-zu1ehVNN.js.map → src-BDJeYiVE.js.map} +1 -1
  100. package/dist/cdn/chunks/{styles-Dx-jXeCd.js → styles-Bp5Jsu9J.js} +1422 -1332
  101. package/dist/cdn/chunks/styles-Bp5Jsu9J.js.map +1 -0
  102. package/dist/cdn/chunks/{tiptap-C2indasq.js → tiptap-BMZ-OENR.js} +2012 -1863
  103. package/dist/cdn/chunks/tiptap-BMZ-OENR.js.map +1 -0
  104. package/dist/cdn/editor.css +1 -1
  105. package/dist/cdn/editor.js +123 -114
  106. package/dist/cdn/editor.js.map +1 -1
  107. package/dist/{check-Cg6Mc2pP.js → check-BpQDKiPz.js} +1 -1
  108. package/dist/{chevron-down-dClfxKrJ.js → chevron-down-j8GrdTyz.js} +1 -1
  109. package/dist/chevron-up-BACyVhyC.js +7 -0
  110. package/dist/{circle-alert-Bhzm-fNA.js → circle-alert-CgtE46ND.js} +1 -1
  111. package/dist/{clock-m7TwQw4b.js → clock-BzKLLW5L.js} +1 -1
  112. package/dist/{cloud-B-RebwxI.js → cloud-Du7mnkz2.js} +19 -47
  113. package/dist/{createLucideIcon-FSF4peHQ.js → createLucideIcon-JWHwTI6N.js} +2 -2
  114. package/dist/{cdn/chunks/de-CTYXVU9v.js → de-Bw6fB5JU.js} +0 -26
  115. package/dist/{de-CgGOnerg.js → de-D7WbpFBR.js} +49 -2
  116. package/dist/{dist-CgTKuIUN.js → dist-BEpCh2mG.js} +1158 -1125
  117. package/dist/{dist-Cx7IUM7J.js → dist-BgPYC_8-.js} +14 -6
  118. package/dist/{dist-BKKo5wPC.js → dist-BkM8A17N.js} +2 -2
  119. package/dist/{dist-CcX5sLpz.js → dist-BuNDAAVp.js} +361 -256
  120. package/dist/{dist-COSN3oDJ.js → dist-CBzCU-a-.js} +2 -2
  121. package/dist/{dist-YSCPD13F.js → dist-CDO52Rxy.js} +2 -2
  122. package/dist/{dist-Dk5AdwoQ.js → dist-CrjzhIxB.js} +2 -2
  123. package/dist/{dist-DXAZUjj3.js → dist-CtcgoC_R.js} +2 -2
  124. package/dist/{dist-D6M5FAY7.js → dist-CuXha2_7.js} +2 -2
  125. package/dist/dist-CweLDZrs.js +5 -0
  126. package/dist/dist-DOsdqAEZ.js +5 -0
  127. package/dist/{dist-8TKf-Jpg.js → dist-DYClLqy8.js} +6 -3
  128. package/dist/{cdn/chunks/en-DrUV9xth.js → en-BrZ0uGK2.js} +49 -4
  129. package/dist/{cdn/chunks/en-BtmIaJeb.js → en-DAdHJz7h.js} +0 -26
  130. package/dist/{cdn/chunks/es-DwbKjU7q.js → es-tLSLysPs.js} +49 -4
  131. package/dist/{extensions-BCA9pyer.js → extensions-ClY5Sh7S.js} +5 -5
  132. package/dist/{image-up-CDEgJqwA.js → image-up-CQdtq8ge.js} +1 -1
  133. package/dist/index.d.ts +81 -4
  134. package/dist/{info-BNP8yGsK.js → info-BUJBXoE6.js} +1 -1
  135. package/dist/{keys-DFaIbGR8.js → keys-CHPcp-Nz.js} +2 -2
  136. package/dist/{list-checks-jepi4iYr.js → list-checks-BGHaCSD5.js} +1 -1
  137. package/dist/{loader-circle-BT38qSm3.js → loader-circle-C-Z6kgI6.js} +1 -1
  138. package/dist/{message-circle-BAHcL9S-.js → message-circle-CEm5qckV.js} +1 -1
  139. package/dist/pencil-DdwmkKLb.js +10 -0
  140. package/dist/{pt-BR-Bcc5Tjed.js → pt-BR-BWFokdTU.js} +49 -2
  141. package/dist/{cdn/chunks/pt-BR-B2ZvFlRL.js → pt-BR-w2sGzHNX.js} +0 -26
  142. package/dist/{refresh-cw-as5Bmg4X.js → refresh-cw-maKlg0dl.js} +1 -1
  143. package/dist/{scan-line-IAMjPtRw.js → scan-line-BFgesTOY.js} +1 -1
  144. package/dist/{send-DvMay6bt.js → send-B70aQDrA.js} +1 -1
  145. package/dist/{shield-check-YYDhGroE.js → shield-check-B7x5OKt5.js} +1 -1
  146. package/dist/{sparkles-CCwQMMMZ.js → sparkles-DVlm1Ipp.js} +1 -1
  147. package/dist/style.css +1 -1
  148. package/dist/{styles-64uLkPJV.js → styles-DIDAJdkj.js} +1241 -1151
  149. package/dist/templatical-editor.js +134 -125
  150. package/dist/{text-align-start-BwsA6QzC.js → text-align-start-Vay3Kvo2.js} +1 -1
  151. package/dist/{trash-2-CRBDolnR.js → trash-2-DE8CmxAG.js} +1 -1
  152. package/dist/{triangle-alert-B2g0ALvq.js → triangle-alert-Djg6IG8N.js} +1 -1
  153. package/dist/{upload-y4gxiFp5.js → upload-BwwE0U6G.js} +1 -1
  154. package/dist/{useCloudI18n-PCDOC2kz.js → useCloudI18n-BmiygEM4.js} +1 -1
  155. package/dist/{useEditorCore-ea9OrrH3.js → useEditorCore-Bd9CA4L_.js} +1236 -1013
  156. package/dist/{useI18n-BNMzZTM5.js → useI18n-D2L9Mkik.js} +1 -1
  157. package/dist/{useMergeTag-DfEY0eK5.js → useMergeTag-BTdDq5DC.js} +1 -1
  158. package/dist/{usePopoverPosition-F9STHRIr.js → usePopoverPosition-BO2LNy5n.js} +1 -1
  159. package/dist/{x-Ctg_250T.js → x-CkD6A1iB.js} +1 -1
  160. package/package.json +23 -23
  161. package/dist/CommentsSidebar-BYMVucZh.js +0 -442
  162. package/dist/ModuleBrowserModal-BNalLx0k.js +0 -202
  163. package/dist/ModulePreviewCanvas-BwObwisa.js +0 -106
  164. package/dist/NumberWithSuffix-D3BKz66W.js +0 -89
  165. package/dist/SaveModuleDialog-MTjwiF9D.js +0 -125
  166. package/dist/ToggleSwitch-DUNuUPsZ.js +0 -37
  167. package/dist/cdn/chunks/CloudEditor-Dufl354p.js.map +0 -1
  168. package/dist/cdn/chunks/ColorPicker-y_obnw4o.js.map +0 -1
  169. package/dist/cdn/chunks/ModuleBrowserModal-DG4AVFjH.js +0 -198
  170. package/dist/cdn/chunks/ModuleBrowserModal-DG4AVFjH.js.map +0 -1
  171. package/dist/cdn/chunks/ModulePreviewCanvas-Bc_PcJuc.js +0 -107
  172. package/dist/cdn/chunks/ModulePreviewCanvas-Bc_PcJuc.js.map +0 -1
  173. package/dist/cdn/chunks/NumberWithSuffix-8fOO-LC_.js +0 -91
  174. package/dist/cdn/chunks/NumberWithSuffix-8fOO-LC_.js.map +0 -1
  175. package/dist/cdn/chunks/SaveModuleDialog-DhsfYf2n.js +0 -120
  176. package/dist/cdn/chunks/SaveModuleDialog-DhsfYf2n.js.map +0 -1
  177. package/dist/cdn/chunks/ToggleSwitch-OrmX_w18.js +0 -39
  178. package/dist/cdn/chunks/ToggleSwitch-OrmX_w18.js.map +0 -1
  179. package/dist/cdn/chunks/ca-DbWoy4rG.js.map +0 -1
  180. package/dist/cdn/chunks/de-CgGOnerg.js.map +0 -1
  181. package/dist/cdn/chunks/en-DrUV9xth.js.map +0 -1
  182. package/dist/cdn/chunks/es-DwbKjU7q.js.map +0 -1
  183. package/dist/cdn/chunks/features-Cnfv4QAY.js.map +0 -1
  184. package/dist/cdn/chunks/pt-BR-Bcc5Tjed.js.map +0 -1
  185. package/dist/cdn/chunks/pusher-CIwiKF8H.js.map +0 -1
  186. package/dist/cdn/chunks/styles-Dx-jXeCd.js.map +0 -1
  187. package/dist/cdn/chunks/tiptap-C2indasq.js.map +0 -1
  188. package/dist/dist-BDVm2MrW.js +0 -5
  189. package/dist/dist-DbekZDmJ.js +0 -5
@@ -1,7 +1,7 @@
1
1
  import { A as e, C as t, M as n, N as r, P as i, V as a, Z as o, ct as s, f as c, g as l, h as u, it as d, l as ee, m as f, n as p, ot as te, p as m, r as h, st as g, u as _, v, x as y, y as b } from "./draggable-D840DIZB.js";
2
- import { C as x, D as S, Ot as C, Pt as ne } from "./features-Cnfv4QAY.js";
3
- import { B as re, L as ie, W as ae, k as oe, y as se } from "./icons-DbcM69bb.js";
4
- import { a as ce, c as le, d as ue, f as de, g as w, h as T, i as E, l as D, n as O, o as k, p as A, r as j, s as M, t as N, u as P } from "./media-library-DpSMwHd4.js";
2
+ import { O as x, Rt as ne, jt as S, w as C } from "./features-pLfGJWIB.js";
3
+ import { B as re, L as ie, W as ae, k as oe, y as se } from "./icons-FLemooQz.js";
4
+ import { a as ce, c as le, d as ue, f as de, g as w, h as T, i as E, l as D, n as O, o as k, p as A, r as j, s as M, t as N, u as P } from "./media-library-mCCZieYO.js";
5
5
  //#region ../media-library/src/standalone/MediaLibrary.vue?vue&type=script&setup=true&lang.ts
6
6
  var F = {
7
7
  class: "tpl tpl:flex tpl:flex-col tpl:overflow-hidden tpl:rounded-[var(--tpl-radius-lg)]",
@@ -78,7 +78,7 @@ var F = {
78
78
  },
79
79
  emits: ["ready"],
80
80
  setup(t, { emit: h }) {
81
- let y = t, x = h, S = c(() => y.translations);
81
+ let y = t, x = h, C = c(() => y.translations);
82
82
  r("translations", y.translations), r("authManager", y.authManager), r("projectId", c(() => y.projectId)), r("planConfig", {
83
83
  config: o(y.planConfig),
84
84
  isLoading: o(!1),
@@ -93,7 +93,7 @@ var F = {
93
93
  }), J = O({
94
94
  library: q,
95
95
  canUseMediaFolders: w,
96
- translations: S
96
+ translations: C
97
97
  });
98
98
  function Y() {
99
99
  if (!q.previewItem.value) return;
@@ -106,7 +106,7 @@ var F = {
106
106
  return e(() => {
107
107
  q.loadItems(), q.loadFrequentlyUsed(), x("ready");
108
108
  }), (e, r) => (n(), l("div", F, [
109
- m("div", I, [m("h2", L, s(S.value.mediaLibrary.title), 1), m("div", R, [b(j, {
109
+ m("div", I, [m("h2", L, s(C.value.mediaLibrary.title), 1), m("div", R, [b(j, {
110
110
  "used-bytes": W.value,
111
111
  "limit-bytes": G.value,
112
112
  size: 22
@@ -119,7 +119,7 @@ var F = {
119
119
  "background-color": "var(--tpl-bg)",
120
120
  color: "var(--tpl-text)"
121
121
  },
122
- placeholder: S.value.mediaLibrary.searchPlaceholder,
122
+ placeholder: C.value.mediaLibrary.searchPlaceholder,
123
123
  onInput: r[0] ||= (e) => d(J).handleSearchInput(e.target.value)
124
124
  }, null, 40, B), b(d(se), {
125
125
  class: "tpl:absolute tpl:top-1/2 tpl:left-2.5 tpl:-translate-y-1/2",
@@ -166,13 +166,13 @@ var F = {
166
166
  backgroundColor: d(J).showSidebar.value ? "var(--tpl-bg)" : "transparent",
167
167
  border: d(J).showSidebar.value ? "1px solid var(--tpl-border)" : "1px solid transparent"
168
168
  }),
169
- title: d(J).showSidebar.value ? S.value.mediaLibrary.hideFolders : S.value.mediaLibrary.showFolders,
169
+ title: d(J).showSidebar.value ? C.value.mediaLibrary.hideFolders : C.value.mediaLibrary.showFolders,
170
170
  onClick: r[1] ||= (e) => d(J).showSidebar.value = !d(J).showSidebar.value
171
171
  }, [b(d(oe), {
172
172
  size: 16,
173
173
  "stroke-width": 2
174
174
  })], 12, he)) : u("", !0),
175
- d(q).viewMode.value === "frequently-used" ? (n(), l("span", ge, s(S.value.mediaLibrary.frequentlyUsed), 1)) : (n(), f(A, {
175
+ d(q).viewMode.value === "frequently-used" ? (n(), l("span", ge, s(C.value.mediaLibrary.frequentlyUsed), 1)) : (n(), f(A, {
176
176
  key: 2,
177
177
  folders: d(q).folders.value,
178
178
  "current-folder-id": d(q).currentFolderId.value,
@@ -188,7 +188,7 @@ var F = {
188
188
  color: d(J).layoutMode.value === "grid" ? "var(--tpl-primary)" : "var(--tpl-text-muted)",
189
189
  backgroundColor: d(J).layoutMode.value === "grid" ? "var(--tpl-bg-elevated)" : "transparent"
190
190
  }),
191
- title: S.value.mediaLibrary.viewGrid,
191
+ title: C.value.mediaLibrary.viewGrid,
192
192
  onClick: r[2] ||= (e) => d(J).layoutMode.value = "grid"
193
193
  }, [b(d(ae), {
194
194
  size: 14,
@@ -199,7 +199,7 @@ var F = {
199
199
  color: d(J).layoutMode.value === "list" ? "var(--tpl-primary)" : "var(--tpl-text-muted)",
200
200
  backgroundColor: d(J).layoutMode.value === "list" ? "var(--tpl-bg-elevated)" : "transparent"
201
201
  }),
202
- title: S.value.mediaLibrary.viewList,
202
+ title: C.value.mediaLibrary.viewList,
203
203
  onClick: r[3] ||= (e) => d(J).layoutMode.value = "list"
204
204
  }, [b(d(ie), {
205
205
  size: 14,
@@ -215,7 +215,7 @@ var F = {
215
215
  },
216
216
  value: d(q).categoryFilter.value ?? "",
217
217
  onChange: r[4] ||= (e) => d(q).filterByCategory(e.target.value || null)
218
- }, [m("option", U, s(S.value.mediaLibrary.filterAll), 1), (n(!0), l(_, null, i(d(K), (e) => (n(), l("option", {
218
+ }, [m("option", U, s(C.value.mediaLibrary.filterAll), 1), (n(!0), l(_, null, i(d(K), (e) => (n(), l("option", {
219
219
  key: e,
220
220
  value: e
221
221
  }, s(d(J).getCategoryLabel(e)), 9, Se))), 128))], 40, xe)) : u("", !0), m("select", {
@@ -228,12 +228,12 @@ var F = {
228
228
  value: d(q).sortOption.value,
229
229
  onChange: r[5] ||= (e) => d(q).sortBy(e.target.value)
230
230
  }, [
231
- m("option", we, s(S.value.mediaLibrary.sortNewest), 1),
232
- m("option", Te, s(S.value.mediaLibrary.sortOldest), 1),
233
- m("option", Ee, s(S.value.mediaLibrary.sortNameAsc), 1),
234
- m("option", De, s(S.value.mediaLibrary.sortNameDesc), 1),
235
- m("option", Oe, s(S.value.mediaLibrary.sortSizeAsc), 1),
236
- m("option", ke, s(S.value.mediaLibrary.sortSizeDesc), 1)
231
+ m("option", we, s(C.value.mediaLibrary.sortNewest), 1),
232
+ m("option", Te, s(C.value.mediaLibrary.sortOldest), 1),
233
+ m("option", Ee, s(C.value.mediaLibrary.sortNameAsc), 1),
234
+ m("option", De, s(C.value.mediaLibrary.sortNameDesc), 1),
235
+ m("option", Oe, s(C.value.mediaLibrary.sortSizeAsc), 1),
236
+ m("option", ke, s(C.value.mediaLibrary.sortSizeDesc), 1)
237
237
  ], 40, Ce)])]), m("div", Ae, [d(q).viewMode.value === "files" ? (n(), l("div", je, [b(E, {
238
238
  "is-uploading": d(q).isUploading.value,
239
239
  "upload-progress": d(q).uploadProgress.value,
@@ -254,7 +254,7 @@ var F = {
254
254
  }, [b(d(re), {
255
255
  size: 14,
256
256
  "stroke-width": 2
257
- }), v(" " + s(S.value.mediaLibrary.importFromUrl), 1)])) : u("", !0)])) : u("", !0), b(D, {
257
+ }), v(" " + s(C.value.mediaLibrary.importFromUrl), 1)])) : u("", !0)])) : u("", !0), b(D, {
258
258
  items: d(J).displayItems.value,
259
259
  "selected-ids": d(q).selectedItems.value,
260
260
  "is-loading": d(q).isLoading.value,
@@ -334,17 +334,17 @@ var F = {
334
334
  },
335
335
  onClick: r[11] ||= ee((...e) => d(q).cancelDelete && d(q).cancelDelete(...e), ["self"])
336
336
  }, [m("div", Me, [
337
- m("h3", Ne, s(S.value.mediaLibrary.deleteWarningTitle), 1),
337
+ m("h3", Ne, s(C.value.mediaLibrary.deleteWarningTitle), 1),
338
338
  m("p", {
339
339
  class: te(["tpl:text-xs", d(J).hasUsedFiles.value ? "tpl:mb-2" : "tpl:mb-4"]),
340
340
  style: { color: "var(--tpl-text-muted)" }
341
- }, s(S.value.mediaLibrary.deleteWarningMessage), 3),
342
- d(J).hasUsedFiles.value ? (n(), l("p", Pe, s(S.value.mediaLibrary.deleteWarningUsageNote), 1)) : u("", !0),
341
+ }, s(C.value.mediaLibrary.deleteWarningMessage), 3),
342
+ d(J).hasUsedFiles.value ? (n(), l("p", Pe, s(C.value.mediaLibrary.deleteWarningUsageNote), 1)) : u("", !0),
343
343
  d(J).hasUsedFiles.value ? (n(), l("div", Fe, [(n(!0), l(_, null, i(d(q).deleteUsageInfo.value, (e, t) => (n(), l("div", {
344
344
  key: t,
345
345
  class: "tpl:text-xs",
346
346
  style: { color: "var(--tpl-text)" }
347
- }, [e.template_count > 0 ? (n(), l(_, { key: 0 }, [m("span", Ie, s(d(J).displayItems.value.find((e) => e.id === t)?.filename || t), 1), m("span", Le, " - " + s(S.value.mediaLibrary.usedInTemplates.replace("{count}", e.template_count.toString())), 1)], 64)) : u("", !0)]))), 128))])) : u("", !0),
347
+ }, [e.template_count > 0 ? (n(), l(_, { key: 0 }, [m("span", Ie, s(d(J).displayItems.value.find((e) => e.id === t)?.filename || t), 1), m("span", Le, " - " + s(C.value.mediaLibrary.usedInTemplates.replace("{count}", e.template_count.toString())), 1)], 64)) : u("", !0)]))), 128))])) : u("", !0),
348
348
  m("div", Re, [m("button", {
349
349
  class: "tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150",
350
350
  style: {
@@ -353,7 +353,7 @@ var F = {
353
353
  "background-color": "var(--tpl-bg)"
354
354
  },
355
355
  onClick: r[9] ||= (...e) => d(q).cancelDelete && d(q).cancelDelete(...e)
356
- }, s(S.value.mediaLibrary.cancel), 1), m("button", {
356
+ }, s(C.value.mediaLibrary.cancel), 1), m("button", {
357
357
  class: "tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150",
358
358
  style: {
359
359
  "border-color": "var(--tpl-danger)",
@@ -361,7 +361,7 @@ var F = {
361
361
  "background-color": "var(--tpl-danger-light)"
362
362
  },
363
363
  onClick: r[10] ||= (...e) => d(q).confirmDelete && d(q).confirmDelete(...e)
364
- }, s(d(J).hasUsedFiles.value ? S.value.mediaLibrary.deleteAnyway : S.value.mediaLibrary.confirmDelete), 1)])
364
+ }, s(d(J).hasUsedFiles.value ? C.value.mediaLibrary.deleteAnyway : C.value.mediaLibrary.confirmDelete), 1)])
365
365
  ])])) : u("", !0)]),
366
366
  _: 1
367
367
  }),
@@ -388,11 +388,11 @@ var F = {
388
388
  key: 1,
389
389
  size: 12,
390
390
  "stroke-width": 2
391
- })) : (n(), f(d(C), {
391
+ })) : (n(), f(d(S), {
392
392
  key: 0,
393
393
  size: 12,
394
394
  "stroke-width": 2
395
- })), v(" " + s(d(J).copied.value ? S.value.mediaLibrary.copied : S.value.mediaLibrary.copyUrl), 1)], 4)) : u("", !0), w.value ? (n(), l("div", Ue, [m("button", {
395
+ })), v(" " + s(d(J).copied.value ? C.value.mediaLibrary.copied : C.value.mediaLibrary.copyUrl), 1)], 4)) : u("", !0), w.value ? (n(), l("div", Ue, [m("button", {
396
396
  class: "tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150",
397
397
  style: {
398
398
  "border-color": "var(--tpl-border)",
@@ -400,7 +400,7 @@ var F = {
400
400
  "background-color": "var(--tpl-bg)"
401
401
  },
402
402
  onClick: r[14] ||= (e) => d(J).showMovePicker.value = !d(J).showMovePicker.value
403
- }, s(S.value.mediaLibrary.moveSelected), 1), d(J).showMovePicker.value ? (n(), f(M, {
403
+ }, s(C.value.mediaLibrary.moveSelected), 1), d(J).showMovePicker.value ? (n(), f(M, {
404
404
  key: 0,
405
405
  folders: d(q).folders.value,
406
406
  "current-folder-id": d(q).currentFolderId.value,
@@ -419,7 +419,7 @@ var F = {
419
419
  "background-color": "var(--tpl-danger-light)"
420
420
  },
421
421
  onClick: r[16] ||= (...e) => d(J).handleDeleteClick && d(J).handleDeleteClick(...e)
422
- }, s(S.value.mediaLibrary.deleteSelected), 1)) : u("", !0), t.onSelect ? (n(), l("button", {
422
+ }, s(C.value.mediaLibrary.deleteSelected), 1)) : u("", !0), t.onSelect ? (n(), l("button", {
423
423
  key: 1,
424
424
  class: "tpl:cursor-pointer tpl:rounded-md tpl:px-4 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50",
425
425
  style: {
@@ -428,7 +428,7 @@ var F = {
428
428
  },
429
429
  disabled: !d(q).previewItem.value,
430
430
  onClick: Y
431
- }, s(S.value.mediaLibrary.selectFile), 9, Ge)) : u("", !0)])])])
431
+ }, s(C.value.mediaLibrary.selectFile), 9, Ge)) : u("", !0)])])])
432
432
  ]));
433
433
  }
434
434
  }), G = /* #__PURE__ */ Object.assign({
@@ -465,9 +465,9 @@ var X = null, Z = o(null);
465
465
  async function Ye(e) {
466
466
  let n = typeof e.container == "string" ? document.querySelector(e.container) : e.container;
467
467
  if (!n) throw Error(`Container element not found: ${e.container}`);
468
- let r = S(e.auth, e.onError);
468
+ let r = x(e.auth, e.onError);
469
469
  await r.initialize();
470
- let i = await new x(r).fetchConfig(), a = await Je(e.locale ?? "en");
470
+ let i = await new C(r).fetchConfig(), a = await Je(e.locale ?? "en");
471
471
  return $(n, e.theme), X && Q(), new Promise((o, s) => {
472
472
  try {
473
473
  X = h({ setup() {
@@ -506,4 +506,4 @@ typeof window < "u" && (window.TemplaticalMedia = {
506
506
  //#endregion
507
507
  export { w as MediaApiClient, N as MediaLibraryModal };
508
508
 
509
- //# sourceMappingURL=src-zu1ehVNN.js.map
509
+ //# sourceMappingURL=src-BDJeYiVE.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"src-zu1ehVNN.js","names":[],"sources":["../../../../media-library/src/standalone/MediaLibrary.vue","../../../../media-library/src/standalone/MediaLibrary.vue","../../../../media-library/src/i18n/index.ts","../../../../media-library/src/standalone/visual.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport MediaBreadcrumb from \"../components/media/MediaBreadcrumb.vue\";\nimport MediaEditModal from \"../components/media/MediaEditModal.vue\";\nimport MediaFolderTree from \"../components/media/MediaFolderTree.vue\";\nimport MediaGrid from \"../components/media/MediaGrid.vue\";\nimport MediaImportUrlModal from \"../components/media/MediaImportUrlModal.vue\";\nimport MediaMovePicker from \"../components/media/MediaMovePicker.vue\";\nimport MediaPreviewPanel from \"../components/media/MediaPreviewPanel.vue\";\nimport MediaReplaceModal from \"../components/media/MediaReplaceModal.vue\";\nimport MediaUploadZone from \"../components/media/MediaUploadZone.vue\";\nimport StorageProgressRing from \"../components/media/StorageProgressRing.vue\";\nimport { useMediaLibrary } from \"../composable\";\nimport { useMediaCategories } from \"../composables/useMediaCategories\";\nimport { useMediaLibraryUI } from \"../composables/useMediaLibraryUI\";\nimport type { PlanConfig, PlanFeatures } from \"@templatical/types\";\nimport type { MediaItem } from \"../types\";\nimport type { AuthManager } from \"@templatical/core/cloud\";\nimport type { MediaTranslations } from \"../i18n\";\nimport {\n Check,\n Copy,\n Grid2x2,\n Link,\n List,\n PanelLeft,\n Search,\n} from \"@lucide/vue\";\nimport { computed, onMounted, provide, ref } from \"vue\";\n\nconst props = defineProps<{\n authManager: AuthManager;\n projectId: string;\n planConfig: PlanConfig;\n translations: MediaTranslations;\n onSelect?: (item: MediaItem) => void;\n onError?: (error: Error) => void;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\"): void;\n}>();\n\nconst t = computed(() => props.translations);\n\n// Provide translations for sub-components that use inject('translations')\nprovide(\"translations\", props.translations);\nprovide(\"authManager\", props.authManager);\nprovide(\n \"projectId\",\n computed(() => props.projectId),\n);\n\n// Provide planConfig in the format that sub-components expect\nconst planConfigRef = ref<PlanConfig | null>(props.planConfig);\nprovide(\"planConfig\", {\n config: planConfigRef,\n isLoading: ref(false),\n hasFeature: (feature: keyof PlanFeatures) =>\n props.planConfig.features[feature] ?? false,\n features: computed(() => props.planConfig.features),\n fetchConfig: async () => {},\n});\n\n// Feature flags\nconst canUseMediaFolders = computed(\n () => props.planConfig.features.media_folders ?? false,\n);\nconst canImportFromUrl = computed(\n () => props.planConfig.features.import_from_url ?? false,\n);\n\n// Storage info\nconst storageUsedBytes = computed(\n () => props.planConfig.storage.used_bytes ?? 0,\n);\nconst storageLimitBytes = computed(\n () => props.planConfig.storage.limit_bytes ?? 0,\n);\n\nconst { availableCategories } = useMediaCategories();\n\nconst library = useMediaLibrary({\n projectId: props.projectId,\n authManager: props.authManager,\n onError: props.onError,\n});\n\nconst ui = useMediaLibraryUI({\n library,\n canUseMediaFolders,\n translations: t,\n});\n\n// Standalone-specific: confirm selection via callback\nfunction confirmSelection(): void {\n if (!library.previewItem.value) {\n return;\n }\n\n const item = library.previewItem.value;\n const itemWithSelectedUrl: MediaItem = {\n ...item,\n url: ui.selectedUrl.value || item.url,\n };\n props.onSelect?.(itemWithSelectedUrl);\n}\n\nonMounted(() => {\n library.loadItems();\n library.loadFrequentlyUsed();\n emit(\"ready\");\n});\n</script>\n\n<template>\n <div\n class=\"tpl tpl:flex tpl:flex-col tpl:overflow-hidden tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n width: 100%;\n height: 100%;\n background-color: var(--tpl-bg-elevated);\n border: 1px solid var(--tpl-border);\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-3.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <h2 class=\"tpl:text-sm tpl:font-semibold\" style=\"color: var(--tpl-text)\">\n {{ t.mediaLibrary.title }}\n </h2>\n <div class=\"tpl:flex tpl:items-center tpl:gap-3\">\n <StorageProgressRing\n :used-bytes=\"storageUsedBytes\"\n :limit-bytes=\"storageLimitBytes\"\n :size=\"22\"\n />\n <div class=\"tpl:relative\">\n <input\n :value=\"ui.searchInput.value\"\n type=\"text\"\n class=\"tpl:w-52 tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-3 tpl:pl-8 tpl:text-xs tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:outline-none tpl:focus:shadow-[var(--tpl-ring)]\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :placeholder=\"t.mediaLibrary.searchPlaceholder\"\n @input=\"\n ui.handleSearchInput(($event.target as HTMLInputElement).value)\n \"\n />\n <Search\n class=\"tpl:absolute tpl:top-1/2 tpl:left-2.5 tpl:-translate-y-1/2\"\n :size=\"13\"\n :stroke-width=\"2\"\n style=\"color: var(--tpl-text-dim)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Sidebar (only when media folders feature is enabled and toggled on) -->\n <Transition\n enter-active-class=\"tpl:transition-all tpl:duration-200 tpl:ease-out\"\n enter-from-class=\"tpl:-ml-48 tpl:opacity-0\"\n enter-to-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-active-class=\"tpl:transition-all tpl:duration-150 tpl:ease-in\"\n leave-from-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-to-class=\"tpl:-ml-48 tpl:opacity-0\"\n >\n <div\n v-if=\"canUseMediaFolders && ui.showSidebar.value\"\n class=\"tpl:flex tpl:w-48 tpl:shrink-0 tpl:flex-col tpl:border-r\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <MediaFolderTree\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n :view-mode=\"library.viewMode.value\"\n :has-frequently-used=\"ui.hasFrequentlyUsed.value\"\n @navigate=\"library.navigateToFolder\"\n @create-folder=\"ui.handleCreateFolder\"\n @rename-folder=\"ui.handleRenameFolder\"\n @delete-folder=\"ui.handleDeleteFolder\"\n @show-frequently-used=\"library.showFrequentlyUsed\"\n />\n </div>\n </Transition>\n\n <!-- Content area -->\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:flex-col\">\n <!-- Breadcrumb + Upload -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-4 tpl:py-2.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <!-- Sidebar toggle (only when media folders feature is enabled) -->\n <button\n v-if=\"canUseMediaFolders\"\n class=\"tpl:flex tpl:size-7 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-md tpl:transition-all tpl:duration-150\"\n :style=\"{\n color: ui.showSidebar.value\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor: ui.showSidebar.value\n ? 'var(--tpl-bg)'\n : 'transparent',\n border: ui.showSidebar.value\n ? '1px solid var(--tpl-border)'\n : '1px solid transparent',\n }\"\n :title=\"\n ui.showSidebar.value\n ? t.mediaLibrary.hideFolders\n : t.mediaLibrary.showFolders\n \"\n @click=\"ui.showSidebar.value = !ui.showSidebar.value\"\n >\n <PanelLeft :size=\"16\" :stroke-width=\"2\" />\n </button>\n\n <template v-if=\"library.viewMode.value === 'frequently-used'\">\n <span\n class=\"tpl:text-xs tpl:font-medium\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.frequentlyUsed }}\n </span>\n </template>\n <template v-else>\n <MediaBreadcrumb\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @navigate=\"library.navigateToFolder\"\n />\n </template>\n\n <!-- Layout toggle -->\n <div\n class=\"tpl:flex tpl:rounded-md tpl:p-0.5\"\n style=\"\n border: 1px solid var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewGrid\"\n @click=\"ui.layoutMode.value = 'grid'\"\n >\n <Grid2x2 :size=\"14\" :stroke-width=\"2\" />\n </button>\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewList\"\n @click=\"ui.layoutMode.value = 'list'\"\n >\n <List :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <select\n v-if=\"availableCategories.length > 1\"\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.categoryFilter.value ?? ''\"\n @change=\"\n library.filterByCategory(\n ($event.target as HTMLSelectElement).value || null,\n )\n \"\n >\n <option value=\"\">\n {{ t.mediaLibrary.filterAll }}\n </option>\n <option\n v-for=\"category in availableCategories\"\n :key=\"category\"\n :value=\"category\"\n >\n {{ ui.getCategoryLabel(category) }}\n </option>\n </select>\n <select\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.sortOption.value\"\n @change=\"\n library.sortBy(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"newest\">\n {{ t.mediaLibrary.sortNewest }}\n </option>\n <option value=\"oldest\">\n {{ t.mediaLibrary.sortOldest }}\n </option>\n <option value=\"name_asc\">\n {{ t.mediaLibrary.sortNameAsc }}\n </option>\n <option value=\"name_desc\">\n {{ t.mediaLibrary.sortNameDesc }}\n </option>\n <option value=\"size_asc\">\n {{ t.mediaLibrary.sortSizeAsc }}\n </option>\n <option value=\"size_desc\">\n {{ t.mediaLibrary.sortSizeDesc }}\n </option>\n </select>\n </div>\n </div>\n\n <!-- Scrollable content area -->\n <div class=\"tpl:min-h-0 tpl:flex-1 tpl:overflow-y-auto\">\n <!-- Upload zone (only in files mode) -->\n <div\n v-if=\"library.viewMode.value === 'files'\"\n class=\"tpl:px-4 tpl:pt-3\"\n >\n <MediaUploadZone\n :is-uploading=\"library.isUploading.value\"\n :upload-progress=\"library.uploadProgress.value\"\n @upload=\"ui.handleUpload\"\n />\n <button\n v-if=\"canImportFromUrl\"\n class=\"tpl:mt-2 tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:border-dashed tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text-muted);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showImportUrlModal.value = true\"\n >\n <Link :size=\"14\" :stroke-width=\"2\" />\n {{ t.mediaLibrary.importFromUrl }}\n </button>\n </div>\n\n <!-- Image grid -->\n <MediaGrid\n :items=\"ui.displayItems.value\"\n :selected-ids=\"library.selectedItems.value\"\n :is-loading=\"library.isLoading.value\"\n :has-more=\"\n library.viewMode.value === 'files' && library.hasMore.value\n \"\n :layout=\"ui.layoutMode.value\"\n @select=\"ui.handleSelect\"\n @toggle=\"library.toggleSelection\"\n @load-more=\"library.loadMore\"\n @edit=\"ui.handleEditItem\"\n @replace=\"ui.handleReplaceItem\"\n />\n </div>\n </div>\n </div>\n\n <!-- Import from URL Modal -->\n <MediaImportUrlModal\n :visible=\"ui.showImportUrlModal.value\"\n :is-importing=\"library.isImportingFromUrl.value\"\n :error=\"library.importFromUrlError.value\"\n @import=\"ui.handleImportFromUrl\"\n @close=\"ui.showImportUrlModal.value = false\"\n />\n\n <!-- Edit Modal -->\n <MediaEditModal\n :visible=\"!!ui.editingItem.value\"\n :item=\"ui.editingItem.value\"\n @save=\"ui.handleEditSave\"\n @close=\"ui.editingItem.value = null\"\n />\n\n <!-- Replace Modal -->\n <MediaReplaceModal\n :visible=\"library.showReplaceWarning.value\"\n :item=\"library.pendingReplaceItem.value\"\n :usage-info=\"library.replaceUsageInfo.value\"\n :is-replacing=\"library.isReplacing.value\"\n :error=\"library.replaceError.value\"\n @replace=\"ui.handleReplaceFile\"\n @close=\"library.cancelReplace\"\n />\n\n <!-- Delete Warning Dialog -->\n <Transition\n enter-active-class=\"tpl:transition tpl:ease-out tpl:duration-150\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:ease-in tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <div\n v-if=\"library.showDeleteWarning.value\"\n class=\"tpl:absolute tpl:inset-0 tpl:z-10 tpl:flex tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n @click.self=\"library.cancelDelete\"\n >\n <div\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n class=\"tpl:mb-2 tpl:text-sm tpl:font-semibold\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.deleteWarningTitle }}\n </h3>\n <p\n class=\"tpl:text-xs\"\n :class=\"ui.hasUsedFiles.value ? 'tpl:mb-2' : 'tpl:mb-4'\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningMessage }}\n </p>\n <p\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:text-xs\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningUsageNote }}\n </p>\n\n <div\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:max-h-32 tpl:overflow-y-auto tpl:rounded tpl:border tpl:p-2\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div\n v-for=\"(info, mediaId) in library.deleteUsageInfo.value\"\n :key=\"mediaId\"\n class=\"tpl:text-xs\"\n style=\"color: var(--tpl-text)\"\n >\n <template v-if=\"info.template_count > 0\">\n <span class=\"tpl:font-medium\">\n {{\n ui.displayItems.value.find((i) => i.id === mediaId)\n ?.filename || mediaId\n }}\n </span>\n <span style=\"color: var(--tpl-text-muted)\">\n -\n {{\n t.mediaLibrary.usedInTemplates.replace(\n \"{count}\",\n info.template_count.toString(),\n )\n }}\n </span>\n </template>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"library.cancelDelete\"\n >\n {{ t.mediaLibrary.cancel }}\n </button>\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"library.confirmDelete\"\n >\n {{\n ui.hasUsedFiles.value\n ? t.mediaLibrary.deleteAnyway\n : t.mediaLibrary.confirmDelete\n }}\n </button>\n </div>\n </div>\n </div>\n </Transition>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:items-center tpl:gap-3\">\n <MediaPreviewPanel\n v-if=\"library.previewItem.value\"\n v-model:selected-conversion=\"ui.selectedConversion.value\"\n :item=\"library.previewItem.value\"\n :folders=\"library.folders.value\"\n />\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-5\">\n <!-- Copy URL + Move group -->\n <div\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:flex tpl:items-center tpl:gap-2\"\n >\n <button\n v-if=\"library.previewItem.value\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-1 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n :style=\"{\n borderColor: ui.copied.value\n ? 'var(--tpl-success)'\n : 'var(--tpl-border)',\n color: ui.copied.value ? 'var(--tpl-success)' : 'var(--tpl-text)',\n backgroundColor: 'var(--tpl-bg)',\n }\"\n @click=\"ui.copy(ui.selectedUrl.value!)\"\n >\n <Copy v-if=\"!ui.copied.value\" :size=\"12\" :stroke-width=\"2\" />\n <Check v-else :size=\"12\" :stroke-width=\"2\" />\n {{\n ui.copied.value ? t.mediaLibrary.copied : t.mediaLibrary.copyUrl\n }}\n </button>\n <div v-if=\"canUseMediaFolders\" class=\"tpl:relative\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showMovePicker.value = !ui.showMovePicker.value\"\n >\n {{ t.mediaLibrary.moveSelected }}\n </button>\n <MediaMovePicker\n v-if=\"ui.showMovePicker.value\"\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @select=\"ui.handleMoveToFolder\"\n @close=\"ui.showMovePicker.value = false\"\n />\n </div>\n </div>\n <!-- Delete + Select group -->\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"ui.handleDeleteClick\"\n >\n {{ t.mediaLibrary.deleteSelected }}\n </button>\n <button\n v-if=\"onSelect\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-4 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50\"\n style=\"background-color: var(--tpl-primary); color: var(--tpl-bg)\"\n :disabled=\"!library.previewItem.value\"\n @click=\"confirmSelection\"\n >\n {{ t.mediaLibrary.selectFile }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport MediaBreadcrumb from \"../components/media/MediaBreadcrumb.vue\";\nimport MediaEditModal from \"../components/media/MediaEditModal.vue\";\nimport MediaFolderTree from \"../components/media/MediaFolderTree.vue\";\nimport MediaGrid from \"../components/media/MediaGrid.vue\";\nimport MediaImportUrlModal from \"../components/media/MediaImportUrlModal.vue\";\nimport MediaMovePicker from \"../components/media/MediaMovePicker.vue\";\nimport MediaPreviewPanel from \"../components/media/MediaPreviewPanel.vue\";\nimport MediaReplaceModal from \"../components/media/MediaReplaceModal.vue\";\nimport MediaUploadZone from \"../components/media/MediaUploadZone.vue\";\nimport StorageProgressRing from \"../components/media/StorageProgressRing.vue\";\nimport { useMediaLibrary } from \"../composable\";\nimport { useMediaCategories } from \"../composables/useMediaCategories\";\nimport { useMediaLibraryUI } from \"../composables/useMediaLibraryUI\";\nimport type { PlanConfig, PlanFeatures } from \"@templatical/types\";\nimport type { MediaItem } from \"../types\";\nimport type { AuthManager } from \"@templatical/core/cloud\";\nimport type { MediaTranslations } from \"../i18n\";\nimport {\n Check,\n Copy,\n Grid2x2,\n Link,\n List,\n PanelLeft,\n Search,\n} from \"@lucide/vue\";\nimport { computed, onMounted, provide, ref } from \"vue\";\n\nconst props = defineProps<{\n authManager: AuthManager;\n projectId: string;\n planConfig: PlanConfig;\n translations: MediaTranslations;\n onSelect?: (item: MediaItem) => void;\n onError?: (error: Error) => void;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\"): void;\n}>();\n\nconst t = computed(() => props.translations);\n\n// Provide translations for sub-components that use inject('translations')\nprovide(\"translations\", props.translations);\nprovide(\"authManager\", props.authManager);\nprovide(\n \"projectId\",\n computed(() => props.projectId),\n);\n\n// Provide planConfig in the format that sub-components expect\nconst planConfigRef = ref<PlanConfig | null>(props.planConfig);\nprovide(\"planConfig\", {\n config: planConfigRef,\n isLoading: ref(false),\n hasFeature: (feature: keyof PlanFeatures) =>\n props.planConfig.features[feature] ?? false,\n features: computed(() => props.planConfig.features),\n fetchConfig: async () => {},\n});\n\n// Feature flags\nconst canUseMediaFolders = computed(\n () => props.planConfig.features.media_folders ?? false,\n);\nconst canImportFromUrl = computed(\n () => props.planConfig.features.import_from_url ?? false,\n);\n\n// Storage info\nconst storageUsedBytes = computed(\n () => props.planConfig.storage.used_bytes ?? 0,\n);\nconst storageLimitBytes = computed(\n () => props.planConfig.storage.limit_bytes ?? 0,\n);\n\nconst { availableCategories } = useMediaCategories();\n\nconst library = useMediaLibrary({\n projectId: props.projectId,\n authManager: props.authManager,\n onError: props.onError,\n});\n\nconst ui = useMediaLibraryUI({\n library,\n canUseMediaFolders,\n translations: t,\n});\n\n// Standalone-specific: confirm selection via callback\nfunction confirmSelection(): void {\n if (!library.previewItem.value) {\n return;\n }\n\n const item = library.previewItem.value;\n const itemWithSelectedUrl: MediaItem = {\n ...item,\n url: ui.selectedUrl.value || item.url,\n };\n props.onSelect?.(itemWithSelectedUrl);\n}\n\nonMounted(() => {\n library.loadItems();\n library.loadFrequentlyUsed();\n emit(\"ready\");\n});\n</script>\n\n<template>\n <div\n class=\"tpl tpl:flex tpl:flex-col tpl:overflow-hidden tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n width: 100%;\n height: 100%;\n background-color: var(--tpl-bg-elevated);\n border: 1px solid var(--tpl-border);\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-3.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <h2 class=\"tpl:text-sm tpl:font-semibold\" style=\"color: var(--tpl-text)\">\n {{ t.mediaLibrary.title }}\n </h2>\n <div class=\"tpl:flex tpl:items-center tpl:gap-3\">\n <StorageProgressRing\n :used-bytes=\"storageUsedBytes\"\n :limit-bytes=\"storageLimitBytes\"\n :size=\"22\"\n />\n <div class=\"tpl:relative\">\n <input\n :value=\"ui.searchInput.value\"\n type=\"text\"\n class=\"tpl:w-52 tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-3 tpl:pl-8 tpl:text-xs tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:outline-none tpl:focus:shadow-[var(--tpl-ring)]\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :placeholder=\"t.mediaLibrary.searchPlaceholder\"\n @input=\"\n ui.handleSearchInput(($event.target as HTMLInputElement).value)\n \"\n />\n <Search\n class=\"tpl:absolute tpl:top-1/2 tpl:left-2.5 tpl:-translate-y-1/2\"\n :size=\"13\"\n :stroke-width=\"2\"\n style=\"color: var(--tpl-text-dim)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Sidebar (only when media folders feature is enabled and toggled on) -->\n <Transition\n enter-active-class=\"tpl:transition-all tpl:duration-200 tpl:ease-out\"\n enter-from-class=\"tpl:-ml-48 tpl:opacity-0\"\n enter-to-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-active-class=\"tpl:transition-all tpl:duration-150 tpl:ease-in\"\n leave-from-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-to-class=\"tpl:-ml-48 tpl:opacity-0\"\n >\n <div\n v-if=\"canUseMediaFolders && ui.showSidebar.value\"\n class=\"tpl:flex tpl:w-48 tpl:shrink-0 tpl:flex-col tpl:border-r\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <MediaFolderTree\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n :view-mode=\"library.viewMode.value\"\n :has-frequently-used=\"ui.hasFrequentlyUsed.value\"\n @navigate=\"library.navigateToFolder\"\n @create-folder=\"ui.handleCreateFolder\"\n @rename-folder=\"ui.handleRenameFolder\"\n @delete-folder=\"ui.handleDeleteFolder\"\n @show-frequently-used=\"library.showFrequentlyUsed\"\n />\n </div>\n </Transition>\n\n <!-- Content area -->\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:flex-col\">\n <!-- Breadcrumb + Upload -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-4 tpl:py-2.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <!-- Sidebar toggle (only when media folders feature is enabled) -->\n <button\n v-if=\"canUseMediaFolders\"\n class=\"tpl:flex tpl:size-7 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-md tpl:transition-all tpl:duration-150\"\n :style=\"{\n color: ui.showSidebar.value\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor: ui.showSidebar.value\n ? 'var(--tpl-bg)'\n : 'transparent',\n border: ui.showSidebar.value\n ? '1px solid var(--tpl-border)'\n : '1px solid transparent',\n }\"\n :title=\"\n ui.showSidebar.value\n ? t.mediaLibrary.hideFolders\n : t.mediaLibrary.showFolders\n \"\n @click=\"ui.showSidebar.value = !ui.showSidebar.value\"\n >\n <PanelLeft :size=\"16\" :stroke-width=\"2\" />\n </button>\n\n <template v-if=\"library.viewMode.value === 'frequently-used'\">\n <span\n class=\"tpl:text-xs tpl:font-medium\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.frequentlyUsed }}\n </span>\n </template>\n <template v-else>\n <MediaBreadcrumb\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @navigate=\"library.navigateToFolder\"\n />\n </template>\n\n <!-- Layout toggle -->\n <div\n class=\"tpl:flex tpl:rounded-md tpl:p-0.5\"\n style=\"\n border: 1px solid var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewGrid\"\n @click=\"ui.layoutMode.value = 'grid'\"\n >\n <Grid2x2 :size=\"14\" :stroke-width=\"2\" />\n </button>\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewList\"\n @click=\"ui.layoutMode.value = 'list'\"\n >\n <List :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <select\n v-if=\"availableCategories.length > 1\"\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.categoryFilter.value ?? ''\"\n @change=\"\n library.filterByCategory(\n ($event.target as HTMLSelectElement).value || null,\n )\n \"\n >\n <option value=\"\">\n {{ t.mediaLibrary.filterAll }}\n </option>\n <option\n v-for=\"category in availableCategories\"\n :key=\"category\"\n :value=\"category\"\n >\n {{ ui.getCategoryLabel(category) }}\n </option>\n </select>\n <select\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.sortOption.value\"\n @change=\"\n library.sortBy(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"newest\">\n {{ t.mediaLibrary.sortNewest }}\n </option>\n <option value=\"oldest\">\n {{ t.mediaLibrary.sortOldest }}\n </option>\n <option value=\"name_asc\">\n {{ t.mediaLibrary.sortNameAsc }}\n </option>\n <option value=\"name_desc\">\n {{ t.mediaLibrary.sortNameDesc }}\n </option>\n <option value=\"size_asc\">\n {{ t.mediaLibrary.sortSizeAsc }}\n </option>\n <option value=\"size_desc\">\n {{ t.mediaLibrary.sortSizeDesc }}\n </option>\n </select>\n </div>\n </div>\n\n <!-- Scrollable content area -->\n <div class=\"tpl:min-h-0 tpl:flex-1 tpl:overflow-y-auto\">\n <!-- Upload zone (only in files mode) -->\n <div\n v-if=\"library.viewMode.value === 'files'\"\n class=\"tpl:px-4 tpl:pt-3\"\n >\n <MediaUploadZone\n :is-uploading=\"library.isUploading.value\"\n :upload-progress=\"library.uploadProgress.value\"\n @upload=\"ui.handleUpload\"\n />\n <button\n v-if=\"canImportFromUrl\"\n class=\"tpl:mt-2 tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:border-dashed tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text-muted);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showImportUrlModal.value = true\"\n >\n <Link :size=\"14\" :stroke-width=\"2\" />\n {{ t.mediaLibrary.importFromUrl }}\n </button>\n </div>\n\n <!-- Image grid -->\n <MediaGrid\n :items=\"ui.displayItems.value\"\n :selected-ids=\"library.selectedItems.value\"\n :is-loading=\"library.isLoading.value\"\n :has-more=\"\n library.viewMode.value === 'files' && library.hasMore.value\n \"\n :layout=\"ui.layoutMode.value\"\n @select=\"ui.handleSelect\"\n @toggle=\"library.toggleSelection\"\n @load-more=\"library.loadMore\"\n @edit=\"ui.handleEditItem\"\n @replace=\"ui.handleReplaceItem\"\n />\n </div>\n </div>\n </div>\n\n <!-- Import from URL Modal -->\n <MediaImportUrlModal\n :visible=\"ui.showImportUrlModal.value\"\n :is-importing=\"library.isImportingFromUrl.value\"\n :error=\"library.importFromUrlError.value\"\n @import=\"ui.handleImportFromUrl\"\n @close=\"ui.showImportUrlModal.value = false\"\n />\n\n <!-- Edit Modal -->\n <MediaEditModal\n :visible=\"!!ui.editingItem.value\"\n :item=\"ui.editingItem.value\"\n @save=\"ui.handleEditSave\"\n @close=\"ui.editingItem.value = null\"\n />\n\n <!-- Replace Modal -->\n <MediaReplaceModal\n :visible=\"library.showReplaceWarning.value\"\n :item=\"library.pendingReplaceItem.value\"\n :usage-info=\"library.replaceUsageInfo.value\"\n :is-replacing=\"library.isReplacing.value\"\n :error=\"library.replaceError.value\"\n @replace=\"ui.handleReplaceFile\"\n @close=\"library.cancelReplace\"\n />\n\n <!-- Delete Warning Dialog -->\n <Transition\n enter-active-class=\"tpl:transition tpl:ease-out tpl:duration-150\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:ease-in tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <div\n v-if=\"library.showDeleteWarning.value\"\n class=\"tpl:absolute tpl:inset-0 tpl:z-10 tpl:flex tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n @click.self=\"library.cancelDelete\"\n >\n <div\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n class=\"tpl:mb-2 tpl:text-sm tpl:font-semibold\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.deleteWarningTitle }}\n </h3>\n <p\n class=\"tpl:text-xs\"\n :class=\"ui.hasUsedFiles.value ? 'tpl:mb-2' : 'tpl:mb-4'\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningMessage }}\n </p>\n <p\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:text-xs\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningUsageNote }}\n </p>\n\n <div\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:max-h-32 tpl:overflow-y-auto tpl:rounded tpl:border tpl:p-2\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div\n v-for=\"(info, mediaId) in library.deleteUsageInfo.value\"\n :key=\"mediaId\"\n class=\"tpl:text-xs\"\n style=\"color: var(--tpl-text)\"\n >\n <template v-if=\"info.template_count > 0\">\n <span class=\"tpl:font-medium\">\n {{\n ui.displayItems.value.find((i) => i.id === mediaId)\n ?.filename || mediaId\n }}\n </span>\n <span style=\"color: var(--tpl-text-muted)\">\n -\n {{\n t.mediaLibrary.usedInTemplates.replace(\n \"{count}\",\n info.template_count.toString(),\n )\n }}\n </span>\n </template>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"library.cancelDelete\"\n >\n {{ t.mediaLibrary.cancel }}\n </button>\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"library.confirmDelete\"\n >\n {{\n ui.hasUsedFiles.value\n ? t.mediaLibrary.deleteAnyway\n : t.mediaLibrary.confirmDelete\n }}\n </button>\n </div>\n </div>\n </div>\n </Transition>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:items-center tpl:gap-3\">\n <MediaPreviewPanel\n v-if=\"library.previewItem.value\"\n v-model:selected-conversion=\"ui.selectedConversion.value\"\n :item=\"library.previewItem.value\"\n :folders=\"library.folders.value\"\n />\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-5\">\n <!-- Copy URL + Move group -->\n <div\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:flex tpl:items-center tpl:gap-2\"\n >\n <button\n v-if=\"library.previewItem.value\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-1 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n :style=\"{\n borderColor: ui.copied.value\n ? 'var(--tpl-success)'\n : 'var(--tpl-border)',\n color: ui.copied.value ? 'var(--tpl-success)' : 'var(--tpl-text)',\n backgroundColor: 'var(--tpl-bg)',\n }\"\n @click=\"ui.copy(ui.selectedUrl.value!)\"\n >\n <Copy v-if=\"!ui.copied.value\" :size=\"12\" :stroke-width=\"2\" />\n <Check v-else :size=\"12\" :stroke-width=\"2\" />\n {{\n ui.copied.value ? t.mediaLibrary.copied : t.mediaLibrary.copyUrl\n }}\n </button>\n <div v-if=\"canUseMediaFolders\" class=\"tpl:relative\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showMovePicker.value = !ui.showMovePicker.value\"\n >\n {{ t.mediaLibrary.moveSelected }}\n </button>\n <MediaMovePicker\n v-if=\"ui.showMovePicker.value\"\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @select=\"ui.handleMoveToFolder\"\n @close=\"ui.showMovePicker.value = false\"\n />\n </div>\n </div>\n <!-- Delete + Select group -->\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"ui.handleDeleteClick\"\n >\n {{ t.mediaLibrary.deleteSelected }}\n </button>\n <button\n v-if=\"onSelect\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-4 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50\"\n style=\"background-color: var(--tpl-primary); color: var(--tpl-bg)\"\n :disabled=\"!library.previewItem.value\"\n @click=\"confirmSelection\"\n >\n {{ t.mediaLibrary.selectFile }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n","/// <reference types=\"vite/client\" />\n\nimport type en from \"./locales/en\";\n\nexport type MediaTranslations = typeof en;\n\n// Vite resolves this glob at build time. Adding a new locale file\n// automatically registers it — no array to keep in sync.\nconst localeModules = import.meta.glob<{ default: MediaTranslations }>(\n \"./locales/*.ts\",\n);\n\nfunction localesFromGlob(modules: Record<string, unknown>): string[] {\n return Object.keys(modules)\n .map((path) => path.match(/\\/([^/]+)\\.ts$/)?.[1])\n .filter((locale): locale is string => Boolean(locale));\n}\n\nconst supportedLocales = localesFromGlob(localeModules);\n\nfunction canonicalize(locale: string): string {\n return locale.trim().replace(/_/g, \"-\").toLowerCase();\n}\n\nfunction findSupportedLocale(locale: string): string | undefined {\n const canonical = canonicalize(locale);\n return supportedLocales.find((s) => canonicalize(s) === canonical);\n}\n\nfunction getBaseLocale(locale: string): string {\n return canonicalize(locale).split(\"-\")[0];\n}\n\nfunction resolveLocale(locale: string): string {\n return (\n findSupportedLocale(locale) ??\n findSupportedLocale(getBaseLocale(locale)) ??\n \"en\"\n );\n}\n\nexport async function loadMediaTranslations(\n locale: string,\n): Promise<MediaTranslations> {\n const target = resolveLocale(locale);\n const loader = localeModules[`./locales/${target}.ts`];\n const module = await loader();\n return module.default;\n}\n","import { createSdkAuthManager } from \"@templatical/core/cloud\";\nimport type { PlanConfig } from \"@templatical/types\";\nimport { ApiClient } from \"@templatical/core/cloud\";\nimport MediaLibrary from \"./MediaLibrary.vue\";\nimport { loadMediaTranslations, type MediaTranslations } from \"../i18n\";\nimport type { MediaLibraryConfig, MediaLibraryInstance } from \"./types\";\nimport { createApp, h, ref, type App, type Ref } from \"vue\";\n\n// Import SDK styles\nimport \"../styles/index.css\";\n\n// Re-export types for consumers\nexport type { MediaFolder, MediaItem } from \"../types\";\nexport type { MediaLibraryConfig, MediaLibraryInstance } from \"./types\";\n\nlet appInstance: App | null = null;\nconst mediaLibraryRef: Ref<InstanceType<typeof MediaLibrary> | null> =\n ref(null);\n\nasync function init(config: MediaLibraryConfig): Promise<MediaLibraryInstance> {\n const container =\n typeof config.container === \"string\"\n ? document.querySelector(config.container)\n : config.container;\n\n if (!container) {\n throw new Error(`Container element not found: ${config.container}`);\n }\n\n // Initialize auth\n const authManager = createSdkAuthManager(config.auth, config.onError);\n await authManager.initialize();\n\n // Fetch plan config\n const apiClient = new ApiClient(authManager);\n const planConfig: PlanConfig = await apiClient.fetchConfig();\n\n // Load translations\n const translations: MediaTranslations = await loadMediaTranslations(\n config.locale ?? \"en\",\n );\n\n // Apply theme overrides to container\n applyTheme(container as HTMLElement, config.theme);\n\n // Unmount any prior app *after* awaits so concurrent init() calls don't\n // both pass an early check while appInstance is still null and orphan\n // the first-mounted app.\n if (appInstance) {\n unmount();\n }\n\n return new Promise((resolve, reject) => {\n try {\n appInstance = createApp({\n setup() {\n const onReady = () => {\n const instance: MediaLibraryInstance = {\n setTheme: (theme) => applyTheme(container as HTMLElement, theme),\n unmount,\n };\n\n resolve(instance);\n };\n\n return () =>\n h(MediaLibrary, {\n authManager,\n projectId: authManager.projectId,\n planConfig,\n translations,\n onSelect: config.onSelect,\n onError: config.onError,\n ref: mediaLibraryRef,\n onReady,\n });\n },\n });\n\n appInstance.mount(container);\n } catch (error) {\n reject(error);\n }\n });\n}\n\nfunction unmount(): void {\n if (appInstance) {\n appInstance.unmount();\n appInstance = null;\n mediaLibraryRef.value = null;\n }\n}\n\nfunction applyTheme(\n container: HTMLElement,\n theme?: { primaryColor?: string; borderRadius?: number },\n): void {\n if (!theme) {\n return;\n }\n\n if (theme.primaryColor) {\n container.style.setProperty(\"--tpl-primary\", theme.primaryColor);\n }\n\n if (theme.borderRadius !== undefined) {\n container.style.setProperty(\"--tpl-radius\", `${theme.borderRadius}px`);\n container.style.setProperty(\n \"--tpl-radius-sm\",\n `${Math.max(0, theme.borderRadius - 3)}px`,\n );\n container.style.setProperty(\n \"--tpl-radius-lg\",\n `${theme.borderRadius + 4}px`,\n );\n }\n}\n\nconst TemplaticalMedia = {\n init,\n unmount,\n};\n\n// Assign to window for IIFE usage\nif (typeof window !== \"undefined\") {\n (\n window as unknown as Window & { TemplaticalMedia: typeof TemplaticalMedia }\n ).TemplaticalMedia = TemplaticalMedia;\n}\n\n// Named exports for destructured imports\nexport { init, unmount };\n\n// Default export for library mode\nexport default TemplaticalMedia;\n"],"mappings":"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"}
1
+ {"version":3,"file":"src-BDJeYiVE.js","names":[],"sources":["../../../../media-library/src/standalone/MediaLibrary.vue","../../../../media-library/src/standalone/MediaLibrary.vue","../../../../media-library/src/i18n/index.ts","../../../../media-library/src/standalone/visual.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport MediaBreadcrumb from \"../components/media/MediaBreadcrumb.vue\";\nimport MediaEditModal from \"../components/media/MediaEditModal.vue\";\nimport MediaFolderTree from \"../components/media/MediaFolderTree.vue\";\nimport MediaGrid from \"../components/media/MediaGrid.vue\";\nimport MediaImportUrlModal from \"../components/media/MediaImportUrlModal.vue\";\nimport MediaMovePicker from \"../components/media/MediaMovePicker.vue\";\nimport MediaPreviewPanel from \"../components/media/MediaPreviewPanel.vue\";\nimport MediaReplaceModal from \"../components/media/MediaReplaceModal.vue\";\nimport MediaUploadZone from \"../components/media/MediaUploadZone.vue\";\nimport StorageProgressRing from \"../components/media/StorageProgressRing.vue\";\nimport { useMediaLibrary } from \"../composable\";\nimport { useMediaCategories } from \"../composables/useMediaCategories\";\nimport { useMediaLibraryUI } from \"../composables/useMediaLibraryUI\";\nimport type { PlanConfig, PlanFeatures } from \"@templatical/types\";\nimport type { MediaItem } from \"../types\";\nimport type { AuthManager } from \"@templatical/core/cloud\";\nimport type { MediaTranslations } from \"../i18n\";\nimport {\n Check,\n Copy,\n Grid2x2,\n Link,\n List,\n PanelLeft,\n Search,\n} from \"@lucide/vue\";\nimport { computed, onMounted, provide, ref } from \"vue\";\n\nconst props = defineProps<{\n authManager: AuthManager;\n projectId: string;\n planConfig: PlanConfig;\n translations: MediaTranslations;\n onSelect?: (item: MediaItem) => void;\n onError?: (error: Error) => void;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\"): void;\n}>();\n\nconst t = computed(() => props.translations);\n\n// Provide translations for sub-components that use inject('translations')\nprovide(\"translations\", props.translations);\nprovide(\"authManager\", props.authManager);\nprovide(\n \"projectId\",\n computed(() => props.projectId),\n);\n\n// Provide planConfig in the format that sub-components expect\nconst planConfigRef = ref<PlanConfig | null>(props.planConfig);\nprovide(\"planConfig\", {\n config: planConfigRef,\n isLoading: ref(false),\n hasFeature: (feature: keyof PlanFeatures) =>\n props.planConfig.features[feature] ?? false,\n features: computed(() => props.planConfig.features),\n fetchConfig: async () => {},\n});\n\n// Feature flags\nconst canUseMediaFolders = computed(\n () => props.planConfig.features.media_folders ?? false,\n);\nconst canImportFromUrl = computed(\n () => props.planConfig.features.import_from_url ?? false,\n);\n\n// Storage info\nconst storageUsedBytes = computed(\n () => props.planConfig.storage.used_bytes ?? 0,\n);\nconst storageLimitBytes = computed(\n () => props.planConfig.storage.limit_bytes ?? 0,\n);\n\nconst { availableCategories } = useMediaCategories();\n\nconst library = useMediaLibrary({\n projectId: props.projectId,\n authManager: props.authManager,\n onError: props.onError,\n});\n\nconst ui = useMediaLibraryUI({\n library,\n canUseMediaFolders,\n translations: t,\n});\n\n// Standalone-specific: confirm selection via callback\nfunction confirmSelection(): void {\n if (!library.previewItem.value) {\n return;\n }\n\n const item = library.previewItem.value;\n const itemWithSelectedUrl: MediaItem = {\n ...item,\n url: ui.selectedUrl.value || item.url,\n };\n props.onSelect?.(itemWithSelectedUrl);\n}\n\nonMounted(() => {\n library.loadItems();\n library.loadFrequentlyUsed();\n emit(\"ready\");\n});\n</script>\n\n<template>\n <div\n class=\"tpl tpl:flex tpl:flex-col tpl:overflow-hidden tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n width: 100%;\n height: 100%;\n background-color: var(--tpl-bg-elevated);\n border: 1px solid var(--tpl-border);\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-3.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <h2 class=\"tpl:text-sm tpl:font-semibold\" style=\"color: var(--tpl-text)\">\n {{ t.mediaLibrary.title }}\n </h2>\n <div class=\"tpl:flex tpl:items-center tpl:gap-3\">\n <StorageProgressRing\n :used-bytes=\"storageUsedBytes\"\n :limit-bytes=\"storageLimitBytes\"\n :size=\"22\"\n />\n <div class=\"tpl:relative\">\n <input\n :value=\"ui.searchInput.value\"\n type=\"text\"\n class=\"tpl:w-52 tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-3 tpl:pl-8 tpl:text-xs tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:outline-none tpl:focus:shadow-[var(--tpl-ring)]\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :placeholder=\"t.mediaLibrary.searchPlaceholder\"\n @input=\"\n ui.handleSearchInput(($event.target as HTMLInputElement).value)\n \"\n />\n <Search\n class=\"tpl:absolute tpl:top-1/2 tpl:left-2.5 tpl:-translate-y-1/2\"\n :size=\"13\"\n :stroke-width=\"2\"\n style=\"color: var(--tpl-text-dim)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Sidebar (only when media folders feature is enabled and toggled on) -->\n <Transition\n enter-active-class=\"tpl:transition-all tpl:duration-200 tpl:ease-out\"\n enter-from-class=\"tpl:-ml-48 tpl:opacity-0\"\n enter-to-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-active-class=\"tpl:transition-all tpl:duration-150 tpl:ease-in\"\n leave-from-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-to-class=\"tpl:-ml-48 tpl:opacity-0\"\n >\n <div\n v-if=\"canUseMediaFolders && ui.showSidebar.value\"\n class=\"tpl:flex tpl:w-48 tpl:shrink-0 tpl:flex-col tpl:border-r\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <MediaFolderTree\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n :view-mode=\"library.viewMode.value\"\n :has-frequently-used=\"ui.hasFrequentlyUsed.value\"\n @navigate=\"library.navigateToFolder\"\n @create-folder=\"ui.handleCreateFolder\"\n @rename-folder=\"ui.handleRenameFolder\"\n @delete-folder=\"ui.handleDeleteFolder\"\n @show-frequently-used=\"library.showFrequentlyUsed\"\n />\n </div>\n </Transition>\n\n <!-- Content area -->\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:flex-col\">\n <!-- Breadcrumb + Upload -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-4 tpl:py-2.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <!-- Sidebar toggle (only when media folders feature is enabled) -->\n <button\n v-if=\"canUseMediaFolders\"\n class=\"tpl:flex tpl:size-7 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-md tpl:transition-all tpl:duration-150\"\n :style=\"{\n color: ui.showSidebar.value\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor: ui.showSidebar.value\n ? 'var(--tpl-bg)'\n : 'transparent',\n border: ui.showSidebar.value\n ? '1px solid var(--tpl-border)'\n : '1px solid transparent',\n }\"\n :title=\"\n ui.showSidebar.value\n ? t.mediaLibrary.hideFolders\n : t.mediaLibrary.showFolders\n \"\n @click=\"ui.showSidebar.value = !ui.showSidebar.value\"\n >\n <PanelLeft :size=\"16\" :stroke-width=\"2\" />\n </button>\n\n <template v-if=\"library.viewMode.value === 'frequently-used'\">\n <span\n class=\"tpl:text-xs tpl:font-medium\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.frequentlyUsed }}\n </span>\n </template>\n <template v-else>\n <MediaBreadcrumb\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @navigate=\"library.navigateToFolder\"\n />\n </template>\n\n <!-- Layout toggle -->\n <div\n class=\"tpl:flex tpl:rounded-md tpl:p-0.5\"\n style=\"\n border: 1px solid var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewGrid\"\n @click=\"ui.layoutMode.value = 'grid'\"\n >\n <Grid2x2 :size=\"14\" :stroke-width=\"2\" />\n </button>\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewList\"\n @click=\"ui.layoutMode.value = 'list'\"\n >\n <List :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <select\n v-if=\"availableCategories.length > 1\"\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.categoryFilter.value ?? ''\"\n @change=\"\n library.filterByCategory(\n ($event.target as HTMLSelectElement).value || null,\n )\n \"\n >\n <option value=\"\">\n {{ t.mediaLibrary.filterAll }}\n </option>\n <option\n v-for=\"category in availableCategories\"\n :key=\"category\"\n :value=\"category\"\n >\n {{ ui.getCategoryLabel(category) }}\n </option>\n </select>\n <select\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.sortOption.value\"\n @change=\"\n library.sortBy(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"newest\">\n {{ t.mediaLibrary.sortNewest }}\n </option>\n <option value=\"oldest\">\n {{ t.mediaLibrary.sortOldest }}\n </option>\n <option value=\"name_asc\">\n {{ t.mediaLibrary.sortNameAsc }}\n </option>\n <option value=\"name_desc\">\n {{ t.mediaLibrary.sortNameDesc }}\n </option>\n <option value=\"size_asc\">\n {{ t.mediaLibrary.sortSizeAsc }}\n </option>\n <option value=\"size_desc\">\n {{ t.mediaLibrary.sortSizeDesc }}\n </option>\n </select>\n </div>\n </div>\n\n <!-- Scrollable content area -->\n <div class=\"tpl:min-h-0 tpl:flex-1 tpl:overflow-y-auto\">\n <!-- Upload zone (only in files mode) -->\n <div\n v-if=\"library.viewMode.value === 'files'\"\n class=\"tpl:px-4 tpl:pt-3\"\n >\n <MediaUploadZone\n :is-uploading=\"library.isUploading.value\"\n :upload-progress=\"library.uploadProgress.value\"\n @upload=\"ui.handleUpload\"\n />\n <button\n v-if=\"canImportFromUrl\"\n class=\"tpl:mt-2 tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:border-dashed tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text-muted);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showImportUrlModal.value = true\"\n >\n <Link :size=\"14\" :stroke-width=\"2\" />\n {{ t.mediaLibrary.importFromUrl }}\n </button>\n </div>\n\n <!-- Image grid -->\n <MediaGrid\n :items=\"ui.displayItems.value\"\n :selected-ids=\"library.selectedItems.value\"\n :is-loading=\"library.isLoading.value\"\n :has-more=\"\n library.viewMode.value === 'files' && library.hasMore.value\n \"\n :layout=\"ui.layoutMode.value\"\n @select=\"ui.handleSelect\"\n @toggle=\"library.toggleSelection\"\n @load-more=\"library.loadMore\"\n @edit=\"ui.handleEditItem\"\n @replace=\"ui.handleReplaceItem\"\n />\n </div>\n </div>\n </div>\n\n <!-- Import from URL Modal -->\n <MediaImportUrlModal\n :visible=\"ui.showImportUrlModal.value\"\n :is-importing=\"library.isImportingFromUrl.value\"\n :error=\"library.importFromUrlError.value\"\n @import=\"ui.handleImportFromUrl\"\n @close=\"ui.showImportUrlModal.value = false\"\n />\n\n <!-- Edit Modal -->\n <MediaEditModal\n :visible=\"!!ui.editingItem.value\"\n :item=\"ui.editingItem.value\"\n @save=\"ui.handleEditSave\"\n @close=\"ui.editingItem.value = null\"\n />\n\n <!-- Replace Modal -->\n <MediaReplaceModal\n :visible=\"library.showReplaceWarning.value\"\n :item=\"library.pendingReplaceItem.value\"\n :usage-info=\"library.replaceUsageInfo.value\"\n :is-replacing=\"library.isReplacing.value\"\n :error=\"library.replaceError.value\"\n @replace=\"ui.handleReplaceFile\"\n @close=\"library.cancelReplace\"\n />\n\n <!-- Delete Warning Dialog -->\n <Transition\n enter-active-class=\"tpl:transition tpl:ease-out tpl:duration-150\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:ease-in tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <div\n v-if=\"library.showDeleteWarning.value\"\n class=\"tpl:absolute tpl:inset-0 tpl:z-10 tpl:flex tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n @click.self=\"library.cancelDelete\"\n >\n <div\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n class=\"tpl:mb-2 tpl:text-sm tpl:font-semibold\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.deleteWarningTitle }}\n </h3>\n <p\n class=\"tpl:text-xs\"\n :class=\"ui.hasUsedFiles.value ? 'tpl:mb-2' : 'tpl:mb-4'\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningMessage }}\n </p>\n <p\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:text-xs\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningUsageNote }}\n </p>\n\n <div\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:max-h-32 tpl:overflow-y-auto tpl:rounded tpl:border tpl:p-2\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div\n v-for=\"(info, mediaId) in library.deleteUsageInfo.value\"\n :key=\"mediaId\"\n class=\"tpl:text-xs\"\n style=\"color: var(--tpl-text)\"\n >\n <template v-if=\"info.template_count > 0\">\n <span class=\"tpl:font-medium\">\n {{\n ui.displayItems.value.find((i) => i.id === mediaId)\n ?.filename || mediaId\n }}\n </span>\n <span style=\"color: var(--tpl-text-muted)\">\n -\n {{\n t.mediaLibrary.usedInTemplates.replace(\n \"{count}\",\n info.template_count.toString(),\n )\n }}\n </span>\n </template>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"library.cancelDelete\"\n >\n {{ t.mediaLibrary.cancel }}\n </button>\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"library.confirmDelete\"\n >\n {{\n ui.hasUsedFiles.value\n ? t.mediaLibrary.deleteAnyway\n : t.mediaLibrary.confirmDelete\n }}\n </button>\n </div>\n </div>\n </div>\n </Transition>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:items-center tpl:gap-3\">\n <MediaPreviewPanel\n v-if=\"library.previewItem.value\"\n v-model:selected-conversion=\"ui.selectedConversion.value\"\n :item=\"library.previewItem.value\"\n :folders=\"library.folders.value\"\n />\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-5\">\n <!-- Copy URL + Move group -->\n <div\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:flex tpl:items-center tpl:gap-2\"\n >\n <button\n v-if=\"library.previewItem.value\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-1 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n :style=\"{\n borderColor: ui.copied.value\n ? 'var(--tpl-success)'\n : 'var(--tpl-border)',\n color: ui.copied.value ? 'var(--tpl-success)' : 'var(--tpl-text)',\n backgroundColor: 'var(--tpl-bg)',\n }\"\n @click=\"ui.copy(ui.selectedUrl.value!)\"\n >\n <Copy v-if=\"!ui.copied.value\" :size=\"12\" :stroke-width=\"2\" />\n <Check v-else :size=\"12\" :stroke-width=\"2\" />\n {{\n ui.copied.value ? t.mediaLibrary.copied : t.mediaLibrary.copyUrl\n }}\n </button>\n <div v-if=\"canUseMediaFolders\" class=\"tpl:relative\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showMovePicker.value = !ui.showMovePicker.value\"\n >\n {{ t.mediaLibrary.moveSelected }}\n </button>\n <MediaMovePicker\n v-if=\"ui.showMovePicker.value\"\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @select=\"ui.handleMoveToFolder\"\n @close=\"ui.showMovePicker.value = false\"\n />\n </div>\n </div>\n <!-- Delete + Select group -->\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"ui.handleDeleteClick\"\n >\n {{ t.mediaLibrary.deleteSelected }}\n </button>\n <button\n v-if=\"onSelect\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-4 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50\"\n style=\"background-color: var(--tpl-primary); color: var(--tpl-bg)\"\n :disabled=\"!library.previewItem.value\"\n @click=\"confirmSelection\"\n >\n {{ t.mediaLibrary.selectFile }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport MediaBreadcrumb from \"../components/media/MediaBreadcrumb.vue\";\nimport MediaEditModal from \"../components/media/MediaEditModal.vue\";\nimport MediaFolderTree from \"../components/media/MediaFolderTree.vue\";\nimport MediaGrid from \"../components/media/MediaGrid.vue\";\nimport MediaImportUrlModal from \"../components/media/MediaImportUrlModal.vue\";\nimport MediaMovePicker from \"../components/media/MediaMovePicker.vue\";\nimport MediaPreviewPanel from \"../components/media/MediaPreviewPanel.vue\";\nimport MediaReplaceModal from \"../components/media/MediaReplaceModal.vue\";\nimport MediaUploadZone from \"../components/media/MediaUploadZone.vue\";\nimport StorageProgressRing from \"../components/media/StorageProgressRing.vue\";\nimport { useMediaLibrary } from \"../composable\";\nimport { useMediaCategories } from \"../composables/useMediaCategories\";\nimport { useMediaLibraryUI } from \"../composables/useMediaLibraryUI\";\nimport type { PlanConfig, PlanFeatures } from \"@templatical/types\";\nimport type { MediaItem } from \"../types\";\nimport type { AuthManager } from \"@templatical/core/cloud\";\nimport type { MediaTranslations } from \"../i18n\";\nimport {\n Check,\n Copy,\n Grid2x2,\n Link,\n List,\n PanelLeft,\n Search,\n} from \"@lucide/vue\";\nimport { computed, onMounted, provide, ref } from \"vue\";\n\nconst props = defineProps<{\n authManager: AuthManager;\n projectId: string;\n planConfig: PlanConfig;\n translations: MediaTranslations;\n onSelect?: (item: MediaItem) => void;\n onError?: (error: Error) => void;\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\"): void;\n}>();\n\nconst t = computed(() => props.translations);\n\n// Provide translations for sub-components that use inject('translations')\nprovide(\"translations\", props.translations);\nprovide(\"authManager\", props.authManager);\nprovide(\n \"projectId\",\n computed(() => props.projectId),\n);\n\n// Provide planConfig in the format that sub-components expect\nconst planConfigRef = ref<PlanConfig | null>(props.planConfig);\nprovide(\"planConfig\", {\n config: planConfigRef,\n isLoading: ref(false),\n hasFeature: (feature: keyof PlanFeatures) =>\n props.planConfig.features[feature] ?? false,\n features: computed(() => props.planConfig.features),\n fetchConfig: async () => {},\n});\n\n// Feature flags\nconst canUseMediaFolders = computed(\n () => props.planConfig.features.media_folders ?? false,\n);\nconst canImportFromUrl = computed(\n () => props.planConfig.features.import_from_url ?? false,\n);\n\n// Storage info\nconst storageUsedBytes = computed(\n () => props.planConfig.storage.used_bytes ?? 0,\n);\nconst storageLimitBytes = computed(\n () => props.planConfig.storage.limit_bytes ?? 0,\n);\n\nconst { availableCategories } = useMediaCategories();\n\nconst library = useMediaLibrary({\n projectId: props.projectId,\n authManager: props.authManager,\n onError: props.onError,\n});\n\nconst ui = useMediaLibraryUI({\n library,\n canUseMediaFolders,\n translations: t,\n});\n\n// Standalone-specific: confirm selection via callback\nfunction confirmSelection(): void {\n if (!library.previewItem.value) {\n return;\n }\n\n const item = library.previewItem.value;\n const itemWithSelectedUrl: MediaItem = {\n ...item,\n url: ui.selectedUrl.value || item.url,\n };\n props.onSelect?.(itemWithSelectedUrl);\n}\n\nonMounted(() => {\n library.loadItems();\n library.loadFrequentlyUsed();\n emit(\"ready\");\n});\n</script>\n\n<template>\n <div\n class=\"tpl tpl:flex tpl:flex-col tpl:overflow-hidden tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n width: 100%;\n height: 100%;\n background-color: var(--tpl-bg-elevated);\n border: 1px solid var(--tpl-border);\n \"\n >\n <!-- Header -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-5 tpl:py-3.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <h2 class=\"tpl:text-sm tpl:font-semibold\" style=\"color: var(--tpl-text)\">\n {{ t.mediaLibrary.title }}\n </h2>\n <div class=\"tpl:flex tpl:items-center tpl:gap-3\">\n <StorageProgressRing\n :used-bytes=\"storageUsedBytes\"\n :limit-bytes=\"storageLimitBytes\"\n :size=\"22\"\n />\n <div class=\"tpl:relative\">\n <input\n :value=\"ui.searchInput.value\"\n type=\"text\"\n class=\"tpl:w-52 tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-3 tpl:pl-8 tpl:text-xs tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:outline-none tpl:focus:shadow-[var(--tpl-ring)]\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :placeholder=\"t.mediaLibrary.searchPlaceholder\"\n @input=\"\n ui.handleSearchInput(($event.target as HTMLInputElement).value)\n \"\n />\n <Search\n class=\"tpl:absolute tpl:top-1/2 tpl:left-2.5 tpl:-translate-y-1/2\"\n :size=\"13\"\n :stroke-width=\"2\"\n style=\"color: var(--tpl-text-dim)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Body -->\n <div class=\"tpl:flex tpl:min-h-0 tpl:flex-1 tpl:overflow-hidden\">\n <!-- Sidebar (only when media folders feature is enabled and toggled on) -->\n <Transition\n enter-active-class=\"tpl:transition-all tpl:duration-200 tpl:ease-out\"\n enter-from-class=\"tpl:-ml-48 tpl:opacity-0\"\n enter-to-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-active-class=\"tpl:transition-all tpl:duration-150 tpl:ease-in\"\n leave-from-class=\"tpl:ml-0 tpl:opacity-100\"\n leave-to-class=\"tpl:-ml-48 tpl:opacity-0\"\n >\n <div\n v-if=\"canUseMediaFolders && ui.showSidebar.value\"\n class=\"tpl:flex tpl:w-48 tpl:shrink-0 tpl:flex-col tpl:border-r\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <MediaFolderTree\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n :view-mode=\"library.viewMode.value\"\n :has-frequently-used=\"ui.hasFrequentlyUsed.value\"\n @navigate=\"library.navigateToFolder\"\n @create-folder=\"ui.handleCreateFolder\"\n @rename-folder=\"ui.handleRenameFolder\"\n @delete-folder=\"ui.handleDeleteFolder\"\n @show-frequently-used=\"library.showFrequentlyUsed\"\n />\n </div>\n </Transition>\n\n <!-- Content area -->\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:flex-col\">\n <!-- Breadcrumb + Upload -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-b tpl:px-4 tpl:py-2.5\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <!-- Sidebar toggle (only when media folders feature is enabled) -->\n <button\n v-if=\"canUseMediaFolders\"\n class=\"tpl:flex tpl:size-7 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-md tpl:transition-all tpl:duration-150\"\n :style=\"{\n color: ui.showSidebar.value\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor: ui.showSidebar.value\n ? 'var(--tpl-bg)'\n : 'transparent',\n border: ui.showSidebar.value\n ? '1px solid var(--tpl-border)'\n : '1px solid transparent',\n }\"\n :title=\"\n ui.showSidebar.value\n ? t.mediaLibrary.hideFolders\n : t.mediaLibrary.showFolders\n \"\n @click=\"ui.showSidebar.value = !ui.showSidebar.value\"\n >\n <PanelLeft :size=\"16\" :stroke-width=\"2\" />\n </button>\n\n <template v-if=\"library.viewMode.value === 'frequently-used'\">\n <span\n class=\"tpl:text-xs tpl:font-medium\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.frequentlyUsed }}\n </span>\n </template>\n <template v-else>\n <MediaBreadcrumb\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @navigate=\"library.navigateToFolder\"\n />\n </template>\n\n <!-- Layout toggle -->\n <div\n class=\"tpl:flex tpl:rounded-md tpl:p-0.5\"\n style=\"\n border: 1px solid var(--tpl-border);\n background-color: var(--tpl-bg);\n \"\n >\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'grid'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewGrid\"\n @click=\"ui.layoutMode.value = 'grid'\"\n >\n <Grid2x2 :size=\"14\" :stroke-width=\"2\" />\n </button>\n <button\n class=\"tpl:flex tpl:size-6 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded tpl:transition-all tpl:duration-150\"\n :style=\"{\n color:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-primary)'\n : 'var(--tpl-text-muted)',\n backgroundColor:\n ui.layoutMode.value === 'list'\n ? 'var(--tpl-bg-elevated)'\n : 'transparent',\n }\"\n :title=\"t.mediaLibrary.viewList\"\n @click=\"ui.layoutMode.value = 'list'\"\n >\n <List :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <select\n v-if=\"availableCategories.length > 1\"\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.categoryFilter.value ?? ''\"\n @change=\"\n library.filterByCategory(\n ($event.target as HTMLSelectElement).value || null,\n )\n \"\n >\n <option value=\"\">\n {{ t.mediaLibrary.filterAll }}\n </option>\n <option\n v-for=\"category in availableCategories\"\n :key=\"category\"\n :value=\"category\"\n >\n {{ ui.getCategoryLabel(category) }}\n </option>\n </select>\n <select\n class=\"tpl:rounded-md tpl:border tpl:py-1.5 tpl:pr-7 tpl:pl-2.5 tpl:text-xs tpl:transition-all tpl:duration-150 tpl:outline-none\"\n style=\"\n border-color: var(--tpl-border);\n background-color: var(--tpl-bg);\n color: var(--tpl-text);\n \"\n :value=\"library.sortOption.value\"\n @change=\"\n library.sortBy(($event.target as HTMLSelectElement).value)\n \"\n >\n <option value=\"newest\">\n {{ t.mediaLibrary.sortNewest }}\n </option>\n <option value=\"oldest\">\n {{ t.mediaLibrary.sortOldest }}\n </option>\n <option value=\"name_asc\">\n {{ t.mediaLibrary.sortNameAsc }}\n </option>\n <option value=\"name_desc\">\n {{ t.mediaLibrary.sortNameDesc }}\n </option>\n <option value=\"size_asc\">\n {{ t.mediaLibrary.sortSizeAsc }}\n </option>\n <option value=\"size_desc\">\n {{ t.mediaLibrary.sortSizeDesc }}\n </option>\n </select>\n </div>\n </div>\n\n <!-- Scrollable content area -->\n <div class=\"tpl:min-h-0 tpl:flex-1 tpl:overflow-y-auto\">\n <!-- Upload zone (only in files mode) -->\n <div\n v-if=\"library.viewMode.value === 'files'\"\n class=\"tpl:px-4 tpl:pt-3\"\n >\n <MediaUploadZone\n :is-uploading=\"library.isUploading.value\"\n :upload-progress=\"library.uploadProgress.value\"\n @upload=\"ui.handleUpload\"\n />\n <button\n v-if=\"canImportFromUrl\"\n class=\"tpl:mt-2 tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded-md tpl:border tpl:border-dashed tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text-muted);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showImportUrlModal.value = true\"\n >\n <Link :size=\"14\" :stroke-width=\"2\" />\n {{ t.mediaLibrary.importFromUrl }}\n </button>\n </div>\n\n <!-- Image grid -->\n <MediaGrid\n :items=\"ui.displayItems.value\"\n :selected-ids=\"library.selectedItems.value\"\n :is-loading=\"library.isLoading.value\"\n :has-more=\"\n library.viewMode.value === 'files' && library.hasMore.value\n \"\n :layout=\"ui.layoutMode.value\"\n @select=\"ui.handleSelect\"\n @toggle=\"library.toggleSelection\"\n @load-more=\"library.loadMore\"\n @edit=\"ui.handleEditItem\"\n @replace=\"ui.handleReplaceItem\"\n />\n </div>\n </div>\n </div>\n\n <!-- Import from URL Modal -->\n <MediaImportUrlModal\n :visible=\"ui.showImportUrlModal.value\"\n :is-importing=\"library.isImportingFromUrl.value\"\n :error=\"library.importFromUrlError.value\"\n @import=\"ui.handleImportFromUrl\"\n @close=\"ui.showImportUrlModal.value = false\"\n />\n\n <!-- Edit Modal -->\n <MediaEditModal\n :visible=\"!!ui.editingItem.value\"\n :item=\"ui.editingItem.value\"\n @save=\"ui.handleEditSave\"\n @close=\"ui.editingItem.value = null\"\n />\n\n <!-- Replace Modal -->\n <MediaReplaceModal\n :visible=\"library.showReplaceWarning.value\"\n :item=\"library.pendingReplaceItem.value\"\n :usage-info=\"library.replaceUsageInfo.value\"\n :is-replacing=\"library.isReplacing.value\"\n :error=\"library.replaceError.value\"\n @replace=\"ui.handleReplaceFile\"\n @close=\"library.cancelReplace\"\n />\n\n <!-- Delete Warning Dialog -->\n <Transition\n enter-active-class=\"tpl:transition tpl:ease-out tpl:duration-150\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:ease-in tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <div\n v-if=\"library.showDeleteWarning.value\"\n class=\"tpl:absolute tpl:inset-0 tpl:z-10 tpl:flex tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-lg)]\"\n style=\"\n background-color: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n @click.self=\"library.cancelDelete\"\n >\n <div\n class=\"tpl-scale-in tpl:mx-4 tpl:w-full tpl:max-w-sm tpl:rounded-[var(--tpl-radius-lg)] tpl:p-5\"\n style=\"\n background-color: var(--tpl-bg-elevated);\n box-shadow: var(--tpl-shadow-xl);\n \"\n >\n <h3\n class=\"tpl:mb-2 tpl:text-sm tpl:font-semibold\"\n style=\"color: var(--tpl-text)\"\n >\n {{ t.mediaLibrary.deleteWarningTitle }}\n </h3>\n <p\n class=\"tpl:text-xs\"\n :class=\"ui.hasUsedFiles.value ? 'tpl:mb-2' : 'tpl:mb-4'\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningMessage }}\n </p>\n <p\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:text-xs\"\n style=\"color: var(--tpl-text-muted)\"\n >\n {{ t.mediaLibrary.deleteWarningUsageNote }}\n </p>\n\n <div\n v-if=\"ui.hasUsedFiles.value\"\n class=\"tpl:mb-4 tpl:max-h-32 tpl:overflow-y-auto tpl:rounded tpl:border tpl:p-2\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div\n v-for=\"(info, mediaId) in library.deleteUsageInfo.value\"\n :key=\"mediaId\"\n class=\"tpl:text-xs\"\n style=\"color: var(--tpl-text)\"\n >\n <template v-if=\"info.template_count > 0\">\n <span class=\"tpl:font-medium\">\n {{\n ui.displayItems.value.find((i) => i.id === mediaId)\n ?.filename || mediaId\n }}\n </span>\n <span style=\"color: var(--tpl-text-muted)\">\n -\n {{\n t.mediaLibrary.usedInTemplates.replace(\n \"{count}\",\n info.template_count.toString(),\n )\n }}\n </span>\n </template>\n </div>\n </div>\n\n <div class=\"tpl:flex tpl:justify-end tpl:gap-2\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"library.cancelDelete\"\n >\n {{ t.mediaLibrary.cancel }}\n </button>\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"library.confirmDelete\"\n >\n {{\n ui.hasUsedFiles.value\n ? t.mediaLibrary.deleteAnyway\n : t.mediaLibrary.confirmDelete\n }}\n </button>\n </div>\n </div>\n </div>\n </Transition>\n\n <!-- Footer -->\n <div\n class=\"tpl:flex tpl:shrink-0 tpl:items-center tpl:justify-between tpl:border-t tpl:px-5 tpl:py-3\"\n style=\"border-color: var(--tpl-border)\"\n >\n <div class=\"tpl:flex tpl:min-w-0 tpl:flex-1 tpl:items-center tpl:gap-3\">\n <MediaPreviewPanel\n v-if=\"library.previewItem.value\"\n v-model:selected-conversion=\"ui.selectedConversion.value\"\n :item=\"library.previewItem.value\"\n :folders=\"library.folders.value\"\n />\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-5\">\n <!-- Copy URL + Move group -->\n <div\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:flex tpl:items-center tpl:gap-2\"\n >\n <button\n v-if=\"library.previewItem.value\"\n class=\"tpl:flex tpl:cursor-pointer tpl:items-center tpl:gap-1 tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n :style=\"{\n borderColor: ui.copied.value\n ? 'var(--tpl-success)'\n : 'var(--tpl-border)',\n color: ui.copied.value ? 'var(--tpl-success)' : 'var(--tpl-text)',\n backgroundColor: 'var(--tpl-bg)',\n }\"\n @click=\"ui.copy(ui.selectedUrl.value!)\"\n >\n <Copy v-if=\"!ui.copied.value\" :size=\"12\" :stroke-width=\"2\" />\n <Check v-else :size=\"12\" :stroke-width=\"2\" />\n {{\n ui.copied.value ? t.mediaLibrary.copied : t.mediaLibrary.copyUrl\n }}\n </button>\n <div v-if=\"canUseMediaFolders\" class=\"tpl:relative\">\n <button\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-border);\n color: var(--tpl-text);\n background-color: var(--tpl-bg);\n \"\n @click=\"ui.showMovePicker.value = !ui.showMovePicker.value\"\n >\n {{ t.mediaLibrary.moveSelected }}\n </button>\n <MediaMovePicker\n v-if=\"ui.showMovePicker.value\"\n :folders=\"library.folders.value\"\n :current-folder-id=\"library.currentFolderId.value\"\n @select=\"ui.handleMoveToFolder\"\n @close=\"ui.showMovePicker.value = false\"\n />\n </div>\n </div>\n <!-- Delete + Select group -->\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n v-if=\"library.selectedItems.value.size > 0\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:border tpl:px-3 tpl:py-1.5 tpl:text-xs tpl:font-medium tpl:transition-all tpl:duration-150\"\n style=\"\n border-color: var(--tpl-danger);\n color: var(--tpl-danger);\n background-color: var(--tpl-danger-light);\n \"\n @click=\"ui.handleDeleteClick\"\n >\n {{ t.mediaLibrary.deleteSelected }}\n </button>\n <button\n v-if=\"onSelect\"\n class=\"tpl:cursor-pointer tpl:rounded-md tpl:px-4 tpl:py-1.5 tpl:text-sm tpl:font-medium tpl:shadow-xs tpl:transition-all tpl:duration-150 tpl:hover:opacity-90 tpl:disabled:cursor-not-allowed tpl:disabled:opacity-50\"\n style=\"background-color: var(--tpl-primary); color: var(--tpl-bg)\"\n :disabled=\"!library.previewItem.value\"\n @click=\"confirmSelection\"\n >\n {{ t.mediaLibrary.selectFile }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</template>\n","/// <reference types=\"vite/client\" />\n\nimport type en from \"./locales/en\";\n\nexport type MediaTranslations = typeof en;\n\n// Vite resolves this glob at build time. Adding a new locale file\n// automatically registers it — no array to keep in sync.\nconst localeModules = import.meta.glob<{ default: MediaTranslations }>(\n \"./locales/*.ts\",\n);\n\nfunction localesFromGlob(modules: Record<string, unknown>): string[] {\n return Object.keys(modules)\n .map((path) => path.match(/\\/([^/]+)\\.ts$/)?.[1])\n .filter((locale): locale is string => Boolean(locale));\n}\n\nconst supportedLocales = localesFromGlob(localeModules);\n\nfunction canonicalize(locale: string): string {\n return locale.trim().replace(/_/g, \"-\").toLowerCase();\n}\n\nfunction findSupportedLocale(locale: string): string | undefined {\n const canonical = canonicalize(locale);\n return supportedLocales.find((s) => canonicalize(s) === canonical);\n}\n\nfunction getBaseLocale(locale: string): string {\n return canonicalize(locale).split(\"-\")[0];\n}\n\nfunction resolveLocale(locale: string): string {\n return (\n findSupportedLocale(locale) ??\n findSupportedLocale(getBaseLocale(locale)) ??\n \"en\"\n );\n}\n\nexport async function loadMediaTranslations(\n locale: string,\n): Promise<MediaTranslations> {\n const target = resolveLocale(locale);\n const loader = localeModules[`./locales/${target}.ts`];\n const module = await loader();\n return module.default;\n}\n","import { createSdkAuthManager } from \"@templatical/core/cloud\";\nimport type { PlanConfig } from \"@templatical/types\";\nimport { ApiClient } from \"@templatical/core/cloud\";\nimport MediaLibrary from \"./MediaLibrary.vue\";\nimport { loadMediaTranslations, type MediaTranslations } from \"../i18n\";\nimport type { MediaLibraryConfig, MediaLibraryInstance } from \"./types\";\nimport { createApp, h, ref, type App, type Ref } from \"vue\";\n\n// Import SDK styles\nimport \"../styles/index.css\";\n\n// Re-export types for consumers\nexport type { MediaFolder, MediaItem } from \"../types\";\nexport type { MediaLibraryConfig, MediaLibraryInstance } from \"./types\";\n\nlet appInstance: App | null = null;\nconst mediaLibraryRef: Ref<InstanceType<typeof MediaLibrary> | null> =\n ref(null);\n\nasync function init(config: MediaLibraryConfig): Promise<MediaLibraryInstance> {\n const container =\n typeof config.container === \"string\"\n ? document.querySelector(config.container)\n : config.container;\n\n if (!container) {\n throw new Error(`Container element not found: ${config.container}`);\n }\n\n // Initialize auth\n const authManager = createSdkAuthManager(config.auth, config.onError);\n await authManager.initialize();\n\n // Fetch plan config\n const apiClient = new ApiClient(authManager);\n const planConfig: PlanConfig = await apiClient.fetchConfig();\n\n // Load translations\n const translations: MediaTranslations = await loadMediaTranslations(\n config.locale ?? \"en\",\n );\n\n // Apply theme overrides to container\n applyTheme(container as HTMLElement, config.theme);\n\n // Unmount any prior app *after* awaits so concurrent init() calls don't\n // both pass an early check while appInstance is still null and orphan\n // the first-mounted app.\n if (appInstance) {\n unmount();\n }\n\n return new Promise((resolve, reject) => {\n try {\n appInstance = createApp({\n setup() {\n const onReady = () => {\n const instance: MediaLibraryInstance = {\n setTheme: (theme) => applyTheme(container as HTMLElement, theme),\n unmount,\n };\n\n resolve(instance);\n };\n\n return () =>\n h(MediaLibrary, {\n authManager,\n projectId: authManager.projectId,\n planConfig,\n translations,\n onSelect: config.onSelect,\n onError: config.onError,\n ref: mediaLibraryRef,\n onReady,\n });\n },\n });\n\n appInstance.mount(container);\n } catch (error) {\n reject(error);\n }\n });\n}\n\nfunction unmount(): void {\n if (appInstance) {\n appInstance.unmount();\n appInstance = null;\n mediaLibraryRef.value = null;\n }\n}\n\nfunction applyTheme(\n container: HTMLElement,\n theme?: { primaryColor?: string; borderRadius?: number },\n): void {\n if (!theme) {\n return;\n }\n\n if (theme.primaryColor) {\n container.style.setProperty(\"--tpl-primary\", theme.primaryColor);\n }\n\n if (theme.borderRadius !== undefined) {\n container.style.setProperty(\"--tpl-radius\", `${theme.borderRadius}px`);\n container.style.setProperty(\n \"--tpl-radius-sm\",\n `${Math.max(0, theme.borderRadius - 3)}px`,\n );\n container.style.setProperty(\n \"--tpl-radius-lg\",\n `${theme.borderRadius + 4}px`,\n );\n }\n}\n\nconst TemplaticalMedia = {\n init,\n unmount,\n};\n\n// Assign to window for IIFE usage\nif (typeof window !== \"undefined\") {\n (\n window as unknown as Window & { TemplaticalMedia: typeof TemplaticalMedia }\n ).TemplaticalMedia = TemplaticalMedia;\n}\n\n// Named exports for destructured imports\nexport { init, unmount };\n\n// Default export for library mode\nexport default TemplaticalMedia;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA,IAAM,IAAQ,GASR,IAAO,GAIP,IAAI,QAAe,EAAM,YAAY;EAY3C,AATA,EAAQ,gBAAgB,EAAM,YAAY,GAC1C,EAAQ,eAAe,EAAM,WAAW,GACxC,EACE,aACA,QAAe,EAAM,SAAS,CAChC,GAIA,EAAQ,cAAc;GACpB,QAFoB,EAAuB,EAAM,UAEzC;GACR,WAAW,EAAI,EAAK;GACpB,aAAa,MACX,EAAM,WAAW,SAAS,MAAY;GACxC,UAAU,QAAe,EAAM,WAAW,QAAQ;GAClD,aAAa,YAAY,CAAC;EAC5B,CAAC;EAGD,IAAM,IAAqB,QACnB,EAAM,WAAW,SAAS,iBAAiB,EACnD,GACM,IAAmB,QACjB,EAAM,WAAW,SAAS,mBAAmB,EACrD,GAGM,IAAmB,QACjB,EAAM,WAAW,QAAQ,cAAc,CAC/C,GACM,IAAoB,QAClB,EAAM,WAAW,QAAQ,eAAe,CAChD,GAEM,EAAE,2BAAwB,GAAmB,GAE7C,IAAU,EAAgB;GAC9B,WAAW,EAAM;GACjB,aAAa,EAAM;GACnB,SAAS,EAAM;EACjB,CAAC,GAEK,IAAK,EAAkB;GAC3B;GACA;GACA,cAAc;EAChB,CAAC;EAGD,SAAS,IAAyB;GAChC,IAAI,CAAC,EAAQ,YAAY,OACvB;GAGF,IAAM,IAAO,EAAQ,YAAY;GAKjC,EAAM,WAAW;IAHf,GAAG;IACH,KAAK,EAAG,YAAY,SAAS,EAAK;GAEnB,CAAmB;EACtC;SAEA,QAAgB;GAGd,AAFA,EAAQ,UAAU,GAClB,EAAQ,mBAAmB,GAC3B,EAAK,OAAO;EACd,CAAC,mBAIC,EAwfM,OAxfN,GAwfM;GA9eJ,EAoCM,OApCN,GAoCM,CAhCJ,EAEK,MAFL,GAEK,EADA,EAAA,MAAE,aAAa,KAAK,GAAA,CAAA,GAEzB,EA4BM,OA5BN,GA4BM,CA3BJ,EAIE,GAAA;IAHC,cAAY,EAAA;IACZ,eAAa,EAAA;IACb,MAAM;+CAET,EAqBM,OArBN,GAqBM,CApBJ,EAaE,SAAA;IAZC,OAAO,EAAA,CAAA,CAAE,CAAC,YAAY;IACvB,MAAK;IACL,OAAM;IACN,OAAA;KAAA,gBAAA;KAAA,oBAAA;KAAA,OAAA;IAAA;IAKC,aAAa,EAAA,MAAE,aAAa;IAC5B,SAAK,AAAA,EAAA,QAAA,MAAiB,EAAA,CAAA,CAAE,CAAC,kBAAmB,EAAO,OAA4B,KAAK;oBAIvF,EAKE,EAAA,EAAA,GAAA;IAJA,OAAM;IACL,MAAM;IACN,gBAAc;IACf,OAAA,EAAA,OAAA,sBAAA;;GAOR,EAuOM,OAvON,GAuOM,CArOJ,EA4Ba,GAAA;IA3BX,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;IACf,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;;qBAqBT,CAlBE,EAAA,SAAsB,EAAA,CAAA,CAAE,CAAC,YAAY,SAAA,EAAA,GAD7C,EAmBM,OAnBN,GAmBM,CAXJ,EAUE,GAAA;KATC,SAAS,EAAA,CAAA,CAAO,CAAC,QAAQ;KACzB,qBAAmB,EAAA,CAAA,CAAO,CAAC,gBAAgB;KAC3C,aAAW,EAAA,CAAA,CAAO,CAAC,SAAS;KAC5B,uBAAqB,EAAA,CAAA,CAAE,CAAC,kBAAkB;KAC1C,YAAU,EAAA,CAAA,CAAO,CAAC;KAClB,gBAAe,EAAA,CAAA,CAAE,CAAC;KAClB,gBAAe,EAAA,CAAA,CAAE,CAAC;KAClB,gBAAe,EAAA,CAAA,CAAE,CAAC;KAClB,sBAAsB,EAAA,CAAA,CAAO,CAAC;;;;;;;;;;;;;OAMrC,EAqMM,OArMN,IAqMM,CAnMJ,EAsJM,OAtJN,IAsJM,CAlJJ,EAqFM,OArFN,IAqFM;IAlFI,EAAA,SAAA,EAAA,GADR,EAsBS,UAAA;;KApBP,OAAM;KACL,OAAK,EAAA;aAA2B,EAAA,CAAA,CAAE,CAAC,YAAY,QAAA,uBAAA;uBAA6H,EAAA,CAAA,CAAE,CAAC,YAAY,QAAA,kBAAA;cAAqG,EAAA,CAAA,CAAE,CAAC,YAAY,QAAA,gCAAA;;KAW/S,OAAwB,EAAA,CAAA,CAAE,CAAC,YAAY,QAA0B,EAAA,MAAE,aAAa,cAAgC,EAAA,MAAE,aAAa;KAK/H,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAE,CAAC,YAAY,QAAK,CAAI,EAAA,CAAA,CAAE,CAAC,YAAY;QAE/C,EAA0C,EAAA,EAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;;IAGvB,EAAA,CAAA,CAAO,CAAC,SAAS,UAAK,qBAAA,EAAA,GACpC,EAKO,QALP,IAKO,EADF,EAAA,MAAE,aAAa,cAAc,GAAA,CAAA,MAAA,EAAA,GAIlC,EAIE,GAAA;;KAHC,SAAS,EAAA,CAAA,CAAO,CAAC,QAAQ;KACzB,qBAAmB,EAAA,CAAA,CAAO,CAAC,gBAAgB;KAC3C,YAAU,EAAA,CAAA,CAAO,CAAC;;;;;;IAKvB,EAyCM,OAzCN,IAyCM,CAlCJ,EAgBS,UAAA;KAfP,OAAM;KACL,OAAK,EAAA;aAAiD,EAAA,CAAA,CAAE,CAAC,WAAW,UAAK,SAAA,uBAAA;uBAAiK,EAAA,CAAA,CAAE,CAAC,WAAW,UAAK,SAAA,2BAAA;;KAU7P,OAAO,EAAA,MAAE,aAAa;KACtB,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAE,CAAC,WAAW,QAAK;QAE3B,EAAwC,EAAA,EAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;kBAErC,EAgBS,UAAA;KAfP,OAAM;KACL,OAAK,EAAA;aAAiD,EAAA,CAAA,CAAE,CAAC,WAAW,UAAK,SAAA,uBAAA;uBAAiK,EAAA,CAAA,CAAE,CAAC,WAAW,UAAK,SAAA,2BAAA;;KAU7P,OAAO,EAAA,MAAE,aAAa;KACtB,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAE,CAAC,WAAW,QAAK;QAE3B,EAAqC,EAAA,EAAA,GAAA;KAA9B,MAAM;KAAK,gBAAc;;OAKtC,EA0DM,OA1DN,IA0DM,CAxDI,EAAA,CAAA,CAAmB,CAAC,SAAM,KAAA,EAAA,GADlC,EAyBS,UAAA;;IAvBP,OAAM;IACN,OAAA;KAAA,gBAAA;KAAA,oBAAA;KAAA,OAAA;IAAA;IAKC,OAAO,EAAA,CAAA,CAAO,CAAC,eAAe,SAAK;IACnC,UAAM,AAAA,EAAA,QAAA,MAAmB,EAAA,CAAA,CAAO,CAAC,iBAAqC,EAAO,OAA6B,SAAK,IAAA;OAMhH,EAES,UAFT,GAES,EADJ,EAAA,MAAE,aAAa,SAAS,GAAA,CAAA,IAAA,EAAA,EAAA,GAE7B,EAMS,GAAA,MAAA,EALY,EAAA,CAAA,IAAZ,YADT,EAMS,UAAA;IAJN,KAAK;IACL,OAAO;QAEL,EAAA,CAAA,CAAE,CAAC,iBAAiB,CAAQ,CAAA,GAAA,GAAA,EAAA,mCAGnC,EA8BS,UAAA;IA7BP,OAAM;IACN,OAAA;KAAA,gBAAA;KAAA,oBAAA;KAAA,OAAA;IAAA;IAKC,OAAO,EAAA,CAAA,CAAO,CAAC,WAAW;IAC1B,UAAM,AAAA,EAAA,QAAA,MAAmB,EAAA,CAAA,CAAO,CAAC,OAAQ,EAAO,OAA6B,KAAK;;IAInF,EAES,UAFT,IAES,EADJ,EAAA,MAAE,aAAa,UAAU,GAAA,CAAA;IAE9B,EAES,UAFT,IAES,EADJ,EAAA,MAAE,aAAa,UAAU,GAAA,CAAA;IAE9B,EAES,UAFT,IAES,EADJ,EAAA,MAAE,aAAa,WAAW,GAAA,CAAA;IAE/B,EAES,UAFT,IAES,EADJ,EAAA,MAAE,aAAa,YAAY,GAAA,CAAA;IAEhC,EAES,UAFT,IAES,EADJ,EAAA,MAAE,aAAa,WAAW,GAAA,CAAA;IAE/B,EAES,UAFT,IAES,EADJ,EAAA,MAAE,aAAa,YAAY,GAAA,CAAA;mBAOtC,EAyCM,OAzCN,IAyCM,CAtCI,EAAA,CAAA,CAAO,CAAC,SAAS,UAAK,WAAA,EAAA,GAD9B,EAsBM,OAtBN,IAsBM,CAlBJ,EAIE,GAAA;IAHC,gBAAc,EAAA,CAAA,CAAO,CAAC,YAAY;IAClC,mBAAiB,EAAA,CAAA,CAAO,CAAC,eAAe;IACxC,UAAQ,EAAA,CAAA,CAAE,CAAC;;;;;OAGN,EAAA,SAAA,EAAA,GADR,EAYS,UAAA;;IAVP,OAAM;IACN,OAAA;KAAA,gBAAA;KAAA,OAAA;KAAA,oBAAA;IAAA;IAKC,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAE,CAAC,mBAAmB,QAAK;OAEnC,EAAqC,EAAA,EAAA,GAAA;IAA9B,MAAM;IAAK,gBAAc;SAAK,MACrC,EAAG,EAAA,MAAE,aAAa,aAAa,GAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAKnC,EAaE,GAAA;IAZC,OAAO,EAAA,CAAA,CAAE,CAAC,aAAa;IACvB,gBAAc,EAAA,CAAA,CAAO,CAAC,cAAc;IACpC,cAAY,EAAA,CAAA,CAAO,CAAC,UAAU;IAC9B,YAAyB,EAAA,CAAA,CAAO,CAAC,SAAS,UAAK,WAAgB,EAAA,CAAA,CAAO,CAAC,QAAQ;IAG/E,QAAQ,EAAA,CAAA,CAAE,CAAC,WAAW;IACtB,UAAQ,EAAA,CAAA,CAAE,CAAC;IACX,UAAQ,EAAA,CAAA,CAAO,CAAC;IAChB,YAAW,EAAA,CAAA,CAAO,CAAC;IACnB,QAAM,EAAA,CAAA,CAAE,CAAC;IACT,WAAS,EAAA,CAAA,CAAE,CAAC;;;;;;;;;;;;;GAOrB,EAME,IAAA;IALC,SAAS,EAAA,CAAA,CAAE,CAAC,mBAAmB;IAC/B,gBAAc,EAAA,CAAA,CAAO,CAAC,mBAAmB;IACzC,OAAO,EAAA,CAAA,CAAO,CAAC,mBAAmB;IAClC,UAAQ,EAAA,CAAA,CAAE,CAAC;IACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAE,CAAC,mBAAmB,QAAK;;;;;;;GAIrC,EAKE,IAAA;IAJC,SAAO,CAAA,CAAI,EAAA,CAAA,CAAE,CAAC,YAAY;IAC1B,MAAM,EAAA,CAAA,CAAE,CAAC,YAAY;IACrB,QAAM,EAAA,CAAA,CAAE,CAAC;IACT,SAAK,AAAA,EAAA,QAAA,MAAE,EAAA,CAAA,CAAE,CAAC,YAAY,QAAK;;;;;;GAI9B,EAQE,IAAA;IAPC,SAAS,EAAA,CAAA,CAAO,CAAC,mBAAmB;IACpC,MAAM,EAAA,CAAA,CAAO,CAAC,mBAAmB;IACjC,cAAY,EAAA,CAAA,CAAO,CAAC,iBAAiB;IACrC,gBAAc,EAAA,CAAA,CAAO,CAAC,YAAY;IAClC,OAAO,EAAA,CAAA,CAAO,CAAC,aAAa;IAC5B,WAAS,EAAA,CAAA,CAAE,CAAC;IACZ,SAAO,EAAA,CAAA,CAAO,CAAC;;;;;;;;;;GAIlB,EA2Ga,GAAA;IA1GX,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;IACf,sBAAmB;IACnB,oBAAiB;IACjB,kBAAe;;qBAoGT,CAjGE,EAAA,CAAA,CAAO,CAAC,kBAAkB,SAAA,EAAA,GADlC,EAkGM,OAAA;;KAhGJ,OAAM;KACN,OAAA;MAAA,oBAAA;MAAA,mBAAA;MAAA,2BAAA;KAAA;KAKC,SAAK,AAAA,EAAA,QAAA,IAAA,GAAA,MAAO,EAAA,CAAA,CAAO,CAAC,gBAAR,EAAA,CAAA,CAAO,CAAC,aAAY,GAAA,CAAA,GAAA,CAAA,MAAA,CAAA;QAEjC,EAuFM,OAvFN,IAuFM;KAhFJ,EAKK,MALL,IAKK,EADA,EAAA,MAAE,aAAa,kBAAkB,GAAA,CAAA;KAEtC,EAMI,KAAA;MALF,OAAK,GAAA,CAAC,eACE,EAAA,CAAA,CAAE,CAAC,aAAa,QAAK,aAAA,UAAA,CAAA;MAC7B,OAAA,EAAA,OAAA,wBAAA;UAEG,EAAA,MAAE,aAAa,oBAAoB,GAAA,CAAA;KAGhC,EAAA,CAAA,CAAE,CAAC,aAAa,SAAA,EAAA,GADxB,EAMI,KANJ,IAMI,EADC,EAAA,MAAE,aAAa,sBAAsB,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA;KAIlC,EAAA,CAAA,CAAE,CAAC,aAAa,SAAA,EAAA,GADxB,EA6BM,OA7BN,IA6BM,EAAA,EAAA,EAAA,GAxBJ,EAuBM,GAAA,MAAA,EAtBsB,EAAA,CAAA,CAAO,CAAC,gBAAgB,QAA1C,GAAM,YADhB,EAuBM,OAAA;MArBH,KAAK;MACN,OAAM;MACN,OAAA,EAAA,OAAA,kBAAA;SAEgB,EAAK,iBAAc,KAAA,EAAA,GAAnC,EAgBW,GAAA,EAAA,KAAA,EAAA,GAAA,CAfT,EAKO,QALP,IAKO,EAHH,EAAA,CAAA,CAAE,CAAC,aAAa,MAAM,MAAM,MAAM,EAAE,OAAO,CAAO,CAAA,EAA0B,YAAY,CAAO,GAAA,CAAA,GAInG,EAQO,QARP,IAA2C,QAEzC,EACE,EAAA,MAAE,aAAa,gBAAgB,QAAA,WAAgE,EAAK,eAAe,SAAQ,CAAA,CAAA,GAAA,CAAA,CAAA,GAAA,EAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA;KAUrI,EA2BM,OA3BN,IA2BM,CA1BJ,EAUS,UAAA;MATP,OAAM;MACN,OAAA;OAAA,gBAAA;OAAA,OAAA;OAAA,oBAAA;MAAA;MAKC,SAAK,AAAA,EAAA,QAAA,GAAA,MAAE,EAAA,CAAA,CAAO,CAAC,gBAAR,EAAA,CAAA,CAAO,CAAC,aAAY,GAAA,CAAA;UAEzB,EAAA,MAAE,aAAa,MAAM,GAAA,CAAA,GAE1B,EAcS,UAAA;MAbP,OAAM;MACN,OAAA;OAAA,gBAAA;OAAA,OAAA;OAAA,oBAAA;MAAA;MAKC,SAAK,AAAA,EAAA,SAAA,GAAA,MAAE,EAAA,CAAA,CAAO,CAAC,iBAAR,EAAA,CAAA,CAAO,CAAC,cAAa,GAAA,CAAA;UAG3B,EAAA,CAAA,CAAE,CAAC,aAAa,QAA0B,EAAA,MAAE,aAAa,eAAiC,EAAA,MAAE,aAAa,aAAa,GAAA,CAAA,CAAA,CAAA;;;;GAWlI,EAkFM,OAlFN,IAkFM,CA9EJ,EAOM,OAPN,IAOM,CALI,EAAA,CAAA,CAAO,CAAC,YAAY,SAAA,EAAA,GAD5B,EAKE,GAAA;;IAHQ,uBAAqB,EAAA,CAAA,CAAE,CAAC,mBAAmB;sDAAtB,CAAA,CAAE,CAAC,mBAAmB,QAAK;IACvD,MAAM,EAAA,CAAA,CAAO,CAAC,YAAY;IAC1B,SAAS,EAAA,CAAA,CAAO,CAAC,QAAQ;;;;;sBAG9B,EAqEM,OArEN,IAqEM,CAlEI,EAAA,CAAA,CAAO,CAAC,cAAc,MAAM,OAAI,KAAA,EAAA,GADxC,EA0CM,OA1CN,IA0CM,CArCI,EAAA,CAAA,CAAO,CAAC,YAAY,SAAA,EAAA,GAD5B,EAiBS,UAAA;;IAfP,OAAM;IACL,OAAK,EAAA;kBAA+B,EAAA,CAAA,CAAE,CAAC,OAAO,QAAA,uBAAA;YAAyG,EAAA,CAAA,CAAE,CAAC,OAAO,QAAK,uBAAA;;;IAOtK,SAAK,AAAA,EAAA,SAAA,MAAE,EAAA,CAAA,CAAE,CAAC,KAAK,EAAA,CAAA,CAAE,CAAC,YAAY,KAAK;OAEvB,EAAA,CAAA,CAAE,CAAC,OAAO,cACvB,EAA6C,EAAA,EAAA,GAAA;;IAA9B,MAAM;IAAK,gBAAc;UADjB,EAAA,GAAvB,EAA6D,EAAA,CAAA,GAAA;;IAA9B,MAAM;IAAK,gBAAc;UACX,MAC7C,EACE,EAAA,CAAA,CAAE,CAAC,OAAO,QAAQ,EAAA,MAAE,aAAa,SAAS,EAAA,MAAE,aAAa,OAAO,GAAA,CAAA,CAAA,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAGzD,EAAA,SAAA,EAAA,GAAX,EAmBM,OAnBN,IAmBM,CAlBJ,EAUS,UAAA;IATP,OAAM;IACN,OAAA;KAAA,gBAAA;KAAA,OAAA;KAAA,oBAAA;IAAA;IAKC,SAAK,AAAA,EAAA,SAAA,MAAE,EAAA,CAAA,CAAE,CAAC,eAAe,QAAK,CAAI,EAAA,CAAA,CAAE,CAAC,eAAe;QAElD,EAAA,MAAE,aAAa,YAAY,GAAA,CAAA,GAGxB,EAAA,CAAA,CAAE,CAAC,eAAe,SAAA,EAAA,GAD1B,EAME,GAAA;;IAJC,SAAS,EAAA,CAAA,CAAO,CAAC,QAAQ;IACzB,qBAAmB,EAAA,CAAA,CAAO,CAAC,gBAAgB;IAC3C,UAAQ,EAAA,CAAA,CAAE,CAAC;IACX,SAAK,AAAA,EAAA,SAAA,MAAE,EAAA,CAAA,CAAE,CAAC,eAAe,QAAK;;;;;kDAKrC,EAsBM,OAtBN,IAsBM,CApBI,EAAA,CAAA,CAAO,CAAC,cAAc,MAAM,OAAI,KAAA,EAAA,GADxC,EAWS,UAAA;;IATP,OAAM;IACN,OAAA;KAAA,gBAAA;KAAA,OAAA;KAAA,oBAAA;IAAA;IAKC,SAAK,AAAA,EAAA,SAAA,GAAA,MAAE,EAAA,CAAA,CAAE,CAAC,qBAAH,EAAA,CAAA,CAAE,CAAC,kBAAiB,GAAA,CAAA;QAEzB,EAAA,MAAE,aAAa,cAAc,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAG1B,EAAA,YAAA,EAAA,GADR,EAQS,UAAA;;IANP,OAAM;IACN,OAAA;KAAA,oBAAA;KAAA,OAAA;IAAA;IACC,UAAQ,CAAG,EAAA,CAAA,CAAO,CAAC,YAAY;IAC/B,SAAO;QAEL,EAAA,MAAE,aAAa,UAAU,GAAA,GAAA,EAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;;IE9lBlC,IAAgB,uBAAA,OAAA;CAAA,yBAAA,OAAA;CAAA,yBAAA,OAAA;CAAA,yBAAA,OAAA;CAAA,yBAAA,OAAA;CAAA,4BAAA,OAAA;AAAA,CAAA;AAItB,SAAS,EAAgB,GAA4C;CACnE,OAAO,OAAO,KAAK,CAAO,CAAC,CACxB,KAAK,MAAS,EAAK,MAAM,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAChD,QAAQ,MAA6B,EAAQ,CAAO;AACzD;AAEA,IAAM,IAAmB,EAAgB,CAAa;AAEtD,SAAS,EAAa,GAAwB;CAC5C,OAAO,EAAO,KAAK,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,CAAC,YAAY;AACtD;AAEA,SAAS,EAAoB,GAAoC;CAC/D,IAAM,IAAY,EAAa,CAAM;CACrC,OAAO,EAAiB,MAAM,MAAM,EAAa,CAAC,MAAM,CAAS;AACnE;AAEA,SAAS,GAAc,GAAwB;CAC7C,OAAO,EAAa,CAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AACzC;AAEA,SAAS,GAAc,GAAwB;CAC7C,OACE,EAAoB,CAAM,KAC1B,EAAoB,GAAc,CAAM,CAAC,KACzC;AAEJ;AAEA,eAAsB,GACpB,GAC4B;CAE5B,IAAM,IAAS,EAAc,aADd,GAAc,CACa,EAAO;CAEjD,QAAO,MADc,EAAO,EAAA,CACd;AAChB;;;ACjCA,IAAI,IAA0B,MACxB,IACJ,EAAI,IAAI;AAEV,eAAe,GAAK,GAA2D;CAC7E,IAAM,IACJ,OAAO,EAAO,aAAc,WACxB,SAAS,cAAc,EAAO,SAAS,IACvC,EAAO;CAEb,IAAI,CAAC,GACH,MAAU,MAAM,gCAAgC,EAAO,WAAW;CAIpE,IAAM,IAAc,EAAqB,EAAO,MAAM,EAAO,OAAO;CACpE,MAAM,EAAY,WAAW;CAI7B,IAAM,IAAyB,MAAM,IADf,EAAU,CACK,CAAA,CAAU,YAAY,GAGrD,IAAkC,MAAM,GAC5C,EAAO,UAAU,IACnB;CAYA,OATA,EAAW,GAA0B,EAAO,KAAK,GAK7C,KACF,EAAQ,GAGH,IAAI,SAAS,GAAS,MAAW;EACtC,IAAI;GA0BF,AAzBA,IAAc,EAAU,EACtB,QAAQ;IACN,IAAM,UAAgB;KAMpB,EAAQ;MAJN,WAAW,MAAU,EAAW,GAA0B,CAAK;MAC/D;KAGM,CAAQ;IAClB;IAEA,aACE,EAAE,GAAc;KACd;KACA,WAAW,EAAY;KACvB;KACA;KACA,UAAU,EAAO;KACjB,SAAS,EAAO;KAChB,KAAK;KACL;IACF,CAAC;GACL,EACF,CAAC,GAED,EAAY,MAAM,CAAS;EAC7B,SAAS,GAAO;GACd,EAAO,CAAK;EACd;CACF,CAAC;AACH;AAEA,SAAS,IAAgB;CACvB,AAAI,MACF,EAAY,QAAQ,GACpB,IAAc,MACd,EAAgB,QAAQ;AAE5B;AAEA,SAAS,EACP,GACA,GACM;CACD,MAID,EAAM,gBACR,EAAU,MAAM,YAAY,iBAAiB,EAAM,YAAY,GAG7D,EAAM,iBAAiB,KAAA,MACzB,EAAU,MAAM,YAAY,gBAAgB,GAAG,EAAM,aAAa,GAAG,GACrE,EAAU,MAAM,YACd,mBACA,GAAG,KAAK,IAAI,GAAG,EAAM,eAAe,CAAC,EAAE,GACzC,GACA,EAAU,MAAM,YACd,mBACA,GAAG,EAAM,eAAe,EAAE,GAC5B;AAEJ;AAQI,OAAO,SAAW,QACpB,OAEE,mBAAmB;CARrB;CACA;AAOqB"}