@templatical/editor 0.27.6 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/dist/{AiChatSidebar-jbpwD_4k.js → AiChatSidebar-mZyf81xG.js} +14 -14
  2. package/dist/{AiFeatureMenu-BeZR46ZG.js → AiFeatureMenu-wpL2vbbd.js} +7 -7
  3. package/dist/{BlockIssueBadge-B8wQY1tM.js → BlockIssueBadge-CavnyR3o.js} +5 -5
  4. package/dist/{BlockPreviewCanvas-CIjts7SP.js → BlockPreviewCanvas-CeNJqtJ6.js} +3 -3
  5. package/dist/{CloudHeaderExtras-mMqnnTi1.js → CloudHeaderExtras-fH0cB-Ru.js} +5 -5
  6. package/dist/{CloudPanels-fiTneIeJ.js → CloudPanels-Davlnzfd.js} +7 -7
  7. package/dist/{CollaboratorBar-C48K85la.js → CollaboratorBar-BvQZriPA.js} +4 -4
  8. package/dist/{ColorPicker-Bc1lGovM.js → ColorPicker-OLSFZBBZ.js} +7 -7
  9. package/dist/{CommentsPanel-D5Ljv1oj.js → CommentsPanel-B4_63eIS.js} +2 -2
  10. package/dist/{CommentsSidebar-C5mDJVjC.js → CommentsSidebar-BkBHMXez.js} +14 -14
  11. package/dist/{CountdownBlock-qKtJVRIV.js → CountdownBlock-Drr1WErd.js} +3 -3
  12. package/dist/{CountdownToolbar-B-9EdQvm.js → CountdownToolbar-D8FsDIfa.js} +4 -4
  13. package/dist/{DesignReferenceSidebar-DOy4ENYv.js → DesignReferenceSidebar-Dp44REBY.js} +11 -11
  14. package/dist/{IssuesPanel-DZUehVZS.js → IssuesPanel-C1v3dmoB.js} +8 -8
  15. package/dist/{LoadingTrack-C2T8ixEL.js → LoadingTrack-Db9j_aBr.js} +1 -1
  16. package/dist/{MergeTagModeToggle-Fn9Q1SrJ.js → MergeTagModeToggle-CZN0Pr1o.js} +5 -5
  17. package/dist/{MergeTagSuggestion-DflUPfkT.js → MergeTagSuggestion-a7Tk8tBB.js} +2 -2
  18. package/dist/{NumberWithSuffix-DZAktKby.js → NumberWithSuffix-C1D0WFrN.js} +1 -1
  19. package/dist/{ParagraphEditor-BwTQoxxF.js → ParagraphEditor-CGxsm0Mx.js} +15 -15
  20. package/dist/{RestoreVersionDialog-CVuUY3CK.js → RestoreVersionDialog-BLW8wC1J.js} +5 -5
  21. package/dist/{RichTextEditorContent-CoXoAfZ1.js → RichTextEditorContent-COBy_Q9j.js} +8 -8
  22. package/dist/{SaveBlockDialog-Bn5JtRSE.js → SaveBlockDialog-DPDQTGTB.js} +10 -10
  23. package/dist/{SavedBlocksBrowserModal-WWGhUC8R.js → SavedBlocksBrowserModal-D8a-wIRe.js} +11 -11
  24. package/dist/{SavedBlocksPanels-R_4C58EN.js → SavedBlocksPanels-CmnGyJHO.js} +2 -2
  25. package/dist/{SavedBlocksPickBar-D5KZVvvu.js → SavedBlocksPickBar-Z-YRd488.js} +4 -4
  26. package/dist/{TemplateScoringPanel-Cz25F9Cf.js → TemplateScoringPanel-5zp1qOSl.js} +15 -15
  27. package/dist/{TestEmailModal-C_C228mX.js → TestEmailModal-C69UbsNy.js} +10 -10
  28. package/dist/{TestEmailPanel-D7YOLrOb.js → TestEmailPanel-CH2dG-8A.js} +2 -2
  29. package/dist/{TitleEditor-XOQQlb1V.js → TitleEditor-BfWPus_C.js} +10 -10
  30. package/dist/{TplModal-DLXIufsn.js → TplModal-DBlMd7h9.js} +5 -5
  31. package/dist/{VersionHistoryMenu-Bk5zEClP.js → VersionHistoryMenu-Cg4UKxKc.js} +8 -8
  32. package/dist/{VersionHistoryPanels-D-km60IA.js → VersionHistoryPanels-BKjbNEOM.js} +2 -2
  33. package/dist/{VersionPreviewBanner-PMaxy3tA.js → VersionPreviewBanner-B0thyJ8F.js} +3 -3
  34. package/dist/{blockTypeIcons-BG5c5gc8.js → blockTypeIcons-CQMkcHo9.js} +2 -2
  35. package/dist/bundle-stats.json +6 -6
  36. package/dist/{ca-CEuJ6IRr.js → ca-DY0AYOLG.js} +6 -0
  37. package/dist/cdn/chunks/{AiChatSidebar-hq9GgASn.js → AiChatSidebar-BQATQ3Tr.js} +8 -8
  38. package/dist/cdn/chunks/{AiChatSidebar-hq9GgASn.js.map → AiChatSidebar-BQATQ3Tr.js.map} +1 -1
  39. package/dist/cdn/chunks/{AiFeatureMenu-B8B-XgQB.js → AiFeatureMenu-cNoZ0xl_.js} +6 -6
  40. package/dist/cdn/chunks/{AiFeatureMenu-B8B-XgQB.js.map → AiFeatureMenu-cNoZ0xl_.js.map} +1 -1
  41. package/dist/cdn/chunks/{BlockIssueBadge-DOvq0xJb.js → BlockIssueBadge-CH_3vFw4.js} +5 -5
  42. package/dist/cdn/chunks/{BlockIssueBadge-DOvq0xJb.js.map → BlockIssueBadge-CH_3vFw4.js.map} +1 -1
  43. package/dist/cdn/chunks/{BlockPreviewCanvas-ZN-5MezA.js → BlockPreviewCanvas-9tFXPVgi.js} +4 -4
  44. package/dist/cdn/chunks/{BlockPreviewCanvas-ZN-5MezA.js.map → BlockPreviewCanvas-9tFXPVgi.js.map} +1 -1
  45. package/dist/cdn/chunks/{CloudHeaderExtras-Dbd6brlz.js → CloudHeaderExtras-CUAM2ADe.js} +5 -5
  46. package/dist/cdn/chunks/{CloudHeaderExtras-Dbd6brlz.js.map → CloudHeaderExtras-CUAM2ADe.js.map} +1 -1
  47. package/dist/cdn/chunks/{CloudPanels-CxkGH1dy.js → CloudPanels-DMnnSIkX.js} +7 -7
  48. package/dist/cdn/chunks/{CloudPanels-CxkGH1dy.js.map → CloudPanels-DMnnSIkX.js.map} +1 -1
  49. package/dist/cdn/chunks/{CollaboratorBar-DpP8oKTU.js → CollaboratorBar-C6sorNRi.js} +5 -5
  50. package/dist/cdn/chunks/{CollaboratorBar-DpP8oKTU.js.map → CollaboratorBar-C6sorNRi.js.map} +1 -1
  51. package/dist/cdn/chunks/{ColorPicker-BsYEtL7B.js → ColorPicker-q1V7ggWI.js} +7 -7
  52. package/dist/cdn/chunks/{ColorPicker-BsYEtL7B.js.map → ColorPicker-q1V7ggWI.js.map} +1 -1
  53. package/dist/cdn/chunks/{CommentsPanel-B1B_UQ2z.js → CommentsPanel-ExfxJZM3.js} +3 -3
  54. package/dist/cdn/chunks/{CommentsPanel-B1B_UQ2z.js.map → CommentsPanel-ExfxJZM3.js.map} +1 -1
  55. package/dist/cdn/chunks/{CommentsSidebar-B4waNT5L.js → CommentsSidebar-CzALURMJ.js} +5 -5
  56. package/dist/cdn/chunks/{CommentsSidebar-B4waNT5L.js.map → CommentsSidebar-CzALURMJ.js.map} +1 -1
  57. package/dist/cdn/chunks/{CountdownBlock-BKrYGRiT.js → CountdownBlock-_7TUBqJS.js} +4 -4
  58. package/dist/cdn/chunks/{CountdownBlock-BKrYGRiT.js.map → CountdownBlock-_7TUBqJS.js.map} +1 -1
  59. package/dist/cdn/chunks/{CountdownToolbar-DhJg2sQa.js → CountdownToolbar-CkbWSrAH.js} +5 -5
  60. package/dist/cdn/chunks/{CountdownToolbar-DhJg2sQa.js.map → CountdownToolbar-CkbWSrAH.js.map} +1 -1
  61. package/dist/cdn/chunks/{DesignReferenceSidebar-4Ds4D0M0.js → DesignReferenceSidebar-COh0Rx_A.js} +7 -7
  62. package/dist/cdn/chunks/{DesignReferenceSidebar-4Ds4D0M0.js.map → DesignReferenceSidebar-COh0Rx_A.js.map} +1 -1
  63. package/dist/cdn/chunks/{IssuesPanel-CyGgRHuI.js → IssuesPanel-C1NG0xRI.js} +6 -6
  64. package/dist/cdn/chunks/{IssuesPanel-CyGgRHuI.js.map → IssuesPanel-C1NG0xRI.js.map} +1 -1
  65. package/dist/cdn/chunks/{LoadingTrack-Dp_QZvAK.js → LoadingTrack-D_wweXVz.js} +2 -2
  66. package/dist/cdn/chunks/{LoadingTrack-Dp_QZvAK.js.map → LoadingTrack-D_wweXVz.js.map} +1 -1
  67. package/dist/cdn/chunks/{MergeTagModeToggle-B_oHsH0i.js → MergeTagModeToggle-B1yXCp3D.js} +5 -5
  68. package/dist/cdn/chunks/{MergeTagModeToggle-B_oHsH0i.js.map → MergeTagModeToggle-B1yXCp3D.js.map} +1 -1
  69. package/dist/cdn/chunks/{MergeTagSuggestion-Df7jcLpS.js → MergeTagSuggestion-DqYR3jPA.js} +3 -3
  70. package/dist/cdn/chunks/{MergeTagSuggestion-Df7jcLpS.js.map → MergeTagSuggestion-DqYR3jPA.js.map} +1 -1
  71. package/dist/cdn/chunks/{NumberWithSuffix-DNBrbl4H.js → NumberWithSuffix-CWvM_I3T.js} +2 -2
  72. package/dist/cdn/chunks/{NumberWithSuffix-DNBrbl4H.js.map → NumberWithSuffix-CWvM_I3T.js.map} +1 -1
  73. package/dist/cdn/chunks/{ParagraphEditor-9GPXDRns.js → ParagraphEditor-DPM1hUKo.js} +22 -22
  74. package/dist/cdn/chunks/{ParagraphEditor-9GPXDRns.js.map → ParagraphEditor-DPM1hUKo.js.map} +1 -1
  75. package/dist/cdn/chunks/{RestoreVersionDialog-BWewwJIZ.js → RestoreVersionDialog-Dz0bX5ZZ.js} +5 -5
  76. package/dist/cdn/chunks/{RestoreVersionDialog-BWewwJIZ.js.map → RestoreVersionDialog-Dz0bX5ZZ.js.map} +1 -1
  77. package/dist/cdn/chunks/{RichTextEditorContent-DWD1--Yi.js → RichTextEditorContent-nkyIRAyN.js} +7 -7
  78. package/dist/cdn/chunks/{RichTextEditorContent-DWD1--Yi.js.map → RichTextEditorContent-nkyIRAyN.js.map} +1 -1
  79. package/dist/cdn/chunks/{SaveBlockDialog-DUyrK4nE.js → SaveBlockDialog-DVMxZbmf.js} +8 -8
  80. package/dist/cdn/chunks/{SaveBlockDialog-DUyrK4nE.js.map → SaveBlockDialog-DVMxZbmf.js.map} +1 -1
  81. package/dist/cdn/chunks/{SavedBlocksBrowserModal-DZrk2Fxx.js → SavedBlocksBrowserModal-C3nfKRQg.js} +9 -9
  82. package/dist/cdn/chunks/{SavedBlocksBrowserModal-DZrk2Fxx.js.map → SavedBlocksBrowserModal-C3nfKRQg.js.map} +1 -1
  83. package/dist/cdn/chunks/{SavedBlocksPanels-iSAXI4IM.js → SavedBlocksPanels-DVat5S7j.js} +3 -3
  84. package/dist/cdn/chunks/{SavedBlocksPanels-iSAXI4IM.js.map → SavedBlocksPanels-DVat5S7j.js.map} +1 -1
  85. package/dist/cdn/chunks/{SavedBlocksPickBar-CFeccSg9.js → SavedBlocksPickBar-Brg8US_n.js} +5 -5
  86. package/dist/cdn/chunks/{SavedBlocksPickBar-CFeccSg9.js.map → SavedBlocksPickBar-Brg8US_n.js.map} +1 -1
  87. package/dist/cdn/chunks/{TemplateScoringPanel-Ct5p7X_i.js → TemplateScoringPanel-DO86BvdQ.js} +6 -6
  88. package/dist/cdn/chunks/{TemplateScoringPanel-Ct5p7X_i.js.map → TemplateScoringPanel-DO86BvdQ.js.map} +1 -1
  89. package/dist/cdn/chunks/{TestEmailModal-BJo6q_Dm.js → TestEmailModal-CDx1Pqtx.js} +9 -9
  90. package/dist/cdn/chunks/{TestEmailModal-BJo6q_Dm.js.map → TestEmailModal-CDx1Pqtx.js.map} +1 -1
  91. package/dist/cdn/chunks/{TestEmailPanel-LuLd-ErE.js → TestEmailPanel--PpajGV7.js} +3 -3
  92. package/dist/cdn/chunks/{TestEmailPanel-LuLd-ErE.js.map → TestEmailPanel--PpajGV7.js.map} +1 -1
  93. package/dist/cdn/chunks/{TitleEditor-BsGfiDXQ.js → TitleEditor-CLkXt5RZ.js} +12 -12
  94. package/dist/cdn/chunks/{TitleEditor-BsGfiDXQ.js.map → TitleEditor-CLkXt5RZ.js.map} +1 -1
  95. package/dist/cdn/chunks/{TplModal-lUdHsbjL.js → TplModal-BhfPoZ_W.js} +5 -5
  96. package/dist/cdn/chunks/{TplModal-lUdHsbjL.js.map → TplModal-BhfPoZ_W.js.map} +1 -1
  97. package/dist/cdn/chunks/{VersionHistoryMenu-CXMPsVMR.js → VersionHistoryMenu-_DyRYBRP.js} +5 -5
  98. package/dist/cdn/chunks/{VersionHistoryMenu-CXMPsVMR.js.map → VersionHistoryMenu-_DyRYBRP.js.map} +1 -1
  99. package/dist/cdn/chunks/{VersionHistoryPanels-oTKA6TUS.js → VersionHistoryPanels-DGfOOcKV.js} +3 -3
  100. package/dist/cdn/chunks/{VersionHistoryPanels-oTKA6TUS.js.map → VersionHistoryPanels-DGfOOcKV.js.map} +1 -1
  101. package/dist/cdn/chunks/{VersionPreviewBanner-7DZLUVaE.js → VersionPreviewBanner-FbBmgknN.js} +4 -4
  102. package/dist/cdn/chunks/{VersionPreviewBanner-7DZLUVaE.js.map → VersionPreviewBanner-FbBmgknN.js.map} +1 -1
  103. package/dist/cdn/chunks/{blockTypeIcons-D8dtoELC.js → blockTypeIcons-o4ammRlm.js} +2 -2
  104. package/dist/cdn/chunks/{blockTypeIcons-D8dtoELC.js.map → blockTypeIcons-o4ammRlm.js.map} +1 -1
  105. package/dist/cdn/chunks/{ca-CEuJ6IRr.js → ca-DY0AYOLG.js} +7 -1
  106. package/dist/cdn/chunks/ca-DY0AYOLG.js.map +1 -0
  107. package/dist/cdn/chunks/{cloud-BA0OpRh-.js → cloud-CRCcXTc5.js} +2 -2
  108. package/dist/cdn/chunks/{cloud-BA0OpRh-.js.map → cloud-CRCcXTc5.js.map} +1 -1
  109. package/dist/cdn/chunks/{createCloudRuntime-CedWXagq.js → createCloudRuntime-C-u7oIGa.js} +7 -7
  110. package/dist/cdn/chunks/{createCloudRuntime-CedWXagq.js.map → createCloudRuntime-C-u7oIGa.js.map} +1 -1
  111. package/dist/{de-aRxhZF_K.js → cdn/chunks/de-CYLWugqb.js} +8 -0
  112. package/dist/cdn/chunks/de-CYLWugqb.js.map +1 -0
  113. package/dist/cdn/chunks/{dist-CM8TB0VD.js → dist-2fOlspdg.js} +3 -3
  114. package/dist/cdn/chunks/{dist-CM8TB0VD.js.map → dist-2fOlspdg.js.map} +1 -1
  115. package/dist/cdn/chunks/{dist-CYLJiSiH.js → dist-eKG4m5Wx.js} +2 -2
  116. package/dist/cdn/chunks/{dist-CYLJiSiH.js.map → dist-eKG4m5Wx.js.map} +1 -1
  117. package/dist/cdn/chunks/{draggable-BfpsXFg7.js → draggable-BLMjz0GK.js} +565 -579
  118. package/dist/cdn/chunks/{draggable-BfpsXFg7.js.map → draggable-BLMjz0GK.js.map} +1 -1
  119. package/dist/cdn/chunks/{en-BX4V_7YO.js → en-C3TM249M.js} +7 -1
  120. package/dist/cdn/chunks/en-C3TM249M.js.map +1 -0
  121. package/dist/cdn/chunks/en-C6FKrw69.js +2 -0
  122. package/dist/cdn/chunks/{es-CA9uQ-5x.js → es-D1SF4nCR.js} +7 -1
  123. package/dist/cdn/chunks/es-D1SF4nCR.js.map +1 -0
  124. package/dist/cdn/chunks/{extensions-P0lpi6k8.js → extensions-qSqWdFko.js} +6 -6
  125. package/dist/cdn/chunks/{extensions-P0lpi6k8.js.map → extensions-qSqWdFko.js.map} +1 -1
  126. package/dist/{fr-iBuE60Ap.js → cdn/chunks/fr-CdLhJ7kw.js} +8 -0
  127. package/dist/cdn/chunks/fr-CdLhJ7kw.js.map +1 -0
  128. package/dist/cdn/chunks/{icons-BrdgOeXm.js → icons-MeYdeH4P.js} +2 -2
  129. package/dist/cdn/chunks/{icons-BrdgOeXm.js.map → icons-MeYdeH4P.js.map} +1 -1
  130. package/dist/cdn/chunks/{keys-oJdkdtPn.js → keys-D7OpfE2s.js} +2 -2
  131. package/dist/cdn/chunks/{keys-oJdkdtPn.js.map → keys-D7OpfE2s.js.map} +1 -1
  132. package/dist/cdn/chunks/{nl-Btw4ojNo.js → nl-BvsLoyKp.js} +7 -1
  133. package/dist/cdn/chunks/nl-BvsLoyKp.js.map +1 -0
  134. package/dist/cdn/chunks/{pt-BR-GjVsCqbN.js → pt-BR-CAGS5YXp.js} +7 -1
  135. package/dist/cdn/chunks/pt-BR-CAGS5YXp.js.map +1 -0
  136. package/dist/cdn/chunks/{src-BS2ClsbB.js → src-2QDLdUyx.js} +93 -11
  137. package/dist/cdn/chunks/src-2QDLdUyx.js.map +1 -0
  138. package/dist/cdn/chunks/src-B_QJduQD.js.map +1 -1
  139. package/dist/cdn/chunks/{src-rhf0R6xZ.js → src-DgxiymKd.js} +62 -59
  140. package/dist/cdn/chunks/src-DgxiymKd.js.map +1 -0
  141. package/dist/cdn/chunks/{tiptap-DWeSx_P8.js → tiptap-DgH_wKK_.js} +2 -2
  142. package/dist/cdn/chunks/{tiptap-DWeSx_P8.js.map → tiptap-DgH_wKK_.js.map} +1 -1
  143. package/dist/cdn/chunks/{useAliveFlag-Dtm174fG.js → useAliveFlag-C1pwLtPO.js} +2 -2
  144. package/dist/cdn/chunks/{useAliveFlag-Dtm174fG.js.map → useAliveFlag-C1pwLtPO.js.map} +1 -1
  145. package/dist/cdn/chunks/{useCloudI18n-Ch-SiRjU.js → useCloudI18n-D4gzxtqF.js} +3 -3
  146. package/dist/cdn/chunks/{useCloudI18n-Ch-SiRjU.js.map → useCloudI18n-D4gzxtqF.js.map} +1 -1
  147. package/dist/cdn/chunks/{useEditorCore-CwJIw1Uy.js → useEditorCore-2ZVOY0Rh.js} +30 -25
  148. package/dist/cdn/chunks/{useEditorCore-CwJIw1Uy.js.map → useEditorCore-2ZVOY0Rh.js.map} +1 -1
  149. package/dist/cdn/chunks/useEditorRoot-BY-amddA.js +10 -0
  150. package/dist/cdn/chunks/{useEditorRoot-Cxnmf5hM.js.map → useEditorRoot-BY-amddA.js.map} +1 -1
  151. package/dist/cdn/chunks/{useI18n-4sUbTM3Y.js → useI18n-DYb1SgLB.js} +3 -3
  152. package/dist/cdn/chunks/{useI18n-4sUbTM3Y.js.map → useI18n-DYb1SgLB.js.map} +1 -1
  153. package/dist/cdn/chunks/{useMergeTag-DxjTEyin.js → useMergeTag-D-SE_XN8.js} +3 -3
  154. package/dist/cdn/chunks/{useMergeTag-DxjTEyin.js.map → useMergeTag-D-SE_XN8.js.map} +1 -1
  155. package/dist/cdn/chunks/{usePopoverPosition-C1N2kaiZ.js → usePopoverPosition-CJZ6EkS4.js} +3 -3
  156. package/dist/cdn/chunks/{usePopoverPosition-C1N2kaiZ.js.map → usePopoverPosition-CJZ6EkS4.js.map} +1 -1
  157. package/dist/cdn/chunks/{useScrollToBlock-BvWAfWd8.js → useScrollToBlock-D6gyIzT1.js} +3 -3
  158. package/dist/cdn/chunks/{useScrollToBlock-BvWAfWd8.js.map → useScrollToBlock-D6gyIzT1.js.map} +1 -1
  159. package/dist/cdn/editor.js +1010 -956
  160. package/dist/cdn/editor.js.map +1 -1
  161. package/dist/{check-C2h94k_8.js → check-CLfibuQc.js} +1 -1
  162. package/dist/{chevron-down-ulZzvfvk.js → chevron-down-DamTR8ta.js} +1 -1
  163. package/dist/{chevron-up-8g-VtBW4.js → chevron-up-CrV_Ksg-.js} +1 -1
  164. package/dist/{circle-alert-BJFqBtRt.js → circle-alert-BLy-e34e.js} +1 -1
  165. package/dist/{clock-C-1JiH38.js → clock-DQI6aaFT.js} +1 -1
  166. package/dist/{cloud-BAefVBb_.js → cloud-DXFUA8H_.js} +1 -1
  167. package/dist/{createCloudRuntime-FEZG-Gve.js → createCloudRuntime-BrgMP9gS.js} +5 -5
  168. package/dist/{createLucideIcon-DJb_1j1D.js → createLucideIcon-Cbl3Ma_H.js} +1 -1
  169. package/dist/{cdn/chunks/de-aRxhZF_K.js → de-CYLWugqb.js} +6 -2
  170. package/dist/{dist-BLVvhIFj.js → dist-7Lr_A7Va.js} +2 -2
  171. package/dist/{dist-B5iReTtK.js → dist-CkSgS-K9.js} +2 -2
  172. package/dist/{dist-CqcGTIiX.js → dist-WE11SQGe.js} +1 -1
  173. package/dist/{en-BX4V_7YO.js → en-C3TM249M.js} +6 -0
  174. package/dist/{es-CA9uQ-5x.js → es-D1SF4nCR.js} +6 -0
  175. package/dist/{extensions-DWp4eXoE.js → extensions-PJK0gLCL.js} +6 -6
  176. package/dist/{cdn/chunks/fr-iBuE60Ap.js → fr-CdLhJ7kw.js} +6 -2
  177. package/dist/{image-up-0rvCz8rh.js → image-up-BVOMy_Fs.js} +1 -1
  178. package/dist/{info-CXvc-MZk.js → info-BKMKasyT.js} +1 -1
  179. package/dist/{keys-CVpi8xCT.js → keys-CAor2T5q.js} +1 -1
  180. package/dist/{loader-circle-DQIuGTFk.js → loader-circle-CSGh8n8A.js} +1 -1
  181. package/dist/{message-circle-BqX2Y80d.js → message-circle-C6q2Fm_W.js} +1 -1
  182. package/dist/{nl-Btw4ojNo.js → nl-BvsLoyKp.js} +6 -0
  183. package/dist/{pencil-DpGX5hCB.js → pencil-DaTN0HKw.js} +1 -1
  184. package/dist/{pt-BR-GjVsCqbN.js → pt-BR-CAGS5YXp.js} +6 -0
  185. package/dist/{refresh-cw-B13pUg95.js → refresh-cw-Cu4wRQwT.js} +1 -1
  186. package/dist/{runtime-dom.esm-bundler-BgKXIPLV.js → runtime-dom.esm-bundler-CHEsXNQz.js} +1 -1
  187. package/dist/{scan-line-BDZEtA92.js → scan-line-O_o657Gv.js} +1 -1
  188. package/dist/{send-DQ52s_T6.js → send-GS3soauT.js} +1 -1
  189. package/dist/{shield-check-C4uQTy20.js → shield-check-B2TzT3Wp.js} +1 -1
  190. package/dist/{sparkles-CphMFXxu.js → sparkles-CNENcXZl.js} +1 -1
  191. package/dist/templatical-editor.js +464 -410
  192. package/dist/{text-align-start-Cem3VGu8.js → text-align-start-D0-k8RUf.js} +1 -1
  193. package/dist/{trash-2-ijNDbe1n.js → trash-2-BE-qGIpG.js} +1 -1
  194. package/dist/{triangle-alert-C1e0A199.js → triangle-alert-DNM2_dyh.js} +1 -1
  195. package/dist/{upload-CXwGBFi0.js → upload-Cv2Jx-yM.js} +1 -1
  196. package/dist/{useAliveFlag-BGIAZii_.js → useAliveFlag-1yBub211.js} +1 -1
  197. package/dist/{useCloudI18n-DmWo4nzs.js → useCloudI18n-Dwo7usTl.js} +2 -2
  198. package/dist/{useEditorCore-BfPXdBsv.js → useEditorCore-DM8vzMZQ.js} +35 -30
  199. package/dist/{useEditorRoot-DKyG95pb.js → useEditorRoot-CUIzpMYc.js} +2 -2
  200. package/dist/{useI18n-CvYvat9_.js → useI18n-DT_DKupw.js} +2 -2
  201. package/dist/{useMergeTag-D6Z6cyDa.js → useMergeTag-CcHQCcPN.js} +2 -2
  202. package/dist/{usePopoverPosition-WslxM_PU.js → usePopoverPosition-DaHz1kqb.js} +2 -2
  203. package/dist/{useScrollToBlock-B3H6frtG.js → useScrollToBlock-C2LYXENK.js} +3 -3
  204. package/dist/{vue.runtime.esm-bundler-DzEsDRtY.js → vue.runtime.esm-bundler-CdH_W9qX.js} +158 -172
  205. package/dist/{x-eZrtE6uf.js → x-DUPrT6Aa.js} +1 -1
  206. package/package.json +9 -9
  207. package/dist/cdn/chunks/ca-CEuJ6IRr.js.map +0 -1
  208. package/dist/cdn/chunks/de-aRxhZF_K.js.map +0 -1
  209. package/dist/cdn/chunks/en-BCgVx9zM.js +0 -90
  210. package/dist/cdn/chunks/en-BCgVx9zM.js.map +0 -1
  211. package/dist/cdn/chunks/en-BX4V_7YO.js.map +0 -1
  212. package/dist/cdn/chunks/es-CA9uQ-5x.js.map +0 -1
  213. package/dist/cdn/chunks/fr-iBuE60Ap.js.map +0 -1
  214. package/dist/cdn/chunks/nl-Btw4ojNo.js.map +0 -1
  215. package/dist/cdn/chunks/pt-BR-GjVsCqbN.js.map +0 -1
  216. package/dist/cdn/chunks/src-BS2ClsbB.js.map +0 -1
  217. package/dist/cdn/chunks/src-rhf0R6xZ.js.map +0 -1
  218. package/dist/cdn/chunks/useEditorRoot-Cxnmf5hM.js +0 -10
@@ -1 +1 @@
1
- {"version":3,"file":"TitleEditor-BsGfiDXQ.js","names":[],"sources":["../../../src/components/blocks/TitleEditor.vue","../../../src/components/blocks/TitleEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode, LineBoundaryKeys },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n LineBoundaryKeys,\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:absolute tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-[var(--tpl-shadow-lg)]\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode, LineBoundaryKeys },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n LineBoundaryKeys,\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:absolute tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-[var(--tpl-shadow-lg)]\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"TitleEditor-CLkXt5RZ.js","names":[],"sources":["../../../src/components/blocks/TitleEditor.vue","../../../src/components/blocks/TitleEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode, LineBoundaryKeys },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n LineBoundaryKeys,\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:absolute tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-[var(--tpl-shadow-lg)]\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { useI18n } from \"../../composables\";\nimport { useRichTextEditor } from \"../../composables/useRichTextEditor\";\nimport { usePopoverRoot } from \"../../composables/usePopoverRoot\";\nimport type { TitleBlock as TitleBlockType } from \"@templatical/types\";\nimport {\n Bold,\n Braces,\n Italic,\n Link,\n LoaderCircle,\n ScanLine,\n} from \"@lucide/vue\";\nimport { computed, inject } from \"vue\";\nimport {\n THEME_STYLES_KEY,\n UI_THEME_KEY,\n MERGE_TAG_PICKER_KEY,\n LOGIC_TAG_PICKER_KEY,\n} from \"../../keys\";\nimport RichTextLinkDialog from \"./RichTextLinkDialog.vue\";\nimport RichTextEditorContent from \"./RichTextEditorContent.vue\";\nimport { withLinkColor } from \"../../utils/linkColorExtension\";\n\nconst props = defineProps<{\n block: TitleBlockType;\n toolbarPosition: { top: number; left: number };\n}>();\n\nconst emit = defineEmits<{\n (e: \"done\"): void;\n}>();\n\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst tplUiTheme = inject(UI_THEME_KEY, null);\nconst popoverRoot = usePopoverRoot();\n// Hide the floating toolbar while either built-in picker modal is open — see\n// ParagraphToolbar.vue for the same rationale.\nconst picker = inject(MERGE_TAG_PICKER_KEY, null);\nconst logicPicker = inject(LOGIC_TAG_PICKER_KEY, null);\nconst pickerIsOpen = computed(\n () => (picker?.isOpen.value ?? false) || (logicPicker?.isOpen.value ?? false),\n);\n\nconst { t } = useI18n();\n\nconst {\n editor,\n EditorContent,\n isLoading,\n initError,\n retry,\n showLinkDialog,\n linkUrl,\n linkColor,\n linkDialogRef,\n canRequestMergeTag,\n canInsertLogicTag,\n openLinkDialog,\n insertLink,\n removeLink,\n closeLinkDialog,\n handleLinkKeydown,\n handleAddMergeTag,\n handleAddLogicTag,\n} = useRichTextEditor({\n blockId: () => props.block.id,\n blockContent: () => props.block.content,\n onDone: () => emit(\"done\"),\n editorName: \"TitleEditor\",\n async loadExtensions({\n mergeTags,\n syntax,\n triggerChar,\n autocompleteEnabled,\n suggestionEmptyText,\n }) {\n const [\n { Editor: TiptapEditor, EditorContent: EC },\n { default: StarterKit },\n { default: LinkExt },\n { MergeTagNode, MergeTagSuggestion, LogicMergeTagNode, LineBoundaryKeys },\n ] = await Promise.all([\n import(\"@tiptap/vue-3\"),\n import(\"@tiptap/starter-kit\"),\n import(\"@tiptap/extension-link\"),\n import(\"../../extensions\"),\n ]);\n\n return {\n TiptapEditor,\n EC,\n extensions: [\n StarterKit.configure({\n heading: false,\n codeBlock: false,\n blockquote: false,\n horizontalRule: false,\n bulletList: false,\n orderedList: false,\n listItem: false,\n strike: false,\n // StarterKit bundles @tiptap/extension-link (openOnClick: true).\n // Disable it so the LinkExt below (openOnClick: false) is the only\n // link extension — otherwise clicking a link while editing opens it.\n link: false,\n }),\n withLinkColor(LinkExt).configure({\n openOnClick: false,\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n },\n }),\n MergeTagNode.configure({ mergeTags, syntax }),\n LogicMergeTagNode.configure({ syntax }),\n LineBoundaryKeys,\n ...(autocompleteEnabled && triggerChar && mergeTags.length > 0\n ? [\n MergeTagSuggestion.configure({\n mergeTags,\n char: triggerChar,\n emptyText: suggestionEmptyText,\n popoverRoot,\n }),\n ]\n : []),\n ],\n };\n },\n});\n</script>\n\n<template>\n <div class=\"tpl-text-editor-wrapper tpl:relative\">\n <Teleport v-if=\"popoverRoot && !pickerIsOpen\" :to=\"popoverRoot\">\n <div\n :data-tpl-theme=\"tplUiTheme\"\n role=\"toolbar\"\n :aria-label=\"t.titleEditor.toolbar\"\n class=\"tpl tpl-text-toolbar tpl:absolute tpl:z-popover tpl:flex tpl:items-center tpl:gap-1 tpl:rounded-lg tpl:border tpl:border-[var(--tpl-border)] tpl:bg-[var(--tpl-bg)] tpl:px-3 tpl:py-2 tpl:shadow-[var(--tpl-shadow-lg)]\"\n :style=\"{\n ...themeStyles,\n top: `${toolbarPosition.top}px`,\n left: `${toolbarPosition.left}px`,\n transform: 'translateY(-100%)',\n }\"\n >\n <template v-if=\"!isLoading && editor\">\n <!-- Bold -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('bold'),\n }\"\n :aria-label=\"t.titleEditor.bold\"\n :title=\"t.titleEditor.bold\"\n @click=\"editor?.chain().focus().toggleBold().run()\"\n >\n <Bold :size=\"16\" :stroke-width=\"2.5\" />\n </button>\n <!-- Italic -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('italic'),\n }\"\n :aria-label=\"t.titleEditor.italic\"\n :title=\"t.titleEditor.italic\"\n @click=\"editor?.chain().focus().toggleItalic().run()\"\n >\n <Italic :size=\"16\" :stroke-width=\"2\" />\n </button>\n <span\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n aria-hidden=\"true\"\n ></span>\n <!-- Link -->\n <button\n type=\"button\"\n class=\"tpl-text-toolbar-btn\"\n :class=\"{\n 'tpl-text-toolbar-btn--active': editor?.isActive('link'),\n }\"\n :aria-label=\"t.titleEditor.addLink\"\n :title=\"t.titleEditor.addLink\"\n @click=\"openLinkDialog\"\n >\n <Link :size=\"16\" :stroke-width=\"2\" />\n </button>\n <!-- Add Merge Tag -->\n <span\n v-if=\"canRequestMergeTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canRequestMergeTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.mergeTag.insert\"\n :title=\"t.mergeTag.insert\"\n @click=\"handleAddMergeTag\"\n >\n <ScanLine :size=\"16\" :stroke-width=\"2\" />\n {{ t.mergeTag.insertShort }}\n </button>\n <!-- Insert Logic -->\n <span\n v-if=\"canInsertLogicTag\"\n class=\"tpl:mx-1.5 tpl:h-6 tpl:w-px tpl:bg-[var(--tpl-border)]\"\n ></span>\n <button\n v-if=\"canInsertLogicTag\"\n type=\"button\"\n class=\"tpl:flex tpl:h-8 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:gap-1.5 tpl:rounded tpl:border-none tpl:bg-transparent tpl:px-2.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)] tpl:transition-all tpl:hover:bg-[var(--tpl-bg-active)]\"\n :aria-label=\"t.logicTag.insert\"\n :title=\"t.logicTag.insert\"\n data-testid=\"insert-logic-button\"\n @click=\"handleAddLogicTag\"\n >\n <Braces :size=\"16\" :stroke-width=\"2\" />\n {{ t.logicTag.insertShort }}\n </button>\n </template>\n <template v-else>\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:px-2 tpl:text-xs tpl:text-[var(--tpl-text-dim)]\"\n >\n <LoaderCircle class=\"tpl-spinner\" :size=\"14\" :stroke-width=\"2\" />\n {{ t.errors.editorLoading }}\n </div>\n </template>\n </div>\n </Teleport>\n\n <RichTextEditorContent\n :editor=\"editor\"\n :editor-content=\"EditorContent\"\n :is-loading=\"isLoading\"\n :init-error=\"initError\"\n @retry=\"retry\"\n />\n\n <RichTextLinkDialog\n :visible=\"showLinkDialog\"\n :is-editing-link=\"editor?.isActive('link') ?? false\"\n v-model:dialog-ref=\"linkDialogRef\"\n v-model:link-url=\"linkUrl\"\n v-model:link-color=\"linkColor\"\n @close=\"closeLinkDialog\"\n @insert=\"insertLink\"\n @remove=\"removeLink\"\n @keydown=\"handleLinkKeydown\"\n />\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { E as e, H as t, I as n, N as r, Q as i, S as a, at as o, b as s, d as c, f as l, g as u, h as d, l as f, lt as p, m, n as h, p as g } from "./draggable-BfpsXFg7.js";
2
- import { E as _ } from "./useEditorCore-CwJIw1Uy.js";
3
- import { B as v, H as y } from "./keys-oJdkdtPn.js";
4
- import { n as b } from "./usePopoverPosition-C1N2kaiZ.js";
1
+ import { E as e, H as t, I as n, N as r, Q as i, S as a, at as o, b as s, d as c, f as l, g as u, h as d, l as f, lt as p, m, n as h, p as g } from "./draggable-BLMjz0GK.js";
2
+ import { E as _ } from "./useEditorCore-2ZVOY0Rh.js";
3
+ import { B as v, H as y } from "./keys-D7OpfE2s.js";
4
+ import { n as b } from "./usePopoverPosition-CJZ6EkS4.js";
5
5
  //#region src/components/TplModal.vue?vue&type=script&setup=true&lang.ts
6
6
  var x = ["data-tpl-theme"], S = /* @__PURE__ */ a({
7
7
  __name: "TplModal",
@@ -49,4 +49,4 @@ var x = ["data-tpl-theme"], S = /* @__PURE__ */ a({
49
49
  //#endregion
50
50
  export { S as t };
51
51
 
52
- //# sourceMappingURL=TplModal-lUdHsbjL.js.map
52
+ //# sourceMappingURL=TplModal-BhfPoZ_W.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TplModal-lUdHsbjL.js","names":[],"sources":["../../../src/components/TplModal.vue","../../../src/components/TplModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useFocusTrap } from \"../composables\";\nimport { usePopoverRoot } from \"../composables/usePopoverRoot\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../keys\";\nimport { computed, inject, ref } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"keydown\", event: KeyboardEvent): void;\n}>();\n\nconst dialogRef = ref<HTMLElement | null>(null);\nconst isVisible = computed(() => props.visible);\nuseFocusTrap(dialogRef, isVisible);\n\nconst tplUiTheme = inject(UI_THEME_KEY);\n\n// The backdrop below carries the bare `tpl` class, which re-declares every\n// `--tpl-*` token from the base `.tpl` rule. A custom property declared on an\n// element beats one inherited from an ancestor, so that re-declaration shadows\n// the consumer's `theme` config — which lives as inline styles on the editor\n// root — for this whole teleported subtree. Re-applying `themeStyles` here is\n// what restores it, and doing it on the backdrop covers every dialog rendered\n// through this wrapper rather than each one remembering to. `data-tpl-theme`\n// does the same job for the dark token block. See the invariant in\n// `tests/theme-token-scope.test.ts` (issue #487).\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst popoverRoot = usePopoverRoot();\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n emit(\"close\");\n }\n emit(\"keydown\", event);\n}\n</script>\n\n<template>\n <Teleport v-if=\"popoverRoot\" :to=\"popoverRoot\">\n <Transition\n enter-active-class=\"tpl:transition\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <!-- The backdrop is the reference box every slotted panel caps against,\n which is why it owns the gutter (`p-4`) rather than each panel\n carrying its own margin. `inset-0` gives it a definite height; the\n wrapper below spans that height so a panel's percentage cap\n (`max-h-[90%]` / `max-h-[80%]`) has an unbroken chain to resolve\n through. Those numbers are the `vh` values they replaced, so an\n untrapped editor renders exactly as before.\n\n Panels must never cap in `vh`. `fixed` covers the viewport only while\n nothing traps it, and an ancestor with `transform`, `filter`,\n `backdrop-filter`, `will-change: transform`, `contain: paint`,\n `container-type` or a transform animation becomes the containing\n block for fixed descendants. The editor is embedded in someone\n else's page, so any of those can sit above it: `inset-0` then\n resolves to that ancestor's box while a `vh` cap still resolves to\n the viewport, and the panel overflows a container that usually also\n has `overflow: hidden`. That is issue #575 — in a 420px host inside a\n 720px viewport, a 648px panel clipped ~113px off both the top and the\n bottom, with no scrollbar to reach the buttons. Capping against the\n backdrop is self-correcting whether or not the trap is present.\n Locked by `tests/overlay-height-scope.test.ts`.\n\n The padding belongs here and not on the wrapper: preflight is\n omitted, so non-form elements keep `content-box` and padding on an\n `h-full` element would add to 100% and overflow by exactly the\n padding (the trap behind issue #115). Insets size the backdrop's\n border box, so padding here safely shrinks the content box instead. -->\n <div\n v-if=\"visible\"\n :data-tpl-theme=\"tplUiTheme\"\n class=\"tpl tpl:fixed tpl:inset-0 tpl:z-modal tpl:flex tpl:items-center tpl:justify-center tpl:p-4\"\n style=\"\n background-color: var(--tpl-overlay);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n :style=\"themeStyles\"\n @click.self=\"emit('close')\"\n @keydown=\"handleKeydown\"\n >\n <!-- `h-full` only, deliberately no `w-full`: height is what has to\n become definite, and widening this element would change what\n `w-full` on a panel resolves against. Panels are shrink-to-fit\n horizontally — the test-email dialog stays compact until its\n preview opens, and the saved-blocks browser pins an explicit width\n precisely because this wrapper is shrink-to-fit. Constraining one\n axis leaves all of that intact.\n\n It repeats `@click.self` because it now covers the backdrop's full\n height: clicks in the gap above or below the panel land here, so\n without it click-outside-to-close would only work on the padding\n ring and the columns either side. -->\n <div\n ref=\"dialogRef\"\n class=\"tpl:flex tpl:h-full tpl:items-center tpl:justify-center\"\n @click.self=\"emit('close')\"\n >\n <slot />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { useFocusTrap } from \"../composables\";\nimport { usePopoverRoot } from \"../composables/usePopoverRoot\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../keys\";\nimport { computed, inject, ref } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"keydown\", event: KeyboardEvent): void;\n}>();\n\nconst dialogRef = ref<HTMLElement | null>(null);\nconst isVisible = computed(() => props.visible);\nuseFocusTrap(dialogRef, isVisible);\n\nconst tplUiTheme = inject(UI_THEME_KEY);\n\n// The backdrop below carries the bare `tpl` class, which re-declares every\n// `--tpl-*` token from the base `.tpl` rule. A custom property declared on an\n// element beats one inherited from an ancestor, so that re-declaration shadows\n// the consumer's `theme` config — which lives as inline styles on the editor\n// root — for this whole teleported subtree. Re-applying `themeStyles` here is\n// what restores it, and doing it on the backdrop covers every dialog rendered\n// through this wrapper rather than each one remembering to. `data-tpl-theme`\n// does the same job for the dark token block. See the invariant in\n// `tests/theme-token-scope.test.ts` (issue #487).\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst popoverRoot = usePopoverRoot();\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n emit(\"close\");\n }\n emit(\"keydown\", event);\n}\n</script>\n\n<template>\n <Teleport v-if=\"popoverRoot\" :to=\"popoverRoot\">\n <Transition\n enter-active-class=\"tpl:transition\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <!-- The backdrop is the reference box every slotted panel caps against,\n which is why it owns the gutter (`p-4`) rather than each panel\n carrying its own margin. `inset-0` gives it a definite height; the\n wrapper below spans that height so a panel's percentage cap\n (`max-h-[90%]` / `max-h-[80%]`) has an unbroken chain to resolve\n through. Those numbers are the `vh` values they replaced, so an\n untrapped editor renders exactly as before.\n\n Panels must never cap in `vh`. `fixed` covers the viewport only while\n nothing traps it, and an ancestor with `transform`, `filter`,\n `backdrop-filter`, `will-change: transform`, `contain: paint`,\n `container-type` or a transform animation becomes the containing\n block for fixed descendants. The editor is embedded in someone\n else's page, so any of those can sit above it: `inset-0` then\n resolves to that ancestor's box while a `vh` cap still resolves to\n the viewport, and the panel overflows a container that usually also\n has `overflow: hidden`. That is issue #575 — in a 420px host inside a\n 720px viewport, a 648px panel clipped ~113px off both the top and the\n bottom, with no scrollbar to reach the buttons. Capping against the\n backdrop is self-correcting whether or not the trap is present.\n Locked by `tests/overlay-height-scope.test.ts`.\n\n The padding belongs here and not on the wrapper: preflight is\n omitted, so non-form elements keep `content-box` and padding on an\n `h-full` element would add to 100% and overflow by exactly the\n padding (the trap behind issue #115). Insets size the backdrop's\n border box, so padding here safely shrinks the content box instead. -->\n <div\n v-if=\"visible\"\n :data-tpl-theme=\"tplUiTheme\"\n class=\"tpl tpl:fixed tpl:inset-0 tpl:z-modal tpl:flex tpl:items-center tpl:justify-center tpl:p-4\"\n style=\"\n background-color: var(--tpl-overlay);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n :style=\"themeStyles\"\n @click.self=\"emit('close')\"\n @keydown=\"handleKeydown\"\n >\n <!-- `h-full` only, deliberately no `w-full`: height is what has to\n become definite, and widening this element would change what\n `w-full` on a panel resolves against. Panels are shrink-to-fit\n horizontally — the test-email dialog stays compact until its\n preview opens, and the saved-blocks browser pins an explicit width\n precisely because this wrapper is shrink-to-fit. Constraining one\n axis leaves all of that intact.\n\n It repeats `@click.self` because it now covers the backdrop's full\n height: clicks in the gap above or below the panel land here, so\n without it click-outside-to-close would only work on the padding\n ring and the columns either side. -->\n <div\n ref=\"dialogRef\"\n class=\"tpl:flex tpl:h-full tpl:items-center tpl:justify-center\"\n @click.self=\"emit('close')\"\n >\n <slot />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n"],"mappings":";;;;;;;;;;EAMA,IAAM,IAAQ,GAIR,IAAO,GAKP,IAAY,EAAwB,IAAI,GACxC,IAAY,QAAe,EAAM,OAAO;EAC9C,EAAa,GAAW,CAAS;EAEjC,IAAM,IAAa,EAAO,CAAY,GAWhC,IAAc,EAAO,GAAkB,IAAI,GAC3C,IAAc,EAAe;EAEnC,SAAS,EAAc,GAA4B;GAIjD,AAHI,EAAM,QAAQ,YAChB,EAAK,OAAO,GAEd,EAAK,WAAW,CAAK;EACvB;mBAIkB,EAAA,CAAA,KAAhB,EAAA,GAAA,EAsEW,GAAA;;GAtEmB,IAAI,EAAA,CAAA;EAChC,GAAA,CAAA,EAoEa,GAAA;GAnEX,sBAAmB;GACnB,oBAAiB;GACjB,kBAAe;GACf,sBAAmB;GACnB,oBAAiB;GACjB,kBAAe;;GA6Bf,SAAA,QAgCM,CA/BE,EAAA,WADR,EAAA,GAAA,EAgCM,OAAA;;IA9BH,kBAAgB,EAAA,CAAA;IACjB,OAAM;IACN,OAIC,EAAA,CAJD;KAAA,oBAAA;KAAA,mBAAA;KAAA,2BAAA;IAAA,GAKQ,EAAA,CAAA,CAAW,CAAA;IAClB,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAI,OAAA,GAAA,CAAA,MAAA,CAAA;IAChB,WAAS;GAcV,GAAA,CAAA,EAMM,OAAA;IALA,SAAA;IAAJ,KAAI;IACJ,OAAM;IACL,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAI,OAAA,GAAA,CAAA,MAAA,CAAA;GAEjB,GAAA,CAAA,EAAQ,EAAA,QAAA,SAAA,CAAA,GAAA,GAAA,CAAA,GAAA,IAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"TplModal-BhfPoZ_W.js","names":[],"sources":["../../../src/components/TplModal.vue","../../../src/components/TplModal.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useFocusTrap } from \"../composables\";\nimport { usePopoverRoot } from \"../composables/usePopoverRoot\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../keys\";\nimport { computed, inject, ref } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"keydown\", event: KeyboardEvent): void;\n}>();\n\nconst dialogRef = ref<HTMLElement | null>(null);\nconst isVisible = computed(() => props.visible);\nuseFocusTrap(dialogRef, isVisible);\n\nconst tplUiTheme = inject(UI_THEME_KEY);\n\n// The backdrop below carries the bare `tpl` class, which re-declares every\n// `--tpl-*` token from the base `.tpl` rule. A custom property declared on an\n// element beats one inherited from an ancestor, so that re-declaration shadows\n// the consumer's `theme` config — which lives as inline styles on the editor\n// root — for this whole teleported subtree. Re-applying `themeStyles` here is\n// what restores it, and doing it on the backdrop covers every dialog rendered\n// through this wrapper rather than each one remembering to. `data-tpl-theme`\n// does the same job for the dark token block. See the invariant in\n// `tests/theme-token-scope.test.ts` (issue #487).\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst popoverRoot = usePopoverRoot();\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n emit(\"close\");\n }\n emit(\"keydown\", event);\n}\n</script>\n\n<template>\n <Teleport v-if=\"popoverRoot\" :to=\"popoverRoot\">\n <Transition\n enter-active-class=\"tpl:transition\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <!-- The backdrop is the reference box every slotted panel caps against,\n which is why it owns the gutter (`p-4`) rather than each panel\n carrying its own margin. `inset-0` gives it a definite height; the\n wrapper below spans that height so a panel's percentage cap\n (`max-h-[90%]` / `max-h-[80%]`) has an unbroken chain to resolve\n through. Those numbers are the `vh` values they replaced, so an\n untrapped editor renders exactly as before.\n\n Panels must never cap in `vh`. `fixed` covers the viewport only while\n nothing traps it, and an ancestor with `transform`, `filter`,\n `backdrop-filter`, `will-change: transform`, `contain: paint`,\n `container-type` or a transform animation becomes the containing\n block for fixed descendants. The editor is embedded in someone\n else's page, so any of those can sit above it: `inset-0` then\n resolves to that ancestor's box while a `vh` cap still resolves to\n the viewport, and the panel overflows a container that usually also\n has `overflow: hidden`. That is issue #575 — in a 420px host inside a\n 720px viewport, a 648px panel clipped ~113px off both the top and the\n bottom, with no scrollbar to reach the buttons. Capping against the\n backdrop is self-correcting whether or not the trap is present.\n Locked by `tests/overlay-height-scope.test.ts`.\n\n The padding belongs here and not on the wrapper: preflight is\n omitted, so non-form elements keep `content-box` and padding on an\n `h-full` element would add to 100% and overflow by exactly the\n padding (the trap behind issue #115). Insets size the backdrop's\n border box, so padding here safely shrinks the content box instead. -->\n <div\n v-if=\"visible\"\n :data-tpl-theme=\"tplUiTheme\"\n class=\"tpl tpl:fixed tpl:inset-0 tpl:z-modal tpl:flex tpl:items-center tpl:justify-center tpl:p-4\"\n style=\"\n background-color: var(--tpl-overlay);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n :style=\"themeStyles\"\n @click.self=\"emit('close')\"\n @keydown=\"handleKeydown\"\n >\n <!-- `h-full` only, deliberately no `w-full`: height is what has to\n become definite, and widening this element would change what\n `w-full` on a panel resolves against. Panels are shrink-to-fit\n horizontally — the test-email dialog stays compact until its\n preview opens, and the saved-blocks browser pins an explicit width\n precisely because this wrapper is shrink-to-fit. Constraining one\n axis leaves all of that intact.\n\n It repeats `@click.self` because it now covers the backdrop's full\n height: clicks in the gap above or below the panel land here, so\n without it click-outside-to-close would only work on the padding\n ring and the columns either side. -->\n <div\n ref=\"dialogRef\"\n class=\"tpl:flex tpl:h-full tpl:items-center tpl:justify-center\"\n @click.self=\"emit('close')\"\n >\n <slot />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { useFocusTrap } from \"../composables\";\nimport { usePopoverRoot } from \"../composables/usePopoverRoot\";\nimport { THEME_STYLES_KEY, UI_THEME_KEY } from \"../keys\";\nimport { computed, inject, ref } from \"vue\";\n\nconst props = defineProps<{\n visible: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"close\"): void;\n (e: \"keydown\", event: KeyboardEvent): void;\n}>();\n\nconst dialogRef = ref<HTMLElement | null>(null);\nconst isVisible = computed(() => props.visible);\nuseFocusTrap(dialogRef, isVisible);\n\nconst tplUiTheme = inject(UI_THEME_KEY);\n\n// The backdrop below carries the bare `tpl` class, which re-declares every\n// `--tpl-*` token from the base `.tpl` rule. A custom property declared on an\n// element beats one inherited from an ancestor, so that re-declaration shadows\n// the consumer's `theme` config — which lives as inline styles on the editor\n// root — for this whole teleported subtree. Re-applying `themeStyles` here is\n// what restores it, and doing it on the backdrop covers every dialog rendered\n// through this wrapper rather than each one remembering to. `data-tpl-theme`\n// does the same job for the dark token block. See the invariant in\n// `tests/theme-token-scope.test.ts` (issue #487).\nconst themeStyles = inject(THEME_STYLES_KEY, null);\nconst popoverRoot = usePopoverRoot();\n\nfunction handleKeydown(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n emit(\"close\");\n }\n emit(\"keydown\", event);\n}\n</script>\n\n<template>\n <Teleport v-if=\"popoverRoot\" :to=\"popoverRoot\">\n <Transition\n enter-active-class=\"tpl:transition\"\n enter-from-class=\"tpl:opacity-0\"\n enter-to-class=\"tpl:opacity-100\"\n leave-active-class=\"tpl:transition tpl:duration-100\"\n leave-from-class=\"tpl:opacity-100\"\n leave-to-class=\"tpl:opacity-0\"\n >\n <!-- The backdrop is the reference box every slotted panel caps against,\n which is why it owns the gutter (`p-4`) rather than each panel\n carrying its own margin. `inset-0` gives it a definite height; the\n wrapper below spans that height so a panel's percentage cap\n (`max-h-[90%]` / `max-h-[80%]`) has an unbroken chain to resolve\n through. Those numbers are the `vh` values they replaced, so an\n untrapped editor renders exactly as before.\n\n Panels must never cap in `vh`. `fixed` covers the viewport only while\n nothing traps it, and an ancestor with `transform`, `filter`,\n `backdrop-filter`, `will-change: transform`, `contain: paint`,\n `container-type` or a transform animation becomes the containing\n block for fixed descendants. The editor is embedded in someone\n else's page, so any of those can sit above it: `inset-0` then\n resolves to that ancestor's box while a `vh` cap still resolves to\n the viewport, and the panel overflows a container that usually also\n has `overflow: hidden`. That is issue #575 — in a 420px host inside a\n 720px viewport, a 648px panel clipped ~113px off both the top and the\n bottom, with no scrollbar to reach the buttons. Capping against the\n backdrop is self-correcting whether or not the trap is present.\n Locked by `tests/overlay-height-scope.test.ts`.\n\n The padding belongs here and not on the wrapper: preflight is\n omitted, so non-form elements keep `content-box` and padding on an\n `h-full` element would add to 100% and overflow by exactly the\n padding (the trap behind issue #115). Insets size the backdrop's\n border box, so padding here safely shrinks the content box instead. -->\n <div\n v-if=\"visible\"\n :data-tpl-theme=\"tplUiTheme\"\n class=\"tpl tpl:fixed tpl:inset-0 tpl:z-modal tpl:flex tpl:items-center tpl:justify-center tpl:p-4\"\n style=\"\n background-color: var(--tpl-overlay);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n \"\n :style=\"themeStyles\"\n @click.self=\"emit('close')\"\n @keydown=\"handleKeydown\"\n >\n <!-- `h-full` only, deliberately no `w-full`: height is what has to\n become definite, and widening this element would change what\n `w-full` on a panel resolves against. Panels are shrink-to-fit\n horizontally — the test-email dialog stays compact until its\n preview opens, and the saved-blocks browser pins an explicit width\n precisely because this wrapper is shrink-to-fit. Constraining one\n axis leaves all of that intact.\n\n It repeats `@click.self` because it now covers the backdrop's full\n height: clicks in the gap above or below the panel land here, so\n without it click-outside-to-close would only work on the padding\n ring and the columns either side. -->\n <div\n ref=\"dialogRef\"\n class=\"tpl:flex tpl:h-full tpl:items-center tpl:justify-center\"\n @click.self=\"emit('close')\"\n >\n <slot />\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n"],"mappings":";;;;;;;;;;EAMA,IAAM,IAAQ,GAIR,IAAO,GAKP,IAAY,EAAwB,IAAI,GACxC,IAAY,QAAe,EAAM,OAAO;EAC9C,EAAa,GAAW,CAAS;EAEjC,IAAM,IAAa,EAAO,CAAY,GAWhC,IAAc,EAAO,GAAkB,IAAI,GAC3C,IAAc,EAAe;EAEnC,SAAS,EAAc,GAA4B;GAIjD,AAHI,EAAM,QAAQ,YAChB,EAAK,OAAO,GAEd,EAAK,WAAW,CAAK;EACvB;mBAIkB,EAAA,CAAA,KAAhB,EAAA,GAAA,EAsEW,GAAA;;GAtEmB,IAAI,EAAA,CAAA;EAChC,GAAA,CAAA,EAoEa,GAAA;GAnEX,sBAAmB;GACnB,oBAAiB;GACjB,kBAAe;GACf,sBAAmB;GACnB,oBAAiB;GACjB,kBAAe;;GA6Bf,SAAA,QAgCM,CA/BE,EAAA,WADR,EAAA,GAAA,EAgCM,OAAA;;IA9BH,kBAAgB,EAAA,CAAA;IACjB,OAAM;IACN,OAIC,EAAA,CAJD;KAAA,oBAAA;KAAA,mBAAA;KAAA,2BAAA;IAAA,GAKQ,EAAA,CAAA,CAAW,CAAA;IAClB,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAI,OAAA,GAAA,CAAA,MAAA,CAAA;IAChB,WAAS;GAcV,GAAA,CAAA,EAMM,OAAA;IALA,SAAA;IAAJ,KAAI;IACJ,OAAM;IACL,SAAK,AAAA,EAAA,OAAA,GAAA,MAAO,EAAI,OAAA,GAAA,CAAA,MAAA,CAAA;GAEjB,GAAA,CAAA,EAAQ,EAAA,QAAA,SAAA,CAAA,GAAA,GAAA,CAAA,GAAA,IAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA"}
@@ -1,7 +1,7 @@
1
- import { F as e, H as t, N as n, Q as r, S as i, at as a, b as o, ct as s, f as c, g as l, h as u, l as d, n as f, p, u as m, ut as h, y as g } from "./draggable-BfpsXFg7.js";
2
- import { t as _ } from "./dist-CM8TB0VD.js";
3
- import { t as v } from "./useI18n-4sUbTM3Y.js";
4
- import { Ft as y, It as b, Nt as x, it as S, kt as C } from "./icons-BrdgOeXm.js";
1
+ import { F as e, H as t, N as n, Q as r, S as i, at as a, b as o, ct as s, f as c, g as l, h as u, l as d, n as f, p, u as m, ut as h, y as g } from "./draggable-BLMjz0GK.js";
2
+ import { t as _ } from "./dist-2fOlspdg.js";
3
+ import { t as v } from "./useI18n-DYb1SgLB.js";
4
+ import { Ft as y, It as b, Nt as x, it as S, kt as C } from "./icons-MeYdeH4P.js";
5
5
  import { t as w } from "./formatRelativeTime-CtUU-QZ8.js";
6
6
  //#region src/components/VersionHistoryMenu.vue?vue&type=script&setup=true&lang.ts
7
7
  var T = [
@@ -145,4 +145,4 @@ var T = [
145
145
  //#endregion
146
146
  export { R as default };
147
147
 
148
- //# sourceMappingURL=VersionHistoryMenu-CXMPsVMR.js.map
148
+ //# sourceMappingURL=VersionHistoryMenu-_DyRYBRP.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VersionHistoryMenu-CXMPsVMR.js","names":[],"sources":["../../../src/components/VersionHistoryMenu.vue","../../../src/components/VersionHistoryMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The header's version-history control: step older / newer through the list, or\n * open the dropdown and jump straight to one.\n *\n * Shared by both editors — it was `cloud/components/SnapshotHistory.vue` and\n * spoke Cloud's wire shape (`created_at`, `is_autosave`) directly. It now reads\n * the `TemplateVersion` contract, so any provider drives it.\n */\nimport { computed, ref } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport type { TemplateVersion } from \"@templatical/types\";\nimport { useI18n } from \"../composables/useI18n\";\nimport { formatRelativeTime } from \"../utils/formatRelativeTime\";\n\nconst props = defineProps<{\n versions: TemplateVersion[];\n isLoading: boolean;\n isRestoring: boolean;\n /** Which version is on the canvas, or `null` while editing normally. */\n previewingId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"open\"): void;\n (e: \"navigate\", version: TemplateVersion): void;\n}>();\n\nconst { t, format } = useI18n();\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n/**\n * Position in the list (0 = newest), derived from what is actually previewed\n * rather than tracked locally. A local index went stale the moment the user\n * cancelled a preview — the arrows then stepped from wherever they had left off\n * instead of from the top.\n */\nconst currentIndex = computed(() =>\n props.previewingId === null\n ? -1\n : props.versions.findIndex((v) => v.id === props.previewingId),\n);\n\nconst canGoNewer = computed(\n () => currentIndex.value > 0 && !props.isRestoring && !props.isLoading,\n);\n\nconst canGoOlder = computed(\n () =>\n currentIndex.value < props.versions.length - 1 &&\n props.versions.length > 0 &&\n !props.isRestoring &&\n !props.isLoading,\n);\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n emit(\"navigate\", props.versions[currentIndex.value - 1]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n emit(\"navigate\", props.versions[currentIndex.value + 1]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n // Always on open, never only when empty: history grows behind the user's back\n // (every save may record one), so a list fetched once would go stale silently.\n if (isOpen.value) emit(\"open\");\n}\n\nfunction selectVersion(version: TemplateVersion): void {\n emit(\"navigate\", version);\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(dateString, t.time, format, 7);\n if (result !== null) return result;\n\n return new Date(dateString).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n data-testid=\"version-history\"\n >\n <!-- Step to an older version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-older\"\n :disabled=\"!canGoOlder\"\n :title=\"t.versionHistory.olderVersion\"\n :aria-label=\"t.versionHistory.olderVersion\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-toggle\"\n :aria-expanded=\"isOpen\"\n :title=\"t.versionHistory.tooltip\"\n :aria-label=\"t.versionHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n data-testid=\"version-history-dropdown\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ t.versionHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading && versions.length === 0\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n role=\"status\"\n aria-busy=\"true\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"versions.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-empty\"\n >\n {{ t.versionHistory.empty }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"version in versions\"\n :key=\"version.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-l-2 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:hover:border-l-[var(--tpl-primary)] tpl:hover:bg-[var(--tpl-bg-hover)]\"\n :class=\"\n version.id === previewingId\n ? 'tpl:border-l-[var(--tpl-primary)] tpl:bg-[var(--tpl-bg-active)]'\n : 'tpl:border-l-transparent'\n \"\n style=\"background-color: transparent\"\n data-testid=\"version-history-entry\"\n :data-version-id=\"version.id\"\n :disabled=\"isRestoring\"\n @click=\"selectVersion(version)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{\n version.label ?? formatDate(version.createdAt)\n }}</span>\n <span\n v-if=\"version.isAutomatic\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-xs tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ t.versionHistory.auto }}\n </span>\n </div>\n <!-- A labelled version still shows when it was taken, and by whom\n if the store tracks that; an unlabelled one already leads with\n the date, so the line would repeat it. -->\n <div\n v-if=\"version.label || version.author?.name\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n <template v-if=\"version.label\">{{\n formatDate(version.createdAt)\n }}</template>\n <template v-if=\"version.label && version.author?.name\">\n ·\n </template>\n <template v-if=\"version.author?.name\">{{\n version.author.name\n }}</template>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Step to a newer version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-newer\"\n :disabled=\"!canGoNewer\"\n :title=\"t.versionHistory.newerVersion\"\n :aria-label=\"t.versionHistory.newerVersion\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * The header's version-history control: step older / newer through the list, or\n * open the dropdown and jump straight to one.\n *\n * Shared by both editors — it was `cloud/components/SnapshotHistory.vue` and\n * spoke Cloud's wire shape (`created_at`, `is_autosave`) directly. It now reads\n * the `TemplateVersion` contract, so any provider drives it.\n */\nimport { computed, ref } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport type { TemplateVersion } from \"@templatical/types\";\nimport { useI18n } from \"../composables/useI18n\";\nimport { formatRelativeTime } from \"../utils/formatRelativeTime\";\n\nconst props = defineProps<{\n versions: TemplateVersion[];\n isLoading: boolean;\n isRestoring: boolean;\n /** Which version is on the canvas, or `null` while editing normally. */\n previewingId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"open\"): void;\n (e: \"navigate\", version: TemplateVersion): void;\n}>();\n\nconst { t, format } = useI18n();\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n/**\n * Position in the list (0 = newest), derived from what is actually previewed\n * rather than tracked locally. A local index went stale the moment the user\n * cancelled a preview — the arrows then stepped from wherever they had left off\n * instead of from the top.\n */\nconst currentIndex = computed(() =>\n props.previewingId === null\n ? -1\n : props.versions.findIndex((v) => v.id === props.previewingId),\n);\n\nconst canGoNewer = computed(\n () => currentIndex.value > 0 && !props.isRestoring && !props.isLoading,\n);\n\nconst canGoOlder = computed(\n () =>\n currentIndex.value < props.versions.length - 1 &&\n props.versions.length > 0 &&\n !props.isRestoring &&\n !props.isLoading,\n);\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n emit(\"navigate\", props.versions[currentIndex.value - 1]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n emit(\"navigate\", props.versions[currentIndex.value + 1]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n // Always on open, never only when empty: history grows behind the user's back\n // (every save may record one), so a list fetched once would go stale silently.\n if (isOpen.value) emit(\"open\");\n}\n\nfunction selectVersion(version: TemplateVersion): void {\n emit(\"navigate\", version);\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(dateString, t.time, format, 7);\n if (result !== null) return result;\n\n return new Date(dateString).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n data-testid=\"version-history\"\n >\n <!-- Step to an older version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-older\"\n :disabled=\"!canGoOlder\"\n :title=\"t.versionHistory.olderVersion\"\n :aria-label=\"t.versionHistory.olderVersion\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-toggle\"\n :aria-expanded=\"isOpen\"\n :title=\"t.versionHistory.tooltip\"\n :aria-label=\"t.versionHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n data-testid=\"version-history-dropdown\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ t.versionHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading && versions.length === 0\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n role=\"status\"\n aria-busy=\"true\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"versions.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-empty\"\n >\n {{ t.versionHistory.empty }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"version in versions\"\n :key=\"version.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-l-2 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:hover:border-l-[var(--tpl-primary)] tpl:hover:bg-[var(--tpl-bg-hover)]\"\n :class=\"\n version.id === previewingId\n ? 'tpl:border-l-[var(--tpl-primary)] tpl:bg-[var(--tpl-bg-active)]'\n : 'tpl:border-l-transparent'\n \"\n style=\"background-color: transparent\"\n data-testid=\"version-history-entry\"\n :data-version-id=\"version.id\"\n :disabled=\"isRestoring\"\n @click=\"selectVersion(version)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{\n version.label ?? formatDate(version.createdAt)\n }}</span>\n <span\n v-if=\"version.isAutomatic\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-xs tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ t.versionHistory.auto }}\n </span>\n </div>\n <!-- A labelled version still shows when it was taken, and by whom\n if the store tracks that; an unlabelled one already leads with\n the date, so the line would repeat it. -->\n <div\n v-if=\"version.label || version.author?.name\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n <template v-if=\"version.label\">{{\n formatDate(version.createdAt)\n }}</template>\n <template v-if=\"version.label && version.author?.name\">\n ·\n </template>\n <template v-if=\"version.author?.name\">{{\n version.author.name\n }}</template>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Step to a newer version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-newer\"\n :disabled=\"!canGoNewer\"\n :title=\"t.versionHistory.newerVersion\"\n :aria-label=\"t.versionHistory.newerVersion\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"VersionHistoryMenu-_DyRYBRP.js","names":[],"sources":["../../../src/components/VersionHistoryMenu.vue","../../../src/components/VersionHistoryMenu.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The header's version-history control: step older / newer through the list, or\n * open the dropdown and jump straight to one.\n *\n * Shared by both editors — it was `cloud/components/SnapshotHistory.vue` and\n * spoke Cloud's wire shape (`created_at`, `is_autosave`) directly. It now reads\n * the `TemplateVersion` contract, so any provider drives it.\n */\nimport { computed, ref } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport type { TemplateVersion } from \"@templatical/types\";\nimport { useI18n } from \"../composables/useI18n\";\nimport { formatRelativeTime } from \"../utils/formatRelativeTime\";\n\nconst props = defineProps<{\n versions: TemplateVersion[];\n isLoading: boolean;\n isRestoring: boolean;\n /** Which version is on the canvas, or `null` while editing normally. */\n previewingId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"open\"): void;\n (e: \"navigate\", version: TemplateVersion): void;\n}>();\n\nconst { t, format } = useI18n();\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n/**\n * Position in the list (0 = newest), derived from what is actually previewed\n * rather than tracked locally. A local index went stale the moment the user\n * cancelled a preview — the arrows then stepped from wherever they had left off\n * instead of from the top.\n */\nconst currentIndex = computed(() =>\n props.previewingId === null\n ? -1\n : props.versions.findIndex((v) => v.id === props.previewingId),\n);\n\nconst canGoNewer = computed(\n () => currentIndex.value > 0 && !props.isRestoring && !props.isLoading,\n);\n\nconst canGoOlder = computed(\n () =>\n currentIndex.value < props.versions.length - 1 &&\n props.versions.length > 0 &&\n !props.isRestoring &&\n !props.isLoading,\n);\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n emit(\"navigate\", props.versions[currentIndex.value - 1]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n emit(\"navigate\", props.versions[currentIndex.value + 1]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n // Always on open, never only when empty: history grows behind the user's back\n // (every save may record one), so a list fetched once would go stale silently.\n if (isOpen.value) emit(\"open\");\n}\n\nfunction selectVersion(version: TemplateVersion): void {\n emit(\"navigate\", version);\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(dateString, t.time, format, 7);\n if (result !== null) return result;\n\n return new Date(dateString).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n data-testid=\"version-history\"\n >\n <!-- Step to an older version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-older\"\n :disabled=\"!canGoOlder\"\n :title=\"t.versionHistory.olderVersion\"\n :aria-label=\"t.versionHistory.olderVersion\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-toggle\"\n :aria-expanded=\"isOpen\"\n :title=\"t.versionHistory.tooltip\"\n :aria-label=\"t.versionHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n data-testid=\"version-history-dropdown\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ t.versionHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading && versions.length === 0\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n role=\"status\"\n aria-busy=\"true\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"versions.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-empty\"\n >\n {{ t.versionHistory.empty }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"version in versions\"\n :key=\"version.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-l-2 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:hover:border-l-[var(--tpl-primary)] tpl:hover:bg-[var(--tpl-bg-hover)]\"\n :class=\"\n version.id === previewingId\n ? 'tpl:border-l-[var(--tpl-primary)] tpl:bg-[var(--tpl-bg-active)]'\n : 'tpl:border-l-transparent'\n \"\n style=\"background-color: transparent\"\n data-testid=\"version-history-entry\"\n :data-version-id=\"version.id\"\n :disabled=\"isRestoring\"\n @click=\"selectVersion(version)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{\n version.label ?? formatDate(version.createdAt)\n }}</span>\n <span\n v-if=\"version.isAutomatic\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-xs tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ t.versionHistory.auto }}\n </span>\n </div>\n <!-- A labelled version still shows when it was taken, and by whom\n if the store tracks that; an unlabelled one already leads with\n the date, so the line would repeat it. -->\n <div\n v-if=\"version.label || version.author?.name\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n <template v-if=\"version.label\">{{\n formatDate(version.createdAt)\n }}</template>\n <template v-if=\"version.label && version.author?.name\">\n ·\n </template>\n <template v-if=\"version.author?.name\">{{\n version.author.name\n }}</template>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Step to a newer version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-newer\"\n :disabled=\"!canGoNewer\"\n :title=\"t.versionHistory.newerVersion\"\n :aria-label=\"t.versionHistory.newerVersion\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * The header's version-history control: step older / newer through the list, or\n * open the dropdown and jump straight to one.\n *\n * Shared by both editors — it was `cloud/components/SnapshotHistory.vue` and\n * spoke Cloud's wire shape (`created_at`, `is_autosave`) directly. It now reads\n * the `TemplateVersion` contract, so any provider drives it.\n */\nimport { computed, ref } from \"vue\";\nimport { onClickOutside } from \"@vueuse/core\";\nimport {\n ChevronDown,\n ChevronLeft,\n ChevronRight,\n Clock,\n LoaderCircle,\n} from \"@lucide/vue\";\nimport type { TemplateVersion } from \"@templatical/types\";\nimport { useI18n } from \"../composables/useI18n\";\nimport { formatRelativeTime } from \"../utils/formatRelativeTime\";\n\nconst props = defineProps<{\n versions: TemplateVersion[];\n isLoading: boolean;\n isRestoring: boolean;\n /** Which version is on the canvas, or `null` while editing normally. */\n previewingId: string | null;\n}>();\n\nconst emit = defineEmits<{\n (e: \"open\"): void;\n (e: \"navigate\", version: TemplateVersion): void;\n}>();\n\nconst { t, format } = useI18n();\n\nconst isOpen = ref(false);\nconst dropdownRef = ref<HTMLElement | null>(null);\n\n/**\n * Position in the list (0 = newest), derived from what is actually previewed\n * rather than tracked locally. A local index went stale the moment the user\n * cancelled a preview — the arrows then stepped from wherever they had left off\n * instead of from the top.\n */\nconst currentIndex = computed(() =>\n props.previewingId === null\n ? -1\n : props.versions.findIndex((v) => v.id === props.previewingId),\n);\n\nconst canGoNewer = computed(\n () => currentIndex.value > 0 && !props.isRestoring && !props.isLoading,\n);\n\nconst canGoOlder = computed(\n () =>\n currentIndex.value < props.versions.length - 1 &&\n props.versions.length > 0 &&\n !props.isRestoring &&\n !props.isLoading,\n);\n\nfunction goNewer(): void {\n if (!canGoNewer.value) return;\n emit(\"navigate\", props.versions[currentIndex.value - 1]);\n}\n\nfunction goOlder(): void {\n if (!canGoOlder.value) return;\n emit(\"navigate\", props.versions[currentIndex.value + 1]);\n}\n\nfunction toggleDropdown(): void {\n isOpen.value = !isOpen.value;\n // Always on open, never only when empty: history grows behind the user's back\n // (every save may record one), so a list fetched once would go stale silently.\n if (isOpen.value) emit(\"open\");\n}\n\nfunction selectVersion(version: TemplateVersion): void {\n emit(\"navigate\", version);\n isOpen.value = false;\n}\n\nfunction formatDate(dateString: string): string {\n const result = formatRelativeTime(dateString, t.time, format, 7);\n if (result !== null) return result;\n\n return new Date(dateString).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n}\n\nonClickOutside(dropdownRef, () => {\n isOpen.value = false;\n});\n</script>\n\n<template>\n <div\n ref=\"dropdownRef\"\n class=\"tpl:relative tpl:flex tpl:items-center tpl:gap-0.5\"\n data-testid=\"version-history\"\n >\n <!-- Step to an older version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-older\"\n :disabled=\"!canGoOlder\"\n :title=\"t.versionHistory.olderVersion\"\n :aria-label=\"t.versionHistory.olderVersion\"\n @click.stop=\"goOlder\"\n >\n <ChevronLeft :size=\"14\" :stroke-width=\"2\" />\n </button>\n\n <!-- History dropdown toggle -->\n <button\n class=\"tpl:flex tpl:h-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:gap-0.5 tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:px-1.5 tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-toggle\"\n :aria-expanded=\"isOpen\"\n :title=\"t.versionHistory.tooltip\"\n :aria-label=\"t.versionHistory.tooltip\"\n @click.stop=\"toggleDropdown\"\n >\n <Clock :size=\"16\" :stroke-width=\"1.5\" />\n <ChevronDown\n class=\"tpl:transition-transform\"\n :class=\"{ 'tpl:rotate-180': isOpen }\"\n :size=\"10\"\n :stroke-width=\"2\"\n />\n </button>\n\n <Transition name=\"tpl-dropdown\">\n <div\n v-if=\"isOpen\"\n class=\"tpl-scale-in tpl:absolute tpl:top-full tpl:left-1/2 tpl:z-50 tpl:mt-2 tpl:w-72 tpl:-translate-x-1/2 tpl:overflow-hidden tpl:rounded-[var(--tpl-radius)] tpl:bg-[var(--tpl-bg)] tpl:border tpl:border-[var(--tpl-border)] tpl:shadow-[var(--tpl-shadow-lg)]\"\n data-testid=\"version-history-dropdown\"\n >\n <div\n class=\"tpl:border-b tpl:px-3 tpl:py-2 tpl:text-xs tpl:font-semibold tpl:text-[var(--tpl-text)] tpl:border-[var(--tpl-border)]\"\n >\n {{ t.versionHistory.dropdownTitle }}\n </div>\n\n <div\n v-if=\"isLoading && versions.length === 0\"\n class=\"tpl:flex tpl:items-center tpl:justify-center tpl:py-8\"\n role=\"status\"\n aria-busy=\"true\"\n >\n <LoaderCircle\n class=\"tpl:animate-spin tpl:text-[var(--tpl-primary)]\"\n :size=\"20\"\n :stroke-width=\"2\"\n />\n </div>\n\n <div\n v-else-if=\"versions.length === 0\"\n class=\"tpl:px-3 tpl:py-6 tpl:text-center tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-empty\"\n >\n {{ t.versionHistory.empty }}\n </div>\n\n <div v-else class=\"tpl:max-h-64 tpl:overflow-y-auto\">\n <button\n v-for=\"version in versions\"\n :key=\"version.id\"\n class=\"tpl:flex tpl:w-full tpl:cursor-pointer tpl:items-center tpl:border-l-2 tpl:px-3 tpl:py-2.5 tpl:text-left tpl:transition-all tpl:hover:border-l-[var(--tpl-primary)] tpl:hover:bg-[var(--tpl-bg-hover)]\"\n :class=\"\n version.id === previewingId\n ? 'tpl:border-l-[var(--tpl-primary)] tpl:bg-[var(--tpl-bg-active)]'\n : 'tpl:border-l-transparent'\n \"\n style=\"background-color: transparent\"\n data-testid=\"version-history-entry\"\n :data-version-id=\"version.id\"\n :disabled=\"isRestoring\"\n @click=\"selectVersion(version)\"\n >\n <div class=\"tpl:flex tpl:flex-col tpl:gap-0.5\">\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-1.5 tpl:text-xs tpl:font-medium tpl:text-[var(--tpl-text)]\"\n >\n <span>{{\n version.label ?? formatDate(version.createdAt)\n }}</span>\n <span\n v-if=\"version.isAutomatic\"\n class=\"tpl:rounded tpl:px-1 tpl:py-0.5 tpl:text-xs tpl:font-normal tpl:bg-[var(--tpl-bg-active)] tpl:text-[var(--tpl-text-muted)]\"\n >\n {{ t.versionHistory.auto }}\n </span>\n </div>\n <!-- A labelled version still shows when it was taken, and by whom\n if the store tracks that; an unlabelled one already leads with\n the date, so the line would repeat it. -->\n <div\n v-if=\"version.label || version.author?.name\"\n class=\"tpl:text-xs tpl:text-[var(--tpl-text-muted)]\"\n >\n <template v-if=\"version.label\">{{\n formatDate(version.createdAt)\n }}</template>\n <template v-if=\"version.label && version.author?.name\">\n ·\n </template>\n <template v-if=\"version.author?.name\">{{\n version.author.name\n }}</template>\n </div>\n </div>\n </button>\n </div>\n </div>\n </Transition>\n\n <!-- Step to a newer version -->\n <button\n class=\"tpl:flex tpl:size-7 tpl:shrink-0 tpl:cursor-pointer tpl:items-center tpl:justify-center tpl:rounded-[var(--tpl-radius-sm)] tpl:border-none tpl:bg-transparent tpl:transition-colors tpl:hover:bg-[var(--tpl-bg-hover)] tpl:disabled:cursor-not-allowed tpl:disabled:opacity-30 tpl:disabled:hover:bg-transparent tpl:text-[var(--tpl-text-muted)]\"\n data-testid=\"version-history-newer\"\n :disabled=\"!canGoNewer\"\n :title=\"t.versionHistory.newerVersion\"\n :aria-label=\"t.versionHistory.newerVersion\"\n @click.stop=\"goNewer\"\n >\n <ChevronRight :size=\"14\" :stroke-width=\"2\" />\n </button>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import { N as e, S as t, at as n, g as r, h as i, m as a, u as o, x as s } from "./draggable-BfpsXFg7.js";
1
+ import { N as e, S as t, at as n, g as r, h as i, m as a, u as o, x as s } from "./draggable-BLMjz0GK.js";
2
2
  //#endregion
3
3
  //#region src/components/VersionHistoryPanels.vue
4
4
  var c = /* @__PURE__ */ t({
5
5
  __name: "VersionHistoryPanels",
6
6
  props: { feature: {} },
7
7
  setup(t) {
8
- let c = t, l = s(() => import("./VersionPreviewBanner-7DZLUVaE.js")), u = s(() => import("./RestoreVersionDialog-BWewwJIZ.js"));
8
+ let c = t, l = s(() => import("./VersionPreviewBanner-FbBmgknN.js")), u = s(() => import("./RestoreVersionDialog-Dz0bX5ZZ.js"));
9
9
  async function d() {
10
10
  try {
11
11
  await c.feature.requestRestore();
@@ -45,4 +45,4 @@ var c = /* @__PURE__ */ t({
45
45
  //#endregion
46
46
  export { c as default };
47
47
 
48
- //# sourceMappingURL=VersionHistoryPanels-oTKA6TUS.js.map
48
+ //# sourceMappingURL=VersionHistoryPanels-DGfOOcKV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VersionHistoryPanels-oTKA6TUS.js","names":[],"sources":["../../../src/components/VersionHistoryPanels.vue","../../../src/components/VersionHistoryPanels.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Mount point for the version-history chrome that sits outside the header,\n * shared by the OSS and Cloud editors.\n *\n * Same shape as `SavedBlocksPanels.vue` / `TestEmailPanel.vue`: everything here\n * is `defineAsyncComponent` behind a `v-if` on its own state, and the editors in\n * turn lazy-load *this* wrapper and render it only when a\n * `VersionHistoryProvider` is configured — so a consumer without one downloads\n * none of it.\n *\n * The header's dropdown control is not here for one reason only: it has to sit\n * in the header's centre column. It is lazily imported at those two sites\n * instead, and covered by the same CDN chunk guard.\n */\nimport { defineAsyncComponent } from \"vue\";\nimport type { UseVersionHistoryFeatureReturn } from \"../composables/useVersionHistoryFeature\";\n\nconst props = defineProps<{\n feature: UseVersionHistoryFeatureReturn;\n}>();\n\nconst VersionPreviewBanner = defineAsyncComponent(\n () => import(\"./VersionPreviewBanner.vue\"),\n);\n// Its own chunk, fetched only if a restore is attempted with unsaved work —\n// which for a Cloud session (autosave on) is the uncommon case.\nconst RestoreVersionDialog = defineAsyncComponent(\n () => import(\"./RestoreVersionDialog.vue\"),\n);\n\n/**\n * Every action here swallows its rejection: the feature already reported it\n * through `onError` and rolled the canvas back, and an unhandled rejection out\n * of a DOM event binding helps nobody.\n */\nasync function handleRequestRestore(): Promise<void> {\n try {\n await props.feature.requestRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleSaveAndRestore(): Promise<void> {\n try {\n await props.feature.saveAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleDiscardAndRestore(): Promise<void> {\n try {\n await props.feature.discardAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n</script>\n\n<template>\n <VersionPreviewBanner\n v-if=\"feature.isPreviewing.value\"\n :visible=\"feature.isPreviewing.value\"\n :can-restore=\"feature.canRestore.value\"\n @cancel=\"feature.cancelPreview()\"\n @confirm=\"handleRequestRestore\"\n />\n\n <RestoreVersionDialog\n v-if=\"feature.isConfirmingRestore.value\"\n :visible=\"feature.isConfirmingRestore.value\"\n :can-save=\"feature.canSaveBeforeRestore.value\"\n :is-busy=\"feature.isConfirmBusy.value\"\n @cancel=\"feature.cancelRestoreConfirm()\"\n @save-and-restore=\"handleSaveAndRestore\"\n @discard-and-restore=\"handleDiscardAndRestore\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * Mount point for the version-history chrome that sits outside the header,\n * shared by the OSS and Cloud editors.\n *\n * Same shape as `SavedBlocksPanels.vue` / `TestEmailPanel.vue`: everything here\n * is `defineAsyncComponent` behind a `v-if` on its own state, and the editors in\n * turn lazy-load *this* wrapper and render it only when a\n * `VersionHistoryProvider` is configured — so a consumer without one downloads\n * none of it.\n *\n * The header's dropdown control is not here for one reason only: it has to sit\n * in the header's centre column. It is lazily imported at those two sites\n * instead, and covered by the same CDN chunk guard.\n */\nimport { defineAsyncComponent } from \"vue\";\nimport type { UseVersionHistoryFeatureReturn } from \"../composables/useVersionHistoryFeature\";\n\nconst props = defineProps<{\n feature: UseVersionHistoryFeatureReturn;\n}>();\n\nconst VersionPreviewBanner = defineAsyncComponent(\n () => import(\"./VersionPreviewBanner.vue\"),\n);\n// Its own chunk, fetched only if a restore is attempted with unsaved work —\n// which for a Cloud session (autosave on) is the uncommon case.\nconst RestoreVersionDialog = defineAsyncComponent(\n () => import(\"./RestoreVersionDialog.vue\"),\n);\n\n/**\n * Every action here swallows its rejection: the feature already reported it\n * through `onError` and rolled the canvas back, and an unhandled rejection out\n * of a DOM event binding helps nobody.\n */\nasync function handleRequestRestore(): Promise<void> {\n try {\n await props.feature.requestRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleSaveAndRestore(): Promise<void> {\n try {\n await props.feature.saveAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleDiscardAndRestore(): Promise<void> {\n try {\n await props.feature.discardAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n</script>\n\n<template>\n <VersionPreviewBanner\n v-if=\"feature.isPreviewing.value\"\n :visible=\"feature.isPreviewing.value\"\n :can-restore=\"feature.canRestore.value\"\n @cancel=\"feature.cancelPreview()\"\n @confirm=\"handleRequestRestore\"\n />\n\n <RestoreVersionDialog\n v-if=\"feature.isConfirmingRestore.value\"\n :visible=\"feature.isConfirmingRestore.value\"\n :can-save=\"feature.canSaveBeforeRestore.value\"\n :is-busy=\"feature.isConfirmBusy.value\"\n @cancel=\"feature.cancelRestoreConfirm()\"\n @save-and-restore=\"handleSaveAndRestore\"\n @discard-and-restore=\"handleDiscardAndRestore\"\n />\n</template>\n"],"mappings":";;;;;;;EAkBA,IAAM,IAAQ,GAIR,IAAuB,QACrB,OAAO,qCACf,GAGM,IAAuB,QACrB,OAAO,qCACf;EAOA,eAAe,IAAsC;GACnD,IAAI;IACF,MAAM,EAAM,QAAQ,eAAe;GACrC,QAAQ,CAER;EACF;EAEA,eAAe,IAAsC;GACnD,IAAI;IACF,MAAM,EAAM,QAAQ,eAAe;GACrC,QAAQ,CAER;EACF;EAEA,eAAe,IAAyC;GACtD,IAAI;IACF,MAAM,EAAM,QAAQ,kBAAkB;GACxC,QAAQ,CAER;EACF;oBAKU,EAAA,GAAA,EAAA,GAAA,MAAA,CAAA,EAAA,QAAQ,aAAa,SAD7B,EAAA,GAAA,EAME,EAAA,CAAA,GAAA;;GAJC,SAAS,EAAA,QAAQ,aAAa;GAC9B,eAAa,EAAA,QAAQ,WAAW;GAChC,UAAM,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,cAAa;GAC7B,WAAS;EAIJ,GAAA,MAAA,GAAA,CAAA,WAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAAA,EAAA,QAAQ,oBAAoB,SADpC,EAAA,GAAA,EAQE,EAAA,CAAA,GAAA;;GANC,SAAS,EAAA,QAAQ,oBAAoB;GACrC,YAAU,EAAA,QAAQ,qBAAqB;GACvC,WAAS,EAAA,QAAQ,cAAc;GAC/B,UAAM,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,qBAAoB;GACpC,kBAAkB;GAClB,qBAAqB"}
1
+ {"version":3,"file":"VersionHistoryPanels-DGfOOcKV.js","names":[],"sources":["../../../src/components/VersionHistoryPanels.vue","../../../src/components/VersionHistoryPanels.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * Mount point for the version-history chrome that sits outside the header,\n * shared by the OSS and Cloud editors.\n *\n * Same shape as `SavedBlocksPanels.vue` / `TestEmailPanel.vue`: everything here\n * is `defineAsyncComponent` behind a `v-if` on its own state, and the editors in\n * turn lazy-load *this* wrapper and render it only when a\n * `VersionHistoryProvider` is configured — so a consumer without one downloads\n * none of it.\n *\n * The header's dropdown control is not here for one reason only: it has to sit\n * in the header's centre column. It is lazily imported at those two sites\n * instead, and covered by the same CDN chunk guard.\n */\nimport { defineAsyncComponent } from \"vue\";\nimport type { UseVersionHistoryFeatureReturn } from \"../composables/useVersionHistoryFeature\";\n\nconst props = defineProps<{\n feature: UseVersionHistoryFeatureReturn;\n}>();\n\nconst VersionPreviewBanner = defineAsyncComponent(\n () => import(\"./VersionPreviewBanner.vue\"),\n);\n// Its own chunk, fetched only if a restore is attempted with unsaved work —\n// which for a Cloud session (autosave on) is the uncommon case.\nconst RestoreVersionDialog = defineAsyncComponent(\n () => import(\"./RestoreVersionDialog.vue\"),\n);\n\n/**\n * Every action here swallows its rejection: the feature already reported it\n * through `onError` and rolled the canvas back, and an unhandled rejection out\n * of a DOM event binding helps nobody.\n */\nasync function handleRequestRestore(): Promise<void> {\n try {\n await props.feature.requestRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleSaveAndRestore(): Promise<void> {\n try {\n await props.feature.saveAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleDiscardAndRestore(): Promise<void> {\n try {\n await props.feature.discardAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n</script>\n\n<template>\n <VersionPreviewBanner\n v-if=\"feature.isPreviewing.value\"\n :visible=\"feature.isPreviewing.value\"\n :can-restore=\"feature.canRestore.value\"\n @cancel=\"feature.cancelPreview()\"\n @confirm=\"handleRequestRestore\"\n />\n\n <RestoreVersionDialog\n v-if=\"feature.isConfirmingRestore.value\"\n :visible=\"feature.isConfirmingRestore.value\"\n :can-save=\"feature.canSaveBeforeRestore.value\"\n :is-busy=\"feature.isConfirmBusy.value\"\n @cancel=\"feature.cancelRestoreConfirm()\"\n @save-and-restore=\"handleSaveAndRestore\"\n @discard-and-restore=\"handleDiscardAndRestore\"\n />\n</template>\n","<script setup lang=\"ts\">\n/**\n * Mount point for the version-history chrome that sits outside the header,\n * shared by the OSS and Cloud editors.\n *\n * Same shape as `SavedBlocksPanels.vue` / `TestEmailPanel.vue`: everything here\n * is `defineAsyncComponent` behind a `v-if` on its own state, and the editors in\n * turn lazy-load *this* wrapper and render it only when a\n * `VersionHistoryProvider` is configured — so a consumer without one downloads\n * none of it.\n *\n * The header's dropdown control is not here for one reason only: it has to sit\n * in the header's centre column. It is lazily imported at those two sites\n * instead, and covered by the same CDN chunk guard.\n */\nimport { defineAsyncComponent } from \"vue\";\nimport type { UseVersionHistoryFeatureReturn } from \"../composables/useVersionHistoryFeature\";\n\nconst props = defineProps<{\n feature: UseVersionHistoryFeatureReturn;\n}>();\n\nconst VersionPreviewBanner = defineAsyncComponent(\n () => import(\"./VersionPreviewBanner.vue\"),\n);\n// Its own chunk, fetched only if a restore is attempted with unsaved work —\n// which for a Cloud session (autosave on) is the uncommon case.\nconst RestoreVersionDialog = defineAsyncComponent(\n () => import(\"./RestoreVersionDialog.vue\"),\n);\n\n/**\n * Every action here swallows its rejection: the feature already reported it\n * through `onError` and rolled the canvas back, and an unhandled rejection out\n * of a DOM event binding helps nobody.\n */\nasync function handleRequestRestore(): Promise<void> {\n try {\n await props.feature.requestRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleSaveAndRestore(): Promise<void> {\n try {\n await props.feature.saveAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n\nasync function handleDiscardAndRestore(): Promise<void> {\n try {\n await props.feature.discardAndRestore();\n } catch {\n /* reported through onError */\n }\n}\n</script>\n\n<template>\n <VersionPreviewBanner\n v-if=\"feature.isPreviewing.value\"\n :visible=\"feature.isPreviewing.value\"\n :can-restore=\"feature.canRestore.value\"\n @cancel=\"feature.cancelPreview()\"\n @confirm=\"handleRequestRestore\"\n />\n\n <RestoreVersionDialog\n v-if=\"feature.isConfirmingRestore.value\"\n :visible=\"feature.isConfirmingRestore.value\"\n :can-save=\"feature.canSaveBeforeRestore.value\"\n :is-busy=\"feature.isConfirmBusy.value\"\n @cancel=\"feature.cancelRestoreConfirm()\"\n @save-and-restore=\"handleSaveAndRestore\"\n @discard-and-restore=\"handleDiscardAndRestore\"\n />\n</template>\n"],"mappings":";;;;;;;EAkBA,IAAM,IAAQ,GAIR,IAAuB,QACrB,OAAO,qCACf,GAGM,IAAuB,QACrB,OAAO,qCACf;EAOA,eAAe,IAAsC;GACnD,IAAI;IACF,MAAM,EAAM,QAAQ,eAAe;GACrC,QAAQ,CAER;EACF;EAEA,eAAe,IAAsC;GACnD,IAAI;IACF,MAAM,EAAM,QAAQ,eAAe;GACrC,QAAQ,CAER;EACF;EAEA,eAAe,IAAyC;GACtD,IAAI;IACF,MAAM,EAAM,QAAQ,kBAAkB;GACxC,QAAQ,CAER;EACF;oBAKU,EAAA,GAAA,EAAA,GAAA,MAAA,CAAA,EAAA,QAAQ,aAAa,SAD7B,EAAA,GAAA,EAME,EAAA,CAAA,GAAA;;GAJC,SAAS,EAAA,QAAQ,aAAa;GAC9B,eAAa,EAAA,QAAQ,WAAW;GAChC,UAAM,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,cAAa;GAC7B,WAAS;EAIJ,GAAA,MAAA,GAAA,CAAA,WAAA,aAAA,CAAA,KAAA,EAAA,IAAA,EAAA,GAAA,EAAA,QAAQ,oBAAoB,SADpC,EAAA,GAAA,EAQE,EAAA,CAAA,GAAA;;GANC,SAAS,EAAA,QAAQ,oBAAoB;GACrC,YAAU,EAAA,QAAQ,qBAAqB;GACvC,WAAS,EAAA,QAAQ,cAAc;GAC/B,UAAM,AAAA,EAAA,QAAA,MAAE,EAAA,QAAQ,qBAAoB;GACpC,kBAAkB;GAClB,qBAAqB"}
@@ -1,6 +1,6 @@
1
- import { N as e, S as t, at as n, b as r, ct as i, g as a, h as o, p as s, ut as c } from "./draggable-BfpsXFg7.js";
2
- import { t as l } from "./useI18n-4sUbTM3Y.js";
3
- import { kt as u } from "./icons-BrdgOeXm.js";
1
+ import { N as e, S as t, at as n, b as r, ct as i, g as a, h as o, p as s, ut as c } from "./draggable-BLMjz0GK.js";
2
+ import { t as l } from "./useI18n-DYb1SgLB.js";
3
+ import { kt as u } from "./icons-MeYdeH4P.js";
4
4
  import { f as d, v as f } from "./styleConstants-C_YAPdQS.js";
5
5
  //#region src/components/VersionPreviewBanner.vue?vue&type=script&setup=true&lang.ts
6
6
  var p = {
@@ -37,4 +37,4 @@ var p = {
37
37
  //#endregion
38
38
  export { g as default };
39
39
 
40
- //# sourceMappingURL=VersionPreviewBanner-7DZLUVaE.js.map
40
+ //# sourceMappingURL=VersionPreviewBanner-FbBmgknN.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VersionPreviewBanner-7DZLUVaE.js","names":[],"sources":["../../../src/components/VersionPreviewBanner.vue","../../../src/components/VersionPreviewBanner.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ghostBtnClass, primaryBtnClass } from \"../constants/styleConstants\";\n/**\n * Shown while a past version is on the canvas instead of the user's own work.\n * Cancel puts the pre-preview content back; Restore makes the version current.\n *\n * Lives outside `src/cloud/` because version history is a BYO provider, not a\n * Cloud feature — a consumer's own `versionHistory` provider drives this banner\n * with no Cloud involved.\n */\nimport { Clock } from \"@lucide/vue\";\nimport { useI18n } from \"../composables/useI18n\";\n\ndefineProps<{\n visible: boolean;\n /**\n * Whether the provider supplied `restore`. When it didn't, history is\n * browse-and-preview only, so the confirm action does not render at all\n * rather than rendering disabled — the same discipline saved blocks uses.\n */\n canRestore: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"cancel\"): void;\n (e: \"confirm\"): void;\n}>();\n\nconst { t } = useI18n();\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n class=\"tpl-preview-banner tpl:absolute tpl:top-14 tpl:right-0 tpl:left-0 tpl:z-40 tpl:flex tpl:items-center tpl:justify-center tpl:gap-4 tpl:px-4 tpl:py-3 tpl:bg-[var(--tpl-primary-light)] tpl:border-b tpl:border-[var(--tpl-primary)]\"\n data-testid=\"version-preview-banner\"\n role=\"status\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:text-sm tpl:text-[var(--tpl-text)]\"\n >\n <Clock\n :size=\"18\"\n :stroke-width=\"2\"\n class=\"tpl:text-[var(--tpl-primary)]\"\n />\n <span>{{ t.versionPreview.message }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n :class=\"ghostBtnClass\"\n style=\"background-color: transparent\"\n data-testid=\"version-preview-cancel\"\n @click=\"emit('cancel')\"\n >\n {{ t.versionPreview.cancel }}\n </button>\n <button\n v-if=\"canRestore\"\n :class=\"primaryBtnClass\"\n data-testid=\"version-preview-restore\"\n @click=\"emit('confirm')\"\n >\n {{ t.versionPreview.restore }}\n </button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ghostBtnClass, primaryBtnClass } from \"../constants/styleConstants\";\n/**\n * Shown while a past version is on the canvas instead of the user's own work.\n * Cancel puts the pre-preview content back; Restore makes the version current.\n *\n * Lives outside `src/cloud/` because version history is a BYO provider, not a\n * Cloud feature — a consumer's own `versionHistory` provider drives this banner\n * with no Cloud involved.\n */\nimport { Clock } from \"@lucide/vue\";\nimport { useI18n } from \"../composables/useI18n\";\n\ndefineProps<{\n visible: boolean;\n /**\n * Whether the provider supplied `restore`. When it didn't, history is\n * browse-and-preview only, so the confirm action does not render at all\n * rather than rendering disabled — the same discipline saved blocks uses.\n */\n canRestore: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"cancel\"): void;\n (e: \"confirm\"): void;\n}>();\n\nconst { t } = useI18n();\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n class=\"tpl-preview-banner tpl:absolute tpl:top-14 tpl:right-0 tpl:left-0 tpl:z-40 tpl:flex tpl:items-center tpl:justify-center tpl:gap-4 tpl:px-4 tpl:py-3 tpl:bg-[var(--tpl-primary-light)] tpl:border-b tpl:border-[var(--tpl-primary)]\"\n data-testid=\"version-preview-banner\"\n role=\"status\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:text-sm tpl:text-[var(--tpl-text)]\"\n >\n <Clock\n :size=\"18\"\n :stroke-width=\"2\"\n class=\"tpl:text-[var(--tpl-primary)]\"\n />\n <span>{{ t.versionPreview.message }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n :class=\"ghostBtnClass\"\n style=\"background-color: transparent\"\n data-testid=\"version-preview-cancel\"\n @click=\"emit('cancel')\"\n >\n {{ t.versionPreview.cancel }}\n </button>\n <button\n v-if=\"canRestore\"\n :class=\"primaryBtnClass\"\n data-testid=\"version-preview-restore\"\n @click=\"emit('confirm')\"\n >\n {{ t.versionPreview.restore }}\n </button>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAuBA,IAAM,IAAO,GAKP,EAAE,SAAM,EAAQ;mBAKZ,EAAA,WADR,EAAA,GAAA,EAkCM,OAlCN,GAkCM,CA5BJ,EASM,OATN,GASM,CANJ,EAIE,EAAA,CAAA,GAAA;GAHC,MAAM;GACN,gBAAc;GACf,OAAM;EAER,CAAA,GAAA,EAA2C,QAAA,MAAA,EAAlC,EAAA,CAAA,CAAC,CAAC,eAAe,OAAO,GAAA,CAAA,CAAA,CAAA,GAEnC,EAiBM,OAjBN,GAiBM,CAhBJ,EAOS,UAAA;GANN,OAAK,EAAE,EAAA,CAAA,CAAa;GACrB,OAAA,EAAA,oBAAA,cAAA;GACA,eAAY;GACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAI,QAAA;EAET,GAAA,EAAA,EAAA,CAAA,CAAC,CAAC,eAAe,MAAM,GAAA,CAAA,GAGpB,EAAA,cADR,EAAA,GAAA,EAOS,UAAA;;GALN,OAAK,EAAE,EAAA,CAAA,CAAe;GACvB,eAAY;GACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAI,SAAA;EAET,GAAA,EAAA,EAAA,CAAA,CAAC,CAAC,eAAe,OAAO,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
1
+ {"version":3,"file":"VersionPreviewBanner-FbBmgknN.js","names":[],"sources":["../../../src/components/VersionPreviewBanner.vue","../../../src/components/VersionPreviewBanner.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ghostBtnClass, primaryBtnClass } from \"../constants/styleConstants\";\n/**\n * Shown while a past version is on the canvas instead of the user's own work.\n * Cancel puts the pre-preview content back; Restore makes the version current.\n *\n * Lives outside `src/cloud/` because version history is a BYO provider, not a\n * Cloud feature — a consumer's own `versionHistory` provider drives this banner\n * with no Cloud involved.\n */\nimport { Clock } from \"@lucide/vue\";\nimport { useI18n } from \"../composables/useI18n\";\n\ndefineProps<{\n visible: boolean;\n /**\n * Whether the provider supplied `restore`. When it didn't, history is\n * browse-and-preview only, so the confirm action does not render at all\n * rather than rendering disabled — the same discipline saved blocks uses.\n */\n canRestore: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"cancel\"): void;\n (e: \"confirm\"): void;\n}>();\n\nconst { t } = useI18n();\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n class=\"tpl-preview-banner tpl:absolute tpl:top-14 tpl:right-0 tpl:left-0 tpl:z-40 tpl:flex tpl:items-center tpl:justify-center tpl:gap-4 tpl:px-4 tpl:py-3 tpl:bg-[var(--tpl-primary-light)] tpl:border-b tpl:border-[var(--tpl-primary)]\"\n data-testid=\"version-preview-banner\"\n role=\"status\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:text-sm tpl:text-[var(--tpl-text)]\"\n >\n <Clock\n :size=\"18\"\n :stroke-width=\"2\"\n class=\"tpl:text-[var(--tpl-primary)]\"\n />\n <span>{{ t.versionPreview.message }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n :class=\"ghostBtnClass\"\n style=\"background-color: transparent\"\n data-testid=\"version-preview-cancel\"\n @click=\"emit('cancel')\"\n >\n {{ t.versionPreview.cancel }}\n </button>\n <button\n v-if=\"canRestore\"\n :class=\"primaryBtnClass\"\n data-testid=\"version-preview-restore\"\n @click=\"emit('confirm')\"\n >\n {{ t.versionPreview.restore }}\n </button>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ghostBtnClass, primaryBtnClass } from \"../constants/styleConstants\";\n/**\n * Shown while a past version is on the canvas instead of the user's own work.\n * Cancel puts the pre-preview content back; Restore makes the version current.\n *\n * Lives outside `src/cloud/` because version history is a BYO provider, not a\n * Cloud feature — a consumer's own `versionHistory` provider drives this banner\n * with no Cloud involved.\n */\nimport { Clock } from \"@lucide/vue\";\nimport { useI18n } from \"../composables/useI18n\";\n\ndefineProps<{\n visible: boolean;\n /**\n * Whether the provider supplied `restore`. When it didn't, history is\n * browse-and-preview only, so the confirm action does not render at all\n * rather than rendering disabled — the same discipline saved blocks uses.\n */\n canRestore: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: \"cancel\"): void;\n (e: \"confirm\"): void;\n}>();\n\nconst { t } = useI18n();\n</script>\n\n<template>\n <div\n v-if=\"visible\"\n class=\"tpl-preview-banner tpl:absolute tpl:top-14 tpl:right-0 tpl:left-0 tpl:z-40 tpl:flex tpl:items-center tpl:justify-center tpl:gap-4 tpl:px-4 tpl:py-3 tpl:bg-[var(--tpl-primary-light)] tpl:border-b tpl:border-[var(--tpl-primary)]\"\n data-testid=\"version-preview-banner\"\n role=\"status\"\n >\n <div\n class=\"tpl:flex tpl:items-center tpl:gap-2 tpl:text-sm tpl:text-[var(--tpl-text)]\"\n >\n <Clock\n :size=\"18\"\n :stroke-width=\"2\"\n class=\"tpl:text-[var(--tpl-primary)]\"\n />\n <span>{{ t.versionPreview.message }}</span>\n </div>\n <div class=\"tpl:flex tpl:items-center tpl:gap-2\">\n <button\n :class=\"ghostBtnClass\"\n style=\"background-color: transparent\"\n data-testid=\"version-preview-cancel\"\n @click=\"emit('cancel')\"\n >\n {{ t.versionPreview.cancel }}\n </button>\n <button\n v-if=\"canRestore\"\n :class=\"primaryBtnClass\"\n data-testid=\"version-preview-restore\"\n @click=\"emit('confirm')\"\n >\n {{ t.versionPreview.restore }}\n </button>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;EAuBA,IAAM,IAAO,GAKP,EAAE,SAAM,EAAQ;mBAKZ,EAAA,WADR,EAAA,GAAA,EAkCM,OAlCN,GAkCM,CA5BJ,EASM,OATN,GASM,CANJ,EAIE,EAAA,CAAA,GAAA;GAHC,MAAM;GACN,gBAAc;GACf,OAAM;EAER,CAAA,GAAA,EAA2C,QAAA,MAAA,EAAlC,EAAA,CAAA,CAAC,CAAC,eAAe,OAAO,GAAA,CAAA,CAAA,CAAA,GAEnC,EAiBM,OAjBN,GAiBM,CAhBJ,EAOS,UAAA;GANN,OAAK,EAAE,EAAA,CAAA,CAAa;GACrB,OAAA,EAAA,oBAAA,cAAA;GACA,eAAY;GACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAI,QAAA;EAET,GAAA,EAAA,EAAA,CAAA,CAAC,CAAC,eAAe,MAAM,GAAA,CAAA,GAGpB,EAAA,cADR,EAAA,GAAA,EAOS,UAAA;;GALN,OAAK,EAAE,EAAA,CAAA,CAAe;GACvB,eAAY;GACX,SAAK,AAAA,EAAA,QAAA,MAAE,EAAI,SAAA;EAET,GAAA,EAAA,EAAA,CAAA,CAAC,CAAC,eAAe,OAAO,GAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAAA,IAAA,EAAA"}
@@ -1,4 +1,4 @@
1
- import { A as e, Dt as t, G as n, Ot as r, V as i, W as a, X as o, Z as s, et as c, f as l, ft as u, mt as d, v as f } from "./icons-BrdgOeXm.js";
1
+ import { A as e, Dt as t, G as n, Ot as r, V as i, W as a, X as o, Z as s, et as c, f as l, ft as u, mt as d, v as f } from "./icons-MeYdeH4P.js";
2
2
  //#region src/utils/blockTypeIcons.ts
3
3
  var p = {
4
4
  section: t,
@@ -18,4 +18,4 @@ var p = {
18
18
  //#endregion
19
19
  export { p as t };
20
20
 
21
- //# sourceMappingURL=blockTypeIcons-D8dtoELC.js.map
21
+ //# sourceMappingURL=blockTypeIcons-o4ammRlm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"blockTypeIcons-D8dtoELC.js","names":[],"sources":["../../../src/utils/blockTypeIcons.ts"],"sourcesContent":["import {\n Code,\n Columns3,\n Heading,\n Image,\n Minus,\n MoveVertical,\n Navigation,\n Pilcrow,\n Play,\n RectangleHorizontal,\n Share2,\n Table,\n Timer,\n} from \"@lucide/vue\";\nimport type { Component } from \"vue\";\n\nexport const blockTypeIcons: Record<string, Component> = {\n section: Columns3,\n title: Heading,\n paragraph: Pilcrow,\n image: Image,\n button: RectangleHorizontal,\n divider: Minus,\n video: Play,\n social: Share2,\n menu: Navigation,\n table: Table,\n spacer: MoveVertical,\n countdown: Timer,\n html: Code,\n};\n"],"mappings":";;AAiBA,IAAa,IAA4C;CACvD,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,WAAW;CACX,MAAM;AACR"}
1
+ {"version":3,"file":"blockTypeIcons-o4ammRlm.js","names":[],"sources":["../../../src/utils/blockTypeIcons.ts"],"sourcesContent":["import {\n Code,\n Columns3,\n Heading,\n Image,\n Minus,\n MoveVertical,\n Navigation,\n Pilcrow,\n Play,\n RectangleHorizontal,\n Share2,\n Table,\n Timer,\n} from \"@lucide/vue\";\nimport type { Component } from \"vue\";\n\nexport const blockTypeIcons: Record<string, Component> = {\n section: Columns3,\n title: Heading,\n paragraph: Pilcrow,\n image: Image,\n button: RectangleHorizontal,\n divider: Minus,\n video: Play,\n social: Share2,\n menu: Navigation,\n table: Table,\n spacer: MoveVertical,\n countdown: Timer,\n html: Code,\n};\n"],"mappings":";;AAiBA,IAAa,IAA4C;CACvD,SAAS;CACT,OAAO;CACP,WAAW;CACX,OAAO;CACP,QAAQ;CACR,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,WAAW;CACX,MAAM;AACR"}
@@ -164,6 +164,9 @@ var e = {
164
164
  width: "Amplada",
165
165
  fullWidth: "Amplada completa",
166
166
  widthCustom: "Personalitzada",
167
+ height: "Alçada",
168
+ heightAuto: "Automàtica",
169
+ heightCustom: "Personalitzada",
167
170
  linkUrl: "URL de l'enllaç",
168
171
  openInNewTab: "Obre en una pestanya nova",
169
172
  placeholderUrl: "Imatge de mostra",
@@ -188,6 +191,9 @@ var e = {
188
191
  altTextPlaceholder: "Descripció del vídeo",
189
192
  width: "Amplada",
190
193
  fullWidth: "Amplada completa",
194
+ height: "Alçada",
195
+ heightAuto: "Automàtica",
196
+ heightCustom: "Personalitzada",
191
197
  placeholderUrl: "Miniatura de mostra",
192
198
  placeholderUrlPlaceholder: "https://... (només per al disseny)",
193
199
  placeholderUrlTooltip: "Com que la URL del vídeo utilitza una etiqueta de fusió, podeu proporcionar una miniatura real aquí per previsualitzar el disseny mentre dissenyeu. Això no s'inclou a la sortida final.",
@@ -601,4 +607,4 @@ var e = {
601
607
  //#endregion
602
608
  export { e as default };
603
609
 
604
- //# sourceMappingURL=ca-CEuJ6IRr.js.map
610
+ //# sourceMappingURL=ca-DY0AYOLG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ca-DY0AYOLG.js","names":[],"sources":["../../../src/i18n/locales/ca.ts"],"sourcesContent":["import type en from \"./en\";\n\nconst ca: typeof en = {\n // Footer (OSS only)\n footer: {\n poweredBy: \"Amb la tecnologia de\",\n openSource: \"Codi obert\",\n },\n\n // Header — nom de la plantilla + estat de desat. Només es mostra quan hi ha un\n // proveïdor de plantilles configurat.\n header: {\n save: \"Desa\",\n saving: \"S'està desant...\",\n saved: \"Desat\",\n unsaved: \"Sense desar\",\n saveFailed: \"No s'ha pogut desar\",\n saveNoTemplate: \"Primer carrega o crea una plantilla\",\n templateName: \"Nom de la plantilla\",\n rename: \"Canvia el nom de la plantilla\",\n untitled: \"Sense títol\",\n updatedAt: \"Actualitzat {time}\",\n createdAt: \"Creat {time}\",\n updatedJustNow: \"Actualitzat ara mateix\",\n createdJustNow: \"Creat ara mateix\",\n },\n\n // Relative timestamps, shared by every surface that shows one: the header's\n // updated line, saved blocks, comments and version history.\n time: {\n justNow: \"Ara mateix\",\n minutesAgo: \"fa {minutes} min\",\n hoursAgo: \"fa {hours} h\",\n daysAgo: \"fa {days} d\",\n },\n\n // History (undo/redo)\n history: {\n collabWarning: \"Desfer pot afectar els canvis recents dels col·laboradors\",\n undo: \"Desfer\",\n redo: \"Refer\",\n },\n\n // Viewport toggle\n viewport: {\n label: \"Àrea de visualització\",\n desktop: \"Escriptori\",\n mobile: \"Mòbil\",\n },\n\n // Dark mode preview\n darkMode: {\n enable: \"Vista prèvia del mode fosc\",\n disable: \"Vista prèvia del mode clar\",\n },\n\n // Preview mode\n previewMode: {\n enable: \"Mode de vista prèvia\",\n disable: \"Surt de la vista prèvia\",\n },\n\n // Sidebar - Block types\n blocks: {\n section: \"Secció\",\n image: \"Imatge\",\n title: \"Títol\",\n paragraph: \"Paràgraf\",\n button: \"Botó\",\n divider: \"Divisor\",\n video: \"Vídeo\",\n social: \"Xarxes socials\",\n spacer: \"Espaiador\",\n html: \"HTML\",\n menu: \"Menú\",\n table: \"Taula\",\n countdown: \"Compta enrere\",\n },\n\n // Right sidebar\n sidebar: {\n content: \"Contingut\",\n settings: \"Configuració\",\n noSelection: \"Cap element seleccionat\",\n noSelectionHint: \"Selecciona un bloc al llenç per editar-lo\",\n },\n\n // Toolbar - Common\n toolbar: {\n duplicate: \"Duplica\",\n delete: \"Elimina\",\n },\n\n // Title editor toolbar\n titleEditor: {\n toolbar: \"Format del títol\",\n bold: \"Negreta (Ctrl+B)\",\n italic: \"Cursiva (Ctrl+I)\",\n addLink: \"Afegeix un enllaç\",\n },\n\n // Paragraph editor toolbar\n paragraphEditor: {\n toolbar: \"Format del text\",\n bold: \"Negreta (Ctrl+B)\",\n italic: \"Cursiva (Ctrl+I)\",\n underline: \"Subratllat (Ctrl+U)\",\n strikethrough: \"Text ratllat\",\n subscript: \"Subíndex\",\n superscript: \"Superíndex\",\n addLink: \"Afegeix un enllaç\",\n bulletList: \"Llista de vinyetes\",\n numberedList: \"Llista numerada\",\n alignLeft: \"Alinea a l'esquerra\",\n alignCenter: \"Alinea al centre\",\n alignRight: \"Alinea a la dreta\",\n alignJustify: \"Justifica\",\n clearFormatting: \"Neteja el format\",\n insertEmoji: \"Insereix un emoji\",\n fontFamily: \"Tipus de lletra\",\n defaultFont: \"Per defecte\",\n fontSize: \"Mida de la font\",\n defaultSize: \"Per defecte\",\n textColor: \"Color del text\",\n highlightColor: \"Color de ressaltat\",\n lineHeight: \"Interlínia\",\n letterSpacing: \"Espaiat de lletres\",\n emojiItemLabel: \"Insereix l'emoji {emoji}\",\n },\n\n // Block actions (BlockWrapper)\n blockActions: {\n drag: \"Arrossega per reordenar, o prem Espai per moure amb el teclat\",\n dragLifted:\n \"Movent {block}. Utilitza les fletxes amunt i avall per reposicionar, Espai o Retorn per deixar anar, Esc per cancel·lar.\",\n duplicate: \"Duplica el bloc\",\n delete: \"Elimina el bloc\",\n hiddenOnViewport: \"Ocult a {viewport}\",\n saveAsBlock: \"Desa com a bloc\",\n conditionToggle: \"Alterna la condició de visualització\",\n comments: \"Comentaris ({count})\",\n lifted: \"{block} aixecat. Posició {position} de {total}.\",\n moved: \"{block} mogut a la posició {position} de {total}.\",\n dropped: \"{block} deixat anar a la posició {position} de {total}.\",\n cancelled:\n \"Moviment cancel·lat. {block} ha tornat a la posició {position}.\",\n },\n\n // Toolbar - Section\n section: {\n dropHere: \"Deixa anar els blocs aquí\",\n columns: \"Columnes\",\n column1: \"1 columna\",\n column2: \"2 columnes\",\n column3: \"3 columnes\",\n ratio12: \"Proporció 1:2\",\n ratio21: \"Proporció 2:1\",\n borderRadius: \"Radi de la vora\",\n wrapperEnable: \"Afegeix un contenidor\",\n stackOnMobile: \"Apila en mòbil\",\n },\n\n // Text editor link dialog\n linkDialog: {\n editLink: \"Edita l'enllaç\",\n insertLink: \"Insereix l'enllaç\",\n updateLink: \"Actualitza l'enllaç\",\n removeLink: \"Elimina l'enllaç\",\n cancel: \"Cancel·la\",\n urlPlaceholder: \"https://example.com\",\n urlLabel: \"URL\",\n colorLabel: \"Color de l'enllaç\",\n },\n\n // Toolbar - Title\n title: {\n level: \"Nivell d'encapçalament\",\n heading1: \"Encapçalament 1 (36px)\",\n heading2: \"Encapçalament 2 (28px)\",\n heading3: \"Encapçalament 3 (22px)\",\n heading4: \"Encapçalament 4 (18px)\",\n fontFamily: \"Tipus de lletra\",\n inheritFont: \"Utilitza la font de la plantilla\",\n color: \"Color\",\n align: \"Alineació\",\n alignLeft: \"Esquerra\",\n alignCenter: \"Centre\",\n alignRight: \"Dreta\",\n },\n\n // Emoji picker\n emoji: {\n smileys: \"Emoticones\",\n gestures: \"Gestos\",\n objects: \"Objectes\",\n },\n\n // Toolbar - Image\n image: {\n imageUrl: \"URL de la imatge\",\n imageUrlPlaceholder: \"https://...\",\n altText: \"Text alternatiu\",\n altTextPlaceholder: \"Descripció de la imatge\",\n width: \"Amplada\",\n fullWidth: \"Amplada completa\",\n widthCustom: \"Personalitzada\",\n height: \"Alçada\",\n heightAuto: \"Automàtica\",\n heightCustom: \"Personalitzada\",\n linkUrl: \"URL de l'enllaç\",\n openInNewTab: \"Obre en una pestanya nova\",\n placeholderUrl: \"Imatge de mostra\",\n optional: \"(opcional)\",\n placeholderUrlPlaceholder: \"https://... (només per al disseny)\",\n placeholderUrlTooltip:\n \"Com que la URL de la imatge utilitza una etiqueta de fusió, podeu proporcionar una imatge real aquí per previsualitzar el disseny mentre dissenyeu. Això no s'inclou a la sortida final.\",\n clickToAdd: \"Feu clic per afegir la URL de la imatge\",\n browseMedia: \"Explora multimèdia\",\n dropToUpload: \"Deixeu anar la imatge per pujar-la\",\n uploading: \"Pujant…\",\n decorative: \"Imatge decorativa\",\n decorativeHint:\n \"Ocult per als lectors de pantalla. Utilitzeu-lo només per a espaiadors i detalls visuals.\",\n },\n\n // Toolbar - Video\n video: {\n videoUrl: \"URL del vídeo\",\n videoUrlPlaceholder: \"https://youtube.com/...\",\n openInNewTab: \"Obre en una pestanya nova\",\n customThumbnail: \"Miniatura personalitzada\",\n optional: \"(opcional)\",\n thumbnailPlaceholder: \"Generat automàticament des de la URL del vídeo\",\n altText: \"Text alternatiu\",\n altTextPlaceholder: \"Descripció del vídeo\",\n width: \"Amplada\",\n fullWidth: \"Amplada completa\",\n height: \"Alçada\",\n heightAuto: \"Automàtica\",\n heightCustom: \"Personalitzada\",\n placeholderUrl: \"Miniatura de mostra\",\n placeholderUrlPlaceholder: \"https://... (només per al disseny)\",\n placeholderUrlTooltip:\n \"Com que la URL del vídeo utilitza una etiqueta de fusió, podeu proporcionar una miniatura real aquí per previsualitzar el disseny mentre dissenyeu. Això no s'inclou a la sortida final.\",\n addVideo: \"Afegeix una URL de vídeo\",\n },\n\n // Toolbar - Button\n button: {\n fontFamily: \"Tipus de lletra\",\n inheritFont: \"Utilitza la font de la plantilla\",\n text: \"Text\",\n url: \"URL\",\n urlPlaceholder: \"https://...\",\n openInNewTab: \"Obre en una pestanya nova\",\n background: \"Fons\",\n textColor: \"Color del text\",\n borderRadius: \"Radi de la vora\",\n fontSize: \"Mida de la font\",\n width: \"Amplada\",\n widthAuto: \"Ajusta al contingut\",\n fullWidth: \"Amplada completa\",\n widthCustom: \"Personalitzada\",\n },\n\n // Toolbar - Divider\n divider: {\n style: \"Estil\",\n solid: \"Sòlid\",\n dashed: \"Amb guions\",\n dotted: \"Amb punts\",\n color: \"Color\",\n thickness: \"Gruix\",\n },\n\n // Toolbar - Social Icons\n social: {\n icons: \"Icones\",\n addIcon: \"Afegeix una icona\",\n addIcons: \"Afegeix icones de xarxes socials\",\n removeIcon: \"Elimina\",\n urlPlaceholder: \"https://...\",\n style: \"Estil\",\n styleSolid: \"Sòlid\",\n styleOutlined: \"Contornejat\",\n styleRounded: \"Arrodonit\",\n styleSquare: \"Quadrat\",\n styleCircle: \"Cercle\",\n size: \"Mida\",\n sizeSmall: \"S\",\n sizeMedium: \"M\",\n sizeLarge: \"L\",\n spacing: \"Espaiat\",\n align: \"Alineació\",\n platforms: {\n facebook: \"Facebook\",\n twitter: \"X (Twitter)\",\n instagram: \"Instagram\",\n linkedin: \"LinkedIn\",\n youtube: \"YouTube\",\n tiktok: \"TikTok\",\n pinterest: \"Pinterest\",\n email: \"Correu electrònic\",\n website: \"Lloc web\",\n whatsapp: \"WhatsApp\",\n telegram: \"Telegram\",\n discord: \"Discord\",\n snapchat: \"Snapchat\",\n reddit: \"Reddit\",\n github: \"GitHub\",\n dribbble: \"Dribbble\",\n behance: \"Behance\",\n },\n },\n\n // Toolbar - Menu\n menu: {\n items: \"Elements del menú\",\n addItem: \"Afegeix un element\",\n removeItem: \"Elimina\",\n text: \"Text\",\n urlPlaceholder: \"https://example.com\",\n openInNewTab: \"Obre en una pestanya nova\",\n bold: \"Negreta\",\n underline: \"Subratllat\",\n color: \"Color\",\n linkColor: \"Color de l'enllaç\",\n fontSize: \"Mida de la font\",\n fontFamily: \"Tipus de lletra\",\n separator: \"Separador\",\n separatorColor: \"Color del separador\",\n spacing: \"Espaiat\",\n textAlign: \"Alineació\",\n addLinks: \"Afegeix enllaços al menú\",\n },\n\n // Toolbar - Table\n table: {\n dimensions: \"Dimensions\",\n rows: \"Files\",\n columns: \"Columnes\",\n hasHeaderRow: \"Fila de capçalera\",\n headerBackgroundColor: \"Fons de la capçalera\",\n noHeaderBg: \"Sense fons\",\n borderColor: \"Color de la vora\",\n borderWidth: \"Gruix de la vora\",\n cellPadding: \"Farciment de la cel·la\",\n fontFamily: \"Tipus de lletra\",\n fontSize: \"Mida de la font\",\n color: \"Color del text\",\n textAlign: \"Alineació\",\n cellPlaceholder: \"Introdueix el text...\",\n empty: \"Afegeix una taula\",\n },\n\n // Toolbar - Spacer\n spacer: {\n height: \"Alçada\",\n },\n\n // Toolbar - Countdown\n countdown: {\n targetDate: \"Data límit\",\n timezone: \"Zona horària\",\n display: \"Visualització\",\n days: \"Dies\",\n hours: \"Hores\",\n minutes: \"Minuts\",\n seconds: \"Segons\",\n separator: \"Separador\",\n fontFamily: \"Tipus de lletra\",\n inheritFont: \"Per defecte\",\n digitFontSize: \"Mida dels dígits\",\n digitColor: \"Color dels dígits\",\n labelColor: \"Color de l'etiqueta\",\n labelFontSize: \"Mida de l'etiqueta\",\n background: \"Fons\",\n labels: \"Etiquetes\",\n expiry: \"Missatge de caducitat\",\n expiredMessagePlaceholder: \"Aquesta oferta ha caducat\",\n expiredImageUrl: \"URL de la imatge caducada\",\n hideOnExpiry: \"Oculta quan hagi caducat\",\n setDate: \"Defineix una data límit al panell de configuració\",\n hidden: \"Ocult (caducat)\",\n },\n\n // Custom Blocks\n customBlocks: {\n definitionNotFound:\n \"Tipus de bloc desconegut: aquest bloc no està registrat\",\n renderError:\n \"No s'ha pogut renderitzar aquest bloc. Comproveu si hi ha errors a la plantilla del bloc.\",\n fields: {\n required: \"Obligatori\",\n addItem: \"Afegeix un element\",\n removeItem: \"Elimina\",\n maxItemsReached: \"S'ha arribat al límit màxim d'elements\",\n minItemsRequired: \"Es requereix un mínim de {count} elements\",\n },\n toolbar: {\n noDefinition:\n \"Enregistreu aquest tipus de bloc a la configuració de l'SDK per editar-ne les propietats\",\n },\n dataSource: {\n fetchButton: \"Carrega el contingut\",\n changeButton: \"Canvia\",\n fetching: \"Carregant...\",\n readOnlyTooltip: \"Aquest valor es carrega des de la vostra font de dades\",\n fetchError: \"No s'ha pogut carregar el contingut\",\n },\n },\n\n // Toolbar - HTML\n html: {\n content: \"Contingut HTML\",\n preview: \"Bloc HTML personalitzat\",\n empty: \"Afegeix contingut HTML al panell\",\n sanitizationHint:\n \"L'HTML s'exporta tal qual i no es depura — assegura't que el contingut sigui segur.\",\n },\n\n // Toolbar - Common block settings\n blockSettings: {\n spacing: \"Espaiat\",\n padding: \"Farciment\",\n background: \"Fons\",\n color: \"Color\",\n display: \"Visualització\",\n showOnDesktop: \"Mostra a l'escriptori\",\n showOnMobile: \"Mostra al mòbil\",\n hiddenOnDevice: \"Ocult a {device}\",\n displayCondition: \"Condició de visualització\",\n selectCondition: \"Selecciona una condició\",\n removeCondition: \"Elimina la condició\",\n noCondition: \"Sempre visible\",\n conditionApplied: \"Condició aplicada\",\n customCondition: \"Condició personalitzada\",\n customConditionLabel: \"Nom de la condició\",\n customConditionBefore: \"Abans (lògica d'obertura)\",\n customConditionAfter: \"Després (lògica de tancament)\",\n applyCondition: \"Aplica\",\n cancelCondition: \"Cancel·la\",\n customBadge: \"Personalitzat\",\n restoreHiddenBlocks: \"Mostra tots els blocs ocults\",\n },\n\n // Template settings\n templateSettings: {\n layout: \"Disposició\",\n widthPreset: \"Amplada predefinida\",\n customWidth: \"Amplada personalitzada\",\n appearance: \"Aparença\",\n backgroundColor: \"Color de fons\",\n textColor: \"Color del text\",\n linkColor: \"Color de l'enllaç\",\n linkUnderline: \"Subratllar enllaços\",\n fontFamily: \"Tipus de lletra\",\n preheaderText: \"Text de la precapçalera\",\n preheaderTextPlaceholder:\n \"Text de vista prèvia que es mostra després de la línia de l'assumpte a la bústia...\",\n preheaderTextHint:\n \"Aquest text apareix després de la línia de l'assumpte a les vistes prèvies dels clients de correu. Admet etiquetes de fusió.\",\n language: \"Idioma\",\n contentLocale: \"Idioma del contingut\",\n contentLocaleHint:\n \"Codi BCP 47 (p. ex. ca, en, de). Estableix l'atribut lang del correu renderitzat perquè els lectors de pantalla pronunciïn el contingut correctament.\",\n tips: \"Consells\",\n tip1: \"600px és l'amplada estàndard per a les plantilles de correu electrònic\",\n tip2: \"Utilitzeu fonts segures per a la web per obtenir la millor compatibilitat\",\n tip3: \"Els fons clars funcionen millor per a la llegibilitat\",\n },\n\n // Spacing control\n spacingControl: {\n lockAll: \"Bloqueja tots els costats\",\n unlock: \"Desbloqueja els costats\",\n top: \"Superior\",\n right: \"Dret\",\n bottom: \"Inferior\",\n left: \"Esquerre\",\n decreaseTop: \"Disminueix superior\",\n increaseTop: \"Augmenta superior\",\n decreaseLeft: \"Disminueix esquerre\",\n increaseLeft: \"Augmenta esquerre\",\n decreaseRight: \"Disminueix dret\",\n increaseRight: \"Augmenta dret\",\n decreaseBottom: \"Disminueix inferior\",\n increaseBottom: \"Augmenta inferior\",\n },\n\n // Color Picker\n colorPicker: {\n pickColor: \"Tria un color\",\n hexValue: \"Valor del color en Hex\",\n notSet: \"No definit\",\n clear: \"Neteja el color\",\n presetColors: \"Colors predefinits\",\n },\n\n // Merge Tag\n mergeTag: {\n clickToEdit: \"Feu clic per editar\",\n remove: \"Elimina l'etiqueta de fusió\",\n insert: \"Insereix l'etiqueta de fusió\",\n insertShort: \"Etiqueta de fusió\",\n editValue: \"Edita el valor de l'etiqueta de fusió\",\n deleteMergeTag: \"Elimina l'etiqueta de fusió\",\n suggestionEmpty: \"No hi ha etiquetes de fusió coincidents\",\n picker: {\n title: \"Insereix l'etiqueta de fusió\",\n searchPlaceholder: \"Cerca etiquetes de fusió\",\n searchAriaLabel: \"Cerca etiquetes de fusió\",\n noResults: \"No hi ha etiquetes de fusió coincidents\",\n empty: \"No hi ha etiquetes de fusió configurades\",\n otherGroup: \"Altres\",\n close: \"Tanca\",\n groupCount: \"{count}\",\n sample: \"Vista prèvia: {sample}\",\n },\n },\n\n // Logic tags (standalone, separate from merge tags)\n logicTag: {\n insert: \"Insereix lògica\",\n insertShort: \"Lògica\",\n picker: {\n title: \"Insereix lògica\",\n searchPlaceholder: \"Cerca etiquetes de lògica\",\n searchAriaLabel: \"Cerca etiquetes de lògica\",\n noResults: \"No hi ha etiquetes de lògica coincidents\",\n empty: \"No hi ha etiquetes de lògica configurades\",\n otherGroup: \"Altres\",\n close: \"Tanca\",\n },\n },\n\n // Canvas\n canvas: {\n noBlocks: \"Encara no hi ha blocs\",\n dragHint: \"Comenceu des de zero arrossegant blocs des de la barra lateral\",\n dropHere: \"Deixeu anar aquí\",\n aiHintChat: \"o deixeu que\",\n aiHintChatSuffix:\n \"generi una plantilla completa per a vosaltres en pocs segons\",\n aiHintDesign:\n \"Teniu un disseny existent? Pugeu una captura de pantalla, una imatge o un PDF i\",\n aiHintDesignSuffix: \"el recrearà a l'instant\",\n },\n\n // Sidebar\n savedBlocks: {\n title: \"Blocs desats\",\n saveAsBlock: \"Desa com a bloc\",\n name: \"Nom\",\n namePlaceholder: \"p. ex. Encapçalament, Peu de pàgina, CTA...\",\n save: \"Desa el bloc\",\n saving: \"S'està desant...\",\n cancel: \"Cancel·la\",\n empty: \"Encara no hi ha blocs desats\",\n emptyHint:\n \"Desa blocs de les teves plantilles per reutilitzar-los més tard.\",\n noResults: \"Cap bloc desat coincideix amb la teva cerca\",\n search: \"Cerca blocs desats...\",\n loading: \"S'estan carregant els blocs desats…\",\n category: \"Categoria\",\n categoryPlaceholder: \"p. ex. Capçaleres, Promocions... (opcional)\",\n allCategories: \"Totes les categories\",\n filterByCategory: \"Filtra per categoria\",\n insert: \"Insereix\",\n rename: \"Canvia el nom\",\n delete: \"Elimina\",\n deleteConfirm: \"Vols eliminar aquest bloc desat?\",\n blockCount: \"{count} bloc(s)\",\n browse: \"Explora els blocs desats\",\n selectToPreview: \"Selecciona un bloc desat per previsualitzar-lo\",\n insertAtBeginning: \"Al principi\",\n insertAfterBlock: \"Després de {block}\",\n insertAtEnd: \"Al final\",\n insertPosition: \"Posició d'inserció\",\n close: \"Tanca\",\n pickToolbar: \"Selecció de bloc desat\",\n pickCount: \"{count} bloc(s) seleccionat(s)\",\n pickHint: \"Fes clic als blocs per afegir-los o treure'ls\",\n savingCount: \"S'estan desant {count} bloc(s):\",\n reorderHint: \"Arrossega per reordenar: els blocs es desen en aquest ordre\",\n reorderHandle: \"Reordena {block}, posició {position} de {total}\",\n reorderAnnouncement: \"{block} mogut a la posició {position} de {total}\",\n expand: \"Amplia\",\n collapse: \"Redueix\",\n expandPreview: \"Amplia la vista prèvia de {block}\",\n collapsePreview: \"Redueix la vista prèvia de {block}\",\n },\n comments: {\n button: \"Comentaris\",\n title: \"Comentaris\",\n placeholder: \"Escriu un comentari...\",\n replyPlaceholder: \"Escriu una resposta...\",\n reply: \"Respondre\",\n resolve: \"Resoldre\",\n unresolve: \"Reobrir\",\n delete: \"Eliminar\",\n edit: \"Editar\",\n cancel: \"Cancel·lar\",\n save: \"Desar\",\n noComments: \"Encara no hi ha comentaris\",\n noCommentsHint:\n \"Comença una conversa afegint un comentari a la plantilla o a un bloc concret.\",\n deleteConfirm: \"Vols eliminar aquest comentari?\",\n filterAll: \"Tots\",\n filterUnresolved: \"Sense resoldre\",\n filterBlock: \"Aquest bloc\",\n jumpToBlock: \"Bloc\",\n ownedByYou: \"Tu\",\n edited: \"editat\",\n resolvedBy: \"Resolt per {name}\",\n replyOne: \"{count} resposta\",\n replyMany: \"{count} respostes\",\n missingBlock: \"Bloc no trobat\",\n saveTemplateFirst: \"Desa la plantilla abans de comentar en aquest bloc.\",\n },\n versionHistory: {\n tooltip: \"Historial de versions\",\n dropdownTitle: \"Historial de versions\",\n empty: \"Encara no hi ha versions\",\n auto: \"auto\",\n olderVersion: \"Versió anterior\",\n newerVersion: \"Versió més recent\",\n },\n versionPreview: {\n message: \"Estàs veient una versió anterior d’aquesta plantilla.\",\n cancel: \"Cancel·la\",\n restore: \"Restaura aquesta versió\",\n restoreConfirm: {\n title: \"Vols restaurar aquesta versió?\",\n unsavedWithSave:\n \"Tens canvis sense desar. Desa’ls primer i es mantindran a l’historial; si restaures sense desar, es perdran.\",\n unsavedNoSave:\n \"Tens canvis sense desar i cap lloc on desar-los. Si restaures aquesta versió, es perdran.\",\n saveAndRestore: \"Desa i restaura\",\n restoreAnyway: \"Restaura igualment\",\n cancel: \"Cancel·la\",\n },\n },\n previewResolution: {\n resolving: \"S’està resolent la vista prèvia…\",\n failed:\n \"No s’ha pogut resoldre la vista prèvia; es mostra la plantilla sense resoldre.\",\n hint: \"La vista prèvia utilitza dades resoltes pel teu backend.\",\n },\n mergeTagPreview: {\n label: \"Vista d’etiquetes de combinació\",\n sample: \"Exemple\",\n labelView: \"Etiqueta\",\n },\n testEmail: {\n title: \"Envia un correu de prova\",\n recipientLabel: \"Destinatari\",\n recipientPlaceholder: \"tu@exemple.cat\",\n invalidAddress: \"Introduïu una adreça de correu vàlida.\",\n preview: \"Previsualització\",\n previewHint:\n \"Les etiquetes de combinació es mostren sense resoldre — el vostre backend les omple.\",\n previewHintSample:\n \"Les etiquetes de combinació mostren valors d’exemple; el teu backend insereix les dades reals.\",\n recipientNotAllowed:\n \"Aquesta adreça no és a la llista de destinataris permesos.\",\n send: \"Envia\",\n sending: \"S'està enviant...\",\n cancel: \"Cancel·la\",\n success: \"Correu de prova enviat correctament\",\n button: \"Prova\",\n },\n sidebarNav: {\n browseSavedBlocks: \"Explora els blocs desats\",\n palette: \"Paleta de blocs\",\n insertBlock: \"Insereix un bloc de tipus {block}\",\n },\n\n // Landmark region labels for assistive technology\n landmarks: {\n canvas: \"Llenç del correu\",\n blockToolbar: \"Propietats del bloc\",\n rightSidebar: \"Propietats del bloc i configuració de la plantilla\",\n reorderAnnouncements: \"Avisos de reordenació de blocs\",\n },\n\n // Design Reference (cloud)\n errors: {\n editorLoading: \"Carregant l'editor...\",\n editorLoadFailed: \"No s'ha pogut carregar l'editor.\",\n retry: \"Torna-ho a provar\",\n },\n\n issues: {\n panelTitle: \"Problemes\",\n panelTabLabel: \"Problemes\",\n groupErrors: \"Errors\",\n groupWarnings: \"Avisos\",\n groupInfo: \"Informació\",\n jump: \"Vés al bloc\",\n fix: \"Corregeix\",\n emptyState: \"Sense problemes, tot correcte.\",\n badgeError: \"Té errors\",\n badgeWarning: \"Té avisos\",\n issueCountTooltip: \"{count} problema/es\",\n },\n\n smallScreen: {\n title: \"Cal una pantalla més gran\",\n message:\n \"L'editor necessita més espai del que ofereix aquesta pantalla. Obriu-lo en una tauleta o ordinador d'escriptori per començar a editar.\",\n },\n};\n\nexport default ca;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { r as e } from "./rolldown-runtime-B0aSnxlc.js";
2
- import { B as t, Q as n, Y as r, f as i } from "./draggable-BfpsXFg7.js";
2
+ import { B as t, Q as n, Y as r, f as i } from "./draggable-BLMjz0GK.js";
3
3
  import { t as a } from "./src-B_QJduQD.js";
4
4
  //#region ../core/src/cloud/auth.ts
5
5
  function o(e) {
@@ -1508,4 +1508,4 @@ function Q(e) {
1508
1508
  //#endregion
1509
1509
  export { l as C, o as E, g as S, c as T, T as _, W as a, v as b, z as c, I as d, F as f, E as g, k as h, G as i, B as l, N as m, Z as n, U as o, P as p, K as r, V as s, Q as t, R as u, w as v, s as w, _ as x, C as y };
1510
1510
 
1511
- //# sourceMappingURL=cloud-BA0OpRh-.js.map
1511
+ //# sourceMappingURL=cloud-CRCcXTc5.js.map