@templatical/editor 0.10.0 → 0.10.1

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 (128) hide show
  1. package/dist/{AiChatSidebar-D30WPhbv.js → AiChatSidebar-Dz5bH1z3.js} +13 -13
  2. package/dist/{AiFeatureMenu-B5CJX5zr.js → AiFeatureMenu-D2Xn0jFx.js} +7 -7
  3. package/dist/{BlockIssueBadge-CkB4Yyz2.js → BlockIssueBadge-CnqD1cGo.js} +5 -5
  4. package/dist/{CloudEditor-nT-R769W.js → CloudEditor-BizZwsfD.js} +158 -155
  5. package/dist/{CollaboratorBar-CwhlXODK.js → CollaboratorBar-Bn2JDu6l.js} +4 -4
  6. package/dist/{CommentsSidebar-gpZMMI5w.js → CommentsSidebar-BAG6rdVC.js} +12 -12
  7. package/dist/{CountdownBlock-BNvuXucv.js → CountdownBlock-B_Hr9Bm9.js} +3 -3
  8. package/dist/{CountdownToolbar-Dl82DAmI.js → CountdownToolbar-DaqDLKLk.js} +3 -3
  9. package/dist/{DesignReferenceSidebar-Bs5AMxVd.js → DesignReferenceSidebar-I9LWjvrj.js} +9 -9
  10. package/dist/{IssuesPanel-CqQa2BtU.js → IssuesPanel-B32Ifp4x.js} +8 -8
  11. package/dist/{LoadingTrack-xCOLUR3o.js → LoadingTrack-UTqOUN4O.js} +1 -1
  12. package/dist/{ModuleBrowserModal-BWWgF0LC.js → ModuleBrowserModal-DodRped1.js} +10 -10
  13. package/dist/{ModulePreviewCanvas-D7Tk5HOt.js → ModulePreviewCanvas-DhcnddJF.js} +3 -3
  14. package/dist/{NumberWithSuffix-DVy5HxMi.js → NumberWithSuffix-DB7GyyCI.js} +3 -3
  15. package/dist/{ParagraphEditor-DVSGdMOo.js → ParagraphEditor-pJA9BHAL.js} +25 -25
  16. package/dist/{RichTextEditorContent-DN-fRjMa.js → RichTextEditorContent-dTGSUff_.js} +6 -6
  17. package/dist/{SaveModuleDialog-CkEYkyVD.js → SaveModuleDialog-D634e99d.js} +7 -7
  18. package/dist/{SnapshotHistory-Nx9wrlbF.js → SnapshotHistory-m_nGAHlb.js} +9 -9
  19. package/dist/{TemplateScoringPanel-BG9M-29t.js → TemplateScoringPanel-BOQh9neV.js} +14 -14
  20. package/dist/{TestEmailModal-CRjtEs6S.js → TestEmailModal-DOcwoKkc.js} +5 -5
  21. package/dist/{TitleEditor-CvtV4pCA.js → TitleEditor-t6JMWamY.js} +12 -12
  22. package/dist/{TplModal-BudEYVcJ.js → TplModal-BAtbfDB0.js} +4 -4
  23. package/dist/{blockTypeIcons-Dd-UvfnC.js → blockTypeIcons-C4lXx3Au.js} +2 -2
  24. package/dist/bundle-stats.json +6 -6
  25. package/dist/cdn/chunks/{AiFeatureMenu-DKOv8VnB.js → AiFeatureMenu-BeOyHAoZ.js} +3 -3
  26. package/dist/cdn/chunks/{AiFeatureMenu-DKOv8VnB.js.map → AiFeatureMenu-BeOyHAoZ.js.map} +1 -1
  27. package/dist/cdn/chunks/{BlockIssueBadge-DpiSTwM7.js → BlockIssueBadge-C6YilQdl.js} +3 -3
  28. package/dist/cdn/chunks/{BlockIssueBadge-DpiSTwM7.js.map → BlockIssueBadge-C6YilQdl.js.map} +1 -1
  29. package/dist/cdn/chunks/{CloudEditor-xc_uOEgn.js → CloudEditor-DEA37rdW.js} +35 -32
  30. package/dist/cdn/chunks/CloudEditor-DEA37rdW.js.map +1 -0
  31. package/dist/cdn/chunks/{CollaboratorBar-VWfPri_h.js → CollaboratorBar-CKW7jOW4.js} +4 -4
  32. package/dist/cdn/chunks/{CollaboratorBar-VWfPri_h.js.map → CollaboratorBar-CKW7jOW4.js.map} +1 -1
  33. package/dist/cdn/chunks/{CountdownBlock-BKsCWboK.js → CountdownBlock-DU9ga9Ki.js} +3 -3
  34. package/dist/cdn/chunks/{CountdownBlock-BKsCWboK.js.map → CountdownBlock-DU9ga9Ki.js.map} +1 -1
  35. package/dist/cdn/chunks/{CountdownToolbar-BLtECDNb.js → CountdownToolbar-BHWsxth7.js} +4 -4
  36. package/dist/cdn/chunks/{CountdownToolbar-BLtECDNb.js.map → CountdownToolbar-BHWsxth7.js.map} +1 -1
  37. package/dist/cdn/chunks/{IssuesPanel-BW2piyvs.js → IssuesPanel-BkYhij39.js} +4 -4
  38. package/dist/cdn/chunks/{IssuesPanel-BW2piyvs.js.map → IssuesPanel-BkYhij39.js.map} +1 -1
  39. package/dist/cdn/chunks/{ModuleBrowserModal-TLlKpvjX.js → ModuleBrowserModal-D51w942J.js} +6 -6
  40. package/dist/cdn/chunks/{ModuleBrowserModal-TLlKpvjX.js.map → ModuleBrowserModal-D51w942J.js.map} +1 -1
  41. package/dist/cdn/chunks/{ModulePreviewCanvas-wu7y-vrh.js → ModulePreviewCanvas-BqTqcKHS.js} +3 -3
  42. package/dist/cdn/chunks/{ModulePreviewCanvas-wu7y-vrh.js.map → ModulePreviewCanvas-BqTqcKHS.js.map} +1 -1
  43. package/dist/cdn/chunks/{NumberWithSuffix-DxoUtTMr.js → NumberWithSuffix-DuUcF2zG.js} +3 -3
  44. package/dist/cdn/chunks/{NumberWithSuffix-DxoUtTMr.js.map → NumberWithSuffix-DuUcF2zG.js.map} +1 -1
  45. package/dist/cdn/chunks/{ParagraphEditor-DvxIO2LN.js → ParagraphEditor-Bqjn3ZNm.js} +19 -19
  46. package/dist/cdn/chunks/{ParagraphEditor-DvxIO2LN.js.map → ParagraphEditor-Bqjn3ZNm.js.map} +1 -1
  47. package/dist/cdn/chunks/{RichTextEditorContent-Dm9GXJmo.js → RichTextEditorContent-mIkkb5EK.js} +3 -3
  48. package/dist/cdn/chunks/{RichTextEditorContent-Dm9GXJmo.js.map → RichTextEditorContent-mIkkb5EK.js.map} +1 -1
  49. package/dist/cdn/chunks/{SaveModuleDialog-BRAdVcYM.js → SaveModuleDialog-Felfmkcj.js} +3 -3
  50. package/dist/cdn/chunks/{SaveModuleDialog-BRAdVcYM.js.map → SaveModuleDialog-Felfmkcj.js.map} +1 -1
  51. package/dist/cdn/chunks/{TitleEditor-D3gPRd0x.js → TitleEditor-Dcldr8D6.js} +9 -9
  52. package/dist/cdn/chunks/{TitleEditor-D3gPRd0x.js.map → TitleEditor-Dcldr8D6.js.map} +1 -1
  53. package/dist/cdn/chunks/{blockTypeIcons-C2cm4RjU.js → blockTypeIcons-D05Wqf5u.js} +3 -3
  54. package/dist/cdn/chunks/{blockTypeIcons-C2cm4RjU.js.map → blockTypeIcons-D05Wqf5u.js.map} +1 -1
  55. package/dist/cdn/chunks/{draggable-BwWMFq33.js → draggable-J_1CPXYc.js} +1254 -1253
  56. package/dist/cdn/chunks/draggable-J_1CPXYc.js.map +1 -0
  57. package/dist/cdn/chunks/{extensions-SS1ywPUR.js → extensions-CNmpC18A.js} +108 -105
  58. package/dist/cdn/chunks/{extensions-SS1ywPUR.js.map → extensions-CNmpC18A.js.map} +1 -1
  59. package/dist/cdn/chunks/{features-CwZTdcbt.js → features-_ar9QbVv.js} +264 -258
  60. package/dist/cdn/chunks/{features-CwZTdcbt.js.map → features-_ar9QbVv.js.map} +1 -1
  61. package/dist/cdn/chunks/{icons-CbNEr1kc.js → icons-CnwCLJX-.js} +12 -12
  62. package/dist/cdn/chunks/{icons-CbNEr1kc.js.map → icons-CnwCLJX-.js.map} +1 -1
  63. package/dist/cdn/chunks/{media-library-BRpHZOl7.js → media-library-9jyt7Bf9.js} +10 -6
  64. package/dist/cdn/chunks/media-library-9jyt7Bf9.js.map +1 -0
  65. package/dist/cdn/chunks/{quality-BqJqIPRU.js → quality-CO9mj_RH.js} +2 -2
  66. package/dist/cdn/chunks/{quality-BqJqIPRU.js.map → quality-CO9mj_RH.js.map} +1 -1
  67. package/dist/cdn/chunks/{renderer-CGVYkdUi.js → renderer-m6XTCWCL.js} +55 -54
  68. package/dist/cdn/chunks/renderer-m6XTCWCL.js.map +1 -0
  69. package/dist/cdn/chunks/{src-CvzfrFlT.js → src-DfMSYqvE.js} +5 -5
  70. package/dist/cdn/chunks/{src-CvzfrFlT.js.map → src-DfMSYqvE.js.map} +1 -1
  71. package/dist/cdn/chunks/{styles-2P5yvfsS.js → styles-1uFWdD5T.js} +17 -17
  72. package/dist/cdn/chunks/{styles-2P5yvfsS.js.map → styles-1uFWdD5T.js.map} +1 -1
  73. package/dist/cdn/chunks/{tiptap-BBbH3IT9.js → tiptap-CJbIm_hE.js} +5 -5
  74. package/dist/cdn/chunks/{tiptap-BBbH3IT9.js.map → tiptap-CJbIm_hE.js.map} +1 -1
  75. package/dist/cdn/editor.css +1 -1
  76. package/dist/cdn/editor.js +7 -7
  77. package/dist/{check-ChQyfxJ3.js → check-Bs6_uQpm.js} +1 -1
  78. package/dist/{chevron-down-DJjo0jSV.js → chevron-down-so1rnGwF.js} +1 -1
  79. package/dist/{circle-alert-CPH6l3Lc.js → circle-alert-CrKv0AuW.js} +1 -1
  80. package/dist/{clock-DHl_BIkU.js → clock-Cpx6GYpa.js} +1 -1
  81. package/dist/{cloud-BBC7bv8q.js → cloud-bHhCNRZa.js} +80 -74
  82. package/dist/{createLucideIcon-XgXOJ05E.js → createLucideIcon-DFBxEm5K.js} +3 -3
  83. package/dist/{dist-C0jo8wtG.js → dist-0RguD1vS.js} +1 -1
  84. package/dist/{dist-CNLAS2v2.js → dist-2-A7SaKm.js} +3 -3
  85. package/dist/{dist-UK-lbEBc.js → dist-74n2Mqc6.js} +1 -1
  86. package/dist/{dist-BzuC8o3y.js → dist-B3CcePtK.js} +3 -3
  87. package/dist/{dist-D8C6jIXM.js → dist-BejBMbBX.js} +3 -3
  88. package/dist/{dist-DILjuzSv.js → dist-Bvje_Tqb.js} +1 -1
  89. package/dist/{dist-BDgf2G-V.js → dist-BxHa6kIT.js} +3 -3
  90. package/dist/{dist-CUpJmrjt.js → dist-CIK3BYgh.js} +1 -1
  91. package/dist/{dist-C8wMh_gi.js → dist-CMkZaqX1.js} +1 -1
  92. package/dist/{dist-BxP6TB0l.js → dist-CoaWXQ7N.js} +1 -1
  93. package/dist/{dist-D5lmdi1F.js → dist-D1YvgM6p.js} +1 -1
  94. package/dist/{dist-DYO-w_Jf.js → dist-DJ5YJLXn.js} +1 -1
  95. package/dist/{dist-DXaxGLsw.js → dist-DwEpKyry.js} +1 -1
  96. package/dist/{extensions-C87ZSllQ.js → extensions-C810eSzv.js} +107 -104
  97. package/dist/{image-up-CPBCOMit.js → image-up-kMLE5GsI.js} +1 -1
  98. package/dist/{info-DIY9mguM.js → info-xqRxLfNz.js} +1 -1
  99. package/dist/{keys-Vt3XipJl.js → keys-BoYBr3PU.js} +1 -1
  100. package/dist/{list-checks-CSCyu3fH.js → list-checks-C81htkBJ.js} +1 -1
  101. package/dist/{loader-circle-Rz_4vJLH.js → loader-circle-C6cZPIum.js} +1 -1
  102. package/dist/{message-circle-D-umK_MU.js → message-circle-dqOBRe07.js} +1 -1
  103. package/dist/{refresh-cw-CvWF4jfR.js → refresh-cw-DCjNd6o0.js} +1 -1
  104. package/dist/{scan-line-wanvAFDr.js → scan-line-DXz0nZVJ.js} +1 -1
  105. package/dist/{send-BhbhbIFT.js → send-C4uH_WaI.js} +1 -1
  106. package/dist/{shield-check-CXPPMWth.js → shield-check-B3U68ssA.js} +1 -1
  107. package/dist/{sparkles-CrUN0KWY.js → sparkles-CsDweGUy.js} +1 -1
  108. package/dist/style.css +1 -1
  109. package/dist/{styles-DOjWbqA9.js → styles-CBlNpqL9.js} +35 -35
  110. package/dist/templatical-editor.js +5 -5
  111. package/dist/{text-align-end-Bkq8oBrD.js → text-align-start-BkKQePFp.js} +11 -11
  112. package/dist/{trash-2-BpY5BCLT.js → trash-2-BIOkaEz1.js} +1 -1
  113. package/dist/{triangle-alert-MwJBKR2e.js → triangle-alert-Bbgu6uUG.js} +1 -1
  114. package/dist/{useAliveFlag-BLyG8L4d.js → useAliveFlag-Bc99FWyR.js} +1 -1
  115. package/dist/{useCloudI18n-sRfoQCZY.js → useCloudI18n-DiwsLi6z.js} +2 -2
  116. package/dist/{useEditorCore-DxApq2hZ.js → useEditorCore-7c1QpPlw.js} +20 -20
  117. package/dist/{useI18n-lF6hYgZu.js → useI18n-DskZMfRJ.js} +2 -2
  118. package/dist/{useMergeTag-CZVI7Xe5.js → useMergeTag-Co4xYwG6.js} +3 -3
  119. package/dist/usePopoverRoot-DYH_gX8o.js +8 -0
  120. package/dist/{vue.runtime.esm-bundler-BDSGA5hA.js → vue.runtime.esm-bundler-D0Hg03Ub.js} +1289 -1288
  121. package/dist/{x-rcnxRG8Y.js → x-DWU6NCuE.js} +1 -1
  122. package/package.json +9 -9
  123. package/dist/cdn/chunks/CloudEditor-xc_uOEgn.js.map +0 -1
  124. package/dist/cdn/chunks/draggable-BwWMFq33.js.map +0 -1
  125. package/dist/cdn/chunks/media-library-BRpHZOl7.js.map +0 -1
  126. package/dist/cdn/chunks/renderer-CGVYkdUi.js.map +0 -1
  127. package/dist/usePopoverRoot-p2BanBI7.js +0 -8
  128. package/dist/{dist-GAmhYvUK.js → dist-BufRk8ZY.js} +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"src-CvzfrFlT.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","import type en from \"./locales/en\";\n\nexport type MediaTranslations = typeof en;\n\nconst supportedLocales = [\"en\", \"de\", \"pt-BR\"] as const;\ntype SupportedLocale = (typeof supportedLocales)[number];\n\nfunction canonicalize(locale: string): string {\n return locale.trim().replace(/_/g, \"-\").toLowerCase();\n}\n\nfunction findSupportedLocale(locale: string): SupportedLocale | 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): SupportedLocale {\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 module = (await import(`./locales/${target}.ts`)) as {\n default: MediaTranslations;\n };\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-DfMSYqvE.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","import type en from \"./locales/en\";\n\nexport type MediaTranslations = typeof en;\n\nconst supportedLocales = [\"en\", \"de\", \"pt-BR\"] as const;\ntype SupportedLocale = (typeof supportedLocales)[number];\n\nfunction canonicalize(locale: string): string {\n return locale.trim().replace(/_/g, \"-\").toLowerCase();\n}\n\nfunction findSupportedLocale(locale: string): SupportedLocale | 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): SupportedLocale {\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 module = (await import(`./locales/${target}.ts`)) as {\n default: MediaTranslations;\n };\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,11 +1,11 @@
1
- import { C as e, F as t, G as n, H as r, J as i, L as a, M as o, O as s, P as c, T as l, V as u, Y as d, Z as f, b as p, c as m, ct as h, f as g, g as _, h as v, it as y, l as b, m as x, n as S, o as C, ot as w, p as T, s as E, st as D, t as ee, u as O, v as k, x as A, y as j, z as M } from "./draggable-BwWMFq33.js";
2
- import { $ as N, Bt as P, Cn as te, Ct as F, Dn as I, Dt as L, F as R, Ft as z, G as B, Gt as ne, H as re, I as ie, J as ae, Jt as oe, K as se, Kt as ce, L as le, Lt as ue, M as de, Mt as fe, N as pe, O as V, P as me, Pt as he, Qt as ge, R as _e, St as ve, Tn as ye, Tt as be, U as xe, V as Se, Vt as Ce, W as we, Wt as Te, Xt as Ee, Yt as De, Zt as Oe, _n as ke, at as Ae, bt as je, ct as Me, dn as Ne, et as Pe, hn as Fe, in as Ie, it as Le, j as Re, kt as ze, mn as Be, mt as Ve, nn as He, q as Ue, qt as We, rn as Ge, rt as Ke, tn as qe, ut as Je, vn as Ye, wn as Xe, wt as Ze, xn as Qe, xt as $e, yn as et, yt as tt, z as nt, zt as rt } from "./features-CwZTdcbt.js";
3
- import { A as it, F as at, G as ot, I as st, M as ct, N as lt, O as ut, P as dt, T as H, V as ft, Y as pt, _ as mt, b as ht, c as gt, h as _t, m as vt, o as yt, s as bt, u as xt, v as St, y as Ct, z as wt } from "./icons-CbNEr1kc.js";
1
+ import { C as e, F as t, G as n, H as r, J as i, L as a, M as o, O as s, P as c, T as l, V as u, Y as d, Z as f, b as p, c as m, ct as h, f as g, g as _, h as v, it as y, l as b, m as x, n as S, o as C, ot as w, p as T, s as E, st as D, t as ee, u as O, v as k, x as A, y as j, z as M } from "./draggable-J_1CPXYc.js";
2
+ import { $ as N, Bt as P, Cn as te, Ct as F, Dn as I, Dt as L, F as R, Ft as z, G as B, Gt as ne, H as re, I as ie, J as ae, Jt as oe, K as se, Kt as ce, L as le, Lt as ue, M as de, Mt as fe, N as pe, O as V, P as me, Pt as he, Qt as ge, R as _e, St as ve, Tn as ye, Tt as be, U as xe, V as Se, Vt as Ce, W as we, Wt as Te, Xt as Ee, Yt as De, Zt as Oe, _n as ke, at as Ae, bt as je, ct as Me, dn as Ne, et as Pe, hn as Fe, in as Ie, it as Le, j as Re, kt as ze, mn as Be, mt as Ve, nn as He, q as Ue, qt as We, rn as Ge, rt as Ke, tn as qe, ut as Je, vn as Ye, wn as Xe, wt as Ze, xn as Qe, xt as $e, yn as et, yt as tt, z as nt, zt as rt } from "./features-_ar9QbVv.js";
3
+ import { A as it, F as at, G as ot, I as st, M as ct, N as lt, O as ut, P as dt, T as H, V as ft, Y as pt, _ as mt, b as ht, c as gt, h as _t, m as vt, o as yt, s as bt, u as xt, v as St, y as Ct, z as wt } from "./icons-CnwCLJX-.js";
4
4
  import { t as Tt } from "./readableTextColor-f8Kykfnh.js";
5
- import { t as Et } from "./CountdownBlock-BKsCWboK.js";
6
- import { t as Dt } from "./blockTypeIcons-C2cm4RjU.js";
5
+ import { t as Et } from "./CountdownBlock-DU9ga9Ki.js";
6
+ import { t as Dt } from "./blockTypeIcons-D05Wqf5u.js";
7
7
  import { _ as Ot, c as kt, f as U, g as At, h as W, l as jt, m as G, p as K, t as Mt } from "./styleConstants-lGobwiLH.js";
8
- import { i as q, n as J, r as Y, t as Nt } from "./NumberWithSuffix-DxoUtTMr.js";
8
+ import { i as q, n as J, r as Y, t as Nt } from "./NumberWithSuffix-DuUcF2zG.js";
9
9
  //#region src/utils/resolveLintOptions.ts
10
10
  function Pt(e) {
11
11
  return {
@@ -1860,7 +1860,7 @@ var Mi = {
1860
1860
  {
1861
1861
  value: "left",
1862
1862
  label: i.title.alignLeft,
1863
- icon: bt
1863
+ icon: yt
1864
1864
  },
1865
1865
  {
1866
1866
  value: "center",
@@ -1870,7 +1870,7 @@ var Mi = {
1870
1870
  {
1871
1871
  value: "right",
1872
1872
  label: i.title.alignRight,
1873
- icon: yt
1873
+ icon: bt
1874
1874
  }
1875
1875
  ]);
1876
1876
  function l(e, t) {
@@ -2184,7 +2184,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2184
2184
  {
2185
2185
  value: "left",
2186
2186
  label: y(i).title.alignLeft,
2187
- icon: y(bt)
2187
+ icon: y(yt)
2188
2188
  },
2189
2189
  {
2190
2190
  value: "center",
@@ -2194,7 +2194,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2194
2194
  {
2195
2195
  value: "right",
2196
2196
  label: y(i).title.alignRight,
2197
- icon: y(yt)
2197
+ icon: y(bt)
2198
2198
  }
2199
2199
  ],
2200
2200
  "model-value": e.block.align,
@@ -2363,7 +2363,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2363
2363
  {
2364
2364
  value: "left",
2365
2365
  label: y(i).title.alignLeft,
2366
- icon: y(bt)
2366
+ icon: y(yt)
2367
2367
  },
2368
2368
  {
2369
2369
  value: "center",
@@ -2373,7 +2373,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2373
2373
  {
2374
2374
  value: "right",
2375
2375
  label: y(i).title.alignRight,
2376
- icon: y(yt)
2376
+ icon: y(bt)
2377
2377
  }
2378
2378
  ],
2379
2379
  "model-value": e.block.textAlign,
@@ -2421,7 +2421,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2421
2421
  {
2422
2422
  value: "left",
2423
2423
  label: y(r).title.alignLeft,
2424
- icon: y(bt)
2424
+ icon: y(yt)
2425
2425
  },
2426
2426
  {
2427
2427
  value: "center",
@@ -2431,7 +2431,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2431
2431
  {
2432
2432
  value: "right",
2433
2433
  label: y(r).title.alignRight,
2434
- icon: y(yt)
2434
+ icon: y(bt)
2435
2435
  }
2436
2436
  ],
2437
2437
  "model-value": e.block.textAlign,
@@ -2560,7 +2560,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2560
2560
  "duplicate"
2561
2561
  ],
2562
2562
  setup(e, { emit: t }) {
2563
- let n = p(() => import("./CountdownToolbar-BLtECDNb.js")), r = e, i = t, { t: s } = z(), c = Ie(De, "Toolbar"), u = l(ne, []), d = g(() => r.block.type), f = g(() => I(r.block)), m = g(() => {
2563
+ let n = p(() => import("./CountdownToolbar-BHWsxth7.js")), r = e, i = t, { t: s } = z(), c = Ie(De, "Toolbar"), u = l(ne, []), d = g(() => r.block.type), f = g(() => I(r.block)), m = g(() => {
2564
2564
  if (f.value) return u.find((e) => e.type === r.block.customType);
2565
2565
  }), b = g(() => f.value ? m.value?.name ?? r.block.customType : he(d.value, s)), S = c.fonts;
2566
2566
  function C(e) {
@@ -2708,7 +2708,7 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
2708
2708
  "update-settings"
2709
2709
  ],
2710
2710
  setup(e, { emit: t }) {
2711
- let n = p(() => import("./IssuesPanel-BW2piyvs.js")), r = e, i = t, { t: a } = z(), s = f("content"), c = l(qe, null), u = g(() => c !== null), d = g(() => c?.issues.value.length ?? 0);
2711
+ let n = p(() => import("./IssuesPanel-BkYhij39.js")), r = e, i = t, { t: a } = z(), s = f("content"), c = l(qe, null), u = g(() => c !== null), d = g(() => c?.issues.value.length ?? 0);
2712
2712
  function m(e) {
2713
2713
  return s.value === e ? "tpl:flex-1 tpl:text-[var(--tpl-primary)]" : "tpl:shrink-0 tpl:text-[var(--tpl-text-muted)] hover:tpl:text-[var(--tpl-text)]";
2714
2714
  }
@@ -3226,4 +3226,4 @@ var Ea = { class: "tpl:mb-3.5" }, Da = ["value"], Oa = ["value"], ka = /* @__PUR
3226
3226
  //#endregion
3227
3227
  export { Fs as a, Gt as c, Ls as i, Wt as l, Hs as n, Ms as o, zs as r, en as s, oc as t, Pt as u };
3228
3228
 
3229
- //# sourceMappingURL=styles-2P5yvfsS.js.map
3229
+ //# sourceMappingURL=styles-1uFWdD5T.js.map