domma-cms 0.6.22 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/admin/js/api.js CHANGED
@@ -1 +1 @@
1
- const r="/api";function a(){return S.get("auth_token")}function h(){return S.get("auth_refresh_token")}function m(e){S.set("auth_token",e)}function c(){S.remove("auth_token"),S.remove("auth_refresh_token"),S.remove("auth_user")}async function l(){const e=h();if(!e)throw new Error("No refresh token");const o=await fetch(`${r}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(!o.ok)throw c(),R.navigate("/login"),new Error("Token refresh failed");const{token:s}=await o.json();return m(s),s}async function t(e,o={}){let s=a();const d=i=>({...o.body!==void 0?{"Content-Type":"application/json"}:{},...o.headers,...i?{Authorization:`Bearer ${i}`}:{}});let n=await fetch(`${r}${e}`,{...o,headers:d(s)});if(n.status===401&&h())try{s=await l(),n=await fetch(`${r}${e}`,{...o,headers:d(s)})}catch{return}if(!n.ok){const i=await n.json().catch(()=>({error:"Request failed"}));throw new Error(i.error||i.message||`HTTP ${n.status}`)}return n.status===204?null:n.json()}async function u(e,o){const s=a(),d=s?{Authorization:`Bearer ${s}`}:{},n=await fetch(`${r}${e}`,{method:"POST",headers:d,body:o});if(!n.ok){const i=await n.json().catch(()=>({error:"Upload failed"}));throw new Error(i.error||i.message||`HTTP ${n.status}`)}return n.json()}export const api={auth:{setupStatus:()=>t("/auth/setup-status",{method:"GET"}),setup:e=>t("/auth/setup",{method:"POST",body:JSON.stringify(e)}),login:e=>t("/auth/login",{method:"POST",body:JSON.stringify(e)}),me:()=>t("/auth/me",{method:"GET"}),updateMe:e=>t("/auth/me",{method:"PUT",body:JSON.stringify(e)}),refresh:e=>t("/auth/refresh",{method:"POST",body:JSON.stringify({refreshToken:e})}),forgotPassword:e=>t("/auth/forgot-password",{method:"POST",body:JSON.stringify({email:e})}),resetPassword:(e,o)=>t("/auth/reset-password",{method:"POST",body:JSON.stringify({token:e,password:o})})},pages:{list:()=>t("/pages",{method:"GET"}),get:e=>t(`/pages${e}`,{method:"GET"}),create:e=>t("/pages",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/pages${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/pages${e}`,{method:"DELETE"}),preview:e=>t("/pages/preview",{method:"POST",body:JSON.stringify({markdown:e})}),tags:()=>t("/pages/tags",{method:"GET"}).then(e=>e.tags||[])},settings:{get:()=>t("/settings",{method:"GET"}),save:e=>t("/settings",{method:"PUT",body:JSON.stringify(e)})},navigation:{get:()=>t("/navigation",{method:"GET"}),save:e=>t("/navigation",{method:"PUT",body:JSON.stringify(e)})},layouts:{get:()=>t("/layouts",{method:"GET"}),save:e=>t("/layouts",{method:"PUT",body:JSON.stringify(e)}),getOptions:()=>t("/layouts/options",{method:"GET"}),saveOptions:e=>t("/layouts/options",{method:"PUT",body:JSON.stringify(e)})},media:{list:()=>t("/media",{method:"GET"}),upload:e=>u("/media",e),delete:e=>t(`/media/${encodeURIComponent(e)}`,{method:"DELETE"}),rename:(e,o)=>t(`/media/${encodeURIComponent(e)}`,{method:"PATCH",body:JSON.stringify({newName:o})}),info:e=>t(`/media/${encodeURIComponent(e)}/info`,{method:"GET"}),transform:(e,o)=>t(`/media/${encodeURIComponent(e)}/transform`,{method:"POST",body:JSON.stringify(o)})},users:{list:()=>t("/users",{method:"GET"}),get:e=>t(`/users/${e}`,{method:"GET"}),create:e=>t("/users",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/users/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/users/${e}`,{method:"DELETE"})},plugins:{list:()=>t("/plugins",{method:"GET"}),update:(e,o)=>t(`/plugins/${e}`,{method:"PUT",body:JSON.stringify(o)}),adminConfig:()=>t("/plugins/admin-config",{method:"GET"})},collections:{list:()=>t("/collections",{method:"GET"}),proStatus:()=>t("/collections/pro-status",{method:"GET"}),get:e=>t(`/collections/${e}`,{method:"GET"}),create:e=>t("/collections",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/collections/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/collections/${e}`,{method:"DELETE"}),listEntries:(e,o={})=>{const s=new URLSearchParams(o).toString();return t(`/collections/${e}/entries${s?"?"+s:""}`,{method:"GET"})},getEntry:(e,o)=>t(`/collections/${e}/entries/${o}`,{method:"GET"}),createEntry:(e,o)=>t(`/collections/${e}/entries`,{method:"POST",body:JSON.stringify({data:o})}),updateEntry:(e,o,s)=>t(`/collections/${e}/entries/${o}`,{method:"PUT",body:JSON.stringify({data:s})}),deleteEntry:(e,o)=>t(`/collections/${e}/entries/${o}`,{method:"DELETE"}),clearEntries:e=>t(`/collections/${e}/entries`,{method:"DELETE"}),import:(e,o)=>t(`/collections/${e}/import`,{method:"POST",body:JSON.stringify({entries:o})}),publicList:(e,o={})=>{const s=new URLSearchParams(o).toString();return t(`/collections/${e}/public${s?"?"+s:""}`,{method:"GET"})},getConnections:()=>t("/collections/connections",{method:"GET"}),saveConnections:e=>t("/collections/connections",{method:"PUT",body:JSON.stringify(e)}),migrateStorage:(e,o)=>t(`/collections/${e}/migrate-storage`,{method:"POST",body:JSON.stringify({storage:o})})},forms:{list:()=>t("/forms",{method:"GET"}),create:e=>t("/forms",{method:"POST",body:JSON.stringify(e)}),get:e=>t(`/forms/${e}`,{method:"GET"}),update:(e,o)=>t(`/forms/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/forms/${e}`,{method:"DELETE"}),listSubmissions:e=>t(`/forms/${e}/submissions`,{method:"GET"}),clearSubmissions:e=>t(`/forms/${e}/submissions`,{method:"DELETE"}),deleteSubmission:(e,o)=>t(`/forms/${e}/submissions/${o}`,{method:"DELETE"}),testEmail:e=>t("/forms/test-email",{method:"POST",body:JSON.stringify({to:e})})},views:{list:()=>t("/views",{method:"GET"}),get:e=>t(`/views/${e}`,{method:"GET"}),create:e=>t("/views",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/views/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/views/${e}`,{method:"DELETE"}),execute:(e,o={})=>{const s=new URLSearchParams(o).toString();return t(`/views/${e}/execute${s?"?"+s:""}`,{method:"GET"})},forCollection:e=>t(`/views/collection/${e}`,{method:"GET"})},actions:{list:()=>t("/actions",{method:"GET"}),get:e=>t(`/actions/${e}`,{method:"GET"}),create:e=>t("/actions",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/actions/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/actions/${e}`,{method:"DELETE"}),execute:(e,o)=>t(`/actions/${e}/execute`,{method:"POST",body:JSON.stringify({entryId:o})}),forCollection:e=>t(`/actions/collection/${e}`,{method:"GET"}),checkAccess:(e,o)=>t(`/actions/${e}/check-access`,{method:"POST",body:JSON.stringify({entryIds:o})})},versions:{list:e=>t(`/versions/list${e}`),get:(e,o)=>t(`/versions/get/${encodeURIComponent(o)}${e}`),create:(e,o)=>t(`/versions/create${e}`,{method:"POST",body:JSON.stringify({label:o})}),restore:(e,o)=>t(`/versions/restore/${encodeURIComponent(o)}${e}`,{method:"POST"}),delete:(e,o)=>t(`/versions/delete/${encodeURIComponent(o)}${e}`,{method:"DELETE"})},blocks:{list:()=>t("/blocks",{method:"GET"}),get:e=>t(`/blocks/${encodeURIComponent(e)}`,{method:"GET"}),put:(e,o)=>t(`/blocks/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/blocks/${encodeURIComponent(e)}`,{method:"DELETE"})},get:e=>t(e,{method:"GET"}),post:(e,o)=>t(e,{method:"POST",body:JSON.stringify(o)}),put:(e,o)=>t(e,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(e,{method:"DELETE"}),themes:{list:()=>t("/plugins/theme-roller/themes",{method:"GET"})},settingsExt:{testEmail:e=>t("/settings/test-email",{method:"POST",body:JSON.stringify({to:e})})}};export function isAuthenticated(){return!!a()}export function getUser(){return S.get("auth_user")}export function setAuthData({token:e,refreshToken:o,user:s}){e&&m(e),o&&S.set("auth_refresh_token",o),s&&S.set("auth_user",s)}export function logout(){const e=h();e&&fetch(`${r}/auth/logout`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})}).catch(()=>{}),c(),R.navigate("/login")}export{t as apiRequest};
1
+ const r="/api";function a(){return S.get("auth_token")}function h(){return S.get("auth_refresh_token")}function m(e){S.set("auth_token",e)}function c(){S.remove("auth_token"),S.remove("auth_refresh_token"),S.remove("auth_user")}async function l(){const e=h();if(!e)throw new Error("No refresh token");const o=await fetch(`${r}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(!o.ok)throw c(),R.navigate("/login"),new Error("Token refresh failed");const{token:s}=await o.json();return m(s),s}async function t(e,o={}){let s=a();const d=i=>({...o.body!==void 0?{"Content-Type":"application/json"}:{},...o.headers,...i?{Authorization:`Bearer ${i}`}:{}});let n=await fetch(`${r}${e}`,{...o,headers:d(s)});if(n.status===401&&h())try{s=await l(),n=await fetch(`${r}${e}`,{...o,headers:d(s)})}catch{return}if(!n.ok){const i=await n.json().catch(()=>({error:"Request failed"}));throw new Error(i.error||i.message||`HTTP ${n.status}`)}return n.status===204?null:n.json()}async function u(e,o){const s=a(),d=s?{Authorization:`Bearer ${s}`}:{},n=await fetch(`${r}${e}`,{method:"POST",headers:d,body:o});if(!n.ok){const i=await n.json().catch(()=>({error:"Upload failed"}));throw new Error(i.error||i.message||`HTTP ${n.status}`)}return n.json()}export const api={auth:{setupStatus:()=>t("/auth/setup-status",{method:"GET"}),setup:e=>t("/auth/setup",{method:"POST",body:JSON.stringify(e)}),login:e=>t("/auth/login",{method:"POST",body:JSON.stringify(e)}),me:()=>t("/auth/me",{method:"GET"}),updateMe:e=>t("/auth/me",{method:"PUT",body:JSON.stringify(e)}),refresh:e=>t("/auth/refresh",{method:"POST",body:JSON.stringify({refreshToken:e})}),forgotPassword:e=>t("/auth/forgot-password",{method:"POST",body:JSON.stringify({email:e})}),resetPassword:(e,o)=>t("/auth/reset-password",{method:"POST",body:JSON.stringify({token:e,password:o})})},pages:{list:()=>t("/pages",{method:"GET"}),get:e=>t(`/pages${e}`,{method:"GET"}),create:e=>t("/pages",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/pages${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/pages${e}`,{method:"DELETE"}),preview:e=>t("/pages/preview",{method:"POST",body:JSON.stringify({markdown:e})}),tags:()=>t("/pages/tags",{method:"GET"}).then(e=>e.tags||[])},settings:{get:()=>t("/settings",{method:"GET"}),save:e=>t("/settings",{method:"PUT",body:JSON.stringify(e)}),getCustomCss:()=>t("/settings/custom-css",{method:"GET"}),saveCustomCss:e=>t("/settings/custom-css",{method:"PUT",body:JSON.stringify({css:e})})},navigation:{get:()=>t("/navigation",{method:"GET"}),save:e=>t("/navigation",{method:"PUT",body:JSON.stringify(e)})},layouts:{get:()=>t("/layouts",{method:"GET"}),save:e=>t("/layouts",{method:"PUT",body:JSON.stringify(e)}),getOptions:()=>t("/layouts/options",{method:"GET"}),saveOptions:e=>t("/layouts/options",{method:"PUT",body:JSON.stringify(e)})},media:{list:()=>t("/media",{method:"GET"}),upload:e=>u("/media",e),delete:e=>t(`/media/${encodeURIComponent(e)}`,{method:"DELETE"}),rename:(e,o)=>t(`/media/${encodeURIComponent(e)}`,{method:"PATCH",body:JSON.stringify({newName:o})}),info:e=>t(`/media/${encodeURIComponent(e)}/info`,{method:"GET"}),transform:(e,o)=>t(`/media/${encodeURIComponent(e)}/transform`,{method:"POST",body:JSON.stringify(o)})},users:{list:()=>t("/users",{method:"GET"}),get:e=>t(`/users/${e}`,{method:"GET"}),create:e=>t("/users",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/users/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/users/${e}`,{method:"DELETE"})},plugins:{list:()=>t("/plugins",{method:"GET"}),update:(e,o)=>t(`/plugins/${e}`,{method:"PUT",body:JSON.stringify(o)}),adminConfig:()=>t("/plugins/admin-config",{method:"GET"})},collections:{list:()=>t("/collections",{method:"GET"}),proStatus:()=>t("/collections/pro-status",{method:"GET"}),get:e=>t(`/collections/${e}`,{method:"GET"}),create:e=>t("/collections",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/collections/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/collections/${e}`,{method:"DELETE"}),listEntries:(e,o={})=>{const s=new URLSearchParams(o).toString();return t(`/collections/${e}/entries${s?"?"+s:""}`,{method:"GET"})},getEntry:(e,o)=>t(`/collections/${e}/entries/${o}`,{method:"GET"}),createEntry:(e,o)=>t(`/collections/${e}/entries`,{method:"POST",body:JSON.stringify({data:o})}),updateEntry:(e,o,s)=>t(`/collections/${e}/entries/${o}`,{method:"PUT",body:JSON.stringify({data:s})}),deleteEntry:(e,o)=>t(`/collections/${e}/entries/${o}`,{method:"DELETE"}),clearEntries:e=>t(`/collections/${e}/entries`,{method:"DELETE"}),import:(e,o)=>t(`/collections/${e}/import`,{method:"POST",body:JSON.stringify({entries:o})}),publicList:(e,o={})=>{const s=new URLSearchParams(o).toString();return t(`/collections/${e}/public${s?"?"+s:""}`,{method:"GET"})},getConnections:()=>t("/collections/connections",{method:"GET"}),saveConnections:e=>t("/collections/connections",{method:"PUT",body:JSON.stringify(e)}),migrateStorage:(e,o)=>t(`/collections/${e}/migrate-storage`,{method:"POST",body:JSON.stringify({storage:o})})},forms:{list:()=>t("/forms",{method:"GET"}),create:e=>t("/forms",{method:"POST",body:JSON.stringify(e)}),get:e=>t(`/forms/${e}`,{method:"GET"}),update:(e,o)=>t(`/forms/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/forms/${e}`,{method:"DELETE"}),listSubmissions:e=>t(`/forms/${e}/submissions`,{method:"GET"}),clearSubmissions:e=>t(`/forms/${e}/submissions`,{method:"DELETE"}),deleteSubmission:(e,o)=>t(`/forms/${e}/submissions/${o}`,{method:"DELETE"}),testEmail:e=>t("/forms/test-email",{method:"POST",body:JSON.stringify({to:e})})},views:{list:()=>t("/views",{method:"GET"}),get:e=>t(`/views/${e}`,{method:"GET"}),create:e=>t("/views",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/views/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/views/${e}`,{method:"DELETE"}),execute:(e,o={})=>{const s=new URLSearchParams(o).toString();return t(`/views/${e}/execute${s?"?"+s:""}`,{method:"GET"})},forCollection:e=>t(`/views/collection/${e}`,{method:"GET"})},actions:{list:()=>t("/actions",{method:"GET"}),get:e=>t(`/actions/${e}`,{method:"GET"}),create:e=>t("/actions",{method:"POST",body:JSON.stringify(e)}),update:(e,o)=>t(`/actions/${e}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/actions/${e}`,{method:"DELETE"}),execute:(e,o)=>t(`/actions/${e}/execute`,{method:"POST",body:JSON.stringify({entryId:o})}),forCollection:e=>t(`/actions/collection/${e}`,{method:"GET"}),checkAccess:(e,o)=>t(`/actions/${e}/check-access`,{method:"POST",body:JSON.stringify({entryIds:o})})},versions:{list:e=>t(`/versions/list${e}`),get:(e,o)=>t(`/versions/get/${encodeURIComponent(o)}${e}`),create:(e,o)=>t(`/versions/create${e}`,{method:"POST",body:JSON.stringify({label:o})}),restore:(e,o)=>t(`/versions/restore/${encodeURIComponent(o)}${e}`,{method:"POST"}),delete:(e,o)=>t(`/versions/delete/${encodeURIComponent(o)}${e}`,{method:"DELETE"}),bulkDelete:(e,o)=>t(`/versions/bulk-delete${e}`,{method:"POST",body:JSON.stringify({filenames:o})})},blocks:{list:()=>t("/blocks",{method:"GET"}),get:e=>t(`/blocks/${encodeURIComponent(e)}`,{method:"GET"}),put:(e,o)=>t(`/blocks/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(`/blocks/${encodeURIComponent(e)}`,{method:"DELETE"})},get:e=>t(e,{method:"GET"}),post:(e,o)=>t(e,{method:"POST",body:JSON.stringify(o)}),put:(e,o)=>t(e,{method:"PUT",body:JSON.stringify(o)}),delete:e=>t(e,{method:"DELETE"}),themes:{list:()=>t("/plugins/theme-roller/themes",{method:"GET"})},settingsExt:{testEmail:e=>t("/settings/test-email",{method:"POST",body:JSON.stringify({to:e})})}};export function isAuthenticated(){return!!a()}export function getUser(){return S.get("auth_user")}export function setAuthData({token:e,refreshToken:o,user:s}){e&&m(e),o&&S.set("auth_refresh_token",o),s&&S.set("auth_user",s)}export function logout(){const e=h();e&&fetch(`${r}/auth/logout`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})}).catch(()=>{}),c(),R.navigate("/login")}export{t as apiRequest};
@@ -1,6 +1,11 @@
1
- function le(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6H7V5zM7 11H15a3 3 0 0 1 0 6H7V11z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("italic",{viewBox:"0 0 24 24",path:"M11 5h4M9 19h4M13 5l-2 14",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("strikethrough",{viewBox:"0 0 24 24",path:"M16 4H9a3 3 0 0 0 0 6h6a3 3 0 0 1 0 6H6M3 12h18",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("quote",{viewBox:"0 0 24 24",path:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zM15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("eye",{viewBox:"0 0 24 24",path:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("expand",{viewBox:"0 0 24 24",path:"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("columns",{viewBox:"0 0 24 24",path:"M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM12 4v16",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("card",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M3 9h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("help-circle",{viewBox:"0 0 24 24",path:"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 17h.01M12 13a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("spacer-insert",{viewBox:"0 0 24 24",paths:["M3 8h18","M3 16h18","M12 8v8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("icon-pick",{viewBox:"0 0 24 24",paths:["M4 4h6v6H4z","M14 4h6v6h-6z","M4 14h6v6H4z","M14 14h6v6h-6z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("btn-insert",{viewBox:"0 0 24 24",paths:["M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z","M8 12h8M12 9v6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("link-shortcode",{viewBox:"0 0 24 24",paths:["M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71","M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("layout-list",{viewBox:"0 0 24 24",paths:["M3 5h18M3 9h18","M3 14h4v6H3zM9 14h12M9 17h8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("sparkles",{viewBox:"0 0 24 24",paths:["M12 3L13.5 8.5H19L14.5 11.5L16 17L12 14L8 17L9.5 11.5L5 8.5H10.5L12 3Z","M19 3L19.7 5.3H22L20.2 6.6L20.9 9L19 7.7L17.1 9L17.8 6.6L16 5.3H18.3L19 3Z","M5 13L5.5 14.7H7L5.8 15.5L6.3 17.2L5 16.3L3.7 17.2L4.2 15.5L3 14.7H4.5L5 13Z"],stroke:"currentColor",fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("accordion-insert",{viewBox:"0 0 24 24",paths:["M3 4h18","M3 8h18","M8 11l4 4 4-4","M3 16h18","M3 20h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("hero",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5z","M7 8h10M7 11h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("text-style",{viewBox:"0 0 24 24",paths:["M4 7V5h16v2","M9 19h6","M12 5v14","M5 12h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}export function wrapSelection(t,e,b){const l=t.selectionStart,a=t.selectionEnd,o=t.value,r=o.substring(l,a);r?(t.value=o.substring(0,l)+e+r+b+o.substring(a),t.selectionStart=l+e.length,t.selectionEnd=a+e.length):(t.value=o.substring(0,l)+e+b+o.substring(l),t.selectionStart=t.selectionEnd=l+e.length),t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertAtCursor(t,e){const b=t.selectionStart,l=t.value;t.value=l.substring(0,b)+e+l.substring(b),t.selectionStart=t.selectionEnd=b+e.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertLine(t,e){const b=t.selectionStart,l=t.value,a=l.lastIndexOf(`
2
- `,b-1)+1,o=l.indexOf(`
3
- `,a),r=l.substring(a,o===-1?l.length:o);if(r.startsWith(e)){const i=o===-1?"":l.substring(o);t.value=l.substring(0,a)+r.substring(e.length)+i,t.selectionStart=t.selectionEnd=Math.max(a,b-e.length)}else t.value=l.substring(0,a)+e+l.substring(a),t.selectionStart=t.selectionEnd=b+e.length;t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}const re=[{category:"Entrance"},{label:"Reveal (fade)",snippet:t=>`[reveal animation="fade"]
1
+ function re(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6H7V5zM7 11H15a3 3 0 0 1 0 6H7V11z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("italic",{viewBox:"0 0 24 24",path:"M11 5h4M9 19h4M13 5l-2 14",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("strikethrough",{viewBox:"0 0 24 24",path:"M16 4H9a3 3 0 0 0 0 6h6a3 3 0 0 1 0 6H6M3 12h18",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("quote",{viewBox:"0 0 24 24",path:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zM15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("eye",{viewBox:"0 0 24 24",path:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("expand",{viewBox:"0 0 24 24",path:"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("columns",{viewBox:"0 0 24 24",path:"M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM12 4v16",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("card",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M3 9h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("help-circle",{viewBox:"0 0 24 24",path:"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 17h.01M12 13a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("spacer-insert",{viewBox:"0 0 24 24",paths:["M3 8h18","M3 16h18","M12 8v8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("icon-pick",{viewBox:"0 0 24 24",paths:["M4 4h6v6H4z","M14 4h6v6h-6z","M4 14h6v6H4z","M14 14h6v6h-6z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("colour-picker",{viewBox:"0 0 24 24",paths:["M12 2a5 5 0 0 1 5 5c0 3-5 10-5 10S7 10 7 7a5 5 0 0 1 5-5z","M12 7a1 1 0 1 0 0-2 1 1 0 0 0 0 2"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("btn-insert",{viewBox:"0 0 24 24",paths:["M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z","M8 12h8M12 9v6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("link-shortcode",{viewBox:"0 0 24 24",paths:["M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71","M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("layout-list",{viewBox:"0 0 24 24",paths:["M3 5h18M3 9h18","M3 14h4v6H3zM9 14h12M9 17h8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("sparkles",{viewBox:"0 0 24 24",paths:["M12 3L13.5 8.5H19L14.5 11.5L16 17L12 14L8 17L9.5 11.5L5 8.5H10.5L12 3Z","M19 3L19.7 5.3H22L20.2 6.6L20.9 9L19 7.7L17.1 9L17.8 6.6L16 5.3H18.3L19 3Z","M5 13L5.5 14.7H7L5.8 15.5L6.3 17.2L5 16.3L3.7 17.2L4.2 15.5L3 14.7H4.5L5 13Z"],stroke:"currentColor",fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("accordion-insert",{viewBox:"0 0 24 24",paths:["M3 4h18","M3 8h18","M8 11l4 4 4-4","M3 16h18","M3 20h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("hero",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5z","M7 8h10M7 11h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("text-style",{viewBox:"0 0 24 24",paths:["M4 7V5h16v2","M9 19h6","M12 5v14","M5 12h14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("css-code",{viewBox:"0 0 24 24",paths:["M9 9l-6 3 6 3","M15 9l6 3-6 3","M13 5l-2 14"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}export function wrapSelection(t,e,h){const i=t.selectionStart,c=t.selectionEnd,o=t.value,l=o.substring(i,c);l?(t.value=o.substring(0,i)+e+l+h+o.substring(c),t.selectionStart=i+e.length,t.selectionEnd=c+e.length):(t.value=o.substring(0,i)+e+h+o.substring(i),t.selectionStart=t.selectionEnd=i+e.length),t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertAtCursor(t,e){const h=t.selectionStart,i=t.value;t.value=i.substring(0,h)+e+i.substring(h),t.selectionStart=t.selectionEnd=h+e.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function attachEditorKeybindings(t){t.addEventListener("keydown",e=>{if(e.key==="Tab"){e.preventDefault();const i=t.selectionStart;if(e.shiftKey){const c=t.value.lastIndexOf(`
2
+ `,i-1)+1,o=t.value.substring(c).match(/^ {1,2}/);o&&(t.value=t.value.substring(0,c)+t.value.substring(c+o[0].length),t.selectionStart=t.selectionEnd=Math.max(c,i-o[0].length),t.dispatchEvent(new Event("input",{bubbles:!0})),E.toast("Dedented",{type:"info",duration:800}))}else t.value=t.value.substring(0,i)+" "+t.value.substring(i),t.selectionStart=t.selectionEnd=i+2,t.dispatchEvent(new Event("input",{bubbles:!0})),E.toast("Indented",{type:"info",duration:800});return}if(!(e.ctrlKey||e.metaKey))return;const h=e.key.toLowerCase();if(h==="z")e.preventDefault(),document.execCommand("undo"),E.toast("Undo",{type:"info",duration:1200});else if(h==="y")e.preventDefault(),document.execCommand("redo"),E.toast("Redo",{type:"info",duration:1200});else if(h==="x"&&t.selectionStart===t.selectionEnd){e.preventDefault();const i=t.value.lastIndexOf(`
3
+ `,t.selectionStart-1)+1,c=t.value.indexOf(`
4
+ `,t.selectionStart),o=c===-1?t.value.length:c+1;t.setSelectionRange(i,o),document.execCommand("cut"),t.dispatchEvent(new Event("input",{bubbles:!0})),E.toast("Line cut",{type:"info",duration:1200})}else if(h==="c"&&t.selectionStart===t.selectionEnd){e.preventDefault();const i=t.selectionStart,c=t.value.lastIndexOf(`
5
+ `,i-1)+1,o=t.value.indexOf(`
6
+ `,i),l=o===-1?t.value.length:o+1;t.setSelectionRange(c,l),document.execCommand("copy"),t.setSelectionRange(i,i),E.toast("Line copied",{type:"info",duration:1200})}})}export function insertLine(t,e){const h=t.selectionStart,i=t.value,c=i.lastIndexOf(`
7
+ `,h-1)+1,o=i.indexOf(`
8
+ `,c),l=i.substring(c,o===-1?i.length:o);if(l.startsWith(e)){const r=o===-1?"":i.substring(o);t.value=i.substring(0,c)+l.substring(e.length)+r,t.selectionStart=t.selectionEnd=Math.max(c,h-e.length)}else t.value=i.substring(0,c)+e+i.substring(c),t.selectionStart=t.selectionEnd=h+e.length;t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}const le=[{category:"Entrance"},{label:"Reveal (fade)",snippet:t=>`[reveal animation="fade"]
4
9
  ${t||"Content"}
5
10
  [/reveal]`},{label:"Reveal (slide up)",snippet:t=>`[reveal animation="slide-up"]
6
11
  ${t||"Content"}
@@ -29,12 +34,12 @@ ${t||"Content"}
29
34
  [/firework]`},{label:"Fireworks show",snippet:()=>`[fireworks]
30
35
  [firework type="burst" colour="rainbow" /]
31
36
  [firework type="sparkle" colour="primary" /]
32
- [/fireworks]`,insert:!0},{label:"Celebrate",snippet:()=>'[celebrate theme="auto" intensity="medium" /]',insert:!0}];function se(t,e){const b=document.querySelector(".editor-effects-dropdown-menu");if(b){b.remove();return}const l=document.createElement("div");l.className="editor-effects-dropdown-menu",re.forEach(function(i){if(i.category){const p=document.createElement("div");p.className="editor-effects-category",p.textContent=i.category,l.appendChild(p)}else{const p=document.createElement("button");p.type="button",p.className="editor-effects-item",p.textContent=i.label,p.addEventListener("click",function(){if(l.remove(),i.insert)insertAtCursor(t,i.snippet(""));else{const d=t.selectionStart,f=t.selectionEnd,n=t.value.substring(d,f),s=i.snippet(n);t.value=t.value.substring(0,d)+s+t.value.substring(f),t.selectionStart=d,t.selectionEnd=d+s.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}}),l.appendChild(p)}});const a=e.getBoundingClientRect(),o=e.closest(".editor-toolbar").getBoundingClientRect();l.style.top=a.bottom-o.top+4+"px",l.style.left=a.left-o.left+"px",e.closest(".editor-toolbar").appendChild(l);function r(i){!l.contains(i.target)&&i.target!==e&&(l.remove(),document.removeEventListener("click",r,!0))}setTimeout(function(){document.addEventListener("click",r,!0)},0)}const Z=["activity","airpods","airport","alert-circle","alert-warning","ambulance","angry","annoyed","apartment","arch","archive","arrow-down","arrow-down-left","arrow-down-right","arrow-left","arrow-right","arrow-up","arrow-up-left","arrow-up-right","astonished","at-sign","attachment","award","badge","ban","bandage","bank","banknote","barbell","barcode","barn","baseball","basketball","battery","battery-charging","bauble","bell","bell-off","bells","bicycle","bitcoin","blood-drop","blush","bold","bone","book","book-closed","book-open","bookmark","bookmark-filled","bowling","box","boxing-glove","brain","bridge","briefcase","building","bus","cabin","cake","calculator","calendar","camera","camera-off","candy-cane","capsule","car","cart","cart-add","cash","cast","castle","chart-area","chart-bar","chart-bar-horizontal","chart-candlestick","chart-line","chart-pie","chat","chat-alt","check","check-circle","check-circle-filled","check-square","chevron-down","chevron-left","chevron-right","chevron-up","chevrons-down","chevrons-left","chevrons-right","chevrons-up","church","circle","circle-filled","clear-format","clipboard","clipboard-check","clipboard-list","clock","close","cloud","cloud-download","cloud-drizzle","cloud-lightning","cloud-off","cloud-rain","cloud-sun","cloud-upload","code","code-block","code-inline","cog","coins","columns","comment","compass","component","confused","cool","copy","corner-down-left","corner-down-right","corner-up-left","corner-up-right","court","cpu","credit-card","crown","crutch","cry","currency-dollar","currency-euro","currency-pound","cycling","database","dead","desktop","disappointed","dna","document","document-add","document-check","document-remove","document-text","dollar-sign","dome","dot","dots-horizontal","dots-vertical","download","droplet","droplets","dumbbell","edit","embed","emoji-happy","emoji-sad","euro-sign","exclamation","expand","expressionless","external-link","eye","eye-medical","eye-off","factory","fast-forward","feather","file-code","file-text","file-zip","fill","film","filter","fire","first-aid","fishing","flag","fog","folder","folder-add","folder-minus","folder-open","folder-plus","folder-remove","football","fortress","fuel","gamepad","garage","gauge","gift","git-branch","github","globe","golf","grid","grin","growth","hard-drive","hash","haze","heading-1","heading-2","heading-3","headphones","heart","heart-eyes","heart-filled","heart-pulse","heartbeat","help-circle","holly","home","hospital","hotel","house","image","image-add","images","inbox","indent","info","info-filled","investment","invoice","italic","joy","joystick","key","kettlebell","keyboard","laptop","laugh","layers","layout","library","lighthouse","lightning","link","link-2","link-add","linkedin","list","list-bullet","list-numbered","loader","loading","lock","log-in","log-out","lungs","mail","mail-open","map","map-pin","mask","maximize","medal","medical-cross","menu","menu-alt","message-circle","message-square","mic","mic-off","microscope","minimize","minus","minus-circle","minus-square","monitor","monument","moon","moon-star","more-horizontal","more-vertical","mosque","motorcycle","mountain","mouse","mouse-pointer","move","museum","music","nerd","neutral","notification","obelisk","office","outdent","package","palette","panel-bottom","panel-left","panel-right","panel-top","paperclip","parking","pause","pause-filled","percent","phone","phone-call","phone-incoming","phone-off","phone-outgoing","piggy-bank","pill","pill-bottle","pin","play","play-circle","play-filled","plug","plus","plus-circle","plus-square","podium","pound-sign","printer","pulse","pyramid","qrcode","question","quote","racket","radio","rage","rain","rainbow","receipt","redo","refresh","refresh-cw","reindeer","rewind","road","rotate-ccw","rotate-cw","router","rss","running","sad","safe","save","scale","scale-weight","school","search","send","server","settings","share","share-2","share-alt","shield","shield-alert","shield-check","shield-x","shipping","shocked","shopping-bag","shrink","sick","sidebar-left","sidebar-right","silly","skate","ski","skip-back","skip-forward","skyscraper","sleepy","sleigh","sliders","smartphone","smartwatch","smile","snow","snowflake","snowman","sob","soccer","sort","sparkles","speaker","spinner","square","stadium","star","star-decoration","star-eyes","star-filled","stethoscope","stop","stop-filled","stopwatch","store","strikethrough","sun","sunrise","sunset","surfboard","surprised","swimming","sync","syringe","tablet","tablet-smartphone","tag","tags","target","taxi","temple","tennis","tent","terminal","test-tube","text-center","text-left","text-right","thermometer","thermometer-medical","thermometer-sun","thinking","thumb-down","thumb-up","tongue","tool","tooth","tower","train-station","trash","tree","trending-down","trending-neutral","trending-up","trophy","truck","tv","tv-minimal","twitter","type","umbrella","underline","undo","university","unlink","unlock","upload","usb","user","user-add","user-check","user-group","user-plus","user-remove","users","vaccine","van","vault","video","video-off","volleyball","volume","volume-down","volume-mute","volume-off","volume-up","wallet","warehouse","warning","warning-filled","watch","webcam","wheelchair","whistle","wifi","wifi-off","wind","windmill","wink","wreath","x","x-circle","x-circle-filled","yoga","youtube","zany","zap"];function ce(t,e,b){const l=document.querySelector(".editor-spacer-picker");if(l){l.remove();return}const a=document.createElement("div");a.className="editor-spacer-picker";const o=document.createElement("div");o.className="editor-spacer-picker-label",o.textContent="Spacer height",a.appendChild(o);const r=document.createElement("div");r.className="editor-spacer-picker-row";const i=document.createElement("input");i.type="range",i.className="editor-spacer-slider",i.min="4",i.max="200",i.step="4",i.value=b;const p=document.createElement("span");p.className="editor-spacer-slider-value",p.textContent=b+"px",i.addEventListener("input",function(){p.textContent=this.value+"px"}),r.appendChild(i),r.appendChild(p),a.appendChild(r);const d=document.createElement("button");d.type="button",d.className="btn btn-primary btn-sm editor-spacer-insert-btn",d.textContent="Insert",a.appendChild(d);function f(k){!a.contains(k.target)&&k.target!==e&&(a.remove(),document.removeEventListener("click",f,!0))}d.addEventListener("click",function(){a.remove(),document.removeEventListener("click",f,!0),insertAtCursor(t,`[spacer size="${i.value}" /]
33
- `)});const n=e.getBoundingClientRect(),s=e.closest(".editor-toolbar").getBoundingClientRect();a.style.top=n.bottom-s.top+4+"px";const u=n.left-s.left;a.style.left=Math.min(u,s.width-240-8)+"px",e.closest(".editor-toolbar").appendChild(a),setTimeout(function(){document.addEventListener("click",f,!0)},0)}function ae(t,e){const b=document.querySelector(".editor-icon-picker");if(b){b.remove();return}const l=document.createElement("div");l.className="editor-icon-picker";const a=document.createElement("input");a.type="text",a.className="form-input editor-icon-picker-search",a.placeholder="Search icons\u2026",l.appendChild(a);const o=document.createElement("div");o.className="editor-icon-picker-size-row";const r=document.createElement("label");r.textContent="Size (px)";const i=document.createElement("input");i.type="number",i.className="form-input editor-icon-picker-size",i.placeholder="default",i.min="8",i.max="256",o.appendChild(r),o.appendChild(i),l.appendChild(o);const p=document.createElement("div");p.className="editor-icon-picker-grid",l.appendChild(p);function d(C){!l.contains(C.target)&&C.target!==e&&(l.remove(),document.removeEventListener("click",d,!0))}function f(C){p.textContent="";const v=C?Z.filter(w=>w.includes(C.toLowerCase())):Z;if(v.length===0){const w=document.createElement("div");w.className="editor-icon-picker-empty",w.textContent="No icons found",p.appendChild(w);return}v.forEach(function(w){const y=document.createElement("button");y.type="button",y.className="editor-icon-picker-item";const S=document.createElement("span");S.setAttribute("data-icon",w);const x=document.createElement("span");x.textContent=w,y.appendChild(S),y.appendChild(x),y.addEventListener("click",function(){l.remove(),document.removeEventListener("click",d,!0);const V=i.value.trim(),M=V?`[icon name="${w}" size="${V}" /]`:`[icon name="${w}" /]`;insertAtCursor(t,M)}),p.appendChild(y)}),Domma.icons.scan(p)}f(""),a.addEventListener("input",function(){f(this.value.trim())});const n=e.getBoundingClientRect(),s=e.closest(".editor-toolbar").getBoundingClientRect();l.style.top=n.bottom-s.top+4+"px";const u=n.left-s.left,k=320,g=s.width;l.style.left=Math.min(u,g-k-8)+"px",e.closest(".editor-toolbar").appendChild(l),requestAnimationFrame(function(){a.focus()}),setTimeout(function(){document.addEventListener("click",d,!0)},0)}function de(t,e,b,l){const a=document.querySelector(".editor-toolbar-dropdown");if(a){a.remove();return}const o=document.createElement("div");o.className="editor-toolbar-dropdown",b.forEach(function(f){const n=document.createElement("button");if(n.type="button",n.className="editor-toolbar-dropdown-item",f.icon){const u=document.createElement("span");u.setAttribute("data-icon",f.icon),n.appendChild(u)}const s=document.createElement("span");s.textContent=f.label,n.appendChild(s),n.addEventListener("click",function(){o.remove(),document.removeEventListener("click",d,!0),U(f.action,t,e,l)}),o.appendChild(n)});const r=e.getBoundingClientRect(),i=e.closest(".editor-toolbar").getBoundingClientRect();o.style.top=r.bottom-i.top+4+"px";const p=r.left-i.left;o.style.left=Math.min(p,i.width-180-8)+"px",e.closest(".editor-toolbar").appendChild(o),Domma.icons.scan(o);function d(f){!o.contains(f.target)&&f.target!==e&&(o.remove(),document.removeEventListener("click",d,!0))}setTimeout(function(){document.addEventListener("click",d,!0)},0)}function U(t,e,b,l){const{spacerDefault:a,handlers:o}=l;if(typeof t=="function")t(e);else if(t==="block")if(o.block)o.block(e);else{const r=e.selectionStart,i='[block template="" /]';e.value=e.value.substring(0,r)+i+e.value.substring(r),e.selectionStart=e.selectionEnd=r+17,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="button")if(o.button)o.button(e);else{const r=e.selectionStart,i=e.selectionEnd,d=`[button href="" variant="primary"]${e.value.substring(r,i)||"Click me"}[/button]`;e.value=e.value.substring(0,r)+d+e.value.substring(i),e.selectionStart=e.selectionEnd=r+14,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="linksc")if(o.linksc)o.linksc(e);else{const r=e.selectionStart,i=e.selectionEnd,d=`[link href=""]${e.value.substring(r,i)||"Link text"}[/link]`;e.value=e.value.substring(0,r)+d+e.value.substring(i),e.selectionStart=e.selectionEnd=r+12,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="link")o.link&&o.link(e);else if(t==="image")o.image&&o.image(e);else if(t==="card")if(o.card)o.card(e);else{const r=e.selectionStart,i=e.selectionEnd,d=`[card title="Card Title"]
34
- ${e.value.substring(r,i)||"Content here"}
35
- [/card]`;e.value=e.value.substring(0,r)+d+e.value.substring(i),e.selectionStart=r+13,e.selectionEnd=r+23,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="hero"){const r=e.selectionStart,i=e.selectionEnd,d=`[hero title="Hero Title" tagline="A short tagline" size="lg" variant="gradient-blue"]
36
- ${e.value.substring(r,i)||"Optional body content here."}
37
- [/hero]`;e.value=e.value.substring(0,r)+d+e.value.substring(i),e.selectionStart=e.selectionEnd=r+d.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="grid")if(o.grid)o.grid(e);else{const r=e.selectionStart,i=`[grid cols="2" gap="4"]
37
+ [/fireworks]`,insert:!0},{label:"Celebrate",snippet:()=>'[celebrate theme="auto" intensity="medium" /]',insert:!0}];function se(t,e){const h=document.querySelector(".editor-effects-dropdown-menu");if(h){h.remove();return}const i=document.createElement("div");i.className="editor-effects-dropdown-menu",le.forEach(function(r){if(r.category){const d=document.createElement("div");d.className="editor-effects-category",d.textContent=r.category,i.appendChild(d)}else{const d=document.createElement("button");d.type="button",d.className="editor-effects-item",d.textContent=r.label,d.addEventListener("click",function(){if(i.remove(),r.insert)insertAtCursor(t,r.snippet(""));else{const a=t.selectionStart,b=t.selectionEnd,n=t.value.substring(a,b),s=r.snippet(n);t.value=t.value.substring(0,a)+s+t.value.substring(b),t.selectionStart=a,t.selectionEnd=a+s.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}}),i.appendChild(d)}});const c=e.getBoundingClientRect(),o=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=c.bottom-o.top+4+"px",i.style.left=c.left-o.left+"px",e.closest(".editor-toolbar").appendChild(i);function l(r){!i.contains(r.target)&&r.target!==e&&(i.remove(),document.removeEventListener("click",l,!0))}setTimeout(function(){document.addEventListener("click",l,!0)},0)}const Z=["activity","airpods","airport","alert-circle","alert-warning","ambulance","angry","annoyed","apartment","arch","archive","arrow-down","arrow-down-left","arrow-down-right","arrow-left","arrow-right","arrow-up","arrow-up-left","arrow-up-right","astonished","at-sign","attachment","award","badge","ban","bandage","bank","banknote","barbell","barcode","barn","baseball","basketball","battery","battery-charging","bauble","bell","bell-off","bells","bicycle","bitcoin","blood-drop","blush","bold","bone","book","book-closed","book-open","bookmark","bookmark-filled","bowling","box","boxing-glove","brain","bridge","briefcase","building","bus","cabin","cake","calculator","calendar","camera","camera-off","candy-cane","capsule","car","cart","cart-add","cash","cast","castle","chart-area","chart-bar","chart-bar-horizontal","chart-candlestick","chart-line","chart-pie","chat","chat-alt","check","check-circle","check-circle-filled","check-square","chevron-down","chevron-left","chevron-right","chevron-up","chevrons-down","chevrons-left","chevrons-right","chevrons-up","church","circle","circle-filled","clear-format","clipboard","clipboard-check","clipboard-list","clock","close","cloud","cloud-download","cloud-drizzle","cloud-lightning","cloud-off","cloud-rain","cloud-sun","cloud-upload","code","code-block","code-inline","cog","coins","columns","comment","compass","component","confused","cool","copy","corner-down-left","corner-down-right","corner-up-left","corner-up-right","court","cpu","credit-card","crown","crutch","cry","currency-dollar","currency-euro","currency-pound","cycling","database","dead","desktop","disappointed","dna","document","document-add","document-check","document-remove","document-text","dollar-sign","dome","dot","dots-horizontal","dots-vertical","download","droplet","droplets","dumbbell","edit","embed","emoji-happy","emoji-sad","euro-sign","exclamation","expand","expressionless","external-link","eye","eye-medical","eye-off","factory","fast-forward","feather","file-code","file-text","file-zip","fill","film","filter","fire","first-aid","fishing","flag","fog","folder","folder-add","folder-minus","folder-open","folder-plus","folder-remove","football","fortress","fuel","gamepad","garage","gauge","gift","git-branch","github","globe","golf","grid","grin","growth","hard-drive","hash","haze","heading-1","heading-2","heading-3","headphones","heart","heart-eyes","heart-filled","heart-pulse","heartbeat","help-circle","holly","home","hospital","hotel","house","image","image-add","images","inbox","indent","info","info-filled","investment","invoice","italic","joy","joystick","key","kettlebell","keyboard","laptop","laugh","layers","layout","library","lighthouse","lightning","link","link-2","link-add","linkedin","list","list-bullet","list-numbered","loader","loading","lock","log-in","log-out","lungs","mail","mail-open","map","map-pin","mask","maximize","medal","medical-cross","menu","menu-alt","message-circle","message-square","mic","mic-off","microscope","minimize","minus","minus-circle","minus-square","monitor","monument","moon","moon-star","more-horizontal","more-vertical","mosque","motorcycle","mountain","mouse","mouse-pointer","move","museum","music","nerd","neutral","notification","obelisk","office","outdent","package","palette","panel-bottom","panel-left","panel-right","panel-top","paperclip","parking","pause","pause-filled","percent","phone","phone-call","phone-incoming","phone-off","phone-outgoing","piggy-bank","pill","pill-bottle","pin","play","play-circle","play-filled","plug","plus","plus-circle","plus-square","podium","pound-sign","printer","pulse","pyramid","qrcode","question","quote","racket","radio","rage","rain","rainbow","receipt","redo","refresh","refresh-cw","reindeer","rewind","road","rotate-ccw","rotate-cw","router","rss","running","sad","safe","save","scale","scale-weight","school","search","send","server","settings","share","share-2","share-alt","shield","shield-alert","shield-check","shield-x","shipping","shocked","shopping-bag","shrink","sick","sidebar-left","sidebar-right","silly","skate","ski","skip-back","skip-forward","skyscraper","sleepy","sleigh","sliders","smartphone","smartwatch","smile","snow","snowflake","snowman","sob","soccer","sort","sparkles","speaker","spinner","square","stadium","star","star-decoration","star-eyes","star-filled","stethoscope","stop","stop-filled","stopwatch","store","strikethrough","sun","sunrise","sunset","surfboard","surprised","swimming","sync","syringe","tablet","tablet-smartphone","tag","tags","target","taxi","temple","tennis","tent","terminal","test-tube","text-center","text-left","text-right","thermometer","thermometer-medical","thermometer-sun","thinking","thumb-down","thumb-up","tongue","tool","tooth","tower","train-station","trash","tree","trending-down","trending-neutral","trending-up","trophy","truck","tv","tv-minimal","twitter","type","umbrella","underline","undo","university","unlink","unlock","upload","usb","user","user-add","user-check","user-group","user-plus","user-remove","users","vaccine","van","vault","video","video-off","volleyball","volume","volume-down","volume-mute","volume-off","volume-up","wallet","warehouse","warning","warning-filled","watch","webcam","wheelchair","whistle","wifi","wifi-off","wind","windmill","wink","wreath","x","x-circle","x-circle-filled","yoga","youtube","zany","zap"];function ce(t,e,h){const i=document.querySelector(".editor-spacer-picker");if(i){i.remove();return}const c=document.createElement("div");c.className="editor-spacer-picker";const o=document.createElement("div");o.className="editor-spacer-picker-label",o.textContent="Spacer height",c.appendChild(o);const l=document.createElement("div");l.className="editor-spacer-picker-row";const r=document.createElement("input");r.type="range",r.className="editor-spacer-slider",r.min="4",r.max="200",r.step="4",r.value=h;const d=document.createElement("span");d.className="editor-spacer-slider-value",d.textContent=h+"px",r.addEventListener("input",function(){d.textContent=this.value+"px"}),l.appendChild(r),l.appendChild(d),c.appendChild(l);const a=document.createElement("button");a.type="button",a.className="btn btn-primary btn-sm editor-spacer-insert-btn",a.textContent="Insert",c.appendChild(a);function b(v){!c.contains(v.target)&&v.target!==e&&(c.remove(),document.removeEventListener("click",b,!0))}a.addEventListener("click",function(){c.remove(),document.removeEventListener("click",b,!0),insertAtCursor(t,`[spacer size="${r.value}" /]
38
+ `)});const n=e.getBoundingClientRect(),s=e.closest(".editor-toolbar").getBoundingClientRect();c.style.top=n.bottom-s.top+4+"px";const p=n.left-s.left;c.style.left=Math.min(p,s.width-240-8)+"px",e.closest(".editor-toolbar").appendChild(c),setTimeout(function(){document.addEventListener("click",b,!0)},0)}function ae(t,e){const h=document.querySelector(".editor-icon-picker");if(h){h.remove();return}const i=document.createElement("div");i.className="editor-icon-picker";const c=document.createElement("input");c.type="text",c.className="form-input editor-icon-picker-search",c.placeholder="Search icons\u2026",i.appendChild(c);const o=document.createElement("div");o.className="editor-icon-picker-size-row";const l=document.createElement("label");l.textContent="Size (px)";const r=document.createElement("input");r.type="number",r.className="form-input editor-icon-picker-size",r.placeholder="default",r.min="8",r.max="256",o.appendChild(l),o.appendChild(r),i.appendChild(o);const d=document.createElement("div");d.className="editor-icon-picker-grid",i.appendChild(d);function a(k){!i.contains(k.target)&&k.target!==e&&(i.remove(),document.removeEventListener("click",a,!0))}function b(k){d.textContent="";const g=k?Z.filter(w=>w.includes(k.toLowerCase())):Z;if(g.length===0){const w=document.createElement("div");w.className="editor-icon-picker-empty",w.textContent="No icons found",d.appendChild(w);return}g.forEach(function(w){const C=document.createElement("button");C.type="button",C.className="editor-icon-picker-item";const S=document.createElement("span");S.setAttribute("data-icon",w);const x=document.createElement("span");x.textContent=w,C.appendChild(S),C.appendChild(x),C.addEventListener("click",function(){i.remove(),document.removeEventListener("click",a,!0);const j=r.value.trim(),M=j?`[icon name="${w}" size="${j}" /]`:`[icon name="${w}" /]`;insertAtCursor(t,M)}),d.appendChild(C)}),Domma.icons.scan(d)}b(""),c.addEventListener("input",function(){b(this.value.trim())});const n=e.getBoundingClientRect(),s=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=n.bottom-s.top+4+"px";const p=n.left-s.left,v=320,y=s.width;i.style.left=Math.min(p,y-v-8)+"px",e.closest(".editor-toolbar").appendChild(i),requestAnimationFrame(function(){c.focus()}),setTimeout(function(){document.addEventListener("click",a,!0)},0)}function de(t,e,h,i){const c=document.querySelector(".editor-toolbar-dropdown");if(c){c.remove();return}const o=document.createElement("div");o.className="editor-toolbar-dropdown",h.forEach(function(b){const n=document.createElement("button");if(n.type="button",n.className="editor-toolbar-dropdown-item",b.icon){const p=document.createElement("span");p.setAttribute("data-icon",b.icon),n.appendChild(p)}const s=document.createElement("span");s.textContent=b.label,n.appendChild(s),n.addEventListener("click",function(){o.remove(),document.removeEventListener("click",a,!0),U(b.action,t,e,i)}),o.appendChild(n)});const l=e.getBoundingClientRect(),r=e.closest(".editor-toolbar").getBoundingClientRect();o.style.top=l.bottom-r.top+4+"px";const d=l.left-r.left;o.style.left=Math.min(d,r.width-180-8)+"px",e.closest(".editor-toolbar").appendChild(o),Domma.icons.scan(o);function a(b){!o.contains(b.target)&&b.target!==e&&(o.remove(),document.removeEventListener("click",a,!0))}setTimeout(function(){document.addEventListener("click",a,!0)},0)}function U(t,e,h,i){const{spacerDefault:c,handlers:o}=i;if(typeof t=="function")t(e);else if(t==="block")if(o.block)o.block(e);else{const l=e.selectionStart,r='[block template="" /]';e.value=e.value.substring(0,l)+r+e.value.substring(l),e.selectionStart=e.selectionEnd=l+17,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="button")if(o.button)o.button(e);else{const l=e.selectionStart,r=e.selectionEnd,a=`[button href="" variant="primary"]${e.value.substring(l,r)||"Click me"}[/button]`;e.value=e.value.substring(0,l)+a+e.value.substring(r),e.selectionStart=e.selectionEnd=l+14,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="linksc")if(o.linksc)o.linksc(e);else{const l=e.selectionStart,r=e.selectionEnd,a=`[link href=""]${e.value.substring(l,r)||"Link text"}[/link]`;e.value=e.value.substring(0,l)+a+e.value.substring(r),e.selectionStart=e.selectionEnd=l+12,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="colourpick"){const l=e.selectionStart;document.getElementById("dm-colour-overlay")?.remove();const r=document.createElement("div");r.id="dm-colour-overlay",r.style.cssText="position:fixed;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.5);";const d=document.createElement("div");d.style.cssText="background:var(--dm-surface,#1e1e2e);border:1px solid var(--dm-border,#3a3a5c);border-radius:12px;padding:1.75rem 2rem;display:flex;flex-direction:column;align-items:center;gap:1.25rem;min-width:260px;box-shadow:0 16px 48px rgba(0,0,0,.55);";const a=document.createElement("p");a.textContent="Colour Picker",a.style.cssText="margin:0;font-weight:700;font-size:1rem;letter-spacing:.02em;";const b=document.createElement("input");b.type="color",b.value="#000000",b.style.cssText="width:160px;height:110px;cursor:pointer;border:none;background:none;padding:0;border-radius:6px;overflow:hidden;";const n=document.createElement("div");n.style.cssText="display:flex;align-items:center;gap:.5rem;";const s=document.createElement("input");s.type="text",s.value="#000000",s.className="form-input",s.style.cssText="font-family:monospace;width:100px;text-transform:uppercase;letter-spacing:.05em;";const p=document.createElement("button");p.type="button",p.className="btn btn-ghost btn-sm",p.textContent="Copy";const v=document.createElement("button");v.type="button",v.className="btn btn-primary btn-sm",v.textContent="Insert";const y=()=>r.remove();b.addEventListener("input",()=>{s.value=b.value}),s.addEventListener("input",()=>{/^#[0-9a-f]{6}$/i.test(s.value)&&(b.value=s.value)}),p.addEventListener("click",()=>{const k=document.createElement("input");k.value=s.value,document.body.appendChild(k),k.select(),document.execCommand("copy"),k.remove(),p.textContent="Copied!",setTimeout(()=>{p.textContent="Copy"},1500)}),v.addEventListener("click",()=>{e.selectionStart=e.selectionEnd=l,insertAtCursor(e,s.value),y()}),r.addEventListener("click",k=>{k.target===r&&y()}),n.appendChild(s),n.appendChild(p),n.appendChild(v),d.appendChild(a),d.appendChild(b),d.appendChild(n),r.appendChild(d),document.body.appendChild(r)}else if(t==="link")o.link&&o.link(e);else if(t==="image")o.image&&o.image(e);else if(t==="card")if(o.card)o.card(e);else{const l=e.selectionStart,r=e.selectionEnd,a=`[card title="Card Title"]
39
+ ${e.value.substring(l,r)||"Content here"}
40
+ [/card]`;e.value=e.value.substring(0,l)+a+e.value.substring(r),e.selectionStart=l+13,e.selectionEnd=l+23,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="hero"){const l=e.selectionStart,r=e.selectionEnd,a=`[hero title="Hero Title" tagline="A short tagline" size="lg" variant="gradient-blue"]
41
+ ${e.value.substring(l,r)||"Optional body content here."}
42
+ [/hero]`;e.value=e.value.substring(0,l)+a+e.value.substring(r),e.selectionStart=e.selectionEnd=l+a.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="grid")if(o.grid)o.grid(e);else{const l=e.selectionStart,r=`[grid cols="2" gap="4"]
38
43
  [col]
39
44
  Column 1
40
45
  [/col]
@@ -42,7 +47,7 @@ Column 1
42
47
  Column 2
43
48
  [/col]
44
49
  [/grid]
45
- `;e.value=e.value.substring(0,r)+i+e.value.substring(r),e.selectionStart=e.selectionEnd=r+i.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="badge"){const r=e.selectionStart,i=e.selectionEnd,d=`[badge variant="primary"]${e.value.substring(r,i)||"New"}[/badge]`;e.value=e.value.substring(0,r)+d+e.value.substring(i),e.selectionStart=r+16,e.selectionEnd=r+23,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="timeline"){const r=e.selectionStart,i=`[timeline layout="vertical"]
50
+ `;e.value=e.value.substring(0,l)+r+e.value.substring(l),e.selectionStart=e.selectionEnd=l+r.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="badge"){const l=e.selectionStart,r=e.selectionEnd,a=`[badge variant="primary"]${e.value.substring(l,r)||"New"}[/badge]`;e.value=e.value.substring(0,l)+a+e.value.substring(r),e.selectionStart=l+16,e.selectionEnd=l+23,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="timeline"){const l=e.selectionStart,r=`[timeline layout="vertical"]
46
51
  [event title="First Event" date="${new Date().toISOString().slice(0,10)}" status="completed"]
47
52
  Describe this event.
48
53
  [/event]
@@ -50,11 +55,15 @@ Describe this event.
50
55
  Describe this event.
51
56
  [/event]
52
57
  [/timeline]
53
- `;e.value=e.value.substring(0,r)+i+e.value.substring(r),e.selectionStart=e.selectionEnd=r+i.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="effects")o.effects?o.effects(e):se(e,b);else if(t==="spacerpick")ce(e,b,a);else if(t==="iconpick")ae(e,b);else if(t==="collection")o.collection?o.collection(e):insertAtCursor(e,'[collection slug="" display="table" /]');else if(t==="view")o.view&&o.view(e);else if(t==="cta")o.cta&&o.cta(e);else if(t==="form")o.form?o.form(e):insertAtCursor(e,'[form slug="" /]');else if(t==="tabs")o.tabs&&o.tabs(e);else if(t==="accordion")if(o.accordion)o.accordion(e);else{const r=e.selectionStart,i=`[accordion]
58
+ `;e.value=e.value.substring(0,l)+r+e.value.substring(l),e.selectionStart=e.selectionEnd=l+r.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="effects")o.effects?o.effects(e):se(e,h);else if(t==="spacerpick")ce(e,h,c);else if(t==="iconpick")ae(e,h);else if(t==="listgroup")o.listgroup?o.listgroup(e):insertAtCursor(e,`[listgroup]
59
+ [item]Item 1[/item]
60
+ [item]Item 2[/item]
61
+ [item]Item 3[/item]
62
+ [/listgroup]
63
+ `);else if(t==="collection")o.collection?o.collection(e):insertAtCursor(e,'[collection slug="" display="table" /]');else if(t==="view")o.view&&o.view(e);else if(t==="cta")o.cta&&o.cta(e);else if(t==="form")o.form?o.form(e):insertAtCursor(e,'[form slug="" /]');else if(t==="tabs")o.tabs&&o.tabs(e);else if(t==="accordion")if(o.accordion)o.accordion(e);else{const l=e.selectionStart,r=`[accordion]
54
64
  [item title="Item 1"]Content here.[/item]
55
65
  [item title="Item 2"]Content here.[/item]
56
66
  [/accordion]
57
- `;e.value=e.value.substring(0,r)+i+e.value.substring(r),e.selectionStart=e.selectionEnd=r+i.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="text"){let n=function(m,c){const h=document.createElement("div"),L=document.createElement("label");return L.style.cssText=d,L.textContent=m,h.appendChild(L),h.appendChild(c),h},s=function(m){const c=document.createElement("select");return c.style.cssText=f,[["","\u2014 default \u2014"],...m].forEach(([h,L])=>{const P=document.createElement("option");P.value=h,P.textContent=L,c.appendChild(P)}),c},u=function(m,c){const h=document.createElement("input");return h.type="text",h.placeholder=m||"",h.value=c||"",h.style.cssText=f,h},k=function(m){const c=document.createElement("label");c.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const h=document.createElement("input");h.type="checkbox";const L=document.createElement("span");return L.style.cssText="font-size:.85em;color:var(--dm-text,#eee);",L.textContent=m,c.appendChild(h),c.appendChild(L),{wrap:c,cb:h}},g=function(m,c){const h=document.createElement("div");return h.style.cssText="display:grid;grid-template-columns:1fr 1fr;gap:.5rem;",h.appendChild(m),h.appendChild(c),h},C=function(m){const c=document.createElement("div");return c.style.cssText="border-top:1px solid var(--dm-border,#333);padding-top:.5rem;margin-top:.1rem;font-size:.65rem;font-weight:700;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.08em;",c.textContent=m,c},D=function(){const m=[];y.value&&m.push(`font-size:${Y[y.value]||y.value}`);const c=parseFloat(S.value);!isNaN(c)&&c>0&&m.push(`font-size:${c}pt`),M.checked?m.push("font-weight:700"):x.value&&m.push(`font-weight:${ee[x.value]||x.value}`),_.checked&&m.push("font-style:italic");const h=H.value.trim();h&&m.push(`color:${X[h]||h}`),z.value&&m.push(`font-family:${ne[z.value]}`),N.value&&m.push(`text-transform:${oe[N.value]}`),T.value&&m.push(`text-decoration:${ie[T.value]}`),B.value&&m.push(`letter-spacing:${te[B.value]}`),A.value&&(m.push("display:block"),m.push(`text-align:${A.value}`)),R.value.trim()&&m.push(R.value.trim()),q.style.cssText=m.join(";"),q.textContent=w.value||"Preview text"};const r=e.selectionStart,i=e.selectionEnd,p=e.value.substring(r,i)||"",d="display:block;font-size:.7rem;font-weight:600;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",f="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",v=document.createElement("div");v.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.6rem;overflow-y:auto;max-height:75vh;";const w=u("Text to style\u2026",p);v.appendChild(n("Content",w)),v.appendChild(C("Typography"));const y=s([["xs","xs \u2014 0.75rem"],["sm","sm \u2014 0.875rem"],["base","base \u2014 1rem"],["lg","lg \u2014 1.125rem"],["xl","xl \u2014 1.25rem"],["2xl","2xl \u2014 1.5rem"],["3xl","3xl \u2014 1.875rem"],["4xl","4xl \u2014 2.25rem"]]),S=u("pt value (overrides Size)");v.appendChild(g(n("Size",y),n("Point Size (pt)",S)));const x=s([["thin","Thin (100)"],["light","Light (300)"],["normal","Normal (400)"],["medium","Medium (500)"],["semibold","Semibold (600)"],["bold","Bold (700)"],["extrabold","Extrabold (800)"],["black","Black (900)"]]),{wrap:V,cb:M}=k("Bold (overrides Weight)"),{wrap:Q,cb:_}=k("Italic"),j=document.createElement("div");j.style.cssText="display:flex;flex-direction:column;gap:.4rem;justify-content:flex-end;",j.appendChild(V),j.appendChild(Q),v.appendChild(g(n("Weight",x),j)),v.appendChild(C("Appearance"));const H=u("e.g. primary, #ff0000"),z=s([["Georgia","Georgia (serif)"],["Arial","Arial (sans-serif)"],["Verdana","Verdana (sans-serif)"],["Courier New","Courier New (mono)"],["Times New Roman","Times New Roman (serif)"],["Trebuchet MS","Trebuchet MS"]]);v.appendChild(g(n("Colour",H),n("Font",z))),v.appendChild(C("Formatting"));const N=s([["upper","Uppercase"],["lower","Lowercase"],["capitalize","Capitalise"],["none","None"]]),T=s([["underline","Underline"],["line-through","Line-through"],["none","None"]]);v.appendChild(g(n("Transform",N),n("Decoration",T)));const B=s([["tight","Tight"],["normal","Normal"],["wide","Wide"],["wider","Wider"]]),A=s([["left","Left"],["center","Centre"],["right","Right"],["justify","Justify"]]);v.appendChild(g(n("Spacing",B),n("Align",A))),v.appendChild(C("Advanced"));const R=u("e.g. margin-top:1rem;display:block");v.appendChild(n("Style",R));const O=u("CSS class(es)"),F=u("ID");v.appendChild(g(n("Class",O),n("ID",F)));const G=document.createElement("div");G.style.cssText="padding:.75rem;background:var(--dm-surface-subtle,#111);border-radius:4px;min-height:2.5rem;display:flex;align-items:center;";const q=document.createElement("span");q.textContent=p||"Preview text",G.appendChild(q),v.appendChild(n("Preview",G));const X={primary:"var(--dm-color-primary)",secondary:"var(--dm-color-secondary)",muted:"var(--dm-text-muted)",danger:"var(--dm-color-danger)",success:"var(--dm-color-success)",warning:"var(--dm-color-warning)",info:"var(--dm-color-info)"},Y={xs:".75rem",sm:".875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},ee={thin:"100",light:"300",normal:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},te={tight:"-0.05em",normal:"0em",wide:"0.05em",wider:"0.1em"},ne={Georgia:"Georgia,serif",Arial:"Arial,sans-serif",Verdana:"Verdana,sans-serif","Courier New":"'Courier New',monospace","Times New Roman":"'Times New Roman',serif","Trebuchet MS":"'Trebuchet MS',sans-serif"},oe={upper:"uppercase",lower:"lowercase",capitalize:"capitalize",none:"none"},ie={underline:"underline","line-through":"line-through",none:"none"};M.addEventListener("change",()=>{x.disabled=M.checked,M.checked&&(x.value=""),D()}),[y,x,z,N,T,B,A].forEach(m=>{m.addEventListener("change",D)}),[H,w,R,S].forEach(m=>{m.addEventListener("input",D)}),_.addEventListener("change",D);const W=document.createElement("button");W.type="button",W.className="btn btn-primary",W.textContent="Insert",v.appendChild(W);const K=E.modal({title:"Style Text",size:"md"});K.element.appendChild(v),K.open(),W.addEventListener("click",()=>{const m=w.value;if(!m.trim())return;const c=[];y.value&&c.push(`size="${y.value}"`);const h=parseFloat(S.value);!isNaN(h)&&h>0&&c.push(`point-size="${h}"`),M.checked?c.push("bold"):x.value&&c.push(`weight="${x.value}"`),_.checked&&c.push("italic"),H.value.trim()&&c.push(`color="${H.value.trim()}"`),z.value&&c.push(`font="${z.value}"`),N.value&&c.push(`transform="${N.value}"`),T.value&&c.push(`decoration="${T.value}"`),B.value&&c.push(`spacing="${B.value}"`),A.value&&c.push(`align="${A.value}"`),R.value.trim()&&c.push(`style="${R.value.trim().replace(/"/g,""")}"`),O.value.trim()&&c.push(`class="${O.value.trim()}"`),F.value.trim()&&c.push(`id="${F.value.trim()}"`);const P=`[text${c.length?" "+c.join(" "):""}]${m}[/text]`;K.close(),insertAtCursor(e,P),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}else t==="help"&&o.help&&o.help(e)}const J=[{icon:"bold",title:"Bold (Ctrl+B)",action:t=>wrapSelection(t,"**","**")},{icon:"italic",title:"Italic (Ctrl+I)",action:t=>wrapSelection(t,"_","_")},{icon:"strikethrough",title:"Strikethrough",action:t=>wrapSelection(t,"~~","~~")},"|",{type:"dropdown",icon:"heading-1",title:"Headings",items:[{label:"Heading 1",icon:"heading-1",action:t=>insertLine(t,"# ")},{label:"Heading 2",icon:"heading-2",action:t=>insertLine(t,"## ")},{label:"Heading 3",icon:"heading-3",action:t=>insertLine(t,"### ")}]},"|",{icon:"list-bullet",title:"Bullet list",action:t=>insertLine(t,"- ")},{icon:"list-numbered",title:"Numbered list",action:t=>insertLine(t,"1. ")},"|",{type:"dropdown",icon:"quote",title:"Paragraph",items:[{label:"Blockquote",icon:"quote",action:t=>insertLine(t,"> ")},{label:"Horizontal rule",icon:"minus-circle",action:t=>insertAtCursor(t,`
67
+ `;e.value=e.value.substring(0,l)+r+e.value.substring(l),e.selectionStart=e.selectionEnd=l+r.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="text"){let n=function(m,u){const f=document.createElement("div"),L=document.createElement("label");return L.style.cssText=a,L.textContent=m,f.appendChild(L),f.appendChild(u),f},s=function(m){const u=document.createElement("select");return u.style.cssText=b,[["","\u2014 default \u2014"],...m].forEach(([f,L])=>{const H=document.createElement("option");H.value=f,H.textContent=L,u.appendChild(H)}),u},p=function(m,u){const f=document.createElement("input");return f.type="text",f.placeholder=m||"",f.value=u||"",f.style.cssText=b,f},v=function(m){const u=document.createElement("label");u.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const f=document.createElement("input");f.type="checkbox";const L=document.createElement("span");return L.style.cssText="font-size:.85em;color:var(--dm-text,#eee);",L.textContent=m,u.appendChild(f),u.appendChild(L),{wrap:u,cb:f}},y=function(m,u){const f=document.createElement("div");return f.style.cssText="display:grid;grid-template-columns:1fr 1fr;gap:.5rem;",f.appendChild(m),f.appendChild(u),f},k=function(m){const u=document.createElement("div");return u.style.cssText="border-top:1px solid var(--dm-border,#333);padding-top:.5rem;margin-top:.1rem;font-size:.65rem;font-weight:700;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.08em;",u.textContent=m,u},q=function(){const m=[];C.value&&m.push(`font-size:${Y[C.value]||C.value}`);const u=parseFloat(S.value);!isNaN(u)&&u>0&&m.push(`font-size:${u}pt`),M.checked?m.push("font-weight:700"):x.value&&m.push(`font-weight:${ee[x.value]||x.value}`),O.checked&&m.push("font-style:italic");const f=W.value.trim();f&&m.push(`color:${X[f]||f}`),z.value&&m.push(`font-family:${ne[z.value]}`),T.value&&m.push(`text-transform:${oe[T.value]}`),N.value&&m.push(`text-decoration:${ie[N.value]}`),B.value&&m.push(`letter-spacing:${te[B.value]}`),A.value&&(m.push("display:block"),m.push(`text-align:${A.value}`)),R.value.trim()&&m.push(R.value.trim()),D.style.cssText=m.join(";"),D.textContent=w.value||"Preview text"};const l=e.selectionStart,r=e.selectionEnd,d=e.value.substring(l,r)||"",a="display:block;font-size:.7rem;font-weight:600;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",b="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",g=document.createElement("div");g.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.6rem;overflow-y:auto;max-height:75vh;";const w=p("Text to style\u2026",d);g.appendChild(n("Content",w)),g.appendChild(k("Typography"));const C=s([["xs","xs \u2014 0.75rem"],["sm","sm \u2014 0.875rem"],["base","base \u2014 1rem"],["lg","lg \u2014 1.125rem"],["xl","xl \u2014 1.25rem"],["2xl","2xl \u2014 1.5rem"],["3xl","3xl \u2014 1.875rem"],["4xl","4xl \u2014 2.25rem"]]),S=p("pt value (overrides Size)");g.appendChild(y(n("Size",C),n("Point Size (pt)",S)));const x=s([["thin","Thin (100)"],["light","Light (300)"],["normal","Normal (400)"],["medium","Medium (500)"],["semibold","Semibold (600)"],["bold","Bold (700)"],["extrabold","Extrabold (800)"],["black","Black (900)"]]),{wrap:j,cb:M}=v("Bold (overrides Weight)"),{wrap:Q,cb:O}=v("Italic"),V=document.createElement("div");V.style.cssText="display:flex;flex-direction:column;gap:.4rem;justify-content:flex-end;",V.appendChild(j),V.appendChild(Q),g.appendChild(y(n("Weight",x),V)),g.appendChild(k("Appearance"));const W=p("e.g. primary, #ff0000"),z=s([["Georgia","Georgia (serif)"],["Arial","Arial (sans-serif)"],["Verdana","Verdana (sans-serif)"],["Courier New","Courier New (mono)"],["Times New Roman","Times New Roman (serif)"],["Trebuchet MS","Trebuchet MS"]]);g.appendChild(y(n("Colour",W),n("Font",z))),g.appendChild(k("Formatting"));const T=s([["upper","Uppercase"],["lower","Lowercase"],["capitalize","Capitalise"],["none","None"]]),N=s([["underline","Underline"],["line-through","Line-through"],["none","None"]]);g.appendChild(y(n("Transform",T),n("Decoration",N)));const B=s([["tight","Tight"],["normal","Normal"],["wide","Wide"],["wider","Wider"]]),A=s([["left","Left"],["center","Centre"],["right","Right"],["justify","Justify"]]);g.appendChild(y(n("Spacing",B),n("Align",A))),g.appendChild(k("Advanced"));const R=p("e.g. margin-top:1rem;display:block");g.appendChild(n("Style",R));const _=p("CSS class(es)"),F=p("ID");g.appendChild(y(n("Class",_),n("ID",F)));const G=document.createElement("div");G.style.cssText="padding:.75rem;background:var(--dm-surface-subtle,#111);border-radius:4px;min-height:2.5rem;display:flex;align-items:center;";const D=document.createElement("span");D.textContent=d||"Preview text",G.appendChild(D),g.appendChild(n("Preview",G));const X={primary:"var(--dm-color-primary)",secondary:"var(--dm-color-secondary)",muted:"var(--dm-text-muted)",danger:"var(--dm-color-danger)",success:"var(--dm-color-success)",warning:"var(--dm-color-warning)",info:"var(--dm-color-info)"},Y={xs:".75rem",sm:".875rem",base:"1rem",lg:"1.125rem",xl:"1.25rem","2xl":"1.5rem","3xl":"1.875rem","4xl":"2.25rem"},ee={thin:"100",light:"300",normal:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},te={tight:"-0.05em",normal:"0em",wide:"0.05em",wider:"0.1em"},ne={Georgia:"Georgia,serif",Arial:"Arial,sans-serif",Verdana:"Verdana,sans-serif","Courier New":"'Courier New',monospace","Times New Roman":"'Times New Roman',serif","Trebuchet MS":"'Trebuchet MS',sans-serif"},oe={upper:"uppercase",lower:"lowercase",capitalize:"capitalize",none:"none"},ie={underline:"underline","line-through":"line-through",none:"none"};M.addEventListener("change",()=>{x.disabled=M.checked,M.checked&&(x.value=""),q()}),[C,x,z,T,N,B,A].forEach(m=>{m.addEventListener("change",q)}),[W,w,R,S].forEach(m=>{m.addEventListener("input",q)}),O.addEventListener("change",q);const P=document.createElement("button");P.type="button",P.className="btn btn-primary",P.textContent="Insert",g.appendChild(P);const K=E.modal({title:"Style Text",size:"md"});K.element.appendChild(g),K.open(),P.addEventListener("click",()=>{const m=w.value;if(!m.trim())return;const u=[];C.value&&u.push(`size="${C.value}"`);const f=parseFloat(S.value);!isNaN(f)&&f>0&&u.push(`point-size="${f}"`),M.checked?u.push("bold"):x.value&&u.push(`weight="${x.value}"`),O.checked&&u.push("italic"),W.value.trim()&&u.push(`color="${W.value.trim()}"`),z.value&&u.push(`font="${z.value}"`),T.value&&u.push(`transform="${T.value}"`),N.value&&u.push(`decoration="${N.value}"`),B.value&&u.push(`spacing="${B.value}"`),A.value&&u.push(`align="${A.value}"`),R.value.trim()&&u.push(`style="${R.value.trim().replace(/"/g,""")}"`),_.value.trim()&&u.push(`class="${_.value.trim()}"`),F.value.trim()&&u.push(`id="${F.value.trim()}"`);const H=`[text${u.length?" "+u.join(" "):""}]${m}[/text]`;K.close(),insertAtCursor(e,H),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()})}else t==="help"&&o.help&&o.help(e)}const J=[{icon:"bold",title:"Bold (Ctrl+B)",action:t=>wrapSelection(t,"**","**")},{icon:"italic",title:"Italic (Ctrl+I)",action:t=>wrapSelection(t,"_","_")},{icon:"strikethrough",title:"Strikethrough",action:t=>wrapSelection(t,"~~","~~")},"|",{type:"dropdown",icon:"heading-1",title:"Headings",items:[{label:"Heading 1",icon:"heading-1",action:t=>insertLine(t,"# ")},{label:"Heading 2",icon:"heading-2",action:t=>insertLine(t,"## ")},{label:"Heading 3",icon:"heading-3",action:t=>insertLine(t,"### ")}]},"|",{icon:"list-bullet",title:"Bullet list",action:t=>insertLine(t,"- ")},{icon:"list-numbered",title:"Numbered list",action:t=>insertLine(t,"1. ")},"|",{type:"dropdown",icon:"quote",title:"Paragraph",items:[{label:"Blockquote",icon:"quote",action:t=>insertLine(t,"> ")},{label:"Horizontal rule",icon:"minus-circle",action:t=>insertAtCursor(t,`
58
68
  ---
59
- `)}]},"|",{type:"dropdown",icon:"code-inline",title:"Code",items:[{label:"Inline code",icon:"code-inline",action:t=>wrapSelection(t,"`","`")},{label:"Code block",icon:"code-block",action:t=>wrapSelection(t,"\n```\n","\n```\n")}]},"|",{type:"dropdown",icon:"plus-circle",title:"Insert",items:[{label:"Accordion",icon:"accordion-insert",action:"accordion"},{label:"Badge",icon:"badge",action:"badge"},{label:"Block",icon:"layout",action:"block"},{label:"Button",icon:"btn-insert",action:"button"},{label:"Card",icon:"card",action:"card"},{label:"Collection",icon:"database",action:"collection"},{label:"CTA Button",icon:"mouse-pointer",action:"cta"},{label:"Form",icon:"file-text",action:"form"},{label:"Grid",icon:"columns",action:"grid"},{label:"Hero",icon:"hero",action:"hero"},{label:"Icon",icon:"icon-pick",action:"iconpick"},{label:"Image",icon:"image-add",action:"image"},{label:"Link",icon:"link-shortcode",action:"linksc"},{label:"Spacer",icon:"spacer-insert",action:"spacerpick"},{label:"Tabs",icon:"layout-list",action:"tabs"},{label:"Text",icon:"text-style",action:"text"},{label:"Timeline",icon:"activity",action:"timeline"},{label:"View",icon:"eye",action:"view"}]},"|",{icon:"sparkles",title:"Effects",action:"effects"},{icon:"help-circle",title:"Editor help",action:"help"}];export function createToolbar(t,e,b={}){le();const l={link:null,image:null,card:null,grid:null,help:null,effects:null,collection:null,view:null,cta:null,form:null,button:null,linksc:null,tabs:null,accordion:null},a=b.spacerDefault??40,o=t.get(0),r=e.get(0);r.textContent="",J.forEach((n,s)=>{if(n==="|"){const u=document.createElement("span");u.className="editor-toolbar-sep",r.appendChild(u)}else{const u=document.createElement("button");u.className=n.type==="dropdown"?"editor-toolbar-btn editor-toolbar-dropdown-trigger":"editor-toolbar-btn",u.setAttribute("data-tooltip",n.title),u.setAttribute("data-idx",String(s)),u.type="button";const k=document.createElement("span");if(k.setAttribute("data-icon",n.icon),u.appendChild(k),n.type==="dropdown"){const g=document.createElement("span");g.className="editor-toolbar-caret",g.textContent="\u25BE",u.appendChild(g)}r.appendChild(u)}});const i=document.createElement("div");i.className="editor-toolbar-right",[{mode:"split",icon:"columns",label:"Split view",active:!0},{mode:"write",icon:"file-text",label:"Write only",active:!1},{mode:"preview",icon:"eye",label:"Preview only",active:!1}].forEach(n=>{const s=document.createElement("button");s.className="editor-view-btn"+(n.active?" active":""),s.setAttribute("data-mode",n.mode),s.setAttribute("data-tooltip",n.label),s.type="button";const u=document.createElement("span");u.setAttribute("data-icon",n.icon),s.appendChild(u),i.appendChild(s)});const p=document.createElement("span");p.className="editor-toolbar-sep",i.appendChild(p);const d=document.createElement("button");d.id="fullscreen-btn",d.className="editor-toolbar-btn",d.setAttribute("data-tooltip","Toggle fullscreen"),d.type="button";const f=document.createElement("span");return f.setAttribute("data-icon","expand"),d.appendChild(f),i.appendChild(d),r.appendChild(i),Domma.icons.scan(),r.querySelectorAll("[data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})}),e.on("click",".editor-toolbar-btn[data-idx]",function(){const n=parseInt($(this).data("idx"),10),s=J[n];if(!s||s==="|")return;const u=e.get(0).querySelector(`[data-idx="${n}"]`),k={spacerDefault:a,handlers:l};s.type==="dropdown"?de(o,u,s.items,k):U(s.action,o,u,k)}),t.on("keydown",function(n){const s=n.key.toLowerCase();if(n.ctrlKey||n.metaKey)s==="b"?(n.preventDefault(),wrapSelection(o,"**","**")):s==="i"?(n.preventDefault(),wrapSelection(o,"_","_")):s==="k"&&(n.preventDefault(),l.link&&l.link(o));else if(n.key==="Tab")if(n.preventDefault(),n.shiftKey){const u=o.value.lastIndexOf(`
60
- `,o.selectionStart-1)+1,k=o.value.substring(u),g=k.match(/^ {1,4}/);if(g){const C=o.value.substring(0,u),v=o.value.substring(u+g[0].length);o.value=C+k.substring(g[0].length),o.selectionStart=o.selectionEnd=Math.max(u,o.selectionStart-g[0].length),o.dispatchEvent(new Event("input",{bubbles:!0}))}}else insertAtCursor(o," ")}),{$toolbar:e,onLink(n){l.link=n},onImage(n){l.image=n},onCard(n){l.card=n},onGrid(n){l.grid=n},onHelp(n){l.help=n},onEffects(n){l.effects=n},onCollection(n){l.collection=n},onBlock(n){l.block=n},onView(n){l.view=n},onCta(n){l.cta=n},onForm(n){l.form=n},onButton(n){l.button=n},onLinkShortcode(n){l.linksc=n},onTabs(n){l.tabs=n},onAccordion(n){l.accordion=n}}}
69
+ `)}]},"|",{type:"dropdown",icon:"code-inline",title:"Code",items:[{label:"Inline code",icon:"code-inline",action:t=>wrapSelection(t,"`","`")},{label:"Code block",icon:"code-block",action:t=>wrapSelection(t,"\n```\n","\n```\n")}]},"|",{type:"dropdown",icon:"plus-circle",title:"Insert",items:[{label:"Accordion",icon:"accordion-insert",action:"accordion"},{label:"Badge",icon:"badge",action:"badge"},{label:"Block",icon:"layout",action:"block"},{label:"Button",icon:"btn-insert",action:"button"},{label:"Card",icon:"card",action:"card"},{label:"Colour Picker",icon:"colour-picker",action:"colourpick"},{label:"Collection",icon:"database",action:"collection"},{label:"CTA Button",icon:"mouse-pointer",action:"cta"},{label:"Form",icon:"file-text",action:"form"},{label:"Grid",icon:"columns",action:"grid"},{label:"Hero",icon:"hero",action:"hero"},{label:"Icon",icon:"icon-pick",action:"iconpick"},{label:"Image",icon:"image-add",action:"image"},{label:"Link",icon:"link-shortcode",action:"linksc"},{label:"List Group",icon:"list",action:"listgroup"},{label:"Spacer",icon:"spacer-insert",action:"spacerpick"},{label:"Tabs",icon:"layout-list",action:"tabs"},{label:"Text",icon:"text-style",action:"text"},{label:"Timeline",icon:"activity",action:"timeline"},{label:"View",icon:"eye",action:"view"}]},"|",{icon:"sparkles",title:"Effects",action:"effects"},{icon:"help-circle",title:"Editor help",action:"help"}];export function createToolbar(t,e,h={}){re();const i={link:null,image:null,card:null,grid:null,help:null,effects:null,collection:null,view:null,cta:null,form:null,button:null,linksc:null,tabs:null,accordion:null},c=h.spacerDefault??40,o=t.get(0),l=e.get(0);l.textContent="",J.forEach((n,s)=>{if(n==="|"){const p=document.createElement("span");p.className="editor-toolbar-sep",l.appendChild(p)}else{const p=document.createElement("button");p.className=n.type==="dropdown"?"editor-toolbar-btn editor-toolbar-dropdown-trigger":"editor-toolbar-btn",p.setAttribute("data-tooltip",n.title),p.setAttribute("data-idx",String(s)),p.type="button";const v=document.createElement("span");if(v.setAttribute("data-icon",n.icon),p.appendChild(v),n.type==="dropdown"){const y=document.createElement("span");y.className="editor-toolbar-caret",y.textContent="\u25BE",p.appendChild(y)}l.appendChild(p)}});const r=document.createElement("div");r.className="editor-toolbar-right",[{mode:"split",icon:"columns",label:"Split view",active:!0},{mode:"write",icon:"file-text",label:"Write only",active:!1},{mode:"preview",icon:"eye",label:"Preview only",active:!1}].forEach(n=>{const s=document.createElement("button");s.className="editor-view-btn"+(n.active?" active":""),s.setAttribute("data-mode",n.mode),s.setAttribute("data-tooltip",n.label),s.type="button";const p=document.createElement("span");p.setAttribute("data-icon",n.icon),s.appendChild(p),r.appendChild(s)});const d=document.createElement("span");d.className="editor-toolbar-sep",r.appendChild(d);const a=document.createElement("button");a.id="fullscreen-btn",a.className="editor-toolbar-btn",a.setAttribute("data-tooltip","Toggle fullscreen"),a.type="button";const b=document.createElement("span");return b.setAttribute("data-icon","expand"),a.appendChild(b),r.appendChild(a),l.appendChild(r),Domma.icons.scan(),l.querySelectorAll("[data-tooltip]").forEach(n=>{E.tooltip(n,{content:n.getAttribute("data-tooltip"),position:"top"})}),e.on("click",".editor-toolbar-btn[data-idx]",function(){const n=parseInt($(this).data("idx"),10),s=J[n];if(!s||s==="|")return;const p=e.get(0).querySelector(`[data-idx="${n}"]`),v={spacerDefault:c,handlers:i};s.type==="dropdown"?de(o,p,s.items,v):U(s.action,o,p,v)}),attachEditorKeybindings(o),o.addEventListener("keydown",n=>{const s=n.key.toLowerCase();(n.ctrlKey||n.metaKey)&&(s==="b"?(n.preventDefault(),wrapSelection(o,"**","**")):s==="i"?(n.preventDefault(),wrapSelection(o,"_","_")):s==="k"&&(n.preventDefault(),i.link&&i.link(o)))}),{$toolbar:e,onLink(n){i.link=n},onImage(n){i.image=n},onCard(n){i.card=n},onGrid(n){i.grid=n},onHelp(n){i.help=n},onEffects(n){i.effects=n},onCollection(n){i.collection=n},onBlock(n){i.block=n},onView(n){i.view=n},onCta(n){i.cta=n},onForm(n){i.form=n},onButton(n){i.button=n},onLinkShortcode(n){i.linksc=n},onTabs(n){i.tabs=n},onAccordion(n){i.accordion=n},onListGroup(n){i.listgroup=n}}}
@@ -32,6 +32,8 @@
32
32
  <div class="editor-pane editor-pane--write">
33
33
  <textarea id="markdown-editor" class="editor-textarea"
34
34
  placeholder="Write your page content in Markdown..."></textarea>
35
+ <textarea id="css-editor" class="editor-textarea" style="display:none;font-family:monospace;"
36
+ placeholder="/* Custom CSS… */"></textarea>
35
37
  </div>
36
38
  <div class="editor-divider"></div>
37
39
  <div class="editor-pane editor-pane--preview">
@@ -162,9 +164,15 @@
162
164
  <div class="tab-panel" id="history-panel">
163
165
  <div class="mb-3" style="display:flex;align-items:center;justify-content:space-between;">
164
166
  <h3 style="margin:0;font-size:1rem;">Version History</h3>
165
- <button class="btn btn-ghost btn-sm" id="history-save-named-btn">
166
- <span data-icon="bookmark"></span> Save Named Version
167
- </button>
167
+ <div style="display:flex;gap:.5rem;align-items:center;">
168
+ <button class="btn btn-ghost btn-sm" id="history-delete-selected-btn"
169
+ style="display:none;color:var(--dm-text-danger,#e55);">
170
+ <span data-icon="trash"></span> Delete Selected
171
+ </button>
172
+ <button class="btn btn-ghost btn-sm" id="history-save-named-btn">
173
+ <span data-icon="bookmark"></span> Save Named Version
174
+ </button>
175
+ </div>
168
176
  </div>
169
177
  <div id="version-list"></div>
170
178
  <div id="version-compare" style="display:none;">
@@ -1,14 +1,14 @@
1
- import{api as V}from"../api.js";import{createToolbar as Te,insertAtCursor as fe}from"../lib/markdown-toolbar.js";import{populateThemeSelect as Se}from"../lib/themes.js";function Le(){const s=E.slideover({title:"Editor Reference",size:"md",position:"right"}),ie="background:var(--dm-surface-subtle,#1a1a2e);padding:.2rem .4rem;border-radius:3px;font-size:.85em;font-family:monospace;",ye="margin:1rem 0 .5rem;font-size:1rem;";function P(m){const t=document.createElement("code");return t.style.cssText=ie,t.textContent=m,t}function M(m){const t=document.createElement("h3");return t.style.cssText=ye,t.textContent=m,t}const xe=document.createElement("div");xe.style.cssText="padding:1rem;";const se=document.createElement("div");se.className="tabs";const Ee=document.createElement("div");Ee.className="tab-list",["Basics","Layout","Components","Data","Advanced"].forEach((m,t)=>{const e=document.createElement("button");e.className="tab-item"+(t===0?" active":""),e.textContent=m,Ee.appendChild(e)});const re=document.createElement("div");re.className="tab-content";const H="display:flex;flex-direction:column;gap:1rem;",ce=document.createElement("div");ce.className="tab-panel active",ce.style.cssText=H;const ne=document.createElement("div");ne.className="tab-panel",ne.style.cssText=H;const G=document.createElement("div");G.className="tab-panel",G.style.cssText=H;const pe=document.createElement("div");pe.className="tab-panel",pe.style.cssText=H;const ue=document.createElement("div");ue.className="tab-panel",ue.style.cssText=H,re.appendChild(ce),re.appendChild(ne),re.appendChild(G),re.appendChild(pe),re.appendChild(ue),se.appendChild(Ee),se.appendChild(re),xe.appendChild(se);const he=document.createElement("div");he.appendChild(M("Markdown Basics"));const X=document.createElement("table");X.style.cssText="width:100%;border-collapse:collapse;font-size:.9em;";const W=document.createElement("thead"),Q=document.createElement("tr");["Syntax","Result"].forEach(m=>{const t=document.createElement("th");t.style.cssText="text-align:left;padding:.4rem .5rem;border-bottom:1px solid var(--dm-border,#333);",t.textContent=m,Q.appendChild(t)}),W.appendChild(Q),X.appendChild(W);const Y=document.createElement("tbody");[["**bold**","bold (rendered bold)"],["_italic_","italic (rendered italic)"],["## Heading","Heading (h2)"],["[text](url)","Link"],["![alt](url)","Image"],["- item","Bullet list"],["`code`","Inline code"],["---","Divider"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.35rem .5rem;vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.35rem .5rem;vertical-align:top;color:var(--dm-text-muted,#aaa);font-size:.85em;",u.textContent=t,e.appendChild(l),e.appendChild(u),Y.appendChild(e)}),X.appendChild(Y),he.appendChild(X),ce.appendChild(he);const Z=document.createElement("div");Z.appendChild(M("Grid & Columns"));function A(m){const t=document.createElement("p");return t.style.cssText="margin:.3rem 0 .6rem;font-size:.82em;color:var(--dm-text-muted,#aaa);",t.textContent=m,t}function y(m,t,e){const l=document.createElement("p");l.style.cssText="margin:.75rem 0 .25rem;font-size:.85em;font-weight:600;",l.textContent=m;const u=document.createElement("pre");u.style.cssText=ie+"display:block;padding:.5rem .75rem;white-space:pre;overflow-x:auto;margin:0;",u.textContent=t;const ge=document.createDocumentFragment();return ge.appendChild(l),ge.appendChild(u),e&&ge.appendChild(A(e)),ge}const j=document.createElement("table");j.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['cols="N"',"[grid] only","Number of columns (1\u201312)"],['gap="N"',"[grid], [row]","Gap between columns/rows (1\u20136)"],['span="N"',"[col] only","How many columns this cell spans"],['fullwidth="true"',"[grid] only","Break out of page container to span full viewport"],['class="x"',"all","Add extra CSS classes"]].forEach(([m,t,e])=>{const l=document.createElement("tr");[m,t,e].forEach((u,ge)=>{const ve=document.createElement("td");ve.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",ge===0?ve.appendChild(P(m)):(ve.style.color="var(--dm-text-muted,#aaa)",ve.textContent=u),l.appendChild(ve)}),j.appendChild(l)}),Z.appendChild(j),Z.appendChild(y("Equal columns",`[grid cols="3" gap="4"]
1
+ import{api as U}from"../api.js";import{attachEditorKeybindings as De,createToolbar as Re,insertAtCursor as xe}from"../lib/markdown-toolbar.js?v=9";import{populateThemeSelect as Pe}from"../lib/themes.js";function Fe(){const i=E.slideover({title:"Editor Reference",size:"md",position:"right"}),ue="background:var(--dm-surface-subtle,#1a1a2e);padding:.2rem .4rem;border-radius:3px;font-size:.85em;font-family:monospace;",Se="margin:1rem 0 .5rem;font-size:1rem;";function P(g){const b=document.createElement("code");return b.style.cssText=ue,b.textContent=g,b}function F(g){const b=document.createElement("h3");return b.style.cssText=Se,b.textContent=g,b}const ke=document.createElement("div");ke.style.cssText="padding:1rem;";const ge=document.createElement("div");ge.className="tabs";const Le=document.createElement("div");Le.className="tab-list",["Basics","Layout","Components","Data","Advanced"].forEach((g,b)=>{const t=document.createElement("button");t.className="tab-item"+(b===0?" active":""),t.textContent=g,Le.appendChild(t)});const Ce=document.createElement("div");Ce.className="tab-content";const _="display:flex;flex-direction:column;gap:1rem;",he=document.createElement("div");he.className="tab-panel active",he.style.cssText=_;const ie=document.createElement("div");ie.className="tab-panel",ie.style.cssText=_;const X=document.createElement("div");X.className="tab-panel",X.style.cssText=_;const ae=document.createElement("div");ae.className="tab-panel",ae.style.cssText=_;const be=document.createElement("div");be.className="tab-panel",be.style.cssText=_,Ce.appendChild(he),Ce.appendChild(ie),Ce.appendChild(X),Ce.appendChild(ae),Ce.appendChild(be),ge.appendChild(Le),ge.appendChild(Ce),ke.appendChild(ge);const Te=document.createElement("div");Te.appendChild(F("Markdown Basics"));const ve=document.createElement("table");ve.style.cssText="width:100%;border-collapse:collapse;font-size:.9em;";const W=document.createElement("thead"),G=document.createElement("tr");["Syntax","Result"].forEach(g=>{const b=document.createElement("th");b.style.cssText="text-align:left;padding:.4rem .5rem;border-bottom:1px solid var(--dm-border,#333);",b.textContent=g,G.appendChild(b)}),W.appendChild(G),ve.appendChild(W);const K=document.createElement("tbody");[["**bold**","bold (rendered bold)"],["_italic_","italic (rendered italic)"],["## Heading","Heading (h2)"],["[text](url)","Link"],["![alt](url)","Image"],["- item","Bullet list"],["`code`","Inline code"],["---","Divider"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.35rem .5rem;vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.35rem .5rem;vertical-align:top;color:var(--dm-text-muted,#aaa);font-size:.85em;",n.textContent=b,t.appendChild(e),t.appendChild(n),K.appendChild(t)}),ve.appendChild(K),Te.appendChild(ve),he.appendChild(Te);const Y=document.createElement("div");Y.appendChild(F("Grid & Columns"));function M(g){const b=document.createElement("p");return b.style.cssText="margin:.3rem 0 .6rem;font-size:.82em;color:var(--dm-text-muted,#aaa);",b.textContent=g,b}function z(g,b,t){const e=document.createElement("p");e.style.cssText="margin:.75rem 0 .25rem;font-size:.85em;font-weight:600;",e.textContent=g;const n=document.createElement("div");n.style.cssText="position:relative;";const Q=document.createElement("pre");Q.style.cssText=ue+"display:block;padding:.5rem 2rem .5rem .75rem;white-space:pre;overflow-x:auto;margin:0;",Q.textContent=b;const Z=document.createElement("button");Z.type="button",Z.title="Copy code",Z.style.cssText="position:absolute;top:.3rem;right:.3rem;background:none;border:none;cursor:pointer;opacity:.45;padding:.15rem;line-height:1;color:inherit;",Z.addEventListener("mouseenter",()=>{Z.style.opacity="1"}),Z.addEventListener("mouseleave",()=>{Z.style.opacity=".45"});const ze=document.createElement("span");ze.setAttribute("data-icon","copy"),Z.appendChild(ze),Z.addEventListener("click",()=>{const Ae=document.createElement("textarea");Ae.value=b,Ae.style.cssText="position:fixed;opacity:0;",document.body.appendChild(Ae),Ae.select(),document.execCommand("copy"),Ae.remove(),E.toast("Copied!",{type:"success",duration:1200})}),n.appendChild(Q),n.appendChild(Z);const Ie=document.createDocumentFragment();return Ie.appendChild(e),Ie.appendChild(n),t&&Ie.appendChild(M(t)),Ie}const fe=document.createElement("table");fe.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['cols="N"',"[grid] only","Number of columns (1\u201312)"],['gap="N"',"[grid], [row]","Gap between columns/rows (1\u20136)"],['span="N"',"[col] only","How many columns this cell spans"],['fullwidth="true"',"[grid] only","Break out of page container to span full viewport"],['class="x"',"all","Add extra CSS classes"]].forEach(([g,b,t])=>{const e=document.createElement("tr");[g,b,t].forEach((n,Q)=>{const Z=document.createElement("td");Z.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",Q===0?Z.appendChild(P(g)):(Z.style.color="var(--dm-text-muted,#aaa)",Z.textContent=n),e.appendChild(Z)}),fe.appendChild(e)}),Y.appendChild(fe),Y.appendChild(z("Equal columns",`[grid cols="3" gap="4"]
2
2
  [col]One[/col]
3
3
  [col]Two[/col]
4
4
  [col]Three[/col]
5
- [/grid]`,"cols sets the track count; each [col] fills one track.")),Z.appendChild(y("Column spanning (12-col base)",`[grid cols="12" gap="3"]
5
+ [/grid]`,"cols sets the track count; each [col] fills one track.")),Y.appendChild(z("Column spanning (12-col base)",`[grid cols="12" gap="3"]
6
6
  [col span="8"]Main content[/col]
7
7
  [col span="4"]Sidebar[/col]
8
- [/grid]`,"span values must add up to cols. Common splits: 8/4, 6/6, 9/3.")),Z.appendChild(y("Row (flexbox, equal-width)",`[row gap="4"]
8
+ [/grid]`,"span values must add up to cols. Common splits: 8/4, 6/6, 9/3.")),Y.appendChild(z("Row (flexbox, equal-width)",`[row gap="4"]
9
9
  [col]Left[/col]
10
10
  [col]Right[/col]
11
- [/row]`,"Use [row] when you want equal-width columns without specifying a count.")),Z.appendChild(y("Card in a grid",`[grid cols="3" gap="4"]
11
+ [/row]`,"Use [row] when you want equal-width columns without specifying a count.")),Y.appendChild(z("Card in a grid",`[grid cols="3" gap="4"]
12
12
  [col]
13
13
  [card title="One"]Content[/card]
14
14
  [/col]
@@ -18,21 +18,21 @@ import{api as V}from"../api.js";import{createToolbar as Te,insertAtCursor as fe}
18
18
  [col]
19
19
  [card title="Three"]Content[/card]
20
20
  [/col]
21
- [/grid]`,null)),ne.appendChild(Z);const K=document.createElement("div");K.appendChild(M("Cards")),K.appendChild(y("Basic card",`[card title="Optional Title"]
21
+ [/grid]`,null)),ie.appendChild(Y);const ne=document.createElement("div");ne.appendChild(F("Cards")),ne.appendChild(z("Basic card",`[card title="Optional Title"]
22
22
  Markdown **works** here.
23
- [/card]`,"Omit title for a card with no header.")),K.appendChild(y("Icon \u2014 inline (default)",`[card title="Feature" icon="star"]
23
+ [/card]`,"Omit title for a card with no header.")),ne.appendChild(z("Icon \u2014 inline (default)",`[card title="Feature" icon="star"]
24
24
  Icon sits left of the title in a flex row.
25
- [/card]`,"icon accepts any Domma icon name. Default layout when icon is set.")),K.appendChild(y("Icon \u2014 stacked (centred)",`[card title="Feature" icon="star" icon-layout="stacked" hover]
25
+ [/card]`,"icon accepts any Domma icon name. Default layout when icon is set.")),ne.appendChild(z("Icon \u2014 stacked (centred)",`[card title="Feature" icon="star" icon-layout="stacked" hover]
26
26
  Icon is centred above the title. Great for feature tiles.
27
- [/card]`,'icon-layout="stacked" centres the icon above the title. Combine with hover for a lift effect.')),K.appendChild(y("Icon with subtitle",`[card title="Feature" subtitle="Tagline here" icon="star" icon-layout="stacked"]
27
+ [/card]`,'icon-layout="stacked" centres the icon above the title. Combine with hover for a lift effect.')),ne.appendChild(z("Icon with subtitle",`[card title="Feature" subtitle="Tagline here" icon="star" icon-layout="stacked"]
28
28
  Body content.
29
- [/card]`,"subtitle adds a secondary line beneath the title in both layouts.")),K.appendChild(y("Collapsible card",`[card title="Click to expand" collapsible="true"]
29
+ [/card]`,"subtitle adds a secondary line beneath the title in both layouts.")),ne.appendChild(z("Collapsible card",`[card title="Click to expand" collapsible="true"]
30
30
  Hidden by default.
31
- [/card]`,null)),K.appendChild(y("Full attribute reference",`[card title="Title" subtitle="Sub" icon="star" icon-layout="stacked"
31
+ [/card]`,null)),ne.appendChild(z("Full attribute reference",`[card title="Title" subtitle="Sub" icon="star" icon-layout="stacked"
32
32
  variant="primary" hover footer="Footer text"
33
33
  collapsible="true" class="extra" id="my-card"]
34
34
  Body content.
35
- [/card]`,'All attributes are optional. variant accepts "primary". icon-layout accepts "inline" (default) or "stacked".')),K.appendChild(y("Rich header / footer sub-tags",`[card]
35
+ [/card]`,'All attributes are optional. variant accepts "primary". icon-layout accepts "inline" (default) or "stacked".')),ne.appendChild(z("Rich header / footer sub-tags",`[card]
36
36
  [header]
37
37
  ### Custom Title with **bold** and [a link](/about)
38
38
  [/header]
@@ -42,45 +42,47 @@ Body content here.
42
42
  [footer]
43
43
  [Read more](/about) | [icon name="arrow-right" /]
44
44
  [/footer]
45
- [/card]`,"Use [header] and [footer] sub-tags for Markdown-rendered header/footer regions. Sub-tags override the title/subtitle/icon and footer attributes when both are present.")),G.appendChild(K);const n=document.createElement("div");n.appendChild(M("Badge")),n.appendChild(A("Inline badge/label elements. Self-closing renders an empty coloured dot."));const f=document.createElement("table");f.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['variant="..."',"primary (default), secondary, success, danger, warning, info, light, dark"],["pill","Flag: rounded pill shape (.badge-pill)"],["outline","Flag: outlined style (.badge-outline)"],['size="small|large"',"Reduced or enlarged badge"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),f.appendChild(e)}),n.appendChild(f),n.appendChild(y("Basic badge",'[badge variant="success"]New[/badge]',null)),n.appendChild(y("Pill outline badge",'[badge variant="danger" outline pill]Deprecated[/badge]',null)),G.appendChild(n);const d=document.createElement("div");d.appendChild(M("Button")),d.appendChild(A("Renders a styled anchor as a Domma button. Use the Insert \u2192 Button toolbar item for a guided dialog."));const o=document.createElement("table");o.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['href="..."',"Link destination (required)"],['label="..."',"Button text (self-closing form)"],['variant="..."',"primary (default), secondary, success, danger, warning, info, outline, ghost, link, outline-*"],['size="sm|lg"',"Button size modifier"],['icon="..."',"Domma icon name before the label"],['icon-after="..."',"Domma icon name after the label"],['target="..."','Link target, e.g. "_blank"'],['class="..."',"Extra CSS classes"],['id="..."',"Element id"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),o.appendChild(e)}),d.appendChild(o),d.appendChild(y("Primary button",'[button href="/contact" variant="primary"]Get in touch[/button]',null)),d.appendChild(y("Self-closing with icon",'[button href="/download" variant="success" icon="download" size="sm" label="Download" /]',null)),d.appendChild(y("Opens in new tab",'[button href="https://example.com" variant="outline" target="_blank"]Visit site[/button]',null)),G.appendChild(d);const v=document.createElement("div");v.appendChild(M("Link (shortcode)")),v.appendChild(A("Renders a plain anchor with optional icon, target, and class. Use Insert \u2192 Link for a guided dialog. For simple inline links, standard Markdown [text](url) is fine."));const h=document.createElement("table");h.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['href="..."',"Link destination (required)"],['label="..."',"Link text (self-closing form)"],['target="..."','Link target, e.g. "_blank"'],['class="..."',"CSS classes on the <a>"],['icon="..."',"Domma icon name before the text"],['icon-after="..."',"Domma icon name after the text"],['id="..."',"Element id"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),h.appendChild(e)}),v.appendChild(h),v.appendChild(y("External link in new tab",'[link href="https://example.com" target="_blank" icon-after="external-link"]Visit site[/link]',null)),v.appendChild(y("Self-closing with icon",'[link href="/about" icon="arrow-right" label="About us" /]',null)),G.appendChild(v);const c=document.createElement("div");c.appendChild(M("Spacer")),c.appendChild(A("Self-closing shortcode that inserts a fixed-height blank gap."));const w=document.createElement("table");w.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['size="N"',"Height in px (default: 8)"],['class="..."',"Extra CSS class on the spacer div"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),w.appendChild(e)}),c.appendChild(w),c.appendChild(y("32px gap",'[spacer size="32" /]',null)),ne.appendChild(c);const g=document.createElement("div");g.appendChild(M("Icon")),g.appendChild(A("Self-closing shortcode that renders any Domma icon inline."));const b=document.createElement("table");b.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['name="..."',"Domma icon name (required). Also accepted as src=."],['size="N"',"Width and height in px"],['color="..."',"CSS colour applied via style"],['class="..."',"Extra CSS classes"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),b.appendChild(e)}),g.appendChild(b),g.appendChild(y("Coloured icon",'[icon name="star" size="24" color="#f5a623" /]',null)),G.appendChild(g);const x=document.createElement("div");x.appendChild(M("Center")),x.appendChild(A("Wraps content in a centred div. Works with any content including cards, grids, and text.")),x.appendChild(y("Example","[center]Centred content here[/center]",'Accepts an optional class="..." attribute for extra styling.')),ne.appendChild(x);const S=document.createElement("div");S.appendChild(M("Hero")),S.appendChild(A("Full-width hero sections \u2014 no plugin required. Uses Domma's built-in Hero CSS component."));const z=document.createElement("table");z.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['title="..."',"Heading text"],['tagline="..."',"Subtitle text"],['size="sm|lg|full"',"Height variant (default: normal)"],['variant="dark|primary|gradient-blue|gradient-purple|gradient-sunset|gradient-ocean"',"Colour / gradient preset"],['image="url"',"Background image URL (adds cover mode)"],['overlay="light|dark|darker|gradient|gradient-reverse"',"Image overlay style"],['align="center|left"',"Content alignment (default: center)"],['fullwidth="true"',"Break out of the page container to span full viewport width"],['bg="..."',"Background colour CSS value"],["twinkle","Flag: adds particle overlay (requires Effects plugin)"],['twinkle-count="N"',"Number of particles"],['twinkle-colour="..."',"Particle colour CSS value"],["blobs","Flag: adds ambient blob background"],['blobs-type="..."',"Blob animation type (default: float-blobs)"],['class="..."',"Extra CSS classes"],['id="..."',"Element id"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),z.appendChild(e)}),S.appendChild(z),S.appendChild(y("Basic hero",'[hero title="Welcome" tagline="Build something great"][/hero]',null)),S.appendChild(y("Gradient with body content",`[hero title="Get Started" tagline="Everything you need." size="lg" variant="gradient-blue" align="center"]
45
+ [/card]`,"Use [header] and [footer] sub-tags for Markdown-rendered header/footer regions. Sub-tags override the title/subtitle/icon and footer attributes when both are present.")),X.appendChild(ne);const j=document.createElement("div");j.appendChild(F("Badge")),j.appendChild(M("Inline badge/label elements. Self-closing renders an empty coloured dot."));const q=document.createElement("table");q.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['variant="..."',"primary (default), secondary, success, danger, warning, info, light, dark"],["pill","Flag: rounded pill shape (.badge-pill)"],["outline","Flag: outlined style (.badge-outline)"],['size="small|large"',"Reduced or enlarged badge"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),q.appendChild(t)}),j.appendChild(q),j.appendChild(z("Basic badge",'[badge variant="success"]New[/badge]',null)),j.appendChild(z("Pill outline badge",'[badge variant="danger" outline pill]Deprecated[/badge]',null)),X.appendChild(j);const H=document.createElement("div");H.appendChild(F("Button")),H.appendChild(M("Renders a styled anchor as a Domma button. Use the Insert \u2192 Button toolbar item for a guided dialog."));const oe=document.createElement("table");oe.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['href="..."',"Link destination (required)"],['label="..."',"Button text (self-closing form)"],['variant="..."',"primary (default), secondary, success, danger, warning, info, outline, ghost, link, outline-*"],['size="sm|lg"',"Button size modifier"],['icon="..."',"Domma icon name before the label"],['icon-after="..."',"Domma icon name after the label"],['target="..."','Link target, e.g. "_blank"'],['class="..."',"Extra CSS classes"],['id="..."',"Element id"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),oe.appendChild(t)}),H.appendChild(oe),H.appendChild(z("Primary button",'[button href="/contact" variant="primary"]Get in touch[/button]',null)),H.appendChild(z("Self-closing with icon",'[button href="/download" variant="success" icon="download" size="sm" label="Download" /]',null)),H.appendChild(z("Opens in new tab",'[button href="https://example.com" variant="outline" target="_blank"]Visit site[/button]',null)),X.appendChild(H);const J=document.createElement("div");J.appendChild(F("Link (shortcode)")),J.appendChild(M("Renders a plain anchor with optional icon, target, and class. Use Insert \u2192 Link for a guided dialog. For simple inline links, standard Markdown [text](url) is fine."));const Ee=document.createElement("table");Ee.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['href="..."',"Link destination (required)"],['label="..."',"Link text (self-closing form)"],['target="..."','Link target, e.g. "_blank"'],['class="..."',"CSS classes on the <a>"],['icon="..."',"Domma icon name before the text"],['icon-after="..."',"Domma icon name after the text"],['id="..."',"Element id"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),Ee.appendChild(t)}),J.appendChild(Ee),J.appendChild(z("External link in new tab",'[link href="https://example.com" target="_blank" icon-after="external-link"]Visit site[/link]',null)),J.appendChild(z("Self-closing with icon",'[link href="/about" icon="arrow-right" label="About us" /]',null)),X.appendChild(J);const se=document.createElement("div");se.appendChild(F("Spacer")),se.appendChild(M("Self-closing shortcode that inserts a fixed-height blank gap."));const a=document.createElement("table");a.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['size="N"',"Height in px (default: 8)"],['class="..."',"Extra CSS class on the spacer div"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),a.appendChild(t)}),se.appendChild(a),se.appendChild(z("32px gap",'[spacer size="32" /]',null)),ie.appendChild(se);const l=document.createElement("div");l.appendChild(F("Icon")),l.appendChild(M("Self-closing shortcode that renders any Domma icon inline."));const r=document.createElement("table");r.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['name="..."',"Domma icon name (required). Also accepted as src=."],['size="N"',"Width and height in px"],['color="..."',"CSS colour applied via style"],['class="..."',"Extra CSS classes"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),r.appendChild(t)}),l.appendChild(r),l.appendChild(z("Coloured icon",'[icon name="star" size="24" color="#f5a623" /]',null)),X.appendChild(l);const d=document.createElement("div");d.appendChild(F("Center")),d.appendChild(M("Wraps content in a centred div. Works with any content including cards, grids, and text.")),d.appendChild(z("Example","[center]Centred content here[/center]",'Accepts an optional class="..." attribute for extra styling.')),ie.appendChild(d);const C=document.createElement("div");C.appendChild(F("Hero")),C.appendChild(M("Full-width hero sections \u2014 no plugin required. Uses Domma's built-in Hero CSS component."));const f=document.createElement("table");f.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['title="..."',"Heading text"],['tagline="..."',"Subtitle text"],['size="sm|lg|full"',"Height variant (default: normal)"],['variant="dark|primary|gradient-blue|gradient-purple|gradient-sunset|gradient-ocean"',"Colour / gradient preset"],['image="url"',"Background image URL (adds cover mode)"],['overlay="light|dark|darker|gradient|gradient-reverse"',"Image overlay style"],['align="center|left"',"Content alignment (default: center)"],['fullwidth="true"',"Break out of the page container to span full viewport width"],['bg="..."',"Background colour CSS value"],["twinkle","Flag: adds particle overlay (requires Effects plugin)"],['twinkle-count="N"',"Number of particles"],['twinkle-colour="..."',"Particle colour CSS value"],["blobs","Flag: adds ambient blob background"],['blobs-type="..."',"Blob animation type (default: float-blobs)"],['class="..."',"Extra CSS classes"],['id="..."',"Element id"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),f.appendChild(t)}),C.appendChild(f),C.appendChild(z("Basic hero",'[hero title="Welcome" tagline="Build something great"][/hero]',null)),C.appendChild(z("Gradient with body content",`[hero title="Get Started" tagline="Everything you need." size="lg" variant="gradient-blue" align="center"]
46
46
  Some introductory **Markdown** content here.
47
- [/hero]`,null)),S.appendChild(y("Background image with overlay",'[hero title="Our Story" image="/media/hero.jpg" overlay="dark" size="full"][/hero]',"Combine image + overlay for text legibility over photos.")),ne.appendChild(S);const k=document.createElement("div");k.appendChild(M("Interactive Components")),k.appendChild(A("Tabs, accordion, carousel, and countdown \u2014 no plugin required.")),k.appendChild(y("Tabs",`[tabs]
47
+ [/hero]`,null)),C.appendChild(z("Background image with overlay",'[hero title="Our Story" image="/media/hero.jpg" overlay="dark" size="full"][/hero]',"Combine image + overlay for text legibility over photos.")),ie.appendChild(C);const p=document.createElement("div");p.appendChild(F("Interactive Components")),p.appendChild(M("Tabs, accordion, carousel, and countdown \u2014 no plugin required.")),p.appendChild(z("Tabs",`[tabs]
48
48
  [tab title="First"]Content **A**[/tab]
49
49
  [tab title="Second"]Content **B**[/tab]
50
- [/tabs]`,'Add style="pills" for pill-style navigation.')),k.appendChild(y("Accordion",`[accordion]
50
+ [/tabs]`,'Add style="pills" for pill-style navigation.')),p.appendChild(z("Accordion",`[accordion]
51
51
  [item title="Question 1"]Answer here.[/item]
52
52
  [item title="Question 2"]Answer here.[/item]
53
- [/accordion]`,'Add multiple="true" to allow several panels open at once.')),k.appendChild(y("Accordion \u2014 collection-bound",'[collection slug="faq" display="accordion" title-field="title" body-field="description" /]',"Renders collection entries as accordion items. Use Insert \u2192 Accordion for a guided dialog.")),k.appendChild(y("Carousel",`[carousel autoplay="true" interval="5000"]
53
+ [/accordion]`,'Add multiple="true" to allow several panels open at once.')),p.appendChild(z("Accordion \u2014 collection-bound",'[collection slug="faq" display="accordion" title-field="title" body-field="description" /]',"Renders collection entries as accordion items. Use Insert \u2192 Accordion for a guided dialog.")),p.appendChild(z("Carousel",`[carousel autoplay="true" interval="5000"]
54
54
  [slide title="Slide 1"]Description[/slide]
55
55
  [slide image="/media/photo.jpg" title="Slide 2"]Caption[/slide]
56
- [/carousel]`,'Omit autoplay for a manual carousel. loop="false" disables wrapping.')),k.appendChild(y("Countdown (to date)",'[countdown to="2026-12-31" format="DD:HH:mm:ss" /]',null)),k.appendChild(y("Countdown (duration)",'[countdown duration="300" format="mm:ss" /]',"duration is in seconds. format options: mm:ss \xB7 HH:mm:ss \xB7 DD:HH:mm:ss")),G.appendChild(k);const T=document.createElement("div");T.appendChild(M("Timeline")),T.appendChild(A("Renders a Domma Progression component with event items."));const B=document.createElement("table");B.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['layout="vertical|centred|horizontal"',"[timeline] \u2014 layout orientation (default: vertical)"],['theme="minimal|corporate|modern"',"[timeline] \u2014 visual theme (default: minimal)"],['mode="timeline|roadmap"',"[timeline] \u2014 display mode (default: timeline)"],['class="..."',"[timeline] \u2014 extra CSS classes"],['id="..."',"[timeline] \u2014 element id"],['title="..."',"[event] \u2014 event heading"],['date="..."',"[event] \u2014 display date string"],['status="planned|in-progress|completed|blocked"',"[event] \u2014 progress status"],['icon="..."',"[event] \u2014 Domma icon name"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),B.appendChild(e)}),T.appendChild(B),T.appendChild(y("Vertical timeline",`[timeline layout="vertical" theme="modern"]
56
+ [/carousel]`,'Omit autoplay for a manual carousel. loop="false" disables wrapping.')),p.appendChild(z("Countdown (to date)",'[countdown to="2026-12-31" format="DD:HH:mm:ss" /]',null)),p.appendChild(z("Countdown (duration)",'[countdown duration="300" format="mm:ss" /]',"duration is in seconds. format options: mm:ss \xB7 HH:mm:ss \xB7 DD:HH:mm:ss")),X.appendChild(p);const y=document.createElement("div");y.appendChild(F("Timeline")),y.appendChild(M("Renders a Domma Progression component with event items."));const v=document.createElement("table");v.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['layout="vertical|centred|horizontal"',"[timeline] \u2014 layout orientation (default: vertical)"],['theme="minimal|corporate|modern"',"[timeline] \u2014 visual theme (default: minimal)"],['mode="timeline|roadmap"',"[timeline] \u2014 display mode (default: timeline)"],['class="..."',"[timeline] \u2014 extra CSS classes"],['id="..."',"[timeline] \u2014 element id"],['title="..."',"[event] \u2014 event heading"],['date="..."',"[event] \u2014 display date string"],['status="planned|in-progress|completed|blocked"',"[event] \u2014 progress status"],['icon="..."',"[event] \u2014 Domma icon name"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),v.appendChild(t)}),y.appendChild(v),y.appendChild(z("Vertical timeline",`[timeline layout="vertical" theme="modern"]
57
57
  [event title="Kickoff" date="Jan 2025" status="completed" icon="flag"]
58
58
  Project launched.
59
59
  [/event]
60
60
  [event title="Beta" date="Jun 2025" status="in-progress" icon="rocket"]
61
61
  In active development.
62
62
  [/event]
63
- [/timeline]`,null)),G.appendChild(T);const r=document.createElement("div");r.appendChild(M("Embedding a Form"));const p=document.createElement("table");p.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['name="..."',"Form slug (required). Also accepted as slug=."],['class="..."',"Extra CSS classes on the wrapper div"],['id="..."',"id attribute on the wrapper div"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),p.appendChild(e)}),r.appendChild(p),r.appendChild(y("Basic",'[form name="contact" /]',"Forms are managed under Forms in the sidebar.")),r.appendChild(y("With wrapper styling",'[form name="newsletter" class="mt-4" id="newsletter-form" /]',null)),pe.appendChild(r);const a=document.createElement("div");a.appendChild(M("Displaying a Collection"));const C=document.createElement("pre");C.style.cssText=ie+"display:block;padding:.5rem .75rem;white-space:pre;overflow-x:auto;",C.textContent='[collection slug="enquiries" display="table" /]',a.appendChild(C);const i=[["slug","Required. The collection slug."],["display","table (default), cards, or list."],["fields","Comma-separated field keys to show. Defaults to all."],["limit","Maximum number of entries to display."],["sort","Field key to sort by."],["order","asc or desc (default asc)."],["title-field","Field used as the card/list title (cards + list)."],["columns","Grid columns for cards display (2\u20134, default 3)."],["search","true/false \u2014 enable search in table mode (default true)."],["sortable","true/false \u2014 enable column sorting in table mode (default true)."],["exportable","true/false \u2014 show CSV export button in table mode (default false)."],["page-size","Rows per page in table mode (default 25)."],["empty","Text shown when there are no entries."],["cta","Action slug: enables per-entry CTA buttons."],["cta-label",'CTA button label (default: "Run").'],["cta-icon","CTA button icon name."],["cta-style","CTA button variant (default: primary)."],["cta-confirm","CTA confirmation prompt text."]],L=document.createElement("table");L.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",i.forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;width:35%;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),L.appendChild(e)}),a.appendChild(L),a.appendChild(A("Table display uses Domma Table \u2014 search, sort, pagination, column selector, and CSV export are all built in. Cards and lists are static.")),pe.appendChild(a);const N=document.createElement("div");N.appendChild(M("View \u2014 Pro")),N.appendChild(A("Renders a Collection with full filtering, pagination, and display options. Requires a Pro MongoDB collection."));const F=document.createElement("table");F.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["slug","Required. The collection slug."],["display","table (default), cards, or list."],["limit","Maximum number of entries to display."],["fields","Comma-separated field keys to show."],["title-field","Field used as the card/list title."],["columns","Grid columns for cards display (2\u20134, default 3)."],["empty","Text shown when there are no entries."]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;width:35%;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),F.appendChild(e)}),N.appendChild(F),N.appendChild(y("Table display",'[view slug="products" display="table" limit="50" /]',null)),N.appendChild(y("Cards display",'[view slug="team" display="cards" columns="3" title-field="name" /]',null)),pe.appendChild(N);const O=document.createElement("div");O.appendChild(M("CTA \u2014 Pro")),O.appendChild(A("Renders an action button that triggers a Pro Action against an entry. Requires the Pro Actions feature."));const le=document.createElement("table");le.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["action","Required. The action slug."],["entry","Required. The entry id to act on."],["style","Button variant (default: primary)."],["icon","Domma icon name for the button."],["size","Button size (sm, lg)."],["confirm","Confirmation prompt text before running."],["label","Self-closing only: button label text."]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;width:35%;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),le.appendChild(e)}),O.appendChild(le),O.appendChild(y("Wrapping form",'[cta action="approve" entry="abc123" style="success" confirm="Approve this entry?"]Approve[/cta]',null)),O.appendChild(y("Self-closing",'[cta action="archive" entry="abc123" icon="archive" label="Archive" /]',null)),pe.appendChild(O);const ee=document.createElement("div");ee.appendChild(M("Effects")),ee.appendChild(A("Shortcodes for scroll-triggered animations, counters, typewriter text, and more. Requires the Domma Effects plugin."));const be=[['[reveal animation="fade"]...[/reveal]',"Fade/slide/zoom on scroll"],["[breathe]...[/breathe]","Continuous gentle scale loop"],["[pulse]...[/pulse]","Repeating scale pulse"],["[shake]...[/shake]","One-shot shake"],['[scribe speed="50"]...[/scribe]',"Typewriter \u2014 simple mode (text typed letter by letter)"],['[scribe loop="true"][render]Text[/render][wait]1500[/wait][undo /][/scribe]',"Typewriter \u2014 script mode (sequenced render/wait/undo actions)"],["[scramble]...[/scramble]","Character-scramble reveal"],['[counter to="100" /]',"Animated number counter (self-closing)"],["[ripple]...[/ripple]","Click-triggered ripple"],['[twinkle count="50"]...[/twinkle]',"Particle/star overlay"],['[animate type="fade-in-up"]...[/animate]',"CSS-only animation (no plugin needed)"],['[ambient type="aurora"]...[/ambient]',"CSS-only animated background"],['[firework type="burst" colour="rainbow" /]',"CSS firework (self-closing)"],["[fireworks]...[/fireworks]","Fireworks display container"],['[celebrate theme="auto" /]',"Seasonal canvas celebration"]],oe=document.createElement("table");oe.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",be.forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),oe.appendChild(e)}),ee.appendChild(oe),ee.appendChild(y("Scribe script \u2014 looping multi-phrase typewriter",`[scribe loop="true" loop-delay="2000" delete-speed="20"]
63
+ [/timeline]`,null)),X.appendChild(y);const h=document.createElement("div");h.appendChild(F("Embedding a Form"));const w=document.createElement("table");w.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['name="..."',"Form slug (required). Also accepted as slug=."],['class="..."',"Extra CSS classes on the wrapper div"],['id="..."',"id attribute on the wrapper div"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),w.appendChild(t)}),h.appendChild(w),h.appendChild(z("Basic",'[form name="contact" /]',"Forms are managed under Forms in the sidebar.")),h.appendChild(z("With wrapper styling",'[form name="newsletter" class="mt-4" id="newsletter-form" /]',null)),ae.appendChild(h);const L=document.createElement("div");L.appendChild(F("Displaying a Collection"));const A=document.createElement("pre");A.style.cssText=ue+"display:block;padding:.5rem .75rem;white-space:pre;overflow-x:auto;",A.textContent='[collection slug="enquiries" display="table" /]',L.appendChild(A);const k=[["slug","Required. The collection slug."],["display","table (default), cards, or list."],["fields","Comma-separated field keys to show. Defaults to all."],["limit","Maximum number of entries to display."],["sort","Field key to sort by."],["order","asc or desc (default asc)."],["title-field","Field used as the card/list title (cards + list)."],["columns","Grid columns for cards display (2\u20134, default 3)."],["search","true/false \u2014 enable search in table mode (default true)."],["sortable","true/false \u2014 enable column sorting in table mode (default true)."],["exportable","true/false \u2014 show CSV export button in table mode (default false)."],["page-size","Rows per page in table mode (default 25)."],["empty","Text shown when there are no entries."],["cta","Action slug: enables per-entry CTA buttons."],["cta-label",'CTA button label (default: "Run").'],["cta-icon","CTA button icon name."],["cta-style","CTA button variant (default: primary)."],["cta-confirm","CTA confirmation prompt text."],["class","Extra CSS classes on the wrapper div."],["id","id attribute on the wrapper div."]],S=document.createElement("table");S.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",k.forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;width:35%;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),S.appendChild(t)}),L.appendChild(S),L.appendChild(M("Table display uses Domma Table \u2014 search, sort, pagination, column selector, and CSV export are all built in. Cards and lists are static.")),ae.appendChild(L);const N=document.createElement("div");N.appendChild(F("View \u2014 Pro")),N.appendChild(M("Renders a Collection with full filtering, pagination, and display options. Requires a Pro MongoDB collection."));const u=document.createElement("table");u.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["slug","Required. The collection slug."],["display","table (default), cards, or list."],["limit","Maximum number of entries to display."],["fields","Comma-separated field keys to show."],["title-field","Field used as the card/list title."],["columns","Grid columns for cards display (2\u20134, default 3)."],["empty","Text shown when there are no entries."],["class","Extra CSS classes on the wrapper div."],["id","id attribute on the wrapper div."]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;width:35%;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),u.appendChild(t)}),N.appendChild(u),N.appendChild(z("Table display",'[view slug="products" display="table" limit="50" /]',null)),N.appendChild(z("Cards display",'[view slug="team" display="cards" columns="3" title-field="name" /]',null)),ae.appendChild(N);const m=document.createElement("div");m.appendChild(F("CTA \u2014 Pro")),m.appendChild(M("Renders an action button that triggers a Pro Action against an entry. Requires the Pro Actions feature."));const s=document.createElement("table");s.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["action","Required. The action slug."],["entry","Required. The entry id to act on."],["style","Button variant (default: primary)."],["icon","Domma icon name for the button."],["size","Button size (sm, lg)."],["confirm","Confirmation prompt text before running."],["label","Self-closing only: button label text."]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;width:35%;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),s.appendChild(t)}),m.appendChild(s),m.appendChild(z("Wrapping form",'[cta action="approve" entry="abc123" style="success" confirm="Approve this entry?"]Approve[/cta]',null)),m.appendChild(z("Self-closing",'[cta action="archive" entry="abc123" icon="archive" label="Archive" /]',null)),ae.appendChild(m);const c=document.createElement("div");c.appendChild(F("Effects")),c.appendChild(M("Shortcodes for scroll-triggered animations, counters, typewriter text, and more. Requires the Domma Effects plugin."));const o=[['[reveal animation="fade"]...[/reveal]',"Fade/slide/zoom on scroll"],["[breathe]...[/breathe]","Continuous gentle scale loop"],["[pulse]...[/pulse]","Repeating scale pulse"],["[shake]...[/shake]","One-shot shake"],['[scribe speed="50"]...[/scribe]',"Typewriter \u2014 simple mode (text typed letter by letter)"],['[scribe loop="true"][render]Text[/render][wait]1500[/wait][undo /][/scribe]',"Typewriter \u2014 script mode (sequenced render/wait/undo actions)"],["[scramble]...[/scramble]","Character-scramble reveal"],['[counter to="100" /]',"Animated number counter (self-closing)"],["[ripple]...[/ripple]","Click-triggered ripple"],['[twinkle count="50"]...[/twinkle]',"Particle/star overlay"],['[animate type="fade-in-up"]...[/animate]',"CSS-only animation (no plugin needed)"],['[ambient type="aurora"]...[/ambient]',"CSS-only animated background"],['[firework type="burst" colour="rainbow" /]',"CSS firework (self-closing)"],["[fireworks]...[/fireworks]","Fireworks display container"],['[celebrate theme="auto" /]',"Seasonal canvas celebration"]],x=document.createElement("table");x.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",o.forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),x.appendChild(t)}),c.appendChild(x),c.appendChild(z("Scribe script \u2014 looping multi-phrase typewriter",`[scribe loop="true" loop-delay="2000" delete-speed="20"]
64
64
  [render]We build things that matter.[/render]
65
65
  [wait]1200[/wait]
66
66
  [undo all="true" /]
67
67
  [render]We design for humans.[/render]
68
68
  [wait]1200[/wait]
69
69
  [undo all="true" /]
70
- [/scribe]`,'Use [render]...[/render] to type text, [wait]Ms[/wait] to pause, and [undo /] to delete. loop="true" replays the sequence. Only [render], [wait], and [undo] shortcodes are parsed \u2014 plain text between actions is ignored.')),ee.appendChild(A("Enable the Domma Effects plugin to activate these shortcodes on your site.")),ue.appendChild(ee);const J=document.createElement("div");J.appendChild(M("Tables")),J.appendChild(A("Wrap a standard Markdown (GFM) table with Domma CSS classes and responsive horizontal scrolling."));const me=document.createElement("table");me.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['striped="true"',"Alternate row background (.table-striped)"],['bordered="true"',"Borders on all cells (.table-bordered)"],['compact="true"',"Reduced cell padding (.table-compact)"],['caption="..."',"Caption text above the table"],['class="..."',"Extra CSS classes appended to .table"],['id="..."',"id attribute on the <table> element"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),me.appendChild(e)}),J.appendChild(me),J.appendChild(y("Striped + bordered table",`[table striped="true" bordered="true" caption="Product Pricing"]
70
+ [/scribe]`,'Use [render]...[/render] to type text, [wait]Ms[/wait] to pause, and [undo /] to delete. loop="true" replays the sequence. Only [render], [wait], and [undo] shortcodes are parsed \u2014 plain text between actions is ignored.')),c.appendChild(M("Enable the Domma Effects plugin to activate these shortcodes on your site.")),be.appendChild(c);const T=document.createElement("div");T.appendChild(F("Tables")),T.appendChild(M("Wrap a standard Markdown (GFM) table with Domma CSS classes and responsive horizontal scrolling."));const B=document.createElement("table");B.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['striped="true"',"Alternate row background (.table-striped)"],['bordered="true"',"Borders on all cells (.table-bordered)"],['compact="true"',"Reduced cell padding (.table-compact)"],['caption="..."',"Caption text above the table"],['class="..."',"Extra CSS classes appended to .table"],['id="..."',"id attribute on the <table> element"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),B.appendChild(t)}),T.appendChild(B),T.appendChild(z("Striped + bordered table",`[table striped="true" bordered="true" caption="Product Pricing"]
71
71
  | Product | Price |
72
72
  | ------- | ----: |
73
73
  | Widget | $9.99 |
74
74
  | Gadget | $14.99 |
75
- [/table]`,"The inner content must be a valid GFM Markdown table. The shortcode adds Domma CSS classes and wraps in a responsive scroll container.")),G.appendChild(J);const te=document.createElement("div");te.appendChild(M("Slideover")),te.appendChild(A("A trigger button that opens a slide-in panel with Markdown content. No plugin required."));const de=document.createElement("table");de.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['title="..."',"Panel header text"],['trigger="..."','Button label (default: "Open")'],['size="sm|md|lg"',"Panel width (default: md)"],['position="right|left"',"Slide direction (default: right)"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),de.appendChild(e)}),te.appendChild(de),te.appendChild(y("Example",`[slideover title="More Info" trigger="Read more" size="md"]
75
+ [/table]`,"The inner content must be a valid GFM Markdown table. The shortcode adds Domma CSS classes and wraps in a responsive scroll container.")),X.appendChild(T);const O=document.createElement("div");O.appendChild(F("Slideover")),O.appendChild(M("A trigger button that opens a slide-in panel with Markdown content. No plugin required."));const re=document.createElement("table");re.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['title="..."',"Panel header text"],['trigger="..."','Button label (default: "Open")'],['size="sm|md|lg"',"Panel width (default: md)"],['position="right|left"',"Slide direction (default: right)"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),re.appendChild(t)}),O.appendChild(re),O.appendChild(z("Example",`[slideover title="More Info" trigger="Read more" size="md"]
76
76
  ## Details
77
77
  Markdown content here.
78
- [/slideover]`,"Nested [card] and [grid] shortcodes work inside the slideover body.")),G.appendChild(te);const q=document.createElement("div");q.appendChild(M("DConfig \u2014 Declarative Behaviour")),q.appendChild(A("Define click handlers and class toggles without writing JavaScript. Use the DConfig section above or embed inline with [dconfig]...[/dconfig] in the content body. Inline shortcodes win on selector conflict.")),q.appendChild(y("Toggle a class on click",'{ "#my-btn": { "events": { "click": { "target": "#panel", "toggleClass": "hidden" } } } }','Selector keys use standard CSS selectors. "target" is optional \u2014 defaults to the element itself.')),q.appendChild(y("Inline shortcode syntax",`[dconfig]
78
+ [/slideover]`,"Nested [card] and [grid] shortcodes work inside the slideover body.")),X.appendChild(O);const le=document.createElement("div");le.appendChild(F("DConfig \u2014 Declarative Behaviour")),le.appendChild(M("Define click handlers and class toggles without writing JavaScript. Use the DConfig section above or embed inline with [dconfig]...[/dconfig] in the content body. Inline shortcodes win on selector conflict.")),le.appendChild(z("Toggle a class on click",'{ "#my-btn": { "events": { "click": { "target": "#panel", "toggleClass": "hidden" } } } }','Selector keys use standard CSS selectors. "target" is optional \u2014 defaults to the element itself.')),le.appendChild(z("Inline shortcode syntax",`[dconfig]
79
79
  { "#my-btn": { "events": { "click": { "target": "#panel", "toggleClass": "hidden" } } } }
80
- [/dconfig]`,null)),ue.appendChild(q);const U=document.createElement("div");U.appendChild(M("Tips"));const _=document.createElement("table");_.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['class="text-center"',"Centre text and inline elements on any shortcode"],['class="mx-auto"',"Centre a block element horizontally"],["[center]...[/center]","Shorthand wrapper for centred content"]].forEach(([m,t])=>{const e=document.createElement("tr"),l=document.createElement("td");l.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",l.appendChild(P(m));const u=document.createElement("td");u.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",u.textContent=t,e.appendChild(l),e.appendChild(u),_.appendChild(e)}),U.appendChild(_),U.appendChild(A("Most shortcodes accept a class attribute for custom styling.")),ce.appendChild(U),s.setContent(xe),s.open(),E.tabs(se)}function ze(s,ie){const ye=s.find("#history-tab").get(0),P=s.find("#version-list").get(0),M=s.find("#version-compare").get(0),xe=s.find("#version-compare-old").get(0),se=s.find("#version-compare-new").get(0),Ee=s.find("#version-compare-label").get(0),re=s.find("#version-compare-back-btn").get(0),H=s.find("#version-restore-btn").get(0),ce=s.find("#history-save-named-btn").get(0);let ne=!1,G=null;function pe(){P.style.display="",M.style.display="none",G=null}function ue(){P.style.display="none",M.style.display=""}async function he(){P.textContent="";const X=document.createElement("p");X.style.color="var(--dm-text-muted)",X.textContent="Loading\u2026",P.appendChild(X);let W;try{W=(await V.versions.list(ie)).versions||[]}catch(A){P.textContent="";const y=document.createElement("p");y.style.color="var(--dm-text-danger,#e55)",y.textContent="Failed to load versions: "+A.message,P.appendChild(y);return}if(P.textContent="",!W.length){const A=document.createElement("p");A.style.color="var(--dm-text-muted)",A.textContent="No versions saved yet. Versions are created automatically on each save.",P.appendChild(A);return}const Q=document.createElement("table");Q.style.cssText="width:100%;border-collapse:collapse;font-size:.875rem;";const Y=document.createElement("thead"),ae=document.createElement("tr");["Date","Author","Type","Label","Actions"].forEach(A=>{const y=document.createElement("th");y.style.cssText="text-align:left;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border);font-size:.8rem;color:var(--dm-text-muted);",y.textContent=A,ae.appendChild(y)}),Y.appendChild(ae),Q.appendChild(Y);const Z=document.createElement("tbody");W.forEach(A=>{const y=document.createElement("tr");y.style.borderBottom="1px solid var(--dm-border)";const j=document.createElement("td");j.style.padding=".5rem .75rem",j.textContent=D(A.createdAt).format("D MMM YYYY, HH:mm");const K=document.createElement("td");K.style.padding=".5rem .75rem",K.textContent=A.author||"\u2014";const n=document.createElement("td");n.style.padding=".5rem .75rem";const f=document.createElement("span");f.className="badge badge-"+(A.type==="manual"?"primary":"secondary"),f.style.cssText="font-size:.75rem;padding:.2rem .5rem;border-radius:4px;",f.textContent=A.type,n.appendChild(f);const d=document.createElement("td");d.style.cssText="padding:.5rem .75rem;color:var(--dm-text-muted);",d.textContent=A.label||"\u2014";const o=document.createElement("td");o.style.padding=".5rem .75rem";const v=document.createElement("button");v.className="btn btn-ghost btn-xs",v.style.marginRight=".4rem",v.textContent="Compare",v.addEventListener("click",async()=>{try{const c=await V.versions.get(ie,A.filename);xe.textContent=c.content,se.textContent=s.find("#markdown-editor").get(0).value,Ee.textContent=D(A.createdAt).format("D MMM YYYY, HH:mm")+(A.label?` \u2014 ${A.label}`:""),G=A.filename,ue()}catch(c){E.toast("Failed to load version: "+c.message,{type:"error"})}});const h=document.createElement("button");h.className="btn btn-ghost btn-xs",h.style.color="var(--dm-text-danger,#e55)",h.textContent="Delete",h.addEventListener("click",async()=>{if(await E.confirm("Delete this version? This cannot be undone."))try{await V.versions.delete(ie,A.filename),E.toast("Version deleted.",{type:"success"}),await he()}catch(w){E.toast("Failed to delete: "+w.message,{type:"error"})}}),o.appendChild(v),o.appendChild(h),y.appendChild(j),y.appendChild(K),y.appendChild(n),y.appendChild(d),y.appendChild(o),Z.appendChild(y)}),Q.appendChild(Z),P.appendChild(Q)}ye.addEventListener("click",async()=>{ne||(ne=!0,await he())}),re.addEventListener("click",()=>{pe()}),H.addEventListener("click",async()=>{if(!(!G||!await E.confirm("Restore this version? The current page content will be overwritten (a pre-restore snapshot will be saved automatically).")))try{await V.versions.restore(ie,G),E.toast("Page restored. Reloading editor\u2026",{type:"success"}),R.navigate("/pages"),setTimeout(()=>R.navigate(`/pages/edit${ie}`),300)}catch(W){E.toast("Restore failed: "+W.message,{type:"error"})}}),ce.addEventListener("click",()=>{const X=E.modal({title:"Save Named Version"}),W=document.createElement("div");W.style.padding="1rem";const Q=document.createElement("label");Q.className="form-label",Q.textContent="Version Label";const Y=document.createElement("input");Y.type="text",Y.className="form-input",Y.placeholder="e.g. Initial design, Before restructure",Y.style.marginBottom=".75rem";const ae=document.createElement("button");ae.className="btn btn-primary",ae.textContent="Save Version",ae.addEventListener("click",async()=>{const Z=Y.value.trim();try{await V.versions.create(ie,Z||null),E.toast("Named version saved.",{type:"success"}),X.close(),ne=!1,ye.classList.contains("active")&&(ne=!0,await he())}catch(A){E.toast("Failed to save version: "+A.message,{type:"error"})}}),W.appendChild(Q),W.appendChild(Y),W.appendChild(ae),X.element.appendChild(W),X.open(),setTimeout(()=>Y.focus(),100)})}let Ce=!1,we=null,ke=!1;export const pageEditorView={templateUrl:"/admin/js/templates/page-editor.html",async onMount(s){const ye=window.location.hash.match(/#\/pages\/edit(\/.*)/),P=ye?ye[1]:null,M=!!P,xe=E.loader(s.get(0),{type:"dots"}),se=[V.layouts.get().catch(()=>({})),V.settings.get().catch(()=>({}))];M&&(se.push(V.pages.get(P).catch(()=>null)),se.push(V.pages.list().catch(()=>[])));const[Ee,re,H,ce]=await Promise.all(se);xe.destroy(),Se(s.find("#field-theme").get(0),{includeDefault:!0});const ne=re?.layoutOptions?.spacerSize??40;if(M&&!H){E.toast("Page not found.",{type:"error"}),R.navigate("/pages");return}s.find("#editor-title").text(M?`Edit Page \u2014 ${H.title||P}`:"New Page"),M&&s.find("#page-url-path").val(P),H&&(s.find("#field-title").val(H.title||""),s.find("#field-description").val(H.description||""),s.find("#field-status").val(H.status||"draft"),s.find("#field-sort-order").val(H.sortOrder??99),s.find("#field-show-in-nav").prop("checked",!!H.showInNav),s.find("#field-sidebar").prop("checked",!!H.sidebar),s.find("#field-show-breadcrumbs").prop("checked",H.breadcrumbs!==!1),s.find("#field-category").val(H.category||""),s.find("#field-visibility").val(H.visibility||"public"),s.find("#field-theme").val(H.theme||""),s.find("#field-seo-title").val(H.seo?.title||""),s.find("#field-seo-desc").val(H.seo?.description||""),H.dconfig&&s.find("#field-dconfig").val(JSON.stringify(H.dconfig,null,2)));const G=s.find("#quick-switch");M&&Array.isArray(ce)&&ce.length&&([...ce].sort((f,d)=>(f.title||f.urlPath).localeCompare(d.title||d.urlPath)).forEach(f=>{const d=document.createElement("option");d.value=f.urlPath,d.textContent=`${f.title||"Untitled"} (${f.urlPath})`,f.urlPath===P&&(d.selected=!0),G.get(0).appendChild(d)}),G.css("display",""),G.on("change",function(){const f=this.value;f&&R.navigate("/pages/edit"+f)}));const pe=await V.pages.tags().catch(()=>[]),ue=s.find("#field-tags").get(0),he=ue?E.pillbox(ue,{data:pe,value:H?.tags||[],creatable:!0,searchable:!0,placeholder:"Add tag\u2026"}):null,X=s.find("#field-layout").empty();if(Object.entries(Ee).forEach(([n,f])=>{const d=(H?.layout||"default")===n?"selected":"";X.append(`<option value="${n}" ${d}>${f.label||n}</option>`)}),M){const n=s.find("#view-page-btn").get(0);n.href=P,n.style.display="";const f=s.find("#live-preview-tab").get(0);f.style.display="";const d=s.find("#history-tab").get(0);d.style.display=""}if(E.tabs(s.find("#editor-meta-tabs").get(0)),M){const n=s.find("#live-preview-tab").get(0),f=s.find("#live-preview-frame").get(0);let d=!1;n.addEventListener("click",function(){d||(f.src=P,d=!0)}),ze(s,P)}const W=s.find("#markdown-editor"),Q=s.find("#markdown-preview");H&&W.val(H.content||"");const Y=W.get(0),ae=document.createElement("div");ae.className="editor-line-numbers",Y.parentElement.insertBefore(ae,Y);const Z=()=>{const n=Y.value.split(`
81
- `).length;ae.textContent=Array.from({length:n},(f,d)=>d+1).join(`
82
- `),ae.scrollTop=Y.scrollTop};Z(),Y.addEventListener("input",Z),Y.addEventListener("scroll",()=>{ae.scrollTop=Y.scrollTop});let A=null;const y=()=>{clearTimeout(A),A=setTimeout(async()=>{try{const{html:n}=await V.pages.preview(W.val());Q.html(n,{safe:!1}),I.scan(Q.get(0)),Q.get(0).querySelectorAll(".tabs").forEach(f=>Domma.elements.tabs(f))}catch{window.marked&&Q.html(marked.parse(W.val()))}},400)},j=Te(W,s.find("#editor-toolbar"),{spacerDefault:ne});j.onLink(async n=>{const d=(await V.pages.list().catch(()=>[])).map(r=>({label:r.title||r.urlPath,value:r.urlPath})),o=document.createElement("div");o.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const v=document.createElement("label");v.className="form-label",v.textContent="URL";const h=document.createElement("input");h.type="text",h.className="form-input",h.placeholder="/about or https://example.com";const c=n.value.substring(n.selectionStart,n.selectionEnd);c&&c.startsWith("/")&&(h.value=c),o.appendChild(v),o.appendChild(h);const w=document.createElement("label");w.className="form-label",w.textContent="Link text";const g=document.createElement("input");g.type="text",g.className="form-input",g.placeholder="Display text",c&&!c.startsWith("/")&&(g.value=c),o.appendChild(w),o.appendChild(g);const b=document.createElement("label");b.className="form-label",b.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const x=document.createElement("input");x.type="checkbox",x.style.cssText="width:1rem;height:1rem;cursor:pointer;",b.appendChild(x),b.appendChild(document.createTextNode("Display as button")),o.appendChild(b);const S=document.createElement("label");S.className="form-label",S.textContent="Button colour",S.style.display="none";const z=document.createElement("select");z.className="form-select",z.style.display="none",[["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["outline-success","Outline Success"],["outline-danger","Outline Danger"],["ghost","Ghost"]].forEach(([r,p])=>{const a=document.createElement("option");a.value=r,a.textContent=p,z.appendChild(a)}),o.appendChild(S),o.appendChild(z),x.addEventListener("change",()=>{const r=x.checked;S.style.display=r?"":"none",z.style.display=r?"":"none"});const T=document.createElement("button");T.type="button",T.className="btn btn-primary",T.textContent="Insert Link",o.appendChild(T);const B=E.modal({title:"Insert Link",size:"sm"});B.element.appendChild(o),B.open(),requestAnimationFrame(()=>{E.autocomplete(h,{data:d,minChars:1,onSelect:r=>{h.value=r.value,g.value||(g.value=r.label)}}),h.focus()}),T.addEventListener("click",()=>{const r=h.value.trim(),p=g.value.trim();if(!r)return;B.close();const a=x.checked?`[button href="${r}" variant="${z.value}"]${p||r}[/button]`:`[${p||r}](${r})`,C=n.selectionStart,i=n.selectionEnd;n.value=n.value.substring(0,C)+a+n.value.substring(i),n.selectionStart=n.selectionEnd=C+a.length,n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()})}),j.onImage(async n=>{const d=(await V.media.list().catch(()=>[])).filter(h=>/\.(png|jpe?g|gif|webp|svg)$/i.test(h.name)),o=document.createElement("div");if(o.className="media-picker-grid",d.length)d.forEach(h=>{const c=document.createElement("div");c.className="media-picker-item",c.dataset.url=h.url;const w=document.createElement("img");w.src=h.url,w.alt=h.name;const g=document.createElement("span");g.textContent=h.name,c.appendChild(w),c.appendChild(g),o.appendChild(c)});else{const h=document.createElement("p");h.className="text-muted p-3",h.textContent="No images uploaded yet.",o.appendChild(h)}const v=E.modal({title:"Insert Image",size:"lg"});v.element.appendChild(o),$(v.element).on("click",".media-picker-item",function(){const h=$(this).data("url"),c=$(this).find("span").text();fe(n,`![${c}](${h})`),v.close(),W.get(0).dispatchEvent(new Event("input",{bubbles:!0}))}),v.open()}),j.onCollection(async n=>{const[f,d]=await Promise.all([V.collections.list().catch(()=>[]),V.blocks.list().catch(()=>[])]),o=document.createElement("div");o.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const v="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",h="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",c=document.createElement("div"),w=document.createElement("label");w.style.cssText=v,w.textContent="Collection";const g=document.createElement("select");if(g.style.cssText=h,f.length)f.forEach(t=>{const e=document.createElement("option");e.value=t.slug,e.textContent=t.title||t.slug,g.appendChild(e)});else{const t=document.createElement("option");t.value="",t.textContent="No collections found",g.appendChild(t)}c.appendChild(w),c.appendChild(g),o.appendChild(c);const b=document.createElement("div"),x=document.createElement("label");x.style.cssText=v,x.textContent="Display";const S=document.createElement("select");S.style.cssText=h,["table","cards","list","block"].forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t.charAt(0).toUpperCase()+t.slice(1),S.appendChild(e)}),b.appendChild(x),b.appendChild(S),o.appendChild(b);const z=document.createElement("div");z.style.display="none";const k=document.createElement("label");k.style.cssText=v,k.textContent="Columns (2\u20134)";const T=document.createElement("input");T.type="number",T.min="2",T.max="4",T.value="3",T.style.cssText=h,z.appendChild(k),z.appendChild(T),o.appendChild(z);const B=document.createElement("div");B.style.display="none";const r=document.createElement("label");r.style.cssText=v,r.textContent="Block template";const p=document.createElement("select");if(p.style.cssText=h,d.length)d.forEach(t=>{const e=document.createElement("option");e.value=t.name??t,e.textContent=t.name??t,p.appendChild(e)});else{const t=document.createElement("option");t.value="",t.textContent="No block templates found",p.appendChild(t)}B.appendChild(r),B.appendChild(p),o.appendChild(B);const a=document.createElement("div"),C=document.createElement("label");C.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const i=document.createElement("input");i.type="checkbox",i.checked=!0,C.appendChild(i),C.appendChild(document.createTextNode("Enable search")),a.appendChild(C),o.appendChild(a);const L=document.createElement("div"),N=document.createElement("label");N.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const F=document.createElement("input");F.type="checkbox",F.checked=!0,N.appendChild(F),N.appendChild(document.createTextNode("Sortable columns")),L.appendChild(N),o.appendChild(L);const O=document.createElement("div"),le=document.createElement("label");le.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const ee=document.createElement("input");ee.type="checkbox",ee.checked=!1,le.appendChild(ee),le.appendChild(document.createTextNode("CSV export")),O.appendChild(le),o.appendChild(O);const be=document.createElement("div"),oe=document.createElement("label");oe.style.cssText=v,oe.textContent="Rows per page";const J=document.createElement("input");J.type="number",J.min="5",J.max="100",J.value="25",J.style.cssText=h,be.appendChild(oe),be.appendChild(J),o.appendChild(be);const me=document.createElement("div"),te=document.createElement("label");te.style.cssText=v,te.textContent="Limit (optional)";const de=document.createElement("input");de.type="number",de.placeholder="All",de.style.cssText=h,me.appendChild(te),me.appendChild(de),o.appendChild(me);const q=document.createElement("button");q.type="button",q.className="btn btn-primary",q.textContent="Insert",o.appendChild(q);const U=[a,L,O,be],_=()=>{const t=S.value,e=t==="table";U.forEach(l=>{l.style.display=e?"":"none"}),z.style.display=t==="cards"||t==="block"?"":"none",B.style.display=t==="block"?"":"none"};S.addEventListener("change",_),_();const m=E.modal({title:"Insert Collection",size:"sm"});m.element.appendChild(o),m.open(),q.addEventListener("click",()=>{const t=g.value;if(!t)return;const e=S.value;let l=`[collection slug="${t}" display="${e}"`;if(e==="cards"&&(l+=` columns="${T.value}"`),e==="block"){const ge=p.value;ge&&(l+=` block="${ge}"`);const ve=T.value.trim();ve&&(l+=` cols="${ve}"`)}e==="table"&&!i.checked&&(l+=' search="false"'),e==="table"&&!F.checked&&(l+=' sortable="false"'),e==="table"&&ee.checked&&(l+=' exportable="true"'),e==="table"&&J.value!=="25"&&(l+=` page-size="${J.value}"`);const u=de.value.trim();u&&(l+=` limit="${u}"`),l+=" /]",m.close(),fe(n,l),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()})}),j.onBlock(async n=>{let f=[];try{f=await V.blocks.list()}catch{E.toast("Could not load blocks.",{type:"error"});return}if(!f.length){E.toast("No block templates found. Create one in Blocks first.",{type:"warning"});return}const d=E.modal({title:"Insert Block",size:"lg"}),o=document.createElement("div");o.style.cssText="display:flex;gap:1rem;min-height:320px;";const v=document.createElement("div");v.style.cssText="flex:1;display:flex;flex-direction:column;gap:.75rem;";const h=document.createElement("label");h.className="form-label",h.textContent="Block Template";const c=document.createElement("select");c.className="form-select";const w=document.createElement("option");w.value="",w.textContent="\u2014 select a template \u2014",c.appendChild(w),f.forEach(p=>{const a=document.createElement("option");a.value=p.name,a.textContent=p.name,c.appendChild(a)}),v.appendChild(h),v.appendChild(c);const g=document.createElement("div");g.style.cssText="display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;max-height:260px;",v.appendChild(g);const b=document.createElement("button");b.className="btn btn-primary",b.type="button",b.textContent="Insert",b.disabled=!0,v.appendChild(b);const x=document.createElement("div");x.style.cssText="flex:1;border:1px solid var(--dm-border-color);border-radius:var(--dm-radius);padding:.75rem;overflow:auto;background:var(--dm-surface-bg);";const S=document.createElement("p");S.className="text-muted",S.style.cssText="font-size:.8rem;margin:0;",S.textContent="Select a template to see a preview.",x.appendChild(S),o.appendChild(v),o.appendChild(x),d.element.appendChild(o),d.open();let z=null,k=[];function T(p){return p.replace(/_/g," ").replace(/\b\w/g,a=>a.toUpperCase())}function B(){if(!z)return;const p={};k.forEach(({key:C,input:i})=>{p[C]=i.value});const a=z.replace(/\{\{([\w_]+)\}\}/g,(C,i)=>(p[i]??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"));x.innerHTML=DOMPurify.sanitize(a)}function r(p){g.textContent="",k=[];const a=new Set(["_id","_createdAt","_updatedAt"]),C=new Set;for(const[,i]of p.matchAll(/\{\{([\w_]+)\}\}/g))a.has(i)||C.add(i);if(!C.size){const i=document.createElement("p");i.className="text-muted",i.style.cssText="font-size:.8rem;margin:0;",i.textContent="No editable placeholders in this template.",g.appendChild(i);return}C.forEach(i=>{const L=document.createElement("div"),N=document.createElement("label");N.className="form-label",N.style.cssText="font-size:.8rem;margin-bottom:.2rem;display:block;",N.textContent=T(i);const F=document.createElement("input");F.type="text",F.className="form-input",F.placeholder=T(i),F.addEventListener("input",B),L.appendChild(N),L.appendChild(F),g.appendChild(L),k.push({key:i,input:F})})}c.addEventListener("change",async()=>{const p=c.value;if(!p){z=null,k=[],g.textContent="",x.textContent="",x.appendChild(S),b.disabled=!0;return}z=null,k=[],g.textContent="",b.disabled=!0;try{z=(await V.blocks.get(p)).content||"",r(z),B(),b.disabled=!1}catch{E.toast("Could not load template.",{type:"error"})}}),b.addEventListener("click",()=>{if(!c.value)return;const p=i=>i.replace(/"/g,"&quot;");let a=`template="${p(c.value)}"`;k.forEach(({key:i,input:L})=>{L.value!==""&&(a+=` ${i}="${p(L.value)}"`)});const C=`[block ${a} /]`;fe(n,C),n.dispatchEvent(new Event("input",{bubbles:!0})),d.close(),n.focus()})}),j.onForm(async n=>{const f=await V.forms.list().catch(()=>[]),d=document.createElement("div");d.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const o="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",v="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",h=document.createElement("div"),c=document.createElement("label");c.style.cssText=o,c.textContent="Form";const w=document.createElement("select");if(w.style.cssText=v,f.length)f.forEach(x=>{const S=document.createElement("option");S.value=x.slug,S.textContent=x.title||x.slug,w.appendChild(S)});else{const x=document.createElement("option");x.value="",x.textContent="No forms found",w.appendChild(x)}h.appendChild(c),h.appendChild(w),d.appendChild(h);const g=document.createElement("button");g.className="btn btn-primary btn-sm",g.style.cssText="align-self:flex-end;margin-top:.5rem;",g.textContent="Insert Form",d.appendChild(g);const b=E.modal({title:"Insert Form",size:"sm"});b.element.appendChild(d),b.open(),g.addEventListener("click",()=>{const x=w.value;x&&(fe(n,`[form slug="${x}" /]`),b.close(),W.get(0).dispatchEvent(new Event("input",{bubbles:!0})))})}),j.onView(async n=>{const f=await V.views.list().catch(()=>[]),d=document.createElement("div");d.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const o="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",v="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",h=document.createElement("div"),c=document.createElement("label");c.style.cssText=o,c.textContent="View";const w=document.createElement("select");if(w.style.cssText=v,f.length)f.forEach(k=>{const T=document.createElement("option");T.value=k.slug,T.textContent=k.title||k.slug,w.appendChild(T)});else{const k=document.createElement("option");k.value="",k.textContent="No Views configured yet \u2014 create one under Data \u2192 Views",w.appendChild(k)}h.appendChild(c),h.appendChild(w),d.appendChild(h);const g=document.createElement("div"),b=document.createElement("label");b.style.cssText=o,b.textContent="Display";const x=document.createElement("select");x.style.cssText=v,["table","cards","list"].forEach(k=>{const T=document.createElement("option");T.value=k,T.textContent=k.charAt(0).toUpperCase()+k.slice(1),x.appendChild(T)}),g.appendChild(b),g.appendChild(x),d.appendChild(g);const S=document.createElement("button");S.type="button",S.className="btn btn-primary",S.textContent="Insert",d.appendChild(S);const z=E.modal({title:"Insert View",size:"sm"});z.element.appendChild(d),z.open(),S.addEventListener("click",()=>{const k=w.value;if(!k)return;const T=`[view slug="${k}" display="${x.value}" /]`;z.close(),fe(n,T),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()})}),j.onCta(async n=>{const f=await V.actions.list().catch(()=>[]),d=document.createElement("div");d.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const o="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",v="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function h(r,p){const a=document.createElement("div"),C=document.createElement("label");return C.style.cssText=o,C.textContent=r,a.appendChild(C),a.appendChild(p),a}function c(r){const p=document.createElement("select");return p.style.cssText=v,r.forEach(([a,C])=>{const i=document.createElement("option");i.value=a,i.textContent=C,p.appendChild(i)}),p}function w(r,p,a){const C=document.createElement("input");return C.type=r,C.placeholder=p||"",C.value=a||"",C.style.cssText=v,C}const g=c(f.length?f.map(r=>[r.slug,r.title||r.slug]):[["","No Actions configured yet \u2014 create one under Data \u2192 Actions"]]);d.appendChild(h("Action",g));const b=w("text","Button label","Run");if(d.appendChild(h("Label",b)),g.addEventListener("change",()=>{const r=f.find(p=>p.slug===g.value);r?.trigger?.label&&(b.value=r.trigger.label)}),f.length){const r=f[0];r?.trigger?.label&&(b.value=r.trigger.label)}const x=w("text","Paste entry UUID\u2026","");d.appendChild(h("Entry ID",x));const S=c([["primary","Primary"],["secondary","Secondary"],["ghost","Ghost"],["danger","Danger"]]);d.appendChild(h("Style",S));const z=w("text","e.g. check, zap, send (optional)","");d.appendChild(h("Icon",z));const k=w("text","Confirmation message (optional)","");d.appendChild(h("Confirm prompt",k));const T=document.createElement("button");T.type="button",T.className="btn btn-primary",T.textContent="Insert",d.appendChild(T);const B=E.modal({title:"Insert CTA Button",size:"sm"});B.element.appendChild(d),B.open(),T.addEventListener("click",()=>{const r=g.value;if(!r)return;const p=x.value.trim(),a=(b.value.trim()||"Run").replace(/\[\/cta\]/gi,""),C=S.value,i=z.value.trim().replace(/"/g,""),L=k.value.trim().replace(/"/g,""),N=p.replace(/"/g,"");let F=`action="${r}" style="${C}"`;N&&(F+=` entry="${N}"`),i&&(F+=` icon="${i}"`),L&&(F+=` confirm="${L}"`);const O=`[cta ${F}]${a}[/cta]`;B.close(),fe(n,O),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()})}),j.onButton(async n=>{const d=(await V.pages.list().catch(()=>[])).map(i=>({label:i.title||i.urlPath,value:i.urlPath})),o=document.createElement("div");o.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const v="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",h="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function c(i,L){const N=document.createElement("div"),F=document.createElement("label");return F.style.cssText=v,F.textContent=i,N.appendChild(F),N.appendChild(L),N}function w(i,L){const N=document.createElement("input");return N.type="text",N.placeholder=i,N.value=L||"",N.style.cssText=h,N}function g(i){const L=document.createElement("select");return L.style.cssText=h,i.forEach(([N,F])=>{const O=document.createElement("option");O.value=N,O.textContent=F,L.appendChild(O)}),L}const b=n.value.substring(n.selectionStart,n.selectionEnd),x=w("/about or https://example.com",b.startsWith("/")?b:"");o.appendChild(c("URL",x));const S=w("Button label",b&&!b.startsWith("/")?b:"");o.appendChild(c("Label",S));const z=g([["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["ghost","Ghost"],["link","Link"],["outline-success","Outline Success"],["outline-danger","Outline Danger"]]);o.appendChild(c("Variant",z));const k=g([["","Default"],["sm","Small"],["lg","Large"]]);o.appendChild(c("Size",k));const T=w("e.g. arrow-right, star (optional)","");o.appendChild(c("Icon (before label)",T));const B=w("e.g. arrow-right (optional)","");o.appendChild(c("Icon (after label)",B));const r=document.createElement("label");r.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const p=document.createElement("input");p.type="checkbox",p.style.cssText="width:1rem;height:1rem;",r.appendChild(p),r.appendChild(document.createTextNode("Open in new tab")),o.appendChild(r);const a=document.createElement("button");a.type="button",a.className="btn btn-primary",a.textContent="Insert Button",o.appendChild(a);const C=E.modal({title:"Insert Button",size:"sm"});C.element.appendChild(o),C.open(),requestAnimationFrame(()=>{E.autocomplete(x,{data:d,minChars:1,onSelect:i=>{x.value=i.value,S.value||(S.value=i.label)}}),x.focus()}),a.addEventListener("click",()=>{const i=x.value.trim();if(!i)return;C.close();const L=S.value.trim()||i;let N=`href="${i}" variant="${z.value}"`;k.value&&(N+=` size="${k.value}"`);const F=T.value.trim().replace(/"/g,"");F&&(N+=` icon="${F}"`);const O=B.value.trim().replace(/"/g,"");O&&(N+=` icon-after="${O}"`),p.checked&&(N+=' target="_blank"');const le=`[button ${N}]${L}[/button]`;fe(n,le)})}),j.onLinkShortcode(async n=>{const d=(await V.pages.list().catch(()=>[])).map(a=>({label:a.title||a.urlPath,value:a.urlPath})),o=document.createElement("div");o.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const v="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",h="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function c(a,C){const i=document.createElement("div"),L=document.createElement("label");return L.style.cssText=v,L.textContent=a,i.appendChild(L),i.appendChild(C),i}function w(a,C){const i=document.createElement("input");return i.type="text",i.placeholder=a,i.value=C||"",i.style.cssText=h,i}const g=n.value.substring(n.selectionStart,n.selectionEnd),b=w("/about or https://example.com",g.startsWith("/")?g:"");o.appendChild(c("URL",b));const x=w("Link text",g&&!g.startsWith("/")?g:"");o.appendChild(c("Link text",x));const S=w("e.g. text-primary, fw-bold (optional)","");o.appendChild(c("CSS class",S));const z=w("e.g. arrow-right (optional)","");o.appendChild(c("Icon (before text)",z));const k=w("e.g. external-link (optional)","");o.appendChild(c("Icon (after text)",k));const T=document.createElement("label");T.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const B=document.createElement("input");B.type="checkbox",B.style.cssText="width:1rem;height:1rem;",T.appendChild(B),T.appendChild(document.createTextNode("Open in new tab")),o.appendChild(T);const r=document.createElement("button");r.type="button",r.className="btn btn-primary",r.textContent="Insert Link",o.appendChild(r);const p=E.modal({title:"Insert Link Shortcode",size:"sm"});p.element.appendChild(o),p.open(),requestAnimationFrame(()=>{E.autocomplete(b,{data:d,minChars:1,onSelect:a=>{b.value=a.value,x.value||(x.value=a.label)}}),b.focus()}),r.addEventListener("click",()=>{const a=b.value.trim();if(!a)return;p.close();const C=x.value.trim()||a;let i=`href="${a}"`;const L=S.value.trim().replace(/"/g,"");L&&(i+=` class="${L}"`);const N=z.value.trim().replace(/"/g,"");N&&(i+=` icon="${N}"`);const F=k.value.trim().replace(/"/g,"");F&&(i+=` icon-after="${F}"`),B.checked&&(i+=' target="_blank"');const O=`[link ${i}]${C}[/link]`;fe(n,O)})}),j.onTabs(n=>{const f=document.createElement("div");f.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const d="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",o="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function v(r,p){const a=document.createElement("div"),C=document.createElement("label");return C.style.cssText=d,C.textContent=r,a.appendChild(C),a.appendChild(p),a}function h(r){const p=document.createElement("select");return p.style.cssText=o,r.forEach(([a,C])=>{const i=document.createElement("option");i.value=a,i.textContent=C,p.appendChild(i)}),p}const c=h([["","Default (underline)"],["pills","Pills"]]);f.appendChild(v("Style",c));const w=h([["","Left"],["center","Centre"]]);f.appendChild(v("Alignment",w));const g=document.createElement("div");g.style.cssText="display:flex;flex-direction:column;gap:.4rem;";const b=[];function x(){b.forEach(r=>{r.removeBtn.disabled=b.length<=2,r.removeBtn.style.opacity=b.length<=2?"0.3":"1"})}function S(r){const p=document.createElement("div");p.style.cssText="display:flex;gap:.4rem;align-items:center;";const a=document.createElement("input");a.type="text",a.placeholder="Tab title",a.value=r||"",a.style.cssText=o+"flex:1;";const C=document.createElement("button");C.type="button",C.textContent="\u2715",C.style.cssText="padding:.3rem .5rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;flex-shrink:0;";const i={row:p,input:a,removeBtn:C};b.push(i),p.appendChild(a),p.appendChild(C),g.appendChild(p),C.addEventListener("click",()=>{if(b.length<=2)return;const L=b.indexOf(i);b.splice(L,1),g.removeChild(p),x()}),x()}S("Overview"),S("Details");const z=document.createElement("div");z.style.cssText=d,z.textContent="Tabs",f.appendChild(z),f.appendChild(g);const k=document.createElement("button");k.type="button",k.textContent="+ Add Tab",k.style.cssText="padding:.35rem .75rem;background:transparent;border:1px dashed var(--dm-border,#555);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;align-self:flex-start;",k.addEventListener("click",()=>{b.length>=10||(S(""),b[b.length-1].input.focus())}),f.appendChild(k);const T=document.createElement("button");T.type="button",T.className="btn btn-primary",T.textContent="Insert Tabs",f.appendChild(T);const B=E.modal({title:"Insert Tabs",size:"sm"});B.element.appendChild(f),B.open(),requestAnimationFrame(()=>b[0].input.focus()),T.addEventListener("click",()=>{B.close();const r=c.value,p=w.value;let a=r?` style="${r}"`:"";p&&(a+=` align="${p}"`);let C=`[tabs${a}]
83
- `;b.forEach((i,L)=>{const N=i.input.value.trim()||`Tab ${L+1}`;C+=`[tab title="${N}"]Tab content here.[/tab]
84
- `}),C+="[/tabs]",fe(n,C),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()})}),j.onAccordion(async n=>{const f=await V.collections.list().catch(()=>[]),d=document.createElement("div");d.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const o="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",v="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",h=document.createElement("div");h.style.cssText="display:flex;gap:.5rem;";const c=document.createElement("button");c.type="button",c.className="btn btn-sm btn-primary",c.textContent="Static";const w=document.createElement("button");w.type="button",w.className="btn btn-sm btn-ghost",w.textContent="Collection",h.appendChild(c),h.appendChild(w),d.appendChild(h);let g="static";const b=document.createElement("div");b.style.cssText="display:flex;flex-direction:column;gap:.5rem;";const x=[];function S(q){const U=document.createElement("div");U.style.cssText="display:flex;align-items:center;gap:.5rem;";const _=document.createElement("label");_.style.cssText="font-size:.85em;color:var(--dm-text-muted,#aaa);white-space:nowrap;",_.textContent=`Item ${q}`;const m=document.createElement("input");return m.type="text",m.placeholder="Item title",m.style.cssText=v,U.appendChild(_),U.appendChild(m),{row:U,input:m}}[1,2].forEach(q=>{const U=S(q);x.push(U),b.appendChild(U.row)});const z=document.createElement("button");z.type="button",z.className="btn btn-ghost btn-sm",z.textContent="+ Add Item",z.addEventListener("click",()=>{const q=S(x.length+1);x.push(q),b.insertBefore(q.row,z)}),b.appendChild(z);const k=document.createElement("label");k.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const T=document.createElement("input");T.type="checkbox",k.appendChild(T),k.appendChild(document.createTextNode("Allow multiple open")),b.appendChild(k),d.appendChild(b);const B=document.createElement("div");B.style.cssText="display:none;flex-direction:column;gap:.5rem;";const r=document.createElement("div"),p=document.createElement("label");p.style.cssText=o,p.textContent="Collection";const a=document.createElement("select");if(a.style.cssText=v,f.length)f.forEach(q=>{const U=document.createElement("option");U.value=q.slug,U.textContent=q.title||q.slug,a.appendChild(U)});else{const q=document.createElement("option");q.value="",q.textContent="No collections found",a.appendChild(q)}r.appendChild(p),r.appendChild(a),B.appendChild(r);const C=document.createElement("div"),i=document.createElement("label");i.style.cssText=o,i.textContent="Title field";const L=document.createElement("select");L.style.cssText=v,C.appendChild(i),C.appendChild(L),B.appendChild(C);const N=document.createElement("div"),F=document.createElement("label");F.style.cssText=o,F.textContent="Body field";const O=document.createElement("select");O.style.cssText=v,N.appendChild(F),N.appendChild(O),B.appendChild(N);async function le(q){L.textContent="",O.textContent="";try{const _=(await V.collections.get(q)).fields||[];if(!_.length){const m=document.createElement("option");m.value="",m.textContent="\u2014 none \u2014",L.appendChild(m.cloneNode(!0)),O.appendChild(m);return}_.forEach((m,t)=>{const e=()=>{const l=document.createElement("option");return l.value=m.name,l.textContent=m.label||m.name,l};L.appendChild(e()),O.appendChild(e()),m.name==="title"&&(L.value="title"),m.name==="description"&&(O.value="description")}),!L.value&&_[0]&&(L.value=_[0].name),!O.value&&_[1]&&(O.value=_[1].name)}catch{const U=document.createElement("option");U.value="",U.textContent="\u2014 unknown \u2014",L.appendChild(U.cloneNode(!0)),O.appendChild(U)}}f.length&&le(f[0].slug),a.addEventListener("change",()=>le(a.value));const ee=document.createElement("div"),be=document.createElement("label");be.style.cssText=o,be.textContent="Limit (optional)";const oe=document.createElement("input");oe.type="number",oe.placeholder="All",oe.style.cssText=v,ee.appendChild(be),ee.appendChild(oe),B.appendChild(ee);const J=document.createElement("label");J.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const me=document.createElement("input");me.type="checkbox",J.appendChild(me),J.appendChild(document.createTextNode("Allow multiple open")),B.appendChild(J),d.appendChild(B),c.addEventListener("click",()=>{g="static",c.className="btn btn-sm btn-primary",w.className="btn btn-sm btn-ghost",b.style.display="flex",B.style.display="none"}),w.addEventListener("click",()=>{g="collection",w.className="btn btn-sm btn-primary",c.className="btn btn-sm btn-ghost",B.style.display="flex",b.style.display="none"});const te=document.createElement("button");te.type="button",te.className="btn btn-primary",te.textContent="Insert Accordion",d.appendChild(te);const de=E.modal({title:"Insert Accordion",size:"sm"});de.element.appendChild(d),de.open(),requestAnimationFrame(()=>x[0].input.focus()),te.addEventListener("click",()=>{if(g==="collection"&&!a.value)return;de.close();let q;if(g==="static")q=`[accordion${T.checked?' multiple="true"':""}]
85
- `,x.forEach((_,m)=>{const t=_.input.value.trim()||`Item ${m+1}`;q+=`[item title="${t}"]Content here.[/item]
86
- `}),q+="[/accordion]";else{const U=a.value;if(!U)return;const _=L.value,m=O.value;let t=`slug="${U}" display="accordion"`;_&&(t+=` title-field="${_}"`),m&&(t+=` body-field="${m}"`);const e=oe.value.trim();e&&(t+=` limit="${e}"`),me.checked&&(t+=' multiple="true"'),q=`[collection ${t} /]`}fe(n,q),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()})}),j.onHelp(()=>{Le()}),s.find(".editor-view-btn").on("click",function(){const n=$(this).data("mode");s.find(".editor-view-btn").removeClass("active"),$(this).addClass("active"),s.find("#editor-body").removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${n}`)}),s.find("#fullscreen-btn").on("click",function(){s.find(".editor-card").toggleClass("editor-fullscreen")}),Ce=!1,s.find("#quick-switch").prop("disabled",!1),we&&window.removeEventListener("beforeunload",we),we=n=>{Ce&&n.preventDefault()},window.addEventListener("beforeunload",we),ke||(ke=!0,R.use((n,f,d)=>{const o=window.location.hash.startsWith("#/pages/edit")||window.location.hash==="#/pages/new";if(!Ce||!o)return d();E.confirm("You have unsaved changes. Leave this page?").then(v=>{v&&(Ce=!1,d())})})),W.on("input",()=>{Ce=!0,s.find("#quick-switch").prop("disabled",!0),y()});const K=s.find("#editor-meta-tabs").get(0);K&&(K.addEventListener("input",()=>{Ce=!0,s.find("#quick-switch").prop("disabled",!0)}),K.addEventListener("change",n=>{n.target.id!=="quick-switch"&&(Ce=!0,s.find("#quick-switch").prop("disabled",!0))})),y(),s.find("#save-btn").on("click",async()=>{const n=s.find("#page-url-path").val().trim();if(!n){E.toast("URL path is required.",{type:"warning"});return}const f=s.find("#field-dconfig").val().trim();let d=null;if(f)try{d=JSON.parse(f)}catch{E.toast("DConfig JSON is invalid. Please check the format before saving.",{type:"warning"});return}const o={title:s.find("#field-title").val().trim()||"Untitled",description:s.find("#field-description").val().trim(),layout:s.find("#field-layout").val(),status:s.find("#field-status").val(),sortOrder:parseInt(s.find("#field-sort-order").val(),10)||99,showInNav:s.find("#field-show-in-nav").is(":checked"),sidebar:s.find("#field-sidebar").is(":checked"),...s.find("#field-show-breadcrumbs").is(":checked")?{}:{breadcrumbs:!1},tags:he?he.getValue():[],category:s.find("#field-category").val().trim()||null,visibility:s.find("#field-visibility").val()||"public",seo:{title:s.find("#field-seo-title").val().trim(),description:s.find("#field-seo-desc").val().trim()},dconfig:d,...s.find("#field-theme").val()?{theme:s.find("#field-theme").val()}:{}};try{if(s.find("#save-btn").prop("disabled",!0).text("Saving\u2026"),M){const v={frontmatter:o,body:W.val()};n!==P&&(v.newUrlPath=n),await V.pages.update(P,v),E.toast("Page saved successfully.",{type:"success"}),Ce=!1,s.find("#quick-switch").prop("disabled",!1),n!==P&&R.navigate(`/pages/edit${n}`)}else await V.pages.create({urlPath:n,frontmatter:o,body:W.val()}),E.toast("Page saved successfully.",{type:"success"}),Ce=!1,R.navigate("/pages")}catch(v){E.toast(`Save failed: ${v.message||"Unknown error"}`,{type:"error"})}finally{s.find("#save-btn").prop("disabled",!1).text("Save")}}),s.find("#cancel-btn").on("click",()=>R.navigate("/pages")),Domma.icons.scan()}};
80
+ [/dconfig]`,null)),be.appendChild(le);const ce=document.createElement("div");ce.appendChild(F("CSS Editor")),ce.appendChild(M("The toolbar's </> button (left of the Split View icon) swaps the left pane between Markdown and Custom CSS. Edits are saved together with the page \u2014 one Save, one toast."));const pe=document.createElement("table");pe.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["</> button","Toggle between Markdown editor and Custom CSS editor"],["Split / Write / Preview","Standard view mode buttons to the right of </>"],["Save","Saves both page content and CSS in a single operation"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),pe.appendChild(t)}),ce.appendChild(pe),be.appendChild(ce);const ee=document.createElement("div");ee.appendChild(F("Colour Picker")),ee.appendChild(M("Insert \u2192 Colour Picker opens a centred colour picker. Pick a colour, then use Copy to copy the hex code to the clipboard or Insert to drop it at the cursor. Click outside the panel to dismiss.")),be.appendChild(ee);const ye=document.createElement("div");ye.appendChild(F("Keyboard Shortcuts"));const me=document.createElement("table");me.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[["Ctrl + B","Bold selected text"],["Ctrl + I","Italic selected text"],["Ctrl + K","Insert link dialog"],["Tab","Indent 2 spaces at cursor"],["Shift + Tab","Dedent 2 spaces on current line"],["Ctrl + X","Cut current line (no selection) or cut selection"],["Ctrl + C","Copy current line (no selection) or copy selection"],["Ctrl + V","Paste from clipboard"],["Ctrl + Z","Undo"],["Ctrl + Y","Redo"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;white-space:nowrap;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),me.appendChild(t)}),ye.appendChild(me),he.appendChild(ye);const de=document.createElement("div");de.appendChild(F("Tips"));const V=document.createElement("table");V.style.cssText="width:100%;border-collapse:collapse;font-size:.85em;margin-bottom:.5rem;",[['class="text-center"',"Centre text and inline elements on any shortcode"],['class="mx-auto"',"Centre a block element horizontally"],["[center]...[/center]","Shorthand wrapper for centred content"]].forEach(([g,b])=>{const t=document.createElement("tr"),e=document.createElement("td");e.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;",e.appendChild(P(g));const n=document.createElement("td");n.style.cssText="padding:.3rem .4rem;border-bottom:1px solid var(--dm-border,#333);vertical-align:top;color:var(--dm-text-muted,#aaa);",n.textContent=b,t.appendChild(e),t.appendChild(n),V.appendChild(t)}),de.appendChild(V),de.appendChild(M("Most shortcodes accept a class attribute for custom styling.")),he.appendChild(de),i.setContent(ke),i.open(),E.tabs(ge),I.scan(ke)}function qe(i,ue){const Se=i.find("#history-tab").get(0),P=i.find("#version-list").get(0),F=i.find("#version-compare").get(0),ke=i.find("#version-compare-old").get(0),ge=i.find("#version-compare-new").get(0),Le=i.find("#version-compare-label").get(0),Ce=i.find("#version-compare-back-btn").get(0),_=i.find("#version-restore-btn").get(0),he=i.find("#history-save-named-btn").get(0),ie=i.find("#history-delete-selected-btn").get(0);let X=!1,ae=null;function be(){P.style.display="",F.style.display="none",ae=null}function Te(){P.style.display="none",F.style.display=""}async function ve(){P.textContent="";const W=document.createElement("p");W.style.color="var(--dm-text-muted)",W.textContent="Loading\u2026",P.appendChild(W);let G;try{G=(await U.versions.list(ue)).versions||[]}catch(q){P.textContent="";const H=document.createElement("p");H.style.color="var(--dm-text-danger,#e55)",H.textContent="Failed to load versions: "+q.message,P.appendChild(H);return}if(P.textContent="",ie.style.display="none",!G.length){const q=document.createElement("p");q.style.color="var(--dm-text-muted)",q.textContent="No versions saved yet. Versions are created automatically on each save.",P.appendChild(q);return}const K=document.createElement("table");K.style.cssText="width:100%;border-collapse:collapse;font-size:.875rem;";const te=document.createElement("thead"),Y=document.createElement("tr"),M=document.createElement("th");M.style.cssText="padding:.5rem .75rem;width:2rem;border-bottom:1px solid var(--dm-border);";const z=document.createElement("input");z.type="checkbox",z.setAttribute("aria-label","Select all versions"),M.appendChild(z),Y.appendChild(M),["Date","Author","Type","Label","Actions"].forEach(q=>{const H=document.createElement("th");H.style.cssText="text-align:left;padding:.5rem .75rem;border-bottom:1px solid var(--dm-border);font-size:.8rem;color:var(--dm-text-muted);",H.textContent=q,Y.appendChild(H)}),te.appendChild(Y),K.appendChild(te);const fe=[];function ne(){const q=fe.some(oe=>oe.checked),H=fe.length>0&&fe.every(oe=>oe.checked);ie.style.display=q?"":"none",z.checked=H,z.indeterminate=q&&!H}z.addEventListener("change",()=>{fe.forEach(q=>{q.checked=z.checked}),ne()});const j=document.createElement("tbody");G.forEach(q=>{const H=document.createElement("tr");H.style.borderBottom="1px solid var(--dm-border)";const oe=document.createElement("td");oe.style.padding=".5rem .75rem";const J=document.createElement("input");J.type="checkbox",J.value=q.filename,J.addEventListener("change",ne),oe.appendChild(J),fe.push(J);const Ee=document.createElement("td");Ee.style.padding=".5rem .75rem",Ee.textContent=D(q.createdAt).format("D MMM YYYY, HH:mm");const se=document.createElement("td");se.style.padding=".5rem .75rem",se.textContent=q.author||"\u2014";const a=document.createElement("td");a.style.padding=".5rem .75rem";const l=document.createElement("span");l.className="badge badge-"+(q.type==="manual"?"primary":"secondary"),l.style.cssText="font-size:.75rem;padding:.2rem .5rem;border-radius:4px;",l.textContent=q.type,a.appendChild(l);const r=document.createElement("td");r.style.cssText="padding:.5rem .75rem;color:var(--dm-text-muted);",r.textContent=q.label||"\u2014";const d=document.createElement("td");d.style.padding=".5rem .75rem";const C=document.createElement("button");C.className="btn btn-ghost btn-xs",C.style.marginRight=".4rem",C.textContent="Compare",C.addEventListener("click",async()=>{try{const p=await U.versions.get(ue,q.filename);ke.textContent=p.content,ge.textContent=i.find("#markdown-editor").get(0).value,Le.textContent=D(q.createdAt).format("D MMM YYYY, HH:mm")+(q.label?` \u2014 ${q.label}`:""),ae=q.filename,Te()}catch(p){E.toast("Failed to load version: "+p.message,{type:"error"})}});const f=document.createElement("button");f.className="btn btn-ghost btn-xs",f.style.color="var(--dm-text-danger,#e55)",f.textContent="Delete",f.addEventListener("click",async()=>{if(await E.confirm("Delete this version? This cannot be undone."))try{await U.versions.delete(ue,q.filename),E.toast("Version deleted.",{type:"success"}),await ve()}catch(y){E.toast("Failed to delete: "+y.message,{type:"error"})}}),d.appendChild(C),d.appendChild(f),H.appendChild(oe),H.appendChild(Ee),H.appendChild(se),H.appendChild(a),H.appendChild(r),H.appendChild(d),j.appendChild(H)}),K.appendChild(j),P.appendChild(K)}Se.addEventListener("click",async()=>{X||(X=!0,await ve())}),Ce.addEventListener("click",()=>{be()}),_.addEventListener("click",async()=>{if(!(!ae||!await E.confirm("Restore this version? The current page content will be overwritten (a pre-restore snapshot will be saved automatically).")))try{await U.versions.restore(ue,ae),E.toast("Page restored. Reloading editor\u2026",{type:"success"}),R.navigate("/pages"),setTimeout(()=>R.navigate(`/pages/edit${ue}`),300)}catch(G){E.toast("Restore failed: "+G.message,{type:"error"})}}),ie.addEventListener("click",async()=>{const W=[...P.querySelectorAll("tbody input[type=checkbox]:checked")].map(K=>K.value);if(!(!W.length||!await E.confirm(`Delete ${W.length} version${W.length>1?"s":""}? This cannot be undone.`)))try{await U.versions.bulkDelete(ue,W),E.toast(`${W.length} version${W.length>1?"s":""} deleted.`,{type:"success"}),await ve()}catch(K){E.toast("Delete failed: "+K.message,{type:"error"})}}),he.addEventListener("click",()=>{const W=E.modal({title:"Save Named Version"}),G=document.createElement("div");G.style.padding="1rem";const K=document.createElement("label");K.className="form-label",K.textContent="Version Label";const te=document.createElement("input");te.type="text",te.className="form-input",te.placeholder="e.g. Initial design, Before restructure",te.style.marginBottom=".75rem";const Y=document.createElement("button");Y.className="btn btn-primary",Y.textContent="Save Version",Y.addEventListener("click",async()=>{const M=te.value.trim();try{await U.versions.create(ue,M||null),E.toast("Named version saved.",{type:"success"}),W.close(),X=!1,Se.classList.contains("active")&&(X=!0,await ve())}catch(z){E.toast("Failed to save version: "+z.message,{type:"error"})}}),G.appendChild(K),G.appendChild(te),G.appendChild(Y),W.element.appendChild(G),W.open(),setTimeout(()=>te.focus(),100)})}let we=!1,Ne=null,Be=!1;export const pageEditorView={templateUrl:"/admin/js/templates/page-editor.html",async onMount(i){const Se=window.location.hash.match(/#\/pages\/edit(\/.*)/),P=Se?Se[1]:null,F=!!P,ke=E.loader(i.get(0),{type:"dots"}),ge=[U.layouts.get().catch(()=>({})),U.settings.get().catch(()=>({}))];F&&(ge.push(U.pages.get(P).catch(()=>null)),ge.push(U.pages.list().catch(()=>[])));const[Le,Ce,_,he]=await Promise.all(ge);ke.destroy(),Pe(i.find("#field-theme").get(0),{includeDefault:!0});const ie=Ce?.layoutOptions?.spacerSize??40;if(F&&!_){E.toast("Page not found.",{type:"error"}),R.navigate("/pages");return}i.find("#editor-title").text(F?`Edit Page \u2014 ${_.title||P}`:"New Page"),F&&i.find("#page-url-path").val(P),_&&(i.find("#field-title").val(_.title||""),i.find("#field-description").val(_.description||""),i.find("#field-status").val(_.status||"draft"),i.find("#field-sort-order").val(_.sortOrder??99),i.find("#field-show-in-nav").prop("checked",!!_.showInNav),i.find("#field-sidebar").prop("checked",!!_.sidebar),i.find("#field-show-breadcrumbs").prop("checked",_.breadcrumbs!==!1),i.find("#field-category").val(_.category||""),i.find("#field-visibility").val(_.visibility||"public"),i.find("#field-theme").val(_.theme||""),i.find("#field-seo-title").val(_.seo?.title||""),i.find("#field-seo-desc").val(_.seo?.description||""),_.dconfig&&i.find("#field-dconfig").val(JSON.stringify(_.dconfig,null,2)));const X=i.find("#quick-switch");F&&Array.isArray(he)&&he.length&&([...he].sort((l,r)=>(l.title||l.urlPath).localeCompare(r.title||r.urlPath)).forEach(l=>{const r=document.createElement("option");r.value=l.urlPath,r.textContent=`${l.title||"Untitled"} (${l.urlPath})`,l.urlPath===P&&(r.selected=!0),X.get(0).appendChild(r)}),X.css("display",""),X.on("change",function(){const l=this.value;l&&R.navigate("/pages/edit"+l)}));const ae=await U.pages.tags().catch(()=>[]),be=i.find("#field-tags").get(0),Te=be?E.pillbox(be,{data:ae,value:_?.tags||[],creatable:!0,searchable:!0,placeholder:"Add tag\u2026"}):null,ve=i.find("#field-layout").empty();if(Object.entries(Le).forEach(([a,l])=>{const r=(_?.layout||"default")===a?"selected":"";ve.append(`<option value="${a}" ${r}>${l.label||a}</option>`)}),F){const a=i.find("#view-page-btn").get(0);a.href=P,a.style.display="";const l=i.find("#live-preview-tab").get(0);l.style.display="";const r=i.find("#history-tab").get(0);r.style.display=""}if(E.tabs(i.find("#editor-meta-tabs").get(0)),F){const a=i.find("#live-preview-tab").get(0),l=i.find("#live-preview-frame").get(0);let r=!1;a.addEventListener("click",function(){r||(l.src=P,r=!0)}),qe(i,P)}const W=i.find("#markdown-editor"),G=i.find("#markdown-preview");_&&W.val(_.content||"");let K=!1,te="";U.settings.getCustomCss().then(({css:a})=>{if(te=a||"",!te)return;const l=document.createElement("style");l.id="preview-custom-css",l.textContent=te,G.get(0).parentNode.insertBefore(l,G.get(0))}).catch(()=>{});const Y=W.get(0),M=document.createElement("div");M.className="editor-line-numbers",Y.parentElement.insertBefore(M,Y);const z=()=>{const a=Y.value.split(`
81
+ `).length;M.textContent=Array.from({length:a},(l,r)=>r+1).join(`
82
+ `),M.scrollTop=Y.scrollTop};z(),Y.addEventListener("input",z),Y.addEventListener("scroll",()=>{M.scrollTop=Y.scrollTop});let fe=null;const ne=()=>{clearTimeout(fe),fe=setTimeout(async()=>{try{const{html:a}=await U.pages.preview(W.val());G.html(a,{safe:!1}),I.scan(G.get(0)),G.get(0).querySelectorAll(".tabs").forEach(l=>Domma.elements.tabs(l))}catch{window.marked&&G.html(marked.parse(W.val()))}},400)},j=Re(W,i.find("#editor-toolbar"),{spacerDefault:ie});let q=!1,H="split",oe=null;const J=document.createElement("button");J.className="editor-view-btn",J.setAttribute("data-tooltip","Edit Custom CSS"),J.type="button";const Ee=document.createElement("span");Ee.setAttribute("data-icon","css-code"),J.appendChild(Ee),I.scan(J),i.find(".editor-toolbar-right").get(0).prepend(J),J.addEventListener("click",()=>{q=!q;const a=i.find("#markdown-editor"),l=i.find("#css-editor"),r=i.find("#editor-body");if(q){const d=i.find(".editor-view-btn[data-mode].active").get(0);H=d?d.getAttribute("data-mode"):"split",i.find(".editor-view-btn[data-mode]").removeClass("active"),i.find('.editor-view-btn[data-mode="split"]').addClass("active"),r.removeClass("editor-mode-write editor-mode-preview").addClass("editor-mode-split"),a.hide(),l.show(),K||(l.val(te),K=!0,De(l.get(0))),J.classList.add("active")}else i.find(".editor-view-btn[data-mode]").removeClass("active"),i.find(`.editor-view-btn[data-mode="${H}"]`).addClass("active"),r.removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${H}`),l.hide(),a.show(),J.classList.remove("active")}),i.find("#css-editor").on("input",()=>{clearTimeout(oe),oe=setTimeout(()=>{let a=document.getElementById("preview-custom-css");a||(a=document.createElement("style"),a.id="preview-custom-css",G.get(0).parentNode.insertBefore(a,G.get(0))),a.textContent=i.find("#css-editor").val()},400)}),j.onLink(async a=>{const r=(await U.pages.list().catch(()=>[])).map(u=>({label:u.title||u.urlPath,value:u.urlPath})),d=document.createElement("div");d.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const C=document.createElement("label");C.className="form-label",C.textContent="URL";const f=document.createElement("input");f.type="text",f.className="form-input",f.placeholder="/about or https://example.com";const p=a.value.substring(a.selectionStart,a.selectionEnd);p&&p.startsWith("/")&&(f.value=p),d.appendChild(C),d.appendChild(f);const y=document.createElement("label");y.className="form-label",y.textContent="Link text";const v=document.createElement("input");v.type="text",v.className="form-input",v.placeholder="Display text",p&&!p.startsWith("/")&&(v.value=p),d.appendChild(y),d.appendChild(v);const h=document.createElement("label");h.className="form-label",h.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;";const w=document.createElement("input");w.type="checkbox",w.style.cssText="width:1rem;height:1rem;cursor:pointer;",h.appendChild(w),h.appendChild(document.createTextNode("Display as button")),d.appendChild(h);const L=document.createElement("label");L.className="form-label",L.textContent="Button colour",L.style.display="none";const A=document.createElement("select");A.className="form-select",A.style.display="none",[["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["outline-success","Outline Success"],["outline-danger","Outline Danger"],["ghost","Ghost"]].forEach(([u,m])=>{const s=document.createElement("option");s.value=u,s.textContent=m,A.appendChild(s)}),d.appendChild(L),d.appendChild(A),w.addEventListener("change",()=>{const u=w.checked;L.style.display=u?"":"none",A.style.display=u?"":"none"});const S=document.createElement("button");S.type="button",S.className="btn btn-primary",S.textContent="Insert Link",d.appendChild(S);const N=E.modal({title:"Insert Link",size:"sm"});N.element.appendChild(d),N.open(),requestAnimationFrame(()=>{E.autocomplete(f,{data:r,minChars:1,onSelect:u=>{f.value=u.value,v.value||(v.value=u.label)}}),f.focus()}),S.addEventListener("click",()=>{const u=f.value.trim(),m=v.value.trim();if(!u)return;N.close();const s=w.checked?`[button href="${u}" variant="${A.value}"]${m||u}[/button]`:`[${m||u}](${u})`,c=a.selectionStart,o=a.selectionEnd;a.value=a.value.substring(0,c)+s+a.value.substring(o),a.selectionStart=a.selectionEnd=c+s.length,a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onImage(async a=>{const r=(await U.media.list().catch(()=>[])).filter(f=>/\.(png|jpe?g|gif|webp|svg)$/i.test(f.name)),d=document.createElement("div");if(d.className="media-picker-grid",r.length)r.forEach(f=>{const p=document.createElement("div");p.className="media-picker-item",p.dataset.url=f.url;const y=document.createElement("img");y.src=f.url,y.alt=f.name;const v=document.createElement("span");v.textContent=f.name,p.appendChild(y),p.appendChild(v),d.appendChild(p)});else{const f=document.createElement("p");f.className="text-muted p-3",f.textContent="No images uploaded yet.",d.appendChild(f)}const C=E.modal({title:"Insert Image",size:"lg"});C.element.appendChild(d),$(C.element).on("click",".media-picker-item",function(){const f=$(this).data("url"),p=$(this).find("span").text();xe(a,`![${p}](${f})`),C.close(),W.get(0).dispatchEvent(new Event("input",{bubbles:!0}))}),C.open()}),j.onCollection(async a=>{const[l,r]=await Promise.all([U.collections.list().catch(()=>[]),U.blocks.list().catch(()=>[])]),d=document.createElement("div");d.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const C="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",f="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",p=document.createElement("div"),y=document.createElement("label");y.style.cssText=C,y.textContent="Collection";const v=document.createElement("select");if(v.style.cssText=f,l.length)l.forEach(e=>{const n=document.createElement("option");n.value=e.slug,n.textContent=e.title||e.slug,v.appendChild(n)});else{const e=document.createElement("option");e.value="",e.textContent="No collections found",v.appendChild(e)}p.appendChild(y),p.appendChild(v),d.appendChild(p);const h=document.createElement("div"),w=document.createElement("label");w.style.cssText=C,w.textContent="Display";const L=document.createElement("select");L.style.cssText=f,["table","cards","list","block"].forEach(e=>{const n=document.createElement("option");n.value=e,n.textContent=e.charAt(0).toUpperCase()+e.slice(1),L.appendChild(n)}),h.appendChild(w),h.appendChild(L),d.appendChild(h);const A=document.createElement("div");A.style.display="none";const k=document.createElement("label");k.style.cssText=C,k.textContent="Columns (2\u20134)";const S=document.createElement("input");S.type="number",S.min="2",S.max="4",S.value="3",S.style.cssText=f,A.appendChild(k),A.appendChild(S),d.appendChild(A);const N=document.createElement("div");N.style.display="none";const u=document.createElement("label");u.style.cssText=C,u.textContent="Block template";const m=document.createElement("select");if(m.style.cssText=f,r.length)r.forEach(e=>{const n=document.createElement("option");n.value=e.name??e,n.textContent=e.name??e,m.appendChild(n)});else{const e=document.createElement("option");e.value="",e.textContent="No block templates found",m.appendChild(e)}N.appendChild(u),N.appendChild(m),d.appendChild(N);const s=document.createElement("div"),c=document.createElement("label");c.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const o=document.createElement("input");o.type="checkbox",o.checked=!0,c.appendChild(o),c.appendChild(document.createTextNode("Enable search")),s.appendChild(c),d.appendChild(s);const x=document.createElement("div"),T=document.createElement("label");T.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const B=document.createElement("input");B.type="checkbox",B.checked=!0,T.appendChild(B),T.appendChild(document.createTextNode("Sortable columns")),x.appendChild(T),d.appendChild(x);const O=document.createElement("div"),re=document.createElement("label");re.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const le=document.createElement("input");le.type="checkbox",le.checked=!1,re.appendChild(le),re.appendChild(document.createTextNode("CSV export")),O.appendChild(re),d.appendChild(O);const ce=document.createElement("div"),pe=document.createElement("label");pe.style.cssText=C,pe.textContent="Rows per page";const ee=document.createElement("input");ee.type="number",ee.min="5",ee.max="100",ee.value="25",ee.style.cssText=f,ce.appendChild(pe),ce.appendChild(ee),d.appendChild(ce);const ye=document.createElement("div"),me=document.createElement("label");me.style.cssText=C,me.textContent="Limit (optional)";const de=document.createElement("input");de.type="number",de.placeholder="All",de.style.cssText=f,ye.appendChild(me),ye.appendChild(de),d.appendChild(ye);const V=document.createElement("button");V.type="button",V.className="btn btn-primary",V.textContent="Insert",d.appendChild(V);const g=[s,x,O,ce],b=()=>{const e=L.value,n=e==="table";g.forEach(Q=>{Q.style.display=n?"":"none"}),A.style.display=e==="cards"||e==="block"?"":"none",N.style.display=e==="block"?"":"none"};L.addEventListener("change",b),b();const t=E.modal({title:"Insert Collection",size:"sm"});t.element.appendChild(d),t.open(),V.addEventListener("click",()=>{const e=v.value;if(!e)return;const n=L.value;let Q=`[collection slug="${e}" display="${n}"`;if(n==="cards"&&(Q+=` columns="${S.value}"`),n==="block"){const ze=m.value;ze&&(Q+=` block="${ze}"`);const Ie=S.value.trim();Ie&&(Q+=` cols="${Ie}"`)}n==="table"&&!o.checked&&(Q+=' search="false"'),n==="table"&&!B.checked&&(Q+=' sortable="false"'),n==="table"&&le.checked&&(Q+=' exportable="true"'),n==="table"&&ee.value!=="25"&&(Q+=` page-size="${ee.value}"`);const Z=de.value.trim();Z&&(Q+=` limit="${Z}"`),Q+=" /]",t.close(),xe(a,Q),a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onBlock(async a=>{let l=[];try{l=await U.blocks.list()}catch{E.toast("Could not load blocks.",{type:"error"});return}if(!l.length){E.toast("No block templates found. Create one in Blocks first.",{type:"warning"});return}const r=E.modal({title:"Insert Block",size:"lg"}),d=document.createElement("div");d.style.cssText="display:flex;gap:1rem;min-height:320px;";const C=document.createElement("div");C.style.cssText="flex:1;display:flex;flex-direction:column;gap:.75rem;";const f=document.createElement("label");f.className="form-label",f.textContent="Block Template";const p=document.createElement("select");p.className="form-select";const y=document.createElement("option");y.value="",y.textContent="\u2014 select a template \u2014",p.appendChild(y),l.forEach(m=>{const s=document.createElement("option");s.value=m.name,s.textContent=m.name,p.appendChild(s)}),C.appendChild(f),C.appendChild(p);const v=document.createElement("div");v.style.cssText="display:flex;flex-direction:column;gap:.5rem;overflow-y:auto;max-height:260px;",C.appendChild(v);const h=document.createElement("button");h.className="btn btn-primary",h.type="button",h.textContent="Insert",h.disabled=!0,C.appendChild(h);const w=document.createElement("div");w.style.cssText="flex:1;border:1px solid var(--dm-border-color);border-radius:var(--dm-radius);padding:.75rem;overflow:auto;background:var(--dm-surface-bg);";const L=document.createElement("p");L.className="text-muted",L.style.cssText="font-size:.8rem;margin:0;",L.textContent="Select a template to see a preview.",w.appendChild(L),d.appendChild(C),d.appendChild(w),r.element.appendChild(d),r.open();let A=null,k=[];function S(m){return m.replace(/_/g," ").replace(/\b\w/g,s=>s.toUpperCase())}function N(){if(!A)return;const m={};k.forEach(({key:c,input:o})=>{m[c]=o.value});const s=A.replace(/\{\{([\w_]+)\}\}/g,(c,o)=>(m[o]??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"));w.innerHTML=DOMPurify.sanitize(s)}function u(m){v.textContent="",k=[];const s=new Set(["_id","_createdAt","_updatedAt"]),c=new Set;for(const[,o]of m.matchAll(/\{\{([\w_]+)\}\}/g))s.has(o)||c.add(o);if(!c.size){const o=document.createElement("p");o.className="text-muted",o.style.cssText="font-size:.8rem;margin:0;",o.textContent="No editable placeholders in this template.",v.appendChild(o);return}c.forEach(o=>{const x=document.createElement("div"),T=document.createElement("label");T.className="form-label",T.style.cssText="font-size:.8rem;margin-bottom:.2rem;display:block;",T.textContent=S(o);const B=document.createElement("input");B.type="text",B.className="form-input",B.placeholder=S(o),B.addEventListener("input",N),x.appendChild(T),x.appendChild(B),v.appendChild(x),k.push({key:o,input:B})})}p.addEventListener("change",async()=>{const m=p.value;if(!m){A=null,k=[],v.textContent="",w.textContent="",w.appendChild(L),h.disabled=!0;return}A=null,k=[],v.textContent="",h.disabled=!0;try{A=(await U.blocks.get(m)).content||"",u(A),N(),h.disabled=!1}catch{E.toast("Could not load template.",{type:"error"})}}),h.addEventListener("click",()=>{if(!p.value)return;const m=o=>o.replace(/"/g,"&quot;");let s=`template="${m(p.value)}"`;k.forEach(({key:o,input:x})=>{x.value!==""&&(s+=` ${o}="${m(x.value)}"`)});const c=`[block ${s} /]`;xe(a,c),a.dispatchEvent(new Event("input",{bubbles:!0})),r.close(),a.focus()})}),j.onForm(async a=>{const l=await U.forms.list().catch(()=>[]),r=document.createElement("div");r.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const d="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",C="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",f=document.createElement("div"),p=document.createElement("label");p.style.cssText=d,p.textContent="Form";const y=document.createElement("select");if(y.style.cssText=C,l.length)l.forEach(w=>{const L=document.createElement("option");L.value=w.slug,L.textContent=w.title||w.slug,y.appendChild(L)});else{const w=document.createElement("option");w.value="",w.textContent="No forms found",y.appendChild(w)}f.appendChild(p),f.appendChild(y),r.appendChild(f);const v=document.createElement("button");v.className="btn btn-primary btn-sm",v.style.cssText="align-self:flex-end;margin-top:.5rem;",v.textContent="Insert Form",r.appendChild(v);const h=E.modal({title:"Insert Form",size:"sm"});h.element.appendChild(r),h.open(),v.addEventListener("click",()=>{const w=y.value;w&&(xe(a,`[form slug="${w}" /]`),h.close(),W.get(0).dispatchEvent(new Event("input",{bubbles:!0})))})}),j.onView(async a=>{const l=await U.views.list().catch(()=>[]),r=document.createElement("div");r.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const d="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",C="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",f=document.createElement("div"),p=document.createElement("label");p.style.cssText=d,p.textContent="View";const y=document.createElement("select");if(y.style.cssText=C,l.length)l.forEach(k=>{const S=document.createElement("option");S.value=k.slug,S.textContent=k.title||k.slug,y.appendChild(S)});else{const k=document.createElement("option");k.value="",k.textContent="No Views configured yet \u2014 create one under Data \u2192 Views",y.appendChild(k)}f.appendChild(p),f.appendChild(y),r.appendChild(f);const v=document.createElement("div"),h=document.createElement("label");h.style.cssText=d,h.textContent="Display";const w=document.createElement("select");w.style.cssText=C,["table","cards","list"].forEach(k=>{const S=document.createElement("option");S.value=k,S.textContent=k.charAt(0).toUpperCase()+k.slice(1),w.appendChild(S)}),v.appendChild(h),v.appendChild(w),r.appendChild(v);const L=document.createElement("button");L.type="button",L.className="btn btn-primary",L.textContent="Insert",r.appendChild(L);const A=E.modal({title:"Insert View",size:"sm"});A.element.appendChild(r),A.open(),L.addEventListener("click",()=>{const k=y.value;if(!k)return;const S=`[view slug="${k}" display="${w.value}" /]`;A.close(),xe(a,S),a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onCta(async a=>{const l=await U.actions.list().catch(()=>[]),r=document.createElement("div");r.style.cssText="padding:1rem;display:flex;flex-direction:column;gap:.75rem;";const d="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",C="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function f(u,m){const s=document.createElement("div"),c=document.createElement("label");return c.style.cssText=d,c.textContent=u,s.appendChild(c),s.appendChild(m),s}function p(u){const m=document.createElement("select");return m.style.cssText=C,u.forEach(([s,c])=>{const o=document.createElement("option");o.value=s,o.textContent=c,m.appendChild(o)}),m}function y(u,m,s){const c=document.createElement("input");return c.type=u,c.placeholder=m||"",c.value=s||"",c.style.cssText=C,c}const v=p(l.length?l.map(u=>[u.slug,u.title||u.slug]):[["","No Actions configured yet \u2014 create one under Data \u2192 Actions"]]);r.appendChild(f("Action",v));const h=y("text","Button label","Run");if(r.appendChild(f("Label",h)),v.addEventListener("change",()=>{const u=l.find(m=>m.slug===v.value);u?.trigger?.label&&(h.value=u.trigger.label)}),l.length){const u=l[0];u?.trigger?.label&&(h.value=u.trigger.label)}const w=y("text","Paste entry UUID\u2026","");r.appendChild(f("Entry ID",w));const L=p([["primary","Primary"],["secondary","Secondary"],["ghost","Ghost"],["danger","Danger"]]);r.appendChild(f("Style",L));const A=y("text","e.g. check, zap, send (optional)","");r.appendChild(f("Icon",A));const k=y("text","Confirmation message (optional)","");r.appendChild(f("Confirm prompt",k));const S=document.createElement("button");S.type="button",S.className="btn btn-primary",S.textContent="Insert",r.appendChild(S);const N=E.modal({title:"Insert CTA Button",size:"sm"});N.element.appendChild(r),N.open(),S.addEventListener("click",()=>{const u=v.value;if(!u)return;const m=w.value.trim(),s=(h.value.trim()||"Run").replace(/\[\/cta\]/gi,""),c=L.value,o=A.value.trim().replace(/"/g,""),x=k.value.trim().replace(/"/g,""),T=m.replace(/"/g,"");let B=`action="${u}" style="${c}"`;T&&(B+=` entry="${T}"`),o&&(B+=` icon="${o}"`),x&&(B+=` confirm="${x}"`);const O=`[cta ${B}]${s}[/cta]`;N.close(),xe(a,O),a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onButton(async a=>{const r=(await U.pages.list().catch(()=>[])).map(o=>({label:o.title||o.urlPath,value:o.urlPath})),d=document.createElement("div");d.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const C="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",f="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function p(o,x){const T=document.createElement("div"),B=document.createElement("label");return B.style.cssText=C,B.textContent=o,T.appendChild(B),T.appendChild(x),T}function y(o,x){const T=document.createElement("input");return T.type="text",T.placeholder=o,T.value=x||"",T.style.cssText=f,T}function v(o){const x=document.createElement("select");return x.style.cssText=f,o.forEach(([T,B])=>{const O=document.createElement("option");O.value=T,O.textContent=B,x.appendChild(O)}),x}const h=a.value.substring(a.selectionStart,a.selectionEnd),w=y("/about or https://example.com",h.startsWith("/")?h:"");d.appendChild(p("URL",w));const L=y("Button label",h&&!h.startsWith("/")?h:"");d.appendChild(p("Label",L));const A=v([["primary","Primary"],["secondary","Secondary"],["success","Success (Green)"],["danger","Danger (Red)"],["warning","Warning (Orange)"],["info","Info (Blue)"],["outline","Outline"],["ghost","Ghost"],["link","Link"],["outline-success","Outline Success"],["outline-danger","Outline Danger"]]);d.appendChild(p("Variant",A));const k=v([["","Default"],["sm","Small"],["lg","Large"]]);d.appendChild(p("Size",k));const S=y("e.g. arrow-right, star (optional)","");d.appendChild(p("Icon (before label)",S));const N=y("e.g. arrow-right (optional)","");d.appendChild(p("Icon (after label)",N));const u=document.createElement("label");u.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const m=document.createElement("input");m.type="checkbox",m.style.cssText="width:1rem;height:1rem;",u.appendChild(m),u.appendChild(document.createTextNode("Open in new tab")),d.appendChild(u);const s=document.createElement("button");s.type="button",s.className="btn btn-primary",s.textContent="Insert Button",d.appendChild(s);const c=E.modal({title:"Insert Button",size:"sm"});c.element.appendChild(d),c.open(),requestAnimationFrame(()=>{E.autocomplete(w,{data:r,minChars:1,onSelect:o=>{w.value=o.value,L.value||(L.value=o.label)}}),w.focus()}),s.addEventListener("click",()=>{const o=w.value.trim();if(!o)return;c.close();const x=L.value.trim()||o;let T=`href="${o}" variant="${A.value}"`;k.value&&(T+=` size="${k.value}"`);const B=S.value.trim().replace(/"/g,"");B&&(T+=` icon="${B}"`);const O=N.value.trim().replace(/"/g,"");O&&(T+=` icon-after="${O}"`),m.checked&&(T+=' target="_blank"');const re=`[button ${T}]${x}[/button]`;xe(a,re)})}),j.onLinkShortcode(async a=>{const r=(await U.pages.list().catch(()=>[])).map(s=>({label:s.title||s.urlPath,value:s.urlPath})),d=document.createElement("div");d.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const C="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",f="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function p(s,c){const o=document.createElement("div"),x=document.createElement("label");return x.style.cssText=C,x.textContent=s,o.appendChild(x),o.appendChild(c),o}function y(s,c){const o=document.createElement("input");return o.type="text",o.placeholder=s,o.value=c||"",o.style.cssText=f,o}const v=a.value.substring(a.selectionStart,a.selectionEnd),h=y("/about or https://example.com",v.startsWith("/")?v:"");d.appendChild(p("URL",h));const w=y("Link text",v&&!v.startsWith("/")?v:"");d.appendChild(p("Link text",w));const L=y("e.g. text-primary, fw-bold (optional)","");d.appendChild(p("CSS class",L));const A=y("e.g. arrow-right (optional)","");d.appendChild(p("Icon (before text)",A));const k=y("e.g. external-link (optional)","");d.appendChild(p("Icon (after text)",k));const S=document.createElement("label");S.style.cssText="display:flex;align-items:center;gap:.5rem;cursor:pointer;font-size:.9em;";const N=document.createElement("input");N.type="checkbox",N.style.cssText="width:1rem;height:1rem;",S.appendChild(N),S.appendChild(document.createTextNode("Open in new tab")),d.appendChild(S);const u=document.createElement("button");u.type="button",u.className="btn btn-primary",u.textContent="Insert Link",d.appendChild(u);const m=E.modal({title:"Insert Link Shortcode",size:"sm"});m.element.appendChild(d),m.open(),requestAnimationFrame(()=>{E.autocomplete(h,{data:r,minChars:1,onSelect:s=>{h.value=s.value,w.value||(w.value=s.label)}}),h.focus()}),u.addEventListener("click",()=>{const s=h.value.trim();if(!s)return;m.close();const c=w.value.trim()||s;let o=`href="${s}"`;const x=L.value.trim().replace(/"/g,"");x&&(o+=` class="${x}"`);const T=A.value.trim().replace(/"/g,"");T&&(o+=` icon="${T}"`);const B=k.value.trim().replace(/"/g,"");B&&(o+=` icon-after="${B}"`),N.checked&&(o+=' target="_blank"');const O=`[link ${o}]${c}[/link]`;xe(a,O)})}),j.onTabs(a=>{const l=document.createElement("div");l.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const r="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",d="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function C(u,m){const s=document.createElement("div"),c=document.createElement("label");return c.style.cssText=r,c.textContent=u,s.appendChild(c),s.appendChild(m),s}function f(u){const m=document.createElement("select");return m.style.cssText=d,u.forEach(([s,c])=>{const o=document.createElement("option");o.value=s,o.textContent=c,m.appendChild(o)}),m}const p=f([["","Default (underline)"],["pills","Pills"]]);l.appendChild(C("Style",p));const y=f([["","Left"],["center","Centre"]]);l.appendChild(C("Alignment",y));const v=document.createElement("div");v.style.cssText="display:flex;flex-direction:column;gap:.4rem;";const h=[];function w(){h.forEach(u=>{u.removeBtn.disabled=h.length<=2,u.removeBtn.style.opacity=h.length<=2?"0.3":"1"})}function L(u){const m=document.createElement("div");m.style.cssText="display:flex;gap:.4rem;align-items:center;";const s=document.createElement("input");s.type="text",s.placeholder="Tab title",s.value=u||"",s.style.cssText=d+"flex:1;";const c=document.createElement("button");c.type="button",c.textContent="\u2715",c.style.cssText="padding:.3rem .5rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;flex-shrink:0;";const o={row:m,input:s,removeBtn:c};h.push(o),m.appendChild(s),m.appendChild(c),v.appendChild(m),c.addEventListener("click",()=>{if(h.length<=2)return;const x=h.indexOf(o);h.splice(x,1),v.removeChild(m),w()}),w()}L("Overview"),L("Details");const A=document.createElement("div");A.style.cssText=r,A.textContent="Tabs",l.appendChild(A),l.appendChild(v);const k=document.createElement("button");k.type="button",k.textContent="+ Add Tab",k.style.cssText="padding:.35rem .75rem;background:transparent;border:1px dashed var(--dm-border,#555);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;align-self:flex-start;",k.addEventListener("click",()=>{h.length>=10||(L(""),h[h.length-1].input.focus())}),l.appendChild(k);const S=document.createElement("button");S.type="button",S.className="btn btn-primary",S.textContent="Insert Tabs",l.appendChild(S);const N=E.modal({title:"Insert Tabs",size:"sm"});N.element.appendChild(l),N.open(),requestAnimationFrame(()=>h[0].input.focus()),S.addEventListener("click",()=>{N.close();const u=p.value,m=y.value;let s=u?` style="${u}"`:"";m&&(s+=` align="${m}"`);let c=`[tabs${s}]
83
+ `;h.forEach((o,x)=>{const T=o.input.value.trim()||`Tab ${x+1}`;c+=`[tab title="${T}"]Tab content here.[/tab]
84
+ `}),c+="[/tabs]",xe(a,c),a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onAccordion(async a=>{const l=await U.collections.list().catch(()=>[]),r=document.createElement("div");r.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const d="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",C="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;",f=document.createElement("div");f.style.cssText="display:flex;gap:.5rem;";const p=document.createElement("button");p.type="button",p.className="btn btn-sm btn-primary",p.textContent="Static";const y=document.createElement("button");y.type="button",y.className="btn btn-sm btn-ghost",y.textContent="Collection",f.appendChild(p),f.appendChild(y),r.appendChild(f);let v="static";const h=document.createElement("div");h.style.cssText="display:flex;flex-direction:column;gap:.5rem;";const w=[];function L(V){const g=document.createElement("div");g.style.cssText="display:flex;align-items:center;gap:.5rem;";const b=document.createElement("label");b.style.cssText="font-size:.85em;color:var(--dm-text-muted,#aaa);white-space:nowrap;",b.textContent=`Item ${V}`;const t=document.createElement("input");return t.type="text",t.placeholder="Item title",t.style.cssText=C,g.appendChild(b),g.appendChild(t),{row:g,input:t}}[1,2].forEach(V=>{const g=L(V);w.push(g),h.appendChild(g.row)});const A=document.createElement("button");A.type="button",A.className="btn btn-ghost btn-sm",A.textContent="+ Add Item",A.addEventListener("click",()=>{const V=L(w.length+1);w.push(V),h.insertBefore(V.row,A)}),h.appendChild(A);const k=document.createElement("label");k.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const S=document.createElement("input");S.type="checkbox",k.appendChild(S),k.appendChild(document.createTextNode("Allow multiple open")),h.appendChild(k),r.appendChild(h);const N=document.createElement("div");N.style.cssText="display:none;flex-direction:column;gap:.5rem;";const u=document.createElement("div"),m=document.createElement("label");m.style.cssText=d,m.textContent="Collection";const s=document.createElement("select");if(s.style.cssText=C,l.length)l.forEach(V=>{const g=document.createElement("option");g.value=V.slug,g.textContent=V.title||V.slug,s.appendChild(g)});else{const V=document.createElement("option");V.value="",V.textContent="No collections found",s.appendChild(V)}u.appendChild(m),u.appendChild(s),N.appendChild(u);const c=document.createElement("div"),o=document.createElement("label");o.style.cssText=d,o.textContent="Title field";const x=document.createElement("select");x.style.cssText=C,c.appendChild(o),c.appendChild(x),N.appendChild(c);const T=document.createElement("div"),B=document.createElement("label");B.style.cssText=d,B.textContent="Body field";const O=document.createElement("select");O.style.cssText=C,T.appendChild(B),T.appendChild(O),N.appendChild(T);async function re(V){x.textContent="",O.textContent="";try{const b=(await U.collections.get(V)).fields||[];if(!b.length){const t=document.createElement("option");t.value="",t.textContent="\u2014 none \u2014",x.appendChild(t.cloneNode(!0)),O.appendChild(t);return}b.forEach((t,e)=>{const n=()=>{const Q=document.createElement("option");return Q.value=t.name,Q.textContent=t.label||t.name,Q};x.appendChild(n()),O.appendChild(n()),t.name==="title"&&(x.value="title"),t.name==="description"&&(O.value="description")}),!x.value&&b[0]&&(x.value=b[0].name),!O.value&&b[1]&&(O.value=b[1].name)}catch{const g=document.createElement("option");g.value="",g.textContent="\u2014 unknown \u2014",x.appendChild(g.cloneNode(!0)),O.appendChild(g)}}l.length&&re(l[0].slug),s.addEventListener("change",()=>re(s.value));const le=document.createElement("div"),ce=document.createElement("label");ce.style.cssText=d,ce.textContent="Limit (optional)";const pe=document.createElement("input");pe.type="number",pe.placeholder="All",pe.style.cssText=C,le.appendChild(ce),le.appendChild(pe),N.appendChild(le);const ee=document.createElement("label");ee.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const ye=document.createElement("input");ye.type="checkbox",ee.appendChild(ye),ee.appendChild(document.createTextNode("Allow multiple open")),N.appendChild(ee),r.appendChild(N),p.addEventListener("click",()=>{v="static",p.className="btn btn-sm btn-primary",y.className="btn btn-sm btn-ghost",h.style.display="flex",N.style.display="none"}),y.addEventListener("click",()=>{v="collection",y.className="btn btn-sm btn-primary",p.className="btn btn-sm btn-ghost",N.style.display="flex",h.style.display="none"});const me=document.createElement("button");me.type="button",me.className="btn btn-primary",me.textContent="Insert Accordion",r.appendChild(me);const de=E.modal({title:"Insert Accordion",size:"sm"});de.element.appendChild(r),de.open(),requestAnimationFrame(()=>w[0].input.focus()),me.addEventListener("click",()=>{if(v==="collection"&&!s.value)return;de.close();let V;if(v==="static")V=`[accordion${S.checked?' multiple="true"':""}]
85
+ `,w.forEach((b,t)=>{const e=b.input.value.trim()||`Item ${t+1}`;V+=`[item title="${e}"]Content here.[/item]
86
+ `}),V+="[/accordion]";else{const g=s.value;if(!g)return;const b=x.value,t=O.value;let e=`slug="${g}" display="accordion"`;b&&(e+=` title-field="${b}"`),t&&(e+=` body-field="${t}"`);const n=pe.value.trim();n&&(e+=` limit="${n}"`),ye.checked&&(e+=' multiple="true"'),V=`[collection ${e} /]`}xe(a,V),a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onListGroup(a=>{const l=document.createElement("div");l.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const r="display:block;font-size:.85em;font-weight:600;margin-bottom:.25rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",d="width:100%;padding:.4rem .6rem;background:var(--dm-input-bg,#1a1a1a);border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text,#eee);font-size:.9em;";function C(c,o){const x=document.createElement("div"),T=document.createElement("label");return T.style.cssText=r,T.textContent=c,x.appendChild(T),x.appendChild(o),x}function f(c){const o=document.createElement("select");return o.style.cssText=d,c.forEach(([x,T])=>{const B=document.createElement("option");B.value=x,B.textContent=T,o.appendChild(B)}),o}const p=f([["","Default"],["flush","Flush (no outer border)"],["numbered","Numbered"],["horizontal","Horizontal"]]);l.appendChild(C("Variant",p));const y=f([["","Default"],["sm","Small"],["lg","Large"]]);l.appendChild(C("Size",y));const v=f([["","Default"],["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]);l.appendChild(C("Item Colour",v));const h=document.createElement("label");h.style.cssText="display:flex;align-items:center;gap:.5rem;font-size:.9em;cursor:pointer;";const w=document.createElement("input");w.type="checkbox",h.appendChild(w),h.appendChild(document.createTextNode("Actionable items (hover highlight)")),l.appendChild(h);const L=document.createElement("div");L.style.cssText=r+"margin-bottom:.35rem;",L.textContent="Items",l.appendChild(L);const A=document.createElement("div");A.style.cssText="display:flex;flex-direction:column;gap:.4rem;",l.appendChild(A);const k=[];function S(){k.forEach(c=>{c.removeBtn.disabled=k.length<=1,c.removeBtn.style.opacity=k.length<=1?"0.3":"1"})}function N(c){const o=document.createElement("div");o.style.cssText="display:flex;gap:.4rem;align-items:center;";const x=document.createElement("input");x.type="text",x.placeholder="Item text",x.value=c||"",x.style.cssText=d+"flex:1;";const T=document.createElement("button");T.type="button",T.textContent="\u2715",T.style.cssText="padding:.3rem .5rem;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;flex-shrink:0;";const B={row:o,input:x,removeBtn:T};k.push(B),o.appendChild(x),o.appendChild(T),A.appendChild(o),T.addEventListener("click",()=>{if(k.length<=1)return;const O=k.indexOf(B);k.splice(O,1),A.removeChild(o),S()}),S()}N("Item 1"),N("Item 2"),N("Item 3");const u=document.createElement("button");u.type="button",u.textContent="+ Add Item",u.style.cssText="padding:.35rem .75rem;background:transparent;border:1px dashed var(--dm-border,#555);border-radius:4px;color:var(--dm-text-muted,#aaa);cursor:pointer;font-size:.85em;align-self:flex-start;",u.addEventListener("click",()=>{k.length>=20||(N(""),k[k.length-1].input.focus())}),l.appendChild(u);const m=document.createElement("button");m.type="button",m.className="btn btn-primary",m.textContent="Insert List Group",l.appendChild(m);const s=E.modal({title:"Insert List Group",size:"sm"});s.element.appendChild(l),s.open(),requestAnimationFrame(()=>k[0].input.focus()),m.addEventListener("click",()=>{s.close();let c="";p.value&&(c+=` variant="${p.value}"`),y.value&&(c+=` size="${y.value}"`),v.value&&(c+=` itemvariant="${v.value}"`),w.checked&&(c+=' action="true"');let o=`[listgroup${c}]
87
+ `;k.forEach(x=>{const T=x.input.value.trim();T&&(o+=`[item]${T}[/item]
88
+ `)}),o+="[/listgroup]",xe(a,o),a.dispatchEvent(new Event("input",{bubbles:!0})),a.focus()})}),j.onHelp(()=>{Fe()}),i.find(".editor-view-btn").on("click",function(){const a=$(this).data("mode");a&&(i.find(".editor-view-btn").removeClass("active"),$(this).addClass("active"),i.find("#editor-body").removeClass("editor-mode-split editor-mode-write editor-mode-preview").addClass(`editor-mode-${a}`))}),i.find("#fullscreen-btn").on("click",function(){i.find(".editor-card").toggleClass("editor-fullscreen")}),we=!1,i.find("#quick-switch").prop("disabled",!1),Ne&&window.removeEventListener("beforeunload",Ne),Ne=a=>{we&&a.preventDefault()},window.addEventListener("beforeunload",Ne),Be||(Be=!0,R.use((a,l,r)=>{const d=window.location.hash.startsWith("#/pages/edit")||window.location.hash==="#/pages/new";if(!we||!d)return r();E.confirm("You have unsaved changes. Leave this page?").then(C=>{C&&(we=!1,r())})})),W.on("input",()=>{we=!0,i.find("#quick-switch").prop("disabled",!0),ne()});const se=i.find("#editor-meta-tabs").get(0);se&&(se.addEventListener("input",()=>{we=!0,i.find("#quick-switch").prop("disabled",!0)}),se.addEventListener("change",a=>{a.target.id!=="quick-switch"&&(we=!0,i.find("#quick-switch").prop("disabled",!0))})),ne(),i.find("#save-btn").on("click",async()=>{const a=i.find("#page-url-path").val().trim();if(!a){E.toast("URL path is required.",{type:"warning"});return}const l=i.find("#field-dconfig").val().trim();let r=null;if(l)try{r=JSON.parse(l)}catch{E.toast("DConfig JSON is invalid. Please check the format before saving.",{type:"warning"});return}const d={title:i.find("#field-title").val().trim()||"Untitled",description:i.find("#field-description").val().trim(),layout:i.find("#field-layout").val(),status:i.find("#field-status").val(),sortOrder:parseInt(i.find("#field-sort-order").val(),10)||99,showInNav:i.find("#field-show-in-nav").is(":checked"),sidebar:i.find("#field-sidebar").is(":checked"),...i.find("#field-show-breadcrumbs").is(":checked")?{}:{breadcrumbs:!1},tags:Te?Te.getValue():[],category:i.find("#field-category").val().trim()||null,visibility:i.find("#field-visibility").val()||"public",seo:{title:i.find("#field-seo-title").val().trim(),description:i.find("#field-seo-desc").val().trim()},dconfig:r,...i.find("#field-theme").val()?{theme:i.find("#field-theme").val()}:{}};try{if(i.find("#save-btn").prop("disabled",!0).text("Saving\u2026"),F){const C={frontmatter:d,body:W.val()};a!==P&&(C.newUrlPath=a),await U.pages.update(P,C),K&&await U.settings.saveCustomCss(i.find("#css-editor").val()),E.toast(K?"Page and CSS saved.":"Page saved successfully.",{type:"success"}),we=!1,i.find("#quick-switch").prop("disabled",!1),a!==P&&R.navigate(`/pages/edit${a}`)}else await U.pages.create({urlPath:a,frontmatter:d,body:W.val()}),K&&await U.settings.saveCustomCss(i.find("#css-editor").val()),E.toast(K?"Page and CSS saved.":"Page saved successfully.",{type:"success"}),we=!1,R.navigate("/pages")}catch(C){E.toast(`Save failed: ${C.message||"Unknown error"}`,{type:"error"})}finally{i.find("#save-btn").prop("disabled",!1).text("Save")}}),i.find("#cancel-btn").on("click",()=>R.navigate("/pages")),Domma.icons.scan()}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.6.22",
3
+ "version": "0.7.1",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "/": 161,
3
- "/about": 78,
3
+ "/about": 88,
4
4
  "/blog": 36,
5
5
  "/contact": 30,
6
6
  "/resources/typography": 4,
@@ -11,7 +11,7 @@
11
11
  "/resources/grid": 6,
12
12
  "/forms": 14,
13
13
  "/resources/effects": 6,
14
- "/blog/hello-world": 20,
14
+ "/blog/hello-world": 23,
15
15
  "/feedback": 42,
16
16
  "/resources/dependencies": 2,
17
17
  "/resources/components": 6,
@@ -8,7 +8,14 @@
8
8
  *
9
9
  * Action-first route prefixes avoid wildcard conflicts with Fastify's /* pattern.
10
10
  */
11
- import {listVersions, getVersion, createVersion, deleteVersion, restoreVersion} from '../../services/versions.js';
11
+ import {
12
+ createVersion,
13
+ deleteVersion,
14
+ deleteVersions,
15
+ getVersion,
16
+ listVersions,
17
+ restoreVersion
18
+ } from '../../services/versions.js';
12
19
  import {authenticate, requirePermission} from '../../middleware/auth.js';
13
20
 
14
21
  export async function versionsRoutes(fastify) {
@@ -74,4 +81,19 @@ export async function versionsRoutes(fastify) {
74
81
  return reply.status(400).send({error: err.message});
75
82
  }
76
83
  });
84
+
85
+ // Bulk delete versions (POST used as DELETE with body is poorly supported)
86
+ fastify.post('/versions/bulk-delete/*', canDelete, async (request, reply) => {
87
+ const urlPath = '/' + request.params['*'];
88
+ const {filenames} = request.body || {};
89
+ if (!Array.isArray(filenames) || !filenames.length) {
90
+ return reply.status(400).send({error: 'filenames array required'});
91
+ }
92
+ try {
93
+ await deleteVersions(urlPath, filenames);
94
+ return {success: true, deleted: filenames.length};
95
+ } catch (err) {
96
+ return reply.status(400).send({error: err.message});
97
+ }
98
+ });
77
99
  }
@@ -130,7 +130,9 @@ async function processStaticBlocks(content) {
130
130
  const rendered = tmpl.replace(/\{\{([\w_]+)\}\}/g, (_, key) => {
131
131
  return escapeHtmlText(attrs[key] ?? '');
132
132
  });
133
- replacement = `<div class="dm-static-block">${rendered}</div>`;
133
+ const extraClass = attrs.class ? ` ${escapeAttr(attrs.class)}` : '';
134
+ const idAttr = attrs.id ? ` id="${escapeAttr(attrs.id)}"` : '';
135
+ replacement = `<div class="dm-static-block${extraClass}"${idAttr}>${rendered}</div>`;
134
136
  } catch (_) {
135
137
  // Template not found — emit nothing
136
138
  }
@@ -340,6 +342,12 @@ async function processViewBlocks(markdown) {
340
342
  // View not found, MongoDB not configured, or pipeline error — show empty state
341
343
  }
342
344
 
345
+ if (attrs.class || attrs.id) {
346
+ const cls = attrs.class ? ` ${escapeAttr(attrs.class)}` : '';
347
+ const id = attrs.id ? ` id="${escapeAttr(attrs.id)}"` : '';
348
+ replacement = `<div class="dm-view-wrapper${cls}"${id}>${replacement}</div>`;
349
+ }
350
+
343
351
  result = result.replace(fullMatch, replacement);
344
352
  }
345
353
 
@@ -435,6 +443,12 @@ async function processCollectionBlocks(markdown) {
435
443
  // Collection not found or read error — show empty message
436
444
  }
437
445
 
446
+ if (attrs.class || attrs.id) {
447
+ const cls = attrs.class ? ` ${escapeAttr(attrs.class)}` : '';
448
+ const id = attrs.id ? ` id="${escapeAttr(attrs.id)}"` : '';
449
+ replacement = `<div class="dm-collection-wrapper${cls}"${id}>${replacement}</div>`;
450
+ }
451
+
438
452
  result = result.replace(fullMatch, replacement);
439
453
  }
440
454
 
@@ -1347,6 +1361,63 @@ function processTableBlocks(markdown) {
1347
1361
  * @param {string} markdown
1348
1362
  * @returns {string}
1349
1363
  */
1364
+ /**
1365
+ * Pre-process [listgroup] / [item] shortcodes before running through marked.
1366
+ *
1367
+ * Syntax:
1368
+ * [listgroup variant="flush" size="sm" itemvariant="success" action="true"]
1369
+ * [item]Item text here[/item]
1370
+ * [item]Another item[/item]
1371
+ * [/listgroup]
1372
+ *
1373
+ * Supported attributes on [listgroup]:
1374
+ * variant - flush | numbered | horizontal
1375
+ * size - sm | lg
1376
+ * itemvariant - primary | secondary | success | danger | warning | info
1377
+ * action - "true" to add .list-group-item-action on each item
1378
+ *
1379
+ * @param {string} markdown
1380
+ * @returns {string}
1381
+ */
1382
+ function processListGroupBlocks(markdown) {
1383
+ const {scrubbed, restore} = scrubCodeRegions(markdown);
1384
+ const processed = scrubbed.replace(
1385
+ /\[listgroup([^\]]*)\]([\s\S]*?)\[\/listgroup\]/gi,
1386
+ (_, attrStr, body) => {
1387
+ const attrs = parseShortcodeAttrs(attrStr);
1388
+
1389
+ const variantMap = {
1390
+ flush: 'list-group-flush',
1391
+ numbered: 'list-group-numbered',
1392
+ horizontal: 'list-group-horizontal'
1393
+ };
1394
+ const sizeMap = {sm: 'list-group-sm', lg: 'list-group-lg'};
1395
+
1396
+ const wrapperClasses = ['list-group'];
1397
+ if (variantMap[attrs.variant]) wrapperClasses.push(variantMap[attrs.variant]);
1398
+ if (sizeMap[attrs.size]) wrapperClasses.push(sizeMap[attrs.size]);
1399
+
1400
+ const itemClasses = ['list-group-item'];
1401
+ if (attrs.action === 'true') itemClasses.push('list-group-item-action');
1402
+ if (attrs.itemvariant && /^(primary|secondary|success|danger|warning|info)$/.test(attrs.itemvariant)) {
1403
+ itemClasses.push(`list-group-item-${attrs.itemvariant}`);
1404
+ }
1405
+
1406
+ const itemClassStr = itemClasses.join(' ');
1407
+ let items = '';
1408
+ body.replace(/\[item\]([\s\S]*?)\[\/item\]/gi, (__, content) => {
1409
+ const html = marked.parseInline(restore(content.trim()));
1410
+ items += `<div class="${itemClassStr}">${html}</div>\n`;
1411
+ });
1412
+
1413
+ if (!items) return '';
1414
+
1415
+ return `<div class="${wrapperClasses.join(' ')}">\n${items}</div>\n`;
1416
+ }
1417
+ );
1418
+ return restore(processed);
1419
+ }
1420
+
1350
1421
  function processSpacerBlocks(markdown) {
1351
1422
  const {scrubbed, restore} = scrubCodeRegions(markdown);
1352
1423
  const opts = getConfig('site')?.layoutOptions ?? {};
@@ -1683,7 +1754,8 @@ export async function parseMarkdown(raw) {
1683
1754
  const withCarousel = processCarouselBlocks(withAccordion);
1684
1755
  const withCountdown = processCountdownBlocks(withCarousel);
1685
1756
  const withTimeline = processTimelineBlocks(withCountdown);
1686
- const withSpacer = processSpacerBlocks(withTimeline);
1757
+ const withListGroup = processListGroupBlocks(withTimeline);
1758
+ const withSpacer = processSpacerBlocks(withListGroup);
1687
1759
  const withCenter = processCenterBlocks(withSpacer);
1688
1760
  const withIcon = processIconBlocks(withCenter);
1689
1761
  const withForm = await processFormBlocks(withIcon);
@@ -241,6 +241,22 @@ export async function renameVersionDir(oldUrlPath, newUrlPath) {
241
241
  await fs.rename(oldDir, newDir);
242
242
  }
243
243
 
244
+ /**
245
+ * Delete multiple versions for a page in a single meta read/write cycle.
246
+ *
247
+ * @param {string} urlPath
248
+ * @param {string[]} filenames
249
+ * @returns {Promise<void>}
250
+ */
251
+ export async function deleteVersions(urlPath, filenames) {
252
+ for (const f of filenames) validateFilename(f);
253
+ const dir = versionsDirForPath(urlPath);
254
+ await Promise.all(filenames.map(f => fs.unlink(path.join(dir, f)).catch(() => {
255
+ })));
256
+ const meta = await readMeta(dir);
257
+ await writeMeta(dir, meta.filter(m => !filenames.includes(m.filename)));
258
+ }
259
+
244
260
  /**
245
261
  * Delete all versions for a page (called when the page itself is deleted).
246
262
  *