domma-cms 1.6.43 → 1.6.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/admin/index.html CHANGED
@@ -26,7 +26,7 @@
26
26
 
27
27
  <!-- Menu item hover / current-page effects - the admin sidebar is a menu
28
28
  like any other, so it honours the same `highlight` block. -->
29
- <link rel="stylesheet" href="/public/css/menu-highlight.css?v=20260905-menu-highlight">
29
+ <link rel="stylesheet" href="/public/css/menu-highlight.css?v=20261014-menu-entrance">
30
30
  <link rel="stylesheet" href="/admin/css/calculator.css">
31
31
  </head>
32
32
  <body class="dm-cloaked dm-theme-charcoal-dark dashboard-layout">
@@ -1,2 +1,2 @@
1
- const p=["separator","spacer","theme-switcher"];export const isStructural=t=>p.includes(t?.type);export function siblingsOf(t,e){const i=t.find(n=>n.id===e);return i?t.filter(n=>n.parentId===i.parentId):[]}export function moveRow(t,e,i){const n=siblingsOf(t,e),r=n.findIndex(a=>a.id===e),l=r+(i<0?-1:1);if(r<0||l<0||l>=n.length)return!1;n[r].touched=!0;const o=t.indexOf(n[r]),s=t.indexOf(n[l]);return[t[o],t[s]]=[t[s],t[o]],!0}export function indentRow(t,e){const i=siblingsOf(t,e),n=i.findIndex(r=>r.id===e);return n<=0||isStructural(i[n-1])?!1:(i[n].parentId=i[n-1].id,i[n].touched=!0,!0)}export function outdentRow(t,e){const i=t.find(r=>r.id===e);if(!i||i.parentId==null)return!1;const n=t.find(r=>r.id===i.parentId);return i.parentId=n?n.parentId:null,i.touched=!0,!0}export function newRow(t,e,i=null){return t==="separator"?{id:e,parentId:i,type:"separator"}:t==="theme-switcher"?{id:e,parentId:i,type:"theme-switcher"}:t==="spacer"?{id:e,parentId:i,type:"spacer",size:"md"}:{id:e,parentId:i,text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}}export function insertBelow(t,e,i,n){const r=t.findIndex(o=>o.id===e);if(r===-1)return null;const l=newRow(i,n,t[r].parentId);return t.splice(r+1,0,l),l}export function addChild(t,e,i){const n=t.find(l=>l.id===e);if(!n||isStructural(n))return null;const r=newRow("item",i,n.id);return t.push(r),n.touched=!0,r}export function duplicateRow(t,e,i){const n=t.find(a=>a.id===e);if(!n||n.tool)return null;const r=new Map,l=[],o=(a,u)=>{if(a.tool)return;const c={...m(a),id:i(),parentId:u};delete c.tool,delete c.locked,c.touched=!0,r.set(a.id,c.id),l.push(c);for(const d of t.filter(f=>f.parentId===a.id))o(d,c.id)};if(o(n,n.parentId),!l.length)return null;l[0].text&&(l[0].text=`${l[0].text} (copy)`);const s=t.indexOf(n);return t.splice(s+1,0,l[0]),t.push(...l.slice(1)),l[0]}function m(t){return JSON.parse(JSON.stringify(t))}export function bindingFrom({slot:t="",projects:e=[],pagesText:i=""}={}){return t?{slot:t,projects:[...e],pages:String(i).split(`
2
- `).map(n=>n.trim()).filter(Boolean)}:null}export function badPagePatterns(t=[]){return t.filter(e=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(e))}const g=["fontFamily","fontSize","fontWeight","letterSpacing","iconSize"];export function menuFromForm(t={},e={},i=null,n=[],r={}){const l=Object.fromEntries(g.filter(u=>t[u]).map(u=>[u,t[u]])),o={};if(t.position==="floating"){t.floatAnchor&&(o.anchor=t.floatAnchor);for(const[u,c]of[["offsetX",t.floatOffsetX],["offsetY",t.floatOffsetY],["width",t.floatWidth],["radius",t.floatRadius],["opacity",t.floatOpacity]])c!==""&&c!=null&&Number.isFinite(Number(c))&&(o[u]=Number(c));t.floatShadow&&(o.shadow=t.floatShadow),t.floatAccent&&(o.accent=t.floatAccent),t.floatTitle&&(o.title=String(t.floatTitle).trim()),t.floatCollapsible&&(o.collapsible=!0),t.floatCollapsible&&t.floatCollapsed&&(o.collapsed=!0),t.floatMovable&&(o.movable=!0),t.floatResizable&&(o.resizable=!0)}const s={};t.position!=="floating"&&(t.orientation==="vertical"?(t.dockWidth!==""&&t.dockWidth!=null&&Number.isFinite(Number(t.dockWidth))&&(s.width=Number(t.dockWidth)),t.dockAutohide?s.autohide=!0:t.dockCollapsible&&(s.collapsible=!0,t.dockCollapsed&&(s.collapsed=!0))):t.dockHideOnScroll&&(s.hideOnScroll=!0));const a={};return t.highlightHover&&(a.hover=t.highlightHover),t.highlightActive&&(a.active=t.highlightActive),t.highlightAccent&&(a.accent=t.highlightAccent),{slug:String(e.slug||"").trim(),name:String(e.name||"").trim(),description:String(e.description||"").trim(),...t.variant&&{variant:t.variant},...t.position&&{position:t.position},...t.orientation&&{orientation:t.orientation},...t.orientation==="vertical"&&t.side&&{side:t.side},...t.orientation!=="vertical"&&t.align&&{align:t.align},...Object.keys(o).length&&{float:o},...Object.keys(a).length&&{highlight:a},...Object.keys(s).length&&{dock:s},...t.appearOnHover&&{appearOnHover:!0},...t.class&&String(t.class).trim()&&{class:String(t.class).trim()},...Object.keys(l).length&&{style:l},binding:i,items:n,meta:{...r||{},project:e.project||null}}}export function menuProblems(t){const e=[];/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(t.slug||"")||e.push("The slug must be lowercase letters, numbers and hyphens, no hyphen at either end (Meta tab)."),t.name||e.push("The menu needs a name (Meta tab).");const i=countUnlabelled(t.items);if(i&&e.push(`${i} item${i===1?" has":"s have"} no label - every item needs one (Items tab).`),t.dock?.width!=null&&!(t.dock.width>=160&&t.dock.width<=480)&&e.push("The rail width must be from 160 to 480 px (Behaviour tab)."),t.binding){const n=badPagePatterns(t.binding.pages);n.length&&e.push(`Not valid page patterns: ${n.join(", ")} (Binding tab).`)}return e}export function countUnlabelled(t=[]){let e=0;for(const i of t||[])!isStructural(i)&&!(i.ref===!0&&i.url)&&!String(i.text||"").trim()&&e++,e+=countUnlabelled(i.items);return e}export const snapshot=t=>JSON.stringify(t);export function depthOfItems(t){if(!Array.isArray(t)||!t.length)return 0;let e=0;for(const i of t){const n=Array.isArray(i.items)&&i.items.length?depthOfItems(i.items):0;n>e&&(e=n)}return e+1}export function locationRows(t=[],e={},i={},n=[],r={}){const l=Object.fromEntries(n.map(o=>[o.slug,o.name||o.slug]));return t.map(o=>{const s=e[o.slot]||"",a=s&&r[s]||0,u=!!s&&o.maxDepth!=null&&a>o.maxDepth,c=o.slot==="overlay";return{slot:o.slot,label:o.label||o.slot,source:o.source||"",description:o.description||"",menu:s,menuName:s?l[s]||`${s} (missing)`:"",missing:!!s&&!l[s],tooDeep:u,depthText:u?`Nested ${a} deep - this slot shows ${o.maxDepth}`:"",empty:!s,emptyText:s?"":c?"Optional":"Nothing mapped",changed:(e[o.slot]||"")!==(i[o.slot]||"")}})}export function locationsPayload(t={},e=[]){const i=new Set(e.map(n=>n.slot));return Object.fromEntries(Object.entries(t).filter(([n,r])=>r&&(!e.length||i.has(n))))}export function locationsSnapshot(t={}){return JSON.stringify(Object.keys(t).filter(e=>t[e]).sort().map(e=>[e,t[e]]))}
1
+ const p=["separator","spacer","theme-switcher"];export const isStructural=t=>p.includes(t?.type);export function siblingsOf(t,e){const i=t.find(n=>n.id===e);return i?t.filter(n=>n.parentId===i.parentId):[]}export function moveRow(t,e,i){const n=siblingsOf(t,e),r=n.findIndex(l=>l.id===e),a=r+(i<0?-1:1);if(r<0||a<0||a>=n.length)return!1;n[r].touched=!0;const o=t.indexOf(n[r]),s=t.indexOf(n[a]);return[t[o],t[s]]=[t[s],t[o]],!0}export function indentRow(t,e){const i=siblingsOf(t,e),n=i.findIndex(r=>r.id===e);return n<=0||isStructural(i[n-1])?!1:(i[n].parentId=i[n-1].id,i[n].touched=!0,!0)}export function outdentRow(t,e){const i=t.find(r=>r.id===e);if(!i||i.parentId==null)return!1;const n=t.find(r=>r.id===i.parentId);return i.parentId=n?n.parentId:null,i.touched=!0,!0}export function newRow(t,e,i=null){return t==="separator"?{id:e,parentId:i,type:"separator"}:t==="theme-switcher"?{id:e,parentId:i,type:"theme-switcher"}:t==="spacer"?{id:e,parentId:i,type:"spacer",size:"md"}:{id:e,parentId:i,text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}}export function insertBelow(t,e,i,n){const r=t.findIndex(o=>o.id===e);if(r===-1)return null;const a=newRow(i,n,t[r].parentId);return t.splice(r+1,0,a),a}export function addChild(t,e,i){const n=t.find(a=>a.id===e);if(!n||isStructural(n))return null;const r=newRow("item",i,n.id);return t.push(r),n.touched=!0,r}export function duplicateRow(t,e,i){const n=t.find(l=>l.id===e);if(!n||n.tool)return null;const r=new Map,a=[],o=(l,c)=>{if(l.tool)return;const d={...m(l),id:i(),parentId:c};delete d.tool,delete d.locked,d.touched=!0,r.set(l.id,d.id),a.push(d);for(const f of t.filter(u=>u.parentId===l.id))o(f,d.id)};if(o(n,n.parentId),!a.length)return null;a[0].text&&(a[0].text=`${a[0].text} (copy)`);const s=t.indexOf(n);return t.splice(s+1,0,a[0]),t.push(...a.slice(1)),a[0]}function m(t){return JSON.parse(JSON.stringify(t))}export function bindingFrom({slot:t="",projects:e=[],pagesText:i=""}={}){return t?{slot:t,projects:[...e],pages:String(i).split(`
2
+ `).map(n=>n.trim()).filter(Boolean)}:null}export function badPagePatterns(t=[]){return t.filter(e=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(e))}const g=["fontFamily","fontSize","fontWeight","letterSpacing","iconSize"];export function menuFromForm(t={},e={},i=null,n=[],r={}){const a=Object.fromEntries(g.filter(f=>t[f]).map(f=>[f,t[f]])),o={};if(t.position==="floating"){t.floatAnchor&&(o.anchor=t.floatAnchor);for(const[f,u]of[["offsetX",t.floatOffsetX],["offsetY",t.floatOffsetY],["width",t.floatWidth],["radius",t.floatRadius],["opacity",t.floatOpacity]])u!==""&&u!=null&&Number.isFinite(Number(u))&&(o[f]=Number(u));t.floatShadow&&(o.shadow=t.floatShadow),t.floatAccent&&(o.accent=t.floatAccent),t.floatTitle&&(o.title=String(t.floatTitle).trim()),t.floatCollapsible&&(o.collapsible=!0),t.floatCollapsible&&t.floatCollapsed&&(o.collapsed=!0),t.floatMovable&&(o.movable=!0),t.floatResizable&&(o.resizable=!0)}const s={};t.position!=="floating"&&(t.orientation==="vertical"?(t.dockWidth!==""&&t.dockWidth!=null&&Number.isFinite(Number(t.dockWidth))&&(s.width=Number(t.dockWidth)),t.dockAutohide?s.autohide=!0:t.dockCollapsible&&(s.collapsible=!0,t.dockCollapsed&&(s.collapsed=!0))):t.dockHideOnScroll&&(s.hideOnScroll=!0));const l={};t.highlightHover&&(l.hover=t.highlightHover),t.highlightActive&&(l.active=t.highlightActive),t.highlightAccent&&(l.accent=t.highlightAccent);const c={};t.entranceAnimation&&(c.animation=t.entranceAnimation);for(const[f,u]of[["stagger",t.entranceStagger],["duration",t.entranceDuration]])u!==""&&u!=null&&Number.isFinite(Number(u))&&(c[f]=Number(u));const d=!!t.entranceEnabled||"stagger"in c||"duration"in c||c.animation&&c.animation!=="fade";return{slug:String(e.slug||"").trim(),name:String(e.name||"").trim(),description:String(e.description||"").trim(),...t.variant&&{variant:t.variant},...t.position&&{position:t.position},...t.orientation&&{orientation:t.orientation},...t.orientation==="vertical"&&t.side&&{side:t.side},...t.orientation!=="vertical"&&t.align&&{align:t.align},...Object.keys(o).length&&{float:o},...Object.keys(l).length&&{highlight:l},...d&&{entrance:{enabled:!!t.entranceEnabled,...c}},...Object.keys(s).length&&{dock:s},...t.appearOnHover&&{appearOnHover:!0},...t.class&&String(t.class).trim()&&{class:String(t.class).trim()},...Object.keys(a).length&&{style:a},binding:i,items:n,meta:{...r||{},project:e.project||null}}}export function menuProblems(t){const e=[];/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(t.slug||"")||e.push("The slug must be lowercase letters, numbers and hyphens, no hyphen at either end (Meta tab)."),t.name||e.push("The menu needs a name (Meta tab).");const i=countUnlabelled(t.items);i&&e.push(`${i} item${i===1?" has":"s have"} no label - every item needs one (Items tab).`),t.dock?.width!=null&&!(t.dock.width>=160&&t.dock.width<=480)&&e.push("The rail width must be from 160 to 480 px (Behaviour tab).");const n=t.entrance||{};if(n.stagger!=null&&!(n.stagger>=0&&n.stagger<=1e3)&&e.push("The entrance delay between items must be from 0 to 1000 ms (Behaviour tab - switch Staggered entrance on to edit it)."),n.duration!=null&&!(n.duration>=50&&n.duration<=3e3)&&e.push("Each item's entrance animation must be from 50 to 3000 ms (Behaviour tab - switch Staggered entrance on to edit it)."),t.binding){const r=badPagePatterns(t.binding.pages);r.length&&e.push(`Not valid page patterns: ${r.join(", ")} (Binding tab).`)}return e}export function countUnlabelled(t=[]){let e=0;for(const i of t||[])!isStructural(i)&&!(i.ref===!0&&i.url)&&!String(i.text||"").trim()&&e++,e+=countUnlabelled(i.items);return e}export const snapshot=t=>JSON.stringify(t);export function depthOfItems(t){if(!Array.isArray(t)||!t.length)return 0;let e=0;for(const i of t){const n=Array.isArray(i.items)&&i.items.length?depthOfItems(i.items):0;n>e&&(e=n)}return e+1}export function locationRows(t=[],e={},i={},n=[],r={}){const a=Object.fromEntries(n.map(o=>[o.slug,o.name||o.slug]));return t.map(o=>{const s=e[o.slot]||"",l=s&&r[s]||0,c=!!s&&o.maxDepth!=null&&l>o.maxDepth,d=o.slot==="overlay";return{slot:o.slot,label:o.label||o.slot,source:o.source||"",description:o.description||"",menu:s,menuName:s?a[s]||`${s} (missing)`:"",missing:!!s&&!a[s],tooDeep:c,depthText:c?`Nested ${l} deep - this slot shows ${o.maxDepth}`:"",empty:!s,emptyText:s?"":d?"Optional":"Nothing mapped",changed:(e[o.slot]||"")!==(i[o.slot]||"")}})}export function locationsPayload(t={},e=[]){const i=new Set(e.map(n=>n.slot));return Object.fromEntries(Object.entries(t).filter(([n,r])=>r&&(!e.length||i.has(n))))}export function locationsSnapshot(t={}){return JSON.stringify(Object.keys(t).filter(e=>t[e]).sort().map(e=>[e,t[e]]))}
@@ -1,4 +1,4 @@
1
- import{api as g,getUser as B}from"../api.js";import{isPathAllowed as pe}from"./admin-scope.js";import{colourToCss as Y,applyFloat as he,applyHighlight as ge,itemHighlightAttrs as be}from"/public/js/menu-decor.mjs?v=20261009-hover-darken";import{placeTools as ye,ensureLockedTools as ve,managePluginsItem as xe,stripItemByUrl as $e,insertFoldersBeforeSystem as we,pruneEmptyToolsFolder as ke,sidebarStateKey as J,canAny as U,filterByPermission as Se,MANAGE_PLUGINS_URL as Q}from"./sidebar-grouping.js";import{arrangeButtonMarkup as qe,canArrange as Ce,startArrange as Ae}from"./sidebar-arrange.js";import{collapseButtonMarkup as Fe,wireSidebarSize as Le,COLLAPSED_WIDTH as Ee}from"./sidebar-size.js";import{FREQUENT_MAX as ee,addFrequent as Te,frequentFolder as Be,moveFrequent as te,readFrequent as W,readFrequentHidden as He,removeFrequent as Me,saveFrequent as je,syncFrequent as Ne,writeFrequent as Pe,writeFrequentHidden as ne}from"./sidebar-frequent.js";import{hotkeyFor as se,hotkeyTitle as Re,setHotkeyTree as _e}from"./hotkeys-ui.js";import{hotkeyLabel as Ie}from"./hotkeys.js";function f(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const Oe=[{text:"Dashboard",url:"#/",icon:"home"},{text:"Site menus",url:"#/menus",icon:"menu",permission:"menus"}];async function Ue(e){if(!U(e,"projects"))return[];let n=[];try{n=await g.projects.listWithCounts()}catch{return[]}if(!Array.isArray(n))return[];const s=[{key:"pages",text:"Pages",icon:"file-text",path:"/pages"},{key:"collections",text:"Collections",icon:"database",path:"/collections"},{key:"forms",text:"Forms",icon:"layout",path:"/forms"},{key:"actions",text:"Actions",icon:"zap",path:"/actions"},{key:"menus",text:"Site menus",icon:"menu",path:"/menus"},{key:"blocks",text:"Blocks",icon:"box",path:"/blocks"},{key:"components",text:"Components",icon:"component",path:"/components"},{key:"views",text:"Views",icon:"eye",path:"/views"},{key:"roles",text:"Roles",icon:"shield",path:"/roles"},{key:"users",text:"Users",icon:"users",path:"/users"},{key:"apis",text:"APIs",icon:"code",path:"/apis"}];return n.map(t=>{const o="#/projects/"+encodeURIComponent(t.slug),a=t.counts||{},d=[{text:"Overview",url:o,icon:t.icon||"folder"}];for(const c of s){const r=Number(a[c.key])||0;r<=0||d.push({text:`${c.text} (${r})`,url:o+c.path,icon:c.icon})}d.push({text:"Settings",url:o+"/settings",icon:"settings"});const u=t.enabled===!1;return{text:t.name||t.slug,key:`project.${t.slug}`,icon:t.icon||"folder",items:d,...u&&{colour:"neutral",badge:{text:"off"}}}})}function ze(e,n){for(const s of e)if(!s.hidden&&(s.key==="projects"||!s.key&&(s.text||"").toLowerCase()==="projects")){s.items=Array.isArray(s.items)?s.items.slice():[],s.items.push(...n);return}}function oe(e,n){const s=ae.includes(n.tone)?n.tone:"info",t=n.label||String(n.count);n.details?P.set(e,n.details):P.delete(e);const i=!n.inventory&&F.some(o=>o.url===e&&!o.inventory)?" data-live":"";return`<span class="sidebar-badge sidebar-badge--${s}" data-count-for="${f(e)}"${i} data-badge-label="${f(t)}" aria-label="${f(t)}">${f(String(n.count))}</span>`}function ie(e){for(const n of e.querySelectorAll("details")){const s=n.querySelector(":scope > summary");if(!s)continue;let t=0,i=!1;const o=[];for(const r of n.querySelectorAll(":scope > .sidebar-children .sidebar-badge[data-live]")){const m=Number(r.textContent)||0;m&&(t+=m,i||(i=r.classList.contains("sidebar-badge--danger")),o.push({text:r.closest("a")?.querySelector(".sidebar-text")?.textContent.trim()??"",meta:r.dataset.badgeLabel,tone:r.classList.contains("sidebar-badge--danger")?"danger":void 0}))}const a=`folder:${n.dataset.stateKey||s.textContent.trim()}`;let d=s.querySelector(":scope > .sidebar-badge--sum");if(!t){d?.remove(),P.delete(a);continue}d||(d=document.createElement("span"),s.querySelector(".sidebar-text")?.after(d));const u=s.querySelector(".sidebar-text")?.textContent.trim()||"This folder",c=o.map(r=>`${r.text}: ${r.meta}`).join(" \xB7 ");d.className=`sidebar-badge sidebar-badge--sum sidebar-badge--${i?"danger":"info"}`,d.dataset.countFor=a,d.dataset.badgeLabel=c,d.setAttribute("aria-label",c),d.textContent=String(t),P.set(a,{title:u,items:o})}}const P=new Map;function We(e,n){if(!e.url||!n)return"";const s=n[e.url];return!s||!(s.count>0)&&!s.showZero?"":oe(e.url,s)}const ae=["info","attention","danger","live"],De={"#/pages":["page","pages"],"#/media":["file in the media library","files in the media library"],"#/menus":["menu","menus"],"#/context-menus":["context menu","context menus"],"#/theme":["element override in the theme","element overrides in the theme"],"#/collections":["collection","collections"],"#/forms":["form","forms"],"#/views":["view","views"],"#/actions":["action","actions"],"#/blocks":["block","blocks"],"#/components":["component","components"],"#/users":["user","users"],"#/plugins":["plugin installed","plugins installed"],"#/system/notifications":["unread notification","unread notifications"]};function D(e,{fallbackLabel:n="",tone:s="info"}={}){const t=Number(typeof e=="object"&&e!==null?e.count:e);if(!Number.isFinite(t)||t<0)return null;const i=typeof e?.label=="string"&&e.label||(n?`${t} - ${n}`:String(t)),o={count:Math.round(t),label:i,tone:ae.includes(e?.tone)?e.tone:s};return e?.details&&typeof e.details=="object"&&(o.details=e.details),e?.inventory===!0&&(o.inventory=!0),e?.showZero===!0&&(o.showZero=!0),o}function re(e,n,s=null,{inFrequent:t=!1}={}){if(e&&e.type==="separator")return'<hr class="sidebar-divider">';if(e&&e.type==="theme-switcher")return"";if(e&&e.type==="spacer"){const b=["xs","sm","md","lg","xl","flex"].includes(e.size)?e.size:"md";return`<div class="sidebar-spacer sidebar-spacer--${f(b)}" aria-hidden="true"></div>`}const i=String(e.text||"?").trim().charAt(0).toUpperCase()||"?",o=e.icon?`<span data-icon="${f(e.icon)}"></span>`:`<span class="sidebar-initial" aria-hidden="true">${f(i)}</span>`,a=f(e.text||""),d=e.url?f(e.url):"",u=Array.isArray(e.items)&&e.items.length>0,c=e.colour?Y(e.colour):"",r=be(e),m=[r.hover&&` data-menu-item-hover="${f(r.hover)}"`,r.active&&` data-menu-item-active="${f(r.active)}"`].filter(Boolean).join(""),y=[c&&`color:${f(c)}`,r.accent&&`--dm-menu-highlight:${f(r.accent)}`].filter(Boolean).join(";"),v=y?` style="${y}"`:"",k=e.url?Re(e.url,e.text||"",{inFrequent:t}):"",w=k?` title="${f(k)}"`:"";let L="";if(e.badge&&e.badge.text!=null&&e.badge.text!==""){const b=e.badge.variant?Y(e.badge.variant):"";L=`<span class="dm-menu-badge"${b?` style="background:${f(b)};color:var(--dm-text-inverse,#fff)"`:""}>${f(String(e.badge.text))}</span>`}if(e.frequent&&e.empty){const b=J(e,s),A=S.get(b)!==!1;return`<details data-state-key="${f(b)}"${A?" open":""} data-frequent data-frequent-empty>
1
+ import{api as g,getUser as B}from"../api.js";import{isPathAllowed as pe}from"./admin-scope.js";import{colourToCss as Y,applyFloat as he,applyHighlight as ge,itemHighlightAttrs as be}from"/public/js/menu-decor.mjs?v=20261014-menu-entrance";import{placeTools as ye,ensureLockedTools as ve,managePluginsItem as xe,stripItemByUrl as $e,insertFoldersBeforeSystem as we,pruneEmptyToolsFolder as ke,sidebarStateKey as J,canAny as U,filterByPermission as Se,MANAGE_PLUGINS_URL as Q}from"./sidebar-grouping.js";import{arrangeButtonMarkup as qe,canArrange as Ce,startArrange as Ae}from"./sidebar-arrange.js";import{collapseButtonMarkup as Fe,wireSidebarSize as Le,COLLAPSED_WIDTH as Ee}from"./sidebar-size.js";import{FREQUENT_MAX as ee,addFrequent as Te,frequentFolder as Be,moveFrequent as te,readFrequent as W,readFrequentHidden as He,removeFrequent as Me,saveFrequent as je,syncFrequent as Ne,writeFrequent as Pe,writeFrequentHidden as ne}from"./sidebar-frequent.js";import{hotkeyFor as se,hotkeyTitle as Re,setHotkeyTree as _e}from"./hotkeys-ui.js";import{hotkeyLabel as Ie}from"./hotkeys.js";function f(e){return String(e??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const Oe=[{text:"Dashboard",url:"#/",icon:"home"},{text:"Site menus",url:"#/menus",icon:"menu",permission:"menus"}];async function Ue(e){if(!U(e,"projects"))return[];let n=[];try{n=await g.projects.listWithCounts()}catch{return[]}if(!Array.isArray(n))return[];const s=[{key:"pages",text:"Pages",icon:"file-text",path:"/pages"},{key:"collections",text:"Collections",icon:"database",path:"/collections"},{key:"forms",text:"Forms",icon:"layout",path:"/forms"},{key:"actions",text:"Actions",icon:"zap",path:"/actions"},{key:"menus",text:"Site menus",icon:"menu",path:"/menus"},{key:"blocks",text:"Blocks",icon:"box",path:"/blocks"},{key:"components",text:"Components",icon:"component",path:"/components"},{key:"views",text:"Views",icon:"eye",path:"/views"},{key:"roles",text:"Roles",icon:"shield",path:"/roles"},{key:"users",text:"Users",icon:"users",path:"/users"},{key:"apis",text:"APIs",icon:"code",path:"/apis"}];return n.map(t=>{const o="#/projects/"+encodeURIComponent(t.slug),a=t.counts||{},d=[{text:"Overview",url:o,icon:t.icon||"folder"}];for(const c of s){const r=Number(a[c.key])||0;r<=0||d.push({text:`${c.text} (${r})`,url:o+c.path,icon:c.icon})}d.push({text:"Settings",url:o+"/settings",icon:"settings"});const u=t.enabled===!1;return{text:t.name||t.slug,key:`project.${t.slug}`,icon:t.icon||"folder",items:d,...u&&{colour:"neutral",badge:{text:"off"}}}})}function ze(e,n){for(const s of e)if(!s.hidden&&(s.key==="projects"||!s.key&&(s.text||"").toLowerCase()==="projects")){s.items=Array.isArray(s.items)?s.items.slice():[],s.items.push(...n);return}}function oe(e,n){const s=ae.includes(n.tone)?n.tone:"info",t=n.label||String(n.count);n.details?P.set(e,n.details):P.delete(e);const i=!n.inventory&&F.some(o=>o.url===e&&!o.inventory)?" data-live":"";return`<span class="sidebar-badge sidebar-badge--${s}" data-count-for="${f(e)}"${i} data-badge-label="${f(t)}" aria-label="${f(t)}">${f(String(n.count))}</span>`}function ie(e){for(const n of e.querySelectorAll("details")){const s=n.querySelector(":scope > summary");if(!s)continue;let t=0,i=!1;const o=[];for(const r of n.querySelectorAll(":scope > .sidebar-children .sidebar-badge[data-live]")){const m=Number(r.textContent)||0;m&&(t+=m,i||(i=r.classList.contains("sidebar-badge--danger")),o.push({text:r.closest("a")?.querySelector(".sidebar-text")?.textContent.trim()??"",meta:r.dataset.badgeLabel,tone:r.classList.contains("sidebar-badge--danger")?"danger":void 0}))}const a=`folder:${n.dataset.stateKey||s.textContent.trim()}`;let d=s.querySelector(":scope > .sidebar-badge--sum");if(!t){d?.remove(),P.delete(a);continue}d||(d=document.createElement("span"),s.querySelector(".sidebar-text")?.after(d));const u=s.querySelector(".sidebar-text")?.textContent.trim()||"This folder",c=o.map(r=>`${r.text}: ${r.meta}`).join(" \xB7 ");d.className=`sidebar-badge sidebar-badge--sum sidebar-badge--${i?"danger":"info"}`,d.dataset.countFor=a,d.dataset.badgeLabel=c,d.setAttribute("aria-label",c),d.textContent=String(t),P.set(a,{title:u,items:o})}}const P=new Map;function We(e,n){if(!e.url||!n)return"";const s=n[e.url];return!s||!(s.count>0)&&!s.showZero?"":oe(e.url,s)}const ae=["info","attention","danger","live"],De={"#/pages":["page","pages"],"#/media":["file in the media library","files in the media library"],"#/menus":["menu","menus"],"#/context-menus":["context menu","context menus"],"#/theme":["element override in the theme","element overrides in the theme"],"#/collections":["collection","collections"],"#/forms":["form","forms"],"#/views":["view","views"],"#/actions":["action","actions"],"#/blocks":["block","blocks"],"#/components":["component","components"],"#/users":["user","users"],"#/plugins":["plugin installed","plugins installed"],"#/system/notifications":["unread notification","unread notifications"]};function D(e,{fallbackLabel:n="",tone:s="info"}={}){const t=Number(typeof e=="object"&&e!==null?e.count:e);if(!Number.isFinite(t)||t<0)return null;const i=typeof e?.label=="string"&&e.label||(n?`${t} - ${n}`:String(t)),o={count:Math.round(t),label:i,tone:ae.includes(e?.tone)?e.tone:s};return e?.details&&typeof e.details=="object"&&(o.details=e.details),e?.inventory===!0&&(o.inventory=!0),e?.showZero===!0&&(o.showZero=!0),o}function re(e,n,s=null,{inFrequent:t=!1}={}){if(e&&e.type==="separator")return'<hr class="sidebar-divider">';if(e&&e.type==="theme-switcher")return"";if(e&&e.type==="spacer"){const b=["xs","sm","md","lg","xl","flex"].includes(e.size)?e.size:"md";return`<div class="sidebar-spacer sidebar-spacer--${f(b)}" aria-hidden="true"></div>`}const i=String(e.text||"?").trim().charAt(0).toUpperCase()||"?",o=e.icon?`<span data-icon="${f(e.icon)}"></span>`:`<span class="sidebar-initial" aria-hidden="true">${f(i)}</span>`,a=f(e.text||""),d=e.url?f(e.url):"",u=Array.isArray(e.items)&&e.items.length>0,c=e.colour?Y(e.colour):"",r=be(e),m=[r.hover&&` data-menu-item-hover="${f(r.hover)}"`,r.active&&` data-menu-item-active="${f(r.active)}"`].filter(Boolean).join(""),y=[c&&`color:${f(c)}`,r.accent&&`--dm-menu-highlight:${f(r.accent)}`].filter(Boolean).join(";"),v=y?` style="${y}"`:"",k=e.url?Re(e.url,e.text||"",{inFrequent:t}):"",w=k?` title="${f(k)}"`:"";let L="";if(e.badge&&e.badge.text!=null&&e.badge.text!==""){const b=e.badge.variant?Y(e.badge.variant):"";L=`<span class="dm-menu-badge"${b?` style="background:${f(b)};color:var(--dm-text-inverse,#fff)"`:""}>${f(String(e.badge.text))}</span>`}if(e.frequent&&e.empty){const b=J(e,s),A=S.get(b)!==!1;return`<details data-state-key="${f(b)}"${A?" open":""} data-frequent data-frequent-empty>
2
2
  <summary${v}>${o} <span class="sidebar-text">${a}</span></summary>
3
3
  <div class="sidebar-children"><p class="sidebar-frequent-empty">Right-click any Tool and choose <strong>Add to Frequent</strong> to keep it here.</p></div>
4
4
  </details>`}if(u){const b=J(e,s),A=S.get(b)!==!1,R=e.items.map(T=>re(T,n,b,{inFrequent:!!e.frequent})).join(""),j=e.frequent?' data-frequent title="Your Frequent Tools - right-click any Tool to add or remove it"':"";return`<details data-state-key="${f(b)}"${A?" open":""}${j}>
@@ -230,6 +230,28 @@
230
230
  </div>
231
231
  <small class="form-hint">Used by the colour, underline, overline, tint, glow and pill effects. The underline and overline effects fall back to the item's own text colour when this is unset.</small>
232
232
  </div>
233
+ <div class="form-group">
234
+ <label>Staggered entrance
235
+ <span data-help-title="Staggered entrance" data-help="The items arrive one after another when the menu is drawn, like a row of cards revealing. A dropdown or footer column staggers in on its own when it opens. Visitors who have asked for less motion (their device setting, or the site's motion switch) see the items straight away."></span></label>
236
+ <label style="display:flex;align-items:center;gap:.5rem;font-weight:400;cursor:pointer">
237
+ <input type="checkbox" id="me-entrance-enabled" name="entranceEnabled" style="width:auto;margin:0">
238
+ Bring the items in one after another
239
+ </label>
240
+ <small class="form-hint">Applies wherever this menu is drawn on the site - navbar, footer, <code>[menu]</code> and floating panels.</small>
241
+ </div>
242
+ <div class="form-group dm-entrance-field" style="display:none">
243
+ <label for="me-entrance-animation">Entrance animation</label>
244
+ <!-- Filled from ENTRANCE_ANIMATIONS in menu-decor.mjs on mount. -->
245
+ <select id="me-entrance-animation" name="entranceAnimation" class="form-input"></select>
246
+ </div>
247
+ <div class="form-group dm-entrance-field" style="display:none">
248
+ <label for="me-entrance-stagger">Delay between items (ms)</label>
249
+ <input type="number" id="me-entrance-stagger" name="entranceStagger" class="form-input" placeholder="60" min="0" max="1000" step="10">
250
+ </div>
251
+ <div class="form-group dm-entrance-field" style="display:none">
252
+ <label for="me-entrance-duration">Each item's animation (ms)</label>
253
+ <input type="number" id="me-entrance-duration" name="entranceDuration" class="form-input" placeholder="400" min="50" max="3000" step="50">
254
+ </div>
233
255
  <div class="form-group">
234
256
  <label for="me-class">CSS classes
235
257
  <span data-help-title="CSS classes" data-help="Your own class names, separated by spaces, added to the menu's outer element - the navbar, the footer column or the [menu] nav. Style them in Custom CSS. Each item can carry classes of its own too, in its editor."></span></label>
@@ -1,4 +1,4 @@
1
- import{api as O,apiRequest as Qe}from"../api.js";import{HIGHLIGHT_HOVER as Xe,HIGHLIGHT_ACTIVE as Ze,HIGHLIGHT_HOVER_LABELS as et,HIGHLIGHT_ACTIVE_LABELS as tt}from"/public/js/menu-decor.mjs?v=20261009-hover-darken";import{addBannerAction as at}from"../lib/plugin-chrome.js";import{helpPopovers as Me}from"../lib/help-popover.js";import{onceClosed as Te,openMenuAt as He,sidebarCount as lt}from"../lib/tool-kit.js";import{FILTERS as st,WIDTHS as ot,WIDTH_HINTS as nt,WIDTH_LABELS as it,WIDTH_SHARE as $e,arrangeLayouts as ct,checkLayout as rt,checkOptions as dt,formFromPreset as ut}from"../lib/layouts-arrange.js";const ae=/^\/layouts\/?(\?.*)?$/,Le="#/layouts",le="layouts.draft",z="layouts.options.draft",se="layouts.filter",Oe=(l="")=>`
1
+ import{api as O,apiRequest as Qe}from"../api.js";import{HIGHLIGHT_HOVER as Xe,HIGHLIGHT_ACTIVE as Ze,HIGHLIGHT_HOVER_LABELS as et,HIGHLIGHT_ACTIVE_LABELS as tt}from"/public/js/menu-decor.mjs?v=20261014-menu-entrance";import{addBannerAction as at}from"../lib/plugin-chrome.js";import{helpPopovers as Me}from"../lib/help-popover.js";import{onceClosed as Te,openMenuAt as He,sidebarCount as lt}from"../lib/tool-kit.js";import{FILTERS as st,WIDTHS as ot,WIDTH_HINTS as nt,WIDTH_LABELS as it,WIDTH_SHARE as $e,arrangeLayouts as ct,checkLayout as rt,checkOptions as dt,formFromPreset as ut}from"../lib/layouts-arrange.js";const ae=/^\/layouts\/?(\?.*)?$/,Le="#/layouts",le="layouts.draft",z="layouts.options.draft",se="layouts.filter",Oe=(l="")=>`
2
2
  <span class="lyx-shape" aria-hidden="true" data-bind-style-background-color="bg${l}">
3
3
  <span class="lyx-shape-nav" data-bind-hidden="!hasNav${l}"></span>
4
4
  <span class="lyx-shape-body"><span class="lyx-shape-col" data-bind-style-width="share${l}"></span><span class="lyx-shape-side" data-bind-hidden="!hasSide${l}" data-bind-class="sideRight${l} && 'is-right'"></span></span>
@@ -1,30 +1,30 @@
1
- import{api as j}from"../api.js";import{colourToCss as kt,HIGHLIGHT_HOVER as st,HIGHLIGHT_ACTIVE as lt,HIGHLIGHT_HOVER_LABELS as it,HIGHLIGHT_ACTIVE_LABELS as ct,cssClassProblems as rt,normaliseCssClasses as St}from"/public/js/menu-decor.mjs?v=20261009-hover-darken";import{openIconPicker as $t}from"../lib/card-builder.js";import{sortableMenuRows as xt}from"../lib/menu-drag.js";import{placeTools as At,ensureLockedTools as Et,isLockedUrl as Ct,groupKeyFor as Lt,slugify as _t,GROUP_ICON as Ht,TOOLS_FOLDER_KEY as It}from"../lib/sidebar-grouping.js";import{flatten as dt,nest as Tt,uid as _e}from"../lib/menu-rows.js";import{addBannerAction as qe}from"../lib/plugin-chrome.js";import{helpPopovers as Rt}from"../lib/help-popover.js";import{onceClosed as jt,openMenuAt as Ue,sidebarCount as Dt}from"../lib/tool-kit.js";import{addChild as Ot,bindingFrom as Nt,duplicateRow as Pt,indentRow as Ft,insertBelow as Bt,isStructural as ae,menuFromForm as zt,menuProblems as Mt,moveRow as ut,outdentRow as Wt,siblingsOf as Kt,snapshot as He}from"../lib/menu-editor-arrange.js";import{fmtDateTime as qt}from"../lib/dates.js";const Ut=760,Gt="admin-sidebar",Vt=/^\/menus\/(new|edit\/[^?#]+)(\?.*)?$/;function y(o){return String(o||"").replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;")}const Ie=o=>String(o??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");function Yt(o,r){let l=0,i=r.find(s=>s.id===o);for(;i&&i.parentId;)l++,i=r.find(s=>s.id===i.parentId);return l}function mt(o){const r=new Set,l=new Set,i=s=>{for(const g of o.filter(k=>k.parentId===s))!g.type&&Ct(g.url)&&!l.has(g.url)&&(l.add(g.url),r.add(g.id)),i(g.id)};return i(null),r}const Te='<button type="button" class="btn btn-sm btn-ghost mex-kebab" aria-label="Actions" title="Actions (right-click, or Shift+F10)">\u22EE</button>';function Xt(o,r,l=!1){const i=l?mt(r):new Set,s=[];function g(k){for(const p of r.filter(F=>F.parentId===k)){const A=`style="margin-left:${Yt(p.id,r)*28}px"`;if(p.type==="separator"){s.push(`
2
- <div class="menu-tree-row menu-tree-row--separator" data-id="${p.id}" tabindex="0" ${A}>
1
+ import{api as N}from"../api.js";import{colourToCss as St,HIGHLIGHT_HOVER as lt,HIGHLIGHT_ACTIVE as it,HIGHLIGHT_HOVER_LABELS as ct,HIGHLIGHT_ACTIVE_LABELS as rt,cssClassProblems as dt,normaliseCssClasses as At,ENTRANCE_ANIMATIONS as qe,ENTRANCE_ANIMATION_LABELS as Et}from"/public/js/menu-decor.mjs?v=20261014-menu-entrance";import{openIconPicker as $t}from"../lib/card-builder.js";import{sortableMenuRows as xt}from"../lib/menu-drag.js";import{placeTools as Ct,ensureLockedTools as Lt,isLockedUrl as _t,groupKeyFor as It,slugify as Ht,GROUP_ICON as Tt,TOOLS_FOLDER_KEY as Rt}from"../lib/sidebar-grouping.js";import{flatten as ut,nest as Nt,uid as _e}from"../lib/menu-rows.js";import{addBannerAction as Ue}from"../lib/plugin-chrome.js";import{helpPopovers as Ot}from"../lib/help-popover.js";import{onceClosed as Dt,openMenuAt as Ge,sidebarCount as jt}from"../lib/tool-kit.js";import{addChild as Pt,bindingFrom as Bt,duplicateRow as Ft,indentRow as Mt,insertBelow as zt,isStructural as ae,menuFromForm as Wt,menuProblems as Kt,moveRow as mt,outdentRow as qt,siblingsOf as Ut,snapshot as Ie}from"../lib/menu-editor-arrange.js";import{fmtDateTime as Gt}from"../lib/dates.js";const Vt=760,Yt="admin-sidebar",Xt=/^\/menus\/(new|edit\/[^?#]+)(\?.*)?$/;function y(o){return String(o||"").replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;")}const He=o=>String(o??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");function Jt(o,r){let i=0,c=r.find(s=>s.id===o);for(;c&&c.parentId;)i++,c=r.find(s=>s.id===c.parentId);return i}function pt(o){const r=new Set,i=new Set,c=s=>{for(const v of o.filter(k=>k.parentId===s))!v.type&&_t(v.url)&&!i.has(v.url)&&(i.add(v.url),r.add(v.id)),c(v.id)};return c(null),r}const Te='<button type="button" class="btn btn-sm btn-ghost mex-kebab" aria-label="Actions" title="Actions (right-click, or Shift+F10)">\u22EE</button>';function Qt(o,r,i=!1){const c=i?pt(r):new Set,s=[];function v(k){for(const p of r.filter(B=>B.parentId===k)){const x=`style="margin-left:${Jt(p.id,r)*28}px"`;if(p.type==="separator"){s.push(`
2
+ <div class="menu-tree-row menu-tree-row--separator" data-id="${p.id}" tabindex="0" ${x}>
3
3
  <span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
4
4
  <span class="me-sep-line"><span class="me-sep-label">Separator</span></span>
5
5
  ${Te}
6
- </div>`);continue}if(p.type==="spacer"){const oe=["xs","sm","md","lg","xl","flex"].map(B=>`<option value="${B}"${(p.size||"md")===B?" selected":""}>${B==="flex"?"flexible":B}</option>`).join("");s.push(`
7
- <div class="menu-tree-row menu-tree-row--spacer" data-id="${p.id}" tabindex="0" ${A}>
6
+ </div>`);continue}if(p.type==="spacer"){const ne=["xs","sm","md","lg","xl","flex"].map(F=>`<option value="${F}"${(p.size||"md")===F?" selected":""}>${F==="flex"?"flexible":F}</option>`).join("");s.push(`
7
+ <div class="menu-tree-row menu-tree-row--spacer" data-id="${p.id}" tabindex="0" ${x}>
8
8
  <span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
9
9
  <span class="me-spacer-line">
10
10
  <span class="me-spacer-label">Spacer</span>
11
- <select class="form-input me-spacer-size" title="Spacer size - flexible fills the leftover room" aria-label="Spacer size">${oe}</select>
11
+ <select class="form-input me-spacer-size" title="Spacer size - flexible fills the leftover room" aria-label="Spacer size">${ne}</select>
12
12
  </span>
13
13
  ${Te}
14
14
  </div>`);continue}if(p.type==="theme-switcher"){s.push(`
15
- <div class="menu-tree-row menu-tree-row--switcher" data-id="${p.id}" tabindex="0" ${A}>
15
+ <div class="menu-tree-row menu-tree-row--switcher" data-id="${p.id}" tabindex="0" ${x}>
16
16
  <span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
17
17
  <span class="me-sep-line"><span class="me-sep-label"><span data-icon="palette"></span> Theme switcher - the themes chosen under Theme &gt; Theme switcher</span></span>
18
18
  ${Te}
19
- </div>`);continue}const J=p.badge&&(p.badge.text||p.badge.countFrom)?`<span class="dm-menu-badge">${y(String(p.badge.text||"#"))}</span>`:"",C=p.tool,v=C&&(C.persisted||p.touched),K=C?C.orphan?' <span class="badge badge-secondary me-tool-badge" title="A placeholder for a Tool that is not enabled - it returns here when it is">Not enabled</span>':` <span class="badge badge-secondary me-tool-badge" title="${v?"A Tool, placed here by this menu":"A Tool in its default place - move or edit it to place it here"}">${y(C.source||"Tool")}${v?"":" \xB7 default"}</span>`:"",se=i.has(p.id),te=kt(p.colour),q=te?` style="color:${y(te)}"`:"",le=se?'<button type="button" class="btn btn-sm btn-ghost" disabled title="Always shown - it can be moved, not hidden" aria-label="Always shown"><span data-icon="lock"></span></button>':`<button type="button" class="btn btn-sm btn-ghost me-hidden ${p.hidden?"active":""}" title="${p.hidden?"Hidden - click to show":"Hide"}" aria-label="${p.hidden?"Show":"Hide"}" aria-pressed="${p.hidden?"true":"false"}"><span data-icon="${p.hidden?"eye-off":"eye"}"></span></button>`;s.push(`
20
- <div class="menu-tree-row menu-tree-row--slim${p.hidden?" menu-tree-row--hidden":""}${C?" menu-tree-row--tool":""}${C&&!v?" menu-tree-row--default":""}" data-id="${p.id}" tabindex="0" ${A}>
19
+ </div>`);continue}const J=p.badge&&(p.badge.text||p.badge.countFrom)?`<span class="dm-menu-badge">${y(String(p.badge.text||"#"))}</span>`:"",C=p.tool,g=C&&(C.persisted||p.touched),q=C?C.orphan?' <span class="badge badge-secondary me-tool-badge" title="A placeholder for a Tool that is not enabled - it returns here when it is">Not enabled</span>':` <span class="badge badge-secondary me-tool-badge" title="${g?"A Tool, placed here by this menu":"A Tool in its default place - move or edit it to place it here"}">${y(C.source||"Tool")}${g?"":" \xB7 default"}</span>`:"",se=c.has(p.id),te=St(p.colour),U=te?` style="color:${y(te)}"`:"",le=se?'<button type="button" class="btn btn-sm btn-ghost" disabled title="Always shown - it can be moved, not hidden" aria-label="Always shown"><span data-icon="lock"></span></button>':`<button type="button" class="btn btn-sm btn-ghost me-hidden ${p.hidden?"active":""}" title="${p.hidden?"Hidden - click to show":"Hide"}" aria-label="${p.hidden?"Show":"Hide"}" aria-pressed="${p.hidden?"true":"false"}"><span data-icon="${p.hidden?"eye-off":"eye"}"></span></button>`;s.push(`
20
+ <div class="menu-tree-row menu-tree-row--slim${p.hidden?" menu-tree-row--hidden":""}${C?" menu-tree-row--tool":""}${C&&!g?" menu-tree-row--default":""}" data-id="${p.id}" tabindex="0" ${x}>
21
21
  <span class="menu-tree-grip" data-icon="grip-vertical" data-icon-size="18" title="Drag to move"></span>
22
- <span class="me-row-label${!p.text&&!C?" mex-untitled":""}"${q}>${y(p.text||C?.label||"(no label - click to add one)")}${J}${K}</span>
22
+ <span class="me-row-label${!p.text&&!C?" mex-untitled":""}"${U}>${y(p.text||C?.label||"(no label - click to add one)")}${J}${q}</span>
23
23
  <span class="me-row-url">${y(p.url||"")}</span>
24
24
  ${le}
25
25
  <button type="button" class="btn btn-sm btn-ghost me-edit" title="Edit" aria-label="Edit"><span data-icon="edit"></span></button>
26
26
  ${Te}
27
- </div>`),g(p.id)}}g(null),o.innerHTML=s.join("")||'<p class="mex-note">No items yet - Add item, or right-click an item for more.</p>',I.scan(o)}function w(o,r={},...l){const i=document.createElement(o);Object.assign(i,r);for(const s of l)s!=null&&i.append(s);return i}function T(o,r,l){const i=w("label",{className:"form-field"},w("span",{className:"form-label",textContent:o}),r);return l&&i.append(w("small",{className:"form-hint",textContent:l,style:"display:block;font-size:.78em;opacity:.7;margin-top:.25rem;line-height:1.35"})),i}function Jt(o,r){const l=[["","- Everyone -"],["public","Public - anyone, incl. logged-out"],...(r||[]).map(s=>[s.name,`${s.label||s.name} and above`]),...(r||[]).filter(s=>s.level!==0).map(s=>[`=${s.name}`,`${s.label||s.name} only`]),["private","Private - super-admin only"]];o&&!l.some(([s])=>s===o)&&l.push([o,`${o} (custom)`]);const i=ee(l,o||"");return i.name="visibility",i}function ee(o,r){const l=w("select",{className:"form-select"});return o.forEach(([i,s])=>l.add(new Option(s,i))),l.value=r??"",l}function Re(o,r){const l=typeof r=="string"&&r.startsWith("#"),i=ee([["","- none -"],["primary","primary"],["success","success"],["danger","danger"],["warning","warning"],["info","info"],["neutral","neutral"],["__custom__","Custom\u2026"]],l?"__custom__":r||""),s=w("input",{type:"color",className:"form-input me-colour-hex",value:l?r:"#000000"});s.style.display=l?"":"none",i.addEventListener("change",()=>{s.style.display=i.value==="__custom__"?"":"none"});const g=T(o,i);return g.append(s),g._read=()=>i.value==="__custom__"?s.value:i.value,g}function Qt(o,r){const l=w("input",{className:"form-input me-icon",name:"icon",value:r||""}),i=w("span",{className:"me-icon-preview"});r&&i.setAttribute("data-icon",r);const s=w("button",{type:"button",className:"btn btn-sm btn-ghost",textContent:"Browse\u2026"}),g=k=>{k?i.setAttribute("data-icon",k):i.removeAttribute("data-icon"),Domma.icons.scan(i.parentNode||i)};return s.addEventListener("click",()=>$t(k=>{l.value=k,g(k)})),l.addEventListener("input",()=>g(l.value.trim())),T(o,w("div",{className:"me-icon-field"},l,s,i))}function je(...o){return w("div",{className:"me-field-grid"},...o)}async function Zt(o,r,l,i,s){const g=o.text||o.tool?.label||"",k=u=>w("h4",{className:"me-form-section",textContent:u}),p=T("Label",w("input",{className:"form-input",name:"text",value:o.text||""}),"The text shown for this item."),F=w("input",{className:"form-input",name:"url",value:o.url||""}),A=T("URL",F,o.tool||o.locked?"A Tool's address is its identity, so it cannot be changed here.":"Where it links. Must start with /, #, https://, or mailto: . Leave blank for a parent that only groups sub-items.");(o.tool||o.locked)&&(F.readOnly=!0);const J=Qt("Icon",o.icon||""),C=Jt(o.visibility||"",i),v=T("Visibility",C,o.locked?"Always in the sidebar for everyone who may use it, so it cannot be restricted here.":'Who can see this item. "Role and above" shows it to that role and anyone more senior; "Role only" shows it to holders of that role alone (and the super-admin). Blank = everyone.');o.locked&&(C.disabled=!0);const K=ee([["","- no permission gate -"],...(r||[]).map(u=>[u.key,u.label||u.key])],o.permission||"");K.name="permission";const se=T("Permission",K,o.tool||o.locked?"A Tool is guarded by its own permission, which always applies.":"Hide unless the viewer holds this specific permission. Independent of Visibility - both must pass.");(o.tool||o.locked)&&(K.disabled=!0);const te=T("Badge text",w("input",{className:"form-input",name:"badgeText",value:o.badge?.text||""})),q=ee([["","- none -"],...(l||[]).map(u=>[u.slug,u.title||u.slug])],o.badge?.countFrom||"");q.name="badgeCount";const le=T("Badge count from",q,"Show a live count of this collection\u2019s entries as the badge."),oe=Re("Badge colour",o.badge?.variant||""),B=ee([["link","Link"],["pill","Pill"]],o.pill?"pill":"link");B.name="renderAs";const De=T("Render as",B,"Pill draws the item as a rounded chip. Pill styling applies to top-level navbar items."),D=T("Pill style",ee([["filled","Filled"],["outline","Outline"]],o.pill?.style||"filled"));D.querySelector("select").name="pillStyle";const pe=Re("Pill colour",o.pill?.variant||""),ie=w("div",{className:"me-pill-wrap"},je(D,pe));ie.style.display=o.pill?"":"none",B.addEventListener("change",()=>{ie.style.display=B.value==="pill"?"":"none"});const h=Re("Text colour",o.colour||""),O=ee([["","- use the menu default -"],...st.map(u=>[u,it[u]||u])],o.highlight?.hover||"");O.name="hlHover";const ce=T("Hover effect",O,"Overrides the menu-wide hover effect for this item only."),he=ee([["","- use the menu default -"],...lt.map(u=>[u,ct[u]||u])],o.highlight?.active||"");he.name="hlActive";const Se=T("When selected",he,"How this item is marked when it points at the page being viewed."),z=Re("Highlight colour",o.highlight?.accent||""),L=w("input",{className:"form-input",name:"class",value:o.class||"",placeholder:"nav-cta push-right",autocomplete:"off",spellcheck:!1}),re=T("CSS classes",L,"Your own class names, separated by spaces, added to this item's <li> - target the link with .your-class > a. Style them in Custom CSS."),_=w("small",{className:"text-danger",style:"display:none;margin-top:.25rem"});re.append(_);const U=w("button",{className:"btn btn-primary",textContent:"Apply",title:"Apply to the item (Ctrl+Enter) - Save the menu to keep it"}),N=w("div",{className:"me-item-form"},k("Link"),p,A,J,k("Access"),je(v,se),k("Badge"),je(te,oe),le,k("Appearance"),De,ie,h,k("Highlighting"),je(ce,Se),z,k("Styling"),re,U),x=E.slideover({title:g?`Edit ${Ie(g)}`:"Edit menu item",size:"lg",position:"right"});x.element.appendChild(N);const fe=()=>JSON.stringify([...N.querySelectorAll("input, select, textarea")].map(u=>u.type==="checkbox"?u.checked:u.value)),$e=fe();let de=!1,ue=!1;jt(x);const G=x.close.bind(x);x.close=async u=>{if(!de&&u!==!0&&fe()!==$e){if(ue)return;ue=!0;const Q=await E.confirm("Discard the changes to this item?");if(ue=!1,!Q)return}return de=!0,G()},N.addEventListener("keydown",u=>{(u.ctrlKey||u.metaKey)&&u.key==="Enter"&&(u.preventDefault(),U.click())}),x.open();const ne=x.element.closest(".dm-slideover")||x.element.querySelector(".dm-slideover")||x.element;ne.style.setProperty("width",Ut+"px","important"),ne.style.setProperty("max-width","95vw","important"),Domma.icons.scan(N);const $=u=>N.querySelector(`[name="${u}"]`)?.value||"";U.addEventListener("click",()=>{const u=rt($("class"));if(u.length){_.textContent=u.join("; "),_.style.display="block",L.focus();return}o.class=St($("class")),o.text=$("text"),o.icon=$("icon"),o.locked||(o.visibility=$("visibility")),!o.tool&&!o.locked?(o.url=$("url"),o.permission=$("permission")):o.touched=!0;const Q=$("badgeText"),me=$("badgeCount"),ve=oe._read();if(o.badge=Q||me?{...Q&&{text:Q},...me&&{countFrom:me},...ve&&{variant:ve}}:null,$("renderAs")==="pill"){const we=pe._read();o.pill={style:$("pillStyle")||"filled",...we&&{variant:we}}}else o.pill=null;o.colour=h._read();const ge=$("hlHover"),be=$("hlActive"),ye=z._read();o.highlight=ge||be||ye?{...ge&&{hover:ge},...be&&{active:be},...ye&&{accent:ye}}:null,de=!0,x.close(!0),s()})}let W=null,pt=!1;function eo(){pt||!window.R?.use||(pt=!0,R.use((o,r,l)=>{const i=r?.path||"";return!(Vt.test(i)&&(o?.path||"")!==i)||!W?.dirty()?l():E.confirm(`You have unsaved changes to the menu "${Ie(W.name())}". Leave anyway? They are kept as a draft for your next visit.`).then(g=>{g?l():history.replaceState(null,"",`#${i}`)})}),M.subscribe("router:afterChange",({to:o}={})=>{if(W&&(o?.path||"")!==W.path){const r=W;W=null,r.dispose()}}))}function ht(o,r){const l=o.querySelector(".dm-plugin-banner-name"),i=l?.querySelector(".dm-plugin-banner-sep");if(!(!l||!i)){for(;i.nextSibling;)i.nextSibling.remove();l.appendChild(document.createTextNode(r))}}export const menuEditorView={templateUrl:"/admin/js/templates/menu-editor.html",async onMount(o){if(eo(),W){const e=W;W=null,e.dispose()}const r=[],l=e=>(r.push(e),e);let i=!1;const s=o.get(0).querySelector(".mex")||o.get(0),g=()=>!i&&s.isConnected,k=location.hash.replace(/^#/,""),p=location.hash.match(/^#\/menus\/edit\/([^?#]+)/),F=p?decodeURIComponent(p[1]):null,A=!F,J=`menu-editor.draft.${F||"new"}`,C=E.loader(o.get(0),{type:"dots"});let v,K,se,te,q,le,oe;try{if(A)v={slug:"",name:"",description:"",items:[]};else try{v=await j.menus.get(F)}catch(e){E.toast(`Failed to load menu: ${e.message||e}`,{type:"error"}),location.hash="#/menus";return}[K,se,te,q,le,oe]=await Promise.all([j.projects.list().catch(()=>[]),H.get("/api/auth/permissions-registry").catch(()=>({resources:[]})),j.collections.list().catch(()=>[]),j.get("/collections/roles/entries?limit=100").catch(()=>null),j.menuLocations.registry().catch(()=>[]),j.pages.list().catch(()=>[])])}finally{C.destroy()}if(!s.isConnected)return;const De=(Array.isArray(q)?q:q?.entries||[]).map(e=>({name:e.data?.name,label:e.data?.label,level:e.data?.level??99})).filter(e=>e.name).sort((e,t)=>t.level-e.level),D=!A&&F===Gt;let pe=[];if(D&&(pe=await H.get("/api/sidebar/registered-items").catch(()=>(E.toast("Could not load the Tools - they are not shown, and saving keeps their places as they are.",{type:"warning",duration:8e3}),[])),!s.isConnected))return;const ie=e=>dt(D?Et(At(e||[],pe,{forEditor:!0}),{leaveInHiddenFolders:!0}):e);let h=ie(v.items);const O=M.observable(!1),ce=M.observable(!1),he=M.observable(""),Se=M.observable(0);let z="";const L=s.querySelector("#me-items-list");function re(){Xt(L,h,D),Se.value=h.filter(e=>!ae(e)).length}const _=()=>{re(),Y()},U=()=>D?mt(h):new Set,N=e=>h.find(t=>t.id===e);function x(e){requestAnimationFrame(()=>L.querySelector(`.menu-tree-row[data-id="${CSS.escape(e)}"]`)?.focus())}function fe(e){const t=f=>h.find(c=>!c.type&&!c.url&&!c.tool&&(c.key||"").toLowerCase()===f)||h.find(c=>!c.type&&!c.url&&!c.tool&&!c.key&&(c.text||"").toLowerCase()===f);let a=t(String(e.tool.folder||"").toLowerCase())||t(It);const m=String(e.tool.group||"").trim();if(a&&m){const f=Lt(a.key||_t(a.text),m),c=d=>d!==e&&!d.type&&!d.url&&!d.tool;let b=h.find(d=>c(d)&&(d.key||"").toLowerCase()===f)||h.find(d=>c(d)&&d.parentId===a.id&&(!d.key||d.key.toLowerCase()===f)&&(d.text||"").toLowerCase()===m.toLowerCase());b||([b]=dt([{text:m,key:f,icon:Ht,synthesised:!0}],a.id),h.push(b)),a=b}e.parentId=a?a.id:null,h.splice(h.indexOf(e),1),h.push(e),Object.assign(e,{text:e.tool.defaults.text,icon:e.tool.defaults.icon,visibility:"",hidden:!1,badge:null,pill:null,colour:"",highlight:null,touched:!1}),e.tool={...e.tool,persisted:!1}}const $e=e=>!U().has(e.id)&&!(e.tool&&!e.tool.orphan);async function de(e){const t=N(e);if(!t||!$e(t))return;const a=d=>{let X=d;for(;X;){if(X.id===e)return!0;X=h.find(P=>P.id===X.parentId)}return!1},m=h.filter(d=>d.id!==e&&a(d));if(m.length&&!await E.confirm(`Remove "${Ie(t.text||t.type||"this item")}" and the ${m.length} item${m.length===1?"":"s"} beneath it?`))return;const f=U(),c=m.filter(d=>d.tool),b=m.filter(d=>!d.tool&&f.has(d.id));h=h.filter(d=>!a(d)||c.includes(d)||b.includes(d));for(const d of b)d.parentId=t.parentId??null;for(const d of c)d.tool.orphan?d.parentId=t.parentId??null:fe(d);_()}function ue(e){const t=N(e);!t||ae(t)||U().has(e)||(t.hidden=!t.hidden,t.touched=!0,_())}function G(e){const t=N(e);!t||ae(t)||(t.locked=D&&U().has(t.id),Zt(t,se.resources||[],te,De,()=>{_(),x(e)}))}function ne(e){const t={id:_e(),parentId:null,...e==="separator"||e==="theme-switcher"?{type:e}:e==="spacer"?{type:e,size:"md"}:{text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}};h.push(t),_(),ae(t)?x(t.id):G(t.id)}const $=e=>t=>{e(t)&&(_(),x(t))},u=$(e=>ut(h,e,-1)),Q=$(e=>ut(h,e,1)),me=$(e=>Ft(h,e)),ve=$(e=>Wt(h,e));function ge(e){const t=N(e);if(!t)return[];const a=ae(t),m=U().has(e),f=Kt(h,e),c=f.findIndex(P=>P.id===e),b=t.tool,d=b&&(b.persisted||t.touched),X=P=>()=>{const ke=Bt(h,e,P,_e());_(),ke&&!ae(ke)?G(ke.id):ke&&x(ke.id)};return[{header:a?{separator:"Separator",spacer:"Spacer","theme-switcher":"Theme switcher"}[t.type]:t.text||b?.label||"(untitled)"},...a?[]:[{label:"Edit\u2026",icon:"edit",action:()=>G(e)}],{type:"divider"},{label:"Add item below",icon:"plus",action:X("item")},{label:"Add sub-item",icon:"corner-down-right",disabled:a,action:()=>{const P=Ot(h,e,_e());_(),P&&G(P.id)}},{label:"Add separator below",icon:"minus",action:X("separator")},{label:"Add spacer below",icon:"move",action:X("spacer")},...D?[]:[{label:"Add theme switcher below",icon:"palette",action:X("theme-switcher")}],{type:"divider"},{label:"Move up",icon:"arrow-up",shortcut:"Alt+\u2191",disabled:c<=0,action:()=>u(e)},{label:"Move down",icon:"arrow-down",shortcut:"Alt+\u2193",disabled:c<0||c>=f.length-1,action:()=>Q(e)},{label:"Indent",icon:"chevron-right",shortcut:"Alt+\u2192",disabled:c<=0||ae(f[c-1]),action:()=>me(e)},{label:"Outdent",icon:"chevron-left",shortcut:"Alt+\u2190",disabled:t.parentId==null,action:()=>ve(e)},{type:"divider"},...a?[]:[{label:t.hidden?"Show":"Hide",icon:t.hidden?"eye":"eye-off",disabled:m,action:()=>ue(e)}],{label:"Duplicate",icon:"copy",disabled:!!b,action:()=>{const P=Pt(h,e,_e);_(),P&&x(P.id)}},...b&&!b.orphan&&d?[{label:"Back to its default place",icon:"rotate-ccw",action:()=>{fe(t),_()}}]:[],{label:m?"Remove - always in the sidebar":b&&!b.orphan?"Remove - a Tool is hidden, not removed":"Remove\u2026",icon:"trash",danger:!0,disabled:!$e(t),action:()=>de(e)}]}const be=E.contextMenu(L,{cursor:"glyph",match:".menu-tree-row",inherit:!1,density:"compact",items:e=>ge(e.dataset.id)});l(()=>be?.destroy?.());const ye=xt(L,()=>h,_,{items:".menu-tree-row",handle:".menu-tree-grip"});l(()=>ye?.destroy());const we=e=>{const t=e.target.closest(".menu-tree-row");if(!t)return;const a=t.dataset.id;if(e.target.closest(".mex-kebab")){Ue(e.target.closest(".mex-kebab"));return}if(e.target.closest(".me-hidden")){ue(a);return}if(e.target.closest(".me-edit")){G(a);return}e.target.closest("select, .menu-tree-grip, button")||G(a)},Ge=e=>{const t=e.target.closest(".menu-tree-row");if(!t||e.target!==t){t&&e.key==="F10"&&e.shiftKey&&(e.preventDefault(),Ue(t));return}const a=t.dataset.id;if(e.key==="F10"&&e.shiftKey)e.preventDefault(),Ue(t);else if(e.key==="Enter")e.preventDefault(),G(a);else if(e.key==="Delete")e.preventDefault(),de(a);else if(e.altKey&&e.key==="ArrowUp")e.preventDefault(),u(a);else if(e.altKey&&e.key==="ArrowDown")e.preventDefault(),Q(a);else if(e.altKey&&e.key==="ArrowRight")e.preventDefault(),me(a);else if(e.altKey&&e.key==="ArrowLeft")e.preventDefault(),ve(a);else if(e.key==="ArrowDown"||e.key==="ArrowUp"){const m=[...L.querySelectorAll(".menu-tree-row")],f=m.indexOf(t)+(e.key==="ArrowDown"?1:-1);m[f]&&(e.preventDefault(),m[f].focus())}},Ve=e=>{if(!e.target.matches(".me-spacer-size"))return;const t=N(e.target.closest(".menu-tree-row")?.dataset.id);t&&(t.size=e.target.value,Y())};L.addEventListener("click",we),L.addEventListener("keydown",Ge),L.addEventListener("change",Ve),l(()=>{L.removeEventListener("click",we),L.removeEventListener("keydown",Ge),L.removeEventListener("change",Ve)});const n=e=>o.find(e),xe=n("#me-float-accent"),Oe=n("#me-float-accent-hex"),Ne=()=>{Oe.get(0).style.display=xe.val()==="__custom__"?"":"none"},ft=()=>xe.val()==="__custom__"?Oe.val():xe.val(),Ae=n("#me-highlight-accent"),Pe=n("#me-highlight-accent-hex"),Ye=()=>{Pe.get(0).style.display=Ae.val()==="__custom__"?"":"none"},vt=()=>Ae.val()==="__custom__"?Pe.val():Ae.val(),Xe=()=>{const e=n("#me-position").val()==="floating";n(".dm-float-field").each(function(){this.style.display=e?"":"none"}),e&&Ne();const t=n("#me-orientation").val()==="vertical";n(".dm-vertical-field").each(function(){this.style.display=t?"":"none"}),n(".dm-dock-rail-field").each(function(){this.style.display=t&&!e?"":"none"}),n(".dm-dock-bar-field").each(function(){this.style.display=!t&&!e?"":"none"});const a=!!(n("#me-dock-collapsible").get(0)||{}).checked,m=!!(n("#me-dock-autohide").get(0)||{}).checked;n(".dm-dock-collapsed-field").each(function(){this.style.display=a&&!m?"":"none"});const f=!!(n("#me-float-collapsible").get(0)||{}).checked;n(".dm-float-collapsed-field").each(function(){this.style.display=e&&f?"":"none"})},Je=(e,t,a,m)=>{const f=n(e).get(0);f&&(f.innerHTML="",f.add(new Option(m,"")),t.forEach(c=>f.add(new Option(a[c]||c,c))))};Je("#me-highlight-hover",st,it,"- theme default -"),Je("#me-highlight-active",lt,ct,"- theme default -");const Fe=n("#me-bind-slot"),Be=n("#me-bind-projects"),Ee=n("#me-bind-pages");Fe.html('<option value="">- not bound -</option>'+(le||[]).map(e=>`<option value="${y(e.slot)}">${y(e.label||e.slot)} (${y(e.slot)})</option>`).join("")),Be.html(K.map(e=>`<option value="${y(e.slug)}">${y(e.name||e.slug)}</option>`).join("")),n("#me-bind-page-pick").html('<option value="">- pick a page -</option>'+oe.map(e=>{const t=e.urlPath||e.url||"";return t?`<option value="${y(t)}">${y(e.title||t)} - ${y(t)}</option>`:""}).join(""));const Qe=()=>Nt({slot:Fe.val(),projects:Array.from(Be.get(0).selectedOptions).map(e=>e.value),pagesText:Ee.val()});function ze(){const e=Qe(),t=n("#me-bind-summary");if(!e){t.html('<span class="text-muted">Not bound - this menu renders only where it is mapped or placed by a shortcode.</span>');return}const a=[];e.projects.length&&a.push(`pages in ${e.projects.map(c=>`<code>${y(c)}</code>`).join(", ")}`),e.pages.length&&a.push(`pages matching ${e.pages.map(c=>`<code>${y(c)}</code>`).join(", ")}`);const m=e.pages.filter(c=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(c)),f=m.length?`<div class="text-danger" style="margin-top:.4rem">Not valid page patterns: ${m.map(c=>`<code>${y(c)}</code>`).join(", ")}</div>`:"";t.html(a.length?`Takes over the <code>${y(e.slot)}</code> slot on ${a.join(" and ")}.${f}`:`<span class="text-warning">Slot <code>${y(e.slot)}</code> selected but no project or page chosen - the binding will never match.</span>`)}const{getProjectFromHash:gt}=await import("../lib/project-context.js");if(!g())return;const bt=A?gt():null;n("#me-project").html('<option value="">- none -</option>'+K.map(e=>`<option value="${y(e.slug)}">${y(e.name||e.slug)}</option>`).join(""));function Me(e){h=ie(e.items),n("#me-variant").val(e.variant||""),n("#me-position").val(e.position||"");const t=n("#me-appearOnHover").get(0);t&&(t.checked=e.appearOnHover===!0),n("#me-float-anchor").val(e.float?.anchor||"TL"),n("#me-float-offsetX").val(e.float?.offsetX??""),n("#me-float-offsetY").val(e.float?.offsetY??""),n("#me-float-width").val(e.float?.width??""),n("#me-float-radius").val(e.float?.radius??""),n("#me-float-shadow").val(e.float?.shadow||""),n("#me-float-opacity").val(e.float?.opacity??""),n("#me-float-title").val(e.float?.title||"");for(const[c,b]of[["#me-float-collapsible",e.float?.collapsible],["#me-float-collapsed",e.float?.collapsed],["#me-float-movable",e.float?.movable],["#me-float-resizable",e.float?.resizable]]){const d=n(c).get(0);d&&(d.checked=b===!0)}const a=e.float?.accent||"";xe.val(a.startsWith("#")?"__custom__":a),a.startsWith("#")&&Oe.val(a),Ne(),n("#me-orientation").val(e.orientation||""),n("#me-align").val(e.align||""),n("#me-side").val(e.side||"left"),n("#me-dock-width").val(e.dock?.width??"");for(const c of["collapsible","collapsed","autohide","hideOnScroll"]){const b=n(`#me-dock-${c}`).get(0);b&&(b.checked=e.dock?.[c]===!0)}n("#me-class").val(e.class||""),n("#me-highlight-hover").val(e.highlight?.hover||""),n("#me-highlight-active").val(e.highlight?.active||"");const m=e.highlight?.accent||"";Ae.val(m.startsWith("#")?"__custom__":m),m.startsWith("#")&&Pe.val(m),Ye(),n("#me-fontFamily").val(e.style?.fontFamily||""),n("#me-fontSize").val(e.style?.fontSize||""),n("#me-fontWeight").val(e.style?.fontWeight||""),n("#me-letterSpacing").val(e.style?.letterSpacing||""),n("#me-iconSize").val(e.style?.iconSize||""),Fe.val(e.binding?.slot||"");const f=new Set(e.binding?.projects||[]);Array.from(Be.get(0).options).forEach(c=>{c.selected=f.has(c.value)}),Ee.val((e.binding?.pages||[]).join(`
28
- `)),n("#me-slug").val(e.slug||""),n("#me-name").val(e.name||""),n("#me-description").val(e.description||""),n("#me-project").val(e.meta?.project||bt||""),Xe(),ze(),re()}const V=e=>!!(n(e).get(0)||{}).checked;function Ce(){const e={variant:n("#me-variant").val(),position:n("#me-position").val(),appearOnHover:V("#me-appearOnHover"),floatAnchor:n("#me-float-anchor").val(),floatOffsetX:n("#me-float-offsetX").val(),floatOffsetY:n("#me-float-offsetY").val(),floatWidth:n("#me-float-width").val(),floatRadius:n("#me-float-radius").val(),floatShadow:n("#me-float-shadow").val(),floatAccent:ft(),floatOpacity:n("#me-float-opacity").val(),floatTitle:n("#me-float-title").val(),floatCollapsible:V("#me-float-collapsible"),floatCollapsed:V("#me-float-collapsed"),floatMovable:V("#me-float-movable"),floatResizable:V("#me-float-resizable"),highlightHover:n("#me-highlight-hover").val(),highlightActive:n("#me-highlight-active").val(),highlightAccent:vt(),class:n("#me-class").val(),orientation:n("#me-orientation").val(),align:n("#me-align").val(),side:n("#me-side").val(),fontFamily:n("#me-fontFamily").val(),fontSize:n("#me-fontSize").val(),fontWeight:n("#me-fontWeight").val(),letterSpacing:n("#me-letterSpacing").val(),iconSize:n("#me-iconSize").val(),dockWidth:n("#me-dock-width").val(),dockCollapsible:V("#me-dock-collapsible"),dockCollapsed:V("#me-dock-collapsed"),dockAutohide:V("#me-dock-autohide"),dockHideOnScroll:V("#me-dock-hideOnScroll")},t={slug:n("#me-slug").val(),name:n("#me-name").val(),description:n("#me-description").val(),project:n("#me-project").val()};return zt(e,t,Qe(),Tt(h),v.meta||{})}const Ze=e=>[...Mt(e),...rt(e.class).map(t=>`CSS classes: ${t} (Behaviour tab).`)];let et=!1,We=null;function Y(){if(!z)return;const e=Ce();We=e,O.value=He(e)!==z,he.value=O.peek()||et?Ze(e).join(" "):""}const Le=e=>{e.target.closest("#me-items-list")||(e.target.matches("#me-position, #me-orientation, #me-float-collapsible, #me-dock-collapsible, #me-dock-autohide")&&Xe(),e.target.matches("#me-float-accent")&&Ne(),e.target.matches("#me-highlight-accent")&&Ye(),e.target.closest("#me-binding")&&ze(),Y())};s.addEventListener("input",Le),s.addEventListener("change",Le),l(()=>{s.removeEventListener("input",Le),s.removeEventListener("change",Le)}),n("#me-bind-page-add").on("click",()=>{const e=n("#me-bind-page-pick").val();if(!e)return;const t=Ee.val().split(`
29
- `).map(a=>a.trim()).filter(Boolean);t.includes(e)||t.push(e),Ee.val(t.join(`
30
- `)),ze(),Y()}),Me(v),z=He(Ce()),Y();const tt=()=>{try{S.remove?S.remove(J):S.set(J,null)}catch{}};async function Ke(){if(ce.peek())return;const e=Ce(),t=Ze(e);if(t.length){et=!0,Y(),E.toast(t.join(" "),{type:"warning",duration:7e3});return}ce.value=!0;try{if(A)await j.menus.create(e);else if(e.slug!==v.slug){await j.menus.create(e);const a=await j.menuLocations.get();let m=!1;for(const[f,c]of Object.entries(a))c===v.slug&&(a[f]=e.slug,m=!0);m&&await j.menuLocations.save(a),await j.menus.remove(v.slug)}else await j.menus.update(v.slug,e);if(z=He(e),O.value=!1,tt(),Dt("#/menus"),E.toast("Saved.",{type:"success"}),A||e.slug!==v.slug)location.hash="#/menus/edit/"+encodeURIComponent(e.slug);else{v={...v,...e};for(const a of h)a.tool&&a.touched&&(a.tool={...a.tool,persisted:!0});re(),z=He(Ce()),Y(),ht(o.get(0),e.name||e.slug)}if(D)try{document.dispatchEvent(new CustomEvent("dm:sidebar-rebuild"))}catch{}}catch(a){E.toast(`Save failed: ${a.message||a}`,{type:"error"})}finally{ce.value=!1}}async function yt(){!O.peek()||!await E.confirm("Throw away the changes you have not saved?")||(Me(v),Y())}E.tabs(n("#me-tabs").get(0));const wt=M.applyBindings({dirty:O,saving:ce,problems:he,itemCount:Se},s,{methods:{save:()=>Ke(),discard:()=>yt(),addItem:()=>ne("item"),addSeparator:()=>ne("separator"),addSpacer:()=>ne("spacer"),addSwitcher:()=>ne("theme-switcher")}});l(()=>wt.dispose()),l(Rt(s,{position:"bottom"})),D&&n("#me-add-switcher").hide(),ht(o.get(0),A?"New menu":v.name||v.slug),qe(o,{id:"menu-editor-back",icon:"arrow-left",title:"All menus",onClick:()=>{location.hash="#/menus"}}),qe(o,{id:"menu-editor-locations",icon:"map-pin",title:"Menu locations",onClick:()=>{location.hash="#/menu-locations"}}),qe(o,{id:"menu-editor-save",icon:"save",title:"Save (Ctrl+S)",onClick:()=>Ke()});const ot=e=>{if(!(!(e.ctrlKey||e.metaKey)||e.key!=="s")){if(e.preventDefault(),e.stopImmediatePropagation(),document.querySelector(".me-item-form")?.offsetParent){E.toast("Apply the item first (Ctrl+Enter), then Save.",{type:"info"});return}Ke()}};document.addEventListener("keydown",ot,!0),l(()=>document.removeEventListener("keydown",ot,!0));const nt=()=>{if(!(!O.peek()||!We))try{S.set(J,{menu:We,base:z,at:new Date().toISOString()})}catch{}},at=e=>{O.peek()&&(nt(),e.preventDefault(),e.returnValue="")};window.addEventListener("beforeunload",at),l(()=>window.removeEventListener("beforeunload",at)),W={path:k,dirty:()=>O.peek(),name:()=>n("#me-name").val()||v.name||v.slug||"new menu",dispose(){i=!0,nt(),r.splice(0).reverse().forEach(e=>{try{e()}catch{}})}},I.scan(s);let Z=null;try{Z=S.get(J)}catch{}if(Z?.menu){tt();const e=Z.base&&Z.base!==z,t=Z.at?` (${qt(Z.at)})`:"",a=A?"the new menu you started":`the menu "${Ie(v.name||v.slug)}"`,m=e?`You left unsaved changes to ${a}${t}, but the saved menu has changed since. Restore your version anyway?`:`You left unsaved changes to ${a}${t}. Restore them?`;await E.confirm(m)&&g()&&(Me({...Z.menu,meta:{...v.meta||{},...Z.menu.meta||{}}}),Y())}}};
27
+ </div>`),v(p.id)}}v(null),o.innerHTML=s.join("")||'<p class="mex-note">No items yet - Add item, or right-click an item for more.</p>',I.scan(o)}function w(o,r={},...i){const c=document.createElement(o);Object.assign(c,r);for(const s of i)s!=null&&c.append(s);return c}function T(o,r,i){const c=w("label",{className:"form-field"},w("span",{className:"form-label",textContent:o}),r);return i&&c.append(w("small",{className:"form-hint",textContent:i,style:"display:block;font-size:.78em;opacity:.7;margin-top:.25rem;line-height:1.35"})),c}function Zt(o,r){const i=[["","- Everyone -"],["public","Public - anyone, incl. logged-out"],...(r||[]).map(s=>[s.name,`${s.label||s.name} and above`]),...(r||[]).filter(s=>s.level!==0).map(s=>[`=${s.name}`,`${s.label||s.name} only`]),["private","Private - super-admin only"]];o&&!i.some(([s])=>s===o)&&i.push([o,`${o} (custom)`]);const c=ee(i,o||"");return c.name="visibility",c}function ee(o,r){const i=w("select",{className:"form-select"});return o.forEach(([c,s])=>i.add(new Option(s,c))),i.value=r??"",i}function Re(o,r){const i=typeof r=="string"&&r.startsWith("#"),c=ee([["","- none -"],["primary","primary"],["success","success"],["danger","danger"],["warning","warning"],["info","info"],["neutral","neutral"],["__custom__","Custom\u2026"]],i?"__custom__":r||""),s=w("input",{type:"color",className:"form-input me-colour-hex",value:i?r:"#000000"});s.style.display=i?"":"none",c.addEventListener("change",()=>{s.style.display=c.value==="__custom__"?"":"none"});const v=T(o,c);return v.append(s),v._read=()=>c.value==="__custom__"?s.value:c.value,v}function en(o,r){const i=w("input",{className:"form-input me-icon",name:"icon",value:r||""}),c=w("span",{className:"me-icon-preview"});r&&c.setAttribute("data-icon",r);const s=w("button",{type:"button",className:"btn btn-sm btn-ghost",textContent:"Browse\u2026"}),v=k=>{k?c.setAttribute("data-icon",k):c.removeAttribute("data-icon"),Domma.icons.scan(c.parentNode||c)};return s.addEventListener("click",()=>$t(k=>{i.value=k,v(k)})),i.addEventListener("input",()=>v(i.value.trim())),T(o,w("div",{className:"me-icon-field"},i,s,c))}function Ne(...o){return w("div",{className:"me-field-grid"},...o)}async function tn(o,r,i,c,s){const v=o.text||o.tool?.label||"",k=u=>w("h4",{className:"me-form-section",textContent:u}),p=T("Label",w("input",{className:"form-input",name:"text",value:o.text||""}),"The text shown for this item."),B=w("input",{className:"form-input",name:"url",value:o.url||""}),x=T("URL",B,o.tool||o.locked?"A Tool's address is its identity, so it cannot be changed here.":"Where it links. Must start with /, #, https://, or mailto: . Leave blank for a parent that only groups sub-items.");(o.tool||o.locked)&&(B.readOnly=!0);const J=en("Icon",o.icon||""),C=Zt(o.visibility||"",c),g=T("Visibility",C,o.locked?"Always in the sidebar for everyone who may use it, so it cannot be restricted here.":'Who can see this item. "Role and above" shows it to that role and anyone more senior; "Role only" shows it to holders of that role alone (and the super-admin). Blank = everyone.');o.locked&&(C.disabled=!0);const q=ee([["","- no permission gate -"],...(r||[]).map(u=>[u.key,u.label||u.key])],o.permission||"");q.name="permission";const se=T("Permission",q,o.tool||o.locked?"A Tool is guarded by its own permission, which always applies.":"Hide unless the viewer holds this specific permission. Independent of Visibility - both must pass.");(o.tool||o.locked)&&(q.disabled=!0);const te=T("Badge text",w("input",{className:"form-input",name:"badgeText",value:o.badge?.text||""})),U=ee([["","- none -"],...(i||[]).map(u=>[u.slug,u.title||u.slug])],o.badge?.countFrom||"");U.name="badgeCount";const le=T("Badge count from",U,"Show a live count of this collection\u2019s entries as the badge."),ne=Re("Badge colour",o.badge?.variant||""),F=ee([["link","Link"],["pill","Pill"]],o.pill?"pill":"link");F.name="renderAs";const Oe=T("Render as",F,"Pill draws the item as a rounded chip. Pill styling applies to top-level navbar items."),O=T("Pill style",ee([["filled","Filled"],["outline","Outline"]],o.pill?.style||"filled"));O.querySelector("select").name="pillStyle";const pe=Re("Pill colour",o.pill?.variant||""),ie=w("div",{className:"me-pill-wrap"},Ne(O,pe));ie.style.display=o.pill?"":"none",F.addEventListener("change",()=>{ie.style.display=F.value==="pill"?"":"none"});const h=Re("Text colour",o.colour||""),D=ee([["","- use the menu default -"],...lt.map(u=>[u,ct[u]||u])],o.highlight?.hover||"");D.name="hlHover";const ce=T("Hover effect",D,"Overrides the menu-wide hover effect for this item only."),he=ee([["","- use the menu default -"],...it.map(u=>[u,rt[u]||u])],o.highlight?.active||"");he.name="hlActive";const Se=T("When selected",he,"How this item is marked when it points at the page being viewed."),z=Re("Highlight colour",o.highlight?.accent||""),L=w("input",{className:"form-input",name:"class",value:o.class||"",placeholder:"nav-cta push-right",autocomplete:"off",spellcheck:!1}),re=T("CSS classes",L,"Your own class names, separated by spaces, added to this item's <li> - target the link with .your-class > a. Style them in Custom CSS."),_=w("small",{className:"text-danger",style:"display:none;margin-top:.25rem"});re.append(_);const G=w("button",{className:"btn btn-primary",textContent:"Apply",title:"Apply to the item (Ctrl+Enter) - Save the menu to keep it"}),j=w("div",{className:"me-item-form"},k("Link"),p,x,J,k("Access"),Ne(g,se),k("Badge"),Ne(te,ne),le,k("Appearance"),Oe,ie,h,k("Highlighting"),Ne(ce,Se),z,k("Styling"),re,G),$=E.slideover({title:v?`Edit ${He(v)}`:"Edit menu item",size:"lg",position:"right"});$.element.appendChild(j);const fe=()=>JSON.stringify([...j.querySelectorAll("input, select, textarea")].map(u=>u.type==="checkbox"?u.checked:u.value)),Ae=fe();let de=!1,ue=!1;Dt($);const V=$.close.bind($);$.close=async u=>{if(!de&&u!==!0&&fe()!==Ae){if(ue)return;ue=!0;const Q=await E.confirm("Discard the changes to this item?");if(ue=!1,!Q)return}return de=!0,V()},j.addEventListener("keydown",u=>{(u.ctrlKey||u.metaKey)&&u.key==="Enter"&&(u.preventDefault(),G.click())}),$.open();const oe=$.element.closest(".dm-slideover")||$.element.querySelector(".dm-slideover")||$.element;oe.style.setProperty("width",Vt+"px","important"),oe.style.setProperty("max-width","95vw","important"),Domma.icons.scan(j);const A=u=>j.querySelector(`[name="${u}"]`)?.value||"";G.addEventListener("click",()=>{const u=dt(A("class"));if(u.length){_.textContent=u.join("; "),_.style.display="block",L.focus();return}o.class=At(A("class")),o.text=A("text"),o.icon=A("icon"),o.locked||(o.visibility=A("visibility")),!o.tool&&!o.locked?(o.url=A("url"),o.permission=A("permission")):o.touched=!0;const Q=A("badgeText"),me=A("badgeCount"),ge=ne._read();if(o.badge=Q||me?{...Q&&{text:Q},...me&&{countFrom:me},...ge&&{variant:ge}}:null,A("renderAs")==="pill"){const we=pe._read();o.pill={style:A("pillStyle")||"filled",...we&&{variant:we}}}else o.pill=null;o.colour=h._read();const ve=A("hlHover"),be=A("hlActive"),ye=z._read();o.highlight=ve||be||ye?{...ve&&{hover:ve},...be&&{active:be},...ye&&{accent:ye}}:null,de=!0,$.close(!0),s()})}let K=null,ht=!1;function nn(){ht||!window.R?.use||(ht=!0,R.use((o,r,i)=>{const c=r?.path||"";return!(Xt.test(c)&&(o?.path||"")!==c)||!K?.dirty()?i():E.confirm(`You have unsaved changes to the menu "${He(K.name())}". Leave anyway? They are kept as a draft for your next visit.`).then(v=>{v?i():history.replaceState(null,"",`#${c}`)})}),M.subscribe("router:afterChange",({to:o}={})=>{if(K&&(o?.path||"")!==K.path){const r=K;K=null,r.dispose()}}))}function ft(o,r){const i=o.querySelector(".dm-plugin-banner-name"),c=i?.querySelector(".dm-plugin-banner-sep");if(!(!i||!c)){for(;c.nextSibling;)c.nextSibling.remove();i.appendChild(document.createTextNode(r))}}export const menuEditorView={templateUrl:"/admin/js/templates/menu-editor.html",async onMount(o){if(nn(),K){const e=K;K=null,e.dispose()}const r=[],i=e=>(r.push(e),e);let c=!1;const s=o.get(0).querySelector(".mex")||o.get(0),v=()=>!c&&s.isConnected,k=location.hash.replace(/^#/,""),p=location.hash.match(/^#\/menus\/edit\/([^?#]+)/),B=p?decodeURIComponent(p[1]):null,x=!B,J=`menu-editor.draft.${B||"new"}`,C=E.loader(o.get(0),{type:"dots"});let g,q,se,te,U,le,ne;try{if(x)g={slug:"",name:"",description:"",items:[]};else try{g=await N.menus.get(B)}catch(e){E.toast(`Failed to load menu: ${e.message||e}`,{type:"error"}),location.hash="#/menus";return}[q,se,te,U,le,ne]=await Promise.all([N.projects.list().catch(()=>[]),H.get("/api/auth/permissions-registry").catch(()=>({resources:[]})),N.collections.list().catch(()=>[]),N.get("/collections/roles/entries?limit=100").catch(()=>null),N.menuLocations.registry().catch(()=>[]),N.pages.list().catch(()=>[])])}finally{C.destroy()}if(!s.isConnected)return;const Oe=(Array.isArray(U)?U:U?.entries||[]).map(e=>({name:e.data?.name,label:e.data?.label,level:e.data?.level??99})).filter(e=>e.name).sort((e,t)=>t.level-e.level),O=!x&&B===Yt;let pe=[];if(O&&(pe=await H.get("/api/sidebar/registered-items").catch(()=>(E.toast("Could not load the Tools - they are not shown, and saving keeps their places as they are.",{type:"warning",duration:8e3}),[])),!s.isConnected))return;const ie=e=>ut(O?Lt(Ct(e||[],pe,{forEditor:!0}),{leaveInHiddenFolders:!0}):e);let h=ie(g.items);const D=M.observable(!1),ce=M.observable(!1),he=M.observable(""),Se=M.observable(0);let z="";const L=s.querySelector("#me-items-list");function re(){Qt(L,h,O),Se.value=h.filter(e=>!ae(e)).length}const _=()=>{re(),Y()},G=()=>O?pt(h):new Set,j=e=>h.find(t=>t.id===e);function $(e){requestAnimationFrame(()=>L.querySelector(`.menu-tree-row[data-id="${CSS.escape(e)}"]`)?.focus())}function fe(e){const t=f=>h.find(l=>!l.type&&!l.url&&!l.tool&&(l.key||"").toLowerCase()===f)||h.find(l=>!l.type&&!l.url&&!l.tool&&!l.key&&(l.text||"").toLowerCase()===f);let a=t(String(e.tool.folder||"").toLowerCase())||t(Rt);const m=String(e.tool.group||"").trim();if(a&&m){const f=It(a.key||Ht(a.text),m),l=d=>d!==e&&!d.type&&!d.url&&!d.tool;let b=h.find(d=>l(d)&&(d.key||"").toLowerCase()===f)||h.find(d=>l(d)&&d.parentId===a.id&&(!d.key||d.key.toLowerCase()===f)&&(d.text||"").toLowerCase()===m.toLowerCase());b||([b]=ut([{text:m,key:f,icon:Tt,synthesised:!0}],a.id),h.push(b)),a=b}e.parentId=a?a.id:null,h.splice(h.indexOf(e),1),h.push(e),Object.assign(e,{text:e.tool.defaults.text,icon:e.tool.defaults.icon,visibility:"",hidden:!1,badge:null,pill:null,colour:"",highlight:null,touched:!1}),e.tool={...e.tool,persisted:!1}}const Ae=e=>!G().has(e.id)&&!(e.tool&&!e.tool.orphan);async function de(e){const t=j(e);if(!t||!Ae(t))return;const a=d=>{let X=d;for(;X;){if(X.id===e)return!0;X=h.find(P=>P.id===X.parentId)}return!1},m=h.filter(d=>d.id!==e&&a(d));if(m.length&&!await E.confirm(`Remove "${He(t.text||t.type||"this item")}" and the ${m.length} item${m.length===1?"":"s"} beneath it?`))return;const f=G(),l=m.filter(d=>d.tool),b=m.filter(d=>!d.tool&&f.has(d.id));h=h.filter(d=>!a(d)||l.includes(d)||b.includes(d));for(const d of b)d.parentId=t.parentId??null;for(const d of l)d.tool.orphan?d.parentId=t.parentId??null:fe(d);_()}function ue(e){const t=j(e);!t||ae(t)||G().has(e)||(t.hidden=!t.hidden,t.touched=!0,_())}function V(e){const t=j(e);!t||ae(t)||(t.locked=O&&G().has(t.id),tn(t,se.resources||[],te,Oe,()=>{_(),$(e)}))}function oe(e){const t={id:_e(),parentId:null,...e==="separator"||e==="theme-switcher"?{type:e}:e==="spacer"?{type:e,size:"md"}:{text:"",url:"/",icon:"",visibility:"",permission:"",hidden:!1,bundled:!1}};h.push(t),_(),ae(t)?$(t.id):V(t.id)}const A=e=>t=>{e(t)&&(_(),$(t))},u=A(e=>mt(h,e,-1)),Q=A(e=>mt(h,e,1)),me=A(e=>Mt(h,e)),ge=A(e=>qt(h,e));function ve(e){const t=j(e);if(!t)return[];const a=ae(t),m=G().has(e),f=Ut(h,e),l=f.findIndex(P=>P.id===e),b=t.tool,d=b&&(b.persisted||t.touched),X=P=>()=>{const ke=zt(h,e,P,_e());_(),ke&&!ae(ke)?V(ke.id):ke&&$(ke.id)};return[{header:a?{separator:"Separator",spacer:"Spacer","theme-switcher":"Theme switcher"}[t.type]:t.text||b?.label||"(untitled)"},...a?[]:[{label:"Edit\u2026",icon:"edit",action:()=>V(e)}],{type:"divider"},{label:"Add item below",icon:"plus",action:X("item")},{label:"Add sub-item",icon:"corner-down-right",disabled:a,action:()=>{const P=Pt(h,e,_e());_(),P&&V(P.id)}},{label:"Add separator below",icon:"minus",action:X("separator")},{label:"Add spacer below",icon:"move",action:X("spacer")},...O?[]:[{label:"Add theme switcher below",icon:"palette",action:X("theme-switcher")}],{type:"divider"},{label:"Move up",icon:"arrow-up",shortcut:"Alt+\u2191",disabled:l<=0,action:()=>u(e)},{label:"Move down",icon:"arrow-down",shortcut:"Alt+\u2193",disabled:l<0||l>=f.length-1,action:()=>Q(e)},{label:"Indent",icon:"chevron-right",shortcut:"Alt+\u2192",disabled:l<=0||ae(f[l-1]),action:()=>me(e)},{label:"Outdent",icon:"chevron-left",shortcut:"Alt+\u2190",disabled:t.parentId==null,action:()=>ge(e)},{type:"divider"},...a?[]:[{label:t.hidden?"Show":"Hide",icon:t.hidden?"eye":"eye-off",disabled:m,action:()=>ue(e)}],{label:"Duplicate",icon:"copy",disabled:!!b,action:()=>{const P=Ft(h,e,_e);_(),P&&$(P.id)}},...b&&!b.orphan&&d?[{label:"Back to its default place",icon:"rotate-ccw",action:()=>{fe(t),_()}}]:[],{label:m?"Remove - always in the sidebar":b&&!b.orphan?"Remove - a Tool is hidden, not removed":"Remove\u2026",icon:"trash",danger:!0,disabled:!Ae(t),action:()=>de(e)}]}const be=E.contextMenu(L,{cursor:"glyph",match:".menu-tree-row",inherit:!1,density:"compact",items:e=>ve(e.dataset.id)});i(()=>be?.destroy?.());const ye=xt(L,()=>h,_,{items:".menu-tree-row",handle:".menu-tree-grip"});i(()=>ye?.destroy());const we=e=>{const t=e.target.closest(".menu-tree-row");if(!t)return;const a=t.dataset.id;if(e.target.closest(".mex-kebab")){Ge(e.target.closest(".mex-kebab"));return}if(e.target.closest(".me-hidden")){ue(a);return}if(e.target.closest(".me-edit")){V(a);return}e.target.closest("select, .menu-tree-grip, button")||V(a)},Ve=e=>{const t=e.target.closest(".menu-tree-row");if(!t||e.target!==t){t&&e.key==="F10"&&e.shiftKey&&(e.preventDefault(),Ge(t));return}const a=t.dataset.id;if(e.key==="F10"&&e.shiftKey)e.preventDefault(),Ge(t);else if(e.key==="Enter")e.preventDefault(),V(a);else if(e.key==="Delete")e.preventDefault(),de(a);else if(e.altKey&&e.key==="ArrowUp")e.preventDefault(),u(a);else if(e.altKey&&e.key==="ArrowDown")e.preventDefault(),Q(a);else if(e.altKey&&e.key==="ArrowRight")e.preventDefault(),me(a);else if(e.altKey&&e.key==="ArrowLeft")e.preventDefault(),ge(a);else if(e.key==="ArrowDown"||e.key==="ArrowUp"){const m=[...L.querySelectorAll(".menu-tree-row")],f=m.indexOf(t)+(e.key==="ArrowDown"?1:-1);m[f]&&(e.preventDefault(),m[f].focus())}},Ye=e=>{if(!e.target.matches(".me-spacer-size"))return;const t=j(e.target.closest(".menu-tree-row")?.dataset.id);t&&(t.size=e.target.value,Y())};L.addEventListener("click",we),L.addEventListener("keydown",Ve),L.addEventListener("change",Ye),i(()=>{L.removeEventListener("click",we),L.removeEventListener("keydown",Ve),L.removeEventListener("change",Ye)});const n=e=>o.find(e),Ee=n("#me-float-accent"),De=n("#me-float-accent-hex"),je=()=>{De.get(0).style.display=Ee.val()==="__custom__"?"":"none"},gt=()=>Ee.val()==="__custom__"?De.val():Ee.val(),$e=n("#me-highlight-accent"),Pe=n("#me-highlight-accent-hex"),Xe=()=>{Pe.get(0).style.display=$e.val()==="__custom__"?"":"none"},vt=()=>$e.val()==="__custom__"?Pe.val():$e.val(),Je=()=>{const e=!!(n("#me-entrance-enabled").get(0)||{}).checked;n(".dm-entrance-field").each(function(){this.style.display=e?"":"none"});const t=n("#me-position").val()==="floating";n(".dm-float-field").each(function(){this.style.display=t?"":"none"}),t&&je();const a=n("#me-orientation").val()==="vertical";n(".dm-vertical-field").each(function(){this.style.display=a?"":"none"}),n(".dm-dock-rail-field").each(function(){this.style.display=a&&!t?"":"none"}),n(".dm-dock-bar-field").each(function(){this.style.display=!a&&!t?"":"none"});const m=!!(n("#me-dock-collapsible").get(0)||{}).checked,f=!!(n("#me-dock-autohide").get(0)||{}).checked;n(".dm-dock-collapsed-field").each(function(){this.style.display=m&&!f?"":"none"});const l=!!(n("#me-float-collapsible").get(0)||{}).checked;n(".dm-float-collapsed-field").each(function(){this.style.display=t&&l?"":"none"})},Qe=(e,t,a,m)=>{const f=n(e).get(0);f&&(f.innerHTML="",f.add(new Option(m,"")),t.forEach(l=>f.add(new Option(a[l]||l,l))))};Qe("#me-highlight-hover",lt,ct,"- theme default -"),Qe("#me-highlight-active",it,rt,"- theme default -");{const e=n("#me-entrance-animation").get(0);e&&(e.innerHTML="",qe.forEach(t=>e.add(new Option(Et[t]||t,t))))}const Be=n("#me-bind-slot"),Fe=n("#me-bind-projects"),xe=n("#me-bind-pages");Be.html('<option value="">- not bound -</option>'+(le||[]).map(e=>`<option value="${y(e.slot)}">${y(e.label||e.slot)} (${y(e.slot)})</option>`).join("")),Fe.html(q.map(e=>`<option value="${y(e.slug)}">${y(e.name||e.slug)}</option>`).join("")),n("#me-bind-page-pick").html('<option value="">- pick a page -</option>'+ne.map(e=>{const t=e.urlPath||e.url||"";return t?`<option value="${y(t)}">${y(e.title||t)} - ${y(t)}</option>`:""}).join(""));const Ze=()=>Bt({slot:Be.val(),projects:Array.from(Fe.get(0).selectedOptions).map(e=>e.value),pagesText:xe.val()});function Me(){const e=Ze(),t=n("#me-bind-summary");if(!e){t.html('<span class="text-muted">Not bound - this menu renders only where it is mapped or placed by a shortcode.</span>');return}const a=[];e.projects.length&&a.push(`pages in ${e.projects.map(l=>`<code>${y(l)}</code>`).join(", ")}`),e.pages.length&&a.push(`pages matching ${e.pages.map(l=>`<code>${y(l)}</code>`).join(", ")}`);const m=e.pages.filter(l=>!/^\/[^\s?#*]*(\/\*)?$|^\/\*$/.test(l)),f=m.length?`<div class="text-danger" style="margin-top:.4rem">Not valid page patterns: ${m.map(l=>`<code>${y(l)}</code>`).join(", ")}</div>`:"";t.html(a.length?`Takes over the <code>${y(e.slot)}</code> slot on ${a.join(" and ")}.${f}`:`<span class="text-warning">Slot <code>${y(e.slot)}</code> selected but no project or page chosen - the binding will never match.</span>`)}const{getProjectFromHash:bt}=await import("../lib/project-context.js");if(!v())return;const yt=x?bt():null;n("#me-project").html('<option value="">- none -</option>'+q.map(e=>`<option value="${y(e.slug)}">${y(e.name||e.slug)}</option>`).join(""));function ze(e){h=ie(e.items),n("#me-variant").val(e.variant||""),n("#me-position").val(e.position||"");const t=n("#me-appearOnHover").get(0);t&&(t.checked=e.appearOnHover===!0),n("#me-float-anchor").val(e.float?.anchor||"TL"),n("#me-float-offsetX").val(e.float?.offsetX??""),n("#me-float-offsetY").val(e.float?.offsetY??""),n("#me-float-width").val(e.float?.width??""),n("#me-float-radius").val(e.float?.radius??""),n("#me-float-shadow").val(e.float?.shadow||""),n("#me-float-opacity").val(e.float?.opacity??""),n("#me-float-title").val(e.float?.title||"");for(const[l,b]of[["#me-float-collapsible",e.float?.collapsible],["#me-float-collapsed",e.float?.collapsed],["#me-float-movable",e.float?.movable],["#me-float-resizable",e.float?.resizable]]){const d=n(l).get(0);d&&(d.checked=b===!0)}const a=e.float?.accent||"";Ee.val(a.startsWith("#")?"__custom__":a),a.startsWith("#")&&De.val(a),je(),n("#me-orientation").val(e.orientation||""),n("#me-align").val(e.align||""),n("#me-side").val(e.side||"left"),n("#me-dock-width").val(e.dock?.width??"");for(const l of["collapsible","collapsed","autohide","hideOnScroll"]){const b=n(`#me-dock-${l}`).get(0);b&&(b.checked=e.dock?.[l]===!0)}n("#me-class").val(e.class||""),n("#me-highlight-hover").val(e.highlight?.hover||""),n("#me-highlight-active").val(e.highlight?.active||"");const m=e.highlight?.accent||"";$e.val(m.startsWith("#")?"__custom__":m),m.startsWith("#")&&Pe.val(m),Xe();{const l=n("#me-entrance-enabled").get(0);l&&(l.checked=e.entrance?.enabled===!0)}n("#me-entrance-animation").val(qe.includes(e.entrance?.animation)?e.entrance.animation:qe[0]),n("#me-entrance-stagger").val(e.entrance?.stagger??""),n("#me-entrance-duration").val(e.entrance?.duration??""),n("#me-fontFamily").val(e.style?.fontFamily||""),n("#me-fontSize").val(e.style?.fontSize||""),n("#me-fontWeight").val(e.style?.fontWeight||""),n("#me-letterSpacing").val(e.style?.letterSpacing||""),n("#me-iconSize").val(e.style?.iconSize||""),Be.val(e.binding?.slot||"");const f=new Set(e.binding?.projects||[]);Array.from(Fe.get(0).options).forEach(l=>{l.selected=f.has(l.value)}),xe.val((e.binding?.pages||[]).join(`
28
+ `)),n("#me-slug").val(e.slug||""),n("#me-name").val(e.name||""),n("#me-description").val(e.description||""),n("#me-project").val(e.meta?.project||yt||""),Je(),Me(),re()}const W=e=>!!(n(e).get(0)||{}).checked;function Ce(){const e={variant:n("#me-variant").val(),position:n("#me-position").val(),appearOnHover:W("#me-appearOnHover"),floatAnchor:n("#me-float-anchor").val(),floatOffsetX:n("#me-float-offsetX").val(),floatOffsetY:n("#me-float-offsetY").val(),floatWidth:n("#me-float-width").val(),floatRadius:n("#me-float-radius").val(),floatShadow:n("#me-float-shadow").val(),floatAccent:gt(),floatOpacity:n("#me-float-opacity").val(),floatTitle:n("#me-float-title").val(),floatCollapsible:W("#me-float-collapsible"),floatCollapsed:W("#me-float-collapsed"),floatMovable:W("#me-float-movable"),floatResizable:W("#me-float-resizable"),highlightHover:n("#me-highlight-hover").val(),highlightActive:n("#me-highlight-active").val(),highlightAccent:vt(),class:n("#me-class").val(),entranceEnabled:W("#me-entrance-enabled"),entranceAnimation:n("#me-entrance-animation").val(),entranceStagger:n("#me-entrance-stagger").val(),entranceDuration:n("#me-entrance-duration").val(),orientation:n("#me-orientation").val(),align:n("#me-align").val(),side:n("#me-side").val(),fontFamily:n("#me-fontFamily").val(),fontSize:n("#me-fontSize").val(),fontWeight:n("#me-fontWeight").val(),letterSpacing:n("#me-letterSpacing").val(),iconSize:n("#me-iconSize").val(),dockWidth:n("#me-dock-width").val(),dockCollapsible:W("#me-dock-collapsible"),dockCollapsed:W("#me-dock-collapsed"),dockAutohide:W("#me-dock-autohide"),dockHideOnScroll:W("#me-dock-hideOnScroll")},t={slug:n("#me-slug").val(),name:n("#me-name").val(),description:n("#me-description").val(),project:n("#me-project").val()};return Wt(e,t,Ze(),Nt(h),g.meta||{})}const et=e=>[...Kt(e),...dt(e.class).map(t=>`CSS classes: ${t} (Behaviour tab).`)];let tt=!1,We=null;function Y(){if(!z)return;const e=Ce();We=e,D.value=Ie(e)!==z,he.value=D.peek()||tt?et(e).join(" "):""}const Le=e=>{e.target.closest("#me-items-list")||(e.target.matches("#me-position, #me-orientation, #me-float-collapsible, #me-dock-collapsible, #me-dock-autohide, #me-entrance-enabled")&&Je(),e.target.matches("#me-float-accent")&&je(),e.target.matches("#me-highlight-accent")&&Xe(),e.target.closest("#me-binding")&&Me(),Y())};s.addEventListener("input",Le),s.addEventListener("change",Le),i(()=>{s.removeEventListener("input",Le),s.removeEventListener("change",Le)}),n("#me-bind-page-add").on("click",()=>{const e=n("#me-bind-page-pick").val();if(!e)return;const t=xe.val().split(`
29
+ `).map(a=>a.trim()).filter(Boolean);t.includes(e)||t.push(e),xe.val(t.join(`
30
+ `)),Me(),Y()}),ze(g),z=Ie(Ce()),Y();const nt=()=>{try{S.remove?S.remove(J):S.set(J,null)}catch{}};async function Ke(){if(ce.peek())return;const e=Ce(),t=et(e);if(t.length){tt=!0,Y(),E.toast(t.join(" "),{type:"warning",duration:7e3});return}ce.value=!0;try{if(x)await N.menus.create(e);else if(e.slug!==g.slug){await N.menus.create(e);const a=await N.menuLocations.get();let m=!1;for(const[f,l]of Object.entries(a))l===g.slug&&(a[f]=e.slug,m=!0);m&&await N.menuLocations.save(a),await N.menus.remove(g.slug)}else await N.menus.update(g.slug,e);if(z=Ie(e),D.value=!1,nt(),jt("#/menus"),E.toast("Saved.",{type:"success"}),x||e.slug!==g.slug)location.hash="#/menus/edit/"+encodeURIComponent(e.slug);else{g={...g,...e};for(const a of h)a.tool&&a.touched&&(a.tool={...a.tool,persisted:!0});re(),z=Ie(Ce()),Y(),ft(o.get(0),e.name||e.slug)}if(O)try{document.dispatchEvent(new CustomEvent("dm:sidebar-rebuild"))}catch{}}catch(a){E.toast(`Save failed: ${a.message||a}`,{type:"error"})}finally{ce.value=!1}}async function wt(){!D.peek()||!await E.confirm("Throw away the changes you have not saved?")||(ze(g),Y())}E.tabs(n("#me-tabs").get(0));const kt=M.applyBindings({dirty:D,saving:ce,problems:he,itemCount:Se},s,{methods:{save:()=>Ke(),discard:()=>wt(),addItem:()=>oe("item"),addSeparator:()=>oe("separator"),addSpacer:()=>oe("spacer"),addSwitcher:()=>oe("theme-switcher")}});i(()=>kt.dispose()),i(Ot(s,{position:"bottom"})),O&&n("#me-add-switcher").hide(),ft(o.get(0),x?"New menu":g.name||g.slug),Ue(o,{id:"menu-editor-back",icon:"arrow-left",title:"All menus",onClick:()=>{location.hash="#/menus"}}),Ue(o,{id:"menu-editor-locations",icon:"map-pin",title:"Menu locations",onClick:()=>{location.hash="#/menu-locations"}}),Ue(o,{id:"menu-editor-save",icon:"save",title:"Save (Ctrl+S)",onClick:()=>Ke()});const ot=e=>{if(!(!(e.ctrlKey||e.metaKey)||e.key!=="s")){if(e.preventDefault(),e.stopImmediatePropagation(),document.querySelector(".me-item-form")?.offsetParent){E.toast("Apply the item first (Ctrl+Enter), then Save.",{type:"info"});return}Ke()}};document.addEventListener("keydown",ot,!0),i(()=>document.removeEventListener("keydown",ot,!0));const at=()=>{if(!(!D.peek()||!We))try{S.set(J,{menu:We,base:z,at:new Date().toISOString()})}catch{}},st=e=>{D.peek()&&(at(),e.preventDefault(),e.returnValue="")};window.addEventListener("beforeunload",st),i(()=>window.removeEventListener("beforeunload",st)),K={path:k,dirty:()=>D.peek(),name:()=>n("#me-name").val()||g.name||g.slug||"new menu",dispose(){c=!0,at(),r.splice(0).reverse().forEach(e=>{try{e()}catch{}})}},I.scan(s);let Z=null;try{Z=S.get(J)}catch{}if(Z?.menu){nt();const e=Z.base&&Z.base!==z,t=Z.at?` (${Gt(Z.at)})`:"",a=x?"the new menu you started":`the menu "${He(g.name||g.slug)}"`,m=e?`You left unsaved changes to ${a}${t}, but the saved menu has changed since. Restore your version anyway?`:`You left unsaved changes to ${a}${t}. Restore them?`;await E.confirm(m)&&v()&&(ze({...Z.menu,meta:{...g.meta||{},...Z.menu.meta||{}}}),Y())}}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "1.6.43",
3
+ "version": "1.6.44",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -1 +1 @@
1
- [data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a){transition:color .18s ease,background-color .18s ease,text-shadow .18s ease,transform .18s ease,letter-spacing .18s ease,text-decoration-color .18s ease}.page-body :is([data-menu-hover],[data-menu-active]).dm-menu li>a{color:var(--dm-primary, inherit);text-decoration:none}[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]),[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]),#site-navbar[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{color:inherit!important;background-color:transparent!important;text-decoration:none!important;text-shadow:none!important;transform:none!important}[data-menu-hover=colour] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=colour] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;background-color:transparent!important;text-decoration:none!important}[data-menu-hover=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-hover=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-hover=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}[data-menu-hover=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:#00000029!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}[data-menu-hover=uppercase] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=uppercase] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{text-transform:uppercase!important;letter-spacing:.04em!important;background-color:transparent!important;text-decoration:none!important}:is([data-menu-hover=grow],[data-menu-hover=breathe]) :is(.dm-menu,.footer-nav) li>a{display:inline-block}[data-menu-hover=grow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=grow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{transform:scale(1.08)!important;background-color:transparent!important;text-decoration:none!important}@keyframes dm-menu-breathe{0%,to{opacity:1;transform:scale(1)}50%{opacity:.72;transform:scale(1.05)}}[data-menu-hover=breathe] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=breathe] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{animation:dm-menu-breathe 1.4s ease-in-out infinite!important;background-color:transparent!important;text-decoration:none!important}[data-menu-hover=glow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=glow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{text-shadow:0 0 8px color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 70%,transparent)!important;background-color:transparent!important;text-decoration:none!important}[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){box-shadow:none!important;text-decoration:none!important}[data-menu-active=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){font-weight:inherit!important;background-color:transparent!important}[data-menu-active=bold] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=bold] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){font-weight:700!important;background-color:transparent!important}[data-menu-active=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-active=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-active=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px)}[data-menu-active=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:#00000038!important;border-radius:var(--dm-radius-md, 6px)}[data-menu-active=pill] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=pill] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;color:#fff!important;border-radius:999px;padding-inline:.9em}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover],:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active]{transition:color .18s ease,background-color .18s ease,text-shadow .18s ease,transform .18s ease,letter-spacing .18s ease,text-decoration-color .18s ease}.page-body .dm-menu li>a:is([data-menu-item-hover],[data-menu-item-active]){color:var(--dm-primary, inherit);text-decoration:none}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none],:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none],#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none]:hover{color:inherit!important;background-color:transparent!important;text-decoration:none!important;text-shadow:none!important;transform:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=colour]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=colour]:hover{color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=underline]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=underline]:hover{background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=overline]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=overline]:hover{background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=background]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=background]:hover{background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=darken]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=darken]:hover{background-color:#00000029!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=uppercase]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=uppercase]:hover{text-transform:uppercase!important;letter-spacing:.04em!important;background-color:transparent!important;text-decoration:none!important}:is(.dm-menu,.footer-nav) li>a:is([data-menu-item-hover=grow],[data-menu-item-hover=breathe]){display:inline-block}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=grow]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=grow]:hover{transform:scale(1.08)!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=breathe]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=breathe]:hover{animation:dm-menu-breathe 1.4s ease-in-out infinite!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=glow]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=glow]:hover{text-shadow:0 0 8px color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 70%,transparent)!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active]:is(.active,.is-active,[aria-current=page]){box-shadow:none!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=none]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=none]:is(.active,.is-active,[aria-current=page]){font-weight:inherit!important;background-color:transparent!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=bold]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=bold]:is(.active,.is-active,[aria-current=page]){font-weight:700!important;background-color:transparent!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=underline]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=underline]:is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=overline]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=overline]:is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=background]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=background]:is(.active,.is-active,[aria-current=page]){background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px)}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=darken]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=darken]:is(.active,.is-active,[aria-current=page]){background-color:#00000038!important;border-radius:var(--dm-radius-md, 6px)}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=pill]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=pill]:is(.active,.is-active,[aria-current=page]){background-color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;color:#fff!important;border-radius:999px;padding-inline:.9em}@media(prefers-reduced-motion:reduce){[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover,:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover],:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover]:hover{transition:none;animation:none!important;transform:none!important}}html.dm-reduced-motion [data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),html.dm-reduced-motion [data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover,html.dm-reduced-motion #site-navbar[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover,html.dm-reduced-motion :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover],html.dm-reduced-motion :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover]:hover,html.dm-reduced-motion #site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover]:hover{transition:none;animation:none!important;transform:none!important}
1
+ [data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a){transition:color .18s ease,background-color .18s ease,text-shadow .18s ease,transform .18s ease,letter-spacing .18s ease,text-decoration-color .18s ease}.page-body :is([data-menu-hover],[data-menu-active]).dm-menu li>a{color:var(--dm-primary, inherit);text-decoration:none}[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]),[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]),#site-navbar[data-menu-hover=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{color:inherit!important;background-color:transparent!important;text-decoration:none!important;text-shadow:none!important;transform:none!important}[data-menu-hover=colour] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=colour] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;background-color:transparent!important;text-decoration:none!important}[data-menu-hover=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-hover=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-hover=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}[data-menu-hover=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{background-color:#00000029!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}[data-menu-hover=uppercase] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=uppercase] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{text-transform:uppercase!important;letter-spacing:.04em!important;background-color:transparent!important;text-decoration:none!important}:is([data-menu-hover=grow],[data-menu-hover=breathe]) :is(.dm-menu,.footer-nav) li>a{display:inline-block}[data-menu-hover=grow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=grow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{transform:scale(1.08)!important;background-color:transparent!important;text-decoration:none!important}@keyframes dm-menu-breathe{0%,to{opacity:1;transform:scale(1)}50%{opacity:.72;transform:scale(1.05)}}[data-menu-hover=breathe] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=breathe] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{animation:dm-menu-breathe 1.4s ease-in-out infinite!important;background-color:transparent!important;text-decoration:none!important}[data-menu-hover=glow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover,#site-navbar[data-menu-hover=glow] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-hover]):hover{text-shadow:0 0 8px color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 70%,transparent)!important;background-color:transparent!important;text-decoration:none!important}[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):is(.active,.is-active,[aria-current=page]){box-shadow:none!important;text-decoration:none!important}[data-menu-active=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=none] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){font-weight:inherit!important;background-color:transparent!important}[data-menu-active=bold] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=bold] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){font-weight:700!important;background-color:transparent!important}[data-menu-active=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=underline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-active=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=overline] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}[data-menu-active=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=background] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px)}[data-menu-active=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=darken] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:#00000038!important;border-radius:var(--dm-radius-md, 6px)}[data-menu-active=pill] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]),#site-navbar[data-menu-active=pill] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):not([data-menu-item-active]):is(.active,.is-active,[aria-current=page]){background-color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;color:#fff!important;border-radius:999px;padding-inline:.9em}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover],:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active]{transition:color .18s ease,background-color .18s ease,text-shadow .18s ease,transform .18s ease,letter-spacing .18s ease,text-decoration-color .18s ease}.page-body .dm-menu li>a:is([data-menu-item-hover],[data-menu-item-active]){color:var(--dm-primary, inherit);text-decoration:none}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none],:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none],#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=none]:hover{color:inherit!important;background-color:transparent!important;text-decoration:none!important;text-shadow:none!important;transform:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=colour]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=colour]:hover{color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=underline]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=underline]:hover{background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=overline]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=overline]:hover{background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=background]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=background]:hover{background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=darken]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=darken]:hover{background-color:#00000029!important;border-radius:var(--dm-radius-md, 6px);text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=uppercase]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=uppercase]:hover{text-transform:uppercase!important;letter-spacing:.04em!important;background-color:transparent!important;text-decoration:none!important}:is(.dm-menu,.footer-nav) li>a:is([data-menu-item-hover=grow],[data-menu-item-hover=breathe]){display:inline-block}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=grow]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=grow]:hover{transform:scale(1.08)!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=breathe]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=breathe]:hover{animation:dm-menu-breathe 1.4s ease-in-out infinite!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=glow]:hover,#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover=glow]:hover{text-shadow:0 0 8px color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 70%,transparent)!important;background-color:transparent!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active]:is(.active,.is-active,[aria-current=page]){box-shadow:none!important;text-decoration:none!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=none]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=none]:is(.active,.is-active,[aria-current=page]){font-weight:inherit!important;background-color:transparent!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=bold]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=bold]:is(.active,.is-active,[aria-current=page]){font-weight:700!important;background-color:transparent!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=underline]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=underline]:is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:underline!important;text-decoration-thickness:2px;text-underline-offset:4px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=overline]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=overline]:is(.active,.is-active,[aria-current=page]){background-color:transparent!important;text-decoration:overline!important;text-decoration-thickness:2px;text-decoration-color:var(--dm-menu-highlight, currentColor)!important}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=background]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=background]:is(.active,.is-active,[aria-current=page]){background-color:color-mix(in srgb,var(--dm-menu-highlight, var(--dm-primary, #0d6efd)) 18%,transparent)!important;border-radius:var(--dm-radius-md, 6px)}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=darken]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=darken]:is(.active,.is-active,[aria-current=page]){background-color:#00000038!important;border-radius:var(--dm-radius-md, 6px)}:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=pill]:is(.active,.is-active,[aria-current=page]),#site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-active=pill]:is(.active,.is-active,[aria-current=page]){background-color:var(--dm-menu-highlight, var(--dm-primary, #0d6efd))!important;color:#fff!important;border-radius:999px;padding-inline:.9em}@media(prefers-reduced-motion:reduce){[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover,:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover],:is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover]:hover{transition:none;animation:none!important;transform:none!important}}html.dm-reduced-motion [data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a),html.dm-reduced-motion [data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover,html.dm-reduced-motion #site-navbar[data-menu-hover] :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a):hover,html.dm-reduced-motion :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover],html.dm-reduced-motion :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover]:hover,html.dm-reduced-motion #site-navbar :is(.navbar-link,.navbar-dropdown-item,.navbar-dropdown-toggle,.sidebar-link,li>a)[data-menu-item-hover]:hover{transition:none;animation:none!important;transform:none!important}[data-menu-entrance] li{--dm-menu-i: 0;animation-duration:var(--dm-menu-entrance-duration, .4s);animation-timing-function:cubic-bezier(.22,.61,.36,1);animation-fill-mode:backwards;animation-delay:calc(var(--dm-menu-i) * var(--dm-menu-entrance-step, 60ms))}[data-menu-entrance] li:nth-child(2){--dm-menu-i: 1}[data-menu-entrance] li:nth-child(3){--dm-menu-i: 2}[data-menu-entrance] li:nth-child(4){--dm-menu-i: 3}[data-menu-entrance] li:nth-child(5){--dm-menu-i: 4}[data-menu-entrance] li:nth-child(6){--dm-menu-i: 5}[data-menu-entrance] li:nth-child(7){--dm-menu-i: 6}[data-menu-entrance] li:nth-child(8){--dm-menu-i: 7}[data-menu-entrance] li:nth-child(9){--dm-menu-i: 8}[data-menu-entrance] li:nth-child(10){--dm-menu-i: 9}[data-menu-entrance] li:nth-child(11){--dm-menu-i: 10}[data-menu-entrance] li:nth-child(12){--dm-menu-i: 11}[data-menu-entrance] li:nth-child(13){--dm-menu-i: 12}[data-menu-entrance] li:nth-child(14){--dm-menu-i: 13}[data-menu-entrance] li:nth-child(15){--dm-menu-i: 14}[data-menu-entrance] li:nth-child(16){--dm-menu-i: 15}[data-menu-entrance] li:nth-child(17){--dm-menu-i: 16}[data-menu-entrance] li:nth-child(18){--dm-menu-i: 17}[data-menu-entrance] li:nth-child(19){--dm-menu-i: 18}[data-menu-entrance] li:nth-child(20){--dm-menu-i: 19}[data-menu-entrance] li:nth-child(n+21){--dm-menu-i: 20}[data-menu-entrance] li:is(:hover,:focus-within){z-index:2}.dm-menu-floating[data-menu-entrance],#site-navbar.dm-nav-vertical[data-menu-entrance],#site-navbar[data-menu-entrance] .navbar-collapse{overflow-x:hidden}[data-menu-entrance=fade] li{animation-name:dm-menu-in-fade}[data-menu-entrance=slide-up] li{animation-name:dm-menu-in-slide-up}[data-menu-entrance=slide-down] li{animation-name:dm-menu-in-slide-down}[data-menu-entrance=slide-left] li{animation-name:dm-menu-in-slide-left}[data-menu-entrance=slide-right] li{animation-name:dm-menu-in-slide-right}[data-menu-entrance=zoom] li{animation-name:dm-menu-in-zoom}[data-menu-entrance=pop] li{animation-name:dm-menu-in-pop}[data-menu-entrance=flip] li{animation-name:dm-menu-in-flip}[data-menu-entrance=blur] li{animation-name:dm-menu-in-blur}@keyframes dm-menu-in-fade{0%{opacity:0}}@keyframes dm-menu-in-slide-up{0%{opacity:0;transform:translateY(14px)}}@keyframes dm-menu-in-slide-down{0%{opacity:0;transform:translateY(-14px)}}@keyframes dm-menu-in-slide-left{0%{opacity:0;transform:translate(24px)}}@keyframes dm-menu-in-slide-right{0%{opacity:0;transform:translate(-24px)}}@keyframes dm-menu-in-zoom{0%{opacity:0;transform:scale(.6)}}@keyframes dm-menu-in-pop{0%{opacity:0;transform:scale(.5)}70%{opacity:1;transform:scale(1.08)}to{opacity:1;transform:scale(1)}}@keyframes dm-menu-in-flip{0%{opacity:0;transform:perspective(400px) rotateX(-80deg);transform-origin:top center}to{transform-origin:top center}}@keyframes dm-menu-in-blur{0%{opacity:0;filter:blur(6px)}}@media(prefers-reduced-motion:reduce){[data-menu-entrance] li{animation:none!important}}html.dm-reduced-motion [data-menu-entrance] li{animation:none!important}
@@ -1 +1 @@
1
- export const PRESET_COLOUR_VARS={primary:"--dm-primary",success:"--dm-success",danger:"--dm-danger",warning:"--dm-warning",info:"--dm-info",neutral:"--dm-text-muted"},PRESET_COLOUR_FALLBACKS={primary:"#0d6efd",success:"#198754",danger:"#dc3545",warning:"#ffc107",info:"#0dcaf0",neutral:"#6c757d"};const l=/^#[0-9a-fA-F]{6}$/;export function colourToCss(t){return typeof t!="string"?"":PRESET_COLOUR_VARS[t]?`var(${PRESET_COLOUR_VARS[t]}, ${PRESET_COLOUR_FALLBACKS[t]})`:l.test(t)?t:""}export const FLOAT_ANCHORS=["TL","TR","BL","BR","L","R"],FLOAT_DEFAULTS={anchor:"TL",offsetX:16,offsetY:16,zIndex:150},FLOAT_SHADOWS={none:"none",sm:"var(--dm-shadow-sm)",md:"var(--dm-shadow-md)",lg:"var(--dm-shadow-lg)",xl:"var(--dm-shadow-xl)"};function s(t,e,o,r){const n=Number(t);return Number.isFinite(n)?Math.min(r,Math.max(o,Math.round(n))):e}function d(t){const e=[];if(t.radius!=null&&t.radius!==""&&e.push(`border-radius:${s(t.radius,8,0,48)}px`),t.shadow!=null&&t.shadow!==""&&Object.prototype.hasOwnProperty.call(FLOAT_SHADOWS,t.shadow)&&e.push(`box-shadow:${FLOAT_SHADOWS[t.shadow]}`),t.accent&&colourToCss(t.accent)){const o=colourToCss(t.accent);e.push(`--dm-menu-accent:${o}`,`border-color:${o}`)}return t.opacity!=null&&t.opacity!==""&&e.push(`--dm-menu-panel-opacity:${s(t.opacity,100,20,100)/100}`),e}export function floatToCss(t){if(!t||t.position!=="floating")return"";const e=t.float&&typeof t.float=="object"&&!Array.isArray(t.float)?t.float:{},o=FLOAT_ANCHORS.includes(e.anchor)?e.anchor:FLOAT_DEFAULTS.anchor,r=s(e.offsetX,FLOAT_DEFAULTS.offsetX,0,4e3),n=s(e.offsetY,FLOAT_DEFAULTS.offsetY,0,4e3),a=["position:fixed",`z-index:${s(e.zIndex,FLOAT_DEFAULTS.zIndex,0,2147483647)}`];return o==="L"||o==="R"?(a.push("top:50%","transform:translateY(-50%)"),a.push(o==="L"?`left:${r}px`:`right:${r}px`)):(a.push(o[0]==="T"?`top:${n}px`:`bottom:${n}px`),a.push(o[1]==="L"?`left:${r}px`:`right:${r}px`)),e.width!=null&&e.width!==""&&a.push(`width:${s(e.width,260,120,600)}px`),a.push(`max-height:calc(100vh - ${o==="L"||o==="R"?32:n*2}px)`),a.push(...d(e)),a.join(";")}export const FLOAT_FLAGS=["collapsible","collapsed","movable","resizable"];export function floatBehaviour(t){const e={collapsible:!1,collapsed:!1,movable:!1,resizable:!1,chrome:!1,title:""};if(!t||t.position!=="floating")return e;const o=t.float&&typeof t.float=="object"&&!Array.isArray(t.float)?t.float:{},r={collapsible:!!o.collapsible,collapsed:!!o.collapsible&&!!o.collapsed,movable:!!o.movable,resizable:!!o.resizable},n=r.collapsible||r.movable,i=typeof o.title=="string"&&o.title!==""?o.title:t.name||"";return{...r,chrome:n,title:n?i:""}}export function applyFloat(t,e){const o=floatToCss(e);if(!t||!o)return!1;t.style.cssText+=";"+o,t.classList.add("dm-menu-floating"),e.slug&&!t.hasAttribute("data-menu")&&t.setAttribute("data-menu",e.slug),e.float?.anchor&&t.setAttribute("data-float-anchor",e.float.anchor);const r=floatBehaviour(e);for(const n of FLOAT_FLAGS)n!=="collapsed"&&r[n]&&t.setAttribute(`data-float-${n}`,"1");return r.collapsed&&t.setAttribute("data-float-collapsed","1"),r.title&&t.setAttribute("data-float-title",r.title),!0}export function makeBadgeEl(t){if(!t||t.text==null||t.text==="")return null;const e=document.createElement("span");e.className="dm-menu-badge",e.textContent=String(t.text);const o=t.variant?colourToCss(t.variant):"";return o&&(e.style.background=o,e.style.color="var(--dm-text-inverse, #fff)"),e}export function applyColour(t,e){const o=colourToCss(e);o&&(t.style.color=o)}export function applyPill(t,e){if(!e)return;t.classList.add("dm-nav-pill");const o=e.variant?colourToCss(e.variant):"";e.style==="outline"?(t.classList.add("dm-nav-pill--outline"),o&&(t.style.borderColor=o,t.style.color=o)):o&&(t.style.background=o,t.style.color="#fff")}export const MENU_ALIGN=["left","centre","right","spread"];export function menuAlign(t){const e=t&&t.align;return MENU_ALIGN.includes(e)?e:""}export const HIGHLIGHT_HOVER=["none","colour","underline","overline","background","darken","uppercase","grow","breathe","glow"],HIGHLIGHT_ACTIVE=["none","bold","underline","overline","background","darken","pill"],HIGHLIGHT_HOVER_LABELS={none:"None - no change on hover",colour:"Colour change",underline:"Underline",overline:"Overline",background:"Background tint",darken:"Darkened",uppercase:"Uppercase",grow:"Grow",breathe:"Breathe",glow:"Glow"},HIGHLIGHT_ACTIVE_LABELS={none:"None - not marked at all",bold:"Bold",underline:"Underline",overline:"Overline",background:"Background tint",darken:"Darkened",pill:"Filled pill"},LEGACY_STYLE_HOVER={none:"none",underline:"underline",overline:"overline",transform:"uppercase","text-transform":"uppercase",breathe:"breathe"},LEGACY_STYLE_ACTIVE={none:"none",darken:"darken",background:"background","background-color":"background",underline:"underline",overline:"overline"};export function legacyStyleHighlight(t){const e=t&&typeof t=="object"&&!Array.isArray(t)?t:{};return{hover:LEGACY_STYLE_HOVER[e.hover]||"",active:LEGACY_STYLE_ACTIVE[e.active]||""}}export function highlightAttrs(t){const e=t&&t.highlight&&typeof t.highlight=="object"&&!Array.isArray(t.highlight)?t.highlight:{},o=legacyStyleHighlight(t&&t.style);return{hover:HIGHLIGHT_HOVER.includes(e.hover)?e.hover:o.hover,active:HIGHLIGHT_ACTIVE.includes(e.active)?e.active:o.active,accent:e.accent?colourToCss(e.accent):""}}export function applyHighlight(t,e){if(!t)return!1;const{hover:o,active:r,accent:n}=highlightAttrs(e);return o&&t.setAttribute("data-menu-hover",o),r&&t.setAttribute("data-menu-active",r),n&&t.style.setProperty("--dm-menu-highlight",n),!!(o||r||n)}export function itemHighlightAttrs(t){const e=t&&t.highlight&&typeof t.highlight=="object"&&!Array.isArray(t.highlight)?t.highlight:{};return{hover:HIGHLIGHT_HOVER.includes(e.hover)?e.hover:"",active:HIGHLIGHT_ACTIVE.includes(e.active)?e.active:"",accent:e.accent?colourToCss(e.accent):""}}export function applyItemHighlight(t,e){if(!t)return!1;const{hover:o,active:r,accent:n}=itemHighlightAttrs(e);return o&&t.setAttribute("data-menu-item-hover",o),r&&t.setAttribute("data-menu-item-active",r),n&&t.style.setProperty("--dm-menu-highlight",n),!!(o||r||n)}function c(t){if(typeof t!="string"||!t)return"";const e=t.split("#")[0].split("?")[0];return e.startsWith("/")?e.length>1&&e.endsWith("/")?e.slice(0,-1):e:""}export function isCurrentItem(t,e){const o=c(t),r=c(e);return!!o&&!!r&&o===r}export{CSS_CLASS_RE,CSS_CLASS_MAX,CSS_CLASS_MAX_LEN,cssClasses,cssClassProblems,normaliseCssClasses,applyClasses}from"./css-classes.mjs";
1
+ export const PRESET_COLOUR_VARS={primary:"--dm-primary",success:"--dm-success",danger:"--dm-danger",warning:"--dm-warning",info:"--dm-info",neutral:"--dm-text-muted"},PRESET_COLOUR_FALLBACKS={primary:"#0d6efd",success:"#198754",danger:"#dc3545",warning:"#ffc107",info:"#0dcaf0",neutral:"#6c757d"};const c=/^#[0-9a-fA-F]{6}$/;export function colourToCss(t){return typeof t!="string"?"":PRESET_COLOUR_VARS[t]?`var(${PRESET_COLOUR_VARS[t]}, ${PRESET_COLOUR_FALLBACKS[t]})`:c.test(t)?t:""}export const FLOAT_ANCHORS=["TL","TR","BL","BR","L","R"],FLOAT_DEFAULTS={anchor:"TL",offsetX:16,offsetY:16,zIndex:150},FLOAT_SHADOWS={none:"none",sm:"var(--dm-shadow-sm)",md:"var(--dm-shadow-md)",lg:"var(--dm-shadow-lg)",xl:"var(--dm-shadow-xl)"};function i(t,e,o,n){const r=Number(t);return Number.isFinite(r)?Math.min(n,Math.max(o,Math.round(r))):e}function d(t){const e=[];if(t.radius!=null&&t.radius!==""&&e.push(`border-radius:${i(t.radius,8,0,48)}px`),t.shadow!=null&&t.shadow!==""&&Object.prototype.hasOwnProperty.call(FLOAT_SHADOWS,t.shadow)&&e.push(`box-shadow:${FLOAT_SHADOWS[t.shadow]}`),t.accent&&colourToCss(t.accent)){const o=colourToCss(t.accent);e.push(`--dm-menu-accent:${o}`,`border-color:${o}`)}return t.opacity!=null&&t.opacity!==""&&e.push(`--dm-menu-panel-opacity:${i(t.opacity,100,20,100)/100}`),e}export function floatToCss(t){if(!t||t.position!=="floating")return"";const e=t.float&&typeof t.float=="object"&&!Array.isArray(t.float)?t.float:{},o=FLOAT_ANCHORS.includes(e.anchor)?e.anchor:FLOAT_DEFAULTS.anchor,n=i(e.offsetX,FLOAT_DEFAULTS.offsetX,0,4e3),r=i(e.offsetY,FLOAT_DEFAULTS.offsetY,0,4e3),a=["position:fixed",`z-index:${i(e.zIndex,FLOAT_DEFAULTS.zIndex,0,2147483647)}`];return o==="L"||o==="R"?(a.push("top:50%","transform:translateY(-50%)"),a.push(o==="L"?`left:${n}px`:`right:${n}px`)):(a.push(o[0]==="T"?`top:${r}px`:`bottom:${r}px`),a.push(o[1]==="L"?`left:${n}px`:`right:${n}px`)),e.width!=null&&e.width!==""&&a.push(`width:${i(e.width,260,120,600)}px`),a.push(`max-height:calc(100vh - ${o==="L"||o==="R"?32:r*2}px)`),a.push(...d(e)),a.join(";")}export const FLOAT_FLAGS=["collapsible","collapsed","movable","resizable"];export function floatBehaviour(t){const e={collapsible:!1,collapsed:!1,movable:!1,resizable:!1,chrome:!1,title:""};if(!t||t.position!=="floating")return e;const o=t.float&&typeof t.float=="object"&&!Array.isArray(t.float)?t.float:{},n={collapsible:!!o.collapsible,collapsed:!!o.collapsible&&!!o.collapsed,movable:!!o.movable,resizable:!!o.resizable},r=n.collapsible||n.movable,s=typeof o.title=="string"&&o.title!==""?o.title:t.name||"";return{...n,chrome:r,title:r?s:""}}export function applyFloat(t,e){const o=floatToCss(e);if(!t||!o)return!1;t.style.cssText+=";"+o,t.classList.add("dm-menu-floating"),e.slug&&!t.hasAttribute("data-menu")&&t.setAttribute("data-menu",e.slug),e.float?.anchor&&t.setAttribute("data-float-anchor",e.float.anchor);const n=floatBehaviour(e);for(const r of FLOAT_FLAGS)r!=="collapsed"&&n[r]&&t.setAttribute(`data-float-${r}`,"1");return n.collapsed&&t.setAttribute("data-float-collapsed","1"),n.title&&t.setAttribute("data-float-title",n.title),!0}export function makeBadgeEl(t){if(!t||t.text==null||t.text==="")return null;const e=document.createElement("span");e.className="dm-menu-badge",e.textContent=String(t.text);const o=t.variant?colourToCss(t.variant):"";return o&&(e.style.background=o,e.style.color="var(--dm-text-inverse, #fff)"),e}export function applyColour(t,e){const o=colourToCss(e);o&&(t.style.color=o)}export function applyPill(t,e){if(!e)return;t.classList.add("dm-nav-pill");const o=e.variant?colourToCss(e.variant):"";e.style==="outline"?(t.classList.add("dm-nav-pill--outline"),o&&(t.style.borderColor=o,t.style.color=o)):o&&(t.style.background=o,t.style.color="#fff")}export const MENU_ALIGN=["left","centre","right","spread"];export function menuAlign(t){const e=t&&t.align;return MENU_ALIGN.includes(e)?e:""}export const HIGHLIGHT_HOVER=["none","colour","underline","overline","background","darken","uppercase","grow","breathe","glow"],HIGHLIGHT_ACTIVE=["none","bold","underline","overline","background","darken","pill"],HIGHLIGHT_HOVER_LABELS={none:"None - no change on hover",colour:"Colour change",underline:"Underline",overline:"Overline",background:"Background tint",darken:"Darkened",uppercase:"Uppercase",grow:"Grow",breathe:"Breathe",glow:"Glow"},HIGHLIGHT_ACTIVE_LABELS={none:"None - not marked at all",bold:"Bold",underline:"Underline",overline:"Overline",background:"Background tint",darken:"Darkened",pill:"Filled pill"},LEGACY_STYLE_HOVER={none:"none",underline:"underline",overline:"overline",transform:"uppercase","text-transform":"uppercase",breathe:"breathe"},LEGACY_STYLE_ACTIVE={none:"none",darken:"darken",background:"background","background-color":"background",underline:"underline",overline:"overline"};export function legacyStyleHighlight(t){const e=t&&typeof t=="object"&&!Array.isArray(t)?t:{};return{hover:LEGACY_STYLE_HOVER[e.hover]||"",active:LEGACY_STYLE_ACTIVE[e.active]||""}}export function highlightAttrs(t){const e=t&&t.highlight&&typeof t.highlight=="object"&&!Array.isArray(t.highlight)?t.highlight:{},o=legacyStyleHighlight(t&&t.style);return{hover:HIGHLIGHT_HOVER.includes(e.hover)?e.hover:o.hover,active:HIGHLIGHT_ACTIVE.includes(e.active)?e.active:o.active,accent:e.accent?colourToCss(e.accent):""}}export function applyHighlight(t,e){if(!t)return!1;const{hover:o,active:n,accent:r}=highlightAttrs(e);return o&&t.setAttribute("data-menu-hover",o),n&&t.setAttribute("data-menu-active",n),r&&t.style.setProperty("--dm-menu-highlight",r),!!(o||n||r)}export function itemHighlightAttrs(t){const e=t&&t.highlight&&typeof t.highlight=="object"&&!Array.isArray(t.highlight)?t.highlight:{};return{hover:HIGHLIGHT_HOVER.includes(e.hover)?e.hover:"",active:HIGHLIGHT_ACTIVE.includes(e.active)?e.active:"",accent:e.accent?colourToCss(e.accent):""}}export function applyItemHighlight(t,e){if(!t)return!1;const{hover:o,active:n,accent:r}=itemHighlightAttrs(e);return o&&t.setAttribute("data-menu-item-hover",o),n&&t.setAttribute("data-menu-item-active",n),r&&t.style.setProperty("--dm-menu-highlight",r),!!(o||n||r)}function l(t){if(typeof t!="string"||!t)return"";const e=t.split("#")[0].split("?")[0];return e.startsWith("/")?e.length>1&&e.endsWith("/")?e.slice(0,-1):e:""}export function isCurrentItem(t,e){const o=l(t),n=l(e);return!!o&&!!n&&o===n}export const ENTRANCE_ANIMATIONS=["fade","slide-up","slide-down","slide-left","slide-right","zoom","pop","flip","blur"],ENTRANCE_ANIMATION_LABELS={fade:"Fade in","slide-up":"Slide up","slide-down":"Slide down","slide-left":"Slide in from the right","slide-right":"Slide in from the left",zoom:"Zoom in",pop:"Pop (zoom with a bounce)",flip:"Flip down",blur:"Blur into focus"},ENTRANCE_DEFAULTS={animation:"fade",stagger:60,duration:400},ENTRANCE_LIMITS={stagger:[0,1e3],duration:[50,3e3]};export function entranceAttrs(t){const e=t&&t.entrance;if(!e||typeof e!="object"||Array.isArray(e)||e.enabled!==!0)return null;const o=n=>{const r=Number(e[n]),[s,a]=ENTRANCE_LIMITS[n];return e[n]!==""&&e[n]!=null&&Number.isFinite(r)&&r>=s&&r<=a?Math.round(r):ENTRANCE_DEFAULTS[n]};return{animation:ENTRANCE_ANIMATIONS.includes(e.animation)?e.animation:ENTRANCE_DEFAULTS.animation,stagger:o("stagger"),duration:o("duration")}}export function entranceStyle(t){return t?`--dm-menu-entrance-step:${t.stagger}ms;--dm-menu-entrance-duration:${t.duration}ms`:""}export function applyEntrance(t,e){if(!t)return!1;const o=entranceAttrs(e);return o?(t.style.setProperty("--dm-menu-entrance-step",`${o.stagger}ms`),t.style.setProperty("--dm-menu-entrance-duration",`${o.duration}ms`),t.setAttribute("data-menu-entrance",o.animation),!0):!1}export{CSS_CLASS_RE,CSS_CLASS_MAX,CSS_CLASS_MAX_LEN,cssClasses,cssClassProblems,normaliseCssClasses,applyClasses}from"./css-classes.mjs";
package/public/js/site.js CHANGED
@@ -1 +1 @@
1
- import{decodeBase64Json as P}from"/public/js/utf8-base64.mjs";import{makeBadgeEl as Y,applyColour as J,applyPill as te,applyFloat as oe,applyHighlight as R,applyItemHighlight as ne,itemHighlightAttrs as ae,isCurrentItem as X,menuAlign as se,applyClasses as O,cssClasses as W}from"/public/js/menu-decor.mjs?v=20261009-hover-darken";import{initFloatingMenus as ie}from"/public/js/menu-float.js?v=20260829-float-panel";import{enhancePickerFields as U,markInvalidFields as G,showValidationPopup as K}from"/public/js/forms.js?v=20261009-form-classes";import{buildWizardSteps as re}from"/public/js/form-steps.mjs";import{applyFormClasses as Q,applySubmitButtons as ce,applyWizardButtons as le}from"/public/js/form-submit.mjs";document.addEventListener("click",h=>{const l=h.target?.closest?.(".dm-banner__dismiss");l&&(h.preventDefault(),l.closest(".dm-banner")?.remove())}),$(()=>{const h=window.__CMS_NAV__||{},l=window.__CMS_SITE__||{};if(l.autoTheme?.enabled){let o=function(e){const a=(e||"07:00").split(":");return+a[0]*60+(+a[1]||0)},s=function(){const e=new Date,a=e.getHours()*60+e.getMinutes();return a>=o(n.dayStart)&&a<o(n.nightStart)?n.dayTheme:n.nightTheme},t=function(e){const a=n.apply&&n.apply[e]||{theme:e,custom:""};Domma.theme.set(a.theme);for(const u of[...document.body.classList])u.startsWith("dm-custom-")&&document.body.classList.remove(u);a.custom&&document.body.classList.add(a.custom)};const n=l.autoTheme;t(s()),setInterval(()=>t(s()),6e4)}const x=$("#site-navbar");if(x.length&&h.brand){let s=function(d,m=0){return Array.isArray(d)?d.filter(p=>!(p&&(p.type==="spacer"||p.type==="theme-switcher"))).filter(p=>!(p&&p.type==="separator"&&m===0)).map(p=>p&&p.type==="separator"?{divider:!0}:Array.isArray(p?.items)?{...p,items:s(p.items,m+1)}:p):d},t=function(d){return Array.isArray(d)?d.filter(m=>!(m&&(m.type==="separator"||m.type==="spacer"||m.type==="theme-switcher"))):[]};const n={...h.brand},o=n.size&&n.size!=="md"?` navbar-brand-${n.size}`:"";if(n.logo||n.icon||n.tagline){let d="";n.logo?d+=`<img src="${n.logo}" class="navbar-brand-logo" alt="${n.text||""}">`:n.icon&&(d+=`<span data-icon="${n.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),n.text&&(d+=`<span class="navbar-brand-text${o}">${n.text}</span>`),n.tagline&&(d+=`<small class="navbar-brand-tagline">${n.tagline}</small>`),n.html=d}else o&&n.text&&(n.html=`<span class="navbar-brand-text${o}">${n.text}</span>`);const e=h.position==="floating",a=h.orientation==="vertical";Domma.elements.navbar("#site-navbar",{brand:n,items:s(h.items||[]),variant:h.variant||"dark",position:e?"static":h.position||"sticky",collapsible:!0,appearOnHover:!!h.appearOnHover}),Domma.icons.scan("#site-navbar");const u=x.get(0);u.classList.add(`dm-nav-align-${se(h)||"centre"}`),a&&x.get(0).classList.add("dm-nav-vertical",h.side==="right"?"dm-nav-vertical-right":"dm-nav-vertical-left");const f=h.dock||{};a&&!e&&de(u,h.side==="right"),!a&&f.hideOnScroll&&me(u),R(u,h),O(u,h.class),e&&(oe(x.get(0),h),ie(x.get(0).parentNode||document));const i=u.querySelector(".navbar-toggle"),c=u.querySelector(".navbar-collapse");if(i&&c){let d=null;const m=()=>{c.classList.contains("show")&&i.click()},p=()=>{d&&(d.remove(),d=null),document.body.classList.remove("dm-drawer-open")},y=()=>{d||(d=document.createElement("div"),d.className="dm-navbar-backdrop",d.addEventListener("click",m),document.body.appendChild(d),document.body.classList.add("dm-drawer-open"))};i.addEventListener("click",()=>{requestAnimationFrame(()=>{c.classList.contains("show")?y():p()})}),c.addEventListener("click",C=>{C.target.closest("a")&&requestAnimationFrame(p)}),document.addEventListener("keydown",C=>{C.key==="Escape"&&c.classList.contains("show")&&m()})}const g=u.querySelector(".navbar-nav");if(g){const d=Array.from(g.children);let m=0;for(const p of h.items||[])if(!(p&&p.type==="separator")){if(p&&p.type==="spacer"){const y=document.createElement("li"),C=["xs","sm","md","lg","xl","flex"].includes(p.size)?p.size:"md";y.className=`dm-menu-spacer dm-menu-spacer--${C}`,y.setAttribute("aria-hidden","true"),g.insertBefore(y,d[m]||null);continue}if(p&&p.type==="theme-switcher"){const y=document.createElement("li");y.className="dm-menu-theme-switcher";const C=document.createElement("span");C.dataset.themeSwitcher="menu",C.dataset.position="inline",y.appendChild(C),g.insertBefore(y,d[m]||null);continue}m++}window.CMSThemeSwitcher?.scan(g)}const b=t(h.items||[]);u.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(d=>{const m=b[parseInt(d.dataset.index,10)];if(!m)return;const p=d.dataset.subindex!=null,y=p&&Array.isArray(m.items)?m.items[parseInt(d.dataset.subindex,10)]:m;if(!y)return;y.colour&&J(d,y.colour),y.pill&&!p&&te(d,y.pill),ne(d,y),O(d.closest("li"),y.class);const C=Y(y.badge);C&&d.appendChild(C),X(y.url,location.pathname)&&(d.classList.add("active"),d.setAttribute("aria-current","page"))})}const v=$("#site-footer");if(v.length){let e=function(r){return String(r??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},a=function(r){return e(r).replace(/'/g,"&#39;")},u=function(r){if(r&&r.type==="separator")return'<li class="footer-sep"><hr></li>';if(r&&r.type==="spacer")return`<li class="dm-menu-spacer dm-menu-spacer--${["xs","sm","md","lg","xl","flex"].includes(r.size)?r.size:"md"}" aria-hidden="true"></li>`;if(r&&r.type==="theme-switcher")return'<li class="dm-menu-theme-switcher"><span data-theme-switcher="menu" data-position="inline"></span></li>';const A=a(r.url||"#"),L=e(r.text||""),q=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(u).join("")}</ul>`:"",N=ae(r),Z=[N.hover&&` data-menu-item-hover="${a(N.hover)}"`,N.active&&` data-menu-item-active="${a(N.active)}"`].filter(Boolean).join(""),ee=N.accent?` style="--dm-menu-highlight:${a(N.accent)}"`:"",V=W(r.class).join(" ");return`<li${V?` class="${a(V)}"`:""}><a href="${A}"${Z}${ee}>${L}</a>${q}</li>`},f=function(){if(!l.footer)return"";const r=Object.keys(o).filter(L=>n[L]);if(!r.length)return"";const A=W(l.footer.socialClass).join(" ");return`<div class="footer-social">${r.map(L=>{const{label:q,svg:N}=o[L];return`<a href="${n[L]}" target="_blank" rel="noopener noreferrer" aria-label="${q}" class="footer-social-link${A?` ${a(A)}`:""}">${N}</a>`}).join("")}</div>`},b=function(r){if(!r||r.type==="separator"||r.type==="spacer")return"";if(r.type==="theme-switcher")return`<li class="cms-footer-col">${u(r).replace(/^<li[^>]*>|<\/li>$/g,"")}</li>`;const A=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(u).join("")}</ul>`:"",L=g(r)?`<span class="cms-footer-col-title">${e(r.text||"")}</span>`:`<a class="cms-footer-col-title" href="${a(r.url||"#")}">${e(r.text||"")}</a>`,q=["cms-footer-col",...W(r.class)].join(" ");return`<li class="${a(q)}">${L}${A}</li>`},m=function(r,A,L=!1){return(r||[]).forEach(q=>{q&&(q.type==="separator"||q.type==="spacer"||q.type==="theme-switcher")||(L&&g(q)||A.push(q),Array.isArray(q.items)&&q.items.length&&m(q.items,A))}),A};const n=l.social||{},o={twitter:{label:"X / Twitter",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.742l7.73-8.835L1.254 2.25H8.08l4.259 5.629L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>'},facebook:{label:"Facebook",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'},instagram:{label:"Instagram",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>'},linkedin:{label:"LinkedIn",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'},github:{label:"GitHub",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>'},youtube:{label:"YouTube",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/></svg>'}};let s='<div class="footer-inner container">';const t=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""},i=["columns","row"].includes(l.footer?.layout)?l.footer.layout:"auto",c=i==="columns"||i==="auto"&&t.primary.some(r=>Array.isArray(r?.items)&&r.items.length),g=r=>c&&!r.url&&Array.isArray(r.items)&&r.items.length>0;if(c){const r=h.brand||{},A=r.text||l.title||"",L=r.logo?`<img src="${a(r.logo)}" class="cms-footer-brand-logo" alt="">`:r.icon?'<span class="cms-footer-brand-icon"></span>':"",q=String(l.footer?.blurb||"").trim();s='<div class="footer-inner footer-inner--columns container"><div class="cms-footer-top">',s+=`<div class="cms-footer-brand">${A||L?`<a class="cms-footer-brand-name" href="${a(r.url||"/")}">${L}<span>${e(A)}</span></a>`:""}${q?`<p class="cms-footer-blurb">${e(q)}</p>`:""}${f()}</div>`,t.primary.length&&(s+=`<nav class="footer-nav footer-nav--primary footer-nav--columns" aria-label="Footer"><ul>${t.primary.map(b).join("")}</ul></nav>`),s+='</div><div class="cms-footer-bottom">',t.copyright&&(s+=`<p class="cms-footer-copyright">${e(t.copyright)}</p>`),t.legal.length&&(s+=`<nav class="footer-nav footer-nav--legal" aria-label="Legal"><ul>${t.legal.map(u).join("")}</ul></nav>`),s+="</div>"}else t.copyright&&(s+=`<p>${e(t.copyright)}</p>`),t.primary.length&&(s+=`<nav class="footer-nav footer-nav--primary"><ul>${t.primary.map(u).join("")}</ul></nav>`),t.legal.length&&(s+=`<nav class="footer-nav footer-nav--legal"><ul>${t.legal.map(u).join("")}</ul></nav>`),s+=f();s+="</div>",v.html(s),window.CMSThemeSwitcher?.scan(v.get(0));const d=v.get(0).querySelector(".cms-footer-brand-icon");d&&h.brand?.icon&&d.setAttribute("data-icon",h.brand.icon),O(v.get(0),l.footer?.class);const p=[...m(t.primary,[],!0),...m(t.legal,[])];v.get(0).querySelectorAll(".footer-nav a").forEach((r,A)=>{const L=p[A];if(!L)return;L.colour&&J(r,L.colour);const q=Y(L.badge);q&&r.appendChild(q),X(L.url,location.pathname)&&(r.classList.add("is-active"),r.setAttribute("aria-current","page"))}),R(v.get(0).querySelector(".footer-nav--primary"),{highlight:t.primaryHighlight}),R(v.get(0).querySelector(".footer-nav--legal"),{highlight:t.legalHighlight}),O(v.get(0).querySelector(".footer-nav--primary"),t.primaryClass),O(v.get(0).querySelector(".footer-nav--legal"),t.legalClass);const C=l.footer?.showMotionToggle!==!1,M=S.get("reduced_motion"),D=l.footer?.motionDefault,z=M!=null?!!M:D==="on"?!0:D==="off"?!1:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),B=l.footer?.motionControl==="checkbox",I=v.get(0).querySelector(".cms-footer-bottom")||v.get(0).querySelector(".footer-inner");if(C&&I){const r=document.createElement("input");r.type="checkbox",r.className=B?"footer-motion-checkbox":"form-switch-input",r.id="dm-motion-switch",r.checked=z,r.addEventListener("change",function(){S.set("reduced_motion",this.checked),window.location.reload()});const A=document.createElement("span");A.className=B?"footer-motion-label":"form-switch-label",A.textContent="Reduce motion";const L=document.createElement("label");L.className=B?"footer-motion-check":"form-switch footer-motion-switch",L.title="Reduce motion",L.appendChild(r),L.appendChild(A),I.appendChild(L)}}const k=document.getElementById("site-sidebar");k&&ue(k),Domma.icons.scan(),Domma.syntax?.scan&&Domma.syntax.scan();const w=$(".page-body");if(w.length){w.find(".accordion").each(function(){Domma.elements.accordion(this,{allowMultiple:this.dataset.multi==="true"})}),w.find(".tabs").each(function(){Domma.elements.tabs(this)}),w.find(".carousel").each(function(){const n={primary:"--dm-primary",secondary:"--dm-secondary",accent:"--dm-primary",text:"--dm-text",surface:"--dm-surface",background:"--dm-background",success:"--dm-success",warning:"--dm-warning",danger:"--dm-danger",info:"--dm-info"},o=f=>{const i=String(f||"").trim();return i?n[i.toLowerCase()]?`var(${n[i.toLowerCase()]})`:CSS.supports("color",i)?i:"":""},s=o(this.dataset.background),t=o(this.dataset.arrowBackground),e=o(this.dataset.arrowColor);s&&(this.style.setProperty("--dm-carousel-background",s),this.classList.add("dm-carousel-custom-background")),t&&this.style.setProperty("--dm-carousel-arrow-background",t),e&&this.style.setProperty("--dm-carousel-arrow-color",e);const a=["top","middle","bottom"].includes(this.dataset.arrowPosition)?this.dataset.arrowPosition:"middle";this.classList.add(`dm-carousel-arrows-${a}`);const u={autoplay:this.dataset.autoplay==="true",interval:parseInt(this.dataset.interval,10)||5e3,loop:this.dataset.loop!=="false",animation:this.dataset.animation||"slide",heightMode:this.dataset.heightMode==="average"?"average":"crop"};if(this.dataset.height){const f=Number(this.dataset.height);Number.isFinite(f)&&f>0&&(u.height=f)}if(this.dataset.animationDuration){const f=parseInt(this.dataset.animationDuration,10);Number.isFinite(f)&&(u.animationDuration=f)}this.dataset.animationEasing&&(u.animationEasing=this.dataset.animationEasing),this.dataset.ctx&&(this._dmCtxSlides=Array.from(this.querySelectorAll(".carousel-slide")).map(f=>f.cloneNode(!0)),this._dmCarouselOpts=u),this._dmCarousel=Domma.elements.carousel(this,u)}),w.find(".dm-countdown").each(function(){const n={autoStart:!0},o=String(this.dataset.format||"").trim(),s=String(this.dataset.to||"").trim(),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(s),e=t?new Date(+t[1],+t[2]-1,+t[3]).getTime():s?new Date(s).getTime():NaN;Number.isFinite(e)?n.duration=Math.max(0,e-Date.now()):this.dataset.duration&&(n.duration=(parseInt(this.dataset.duration,10)||0)*1e3);const a=/^dd:/i.test(o);n.format=a?"hh:mm:ss":o||(n.duration>=36e5?"hh:mm:ss":"mm:ss");const u=this,f=c=>String(c).padStart(2,"0"),i=c=>{const g=Math.max(0,Math.floor(c/1e3)),b=u.querySelector(".dm-timer-time");b&&(b.textContent=`${f(Math.floor(g/86400))}:${f(Math.floor(g%86400/3600))}:${f(Math.floor(g%3600/60))}:${f(g%60)}`)};a&&(n.onTick=i),Domma.elements.timer(this,n),a&&i(n.duration||0)}),w.find("[data-tooltip]").each(function(){Domma.elements.tooltip(this,{content:$(this).data("tooltip"),position:$(this).data("tooltip-position")||"top"})}),w.find(".dm-progression").each(function(){const n=Array.from(this.querySelectorAll(".dm-progression-item")).map(t=>{const e={title:t.querySelector(".dm-progression-item-title")?.textContent?.trim()||"",description:t.querySelector(".dm-progression-item-body")?.innerHTML?.trim()||""};return t.dataset.date&&(e.date=t.dataset.date),t.dataset.status&&(e.status=t.dataset.status),t.dataset.eventIcon&&(e.icon=t.dataset.eventIcon),t.dataset.entryId&&(e._entryId=t.dataset.entryId),e}),o=this.dataset.layout==="centred"?"centered":this.dataset.layout||"vertical",s=Domma.elements.progression(this,{layout:o,theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0,allowHtml:!0,...n.length?{items:n}:{}});if((this.dataset.mode||"timeline")==="timeline"){const t={completed:{label:"Completed",icon:"check-circle",tone:"success"},planned:{label:"Planned",icon:"circle",tone:"secondary"},"in-progress":{label:"In progress",icon:"clock",tone:"primary"},blocked:{label:"Blocked",icon:"alert-circle",tone:"danger"}};this.querySelectorAll(".dm-progression-item").forEach((e,a)=>{const u=n[a];if(!u)return;const f=e.querySelector(".dm-progression-title");if(u.icon&&f){const c=document.createElement("span");c.dataset.icon=u.icon,c.style.cssText="display:inline-flex;vertical-align:middle;margin-right:.4em",c.setAttribute("aria-hidden","true"),f.prepend(c)}const i=t[u.status];if(i&&f){const c=document.createElement("span");c.className=`badge badge-${i.tone} cms-timeline-status`,c.style.cssText="display:inline-flex;align-items:center;gap:.35em;margin:.4rem 0";const g=document.createElement("span");g.dataset.icon=i.icon,g.dataset.iconSize="14",g.setAttribute("aria-hidden","true"),c.append(g,document.createTextNode(i.label)),f.after(c)}})}Domma.icons.scan(this),n.length&&(this._dmCtx={instance:s,items:n})});try{Domma.effects.reveal(".page-body .hero",{animation:"slide-up",duration:480,threshold:.06,stagger:60,once:!1})}catch{}document.querySelectorAll(".page-body .row[data-reveal]").forEach(n=>{const o=n.dataset.revealMode||"stagger",s=n.dataset.revealAnimation||"slide-up",t=parseInt(n.dataset.revealDuration,10)||400,e=parseInt(n.dataset.revealStagger,10)||60,a=parseInt(n.dataset.revealDelay,10)||0,u=n.dataset.revealDirection==="rtl",f=Array.from(n.children),i={"slide-up":"translateY(30px)","slide-down":"translateY(-30px)","slide-left":"translateX(30px)","slide-right":"translateX(-30px)",zoom:"scale(0.85)",flip:"perspective(600px) rotateX(15deg)"};f.forEach((c,g)=>{c.style.opacity="0",c.style.transform=i[s]||"",c.style.transition=`opacity ${t}ms ease, transform ${t}ms ease`;const b=u?f.length-1-g:g;c.style.transitionDelay=o==="stagger"?`${a+b*e}ms`:`${a}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const c=new IntersectionObserver(g=>{g.forEach(b=>{b.isIntersecting&&(b.target.offsetWidth,b.target.style.opacity="1",b.target.style.transform="none",c.unobserve(b.target))})},{threshold:.1});f.forEach(g=>c.observe(g))}))}),w.find(".card[data-collapsible]").each(function(){const n=this.querySelector(".card-header");n&&n.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),w.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const n=this.dataset.soTarget,o=document.getElementById(n);if(!o)return;const s=E.slideover({title:o.dataset.soTitle||"",size:o.dataset.soSize||"md",position:o.dataset.soPosition||"right"});o.style.display="",s.setContent(o),s.open()})})}if(typeof $.setup=="function"){const n=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(o=>{try{const s=P(o.dataset.config);Object.assign(n,s)}catch{}}),Object.keys(n).length>0){const o={};for(const[s,t]of Object.entries(n)){const e=t?.events?.click,{confirm:a,toast:u,alert:f,prompt:i,...c}=e||{};a||u||f||i?($(s).on("click",async function(b){if(b.preventDefault(),a&&!await E.confirm(a))return;let d=null;if(!(i&&(d=await E.prompt(i,{inputPlaceholder:c.promptPlaceholder||"",inputValue:c.promptDefault||""}),d===null))){if(c.target){const m=$(c.target);c.toggleClass&&m.toggleClass(c.toggleClass),c.addClass&&m.addClass(c.addClass),c.removeClass&&m.removeClass(c.removeClass),d!==null&&(c.setText&&m.text(d),c.setVal&&m.val(d),c.setAttr&&m.attr(c.setAttr,d))}c.href&&(window.location.href=c.href),u&&E.toast(u,{type:c.toastType||"success"}),f&&E.alert(f)}}),Object.keys(c).length&&(o[s]={...t,events:{...t.events,click:c}})):o[s]=t}$.setup(o)}}w.length&&j(w.get(0))}),window.wireCTAButtons=j;function j(h){h.querySelectorAll(".dm-cta-trigger").forEach(l=>{l.__ctaWired||(l.__ctaWired=!0,l.addEventListener("click",async()=>{const x=l.dataset.action,v=l.dataset.entry,k=l.dataset.confirm;let w=S.get("auth_token");if(!w){E.toast("Please log in to perform this action.",{type:"warning"});return}if(k&&!await E.confirm(k))return;const n=Array.from(l.childNodes).map(s=>s.cloneNode(!0));l.disabled=!0,l.textContent="Running\u2026";const o=s=>fetch(`/api/actions/${x}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify(l.dataset.scope?{entryId:v,scope:l.dataset.scope}:{entryId:v})});try{let s=await o(w);if(s.status===401){const e=S.get("auth_refresh_token");if(e){const a=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(a.ok){const{token:u}=await a.json();S.set("auth_token",u),w=u,s=await o(w)}}}const t=await s.json().catch(()=>({}));if(!s.ok||t.success===!1)throw new Error(t.error||t.message||`Error ${s.status}`);E.toast(t.message||"Action completed.",{type:"success"})}catch(s){E.toast(s.message||"Action failed.",{type:"error"})}finally{l.disabled=!1,l.textContent="",n.forEach(s=>l.appendChild(s)),Domma.icons.scan(l)}}))})}(function(){const l=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!l.length)return;const x=S.get("auth_token");function v(w,n){const o=document.createElement("div");o.className="dm-collection-display dm-collection-empty";const s=document.createElement("p");if(n){s.appendChild(document.createTextNode("Please "));const t=document.createElement("a");t.href="/login",t.textContent="sign in",s.appendChild(t),s.appendChild(document.createTextNode(" to view your entries."))}else s.textContent=w;return o.appendChild(s),o}function k(w,n){const o=document.createElement("template");o.innerHTML=n||"",w.replaceWith(o.content)}l.forEach(async w=>{const n=w.dataset.collectionAttrs;if(!n)return;if(!x){w.replaceChildren(v("",!0));return}const o=s=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({attrs:n})});try{let s=x,t=await o(s);if(t.status===401){const a=S.get("auth_refresh_token");if(a){const u=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:a})});if(u.ok){const{token:f}=await u.json();S.set("auth_token",f),s=f,t=await o(s)}}}if(!t.ok){const{error:a}=await t.json().catch(()=>({}));w.replaceChildren(v(a||"Unable to load entries.",!1));return}const{html:e}=await t.json();k(w,e),window.DommaCollectionBrowser?.hydrate&&window.DommaCollectionBrowser.hydrate(document)}catch{w.replaceChildren(v("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),j(document.body)},100)})(),(function(){const l=document.querySelectorAll("[data-collection-table]");!l.length||typeof T>"u"||!T.create||l.forEach(x=>{let v;try{v=P(x.dataset.payload)}catch{return}const{columns:k,rows:w,search:n,sortable:o,exportable:s,pageSize:t,empty:e,ctaConfig:a,slug:u,exportCfg:f}=v;if(!k?.length)return;if(a){const g=k.findIndex(b=>b.key==="_cta");g!==-1&&(k[g]={key:"_cta",title:"",render:(b,d)=>{const m=document.createElement("button");if(m.className=`btn btn-${a.style||"primary"} dm-cta-trigger`,m.dataset.action=a.action||"",a.scope&&(m.dataset.scope=a.scope),m.dataset.entry=d._entryId||"",a.confirm&&(m.dataset.confirm=a.confirm),a.icon){const p=document.createElement("span");p.dataset.icon=a.icon,m.appendChild(p),m.appendChild(document.createTextNode(" "))}return m.appendChild(document.createTextNode(a.label||"Run")),m}})}const i="col-table-"+Math.random().toString(36).slice(2,7),c=document.createElement("div");c.id=i,x.replaceChildren(c),T.create("#"+i,{data:w,columns:k,search:n,sortable:o,exportable:s,pageSize:t,emptyMessage:e}),a&&j(c),x._dmTable={columns:k,rows:w,slug:u,exportCfg:f,render(g){T.create("#"+i,{data:g,columns:k,search:n,sortable:o,exportable:s,pageSize:t,emptyMessage:e}),a&&j(c)}}})})(),(function(){const l=document.querySelectorAll("[data-form-inline]");if(!l.length||typeof F>"u")return;function x(o){const s=o&&o.logic;return!!(s&&(s.visibility||s.requirement))}function v(o,s){const t={};return(o||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const a=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),u=e.type==="checkbox"?"boolean":e.type==="date"||e.type==="icon"||e.type==="image"?"string":a?"chooser":e.type,f={...e.formConfig||{}};f.span==="full"&&s&&(f.span=s);const i={type:u,required:x(e)?!1:e.required,label:e.label,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...e.tooltip&&{tooltip:e.tooltip},...f}};e.minLength!==void 0&&(i.minLength=e.minLength),e.maxLength!==void 0&&(i.maxLength=e.maxLength),e.min!==void 0&&(i.min=e.min),e.max!==void 0&&(i.max=e.max),a&&(e.variant&&(i.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(i.multiple=!0),e.density&&(i.density=e.density),e.columns&&(i.columns=e.columns),e.accent&&(i.accent=e.accent),e.accentStyle&&(i.accentStyle=e.accentStyle),e.glow&&(i.glow=!0),e.glowColour&&(i.glowColour=e.glowColour),e.shadow&&(i.shadow=e.shadow),e.shadowColour&&(i.shadowColour=e.shadowColour)),t[e.name]=i}),t}function k(o){const s={};return(o||[]).forEach(t=>{if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(s[t.name]=typeof e=="object"?e.value:e)}}),s}function w(o,s){(s||[]).forEach(t=>{if(t.type!=="date"||!t.name)return;const e=o.querySelector(`[name="${t.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function n(o,s,t){let e=o.querySelector(".cms-form-message");e||(e=document.createElement("p"),e.className="cms-form-message",o.appendChild(e)),e.textContent=s,e.style.cssText=t?"color:var(--dm-danger);margin-top:.75rem;":"color:var(--dm-success);margin-top:.75rem;"}l.forEach(o=>{let s;try{s=P(o.dataset.formInline)}catch{return}const t=s.fields||[],e=s.settings||{},a=Number(e.columns)===3?3:2,u=e.layout||"grid",f=t.some(m=>m.type==="page-break"),i=async m=>{if(o.dataset.triggerBlocked==="true"){const p=o._formLogicRuntime,y=p&&p.submitBlock?p.submitBlock().reasons:[];n(o,y.join(" ")||"This form cannot be submitted yet.",!0);const C=new Error("Blocked by a form trigger");throw C.formSubmitFailed=!0,C}try{const p=o.querySelector(".fb-form-honeypot"),y=p?.querySelector('input[type="text"]')||null,C=p?.querySelector('[name="_t"]')||null,M=Object.assign({},m);delete M._t,p?.dataset.hpName&&delete M[p.dataset.hpName],y!==null&&(M._hp=y.value),C!==null&&(M._t=C.value);const D=await H.post(`/api/forms/submit/${s.slug}`,M);if(D&&D.error){n(o,D.error,!0);const z=new Error(D.error);throw z.formSubmitFailed=!0,z}if(D?.redirect){window.location.href=D.redirect;return}for(;o.firstChild;)o.removeChild(o.firstChild);n(o,D?.message||e.successMessage||"Thank you for your submission.",!1)}catch(p){throw p.formSubmitFailed||n(o,p.message||"Submission failed. Please try again.",!0),p}},c=Date.now();function g(m){const p=m.querySelector("form");if(!p||p.querySelector(".fb-form-honeypot"))return;const y=document.createElement("div");y.className="fb-form-honeypot",y.setAttribute("aria-hidden","true");const C=document.createElement("input");C.name=p.querySelector('[name="website"]')?"_website":"website",y.dataset.hpName=C.name,C.type="text",C.tabIndex=-1,C.autocomplete="url",C.placeholder="https://",y.appendChild(C);const M=document.createElement("input");M.name="_t",M.type="hidden",M.value=c,y.appendChild(M),p.appendChild(y)}function b(m){if(!window.FormLogicEngine||!t.some(y=>y.logic||Array.isArray(y.triggers)&&y.triggers.length))return null;const p=new window.FormLogicEngine.FormLogicRuntime(s,o,m?{baseValues:m}:void 0);if(p.init(),o._formLogicRuntime=p,o._formLogicObserved)return p;if(o._formLogicObserved=!0,o.parentNode&&typeof MutationObserver<"u"){const y=new MutationObserver(function(C){for(const M of C)for(const D of M.removedNodes)if(D===o||D.nodeType===1&&D.contains&&D.contains(o)){o._formLogicRuntime&&o._formLogicRuntime.destroy(),y.disconnect();return}});y.observe(o.parentNode,{childList:!0,subtree:!1}),o._formLogicObserver=y}return p}let d=!1;if(o.addEventListener("dm-form-end",m=>{const p=m.detail?.validation;if(p&&!p.valid){G(o,p.missing),K(p);return}d||(d=!0,i(m.detail?.values||{}).catch(()=>{}).finally(()=>{d=!1}))}),f&&F.wizard){const m=re(t,s.title),p=m.map(I=>({title:I.title,description:I.description,fields:v(I.fields,a)})),y=m.map(I=>I.fields);let C=0,M=null,D=null;const z=I=>{const r=window.FormLogicEngine;if(!r||!r.validateFields)return;const A=r.validateFields(o,y[C]||[]);A.valid||(I.preventDefault(),I.stopImmediatePropagation(),G(o,A.missing),K(A))},B=()=>{const I=y[C]||t;le(o,e),Q(o,e,I),w(o,I),U(o,I),e.honeypot!==!1&&g(o),M&&M.destroy(),M=b(D?.getStepData?D.getStepData():void 0),o.querySelectorAll(".wizard-next, .wizard-submit").forEach(r=>r.addEventListener("click",z,!0))};D=F.wizard(o,{schema:{steps:p},layout:u,columns:a,finishText:e.submitText||"Finish",onSubmit:i,onStepChange:I=>{C=I,setTimeout(B,0)}}),o.addEventListener("dm-form-trigger",I=>{if(I.detail?.type!=="goto-step"||!D?.goToStep)return;const r=Number(I.detail.action.step);!Number.isFinite(r)||r<0||r>=p.length||r!==C&&D.goToStep(r)}),Promise.resolve(D).then(B)}else if(F.render){const m=F.render(o,v(t,a),k(t),{submitText:e.submitText||"Submit",layout:u,columns:a,onSubmit:i});Promise.resolve(m).then(function(){ce(o,e,u),Q(o,e,t),w(o,t),U(o,t),e.honeypot!==!1&&g(o),b()})}})})();function de(h,l){const x=document.body,v=x.classList,k=new Set((x.dataset.railSite||"").split(" ").filter(Boolean)),w=()=>window.matchMedia("(min-width: 993px)").matches;h.querySelectorAll(".navbar-link, .navbar-dropdown-toggle").forEach(a=>{const u=a.textContent.trim();u&&(a.setAttribute("title",u),a.querySelector("svg, [data-icon]")||(a.dataset.initial=u.charAt(0).toUpperCase()))});const n=document.createElement("button");n.type="button",n.className="dm-nav-collapse-toggle";const o=()=>{const a=v.contains("dm-vnav-collapsed");n.setAttribute("aria-pressed",String(a)),n.setAttribute("aria-label",a?"Expand menu":"Collapse menu"),n.title=n.getAttribute("aria-label");const u=l?"chevrons-left":"chevrons-right",f=l?"chevrons-right":"chevrons-left";n.innerHTML=`<span data-icon="${a?u:f}"></span>`,window.Domma&&Domma.icons&&Domma.icons.scan(n)},s=a=>{v.toggle("dm-vnav-collapsed",a),S.set("nav_collapsed",a),o()};n.addEventListener("click",()=>s(!v.contains("dm-vnav-collapsed"))),o();const t=h.querySelector(".navbar-container")||h;t.insertBefore(n,t.firstChild?.nextSibling||null);const e=a=>{v.toggle("dm-vnav-autohide",a),v.toggle("dm-vnav-collapsible",!a&&k.has("collapsible")),a?v.remove("dm-vnav-collapsed"):k.has("collapsible")&&S.get("nav_collapsed")===!0&&v.add("dm-vnav-collapsed"),h.classList.remove("dm-nav-revealed"),o()};h.addEventListener("pointerdown",a=>{v.contains("dm-vnav-autohide")&&a.pointerType!=="mouse"&&!h.classList.contains("dm-nav-revealed")&&(h.classList.add("dm-nav-revealed"),a.preventDefault())}),document.addEventListener("pointerdown",a=>{h.contains(a.target)||h.classList.remove("dm-nav-revealed")}),window.E&&typeof E.contextMenu=="function"&&E.contextMenu(h,{items:()=>{const a=v.contains("dm-vnav-autohide"),u=v.contains("dm-vnav-collapsed"),f=S.has("nav_autohide")||S.has("nav_collapsed");return[{header:"Menu"},{label:u?"Expand menu":"Collapse to icons",icon:u?"maximize":"minimize",disabled:!w()||a||!k.has("collapsible"),action:()=>s(!u)},{label:a?"Keep on screen":"Hide when not in use",icon:a?"eye":"eye-off",disabled:!w(),action:()=>{S.set("nav_autohide",!a),e(!a)}},{type:"divider"},{label:"Reset to the site's setting",icon:"refresh",disabled:!f,action:()=>{S.remove("nav_autohide"),S.remove("nav_collapsed"),e(k.has("autohide")),v.toggle("dm-vnav-collapsed",!k.has("autohide")&&k.has("start-collapsed")),o()}}]}})}function me(h){h.classList.add("dm-nav-scroll-hide");let l=window.scrollY,x=!1;window.addEventListener("scroll",()=>{x||(x=!0,requestAnimationFrame(()=>{x=!1;const v=window.scrollY,k=h.matches(":focus-within")||h.querySelector(".navbar-dropdown.open, .navbar-collapse.show");v>l&&v>h.offsetHeight&&!k?h.classList.add("dm-nav-scrolled-away"):v<l&&h.classList.remove("dm-nav-scrolled-away"),l=v}))},{passive:!0})}function ue(h){let l={};try{l=JSON.parse(h.dataset.contents||"{}")}catch{}const x=h.closest(".site-main"),v=document.querySelector(".site-content"),k=new Set(String(l.exclude||"").split(",").map(i=>i.trim().toLowerCase()).filter(Boolean)),w=i=>!i.closest(".hero, .card, .accordion, .tabs, figure, #site-sidebar"),n=i=>(v?[...v.querySelectorAll(i)]:[]).filter(w).filter(c=>!k.has(c.textContent.trim().toLowerCase())),o=l.headings==="h2"?n("h2"):l.headings==="h3"?n("h3"):l.headings==="h2h3"?n("h2, h3"):n("h2").length?n("h2"):n("h3");if(!o.length){x?.classList.add("no-sidebar-items");return}const s=new Set([...document.querySelectorAll("[id]")].map(i=>i.id)),t=document.createElement("nav");t.className="dm-contents",t.setAttribute("aria-label",l.title||"Page contents"),l.hover&&(t.dataset.menuHover=l.hover),l.selected&&(t.dataset.menuActive=l.selected),l.accent&&t.style.setProperty("--dm-menu-highlight",l.accent.startsWith("#")?l.accent:`var(--dm-${l.accent})`),l.font&&(t.style.fontFamily=l.font),l.fontSize&&(t.style.fontSize=l.fontSize),l.fontWeight&&(t.style.fontWeight=l.fontWeight);const e=document.createElement("div");e.className="dm-contents-head";const a=document.createElement("p");a.className="dm-contents-title",a.textContent=l.title||"",e.appendChild(a),t.appendChild(e);const u=document.createElement("ol");u.className="dm-contents-list"+(l.numbered?" is-numbered":"");const f=[];for(const i of o){if(!i.id){const b=(i.textContent||"").toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"section";let d=b;for(let m=2;s.has(d);m++)d=`${b}-${m}`;s.add(d),i.id=d}const c=document.createElement("li");c.className=`dm-contents-item dm-contents-${i.tagName.toLowerCase()}`;const g=document.createElement("a");g.href=`#${i.id}`,g.textContent=i.textContent.trim(),c.appendChild(g),u.appendChild(c),f.push([i,g])}if(t.appendChild(u),h.replaceChildren(t),l.scrollSpy!==!1&&"IntersectionObserver"in window){const i=new Map,c=()=>{const b=f.find(([d])=>i.get(d))||null;f.forEach(([,d])=>{const m=b&&d===b[1];d.classList.toggle("is-active",!!m),m?d.setAttribute("aria-current","location"):d.removeAttribute("aria-current")})},g=new IntersectionObserver(b=>{b.forEach(d=>i.set(d.target,d.isIntersecting)),c()},{rootMargin:"-80px 0px -60% 0px"});f.forEach(([b])=>g.observe(b))}if(x?.classList.contains("contents-collapsible")){const i=document.createElement("button");i.type="button",i.className="dm-contents-toggle";const c=()=>{const g=x.classList.contains("contents-collapsed");i.setAttribute("aria-expanded",String(!g)),i.setAttribute("aria-label",g?"Show the contents":"Hide the contents"),i.title=i.getAttribute("aria-label"),i.innerHTML=`<span data-icon="${g?"list":"x"}"></span>`,window.Domma?.icons&&Domma.icons.scan(i)};i.addEventListener("click",()=>{S.set("contents_collapsed",x.classList.toggle("contents-collapsed")),c()}),c(),e.insertBefore(i,e.firstChild)}if(x?.classList.contains("contents-floating")&&l.movable){t.classList.add("is-movable");const i=S.get("contents_position");i&&Number.isFinite(i.x)&&Object.assign(h.style,{left:`${i.x}px`,top:`${i.y}px`,right:"auto",bottom:"auto"}),e.addEventListener("pointerdown",c=>{if(c.target.closest("button"))return;const g=h.getBoundingClientRect(),b=c.clientX-g.left,d=c.clientY-g.top,m=y=>{const C=Math.max(0,Math.min(window.innerWidth-g.width,y.clientX-b)),M=Math.max(0,Math.min(window.innerHeight-40,y.clientY-d));Object.assign(h.style,{left:`${C}px`,top:`${M}px`,right:"auto",bottom:"auto"})},p=()=>{document.removeEventListener("pointermove",m),S.set("contents_position",{x:parseInt(h.style.left,10),y:parseInt(h.style.top,10)})};document.addEventListener("pointermove",m),document.addEventListener("pointerup",p,{once:!0})})}window.E&&typeof E.contextMenu=="function"&&E.contextMenu(h,{items:()=>{const i=x?.classList.contains("contents-collapsible"),c=x?.classList.contains("contents-collapsed"),g=f.find(([,b])=>b.classList.contains("is-active"));return[{header:"Contents"},...i?[{label:c?"Show the contents":"Collapse to a button",icon:c?"list":"minimize",action:()=>h.querySelector(".dm-contents-toggle")?.click()}]:[],{label:"Copy a link to this section",icon:"link",disabled:!g,action:async()=>{const b=`${location.origin}${location.pathname}#${g[0].id}`;try{await _.copyToClipboard(b),E.toast("Link copied.",{type:"success"})}catch{E.toast("Could not copy the link.",{type:"error"})}}},{label:"Back to the top",icon:"arrow-up",action:()=>window.scrollTo({top:0,behavior:"smooth"})}]}}),x?.classList.contains("contents-autohide")&&(h.addEventListener("pointerdown",i=>{i.pointerType!=="mouse"&&!h.classList.contains("is-revealed")&&(h.classList.add("is-revealed"),i.preventDefault())}),document.addEventListener("pointerdown",i=>{h.contains(i.target)||h.classList.remove("is-revealed")}))}
1
+ import{decodeBase64Json as P}from"/public/js/utf8-base64.mjs";import{makeBadgeEl as J,applyColour as X,applyPill as oe,applyFloat as ne,applyHighlight as R,applyItemHighlight as ae,itemHighlightAttrs as se,isCurrentItem as U,menuAlign as ie,applyClasses as O,cssClasses as W,applyEntrance as V}from"/public/js/menu-decor.mjs?v=20261014-menu-entrance";import{initFloatingMenus as re}from"/public/js/menu-float.js?v=20260829-float-panel";import{enhancePickerFields as G,markInvalidFields as K,showValidationPopup as Q}from"/public/js/forms.js?v=20261009-form-classes";import{buildWizardSteps as ce}from"/public/js/form-steps.mjs";import{applyFormClasses as Z,applySubmitButtons as le,applyWizardButtons as de}from"/public/js/form-submit.mjs";document.addEventListener("click",f=>{const l=f.target?.closest?.(".dm-banner__dismiss");l&&(f.preventDefault(),l.closest(".dm-banner")?.remove())}),$(()=>{const f=window.__CMS_NAV__||{},l=window.__CMS_SITE__||{};if(l.autoTheme?.enabled){let o=function(e){const a=(e||"07:00").split(":");return+a[0]*60+(+a[1]||0)},s=function(){const e=new Date,a=e.getHours()*60+e.getMinutes();return a>=o(n.dayStart)&&a<o(n.nightStart)?n.dayTheme:n.nightTheme},t=function(e){const a=n.apply&&n.apply[e]||{theme:e,custom:""};Domma.theme.set(a.theme);for(const m of[...document.body.classList])m.startsWith("dm-custom-")&&document.body.classList.remove(m);a.custom&&document.body.classList.add(a.custom)};const n=l.autoTheme;t(s()),setInterval(()=>t(s()),6e4)}const x=$("#site-navbar");if(x.length&&f.brand){let s=function(d,u=0){return Array.isArray(d)?d.filter(p=>!(p&&(p.type==="spacer"||p.type==="theme-switcher"))).filter(p=>!(p&&p.type==="separator"&&u===0)).map(p=>p&&p.type==="separator"?{divider:!0}:Array.isArray(p?.items)?{...p,items:s(p.items,u+1)}:p):d},t=function(d){return Array.isArray(d)?d.filter(u=>!(u&&(u.type==="separator"||u.type==="spacer"||u.type==="theme-switcher"))):[]};const n={...f.brand},o=n.size&&n.size!=="md"?` navbar-brand-${n.size}`:"";if(n.logo||n.icon||n.tagline){let d="";n.logo?d+=`<img src="${n.logo}" class="navbar-brand-logo" alt="${n.text||""}">`:n.icon&&(d+=`<span data-icon="${n.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),n.text&&(d+=`<span class="navbar-brand-text${o}">${n.text}</span>`),n.tagline&&(d+=`<small class="navbar-brand-tagline">${n.tagline}</small>`),n.html=d}else o&&n.text&&(n.html=`<span class="navbar-brand-text${o}">${n.text}</span>`);const e=f.position==="floating",a=f.orientation==="vertical";Domma.elements.navbar("#site-navbar",{brand:n,items:s(f.items||[]),variant:f.variant||"dark",position:e?"static":f.position||"sticky",collapsible:!0,appearOnHover:!!f.appearOnHover}),Domma.icons.scan("#site-navbar");const m=x.get(0);m.classList.add(`dm-nav-align-${ie(f)||"centre"}`),a&&x.get(0).classList.add("dm-nav-vertical",f.side==="right"?"dm-nav-vertical-right":"dm-nav-vertical-left");const h=f.dock||{};a&&!e&&me(m,f.side==="right"),!a&&h.hideOnScroll&&ue(m),R(m,f),V(m,f),O(m,f.class),e&&(ne(x.get(0),f),re(x.get(0).parentNode||document));const i=m.querySelector(".navbar-toggle"),c=m.querySelector(".navbar-collapse");if(i&&c){let d=null;const u=()=>{c.classList.contains("show")&&i.click()},p=()=>{d&&(d.remove(),d=null),document.body.classList.remove("dm-drawer-open")},v=()=>{d||(d=document.createElement("div"),d.className="dm-navbar-backdrop",d.addEventListener("click",u),document.body.appendChild(d),document.body.classList.add("dm-drawer-open"))};i.addEventListener("click",()=>{requestAnimationFrame(()=>{c.classList.contains("show")?v():p()})}),c.addEventListener("click",C=>{C.target.closest("a")&&requestAnimationFrame(p)}),document.addEventListener("keydown",C=>{C.key==="Escape"&&c.classList.contains("show")&&u()})}const g=m.querySelector(".navbar-nav");if(g){const d=Array.from(g.children);let u=0;for(const p of f.items||[])if(!(p&&p.type==="separator")){if(p&&p.type==="spacer"){const v=document.createElement("li"),C=["xs","sm","md","lg","xl","flex"].includes(p.size)?p.size:"md";v.className=`dm-menu-spacer dm-menu-spacer--${C}`,v.setAttribute("aria-hidden","true"),g.insertBefore(v,d[u]||null);continue}if(p&&p.type==="theme-switcher"){const v=document.createElement("li");v.className="dm-menu-theme-switcher";const C=document.createElement("span");C.dataset.themeSwitcher="menu",C.dataset.position="inline",v.appendChild(C),g.insertBefore(v,d[u]||null);continue}u++}window.CMSThemeSwitcher?.scan(g)}const b=t(f.items||[]);m.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(d=>{const u=b[parseInt(d.dataset.index,10)];if(!u)return;const p=d.dataset.subindex!=null,v=p&&Array.isArray(u.items)?u.items[parseInt(d.dataset.subindex,10)]:u;if(!v)return;v.colour&&X(d,v.colour),v.pill&&!p&&oe(d,v.pill),ae(d,v),O(d.closest("li"),v.class);const C=J(v.badge);C&&d.appendChild(C),U(v.url,location.pathname)&&(d.classList.add("active"),d.setAttribute("aria-current","page"))})}const y=$("#site-footer");if(y.length){let e=function(r){return String(r??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},a=function(r){return e(r).replace(/'/g,"&#39;")},m=function(r){if(r&&r.type==="separator")return'<li class="footer-sep"><hr></li>';if(r&&r.type==="spacer")return`<li class="dm-menu-spacer dm-menu-spacer--${["xs","sm","md","lg","xl","flex"].includes(r.size)?r.size:"md"}" aria-hidden="true"></li>`;if(r&&r.type==="theme-switcher")return'<li class="dm-menu-theme-switcher"><span data-theme-switcher="menu" data-position="inline"></span></li>';const A=a(r.url||"#"),L=e(r.text||""),D=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(m).join("")}</ul>`:"",N=se(r),ee=[N.hover&&` data-menu-item-hover="${a(N.hover)}"`,N.active&&` data-menu-item-active="${a(N.active)}"`].filter(Boolean).join(""),te=N.accent?` style="--dm-menu-highlight:${a(N.accent)}"`:"",Y=W(r.class).join(" ");return`<li${Y?` class="${a(Y)}"`:""}><a href="${A}"${ee}${te}>${L}</a>${D}</li>`},h=function(){if(!l.footer)return"";const r=Object.keys(o).filter(L=>n[L]);if(!r.length)return"";const A=W(l.footer.socialClass).join(" ");return`<div class="footer-social">${r.map(L=>{const{label:D,svg:N}=o[L];return`<a href="${n[L]}" target="_blank" rel="noopener noreferrer" aria-label="${D}" class="footer-social-link${A?` ${a(A)}`:""}">${N}</a>`}).join("")}</div>`},b=function(r){if(!r||r.type==="separator"||r.type==="spacer")return"";if(r.type==="theme-switcher")return`<li class="cms-footer-col">${m(r).replace(/^<li[^>]*>|<\/li>$/g,"")}</li>`;const A=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(m).join("")}</ul>`:"",L=g(r)?`<span class="cms-footer-col-title">${e(r.text||"")}</span>`:`<a class="cms-footer-col-title" href="${a(r.url||"#")}">${e(r.text||"")}</a>`,D=["cms-footer-col",...W(r.class)].join(" ");return`<li class="${a(D)}">${L}${A}</li>`},u=function(r,A,L=!1){return(r||[]).forEach(D=>{D&&(D.type==="separator"||D.type==="spacer"||D.type==="theme-switcher")||(L&&g(D)||A.push(D),Array.isArray(D.items)&&D.items.length&&u(D.items,A))}),A};const n=l.social||{},o={twitter:{label:"X / Twitter",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.742l7.73-8.835L1.254 2.25H8.08l4.259 5.629L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>'},facebook:{label:"Facebook",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'},instagram:{label:"Instagram",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>'},linkedin:{label:"LinkedIn",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'},github:{label:"GitHub",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>'},youtube:{label:"YouTube",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/></svg>'}};let s='<div class="footer-inner container">';const t=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""},i=["columns","row"].includes(l.footer?.layout)?l.footer.layout:"auto",c=i==="columns"||i==="auto"&&t.primary.some(r=>Array.isArray(r?.items)&&r.items.length),g=r=>c&&!r.url&&Array.isArray(r.items)&&r.items.length>0;if(c){const r=f.brand||{},A=r.text||l.title||"",L=r.logo?`<img src="${a(r.logo)}" class="cms-footer-brand-logo" alt="">`:r.icon?'<span class="cms-footer-brand-icon"></span>':"",D=String(l.footer?.blurb||"").trim();s='<div class="footer-inner footer-inner--columns container"><div class="cms-footer-top">',s+=`<div class="cms-footer-brand">${A||L?`<a class="cms-footer-brand-name" href="${a(r.url||"/")}">${L}<span>${e(A)}</span></a>`:""}${D?`<p class="cms-footer-blurb">${e(D)}</p>`:""}${h()}</div>`,t.primary.length&&(s+=`<nav class="footer-nav footer-nav--primary footer-nav--columns" aria-label="Footer"><ul>${t.primary.map(b).join("")}</ul></nav>`),s+='</div><div class="cms-footer-bottom">',t.copyright&&(s+=`<p class="cms-footer-copyright">${e(t.copyright)}</p>`),t.legal.length&&(s+=`<nav class="footer-nav footer-nav--legal" aria-label="Legal"><ul>${t.legal.map(m).join("")}</ul></nav>`),s+="</div>"}else t.copyright&&(s+=`<p>${e(t.copyright)}</p>`),t.primary.length&&(s+=`<nav class="footer-nav footer-nav--primary"><ul>${t.primary.map(m).join("")}</ul></nav>`),t.legal.length&&(s+=`<nav class="footer-nav footer-nav--legal"><ul>${t.legal.map(m).join("")}</ul></nav>`),s+=h();s+="</div>",y.html(s),window.CMSThemeSwitcher?.scan(y.get(0));const d=y.get(0).querySelector(".cms-footer-brand-icon");d&&f.brand?.icon&&d.setAttribute("data-icon",f.brand.icon),O(y.get(0),l.footer?.class);const p=[...u(t.primary,[],!0),...u(t.legal,[])];y.get(0).querySelectorAll(".footer-nav a").forEach((r,A)=>{const L=p[A];if(!L)return;L.colour&&X(r,L.colour);const D=J(L.badge);D&&r.appendChild(D),U(L.url,location.pathname)&&(r.classList.add("is-active"),r.setAttribute("aria-current","page"))}),R(y.get(0).querySelector(".footer-nav--primary"),{highlight:t.primaryHighlight}),R(y.get(0).querySelector(".footer-nav--legal"),{highlight:t.legalHighlight}),V(y.get(0).querySelector(".footer-nav--primary"),{entrance:t.primaryEntrance}),V(y.get(0).querySelector(".footer-nav--legal"),{entrance:t.legalEntrance}),O(y.get(0).querySelector(".footer-nav--primary"),t.primaryClass),O(y.get(0).querySelector(".footer-nav--legal"),t.legalClass);const C=l.footer?.showMotionToggle!==!1,M=S.get("reduced_motion"),q=l.footer?.motionDefault,z=M!=null?!!M:q==="on"?!0:q==="off"?!1:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),B=l.footer?.motionControl==="checkbox",I=y.get(0).querySelector(".cms-footer-bottom")||y.get(0).querySelector(".footer-inner");if(C&&I){const r=document.createElement("input");r.type="checkbox",r.className=B?"footer-motion-checkbox":"form-switch-input",r.id="dm-motion-switch",r.checked=z,r.addEventListener("change",function(){S.set("reduced_motion",this.checked),window.location.reload()});const A=document.createElement("span");A.className=B?"footer-motion-label":"form-switch-label",A.textContent="Reduce motion";const L=document.createElement("label");L.className=B?"footer-motion-check":"form-switch footer-motion-switch",L.title="Reduce motion",L.appendChild(r),L.appendChild(A),I.appendChild(L)}}const k=document.getElementById("site-sidebar");k&&pe(k),Domma.icons.scan(),Domma.syntax?.scan&&Domma.syntax.scan();const w=$(".page-body");if(w.length){w.find(".accordion").each(function(){Domma.elements.accordion(this,{allowMultiple:this.dataset.multi==="true"})}),w.find(".tabs").each(function(){Domma.elements.tabs(this)}),w.find(".carousel").each(function(){const n={primary:"--dm-primary",secondary:"--dm-secondary",accent:"--dm-primary",text:"--dm-text",surface:"--dm-surface",background:"--dm-background",success:"--dm-success",warning:"--dm-warning",danger:"--dm-danger",info:"--dm-info"},o=h=>{const i=String(h||"").trim();return i?n[i.toLowerCase()]?`var(${n[i.toLowerCase()]})`:CSS.supports("color",i)?i:"":""},s=o(this.dataset.background),t=o(this.dataset.arrowBackground),e=o(this.dataset.arrowColor);s&&(this.style.setProperty("--dm-carousel-background",s),this.classList.add("dm-carousel-custom-background")),t&&this.style.setProperty("--dm-carousel-arrow-background",t),e&&this.style.setProperty("--dm-carousel-arrow-color",e);const a=["top","middle","bottom"].includes(this.dataset.arrowPosition)?this.dataset.arrowPosition:"middle";this.classList.add(`dm-carousel-arrows-${a}`);const m={autoplay:this.dataset.autoplay==="true",interval:parseInt(this.dataset.interval,10)||5e3,loop:this.dataset.loop!=="false",animation:this.dataset.animation||"slide",heightMode:this.dataset.heightMode==="average"?"average":"crop"};if(this.dataset.height){const h=Number(this.dataset.height);Number.isFinite(h)&&h>0&&(m.height=h)}if(this.dataset.animationDuration){const h=parseInt(this.dataset.animationDuration,10);Number.isFinite(h)&&(m.animationDuration=h)}this.dataset.animationEasing&&(m.animationEasing=this.dataset.animationEasing),this.dataset.ctx&&(this._dmCtxSlides=Array.from(this.querySelectorAll(".carousel-slide")).map(h=>h.cloneNode(!0)),this._dmCarouselOpts=m),this._dmCarousel=Domma.elements.carousel(this,m)}),w.find(".dm-countdown").each(function(){const n={autoStart:!0},o=String(this.dataset.format||"").trim(),s=String(this.dataset.to||"").trim(),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(s),e=t?new Date(+t[1],+t[2]-1,+t[3]).getTime():s?new Date(s).getTime():NaN;Number.isFinite(e)?n.duration=Math.max(0,e-Date.now()):this.dataset.duration&&(n.duration=(parseInt(this.dataset.duration,10)||0)*1e3);const a=/^dd:/i.test(o);n.format=a?"hh:mm:ss":o||(n.duration>=36e5?"hh:mm:ss":"mm:ss");const m=this,h=c=>String(c).padStart(2,"0"),i=c=>{const g=Math.max(0,Math.floor(c/1e3)),b=m.querySelector(".dm-timer-time");b&&(b.textContent=`${h(Math.floor(g/86400))}:${h(Math.floor(g%86400/3600))}:${h(Math.floor(g%3600/60))}:${h(g%60)}`)};a&&(n.onTick=i),Domma.elements.timer(this,n),a&&i(n.duration||0)}),w.find("[data-tooltip]").each(function(){Domma.elements.tooltip(this,{content:$(this).data("tooltip"),position:$(this).data("tooltip-position")||"top"})}),w.find(".dm-progression").each(function(){const n=Array.from(this.querySelectorAll(".dm-progression-item")).map(t=>{const e={title:t.querySelector(".dm-progression-item-title")?.textContent?.trim()||"",description:t.querySelector(".dm-progression-item-body")?.innerHTML?.trim()||""};return t.dataset.date&&(e.date=t.dataset.date),t.dataset.status&&(e.status=t.dataset.status),t.dataset.eventIcon&&(e.icon=t.dataset.eventIcon),t.dataset.entryId&&(e._entryId=t.dataset.entryId),e}),o=this.dataset.layout==="centred"?"centered":this.dataset.layout||"vertical",s=Domma.elements.progression(this,{layout:o,theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0,allowHtml:!0,...n.length?{items:n}:{}});if((this.dataset.mode||"timeline")==="timeline"){const t={completed:{label:"Completed",icon:"check-circle",tone:"success"},planned:{label:"Planned",icon:"circle",tone:"secondary"},"in-progress":{label:"In progress",icon:"clock",tone:"primary"},blocked:{label:"Blocked",icon:"alert-circle",tone:"danger"}};this.querySelectorAll(".dm-progression-item").forEach((e,a)=>{const m=n[a];if(!m)return;const h=e.querySelector(".dm-progression-title");if(m.icon&&h){const c=document.createElement("span");c.dataset.icon=m.icon,c.style.cssText="display:inline-flex;vertical-align:middle;margin-right:.4em",c.setAttribute("aria-hidden","true"),h.prepend(c)}const i=t[m.status];if(i&&h){const c=document.createElement("span");c.className=`badge badge-${i.tone} cms-timeline-status`,c.style.cssText="display:inline-flex;align-items:center;gap:.35em;margin:.4rem 0";const g=document.createElement("span");g.dataset.icon=i.icon,g.dataset.iconSize="14",g.setAttribute("aria-hidden","true"),c.append(g,document.createTextNode(i.label)),h.after(c)}})}Domma.icons.scan(this),n.length&&(this._dmCtx={instance:s,items:n})});try{Domma.effects.reveal(".page-body .hero",{animation:"slide-up",duration:480,threshold:.06,stagger:60,once:!1})}catch{}document.querySelectorAll(".page-body .row[data-reveal]").forEach(n=>{const o=n.dataset.revealMode||"stagger",s=n.dataset.revealAnimation||"slide-up",t=parseInt(n.dataset.revealDuration,10)||400,e=parseInt(n.dataset.revealStagger,10)||60,a=parseInt(n.dataset.revealDelay,10)||0,m=n.dataset.revealDirection==="rtl",h=Array.from(n.children),i={"slide-up":"translateY(30px)","slide-down":"translateY(-30px)","slide-left":"translateX(30px)","slide-right":"translateX(-30px)",zoom:"scale(0.85)",flip:"perspective(600px) rotateX(15deg)"};h.forEach((c,g)=>{c.style.opacity="0",c.style.transform=i[s]||"",c.style.transition=`opacity ${t}ms ease, transform ${t}ms ease`;const b=m?h.length-1-g:g;c.style.transitionDelay=o==="stagger"?`${a+b*e}ms`:`${a}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const c=new IntersectionObserver(g=>{g.forEach(b=>{b.isIntersecting&&(b.target.offsetWidth,b.target.style.opacity="1",b.target.style.transform="none",c.unobserve(b.target))})},{threshold:.1});h.forEach(g=>c.observe(g))}))}),w.find(".card[data-collapsible]").each(function(){const n=this.querySelector(".card-header");n&&n.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),w.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const n=this.dataset.soTarget,o=document.getElementById(n);if(!o)return;const s=E.slideover({title:o.dataset.soTitle||"",size:o.dataset.soSize||"md",position:o.dataset.soPosition||"right"});o.style.display="",s.setContent(o),s.open()})})}if(typeof $.setup=="function"){const n=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(o=>{try{const s=P(o.dataset.config);Object.assign(n,s)}catch{}}),Object.keys(n).length>0){const o={};for(const[s,t]of Object.entries(n)){const e=t?.events?.click,{confirm:a,toast:m,alert:h,prompt:i,...c}=e||{};a||m||h||i?($(s).on("click",async function(b){if(b.preventDefault(),a&&!await E.confirm(a))return;let d=null;if(!(i&&(d=await E.prompt(i,{inputPlaceholder:c.promptPlaceholder||"",inputValue:c.promptDefault||""}),d===null))){if(c.target){const u=$(c.target);c.toggleClass&&u.toggleClass(c.toggleClass),c.addClass&&u.addClass(c.addClass),c.removeClass&&u.removeClass(c.removeClass),d!==null&&(c.setText&&u.text(d),c.setVal&&u.val(d),c.setAttr&&u.attr(c.setAttr,d))}c.href&&(window.location.href=c.href),m&&E.toast(m,{type:c.toastType||"success"}),h&&E.alert(h)}}),Object.keys(c).length&&(o[s]={...t,events:{...t.events,click:c}})):o[s]=t}$.setup(o)}}w.length&&j(w.get(0))}),window.wireCTAButtons=j;function j(f){f.querySelectorAll(".dm-cta-trigger").forEach(l=>{l.__ctaWired||(l.__ctaWired=!0,l.addEventListener("click",async()=>{const x=l.dataset.action,y=l.dataset.entry,k=l.dataset.confirm;let w=S.get("auth_token");if(!w){E.toast("Please log in to perform this action.",{type:"warning"});return}if(k&&!await E.confirm(k))return;const n=Array.from(l.childNodes).map(s=>s.cloneNode(!0));l.disabled=!0,l.textContent="Running\u2026";const o=s=>fetch(`/api/actions/${x}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify(l.dataset.scope?{entryId:y,scope:l.dataset.scope}:{entryId:y})});try{let s=await o(w);if(s.status===401){const e=S.get("auth_refresh_token");if(e){const a=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(a.ok){const{token:m}=await a.json();S.set("auth_token",m),w=m,s=await o(w)}}}const t=await s.json().catch(()=>({}));if(!s.ok||t.success===!1)throw new Error(t.error||t.message||`Error ${s.status}`);E.toast(t.message||"Action completed.",{type:"success"})}catch(s){E.toast(s.message||"Action failed.",{type:"error"})}finally{l.disabled=!1,l.textContent="",n.forEach(s=>l.appendChild(s)),Domma.icons.scan(l)}}))})}(function(){const l=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!l.length)return;const x=S.get("auth_token");function y(w,n){const o=document.createElement("div");o.className="dm-collection-display dm-collection-empty";const s=document.createElement("p");if(n){s.appendChild(document.createTextNode("Please "));const t=document.createElement("a");t.href="/login",t.textContent="sign in",s.appendChild(t),s.appendChild(document.createTextNode(" to view your entries."))}else s.textContent=w;return o.appendChild(s),o}function k(w,n){const o=document.createElement("template");o.innerHTML=n||"",w.replaceWith(o.content)}l.forEach(async w=>{const n=w.dataset.collectionAttrs;if(!n)return;if(!x){w.replaceChildren(y("",!0));return}const o=s=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${s}`},body:JSON.stringify({attrs:n})});try{let s=x,t=await o(s);if(t.status===401){const a=S.get("auth_refresh_token");if(a){const m=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:a})});if(m.ok){const{token:h}=await m.json();S.set("auth_token",h),s=h,t=await o(s)}}}if(!t.ok){const{error:a}=await t.json().catch(()=>({}));w.replaceChildren(y(a||"Unable to load entries.",!1));return}const{html:e}=await t.json();k(w,e),window.DommaCollectionBrowser?.hydrate&&window.DommaCollectionBrowser.hydrate(document)}catch{w.replaceChildren(y("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),j(document.body)},100)})(),(function(){const l=document.querySelectorAll("[data-collection-table]");!l.length||typeof T>"u"||!T.create||l.forEach(x=>{let y;try{y=P(x.dataset.payload)}catch{return}const{columns:k,rows:w,search:n,sortable:o,exportable:s,pageSize:t,empty:e,ctaConfig:a,slug:m,exportCfg:h}=y;if(!k?.length)return;if(a){const g=k.findIndex(b=>b.key==="_cta");g!==-1&&(k[g]={key:"_cta",title:"",render:(b,d)=>{const u=document.createElement("button");if(u.className=`btn btn-${a.style||"primary"} dm-cta-trigger`,u.dataset.action=a.action||"",a.scope&&(u.dataset.scope=a.scope),u.dataset.entry=d._entryId||"",a.confirm&&(u.dataset.confirm=a.confirm),a.icon){const p=document.createElement("span");p.dataset.icon=a.icon,u.appendChild(p),u.appendChild(document.createTextNode(" "))}return u.appendChild(document.createTextNode(a.label||"Run")),u}})}const i="col-table-"+Math.random().toString(36).slice(2,7),c=document.createElement("div");c.id=i,x.replaceChildren(c),T.create("#"+i,{data:w,columns:k,search:n,sortable:o,exportable:s,pageSize:t,emptyMessage:e}),a&&j(c),x._dmTable={columns:k,rows:w,slug:m,exportCfg:h,render(g){T.create("#"+i,{data:g,columns:k,search:n,sortable:o,exportable:s,pageSize:t,emptyMessage:e}),a&&j(c)}}})})(),(function(){const l=document.querySelectorAll("[data-form-inline]");if(!l.length||typeof F>"u")return;function x(o){const s=o&&o.logic;return!!(s&&(s.visibility||s.requirement))}function y(o,s){const t={};return(o||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const a=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),m=e.type==="checkbox"?"boolean":e.type==="date"||e.type==="icon"||e.type==="image"?"string":a?"chooser":e.type,h={...e.formConfig||{}};h.span==="full"&&s&&(h.span=s);const i={type:m,required:x(e)?!1:e.required,label:e.label,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...e.tooltip&&{tooltip:e.tooltip},...h}};e.minLength!==void 0&&(i.minLength=e.minLength),e.maxLength!==void 0&&(i.maxLength=e.maxLength),e.min!==void 0&&(i.min=e.min),e.max!==void 0&&(i.max=e.max),a&&(e.variant&&(i.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(i.multiple=!0),e.density&&(i.density=e.density),e.columns&&(i.columns=e.columns),e.accent&&(i.accent=e.accent),e.accentStyle&&(i.accentStyle=e.accentStyle),e.glow&&(i.glow=!0),e.glowColour&&(i.glowColour=e.glowColour),e.shadow&&(i.shadow=e.shadow),e.shadowColour&&(i.shadowColour=e.shadowColour)),t[e.name]=i}),t}function k(o){const s={};return(o||[]).forEach(t=>{if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(s[t.name]=typeof e=="object"?e.value:e)}}),s}function w(o,s){(s||[]).forEach(t=>{if(t.type!=="date"||!t.name)return;const e=o.querySelector(`[name="${t.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function n(o,s,t){let e=o.querySelector(".cms-form-message");e||(e=document.createElement("p"),e.className="cms-form-message",o.appendChild(e)),e.textContent=s,e.style.cssText=t?"color:var(--dm-danger);margin-top:.75rem;":"color:var(--dm-success);margin-top:.75rem;"}l.forEach(o=>{let s;try{s=P(o.dataset.formInline)}catch{return}const t=s.fields||[],e=s.settings||{},a=Number(e.columns)===3?3:2,m=e.layout||"grid",h=t.some(u=>u.type==="page-break"),i=async u=>{if(o.dataset.triggerBlocked==="true"){const p=o._formLogicRuntime,v=p&&p.submitBlock?p.submitBlock().reasons:[];n(o,v.join(" ")||"This form cannot be submitted yet.",!0);const C=new Error("Blocked by a form trigger");throw C.formSubmitFailed=!0,C}try{const p=o.querySelector(".fb-form-honeypot"),v=p?.querySelector('input[type="text"]')||null,C=p?.querySelector('[name="_t"]')||null,M=Object.assign({},u);delete M._t,p?.dataset.hpName&&delete M[p.dataset.hpName],v!==null&&(M._hp=v.value),C!==null&&(M._t=C.value);const q=await H.post(`/api/forms/submit/${s.slug}`,M);if(q&&q.error){n(o,q.error,!0);const z=new Error(q.error);throw z.formSubmitFailed=!0,z}if(q?.redirect){window.location.href=q.redirect;return}for(;o.firstChild;)o.removeChild(o.firstChild);n(o,q?.message||e.successMessage||"Thank you for your submission.",!1)}catch(p){throw p.formSubmitFailed||n(o,p.message||"Submission failed. Please try again.",!0),p}},c=Date.now();function g(u){const p=u.querySelector("form");if(!p||p.querySelector(".fb-form-honeypot"))return;const v=document.createElement("div");v.className="fb-form-honeypot",v.setAttribute("aria-hidden","true");const C=document.createElement("input");C.name=p.querySelector('[name="website"]')?"_website":"website",v.dataset.hpName=C.name,C.type="text",C.tabIndex=-1,C.autocomplete="url",C.placeholder="https://",v.appendChild(C);const M=document.createElement("input");M.name="_t",M.type="hidden",M.value=c,v.appendChild(M),p.appendChild(v)}function b(u){if(!window.FormLogicEngine||!t.some(v=>v.logic||Array.isArray(v.triggers)&&v.triggers.length))return null;const p=new window.FormLogicEngine.FormLogicRuntime(s,o,u?{baseValues:u}:void 0);if(p.init(),o._formLogicRuntime=p,o._formLogicObserved)return p;if(o._formLogicObserved=!0,o.parentNode&&typeof MutationObserver<"u"){const v=new MutationObserver(function(C){for(const M of C)for(const q of M.removedNodes)if(q===o||q.nodeType===1&&q.contains&&q.contains(o)){o._formLogicRuntime&&o._formLogicRuntime.destroy(),v.disconnect();return}});v.observe(o.parentNode,{childList:!0,subtree:!1}),o._formLogicObserver=v}return p}let d=!1;if(o.addEventListener("dm-form-end",u=>{const p=u.detail?.validation;if(p&&!p.valid){K(o,p.missing),Q(p);return}d||(d=!0,i(u.detail?.values||{}).catch(()=>{}).finally(()=>{d=!1}))}),h&&F.wizard){const u=ce(t,s.title),p=u.map(I=>({title:I.title,description:I.description,fields:y(I.fields,a)})),v=u.map(I=>I.fields);let C=0,M=null,q=null;const z=I=>{const r=window.FormLogicEngine;if(!r||!r.validateFields)return;const A=r.validateFields(o,v[C]||[]);A.valid||(I.preventDefault(),I.stopImmediatePropagation(),K(o,A.missing),Q(A))},B=()=>{const I=v[C]||t;de(o,e),Z(o,e,I),w(o,I),G(o,I),e.honeypot!==!1&&g(o),M&&M.destroy(),M=b(q?.getStepData?q.getStepData():void 0),o.querySelectorAll(".wizard-next, .wizard-submit").forEach(r=>r.addEventListener("click",z,!0))};q=F.wizard(o,{schema:{steps:p},layout:m,columns:a,finishText:e.submitText||"Finish",onSubmit:i,onStepChange:I=>{C=I,setTimeout(B,0)}}),o.addEventListener("dm-form-trigger",I=>{if(I.detail?.type!=="goto-step"||!q?.goToStep)return;const r=Number(I.detail.action.step);!Number.isFinite(r)||r<0||r>=p.length||r!==C&&q.goToStep(r)}),Promise.resolve(q).then(B)}else if(F.render){const u=F.render(o,y(t,a),k(t),{submitText:e.submitText||"Submit",layout:m,columns:a,onSubmit:i});Promise.resolve(u).then(function(){le(o,e,m),Z(o,e,t),w(o,t),G(o,t),e.honeypot!==!1&&g(o),b()})}})})();function me(f,l){const x=document.body,y=x.classList,k=new Set((x.dataset.railSite||"").split(" ").filter(Boolean)),w=()=>window.matchMedia("(min-width: 993px)").matches;f.querySelectorAll(".navbar-link, .navbar-dropdown-toggle").forEach(a=>{const m=a.textContent.trim();m&&(a.setAttribute("title",m),a.querySelector("svg, [data-icon]")||(a.dataset.initial=m.charAt(0).toUpperCase()))});const n=document.createElement("button");n.type="button",n.className="dm-nav-collapse-toggle";const o=()=>{const a=y.contains("dm-vnav-collapsed");n.setAttribute("aria-pressed",String(a)),n.setAttribute("aria-label",a?"Expand menu":"Collapse menu"),n.title=n.getAttribute("aria-label");const m=l?"chevrons-left":"chevrons-right",h=l?"chevrons-right":"chevrons-left";n.innerHTML=`<span data-icon="${a?m:h}"></span>`,window.Domma&&Domma.icons&&Domma.icons.scan(n)},s=a=>{y.toggle("dm-vnav-collapsed",a),S.set("nav_collapsed",a),o()};n.addEventListener("click",()=>s(!y.contains("dm-vnav-collapsed"))),o();const t=f.querySelector(".navbar-container")||f;t.insertBefore(n,t.firstChild?.nextSibling||null);const e=a=>{y.toggle("dm-vnav-autohide",a),y.toggle("dm-vnav-collapsible",!a&&k.has("collapsible")),a?y.remove("dm-vnav-collapsed"):k.has("collapsible")&&S.get("nav_collapsed")===!0&&y.add("dm-vnav-collapsed"),f.classList.remove("dm-nav-revealed"),o()};f.addEventListener("pointerdown",a=>{y.contains("dm-vnav-autohide")&&a.pointerType!=="mouse"&&!f.classList.contains("dm-nav-revealed")&&(f.classList.add("dm-nav-revealed"),a.preventDefault())}),document.addEventListener("pointerdown",a=>{f.contains(a.target)||f.classList.remove("dm-nav-revealed")}),window.E&&typeof E.contextMenu=="function"&&E.contextMenu(f,{items:()=>{const a=y.contains("dm-vnav-autohide"),m=y.contains("dm-vnav-collapsed"),h=S.has("nav_autohide")||S.has("nav_collapsed");return[{header:"Menu"},{label:m?"Expand menu":"Collapse to icons",icon:m?"maximize":"minimize",disabled:!w()||a||!k.has("collapsible"),action:()=>s(!m)},{label:a?"Keep on screen":"Hide when not in use",icon:a?"eye":"eye-off",disabled:!w(),action:()=>{S.set("nav_autohide",!a),e(!a)}},{type:"divider"},{label:"Reset to the site's setting",icon:"refresh",disabled:!h,action:()=>{S.remove("nav_autohide"),S.remove("nav_collapsed"),e(k.has("autohide")),y.toggle("dm-vnav-collapsed",!k.has("autohide")&&k.has("start-collapsed")),o()}}]}})}function ue(f){f.classList.add("dm-nav-scroll-hide");let l=window.scrollY,x=!1;window.addEventListener("scroll",()=>{x||(x=!0,requestAnimationFrame(()=>{x=!1;const y=window.scrollY,k=f.matches(":focus-within")||f.querySelector(".navbar-dropdown.open, .navbar-collapse.show");y>l&&y>f.offsetHeight&&!k?f.classList.add("dm-nav-scrolled-away"):y<l&&f.classList.remove("dm-nav-scrolled-away"),l=y}))},{passive:!0})}function pe(f){let l={};try{l=JSON.parse(f.dataset.contents||"{}")}catch{}const x=f.closest(".site-main"),y=document.querySelector(".site-content"),k=new Set(String(l.exclude||"").split(",").map(i=>i.trim().toLowerCase()).filter(Boolean)),w=i=>!i.closest(".hero, .card, .accordion, .tabs, figure, #site-sidebar"),n=i=>(y?[...y.querySelectorAll(i)]:[]).filter(w).filter(c=>!k.has(c.textContent.trim().toLowerCase())),o=l.headings==="h2"?n("h2"):l.headings==="h3"?n("h3"):l.headings==="h2h3"?n("h2, h3"):n("h2").length?n("h2"):n("h3");if(!o.length){x?.classList.add("no-sidebar-items");return}const s=new Set([...document.querySelectorAll("[id]")].map(i=>i.id)),t=document.createElement("nav");t.className="dm-contents",t.setAttribute("aria-label",l.title||"Page contents"),l.hover&&(t.dataset.menuHover=l.hover),l.selected&&(t.dataset.menuActive=l.selected),l.accent&&t.style.setProperty("--dm-menu-highlight",l.accent.startsWith("#")?l.accent:`var(--dm-${l.accent})`),l.font&&(t.style.fontFamily=l.font),l.fontSize&&(t.style.fontSize=l.fontSize),l.fontWeight&&(t.style.fontWeight=l.fontWeight);const e=document.createElement("div");e.className="dm-contents-head";const a=document.createElement("p");a.className="dm-contents-title",a.textContent=l.title||"",e.appendChild(a),t.appendChild(e);const m=document.createElement("ol");m.className="dm-contents-list"+(l.numbered?" is-numbered":"");const h=[];for(const i of o){if(!i.id){const b=(i.textContent||"").toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"section";let d=b;for(let u=2;s.has(d);u++)d=`${b}-${u}`;s.add(d),i.id=d}const c=document.createElement("li");c.className=`dm-contents-item dm-contents-${i.tagName.toLowerCase()}`;const g=document.createElement("a");g.href=`#${i.id}`,g.textContent=i.textContent.trim(),c.appendChild(g),m.appendChild(c),h.push([i,g])}if(t.appendChild(m),f.replaceChildren(t),l.scrollSpy!==!1&&"IntersectionObserver"in window){const i=new Map,c=()=>{const b=h.find(([d])=>i.get(d))||null;h.forEach(([,d])=>{const u=b&&d===b[1];d.classList.toggle("is-active",!!u),u?d.setAttribute("aria-current","location"):d.removeAttribute("aria-current")})},g=new IntersectionObserver(b=>{b.forEach(d=>i.set(d.target,d.isIntersecting)),c()},{rootMargin:"-80px 0px -60% 0px"});h.forEach(([b])=>g.observe(b))}if(x?.classList.contains("contents-collapsible")){const i=document.createElement("button");i.type="button",i.className="dm-contents-toggle";const c=()=>{const g=x.classList.contains("contents-collapsed");i.setAttribute("aria-expanded",String(!g)),i.setAttribute("aria-label",g?"Show the contents":"Hide the contents"),i.title=i.getAttribute("aria-label"),i.innerHTML=`<span data-icon="${g?"list":"x"}"></span>`,window.Domma?.icons&&Domma.icons.scan(i)};i.addEventListener("click",()=>{S.set("contents_collapsed",x.classList.toggle("contents-collapsed")),c()}),c(),e.insertBefore(i,e.firstChild)}if(x?.classList.contains("contents-floating")&&l.movable){t.classList.add("is-movable");const i=S.get("contents_position");i&&Number.isFinite(i.x)&&Object.assign(f.style,{left:`${i.x}px`,top:`${i.y}px`,right:"auto",bottom:"auto"}),e.addEventListener("pointerdown",c=>{if(c.target.closest("button"))return;const g=f.getBoundingClientRect(),b=c.clientX-g.left,d=c.clientY-g.top,u=v=>{const C=Math.max(0,Math.min(window.innerWidth-g.width,v.clientX-b)),M=Math.max(0,Math.min(window.innerHeight-40,v.clientY-d));Object.assign(f.style,{left:`${C}px`,top:`${M}px`,right:"auto",bottom:"auto"})},p=()=>{document.removeEventListener("pointermove",u),S.set("contents_position",{x:parseInt(f.style.left,10),y:parseInt(f.style.top,10)})};document.addEventListener("pointermove",u),document.addEventListener("pointerup",p,{once:!0})})}window.E&&typeof E.contextMenu=="function"&&E.contextMenu(f,{items:()=>{const i=x?.classList.contains("contents-collapsible"),c=x?.classList.contains("contents-collapsed"),g=h.find(([,b])=>b.classList.contains("is-active"));return[{header:"Contents"},...i?[{label:c?"Show the contents":"Collapse to a button",icon:c?"list":"minimize",action:()=>f.querySelector(".dm-contents-toggle")?.click()}]:[],{label:"Copy a link to this section",icon:"link",disabled:!g,action:async()=>{const b=`${location.origin}${location.pathname}#${g[0].id}`;try{await _.copyToClipboard(b),E.toast("Link copied.",{type:"success"})}catch{E.toast("Could not copy the link.",{type:"error"})}}},{label:"Back to the top",icon:"arrow-up",action:()=>window.scrollTo({top:0,behavior:"smooth"})}]}}),x?.classList.contains("contents-autohide")&&(f.addEventListener("pointerdown",i=>{i.pointerType!=="mouse"&&!f.classList.contains("is-revealed")&&(f.classList.add("is-revealed"),i.preventDefault())}),document.addEventListener("pointerdown",i=>{f.contains(i.target)||f.classList.remove("is-revealed")}))}
@@ -14,7 +14,7 @@ import {colourToCss, floatToCss, floatBehaviour, spacerSize} from './menus.js';
14
14
  // Highlight helpers live once, in the browser module, and are imported here -
15
15
  // the same shared-module arrangement collection-export.mjs has with
16
16
  // collections.js. Nothing in them touches the DOM.
17
- import {highlightAttrs, itemHighlightAttrs, isCurrentItem, menuAlign, cssClasses} from '../../public/js/menu-decor.mjs';
17
+ import {highlightAttrs, itemHighlightAttrs, isCurrentItem, menuAlign, cssClasses, entranceAttrs, entranceStyle} from '../../public/js/menu-decor.mjs';
18
18
 
19
19
  /** Attribute-safe escaping - mirrors escapeAttr in markdown.js. */
20
20
  function esc(str) {
@@ -164,12 +164,15 @@ export function buildMenuNav(menu, items, opts = {}) {
164
164
  // The accent joins whatever floatToCss already put in the style attribute
165
165
  // rather than opening a second one.
166
166
  const hlStyle = hl.accent ? `--dm-menu-highlight:${hl.accent}` : '';
167
- const styleAttr = (floatCss || hlStyle)
168
- ? ` style="${esc([floatCss, hlStyle].filter(Boolean).join(';'))}"`
169
- : '';
167
+ // Staggered entrance - one attribute and two custom properties; the items
168
+ // are numbered in menu-highlight.css, so nothing is stamped per <li>.
169
+ const entrance = entranceAttrs(menu);
170
+ const entranceAttr = entrance ? ` data-menu-entrance="${esc(entrance.animation)}"` : '';
171
+ const styleParts = [floatCss, hlStyle, entranceStyle(entrance)].filter(Boolean);
172
+ const styleAttr = styleParts.length ? ` style="${esc(styleParts.join(';'))}"` : '';
170
173
 
171
174
  return `<nav class="dm-menu dm-menu--${esc(menu.slug)}${orientClass}${alignClass}${variantClass}${floatClass}${collapsedClass}${flexClass}${klass}"`
172
- + ` data-menu="${esc(menu.slug)}"${styleAttr}${floatAnchorAttr}${behAttrs}${hlAttrs}>`
175
+ + ` data-menu="${esc(menu.slug)}"${styleAttr}${floatAnchorAttr}${behAttrs}${hlAttrs}${entranceAttr}>`
173
176
  + buildFloatChrome(menu, beh)
174
177
  + renderMenuItemsAsUl(items, opts.currentPath || '')
175
178
  + `</nav>`;
@@ -17,7 +17,7 @@ import * as cache from './cache/index.js';
17
17
  // The highlight vocabularies are defined once, in the browser module, and
18
18
  // imported here so validation and the renderer can never drift apart.
19
19
  import {
20
- HIGHLIGHT_HOVER, HIGHLIGHT_ACTIVE, MENU_ALIGN,
20
+ HIGHLIGHT_HOVER, HIGHLIGHT_ACTIVE, MENU_ALIGN, ENTRANCE_ANIMATIONS, ENTRANCE_LIMITS,
21
21
  LEGACY_STYLE_HOVER, LEGACY_STYLE_ACTIVE, legacyStyleHighlight,
22
22
  PRESET_COLOUR_VARS, PRESET_COLOUR_FALLBACKS, colourToCss, cssClassProblems
23
23
  } from '../../public/js/menu-decor.mjs';
@@ -606,6 +606,8 @@ export async function createMenu(input) {
606
606
  ...(input.appearOnHover != null && {appearOnHover: !!input.appearOnHover}),
607
607
  ...(input.float != null && {float: input.float}),
608
608
  ...(input.highlight != null && {highlight: input.highlight}),
609
+ ...(input.entrance != null && {entrance: input.entrance}),
610
+ ...(input.class != null && input.class !== '' && {class: input.class}),
609
611
  ...(input.style != null && {style: input.style}),
610
612
  ...(normaliseDock(input.dock) && {dock: normaliseDock(input.dock)}),
611
613
  ...(binding != null && {binding}),
@@ -652,6 +654,8 @@ export async function updateMenu(slug, input) {
652
654
  ...(input.appearOnHover != null && {appearOnHover: !!input.appearOnHover}),
653
655
  ...(input.float != null && {float: input.float}),
654
656
  ...(input.highlight != null && {highlight: input.highlight}),
657
+ ...(input.entrance != null && {entrance: input.entrance}),
658
+ ...(input.class != null && input.class !== '' && {class: input.class}),
655
659
  ...(input.style != null && {style: input.style}),
656
660
  ...(normaliseDock(input.dock) && {dock: normaliseDock(input.dock)}),
657
661
  ...(binding != null && {binding}),
@@ -876,6 +880,23 @@ export function validateMenu(menu) {
876
880
  }
877
881
  }
878
882
  }
883
+ if (menu.entrance != null) {
884
+ const e = menu.entrance;
885
+ if (typeof e !== 'object' || Array.isArray(e)) {
886
+ errors.push('entrance must be an object');
887
+ } else {
888
+ if (e.enabled != null && typeof e.enabled !== 'boolean') errors.push('entrance.enabled must be true or false');
889
+ if (e.animation != null && e.animation !== '' && !ENTRANCE_ANIMATIONS.includes(e.animation)) {
890
+ errors.push(`entrance.animation must be one of: ${ENTRANCE_ANIMATIONS.join(', ')}`);
891
+ }
892
+ for (const key of ['stagger', 'duration']) {
893
+ const [min, max] = ENTRANCE_LIMITS[key];
894
+ if (e[key] != null && e[key] !== '' && !(typeof e[key] === 'number' && e[key] >= min && e[key] <= max)) {
895
+ errors.push(`entrance.${key} must be a number from ${min} to ${max}`);
896
+ }
897
+ }
898
+ }
899
+ }
879
900
  if (!Array.isArray(menu.items)) {
880
901
  errors.push('items must be an array');
881
902
  } else {
@@ -308,6 +308,8 @@ export async function renderPage(page, opts = {}) {
308
308
  // Item highlighting: the navbar is built in the browser, so the
309
309
  // config has to travel to site.js rather than being rendered here.
310
310
  ...(navMenu.highlight && {highlight: navMenu.highlight}),
311
+ // Staggered entrance - played by menu-highlight.css once site.js stamps it.
312
+ ...(navMenu.entrance && {entrance: navMenu.entrance}),
311
313
  // Designer classes for the navbar element itself (site.js adds them).
312
314
  ...(navMenu.class && {class: navMenu.class}),
313
315
  ...(navMenu.style && {style: navMenu.style})
@@ -381,6 +383,8 @@ export async function renderPage(page, opts = {}) {
381
383
  // Highlighting is per menu, and the two footer columns are two menus.
382
384
  ...(footerPrimary?.highlight && {primaryHighlight: footerPrimary.highlight}),
383
385
  ...(footerLegal?.highlight && {legalHighlight: footerLegal.highlight}),
386
+ ...(footerPrimary?.entrance && {primaryEntrance: footerPrimary.entrance}),
387
+ ...(footerLegal?.entrance && {legalEntrance: footerLegal.entrance}),
384
388
  // Each column's menu-level designer classes, for its <nav>.
385
389
  ...(footerPrimary?.class && {primaryClass: footerPrimary.class}),
386
390
  ...(footerLegal?.class && {legalClass: footerLegal.class})
@@ -1075,6 +1079,8 @@ export async function renderBlogPage(templatePath, data = {}, seoMeta = {}) {
1075
1079
  // Item highlighting: the navbar is built in the browser, so the
1076
1080
  // config has to travel to site.js rather than being rendered here.
1077
1081
  ...(navMenu.highlight && {highlight: navMenu.highlight}),
1082
+ // Staggered entrance - played by menu-highlight.css once site.js stamps it.
1083
+ ...(navMenu.entrance && {entrance: navMenu.entrance}),
1078
1084
  // Designer classes for the navbar element itself (site.js adds them).
1079
1085
  ...(navMenu.class && {class: navMenu.class}),
1080
1086
  ...(navMenu.style && {style: navMenu.style})
@@ -1136,6 +1142,8 @@ export async function renderBlogPage(templatePath, data = {}, seoMeta = {}) {
1136
1142
  // Highlighting is per menu, and the two footer columns are two menus.
1137
1143
  ...(footerPrimary?.highlight && {primaryHighlight: footerPrimary.highlight}),
1138
1144
  ...(footerLegal?.highlight && {legalHighlight: footerLegal.highlight}),
1145
+ ...(footerPrimary?.entrance && {primaryEntrance: footerPrimary.entrance}),
1146
+ ...(footerLegal?.entrance && {legalEntrance: footerLegal.entrance}),
1139
1147
  // Each column's menu-level designer classes, for its <nav>.
1140
1148
  ...(footerPrimary?.class && {primaryClass: footerPrimary.class}),
1141
1149
  ...(footerLegal?.class && {legalClass: footerLegal.class})
@@ -29,7 +29,7 @@
29
29
  <link rel="stylesheet" href="/public/css/forms.css?v=20260927-submit-btn-css">
30
30
  <!-- Menu item hover / current-page effects. Loaded after site.css so a
31
31
  menu's own highlight wins over the blanket link styling there. -->
32
- <link rel="stylesheet" href="/public/css/menu-highlight.css?v=20261009-hover-darker">
32
+ <link rel="stylesheet" href="/public/css/menu-highlight.css?v=20261014-menu-entrance">
33
33
 
34
34
  <!-- Font overrides -->
35
35
  {{fontStyleTag}}
@@ -173,7 +173,7 @@
173
173
  </script>
174
174
 
175
175
  <!-- Site initialisation -->
176
- <script src="/public/js/site.js?v=20261014-carousel-height" type="module"></script>
176
+ <script src="/public/js/site.js?v=20261014-menu-entrance" type="module"></script>
177
177
  <script src="/public/js/collection-context.js?v=20261010-utf8-payloads" type="module"></script>
178
178
  {{ctxMenusModule}}
179
179