From 2e37c23cf88ae5fb86d15c0476817b53852e2a49 Mon Sep 17 00:00:00 2001 From: prismiwi2015 Date: Thu, 20 Aug 2026 10:50:40 +0200 Subject: [PATCH] The rails trade places with a fly-over, the way they used to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a narrow window the palette and the inspector are mutually exclusive, and the trade is now played rather than cut: selecting a field slides the palette out as the inspector slides in from its own right side, and putting the selection down — a click on the canvas's empty space, a gesture the canvas simply did not have — plays the whole thing backwards. The grid tracks themselves animate, which Chromium interpolates, and the rail contents fade rather than squeeze through the intermediate widths. Below 640px the palette rests folded too and the inspector still flies in over a selection. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp --- assets/css/builder.css | 42 +++++++++++++++++++++++++--------------- assets/js/builder.js | 11 +++++++++++ assets/js/builder.min.js | 2 +- src/builder.ts | 25 ++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/assets/css/builder.css b/assets/css/builder.css index 9b35c5c..c4ef028 100644 --- a/assets/css/builder.css +++ b/assets/css/builder.css @@ -229,46 +229,56 @@ than media queries, because the width that matters is the window's, and the viewport knows nothing about it. */ @container ( max-width: 900px ) { + /* One rail's worth of room, so the rails become mutually exclusive and + trade places with a fly-over: selecting a field slides the palette out + and the inspector in from its own right side; putting the selection + down (a click on the canvas's empty space) plays it backwards. The + tracks themselves animate — Chromium interpolates grid columns — and + the contents fade rather than squeeze. */ .atfb__body { - grid-template-columns: 200px 1fr; + grid-template-columns: 200px minmax( 0, 1fr ) 0px; + transition: grid-template-columns 0.28s ease; } + .atfb__palette, .atfb__inspector { - display: none; + overflow: hidden; + transition: opacity 0.18s ease; + } + + .atfb__inspector { + opacity: 0; + pointer-events: none; } - /* One rail's worth of room, so the rail follows the work: the palette - while adding, the inspector the moment a field is selected — otherwise - a narrow window could select a field and have nowhere to edit it. */ - /* The inspector keeps its own side of the room: canvas left, editor - right, exactly where it lives at full width — only the palette yields. */ .atfb--has-selection .atfb__body { - grid-template-columns: minmax( 0, 1fr ) minmax( 220px, 280px ); + grid-template-columns: 0px minmax( 0, 1fr ) 280px; } .atfb--has-selection .atfb__palette { - display: none; + opacity: 0; + pointer-events: none; } .atfb--has-selection .atfb__inspector { - display: block; + opacity: 1; + pointer-events: auto; } } @container ( max-width: 640px ) { - .atfb__body, .atfe__body { grid-template-columns: 1fr; } - .atfb__palette { - display: none; + /* No room for a resting rail at all: the palette starts folded too, and + the inspector still flies in over selection. */ + .atfb__body { + grid-template-columns: 0px minmax( 0, 1fr ) 0px; } - /* Even here a selected field keeps its editor: the inspector takes the - rail back and the canvas keeps the rest. */ .atfb--has-selection .atfb__body { - grid-template-columns: minmax( 0, 1fr ) minmax( 200px, 240px ); + grid-template-columns: 0px minmax( 0, 1fr ) 240px; } } diff --git a/assets/js/builder.js b/assets/js/builder.js index a5ec22b..84d1911 100644 --- a/assets/js/builder.js +++ b/assets/js/builder.js @@ -3409,6 +3409,17 @@ var allTerrainFormsBuilder = function(exports) { this.palette = root.querySelector("[data-atfb-palette]") ?? el("div"); this.canvas = root.querySelector("[data-atfb-canvas]") ?? el("div"); this.inspector = root.querySelector("[data-atfb-inspector]") ?? el("div"); + this.canvas.addEventListener("click", (event) => { + const target = event.target; + if (this.tab !== "build" || !this.selected || target.closest("[data-atfb-card], button, os-button, a, input, textarea, select, os-select, label, [contenteditable]")) { + return; + } + this.selected = null; + for (const card of this.canvas.querySelectorAll(".atfb-card.is-selected")) { + card.classList.remove("is-selected"); + } + this.renderInspector(); + }); } /** Loads everything and paints. */ async start() { diff --git a/assets/js/builder.min.js b/assets/js/builder.min.js index 5da0049..579676a 100644 --- a/assets/js/builder.min.js +++ b/assets/js/builder.min.js @@ -1,3 +1,3 @@ var allTerrainFormsBuilder=function(U){"use strict";class yt{constructor(){this.targets=[],this.active=null,this.lastEndMs=0}start(e){if(this.active||e.origin.button!==0)return null;const{payload:t,origin:s}=e,i=s.clientX,a=s.clientY;let o=!1,l=!1,c=null,d=null,h=0,_=0;const b=()=>{document.removeEventListener("pointermove",E),document.removeEventListener("pointerup",O),document.removeEventListener("pointercancel",X),document.removeEventListener("keydown",z),window.removeEventListener("blur",X),c?.remove(),c=null,t.source.classList.remove("atf-is-dragging"),d?.onLeave?.(v),d=null,this.active=null,this.lastEndMs=Date.now()},v={payload:t,isFinished:()=>l,cancel:(L="caller")=>{l||(l=!0,b(),e.onCancel?.(L))}},x=L=>{o=!0,t.source.classList.add("atf-is-dragging");const q=t.source.getBoundingClientRect();h=t.ghost?.offsetX??i-q.left,_=t.ghost?.offsetY??a-q.top,c=t.ghost?.element??t.source.cloneNode(!0),c.classList.add("atf-drag-ghost"),c.style.width=`${q.width}px`,document.body.appendChild(c),k(L)},k=L=>{c&&(c.style.transform=`translate3d(${L.clientX-h}px, ${L.clientY-_}px, 0)`)},E=L=>{if(l)return;if(!o){if(Math.hypot(L.clientX-i,L.clientY-a)<4)return;x(L)}k(L);const q=this.hitTest(L.clientX,L.clientY);q!==d&&(d?.onLeave?.(v),d=q,d?.onEnter?.(v))},O=L=>{if(l)return;if(!o){l=!0,b(),e.onClickOnly?.();return}const q=d;if(l=!0,b(),q&&q.accept(t)){e.onCommit?.(q),q.onDrop(v,{clientX:L.clientX,clientY:L.clientY});return}e.onCancel?.(q?"rejected":"no-target")},X=()=>v.cancel("pointercancel"),z=L=>{L.key==="Escape"&&v.cancel("escape")};return document.addEventListener("pointermove",E),document.addEventListener("pointerup",O),document.addEventListener("pointercancel",X),document.addEventListener("keydown",z),window.addEventListener("blur",X),this.active=v,v}registerDropTarget(e){return this.targets=this.targets.filter(t=>t.id!==e.id),this.targets.push(e),()=>{this.targets=this.targets.filter(t=>t.id!==e.id)}}isDragging(){return this.active!==null}recentlyEndedDrag(e=500){return Date.now()-this.lastEndMso.right||to.bottom)continue;const l=wt(a.element);if(l>i){s=a,i=l;continue}l===i&&s&&kt(a.element,s.element)&&(s=a)}return s}}function wt(n){let e=0,t=n;for(;t;)e++,t=t.parentElement;return e}function kt(n,e){return(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)!==0}function he(){return window.wp?.os??null}let ue=null;function K(){const n=he();return n?.dragManager?n.dragManager:(ue||(ue=new yt),ue)}function xt(n){const e=i=>{const a=i.detail?.payload;return a&&n.includes(a.type)?a.source:null},t=i=>e(i)?.classList.add("atf-is-dragging"),s=i=>e(i)?.classList.remove("atf-is-dragging");return document.addEventListener("os.drag.start",t),document.addEventListener("os.drag.end",s),()=>{document.removeEventListener("os.drag.start",t),document.removeEventListener("os.drag.end",s)}}function qe(n,e,t,s,i){const a=e.getBoundingClientRect();return i&&(i.style.width=`${Math.round(a.width)}px`,i.style.maxWidth=`${Math.round(a.width)}px`,i.style.boxSizing="border-box"),{type:n,source:e,data:t,ghost:{element:i,offsetX:s.clientX-a.left,offsetY:s.clientY-a.top,hint:{neutral:"",accept:"",reject:"",hidden:!0}}}}function Oe(n,e,t,s){const i=Array.from(n.querySelectorAll(e)).filter(a=>a!==s&&!a.classList.contains("atf-drag-ghost"));for(let a=0;ai.fetch(l,c,{source:"allterrain-forms"}):(l,c)=>fetch(l,c))(t,{credentials:"same-origin",...e,headers:s});if(!o.ok){let l=`Request failed with status ${o.status}.`,c="";try{const d=await o.json();l=d.message??l,c=d.code??""}catch{}throw new ne(l,o.status,c)}if(o.status!==204)return await o.json()}const P=n=>pe(n);async function _t(n){if(!I?.wpRestUrl)throw new ne("AllTerrain Forms is not configured on this page.",0);const e=I.nonce?{"X-WP-Nonce":I.nonce}:{},t=he(),s=Ie(I.wpRestUrl,n),i=t?.fetch?await t.fetch(s,{credentials:"same-origin",headers:e},{source:"allterrain-forms"}):await fetch(s,{credentials:"same-origin",headers:e});if(!i.ok)throw new ne(`Request failed with status ${i.status}.`,i.status);return await i.json()}function St(n){if(!n||!n.includes("&"))return n;const e=document.createElement("textarea");return e.innerHTML=n,e.value}const G=(n,e)=>pe(n,{method:"POST",body:JSON.stringify(e)}),ie=n=>pe(n,{method:"DELETE"});function Me(n){const e=new URLSearchParams;for(const[s,i]of Object.entries(n))i===void 0||i===""||i===!1||e.set(s,String(i));const t=e.toString();return t?`?${t}`:""}function ae(n){const e=n?.schema?.settings;return e&&(!e.themeOverrides||Array.isArray(e.themeOverrides))&&(e.themeOverrides={...e.themeOverrides}),n}const $={config:()=>P("/config"),listForms:()=>P("/forms"),getForm:n=>P(`/forms/${n}`).then(ae),createForm:n=>G("/forms",n).then(ae),updateForm:(n,e)=>G(`/forms/${n}`,e).then(ae),duplicateForm:n=>G(`/forms/${n}/duplicate`,{}).then(ae),deleteForm:n=>ie(`/forms/${n}`),preview:(n,e)=>G(`/forms/${n}/preview`,e),pages:()=>_t("wp/v2/pages?per_page=100&status=publish&orderby=title&order=asc&_fields=id,title").then(n=>n.map(e=>({id:e.id,title:St(e.title?.rendered??"")||`#${e.id}`}))),mergeTags:n=>P(`/forms/${n}/merge-tags`).then(e=>e.groups),analytics:(n,e="")=>P(`/forms/${n}/analytics${e?`?dimension=${encodeURIComponent(e)}`:""}`),demoStatus:()=>P("/demo"),demoSeed:n=>G("/demo",n?{count:n}:{}),demoRemove:()=>ie("/demo"),listEntries:n=>P(`/entries${Me(n)}`),getEntry:n=>P(`/entries/${n}`),updateEntry:(n,e)=>G(`/entries/${n}`,e),deleteEntry:n=>ie(`/entries/${n}`),exportEntries:n=>P(`/entries/export${Me(n)}`),listThemes:()=>P("/themes"),saveTheme:n=>G("/themes",n),deleteTheme:n=>ie(`/themes/${n}`)};function r(n,e={}){const t=document.createElement(n);e.class&&(t.className=e.class),e.text!==void 0&&(t.textContent=e.text),e.html!==void 0&&(t.innerHTML=e.html),e.title&&(t.title=e.title),e.type&&"type"in t&&(t.type=e.type),e.value!==void 0&&"value"in t&&(t.value=e.value),e.placeholder!==void 0&&"placeholder"in t&&(t.placeholder=e.placeholder),e.href&&"href"in t&&(t.href=e.href);for(const[s,i]of Object.entries(e.attrs??{}))i===void 0||i===!1||t.setAttribute(s,i===!0?"":String(i));Object.assign(t.style,e.style??{});for(const[s,i]of Object.entries(e.on??{}))t.addEventListener(s,i);for(const s of e.children??[])s==null||s===!1||t.append(s);return t}function D(n){n.replaceChildren()}function M(n){return r("span",{class:`dashicons ${n.startsWith("dashicons-")?n:`dashicons-${n}`}`,attrs:{"aria-hidden":"true"}})}function m(n,e,t){const s=e.matches("input, select, textarea, button")?e:e.querySelector("input, select, textarea");if(s){const i=s.id||`atf-c-${Math.random().toString(36).slice(2,9)}`;return s.id=i,r("div",{class:"atfb-row",children:[r("label",{class:"atfb-row__label",text:n,attrs:{for:i}}),e,t?r("p",{class:"atfb-row__hint",text:t}):null]})}return r("div",{class:"atfb-row",children:[r("span",{class:"atfb-row__label",text:n}),e,t?r("p",{class:"atfb-row__hint",text:t}):null]})}function w(n,e,t=""){return r("input",{class:"atfb-input",type:"text",value:n,placeholder:t,on:{input:s=>e(s.target.value)}})}function R(n,e){if(Z("os-number-field")){const t=document.createElement("os-number-field");return t.setAttribute("value",n),t.classList.add("atfb-field"),t.addEventListener("os-input-change",s=>{e(String(s.detail?.value??""))}),t}return r("input",{class:"atfb-input",type:"number",value:n,on:{input:t=>e(t.target.value)}})}function re(n,e,t=4){const s=r("textarea",{class:"atfb-input atfb-input--area",attrs:{rows:t},on:{input:i=>e(i.target.value)}});return s.value=n,s}function F(n,e,t){if(Z("os-select")&&Z("os-option")){const s=document.createElement("os-select");s.setAttribute("value",n),s.classList.add("atfb-field");for(const i of e){const a=document.createElement("os-option");a.setAttribute("value",i.value),a.textContent=i.label,s.append(a)}return s.addEventListener("os-pick",i=>{t(String(i.detail?.value??""))}),s}return r("select",{class:"atfb-input atfb-select",on:{change:s=>t(s.target.value)},children:e.map(s=>r("option",{value:s.value,text:s.label,attrs:{selected:s.value===n}}))})}function A(n,e,t){if(Z("os-checkbox-label")){const i=document.createElement("os-checkbox-label");return i.setAttribute("label",n),i.classList.add("atfb-check"),e&&i.setAttribute("checked",""),i.addEventListener("os-checkbox-change",a=>{t(!!a.detail?.checked)}),i}const s=r("input",{type:"checkbox",on:{change:i=>t(i.target.checked)}});return s.checked=e,r("label",{class:"atfb-check",children:[s,r("span",{text:n})]})}function S(n,e,t="secondary",s){const i=[s?M(s):null,r("span",{text:n})];if(Z("os-button")){const a=document.createElement("os-button");a.setAttribute("variant",t),a.setAttribute("type","button"),a.classList.add("atfb-button",`atfb-button--${t}`),a.addEventListener("click",e);for(const o of i)o&&a.append(o);return a}return r("button",{class:`atfb-button atfb-button--${t}`,type:"button",on:{click:e},children:i})}function Z(n){return typeof customElements<"u"&&!!customElements.get(n)}const Et=["os-button","os-checkbox-label","os-number-field","os-select","os-option","os-segmented","os-segment","os-color-field","os-empty-state"];let oe=null;function Lt(){if(oe)return oe;const n=window.wp?.os;return oe=n?.loadComponents?n.loadComponents(Et).catch(()=>{}):Promise.resolve(),oe}async function fe(n,e=""){const t=window.wp?.os;return t?.confirm?t.confirm({title:e,message:n,danger:!0}):window.confirm(n)}function N(n,e="",t="info"){const s=window.wp?.os;if(s?.notify){s.notify({title:n,body:e,type:t});return}console.info(`[AllTerrain Forms] ${n}${e?`: ${e}`:""}`)}function Ct(n){let e=0,t;return(...s)=>{t=s,!e&&(e=window.requestAnimationFrame(()=>{e=0,n(...t)}))}}function me(n,e){let t=0;return(...s)=>{window.clearTimeout(t),t=window.setTimeout(()=>n(...s),e)}}function Tt(n){try{return window.localStorage.getItem(n)??""}catch{return""}}function $t(n,e){try{window.localStorage.setItem(n,e)}catch{}}function Ne(n){const e=n.closest(".os-window__body");e&&(e.addEventListener("scroll",()=>{e.scrollTop&&(e.scrollTop=0),e.scrollLeft&&(e.scrollLeft=0)},{passive:!0}),e.scrollTop=0,e.scrollLeft=0)}function Pe(){const n=[window];try{window.parent&&window.parent!==window&&n.push(window.parent)}catch{}return n}function At(n){const e=n.wp?.os?.windowManager?.getAll?.()??[];for(const t of e){const s=t.iframe??t.element?.querySelector?.("iframe");if(s&&s.contentWindow===window)return t}return null}const Ft=4e3,Dt=100;function qt(n,e){const t=Date.now()+Ft,s=()=>{const i=At(n);if(i&&i.id!==e){typeof i.close=="function"?i.close():n.wp?.os?.windowManager?.remove?.(i.id);return}!i&&Date.now()0?{form:t}:void 0;t>0&&Nt(t);for(const i of Pe())if(i.wp?.os?.openWindow?.(e,{source:"handoff",params:s})){window.setTimeout(()=>qt(i,e),0);return}}function It(){document.addEventListener("click",n=>{const e=n.target?.closest?.("[data-atf-open-window]");if(!e)return;n.preventDefault();const t=e.getAttribute("data-atf-open-window")??"";for(const s of Pe())if(s.wp?.os?.openWindow?.(t,{source:"handoff"}))return})}const Mt="allterrain-forms/requested-form";function Nt(n){try{window.sessionStorage.setItem(Mt,String(n))}catch{}}function Re(n){return`allterrain-forms/requested-form-${n}`}function Pt(n){try{const e=window.sessionStorage.getItem(Re(n));return window.sessionStorage.removeItem(Re(n)),Number(e)||0}catch{return 0}}const Be={is:"is",is_not:"is not",contains:"contains",not_contains:"does not contain",starts_with:"starts with",ends_with:"ends with",greater:"is more than",less:"is less than",greater_equal:"is at least",less_equal:"is at most",empty:"is empty",not_empty:"has any answer"},He=["empty","not_empty"];function je(n,e){const t=n.find(s=>s.id===e);return t?t.label||"an untitled question":null}function Ue(n,e,t){return n.find(a=>a.id===e)?.choices?.find(a=>a.value===t)?.label||t}function Rt(n,e){const t=Be[n.operator]??String(n.operator);if(He.includes(n.operator))return t;const s=Ue(e,n.field,n.value);return`${n.operator==="is"?"":`${t} `}${s!==""?s:"(nothing)"}`}function We(n,e){const t=je(e,n.field),s=Be[n.operator]??String(n.operator);if(t===null)return[{kind:"field",text:"a question that no longer exists",fieldId:n.field,missing:!0}];const i=[{kind:"field",text:t,fieldId:n.field,missing:!1},{kind:"operator",text:s}];if(He.includes(n.operator))return i;const a=Ue(e,n.field,n.value);return i.push({kind:"value",text:a!==""?a:"(nothing)"}),i}function Bt(n,e){const t=n.logic;if(!t?.enabled||!t.rules.length)return[];const s=[{kind:"verb",text:t.action==="hide"?"Hidden when":"Shown when"}];return t.rules.forEach((i,a)=>{a>0&&s.push({kind:"join",text:t.match==="all"?"and":"or"}),s.push(...We(i,e))}),s}function Ye(n){return n.map(e=>e.text).join(" ")}function Ht(n,e){return Ye(We(n,e))}function be(n){const e=[];for(const t of n){const s=t.logic;if(s?.enabled)for(const i of s.rules)!i.field||i.field===t.id||e.push({from:i.field,to:t.id,label:Ht(i,n),short:Rt(i,n),action:s.action,broken:je(n,i.field)===null})}return e}function jt(n){const e=new Map,t=new Set;for(const s of be(n)){const i=`${s.from}->${s.to}`;s.broken||t.has(i)||(t.add(i),e.set(s.from,(e.get(s.from)??0)+1))}return e}const ze=10,Ge=22,J="http://www.w3.org/2000/svg";class Ut{constructor(e){this.edges=[],this.teardowns=[],this.frame=0,this.host=e,this.svg=document.createElementNS(J,"svg"),this.svg.setAttribute("class","atfb-logicmap"),this.svg.setAttribute("aria-hidden","true"),this.svg.setAttribute("focusable","false"),e.append(this.svg);const t=()=>this.schedule();window.addEventListener("resize",t),this.teardowns.push(()=>window.removeEventListener("resize",t));const s=e.closest(".atfb__canvas")??e;if(s.addEventListener("scroll",t,{passive:!0}),this.teardowns.push(()=>s.removeEventListener("scroll",t)),typeof ResizeObserver<"u"){const i=new ResizeObserver(t);i.observe(e),this.teardowns.push(()=>i.disconnect())}}setEdges(e){this.edges=e,this.schedule()}highlight(e){this.svg.classList.toggle("is-focused",!!e),this.svg.querySelectorAll("[data-from]").forEach(t=>{const s=e&&(t.dataset.from===e||t.dataset.to===e);t.classList.toggle("is-lit",!!s)})}destroy(){this.teardowns.forEach(e=>e()),this.teardowns=[],this.svg.remove(),this.frame&&cancelAnimationFrame(this.frame)}schedule(){this.frame||(this.frame=requestAnimationFrame(()=>{this.frame=0,this.draw()}))}draw(){this.svg.replaceChildren();const e=this.host.getBoundingClientRect();this.svg.setAttribute("viewBox",`0 0 ${e.width} ${e.height}`),this.svg.setAttribute("width",String(e.width)),this.svg.setAttribute("height",String(e.height));const t=new Map;for(const s of this.edges){const i=this.cardRect(s.from),a=this.cardRect(s.to);if(!i||!a)continue;const o=t.get(s.from)??0;t.set(s.from,o+1),this.drawEdge(s,i,a,e,o)}}cardRect(e){const t=this.host.querySelector(`[data-atfb-card="${CSS.escape(e)}"]`);return t?t.getBoundingClientRect():null}drawEdge(e,t,s,i,a){const o=t.right-i.left,l=t.top+t.height/2-i.top,c=s.right-i.left,d=s.top+s.height/2-i.top,h=Math.max(0,i.width-ze-Math.max(o,c)),_=22+a*11+Math.min(22,Math.abs(d-l)/8),b=Math.max(12,Math.min(_,h*.4)),v=document.createElementNS(J,"path");v.setAttribute("d",`M ${o} ${l} C ${o+b} ${l}, ${c+b} ${d}, ${c} ${d}`),v.setAttribute("class",`atfb-logicmap__path is-${e.action}${e.broken?" is-broken":""}`),v.dataset.from=e.from,v.dataset.to=e.to;const x=document.createElementNS(J,"title");x.textContent=e.label,v.append(x);const k=document.createElementNS(J,"circle");k.setAttribute("cx",String(c)),k.setAttribute("cy",String(d)),k.setAttribute("r","3.5"),k.setAttribute("class",`atfb-logicmap__dot is-${e.action}${e.broken?" is-broken":""}`),k.dataset.from=e.from,k.dataset.to=e.to,this.svg.append(v,k);const E=document.createElementNS(J,"text");E.setAttribute("x",String(i.width-ze)),E.setAttribute("y",String(d+3)),E.setAttribute("text-anchor","end"),E.setAttribute("class","atfb-logicmap__label"),E.dataset.from=e.from,E.dataset.to=e.to,E.textContent=e.short.length>Ge?`${e.short.slice(0,Ge-1)}…`:e.short;const O=document.createElementNS(J,"title");O.textContent=e.label,E.append(O),this.svg.append(E)}}const Wt={text:"text",email:"text",url:"text",tel:"text",number:"text",password:"text",date:"text",time:"text",datetime:"text",date_range:"composite",textarea:"textarea",select:"select",country:"select",multiselect:"options",radio:"options",checkboxes:"options",image_choice:"options",quiz:"options",switch:"toggle",consent:"toggle",file:"file",range:"range",rating:"summary",scale:"summary",likert:"summary",signature:"summary",repeater:"summary",color:"text",name:"composite",address:"composite",total:"text",hidden:"static",heading:"static",html:"static",divider:"static",spacer:"static",page_break:"static"};function Yt(n){return Wt[n]??"text"}function Xe(n,e){const t=/^choice:(\d+):(label|value)$/.exec(e);return String(t?n.choices?.[Number(t[1])]?.[t[2]]??"":n[e]??"")}function W(n){const{value:e,onInput:t,onCommit:s}=n,i=r("span",{class:`${n.class} atfb-editable`,text:e,attrs:{contenteditable:"plaintext-only",role:"textbox",spellcheck:"false","data-placeholder":n.placeholder}});return n.bind&&(i.dataset.atfbBind=n.bind),i.addEventListener("pointerdown",a=>a.stopPropagation()),i.addEventListener("input",()=>t(i.textContent??"")),i.addEventListener("keydown",a=>{a.key==="Enter"&&(a.preventDefault(),i.blur()),a.key==="Escape"&&(i.textContent=e,i.blur()),a.stopPropagation()}),i.addEventListener("blur",()=>s?.()),i}function zt(n){const e=r("input",{class:"atf-choice__input",type:n==="checkboxes"||n==="multiselect"?"checkbox":"radio"});return e.disabled=!0,e}function Gt(n,e,t){const s=Yt(n.type),i=W({value:n.label,placeholder:"Write the question…",class:"atf-label",bind:"label",onInput:o=>t.edit(l=>{l.label=o}),onCommit:()=>t.restructure(()=>{})}),a=[s==="static"||s==="toggle"?null:i,Kt(n,e,s,t),Xt(n,e,t)];return r("div",{class:"atfb-preview atf-form",children:[r("div",{class:`atf-field atf-field--${n.type}`,children:a})]})}function Xt(n,e,t){if(!e?.supports.includes("hint"))return null;const s=W({value:n.hint??"",placeholder:"Add a hint…",class:"atf-hint",bind:"hint",onInput:i=>t.edit(a=>{a.hint=i})});return s.setAttribute("aria-label","Hint"),r("p",{class:"atfb-preview__hint",children:[s]})}function Kt(n,e,t,s){switch(t){case"text":return ge(n,"atf-input",s);case"textarea":return ge(n,"atf-input atf-textarea",s,!0);case"select":return r("div",{class:"atfb-preview__select",children:[ge(n,"atf-input atf-select",s)]});case"options":return Vt(n,s);case"toggle":return r("div",{class:n.type==="switch"?"atf-toggle atf-toggle--switch":"atf-toggle",children:[(()=>{const i=r("input",{class:"atf-toggle__input",type:"checkbox"});return i.disabled=!0,i})(),W({value:n.label||"",placeholder:n.type==="consent"?"What are they agreeing to?…":"What does this turn on?…",class:"atf-toggle__label",bind:"label",onInput:i=>s.edit(a=>{a.label=i}),onCommit:()=>s.restructure(()=>{})})]});case"file":return r("div",{class:"atf-file",children:[r("input",{class:"atf-file__input",type:"file"})]});case"range":return r("input",{class:"atf-range__input",type:"range"});case"composite":return r("div",{class:"atf-composite__parts",children:[r("span",{class:"atf-input atfb-preview__ghost",text:""}),r("span",{class:"atf-input atfb-preview__ghost",text:""})]});case"static":return Qt(n,e,s);default:return r("div",{class:"atfb-preview__stack",children:[r("p",{class:"atfb-preview__summary",text:`${e?.label??n.type} — set this up in the panel on the right.`}),n.type==="repeater"?Jt(n,s):null]})}}function ge(n,e,t,s=!1){const i=W({value:n.placeholder??"",placeholder:n.type==="select"||n.type==="country"?"Choose…":"Placeholder…",class:`${e} atfb-preview__box${s?" atfb-preview__box--tall":""}`,bind:"placeholder",onInput:a=>t.edit(o=>{o.placeholder=a})});return i.setAttribute("aria-label","Placeholder"),i}function ve(n,e,t,s,i,a){return r("span",{class:`atf-button ${t} atfb-preview__button`,children:[W({value:n,placeholder:e,class:"atfb-preview__button-text",bind:s,onInput:o=>i.edit(l=>a(l,o))})]})}function Jt(n,e){return ve(String(n.addLabel??""),"Add another","atf-button--secondary","addLabel",e,(t,s)=>{t.addLabel=s})}function Vt(n,e){const t=r("div",{class:"atf-choices__list"});return(n.choices??[]).forEach((s,i)=>{t.append(r("div",{class:"atf-choice atfb-preview__option",children:[zt(n.type),W({value:s.label,placeholder:"Option…",class:"atf-choice__label",bind:`choice:${i}:label`,onInput:a=>{e.edit(o=>{const l=o.choices?.[i];if(!l)return;const c=!l.value||l.value===l.label;l.label=a,c&&(l.value=a)})}}),r("button",{class:"atfb-preview__remove",type:"button",title:"Remove this option",attrs:{"aria-label":`Remove ${s.label||"this option"}`},on:{pointerdown:a=>a.stopPropagation(),click:a=>{a.stopPropagation(),e.restructure(o=>{o.choices.splice(i,1)})}},children:[r("span",{text:"×"})]})]}))}),t.append(r("button",{class:"atfb-preview__add",type:"button",on:{pointerdown:s=>s.stopPropagation(),click:s=>{s.stopPropagation(),e.restructure(i=>{const a=i.choices.length+1;i.choices.push({label:`Option ${a}`,value:`Option ${a}`})})}},children:[r("span",{text:"+ Add option"})]})),r("fieldset",{class:"atf-choices",children:[t]})}function Qt(n,e,t){return n.type==="heading"?W({value:n.label,placeholder:"Section heading…",class:"atf-heading",bind:"label",onInput:s=>t.edit(i=>{i.label=s}),onCommit:()=>t.restructure(()=>{})}):n.type==="divider"?r("hr",{class:"atf-divider"}):n.type==="page_break"?r("div",{class:"atfb-preview__stack",children:[r("p",{class:"atfb-progress-name",children:[W({value:n.label,placeholder:"Name this step…",class:"atf-progress__label",bind:"label",onInput:s=>t.edit(i=>{i.label=s}),onCommit:()=>t.restructure(()=>{})})]}),r("p",{class:"atfb-preview__summary",text:"Everything after this is a new page."}),r("div",{class:"atf-nav atfb-preview__nav",children:[ve(String(n.prevLabel??""),"Back","atf-button--secondary","prevLabel",t,(s,i)=>{s.prevLabel=i}),ve(String(n.nextLabel??""),"Next","","nextLabel",t,(s,i)=>{s.nextLabel=i})]})]}):r("p",{class:"atfb-preview__summary",text:`${e?.label??n.type} — nothing is shown to the visitor here.`})}const ye=new Map;function we(n){let e=ye.get(n);return e||(e=$.mergeTags(n).catch(()=>[]),ye.set(n,e)),e}function Zt(n){ye.delete(n)}function es(n){const e=new Map;for(const t of n)for(const s of t.items)e.set(s.tag,s);return e}function ts(n,e){const t=es(e);return n.replace(/\{[a-z_]+(?::[^}]*)?\}/gi,s=>{const i=t.get(s.toLowerCase());return i?i.sample:s})}function ss(n){return/\{[a-z_]+(?::[^}]*)?\}/i.test(n)}let Y=null;function ee(){Y?.remove(),Y=null}typeof document<"u"&&(document.addEventListener("pointerdown",n=>{const e=n.target;e?.closest(".atfb-tagpick__open")||Y&&!Y.contains(e)&&ee()}),document.addEventListener("keydown",n=>{n.key==="Escape"&&Y&&(ee(),n.stopPropagation())}));function Ke(n,e){const t=n.selectionStart??n.value.length,s=n.selectionEnd??n.value.length;n.value=n.value.slice(0,t)+e+n.value.slice(s);const i=t+e.length;n.setSelectionRange(i,i),n.focus(),n.dispatchEvent(new Event("input",{bubbles:!0}))}function ns(n){let e=n.parentElement;for(;e&&e!==document.body;){const t=getComputedStyle(e).overflowY;if(t==="auto"||t==="scroll"||t==="hidden")return e.getBoundingClientRect().bottom;e=e.parentElement}return window.innerHeight}function is(n,e){const t=r("input",{class:"atfb-input atfb-tagpick__search",type:"search",placeholder:"Search values…",attrs:{"aria-label":"Search values"}}),s=r("div",{class:"atfb-tagpick__list"}),i=a=>{s.replaceChildren();const o=a.trim().toLowerCase();let l=0;for(const c of n){const d=c.items.filter(h=>!o||h.label.toLowerCase().includes(o)||h.tag.toLowerCase().includes(o));if(!d.length){c.empty&&!o&&!c.items.length&&s.append(r("p",{class:"atfb-tagpick__group",text:c.label}),r("p",{class:"atfb-tagpick__empty",text:c.empty}));continue}s.append(r("p",{class:"atfb-tagpick__group",text:c.label}));for(const h of d)l+=1,s.append(r("button",{class:"atfb-tagpick__item",type:"button",on:{click:()=>{e(h.tag),ee()}},children:[r("span",{class:"atfb-tagpick__item-main",children:[r("span",{class:"atfb-tagpick__label",text:h.label}),r("code",{class:"atfb-tagpick__tag",text:h.tag})]}),h.hint||h.sample?r("span",{class:"atfb-tagpick__meta",text:h.sample?`e.g. ${h.sample}`:h.hint}):null]}))}!l&&o&&s.append(r("p",{class:"atfb-tagpick__empty",text:`Nothing matches “${a}”.`}))};return i(""),t.addEventListener("input",()=>i(t.value)),r("div",{class:"atfb-tagpick",attrs:{role:"dialog","aria-label":"Insert a value"},children:[r("p",{class:"atfb-tagpick__intro",text:"Pick something to drop in. It is filled in when the form is submitted."}),t,s]})}function Je(n,e){const t=r("button",{class:"atfb-button atfb-button--ghost atfb-tagpick__open",type:"button",title:"Insert a value from the submission",children:[M("shortcode"),r("span",{text:"Insert a value"})]}),s=r("div",{class:"atfb-taggable",children:[n,r("div",{class:"atfb-taggable__tools",children:[t]})]}),i=e.preview===!1?null:r("p",{class:"atfb-taggable__preview"});i&&s.append(i);const a=()=>{if(i){if(!ss(n.value)){i.textContent="",i.hidden=!0;return}we(e.formId).then(o=>{i.hidden=!1,i.replaceChildren(r("span",{class:"atfb-taggable__preview-label",text:"Reads as"}),r("span",{text:ts(n.value,o)}))})}};return n.addEventListener("input",a),a(),t.addEventListener("click",o=>{if(o.stopPropagation(),Y&&s.contains(Y)){ee();return}ee(),we(e.formId).then(l=>{const c=is(l,d=>{Ke(n,d),a()});s.append(c),Y=c,(window.innerHeight-c.getBoundingClientRect().topns(s))&&c.classList.add("atfb-tagpick--above"),c.querySelector(".atfb-tagpick__search")?.focus()})}),s}function Ve(n,e){const t=parseFloat(String(n??""));return Number.isFinite(t)?t:e}function Qe(n,e){let t=e[0];for(const s of e)Math.abs(s.at-n)n.accent??"#2271b1",apply:n=>({accent:n,"accent-soft":`color-mix( in srgb, ${n} 12%, transparent )`,"border-focus":n,"focus-ring-color":n,"button-bg":n,"button-bg-hover":`color-mix( in srgb, ${n} 88%, #000 )`})},{id:"roundness",label:"Roundness",hint:"Corners, everywhere at once.",kind:"scale",steps:ke.map(({value:n,label:e})=>({value:n,label:e})),owns:["radius-field","radius-button","radius-card","radius-check"],read:n=>Qe(Ve(n["radius-field"],4),ke),apply:n=>{const e=ke.find(t=>t.value===n)?.at??4;return{"radius-field":`${e}px`,"radius-button":`${e}px`,"radius-card":`${Math.min(e*2,28)}px`,"radius-check":`${Math.min(e,6)}px`}}},{id:"density",label:"Density",hint:"How much air the form has.",kind:"scale",steps:xe.map(({value:n,label:e})=>({value:n,label:e})),owns:["pad-field-x","pad-field-y","gap-fields","gap-label","button-pad-x","button-pad-y"],read:n=>Qe(Ve(n["pad-field-y"],9),xe),apply:n=>{const e=xe.find(t=>t.value===n)?.at??9;return{"pad-field-y":`${e}px`,"pad-field-x":`${Math.round(e*1.4)}px`,"gap-fields":`${Math.round(e*2.2)}px`,"gap-label":`${Math.max(4,Math.round(e*.7))}px`,"button-pad-y":`${e+2}px`,"button-pad-x":`${Math.round(e*2.2)}px`}}},{id:"shadow",label:"Depth",hint:"How far the form sits off the page.",kind:"scale",steps:as,owns:["shadow-field","shadow-field-focus","shadow-button","shadow-button-hover","shadow-card"],read:n=>{const e=n["shadow-card"]??"none";return e==="none"||e.trim()===""?n["shadow-field"]&&n["shadow-field"]!=="none"?"hard":"none":e.includes("0 1px")||e.includes("2px")?"subtle":"lifted"},apply:n=>{switch(n){case"subtle":return{"shadow-field":"none","shadow-field-focus":"none","shadow-button":"0 1px 2px rgba( 0, 0, 0, 0.12 )","shadow-button-hover":"0 2px 4px rgba( 0, 0, 0, 0.16 )","shadow-card":"0 1px 3px rgba( 0, 0, 0, 0.1 )"};case"lifted":return{"shadow-field":"none","shadow-field-focus":"0 4px 12px rgba( 0, 0, 0, 0.12 )","shadow-button":"0 4px 10px rgba( 0, 0, 0, 0.16 )","shadow-button-hover":"0 8px 20px rgba( 0, 0, 0, 0.2 )","shadow-card":"0 10px 30px rgba( 0, 0, 0, 0.14 )"};case"hard":return{"shadow-field":"3px 3px 0 currentColor","shadow-field-focus":"5px 5px 0 currentColor","shadow-button":"4px 4px 0 currentColor","shadow-button-hover":"2px 2px 0 currentColor","shadow-card":"none"};default:return{"shadow-field":"none","shadow-field-focus":"none","shadow-button":"none","shadow-button-hover":"none","shadow-card":"none"}}}},{id:"field-style",label:"Fields",hint:"How an input is drawn.",kind:"choice",steps:rs,owns:["field-style"],read:n=>n["field-style"]??"outline",apply:n=>({"field-style":n})},{id:"labels",label:"Labels",hint:"Where the question sits relative to the answer.",kind:"choice",steps:os,owns:["label-position"],read:n=>n["label-position"]??"top",apply:n=>({"label-position":n})}]}function ls(n){return _e().find(e=>e.owns.includes(n))??null}function Ze(n){let e=n.activeSlug,t={...n.overrides},s=n.themes;const i=u=>{t=u,n.onOverridesReplaced?.({...u})},a=r("div",{class:"atfs-preview__frame"}),o=r("div",{class:"atfs-controls__body"}),l=r("div",{class:"atfs-quick"}),c=r("div",{class:"atfs-themes"}),d=me(async()=>{try{const u=await n.previewFor(e,t),p=a.closest(".atf-studio__preview"),f=p?.scrollTop??0;a.innerHTML=u,p&&(p.scrollTop=f),document.dispatchEvent(new CustomEvent("atf-refresh"))}catch(u){D(a),a.append(r("p",{class:"atfb-error",text:u instanceof Error?u.message:"Preview failed."}))}},180),h={"label-position":"atf-labels-","field-style":"atf-fields-"},_=(u,p,f)=>{const g=f.replace(/[^a-z0-9_-]/gi,"");for(const y of[...u.classList])y.startsWith(p)&&u.classList.remove(y);g&&u.classList.add(p+g)},b=u=>{const p=a.querySelector(".atf-form-wrap"),f=p?.querySelector(".atf-form");if(p)for(const[g,y]of Object.entries(u))y===""?p.style.removeProperty(`--atf-${g}`):p.style.setProperty(`--atf-${g}`,y),f&&h[g]&&_(f,h[g],y||(s.find(T=>T.slug===e)?.resolved[g]??""))},v=u=>{b(u.resolved);const p=a.querySelector(".atf-form");p&&(_(p,"atf-theme-",u.slug),p.classList.toggle("atf-is-dark",!!u.dark))},x=u=>t[u.token]!==void 0?t[u.token]:s.find(f=>f.slug===e)?.resolved?.[u.token]??u.default,k=()=>{D(c);for(const u of s){const p=r("button",{class:`atfs-theme${u.slug===e?" is-active":""}`,type:"button",attrs:{"aria-pressed":u.slug===e,title:u.description},children:[r("span",{class:"atfs-theme__chip",style:{background:u.resolved.surface??"#fff",borderColor:u.resolved.border??"#ccc",borderRadius:u.resolved["radius-field"]??"4px",boxShadow:u.resolved["shadow-card"]??"none"},children:[r("span",{class:"atfs-theme__accent",style:{background:u.resolved.accent??"#2271b1",borderRadius:u.resolved["radius-button"]??"4px"}})]}),r("span",{class:"atfs-theme__name",text:u.label}),u.custom?r("span",{class:"atfb-badge",text:"yours"}):null],on:{click:()=>{e=u.slug,i({}),n.onTheme(e),v(u),k(),z(),X(),bt()}}});c.append(p)}},E=()=>{const p={...s.find(f=>f.slug===e)?.resolved??{}};for(const[f,g]of Object.entries(t))p[f]=g;return p},O=u=>{const p=l.closest(".atf-studio__controls"),f=p?.scrollTop??0;u(),p&&(p.scrollTop=f)},X=me(()=>O(Q),150),z=()=>{const u=E(),p=l.querySelectorAll(".atfs-dial");_e().forEach((f,g)=>{const y=p[g];if(!y)return;const T=f.read(u);if(f.kind==="colour"){const C=y.querySelector('input[type="color"]'),B=y.querySelector("input.atfb-input");C&&document.activeElement!==C&&(C.value=le(T)),B&&document.activeElement!==B&&(B.value=T);return}y.querySelectorAll(".atfs-segment").forEach((C,B)=>{const j=f.steps?.[B]?.value===T;C.classList.toggle("is-on",j),C.setAttribute("aria-pressed",String(j))})})},L=(u,p)=>{const f=u.apply(p,E());for(const[g,y]of Object.entries(f))t[g]=y,n.onOverride(g,y);b(f),z(),X()},q=()=>{D(l);const u=E();for(const p of _e()){const f=p.read(u);let g;if(p.kind==="colour"){const y=r("input",{class:"atfs-color",type:"color",value:le(f),attrs:{"aria-label":p.label},on:{input:T=>L(p,T.target.value)}});g=r("div",{class:"atfs-color-row",children:[y,w(f,T=>L(p,T))]})}else g=r("div",{class:`atfs-segmented atfs-segmented--${p.kind}`,attrs:{role:"group","aria-label":p.label},children:(p.steps??[]).map(y=>r("button",{class:`atfs-segment${y.value===f?" is-on":""}`,type:"button",text:y.label,attrs:{"aria-pressed":y.value===f},on:{click:()=>L(p,y.value)}}))});l.append(r("div",{class:"atfs-dial",children:[r("div",{class:"atfs-dial__head",children:[r("span",{class:"atfs-dial__label",text:p.label}),r("span",{class:"atfs-dial__hint",text:p.hint})]}),g]}))}},Q=()=>{D(o);const u=new Map;for(const f of n.tokens){const g=u.get(f.group)??[];g.push(f),u.set(f.group,g)}const p={colour:"Colour",shape:"Corners and borders",shadow:"Shadows",fields:"Field style",space:"Spacing",type:"Type",labels:"Labels",button:"Buttons",focus:"Focus ring",motion:"Motion"};for(const[f,g]of u)o.append(r("details",{class:"atfs-group",attrs:{open:f==="colour"},children:[r("summary",{text:p[f]??f}),...g.map(y=>Ds(y))]}))},Ds=u=>{const p=x(u),f=C=>{C===""?delete t[u.token]:t[u.token]=C,n.onOverride(u.token,C),b({[u.token]:C})};let g;if(u.control==="color"){const C=r("input",{class:"atfs-color",type:"color",value:le(p),attrs:{"aria-label":`${u.label} colour`},on:{input:j=>{const se=j.target.value;B.value=se,f(se)}}}),B=w(p,j=>{C.value=le(j),f(j)});g=r("div",{class:"atfs-color-row",children:[C,B]})}else if(u.control==="select")g=F(p,(u.options??[]).map(C=>({value:C,label:C})),f);else if(u.control==="length"){const C=parseFloat(p)||0,B=u.unit??"px",j=u.token.includes("radius")?60:80,se=r("input",{class:"atfs-range",type:"range",value:String(C),attrs:{min:"0",max:String(j),step:"1","aria-label":u.label},on:{input:de=>{const vt=`${de.target.value}${B}`;gt.value=vt,f(vt)}}}),gt=w(p,de=>{se.value=String(parseFloat(de)||0),f(de)});g=r("div",{class:"atfs-length-row",children:[se,gt]})}else g=w(p,f);const y=m(u.label,g),T=ls(u.token);return T&&(y.classList.add("is-dialled"),y.append(r("span",{class:"atfs-owned",text:T.label}))),t[u.token]!==void 0&&(y.classList.add("is-overridden"),y.append(r("button",{class:"atfs-reset",type:"button",text:"Reset",attrs:{"aria-label":`Reset ${u.label} to the theme's value`},on:{click:()=>{f(""),O(Q)}}}))),y},qs=async()=>{const u=s.find(g=>g.slug===e),p=u?`${u.label} (mine)`:"My theme",f=window.prompt("Name this theme",p);if(f)try{const g={};for(const T of n.tokens){const C=x(T);C!==T.default&&(g[T.token]=C)}const y=await $.saveTheme({label:f,tokens:g});s=[...s.filter(T=>T.slug!==y.slug),y],n.onThemesChanged(s),e=y.slug,i({}),n.onTheme(e),k(),z(),O(Q),N("Theme saved",y.label)}catch(g){N("Could not save the theme",g instanceof Error?g.message:"","error")}},Os=async()=>{const u=s.find(p=>p.slug===e);if(u?.custom&&await fe(`Delete “${u.label}”? Forms using it fall back to Clean.`,"Delete theme"))try{await $.deleteTheme(u.id),s=s.filter(f=>f.slug!==u.slug),n.onThemesChanged(s),e="clean",i({}),n.onTheme(e),k(),z(),O(Q);const p=s.find(f=>f.slug===e);p&&v(p)}catch(p){N("Could not delete the theme",p instanceof Error?p.message:"","error")}},Is=async()=>{const u=s.find(g=>g.slug===e),p={label:u?.label??e,tokens:{...u?.tokens??{},...t}},f=JSON.stringify(p,null," ");try{await navigator.clipboard.writeText(f),N("Theme copied","Paste it into another site to import it.")}catch{window.prompt("Copy this theme",f)}},Ms=()=>{const u=window.prompt("Paste a theme");if(u)try{const p=JSON.parse(u);if(!p.tokens||typeof p.tokens!="object")throw new Error("That does not look like a theme.");for(const[f,g]of Object.entries(p.tokens))t[f]=String(g),n.onOverride(f,String(g));b({...t}),z(),O(Q)}catch(p){N("Could not read that theme",p instanceof Error?p.message:"","error")}},mt=S("Delete",()=>void Os(),"danger"),bt=()=>{const u=s.find(p=>p.slug===e);mt.hidden=!u?.custom};return k(),q(),Q(),d(),bt(),r("div",{class:"atf-studio",children:[r("div",{class:"atf-studio__top",children:[r("div",{class:"atf-studio__topbar",children:[r("h2",{class:"atf-studio__heading",text:"Theme"}),r("div",{class:"atfs__actions",children:[S("Save as a theme",()=>void qs(),"primary"),S("Export",()=>void Is()),S("Import",Ms),mt]})]}),c]}),r("div",{class:"atf-studio__panes",children:[r("aside",{class:"atf-studio__controls",children:[r("p",{class:"atfb-hint",text:"Changes apply to this form only, until you save them as a theme."}),l,r("details",{class:"atfs-advanced",children:[r("summary",{text:"Every setting"}),r("p",{class:"atfb-hint",text:"The full token list. The dials above write into it."}),o]})]}),r("main",{class:"atf-studio__preview",children:[r("h2",{class:"screen-reader-text",text:"Live preview"}),a]})]})]})}async function Se(){const n=document.querySelector("[data-atfs-root]");if(!n||n.dataset.atfsMounted)return;n.dataset.atfsMounted="1",Ne(n);const e=n.querySelector("[data-atfs-bar]"),t=n.querySelector(".atfs__body")??n;try{const[s,i,a]=await Promise.all([$.config(),$.listThemes(),$.listForms()]);if(!a.length){D(t),t.append(r("div",{class:"atfb-empty",children:[r("h2",{text:"No forms to preview"}),r("p",{text:"Make a form first — a theme needs something to dress."})]}));return}let o=a[0],l={},c=o.theme;const d=()=>{D(t),t.append(Ze({themes:i,tokens:s.tokens,activeSlug:c,overrides:l,standalone:!0,onTheme:h=>{c=h},onOverride:(h,_)=>{_===""?delete l[h]:l[h]=_},onOverridesReplaced:h=>{l={...h}},previewFor:async(h,_)=>{const b=await $.getForm(o.id);b.schema.settings.theme=h,b.schema.settings.themeOverrides=_;const{html:v}=await $.preview(o.id,{schema:b.schema,theme:h});return v},onThemesChanged:h=>{i.length=0,i.push(...h)}}))};e&&(D(e),e.append(r("span",{class:"atfs__label",text:"Preview against"}),F(String(o.id),a.map(h=>({value:String(h.id),label:h.title||"(untitled)"})),h=>{o=a.find(_=>String(_.id)===h)??a[0],l={},d()}))),d()}catch(s){D(t),t.append(r("p",{class:"atfb-error",text:s instanceof Error?s.message:"Could not load themes."}))}}typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>void Se()):Se(),document.addEventListener("os-window-content-loaded",()=>void Se()));function le(n){const e=n.trim();return/^#[0-9a-f]{6}$/i.test(e)?e:/^#[0-9a-f]{3}$/i.test(e)?`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`:"#888888"}const cs={min:-1,max:-1,sum:-1,avg:-1,round:-1,ceil:1,floor:1,abs:1,sqrt:1,pow:2},et={"+":{precedence:1,right:!1},"-":{precedence:1,right:!1},"*":{precedence:2,right:!1},"/":{precedence:2,right:!1},"%":{precedence:2,right:!1},"^":{precedence:4,right:!0}};function ds(n,e,t=[]){if(!n||!n.trim()||n.length>2e3)return null;const s=hs(n,e,t),i=us(s);if(!i)return null;const a=fs(i);if(!a)return null;const o=ms(a);return o===null||!Number.isFinite(o)?null:o}function hs(n,e,t){return n.replace(/\{([a-zA-Z0-9_]+)\}/g,(s,i)=>{const a=Object.prototype.hasOwnProperty.call(e,i)?e[i]:null,o=t.find(c=>c.id===i)??null,l=tt(a,o).toFixed(10).replace(/0+$/,"").replace(/\.$/,"");return l===""||l==="-"?"0":l})}function tt(n,e){if(typeof n=="boolean")return n?1:0;if(Array.isArray(n))return n.reduce((i,a)=>i+tt(a,e),0);if(n==null||n==="")return 0;const t=e?.choices??[];for(const i of t)if(String(i.value)===String(n)){if(typeof i.price=="number")return i.price;if(typeof i.points=="number")return i.points;break}const s=Number(n);return Number.isFinite(s)?s:0}function us(n){const e=[];let t=0;for(;ta.precedence||l.precedence===a.precedence&&!a.right){e.push(t.pop());continue}break}t.push(i);break}case"(":t.push(i);break;case")":{for(;t.length&&t[t.length-1].type!=="(";)e.push(t.pop());if(!t.length)return null;if(t.pop(),t.length&&t[t.length-1].type==="function"){const a=t.pop();a.arity=s.length?s.pop():1,e.push(a)}break}}for(;t.length;){const i=t.pop();if(i.type==="(")return null;e.push(i)}return e}function ms(n){const e=[];for(const t of n)switch(t.type){case"number":e.push(t.value);break;case"unary":{if(!e.length)return null;e.push(-e.pop());break}case"operator":{if(e.length<2)return null;const s=e.pop(),i=e.pop();switch(t.value){case"+":e.push(i+s);break;case"-":e.push(i-s);break;case"*":e.push(i*s);break;case"/":e.push(s===0?0:i/s);break;case"%":e.push(s===0?0:i%s);break;case"^":e.push(Math.pow(i,s));break;default:return null}break}case"function":{const s=t.arity??1;if(e.lengtht+s,0);case"avg":return e.reduce((t,s)=>t+s,0)/e.length;case"round":{const t=Math.max(-10,Math.min(10,Math.trunc(e[1]??0))),s=Math.pow(10,t);return Math.round(e[0]*s)/s}case"ceil":return Math.ceil(e[0]);case"floor":return Math.floor(e[0]);case"abs":return Math.abs(e[0]);case"sqrt":return e[0]<0?0:Math.sqrt(e[0]);case"pow":return Math.pow(e[0],e[1]??2);default:return null}}const gs=["sum","min","max","avg","round","ceil","floor","abs","sqrt","pow"],vs=["number","range","scale","rating","total","select","multiselect","radio","checkboxes","switch","quiz"];function Ee(n,e){return n.filter(t=>t.id!==e&&vs.includes(t.type))}function ys(n,e){const t={};return Ee(n,e).forEach((s,i)=>{t[s.id]=i+1}),t}function ws(n){const e=r("div",{class:"atfb-overlay"}),t=()=>{e.remove(),document.removeEventListener("keydown",s)},s=b=>{b.key==="Escape"&&t()},i=r("textarea",{class:"atfb-input atfb-formula__input",attrs:{rows:"3","aria-label":"Formula"}});i.value=String(n.field.formula??"");const a=r("p",{class:"atfb-formula__result",attrs:{"aria-live":"polite"}}),o=ys(n.fields,n.field.id),l=()=>{const b=i.value.trim();if(b===""){a.textContent="Empty. Reference a question below to start.",a.classList.remove("is-error");return}const v=ds(b,o,n.fields);if(v===null){a.textContent="This does not compute yet — check the braces and parentheses.",a.classList.add("is-error");return}const x=Ee(n.fields,n.field.id).map((k,E)=>`${k.label||k.id} = ${E+1}`).join(", ");a.textContent=`With sample answers (${x}): ${v}`,a.classList.remove("is-error")};i.addEventListener("input",l);const c=(b,v,x=0)=>r("button",{class:"atfb-formula__chip",type:"button",text:b,on:{click:()=>{if(Ke(i,v),x>0){const k=(i.selectionStart??i.value.length)-x;i.setSelectionRange(k,k)}}}}),d=Ee(n.fields,n.field.id),h=r("div",{class:"atfb-formula__chips",children:d.length?d.map(b=>c(b.label||b.id,`{${b.id}}`)):[r("p",{class:"atfb-hint",text:"No number-shaped questions yet — add a number, scale or priced choice field and it appears here."})]}),_=r("div",{class:"atfb-formula__chips",children:gs.map(b=>c(`${b}()`,`${b}()`,1))});e.append(r("div",{class:"atfb-modal atfb-formula",attrs:{role:"dialog","aria-label":"Formula editor"},children:[r("h2",{text:"Formula"}),i,a,m("Your questions",h,"Click one to reference its answer."),m("Functions",_),r("div",{class:"atfb-modal__actions",children:[S("Cancel",t),S("Save formula",()=>{n.onSave(i.value.trim()),t()},"primary")]})]})),e.addEventListener("click",b=>{b.target===e&&t()}),document.addEventListener("keydown",s),n.root.append(e),l(),i.focus(),i.setSelectionRange(i.value.length,i.value.length)}function Le(){return window.wp?.os??null}const st="allterrain-forms/preview",Ce="allterrain-forms-preview";function ks(n){const e=Le();if(!e?.registerTitleBarButton)return()=>{};const t=()=>{try{e.registerTitleBarButton({id:st,label:"Preview this form",icon:"dashicons-visibility",placement:"right",order:90,match:s=>{const i=s?.id??s?.config?.id??"";return i==="allterrain-forms"||i.startsWith("allterrain-forms#")},onClick:()=>void nt(n),owner:"allterrain-forms-builder"})}catch{}};return e.ready?e.ready(t):t(),()=>{try{e.unregisterTitleBarButton?.(st)}catch{}}}async function nt(n){n.isDirty()&&await n.save();const e=n.current();e&&it(e.id,e.title,e.previewUrl)}function it(n,e,t){const s=Le();if(!s?.windowManager?.open){window.open(t,"_blank","noopener");return}s.windowManager.open({id:`${Ce}-${n}`,baseId:Ce,url:t,title:`Preview: ${e}`,icon:"dashicons-visibility"})}function xs(n,e,t){if(!Le()?.windowManager?.open||!document.querySelector(`[data-window-id="${Ce}-${n}"]`))return;const a=t.includes("?")?"&":"?";it(n,e,`${t}${a}atf_r=${Date.now()}`)}const _s="allterrain-forms/form";function Ss(){return window.wp?.os?.relations??null}function Es(n){const e=n.closest("[data-window-id], .os-window");if(!e)return null;const t=e.getAttribute("data-window-id");if(t)return t;const s=e.id??"";return s?s.replace(/^wp-window-/,""):null}const Ls=6e3,at=120;function rt(n,e){const t=Ss();if(Te.set(n,e),!t?.set)return;const s=a=>{if(ce.get(n)!==i)return;const o=Es(n);if(!o){Date.now()s(a),at);return}try{t.set(o,e)}catch(c){ot||(ot=!0,console.error("[AllTerrain Forms] The shell refused a window identity.",c,e)),ce.delete(n);return}if(!e||t.get?.(o)?.id===e.id||Date.now()>=a){ce.delete(n);return}window.setTimeout(()=>s(a),at)},i=Symbol("atf-identity");ce.set(n,i),s(Date.now()+Ls)}let ot=!1;const ce=new WeakMap,Te=new Map;function Cs(){for(const[n,e]of Te){if(!n.isConnected){Te.delete(n);continue}rt(n,e)}}if(typeof document<"u")for(const n of["os-window-content-loaded","os-window-opened"])document.addEventListener(n,()=>Cs());function Ts(n,e){return{type:_s,id:n.id,label:n.title||"Untitled form",related:[{id:`allterrain-forms/entries-${n.id}`,label:"Entries for this form",url:`${e}admin.php?page=allterrain-forms-entries&form=${n.id}`,group:"allterrain-forms",groupLabel:"Forms",icon:"dashicons-list-view"}]}}const te="allterrain-forms/field",$s=["openstation/file","desktop-mode/file","openstation/attachment"],lt="allterrain-forms/logic-map-v2";function H(n,e){return n.dataset.atfbBind=e,n}const ct={level:{key:"level",label:"Heading level",control:"select",hint:"Headings should step down one at a time.",options:[{value:"2",label:"Heading 2"},{value:"3",label:"Heading 3"},{value:"4",label:"Heading 4"},{value:"5",label:"Heading 5"},{value:"6",label:"Heading 6"}]},content:{key:"content",label:"HTML",control:"textarea",hint:"Shown as written. Scripts are stripped when the form is saved."},consenttext:{key:"consentText",label:"What they are agreeing to",control:"textarea",hint:"Shown beside the tick box. Links are allowed."},height:{key:"height",label:"Height",control:"number",hint:"In pixels."},columns:{key:"columns",label:"Columns",control:"number",hint:"How many pictures sit side by side."},multiple:{key:"multiple",label:"Let them choose more than one",control:"checkbox"},inline:{key:"inline",label:"Lay the options out in a row",control:"checkbox"},other:{key:"other",label:"Offer an “Other” box",control:"checkbox",hint:"Adds a final option with a box to type in."},filetypes:{key:"filetypes",label:"Accepted file types",control:"commas",hint:"Extensions, separated by commas. Empty accepts anything the site allows."},maxsize:{key:"maxsize",label:"Largest file",control:"number",hint:"In megabytes."},maxfiles:{key:"maxfiles",label:"How many files",control:"number"},minrows:{key:"minRows",label:"Fewest rows",control:"number",also:{key:"maxRows",label:"Most rows"}},endlabels:{key:"minLabel",label:"Label at the low end",control:"text",also:{key:"maxLabel",label:"Label at the high end"}},points:{key:"points",label:"Points if correct",control:"number"},minchoices:{key:"minChoices",label:"Fewest they may pick",control:"number",also:{key:"maxChoices",label:"Most they may pick"}}},As={label:"the canvas edits it in place, and the inspector mirrors it",placeholder:"edited by typing into the control on the canvas",hint:"edited under the control on the canvas",nextlabel:"edited on the page break’s own Next button",prevlabel:"edited on the page break’s own Back button",addlabel:"edited on the repeater’s own Add button",choices:"the choices editor, and the option list on the canvas",required:"the toggle on the card",width:"its own row",css:"its own row",prefill:"its own section",logic:"the conditional logic section",formula:"its own row, with the currency that goes with it",currency:"rendered with the formula",correct:"the choices editor marks the right answer",default:"its own row, typed to match what the field stores",rows:"a row count on a textarea; the statement list on a Likert matrix",parts:"a tick box per part, listed by the server",min:"the validation section, paired with max",max:"the validation section, paired with min",step:"the validation section",minlength:"the validation section, paired with maxlength",maxlength:"the validation section, paired with minlength",mindate:"the validation section, paired with maxdate",maxdate:"the validation section, paired with mindate",mintime:"the validation section, paired with maxtime",maxtime:"the validation section, paired with mintime",pattern:"the validation section",unique:"the validation section",maxchoices:"rendered with minchoices",maxrows:"rendered with minrows"};function dt(n,e,t){const s=n[e.key],i=a=>t(e.key,a);if(e.control==="checkbox")return A(e.label,!!s,i);if(e.control==="commas"){const a=Array.isArray(s)?s:[];return m(e.label,w(a.join(", "),o=>{i(o.split(",").map(l=>l.trim().replace(/^\./,"").toLowerCase()).filter(Boolean))}),e.hint)}return e.control==="select"?m(e.label,F(String(s??""),e.options??[],i),e.hint):e.control==="textarea"?m(e.label,re(String(s??""),i),e.hint):e.control==="number"?m(e.label,R(String(s??""),i),e.hint):m(e.label,H(w(String(s??""),i),e.key),e.hint)}function ht(n,e){const t=new Set(n.map(i=>i.key).filter(Boolean));let s=n.length+1;return e.split(` -`).map(i=>i.trim()).filter(Boolean).map((i,a)=>{const o=n[a]?.key;if(o)return{key:o,label:i};for(;t.has(`r${s}`);)s+=1;return t.add(`r${s}`),{key:`r${s}`,label:i}})}function ut(n,e,t){const s=n.findIndex(a=>a.id===e);if(s<0)return null;const i=Math.max(0,Math.min(t,n.length-1));return i===s?null:{from:s,to:i}}const $e=[{value:"user:email",label:"Their email address",group:"About the person filling it in",tag:"{user:email}"},{value:"user:display_name",label:"Their name",group:"About the person filling it in",tag:"{user:display_name}"},{value:"user:first_name",label:"Their first name",group:"About the person filling it in"},{value:"user:last_name",label:"Their last name",group:"About the person filling it in"},{value:"user:login",label:"Their username",group:"About the person filling it in"},{value:"date:today",label:"Today’s date",group:"The date and time",tag:"{date}"},{value:"date:now",label:"The time right now",group:"The date and time",tag:"{time}"},{value:"site",label:"This site’s name",group:"About this site",tag:"{site}"},{value:"site:url",label:"This site’s address",group:"About this site",tag:"{site:url}"},{value:"site:admin_email",label:"The site administrator’s email",group:"About this site",tag:"{admin_email}"}],Fs=["About the person filling it in","The date and time","About this site"],Ae=(n,e)=>I?.i18n?.[n]??e;class pt{constructor(e){this.config=null,this.themes=[],this.forms=[],this.form=null,this.schema=null,this.selected=null,this.tab="build",this.logicMap=null,this.canvasTheme=r("style"),this.canvasThemeSignature="",this.openSections=new Map,this.logicMapOn=Tt(lt)!=="off",this.dirty=!1,this.editGeneration=0,this.saveInFlight=!1,this.queuedSave=null,this.teardowns=[],this.canvasTarget=null,this.history=[],this.historyAt=-1,this.autosave=me(()=>{this.save(!0)},2500),this.renderInspector=Ct(()=>{if(D(this.inspector),!this.schema||(this.root.classList.toggle("atfb--build-only-panes",this.tab!=="build"),this.tab!=="build"))return;const t=this.schema.fields.find(o=>o.id===this.selected);if(this.root.classList.toggle("atfb--has-selection",!!t),!t){this.inspector.append(r("div",{class:"atfb-placeholder",children:[r("p",{text:"Select a field to change it."}),r("p",{class:"atfb-hint",text:"Drag a field from the palette, or press one to add it to the end."})]}));return}const s=this.config?.fieldTypes.find(o=>o.type===t.type),i=s?.supports??[],a=(o,l)=>{const c=this.liveField(t.id);c&&(c[o]=l,this.markDirty(),this.renderCanvas())};this.inspector.append(r("h3",{class:"atfb-inspector__title",text:s?.label??t.type}),r("p",{class:"atfb-hint",text:`Reference this field as {field:${t.id}}`})),i.includes("label")&&this.inspector.append(m("Label",H(w(t.label,o=>a("label",o)),"label"))),i.includes("placeholder")&&this.inspector.append(m("Placeholder",H(w(t.placeholder,o=>a("placeholder",o)),"placeholder"))),i.includes("hint")&&this.inspector.append(m("Hint",H(w(t.hint,o=>a("hint",o)),"hint"),"Shown under the field, and read out with it.")),i.includes("nextlabel")&&this.inspector.append(m("Next button",H(w(String(t.nextLabel??""),o=>a("nextLabel",o)),"nextLabel"),"Leave empty for “Next”.")),i.includes("prevlabel")&&this.inspector.append(m("Back button",H(w(String(t.prevLabel??""),o=>a("prevLabel",o)),"prevLabel"),"Leave empty for “Back”.")),i.includes("addlabel")&&this.inspector.append(m("Add button",H(w(String(t.addLabel??""),o=>a("addLabel",o)),"addLabel"),"Leave empty for “Add another”.")),i.includes("required")&&this.inspector.append(A("Required",t.required,o=>a("required",o))),i.includes("width")&&this.inspector.append(m("Width",F(t.width,[{value:"full",label:"Full width"},{value:"two-thirds",label:"Two thirds"},{value:"half",label:"Half"},{value:"third",label:"One third"},{value:"quarter",label:"One quarter"}],o=>a("width",o)))),s?.choices&&this.inspector.append(this.renderChoicesEditor(t,a)),this.renderTypeSettings(t,s,i,a),(t.type==="total"||i.includes("formula"))&&this.inspector.append(m("Formula",r("div",{class:"atfb-formula__row",children:[w(String(t.formula??""),o=>a("formula",o)),S("Formula editor",()=>ws({root:this.root,fields:this.schema?.fields??[],field:t,onSave:o=>{a("formula",o),this.renderInspector()}}))]}),"Reference answers with braces — {f1} * {f2} + 10 — or open the editor and click them in."),m("Currency symbol",w(String(t.currency??""),o=>a("currency",o)))),this.inspector.append(this.renderValidationSection(t,i,a)),this.inspector.append(this.renderLogicSection(t,a)),i.includes("prefill")&&this.inspector.append(this.prefillControl(t,a)),i.includes("css")&&this.inspector.append(m("CSS class",w(t.cssClass,o=>a("cssClass",o))))}),this.root=e,this.bar=e.querySelector("[data-atfb-bar]")??r("div"),this.palette=e.querySelector("[data-atfb-palette]")??r("div"),this.canvas=e.querySelector("[data-atfb-canvas]")??r("div"),this.inspector=e.querySelector("[data-atfb-inspector]")??r("div")}async start(){try{const[s,i,a]=await Promise.all([$.config(),$.listThemes(),$.listForms()]);this.config=s,this.themes=i,this.forms=a}catch(s){this.fail(s);return}this.teardowns.push(xt([te])),this.teardowns.push(ks({current:()=>this.form?{id:this.form.id,title:this.form.title,previewUrl:this.form.previewUrl}:null,isDirty:()=>this.dirty,save:()=>this.save(!0)}));const e=s=>{this.dirty&&(s.preventDefault(),s.returnValue="")};window.addEventListener("beforeunload",e),this.teardowns.push(()=>window.removeEventListener("beforeunload",e));const t=s=>{!(s.metaKey||s.ctrlKey)||s.key.toLowerCase()!=="z"||s.target?.closest("input, textarea, [contenteditable]")||(s.preventDefault(),this.travel(s.shiftKey?1:-1))};if(this.root.addEventListener("keydown",t),this.teardowns.push(()=>this.root.removeEventListener("keydown",t)),this.renderBar(),this.renderPalette(),this.forms.length){const s=Pt("builder");await this.open(s&&this.forms.some(i=>i.id===s)?s:this.forms[0].id)}else this.renderFormsList()}destroy(){this.canvasTarget?.(),this.canvasTarget=null,this.teardowns.forEach(e=>e()),this.teardowns=[]}fail(e){D(this.bar),this.bar.append(r("p",{class:"atfb-error",text:e instanceof Error?e.message:"Something went wrong loading your forms."}))}renderBar(){D(this.bar);const e=F(String(this.form?.id??""),[...this.forms.map(i=>({value:String(i.id),label:i.title||"(untitled)"}))],i=>void this.open(Number(i)));e.setAttribute("aria-label","Choose a form");const t=r("input",{class:"atfb-title",type:"text",value:this.form?.title??"",placeholder:"Untitled form",attrs:{"aria-label":"Form title"},on:{input:i=>{this.form&&(this.form.title=i.target.value,this.markDirty())}}}),s=r("div",{class:"atfb-tabs",attrs:{role:"tablist"},children:[["build","Build"],["theme","Theme"],["settings","Settings"],["notify","Notifications"],["confirm","Confirmations"]].map(([i,a])=>r("button",{class:`atfb-tab${this.tab===i?" is-active":""}`,type:"button",text:a,attrs:{role:"tab","aria-selected":this.tab===i},on:{click:()=>{this.tab=i,this.renderBar(),this.renderInspector(),this.renderCanvas()}}}))});this.bar.append(r("div",{class:"atfb-bar__left",children:[this.forms.length>1?e:null,t]}),s,r("div",{class:"atfb-bar__right",children:[this.historyButton("undo","Undo",-1),this.historyButton("redo","Redo",1),S("New",()=>void this.showTemplates(),"secondary","plus-alt2"),S("Export",()=>void this.exportForm(),"secondary","download"),S("Import",()=>void this.importForm(),"secondary","upload"),S("Preview",()=>void this.preview(),"secondary","visibility"),S("Entries",()=>this.openEntries(),"secondary","list-view"),this.logicMapButton(),this.saveButton()]}))}liveField(e){return this.schema?.fields.find(t=>t.id===e)}syncCanvas(e){const t=this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.id)}"]`);if(t)for(const s of t.querySelectorAll(".atfb-editable[data-atfb-bind]")){const i=Xe(e,s.dataset.atfbBind??"");s.textContent!==i&&(s.textContent=i)}}syncInspector(e){if(this.selected===e.id)for(const t of this.inspector.querySelectorAll("[data-atfb-bind]")){const s=Xe(e,t.dataset.atfbBind??"");t.value!==s&&("value"in t?t.value=s:t.setAttribute("value",s))}}rebindCanvas(){if(this.tab!=="build")return;const e=document.activeElement;if(e instanceof HTMLElement&&this.canvas.contains(e)){e.addEventListener("blur",()=>this.rebindCanvas(),{once:!0});return}this.renderCanvas()}snapshot(){if(!this.schema)return;const e=JSON.stringify(this.schema);this.history[this.historyAt]!==e&&(this.history=this.history.slice(0,this.historyAt+1),this.history.push(e),this.history.length>60&&this.history.shift(),this.historyAt=this.history.length-1,this.syncHistoryButtons())}travel(e){const t=this.historyAt+e;!this.schema||t<0||t>=this.history.length||(this.historyAt=t,this.schema=JSON.parse(this.history[t]),this.schema.fields.some(s=>s.id===this.selected)||(this.selected=null),this.markDirty(),this.renderBar(),this.renderCanvas(),this.renderInspector())}historyButton(e,t,s){const i=S(t,()=>this.travel(s),"secondary",e);return i.setAttribute("data-atfb-history",String(s)),i.disabled=!this.canTravel(s),i}canTravel(e){const t=this.historyAt+e;return t>=0&&tURL.revokeObjectURL(s),1e3)}async importForm(){const e=r("input",{type:"file",attrs:{accept:"application/json,.json"}});e.addEventListener("change",async()=>{const t=e.files?.[0];if(t)try{const s=JSON.parse(await t.text());if(!s.schema)throw new Error("That file does not contain a form.");const i=await $.createForm({title:s.title??t.name.replace(/\.json$/i,""),schema:s.schema});this.forms.unshift({id:i.id,title:i.title,status:i.status,modified:i.modified,fields:i.schema.fields.length,theme:i.schema.settings.theme,entries:0,unread:0,views:0,submissions:0,shortcode:i.shortcode}),this.form=i,this.schema=i.schema,this.selected=null,this.dirty=!1,this.history=[],this.historyAt=-1,this.snapshot(),this.renderBar(),this.renderCanvas(),this.renderInspector(),N("Form imported",i.title)}catch(s){N("Could not import that file",s instanceof Error?s.message:"","error")}}),e.click()}saveButton(){const e=S("Save",()=>void this.save(),"primary");return e.disabled=!this.dirty,e.setAttribute("data-atfb-save",""),e}markDirty(){this.dirty=!0,this.editGeneration+=1;const e=this.bar.querySelector("[data-atfb-save]");e&&(e.disabled=!1),this.autosave()}async save(e=!1){if(!this.form||!this.schema)return;if(this.saveInFlight){this.queuedSave={silent:e&&(this.queuedSave?.silent??!0)};return}this.saveInFlight=!0;const t=this.editGeneration;try{const s=await $.updateForm(this.form.id,{title:this.form.title,schema:this.schema});if(t===this.editGeneration){this.form=s,this.schema=s.schema,this.dirty=!1,this.rebindCanvas();const a=this.bar.querySelector("[data-atfb-save]");a&&(a.disabled=!0)}Zt(s.id);const i=this.forms.find(a=>a.id===s.id);i&&(i.title=s.title),xs(s.id,s.title,s.previewUrl),e||N("Form saved",s.title)}catch(s){N(Ae("saveFailed","Could not save"),s instanceof Error?s.message:"","error")}finally{this.saveInFlight=!1;const s=this.queuedSave;this.queuedSave=null,s&&this.save(s.silent)}}async openFormById(e){await this.open(e)}async open(e){if(!(this.dirty&&!await fe("You have unsaved changes. Discard them?"))){try{this.form=await $.getForm(e),this.schema=this.form.schema,this.selected=null,this.dirty=!1,this.history=[],this.historyAt=-1,this.snapshot()}catch(t){this.fail(t);return}this.renderBar(),this.renderCanvas(),this.renderInspector(),this.announceIdentity()}}announceIdentity(){this.form&&rt(this.root,Ts(this.form,I?.adminUrl??""))}async showTemplates(){if(!this.config)return;const e=r("div",{class:"atfb-overlay"}),t=a=>{a.key==="Escape"&&s()},s=()=>{e.remove(),document.removeEventListener("keydown",t)},i=r("div",{class:"atfb-templates",children:this.config.templates.map(a=>r("button",{class:"atfb-template",type:"button",on:{click:async()=>{s();try{const o=await $.createForm({template:a.slug});this.forms.unshift({id:o.id,title:o.title,status:o.status,modified:o.modified,fields:o.schema.fields.length,theme:o.schema.settings.theme,entries:0,unread:0,views:0,submissions:0,shortcode:o.shortcode}),this.form=o,this.schema=o.schema,this.selected=null,this.dirty=!1,this.history=[],this.historyAt=-1,this.snapshot(),this.renderBar(),this.renderCanvas(),this.renderInspector(),this.announceIdentity()}catch(o){N("Could not create the form",o instanceof Error?o.message:"","error")}}},children:[M(a.icon),r("strong",{text:a.label}),r("span",{text:a.description})]}))});e.append(r("div",{class:"atfb-modal",attrs:{role:"dialog","aria-label":"Start a new form"},children:[r("h2",{text:"Start a new form"}),i,r("div",{class:"atfb-modal__actions",children:[S("Cancel",s)]})]})),e.addEventListener("click",a=>{a.target===e&&s()}),document.addEventListener("keydown",t),this.root.append(e),i.querySelector("button")?.focus()}renderFormsList(){D(this.canvas),this.canvas.append(r("div",{class:"atfb-empty",children:[r("h2",{text:"No forms yet"}),r("p",{text:"Start from a template, or build one from nothing."}),S("New form",()=>void this.showTemplates(),"primary","plus-alt2")]}))}openEntries(){const e=window.wp?.os;if(e?.openWindow){e.openWindow("allterrain-forms-entries");return}window.location.assign(`${I?.adminUrl??""}admin.php?page=allterrain-forms-entries`)}renderPalette(){if(!this.config)return;D(this.palette);const e=new Map;for(const s of this.config.fieldTypes){const i=e.get(s.group)??[];i.push(s),e.set(s.group,i)}const t=r("input",{class:"atfb-input atfb-palette__search",type:"search",placeholder:"Search fields",attrs:{"aria-label":"Search field types"},on:{input:s=>{const i=s.target.value.toLowerCase().trim();this.palette.querySelectorAll(".atfb-chip").forEach(a=>{const o=(a.textContent??"").toLowerCase();a.hidden=i!==""&&!o.includes(i)}),this.palette.querySelectorAll(".atfb-group").forEach(a=>{const o=Array.from(a.querySelectorAll(".atfb-chip")).some(l=>!l.hidden);a.hidden=!o})}}});this.palette.append(t);for(const[s,i]of Object.entries(this.config.groups)){const a=e.get(s);a?.length&&this.palette.append(r("div",{class:"atfb-group",children:[r("h3",{class:"atfb-group__title",text:i}),r("div",{class:"atfb-group__items",children:a.map(o=>this.paletteChip(o))})]}))}}paletteChip(e){const t=r("button",{class:"atfb-chip",type:"button",title:e.description,attrs:{"data-atf-type":e.type},children:[M(e.icon),r("span",{text:e.label})]});return t.addEventListener("pointerdown",s=>{const i=r("div",{class:"atfb-chip atfb-chip--ghost",children:[M(e.icon),r("span",{text:e.label})]});K().start({payload:qe(te,t,{fieldType:e.type,isNew:!0},s,i),origin:s,onClickOnly:()=>this.addField(e.type)})}),t.addEventListener("click",s=>{K().recentlyEndedDrag()&&s.preventDefault()}),t}renderCanvas(){if(D(this.canvas),!this.schema||!this.form){this.renderFormsList();return}if(this.tab!=="build"){this.canvas.append(this.renderTabCanvas());return}const e=r("div",{class:"atfb-canvas__list",attrs:{"data-atfb-list":""}});this.schema.fields.length||e.append(r("div",{class:"atfb-placeholder",text:Ae("emptyCanvas","Drag a field from the left to begin.")})),this.schema.fields.forEach((s,i)=>{e.append(this.renderFieldCard(s,i))});const t=r("div",{class:"atfb-canvas__inner",children:[r("p",{class:"atfb-shortcode",text:this.form.shortcode,title:"Paste this anywhere to place the form"}),e]});this.canvas.append(t),this.registerCanvasTarget(e),this.paintLogicMap(t),this.paintCanvasTheme()}prefillControl(e,t){const s=e.prefill.startsWith("query:"),i=$e.some(b=>b.value===e.prefill),a=s?"query":i&&e.prefill||(e.prefill?"custom":""),o=r("div",{class:"atfb-prefill__detail"}),l=r("p",{class:"atfb-row__hint atfb-prefill__preview"}),c=b=>{if(o.replaceChildren(),l.replaceChildren(),b==="query"){const v=e.prefill.startsWith("query:")?e.prefill.slice(6):"";o.append(w(v,x=>{const k=x.trim();t("prefill",k?`query:${k}`:""),d(`query:${k}`)},"utm_source"),r("p",{class:"atfb-row__hint",text:"The name of the parameter in the link people arrive on."}))}b==="custom"&&o.append(w(e.prefill,v=>{t("prefill",v),d(v)},"myplugin:something"),r("p",{class:"atfb-row__hint",text:"For a source another plugin has added through atf_resolve_prefill."})),d(e.prefill)},d=b=>{if(l.replaceChildren(),!b)return;if(b.startsWith("query:")){const x=b.slice(6);x&&(l.textContent=`A visit to …/your-page/?${x}=abc opens the form with “abc” in it.`);return}const v=$e.find(x=>x.value===b)?.tag;v&&we(this.form?.id??0).then(x=>{for(const k of x)for(const E of k.items)if(E.tag===v){const O=b.startsWith("user:");if(!E.sample){l.textContent="Empty unless the visitor is signed in.";return}l.textContent=O?`Opens with “${E.sample}” for you — empty for a visitor who is not signed in.`:`Opens with “${E.sample}”.`;return}})};c(a);const h=r("select",{class:"atfb-input atfb-select",on:{change:b=>{const v=b.target.value;t("prefill",v==="query"||v==="custom"?"":v),c(v)}}});h.append(r("option",{value:"",text:"Nothing — leave it empty",attrs:{selected:a===""}}));for(const b of Fs){const v=document.createElement("optgroup");v.label=b;for(const x of $e.filter(k=>k.group===b))v.append(r("option",{value:x.value,text:x.label,attrs:{selected:x.value===a}}));h.append(v)}const _=document.createElement("optgroup");return _.label="From the link they arrived on",_.append(r("option",{value:"query",text:"A parameter in the web address",attrs:{selected:a==="query"}})),h.append(_,r("option",{value:"custom",text:"Something else (advanced)",attrs:{selected:a==="custom"}})),m("Pre-fill this with",r("div",{class:"atfb-prefill",children:[h,o,l]}),"What the box already contains when the form opens. They can still change it.")}renderCondition(e){const t=e.some(s=>s.kind==="field"&&s.missing);return r("span",{class:`atfb-cond${t?" is-broken":""}`,attrs:{"aria-label":Ye(e)},children:[M("randomize"),...e.map(s=>this.renderConditionToken(s))]})}renderConditionToken(e){return e.kind==="field"&&!e.missing?r("button",{class:"atfb-cond__chip atfb-cond__chip--field",type:"button",text:e.text,title:"Go to this question",on:{click:i=>{i.stopPropagation(),this.selectField(e.fieldId),this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.fieldId)}"]`)?.scrollIntoView({block:"nearest",behavior:"smooth"})}}}):r("span",{class:{verb:"atfb-cond__verb",field:"atfb-cond__chip atfb-cond__chip--missing",operator:"atfb-cond__op",value:"atfb-cond__chip atfb-cond__chip--value",join:"atfb-cond__join"}[e.kind],text:e.text})}section(e,t,s,i=!1){const a=r("details",{class:"atfb-section",attrs:{open:this.openSections.get(e)??i},children:[r("summary",{text:t}),...s]});return a.addEventListener("toggle",()=>this.openSections.set(e,a.open)),a}logicMapButton(){const e=be(this.schema?.fields??[]).length>0,t=S(this.logicMapOn?"Hide logic":"Show logic",()=>{this.logicMapOn=!this.logicMapOn,$t(lt,this.logicMapOn?"on":"off"),this.renderBar(),this.renderCanvas()},this.logicMapOn?"primary":"secondary","randomize");return t.title="Draw a line from each question to the ones it decides.",t.hidden=!e,t}paintLogicMap(e){this.logicMap?.destroy(),this.logicMap=null;const t=this.schema?.fields??[],s=be(t);if(!s.length||!this.logicMapOn)return;e.classList.add("has-logicmap");const i=new Ut(e);i.setEdges(s),i.highlight(this.selected??""),this.logicMap=i,e.addEventListener("pointerover",a=>{const o=a.target.closest("[data-atfb-card]");i.highlight(o?.dataset.atfbCard??this.selected??"")}),e.addEventListener("pointerleave",()=>i.highlight(this.selected??""))}renderFieldCard(e,t){const s=this.config?.fieldTypes.find(d=>d.type===e.type),i=this.selected===e.id,a=this.schema?.fields??[],o=Bt(e,a),l=jt(a).get(e.id)??0,c=r("div",{class:`atfb-card${i?" is-selected":""}`,attrs:{"data-atfb-card":e.id,"data-index":t,tabindex:"0",role:"button","aria-pressed":i,"aria-label":`${e.label||s?.label||e.type}, ${t+1} of ${this.schema?.fields.length??0}`},children:[r("div",{class:"atfb-card__grip",attrs:{"aria-hidden":"true"},children:[M("menu")]}),r("div",{class:"atfb-card__body",children:[r("div",{class:"atfb-card__head",children:[M(s?.icon??"dashicons-forms"),r("span",{class:"atfb-card__type",text:s?.label??e.type}),this.requiredToggle(e),l?r("span",{class:"atfb-badge atfb-badge--controls",text:l===1?"controls 1 field":`controls ${l} fields`,title:"Other questions appear or disappear based on this answer."}):null]}),Gt(e,s,{edit:d=>{const h=this.liveField(e.id);h&&(d(h),this.markDirty(),this.syncInspector(h))},restructure:d=>{const h=this.liveField(e.id);h&&(this.snapshot(),d(h),this.markDirty(),this.renderCanvas(),this.renderInspector())}}),o.length?this.renderCondition(o):null]}),r("div",{class:"atfb-card__actions",children:[this.cardAction("admin-page","Duplicate",()=>this.duplicateField(e.id)),this.cardAction("trash","Delete",()=>void this.deleteField(e.id))]})]});return c.addEventListener("click",d=>{d.target.closest(".atfb-card__actions")||K().recentlyEndedDrag()||this.selectField(e.id)}),c.addEventListener("keydown",d=>{if(d.key==="Enter"||d.key===" "){d.preventDefault(),this.selectField(e.id);return}d.altKey&&(d.key==="ArrowUp"||d.key==="ArrowDown")&&(d.preventDefault(),this.moveField(e.id,d.key==="ArrowUp"?t-1:t+1),window.requestAnimationFrame(()=>{this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.id)}"]`)?.focus()})),(d.key==="Delete"||d.key==="Backspace")&&(d.preventDefault(),this.deleteField(e.id))}),c.addEventListener("pointerdown",d=>{d.target.closest(".atfb-card__actions")||K().start({payload:qe(te,c,{fieldId:e.id,field:e,isNew:!1},d),origin:d})}),c}requiredToggle(e){return r("button",{class:`atfb-req${e.required?" is-on":""}`,type:"button",text:e.required?"Required":"Optional",title:e.required?"This must be answered. Click to make it optional.":"Click to make this required.",attrs:{"aria-pressed":e.required?"true":"false"},on:{pointerdown:s=>s.stopPropagation(),click:s=>{s.stopPropagation(),e.required=!e.required,this.markDirty(),this.renderCanvas(),this.renderInspector()}}})}cardAction(e,t,s){return r("button",{class:"atfb-card__action",type:"button",title:t,attrs:{"aria-label":t},on:{click:i=>{i.stopPropagation(),s()}},children:[M(e)]})}registerCanvasTarget(e){this.canvasTarget?.(),this.canvasTarget=null;const t=r("div",{class:"atfb-marker",attrs:{"aria-hidden":"true"}}),s=K().registerDropTarget({id:`atfb-canvas-${this.form?.id??0}`,element:e,accept:a=>a.type===te,onEnter:()=>e.classList.add("is-dropping"),onLeave:()=>{e.classList.remove("is-dropping"),t.remove()},onDrop:(a,o)=>{e.classList.remove("is-dropping"),t.remove();const l=a.payload.data,c=l.fieldId?this.canvas.querySelector(`[data-atfb-card="${CSS.escape(l.fieldId)}"]`):null,d=Oe(e,".atfb-card",o.clientY,c??void 0);if(l.isNew&&l.fieldType){this.addField(l.fieldType,d);return}if(l.fieldId&&this.schema?.fields.some(h=>h.id===l.fieldId)){this.moveField(l.fieldId,d);return}l.field&&this.insertField({...l.field,id:""},d)}}),i=a=>{const o=a.detail;if(o?.payload?.type!==te||!e.classList.contains("is-dropping"))return;const l=o.payload.data?.fieldId?this.canvas.querySelector(`[data-atfb-card="${CSS.escape(o.payload.data.fieldId)}"]`):null,c=o.clientY??0,d=Oe(e,".atfb-card",c,l??void 0),h=Array.from(e.querySelectorAll(".atfb-card")).filter(_=>_!==l);d>=h.length?e.append(t):h[d].before(t)};document.addEventListener("os.drag.move",i),this.canvasTarget=()=>{s(),document.removeEventListener("os.drag.move",i)}}addField(e,t){const s=this.config?.fieldTypes.find(a=>a.type===e);if(!s||!this.schema)return;const i={id:this.nextFieldId(),type:e,label:s.input?s.label:"",placeholder:"",hint:"",required:!1,width:"full",cssClass:"",default:"",choices:s.choices?[{label:"First choice",value:"first"},{label:"Second choice",value:"second"}]:[],logic:{enabled:!1,action:"show",match:"all",rules:[]},messages:{},prefill:"",...s.settings};this.insertField(i,t)}insertField(e,t){if(!this.schema)return;e.id||(e.id=this.nextFieldId()),this.snapshot();const s=t===void 0?this.schema.fields.length:Math.max(0,Math.min(t,this.schema.fields.length));this.schema.fields.splice(s,0,e),this.selected=e.id,this.markDirty(),this.renderCanvas(),this.renderInspector(),window.requestAnimationFrame(()=>{this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.id)}"]`)?.focus()})}moveField(e,t){if(!this.schema)return;const s=ut(this.schema.fields,e,t);if(!s)return;this.snapshot();const[i]=this.schema.fields.splice(s.from,1);this.schema.fields.splice(s.to,0,i),this.markDirty(),this.renderCanvas()}duplicateField(e){if(!this.schema)return;const t=this.schema.fields.findIndex(i=>i.id===e);if(t<0)return;const s=JSON.parse(JSON.stringify(this.schema.fields[t]));s.id=this.nextFieldId(),this.insertField(s,t+1)}async deleteField(e){if(!this.schema)return;const t=this.schema.fields.filter(i=>i.logic?.rules?.some(a=>a.field===e)),s=t.length?`Delete this field? ${t.length} other field${t.length===1?"":"s"} use it in a condition, and those conditions will stop working.`:Ae("confirmDelete","Delete this? It cannot be undone.");await fe(s,"Delete field")&&(this.snapshot(),this.schema.fields=this.schema.fields.filter(i=>i.id!==e),this.selected===e&&(this.selected=null),this.markDirty(),this.renderCanvas(),this.renderInspector())}selectField(e){this.selected=e;for(const t of this.canvas.querySelectorAll("[data-atfb-card]")){const s=t.dataset.atfbCard===e;t.classList.toggle("is-selected",s),t.setAttribute("aria-pressed",s?"true":"false")}this.logicMap?.highlight(e),this.renderInspector()}nextFieldId(){const e=new Set((this.schema?.fields??[]).map(s=>s.id));let t=e.size+1;for(;e.has(`f${t}`);)t++;return`f${t}`}nextEntryId(e,t){const s=new Set(t.map(a=>a.id));let i=t.length+1;for(;s.has(`${e}${i}`);)i++;return`${e}${i}`}renderTypeSettings(e,t,s,i){for(const a of s){const o=ct[a];o&&(this.inspector.append(dt(e,o,i)),o.also&&this.inspector.append(dt(e,{...o,key:o.also.key,label:o.also.label,hint:o.also.hint},i)))}s.includes("rows")&&e.type!=="likert"&&this.inspector.append(m("Lines tall",R(String(e.rows??""),a=>i("rows",a)))),s.includes("rows")&&e.type==="likert"&&this.inspector.append(this.renderStatementList(e,i)),s.includes("parts")&&this.inspector.append(this.renderPartsEditor(e,t,i)),s.includes("default")&&!["files","object"].includes(t?.value??"")&&this.inspector.append(this.renderDefaultControl(e,t,i))}renderStatementList(e,t){const s=Array.isArray(e.rows)?e.rows:[];return m("Statements",re(s.map(i=>i.label??"").join(` +`).map(i=>i.trim()).filter(Boolean).map((i,a)=>{const o=n[a]?.key;if(o)return{key:o,label:i};for(;t.has(`r${s}`);)s+=1;return t.add(`r${s}`),{key:`r${s}`,label:i}})}function ut(n,e,t){const s=n.findIndex(a=>a.id===e);if(s<0)return null;const i=Math.max(0,Math.min(t,n.length-1));return i===s?null:{from:s,to:i}}const $e=[{value:"user:email",label:"Their email address",group:"About the person filling it in",tag:"{user:email}"},{value:"user:display_name",label:"Their name",group:"About the person filling it in",tag:"{user:display_name}"},{value:"user:first_name",label:"Their first name",group:"About the person filling it in"},{value:"user:last_name",label:"Their last name",group:"About the person filling it in"},{value:"user:login",label:"Their username",group:"About the person filling it in"},{value:"date:today",label:"Today’s date",group:"The date and time",tag:"{date}"},{value:"date:now",label:"The time right now",group:"The date and time",tag:"{time}"},{value:"site",label:"This site’s name",group:"About this site",tag:"{site}"},{value:"site:url",label:"This site’s address",group:"About this site",tag:"{site:url}"},{value:"site:admin_email",label:"The site administrator’s email",group:"About this site",tag:"{admin_email}"}],Fs=["About the person filling it in","The date and time","About this site"],Ae=(n,e)=>I?.i18n?.[n]??e;class pt{constructor(e){this.config=null,this.themes=[],this.forms=[],this.form=null,this.schema=null,this.selected=null,this.tab="build",this.logicMap=null,this.canvasTheme=r("style"),this.canvasThemeSignature="",this.openSections=new Map,this.logicMapOn=Tt(lt)!=="off",this.dirty=!1,this.editGeneration=0,this.saveInFlight=!1,this.queuedSave=null,this.teardowns=[],this.canvasTarget=null,this.history=[],this.historyAt=-1,this.autosave=me(()=>{this.save(!0)},2500),this.renderInspector=Ct(()=>{if(D(this.inspector),!this.schema||(this.root.classList.toggle("atfb--build-only-panes",this.tab!=="build"),this.tab!=="build"))return;const t=this.schema.fields.find(o=>o.id===this.selected);if(this.root.classList.toggle("atfb--has-selection",!!t),!t){this.inspector.append(r("div",{class:"atfb-placeholder",children:[r("p",{text:"Select a field to change it."}),r("p",{class:"atfb-hint",text:"Drag a field from the palette, or press one to add it to the end."})]}));return}const s=this.config?.fieldTypes.find(o=>o.type===t.type),i=s?.supports??[],a=(o,l)=>{const c=this.liveField(t.id);c&&(c[o]=l,this.markDirty(),this.renderCanvas())};this.inspector.append(r("h3",{class:"atfb-inspector__title",text:s?.label??t.type}),r("p",{class:"atfb-hint",text:`Reference this field as {field:${t.id}}`})),i.includes("label")&&this.inspector.append(m("Label",H(w(t.label,o=>a("label",o)),"label"))),i.includes("placeholder")&&this.inspector.append(m("Placeholder",H(w(t.placeholder,o=>a("placeholder",o)),"placeholder"))),i.includes("hint")&&this.inspector.append(m("Hint",H(w(t.hint,o=>a("hint",o)),"hint"),"Shown under the field, and read out with it.")),i.includes("nextlabel")&&this.inspector.append(m("Next button",H(w(String(t.nextLabel??""),o=>a("nextLabel",o)),"nextLabel"),"Leave empty for “Next”.")),i.includes("prevlabel")&&this.inspector.append(m("Back button",H(w(String(t.prevLabel??""),o=>a("prevLabel",o)),"prevLabel"),"Leave empty for “Back”.")),i.includes("addlabel")&&this.inspector.append(m("Add button",H(w(String(t.addLabel??""),o=>a("addLabel",o)),"addLabel"),"Leave empty for “Add another”.")),i.includes("required")&&this.inspector.append(A("Required",t.required,o=>a("required",o))),i.includes("width")&&this.inspector.append(m("Width",F(t.width,[{value:"full",label:"Full width"},{value:"two-thirds",label:"Two thirds"},{value:"half",label:"Half"},{value:"third",label:"One third"},{value:"quarter",label:"One quarter"}],o=>a("width",o)))),s?.choices&&this.inspector.append(this.renderChoicesEditor(t,a)),this.renderTypeSettings(t,s,i,a),(t.type==="total"||i.includes("formula"))&&this.inspector.append(m("Formula",r("div",{class:"atfb-formula__row",children:[w(String(t.formula??""),o=>a("formula",o)),S("Formula editor",()=>ws({root:this.root,fields:this.schema?.fields??[],field:t,onSave:o=>{a("formula",o),this.renderInspector()}}))]}),"Reference answers with braces — {f1} * {f2} + 10 — or open the editor and click them in."),m("Currency symbol",w(String(t.currency??""),o=>a("currency",o)))),this.inspector.append(this.renderValidationSection(t,i,a)),this.inspector.append(this.renderLogicSection(t,a)),i.includes("prefill")&&this.inspector.append(this.prefillControl(t,a)),i.includes("css")&&this.inspector.append(m("CSS class",w(t.cssClass,o=>a("cssClass",o))))}),this.root=e,this.bar=e.querySelector("[data-atfb-bar]")??r("div"),this.palette=e.querySelector("[data-atfb-palette]")??r("div"),this.canvas=e.querySelector("[data-atfb-canvas]")??r("div"),this.inspector=e.querySelector("[data-atfb-inspector]")??r("div"),this.canvas.addEventListener("click",t=>{const s=t.target;if(!(this.tab!=="build"||!this.selected||s.closest("[data-atfb-card], button, os-button, a, input, textarea, select, os-select, label, [contenteditable]"))){this.selected=null;for(const i of this.canvas.querySelectorAll(".atfb-card.is-selected"))i.classList.remove("is-selected");this.renderInspector()}})}async start(){try{const[s,i,a]=await Promise.all([$.config(),$.listThemes(),$.listForms()]);this.config=s,this.themes=i,this.forms=a}catch(s){this.fail(s);return}this.teardowns.push(xt([te])),this.teardowns.push(ks({current:()=>this.form?{id:this.form.id,title:this.form.title,previewUrl:this.form.previewUrl}:null,isDirty:()=>this.dirty,save:()=>this.save(!0)}));const e=s=>{this.dirty&&(s.preventDefault(),s.returnValue="")};window.addEventListener("beforeunload",e),this.teardowns.push(()=>window.removeEventListener("beforeunload",e));const t=s=>{!(s.metaKey||s.ctrlKey)||s.key.toLowerCase()!=="z"||s.target?.closest("input, textarea, [contenteditable]")||(s.preventDefault(),this.travel(s.shiftKey?1:-1))};if(this.root.addEventListener("keydown",t),this.teardowns.push(()=>this.root.removeEventListener("keydown",t)),this.renderBar(),this.renderPalette(),this.forms.length){const s=Pt("builder");await this.open(s&&this.forms.some(i=>i.id===s)?s:this.forms[0].id)}else this.renderFormsList()}destroy(){this.canvasTarget?.(),this.canvasTarget=null,this.teardowns.forEach(e=>e()),this.teardowns=[]}fail(e){D(this.bar),this.bar.append(r("p",{class:"atfb-error",text:e instanceof Error?e.message:"Something went wrong loading your forms."}))}renderBar(){D(this.bar);const e=F(String(this.form?.id??""),[...this.forms.map(i=>({value:String(i.id),label:i.title||"(untitled)"}))],i=>void this.open(Number(i)));e.setAttribute("aria-label","Choose a form");const t=r("input",{class:"atfb-title",type:"text",value:this.form?.title??"",placeholder:"Untitled form",attrs:{"aria-label":"Form title"},on:{input:i=>{this.form&&(this.form.title=i.target.value,this.markDirty())}}}),s=r("div",{class:"atfb-tabs",attrs:{role:"tablist"},children:[["build","Build"],["theme","Theme"],["settings","Settings"],["notify","Notifications"],["confirm","Confirmations"]].map(([i,a])=>r("button",{class:`atfb-tab${this.tab===i?" is-active":""}`,type:"button",text:a,attrs:{role:"tab","aria-selected":this.tab===i},on:{click:()=>{this.tab=i,this.renderBar(),this.renderInspector(),this.renderCanvas()}}}))});this.bar.append(r("div",{class:"atfb-bar__left",children:[this.forms.length>1?e:null,t]}),s,r("div",{class:"atfb-bar__right",children:[this.historyButton("undo","Undo",-1),this.historyButton("redo","Redo",1),S("New",()=>void this.showTemplates(),"secondary","plus-alt2"),S("Export",()=>void this.exportForm(),"secondary","download"),S("Import",()=>void this.importForm(),"secondary","upload"),S("Preview",()=>void this.preview(),"secondary","visibility"),S("Entries",()=>this.openEntries(),"secondary","list-view"),this.logicMapButton(),this.saveButton()]}))}liveField(e){return this.schema?.fields.find(t=>t.id===e)}syncCanvas(e){const t=this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.id)}"]`);if(t)for(const s of t.querySelectorAll(".atfb-editable[data-atfb-bind]")){const i=Xe(e,s.dataset.atfbBind??"");s.textContent!==i&&(s.textContent=i)}}syncInspector(e){if(this.selected===e.id)for(const t of this.inspector.querySelectorAll("[data-atfb-bind]")){const s=Xe(e,t.dataset.atfbBind??"");t.value!==s&&("value"in t?t.value=s:t.setAttribute("value",s))}}rebindCanvas(){if(this.tab!=="build")return;const e=document.activeElement;if(e instanceof HTMLElement&&this.canvas.contains(e)){e.addEventListener("blur",()=>this.rebindCanvas(),{once:!0});return}this.renderCanvas()}snapshot(){if(!this.schema)return;const e=JSON.stringify(this.schema);this.history[this.historyAt]!==e&&(this.history=this.history.slice(0,this.historyAt+1),this.history.push(e),this.history.length>60&&this.history.shift(),this.historyAt=this.history.length-1,this.syncHistoryButtons())}travel(e){const t=this.historyAt+e;!this.schema||t<0||t>=this.history.length||(this.historyAt=t,this.schema=JSON.parse(this.history[t]),this.schema.fields.some(s=>s.id===this.selected)||(this.selected=null),this.markDirty(),this.renderBar(),this.renderCanvas(),this.renderInspector())}historyButton(e,t,s){const i=S(t,()=>this.travel(s),"secondary",e);return i.setAttribute("data-atfb-history",String(s)),i.disabled=!this.canTravel(s),i}canTravel(e){const t=this.historyAt+e;return t>=0&&tURL.revokeObjectURL(s),1e3)}async importForm(){const e=r("input",{type:"file",attrs:{accept:"application/json,.json"}});e.addEventListener("change",async()=>{const t=e.files?.[0];if(t)try{const s=JSON.parse(await t.text());if(!s.schema)throw new Error("That file does not contain a form.");const i=await $.createForm({title:s.title??t.name.replace(/\.json$/i,""),schema:s.schema});this.forms.unshift({id:i.id,title:i.title,status:i.status,modified:i.modified,fields:i.schema.fields.length,theme:i.schema.settings.theme,entries:0,unread:0,views:0,submissions:0,shortcode:i.shortcode}),this.form=i,this.schema=i.schema,this.selected=null,this.dirty=!1,this.history=[],this.historyAt=-1,this.snapshot(),this.renderBar(),this.renderCanvas(),this.renderInspector(),N("Form imported",i.title)}catch(s){N("Could not import that file",s instanceof Error?s.message:"","error")}}),e.click()}saveButton(){const e=S("Save",()=>void this.save(),"primary");return e.disabled=!this.dirty,e.setAttribute("data-atfb-save",""),e}markDirty(){this.dirty=!0,this.editGeneration+=1;const e=this.bar.querySelector("[data-atfb-save]");e&&(e.disabled=!1),this.autosave()}async save(e=!1){if(!this.form||!this.schema)return;if(this.saveInFlight){this.queuedSave={silent:e&&(this.queuedSave?.silent??!0)};return}this.saveInFlight=!0;const t=this.editGeneration;try{const s=await $.updateForm(this.form.id,{title:this.form.title,schema:this.schema});if(t===this.editGeneration){this.form=s,this.schema=s.schema,this.dirty=!1,this.rebindCanvas();const a=this.bar.querySelector("[data-atfb-save]");a&&(a.disabled=!0)}Zt(s.id);const i=this.forms.find(a=>a.id===s.id);i&&(i.title=s.title),xs(s.id,s.title,s.previewUrl),e||N("Form saved",s.title)}catch(s){N(Ae("saveFailed","Could not save"),s instanceof Error?s.message:"","error")}finally{this.saveInFlight=!1;const s=this.queuedSave;this.queuedSave=null,s&&this.save(s.silent)}}async openFormById(e){await this.open(e)}async open(e){if(!(this.dirty&&!await fe("You have unsaved changes. Discard them?"))){try{this.form=await $.getForm(e),this.schema=this.form.schema,this.selected=null,this.dirty=!1,this.history=[],this.historyAt=-1,this.snapshot()}catch(t){this.fail(t);return}this.renderBar(),this.renderCanvas(),this.renderInspector(),this.announceIdentity()}}announceIdentity(){this.form&&rt(this.root,Ts(this.form,I?.adminUrl??""))}async showTemplates(){if(!this.config)return;const e=r("div",{class:"atfb-overlay"}),t=a=>{a.key==="Escape"&&s()},s=()=>{e.remove(),document.removeEventListener("keydown",t)},i=r("div",{class:"atfb-templates",children:this.config.templates.map(a=>r("button",{class:"atfb-template",type:"button",on:{click:async()=>{s();try{const o=await $.createForm({template:a.slug});this.forms.unshift({id:o.id,title:o.title,status:o.status,modified:o.modified,fields:o.schema.fields.length,theme:o.schema.settings.theme,entries:0,unread:0,views:0,submissions:0,shortcode:o.shortcode}),this.form=o,this.schema=o.schema,this.selected=null,this.dirty=!1,this.history=[],this.historyAt=-1,this.snapshot(),this.renderBar(),this.renderCanvas(),this.renderInspector(),this.announceIdentity()}catch(o){N("Could not create the form",o instanceof Error?o.message:"","error")}}},children:[M(a.icon),r("strong",{text:a.label}),r("span",{text:a.description})]}))});e.append(r("div",{class:"atfb-modal",attrs:{role:"dialog","aria-label":"Start a new form"},children:[r("h2",{text:"Start a new form"}),i,r("div",{class:"atfb-modal__actions",children:[S("Cancel",s)]})]})),e.addEventListener("click",a=>{a.target===e&&s()}),document.addEventListener("keydown",t),this.root.append(e),i.querySelector("button")?.focus()}renderFormsList(){D(this.canvas),this.canvas.append(r("div",{class:"atfb-empty",children:[r("h2",{text:"No forms yet"}),r("p",{text:"Start from a template, or build one from nothing."}),S("New form",()=>void this.showTemplates(),"primary","plus-alt2")]}))}openEntries(){const e=window.wp?.os;if(e?.openWindow){e.openWindow("allterrain-forms-entries");return}window.location.assign(`${I?.adminUrl??""}admin.php?page=allterrain-forms-entries`)}renderPalette(){if(!this.config)return;D(this.palette);const e=new Map;for(const s of this.config.fieldTypes){const i=e.get(s.group)??[];i.push(s),e.set(s.group,i)}const t=r("input",{class:"atfb-input atfb-palette__search",type:"search",placeholder:"Search fields",attrs:{"aria-label":"Search field types"},on:{input:s=>{const i=s.target.value.toLowerCase().trim();this.palette.querySelectorAll(".atfb-chip").forEach(a=>{const o=(a.textContent??"").toLowerCase();a.hidden=i!==""&&!o.includes(i)}),this.palette.querySelectorAll(".atfb-group").forEach(a=>{const o=Array.from(a.querySelectorAll(".atfb-chip")).some(l=>!l.hidden);a.hidden=!o})}}});this.palette.append(t);for(const[s,i]of Object.entries(this.config.groups)){const a=e.get(s);a?.length&&this.palette.append(r("div",{class:"atfb-group",children:[r("h3",{class:"atfb-group__title",text:i}),r("div",{class:"atfb-group__items",children:a.map(o=>this.paletteChip(o))})]}))}}paletteChip(e){const t=r("button",{class:"atfb-chip",type:"button",title:e.description,attrs:{"data-atf-type":e.type},children:[M(e.icon),r("span",{text:e.label})]});return t.addEventListener("pointerdown",s=>{const i=r("div",{class:"atfb-chip atfb-chip--ghost",children:[M(e.icon),r("span",{text:e.label})]});K().start({payload:qe(te,t,{fieldType:e.type,isNew:!0},s,i),origin:s,onClickOnly:()=>this.addField(e.type)})}),t.addEventListener("click",s=>{K().recentlyEndedDrag()&&s.preventDefault()}),t}renderCanvas(){if(D(this.canvas),!this.schema||!this.form){this.renderFormsList();return}if(this.tab!=="build"){this.canvas.append(this.renderTabCanvas());return}const e=r("div",{class:"atfb-canvas__list",attrs:{"data-atfb-list":""}});this.schema.fields.length||e.append(r("div",{class:"atfb-placeholder",text:Ae("emptyCanvas","Drag a field from the left to begin.")})),this.schema.fields.forEach((s,i)=>{e.append(this.renderFieldCard(s,i))});const t=r("div",{class:"atfb-canvas__inner",children:[r("p",{class:"atfb-shortcode",text:this.form.shortcode,title:"Paste this anywhere to place the form"}),e]});this.canvas.append(t),this.registerCanvasTarget(e),this.paintLogicMap(t),this.paintCanvasTheme()}prefillControl(e,t){const s=e.prefill.startsWith("query:"),i=$e.some(b=>b.value===e.prefill),a=s?"query":i&&e.prefill||(e.prefill?"custom":""),o=r("div",{class:"atfb-prefill__detail"}),l=r("p",{class:"atfb-row__hint atfb-prefill__preview"}),c=b=>{if(o.replaceChildren(),l.replaceChildren(),b==="query"){const v=e.prefill.startsWith("query:")?e.prefill.slice(6):"";o.append(w(v,x=>{const k=x.trim();t("prefill",k?`query:${k}`:""),d(`query:${k}`)},"utm_source"),r("p",{class:"atfb-row__hint",text:"The name of the parameter in the link people arrive on."}))}b==="custom"&&o.append(w(e.prefill,v=>{t("prefill",v),d(v)},"myplugin:something"),r("p",{class:"atfb-row__hint",text:"For a source another plugin has added through atf_resolve_prefill."})),d(e.prefill)},d=b=>{if(l.replaceChildren(),!b)return;if(b.startsWith("query:")){const x=b.slice(6);x&&(l.textContent=`A visit to …/your-page/?${x}=abc opens the form with “abc” in it.`);return}const v=$e.find(x=>x.value===b)?.tag;v&&we(this.form?.id??0).then(x=>{for(const k of x)for(const E of k.items)if(E.tag===v){const O=b.startsWith("user:");if(!E.sample){l.textContent="Empty unless the visitor is signed in.";return}l.textContent=O?`Opens with “${E.sample}” for you — empty for a visitor who is not signed in.`:`Opens with “${E.sample}”.`;return}})};c(a);const h=r("select",{class:"atfb-input atfb-select",on:{change:b=>{const v=b.target.value;t("prefill",v==="query"||v==="custom"?"":v),c(v)}}});h.append(r("option",{value:"",text:"Nothing — leave it empty",attrs:{selected:a===""}}));for(const b of Fs){const v=document.createElement("optgroup");v.label=b;for(const x of $e.filter(k=>k.group===b))v.append(r("option",{value:x.value,text:x.label,attrs:{selected:x.value===a}}));h.append(v)}const _=document.createElement("optgroup");return _.label="From the link they arrived on",_.append(r("option",{value:"query",text:"A parameter in the web address",attrs:{selected:a==="query"}})),h.append(_,r("option",{value:"custom",text:"Something else (advanced)",attrs:{selected:a==="custom"}})),m("Pre-fill this with",r("div",{class:"atfb-prefill",children:[h,o,l]}),"What the box already contains when the form opens. They can still change it.")}renderCondition(e){const t=e.some(s=>s.kind==="field"&&s.missing);return r("span",{class:`atfb-cond${t?" is-broken":""}`,attrs:{"aria-label":Ye(e)},children:[M("randomize"),...e.map(s=>this.renderConditionToken(s))]})}renderConditionToken(e){return e.kind==="field"&&!e.missing?r("button",{class:"atfb-cond__chip atfb-cond__chip--field",type:"button",text:e.text,title:"Go to this question",on:{click:i=>{i.stopPropagation(),this.selectField(e.fieldId),this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.fieldId)}"]`)?.scrollIntoView({block:"nearest",behavior:"smooth"})}}}):r("span",{class:{verb:"atfb-cond__verb",field:"atfb-cond__chip atfb-cond__chip--missing",operator:"atfb-cond__op",value:"atfb-cond__chip atfb-cond__chip--value",join:"atfb-cond__join"}[e.kind],text:e.text})}section(e,t,s,i=!1){const a=r("details",{class:"atfb-section",attrs:{open:this.openSections.get(e)??i},children:[r("summary",{text:t}),...s]});return a.addEventListener("toggle",()=>this.openSections.set(e,a.open)),a}logicMapButton(){const e=be(this.schema?.fields??[]).length>0,t=S(this.logicMapOn?"Hide logic":"Show logic",()=>{this.logicMapOn=!this.logicMapOn,$t(lt,this.logicMapOn?"on":"off"),this.renderBar(),this.renderCanvas()},this.logicMapOn?"primary":"secondary","randomize");return t.title="Draw a line from each question to the ones it decides.",t.hidden=!e,t}paintLogicMap(e){this.logicMap?.destroy(),this.logicMap=null;const t=this.schema?.fields??[],s=be(t);if(!s.length||!this.logicMapOn)return;e.classList.add("has-logicmap");const i=new Ut(e);i.setEdges(s),i.highlight(this.selected??""),this.logicMap=i,e.addEventListener("pointerover",a=>{const o=a.target.closest("[data-atfb-card]");i.highlight(o?.dataset.atfbCard??this.selected??"")}),e.addEventListener("pointerleave",()=>i.highlight(this.selected??""))}renderFieldCard(e,t){const s=this.config?.fieldTypes.find(d=>d.type===e.type),i=this.selected===e.id,a=this.schema?.fields??[],o=Bt(e,a),l=jt(a).get(e.id)??0,c=r("div",{class:`atfb-card${i?" is-selected":""}`,attrs:{"data-atfb-card":e.id,"data-index":t,tabindex:"0",role:"button","aria-pressed":i,"aria-label":`${e.label||s?.label||e.type}, ${t+1} of ${this.schema?.fields.length??0}`},children:[r("div",{class:"atfb-card__grip",attrs:{"aria-hidden":"true"},children:[M("menu")]}),r("div",{class:"atfb-card__body",children:[r("div",{class:"atfb-card__head",children:[M(s?.icon??"dashicons-forms"),r("span",{class:"atfb-card__type",text:s?.label??e.type}),this.requiredToggle(e),l?r("span",{class:"atfb-badge atfb-badge--controls",text:l===1?"controls 1 field":`controls ${l} fields`,title:"Other questions appear or disappear based on this answer."}):null]}),Gt(e,s,{edit:d=>{const h=this.liveField(e.id);h&&(d(h),this.markDirty(),this.syncInspector(h))},restructure:d=>{const h=this.liveField(e.id);h&&(this.snapshot(),d(h),this.markDirty(),this.renderCanvas(),this.renderInspector())}}),o.length?this.renderCondition(o):null]}),r("div",{class:"atfb-card__actions",children:[this.cardAction("admin-page","Duplicate",()=>this.duplicateField(e.id)),this.cardAction("trash","Delete",()=>void this.deleteField(e.id))]})]});return c.addEventListener("click",d=>{d.target.closest(".atfb-card__actions")||K().recentlyEndedDrag()||this.selectField(e.id)}),c.addEventListener("keydown",d=>{if(d.key==="Enter"||d.key===" "){d.preventDefault(),this.selectField(e.id);return}d.altKey&&(d.key==="ArrowUp"||d.key==="ArrowDown")&&(d.preventDefault(),this.moveField(e.id,d.key==="ArrowUp"?t-1:t+1),window.requestAnimationFrame(()=>{this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.id)}"]`)?.focus()})),(d.key==="Delete"||d.key==="Backspace")&&(d.preventDefault(),this.deleteField(e.id))}),c.addEventListener("pointerdown",d=>{d.target.closest(".atfb-card__actions")||K().start({payload:qe(te,c,{fieldId:e.id,field:e,isNew:!1},d),origin:d})}),c}requiredToggle(e){return r("button",{class:`atfb-req${e.required?" is-on":""}`,type:"button",text:e.required?"Required":"Optional",title:e.required?"This must be answered. Click to make it optional.":"Click to make this required.",attrs:{"aria-pressed":e.required?"true":"false"},on:{pointerdown:s=>s.stopPropagation(),click:s=>{s.stopPropagation(),e.required=!e.required,this.markDirty(),this.renderCanvas(),this.renderInspector()}}})}cardAction(e,t,s){return r("button",{class:"atfb-card__action",type:"button",title:t,attrs:{"aria-label":t},on:{click:i=>{i.stopPropagation(),s()}},children:[M(e)]})}registerCanvasTarget(e){this.canvasTarget?.(),this.canvasTarget=null;const t=r("div",{class:"atfb-marker",attrs:{"aria-hidden":"true"}}),s=K().registerDropTarget({id:`atfb-canvas-${this.form?.id??0}`,element:e,accept:a=>a.type===te,onEnter:()=>e.classList.add("is-dropping"),onLeave:()=>{e.classList.remove("is-dropping"),t.remove()},onDrop:(a,o)=>{e.classList.remove("is-dropping"),t.remove();const l=a.payload.data,c=l.fieldId?this.canvas.querySelector(`[data-atfb-card="${CSS.escape(l.fieldId)}"]`):null,d=Oe(e,".atfb-card",o.clientY,c??void 0);if(l.isNew&&l.fieldType){this.addField(l.fieldType,d);return}if(l.fieldId&&this.schema?.fields.some(h=>h.id===l.fieldId)){this.moveField(l.fieldId,d);return}l.field&&this.insertField({...l.field,id:""},d)}}),i=a=>{const o=a.detail;if(o?.payload?.type!==te||!e.classList.contains("is-dropping"))return;const l=o.payload.data?.fieldId?this.canvas.querySelector(`[data-atfb-card="${CSS.escape(o.payload.data.fieldId)}"]`):null,c=o.clientY??0,d=Oe(e,".atfb-card",c,l??void 0),h=Array.from(e.querySelectorAll(".atfb-card")).filter(_=>_!==l);d>=h.length?e.append(t):h[d].before(t)};document.addEventListener("os.drag.move",i),this.canvasTarget=()=>{s(),document.removeEventListener("os.drag.move",i)}}addField(e,t){const s=this.config?.fieldTypes.find(a=>a.type===e);if(!s||!this.schema)return;const i={id:this.nextFieldId(),type:e,label:s.input?s.label:"",placeholder:"",hint:"",required:!1,width:"full",cssClass:"",default:"",choices:s.choices?[{label:"First choice",value:"first"},{label:"Second choice",value:"second"}]:[],logic:{enabled:!1,action:"show",match:"all",rules:[]},messages:{},prefill:"",...s.settings};this.insertField(i,t)}insertField(e,t){if(!this.schema)return;e.id||(e.id=this.nextFieldId()),this.snapshot();const s=t===void 0?this.schema.fields.length:Math.max(0,Math.min(t,this.schema.fields.length));this.schema.fields.splice(s,0,e),this.selected=e.id,this.markDirty(),this.renderCanvas(),this.renderInspector(),window.requestAnimationFrame(()=>{this.canvas.querySelector(`[data-atfb-card="${CSS.escape(e.id)}"]`)?.focus()})}moveField(e,t){if(!this.schema)return;const s=ut(this.schema.fields,e,t);if(!s)return;this.snapshot();const[i]=this.schema.fields.splice(s.from,1);this.schema.fields.splice(s.to,0,i),this.markDirty(),this.renderCanvas()}duplicateField(e){if(!this.schema)return;const t=this.schema.fields.findIndex(i=>i.id===e);if(t<0)return;const s=JSON.parse(JSON.stringify(this.schema.fields[t]));s.id=this.nextFieldId(),this.insertField(s,t+1)}async deleteField(e){if(!this.schema)return;const t=this.schema.fields.filter(i=>i.logic?.rules?.some(a=>a.field===e)),s=t.length?`Delete this field? ${t.length} other field${t.length===1?"":"s"} use it in a condition, and those conditions will stop working.`:Ae("confirmDelete","Delete this? It cannot be undone.");await fe(s,"Delete field")&&(this.snapshot(),this.schema.fields=this.schema.fields.filter(i=>i.id!==e),this.selected===e&&(this.selected=null),this.markDirty(),this.renderCanvas(),this.renderInspector())}selectField(e){this.selected=e;for(const t of this.canvas.querySelectorAll("[data-atfb-card]")){const s=t.dataset.atfbCard===e;t.classList.toggle("is-selected",s),t.setAttribute("aria-pressed",s?"true":"false")}this.logicMap?.highlight(e),this.renderInspector()}nextFieldId(){const e=new Set((this.schema?.fields??[]).map(s=>s.id));let t=e.size+1;for(;e.has(`f${t}`);)t++;return`f${t}`}nextEntryId(e,t){const s=new Set(t.map(a=>a.id));let i=t.length+1;for(;s.has(`${e}${i}`);)i++;return`${e}${i}`}renderTypeSettings(e,t,s,i){for(const a of s){const o=ct[a];o&&(this.inspector.append(dt(e,o,i)),o.also&&this.inspector.append(dt(e,{...o,key:o.also.key,label:o.also.label,hint:o.also.hint},i)))}s.includes("rows")&&e.type!=="likert"&&this.inspector.append(m("Lines tall",R(String(e.rows??""),a=>i("rows",a)))),s.includes("rows")&&e.type==="likert"&&this.inspector.append(this.renderStatementList(e,i)),s.includes("parts")&&this.inspector.append(this.renderPartsEditor(e,t,i)),s.includes("default")&&!["files","object"].includes(t?.value??"")&&this.inspector.append(this.renderDefaultControl(e,t,i))}renderStatementList(e,t){const s=Array.isArray(e.rows)?e.rows:[];return m("Statements",re(s.map(i=>i.label??"").join(` `),i=>t("rows",ht(s,i)),5),"One per line. Each becomes a row of the matrix.")}renderPartsEditor(e,t,s){const i=t?.parts??[],a=Array.isArray(e.parts)?e.parts:i.map(l=>l.key),o=i.map(l=>A(l.label,a.includes(l.key),c=>{const d=i.map(h=>h.key).filter(h=>h===l.key?c:a.includes(h));s("parts",d.length?d:[l.key])}));return r("div",{class:"atfb-section",children:[r("h4",{class:"atfb-section__title",text:"Parts to ask for"}),...o]})}renderDefaultControl(e,t,s){const i="Filled in before they start. They can change it.";return e.type==="switch"||e.type==="consent"?A("On by default",!!e.default,a=>s("default",a)):t?.choices&&(e.choices??[]).length?m("Default answer",F(String(e.default??""),[{value:"",label:"Nothing chosen"},...(e.choices??[]).map(a=>({value:String(a.value),label:a.label||String(a.value)}))],a=>s("default",a)),i):m("Default answer",w(String(e.default??""),a=>s("default",a)),i)}renderChoicesEditor(e,t){const s=e.choices??[],i=o=>this.liveField(e.id)?.choices?.[o],a=r("div",{class:"atfb-choices"});return s.forEach((o,l)=>{const c=r("div",{class:"atfb-choice-row",children:[e.type==="image_choice"?this.choiceImageWell(o,l,e):null,H(w(o.label,d=>{const h=i(l);if(!h)return;const _=!h.value||h.value===h.label;h.label=d,_&&(h.value=d),this.markDirty();const b=this.liveField(e.id);b&&this.syncCanvas(b)}),`choice:${l}:label`),H(w(o.value,d=>{const h=i(l);h&&(h.value=d,this.markDirty())},"value"),`choice:${l}:value`),e.type==="quiz"||o.points!==void 0?R(String(o.points??""),d=>{const h=i(l);h&&(h.points=d===""?void 0:Number(d),this.markDirty())}):R(String(o.price??""),d=>{const h=i(l);h&&(h.price=d===""?void 0:Number(d),this.markDirty())}),r("button",{class:"atfb-card__action",type:"button",attrs:{"aria-label":`Remove ${o.label}`},on:{click:()=>{const d=this.liveField(e.id);d&&((d.choices??[]).splice(l,1),t("choices",d.choices),this.renderInspector())}},children:[M("trash")]})]});a.append(c)}),r("div",{class:"atfb-section",children:[r("h4",{text:"Choices"}),r("p",{class:"atfb-hint",text:e.type==="quiz"?"Label, value, points.":"Label, value, and a price for calculations."}),a,S("Add choice",()=>{const o=this.liveField(e.id);if(!o)return;const l=o.choices??[];l.push({label:"",value:""}),t("choices",l),this.renderInspector()},"ghost","plus-alt2"),e.type==="quiz"?m("Correct answer",F(String(e.correct??""),[{value:"",label:"—"},...s.map(o=>({value:o.value,label:o.label}))],o=>t("correct",o))):null]})}choiceImageWell(e,t,s){const i=r("div",{class:`atfb-well${e.image?" has-image":""}`,attrs:{"data-choice":t,"aria-label":`Image for ${e.label||`choice ${t+1}`}`},children:[e.image?r("span",{class:"atfb-well__id",text:`#${e.image}`}):M("format-image")]}),a=K().registerDropTarget({id:`atfb-well-${s.id}-${t}`,element:i,accept:o=>$s.includes(o.type),onEnter:()=>i.classList.add("is-dropping"),onLeave:()=>i.classList.remove("is-dropping"),onDrop:o=>{i.classList.remove("is-dropping");const l=o.payload.data,c=Number(l.attachmentId??l.id??l.file?.id??0);if(!c){N("That is not an image this field can use","","error");return}const d=this.liveField(s.id)?.choices?.[t];d&&(d.image=c,this.markDirty(),this.renderInspector())}});return this.teardowns.push(a),i.addEventListener("click",()=>{const o=this.liveField(s.id)?.choices?.[t];o?.image&&(o.image=void 0,this.markDirty(),this.renderInspector())}),i}renderValidationSection(e,t,s){const i=[],a=[];t.includes("minlength")&&a.push(["minlength","Minimum characters"],["maxlength","Maximum characters"]),t.includes("min")?a.push(["min","Minimum"],["max","Maximum"]):t.includes("max")&&a.push(["max","Highest"]),t.includes("step")&&a.push(["step","Steps of"]),t.includes("mindate")&&a.push(["minDate","Earliest date"],["maxDate","Latest date"]),t.includes("mintime")&&a.push(["minTime","Earliest time"],["maxTime","Latest time"]);for(const[l,c]of a)i.push(m(c,w(String(e[l]??""),d=>s(l,d))));t.includes("pattern")&&i.push(m("Pattern",w(String(e.pattern??""),l=>s("pattern",l)),"A regular expression, without slashes.")),t.includes("unique")&&i.push(A("No two people may submit the same value",!!e.unique,l=>s("unique",l)));const o=e.messages??{};return t.includes("required")&&i.push(m("Message when required",w(o.required??"",l=>{o.required=l,s("messages",o)}),"Leave empty for the default wording.")),i.length?this.section(`validation:${e.id}`,"Validation",i):r("div",{class:"atfb-section is-empty"})}renderLogicSection(e,t){const s=e.logic,i=()=>this.liveField(e.id)?.logic,a=(this.schema?.fields??[]).filter(l=>l.id!==e.id&&l.type!=="page_break"),o=r("div",{class:"atfb-rules"});return s.rules.forEach((l,c)=>{o.append(r("div",{class:"atfb-rule",children:[F(l.field,a.map(d=>({value:d.id,label:d.label||d.id})),d=>{const h=i()?.rules[c];h&&(h.field=d,this.markDirty())}),F(l.operator,Object.entries(this.config?.operators??{}).map(([d,h])=>({value:d,label:h})),d=>{const h=i()?.rules[c];h&&(h.operator=d,this.markDirty())}),w(l.value,d=>{const h=i()?.rules[c];h&&(h.value=d,this.markDirty())}),r("button",{class:"atfb-card__action",type:"button",attrs:{"aria-label":"Remove this rule"},on:{click:()=>{const d=i();d&&(d.rules.splice(c,1),t("logic",d),this.renderInspector())}},children:[M("trash")]})]}))}),this.section(`logic:${e.id}`,"Conditional logic",[A("Only show this field sometimes",s.enabled,l=>{const c=i();c&&(c.enabled=l,t("logic",c),this.renderInspector())}),s.enabled?r("div",{children:[r("div",{class:"atfb-rule-head",children:[F(s.action,[{value:"show",label:"Show"},{value:"hide",label:"Hide"}],l=>{const c=i();c&&(c.action=l,t("logic",c))}),r("span",{text:"this field when"}),F(s.match,[{value:"all",label:"all"},{value:"any",label:"any"}],l=>{const c=i();c&&(c.match=l,t("logic",c))}),r("span",{text:"of these match:"})]}),o,S("Add rule",()=>{const l=i();l&&(l.rules.push({field:a[0]?.id??"",operator:"is",value:""}),t("logic",l),this.renderInspector())},"ghost","plus-alt2")]}):null],s.enabled)}renderTabCanvas(){return this.schema?this.tab==="theme"?Ze({themes:this.themes,tokens:this.config?.tokens??[],activeSlug:this.schema.settings.theme,overrides:this.schema.settings.themeOverrides,onTheme:e=>{this.schema.settings.theme=e,this.markDirty()},onOverride:(e,t)=>{t===""?delete this.schema.settings.themeOverrides[e]:this.schema.settings.themeOverrides[e]=t,this.markDirty()},onOverridesReplaced:e=>{this.schema.settings.themeOverrides={...e},this.markDirty()},previewFor:(e,t)=>this.previewHtml(e,t),onThemesChanged:e=>{this.themes=e}}):this.tab==="settings"?this.renderSettingsPane():this.tab==="notify"?this.renderNotificationsPane():this.renderConfirmationsPane():r("div")}async paintCanvasTheme(){if(!this.form||!this.schema)return;const e=this.schema.settings.theme,t=JSON.stringify([e,this.schema.settings.themeOverrides]);if(t!==this.canvasThemeSignature){this.canvasThemeSignature=t;try{const s=await this.previewHtml(e,this.schema.settings.themeOverrides??{});this.root.classList.toggle("atfb--dark-form",/atf-is-dark/.test(s));const i=/