domma-cms 1.10.24 → 1.10.26

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.10.26] - 2026-10-26
4
+
5
+ - **Pages with a carousel, tabs, accordion, grid or timeline made in the insert form are cached again.** The form wrote `expire-scope="ip"` on every slide, tab, item, column and event, which marked the page as expiring: it skipped the response cache, set a cookie and wrote the expiry ledger on every view. `expire-scope` and `expiry-id` on their own are no longer an expiry (they only say how a rule counts) and are taken off the tag, so pages already carrying them are fixed without editing.
6
+ - **The insert form's slide, tab and item rows have room again.** The seven expiry fields sat in each row and squeezed the title and content to nothing; they now fold under the row as Expiry, with the proper controls.
7
+ - **The slideover and countdown fields show Domma's description too**, and a slideover can be extra large or full width, or come from the bottom or top.
8
+
9
+ ## [1.10.25] - 2026-10-25
10
+
11
+ - **Built against domma-js 0.60.0** - see [its release notes](https://github.com/pinpointzero73/domma/releases/tag/v0.60.0).
12
+ - **Shortcode settings built on Domma say what Domma does with them.** The carousel, accordion and timeline fields in the insert/edit form show Domma's own description of the option each becomes (and the right-click menu shows it on hover), read from domma-js's type catalogue. `tests/admin/shortcode-types.test.js` checks every such link against the catalogue and against the code that builds the component on the page - a misnamed option, a field of the wrong kind or a select offering a value Domma does not take fails the build.
13
+ - **A carousel's Loop box can turn looping off.** Carousels loop unless told not to, but the box started unticked and unticking it wrote nothing, so they always looped; it now starts ticked and unticking writes `loop="false"`. A collection or view shown as a carousel also offers the animation duration and easing and the image height settings it already accepted.
14
+
3
15
  ## [1.10.24] - 2026-10-25
4
16
 
5
17
  - **Built against domma-js 0.59.0** - see [its release notes](https://github.com/pinpointzero73/domma/releases/tag/v0.59.0).
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Tools CSS v0.59.0
2
+ * Domma Tools CSS v0.60.0
3
3
  * Dynamic Object Manipulation & Modeling API
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-10-25T20:05:20.812Z
6
- * Commit: f4f2adb
5
+ * Built: 2026-10-25T21:24:50.836Z
6
+ * Commit: 8d8be57
7
7
  */
8
8
 
9
9
  /*!
@@ -1,9 +1,9 @@
1
1
  /*!
2
- * Domma Tools v0.59.0
2
+ * Domma Tools v0.60.0
3
3
  * Developer tools: Theme Roller & Page Roller
4
4
  * (c) 2026 Darryl Waterhouse & DCBW-IT
5
- * Built: 2026-10-25T20:05:02.320Z
6
- * Commit: f4f2adb
5
+ * Built: 2026-10-25T21:24:36.394Z
6
+ * Commit: 8d8be57
7
7
  *
8
8
  * Requires: domma.min.js
9
9
  */
@@ -0,0 +1 @@
1
+ let n=null,p=!1;const i=new Set;export function setCatalogue(t){if(n=t?.types?t:null,p=!0,n)for(const o of i)o(n);i.clear()}export const catalogueNow=()=>n;export function whenCatalogue(t){n?t(n):p||i.add(t)}export function dommaOption(t,o){if(!t||typeof o!="string")return null;const[e,l]=o.split("."),r=t.elements?.[e];return r&&t.types?.[r]?.[l]||null}export function dommaHelp(t,o){const e=dommaOption(t,o?.domma);if(!e?.doc)return"";const[l,r]=o.domma.split(".");return`${e.doc} (Domma ${l} \u203A ${r})`}
@@ -1,3 +1,3 @@
1
- import{SHORTCODES as M}from"./shortcode-registry.js";import{EFFECTS as L,CELEBRATION_THEMES as J,getEffectAttrs as D}from"./effect-defs.js";import{boolState as Q,boolValue as Z,findEnclosingShortcode as ee,setAttr as N,setAttrs as W,effectAttrKeys as te}from"./shortcode-tags.js";import{insertAtCursor as R,replaceRange as ne}from"./markdown-toolbar.js";import{clearLookupCache as oe,lookupOptions as se}from"./shortcode-lookups.js";import{insertMenuGroups as ie,insertShortcodeByName as ae}from"./shortcode-insert.js";import{openShortcodeForm as A}from"./shortcode-form.js";import{pickMedia as ce}from"./media-picker.js";import{blockTagSnippet as le}from"./block-tags.js";function re(e){return se(e,l?.span?.attrs||{})}const de=M.map(e=>({name:e.name,selfClosing:!!e.selfClosing})),j=new Map(M.map(e=>[e.name,e])),z=new Map(L.map(e=>[e.name,e])),pe=L.map(e=>({name:e.name,selfClosing:!!e.selfClosing})),ue=[...de,...pe],F=new Set(["card","box","hero","banner","col","button"]);let l=null;const Y="position:fixed;z-index:10000;min-width:210px;max-height:70vh;overflow-y:auto;background:var(--dm-surface,#1c1c30);border:1px solid var(--dm-border,#2a2a40);border-radius:6px;box-shadow:var(--dm-shadow-lg);padding:.3rem;font-size:.83rem;color:var(--dm-text,#e5e5e5);",m="display:flex;align-items:center;gap:.5rem;width:100%;text-align:left;padding:.35rem .55rem;border:none;background:transparent;color:inherit;border-radius:4px;cursor:pointer;font-size:.83rem;",T="padding:.3rem .55rem;color:var(--dm-text-muted,#8a8a9a);font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;",P="flex:1;min-width:0;padding:.2rem .4rem;background:var(--dm-input-bg,#12121e);border:1px solid var(--dm-border,#333);border-radius:3px;color:var(--dm-text,#eee);font-size:.8rem;",me="height:1px;background:var(--dm-border,#2a2a40);margin:.3rem .2rem;";function h(e){return e.addEventListener("mouseenter",()=>{e.style.background="var(--dm-primary,#4338ca)",e.style.color="var(--dm-primary-text,#fff)"}),e.addEventListener("mouseleave",()=>{e.style.background="transparent",e.style.color="inherit"}),e}export function attachContextMenu(e,{blocks:t=()=>[],openBlock:n=null}={}){const o=()=>{const i=t()||[],s=i.filter(c=>c.shortTag&&!j.has(c.name)&&!z.has(c.name));return{defs:i,specs:[...ue,...s.map(c=>({name:c.name,selfClosing:!0}))]}},a=(i,s)=>{p();const{defs:c,specs:r}=o();V(e,ee(e,r),i,s,c,n)};return typeof Domma>"u"||!Domma.elements?.contextMenu?(e.addEventListener("contextmenu",i=>{i.preventDefault(),a(i.clientX,i.clientY)}),null):Domma.elements.contextMenu(e,{inherit:!1,cursor:!1,render:i=>{a(i.x,i.y)}})}function p(){l&&(k(),l.root.remove(),document.removeEventListener("mousedown",q,!0),document.removeEventListener("keydown",K,!0),window.removeEventListener("scroll",U,!0),l=null)}const q=e=>{l&&!l.root.contains(e.target)&&!(l.submenu&&l.submenu.contains(e.target))&&p()},U=e=>{l&&!l.root.contains(e.target)&&!(l.submenu&&l.submenu.contains(e.target))&&p()},K=e=>{e.key==="Escape"&&p()};function V(e,t,n,o,a=[],i=null){oe();const s=document.createElement("div");s.className="dm-sc-menu",s.style.cssText=Y,l={root:s,textarea:e,span:t,submenu:null,blocks:a,openBlock:i,keepEmpty:!1};const c=new Map(a.map(b=>[b.name,b])),r=t&&(j.get(t.name)||z.get(t.name)),d=t&&(r?t.name==="block"?c.get(String(t.attrs.template||"")):null:c.get(t.name)),x=t&&F.has(t.name)?L.filter(b=>b.name in t.attrs):[];r&&fe(s,r),d&&he(s,d,!!r);for(const b of x)ve(s,b);(r||d||x.length)&&s.appendChild(_()),s.appendChild(y("Celebrations\u2026",()=>we())),s.appendChild(y("Add effect\u2026",()=>Te())),s.appendChild(y("Insert\u2026",()=>ke()));const u=e.selectionStart!==e.selectionEnd;(t||u)&&s.appendChild(y(u?"Wrap selection in\u2026":"Wrap in\u2026",()=>_e())),a.length&&(s.appendChild(_()),s.appendChild(y("Add block\u2026",()=>Le()))),document.body.appendChild(s),X(s,n,o),document.addEventListener("mousedown",q,!0),document.addEventListener("keydown",K,!0),window.addEventListener("scroll",U,!0),window.I&&I.scan(s)}function _(){const e=document.createElement("div");return e.style.cssText=me,e}function v(e){const t=document.createElement("div");return t.style.cssText=T,t.textContent=e,t}function fe(e,t){e.appendChild(v(`${t.label} options`));const n=h(document.createElement("button"));n.type="button",n.style.cssText=m,n.innerHTML='<span data-icon="edit" data-icon-size="13" style="display:inline-flex;align-items:center;"></span>',n.appendChild(document.createTextNode(`Edit ${t.label}\u2026`)),n.addEventListener("click",()=>{const{textarea:i,span:s}=l;p(),A(i,{...t,attrs:D(t,s.attrs)},{span:s})}),e.appendChild(n);for(const i of t.actions||[]){const s=h(document.createElement("button"));s.type="button",s.style.cssText=m,s.innerHTML=`<span data-icon="${i.icon||"zap"}" data-icon-size="13" style="display:inline-flex;align-items:center;"></span>`,s.appendChild(document.createTextNode(i.label)),s.addEventListener("click",()=>{const{textarea:c,span:r}=l;if(i.remove){ne(c,r.openTagStart,r.openTagEnd,""),p();return}l.span=W(c,r,i.set||{}),p()}),e.appendChild(s)}const o=Array.isArray(t.quickAttrs)?new Set(t.quickAttrs):null,a=D(t,l.span.attrs).filter(i=>!o||o.has(i.name));(t.actions||[]).length&&a.length&&e.appendChild(_());for(const i of a)e.appendChild(B(i))}function he(e,t,n){const{span:o}=l;if(l.keepEmpty=!0,n&&e.appendChild(_()),e.appendChild(v(n?`${t.name} parameters`:`${t.name} block`)),t.description&&!n){const s=document.createElement("div");s.style.cssText="padding:0 .55rem .3rem;font-size:.75rem;color:var(--dm-text-muted,#9a9aac);max-width:260px;",s.textContent=t.description,e.appendChild(s)}const a=(s,c,r)=>{const d=h(document.createElement("button"));d.type="button",d.style.cssText=m,d.innerHTML=`<span data-icon="${s}" data-icon-size="13" style="display:inline-flex;align-items:center;"></span>`,d.appendChild(document.createTextNode(c)),d.addEventListener("click",r),e.appendChild(d)};t.attrs.length&&a("edit","Edit parameters\u2026",()=>{const{textarea:s}=l;p(),A(s,{...t,name:o.name,label:t.name},{span:o})});const{openBlock:i}=l;a(i?"layout":"external-link",i?"Edit the block":"Open the block",()=>{p(),i?i(t.name):location.hash=`#/blocks/edit/${encodeURIComponent(t.name)}`});for(const s of t.attrs)e.appendChild(B(s));if(!t.attrs.length){const s=document.createElement("div");s.style.cssText=T+"text-transform:none;letter-spacing:0;",s.textContent="This block takes no parameters.",e.appendChild(s)}}function B(e,t=e.name){const n=l.span.attrs[t];switch(e.type){case"checkbox":return xe(e,t,Q(n,e.default));case"select":return Ee(e,t,n);case"lookup":return Ce(e,t,n);case"colour":return ye(e,t,n);case"icon":return ge(e,t,n);default:return be(e,t,n)}}function w(e,t){if(l.span=N(l.textarea,l.span,e,l.keepEmpty&&t==null?"":t,{keepEmpty:l.keepEmpty}),e==="theme"){const{textarea:n,span:o,root:a}=l,i=a.getBoundingClientRect(),{blocks:s,openBlock:c}=l;p(),V(n,o,i.left,i.top,s,c)}}function xe(e,t,n){const o=h(document.createElement("label"));o.style.cssText=m;const a=document.createElement("input");return a.type="checkbox",a.checked=n,a.addEventListener("change",()=>w(t,Z(e,a.checked))),o.appendChild(a),o.appendChild(document.createTextNode(e.label)),o}function be(e,t,n){const o=document.createElement("div");o.style.cssText=m+"cursor:default;";const a=document.createElement("span");a.textContent=e.label,a.style.cssText="white-space:nowrap;color:var(--dm-text-muted,#9a9aac);";const i=document.createElement("input");i.type=e.type==="number"?"number":"text",i.value=n===!0||n==null?"":n,e.default!=null&&e.default!==""&&(i.placeholder=String(e.default)),i.style.cssText=P;let s=null;if(i.addEventListener("input",()=>{clearTimeout(s),s=setTimeout(()=>w(t,i.value.trim()),180)}),i.addEventListener("mousedown",c=>c.stopPropagation()),o.appendChild(a),o.appendChild(i),e.type==="image"){const c=document.createElement("button");c.type="button",c.textContent="Browse",c.title="Choose from Media",c.style.cssText="padding:2px 8px;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:inherit;cursor:pointer;flex-shrink:0;font:inherit;",c.addEventListener("mousedown",r=>r.stopPropagation()),c.addEventListener("click",async()=>{const{textarea:r,span:d}=l;p();const x=await ce({current:i.value.trim()});x&&r.isConnected&&N(r,d,t,x)}),o.appendChild(c)}return o}function ye(e,t,n){const o=document.createElement("div");o.style.cssText=m+"cursor:default;";const a=document.createElement("span");a.textContent=e.label,a.style.flex="1";const i=document.createElement("input");return i.type="color",typeof n=="string"&&/^#/.test(n)?i.value=n:typeof e.default=="string"&&/^#/.test(e.default)&&(i.value=e.default),i.addEventListener("input",()=>w(t,i.value)),o.appendChild(a),o.appendChild(i),o}function Ee(e,t,n){const o=n==null||n===!0?e.default??"":n;return y(`${e.label}${o!==""?`: ${o}`:""}`,()=>{const a=g();for(const[i,s]of e.options||[]){const c=h(document.createElement("button"));c.type="button",c.style.cssText=m,c.textContent=s,i===o&&(c.style.fontWeight="700"),c.addEventListener("click",()=>{w(t,i),k()}),a.appendChild(c)}return a})}function ge(e,t,n){const o=n==null||n===!0?"":String(n),a=o?`${e.label}: ${o}`:e.label;return y(a,()=>{const i=g();i.style.width="232px";const s=document.createElement("input");s.type="text",s.placeholder="Search icons\u2026",s.style.cssText=P+"margin:6px;width:calc(100% - 12px);",s.addEventListener("mousedown",b=>b.stopPropagation()),i.appendChild(s);const c=h(document.createElement("button"));c.type="button",c.style.cssText=m,c.textContent="- none -",o||(c.style.fontWeight="700"),c.addEventListener("click",()=>{w(t,null),k()}),i.appendChild(c);const r=document.createElement("div");r.style.cssText="display:flex;flex-wrap:wrap;gap:2px;padding:4px 6px;max-height:220px;overflow-y:auto;",i.appendChild(r);const d=96,x=()=>{const b=typeof I<"u"&&typeof I.list=="function"?I.list():[],O=s.value.trim().toLowerCase(),S=O?b.filter(f=>f.toLowerCase().includes(O)):b;r.replaceChildren();for(const f of S.slice(0,d)){const C=h(document.createElement("button"));C.type="button",C.title=f,C.style.cssText="width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;background:none;border:1px solid transparent;border-radius:4px;cursor:pointer;color:inherit;",f===o&&(C.style.borderColor="var(--dm-primary,#5b8cff)");const $=document.createElement("span");$.setAttribute("data-icon",f),$.setAttribute("data-icon-size","15"),$.style.cssText="display:inline-flex;align-items:center;",C.appendChild($),C.addEventListener("click",()=>{w(t,f),k()}),r.appendChild(C)}if(S.length>d){const f=document.createElement("div");f.style.cssText=T,f.textContent=`${S.length-d} more - refine search`,r.appendChild(f)}if(!S.length){const f=document.createElement("div");f.style.cssText=T,f.textContent="No icons match",r.appendChild(f)}window.I&&I.scan(r)};let u=null;return s.addEventListener("input",()=>{clearTimeout(u),u=setTimeout(x,120)}),x(),setTimeout(()=>s.focus(),0),i})}function Ce(e,t,n){const o=n==null||n===!0?e.default??"":n;return y(`${e.label}${o!==""?`: ${o}`:""}`,()=>{const a=g();a.style.minHeight="48px";const i=typeof E<"u"&&E.loader?E.loader(a,{type:"dots"}):null;return re(e.source).then(s=>{if(i&&i.destroy(),!l||l.submenu!==a)return;if(a.style.minHeight="",!s.length){const d=document.createElement("div");d.style.cssText=T,d.textContent="Nothing found",a.appendChild(d)}const c=s.some(([d])=>d===o),r=[["","- none -"],...s];o!==""&&!c&&r.push([o,`${o} (missing)`]);for(const[d,x]of r){const u=h(document.createElement("button"));u.type="button",u.style.cssText=m,u.textContent=x,d===o&&(u.style.fontWeight="700"),u.addEventListener("click",()=>{w(t,d===""?null:d),k()}),a.appendChild(u)}}),a})}function ve(e,t){e.appendChild(v(`Effect: ${t.label}`));for(const o of t.attrs||[])e.appendChild(B(o,`${t.name}-${o.name}`));const n=h(document.createElement("button"));n.type="button",n.style.cssText=m,n.innerHTML='<span data-icon="trash" data-icon-size="13" style="display:inline-flex;align-items:center;"></span> Remove effect',n.addEventListener("click",()=>{const o={};for(const a of te(l.span.attrs,t.name))o[a]=null;W(l.textarea,l.span,o),p()}),e.appendChild(n)}function we(){const e=g();e.appendChild(v("Seasonal themes"));for(const[t,n]of[["auto","Auto (date-detected)"],...Object.entries(J).map(([o,a])=>[o,a.label])]){const o=h(document.createElement("button"));o.type="button",o.style.cssText=m,o.textContent=n,o.addEventListener("click",()=>{R(l.textarea,`[celebrate theme="${t}" /]`),p()}),e.appendChild(o)}e.appendChild(_()),e.appendChild(v("Celebration effects"));for(const t of["butterflies","ticker-tape","firework","fireworks"]){const n=z.get(t),o=h(document.createElement("button"));o.type="button",o.style.cssText=m,o.textContent=n.label,o.addEventListener("click",()=>{const a=l.textarea;p(),A(a,n)}),e.appendChild(o)}return e}function Te(){const e=g(),t=l.span,n=t&&F.has(t.name)?t.name:null;for(const o of[...new Set(L.map(a=>a.category))]){const a=L.filter(i=>i.category===o);if(a.length){e.appendChild(v(o));for(const i of a){const s=n&&(i.hosts||[]).includes(n)&&!(i.name in t.attrs),c=h(document.createElement("button"));if(c.type="button",c.style.cssText=m+"justify-content:space-between;",c.appendChild(document.createTextNode(i.label)),s){const r=document.createElement("span");r.textContent=`inject \u2192 [${n}]`,r.style.cssText="opacity:.6;font-size:.7rem;",c.appendChild(r)}c.addEventListener("click",()=>{if(s)N(l.textarea,l.span,i.name,!0);else{const r=i.selfClosing?`[${i.name} /]`:`[${i.name}]
1
+ import{SHORTCODES as M}from"./shortcode-registry.js";import{EFFECTS as L,CELEBRATION_THEMES as J,getEffectAttrs as D}from"./effect-defs.js";import{boolState as Q,boolValue as Z,findEnclosingShortcode as ee,setAttr as N,setAttrs as W,effectAttrKeys as te}from"./shortcode-tags.js";import{insertAtCursor as R,replaceRange as ne}from"./markdown-toolbar.js";import{clearLookupCache as oe,lookupOptions as se}from"./shortcode-lookups.js";import{insertMenuGroups as ie,insertShortcodeByName as ae}from"./shortcode-insert.js";import{openShortcodeForm as A}from"./shortcode-form.js";import{pickMedia as ce}from"./media-picker.js";import{blockTagSnippet as le}from"./block-tags.js";import{catalogueNow as re,dommaHelp as de}from"./domma-catalogue.js";function pe(e){return se(e,l?.span?.attrs||{})}const me=M.map(e=>({name:e.name,selfClosing:!!e.selfClosing})),j=new Map(M.map(e=>[e.name,e])),z=new Map(L.map(e=>[e.name,e])),ue=L.map(e=>({name:e.name,selfClosing:!!e.selfClosing})),fe=[...me,...ue],F=new Set(["card","box","hero","banner","col","button"]);let l=null;const Y="position:fixed;z-index:10000;min-width:210px;max-height:70vh;overflow-y:auto;background:var(--dm-surface,#1c1c30);border:1px solid var(--dm-border,#2a2a40);border-radius:6px;box-shadow:var(--dm-shadow-lg);padding:.3rem;font-size:.83rem;color:var(--dm-text,#e5e5e5);",u="display:flex;align-items:center;gap:.5rem;width:100%;text-align:left;padding:.35rem .55rem;border:none;background:transparent;color:inherit;border-radius:4px;cursor:pointer;font-size:.83rem;",T="padding:.3rem .55rem;color:var(--dm-text-muted,#8a8a9a);font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;",P="flex:1;min-width:0;padding:.2rem .4rem;background:var(--dm-input-bg,#12121e);border:1px solid var(--dm-border,#333);border-radius:3px;color:var(--dm-text,#eee);font-size:.8rem;",he="height:1px;background:var(--dm-border,#2a2a40);margin:.3rem .2rem;";function h(e){return e.addEventListener("mouseenter",()=>{e.style.background="var(--dm-primary,#4338ca)",e.style.color="var(--dm-primary-text,#fff)"}),e.addEventListener("mouseleave",()=>{e.style.background="transparent",e.style.color="inherit"}),e}export function attachContextMenu(e,{blocks:t=()=>[],openBlock:n=null}={}){const o=()=>{const i=t()||[],s=i.filter(c=>c.shortTag&&!j.has(c.name)&&!z.has(c.name));return{defs:i,specs:[...fe,...s.map(c=>({name:c.name,selfClosing:!0}))]}},a=(i,s)=>{p();const{defs:c,specs:r}=o();V(e,ee(e,r),i,s,c,n)};return typeof Domma>"u"||!Domma.elements?.contextMenu?(e.addEventListener("contextmenu",i=>{i.preventDefault(),a(i.clientX,i.clientY)}),null):Domma.elements.contextMenu(e,{inherit:!1,cursor:!1,render:i=>{a(i.x,i.y)}})}function p(){l&&(k(),l.root.remove(),document.removeEventListener("mousedown",q,!0),document.removeEventListener("keydown",K,!0),window.removeEventListener("scroll",U,!0),l=null)}const q=e=>{l&&!l.root.contains(e.target)&&!(l.submenu&&l.submenu.contains(e.target))&&p()},U=e=>{l&&!l.root.contains(e.target)&&!(l.submenu&&l.submenu.contains(e.target))&&p()},K=e=>{e.key==="Escape"&&p()};function V(e,t,n,o,a=[],i=null){oe();const s=document.createElement("div");s.className="dm-sc-menu",s.style.cssText=Y,l={root:s,textarea:e,span:t,submenu:null,blocks:a,openBlock:i,keepEmpty:!1};const c=new Map(a.map(b=>[b.name,b])),r=t&&(j.get(t.name)||z.get(t.name)),d=t&&(r?t.name==="block"?c.get(String(t.attrs.template||"")):null:c.get(t.name)),x=t&&F.has(t.name)?L.filter(b=>b.name in t.attrs):[];r&&xe(s,r),d&&be(s,d,!!r);for(const b of x)ke(s,b);(r||d||x.length)&&s.appendChild(_()),s.appendChild(y("Celebrations\u2026",()=>Le())),s.appendChild(y("Add effect\u2026",()=>_e())),s.appendChild(y("Insert\u2026",()=>Se()));const m=e.selectionStart!==e.selectionEnd;(t||m)&&s.appendChild(y(m?"Wrap selection in\u2026":"Wrap in\u2026",()=>Ae())),a.length&&(s.appendChild(_()),s.appendChild(y("Add block\u2026",()=>$e()))),document.body.appendChild(s),X(s,n,o),document.addEventListener("mousedown",q,!0),document.addEventListener("keydown",K,!0),window.addEventListener("scroll",U,!0),window.I&&I.scan(s)}function _(){const e=document.createElement("div");return e.style.cssText=he,e}function v(e){const t=document.createElement("div");return t.style.cssText=T,t.textContent=e,t}function xe(e,t){e.appendChild(v(`${t.label} options`));const n=h(document.createElement("button"));n.type="button",n.style.cssText=u,n.innerHTML='<span data-icon="edit" data-icon-size="13" style="display:inline-flex;align-items:center;"></span>',n.appendChild(document.createTextNode(`Edit ${t.label}\u2026`)),n.addEventListener("click",()=>{const{textarea:i,span:s}=l;p(),A(i,{...t,attrs:D(t,s.attrs)},{span:s})}),e.appendChild(n);for(const i of t.actions||[]){const s=h(document.createElement("button"));s.type="button",s.style.cssText=u,s.innerHTML=`<span data-icon="${i.icon||"zap"}" data-icon-size="13" style="display:inline-flex;align-items:center;"></span>`,s.appendChild(document.createTextNode(i.label)),s.addEventListener("click",()=>{const{textarea:c,span:r}=l;if(i.remove){ne(c,r.openTagStart,r.openTagEnd,""),p();return}l.span=W(c,r,i.set||{}),p()}),e.appendChild(s)}const o=Array.isArray(t.quickAttrs)?new Set(t.quickAttrs):null,a=D(t,l.span.attrs).filter(i=>!o||o.has(i.name));(t.actions||[]).length&&a.length&&e.appendChild(_());for(const i of a)e.appendChild(H(i))}function be(e,t,n){const{span:o}=l;if(l.keepEmpty=!0,n&&e.appendChild(_()),e.appendChild(v(n?`${t.name} parameters`:`${t.name} block`)),t.description&&!n){const s=document.createElement("div");s.style.cssText="padding:0 .55rem .3rem;font-size:.75rem;color:var(--dm-text-muted,#9a9aac);max-width:260px;",s.textContent=t.description,e.appendChild(s)}const a=(s,c,r)=>{const d=h(document.createElement("button"));d.type="button",d.style.cssText=u,d.innerHTML=`<span data-icon="${s}" data-icon-size="13" style="display:inline-flex;align-items:center;"></span>`,d.appendChild(document.createTextNode(c)),d.addEventListener("click",r),e.appendChild(d)};t.attrs.length&&a("edit","Edit parameters\u2026",()=>{const{textarea:s}=l;p(),A(s,{...t,name:o.name,label:t.name},{span:o})});const{openBlock:i}=l;a(i?"layout":"external-link",i?"Edit the block":"Open the block",()=>{p(),i?i(t.name):location.hash=`#/blocks/edit/${encodeURIComponent(t.name)}`});for(const s of t.attrs)e.appendChild(H(s));if(!t.attrs.length){const s=document.createElement("div");s.style.cssText=T+"text-transform:none;letter-spacing:0;",s.textContent="This block takes no parameters.",e.appendChild(s)}}function H(e,t=e.name){const n=ye(e,t),o=e.domma?de(re(),e):"";return o&&n&&!n.title&&(n.title=o),n}function ye(e,t){const n=l.span.attrs[t];switch(e.type){case"checkbox":return Ee(e,t,Q(n,e.default));case"select":return ve(e,t,n);case"lookup":return Te(e,t,n);case"colour":return Ce(e,t,n);case"icon":return we(e,t,n);default:return ge(e,t,n)}}function w(e,t){if(l.span=N(l.textarea,l.span,e,l.keepEmpty&&t==null?"":t,{keepEmpty:l.keepEmpty}),e==="theme"){const{textarea:n,span:o,root:a}=l,i=a.getBoundingClientRect(),{blocks:s,openBlock:c}=l;p(),V(n,o,i.left,i.top,s,c)}}function Ee(e,t,n){const o=h(document.createElement("label"));o.style.cssText=u;const a=document.createElement("input");return a.type="checkbox",a.checked=n,a.addEventListener("change",()=>w(t,Z(e,a.checked))),o.appendChild(a),o.appendChild(document.createTextNode(e.label)),o}function ge(e,t,n){const o=document.createElement("div");o.style.cssText=u+"cursor:default;";const a=document.createElement("span");a.textContent=e.label,a.style.cssText="white-space:nowrap;color:var(--dm-text-muted,#9a9aac);";const i=document.createElement("input");i.type=e.type==="number"?"number":"text",i.value=n===!0||n==null?"":n,e.default!=null&&e.default!==""&&(i.placeholder=String(e.default)),i.style.cssText=P;let s=null;if(i.addEventListener("input",()=>{clearTimeout(s),s=setTimeout(()=>w(t,i.value.trim()),180)}),i.addEventListener("mousedown",c=>c.stopPropagation()),o.appendChild(a),o.appendChild(i),e.type==="image"){const c=document.createElement("button");c.type="button",c.textContent="Browse",c.title="Choose from Media",c.style.cssText="padding:2px 8px;background:transparent;border:1px solid var(--dm-border,#333);border-radius:4px;color:inherit;cursor:pointer;flex-shrink:0;font:inherit;",c.addEventListener("mousedown",r=>r.stopPropagation()),c.addEventListener("click",async()=>{const{textarea:r,span:d}=l;p();const x=await ce({current:i.value.trim()});x&&r.isConnected&&N(r,d,t,x)}),o.appendChild(c)}return o}function Ce(e,t,n){const o=document.createElement("div");o.style.cssText=u+"cursor:default;";const a=document.createElement("span");a.textContent=e.label,a.style.flex="1";const i=document.createElement("input");return i.type="color",typeof n=="string"&&/^#/.test(n)?i.value=n:typeof e.default=="string"&&/^#/.test(e.default)&&(i.value=e.default),i.addEventListener("input",()=>w(t,i.value)),o.appendChild(a),o.appendChild(i),o}function ve(e,t,n){const o=n==null||n===!0?e.default??"":n;return y(`${e.label}${o!==""?`: ${o}`:""}`,()=>{const a=g();for(const[i,s]of e.options||[]){const c=h(document.createElement("button"));c.type="button",c.style.cssText=u,c.textContent=s,i===o&&(c.style.fontWeight="700"),c.addEventListener("click",()=>{w(t,i),k()}),a.appendChild(c)}return a})}function we(e,t,n){const o=n==null||n===!0?"":String(n),a=o?`${e.label}: ${o}`:e.label;return y(a,()=>{const i=g();i.style.width="232px";const s=document.createElement("input");s.type="text",s.placeholder="Search icons\u2026",s.style.cssText=P+"margin:6px;width:calc(100% - 12px);",s.addEventListener("mousedown",b=>b.stopPropagation()),i.appendChild(s);const c=h(document.createElement("button"));c.type="button",c.style.cssText=u,c.textContent="- none -",o||(c.style.fontWeight="700"),c.addEventListener("click",()=>{w(t,null),k()}),i.appendChild(c);const r=document.createElement("div");r.style.cssText="display:flex;flex-wrap:wrap;gap:2px;padding:4px 6px;max-height:220px;overflow-y:auto;",i.appendChild(r);const d=96,x=()=>{const b=typeof I<"u"&&typeof I.list=="function"?I.list():[],O=s.value.trim().toLowerCase(),S=O?b.filter(f=>f.toLowerCase().includes(O)):b;r.replaceChildren();for(const f of S.slice(0,d)){const C=h(document.createElement("button"));C.type="button",C.title=f,C.style.cssText="width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;background:none;border:1px solid transparent;border-radius:4px;cursor:pointer;color:inherit;",f===o&&(C.style.borderColor="var(--dm-primary,#5b8cff)");const $=document.createElement("span");$.setAttribute("data-icon",f),$.setAttribute("data-icon-size","15"),$.style.cssText="display:inline-flex;align-items:center;",C.appendChild($),C.addEventListener("click",()=>{w(t,f),k()}),r.appendChild(C)}if(S.length>d){const f=document.createElement("div");f.style.cssText=T,f.textContent=`${S.length-d} more - refine search`,r.appendChild(f)}if(!S.length){const f=document.createElement("div");f.style.cssText=T,f.textContent="No icons match",r.appendChild(f)}window.I&&I.scan(r)};let m=null;return s.addEventListener("input",()=>{clearTimeout(m),m=setTimeout(x,120)}),x(),setTimeout(()=>s.focus(),0),i})}function Te(e,t,n){const o=n==null||n===!0?e.default??"":n;return y(`${e.label}${o!==""?`: ${o}`:""}`,()=>{const a=g();a.style.minHeight="48px";const i=typeof E<"u"&&E.loader?E.loader(a,{type:"dots"}):null;return pe(e.source).then(s=>{if(i&&i.destroy(),!l||l.submenu!==a)return;if(a.style.minHeight="",!s.length){const d=document.createElement("div");d.style.cssText=T,d.textContent="Nothing found",a.appendChild(d)}const c=s.some(([d])=>d===o),r=[["","- none -"],...s];o!==""&&!c&&r.push([o,`${o} (missing)`]);for(const[d,x]of r){const m=h(document.createElement("button"));m.type="button",m.style.cssText=u,m.textContent=x,d===o&&(m.style.fontWeight="700"),m.addEventListener("click",()=>{w(t,d===""?null:d),k()}),a.appendChild(m)}}),a})}function ke(e,t){e.appendChild(v(`Effect: ${t.label}`));for(const o of t.attrs||[])e.appendChild(H(o,`${t.name}-${o.name}`));const n=h(document.createElement("button"));n.type="button",n.style.cssText=u,n.innerHTML='<span data-icon="trash" data-icon-size="13" style="display:inline-flex;align-items:center;"></span> Remove effect',n.addEventListener("click",()=>{const o={};for(const a of te(l.span.attrs,t.name))o[a]=null;W(l.textarea,l.span,o),p()}),e.appendChild(n)}function Le(){const e=g();e.appendChild(v("Seasonal themes"));for(const[t,n]of[["auto","Auto (date-detected)"],...Object.entries(J).map(([o,a])=>[o,a.label])]){const o=h(document.createElement("button"));o.type="button",o.style.cssText=u,o.textContent=n,o.addEventListener("click",()=>{R(l.textarea,`[celebrate theme="${t}" /]`),p()}),e.appendChild(o)}e.appendChild(_()),e.appendChild(v("Celebration effects"));for(const t of["butterflies","ticker-tape","firework","fireworks"]){const n=z.get(t),o=h(document.createElement("button"));o.type="button",o.style.cssText=u,o.textContent=n.label,o.addEventListener("click",()=>{const a=l.textarea;p(),A(a,n)}),e.appendChild(o)}return e}function _e(){const e=g(),t=l.span,n=t&&F.has(t.name)?t.name:null;for(const o of[...new Set(L.map(a=>a.category))]){const a=L.filter(i=>i.category===o);if(a.length){e.appendChild(v(o));for(const i of a){const s=n&&(i.hosts||[]).includes(n)&&!(i.name in t.attrs),c=h(document.createElement("button"));if(c.type="button",c.style.cssText=u+"justify-content:space-between;",c.appendChild(document.createTextNode(i.label)),s){const r=document.createElement("span");r.textContent=`inject \u2192 [${n}]`,r.style.cssText="opacity:.6;font-size:.7rem;",c.appendChild(r)}c.addEventListener("click",()=>{if(s)N(l.textarea,l.span,i.name,!0);else{const r=i.selfClosing?`[${i.name} /]`:`[${i.name}]
2
2
  Content
3
- [/${i.name}]`;R(l.textarea,r)}p()}),e.appendChild(c)}}}return e}function y(e,t){const n=h(document.createElement("button"));n.type="button",n.style.cssText=m+"justify-content:space-between;",n.appendChild(document.createTextNode(e));const o=document.createElement("span");return o.setAttribute("data-icon","chevron-right"),o.setAttribute("data-icon-size","12"),o.style.cssText="opacity:.6;display:inline-flex;align-items:center;flex-shrink:0;",n.appendChild(o),n.addEventListener("mouseenter",()=>G(n,t)),n.addEventListener("click",a=>{a.stopPropagation(),G(n,t)}),n}function g(){const e=document.createElement("div");return e.className="dm-sc-submenu",e.style.cssText=Y,e}function G(e,t){k();const n=t();l.submenu=n,document.body.appendChild(n);const o=e.getBoundingClientRect();X(n,o.right+2,o.top,o.left-2),window.I&&I.scan(n)}function k(){l&&l.submenu&&(l.submenu.remove(),l.submenu=null)}function H(e){const t=h(document.createElement("button"));if(t.type="button",t.style.cssText=m,e.icon){const n=document.createElement("span");n.setAttribute("data-icon",e.icon),n.setAttribute("data-icon-size","14"),n.style.cssText="opacity:.75;display:inline-flex;align-items:center;flex-shrink:0;",t.appendChild(n)}return t.appendChild(document.createTextNode(e.label)),t}function ke(){const e=g();for(const{category:t,items:n}of ie()){e.appendChild(v(t));for(const o of n){const a=H(o);a.addEventListener("click",()=>{const i=l.textarea;p(),ae(o.name,i)}),e.appendChild(a)}}return e}function Le(){const e=g();e.style.maxWidth="320px";const t=document.createElement("input");t.type="text",t.placeholder="Find a block\u2026",t.style.cssText=P+"margin:6px;width:calc(100% - 12px);",t.addEventListener("mousedown",a=>a.stopPropagation());const n=document.createElement("div");e.append(t,n);const o=()=>{const a=t.value.trim().toLowerCase(),i=l.blocks.filter(s=>!a||s.name.includes(a)||s.description.toLowerCase().includes(a));n.replaceChildren();for(const s of i){const c=H(s);if(s.description&&(c.title=s.description),!s.shortTag){const r=document.createElement("small");r.style.cssText="margin-left:auto;opacity:.6;",r.textContent="[block]",r.title='A built-in shortcode has this name, so it goes in as [block template="\u2026"]',c.appendChild(r)}c.addEventListener("click",()=>{const r=l.textarea;p();const d=r.selectionStart,x=le(s);R(r,x);const u=x.indexOf('=""');u>=0&&r.setSelectionRange(d+u+2,d+u+2),r.focus()}),n.appendChild(c)}if(!i.length){const s=document.createElement("div");s.style.cssText=T,s.textContent="No blocks match",n.appendChild(s)}window.I&&I.scan(n)};return t.addEventListener("input",o),o(),setTimeout(()=>t.focus(),0),e}function _e(){const e=g();for(const t of M.filter(n=>n.wrappable||n.container)){const n=H(t);n.addEventListener("click",()=>{const o=l.textarea;p(),A(o,t)}),e.appendChild(n)}return e}function X(e,t,n,o){e.style.left="0px",e.style.top="0px";const a=e.getBoundingClientRect();let i=t;t+a.width>window.innerWidth-8&&(i=o!=null?o-a.width:t-a.width);let s=n;n+a.height>window.innerHeight-8&&(s=Math.max(8,window.innerHeight-a.height-8)),e.style.left=`${Math.max(8,i)}px`,e.style.top=`${Math.max(8,s)}px`}
3
+ [/${i.name}]`;R(l.textarea,r)}p()}),e.appendChild(c)}}}return e}function y(e,t){const n=h(document.createElement("button"));n.type="button",n.style.cssText=u+"justify-content:space-between;",n.appendChild(document.createTextNode(e));const o=document.createElement("span");return o.setAttribute("data-icon","chevron-right"),o.setAttribute("data-icon-size","12"),o.style.cssText="opacity:.6;display:inline-flex;align-items:center;flex-shrink:0;",n.appendChild(o),n.addEventListener("mouseenter",()=>G(n,t)),n.addEventListener("click",a=>{a.stopPropagation(),G(n,t)}),n}function g(){const e=document.createElement("div");return e.className="dm-sc-submenu",e.style.cssText=Y,e}function G(e,t){k();const n=t();l.submenu=n,document.body.appendChild(n);const o=e.getBoundingClientRect();X(n,o.right+2,o.top,o.left-2),window.I&&I.scan(n)}function k(){l&&l.submenu&&(l.submenu.remove(),l.submenu=null)}function B(e){const t=h(document.createElement("button"));if(t.type="button",t.style.cssText=u,e.icon){const n=document.createElement("span");n.setAttribute("data-icon",e.icon),n.setAttribute("data-icon-size","14"),n.style.cssText="opacity:.75;display:inline-flex;align-items:center;flex-shrink:0;",t.appendChild(n)}return t.appendChild(document.createTextNode(e.label)),t}function Se(){const e=g();for(const{category:t,items:n}of ie()){e.appendChild(v(t));for(const o of n){const a=B(o);a.addEventListener("click",()=>{const i=l.textarea;p(),ae(o.name,i)}),e.appendChild(a)}}return e}function $e(){const e=g();e.style.maxWidth="320px";const t=document.createElement("input");t.type="text",t.placeholder="Find a block\u2026",t.style.cssText=P+"margin:6px;width:calc(100% - 12px);",t.addEventListener("mousedown",a=>a.stopPropagation());const n=document.createElement("div");e.append(t,n);const o=()=>{const a=t.value.trim().toLowerCase(),i=l.blocks.filter(s=>!a||s.name.includes(a)||s.description.toLowerCase().includes(a));n.replaceChildren();for(const s of i){const c=B(s);if(s.description&&(c.title=s.description),!s.shortTag){const r=document.createElement("small");r.style.cssText="margin-left:auto;opacity:.6;",r.textContent="[block]",r.title='A built-in shortcode has this name, so it goes in as [block template="\u2026"]',c.appendChild(r)}c.addEventListener("click",()=>{const r=l.textarea;p();const d=r.selectionStart,x=le(s);R(r,x);const m=x.indexOf('=""');m>=0&&r.setSelectionRange(d+m+2,d+m+2),r.focus()}),n.appendChild(c)}if(!i.length){const s=document.createElement("div");s.style.cssText=T,s.textContent="No blocks match",n.appendChild(s)}window.I&&I.scan(n)};return t.addEventListener("input",o),o(),setTimeout(()=>t.focus(),0),e}function Ae(){const e=g();for(const t of M.filter(n=>n.wrappable||n.container)){const n=B(t);n.addEventListener("click",()=>{const o=l.textarea;p(),A(o,t)}),e.appendChild(n)}return e}function X(e,t,n,o){e.style.left="0px",e.style.top="0px";const a=e.getBoundingClientRect();let i=t;t+a.width>window.innerWidth-8&&(i=o!=null?o-a.width:t-a.width);let s=n;n+a.height>window.innerHeight-8&&(s=Math.max(8,window.innerHeight-a.height-8)),e.style.left=`${Math.max(8,i)}px`,e.style.top=`${Math.max(8,s)}px`}
@@ -1,8 +1,8 @@
1
- import{replaceRange as ne}from"./markdown-toolbar.js";import{boolState as oe,boolValue as le,parseAttrs as Q,serialiseTag as U,setAttrs as se}from"./shortcode-tags.js";import{SHORTCODES as re}from"./shortcode-registry.js";import{clearLookupCache as ie,lookupOptions as ce}from"./shortcode-lookups.js";import{PREVIEW_RENDERERS as ae}from"./shortcode-preview.js";import{makeCheckbox as de,makeColourInput as pe,makeField as x,makeIconInput as X,makeImageInput as Z,makeLivePreview as ue,makeSelect as M,makeTextInput as _}from"./shortcode-modal.js";const me=new Map(re.map(e=>[e.name,e])),ee=6;export function templateAttrs(e){const n=String(e.template||"").match(new RegExp(`^\\[${e.name}([\\s\\S]*?)\\s*/?\\]`));return n?Q(n[1]):{}}export function templateBody(e){if(e.selfClosing)return"";const n=String(e.template||"").match(new RegExp(`^\\[${e.name}[^\\]]*\\]([\\s\\S]*)\\[/${e.name}\\]$`));return n?n[1].replace(/^\n/,"").replace(/\n$/,""):""}export function templateChildren(e){if(!e.children)return[];const n=e.children.name,i=new RegExp(`\\[${n}([^\\]]*)\\]([\\s\\S]*?)\\[/${n}\\]`,"g"),a=[];for(const s of templateBody(e).matchAll(i))a.push({attrs:Q(s[1]),body:s[2].replace(/^\n/,"").replace(/\n$/,"")});return a}const fe=new Set(["lookup","url"]);export function seedAttrs(e,n){const i=new Map((e.attrs||[]).map(s=>[s.name,s.type])),a={};for(const[s,c]of Object.entries(n))fe.has(i.get(s))||(a[s]=c);return a}export function buildSnippet(e,n,i=""){const a=U(e.name,n,e.selfClosing);if(e.selfClosing)return a;const s=`[/${e.name}]`;return e.inline?`${a}${i}${s}`:`${a}
2
- ${i}
3
- ${s}`}export function buildChildrenBody(e,n){return n.map(i=>buildSnippet(e,i.attrs,i.body)).join(`
4
- `)}export function emitSnippet(e,n,i,a){const s=(e.formats||[]).find(c=>c.value===a);if(s&&typeof s.emit=="function"){const c=s.emit(n,i);if(c!=null)return c}return buildSnippet(e,n,i)}const he="display:block;font-size:.7rem;font-weight:600;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;margin-bottom:.25rem;";function be(e,n,i,a){const s=n===!0||n==null?"":String(n);if(e.type==="checkbox"){const l=de(e.label),r=l.querySelector("input");return r.checked=oe(n,e.default),r.addEventListener("change",i),{el:l,bare:!0,get:()=>le(e,r.checked)}}if(e.type==="select"){const l=e.options.some(([C])=>C==="")?e.options:[["","- none -"],...e.options],r=M(l);return r.value=s,r.addEventListener("change",i),{el:x(e.label,r),get:()=>r.value||null}}if(e.type==="icon"){const{el:l,input:r}=X("icon name (optional)",s);return r.addEventListener("input",i),{el:x(e.label,l),get:()=>r.value.trim()||null}}if(e.type==="image"){const{el:l,input:r}=Z("/media/photo.jpg",s);return r.addEventListener("input",i),{el:x(e.label,l),get:()=>r.value.trim()||null}}if(e.type==="colour"){const{el:l,input:r}=pe("#0f172a or a theme colour",s);return r.addEventListener("input",i),{el:x(e.label,l),get:()=>r.value.trim()||null}}if(e.type==="lookup"){const l=M([["","Loading\u2026"]]);l.disabled=!0,l.addEventListener("change",i);let r;const C=()=>{const h=a(),O=e.source==="collection-fields"?String(h.slug??""):e.source;O!==r&&(r=O,l.disabled=!0,ce(e.source,h).then(u=>{const v=l.value||s,b=u.some(([S])=>S===v),k=[["","- none -"],...u];v&&!b&&k.push([v,`${v} (missing)`]),l.replaceChildren();for(const[S,y]of k){const T=document.createElement("option");T.value=S,T.textContent=y,l.appendChild(T)}l.value=v,l.disabled=!1,i()}))};return C(),{el:x(e.label,l),get:()=>l.value||null,refresh:e.source==="collection-fields"?C:null}}const c=_(e.placeholder||(e.type==="url"?"/about or https://example.com":""),s);return e.type==="number"&&(c.type="number"),c.addEventListener("input",i),{el:x(e.label,c),get:()=>c.value.trim()||null}}export function openShortcodeForm(e,n,i={}){const{span:a=null,defaults:s=null}=i,c=!!a;ie();const l=e.selectionStart,r=e.selectionEnd,C=e.value.slice(l,r),h=n.children?me.get(n.children.name):null,O={...seedAttrs(n,templateAttrs(n)),...s||{}},u=document.createElement("div");u.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const v=[],b=[];let k=()=>{};const S=()=>{const t={};for(const{attr:o,w:p}of v){const d=p.get();d!=null&&d!==""&&(t[o.name]=d)}return t},y=()=>k(),T=()=>S();let z=null;!c&&n.formats?.length&&(z=M(n.formats.map(t=>[t.value,t.label])),z.addEventListener("change",y),u.appendChild(x("Format",z)));const $=n.attrs||[],P=$.length>ee+2?ee:$.length,D=(t,o)=>{const p=c?a.attrs[t.name]:O[t.name],d=be(t,p,y,T);v.push({attr:t,w:d,initial:d.get()}),o.appendChild(d.el)};for(const t of $.slice(0,P))D(t,u);if(P<$.length){const t=document.createElement("details");t.style.cssText="border-top:1px solid var(--dm-border,#333);padding-top:.6rem;";const o=document.createElement("summary");o.textContent=`More options (${$.length-P})`,o.style.cssText="cursor:pointer;font-size:.75rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",t.appendChild(o);const p=document.createElement("div");p.style.cssText="display:flex;flex-direction:column;gap:.75rem;padding-top:.75rem;",t.appendChild(p);for(const d of $.slice(P))D(d,p);u.appendChild(t)}let w=null,L=null;const N=document.createElement("div");if(!c&&h){const t=document.createElement("div");t.style.cssText=he,t.textContent=`${h.label}s`,u.appendChild(t),N.style.cssText="display:flex;flex-direction:column;gap:.4rem;",u.appendChild(N),L=document.createElement("button"),L.type="button",L.textContent=`+ Add ${h.label.toLowerCase()}`,L.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;",L.addEventListener("click",()=>{F({attrs:{},body:templateBody(h)||"Content"}),k()}),u.appendChild(L);const o=templateChildren(n),p=o.length?o:[{attrs:{},body:"Content"}];for(const d of p)F({attrs:seedAttrs(h,d.attrs),body:d.body});C&&(b[0].bodyInput.value=C)}else!c&&!n.selfClosing&&(w=document.createElement("textarea"),w.rows=n.inline?2:4,w.value=C||templateBody(n),w.style.cssText="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;font-family:inherit;box-sizing:border-box;resize:vertical;",w.addEventListener("input",y),u.appendChild(x("Content",w)));function F(t){if(b.length>=(n.children.max??20))return;const o=document.createElement("div");o.style.cssText="display:flex;gap:.35rem;align-items:center;";const p=[];for(const m of h.attrs||[])if(m.type==="icon"){const{el:f,input:B}=X(m.label.toLowerCase(),t.attrs[m.name]||"");f.style.flex=".7",B.addEventListener("input",y),p.push({attr:m,get:()=>B.value.trim()||null}),o.appendChild(f)}else if(m.type==="image"){const{el:f,input:B}=Z(m.label,t.attrs[m.name]||"");f.style.flex="1",B.addEventListener("input",y),p.push({attr:m,get:()=>B.value.trim()||null}),o.appendChild(f)}else if(m.type==="select"){const f=M(m.options);f.value=t.attrs[m.name]||m.options[0][0],f.style.flex=".7",f.addEventListener("change",y),p.push({attr:m,get:()=>f.value||null}),o.appendChild(f)}else{const f=_(m.label,t.attrs[m.name]||"");f.style.flex="1",f.addEventListener("input",y),p.push({attr:m,get:()=>f.value.trim()||null}),o.appendChild(f)}const d=_("Content",t.body||"");d.style.flex="1.2",d.addEventListener("input",y),o.appendChild(d);const g=document.createElement("button");g.type="button",g.textContent="\xD7",g.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 J={row:o,fields:p,bodyInput:d,remove:g};g.addEventListener("click",()=>{b.length<=(n.children.min??1)||(b.splice(b.indexOf(J),1),o.remove(),k())}),o.appendChild(g),b.push(J),N.appendChild(o),window.I?.scan?.(o)}const q=ae[n.preview];let R=null;if(q){const t=document.createElement("div");t.style.cssText="background:var(--dm-background-alt,#111);border:1px solid var(--dm-border,#333);border-radius:4px;padding:.75rem;min-height:2.5rem;display:flex;align-items:center;overflow-x:auto;",R=document.createElement("span"),t.appendChild(R),u.appendChild(x("Preview",t))}const Y=ue();u.appendChild(x(c?"Tag preview":"Shortcode preview",Y.el));const j=document.createElement("div");j.style.cssText="display:flex;justify-content:flex-end;gap:.75rem;padding-top:.75rem;border-top:1px solid var(--dm-border,#333);";const A=document.createElement("button");A.type="button",A.className="btn btn-ghost",A.textContent="Cancel";const I=document.createElement("button");I.type="button",I.className="btn btn-primary",I.textContent=c?"Apply":`Insert ${n.label}`,j.appendChild(A),j.appendChild(I),u.appendChild(j);const H=()=>h&&b.length?buildChildrenBody(h,b.map(t=>({attrs:Object.fromEntries(t.fields.map(o=>[o.attr.name,o.get()]).filter(([,o])=>o!=null)),body:t.bodyInput.value}))):w?w.value:templateBody(n),V=()=>emitSnippet(n,S(),H(),z?.value),te=t=>{if(n.inline||n.selfClosing||!t.startsWith("["))return t;const o=e.value.slice(0,l),p=e.value.slice(r),d=o===""||o.endsWith(`
1
+ import{replaceRange as ce}from"./markdown-toolbar.js";import{boolState as de,boolValue as pe,parseAttrs as te,serialiseTag as ne,setAttrs as me}from"./shortcode-tags.js";import{SHORTCODES as ue}from"./shortcode-registry.js";import{clearLookupCache as fe,lookupOptions as he}from"./shortcode-lookups.js";import{PREVIEW_RENDERERS as ge}from"./shortcode-preview.js";import{dommaHelp as be,whenCatalogue as xe}from"./domma-catalogue.js";import{SHORTCODE_EXPIRY_FIELDS as ye}from"../../../public/js/shortcode-expiry.mjs";import{makeCheckbox as ve,makeColourInput as Ee,makeField as v,makeIconInput as oe,makeImageInput as le,makeLivePreview as Ce,makeSelect as W,makeTextInput as Y}from"./shortcode-modal.js";const we=new Map(ue.map(e=>[e.name,e])),se=new Set(ye.map(e=>e.name)),re=6;export function templateAttrs(e){const n=String(e.template||"").match(new RegExp(`^\\[${e.name}([\\s\\S]*?)\\s*/?\\]`));return n?te(n[1]):{}}export function templateBody(e){if(e.selfClosing)return"";const n=String(e.template||"").match(new RegExp(`^\\[${e.name}[^\\]]*\\]([\\s\\S]*)\\[/${e.name}\\]$`));return n?n[1].replace(/^\n/,"").replace(/\n$/,""):""}export function templateChildren(e){if(!e.children)return[];const n=e.children.name,a=new RegExp(`\\[${n}([^\\]]*)\\]([\\s\\S]*?)\\[/${n}\\]`,"g"),c=[];for(const l of templateBody(e).matchAll(a))c.push({attrs:te(l[1]),body:l[2].replace(/^\n/,"").replace(/\n$/,"")});return c}const ke=new Set(["lookup","url"]);export function seedAttrs(e,n){const a=new Map((e.attrs||[]).map(l=>[l.name,l.type])),c={};for(const[l,p]of Object.entries(n))ke.has(a.get(l))||(c[l]=p);return c}export function buildSnippet(e,n,a=""){const c=ne(e.name,n,e.selfClosing);if(e.selfClosing)return c;const l=`[/${e.name}]`;return e.inline?`${c}${a}${l}`:`${c}
2
+ ${a}
3
+ ${l}`}export function buildChildrenBody(e,n){return n.map(a=>buildSnippet(e,a.attrs,a.body)).join(`
4
+ `)}export function emitSnippet(e,n,a,c){const l=(e.formats||[]).find(p=>p.value===c);if(l&&typeof l.emit=="function"){const p=l.emit(n,a);if(p!=null)return p}return buildSnippet(e,n,a)}const Le="display:block;font-size:.7rem;font-weight:600;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;margin-bottom:.25rem;";function ie(e,n,a,c){const l=n===!0||n==null?"":String(n);if(e.type==="checkbox"){const s=ve(e.label),d=s.querySelector("input");return d.checked=de(n,e.default),d.addEventListener("change",a),{el:s,bare:!0,get:()=>pe(e,d.checked)}}if(e.type==="select"){const s=e.options.some(([w])=>w==="")?e.options:[["","- none -"],...e.options],d=W(s);return d.value=l,d.addEventListener("change",a),{el:v(e.label,d),get:()=>d.value||null}}if(e.type==="icon"){const{el:s,input:d}=oe("icon name (optional)",l);return d.addEventListener("input",a),{el:v(e.label,s),get:()=>d.value.trim()||null}}if(e.type==="image"){const{el:s,input:d}=le("/media/photo.jpg",l);return d.addEventListener("input",a),{el:v(e.label,s),get:()=>d.value.trim()||null}}if(e.type==="colour"){const{el:s,input:d}=Ee("#0f172a or a theme colour",l);return d.addEventListener("input",a),{el:v(e.label,s),get:()=>d.value.trim()||null}}if(e.type==="lookup"){const s=W([["","Loading\u2026"]]);s.disabled=!0,s.addEventListener("change",a);let d;const w=()=>{const h=c(),P=e.source==="collection-fields"?String(h.slug??""):e.source;P!==d&&(d=P,s.disabled=!0,he(e.source,h).then(f=>{const y=s.value||l,g=f.some(([T])=>T===y),k=[["","- none -"],...f];y&&!g&&k.push([y,`${y} (missing)`]),s.replaceChildren();for(const[T,b]of k){const $=document.createElement("option");$.value=T,$.textContent=b,s.appendChild($)}s.value=y,s.disabled=!1,a()}))};return w(),{el:v(e.label,s),get:()=>s.value||null,refresh:e.source==="collection-fields"?w:null}}const p=Y(e.placeholder||(e.type==="url"?"/about or https://example.com":""),l);return e.type==="number"&&(p.type="number"),p.addEventListener("input",a),{el:v(e.label,p),get:()=>p.value.trim()||null}}function Se(e,n){xe(a=>{const c=be(a,n);if(!c)return;const l=document.createElement("small");l.className="sc-domma-help",l.style.cssText="display:block;margin-top:.2rem;font-size:.75em;color:var(--dm-text-muted,#999);",l.textContent=c,e.appendChild(l)})}export function openShortcodeForm(e,n,a={}){const{span:c=null,defaults:l=null}=a,p=!!c;fe();const s=e.selectionStart,d=e.selectionEnd,w=e.value.slice(s,d),h=n.children?we.get(n.children.name):null,P={...seedAttrs(n,templateAttrs(n)),...l||{}},f=document.createElement("div");f.style.cssText="padding:.25rem 0 .5rem;display:flex;flex-direction:column;gap:.75rem;";const y=[],g=[];let k=()=>{};const T=()=>{const t={};for(const{attr:o,w:m}of y){const r=m.get();r!=null&&r!==""&&(t[o.name]=r)}return t},b=()=>k(),$=()=>T();let _=null;!p&&n.formats?.length&&(_=W(n.formats.map(t=>[t.value,t.label])),_.addEventListener("change",b),f.appendChild(v("Format",_)));const R=n.attrs||[],D=R.length>re+2?re:R.length,q=(t,o)=>{const m=p?c.attrs[t.name]:P[t.name],r=ie(t,m,b,$);y.push({attr:t,w:r,initial:r.get()});const x=t.domma&&r.bare?document.createElement("div"):r.el;x!==r.el&&x.appendChild(r.el),o.appendChild(x),t.domma&&Se(x,t)};for(const t of R.slice(0,D))q(t,f);if(D<R.length){const t=document.createElement("details");t.style.cssText="border-top:1px solid var(--dm-border,#333);padding-top:.6rem;";const o=document.createElement("summary");o.textContent=`More options (${R.length-D})`,o.style.cssText="cursor:pointer;font-size:.75rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",t.appendChild(o);const m=document.createElement("div");m.style.cssText="display:flex;flex-direction:column;gap:.75rem;padding-top:.75rem;",t.appendChild(m);for(const r of R.slice(D))q(r,m);f.appendChild(t)}let L=null,S=null;const F=document.createElement("div");if(!p&&h){const t=document.createElement("div");t.style.cssText=Le,t.textContent=`${h.label}s`,f.appendChild(t),F.style.cssText="display:flex;flex-direction:column;gap:.4rem;",f.appendChild(F),S=document.createElement("button"),S.type="button",S.textContent=`+ Add ${h.label.toLowerCase()}`,S.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;",S.addEventListener("click",()=>{V({attrs:{},body:templateBody(h)||"Content"}),k()}),f.appendChild(S);const o=templateChildren(n),m=o.length?o:[{attrs:{},body:"Content"}];for(const r of m)V({attrs:seedAttrs(h,r.attrs),body:r.body});w&&(g[0].bodyInput.value=w)}else!p&&!n.selfClosing&&(L=document.createElement("textarea"),L.rows=n.inline?2:4,L.value=w||templateBody(n),L.style.cssText="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;font-family:inherit;box-sizing:border-box;resize:vertical;",L.addEventListener("input",b),f.appendChild(v("Content",L)));function V(t){if(g.length>=(n.children.max??20))return;const o=document.createElement("div");o.style.cssText="display:flex;flex-direction:column;gap:.25rem;";const m=document.createElement("div");m.style.cssText="display:flex;gap:.35rem;align-items:center;",o.appendChild(m);const r=[],x=(h.attrs||[]).filter(i=>!se.has(i.name)),H=(h.attrs||[]).filter(i=>se.has(i.name));for(const i of x)if(i.type==="icon"){const{el:u,input:C}=oe(i.label.toLowerCase(),t.attrs[i.name]||"");u.style.flex=".7",C.addEventListener("input",b),r.push({attr:i,get:()=>C.value.trim()||null}),m.appendChild(u)}else if(i.type==="image"){const{el:u,input:C}=le(i.label,t.attrs[i.name]||"");u.style.flex="1",C.addEventListener("input",b),r.push({attr:i,get:()=>C.value.trim()||null}),m.appendChild(u)}else if(i.type==="select"){const u=W(i.options);u.value=t.attrs[i.name]||i.options[0][0],u.style.flex=".7",u.addEventListener("change",b),r.push({attr:i,get:()=>u.value||null}),m.appendChild(u)}else{const u=Y(i.label,t.attrs[i.name]||"");u.style.flex="1",u.addEventListener("input",b),r.push({attr:i,get:()=>u.value.trim()||null}),m.appendChild(u)}const M=Y("Content",t.body||"");M.style.flex="1.2",M.addEventListener("input",b),m.appendChild(M);const A=document.createElement("button");if(A.type="button",A.textContent="\xD7",A.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;",H.length){const i=document.createElement("details");i.style.cssText="margin-left:.15rem;";const u=document.createElement("summary");u.textContent="Expiry",u.style.cssText="cursor:pointer;font-size:.7rem;color:var(--dm-text-muted,#aaa);text-transform:uppercase;letter-spacing:.05em;",i.appendChild(u);const C=document.createElement("div");C.style.cssText="display:flex;flex-direction:column;gap:.6rem;padding:.5rem 0 .25rem .75rem;",i.appendChild(C);for(const z of H){const ee=ie(z,t.attrs[z.name],b,$);r.push({attr:z,get:ee.get}),C.appendChild(ee.el)}H.some(z=>t.attrs[z.name]!=null)&&(i.open=!0),o.appendChild(i)}const Z={row:o,fields:r,bodyInput:M,remove:A};A.addEventListener("click",()=>{g.length<=(n.children.min??1)||(g.splice(g.indexOf(Z),1),o.remove(),k())}),m.appendChild(A),g.push(Z),F.appendChild(o),window.I?.scan?.(o)}const X=ge[n.preview];let I=null;if(X){const t=document.createElement("div");t.style.cssText="background:var(--dm-background-alt,#111);border:1px solid var(--dm-border,#333);border-radius:4px;padding:.75rem;min-height:2.5rem;display:flex;align-items:center;overflow-x:auto;",I=document.createElement("span"),t.appendChild(I),f.appendChild(v("Preview",t))}const K=Ce();f.appendChild(v(p?"Tag preview":"Shortcode preview",K.el));const N=document.createElement("div");N.style.cssText="display:flex;justify-content:flex-end;gap:.75rem;padding-top:.75rem;border-top:1px solid var(--dm-border,#333);";const B=document.createElement("button");B.type="button",B.className="btn btn-ghost",B.textContent="Cancel";const O=document.createElement("button");O.type="button",O.className="btn btn-primary",O.textContent=p?"Apply":`Insert ${n.label}`,N.appendChild(B),N.appendChild(O),f.appendChild(N);const G=()=>h&&g.length?buildChildrenBody(h,g.map(t=>({attrs:Object.fromEntries(t.fields.map(o=>[o.attr.name,o.get()]).filter(([,o])=>o!=null)),body:t.bodyInput.value}))):L?L.value:templateBody(n),J=()=>emitSnippet(n,T(),G(),_?.value),ae=t=>{if(n.inline||n.selfClosing||!t.startsWith("["))return t;const o=e.value.slice(0,s),m=e.value.slice(d),r=o===""||o.endsWith(`
5
5
  `)?"":`
6
- `,g=p===""||p.startsWith(`
6
+ `,x=m===""||m.startsWith(`
7
7
  `)?"":`
8
- `;return`${d}${t}${g}`};k=()=>{L&&(L.disabled=b.length>=(n.children.max??20));for(const{w:t}of v)t.refresh?.();if(R){const t=q(c?{...a.attrs,...K()}:S(),c?"":H());R.style.cssText=t.css,R.textContent=t.text}Y.update(c?U(a.name,{...a.attrs,...G()},a.selfClosing,{keepEmpty:!!n.block}):V())};function K(){const t={};for(const{attr:o,w:p,initial:d}of v){const g=p.get();g!==d&&(t[o.name]=g)}return t}function G(){const t=K();if(n.block)for(const o of Object.keys(t))t[o]==null&&(t[o]="");return t}const W=E.slideover({title:c?`Edit ${n.label}`:`Insert ${n.label}`,size:h?"lg":"md",position:"right",content:u});return W.open(),window.I?.scan?.(u),k(),A.addEventListener("click",()=>W.close()),I.addEventListener("click",()=>{if(W.close(),c)se(e,a,G(),{keepEmpty:!!n.block});else{const t=te(V());ne(e,l,r,t),e.setSelectionRange(l+t.length,l+t.length)}e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}),requestAnimationFrame(()=>{u.querySelector("input:not([type=checkbox]):not([type=color]), select, textarea")?.focus()}),W}
8
+ `;return`${r}${t}${x}`};k=()=>{S&&(S.disabled=g.length>=(n.children.max??20));for(const{w:t}of y)t.refresh?.();if(I){const t=X(p?{...c.attrs,...Q()}:T(),p?"":G());I.style.cssText=t.css,I.textContent=t.text}K.update(p?ne(c.name,{...c.attrs,...U()},c.selfClosing,{keepEmpty:!!n.block}):J())};function Q(){const t={};for(const{attr:o,w:m,initial:r}of y){const x=m.get();x!==r&&(t[o.name]=x)}return t}function U(){const t=Q();if(n.block)for(const o of Object.keys(t))t[o]==null&&(t[o]="");return t}const j=E.slideover({title:p?`Edit ${n.label}`:`Insert ${n.label}`,size:h?"lg":"md",position:"right",content:f});return j.open(),window.I?.scan?.(f),k(),B.addEventListener("click",()=>j.close()),O.addEventListener("click",()=>{if(j.close(),p)me(e,c,U(),{keepEmpty:!!n.block});else{const t=ae(J());ce(e,s,d,t),e.setSelectionRange(s+t.length,s+t.length)}e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}),requestAnimationFrame(()=>{f.querySelector("input:not([type=checkbox]):not([type=color]), select, textarea")?.focus()}),j}
@@ -20,7 +20,7 @@ Right
20
20
  Content
21
21
  [/col]`,attrs:[{name:"span",type:"number",label:"Span"},{name:"align",type:"select",label:"Content alignment",options:[["","Inherit"],["left","Left"],["center","Centre"],["centre","Centre (alias)"],["right","Right"]]},{name:"id",type:"text",label:"ID"}]},{name:"slideover",label:"Slideover",icon:"panel-right",category:"Layout",selfClosing:!1,container:!0,wrappable:!0,template:`[slideover title="More information" trigger="Read more"]
22
22
  Content
23
- [/slideover]`,attrs:[{name:"title",type:"text",label:"Title"},{name:"trigger",type:"text",label:"Trigger label"},{name:"size",type:"select",label:"Size",options:[["sm","Small"],["md","Medium"],["lg","Large"]]},{name:"position",type:"select",label:"Position",options:[["right","Right"],["left","Left"]]}]},{name:"center",label:"Centre",icon:"text-center",category:"Layout",selfClosing:!1,container:!0,wrappable:!0,template:`[center]
23
+ [/slideover]`,attrs:[{name:"title",type:"text",label:"Title",domma:"slideover.title"},{name:"trigger",type:"text",label:"Trigger label"},{name:"size",type:"select",label:"Size",options:[["sm","Small"],["md","Medium"],["lg","Large"],["xl","Extra large"],["full","Full width"]],domma:"slideover.size"},{name:"position",type:"select",label:"Position",options:[["right","Right"],["left","Left"],["bottom","Bottom"],["top","Top"]],domma:"slideover.position"}]},{name:"center",label:"Centre",icon:"text-center",category:"Layout",selfClosing:!1,container:!0,wrappable:!0,template:`[center]
24
24
  Centred content
25
25
  [/center]`,attrs:[{name:"class",type:"text",label:"CSS class"}]},{name:"spacer",label:"Spacer",icon:"spacer-insert",category:"Layout",selfClosing:!0,container:!1,wrappable:!1,template:'[spacer size="24" /]',attrs:[{name:"size",type:"number",label:"Height (px)"},{name:"class",type:"text",label:"CSS class"}]},{name:"banner",label:"Banner",icon:"banner-insert",category:"Layout",selfClosing:!1,container:!0,wrappable:!0,template:`[banner type="info" title="Note"]
26
26
  Banner content
@@ -30,12 +30,12 @@ Banner content
30
30
  [/tabs]`,children:{name:"tab",min:2,max:10},attrs:[{name:"style",type:"select",label:"Style",options:[["","Underline"],["pills","Pills"],["bordered","Bordered"]]},{name:"align",type:"select",label:"Alignment",options:[["","Left"],["center","Centre"],["right","Right"]]},{name:"fade",type:"checkbox",label:"Fade panels"},{name:"id",type:"text",label:"ID"}]},{name:"tab",label:"Tab",icon:"layout-list",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[tab title="Tab title"]Content[/tab]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"},{name:"icon",type:"icon",label:"Icon"}]},{name:"accordion",label:"Accordion",icon:"accordion-insert",category:"Components",selfClosing:!1,container:!0,wrappable:!1,template:`[accordion]
31
31
  [item title="Question 1"]Answer 1.[/item]
32
32
  [item title="Question 2"]Answer 2.[/item]
33
- [/accordion]`,children:{name:"item",min:2,max:12},attrs:[{name:"multiple",type:"checkbox",label:"Allow multiple open"},{name:"id",type:"text",label:"ID"}]},{name:"item",label:"Item",icon:"list",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[item title="Item title"]Content[/item]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"}]},{name:"carousel",label:"Carousel",icon:"carousel-insert",category:"Components",selfClosing:!1,container:!0,wrappable:!1,template:`[carousel autoplay="true" interval="5000"]
33
+ [/accordion]`,children:{name:"item",min:2,max:12},attrs:[{name:"multiple",type:"checkbox",label:"Allow multiple open",domma:"accordion.allowMultiple"},{name:"id",type:"text",label:"ID"}]},{name:"item",label:"Item",icon:"list",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[item title="Item title"]Content[/item]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"}]},{name:"carousel",label:"Carousel",icon:"carousel-insert",category:"Components",selfClosing:!1,container:!0,wrappable:!1,template:`[carousel autoplay="true" interval="5000"]
34
34
  [slide title="Slide 1" image="/media/photo.jpg"]Caption.[/slide]
35
35
  [slide title="Slide 2"]Text-only slide.[/slide]
36
- [/carousel]`,children:{name:"slide",min:2,max:12},quickAttrs:["height-mode","height","arrow-position","background","arrow-background","arrow-color"],attrs:[{name:"autoplay",type:"checkbox",label:"Autoplay"},{name:"interval",type:"number",label:"Interval (ms)"},{name:"loop",type:"checkbox",label:"Loop"},{name:"animation",type:"select",label:"Animation",options:[["slide","Slide"],["fade","Fade"],["crossfade","Crossfade"]]},{name:"animation-duration",type:"number",label:"Animation duration (ms)"},{name:"animation-easing",type:"text",label:"Animation easing"},{name:"height-mode",type:"select",label:"Image height",options:[["crop","Top-aligned crop (shortest image)"],["average","Average of shortest and tallest images"]]},{name:"height",type:"number",label:"Fixed height (px, optional)"},{name:"mobile-popup",type:"checkbox",label:"Open carousel cards in a popup on mobile"},{name:"arrow-position",type:"select",label:"Arrow position",options:[["middle","Middle"],["top","Top"],["bottom","Bottom"]]},{name:"background",type:"colour",label:"Background colour"},{name:"arrow-background",type:"colour",label:"Arrow background"},{name:"arrow-color",type:"colour",label:"Arrow colour"},{name:"id",type:"text",label:"ID"}]},{name:"slide",label:"Slide",icon:"image",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[slide title="Slide title" image="/media/photo.jpg"]Caption[/slide]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"},{name:"image",type:"image",label:"Image"}]},{name:"countdown",label:"Countdown",icon:"stopwatch",category:"Components",selfClosing:!0,container:!1,wrappable:!1,template:'[countdown to="2026-12-31" format="DD:HH:mm:ss" /]',attrs:[{name:"to",type:"text",label:"Target date (ISO)"},{name:"duration",type:"number",label:"Duration (seconds)"},{name:"format",type:"select",label:"Format",options:[["mm:ss","mm:ss"],["HH:mm:ss","HH:mm:ss"],["DD:HH:mm:ss","DD:HH:mm:ss"]]},{name:"id",type:"text",label:"ID"}]},{name:"timeline",label:"Timeline",icon:"activity",category:"Components",selfClosing:!1,container:!0,wrappable:!1,template:`[timeline layout="vertical" theme="modern"]
36
+ [/carousel]`,children:{name:"slide",min:2,max:12},quickAttrs:["height-mode","height","arrow-position","background","arrow-background","arrow-color"],attrs:[{name:"autoplay",type:"checkbox",label:"Autoplay",domma:"carousel.autoplay"},{name:"interval",type:"number",label:"Interval (ms)",domma:"carousel.interval"},{name:"loop",type:"checkbox",label:"Loop",default:!0,domma:"carousel.loop"},{name:"animation",type:"select",label:"Animation",options:[["slide","Slide"],["fade","Fade"],["crossfade","Crossfade"]],domma:"carousel.animation"},{name:"animation-duration",type:"number",label:"Animation duration (ms)",domma:"carousel.animationDuration"},{name:"animation-easing",type:"text",label:"Animation easing",domma:"carousel.animationEasing"},{name:"height-mode",type:"select",label:"Image height",options:[["crop","Top-aligned crop (shortest image)"],["average","Average of shortest and tallest images"]],domma:"carousel.heightMode"},{name:"height",type:"number",label:"Fixed height (px, optional)",domma:"carousel.height"},{name:"mobile-popup",type:"checkbox",label:"Open carousel cards in a popup on mobile"},{name:"arrow-position",type:"select",label:"Arrow position",options:[["middle","Middle"],["top","Top"],["bottom","Bottom"]]},{name:"background",type:"colour",label:"Background colour"},{name:"arrow-background",type:"colour",label:"Arrow background"},{name:"arrow-color",type:"colour",label:"Arrow colour"},{name:"id",type:"text",label:"ID"}]},{name:"slide",label:"Slide",icon:"image",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[slide title="Slide title" image="/media/photo.jpg"]Caption[/slide]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"},{name:"image",type:"image",label:"Image"}]},{name:"countdown",label:"Countdown",icon:"stopwatch",category:"Components",selfClosing:!0,container:!1,wrappable:!1,template:'[countdown to="2026-12-31" format="DD:HH:mm:ss" /]',attrs:[{name:"to",type:"text",label:"Target date (ISO)"},{name:"duration",type:"number",label:"Duration (seconds)"},{name:"format",type:"select",label:"Format",options:[["mm:ss","mm:ss"],["HH:mm:ss","HH:mm:ss"],["DD:HH:mm:ss","DD:HH:mm:ss"]],domma:"timer.format"},{name:"id",type:"text",label:"ID"}]},{name:"timeline",label:"Timeline",icon:"activity",category:"Components",selfClosing:!1,container:!0,wrappable:!1,template:`[timeline layout="vertical" theme="modern"]
37
37
  [event title="Launch" date="2025-01-15" status="completed"]Launched.[/event]
38
- [/timeline]`,children:{name:"event",min:1,max:20},custom:"timeline",attrs:[{name:"layout",type:"select",label:"Layout",options:[["vertical","Vertical"],["centred","Centred"],["horizontal","Horizontal"]]},{name:"theme",type:"select",label:"Theme",options:[["minimal","Minimal"],["corporate","Corporate"],["modern","Modern"]]},{name:"mode",type:"select",label:"Mode",options:[["timeline","Timeline"],["roadmap","Roadmap"]]},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"event",label:"Event",icon:"dot",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[event title="Milestone" date="2025-01-15" status="completed"]Description[/event]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"},{name:"date",type:"text",label:"Date"},{name:"status",type:"select",label:"Status",options:[["planned","Planned"],["in-progress","In progress"],["completed","Completed"],["blocked","Blocked"]]},{name:"icon",type:"icon",label:"Icon"}]},{name:"hero",label:"Hero",icon:"hero",category:"Content",selfClosing:!1,container:!0,wrappable:!0,template:`[hero title="Welcome" tagline="Build something great" size="lg" variant="gradient-blue"]
38
+ [/timeline]`,children:{name:"event",min:1,max:20},custom:"timeline",attrs:[{name:"layout",type:"select",label:"Layout",options:[["vertical","Vertical"],["centred","Centred"],["horizontal","Horizontal"]],domma:"progression.layout",dommaValues:{centred:"centered"}},{name:"theme",type:"select",label:"Theme",options:[["minimal","Minimal"],["corporate","Corporate"],["modern","Modern"]],domma:"progression.theme"},{name:"mode",type:"select",label:"Mode",options:[["timeline","Timeline"],["roadmap","Roadmap"]],domma:"progression.mode"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"event",label:"Event",icon:"dot",category:"Components",child:!0,selfClosing:!1,container:!0,wrappable:!1,template:'[event title="Milestone" date="2025-01-15" status="completed"]Description[/event]',inline:!0,attrs:[{name:"title",type:"text",label:"Title"},{name:"date",type:"text",label:"Date"},{name:"status",type:"select",label:"Status",options:[["planned","Planned"],["in-progress","In progress"],["completed","Completed"],["blocked","Blocked"]]},{name:"icon",type:"icon",label:"Icon"}]},{name:"hero",label:"Hero",icon:"hero",category:"Content",selfClosing:!1,container:!0,wrappable:!0,template:`[hero title="Welcome" tagline="Build something great" size="lg" variant="gradient-blue"]
39
39
  Optional body content.
40
40
  [/hero]`,attrs:[{name:"title",type:"text",label:"Title"},{name:"tagline",type:"text",label:"Tagline"},{name:"size",type:"select",label:"Size",options:[["","Default"],["sm","Small"],["lg","Large"],["xl","Extra large"],["full","Full"]]},{name:"fullwidth",type:"checkbox",label:"Break out full-width"},{name:"variant",type:"select",label:"Variant",options:[["","None"],["dark","Dark"],["primary","Primary"],["gradient-purple","Gradient purple"],["gradient-blue","Gradient blue"],["gradient-green","Gradient green"],["gradient-sunset","Gradient sunset"],["gradient-ocean","Gradient ocean"],["gradient-rose","Gradient rose"],["gradient-forest","Gradient forest"],["gradient-night","Gradient night"]]},{name:"image",type:"image",label:"Background image"},{name:"overlay",type:"select",label:"Overlay",options:[["","None"],["light","Light"],["dark","Dark"],["darker","Darker"],["gradient","Gradient"],["gradient-reverse","Gradient reverse"]]},{name:"align",type:"select",label:"Content alignment",options:[["center","Centre"],["left","Left"]]},{name:"bg-fit",type:"select",label:"Background fit",options:[["","Fill area (default)"],["contain","Show whole image"],["cover","Fill area (crop)"]]},{name:"bg-x",type:"select",label:"Background horizontal position",options:[["center","Centre"],["left","Left"],["right","Right"]]},{name:"bg-y",type:"select",label:"Background vertical position",options:[["center","Centre"],["top","Top"],["bottom","Bottom"]]},{name:"bg",type:"colour",label:"Background colour"},{name:"color",type:"colour",label:"Background colour (alias)"},{name:"min-height",type:"text",label:"Min height"},{name:"twinkle",type:"checkbox",label:"Twinkle particles"},{name:"twinkle-count",type:"number",label:"Twinkle count"},{name:"twinkle-colour",type:"colour",label:"Twinkle colour"},{name:"blobs",type:"checkbox",label:"Ambient blobs"},{name:"blobs-type",type:"text",label:"Blobs type"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"table",label:"Table",icon:"grid",category:"Content",selfClosing:!1,container:!1,wrappable:!1,template:`[table striped="true"]
41
41
  | Product | Price |
@@ -44,4 +44,4 @@ Optional body content.
44
44
  [/table]`,attrs:[{name:"striped",type:"checkbox",label:"Striped"},{name:"bordered",type:"checkbox",label:"Bordered"},{name:"compact",type:"checkbox",label:"Compact"},{name:"caption",type:"text",label:"Caption"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"badge",label:"Badge",icon:"badge",category:"Content",selfClosing:!1,container:!1,wrappable:!1,template:'[badge variant="success"]New[/badge]',inline:!0,attrs:[{name:"variant",type:"select",label:"Variant",options:[["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"],["light","Light"],["dark","Dark"]]},{name:"pill",type:"checkbox",label:"Pill"},{name:"outline",type:"checkbox",label:"Outline"},{name:"size",type:"select",label:"Size",options:[["","Default"],["small","Small"],["large","Large"]]}]},{name:"text",label:"Text",icon:"text-style",preview:"text",category:"Content",selfClosing:!1,container:!0,wrappable:!0,template:"[text]Styled text[/text]",inline:!0,attrs:[{name:"size",type:"select",label:"Size",options:[["xs","XS"],["sm","Small"],["base","Base"],["lg","Large"],["xl","XL"],["2xl","2XL"],["3xl","3XL"],["4xl","4XL"]]},{name:"weight",type:"select",label:"Weight",options:[["thin","Thin"],["light","Light"],["normal","Normal"],["medium","Medium"],["semibold","Semibold"],["bold","Bold"],["extrabold","Extra bold"],["black","Black"]]},{name:"point-size",type:"number",label:"Point size"},{name:"bold",type:"checkbox",label:"Bold"},{name:"italic",type:"checkbox",label:"Italic"},{name:"color",type:"colour",label:"Colour"},{name:"font",type:"select",label:"Font",options:[["Georgia","Georgia"],["Arial","Arial"],["Verdana","Verdana"],["Courier New","Courier New"],["Times New Roman","Times New Roman"],["Trebuchet MS","Trebuchet MS"]]},{name:"transform",type:"select",label:"Transform",options:[["upper","Uppercase"],["lower","Lowercase"],["capitalize","Capitalise"],["none","None"]]},{name:"decoration",type:"select",label:"Decoration",options:[["underline","Underline"],["line-through","Line through"],["none","None"]]},{name:"spacing",type:"select",label:"Letter spacing",options:[["tight","Tight"],["normal","Normal"],["wide","Wide"],["wider","Wider"]]},{name:"align",type:"select",label:"Align",options:[["","None"],["left","Left"],["center","Centre"],["right","Right"]]},{name:"style",type:"text",label:"Inline CSS"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"button",label:"Button",icon:"btn-insert",category:"Content",selfClosing:!0,container:!1,wrappable:!1,template:'[button href="/contact" variant="primary" label="Get in touch" /]',attrs:[{name:"href",type:"url",label:"Link"},{name:"label",type:"text",label:"Label"},{name:"variant",type:"select",label:"Variant",options:[["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"],["outline","Outline"],["ghost","Ghost"],["link","Link"],["outline-success","Outline success"],["outline-danger","Outline danger"],["outline-warning","Outline warning"],["outline-info","Outline info"]]},{name:"size",type:"select",label:"Size",options:[["","Default"],["sm","Small"],["lg","Large"]]},{name:"icon",type:"icon",label:"Icon (before)"},{name:"icon-after",type:"icon",label:"Icon (after)"},{name:"target",type:"text",label:"Target"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"link",label:"Link",icon:"link-shortcode",category:"Content",selfClosing:!0,container:!1,wrappable:!1,template:'[link href="/about" label="About us" /]',formats:[{value:"markdown",label:"Markdown link",emit:e=>Object.keys(e).some(t=>t!=="href"&&t!=="label"&&e[t])||!e.href?null:`[${e.label||e.href}](${e.href})`},{value:"shortcode",label:"Link shortcode"}],attrs:[{name:"href",type:"url",label:"Link"},{name:"label",type:"text",label:"Label"},{name:"target",type:"text",label:"Target"},{name:"class",type:"text",label:"CSS class"},{name:"icon",type:"icon",label:"Icon (before)"},{name:"icon-after",type:"icon",label:"Icon (after)"},{name:"id",type:"text",label:"ID"}]},{name:"listgroup",label:"List group",icon:"list",category:"Content",selfClosing:!1,container:!0,wrappable:!1,template:`[listgroup]
45
45
  [item]First item[/item]
46
46
  [item]Second item[/item]
47
- [/listgroup]`,children:{name:"item",min:1,max:20},attrs:[{name:"variant",type:"select",label:"Variant",options:[["","Default"],["flush","Flush"],["numbered","Numbered"],["horizontal","Horizontal"]]},{name:"size",type:"select",label:"Size",options:[["","Default"],["sm","Small"],["lg","Large"]]},{name:"itemvariant",type:"select",label:"Item variant",options:[["","Default"],["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]},{name:"action",type:"checkbox",label:"Actionable items"}]},{name:"collection",label:"Collection",icon:"database",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[collection slug="enquiries" display="table" /]',attrs:[{name:"slug",type:"lookup",source:"collections",label:"Collection"},{name:"display",type:"select",label:"Display",options:[["table","Table"],["cards","Cards"],["list","List"],["accordion","Accordion"],["timeline","Timeline"],["carousel","Carousel"],["block","Block"]]},{name:"fields",type:"text",label:"Fields (comma-separated)"},{name:"limit",type:"number",label:"Limit"},{name:"sort",type:"lookup",source:"collection-fields",label:"Sort field"},{name:"order",type:"select",label:"Order",options:[["desc","Descending"],["asc","Ascending"]]},{name:"title-field",type:"lookup",source:"collection-fields",label:"Title field"},{name:"image-field",type:"lookup",source:"collection-fields",label:"Image field"},{name:"body-field",type:"lookup",source:"collection-fields",label:"Body field"},{name:"mobile-popup",type:"checkbox",label:"Open carousel cards in a popup on mobile"},{name:"arrow-position",type:"select",label:"Arrow position",options:[["middle","Middle"],["top","Top"],["bottom","Bottom"]]},{name:"background",type:"colour",label:"Carousel background"},{name:"arrow-background",type:"colour",label:"Arrow background"},{name:"arrow-color",type:"colour",label:"Arrow colour"},{name:"autoplay",type:"checkbox",label:"Autoplay"},{name:"interval",type:"number",label:"Interval (ms)"},{name:"loop",type:"checkbox",label:"Loop"},{name:"animation",type:"select",label:"Animation",options:[["slide","Slide"],["fade","Fade"],["crossfade","Crossfade"]]},{name:"columns",type:"number",label:"Card columns"},{name:"search",type:"checkbox",label:"Search (table)",default:!0},{name:"sortable",type:"checkbox",label:"Sortable (table)",default:!0},{name:"exportable",type:"checkbox",label:"CSV export"},{name:"page-size",type:"number",label:"Page size"},{name:"empty",type:"text",label:"Empty message"},{name:"scope",type:"select",label:"Scope",options:[["","All"],["mine","Current user"]]},{name:"cta",type:"lookup",source:"actions",label:"CTA action"},{name:"cta-label",type:"text",label:"CTA label"},{name:"cta-icon",type:"icon",label:"CTA icon"},{name:"cta-style",type:"select",label:"CTA style",options:[["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]},{name:"cta-confirm",type:"text",label:"CTA confirm text"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"view",label:"View",icon:"eye",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[view slug="products" display="table" limit="50" /]',attrs:[{name:"slug",type:"lookup",source:"views",label:"View"},{name:"display",type:"select",label:"Display",options:[["table","Table"],["cards","Cards"],["list","List"],["accordion","Accordion"],["timeline","Timeline"],["carousel","Carousel"],["block","Block"]]},{name:"limit",type:"number",label:"Limit"},{name:"fields",type:"text",label:"Fields (comma-separated)"},{name:"title-field",type:"text",label:"Title field"},{name:"image-field",type:"text",label:"Image field"},{name:"body-field",type:"text",label:"Body field"},{name:"mobile-popup",type:"checkbox",label:"Open carousel cards in a popup on mobile"},{name:"arrow-position",type:"select",label:"Arrow position",options:[["middle","Middle"],["top","Top"],["bottom","Bottom"]]},{name:"background",type:"colour",label:"Carousel background"},{name:"arrow-background",type:"colour",label:"Arrow background"},{name:"arrow-color",type:"colour",label:"Arrow colour"},{name:"autoplay",type:"checkbox",label:"Autoplay"},{name:"interval",type:"number",label:"Interval (ms)"},{name:"loop",type:"checkbox",label:"Loop"},{name:"animation",type:"select",label:"Animation",options:[["slide","Slide"],["fade","Fade"],["crossfade","Crossfade"]]},{name:"columns",type:"number",label:"Card columns"},{name:"empty",type:"text",label:"Empty message"}]},{name:"block",label:"Block",icon:"layout",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[block template="post-card" title="My Post" /]',attrs:[{name:"template",type:"lookup",source:"blocks",label:"Template"}]},{name:"form",label:"Form",icon:"file-text",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[form name="contact" /]',attrs:[{name:"name",type:"lookup",source:"forms",label:"Form"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"cta",label:"CTA",icon:"mouse-pointer",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[cta action="send-welcome" entry="abc123" style="primary" label="Send" /]',attrs:[{name:"action",type:"lookup",source:"actions",label:"Action"},{name:"entry",type:"text",label:"Entry ID"},{name:"style",type:"select",label:"Style",options:[["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]},{name:"icon",type:"icon",label:"Icon"},{name:"size",type:"select",label:"Size",options:[["","Default"],["sm","Small"],["lg","Large"]]},{name:"confirm",type:"text",label:"Confirm text"},{name:"label",type:"text",label:"Label"}]},{name:"menu",label:"Menu",icon:"menu",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[menu slug="legal" /]',attrs:[{name:"slug",type:"lookup",source:"menus",label:"Menu"},{name:"location",type:"lookup",source:"menu-locations",label:"Location slot"},{name:"variant",type:"text",label:"Variant"},{name:"class",type:"text",label:"CSS class"},{name:"depth",type:"number",label:"Max depth"},{name:"orientation",type:"select",label:"Orientation",options:[["","Menu default"],["horizontal","Horizontal"],["vertical","Vertical"]]},{name:"float",type:"select",label:"Floating",options:[["","Menu default"],["no","Render inline here"]]}]},{name:"contents",label:"Page contents (this page)",icon:"list",category:"Layout",selfClosing:!0,container:!1,wrappable:!1,template:'[contents numbered="true" /]',actions:[{label:"Number the contents",icon:"hash",set:{numbered:"true"}},{label:"List H2 and H3 headings",icon:"list",set:{headings:"h2h3"}},{label:"Contents on the right",icon:"sidebar-right",set:{side:"right"}},{label:"Collapse the contents to a button",icon:"minimize",set:{collapsible:"true",collapsed:"true"}},{label:"Float the contents",icon:"move",set:{floating:"true","float-anchor":"TR",movable:"true"}},{label:"No contents on this page",icon:"eye-off",set:{hidden:"true"}},{label:"Remove this override",icon:"trash",remove:!0}],quickAttrs:["side","headings","numbered","title","collapsible","floating","hidden"],attrs:[{name:"side",type:"select",label:"Side",options:[["","Layout default"],["left","Left"],["right","Right"]]},{name:"width",type:"number",label:"Width (px, 160-480)"},{name:"headings",type:"select",label:"Headings",options:[["","Layout default"],["auto","Sections (H2s, else H3s)"],["h2","H2 only"],["h3","H3 only"],["h2h3","H2 and H3"]]},{name:"numbered",type:"select",label:"Numbered",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"title",type:"text",label:"Title above the list"},{name:"exclude",type:"text",label:"Leave out (headings, comma separated)"},{name:"sticky",type:"select",label:"Stays in view",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"scroll-spy",type:"select",label:"Marks the section being read",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"collapsible",type:"select",label:"Collapsible to a button",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"collapsed",type:"select",label:"Start collapsed",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"autohide",type:"select",label:"Autohide off its edge",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"floating",type:"select",label:"Floating panel",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"float-anchor",type:"select",label:"Float anchor",options:[["","Layout default"],["TL","Top left"],["TR","Top right"],["BL","Bottom left"],["BR","Bottom right"],["L","Left"],["R","Right"]]},{name:"movable",type:"select",label:"Visitors can move it",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"hidden",type:"select",label:"No contents on this page",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"hover",type:"text",label:"Hover effect"},{name:"selected",type:"text",label:"When selected"},{name:"accent",type:"colour",label:"Accent"},{name:"font",type:"text",label:"Font family"},{name:"font-size",type:"text",label:"Font size"},{name:"font-weight",type:"text",label:"Font weight"}]},{name:"navbar",label:"Navbar settings (this page)",icon:"sliders",category:"Layout",selfClosing:!0,container:!1,wrappable:!1,template:'[navbar collapsed="true" /]',actions:[{label:"Collapse the rail on this page",icon:"chevrons-right",set:{collapsible:"true",collapsed:"true",autohide:"false"}},{label:"Autohide the rail on this page",icon:"eye-off",set:{autohide:"true",collapsed:null}},{label:"Keep the rail open on this page",icon:"eye",set:{autohide:"false",collapsed:"false"}},{label:"Hide the bar on scroll on this page",icon:"arrow-up",set:{"hide-on-scroll":"true"}},{label:"Remove this override",icon:"trash",remove:!0}],quickAttrs:["position","width","collapsible","collapsed","autohide","hide-on-scroll"],attrs:[{name:"position",type:"select",label:"Position",options:[["","Menu default"],["sticky","Sticky"],["fixed","Fixed"],["static","Static"],["floating","Floating"]]},{name:"orientation",type:"select",label:"Orientation",options:[["","Menu default"],["horizontal","Horizontal"],["vertical","Vertical"]]},{name:"side",type:"select",label:"Rail side",options:[["","Menu default"],["left","Left"],["right","Right"]]},{name:"align",type:"select",label:"Alignment",options:[["","Menu default"],["left","Left"],["centre","Centre"],["right","Right"],["spread","Spread"]]},{name:"width",type:"number",label:"Rail width (px, 160-480)"},{name:"collapsible",type:"select",label:"Collapsible to icons",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"collapsed",type:"select",label:"Start collapsed",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"autohide",type:"select",label:"Autohide off-screen",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"hide-on-scroll",type:"select",label:"Hide on scroll (bar)",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"hover-open",type:"select",label:"Open dropdowns on hover",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"hover",type:"text",label:"Hover effect"},{name:"selected",type:"text",label:"When selected"},{name:"accent",type:"colour",label:"Highlight colour"},{name:"variant",type:"text",label:"Variant"},{name:"font",type:"text",label:"Font family"},{name:"font-size",type:"text",label:"Font size"},{name:"font-weight",type:"text",label:"Font weight"},{name:"letter-spacing",type:"text",label:"Letter spacing"},{name:"icon-size",type:"text",label:"Icon size"},{name:"float-anchor",type:"select",label:"Float anchor",options:[["","Menu default"],["TL","Top left"],["TR","Top right"],["BL","Bottom left"],["BR","Bottom right"],["L","Left"],["R","Right"]]},{name:"float-x",type:"number",label:"Float offset X (px)"},{name:"float-y",type:"number",label:"Float offset Y (px)"},{name:"float-width",type:"number",label:"Float width (px)"},{name:"float-collapsible",type:"select",label:"Float: collapsible",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"float-movable",type:"select",label:"Float: movable",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"class",type:"text",label:"CSS classes"}]},{name:"theme-switcher",label:"Theme switcher",icon:"palette",category:"Components",selfClosing:!0,container:!1,wrappable:!1,template:"[theme-switcher /]",attrs:[{name:"position",type:"select",label:"Position",options:[["","Inline - where the tag is"],["top-left","Top left"],["top-right","Top right"],["left-center","Left, centred"],["right-center","Right, centred"],["bottom-left","Bottom left"],["bottom-right","Bottom right"]]},{name:"offset-x",type:"number",label:"Offset from the side (px, pinned only)"},{name:"offset-y",type:"number",label:"Offset from the top/bottom (px, pinned only)"},{name:"themes",type:"text",label:"Themes (comma list - blank for the site's)"}]},{name:"icon",label:"Icon",icon:"icon-pick",category:"Media",selfClosing:!0,container:!1,wrappable:!1,template:'[icon name="arrow-right" /]',attrs:[{name:"name",type:"icon",label:"Icon name"},{name:"size",type:"number",label:"Size (px)"},{name:"color",type:"colour",label:"Colour"},{name:"class",type:"text",label:"CSS class"}]},{name:"embed",label:"Embed",icon:"video",category:"Media",selfClosing:!0,container:!1,wrappable:!1,template:'[embed url="https://youtu.be/dQw4w9WgXcQ" /]',custom:"embed",attrs:[{name:"url",type:"url",label:"URL"},{name:"ratio",type:"select",label:"Aspect ratio",options:[["16:9","16:9"],["4:3","4:3"],["1:1","1:1"],["21:9","21:9"],["9:16","9:16"],["3:4","3:4"]]},{name:"title",type:"text",label:"Title / caption"},{name:"width",type:"text",label:"Width"},{name:"align",type:"select",label:"Alignment",options:[["left","Left"],["center","Centre"],["right","Right"]]},{name:"autoplay",type:"checkbox",label:"Autoplay"},{name:"loop",type:"checkbox",label:"Loop"},{name:"muted",type:"checkbox",label:"Muted"}]}];for(const e of SHORTCODES){e.attrs||(e.attrs=[]);for(const a of l)e.attrs.some(t=>t.name===a.name)||e.attrs.push(a)}export const EDITOR_TOOLS=[{name:"image",label:"Image",icon:"image-add",category:"Media",custom:"image"},{name:"colourpick",label:"Colour picker",icon:"colour-picker",category:"Media",custom:"colourpick"},{name:"component",label:"Component",icon:"component",category:"Components",custom:"component"},{name:"scribe",label:"Scribe",icon:"scribe-insert",category:"Content",custom:"scribe"}];
47
+ [/listgroup]`,children:{name:"item",min:1,max:20},attrs:[{name:"variant",type:"select",label:"Variant",options:[["","Default"],["flush","Flush"],["numbered","Numbered"],["horizontal","Horizontal"]]},{name:"size",type:"select",label:"Size",options:[["","Default"],["sm","Small"],["lg","Large"]]},{name:"itemvariant",type:"select",label:"Item variant",options:[["","Default"],["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]},{name:"action",type:"checkbox",label:"Actionable items"}]},{name:"collection",label:"Collection",icon:"database",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[collection slug="enquiries" display="table" /]',attrs:[{name:"slug",type:"lookup",source:"collections",label:"Collection"},{name:"display",type:"select",label:"Display",options:[["table","Table"],["cards","Cards"],["list","List"],["accordion","Accordion"],["timeline","Timeline"],["carousel","Carousel"],["block","Block"]]},{name:"fields",type:"text",label:"Fields (comma-separated)"},{name:"limit",type:"number",label:"Limit"},{name:"sort",type:"lookup",source:"collection-fields",label:"Sort field"},{name:"order",type:"select",label:"Order",options:[["desc","Descending"],["asc","Ascending"]]},{name:"title-field",type:"lookup",source:"collection-fields",label:"Title field"},{name:"image-field",type:"lookup",source:"collection-fields",label:"Image field"},{name:"body-field",type:"lookup",source:"collection-fields",label:"Body field"},{name:"mobile-popup",type:"checkbox",label:"Open carousel cards in a popup on mobile"},{name:"arrow-position",type:"select",label:"Arrow position",options:[["middle","Middle"],["top","Top"],["bottom","Bottom"]]},{name:"background",type:"colour",label:"Carousel background"},{name:"arrow-background",type:"colour",label:"Arrow background"},{name:"arrow-color",type:"colour",label:"Arrow colour"},{name:"autoplay",type:"checkbox",label:"Autoplay",domma:"carousel.autoplay"},{name:"interval",type:"number",label:"Interval (ms)",domma:"carousel.interval"},{name:"loop",type:"checkbox",label:"Loop",default:!0,domma:"carousel.loop"},{name:"animation",type:"select",label:"Animation",options:[["slide","Slide"],["fade","Fade"],["crossfade","Crossfade"]],domma:"carousel.animation"},{name:"animation-duration",type:"number",label:"Animation duration (ms)",domma:"carousel.animationDuration"},{name:"animation-easing",type:"text",label:"Animation easing",domma:"carousel.animationEasing"},{name:"height-mode",type:"select",label:"Image height",options:[["crop","Top-aligned crop (shortest image)"],["average","Average of shortest and tallest images"]],domma:"carousel.heightMode"},{name:"height",type:"number",label:"Fixed height (px, optional)",domma:"carousel.height"},{name:"columns",type:"number",label:"Card columns"},{name:"search",type:"checkbox",label:"Search (table)",default:!0},{name:"sortable",type:"checkbox",label:"Sortable (table)",default:!0},{name:"exportable",type:"checkbox",label:"CSV export"},{name:"page-size",type:"number",label:"Page size"},{name:"empty",type:"text",label:"Empty message"},{name:"scope",type:"select",label:"Scope",options:[["","All"],["mine","Current user"]]},{name:"cta",type:"lookup",source:"actions",label:"CTA action"},{name:"cta-label",type:"text",label:"CTA label"},{name:"cta-icon",type:"icon",label:"CTA icon"},{name:"cta-style",type:"select",label:"CTA style",options:[["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]},{name:"cta-confirm",type:"text",label:"CTA confirm text"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"view",label:"View",icon:"eye",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[view slug="products" display="table" limit="50" /]',attrs:[{name:"slug",type:"lookup",source:"views",label:"View"},{name:"display",type:"select",label:"Display",options:[["table","Table"],["cards","Cards"],["list","List"],["accordion","Accordion"],["timeline","Timeline"],["carousel","Carousel"],["block","Block"]]},{name:"limit",type:"number",label:"Limit"},{name:"fields",type:"text",label:"Fields (comma-separated)"},{name:"title-field",type:"text",label:"Title field"},{name:"image-field",type:"text",label:"Image field"},{name:"body-field",type:"text",label:"Body field"},{name:"mobile-popup",type:"checkbox",label:"Open carousel cards in a popup on mobile"},{name:"arrow-position",type:"select",label:"Arrow position",options:[["middle","Middle"],["top","Top"],["bottom","Bottom"]]},{name:"background",type:"colour",label:"Carousel background"},{name:"arrow-background",type:"colour",label:"Arrow background"},{name:"arrow-color",type:"colour",label:"Arrow colour"},{name:"autoplay",type:"checkbox",label:"Autoplay",domma:"carousel.autoplay"},{name:"interval",type:"number",label:"Interval (ms)",domma:"carousel.interval"},{name:"loop",type:"checkbox",label:"Loop",default:!0,domma:"carousel.loop"},{name:"animation",type:"select",label:"Animation",options:[["slide","Slide"],["fade","Fade"],["crossfade","Crossfade"]],domma:"carousel.animation"},{name:"animation-duration",type:"number",label:"Animation duration (ms)",domma:"carousel.animationDuration"},{name:"animation-easing",type:"text",label:"Animation easing",domma:"carousel.animationEasing"},{name:"height-mode",type:"select",label:"Image height",options:[["crop","Top-aligned crop (shortest image)"],["average","Average of shortest and tallest images"]],domma:"carousel.heightMode"},{name:"height",type:"number",label:"Fixed height (px, optional)",domma:"carousel.height"},{name:"columns",type:"number",label:"Card columns"},{name:"empty",type:"text",label:"Empty message"}]},{name:"block",label:"Block",icon:"layout",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[block template="post-card" title="My Post" /]',attrs:[{name:"template",type:"lookup",source:"blocks",label:"Template"}]},{name:"form",label:"Form",icon:"file-text",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[form name="contact" /]',attrs:[{name:"name",type:"lookup",source:"forms",label:"Form"},{name:"class",type:"text",label:"CSS class"},{name:"id",type:"text",label:"ID"}]},{name:"cta",label:"CTA",icon:"mouse-pointer",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[cta action="send-welcome" entry="abc123" style="primary" label="Send" /]',attrs:[{name:"action",type:"lookup",source:"actions",label:"Action"},{name:"entry",type:"text",label:"Entry ID"},{name:"style",type:"select",label:"Style",options:[["primary","Primary"],["secondary","Secondary"],["success","Success"],["danger","Danger"],["warning","Warning"],["info","Info"]]},{name:"icon",type:"icon",label:"Icon"},{name:"size",type:"select",label:"Size",options:[["","Default"],["sm","Small"],["lg","Large"]]},{name:"confirm",type:"text",label:"Confirm text"},{name:"label",type:"text",label:"Label"}]},{name:"menu",label:"Menu",icon:"menu",category:"Data",selfClosing:!0,container:!1,wrappable:!1,template:'[menu slug="legal" /]',attrs:[{name:"slug",type:"lookup",source:"menus",label:"Menu"},{name:"location",type:"lookup",source:"menu-locations",label:"Location slot"},{name:"variant",type:"text",label:"Variant"},{name:"class",type:"text",label:"CSS class"},{name:"depth",type:"number",label:"Max depth"},{name:"orientation",type:"select",label:"Orientation",options:[["","Menu default"],["horizontal","Horizontal"],["vertical","Vertical"]]},{name:"float",type:"select",label:"Floating",options:[["","Menu default"],["no","Render inline here"]]}]},{name:"contents",label:"Page contents (this page)",icon:"list",category:"Layout",selfClosing:!0,container:!1,wrappable:!1,template:'[contents numbered="true" /]',actions:[{label:"Number the contents",icon:"hash",set:{numbered:"true"}},{label:"List H2 and H3 headings",icon:"list",set:{headings:"h2h3"}},{label:"Contents on the right",icon:"sidebar-right",set:{side:"right"}},{label:"Collapse the contents to a button",icon:"minimize",set:{collapsible:"true",collapsed:"true"}},{label:"Float the contents",icon:"move",set:{floating:"true","float-anchor":"TR",movable:"true"}},{label:"No contents on this page",icon:"eye-off",set:{hidden:"true"}},{label:"Remove this override",icon:"trash",remove:!0}],quickAttrs:["side","headings","numbered","title","collapsible","floating","hidden"],attrs:[{name:"side",type:"select",label:"Side",options:[["","Layout default"],["left","Left"],["right","Right"]]},{name:"width",type:"number",label:"Width (px, 160-480)"},{name:"headings",type:"select",label:"Headings",options:[["","Layout default"],["auto","Sections (H2s, else H3s)"],["h2","H2 only"],["h3","H3 only"],["h2h3","H2 and H3"]]},{name:"numbered",type:"select",label:"Numbered",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"title",type:"text",label:"Title above the list"},{name:"exclude",type:"text",label:"Leave out (headings, comma separated)"},{name:"sticky",type:"select",label:"Stays in view",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"scroll-spy",type:"select",label:"Marks the section being read",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"collapsible",type:"select",label:"Collapsible to a button",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"collapsed",type:"select",label:"Start collapsed",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"autohide",type:"select",label:"Autohide off its edge",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"floating",type:"select",label:"Floating panel",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"float-anchor",type:"select",label:"Float anchor",options:[["","Layout default"],["TL","Top left"],["TR","Top right"],["BL","Bottom left"],["BR","Bottom right"],["L","Left"],["R","Right"]]},{name:"movable",type:"select",label:"Visitors can move it",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"hidden",type:"select",label:"No contents on this page",options:[["","Layout default"],["true","On"],["false","Off"]]},{name:"hover",type:"text",label:"Hover effect"},{name:"selected",type:"text",label:"When selected"},{name:"accent",type:"colour",label:"Accent"},{name:"font",type:"text",label:"Font family"},{name:"font-size",type:"text",label:"Font size"},{name:"font-weight",type:"text",label:"Font weight"}]},{name:"navbar",label:"Navbar settings (this page)",icon:"sliders",category:"Layout",selfClosing:!0,container:!1,wrappable:!1,template:'[navbar collapsed="true" /]',actions:[{label:"Collapse the rail on this page",icon:"chevrons-right",set:{collapsible:"true",collapsed:"true",autohide:"false"}},{label:"Autohide the rail on this page",icon:"eye-off",set:{autohide:"true",collapsed:null}},{label:"Keep the rail open on this page",icon:"eye",set:{autohide:"false",collapsed:"false"}},{label:"Hide the bar on scroll on this page",icon:"arrow-up",set:{"hide-on-scroll":"true"}},{label:"Remove this override",icon:"trash",remove:!0}],quickAttrs:["position","width","collapsible","collapsed","autohide","hide-on-scroll"],attrs:[{name:"position",type:"select",label:"Position",options:[["","Menu default"],["sticky","Sticky"],["fixed","Fixed"],["static","Static"],["floating","Floating"]]},{name:"orientation",type:"select",label:"Orientation",options:[["","Menu default"],["horizontal","Horizontal"],["vertical","Vertical"]]},{name:"side",type:"select",label:"Rail side",options:[["","Menu default"],["left","Left"],["right","Right"]]},{name:"align",type:"select",label:"Alignment",options:[["","Menu default"],["left","Left"],["centre","Centre"],["right","Right"],["spread","Spread"]]},{name:"width",type:"number",label:"Rail width (px, 160-480)"},{name:"collapsible",type:"select",label:"Collapsible to icons",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"collapsed",type:"select",label:"Start collapsed",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"autohide",type:"select",label:"Autohide off-screen",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"hide-on-scroll",type:"select",label:"Hide on scroll (bar)",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"hover-open",type:"select",label:"Open dropdowns on hover",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"hover",type:"text",label:"Hover effect"},{name:"selected",type:"text",label:"When selected"},{name:"accent",type:"colour",label:"Highlight colour"},{name:"variant",type:"text",label:"Variant"},{name:"font",type:"text",label:"Font family"},{name:"font-size",type:"text",label:"Font size"},{name:"font-weight",type:"text",label:"Font weight"},{name:"letter-spacing",type:"text",label:"Letter spacing"},{name:"icon-size",type:"text",label:"Icon size"},{name:"float-anchor",type:"select",label:"Float anchor",options:[["","Menu default"],["TL","Top left"],["TR","Top right"],["BL","Bottom left"],["BR","Bottom right"],["L","Left"],["R","Right"]]},{name:"float-x",type:"number",label:"Float offset X (px)"},{name:"float-y",type:"number",label:"Float offset Y (px)"},{name:"float-width",type:"number",label:"Float width (px)"},{name:"float-collapsible",type:"select",label:"Float: collapsible",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"float-movable",type:"select",label:"Float: movable",options:[["","Menu default"],["true","On"],["false","Off"]]},{name:"class",type:"text",label:"CSS classes"}]},{name:"theme-switcher",label:"Theme switcher",icon:"palette",category:"Components",selfClosing:!0,container:!1,wrappable:!1,template:"[theme-switcher /]",attrs:[{name:"position",type:"select",label:"Position",options:[["","Inline - where the tag is"],["top-left","Top left"],["top-right","Top right"],["left-center","Left, centred"],["right-center","Right, centred"],["bottom-left","Bottom left"],["bottom-right","Bottom right"]]},{name:"offset-x",type:"number",label:"Offset from the side (px, pinned only)"},{name:"offset-y",type:"number",label:"Offset from the top/bottom (px, pinned only)"},{name:"themes",type:"text",label:"Themes (comma list - blank for the site's)"}]},{name:"icon",label:"Icon",icon:"icon-pick",category:"Media",selfClosing:!0,container:!1,wrappable:!1,template:'[icon name="arrow-right" /]',attrs:[{name:"name",type:"icon",label:"Icon name"},{name:"size",type:"number",label:"Size (px)"},{name:"color",type:"colour",label:"Colour"},{name:"class",type:"text",label:"CSS class"}]},{name:"embed",label:"Embed",icon:"video",category:"Media",selfClosing:!0,container:!1,wrappable:!1,template:'[embed url="https://youtu.be/dQw4w9WgXcQ" /]',custom:"embed",attrs:[{name:"url",type:"url",label:"URL"},{name:"ratio",type:"select",label:"Aspect ratio",options:[["16:9","16:9"],["4:3","4:3"],["1:1","1:1"],["21:9","21:9"],["9:16","9:16"],["3:4","3:4"]]},{name:"title",type:"text",label:"Title / caption"},{name:"width",type:"text",label:"Width"},{name:"align",type:"select",label:"Alignment",options:[["left","Left"],["center","Centre"],["right","Right"]]},{name:"autoplay",type:"checkbox",label:"Autoplay"},{name:"loop",type:"checkbox",label:"Loop"},{name:"muted",type:"checkbox",label:"Muted"}]}];for(const e of SHORTCODES){e.attrs||(e.attrs=[]);for(const a of l)e.attrs.some(t=>t.name===a.name)||e.attrs.push(a)}export const EDITOR_TOOLS=[{name:"image",label:"Image",icon:"image-add",category:"Media",custom:"image"},{name:"colourpick",label:"Colour picker",icon:"colour-picker",category:"Media",custom:"colourpick"},{name:"component",label:"Component",icon:"component",category:"Components",custom:"component"},{name:"scribe",label:"Scribe",icon:"scribe-insert",category:"Content",custom:"scribe"}];
@@ -1,4 +1,4 @@
1
- import{api as h}from"../api.js";import{CardBuilder as tn}from"../lib/card-builder.js";import{TimelineBuilder as on}from"../lib/timeline-builder.js";import{attachEditorKeybindings as an,createToolbar as sn,insertAtCursor as nn}from"../lib/markdown-toolbar.js";import{EffectsBuilder as rn}from"../lib/effects-builder.js";import{attachContextMenu as ln}from"../lib/shortcode-context-menu.js";import{registerCustomInserters as cn}from"../lib/shortcode-insert.js";import{populateThemeSelect as dn}from"../lib/themes.js";import{createFoldingManager as pn}from"../lib/editor-folding.js";import{openScribeComposer as un}from"../lib/scribe-composer.js";import{openCrudTutorial as mn}from"../lib/crud-tutorial.js";import{addBannerAction as dt}from"../lib/plugin-chrome.js";import{exampleJson as fn,parseSchema as Po,schemaText as bn}from"../lib/seo-structured-data.js";import{helpPopovers as qa}from"../lib/help-popover.js";import{onceClosed as Bt,openMenuAt as Ce,sidebarCount as pt}from"../lib/tool-kit.js";import{pickMedia as vn}from"../lib/media-picker.js";import{openPageClone as gn}from"../lib/page-clone.js";import{openEditorReference as Ha}from"../lib/page-editor-reference.js";import{dconfigNotes as hn}from"../lib/dconfig-check.js";import{cleanType as It,DEFAULT_TYPE as Ft,EDITOR_FONTS as yn,fontHref as kn,isDefaultType as wn,LINE_HEIGHTS as Sn,SIZES as En,typeVars as Va}from"../lib/editor-type.js";import{getProjectFromHash as zt}from"../lib/project-context.js";import{attachSmoothCaret as _a,getCaretPreference as Mn,setCaretPreference as Tn}from"../lib/smooth-caret.js";import{SCREEN as Oo,bannerSection as Cn,draftIsStale as xn,draftKey as ze,initialProject as Pn,makeDraft as Ka,problems as Ro,readDraft as On,snapshot as W}from"../lib/page-editor-arrange.js";import{fmtDateTime as qe}from"../lib/dates.js";import{hasDraft as xe,heldBlockEdits as Rn,hold as Ao,takeHeld as $o,wireHeldRouter as An}from"../lib/editor-hop.js";import{hopTarget as Ua}from"../lib/editor-hop-arrange.js";import{checkNewName as $n,copyName as Lo,usageText as Ln}from"../lib/blocks-arrange.js";import{isCollapsed as Ja,setCollapsed as Wa}from"../lib/sidebar-size.js";import{blockTagDefs as Ya,blocksInBody as Nn}from"../lib/block-tags.js";import{draftKey as He,draftOffer as Dn,extractPlaceholders as Ga,formFromBlock as Xa,payloadFromForm as Za,rawPlaceholders as No,shortcodeFor as jn,snapshot as Do}from"../lib/block-editor-arrange.js";import{blockTabs as Bn,notHereLine as In,otherUses as Qa,outlineBlock as Fn,previewBlocks as zn,saveQuestion as qn,savedMessage as Hn,usesLine as Vn}from"../lib/page-blocks-arrange.js";import{addressFor as es,blockAloneBody as _n,blockRows as Kn,cleanLayout as jo,closeTab as Un,componentRows as Jn,componentStatusText as Wn,componentsInBody as Yn,moveTab as Gn,nextLayout as Xn,openTab as Bo,pageRows as Zn,pageStatusText as Qn,rememberedTabs as er,renameTab as tr,sampleRows as ts,saveAllLabel as or,startingTabs as ar,tabId as X,tabItem as I,tabsToClose as Io,workspaceKey as sr}from"../lib/editor-workspace-arrange.js";import{PANES as qt,STARTER_SOURCE as nr,assembleSource as os,attributeFor as rr,draftKey as Ve,draftStatus as ir,nameProblem as lr,previewRows as as,readValue as cr,snapshot as Fo,splitSource as ut,writeValue as ss}from"../lib/component-editor-arrange.js";import{attachColourLayer as ns,createPlainEditor as zo}from"../lib/plain-editor.js";import{cleanCodePrefs as Ht,codePrefs as dr,DEFAULT_CODE_PREFS as Vt,formatTextarea as _e,INDENT_SIZES as pr,setCodePrefs as ur}from"../lib/code-format.js";function mt(d){const b=document.createElement("template");return b.innerHTML=d.trim(),b.content.firstElementChild}const mr=qe,rs=d=>qe(d.createdAt)+(d.label?` - ${d.label}`:""),fr=`
1
+ import{api as h}from"../api.js";import{CardBuilder as tn}from"../lib/card-builder.js";import{TimelineBuilder as on}from"../lib/timeline-builder.js";import{attachEditorKeybindings as an,createToolbar as sn,insertAtCursor as nn}from"../lib/markdown-toolbar.js";import{EffectsBuilder as rn}from"../lib/effects-builder.js";import{attachContextMenu as ln}from"../lib/shortcode-context-menu.js";import{registerCustomInserters as cn}from"../lib/shortcode-insert.js";import{populateThemeSelect as dn}from"../lib/themes.js";import{createFoldingManager as pn}from"../lib/editor-folding.js";import{openScribeComposer as un}from"../lib/scribe-composer.js";import{openCrudTutorial as mn}from"../lib/crud-tutorial.js";import{addBannerAction as dt}from"../lib/plugin-chrome.js";import{exampleJson as fn,parseSchema as Po,schemaText as bn}from"../lib/seo-structured-data.js";import{helpPopovers as qa}from"../lib/help-popover.js";import{onceClosed as Bt,openMenuAt as Ce,sidebarCount as pt}from"../lib/tool-kit.js";import{pickMedia as vn}from"../lib/media-picker.js";import{openPageClone as gn}from"../lib/page-clone.js";import{openEditorReference as Ha}from"../lib/page-editor-reference.js";import{dconfigNotes as hn}from"../lib/dconfig-check.js";import{catalogueNow as yn,setCatalogue as kn}from"../lib/domma-catalogue.js";import{cleanType as It,DEFAULT_TYPE as Ft,EDITOR_FONTS as wn,fontHref as Sn,isDefaultType as En,LINE_HEIGHTS as Mn,SIZES as Tn,typeVars as Va}from"../lib/editor-type.js";import{getProjectFromHash as zt}from"../lib/project-context.js";import{attachSmoothCaret as _a,getCaretPreference as Cn,setCaretPreference as xn}from"../lib/smooth-caret.js";import{SCREEN as Oo,bannerSection as Pn,draftIsStale as On,draftKey as ze,initialProject as Rn,makeDraft as Ka,problems as Ro,readDraft as An,snapshot as W}from"../lib/page-editor-arrange.js";import{fmtDateTime as qe}from"../lib/dates.js";import{hasDraft as xe,heldBlockEdits as $n,hold as Ao,takeHeld as $o,wireHeldRouter as Ln}from"../lib/editor-hop.js";import{hopTarget as Ua}from"../lib/editor-hop-arrange.js";import{checkNewName as Nn,copyName as Lo,usageText as Dn}from"../lib/blocks-arrange.js";import{isCollapsed as Ja,setCollapsed as Wa}from"../lib/sidebar-size.js";import{blockTagDefs as Ya,blocksInBody as jn}from"../lib/block-tags.js";import{draftKey as He,draftOffer as Bn,extractPlaceholders as Ga,formFromBlock as Xa,payloadFromForm as Za,rawPlaceholders as No,shortcodeFor as In,snapshot as Do}from"../lib/block-editor-arrange.js";import{blockTabs as Fn,notHereLine as zn,otherUses as Qa,outlineBlock as qn,previewBlocks as Hn,saveQuestion as Vn,savedMessage as _n,usesLine as Kn}from"../lib/page-blocks-arrange.js";import{addressFor as es,blockAloneBody as Un,blockRows as Jn,cleanLayout as jo,closeTab as Wn,componentRows as Yn,componentStatusText as Gn,componentsInBody as Xn,moveTab as Zn,nextLayout as Qn,openTab as Bo,pageRows as er,pageStatusText as tr,rememberedTabs as or,renameTab as ar,sampleRows as ts,saveAllLabel as sr,startingTabs as nr,tabId as X,tabItem as I,tabsToClose as Io,workspaceKey as rr}from"../lib/editor-workspace-arrange.js";import{PANES as qt,STARTER_SOURCE as ir,assembleSource as os,attributeFor as lr,draftKey as Ve,draftStatus as cr,nameProblem as dr,previewRows as as,readValue as pr,snapshot as Fo,splitSource as ut,writeValue as ss}from"../lib/component-editor-arrange.js";import{attachColourLayer as ns,createPlainEditor as zo}from"../lib/plain-editor.js";import{cleanCodePrefs as Ht,codePrefs as ur,DEFAULT_CODE_PREFS as Vt,formatTextarea as _e,INDENT_SIZES as mr,setCodePrefs as fr}from"../lib/code-format.js";function mt(d){const b=document.createElement("template");return b.innerHTML=d.trim(),b.content.firstElementChild}const br=qe,rs=d=>qe(d.createdAt)+(d.label?` - ${d.label}`:""),vr=`
2
2
  <div class="pe-share">
3
3
  <p class="form-hint" style="margin-top:0">Anyone with the link can view this page even while it is unpublished, without
4
4
  signing in. The link works for this page only, expires on its own, and can be revoked at any time.</p>
@@ -30,7 +30,7 @@ import{api as h}from"../api.js";import{CardBuilder as tn}from"../lib/card-builde
30
30
  .pe-share [hidden] { display: none !important; }
31
31
  .pe-share-row { display: flex; align-items: center; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid var(--dm-border-light); }
32
32
  .pe-share-text { flex: 1 1 auto; min-width: 0; font-size: .82rem; }
33
- </style>`;function is(d){const b=kn(d);if(!b||document.querySelector(`link[data-pe-font="${CSS.escape(d)}"]`))return;const v=Object.assign(document.createElement("link"),{rel:"stylesheet",href:b});v.dataset.peFont=d,document.head.appendChild(v)}const br=`
33
+ </style>`;function is(d){const b=Sn(d);if(!b||document.querySelector(`link[data-pe-font="${CSS.escape(d)}"]`))return;const v=Object.assign(document.createElement("link"),{rel:"stylesheet",href:b});v.dataset.peFont=d,document.head.appendChild(v)}const gr=`
34
34
  <div class="pe-settings">
35
35
  <p class="pe-settings-note">How the editor looks to you - kept in this browser, for every page.</p>
36
36
  <label class="form-label" for="pe-set-font">Font <span data-help="The lettering in the editor (not on the site). Monospace keeps every character the same width, so shortcodes and Markdown line up."></span></label>
@@ -94,17 +94,17 @@ The quick brown fox - 0O 1lI {} [] () =&gt; ==
94
94
  .pe-settings-sample { white-space: pre-wrap; padding: .75rem 1rem; border-radius: var(--dm-radius-md); border: 1px solid var(--dm-border);
95
95
  background: var(--dm-background-alt); font-family: var(--pe-font); font-size: var(--pe-size); line-height: var(--pe-line); }
96
96
  .pe-settings-actions { display: flex; gap: .5rem; border-top: 1px solid var(--dm-border); padding-top: .75rem; }
97
- </style>`;function vr(d,b){const v=E.slideover({title:"Editor settings",size:"sm",position:"right"}),i=mt(`<div>${br}</div>`),k=It(d.peek()),u={font:M.observable(k.font),size:M.observable(String(k.size)),line:M.observable(String(k.line)),wrap:M.observable(k.wrap),caret:M.observable(Mn()),sidebar:M.observable(Pe().closeSidebar===!0)},w=Ht(b.peek());u.indent=M.observable(w.indent),u.indentSize=M.observable(String(w.size));for(const T of["detect","autoIndent","continueLists","shortTags","tables","html","formatOnSave"])u[T]=M.observable(w[T]);const y=M.computed(()=>Ht({indent:u.indent.value,size:u.indentSize.value,detect:u.detect.value,autoIndent:u.autoIndent.value,continueLists:u.continueLists.value,shortTags:u.shortTags.value,tables:u.tables.value,html:u.html.value,formatOnSave:u.formatOnSave.value})),x=M.effect(()=>{const T=y.value;JSON.stringify(T)!==JSON.stringify(Ht(b.peek()))&&(b.value=T,Ke("code",T))}),j=M.effect(()=>{const T=u.sidebar.value;T!==(Pe().closeSidebar===!0)&&Ke("closeSidebar",T)}),c=M.computed(()=>It({font:u.font.value,size:u.size.value,line:u.line.value,wrap:u.wrap.value}));u.isDefault=M.computed(()=>wn(c.value)&&u.caret.value==="auto"&&!u.sidebar.value&&JSON.stringify(y.value)===JSON.stringify(Vt));const A=M.effect(()=>Tn(u.caret.value)),H=i.querySelector("#pe-set-font");for(const[T,ne]of[["mono","Monospace"],["sans","Other"],["serif",null]]){const Oe=yn.filter(re=>re.kind===T),O=ne?Object.assign(document.createElement("optgroup"),{label:ne}):H.querySelector("optgroup:last-of-type");O.append(...Oe.map(re=>new Option(re.label,re.id))),ne&&H.appendChild(O)}i.querySelector("#pe-set-indent-size").append(...pr.map(T=>new Option(String(T),String(T)))),i.querySelector("#pe-set-size").append(...En.map(T=>new Option(`${T}px`,String(T)))),i.querySelector("#pe-set-line").append(...Sn.map(T=>new Option({1.3:"Tight",1.45:"Snug",1.6:"Normal",1.8:"Relaxed",2:"Double"}[T]||String(T),String(T))));const Y=i.querySelector(".pe-settings-sample"),D=M.effect(()=>{const T=c.value;is(T.font);for(const[ne,Oe]of Object.entries(Va(T)))Y.style.setProperty(ne,Oe);Y.style.whiteSpace=T.wrap?"pre-wrap":"pre",Y.style.overflowX=T.wrap?"":"auto",JSON.stringify(T)!==JSON.stringify(It(d.peek()))&&(d.value=T,Ke("type",T))});u.reset=()=>{u.font.value=Ft.font,u.size.value=String(Ft.size),u.line.value=String(Ft.line),u.wrap.value=Ft.wrap,u.caret.value="auto",u.sidebar.value=!1,u.indent.value=Vt.indent,u.indentSize.value=String(Vt.size);for(const T of["detect","autoIndent","continueLists","shortTags","tables","html","formatOnSave"])u[T].value=Vt[T]},u.done=()=>v.close(),v.element.appendChild(i);const se=M.applyBindings(u,i),_t=qa(i);return Bt(v,()=>{se.dispose(),_t(),D?.(),A?.(),j?.(),x?.()}),Domma.icons?.scan?.(i),v.open(),v}async function gr(d){const b=E.slideover({title:"Share preview link",size:"md",position:"right"}),v=mt(`<div>${fr}</div>`),i={expiry:M.observable("7d"),note:M.observable(""),creating:M.observable(!1),url:M.observable(""),links:M.observable([]),loaded:M.observable(!1),listError:M.observable("")},k=async()=>{try{const w=await h.pages.previewLinks.list(d);i.links.value=w.filter(y=>!y.revokedAt&&!y.expired).map(y=>({id:y.id,title:y.label||"Untitled link",meta:`Expires ${mr(y.expiresAt)} - ${y.useCount===1?"1 view":`${y.useCount||0} views`}`})),i.listError.value=""}catch(w){i.listError.value="Could not load existing links: "+(w.message||"unknown error")}finally{i.loaded.value=!0}};i.create=async()=>{i.creating.value=!0;try{const w=await h.pages.previewLinks.create(d,i.expiry.peek(),i.note.peek().trim());i.url.value=w.url,i.note.value="",E.toast("Share link created.",{type:"success"}),await k(),v.querySelector(".pe-share-url")?.select()}catch(w){E.toast("Could not create link: "+(w.message||"unknown error"),{type:"error"})}finally{i.creating.value=!1}},i.copy=async()=>{try{await navigator.clipboard.writeText(i.url.peek()),E.toast("Link copied to clipboard.",{type:"success"})}catch{v.querySelector(".pe-share-url")?.select(),E.toast("Press Ctrl+C to copy the selected link.",{type:"info"})}},i.revoke=async w=>{if(await E.confirm("Revoke this link? Anyone holding it loses access immediately."))try{await h.pages.previewLinks.revoke(w),E.toast("Link revoked.",{type:"success"}),await k()}catch(y){E.toast("Could not revoke: "+(y.message||"unknown error"),{type:"error"})}};const u=M.applyBindings(i,v);Bt(b,()=>u.dispose()),b.element.appendChild(v),b.open(),await k()}function hr(d){return new Promise(b=>{const v=E.slideover({title:"Save Named Version",size:"sm",position:"right"}),i=mt(`
97
+ </style>`;function hr(d,b){const v=E.slideover({title:"Editor settings",size:"sm",position:"right"}),i=mt(`<div>${gr}</div>`),k=It(d.peek()),u={font:M.observable(k.font),size:M.observable(String(k.size)),line:M.observable(String(k.line)),wrap:M.observable(k.wrap),caret:M.observable(Cn()),sidebar:M.observable(Pe().closeSidebar===!0)},w=Ht(b.peek());u.indent=M.observable(w.indent),u.indentSize=M.observable(String(w.size));for(const T of["detect","autoIndent","continueLists","shortTags","tables","html","formatOnSave"])u[T]=M.observable(w[T]);const y=M.computed(()=>Ht({indent:u.indent.value,size:u.indentSize.value,detect:u.detect.value,autoIndent:u.autoIndent.value,continueLists:u.continueLists.value,shortTags:u.shortTags.value,tables:u.tables.value,html:u.html.value,formatOnSave:u.formatOnSave.value})),x=M.effect(()=>{const T=y.value;JSON.stringify(T)!==JSON.stringify(Ht(b.peek()))&&(b.value=T,Ke("code",T))}),j=M.effect(()=>{const T=u.sidebar.value;T!==(Pe().closeSidebar===!0)&&Ke("closeSidebar",T)}),c=M.computed(()=>It({font:u.font.value,size:u.size.value,line:u.line.value,wrap:u.wrap.value}));u.isDefault=M.computed(()=>En(c.value)&&u.caret.value==="auto"&&!u.sidebar.value&&JSON.stringify(y.value)===JSON.stringify(Vt));const A=M.effect(()=>xn(u.caret.value)),H=i.querySelector("#pe-set-font");for(const[T,ne]of[["mono","Monospace"],["sans","Other"],["serif",null]]){const Oe=wn.filter(re=>re.kind===T),O=ne?Object.assign(document.createElement("optgroup"),{label:ne}):H.querySelector("optgroup:last-of-type");O.append(...Oe.map(re=>new Option(re.label,re.id))),ne&&H.appendChild(O)}i.querySelector("#pe-set-indent-size").append(...mr.map(T=>new Option(String(T),String(T)))),i.querySelector("#pe-set-size").append(...Tn.map(T=>new Option(`${T}px`,String(T)))),i.querySelector("#pe-set-line").append(...Mn.map(T=>new Option({1.3:"Tight",1.45:"Snug",1.6:"Normal",1.8:"Relaxed",2:"Double"}[T]||String(T),String(T))));const Y=i.querySelector(".pe-settings-sample"),D=M.effect(()=>{const T=c.value;is(T.font);for(const[ne,Oe]of Object.entries(Va(T)))Y.style.setProperty(ne,Oe);Y.style.whiteSpace=T.wrap?"pre-wrap":"pre",Y.style.overflowX=T.wrap?"":"auto",JSON.stringify(T)!==JSON.stringify(It(d.peek()))&&(d.value=T,Ke("type",T))});u.reset=()=>{u.font.value=Ft.font,u.size.value=String(Ft.size),u.line.value=String(Ft.line),u.wrap.value=Ft.wrap,u.caret.value="auto",u.sidebar.value=!1,u.indent.value=Vt.indent,u.indentSize.value=String(Vt.size);for(const T of["detect","autoIndent","continueLists","shortTags","tables","html","formatOnSave"])u[T].value=Vt[T]},u.done=()=>v.close(),v.element.appendChild(i);const se=M.applyBindings(u,i),_t=qa(i);return Bt(v,()=>{se.dispose(),_t(),D?.(),A?.(),j?.(),x?.()}),Domma.icons?.scan?.(i),v.open(),v}async function yr(d){const b=E.slideover({title:"Share preview link",size:"md",position:"right"}),v=mt(`<div>${vr}</div>`),i={expiry:M.observable("7d"),note:M.observable(""),creating:M.observable(!1),url:M.observable(""),links:M.observable([]),loaded:M.observable(!1),listError:M.observable("")},k=async()=>{try{const w=await h.pages.previewLinks.list(d);i.links.value=w.filter(y=>!y.revokedAt&&!y.expired).map(y=>({id:y.id,title:y.label||"Untitled link",meta:`Expires ${br(y.expiresAt)} - ${y.useCount===1?"1 view":`${y.useCount||0} views`}`})),i.listError.value=""}catch(w){i.listError.value="Could not load existing links: "+(w.message||"unknown error")}finally{i.loaded.value=!0}};i.create=async()=>{i.creating.value=!0;try{const w=await h.pages.previewLinks.create(d,i.expiry.peek(),i.note.peek().trim());i.url.value=w.url,i.note.value="",E.toast("Share link created.",{type:"success"}),await k(),v.querySelector(".pe-share-url")?.select()}catch(w){E.toast("Could not create link: "+(w.message||"unknown error"),{type:"error"})}finally{i.creating.value=!1}},i.copy=async()=>{try{await navigator.clipboard.writeText(i.url.peek()),E.toast("Link copied to clipboard.",{type:"success"})}catch{v.querySelector(".pe-share-url")?.select(),E.toast("Press Ctrl+C to copy the selected link.",{type:"info"})}},i.revoke=async w=>{if(await E.confirm("Revoke this link? Anyone holding it loses access immediately."))try{await h.pages.previewLinks.revoke(w),E.toast("Link revoked.",{type:"success"}),await k()}catch(y){E.toast("Could not revoke: "+(y.message||"unknown error"),{type:"error"})}};const u=M.applyBindings(i,v);Bt(b,()=>u.dispose()),b.element.appendChild(v),b.open(),await k()}function kr(d){return new Promise(b=>{const v=E.slideover({title:"Save Named Version",size:"sm",position:"right"}),i=mt(`
98
98
  <div style="padding:1rem">
99
99
  <label class="form-label" for="pe-version-label">Version Label</label>
100
100
  <input id="pe-version-label" type="text" class="form-input" style="margin-bottom:.75rem"
101
101
  placeholder="e.g. Initial design, Before restructure" data-model="label.value" data-on-keydown="key">
102
102
  <button type="button" class="btn btn-primary" data-on-click="save" data-bind-disabled="saving.value">Save Version</button>
103
- </div>`);let k=!1;const u={label:M.observable(""),saving:M.observable(!1)};u.save=async()=>{u.saving.value=!0;try{await h.versions.create(d,u.label.peek().trim()||null),E.toast("Named version saved.",{type:"success"}),k=!0,v.close()}catch(y){E.toast("Failed to save version: "+y.message,{type:"error"})}finally{u.saving.value=!1}},u.key=y=>{y.key==="Enter"&&(y.preventDefault(),u.save())};const w=M.applyBindings(u,i);Bt(v,()=>{w.dispose(),b(k)}),v.element.appendChild(i),v.open(),setTimeout(()=>i.querySelector("input")?.focus(),100)})}const yr=`<div class="card">
103
+ </div>`);let k=!1;const u={label:M.observable(""),saving:M.observable(!1)};u.save=async()=>{u.saving.value=!0;try{await h.versions.create(d,u.label.peek().trim()||null),E.toast("Named version saved.",{type:"success"}),k=!0,v.close()}catch(y){E.toast("Failed to save version: "+y.message,{type:"error"})}finally{u.saving.value=!1}},u.key=y=>{y.key==="Enter"&&(y.preventDefault(),u.save())};const w=M.applyBindings(u,i);Bt(v,()=>{w.dispose(),b(k)}),v.element.appendChild(i),v.open(),setTimeout(()=>i.querySelector("input")?.focus(),100)})}const wr=`<div class="card">
104
104
  <h3>{{title}}</h3>
105
105
  <p>{{description}}</p>
106
106
  </div>
107
- `,kr=`
107
+ `,Sr=`
108
108
  <div class="pe-new">
109
109
  <p class="form-hint" style="margin-top:0" data-bind-text="hint.value"></p>
110
110
  <label class="form-label" for="pe-new-name">Name</label>
@@ -124,7 +124,7 @@ The quick brown fox - 0O 1lI {} [] () =&gt; ==
124
124
  .pe-new [hidden] { display: none !important; }
125
125
  .pe-new-err { display: block; margin-top: .3rem; color: var(--dm-danger); font-size: var(--dm-text-xs); }
126
126
  .pe-new-actions { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1.25rem; }
127
- </style>`;function ls({kind:d,projects:b,taken:v,project:i="",name:k="",check:u,create:w,register:y=()=>{}}){return new Promise(x=>{const j=E.slideover({title:d==="block"?"New block":"New component",size:"sm",position:"right"});y(()=>{try{j.close()}catch{}});const c=mt(`<div>${kr}</div>`);for(const D of b)c.querySelector("#pe-new-project").append(new Option(D.name||D.slug,D.slug));const A={name:M.observable(k),project:M.observable(i),busy:M.observable(!1),hint:M.observable(d==="block"?"A block is a reusable piece of HTML with {{placeholders}}, used on pages with its short tag or by a collection display. Its name is its tag - fixed once created.":"A component is a custom element - <dm-name> - with a template, props, a script and a style. Its name is its tag - fixed once created."),placeholder:M.observable(d==="block"?"e.g. team-card":"e.g. pricing-table")};A.error=M.computed(()=>A.name.value.trim()?u(A.name.value.trim(),v):""),A.canCreate=M.computed(()=>!A.busy.value&&!!A.name.value.trim()&&!u(A.name.value.trim(),v));let H="";A.create=async()=>{const D=A.name.peek().trim();if(!(!D||A.error.peek()||A.busy.peek())){A.busy.value=!0;try{await w(D,A.project.peek()),H=D,j.close()}catch(se){E.toast(`Not created: ${se.message||se}`,{type:"error"})}finally{A.busy.value=!1}}},A.cancel=()=>j.close(),A.key=D=>{D.key==="Enter"&&(D.preventDefault(),A.create())};const Y=M.applyBindings(A,c);Bt(j,()=>{Y.dispose(),x(H)}),j.element.appendChild(c),c.querySelector("#pe-new-project").value=i,j.open(),setTimeout(()=>{const D=c.querySelector("#pe-new-name");D?.focus(),D?.select()},100)})}let F=null,cs=!1;function wr(){cs||!window.R?.use||(cs=!0,An(),R.use((d,b,v)=>{if(F&&!F.alive()){const u=F;F=null,u.dispose()}const i=b?.path||"",k=d?.path||"";if(!F||!Oo.test(i))return v();if(Oo.test(k)){const u=Ua(k);if(u){F.open(u,k);return}return v()}return F.dirty()?E.confirm("You have unsaved changes. Leave anyway? They are kept as drafts for your next visit.").then(u=>{u?(F?.keepDraft(),v()):F&&history.replaceState({pe:1},"","#"+F.address)}):v()}),M.subscribe("router:afterChange",({to:d}={})=>{if(F&&!Oo.test(d?.path||"")){const b=F;F=null,b.dispose()}}))}const ds="editor_prefs";function Pe(){return S.get(ds)||{viewMode:"split",fullscreen:!1}}let Sr=null;const Er=()=>Sr??(Sr=h.pages.dommaCatalogue().then(d=>d?.types?d:null)),Mr=d=>{try{return document.createDocumentFragment().querySelector(d),!0}catch{return!1}},Tr=()=>{try{return Pe()||{}}catch{return{}}};function Ke(d,b){const v=Pe();v[d]=b,S.set(ds,v)}const ps="editor-workspace.tabs",us="editor-workspace.folded",ft="editor-workspace.css",Cr="/__block-preview",xr=d=>d.replace(/<\/head>/i,"<style>body.dm-cloaked{opacity:1 !important;transition:none !important}</style></head>");function Pr(d,b,v=()=>{}){let i=0;try{i=d.contentWindow.scrollY||0}catch{}d.addEventListener("load",()=>{try{d.contentWindow.scrollTo(0,i)}catch{}v()},{once:!0}),d.srcdoc=b}const Or=["urlPath","title","description","layout","status","sortOrder","category","visibility","project","theme","seoTitle","seoDesc","seoSchema","dconfig"],Rr=["showInNav","sidebar","breadcrumbs","bundled"],ms=()=>({urlPath:"",title:"",description:"",layout:"",status:"draft",sortOrder:"99",showInNav:!1,sidebar:!1,breadcrumbs:!0,bundled:!1,tags:[],adminTags:[],category:"",visibility:"public",project:"",theme:"",seoTitle:"",seoDesc:"",seoSchema:"",dconfig:"",body:"",css:null});export const pageEditorView={templateUrl:"/admin/js/templates/page-editor.html",async onMount(d){if(wr(),F){const e=F;F=null,e.dispose()}const b=window.location.hash.replace(/^#/,""),v=[],i=e=>(v.push(e),e);let k=()=>!1,u=()=>{},w=()=>{};const y=d.get(0),x=y.querySelector("#pe-workspace"),j={address:b,alive:()=>x?.isConnected===!0,dirty:()=>k(),keepDraft:()=>u(),open:(e,t)=>w(e,t),dispose:()=>{v.splice(0).forEach(e=>{try{e()}catch{}})}};F=j;const c=()=>F===j&&j.alive();if(Tr().closeSidebar===!0){const e=document.querySelector("#admin-sidebar");e&&!Ja(e)&&!window.matchMedia("(max-width: 768px)").matches&&(Wa(e,!0,!1),i(()=>{e.isConnected&&Ja(e)&&Wa(e,!1,!1)}))}const A=E.loader(y,{type:"dots"});let[H,Y,D,se,_t,T,ne,Oe]=await Promise.all([h.layouts.get().catch(()=>({})),h.settings.get().catch(()=>({})),h.pages.list().catch(()=>[]),h.projects.list().catch(()=>[]),h.pages.tags().catch(()=>[]),h.listTags.list("pages").then(e=>e.map(t=>t.name)).catch(()=>[]),h.get("/blocks?usage=1").catch(()=>h.blocks.list()).catch(()=>[]),h.components.list().catch(()=>[])]);if(!c()){A.destroy();return}A.destroy();const O=e=>y.querySelector(e);if(D=Array.isArray(D)?D:[],dn(O("#field-theme"),{includeDefault:!0}),await Dr(O("#field-visibility")),!c())return;const re=Object.keys(H||{});Nr(O("#field-layout"),H,re[0]||"default");const Ho=e=>re.includes(e)?e:re[0]||e||"default";for(const e of se)for(const t of["#field-project","#block-project","#comp-project"])O(t).append(new Option(e.name||e.slug,e.slug));let ie=Array.isArray(ne)?ne:[],bt=Ya(ie);const vt=new Map(ie.map(e=>[e.name,e.updatedAt])),Ue=new Map(ie.map(e=>[e.name,e.usage])),be=new Set(ie.map(e=>e.name)),Vo=async()=>{const e=await h.get("/blocks?usage=1").catch(()=>null);if(!(!c()||!Array.isArray(e))){ie=e,bt=Ya(ie);for(const t of ie)be.add(t.name),Ue.set(t.name,t.usage),vt.has(t.name)||vt.set(t.name,t.updatedAt)}},Kt=Array.isArray(Y?.footer?.blocks)?Y.footer.blocks.filter(e=>typeof e=="string"):[];let Je=Array.isArray(Oe)?Oe.filter(e=>typeof e?.name=="string"):[];const le=new Set(Je.map(e=>e.name)),_o=async()=>{const e=await h.components.list().catch(()=>null);if(!(!c()||!Array.isArray(e))){Je=e.filter(t=>typeof t?.name=="string");for(const t of Je)le.add(t.name)}},Z=Pe(),p={urlPath:M.observable(""),title:M.observable(""),description:M.observable(""),layout:M.observable(Ho("default")),status:M.observable("draft"),sortOrder:M.observable("99"),showInNav:M.observable(!1),sidebar:M.observable(!1),breadcrumbs:M.observable(!0),bundled:M.observable(!1),tags:M.observable([]),adminTags:M.observable([]),category:M.observable(""),visibility:M.observable("public"),project:M.observable(""),theme:M.observable(""),seoTitle:M.observable(""),seoDesc:M.observable(""),seoSchema:M.observable(""),dconfig:M.observable(""),css:M.observable(""),cssOpened:M.observable(!1)},o={bodyRev:M.observable(0),base:M.observable(""),saving:M.observable(!1),viewMode:M.observable(jo(Z.viewMode)),fullscreen:M.observable(!!Z.fullscreen),explorerOn:M.observable(Z.explorer??!window.matchMedia("(max-width: 1024px)").matches),dockOn:M.observable(!!Z.dock),dockTab:M.observable("details"),seoSchemaNote:M.observable(""),catalogue:M.observable(null),cssMode:M.observable(!1),folded:M.observable(!1),previewStatus:M.observable("Showing unsaved changes"),liveWidth:M.observable("full"),versions:M.observable([]),histLoading:M.observable(!1),histError:M.observable(""),compare:M.observable(null),heldNote:M.observable(""),tabs:M.observable([]),active:M.observable(""),curId:M.observable(null),blockTab:M.observable(""),blockPart:M.observable("html"),blockReady:M.observable(!1),blockNote:M.observable(""),blockUses:M.observable(""),blockProject:M.observable(""),blockBundled:M.observable(!1),blockWhere:M.observable(""),compTab:M.observable(""),compPart:M.observable("template"),compReady:M.observable(!1),compNote:M.observable(""),compReadOnly:M.observable(!1),compState:M.observable(""),compErrors:M.observable(""),compProject:M.observable(""),compBundled:M.observable(!1),blockRev:M.observable(0),compRev:M.observable(0),docRev:M.observable(0),filter:M.observable(""),secHere:M.observable(Z.secHere!==!1),secPages:M.observable(Z.secPages!==!1),secBlocks:M.observable(Z.secBlocks!==!1),secComps:M.observable(Z.secComps!==!1),thisPage:M.observable([]),pageRows:M.observable([]),blockRows:M.observable([]),compRows:M.observable([])},V=O("#markdown-editor"),ve=O("#css-editor"),fs=_a(V),bs=_a(ve);i(()=>fs.destroy()),i(()=>bs.destroy());const ce=document.createElement("div");ce.className="editor-line-numbers editor-line-numbers--foldable",V.parentElement.insertBefore(ce,V);const We=ns(V,"md"),Ut=ns(ve,"css");i(()=>{We.destroy(),Ut.destroy()});const Ko=()=>{We.paint(),Ut.paint()},Q=pn(V,ce,{onFoldChange:()=>We.paint()});let gt=!1;Q.setGuard(e=>{gt=e});const ht=()=>Q.getUnfoldedContent(),Jt=()=>{Q.unfoldAll(),o.folded.value=!1,We.paint()},vs=e=>{if(e?.kind==="page")Jt(),_e(V,"md");else if(e?.kind==="block")oe&&_e(oe.textarea,"html"),me&&_e(me.textarea,"css");else if(e?.kind==="component"){if(N.get(e.id)?.readOnly)return;for(const[a,s]of Object.entries({template:"html",props:"json",script:"js",style:"css"}))ae[a]&&_e(ae[a].textarea,s)}},Uo=e=>{e.error?E.toast(e.error,{type:"warning"}):E.toast(e.unchanged?"Already tidy":"Formatted",{type:"info",duration:900})},Jo=M.observable(It(Z.type)),Wo=M.observable(Ht(Z.code));i(M.effect(()=>{const e=Wo.value;ur(e),O("#editor-body")?.style.setProperty("--pe-tab",String(e.size))})),i(M.effect(()=>{const e=Jo.value,t=O("#editor-body");if(t){is(e.font);for(const[a,s]of Object.entries(Va(e)))t.style.setProperty(a,s);t.classList.toggle("pe-nowrap",!e.wrap),V.wrap=e.wrap?"soft":"off",ve.wrap=e.wrap?"soft":"off",requestAnimationFrame(()=>{c()&&Ko()})}}));let Yo=null;i(()=>{try{Yo?.close()}catch{}});const _=()=>(o.bodyRev.value,{urlPath:p.urlPath.value.trim(),title:p.title.value,description:p.description.value,layout:p.layout.value,status:p.status.value,sortOrder:p.sortOrder.value,showInNav:p.showInNav.value,sidebar:p.sidebar.value,breadcrumbs:p.breadcrumbs.value,bundled:p.bundled.value,tags:p.tags.value,adminTags:p.adminTags.value,category:p.category.value,visibility:p.visibility.value,project:p.project.value,theme:p.theme.value,seoTitle:p.seoTitle.value,seoDesc:p.seoDesc.value,seoSchema:p.seoSchema.value,dconfig:p.dconfig.value,body:ht(),css:null}),Go=()=>M.untracked?M.untracked(_):_(),ee=M.observable(""),yt=()=>p.cssOpened.peek()&&p.css.peek()!==ee.peek(),K=new Map;let m=null;const L=new Map,N=new Map;let P=[];const de=e=>Do(e.form)!==e.base,ge=()=>[...L.entries()].filter(([,e])=>de(e)).map(([e])=>e),he=e=>!e.readOnly&&Fo({name:e.name,...e.form})!==e.base,Ye=()=>[...N.values()].filter(he).map(e=>e.name),Wt=()=>W(Go())!==o.base.peek(),Yt=e=>e.loaded&&(e===m?Wt():W(e.state)!==e.base),Re=()=>[...K.values()].filter(Yt),gs=M.computed(()=>W(_())!==o.base.value),hs=M.computed(()=>p.cssOpened.value&&p.css.value!==ee.value),ys=M.computed(()=>(o.blockRev.value,o.compRev.value,o.docRev.value,W(_())!==o.base.value||p.cssOpened.value&&p.css.value!==ee.value||Re().some(e=>e!==m)||ge().length>0||Ye().length>0)),ks=M.computed(()=>{o.blockRev.value,o.compRev.value;const e=I(o.active.value);if(e?.kind==="block"){const t=L.get(e.id);return!!(t&&de(t))}if(e?.kind==="component"){const t=N.get(e.id);return!!(t&&he(t))}return W(_())!==o.base.value||p.cssOpened.value&&p.css.value!==ee.value}),ws=M.computed(()=>o.curId.value!==null),Xo=M.computed(()=>I(o.active.value)?.kind||""),Zo=M.computed(()=>!!o.curId.value&&I(o.active.value)?.kind==="page"),Ss=M.computed(()=>p.urlPath.value.trim()||o.curId.value||""),Es=M.computed(()=>Ro({urlPath:p.urlPath.value,dconfig:p.dconfig.value})[0]?.text||""),Ms=M.computed(()=>(o.bodyRev.value,o.catalogue.value?hn({dconfig:p.dconfig.value,body:ht()},o.catalogue.value,{isSelector:Mr}).map((e,t)=>({key:`${t}:${e}`,text:e})):[]));Er().then(e=>{o.catalogue.value=e});const Ts=M.computed(()=>{o.docRev.value;const e=I(o.active.value);return e?e.kind==="block"?o.blockUses.value:e.kind==="component"?Wn({name:e.id,readOnly:o.compReadOnly.value,state:o.compReady.value?o.compState.value:""}):Qn({urlPath:p.urlPath.value,status:p.status.value,isEdit:!!o.curId.value}):""}),Qo=M.computed(()=>o.compTab.value?"component":o.blockTab.value?"block":o.curId.value!==null?"page":""),Cs=M.computed(()=>o.blockTab.value?`[${o.blockTab.value} /]`:""),xs=M.computed(()=>({compiling:"Compiling\u2026",ok:"Compiles",error:"Does not compile"})[o.compState.value]||""),Ps=M.computed(()=>o.compTab.value?`<dm-${o.compTab.value}>`:""),Os=M.computed(()=>o.versions.value.some(e=>e.checked.value)),Rs=M.computed(()=>o.versions.value.length>0&&o.versions.value.every(e=>e.checked.value)),As=M.computed(()=>{const e=o.versions.value.filter(t=>t.checked.value).length;return e>0&&e<o.versions.value.length});k=()=>Re().length>0||ge().length>0||Ye().length>0||yt();const Gt=(e,t,a)=>({title:String(e.title||"").trim()||"Untitled",description:String(e.description||"").trim(),layout:e.layout,status:e.status,sortOrder:parseInt(String(e.sortOrder),10)||99,showInNav:!!e.showInNav,sidebar:!!e.sidebar,...e.breadcrumbs?{}:{breadcrumbs:!1},...e.bundled?{bundled:!0}:{},tags:Array.isArray(e.tags)?e.tags:[],...t?.isEdit&&JSON.stringify(e.adminTags)===t.savedAdminTags?{}:{adminTags:Array.isArray(e.adminTags)?e.adminTags:[]},category:String(e.category||"").trim()||null,visibility:e.visibility||"public",project:e.project||"",seo:{title:String(e.seoTitle||"").trim(),description:String(e.seoDesc||"").trim(),...ea(e)?{schema:ea(e)}:t?.isEdit?{schema:null}:{}},dconfig:a,...e.theme?{theme:e.theme}:{}}),ea=e=>Po(e.seoSchema).value,Xt=e=>{const t=String(e.dconfig||"").trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}},$s=()=>p.urlPath.peek().trim()||m?.id||"/";let kt=[],ta=[];const wt=e=>kt.includes(e)||Kt.includes(e);let Ae=new Set;const St=()=>{const e=[...new Set([...kt,...Kt,...L.keys()])],t=Rn(e.filter(s=>!L.has(s)),vt);Ae=new Set(Object.keys(t));const a=Ae.size?`Preview shows unsaved changes to ${[...Ae].join(", ")}`:"";return a!==o.heldNote.peek()&&(o.heldNote.value=a),zn(t,[...L.entries()].map(([s,r])=>({name:s,content:r.form.content,css:r.form.css,dirty:de(r)})))};let Zt="";const Ls=()=>{oa();const e=Zt;if(e){Zt="";try{$e.contentDocument?.querySelector(`[data-block="${CSS.escape(e)}"]`)?.scrollIntoView({block:"center"})}catch{}}},$e=O("#markdown-preview");h.settings.getCustomCss().then(({css:e})=>{if(!c())return;ee.value=e||"";let t=null;try{t=S.get(ft)}catch{}typeof t=="string"&&t!==ee.peek()?(ia(),p.css.value=t,E.toast("Your unsaved custom CSS is back - the CSS button shows it.",{type:"info"})):p.cssOpened.peek()||(p.css.value=ee.peek()),J(ft)}).catch(()=>{});const oa=()=>{const e=$e?.contentDocument;if(!e?.head)return;const t=p.cssOpened.peek()?p.css.peek():"";if(!t)return;let a=e.getElementById("preview-custom-css");a||(a=e.createElement("style"),a.id="preview-custom-css",e.head.appendChild(a)),a.textContent=t};let Qt=null,eo=0;const U=(e=!1)=>{clearTimeout(Qt),Qt=setTimeout(async()=>{if(!$e||o.viewMode.peek()==="write"||!o.active.peek()||o.compTab.peek())return;const t=++eo,a=o.blockTab.peek();o.previewStatus.value="Rendering\u2026";try{let s;if(a&&(!m||!wt(a)))({html:s}=await h.pages.previewFull(Cr,{title:a,layout:"blank",breadcrumbs:!1},_n(a,_s(a)),St()));else if(m){const r=_();({html:s}=await h.pages.previewFull($s(),Gt(r,m,Xt(r)),r.body,St()))}else{$e.srcdoc="";return}if(!c()||t!==eo)return;Pr($e,Fn(xr(s),a),Ls),o.previewStatus.value="Showing unsaved changes"}catch(s){if(!c()||t!==eo)return;o.previewStatus.value="Preview failed - "+(s?.message||"unknown error"),$e.srcdoc='<!doctype html><meta charset="utf-8"><body style="font:14px system-ui;padding:1rem;color:#b91c1c;">Preview failed: '+String(s?.message||"unknown error").replace(/[<&]/g,r=>r==="<"?"&lt;":"&amp;")+"</body>"}},e?0:500)};i(()=>clearTimeout(Qt));const to=sn(d.find("#markdown-editor"),d.find("#editor-toolbar"),{spacerDefault:Y?.layoutOptions?.spacerSize??40,beforeFormat:()=>Jt()});ln(V,{blocks:()=>bt,openBlock:e=>Be(e)});const Ge=y.querySelector(".editor-toolbar-right");Ge.querySelectorAll(".editor-view-btn[data-mode]").forEach(e=>{const t=e.getAttribute("data-mode");e.classList.remove("active"),e.setAttribute("data-bind-class",`viewMode.value === '${t}' && 'active'`),e.setAttribute("data-on-click",`setMode('${t}')`)}),O("#fullscreen-btn")?.setAttribute("data-on-click","toggleFullscreen");const Ns=mt(`
127
+ </style>`;function ls({kind:d,projects:b,taken:v,project:i="",name:k="",check:u,create:w,register:y=()=>{}}){return new Promise(x=>{const j=E.slideover({title:d==="block"?"New block":"New component",size:"sm",position:"right"});y(()=>{try{j.close()}catch{}});const c=mt(`<div>${Sr}</div>`);for(const D of b)c.querySelector("#pe-new-project").append(new Option(D.name||D.slug,D.slug));const A={name:M.observable(k),project:M.observable(i),busy:M.observable(!1),hint:M.observable(d==="block"?"A block is a reusable piece of HTML with {{placeholders}}, used on pages with its short tag or by a collection display. Its name is its tag - fixed once created.":"A component is a custom element - <dm-name> - with a template, props, a script and a style. Its name is its tag - fixed once created."),placeholder:M.observable(d==="block"?"e.g. team-card":"e.g. pricing-table")};A.error=M.computed(()=>A.name.value.trim()?u(A.name.value.trim(),v):""),A.canCreate=M.computed(()=>!A.busy.value&&!!A.name.value.trim()&&!u(A.name.value.trim(),v));let H="";A.create=async()=>{const D=A.name.peek().trim();if(!(!D||A.error.peek()||A.busy.peek())){A.busy.value=!0;try{await w(D,A.project.peek()),H=D,j.close()}catch(se){E.toast(`Not created: ${se.message||se}`,{type:"error"})}finally{A.busy.value=!1}}},A.cancel=()=>j.close(),A.key=D=>{D.key==="Enter"&&(D.preventDefault(),A.create())};const Y=M.applyBindings(A,c);Bt(j,()=>{Y.dispose(),x(H)}),j.element.appendChild(c),c.querySelector("#pe-new-project").value=i,j.open(),setTimeout(()=>{const D=c.querySelector("#pe-new-name");D?.focus(),D?.select()},100)})}let F=null,cs=!1;function Er(){cs||!window.R?.use||(cs=!0,Ln(),R.use((d,b,v)=>{if(F&&!F.alive()){const u=F;F=null,u.dispose()}const i=b?.path||"",k=d?.path||"";if(!F||!Oo.test(i))return v();if(Oo.test(k)){const u=Ua(k);if(u){F.open(u,k);return}return v()}return F.dirty()?E.confirm("You have unsaved changes. Leave anyway? They are kept as drafts for your next visit.").then(u=>{u?(F?.keepDraft(),v()):F&&history.replaceState({pe:1},"","#"+F.address)}):v()}),M.subscribe("router:afterChange",({to:d}={})=>{if(F&&!Oo.test(d?.path||"")){const b=F;F=null,b.dispose()}}))}const ds="editor_prefs";function Pe(){return S.get(ds)||{viewMode:"split",fullscreen:!1}}let Mr=null;const Tr=()=>Mr??(Mr=h.pages.dommaCatalogue().then(d=>(kn(d),yn()))),Cr=d=>{try{return document.createDocumentFragment().querySelector(d),!0}catch{return!1}},xr=()=>{try{return Pe()||{}}catch{return{}}};function Ke(d,b){const v=Pe();v[d]=b,S.set(ds,v)}const ps="editor-workspace.tabs",us="editor-workspace.folded",ft="editor-workspace.css",Pr="/__block-preview",Or=d=>d.replace(/<\/head>/i,"<style>body.dm-cloaked{opacity:1 !important;transition:none !important}</style></head>");function Rr(d,b,v=()=>{}){let i=0;try{i=d.contentWindow.scrollY||0}catch{}d.addEventListener("load",()=>{try{d.contentWindow.scrollTo(0,i)}catch{}v()},{once:!0}),d.srcdoc=b}const Ar=["urlPath","title","description","layout","status","sortOrder","category","visibility","project","theme","seoTitle","seoDesc","seoSchema","dconfig"],$r=["showInNav","sidebar","breadcrumbs","bundled"],ms=()=>({urlPath:"",title:"",description:"",layout:"",status:"draft",sortOrder:"99",showInNav:!1,sidebar:!1,breadcrumbs:!0,bundled:!1,tags:[],adminTags:[],category:"",visibility:"public",project:"",theme:"",seoTitle:"",seoDesc:"",seoSchema:"",dconfig:"",body:"",css:null});export const pageEditorView={templateUrl:"/admin/js/templates/page-editor.html",async onMount(d){if(Er(),F){const e=F;F=null,e.dispose()}const b=window.location.hash.replace(/^#/,""),v=[],i=e=>(v.push(e),e);let k=()=>!1,u=()=>{},w=()=>{};const y=d.get(0),x=y.querySelector("#pe-workspace"),j={address:b,alive:()=>x?.isConnected===!0,dirty:()=>k(),keepDraft:()=>u(),open:(e,t)=>w(e,t),dispose:()=>{v.splice(0).forEach(e=>{try{e()}catch{}})}};F=j;const c=()=>F===j&&j.alive();if(xr().closeSidebar===!0){const e=document.querySelector("#admin-sidebar");e&&!Ja(e)&&!window.matchMedia("(max-width: 768px)").matches&&(Wa(e,!0,!1),i(()=>{e.isConnected&&Ja(e)&&Wa(e,!1,!1)}))}const A=E.loader(y,{type:"dots"});let[H,Y,D,se,_t,T,ne,Oe]=await Promise.all([h.layouts.get().catch(()=>({})),h.settings.get().catch(()=>({})),h.pages.list().catch(()=>[]),h.projects.list().catch(()=>[]),h.pages.tags().catch(()=>[]),h.listTags.list("pages").then(e=>e.map(t=>t.name)).catch(()=>[]),h.get("/blocks?usage=1").catch(()=>h.blocks.list()).catch(()=>[]),h.components.list().catch(()=>[])]);if(!c()){A.destroy();return}A.destroy();const O=e=>y.querySelector(e);if(D=Array.isArray(D)?D:[],dn(O("#field-theme"),{includeDefault:!0}),await Br(O("#field-visibility")),!c())return;const re=Object.keys(H||{});jr(O("#field-layout"),H,re[0]||"default");const Ho=e=>re.includes(e)?e:re[0]||e||"default";for(const e of se)for(const t of["#field-project","#block-project","#comp-project"])O(t).append(new Option(e.name||e.slug,e.slug));let ie=Array.isArray(ne)?ne:[],bt=Ya(ie);const vt=new Map(ie.map(e=>[e.name,e.updatedAt])),Ue=new Map(ie.map(e=>[e.name,e.usage])),be=new Set(ie.map(e=>e.name)),Vo=async()=>{const e=await h.get("/blocks?usage=1").catch(()=>null);if(!(!c()||!Array.isArray(e))){ie=e,bt=Ya(ie);for(const t of ie)be.add(t.name),Ue.set(t.name,t.usage),vt.has(t.name)||vt.set(t.name,t.updatedAt)}},Kt=Array.isArray(Y?.footer?.blocks)?Y.footer.blocks.filter(e=>typeof e=="string"):[];let Je=Array.isArray(Oe)?Oe.filter(e=>typeof e?.name=="string"):[];const le=new Set(Je.map(e=>e.name)),_o=async()=>{const e=await h.components.list().catch(()=>null);if(!(!c()||!Array.isArray(e))){Je=e.filter(t=>typeof t?.name=="string");for(const t of Je)le.add(t.name)}},Z=Pe(),p={urlPath:M.observable(""),title:M.observable(""),description:M.observable(""),layout:M.observable(Ho("default")),status:M.observable("draft"),sortOrder:M.observable("99"),showInNav:M.observable(!1),sidebar:M.observable(!1),breadcrumbs:M.observable(!0),bundled:M.observable(!1),tags:M.observable([]),adminTags:M.observable([]),category:M.observable(""),visibility:M.observable("public"),project:M.observable(""),theme:M.observable(""),seoTitle:M.observable(""),seoDesc:M.observable(""),seoSchema:M.observable(""),dconfig:M.observable(""),css:M.observable(""),cssOpened:M.observable(!1)},o={bodyRev:M.observable(0),base:M.observable(""),saving:M.observable(!1),viewMode:M.observable(jo(Z.viewMode)),fullscreen:M.observable(!!Z.fullscreen),explorerOn:M.observable(Z.explorer??!window.matchMedia("(max-width: 1024px)").matches),dockOn:M.observable(!!Z.dock),dockTab:M.observable("details"),seoSchemaNote:M.observable(""),catalogue:M.observable(null),cssMode:M.observable(!1),folded:M.observable(!1),previewStatus:M.observable("Showing unsaved changes"),liveWidth:M.observable("full"),versions:M.observable([]),histLoading:M.observable(!1),histError:M.observable(""),compare:M.observable(null),heldNote:M.observable(""),tabs:M.observable([]),active:M.observable(""),curId:M.observable(null),blockTab:M.observable(""),blockPart:M.observable("html"),blockReady:M.observable(!1),blockNote:M.observable(""),blockUses:M.observable(""),blockProject:M.observable(""),blockBundled:M.observable(!1),blockWhere:M.observable(""),compTab:M.observable(""),compPart:M.observable("template"),compReady:M.observable(!1),compNote:M.observable(""),compReadOnly:M.observable(!1),compState:M.observable(""),compErrors:M.observable(""),compProject:M.observable(""),compBundled:M.observable(!1),blockRev:M.observable(0),compRev:M.observable(0),docRev:M.observable(0),filter:M.observable(""),secHere:M.observable(Z.secHere!==!1),secPages:M.observable(Z.secPages!==!1),secBlocks:M.observable(Z.secBlocks!==!1),secComps:M.observable(Z.secComps!==!1),thisPage:M.observable([]),pageRows:M.observable([]),blockRows:M.observable([]),compRows:M.observable([])},V=O("#markdown-editor"),ve=O("#css-editor"),fs=_a(V),bs=_a(ve);i(()=>fs.destroy()),i(()=>bs.destroy());const ce=document.createElement("div");ce.className="editor-line-numbers editor-line-numbers--foldable",V.parentElement.insertBefore(ce,V);const We=ns(V,"md"),Ut=ns(ve,"css");i(()=>{We.destroy(),Ut.destroy()});const Ko=()=>{We.paint(),Ut.paint()},Q=pn(V,ce,{onFoldChange:()=>We.paint()});let gt=!1;Q.setGuard(e=>{gt=e});const ht=()=>Q.getUnfoldedContent(),Jt=()=>{Q.unfoldAll(),o.folded.value=!1,We.paint()},vs=e=>{if(e?.kind==="page")Jt(),_e(V,"md");else if(e?.kind==="block")oe&&_e(oe.textarea,"html"),me&&_e(me.textarea,"css");else if(e?.kind==="component"){if(N.get(e.id)?.readOnly)return;for(const[a,s]of Object.entries({template:"html",props:"json",script:"js",style:"css"}))ae[a]&&_e(ae[a].textarea,s)}},Uo=e=>{e.error?E.toast(e.error,{type:"warning"}):E.toast(e.unchanged?"Already tidy":"Formatted",{type:"info",duration:900})},Jo=M.observable(It(Z.type)),Wo=M.observable(Ht(Z.code));i(M.effect(()=>{const e=Wo.value;fr(e),O("#editor-body")?.style.setProperty("--pe-tab",String(e.size))})),i(M.effect(()=>{const e=Jo.value,t=O("#editor-body");if(t){is(e.font);for(const[a,s]of Object.entries(Va(e)))t.style.setProperty(a,s);t.classList.toggle("pe-nowrap",!e.wrap),V.wrap=e.wrap?"soft":"off",ve.wrap=e.wrap?"soft":"off",requestAnimationFrame(()=>{c()&&Ko()})}}));let Yo=null;i(()=>{try{Yo?.close()}catch{}});const _=()=>(o.bodyRev.value,{urlPath:p.urlPath.value.trim(),title:p.title.value,description:p.description.value,layout:p.layout.value,status:p.status.value,sortOrder:p.sortOrder.value,showInNav:p.showInNav.value,sidebar:p.sidebar.value,breadcrumbs:p.breadcrumbs.value,bundled:p.bundled.value,tags:p.tags.value,adminTags:p.adminTags.value,category:p.category.value,visibility:p.visibility.value,project:p.project.value,theme:p.theme.value,seoTitle:p.seoTitle.value,seoDesc:p.seoDesc.value,seoSchema:p.seoSchema.value,dconfig:p.dconfig.value,body:ht(),css:null}),Go=()=>M.untracked?M.untracked(_):_(),ee=M.observable(""),yt=()=>p.cssOpened.peek()&&p.css.peek()!==ee.peek(),K=new Map;let m=null;const L=new Map,N=new Map;let P=[];const de=e=>Do(e.form)!==e.base,ge=()=>[...L.entries()].filter(([,e])=>de(e)).map(([e])=>e),he=e=>!e.readOnly&&Fo({name:e.name,...e.form})!==e.base,Ye=()=>[...N.values()].filter(he).map(e=>e.name),Wt=()=>W(Go())!==o.base.peek(),Yt=e=>e.loaded&&(e===m?Wt():W(e.state)!==e.base),Re=()=>[...K.values()].filter(Yt),gs=M.computed(()=>W(_())!==o.base.value),hs=M.computed(()=>p.cssOpened.value&&p.css.value!==ee.value),ys=M.computed(()=>(o.blockRev.value,o.compRev.value,o.docRev.value,W(_())!==o.base.value||p.cssOpened.value&&p.css.value!==ee.value||Re().some(e=>e!==m)||ge().length>0||Ye().length>0)),ks=M.computed(()=>{o.blockRev.value,o.compRev.value;const e=I(o.active.value);if(e?.kind==="block"){const t=L.get(e.id);return!!(t&&de(t))}if(e?.kind==="component"){const t=N.get(e.id);return!!(t&&he(t))}return W(_())!==o.base.value||p.cssOpened.value&&p.css.value!==ee.value}),ws=M.computed(()=>o.curId.value!==null),Xo=M.computed(()=>I(o.active.value)?.kind||""),Zo=M.computed(()=>!!o.curId.value&&I(o.active.value)?.kind==="page"),Ss=M.computed(()=>p.urlPath.value.trim()||o.curId.value||""),Es=M.computed(()=>Ro({urlPath:p.urlPath.value,dconfig:p.dconfig.value})[0]?.text||""),Ms=M.computed(()=>(o.bodyRev.value,o.catalogue.value?hn({dconfig:p.dconfig.value,body:ht()},o.catalogue.value,{isSelector:Cr}).map((e,t)=>({key:`${t}:${e}`,text:e})):[]));Tr().then(e=>{o.catalogue.value=e});const Ts=M.computed(()=>{o.docRev.value;const e=I(o.active.value);return e?e.kind==="block"?o.blockUses.value:e.kind==="component"?Gn({name:e.id,readOnly:o.compReadOnly.value,state:o.compReady.value?o.compState.value:""}):tr({urlPath:p.urlPath.value,status:p.status.value,isEdit:!!o.curId.value}):""}),Qo=M.computed(()=>o.compTab.value?"component":o.blockTab.value?"block":o.curId.value!==null?"page":""),Cs=M.computed(()=>o.blockTab.value?`[${o.blockTab.value} /]`:""),xs=M.computed(()=>({compiling:"Compiling\u2026",ok:"Compiles",error:"Does not compile"})[o.compState.value]||""),Ps=M.computed(()=>o.compTab.value?`<dm-${o.compTab.value}>`:""),Os=M.computed(()=>o.versions.value.some(e=>e.checked.value)),Rs=M.computed(()=>o.versions.value.length>0&&o.versions.value.every(e=>e.checked.value)),As=M.computed(()=>{const e=o.versions.value.filter(t=>t.checked.value).length;return e>0&&e<o.versions.value.length});k=()=>Re().length>0||ge().length>0||Ye().length>0||yt();const Gt=(e,t,a)=>({title:String(e.title||"").trim()||"Untitled",description:String(e.description||"").trim(),layout:e.layout,status:e.status,sortOrder:parseInt(String(e.sortOrder),10)||99,showInNav:!!e.showInNav,sidebar:!!e.sidebar,...e.breadcrumbs?{}:{breadcrumbs:!1},...e.bundled?{bundled:!0}:{},tags:Array.isArray(e.tags)?e.tags:[],...t?.isEdit&&JSON.stringify(e.adminTags)===t.savedAdminTags?{}:{adminTags:Array.isArray(e.adminTags)?e.adminTags:[]},category:String(e.category||"").trim()||null,visibility:e.visibility||"public",project:e.project||"",seo:{title:String(e.seoTitle||"").trim(),description:String(e.seoDesc||"").trim(),...ea(e)?{schema:ea(e)}:t?.isEdit?{schema:null}:{}},dconfig:a,...e.theme?{theme:e.theme}:{}}),ea=e=>Po(e.seoSchema).value,Xt=e=>{const t=String(e.dconfig||"").trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}},$s=()=>p.urlPath.peek().trim()||m?.id||"/";let kt=[],ta=[];const wt=e=>kt.includes(e)||Kt.includes(e);let Ae=new Set;const St=()=>{const e=[...new Set([...kt,...Kt,...L.keys()])],t=$n(e.filter(s=>!L.has(s)),vt);Ae=new Set(Object.keys(t));const a=Ae.size?`Preview shows unsaved changes to ${[...Ae].join(", ")}`:"";return a!==o.heldNote.peek()&&(o.heldNote.value=a),Hn(t,[...L.entries()].map(([s,r])=>({name:s,content:r.form.content,css:r.form.css,dirty:de(r)})))};let Zt="";const Ls=()=>{oa();const e=Zt;if(e){Zt="";try{$e.contentDocument?.querySelector(`[data-block="${CSS.escape(e)}"]`)?.scrollIntoView({block:"center"})}catch{}}},$e=O("#markdown-preview");h.settings.getCustomCss().then(({css:e})=>{if(!c())return;ee.value=e||"";let t=null;try{t=S.get(ft)}catch{}typeof t=="string"&&t!==ee.peek()?(ia(),p.css.value=t,E.toast("Your unsaved custom CSS is back - the CSS button shows it.",{type:"info"})):p.cssOpened.peek()||(p.css.value=ee.peek()),J(ft)}).catch(()=>{});const oa=()=>{const e=$e?.contentDocument;if(!e?.head)return;const t=p.cssOpened.peek()?p.css.peek():"";if(!t)return;let a=e.getElementById("preview-custom-css");a||(a=e.createElement("style"),a.id="preview-custom-css",e.head.appendChild(a)),a.textContent=t};let Qt=null,eo=0;const U=(e=!1)=>{clearTimeout(Qt),Qt=setTimeout(async()=>{if(!$e||o.viewMode.peek()==="write"||!o.active.peek()||o.compTab.peek())return;const t=++eo,a=o.blockTab.peek();o.previewStatus.value="Rendering\u2026";try{let s;if(a&&(!m||!wt(a)))({html:s}=await h.pages.previewFull(Pr,{title:a,layout:"blank",breadcrumbs:!1},Un(a,_s(a)),St()));else if(m){const r=_();({html:s}=await h.pages.previewFull($s(),Gt(r,m,Xt(r)),r.body,St()))}else{$e.srcdoc="";return}if(!c()||t!==eo)return;Rr($e,qn(Or(s),a),Ls),o.previewStatus.value="Showing unsaved changes"}catch(s){if(!c()||t!==eo)return;o.previewStatus.value="Preview failed - "+(s?.message||"unknown error"),$e.srcdoc='<!doctype html><meta charset="utf-8"><body style="font:14px system-ui;padding:1rem;color:#b91c1c;">Preview failed: '+String(s?.message||"unknown error").replace(/[<&]/g,r=>r==="<"?"&lt;":"&amp;")+"</body>"}},e?0:500)};i(()=>clearTimeout(Qt));const to=sn(d.find("#markdown-editor"),d.find("#editor-toolbar"),{spacerDefault:Y?.layoutOptions?.spacerSize??40,beforeFormat:()=>Jt()});ln(V,{blocks:()=>bt,openBlock:e=>Be(e)});const Ge=y.querySelector(".editor-toolbar-right");Ge.querySelectorAll(".editor-view-btn[data-mode]").forEach(e=>{const t=e.getAttribute("data-mode");e.classList.remove("active"),e.setAttribute("data-bind-class",`viewMode.value === '${t}' && 'active'`),e.setAttribute("data-on-click",`setMode('${t}')`)}),O("#fullscreen-btn")?.setAttribute("data-on-click","toggleFullscreen");const Ns=mt(`
128
128
  <span class="pe-toolbar-extras" style="display:contents">
129
129
  <button type="button" class="editor-view-btn" data-tip="Edit Custom CSS" data-on-click="toggleCss"
130
130
  data-bind-class="cssMode.value && 'active'"><span>CSS</span></button>
@@ -136,8 +136,8 @@ The quick brown fox - 0O 1lI {} [] () =&gt; ==
136
136
  <span class="pe-fold-icon" hidden data-bind-hidden="!folded.value"><span data-icon="chevrons-right" data-icon-size="10"></span></span>
137
137
  </button>
138
138
  <span class="editor-toolbar-sep"></span>
139
- </span>`);Ge.prepend(Ns),Ge.before(O(".pe-block-bar")),Ge.before(O(".pe-comp-bar"));const aa=e=>(Array.isArray(e)?e:[]).map(t=>({value:t,label:t})),sa=O("#field-tags");let Et=null;Et=sa?E.pillbox(sa,{data:aa(_t),value:[],creatable:!0,searchable:!0,placeholder:"Add tag\u2026",onChange:()=>{Et&&(p.tags.value=[...Et.getValue()])}}):null;const na=O("#field-admin-tags");let Mt=null;Mt=na?E.pillbox(na,{data:aa(T),value:[],creatable:!0,searchable:!0,placeholder:"Add admin tag\u2026",onChange:()=>{Mt&&(p.adminTags.value=[...Mt.getValue()])}}):null;const ra=()=>{o.bodyRev.value=o.bodyRev.peek()+1},Le=()=>{o.blockRev.value=o.blockRev.peek()+1},ye=()=>{o.compRev.value=o.compRev.peek()+1},Xe=()=>{o.docRev.value=o.docRev.peek()+1},ia=()=>{p.cssOpened.peek()||(p.css.peek()||(p.css.value=ee.peek()),p.cssOpened.value=!0,an(ve,{language:"css"}))},Ze=e=>{for(const t of Or)p[t].value=e[t]==null?"":String(e[t]);for(const t of Rr)p[t].value=!!e[t];p.tags.value=Array.isArray(e.tags)?e.tags:[],Et?.setValue(p.tags.peek()),Array.isArray(e.adminTags)&&(p.adminTags.value=e.adminTags),Mt?.setValue(p.adminTags.peek()),qo(O("#field-visibility"),p.visibility.peek()),Q.unfoldAll(),o.folded.value=!1,gt=!0,V.value=e.body==null?"":String(e.body),gt=!1,Q.refresh(),Ko(),ra()},la=(e,t)=>({urlPath:t||"",title:e?.title||"",description:e?.description||"",layout:Ho(e?.layout||"default"),status:e?.status||"draft",sortOrder:String(e?.sortOrder??99),showInNav:!!e?.showInNav,sidebar:!!e?.sidebar,breadcrumbs:e?e.breadcrumbs!==!1:!0,bundled:!!e?.bundled,tags:Array.isArray(e?.tags)?e.tags:[],adminTags:Array.isArray(e?.adminTags)?e.adminTags:[],category:e?.category||"",visibility:typeof e?.visibility=="string"&&e.visibility?e.visibility:"public",project:Pn({isEdit:!!t,page:e,projects:se,fromHash:t?"":zt()||"",urlPath:t||""}),theme:e?.theme||"",seoTitle:e?.seo?.title||"",seoDesc:e?.seo?.description||"",seoSchema:bn(e?.seo?.schema),dconfig:e?.dconfig?JSON.stringify(e.dconfig,null,2):"",body:e?.content||"",css:null}),ca=()=>{m&&(m.state=_(),m.at=Date.now())},da=e=>{m!==e&&(ca(),m=e,Ze(e.state),o.base.value=e.base,o.curId.value=e.id,e.at=Date.now(),Ct(),Xe())},Ds=()=>{ca(),m=null;const e=ms();Ze(e),o.base.value=W(e),o.curId.value=null,Ct(),Xe()};Ze(ms()),o.base.value=W(_());const J=e=>{try{S.remove?S.remove(e):S.set(e,null)}catch{}},pa=(e,t)=>({name:e.name,...e.form,base:e.base,at:t});u=()=>{try{for(const t of Re())S.set(ze(t.id),Ka(t===m?Go():t.state,t.base));yt()&&S.set(ft,p.css.peek());const e=new Date().toISOString();for(const t of ge()){const a=L.get(t);S.set(He(t),{form:{...a.form},base:a.base,at:e})}for(const t of Ye())S.set(Ve(t),pa(N.get(t),e))}catch{}};const ua=e=>{k()&&(u(),e.preventDefault(),e.returnValue="")};window.addEventListener("beforeunload",ua),i(()=>window.removeEventListener("beforeunload",ua));let Qe=!1,Tt=null;const Ct=()=>{Qe=!1,Tt=null,o.versions.value=[],o.compare.value=null,o.histError.value="",o.dockOn.peek()&&o.dockTab.peek()==="history"&&(m?.isEdit?pe():o.dockTab.value="details")},pe=async()=>{const e=m;if(e?.isEdit){Qe=!0,o.histLoading.value=!0,o.histError.value="";try{const t=(await h.versions.list(e.id)).versions||[];if(!c()||m!==e)return;o.versions.value=t.map(a=>({...a,when:qe(a.createdAt),author:a.author||"",label:a.label||"",who:[a.author,a.label].filter(Boolean).join(" - "),checked:M.observable(!1)}))}catch(t){m===e&&(o.histError.value="Failed to load versions: "+t.message)}finally{m===e&&(o.histLoading.value=!1)}}},oo=e=>o.versions.peek().find(t=>t.filename===e),ao=async e=>{const t=m;try{const a=await h.versions.get(t.id,e.filename);if(!c()||m!==t)return;Tt=e.filename,o.compare.value={label:rs(e),old:a.content,current:ht()}}catch(a){E.toast("Failed to load version: "+a.message,{type:"error"})}},js=async()=>{const e=m;if(!e?.isEdit)return;const t=await h.pages.get(e.id).catch(()=>null);if(!c()||m!==e||!t)return;e.page=t;const a=la(t,e.id);e.base=W(a),e.savedAdminTags=JSON.stringify(a.adminTags),Ze(a),o.base.value=e.base,Ct(),o.dockOn.peek()&&o.dockTab.peek()==="history"&&pe(),U()},ma=async e=>{if(!(!e||!await E.confirm("Restore this version? The current page content will be overwritten (a pre-restore snapshot will be saved automatically).")))try{await h.versions.restore(m.id,e),E.toast("Page restored.",{type:"success"}),await js()}catch(t){E.toast("Restore failed: "+t.message,{type:"error"})}},Bs=async e=>{if(await E.confirm("Delete this version? This cannot be undone."))try{await h.versions.delete(m.id,e.filename),E.toast("Version deleted.",{type:"success"}),await pe()}catch(t){E.toast("Failed to delete: "+t.message,{type:"error"})}},Ne=new Map,Is=e=>{if(!Ne.has(e)){const t=I(e);Ne.set(e,{id:e,kind:t.kind,kindText:t.kind==="page"?"Page":t.kind==="component"?"Component":"Block",label:M.observable(""),title:M.observable(""),active:M.observable(!1),dirty:M.observable(!1)})}return Ne.get(e)},fa=e=>{const t=e===m?p.title.peek():e?.loaded?e.state.title:D.find(a=>a.urlPath===e?.id)?.title;return String(t||"").trim()||e?.id||"New page"};let ba=!0,va="";const Fs=()=>{if(ba)return;const e={ids:P,active:o.active.peek()},t=JSON.stringify(e);if(t!==va){va=t;try{S.set(ps,e)}catch{}}},q=()=>{const e=P.map(Is);for(const t of e){const a=I(t.id);let s,r;if(a.kind==="page"){const l=K.get(a.id);s=fa(l),r=l?.loaded?Yt(l):xe(a),t.title.value=a.id?`${s} (${a.id})`:"New page"}else if(a.kind==="component"){const l=N.get(a.id);s=a.id,r=l?he(l):xe(a),t.title.value=`Component <dm-${a.id}>`}else{const l=L.get(a.id);s=a.id,r=l?de(l):Ae.has(a.id)||xe(a),t.title.value=`Block ${a.id}`}t.label.peek()!==s&&(t.label.value=s),t.dirty.peek()!==r&&(t.dirty.value=r);const n=t.id===o.active.peek();t.active.peek()!==n&&(t.active.value=n)}e.map(t=>t.id).join("|")!==o.tabs.peek().map(t=>t.id).join("|")&&(o.tabs.value=e),Fs()};let ke=new Set;try{const e=S.get(us);Array.isArray(e)&&(ke=new Set(e.filter(t=>typeof t=="string")))}catch{}const ga=new Map,so=e=>{let t=ga.get(e.key);return t?(t.label.peek()!==e.label&&(t.label.value=e.label),t.meta.peek()!==(e.meta||"")&&(t.meta.value=e.meta||""),t.status.peek()!==(e.status||"")&&(t.status.value=e.status||""),t.folder.peek()!==!!e.folder&&(t.folder.value=!!e.folder)):(t={...e,label:M.observable(e.label),meta:M.observable(e.meta||""),status:M.observable(e.status||""),folder:M.observable(!!e.folder),active:M.observable(!1),dirty:M.observable(!1),folded:M.observable(!1),title:""},ga.set(e.key,t)),t.title=e.kind==="block"||e.kind==="component"?e.meta?`${e.id} - ${e.meta}`:e.id:e.kind==="folder"?e.meta:`${e.label} (${e.meta})`,t},no=new Map,z=()=>{const e=o.filter.peek(),t=I(o.active.peek()),a=t?.kind==="page"?t.id:null,s=t?.kind==="block"?t.id:null,r=t?.kind==="component"?t.id:null,n=new Set(Re().map(f=>f.id)),l=Zn(D,{filter:e,folded:ke}).map(so);for(const f of l){const C=f.kind==="page"&&f.id===a,B=f.kind==="page"&&(n.has(f.id)||!K.get(f.id)?.loaded&&xe({kind:"page",id:f.id})),fe=ke.has(f.id);f.active.peek()!==C&&(f.active.value=C),f.dirty.peek()!==B&&(f.dirty.value=B),f.folded.peek()!==fe&&(f.folded.value=fe)}const g=Kn(ie,e).map(so),$=f=>{const C=L.get(f);return C?de(C):Ae.has(f)||xe({kind:"block",id:f})};for(const f of g){const C=f.id===s,B=$(f.id);f.active.peek()!==C&&(f.active.value=C),f.dirty.peek()!==B&&(f.dirty.value=B)}const G=Jn(Je,e).map(so),Te=f=>{const C=N.get(f);return C?he(C):xe({kind:"component",id:f})};for(const f of G){const C=f.id===r,B=Te(f.id);f.active.peek()!==C&&(f.active.value=C),f.dirty.peek()!==B&&(f.dirty.value=B)}const Co=m?Bn(kt,Kt,be):[],za=(f,C,B)=>(no.has(f)||no.set(f,{key:f,id:C,label:B,kindText:"",title:"",active:M.observable(!1),dirty:M.observable(!1)}),no.get(f)),xo=Co.map(f=>{const C=za(`block:${f.name}`,f.name,f.name);C.kindText=f.footer?"Footer":"Block",C.title=`${f.name} - ${f.footer?"in the footer, on every page":"a block on this page"}`;const B=f.name===s,fe=$(f.name);return C.active.peek()!==B&&(C.active.value=B),C.dirty.peek()!==fe&&(C.dirty.value=fe),C});for(const f of ta){const C=za(`component:${f}`,f,f);C.kindText="Component",C.title=`<dm-${f}> - a component on this page`;const B=f===r,fe=Te(f);C.active.peek()!==B&&(C.active.value=B),C.dirty.peek()!==fe&&(C.dirty.value=fe),xo.push(C)}const jt=(f,C)=>f.map(B=>B.key).join("|")===C.map(B=>B.key).join("|");jt(l,o.pageRows.peek())||(o.pageRows.value=l),jt(g,o.blockRows.peek())||(o.blockRows.value=g),jt(G,o.compRows.peek())||(o.compRows.value=G),jt(xo,o.thisPage.peek())||(o.thisPage.value=xo)},ha=async()=>{const e=await h.pages.list().catch(()=>null);!c()||!Array.isArray(e)||(D=e,z(),q())},te=()=>{const e=I(o.active.peek()),t=e?es(e):"/pages/new",a=window.location.hash.replace(/^#/,"");j.address=a.split("?")[0]===t?a:t,a.split("?")[0]!==t?history.replaceState({pe:1},"","#"+t):history.state?.pe||history.replaceState({pe:1},"",window.location.hash)},zs=async e=>{if(e.loading)return e.loading;e.loading=(async()=>{let t=null;if(e.isEdit){if(t=await h.pages.get(e.id).catch(()=>null),!c())return!1;if(!t)return E.toast(`Page ${e.id} not found.`,{type:"error"}),!1}e.page=t;const a=la(t,e.id);e.state=a,e.base=W(a),e.savedAdminTags=JSON.stringify(a.adminTags),e.loaded=!0;let s=null;try{s=S.get(ze(e.id))}catch{}const r=On(s),n=$o({kind:"page",id:e.id});if(r){J(ze(e.id));const l=W(r.state)!==e.base,g=xn(r,e.base),$={...a,...r.state,adminTags:a.adminTags};if(l&&n&&!g)e.state=$,E.toast(`Your unsaved changes to ${e.id||"the new page"} are back.`,{type:"info"});else if(l){const G=r.at?` (${qe(r.at)})`:"",Te=g?" The saved page has changed since - restoring puts your version back over it (the saved one stays in History).":"";await E.confirm(`You left unsaved changes to ${e.id||"a new page"}${G}. Restore them?${Te}`)&&c()&&(e.state=$)}}return!0})();try{return await e.loading}finally{e.loading=null}},ya=e=>(K.has(e)||K.set(e,{kind:"page",id:e,isEdit:!!e,loaded:!1,page:null,state:null,base:"",savedAdminTags:"[]",at:0}),K.get(e)),ue=async e=>{const t=X({kind:"page",id:e});({ids:P}=Bo(P,t)),o.active.value=t,o.blockTab.value="",vo();const a=ya(e);if(q(),!a.loaded){o.previewStatus.value=`Opening ${e||"a new page"}\u2026`;const s=await zs(a);if(!c()||!P.includes(t)||K.get(e)!==a)return;if(!s){ka(t);return}if(o.active.peek()!==t){q(),z();return}}da(a),te(),q(),z(),U(),Q.refresh(),V.focus()};w=async(e,t)=>{if(j.address=t,e.kind==="page"){ue(e.id);return}if(!e.id){(e.kind==="block"?Nt:nt)({project:zt(t)||""});return}const a=e.kind==="block"?be:le;if(a.has(e.id)||await(e.kind==="block"?Vo:_o)(),!!c()){if(!a.has(e.id)){E.toast(`There is no ${e.kind} called "${e.id}".`,{type:"warning"}),te(),z();return}e.kind==="block"?Be(e.id):st(e.id)}};const ka=e=>{const t=o.active.peek(),a=Un(P,e,t);P=a.ids,Ne.delete(e);const s=I(e),r=a.active!==t?I(a.active):null;if(s.kind==="page"){if(K.delete(s.id),m?.id===s.id){const n=[...K.values()].filter(l=>l.loaded&&l.id!==s.id).sort((l,g)=>g.at-l.at)[0];n?da(n):Ds()}}else s.kind==="component"?(N.delete(s.id),o.compTab.peek()===s.id&&vo()):(L.delete(s.id),o.blockTab.peek()===s.id&&(o.blockTab.value="",o.blockReady.value=!1));if(o.active.value=a.active,r?.kind==="page"){ue(r.id);return}if(r?.kind==="block"){Be(r.id);return}if(r?.kind==="component"){st(r.id);return}te(),Xe(),Le(),ye(),q(),z(),U()},et=e=>{const t=I(e);if(!t||!P.includes(e))return;let a="";try{if(t.kind==="page"){const s=K.get(t.id);s&&Yt(s)&&(S.set(ze(s.id),Ka(s===m?_():s.state,s.base)),Ao({kind:"page",id:s.id}),a=fa(s))}else if(t.kind==="component"){const s=N.get(t.id);s&&he(s)&&(S.set(Ve(t.id),pa(s,new Date().toISOString())),Ao({kind:"component",id:t.id}),a=t.id)}else{const s=L.get(t.id);s&&de(s)&&(S.set(He(t.id),{form:{...s.form},base:s.base,at:new Date().toISOString()}),Ao({kind:"block",id:t.id}),a=t.id)}}catch{}ka(e),a&&E.toast(`Changes to "${a}" kept as a draft - back when you open it again.`,{type:"info"})},xt=e=>{const t=I(e);t&&(t.kind==="page"?ue(t.id):t.kind==="component"?st(t.id):Be(t.id))},wa=new Set,qs=async e=>{const t=[];for(const a of e){const s=L.get(a);if(!s)continue;const r={...s.form};try{const n=Za(r,s.block?.meta);await h.blocks.put(a,n),s.block={...s.block,meta:n.meta},s.saved=r,s.base=Do(r),vt.set(a,new Date().toISOString()),c()&&J(He(a)),t.push(a)}catch(n){E.toast(`Block "${a}" not saved: ${n.message||"Unknown error"}`,{type:"error"})}}return t.forEach(a=>wa.add(a)),t.length&&(Le(),pt("#/blocks")),t},Hs=async e=>{const t=e===m?_():e.state,a=Po(t.seoSchema).error;if(a)return E.toast(`${e.id||"The new page"} not saved - structured data: ${a}`,{type:"error"}),e===m&&(o.seoSchemaNote.value=a,o.dockOn.value=!0,o.dockTab.value="seo"),!1;const s=Gt(t,e,Xt(t)),r=e.id;try{if(e.isEdit){const n={frontmatter:s,body:t.body};t.urlPath!==e.id&&(n.newUrlPath=t.urlPath),await h.pages.update(e.id,n)}else await h.pages.create({urlPath:t.urlPath,frontmatter:s,body:t.body})}catch(n){return E.toast(`${e.id||"The new page"} not saved: ${n.message||"Unknown error"}`,{type:"error"}),!1}if(!c())return!0;if(e.savedAdminTags=JSON.stringify(t.adminTags),e.base=W(t),e===m?o.base.value=e.base:e.state=t,J(ze(r)),!e.isEdit||t.urlPath!==e.id){K.delete(r),e.id=t.urlPath,e.isEdit=!0,K.set(e.id,e);const n=X({kind:"page",id:r}),l=X({kind:"page",id:e.id});Ne.delete(n),{ids:P}=tr(P,n,l,o.active.peek()),o.active.peek()===n&&(o.active.value=l),e===m&&(o.curId.value=e.id,te())}return!0},Vs=async e=>{const t=[];for(const a of e){const s=N.get(a);if(!s||s.readOnly)continue;if($t===s?(clearTimeout(At),$t=null,ye(),at(s)):s.state||at(s),s.compiling&&await s.compiling,!c())return t;if(s.state!=="ok"){E.toast(`Component "${a}" not saved: ${s.state==="error"?"it does not compile - fix the errors first.":"it has not compiled yet - try again in a moment."}`,{type:"warning"});continue}const r={...s.form},n={...s.meta||{}};delete n.bundled,r.project?n.project=r.project:delete n.project;try{await h.components.put(a,{source:r.source,bundled:r.bundled,meta:n}),s.meta=n,s.saved=r,s.base=Fo({name:a,...r});const l=Je.find(g=>g.name===a);l&&(l.bundled=r.bundled,l.meta=n),c()&&J(Ve(a)),t.push(a)}catch(l){E.toast(`Component "${a}" not saved: ${l.message||"Unknown error"}`,{type:"error"})}}return t.length&&(ye(),pt("#/components")),t};let ro=!1;const io=async(e=!1)=>{if(o.saving.peek()||ro)return;ro=!0;let t,a,s=[];try{if(await Ea(),!c())return;const n=I(o.active.peek());if(dr().formatOnSave&&vs(n),e)t=Re(),a=ge(),s=Ye();else if(n?.kind==="block")t=[],a=L.has(n.id)&&de(L.get(n.id))?[n.id]:[];else if(n?.kind==="component")t=[],a=[],s=N.has(n.id)&&he(N.get(n.id))?[n.id]:[];else if(n?.kind==="page"&&m)a=ge().filter(wt),t=!m.isEdit||Wt()||!a.length?[m]:[];else return;if(!t.length&&!a.length&&!s.length){E.toast("Nothing to save.",{type:"info"});return}for(const g of t){const $=Ro(g===m?_():g.state);if($.length){E.toast(`${g.id||"New page"}: ${$[0].text}`,{type:"warning"}),g!==m&&await ue(g.id),o.dockOn.value=!0,o.dockTab.value=$[0].field==="dconfig"?"dconfig":"details",Ke("dock",!0);return}}const l=qn(a,Object.fromEntries(a.map(g=>[g,Qa(Ue.get(g),m?.id||"")])),wa);if(l&&(!await E.confirm(l)||!c()))return}finally{ro=!1}const r=t.length>0&&yt();o.saving.value=!0;try{let n=0;for(const $ of t)await Hs($)&&n++;if(!c())return;if(r){const $=p.css.peek();await h.settings.saveCustomCss($),ee.value=$,J(ft)}const l=await qs(a);if(!c())return;const g=await Vs(s);if((n||l.length||g.length)&&E.toast(Hn({pages:n,css:r,blocks:l,components:g}),{type:"success"}),Xe(),!c())return;q(),z(),n&&(pt("#/pages"),Ct(),ha())}catch(n){E.toast(`Save failed: ${n.message||"Unknown error"}`,{type:"error"})}finally{o.saving.value=!1}};let oe=null,me=null;const De=new Map,je=new Map,Sa=()=>{const e=L.get(o.blockTab.peek());!e||!oe||(o.blockReady.value=!1,oe.setValue(e.form.content),me.setValue(e.form.css),o.blockProject.value=e.form.project,qo(O("#block-project"),e.form.project),o.blockBundled.value=e.form.bundled,o.blockWhere.value=Ln({usage:Ue.get(e.form.name)})||"Where it is used could not be read.",o.blockNote.value="",o.blockReady.value=!0,uo())},_s=e=>{const t=L.get(e);if(!t)return{};const a=t.form.content;return Object.fromEntries(ts(Ga(a),No(a),t.samples||{}).map(s=>[s.name,s.value]))};i(M.effect(()=>{const e=o.blockProject.value,t=o.blockBundled.value,a=L.get(o.blockTab.peek());!a||!o.blockReady.peek()||a.form.project===e&&a.form.bundled===t||(a.form.project=e,a.form.bundled=t,Le())}));const lo=async(e,{quiet:t=!1}={})=>{for(;De.has(e);)if(await De.get(e),L.has(e)||t)return L.get(e)||null;if(L.has(e))return L.get(e);const a=(async()=>{try{const s=await h.blocks.get(e);if(!c()||!t&&!P.includes(X({kind:"block",id:e})))return null;const r=Xa({...s,name:e}),n={block:s,saved:r,base:Do(r),form:{...r},samples:{}};let l=null;try{l=S.get(He(e))}catch{}const g=Dn(l,n.base);if(t&&g?.stale)return null;if($o({kind:"block",id:e}),g){const $=g.at?` (${qe(g.at)})`:"",G=!g.stale||await E.confirm(`You left unsaved changes to "${e}"${$}, but the block has been saved since. Restore your version anyway?`);if(!c())return null;G&&(n.form={...n.form,...g.form,name:e},g.stale||E.toast(`Your unsaved changes to "${e}" are back.`,{type:"info"}))}return l&&J(He(e)),L.set(e,n),Le(),n}catch(s){return c()&&o.blockTab.peek()===e&&(o.blockNote.value=`Could not open "${e}": ${s.message||"unknown error"}`),null}finally{De.delete(e)}})();return De.set(e,a),a},Ea=async()=>{for(;De.size||je.size;)await Promise.all([...De.values(),...je.values()])},Be=async e=>{if(!e||!be.has(e))return;const t=X({kind:"block",id:e});({ids:P}=Bo(P,t)),o.active.value=t,vo(),o.cssMode.peek()&&(o.cssMode.value=!1),o.viewMode.peek()==="preview"&&(o.viewMode.value="split"),o.blockTab.peek()!==e&&(o.blockReady.value=!1),o.blockTab.value=e,o.blockUses.value=m&&wt(e)?Vn(Qa(Ue.get(e),m.id||"")):In(Ue.get(e)),te(),q(),z();let a=L.get(e);a||(o.blockReady.value=!1,o.blockNote.value=`Opening ${e}\u2026`,a=await lo(e)),!(!a||!c()||o.blockTab.peek()!==e)&&(Sa(),q(),z(),Zt=e,U(),(o.blockPart.peek()==="css"?me:oe)?.focus())};let co=null;i(()=>clearTimeout(co));const Ma=(e,t)=>{const a=L.get(o.blockTab.peek());!a||!o.blockReady.peek()||(a.form[e]=t,clearTimeout(co),co=setTimeout(()=>{Le(),e==="content"&&uo()},120),U())},we=O("#pe-block-samples"),Ta=e=>{we.replaceChildren();const t=document.createElement("p");t.className="pe-dock-none",t.textContent=e,we.appendChild(t)};let tt=[],po=null;function uo(){const e=L.get(o.blockTab.peek());if(!e){tt=[],po=null,Ta("Open a block to see its placeholders.");return}const t=ts(Ga(e.form.content),No(e.form.content),e.samples);if(!(po===e&&t.map(a=>a.name).join("|")===tt.join("|"))){if(tt=t.map(a=>a.name),po=e,!t.length){Ta("No {{placeholders}} in the template yet.");return}we.replaceChildren();for(const a of t){const s=document.createElement("div");s.className="pe-comp-prop",s.tabIndex=0,s.dataset.sample=a.name;const r=document.createElement("label");r.className="pe-comp-prop-label",r.textContent=a.name,r.title=a.raw?`{{{${a.name}}}} - raw markup`:`{{${a.name}}}`;const n=document.createElement("input");n.type="text",n.className="form-input form-input--sm pe-comp-prop-input",n.value=a.value,n.setAttribute("aria-label",`Sample value for ${a.name}`),n.addEventListener("input",()=>{e.samples[a.name]=n.value,U()});const l=document.createElement("button");l.type="button",l.className="pe-kebab",l.setAttribute("aria-label",`Actions for ${a.name}`),l.title="Actions",l.textContent="\u22EE",s.append(r,n,l),we.appendChild(s)}}}const mo=(e,t)=>No(e.form.content).has(t)?`{{{${t}}}}`:`{{${t}}}`,Ks=e=>{const t=L.get(o.blockTab.peek());return!t||!tt.includes(e)?[]:[{header:mo(t,e)},{label:"Insert into the template",icon:"corner-down-right",action:()=>{const a=oe?.textarea;a&&(o.blockPart.value="html",a.focus(),a.setRangeText(mo(t,e),a.selectionStart,a.selectionEnd,"end"),a.dispatchEvent(new Event("input",{bubbles:!0})))}},{label:"Copy the placeholder",icon:"copy",action:()=>Ie(mo(t,e),"Placeholder")},{type:"divider"},{label:"Reset the sample",icon:"rotate-ccw",action:()=>{delete t.samples[e],tt=[],uo(),U()}}]};{const e=E.contextMenu(we,{cursor:"glyph",match:".pe-comp-prop",inherit:!1,density:"compact",items:t=>Ks(t.dataset.sample)});i(()=>e?.destroy?.()),we.addEventListener("click",t=>{const a=t.target.closest(".pe-kebab");a&&Ce(a)}),we.addEventListener("keydown",t=>{const a=t.target.closest(".pe-comp-prop");a&&t.key==="F10"&&t.shiftKey&&(t.preventDefault(),Ce(a))})}const ae={},Se=O("#component-preview"),Pt=e=>{try{Se?.contentWindow?.postMessage(e,"*")}catch{}};let fo=Se.contentDocument?.readyState==="complete"&&/component-preview/.test(Se.contentDocument?.URL||""),Ot=!1,ot=null;const Ca=()=>{fo=!0,ot&&c()&&(Pt({type:"mount",payload:ot}),Ot=!0),ot=null};Se.addEventListener("load",Ca),i(()=>Se.removeEventListener("load",Ca));const Us=e=>{if(!fo){ot=e;return}if(!Ot){Ot=!0,Pt({type:"mount",payload:e});return}ot=e,fo=!1,Ot=!1,Se.src=Se.src};let Rt="";const bo=(e=!1)=>{const t=N.get(o.compTab.peek());if(!(!t||t.state!=="ok"||!t.js)){if(o.viewMode.peek()==="write"){t.previewStale=!0;return}!e&&Rt===t.name&&!t.previewStale||(t.previewStale=!1,Rt=t.name,Us({compiledJs:t.js,tagName:`dm-${t.name}`,props:t.previewProps}))}},at=e=>{const t=++e.seq;return e.state="compiling",o.compTab.peek()===e.name&&(o.compState.value="compiling"),e.compiling=(async()=>{let a;try{a=await h.components.compile(e.name,e.form.source)}catch(s){a={errors:[{type:"request",message:s.message||"Compile request failed."}]}}if(!(t!==e.seq||!c())){if(a.errors?.length?(e.state="error",e.errors=a.errors.map(s=>`[${s.type}] ${s.message}`).join(`
140
- `),e.js=null):(e.state="ok",e.errors="",e.js=a.js),o.compTab.peek()!==e.name){e.previewStale=!0;return}o.compState.value=e.state,o.compErrors.value=e.errors,e.state==="ok"&&(ko(),bo(!0))}})().finally(()=>{e.compiling&&t===e.seq&&(e.compiling=null)}),e.compiling};let At=null,$t=null;i(()=>clearTimeout(At));const xa=()=>{const e=N.get(o.compTab.peek());if(!e||!ae.template)return;o.compReady.value=!1;const t=ut(e.form.source);for(const a of qt)ae[a].setValue(t[a]),ae[a].textarea.readOnly=e.readOnly;o.compReadOnly.value=e.readOnly,o.compProject.value=e.form.project,qo(O("#comp-project"),e.form.project),o.compBundled.value=e.form.bundled,o.compState.value=e.state,o.compErrors.value=e.errors,o.compNote.value="",o.compReady.value=!0,ko(),e.state==="ok"?bo():e.state||at(e)},vo=()=>{o.compTab.peek()&&(o.compTab.value="",o.compReady.value=!1)},Pa={page:"details",block:"details",component:"details"};let Lt="";i(M.effect(()=>{const e=Qo.value;e!==Lt&&(Lt&&(Pa[Lt]=o.dockTab.peek()),Lt=e,e&&(o.dockTab.value=Pa[e]||"details",e==="page"&&o.dockTab.peek()==="history"&&o.dockOn.peek()&&m?.isEdit&&!Qe&&pe()))}));const go=async(e,{quiet:t=!1}={})=>{if(je.has(e))return je.get(e);if(N.has(e))return N.get(e);const a=(async()=>{try{const s=await h.components.get(e);if(!c()||!P.includes(X({kind:"component",id:e})))return null;const r=s.readOnly===!0||s.origin==="plugin",n={project:s.meta?.project||"",bundled:!!s.bundled,source:os(ut(s.source))},l={name:e,comp:s,saved:n,base:Fo({name:e,...n}),form:{...n},meta:s.meta||{},readOnly:r,state:"",errors:"",js:null,seq:0,compiling:null,previewProps:{},previewStale:!1};let g=null;try{g=S.get(Ve(e))}catch{}const $=ir(g,l.base);if(t&&(!$.ok||$.stale||r))return null;const G=$o({kind:"component",id:e});if(t&&!G)return null;if($.ok&&!r){const Te=g.at?` (${qe(g.at)})`:"",Co=G&&!$.stale||await E.confirm($.stale?`You left unsaved changes to the component "${e}"${Te}, but it has been saved since. Restore your version anyway?`:`You left unsaved changes to the component "${e}"${Te}. Restore them?`);if(!c())return null;Co&&(l.form={project:String(g.project??""),bundled:g.bundled===!0,source:String(g.source)},G&&!$.stale&&E.toast(`Your unsaved changes to the component "${e}" are back.`,{type:"info"}))}return g&&J(Ve(e)),N.set(e,l),ye(),l}catch(s){return c()&&o.compTab.peek()===e&&(o.compNote.value=`Could not open <dm-${e}>: ${s.message||"unknown error"}`),null}finally{je.delete(e)}})();return je.set(e,a),a},st=async e=>{if(!e||!le.has(e))return;const t=X({kind:"component",id:e});({ids:P}=Bo(P,t)),o.active.value=t,o.blockTab.value="",o.cssMode.peek()&&(o.cssMode.value=!1),o.viewMode.peek()==="preview"&&(o.viewMode.value="split"),o.compTab.value=e,te(),q(),z();let a=N.get(e);a||(o.compReady.value=!1,o.compReadOnly.value=!1,o.compState.value="",o.compNote.value=`Opening <dm-${e}>\u2026`,a=await go(e)),!(!a||!c()||o.compTab.peek()!==e)&&(xa(),q(),z(),ae[o.compPart.peek()]?.focus())},Js=(e,t)=>{const a=N.get(o.compTab.peek());if(!a||!o.compReady.peek()||a.readOnly)return;const s=ut(a.form.source);s[e]=t,a.form.source=os(s),clearTimeout(At),$t=a,At=setTimeout(()=>{$t=null,ye(),at(a)},300)};i(M.effect(()=>{const e=o.compProject.value,t=o.compBundled.value,a=N.get(o.compTab.peek());!a||!o.compReady.peek()||a.readOnly||a.form.project===e&&a.form.bundled===t||(a.form.project=e,a.form.bundled=t,ye())}));const Ee=O("#pe-comp-props");let ho=[];const yo=e=>{Ee.replaceChildren();const t=document.createElement("p");t.className="pe-dock-none",t.textContent=e,Ee.appendChild(t)};function ko(){const e=N.get(o.compTab.peek());if(!e){ho=[],yo("Open a component to try its props.");return}const{rows:t,error:a}=as(ut(e.form.source).props,e.previewProps);if(ho=t,a){yo("The <props> block is not valid JSON - fix it to see the props here.");return}if(!t.length){e.previewProps={},yo("No props declared. Add them in the <props> block.");return}e.previewProps=Object.fromEntries(t.map(s=>[s.name,s.value])),Ee.replaceChildren();for(const s of t){const r=document.createElement("div");r.className="pe-comp-prop",r.tabIndex=0,r.dataset.prop=s.name;const n=document.createElement("label");n.className="pe-comp-prop-label",n.textContent=s.label,n.title=`${s.name} (${s.type})`;const l=s.type==="array"||s.type==="object"?document.createElement("textarea"):document.createElement("input");s.type==="boolean"?(l.type="checkbox",l.className="form-check",l.checked=ss(s.type,s.value)):(l.tagName==="INPUT"?l.type=s.type==="number"?"number":"text":l.rows=2,l.className="form-input form-input--sm pe-comp-prop-input",l.value=ss(s.type,s.value)),l.setAttribute("aria-label",s.label);const g=()=>{e.previewProps[s.name]=cr(s.type,s.type==="boolean"?l.checked:l.value),Rt===e.name&&Pt({type:"update",payload:{props:e.previewProps}})};l.addEventListener("input",g),l.addEventListener("change",g);const $=document.createElement("button");$.type="button",$.className="pe-kebab",$.setAttribute("aria-label",`Actions for ${s.label}`),$.title="Actions",$.textContent="\u22EE",r.append(n,l,$),Ee.appendChild(r)}}const Ie=async(e,t)=>{try{await navigator.clipboard.writeText(e),E.toast(`${t} copied.`,{type:"success"})}catch{E.toast(e,{type:"info",duration:8e3})}},Ws=e=>{const t=N.get(o.compTab.peek()),a=ho.find(n=>n.name===e);if(!t||!a)return[];const s=rr(a.name,a.type,t.previewProps[a.name]),r=`dm-${t.name}`;return[{header:a.label},{label:"Reset to its default",icon:"rotate-ccw",action:()=>{delete t.previewProps[a.name];const n=as(ut(t.form.source).props,{}).rows.find(l=>l.name===a.name);t.previewProps[a.name]=n?n.value:null,ko(),Rt===t.name&&Pt({type:"update",payload:{props:t.previewProps}})}},{label:"Copy as an attribute",icon:"copy",disabled:!s,action:()=>Ie(s,"Attribute")},{label:"Copy the tag with this value",icon:"code",action:()=>Ie(`<${r}${s?` ${s}`:""}></${r}>`,"Tag")},{label:"Copy the prop name",icon:"copy",action:()=>Ie(a.name,"Name")},{type:"divider"},{label:"Edit in <props>",icon:"edit",action:()=>{o.compPart.value="props";const n=ae.props?.textarea;if(!n)return;const l=n.value.indexOf(`"${a.name}"`);n.focus(),l>=0&&n.setSelectionRange(l,l+a.name.length+2)}}]};{const e=E.contextMenu(Ee,{cursor:"glyph",match:".pe-comp-prop",inherit:!1,density:"compact",items:t=>Ws(t.dataset.prop)});i(()=>e?.destroy?.()),Ee.addEventListener("click",t=>{const a=t.target.closest(".pe-kebab");a&&Ce(a)}),Ee.addEventListener("keydown",t=>{const a=t.target.closest(".pe-comp-prop");a&&t.key==="F10"&&t.shiftKey&&(t.preventDefault(),Ce(a))})}let Fe=!1;const Oa=()=>zt()||"",Nt=async({project:e=Oa(),seed:t="",content:a=yr,css:s=""}={})=>{if(!Fe){Fe=!0;try{const n=await ls({kind:"block",projects:se,taken:[...be],project:e,name:t,check:$n,register:i,create:async(l,g)=>{await h.blocks.put(l,Za({name:l,project:g,bundled:!1,content:a,css:s}))}});if(!c())return;if(!n){te();return}if(await Vo(),!c())return;pt("#/blocks"),E.toast(`Created the block "${n}".`,{type:"success"}),Be(n)}finally{Fe=!1}}},nt=async({name:e="",source:t=nr,project:a=Oa()}={})=>{if(!Fe){Fe=!0;try{const s=await ls({kind:"component",projects:se,taken:[...le],project:a,name:e,register:i,check:(r,n)=>lr(r,{isNew:!0,taken:n}),create:async(r,n)=>{await h.components.put(r,{source:t,bundled:!1,meta:n?{project:n}:{}})}});if(!c())return;if(!s){te();return}if(await _o(),!c())return;pt("#/components"),E.toast(`Created the component "${s}".`,{type:"success"}),st(s)}finally{Fe=!1}}},Ra=y.querySelector(".dm-plugin-body")||y,Ys=M.computed(()=>{o.blockRev.value,o.compRev.value,o.docRev.value,W(_()),o.base.value;const e=I(o.active.value),t=[...Re().map(s=>X({kind:"page",id:s.id})),...ge().map(s=>X({kind:"block",id:s})),...Ye().map(s=>X({kind:"component",id:s}))];let a=[];return e?.kind==="block"||e?.kind==="component"?a=[o.active.value]:e?.kind==="page"&&m&&(a=[o.active.value,...ge().filter(wt).map(s=>X({kind:"block",id:s}))]),or(t,a)}),Gs={...p,...o,dirty:ys,pageDirty:gs,activeDirty:ks,cssUnsaved:hs,hasPage:ws,activeKind:Xo,canView:Zo,viewHref:Ss,problem:Es,dconfigNoteRows:Ms,statusText:Ts,saveAll:Ys,dockKind:Qo,blockTagText:Cs,compStateText:xs,compTagText:Ps,anySelected:Os,allSelected:Rs,someSelected:As},rt=(e,t)=>Ke(e,t),wo={save:()=>io(!1),saveAllOpen:()=>io(!0),discard:async()=>{if(await Ea(),!c())return;const e=I(o.active.peek());if(e?.kind==="block"){const t=L.get(e.id);if(!t||!de(t)||!await E.confirm(`Discard the changes to "${e.id}" you have not saved?`))return;t.form={...t.saved},J(He(e.id)),Sa(),Le()}else if(e?.kind==="component"){const t=N.get(e.id);if(!t||!he(t)||!await E.confirm(`Discard the changes to the component "${e.id}" you have not saved?`))return;t.form={...t.saved},t.state="",J(Ve(e.id)),xa(),ye()}else{if(!m||e?.kind==="page"&&e.id!==m.id||!(Wt()||yt())||!await E.confirm("Discard the changes to this page you have not saved?"))return;Ze(JSON.parse(o.base.peek())),p.cssOpened.peek()&&(p.css.value=ee.peek()),J(ze(m.id)),J(ft),Xe()}q(),z(),U()},newPage:()=>ue(""),newBlock:()=>Nt(),newComponent:()=>nt(),toggleSection:e=>{const t={here:"secHere",pages:"secPages",blocks:"secBlocks",components:"secComps"}[e];t&&(o[t].value=!o[t].peek(),rt(t,o[t].peek()))},toggleExplorer:()=>{o.explorerOn.value=!o.explorerOn.peek(),rt("explorer",o.explorerOn.peek())},toggleDock:()=>{o.dockOn.value=!o.dockOn.peek(),rt("dock",o.dockOn.peek()),o.dockOn.peek()&&o.dockTab.peek()==="history"&&!Qe&&pe()},showDock:e=>{o.dockTab.value=e,e==="history"&&m?.isEdit&&!Qe&&pe()},schemaChanged:()=>{o.seoSchemaNote.value=Po(p.seoSchema.peek()).error},insertSchemaExample:async e=>{const t=e?.target,a=t?.value||"";if(t&&(t.value=""),!a||p.seoSchema.peek().trim()&&!await E.confirm("Replace the structured data with the example?"))return;const s=p.urlPath.peek().trim()||m?.id||"/";p.seoSchema.value=fn(a,{title:p.seoTitle.peek().trim()||p.title.peek().trim(),description:p.seoDesc.peek().trim()||p.description.peek().trim(),url:`${location.origin}${s}`,siteName:Y?.title||Y?.seo?.defaultTitle||""}),o.seoSchemaNote.value=""},setBlockPart:e=>{o.blockPart.value=e==="css"?"css":"html",(e==="css"?me:oe)?.focus()},formatBlock:()=>{const e=o.blockPart.peek()==="css",t=e?me:oe;!t||!o.blockReady.peek()||Uo(_e(t.textarea,e?"css":"html"))},copyShortcode:async()=>{const e=o.blockTab.peek();e&&await Ie(jn(e),"Shortcode")},setCompPart:e=>{o.compPart.value=qt.includes(e)?e:"template",ae[o.compPart.peek()]?.focus()},copyComponent:()=>{const e=N.get(o.compTab.peek());e&&nt({name:Lo(e.name,[...le]),source:e.form.source})},setMode:e=>{o.cssMode.peek()&&(o.cssMode.value=!1),o.viewMode.value=jo(e),rt("viewMode",o.viewMode.peek()),e!=="write"&&(U(!0),bo())},toggleFullscreen:()=>{o.fullscreen.value=!o.fullscreen.peek(),rt("fullscreen",o.fullscreen.peek())},toggleCss:()=>{o.blockTab.peek()||o.compTab.peek()||(o.cssMode.peek()?(o.cssMode.value=!1,o.viewMode.value=jo(Pe().viewMode),Q.refresh()):(ia(),o.cssMode.value=!0,o.viewMode.value="split"))},formatMarkdown:()=>{Jt(),Uo(_e(V,"md"))},toggleFold:()=>{o.folded.peek()?Q.unfoldAll():Q.foldAll(),o.folded.value=!o.folded.peek(),We.paint()},setWidth:e=>{o.liveWidth.value=e},refreshPreview:()=>{if(o.compTab.peek()){const e=N.get(o.compTab.peek());e&&at(e)}else U(!0)},share:async()=>{if(!m?.isEdit){E.toast("Save the page first - a share link needs a page to point at.",{type:"warning"});return}await gr(m.id)},toggleAll:e=>{const t=!!e?.target?.checked;o.versions.peek().forEach(a=>{a.checked.value=t})},deleteSelected:async()=>{const e=o.versions.peek().filter(a=>a.checked.peek()).map(a=>a.filename),t=e.length;if(!(!t||!await E.confirm(`Delete ${t} version${t>1?"s":""}? This cannot be undone.`)))try{await h.versions.bulkDelete(m.id,e),E.toast(`${t} version${t>1?"s":""} deleted.`,{type:"success"}),await pe()}catch(a){E.toast("Delete failed: "+a.message,{type:"error"})}},saveNamed:async()=>{if(!m?.isEdit)return;const e=m;await hr(e.id)&&c()&&m===e&&await pe()},closeCompare:()=>{o.compare.value=null,Tt=null},restoreCompared:()=>ma(Tt)};Ge.querySelectorAll("[data-tip]").forEach(e=>E.tooltip(e,{content:e.getAttribute("data-tip"),position:"top"}));const Xs=M.applyBindings(Gs,Ra,{methods:wo});i(()=>Xs.dispose()),oe=zo(O('.pe-block-edit[data-part="html"]'),{ariaLabel:"Block template HTML",language:"html",onChange:e=>Ma("content",e)}),me=zo(O('.pe-block-edit[data-part="css"]'),{ariaLabel:"Block CSS",language:"css",placeholder:`/* Scoped to this block - e.g.
139
+ </span>`);Ge.prepend(Ns),Ge.before(O(".pe-block-bar")),Ge.before(O(".pe-comp-bar"));const aa=e=>(Array.isArray(e)?e:[]).map(t=>({value:t,label:t})),sa=O("#field-tags");let Et=null;Et=sa?E.pillbox(sa,{data:aa(_t),value:[],creatable:!0,searchable:!0,placeholder:"Add tag\u2026",onChange:()=>{Et&&(p.tags.value=[...Et.getValue()])}}):null;const na=O("#field-admin-tags");let Mt=null;Mt=na?E.pillbox(na,{data:aa(T),value:[],creatable:!0,searchable:!0,placeholder:"Add admin tag\u2026",onChange:()=>{Mt&&(p.adminTags.value=[...Mt.getValue()])}}):null;const ra=()=>{o.bodyRev.value=o.bodyRev.peek()+1},Le=()=>{o.blockRev.value=o.blockRev.peek()+1},ye=()=>{o.compRev.value=o.compRev.peek()+1},Xe=()=>{o.docRev.value=o.docRev.peek()+1},ia=()=>{p.cssOpened.peek()||(p.css.peek()||(p.css.value=ee.peek()),p.cssOpened.value=!0,an(ve,{language:"css"}))},Ze=e=>{for(const t of Ar)p[t].value=e[t]==null?"":String(e[t]);for(const t of $r)p[t].value=!!e[t];p.tags.value=Array.isArray(e.tags)?e.tags:[],Et?.setValue(p.tags.peek()),Array.isArray(e.adminTags)&&(p.adminTags.value=e.adminTags),Mt?.setValue(p.adminTags.peek()),qo(O("#field-visibility"),p.visibility.peek()),Q.unfoldAll(),o.folded.value=!1,gt=!0,V.value=e.body==null?"":String(e.body),gt=!1,Q.refresh(),Ko(),ra()},la=(e,t)=>({urlPath:t||"",title:e?.title||"",description:e?.description||"",layout:Ho(e?.layout||"default"),status:e?.status||"draft",sortOrder:String(e?.sortOrder??99),showInNav:!!e?.showInNav,sidebar:!!e?.sidebar,breadcrumbs:e?e.breadcrumbs!==!1:!0,bundled:!!e?.bundled,tags:Array.isArray(e?.tags)?e.tags:[],adminTags:Array.isArray(e?.adminTags)?e.adminTags:[],category:e?.category||"",visibility:typeof e?.visibility=="string"&&e.visibility?e.visibility:"public",project:Rn({isEdit:!!t,page:e,projects:se,fromHash:t?"":zt()||"",urlPath:t||""}),theme:e?.theme||"",seoTitle:e?.seo?.title||"",seoDesc:e?.seo?.description||"",seoSchema:bn(e?.seo?.schema),dconfig:e?.dconfig?JSON.stringify(e.dconfig,null,2):"",body:e?.content||"",css:null}),ca=()=>{m&&(m.state=_(),m.at=Date.now())},da=e=>{m!==e&&(ca(),m=e,Ze(e.state),o.base.value=e.base,o.curId.value=e.id,e.at=Date.now(),Ct(),Xe())},Ds=()=>{ca(),m=null;const e=ms();Ze(e),o.base.value=W(e),o.curId.value=null,Ct(),Xe()};Ze(ms()),o.base.value=W(_());const J=e=>{try{S.remove?S.remove(e):S.set(e,null)}catch{}},pa=(e,t)=>({name:e.name,...e.form,base:e.base,at:t});u=()=>{try{for(const t of Re())S.set(ze(t.id),Ka(t===m?Go():t.state,t.base));yt()&&S.set(ft,p.css.peek());const e=new Date().toISOString();for(const t of ge()){const a=L.get(t);S.set(He(t),{form:{...a.form},base:a.base,at:e})}for(const t of Ye())S.set(Ve(t),pa(N.get(t),e))}catch{}};const ua=e=>{k()&&(u(),e.preventDefault(),e.returnValue="")};window.addEventListener("beforeunload",ua),i(()=>window.removeEventListener("beforeunload",ua));let Qe=!1,Tt=null;const Ct=()=>{Qe=!1,Tt=null,o.versions.value=[],o.compare.value=null,o.histError.value="",o.dockOn.peek()&&o.dockTab.peek()==="history"&&(m?.isEdit?pe():o.dockTab.value="details")},pe=async()=>{const e=m;if(e?.isEdit){Qe=!0,o.histLoading.value=!0,o.histError.value="";try{const t=(await h.versions.list(e.id)).versions||[];if(!c()||m!==e)return;o.versions.value=t.map(a=>({...a,when:qe(a.createdAt),author:a.author||"",label:a.label||"",who:[a.author,a.label].filter(Boolean).join(" - "),checked:M.observable(!1)}))}catch(t){m===e&&(o.histError.value="Failed to load versions: "+t.message)}finally{m===e&&(o.histLoading.value=!1)}}},oo=e=>o.versions.peek().find(t=>t.filename===e),ao=async e=>{const t=m;try{const a=await h.versions.get(t.id,e.filename);if(!c()||m!==t)return;Tt=e.filename,o.compare.value={label:rs(e),old:a.content,current:ht()}}catch(a){E.toast("Failed to load version: "+a.message,{type:"error"})}},js=async()=>{const e=m;if(!e?.isEdit)return;const t=await h.pages.get(e.id).catch(()=>null);if(!c()||m!==e||!t)return;e.page=t;const a=la(t,e.id);e.base=W(a),e.savedAdminTags=JSON.stringify(a.adminTags),Ze(a),o.base.value=e.base,Ct(),o.dockOn.peek()&&o.dockTab.peek()==="history"&&pe(),U()},ma=async e=>{if(!(!e||!await E.confirm("Restore this version? The current page content will be overwritten (a pre-restore snapshot will be saved automatically).")))try{await h.versions.restore(m.id,e),E.toast("Page restored.",{type:"success"}),await js()}catch(t){E.toast("Restore failed: "+t.message,{type:"error"})}},Bs=async e=>{if(await E.confirm("Delete this version? This cannot be undone."))try{await h.versions.delete(m.id,e.filename),E.toast("Version deleted.",{type:"success"}),await pe()}catch(t){E.toast("Failed to delete: "+t.message,{type:"error"})}},Ne=new Map,Is=e=>{if(!Ne.has(e)){const t=I(e);Ne.set(e,{id:e,kind:t.kind,kindText:t.kind==="page"?"Page":t.kind==="component"?"Component":"Block",label:M.observable(""),title:M.observable(""),active:M.observable(!1),dirty:M.observable(!1)})}return Ne.get(e)},fa=e=>{const t=e===m?p.title.peek():e?.loaded?e.state.title:D.find(a=>a.urlPath===e?.id)?.title;return String(t||"").trim()||e?.id||"New page"};let ba=!0,va="";const Fs=()=>{if(ba)return;const e={ids:P,active:o.active.peek()},t=JSON.stringify(e);if(t!==va){va=t;try{S.set(ps,e)}catch{}}},q=()=>{const e=P.map(Is);for(const t of e){const a=I(t.id);let s,r;if(a.kind==="page"){const l=K.get(a.id);s=fa(l),r=l?.loaded?Yt(l):xe(a),t.title.value=a.id?`${s} (${a.id})`:"New page"}else if(a.kind==="component"){const l=N.get(a.id);s=a.id,r=l?he(l):xe(a),t.title.value=`Component <dm-${a.id}>`}else{const l=L.get(a.id);s=a.id,r=l?de(l):Ae.has(a.id)||xe(a),t.title.value=`Block ${a.id}`}t.label.peek()!==s&&(t.label.value=s),t.dirty.peek()!==r&&(t.dirty.value=r);const n=t.id===o.active.peek();t.active.peek()!==n&&(t.active.value=n)}e.map(t=>t.id).join("|")!==o.tabs.peek().map(t=>t.id).join("|")&&(o.tabs.value=e),Fs()};let ke=new Set;try{const e=S.get(us);Array.isArray(e)&&(ke=new Set(e.filter(t=>typeof t=="string")))}catch{}const ga=new Map,so=e=>{let t=ga.get(e.key);return t?(t.label.peek()!==e.label&&(t.label.value=e.label),t.meta.peek()!==(e.meta||"")&&(t.meta.value=e.meta||""),t.status.peek()!==(e.status||"")&&(t.status.value=e.status||""),t.folder.peek()!==!!e.folder&&(t.folder.value=!!e.folder)):(t={...e,label:M.observable(e.label),meta:M.observable(e.meta||""),status:M.observable(e.status||""),folder:M.observable(!!e.folder),active:M.observable(!1),dirty:M.observable(!1),folded:M.observable(!1),title:""},ga.set(e.key,t)),t.title=e.kind==="block"||e.kind==="component"?e.meta?`${e.id} - ${e.meta}`:e.id:e.kind==="folder"?e.meta:`${e.label} (${e.meta})`,t},no=new Map,z=()=>{const e=o.filter.peek(),t=I(o.active.peek()),a=t?.kind==="page"?t.id:null,s=t?.kind==="block"?t.id:null,r=t?.kind==="component"?t.id:null,n=new Set(Re().map(f=>f.id)),l=er(D,{filter:e,folded:ke}).map(so);for(const f of l){const C=f.kind==="page"&&f.id===a,B=f.kind==="page"&&(n.has(f.id)||!K.get(f.id)?.loaded&&xe({kind:"page",id:f.id})),fe=ke.has(f.id);f.active.peek()!==C&&(f.active.value=C),f.dirty.peek()!==B&&(f.dirty.value=B),f.folded.peek()!==fe&&(f.folded.value=fe)}const g=Jn(ie,e).map(so),$=f=>{const C=L.get(f);return C?de(C):Ae.has(f)||xe({kind:"block",id:f})};for(const f of g){const C=f.id===s,B=$(f.id);f.active.peek()!==C&&(f.active.value=C),f.dirty.peek()!==B&&(f.dirty.value=B)}const G=Yn(Je,e).map(so),Te=f=>{const C=N.get(f);return C?he(C):xe({kind:"component",id:f})};for(const f of G){const C=f.id===r,B=Te(f.id);f.active.peek()!==C&&(f.active.value=C),f.dirty.peek()!==B&&(f.dirty.value=B)}const Co=m?Fn(kt,Kt,be):[],za=(f,C,B)=>(no.has(f)||no.set(f,{key:f,id:C,label:B,kindText:"",title:"",active:M.observable(!1),dirty:M.observable(!1)}),no.get(f)),xo=Co.map(f=>{const C=za(`block:${f.name}`,f.name,f.name);C.kindText=f.footer?"Footer":"Block",C.title=`${f.name} - ${f.footer?"in the footer, on every page":"a block on this page"}`;const B=f.name===s,fe=$(f.name);return C.active.peek()!==B&&(C.active.value=B),C.dirty.peek()!==fe&&(C.dirty.value=fe),C});for(const f of ta){const C=za(`component:${f}`,f,f);C.kindText="Component",C.title=`<dm-${f}> - a component on this page`;const B=f===r,fe=Te(f);C.active.peek()!==B&&(C.active.value=B),C.dirty.peek()!==fe&&(C.dirty.value=fe),xo.push(C)}const jt=(f,C)=>f.map(B=>B.key).join("|")===C.map(B=>B.key).join("|");jt(l,o.pageRows.peek())||(o.pageRows.value=l),jt(g,o.blockRows.peek())||(o.blockRows.value=g),jt(G,o.compRows.peek())||(o.compRows.value=G),jt(xo,o.thisPage.peek())||(o.thisPage.value=xo)},ha=async()=>{const e=await h.pages.list().catch(()=>null);!c()||!Array.isArray(e)||(D=e,z(),q())},te=()=>{const e=I(o.active.peek()),t=e?es(e):"/pages/new",a=window.location.hash.replace(/^#/,"");j.address=a.split("?")[0]===t?a:t,a.split("?")[0]!==t?history.replaceState({pe:1},"","#"+t):history.state?.pe||history.replaceState({pe:1},"",window.location.hash)},zs=async e=>{if(e.loading)return e.loading;e.loading=(async()=>{let t=null;if(e.isEdit){if(t=await h.pages.get(e.id).catch(()=>null),!c())return!1;if(!t)return E.toast(`Page ${e.id} not found.`,{type:"error"}),!1}e.page=t;const a=la(t,e.id);e.state=a,e.base=W(a),e.savedAdminTags=JSON.stringify(a.adminTags),e.loaded=!0;let s=null;try{s=S.get(ze(e.id))}catch{}const r=An(s),n=$o({kind:"page",id:e.id});if(r){J(ze(e.id));const l=W(r.state)!==e.base,g=On(r,e.base),$={...a,...r.state,adminTags:a.adminTags};if(l&&n&&!g)e.state=$,E.toast(`Your unsaved changes to ${e.id||"the new page"} are back.`,{type:"info"});else if(l){const G=r.at?` (${qe(r.at)})`:"",Te=g?" The saved page has changed since - restoring puts your version back over it (the saved one stays in History).":"";await E.confirm(`You left unsaved changes to ${e.id||"a new page"}${G}. Restore them?${Te}`)&&c()&&(e.state=$)}}return!0})();try{return await e.loading}finally{e.loading=null}},ya=e=>(K.has(e)||K.set(e,{kind:"page",id:e,isEdit:!!e,loaded:!1,page:null,state:null,base:"",savedAdminTags:"[]",at:0}),K.get(e)),ue=async e=>{const t=X({kind:"page",id:e});({ids:P}=Bo(P,t)),o.active.value=t,o.blockTab.value="",vo();const a=ya(e);if(q(),!a.loaded){o.previewStatus.value=`Opening ${e||"a new page"}\u2026`;const s=await zs(a);if(!c()||!P.includes(t)||K.get(e)!==a)return;if(!s){ka(t);return}if(o.active.peek()!==t){q(),z();return}}da(a),te(),q(),z(),U(),Q.refresh(),V.focus()};w=async(e,t)=>{if(j.address=t,e.kind==="page"){ue(e.id);return}if(!e.id){(e.kind==="block"?Nt:nt)({project:zt(t)||""});return}const a=e.kind==="block"?be:le;if(a.has(e.id)||await(e.kind==="block"?Vo:_o)(),!!c()){if(!a.has(e.id)){E.toast(`There is no ${e.kind} called "${e.id}".`,{type:"warning"}),te(),z();return}e.kind==="block"?Be(e.id):st(e.id)}};const ka=e=>{const t=o.active.peek(),a=Wn(P,e,t);P=a.ids,Ne.delete(e);const s=I(e),r=a.active!==t?I(a.active):null;if(s.kind==="page"){if(K.delete(s.id),m?.id===s.id){const n=[...K.values()].filter(l=>l.loaded&&l.id!==s.id).sort((l,g)=>g.at-l.at)[0];n?da(n):Ds()}}else s.kind==="component"?(N.delete(s.id),o.compTab.peek()===s.id&&vo()):(L.delete(s.id),o.blockTab.peek()===s.id&&(o.blockTab.value="",o.blockReady.value=!1));if(o.active.value=a.active,r?.kind==="page"){ue(r.id);return}if(r?.kind==="block"){Be(r.id);return}if(r?.kind==="component"){st(r.id);return}te(),Xe(),Le(),ye(),q(),z(),U()},et=e=>{const t=I(e);if(!t||!P.includes(e))return;let a="";try{if(t.kind==="page"){const s=K.get(t.id);s&&Yt(s)&&(S.set(ze(s.id),Ka(s===m?_():s.state,s.base)),Ao({kind:"page",id:s.id}),a=fa(s))}else if(t.kind==="component"){const s=N.get(t.id);s&&he(s)&&(S.set(Ve(t.id),pa(s,new Date().toISOString())),Ao({kind:"component",id:t.id}),a=t.id)}else{const s=L.get(t.id);s&&de(s)&&(S.set(He(t.id),{form:{...s.form},base:s.base,at:new Date().toISOString()}),Ao({kind:"block",id:t.id}),a=t.id)}}catch{}ka(e),a&&E.toast(`Changes to "${a}" kept as a draft - back when you open it again.`,{type:"info"})},xt=e=>{const t=I(e);t&&(t.kind==="page"?ue(t.id):t.kind==="component"?st(t.id):Be(t.id))},wa=new Set,qs=async e=>{const t=[];for(const a of e){const s=L.get(a);if(!s)continue;const r={...s.form};try{const n=Za(r,s.block?.meta);await h.blocks.put(a,n),s.block={...s.block,meta:n.meta},s.saved=r,s.base=Do(r),vt.set(a,new Date().toISOString()),c()&&J(He(a)),t.push(a)}catch(n){E.toast(`Block "${a}" not saved: ${n.message||"Unknown error"}`,{type:"error"})}}return t.forEach(a=>wa.add(a)),t.length&&(Le(),pt("#/blocks")),t},Hs=async e=>{const t=e===m?_():e.state,a=Po(t.seoSchema).error;if(a)return E.toast(`${e.id||"The new page"} not saved - structured data: ${a}`,{type:"error"}),e===m&&(o.seoSchemaNote.value=a,o.dockOn.value=!0,o.dockTab.value="seo"),!1;const s=Gt(t,e,Xt(t)),r=e.id;try{if(e.isEdit){const n={frontmatter:s,body:t.body};t.urlPath!==e.id&&(n.newUrlPath=t.urlPath),await h.pages.update(e.id,n)}else await h.pages.create({urlPath:t.urlPath,frontmatter:s,body:t.body})}catch(n){return E.toast(`${e.id||"The new page"} not saved: ${n.message||"Unknown error"}`,{type:"error"}),!1}if(!c())return!0;if(e.savedAdminTags=JSON.stringify(t.adminTags),e.base=W(t),e===m?o.base.value=e.base:e.state=t,J(ze(r)),!e.isEdit||t.urlPath!==e.id){K.delete(r),e.id=t.urlPath,e.isEdit=!0,K.set(e.id,e);const n=X({kind:"page",id:r}),l=X({kind:"page",id:e.id});Ne.delete(n),{ids:P}=ar(P,n,l,o.active.peek()),o.active.peek()===n&&(o.active.value=l),e===m&&(o.curId.value=e.id,te())}return!0},Vs=async e=>{const t=[];for(const a of e){const s=N.get(a);if(!s||s.readOnly)continue;if($t===s?(clearTimeout(At),$t=null,ye(),at(s)):s.state||at(s),s.compiling&&await s.compiling,!c())return t;if(s.state!=="ok"){E.toast(`Component "${a}" not saved: ${s.state==="error"?"it does not compile - fix the errors first.":"it has not compiled yet - try again in a moment."}`,{type:"warning"});continue}const r={...s.form},n={...s.meta||{}};delete n.bundled,r.project?n.project=r.project:delete n.project;try{await h.components.put(a,{source:r.source,bundled:r.bundled,meta:n}),s.meta=n,s.saved=r,s.base=Fo({name:a,...r});const l=Je.find(g=>g.name===a);l&&(l.bundled=r.bundled,l.meta=n),c()&&J(Ve(a)),t.push(a)}catch(l){E.toast(`Component "${a}" not saved: ${l.message||"Unknown error"}`,{type:"error"})}}return t.length&&(ye(),pt("#/components")),t};let ro=!1;const io=async(e=!1)=>{if(o.saving.peek()||ro)return;ro=!0;let t,a,s=[];try{if(await Ea(),!c())return;const n=I(o.active.peek());if(ur().formatOnSave&&vs(n),e)t=Re(),a=ge(),s=Ye();else if(n?.kind==="block")t=[],a=L.has(n.id)&&de(L.get(n.id))?[n.id]:[];else if(n?.kind==="component")t=[],a=[],s=N.has(n.id)&&he(N.get(n.id))?[n.id]:[];else if(n?.kind==="page"&&m)a=ge().filter(wt),t=!m.isEdit||Wt()||!a.length?[m]:[];else return;if(!t.length&&!a.length&&!s.length){E.toast("Nothing to save.",{type:"info"});return}for(const g of t){const $=Ro(g===m?_():g.state);if($.length){E.toast(`${g.id||"New page"}: ${$[0].text}`,{type:"warning"}),g!==m&&await ue(g.id),o.dockOn.value=!0,o.dockTab.value=$[0].field==="dconfig"?"dconfig":"details",Ke("dock",!0);return}}const l=Vn(a,Object.fromEntries(a.map(g=>[g,Qa(Ue.get(g),m?.id||"")])),wa);if(l&&(!await E.confirm(l)||!c()))return}finally{ro=!1}const r=t.length>0&&yt();o.saving.value=!0;try{let n=0;for(const $ of t)await Hs($)&&n++;if(!c())return;if(r){const $=p.css.peek();await h.settings.saveCustomCss($),ee.value=$,J(ft)}const l=await qs(a);if(!c())return;const g=await Vs(s);if((n||l.length||g.length)&&E.toast(_n({pages:n,css:r,blocks:l,components:g}),{type:"success"}),Xe(),!c())return;q(),z(),n&&(pt("#/pages"),Ct(),ha())}catch(n){E.toast(`Save failed: ${n.message||"Unknown error"}`,{type:"error"})}finally{o.saving.value=!1}};let oe=null,me=null;const De=new Map,je=new Map,Sa=()=>{const e=L.get(o.blockTab.peek());!e||!oe||(o.blockReady.value=!1,oe.setValue(e.form.content),me.setValue(e.form.css),o.blockProject.value=e.form.project,qo(O("#block-project"),e.form.project),o.blockBundled.value=e.form.bundled,o.blockWhere.value=Dn({usage:Ue.get(e.form.name)})||"Where it is used could not be read.",o.blockNote.value="",o.blockReady.value=!0,uo())},_s=e=>{const t=L.get(e);if(!t)return{};const a=t.form.content;return Object.fromEntries(ts(Ga(a),No(a),t.samples||{}).map(s=>[s.name,s.value]))};i(M.effect(()=>{const e=o.blockProject.value,t=o.blockBundled.value,a=L.get(o.blockTab.peek());!a||!o.blockReady.peek()||a.form.project===e&&a.form.bundled===t||(a.form.project=e,a.form.bundled=t,Le())}));const lo=async(e,{quiet:t=!1}={})=>{for(;De.has(e);)if(await De.get(e),L.has(e)||t)return L.get(e)||null;if(L.has(e))return L.get(e);const a=(async()=>{try{const s=await h.blocks.get(e);if(!c()||!t&&!P.includes(X({kind:"block",id:e})))return null;const r=Xa({...s,name:e}),n={block:s,saved:r,base:Do(r),form:{...r},samples:{}};let l=null;try{l=S.get(He(e))}catch{}const g=Bn(l,n.base);if(t&&g?.stale)return null;if($o({kind:"block",id:e}),g){const $=g.at?` (${qe(g.at)})`:"",G=!g.stale||await E.confirm(`You left unsaved changes to "${e}"${$}, but the block has been saved since. Restore your version anyway?`);if(!c())return null;G&&(n.form={...n.form,...g.form,name:e},g.stale||E.toast(`Your unsaved changes to "${e}" are back.`,{type:"info"}))}return l&&J(He(e)),L.set(e,n),Le(),n}catch(s){return c()&&o.blockTab.peek()===e&&(o.blockNote.value=`Could not open "${e}": ${s.message||"unknown error"}`),null}finally{De.delete(e)}})();return De.set(e,a),a},Ea=async()=>{for(;De.size||je.size;)await Promise.all([...De.values(),...je.values()])},Be=async e=>{if(!e||!be.has(e))return;const t=X({kind:"block",id:e});({ids:P}=Bo(P,t)),o.active.value=t,vo(),o.cssMode.peek()&&(o.cssMode.value=!1),o.viewMode.peek()==="preview"&&(o.viewMode.value="split"),o.blockTab.peek()!==e&&(o.blockReady.value=!1),o.blockTab.value=e,o.blockUses.value=m&&wt(e)?Kn(Qa(Ue.get(e),m.id||"")):zn(Ue.get(e)),te(),q(),z();let a=L.get(e);a||(o.blockReady.value=!1,o.blockNote.value=`Opening ${e}\u2026`,a=await lo(e)),!(!a||!c()||o.blockTab.peek()!==e)&&(Sa(),q(),z(),Zt=e,U(),(o.blockPart.peek()==="css"?me:oe)?.focus())};let co=null;i(()=>clearTimeout(co));const Ma=(e,t)=>{const a=L.get(o.blockTab.peek());!a||!o.blockReady.peek()||(a.form[e]=t,clearTimeout(co),co=setTimeout(()=>{Le(),e==="content"&&uo()},120),U())},we=O("#pe-block-samples"),Ta=e=>{we.replaceChildren();const t=document.createElement("p");t.className="pe-dock-none",t.textContent=e,we.appendChild(t)};let tt=[],po=null;function uo(){const e=L.get(o.blockTab.peek());if(!e){tt=[],po=null,Ta("Open a block to see its placeholders.");return}const t=ts(Ga(e.form.content),No(e.form.content),e.samples);if(!(po===e&&t.map(a=>a.name).join("|")===tt.join("|"))){if(tt=t.map(a=>a.name),po=e,!t.length){Ta("No {{placeholders}} in the template yet.");return}we.replaceChildren();for(const a of t){const s=document.createElement("div");s.className="pe-comp-prop",s.tabIndex=0,s.dataset.sample=a.name;const r=document.createElement("label");r.className="pe-comp-prop-label",r.textContent=a.name,r.title=a.raw?`{{{${a.name}}}} - raw markup`:`{{${a.name}}}`;const n=document.createElement("input");n.type="text",n.className="form-input form-input--sm pe-comp-prop-input",n.value=a.value,n.setAttribute("aria-label",`Sample value for ${a.name}`),n.addEventListener("input",()=>{e.samples[a.name]=n.value,U()});const l=document.createElement("button");l.type="button",l.className="pe-kebab",l.setAttribute("aria-label",`Actions for ${a.name}`),l.title="Actions",l.textContent="\u22EE",s.append(r,n,l),we.appendChild(s)}}}const mo=(e,t)=>No(e.form.content).has(t)?`{{{${t}}}}`:`{{${t}}}`,Ks=e=>{const t=L.get(o.blockTab.peek());return!t||!tt.includes(e)?[]:[{header:mo(t,e)},{label:"Insert into the template",icon:"corner-down-right",action:()=>{const a=oe?.textarea;a&&(o.blockPart.value="html",a.focus(),a.setRangeText(mo(t,e),a.selectionStart,a.selectionEnd,"end"),a.dispatchEvent(new Event("input",{bubbles:!0})))}},{label:"Copy the placeholder",icon:"copy",action:()=>Ie(mo(t,e),"Placeholder")},{type:"divider"},{label:"Reset the sample",icon:"rotate-ccw",action:()=>{delete t.samples[e],tt=[],uo(),U()}}]};{const e=E.contextMenu(we,{cursor:"glyph",match:".pe-comp-prop",inherit:!1,density:"compact",items:t=>Ks(t.dataset.sample)});i(()=>e?.destroy?.()),we.addEventListener("click",t=>{const a=t.target.closest(".pe-kebab");a&&Ce(a)}),we.addEventListener("keydown",t=>{const a=t.target.closest(".pe-comp-prop");a&&t.key==="F10"&&t.shiftKey&&(t.preventDefault(),Ce(a))})}const ae={},Se=O("#component-preview"),Pt=e=>{try{Se?.contentWindow?.postMessage(e,"*")}catch{}};let fo=Se.contentDocument?.readyState==="complete"&&/component-preview/.test(Se.contentDocument?.URL||""),Ot=!1,ot=null;const Ca=()=>{fo=!0,ot&&c()&&(Pt({type:"mount",payload:ot}),Ot=!0),ot=null};Se.addEventListener("load",Ca),i(()=>Se.removeEventListener("load",Ca));const Us=e=>{if(!fo){ot=e;return}if(!Ot){Ot=!0,Pt({type:"mount",payload:e});return}ot=e,fo=!1,Ot=!1,Se.src=Se.src};let Rt="";const bo=(e=!1)=>{const t=N.get(o.compTab.peek());if(!(!t||t.state!=="ok"||!t.js)){if(o.viewMode.peek()==="write"){t.previewStale=!0;return}!e&&Rt===t.name&&!t.previewStale||(t.previewStale=!1,Rt=t.name,Us({compiledJs:t.js,tagName:`dm-${t.name}`,props:t.previewProps}))}},at=e=>{const t=++e.seq;return e.state="compiling",o.compTab.peek()===e.name&&(o.compState.value="compiling"),e.compiling=(async()=>{let a;try{a=await h.components.compile(e.name,e.form.source)}catch(s){a={errors:[{type:"request",message:s.message||"Compile request failed."}]}}if(!(t!==e.seq||!c())){if(a.errors?.length?(e.state="error",e.errors=a.errors.map(s=>`[${s.type}] ${s.message}`).join(`
140
+ `),e.js=null):(e.state="ok",e.errors="",e.js=a.js),o.compTab.peek()!==e.name){e.previewStale=!0;return}o.compState.value=e.state,o.compErrors.value=e.errors,e.state==="ok"&&(ko(),bo(!0))}})().finally(()=>{e.compiling&&t===e.seq&&(e.compiling=null)}),e.compiling};let At=null,$t=null;i(()=>clearTimeout(At));const xa=()=>{const e=N.get(o.compTab.peek());if(!e||!ae.template)return;o.compReady.value=!1;const t=ut(e.form.source);for(const a of qt)ae[a].setValue(t[a]),ae[a].textarea.readOnly=e.readOnly;o.compReadOnly.value=e.readOnly,o.compProject.value=e.form.project,qo(O("#comp-project"),e.form.project),o.compBundled.value=e.form.bundled,o.compState.value=e.state,o.compErrors.value=e.errors,o.compNote.value="",o.compReady.value=!0,ko(),e.state==="ok"?bo():e.state||at(e)},vo=()=>{o.compTab.peek()&&(o.compTab.value="",o.compReady.value=!1)},Pa={page:"details",block:"details",component:"details"};let Lt="";i(M.effect(()=>{const e=Qo.value;e!==Lt&&(Lt&&(Pa[Lt]=o.dockTab.peek()),Lt=e,e&&(o.dockTab.value=Pa[e]||"details",e==="page"&&o.dockTab.peek()==="history"&&o.dockOn.peek()&&m?.isEdit&&!Qe&&pe()))}));const go=async(e,{quiet:t=!1}={})=>{if(je.has(e))return je.get(e);if(N.has(e))return N.get(e);const a=(async()=>{try{const s=await h.components.get(e);if(!c()||!P.includes(X({kind:"component",id:e})))return null;const r=s.readOnly===!0||s.origin==="plugin",n={project:s.meta?.project||"",bundled:!!s.bundled,source:os(ut(s.source))},l={name:e,comp:s,saved:n,base:Fo({name:e,...n}),form:{...n},meta:s.meta||{},readOnly:r,state:"",errors:"",js:null,seq:0,compiling:null,previewProps:{},previewStale:!1};let g=null;try{g=S.get(Ve(e))}catch{}const $=cr(g,l.base);if(t&&(!$.ok||$.stale||r))return null;const G=$o({kind:"component",id:e});if(t&&!G)return null;if($.ok&&!r){const Te=g.at?` (${qe(g.at)})`:"",Co=G&&!$.stale||await E.confirm($.stale?`You left unsaved changes to the component "${e}"${Te}, but it has been saved since. Restore your version anyway?`:`You left unsaved changes to the component "${e}"${Te}. Restore them?`);if(!c())return null;Co&&(l.form={project:String(g.project??""),bundled:g.bundled===!0,source:String(g.source)},G&&!$.stale&&E.toast(`Your unsaved changes to the component "${e}" are back.`,{type:"info"}))}return g&&J(Ve(e)),N.set(e,l),ye(),l}catch(s){return c()&&o.compTab.peek()===e&&(o.compNote.value=`Could not open <dm-${e}>: ${s.message||"unknown error"}`),null}finally{je.delete(e)}})();return je.set(e,a),a},st=async e=>{if(!e||!le.has(e))return;const t=X({kind:"component",id:e});({ids:P}=Bo(P,t)),o.active.value=t,o.blockTab.value="",o.cssMode.peek()&&(o.cssMode.value=!1),o.viewMode.peek()==="preview"&&(o.viewMode.value="split"),o.compTab.value=e,te(),q(),z();let a=N.get(e);a||(o.compReady.value=!1,o.compReadOnly.value=!1,o.compState.value="",o.compNote.value=`Opening <dm-${e}>\u2026`,a=await go(e)),!(!a||!c()||o.compTab.peek()!==e)&&(xa(),q(),z(),ae[o.compPart.peek()]?.focus())},Js=(e,t)=>{const a=N.get(o.compTab.peek());if(!a||!o.compReady.peek()||a.readOnly)return;const s=ut(a.form.source);s[e]=t,a.form.source=os(s),clearTimeout(At),$t=a,At=setTimeout(()=>{$t=null,ye(),at(a)},300)};i(M.effect(()=>{const e=o.compProject.value,t=o.compBundled.value,a=N.get(o.compTab.peek());!a||!o.compReady.peek()||a.readOnly||a.form.project===e&&a.form.bundled===t||(a.form.project=e,a.form.bundled=t,ye())}));const Ee=O("#pe-comp-props");let ho=[];const yo=e=>{Ee.replaceChildren();const t=document.createElement("p");t.className="pe-dock-none",t.textContent=e,Ee.appendChild(t)};function ko(){const e=N.get(o.compTab.peek());if(!e){ho=[],yo("Open a component to try its props.");return}const{rows:t,error:a}=as(ut(e.form.source).props,e.previewProps);if(ho=t,a){yo("The <props> block is not valid JSON - fix it to see the props here.");return}if(!t.length){e.previewProps={},yo("No props declared. Add them in the <props> block.");return}e.previewProps=Object.fromEntries(t.map(s=>[s.name,s.value])),Ee.replaceChildren();for(const s of t){const r=document.createElement("div");r.className="pe-comp-prop",r.tabIndex=0,r.dataset.prop=s.name;const n=document.createElement("label");n.className="pe-comp-prop-label",n.textContent=s.label,n.title=`${s.name} (${s.type})`;const l=s.type==="array"||s.type==="object"?document.createElement("textarea"):document.createElement("input");s.type==="boolean"?(l.type="checkbox",l.className="form-check",l.checked=ss(s.type,s.value)):(l.tagName==="INPUT"?l.type=s.type==="number"?"number":"text":l.rows=2,l.className="form-input form-input--sm pe-comp-prop-input",l.value=ss(s.type,s.value)),l.setAttribute("aria-label",s.label);const g=()=>{e.previewProps[s.name]=pr(s.type,s.type==="boolean"?l.checked:l.value),Rt===e.name&&Pt({type:"update",payload:{props:e.previewProps}})};l.addEventListener("input",g),l.addEventListener("change",g);const $=document.createElement("button");$.type="button",$.className="pe-kebab",$.setAttribute("aria-label",`Actions for ${s.label}`),$.title="Actions",$.textContent="\u22EE",r.append(n,l,$),Ee.appendChild(r)}}const Ie=async(e,t)=>{try{await navigator.clipboard.writeText(e),E.toast(`${t} copied.`,{type:"success"})}catch{E.toast(e,{type:"info",duration:8e3})}},Ws=e=>{const t=N.get(o.compTab.peek()),a=ho.find(n=>n.name===e);if(!t||!a)return[];const s=lr(a.name,a.type,t.previewProps[a.name]),r=`dm-${t.name}`;return[{header:a.label},{label:"Reset to its default",icon:"rotate-ccw",action:()=>{delete t.previewProps[a.name];const n=as(ut(t.form.source).props,{}).rows.find(l=>l.name===a.name);t.previewProps[a.name]=n?n.value:null,ko(),Rt===t.name&&Pt({type:"update",payload:{props:t.previewProps}})}},{label:"Copy as an attribute",icon:"copy",disabled:!s,action:()=>Ie(s,"Attribute")},{label:"Copy the tag with this value",icon:"code",action:()=>Ie(`<${r}${s?` ${s}`:""}></${r}>`,"Tag")},{label:"Copy the prop name",icon:"copy",action:()=>Ie(a.name,"Name")},{type:"divider"},{label:"Edit in <props>",icon:"edit",action:()=>{o.compPart.value="props";const n=ae.props?.textarea;if(!n)return;const l=n.value.indexOf(`"${a.name}"`);n.focus(),l>=0&&n.setSelectionRange(l,l+a.name.length+2)}}]};{const e=E.contextMenu(Ee,{cursor:"glyph",match:".pe-comp-prop",inherit:!1,density:"compact",items:t=>Ws(t.dataset.prop)});i(()=>e?.destroy?.()),Ee.addEventListener("click",t=>{const a=t.target.closest(".pe-kebab");a&&Ce(a)}),Ee.addEventListener("keydown",t=>{const a=t.target.closest(".pe-comp-prop");a&&t.key==="F10"&&t.shiftKey&&(t.preventDefault(),Ce(a))})}let Fe=!1;const Oa=()=>zt()||"",Nt=async({project:e=Oa(),seed:t="",content:a=wr,css:s=""}={})=>{if(!Fe){Fe=!0;try{const n=await ls({kind:"block",projects:se,taken:[...be],project:e,name:t,check:Nn,register:i,create:async(l,g)=>{await h.blocks.put(l,Za({name:l,project:g,bundled:!1,content:a,css:s}))}});if(!c())return;if(!n){te();return}if(await Vo(),!c())return;pt("#/blocks"),E.toast(`Created the block "${n}".`,{type:"success"}),Be(n)}finally{Fe=!1}}},nt=async({name:e="",source:t=ir,project:a=Oa()}={})=>{if(!Fe){Fe=!0;try{const s=await ls({kind:"component",projects:se,taken:[...le],project:a,name:e,register:i,check:(r,n)=>dr(r,{isNew:!0,taken:n}),create:async(r,n)=>{await h.components.put(r,{source:t,bundled:!1,meta:n?{project:n}:{}})}});if(!c())return;if(!s){te();return}if(await _o(),!c())return;pt("#/components"),E.toast(`Created the component "${s}".`,{type:"success"}),st(s)}finally{Fe=!1}}},Ra=y.querySelector(".dm-plugin-body")||y,Ys=M.computed(()=>{o.blockRev.value,o.compRev.value,o.docRev.value,W(_()),o.base.value;const e=I(o.active.value),t=[...Re().map(s=>X({kind:"page",id:s.id})),...ge().map(s=>X({kind:"block",id:s})),...Ye().map(s=>X({kind:"component",id:s}))];let a=[];return e?.kind==="block"||e?.kind==="component"?a=[o.active.value]:e?.kind==="page"&&m&&(a=[o.active.value,...ge().filter(wt).map(s=>X({kind:"block",id:s}))]),sr(t,a)}),Gs={...p,...o,dirty:ys,pageDirty:gs,activeDirty:ks,cssUnsaved:hs,hasPage:ws,activeKind:Xo,canView:Zo,viewHref:Ss,problem:Es,dconfigNoteRows:Ms,statusText:Ts,saveAll:Ys,dockKind:Qo,blockTagText:Cs,compStateText:xs,compTagText:Ps,anySelected:Os,allSelected:Rs,someSelected:As},rt=(e,t)=>Ke(e,t),wo={save:()=>io(!1),saveAllOpen:()=>io(!0),discard:async()=>{if(await Ea(),!c())return;const e=I(o.active.peek());if(e?.kind==="block"){const t=L.get(e.id);if(!t||!de(t)||!await E.confirm(`Discard the changes to "${e.id}" you have not saved?`))return;t.form={...t.saved},J(He(e.id)),Sa(),Le()}else if(e?.kind==="component"){const t=N.get(e.id);if(!t||!he(t)||!await E.confirm(`Discard the changes to the component "${e.id}" you have not saved?`))return;t.form={...t.saved},t.state="",J(Ve(e.id)),xa(),ye()}else{if(!m||e?.kind==="page"&&e.id!==m.id||!(Wt()||yt())||!await E.confirm("Discard the changes to this page you have not saved?"))return;Ze(JSON.parse(o.base.peek())),p.cssOpened.peek()&&(p.css.value=ee.peek()),J(ze(m.id)),J(ft),Xe()}q(),z(),U()},newPage:()=>ue(""),newBlock:()=>Nt(),newComponent:()=>nt(),toggleSection:e=>{const t={here:"secHere",pages:"secPages",blocks:"secBlocks",components:"secComps"}[e];t&&(o[t].value=!o[t].peek(),rt(t,o[t].peek()))},toggleExplorer:()=>{o.explorerOn.value=!o.explorerOn.peek(),rt("explorer",o.explorerOn.peek())},toggleDock:()=>{o.dockOn.value=!o.dockOn.peek(),rt("dock",o.dockOn.peek()),o.dockOn.peek()&&o.dockTab.peek()==="history"&&!Qe&&pe()},showDock:e=>{o.dockTab.value=e,e==="history"&&m?.isEdit&&!Qe&&pe()},schemaChanged:()=>{o.seoSchemaNote.value=Po(p.seoSchema.peek()).error},insertSchemaExample:async e=>{const t=e?.target,a=t?.value||"";if(t&&(t.value=""),!a||p.seoSchema.peek().trim()&&!await E.confirm("Replace the structured data with the example?"))return;const s=p.urlPath.peek().trim()||m?.id||"/";p.seoSchema.value=fn(a,{title:p.seoTitle.peek().trim()||p.title.peek().trim(),description:p.seoDesc.peek().trim()||p.description.peek().trim(),url:`${location.origin}${s}`,siteName:Y?.title||Y?.seo?.defaultTitle||""}),o.seoSchemaNote.value=""},setBlockPart:e=>{o.blockPart.value=e==="css"?"css":"html",(e==="css"?me:oe)?.focus()},formatBlock:()=>{const e=o.blockPart.peek()==="css",t=e?me:oe;!t||!o.blockReady.peek()||Uo(_e(t.textarea,e?"css":"html"))},copyShortcode:async()=>{const e=o.blockTab.peek();e&&await Ie(In(e),"Shortcode")},setCompPart:e=>{o.compPart.value=qt.includes(e)?e:"template",ae[o.compPart.peek()]?.focus()},copyComponent:()=>{const e=N.get(o.compTab.peek());e&&nt({name:Lo(e.name,[...le]),source:e.form.source})},setMode:e=>{o.cssMode.peek()&&(o.cssMode.value=!1),o.viewMode.value=jo(e),rt("viewMode",o.viewMode.peek()),e!=="write"&&(U(!0),bo())},toggleFullscreen:()=>{o.fullscreen.value=!o.fullscreen.peek(),rt("fullscreen",o.fullscreen.peek())},toggleCss:()=>{o.blockTab.peek()||o.compTab.peek()||(o.cssMode.peek()?(o.cssMode.value=!1,o.viewMode.value=jo(Pe().viewMode),Q.refresh()):(ia(),o.cssMode.value=!0,o.viewMode.value="split"))},formatMarkdown:()=>{Jt(),Uo(_e(V,"md"))},toggleFold:()=>{o.folded.peek()?Q.unfoldAll():Q.foldAll(),o.folded.value=!o.folded.peek(),We.paint()},setWidth:e=>{o.liveWidth.value=e},refreshPreview:()=>{if(o.compTab.peek()){const e=N.get(o.compTab.peek());e&&at(e)}else U(!0)},share:async()=>{if(!m?.isEdit){E.toast("Save the page first - a share link needs a page to point at.",{type:"warning"});return}await yr(m.id)},toggleAll:e=>{const t=!!e?.target?.checked;o.versions.peek().forEach(a=>{a.checked.value=t})},deleteSelected:async()=>{const e=o.versions.peek().filter(a=>a.checked.peek()).map(a=>a.filename),t=e.length;if(!(!t||!await E.confirm(`Delete ${t} version${t>1?"s":""}? This cannot be undone.`)))try{await h.versions.bulkDelete(m.id,e),E.toast(`${t} version${t>1?"s":""} deleted.`,{type:"success"}),await pe()}catch(a){E.toast("Delete failed: "+a.message,{type:"error"})}},saveNamed:async()=>{if(!m?.isEdit)return;const e=m;await kr(e.id)&&c()&&m===e&&await pe()},closeCompare:()=>{o.compare.value=null,Tt=null},restoreCompared:()=>ma(Tt)};Ge.querySelectorAll("[data-tip]").forEach(e=>E.tooltip(e,{content:e.getAttribute("data-tip"),position:"top"}));const Xs=M.applyBindings(Gs,Ra,{methods:wo});i(()=>Xs.dispose()),oe=zo(O('.pe-block-edit[data-part="html"]'),{ariaLabel:"Block template HTML",language:"html",onChange:e=>Ma("content",e)}),me=zo(O('.pe-block-edit[data-part="css"]'),{ariaLabel:"Block CSS",language:"css",placeholder:`/* Scoped to this block - e.g.
141
141
  color: var(--dm-primary);
142
- h3 { font-size: 1.25rem; } */`,onChange:e=>Ma("css",e)}),i(()=>{oe.destroy(),me.destroy()});for(const e of qt)ae[e]=zo(O(`.pe-comp-edit[data-part="${e}"]`),{ariaLabel:`Component <${e}> block`,language:{template:"html",props:"json",script:"js",style:"css"}[e],onChange:t=>Js(e,t)});i(()=>{for(const e of qt)ae[e].destroy()});const Me=O(".pe-tabs-list"),Dt=e=>e.target.closest(".pe-tab")?.dataset.id||"",Aa=e=>{const t=Dt(e);t&&(e.target.closest(".pe-tab-close")?et(t):xt(t))},$a=e=>{e.button===1&&Dt(e)&&(e.preventDefault(),et(Dt(e)))},La=e=>{const t=Dt(e);!t||e.target.closest(".pe-tab-close")||(e.key==="Enter"||e.key===" "?(e.preventDefault(),xt(t)):e.key==="Delete"?(e.preventDefault(),et(t)):e.key==="F10"&&e.shiftKey&&(e.preventDefault(),Ce(e.target.closest(".pe-tab"))))};Me.addEventListener("click",Aa),Me.addEventListener("auxclick",$a),Me.addEventListener("keydown",La),i(()=>{Me.removeEventListener("click",Aa),Me.removeEventListener("auxclick",$a),Me.removeEventListener("keydown",La)});const So=e=>{for(const t of e)et(t)},Zs=async e=>{const t=I(e);if(t?.id)if(t.kind==="page")o.active.peek()!==e&&await ue(t.id),c()&&m?.id===t.id&&Ba();else if(t.kind==="block"){const s=(L.get(t.id)||await lo(t.id,{quiet:!0}))?.form||Xa(await h.blocks.get(t.id).catch(()=>null));c()&&Nt({seed:Lo(t.id,[...be]),content:s.content,css:s.css})}else{const s=(N.get(t.id)||await go(t.id,{quiet:!0}))?.form.source??(await h.components.get(t.id).catch(()=>null))?.source??"";c()&&nt({name:Lo(t.id,[...le]),source:s})}},Qs=e=>{const t=I(e);if(!t||!P.includes(e))return[];const a=P.indexOf(e),s=Ne.get(e)?.label.peek()||t.id,r=n=>{P=Gn(P,e,n),q()};return[{header:s},{label:"Close",icon:"x",action:()=>et(e)},{label:"Close others",icon:"x-circle",disabled:P.length<2,action:()=>So(Io(P,e,"others"))},{label:"Close to the right",icon:"chevrons-right",disabled:a>=P.length-1,action:()=>So(Io(P,e,"right"))},{label:"Close all",icon:"layers",action:()=>So(Io(P,e,"all"))},{type:"divider"},{label:"Move left",icon:"arrow-left",disabled:a===0,action:()=>r(-1)},{label:"Move right",icon:"arrow-right",disabled:a>=P.length-1,action:()=>r(1)},{type:"divider"},{label:t.kind==="page"?"Clone page\u2026":`Duplicate ${t.kind}\u2026`,icon:"copy",disabled:!t.id,action:()=>Zs(e)},{label:"Copy link",icon:"link",disabled:!t.id,action:()=>Ie(`${location.origin}${location.pathname}#${es(t)}`,"Link")}]};{const e=E.contextMenu(Me,{cursor:"glyph",match:".pe-tab",inherit:!1,density:"compact",items:t=>Qs(t.dataset.id)});i(()=>e?.destroy?.())}const Na=O(".pe-ex-scroll"),Da=e=>{const t=e.target.closest(".pe-ex-item"),a=t?.dataset.id||"";if(!a)return;const s=a.indexOf(":"),r=a.slice(0,s),n=a.slice(s+1),l=()=>{ke.has(n)?ke.delete(n):ke.add(n);try{S.set(us,[...ke])}catch{}z()};if(r==="folder"){l();return}if(r==="page"&&e.target.closest(".pe-ex-chev")&&t.classList.contains("is-folder")){l();return}r==="page"?ue(n):r==="block"?Be(n):r==="component"&&st(n)};Na.addEventListener("click",Da),i(()=>Na.removeEventListener("click",Da));let Eo=null;i(()=>clearTimeout(Eo)),V.addEventListener("input",()=>{Q.refresh(),ce.scrollTop=V.scrollTop,!gt&&(clearTimeout(Eo),Eo=setTimeout(ra,120),U())}),V.addEventListener("scroll",()=>{ce.scrollTop=V.scrollTop}),ve.addEventListener("scroll",()=>{ce.scrollTop=ve.scrollTop}),i(M.effect(()=>{for(const e of Object.keys(p))e!=="css"&&e!=="cssOpened"&&p[e].value;o.bodyRev.value,U()})),i(M.effect(()=>{o.bodyRev.value,o.docRev.value;const e=m?ht():"";kt=m?Nn(e,bt.map(t=>t.name),bt.filter(t=>t.shortTag).map(t=>t.name)):[],ta=m?Yn(e,le):[],St(),z()})),i(M.effect(()=>{o.blockRev.value,o.compRev.value,o.docRev.value,o.active.value,o.filter.value,p.title.value,q(),z()})),i(M.effect(()=>{ce.hidden=!!(o.blockTab.value||o.compTab.value)}));let Mo=null;i(()=>clearTimeout(Mo)),i(M.effect(()=>{const e=p.css.value;o.cssMode.value&&(Ut.paint(),Ar(ce,e,ve),clearTimeout(Mo),Mo=setTimeout(oa,400))}));{const e=O(".pe-version-list"),t=E.contextMenu(e,{cursor:"glyph",match:"tr[data-file]",inherit:!1,density:"compact",items:a=>{const s=oo(a.dataset.file);return s?[{header:rs(s)},{label:"Show beside the editor",icon:"columns",action:()=>ao(s)},{label:"Restore this version\u2026",icon:"rotate-ccw",action:()=>ma(s.filename)},{type:"divider"},{label:"Delete\u2026",icon:"trash",danger:!0,action:()=>Bs(s)}]:[]}});i(()=>t?.destroy?.()),e.addEventListener("click",a=>{const s=a.target.closest("tr[data-file]");if(!s||a.target.matches("input"))return;const r=a.target.closest(".pe-kebab");if(r){Ce(r);return}const n=oo(s.dataset.file);n&&ao(n)}),e.addEventListener("keydown",a=>{const s=a.target.closest("tr[data-file]");if(s){if(a.key==="F10"&&a.shiftKey)a.preventDefault(),Ce(s);else if(a.key==="Enter"&&a.target===s){const r=oo(s.dataset.file);r&&ao(r)}}})}$r(O("#editor-body"),O("#editor-divider"),i),cn({image:e=>(o.cssMode.value=!1,Lr(e)),scribe:e=>un(e),card:e=>tn.open(e,{onMediaBrowse:()=>h.media.list().catch(()=>[])}),timeline:e=>on.open(e,{onPreview:async t=>{try{return await h.pages.preview(t)}catch{return null}},onListCollections:()=>h.collections.list().catch(()=>[]),onGetCollection:t=>h.collections.get(t).catch(()=>null)})}),to.onEffects(e=>rn.open(e)),to.onHelp(()=>Ha()),to.onTutorial(e=>mn(e));const ja=e=>{if(!c())return;const t=sr(e);t&&(e.preventDefault(),t==="save"?io(!1):t==="layout"?wo.setMode(Xn(o.viewMode.peek())):wo.toggleExplorer())};document.addEventListener("keydown",ja),i(()=>document.removeEventListener("keydown",ja));const it=y.querySelector(".dm-plugin-banner-name");i(M.effect(()=>{const e=o.curId.value,t=Xo.value,a=o.blockTab.value||o.compTab.value,s=t==="block"?"Blocks":t==="component"?"Components":"Pages",r=t==="block"||t==="component"?a:e===null?"Editor":Cn(!!e,p.title.value,e);if(!c()||(document.title=`${r} - Domma CMS`,!it))return;const n=it.querySelector(".dm-plugin-banner-parent"),l=it.lastChild;n&&l&&l.nodeType===3&&it.querySelector(".dm-plugin-banner-sep")?(n.textContent=s,l.textContent=r):it.textContent=`${s} \u203A ${r}`})),dt(d,{id:"page-editor-back",icon:"arrow-left",title:"Back to Pages",onClick:()=>R.navigate("/pages")}),dt(d,{id:"page-editor-help",icon:"help-circle",title:"Editor reference",onClick:()=>Ha()});const en=dt(d,{id:"page-editor-view",icon:"external-link",title:"View on the site",onClick:()=>{m?.isEdit&&window.open(p.urlPath.peek().trim()||m.id,"_blank","noopener")}}),Ba=()=>{if(!m?.isEdit||o.saving.peek()||!c())return;const e=m,t=_(),a=Ro({...t,urlPath:e.id});if(a.length){E.toast(a[0].text,{type:"warning"});return}const s=gn({page:e.page,frontmatter:{...Gt(t,e,Xt(t)),adminTags:t.adminTags},body:t.body,source:e.id,pages:D,onCloned:async r=>{c()&&(await ha(),c()&&ue(r))}});i(()=>s.close())},To=dt(d,{id:"page-editor-clone",icon:"copy",title:"Clone page",onClick:Ba});i(M.effect(()=>{const e=Zo.value;for(const t of[en,To])t&&(t.disabled=!e);To&&(To.title=e?"Clone page":"Open a saved page to clone it")})),dt(d,{id:"page-editor-settings",icon:"settings",title:"Editor settings - font, size, spacing",onClick:()=>{Yo=vr(Jo,Wo)}}),i(qa(Ra,{position:"bottom"})),Domma.icons.scan();let Ia={ids:[],active:""};try{Ia=er(S.get(ps))}catch{}const lt=Ua(b),ct=ar(lt,Ia,history.state?.pe===1);P=ct.ids.filter(e=>{const t=I(e);return t.kind==="page"||(t.kind==="component"?le:be).has(t.id)}),ba=!1;for(const e of P){const t=I(e);t.kind==="page"&&ya(t.id)}q(),z(),St();for(const e of Ae)lo(e,{quiet:!0}).then(()=>{c()&&(q(),z())});for(const e of P){const t=I(e);t.kind==="component"&&e!==ct.active&&xe(t)&&go(t.id,{quiet:!0}).then(()=>{c()&&(q(),z())})}const Fa=lt&&!lt.id&&lt.kind!=="page";ct.active&&P.includes(ct.active)?await xt(ct.active):P.length?await xt(P[0]):Fa||te(),Fa&&c()&&(await(lt.kind==="block"?Nt:nt)({project:zt(b)||""}),c()&&te())}};function qo(d,b){!d||typeof b!="string"||!b||[...d.options].some(v=>v.value===b)||(d.append(Object.assign(document.createElement("option"),{value:b,textContent:`${b} (custom)`})),d.value=b)}function Ar(d,b,v){d.replaceChildren(...String(b).split(`
143
- `).map((i,k)=>{const u=document.createElement("span");u.className="editor-line-number-row";const w=document.createElement("span");w.className="fold-toggle fold-toggle--empty";const y=document.createElement("span");return y.className="editor-line-num",y.textContent=String(k+1),u.append(w,y),u})),d.scrollTop=v.scrollTop}function $r(d,b,v){if(!d||!b)return;const i=15,k=85,u=c=>Math.min(k,Math.max(i,c));let w=u(parseFloat(Pe().splitRatio)||50);const y=c=>{d.style.setProperty("--dm-editor-split",w+"%"),b.setAttribute("aria-valuenow",String(Math.round(w))),c&&Ke("splitRatio",w)};y(!1);const x=c=>{const A=d.getBoundingClientRect();A.width&&(w=u((c.clientX-A.left)/A.width*100)),y(!1)},j=()=>{document.removeEventListener("pointermove",x),document.removeEventListener("pointerup",j),d.classList.remove("is-resizing"),b.classList.remove("is-dragging"),y(!0)};v(j),b.addEventListener("pointerdown",c=>{window.matchMedia("(max-width: 768px)").matches||(c.preventDefault(),d.classList.add("is-resizing"),b.classList.add("is-dragging"),document.addEventListener("pointermove",x),document.addEventListener("pointerup",j))}),b.addEventListener("dblclick",()=>{w=50,y(!0)}),b.addEventListener("keydown",c=>{const A=c.shiftKey?10:2;let H=w;if(c.key==="ArrowLeft")H=w-A;else if(c.key==="ArrowRight")H=w+A;else if(c.key==="Home")H=i;else if(c.key==="End")H=k;else if(c.key==="Enter"||c.key===" ")H=50;else return;c.preventDefault(),w=u(H),y(!0)})}async function Lr(d){const b=d.selectionStart,v=d.selectionEnd,i=await vn({title:"Upload or insert an image"});if(!i||!d.isConnected)return;let k=i.split("/").pop().split("?")[0];try{k=decodeURIComponent(k)}catch{}const u=k.replace(/[\\[\]]/g,"\\$&"),w=i.replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/ /g,"%20");d.setSelectionRange(b,v),nn(d,`![${u}](${w})`),d.dispatchEvent(new Event("input",{bubbles:!0}))}function Nr(d,b,v){const i=Object.entries(b||{});return d?(d.replaceChildren(...i.map(([k,u])=>new Option(u?.label||k,k))),i.some(([k])=>k===v)?v:i[0]?.[0]||v):v}async function Dr(d,b){if(!d)return;let v=[];try{const x=await h.get("/collections/roles/entries?limit=100");v=Array.isArray(x)?x:x?.entries||[]}catch{}const i=v.map(x=>({name:x.data?.name,label:x.data?.label||x.data?.name,level:x.data?.level??99})).filter(x=>x.name&&x.level!==0).sort((x,j)=>j.level-x.level),k=(x,j)=>Object.assign(document.createElement("option"),{value:x,textContent:j}),u=()=>{typeof b=="string"&&b&&![...d.options].some(x=>x.value===b)&&d.append(k(b,`${b} (custom)`))};if(!i.length)return u();const w=document.createElement("optgroup");w.label="Role and above",i.forEach(x=>w.append(k(x.name,`${x.label} and above`)));const y=document.createElement("optgroup");y.label="Role only",i.forEach(x=>y.append(k(`=${x.name}`,`${x.label} only`))),d.replaceChildren(k("public","Public - everyone"),w,y,k("private","Private - super-admin only")),u()}
142
+ h3 { font-size: 1.25rem; } */`,onChange:e=>Ma("css",e)}),i(()=>{oe.destroy(),me.destroy()});for(const e of qt)ae[e]=zo(O(`.pe-comp-edit[data-part="${e}"]`),{ariaLabel:`Component <${e}> block`,language:{template:"html",props:"json",script:"js",style:"css"}[e],onChange:t=>Js(e,t)});i(()=>{for(const e of qt)ae[e].destroy()});const Me=O(".pe-tabs-list"),Dt=e=>e.target.closest(".pe-tab")?.dataset.id||"",Aa=e=>{const t=Dt(e);t&&(e.target.closest(".pe-tab-close")?et(t):xt(t))},$a=e=>{e.button===1&&Dt(e)&&(e.preventDefault(),et(Dt(e)))},La=e=>{const t=Dt(e);!t||e.target.closest(".pe-tab-close")||(e.key==="Enter"||e.key===" "?(e.preventDefault(),xt(t)):e.key==="Delete"?(e.preventDefault(),et(t)):e.key==="F10"&&e.shiftKey&&(e.preventDefault(),Ce(e.target.closest(".pe-tab"))))};Me.addEventListener("click",Aa),Me.addEventListener("auxclick",$a),Me.addEventListener("keydown",La),i(()=>{Me.removeEventListener("click",Aa),Me.removeEventListener("auxclick",$a),Me.removeEventListener("keydown",La)});const So=e=>{for(const t of e)et(t)},Zs=async e=>{const t=I(e);if(t?.id)if(t.kind==="page")o.active.peek()!==e&&await ue(t.id),c()&&m?.id===t.id&&Ba();else if(t.kind==="block"){const s=(L.get(t.id)||await lo(t.id,{quiet:!0}))?.form||Xa(await h.blocks.get(t.id).catch(()=>null));c()&&Nt({seed:Lo(t.id,[...be]),content:s.content,css:s.css})}else{const s=(N.get(t.id)||await go(t.id,{quiet:!0}))?.form.source??(await h.components.get(t.id).catch(()=>null))?.source??"";c()&&nt({name:Lo(t.id,[...le]),source:s})}},Qs=e=>{const t=I(e);if(!t||!P.includes(e))return[];const a=P.indexOf(e),s=Ne.get(e)?.label.peek()||t.id,r=n=>{P=Zn(P,e,n),q()};return[{header:s},{label:"Close",icon:"x",action:()=>et(e)},{label:"Close others",icon:"x-circle",disabled:P.length<2,action:()=>So(Io(P,e,"others"))},{label:"Close to the right",icon:"chevrons-right",disabled:a>=P.length-1,action:()=>So(Io(P,e,"right"))},{label:"Close all",icon:"layers",action:()=>So(Io(P,e,"all"))},{type:"divider"},{label:"Move left",icon:"arrow-left",disabled:a===0,action:()=>r(-1)},{label:"Move right",icon:"arrow-right",disabled:a>=P.length-1,action:()=>r(1)},{type:"divider"},{label:t.kind==="page"?"Clone page\u2026":`Duplicate ${t.kind}\u2026`,icon:"copy",disabled:!t.id,action:()=>Zs(e)},{label:"Copy link",icon:"link",disabled:!t.id,action:()=>Ie(`${location.origin}${location.pathname}#${es(t)}`,"Link")}]};{const e=E.contextMenu(Me,{cursor:"glyph",match:".pe-tab",inherit:!1,density:"compact",items:t=>Qs(t.dataset.id)});i(()=>e?.destroy?.())}const Na=O(".pe-ex-scroll"),Da=e=>{const t=e.target.closest(".pe-ex-item"),a=t?.dataset.id||"";if(!a)return;const s=a.indexOf(":"),r=a.slice(0,s),n=a.slice(s+1),l=()=>{ke.has(n)?ke.delete(n):ke.add(n);try{S.set(us,[...ke])}catch{}z()};if(r==="folder"){l();return}if(r==="page"&&e.target.closest(".pe-ex-chev")&&t.classList.contains("is-folder")){l();return}r==="page"?ue(n):r==="block"?Be(n):r==="component"&&st(n)};Na.addEventListener("click",Da),i(()=>Na.removeEventListener("click",Da));let Eo=null;i(()=>clearTimeout(Eo)),V.addEventListener("input",()=>{Q.refresh(),ce.scrollTop=V.scrollTop,!gt&&(clearTimeout(Eo),Eo=setTimeout(ra,120),U())}),V.addEventListener("scroll",()=>{ce.scrollTop=V.scrollTop}),ve.addEventListener("scroll",()=>{ce.scrollTop=ve.scrollTop}),i(M.effect(()=>{for(const e of Object.keys(p))e!=="css"&&e!=="cssOpened"&&p[e].value;o.bodyRev.value,U()})),i(M.effect(()=>{o.bodyRev.value,o.docRev.value;const e=m?ht():"";kt=m?jn(e,bt.map(t=>t.name),bt.filter(t=>t.shortTag).map(t=>t.name)):[],ta=m?Xn(e,le):[],St(),z()})),i(M.effect(()=>{o.blockRev.value,o.compRev.value,o.docRev.value,o.active.value,o.filter.value,p.title.value,q(),z()})),i(M.effect(()=>{ce.hidden=!!(o.blockTab.value||o.compTab.value)}));let Mo=null;i(()=>clearTimeout(Mo)),i(M.effect(()=>{const e=p.css.value;o.cssMode.value&&(Ut.paint(),Lr(ce,e,ve),clearTimeout(Mo),Mo=setTimeout(oa,400))}));{const e=O(".pe-version-list"),t=E.contextMenu(e,{cursor:"glyph",match:"tr[data-file]",inherit:!1,density:"compact",items:a=>{const s=oo(a.dataset.file);return s?[{header:rs(s)},{label:"Show beside the editor",icon:"columns",action:()=>ao(s)},{label:"Restore this version\u2026",icon:"rotate-ccw",action:()=>ma(s.filename)},{type:"divider"},{label:"Delete\u2026",icon:"trash",danger:!0,action:()=>Bs(s)}]:[]}});i(()=>t?.destroy?.()),e.addEventListener("click",a=>{const s=a.target.closest("tr[data-file]");if(!s||a.target.matches("input"))return;const r=a.target.closest(".pe-kebab");if(r){Ce(r);return}const n=oo(s.dataset.file);n&&ao(n)}),e.addEventListener("keydown",a=>{const s=a.target.closest("tr[data-file]");if(s){if(a.key==="F10"&&a.shiftKey)a.preventDefault(),Ce(s);else if(a.key==="Enter"&&a.target===s){const r=oo(s.dataset.file);r&&ao(r)}}})}Nr(O("#editor-body"),O("#editor-divider"),i),cn({image:e=>(o.cssMode.value=!1,Dr(e)),scribe:e=>un(e),card:e=>tn.open(e,{onMediaBrowse:()=>h.media.list().catch(()=>[])}),timeline:e=>on.open(e,{onPreview:async t=>{try{return await h.pages.preview(t)}catch{return null}},onListCollections:()=>h.collections.list().catch(()=>[]),onGetCollection:t=>h.collections.get(t).catch(()=>null)})}),to.onEffects(e=>rn.open(e)),to.onHelp(()=>Ha()),to.onTutorial(e=>mn(e));const ja=e=>{if(!c())return;const t=rr(e);t&&(e.preventDefault(),t==="save"?io(!1):t==="layout"?wo.setMode(Qn(o.viewMode.peek())):wo.toggleExplorer())};document.addEventListener("keydown",ja),i(()=>document.removeEventListener("keydown",ja));const it=y.querySelector(".dm-plugin-banner-name");i(M.effect(()=>{const e=o.curId.value,t=Xo.value,a=o.blockTab.value||o.compTab.value,s=t==="block"?"Blocks":t==="component"?"Components":"Pages",r=t==="block"||t==="component"?a:e===null?"Editor":Pn(!!e,p.title.value,e);if(!c()||(document.title=`${r} - Domma CMS`,!it))return;const n=it.querySelector(".dm-plugin-banner-parent"),l=it.lastChild;n&&l&&l.nodeType===3&&it.querySelector(".dm-plugin-banner-sep")?(n.textContent=s,l.textContent=r):it.textContent=`${s} \u203A ${r}`})),dt(d,{id:"page-editor-back",icon:"arrow-left",title:"Back to Pages",onClick:()=>R.navigate("/pages")}),dt(d,{id:"page-editor-help",icon:"help-circle",title:"Editor reference",onClick:()=>Ha()});const en=dt(d,{id:"page-editor-view",icon:"external-link",title:"View on the site",onClick:()=>{m?.isEdit&&window.open(p.urlPath.peek().trim()||m.id,"_blank","noopener")}}),Ba=()=>{if(!m?.isEdit||o.saving.peek()||!c())return;const e=m,t=_(),a=Ro({...t,urlPath:e.id});if(a.length){E.toast(a[0].text,{type:"warning"});return}const s=gn({page:e.page,frontmatter:{...Gt(t,e,Xt(t)),adminTags:t.adminTags},body:t.body,source:e.id,pages:D,onCloned:async r=>{c()&&(await ha(),c()&&ue(r))}});i(()=>s.close())},To=dt(d,{id:"page-editor-clone",icon:"copy",title:"Clone page",onClick:Ba});i(M.effect(()=>{const e=Zo.value;for(const t of[en,To])t&&(t.disabled=!e);To&&(To.title=e?"Clone page":"Open a saved page to clone it")})),dt(d,{id:"page-editor-settings",icon:"settings",title:"Editor settings - font, size, spacing",onClick:()=>{Yo=hr(Jo,Wo)}}),i(qa(Ra,{position:"bottom"})),Domma.icons.scan();let Ia={ids:[],active:""};try{Ia=or(S.get(ps))}catch{}const lt=Ua(b),ct=nr(lt,Ia,history.state?.pe===1);P=ct.ids.filter(e=>{const t=I(e);return t.kind==="page"||(t.kind==="component"?le:be).has(t.id)}),ba=!1;for(const e of P){const t=I(e);t.kind==="page"&&ya(t.id)}q(),z(),St();for(const e of Ae)lo(e,{quiet:!0}).then(()=>{c()&&(q(),z())});for(const e of P){const t=I(e);t.kind==="component"&&e!==ct.active&&xe(t)&&go(t.id,{quiet:!0}).then(()=>{c()&&(q(),z())})}const Fa=lt&&!lt.id&&lt.kind!=="page";ct.active&&P.includes(ct.active)?await xt(ct.active):P.length?await xt(P[0]):Fa||te(),Fa&&c()&&(await(lt.kind==="block"?Nt:nt)({project:zt(b)||""}),c()&&te())}};function qo(d,b){!d||typeof b!="string"||!b||[...d.options].some(v=>v.value===b)||(d.append(Object.assign(document.createElement("option"),{value:b,textContent:`${b} (custom)`})),d.value=b)}function Lr(d,b,v){d.replaceChildren(...String(b).split(`
143
+ `).map((i,k)=>{const u=document.createElement("span");u.className="editor-line-number-row";const w=document.createElement("span");w.className="fold-toggle fold-toggle--empty";const y=document.createElement("span");return y.className="editor-line-num",y.textContent=String(k+1),u.append(w,y),u})),d.scrollTop=v.scrollTop}function Nr(d,b,v){if(!d||!b)return;const i=15,k=85,u=c=>Math.min(k,Math.max(i,c));let w=u(parseFloat(Pe().splitRatio)||50);const y=c=>{d.style.setProperty("--dm-editor-split",w+"%"),b.setAttribute("aria-valuenow",String(Math.round(w))),c&&Ke("splitRatio",w)};y(!1);const x=c=>{const A=d.getBoundingClientRect();A.width&&(w=u((c.clientX-A.left)/A.width*100)),y(!1)},j=()=>{document.removeEventListener("pointermove",x),document.removeEventListener("pointerup",j),d.classList.remove("is-resizing"),b.classList.remove("is-dragging"),y(!0)};v(j),b.addEventListener("pointerdown",c=>{window.matchMedia("(max-width: 768px)").matches||(c.preventDefault(),d.classList.add("is-resizing"),b.classList.add("is-dragging"),document.addEventListener("pointermove",x),document.addEventListener("pointerup",j))}),b.addEventListener("dblclick",()=>{w=50,y(!0)}),b.addEventListener("keydown",c=>{const A=c.shiftKey?10:2;let H=w;if(c.key==="ArrowLeft")H=w-A;else if(c.key==="ArrowRight")H=w+A;else if(c.key==="Home")H=i;else if(c.key==="End")H=k;else if(c.key==="Enter"||c.key===" ")H=50;else return;c.preventDefault(),w=u(H),y(!0)})}async function Dr(d){const b=d.selectionStart,v=d.selectionEnd,i=await vn({title:"Upload or insert an image"});if(!i||!d.isConnected)return;let k=i.split("/").pop().split("?")[0];try{k=decodeURIComponent(k)}catch{}const u=k.replace(/[\\[\]]/g,"\\$&"),w=i.replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/ /g,"%20");d.setSelectionRange(b,v),nn(d,`![${u}](${w})`),d.dispatchEvent(new Event("input",{bubbles:!0}))}function jr(d,b,v){const i=Object.entries(b||{});return d?(d.replaceChildren(...i.map(([k,u])=>new Option(u?.label||k,k))),i.some(([k])=>k===v)?v:i[0]?.[0]||v):v}async function Br(d,b){if(!d)return;let v=[];try{const x=await h.get("/collections/roles/entries?limit=100");v=Array.isArray(x)?x:x?.entries||[]}catch{}const i=v.map(x=>({name:x.data?.name,label:x.data?.label||x.data?.name,level:x.data?.level??99})).filter(x=>x.name&&x.level!==0).sort((x,j)=>j.level-x.level),k=(x,j)=>Object.assign(document.createElement("option"),{value:x,textContent:j}),u=()=>{typeof b=="string"&&b&&![...d.options].some(x=>x.value===b)&&d.append(k(b,`${b} (custom)`))};if(!i.length)return u();const w=document.createElement("optgroup");w.label="Role and above",i.forEach(x=>w.append(k(x.name,`${x.label} and above`)));const y=document.createElement("optgroup");y.label="Role only",i.forEach(x=>y.append(k(`=${x.name}`,`${x.label} only`))),d.replaceChildren(k("public","Public - everyone"),w,y,k("private","Private - super-admin only")),u()}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "1.10.24",
3
+ "version": "1.10.26",
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",
@@ -86,7 +86,7 @@
86
86
  "bcryptjs": "^3.0.3",
87
87
  "css-select": "^7.0.0",
88
88
  "dom-serializer": "^3.1.1",
89
- "domma-js": "0.59.0",
89
+ "domma-js": "0.60.0",
90
90
  "dotenv": "^17.2.3",
91
91
  "fastify": "5.12.7",
92
92
  "gray-matter": "^4.0.3",
@@ -7,12 +7,19 @@ import {SHORTCODE_EXPIRY_FIELDS} from '../../public/js/shortcode-expiry.mjs';
7
7
 
8
8
  const STATE_FILE = path.resolve('content/shortcode-expiry.json');
9
9
  const EXPIRY_KEYS = new Set(['expires-at', 'expire-after', 'expire-views', 'expire-scope', 'expire-ip', 'expire-session', 'expiry-id']);
10
+ // What can hide a shortcode. expire-scope and expiry-id only say how a rule counts, so a tag carrying
11
+ // just those (the insert forms used to write expire-scope="ip" on every child) is not expiring.
12
+ const RULE_KEYS = new Set(['expires-at', 'expire-after', 'expire-views', 'expire-ip', 'expire-session']);
10
13
  let stateQueue = Promise.resolve();
11
14
 
12
15
  export function hasShortcodeExpiry(attrs) {
13
- return Object.keys(attrs || {}).some(key => EXPIRY_KEYS.has(key));
16
+ return Object.keys(attrs || {}).some(key => RULE_KEYS.has(key));
14
17
  }
15
18
 
19
+ const hasExpiryAttrs = (attrs) => Object.keys(attrs || {}).some(key => EXPIRY_KEYS.has(key));
20
+ // A quoted value is matched whole first, so an expiry name inside one (title="Set expire-scope here") is left alone
21
+ const withoutExpiryAttrs = (raw) => raw.replace(/("[^"]*"|'[^']*')|\s+(?:expires-at|expire-after|expire-views|expire-scope|expire-ip|expire-session|expiry-id)(?![\w-])(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s\]]+))?/gi, (match, quoted) => quoted || '');
22
+
16
23
  export function validSessionCookie(value, secret) {
17
24
  if (!value || !secret) return '';
18
25
  const [id, signature, extra] = String(value).split('.');
@@ -56,6 +63,8 @@ async function applyShortcodeExpiryUnlocked(markdown, {urlPath = '/', ip = '', s
56
63
  }));
57
64
  const ranges = [];
58
65
  const stack = [];
66
+ // Tags with a counting attribute but no rule: shown as they are, the attribute taken off
67
+ const strays = [];
59
68
  for (let i = 0; i < tokens.length; i++) {
60
69
  const t = tokens[i];
61
70
  if (t.close) {
@@ -68,6 +77,7 @@ async function applyShortcodeExpiryUnlocked(markdown, {urlPath = '/', ip = '', s
68
77
  }
69
78
  } else {
70
79
  t.expiring = hasShortcodeExpiry(t.attrs);
80
+ if (!t.expiring && hasExpiryAttrs(t.attrs)) strays.push(t);
71
81
  if (t.self || /\/\s*$/.test(t.attrsText)) {
72
82
  if (t.expiring) ranges.push({start:t.start, end:t.end, token:t});
73
83
  } else stack.push(t);
@@ -75,7 +85,11 @@ async function applyShortcodeExpiryUnlocked(markdown, {urlPath = '/', ip = '', s
75
85
  }
76
86
  // Treat malformed/unclosed expiry tags as extending to the end of the source.
77
87
  for (const open of stack) if (open.expiring) ranges.push({start:open.start, end:markdown.length, token:open});
78
- if (!ranges.length) return {markdown, hasExpiry:false};
88
+ if (!ranges.length) {
89
+ let output = markdown;
90
+ for (const t of strays.sort((a,b)=>b.start-a.start)) output = output.slice(0,t.start) + withoutExpiryAttrs(t.raw) + output.slice(t.end);
91
+ return {markdown:output, hasExpiry:false};
92
+ }
79
93
 
80
94
  const now = Date.now();
81
95
  let state = {};
@@ -129,9 +143,9 @@ async function applyShortcodeExpiryUnlocked(markdown, {urlPath = '/', ip = '', s
129
143
  await fs.rename(temp, STATE_FILE);
130
144
  }
131
145
  const edits = collapsed.map(range => ({start:range.start, end:range.end, value:''}));
132
- for (const token of cleanOpeners) {
146
+ for (const token of [...cleanOpeners, ...strays]) {
133
147
  if (collapsed.some(range => range.start <= token.start && range.end >= token.end)) continue;
134
- const cleaned = token.raw.replace(/\s+(?:expires-at|expire-after|expire-views|expire-scope|expire-ip|expire-session|expiry-id)(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s\]]+))?/gi, '');
148
+ const cleaned = withoutExpiryAttrs(token.raw);
135
149
  if (cleaned !== token.raw) edits.push({start:token.start, end:token.end, value:cleaned});
136
150
  }
137
151
  let output = markdown;