@one-million-lines/email-builder 0.1.0 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -1
- package/README.md +62 -20
- package/dist/email-builder.cjs +1 -1
- package/dist/email-builder.cjs.map +1 -1
- package/dist/email-builder.js +2 -2
- package/dist/email-builder.js.map +1 -1
- package/dist/plugins/imageUploader/index.d.ts +2 -2
- package/dist/styles.css +1 -1
- package/package.json +3 -2
package/dist/email-builder.cjs
CHANGED
|
@@ -76,5 +76,5 @@ ${a}
|
|
|
76
76
|
While dragging, use the arrow keys to move the item.
|
|
77
77
|
Press space again to drop the item in its new position, or press escape to cancel.
|
|
78
78
|
`},Wr={onDragStart(e){let{active:t}=e;return"Picked up draggable item "+t.id+"."},onDragOver(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was moved over droppable area "+n.id+".":"Draggable item "+t.id+" is no longer over a droppable area."},onDragEnd(e){let{active:t,over:n}=e;return n?"Draggable item "+t.id+" was dropped over droppable area "+n.id:"Draggable item "+t.id+" was dropped."},onDragCancel(e){let{active:t}=e;return"Dragging was cancelled. Draggable item "+t.id+" was dropped."}};function Hr(e){let{announcements:t=Wr,container:n,hiddenTextDescribedById:r,screenReaderInstructions:i=_r}=e;const{announce:a,announcement:s}=Ir(),d=Et("DndLiveRegion"),[l,c]=g.useState(!1);if(g.useEffect(()=>{c(!0)},[]),$r(g.useMemo(()=>({onDragStart(p){let{active:f}=p;a(t.onDragStart({active:f}))},onDragMove(p){let{active:f,over:b}=p;t.onDragMove&&a(t.onDragMove({active:f,over:b}))},onDragOver(p){let{active:f,over:b}=p;a(t.onDragOver({active:f,over:b}))},onDragEnd(p){let{active:f,over:b}=p;a(t.onDragEnd({active:f,over:b}))},onDragCancel(p){let{active:f,over:b}=p;a(t.onDragCancel({active:f,over:b}))}}),[a,t])),!l)return null;const m=g.createElement(g.Fragment,null,g.createElement(Lr,{id:r,value:i.draggable}),g.createElement(Mr,{id:d,announcement:s}));return n?xt.createPortal(m,n):m}var J;(function(e){e.DragStart="dragStart",e.DragMove="dragMove",e.DragEnd="dragEnd",e.DragCancel="dragCancel",e.DragOver="dragOver",e.RegisterDroppable="registerDroppable",e.SetDroppableDisabled="setDroppableDisabled",e.UnregisterDroppable="unregisterDroppable"})(J||(J={}));function Ut(){}function Wn(e,t){return g.useMemo(()=>({sensor:e,options:t??{}}),[e,t])}function Ur(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return g.useMemo(()=>[...t].filter(r=>r!=null),[...t])}const fe=Object.freeze({x:0,y:0});function mo(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))}function ho(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return n-r}function Gr(e,t){let{data:{value:n}}=e,{data:{value:r}}=t;return r-n}function Hn(e){let{left:t,top:n,height:r,width:i}=e;return[{x:t,y:n},{x:t+i,y:n},{x:t,y:n+r},{x:t+i,y:n+r}]}function fo(e,t){if(!e||e.length===0)return null;const[n]=e;return n[t]}function Un(e,t,n){return t===void 0&&(t=e.left),n===void 0&&(n=e.top),{x:t+e.width*.5,y:n+e.height*.5}}const Yr=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const i=Un(t,t.left,t.top),a=[];for(const s of r){const{id:d}=s,l=n.get(d);if(l){const c=mo(Un(l),i);a.push({id:d,data:{droppableContainer:s,value:c}})}}return a.sort(ho)},qr=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const i=Hn(t),a=[];for(const s of r){const{id:d}=s,l=n.get(d);if(l){const c=Hn(l),m=i.reduce((f,b,j)=>f+mo(c[j],b),0),p=Number((m/4).toFixed(4));a.push({id:d,data:{droppableContainer:s,value:p}})}}return a.sort(ho)};function Jr(e,t){const n=Math.max(t.top,e.top),r=Math.max(t.left,e.left),i=Math.min(t.left+t.width,e.left+e.width),a=Math.min(t.top+t.height,e.top+e.height),s=i-r,d=a-n;if(r<i&&n<a){const l=t.width*t.height,c=e.width*e.height,m=s*d,p=m/(l+c-m);return Number(p.toFixed(4))}return 0}const Vr=e=>{let{collisionRect:t,droppableRects:n,droppableContainers:r}=e;const i=[];for(const a of r){const{id:s}=a,d=n.get(s);if(d){const l=Jr(d,t);l>0&&i.push({id:s,data:{droppableContainer:a,value:l}})}}return i.sort(Gr)};function Xr(e,t,n){return{...e,scaleX:t&&n?t.width/n.width:1,scaleY:t&&n?t.height/n.height:1}}function bo(e,t){return e&&t?{x:e.left-t.left,y:e.top-t.top}:fe}function Kr(e){return function(n){for(var r=arguments.length,i=new Array(r>1?r-1:0),a=1;a<r;a++)i[a-1]=arguments[a];return i.reduce((s,d)=>({...s,top:s.top+e*d.y,bottom:s.bottom+e*d.y,left:s.left+e*d.x,right:s.right+e*d.x}),{...n})}}const Qr=Kr(1);function Zr(e){if(e.startsWith("matrix3d(")){const t=e.slice(9,-1).split(/, /);return{x:+t[12],y:+t[13],scaleX:+t[0],scaleY:+t[5]}}else if(e.startsWith("matrix(")){const t=e.slice(7,-1).split(/, /);return{x:+t[4],y:+t[5],scaleX:+t[0],scaleY:+t[3]}}return null}function ei(e,t,n){const r=Zr(t);if(!r)return e;const{scaleX:i,scaleY:a,x:s,y:d}=r,l=e.left-s-(1-i)*parseFloat(n),c=e.top-d-(1-a)*parseFloat(n.slice(n.indexOf(" ")+1)),m=i?e.width/i:e.width,p=a?e.height/a:e.height;return{width:m,height:p,top:c,right:l+m,bottom:c+p,left:l}}const ti={ignoreTransform:!1};function nt(e,t){t===void 0&&(t=ti);let n=e.getBoundingClientRect();if(t.ignoreTransform){const{transform:c,transformOrigin:m}=oe(e).getComputedStyle(e);c&&(n=ei(n,c,m))}const{top:r,left:i,width:a,height:s,bottom:d,right:l}=n;return{top:r,left:i,width:a,height:s,bottom:d,right:l}}function Gn(e){return nt(e,{ignoreTransform:!0})}function ni(e){const t=e.innerWidth,n=e.innerHeight;return{top:0,left:0,right:t,bottom:n,width:t,height:n}}function oi(e,t){return t===void 0&&(t=oe(e).getComputedStyle(e)),t.position==="fixed"}function ri(e,t){t===void 0&&(t=oe(e).getComputedStyle(e));const n=/(auto|scroll|overlay)/;return["overflow","overflowX","overflowY"].some(i=>{const a=t[i];return typeof a=="string"?n.test(a):!1})}function Vt(e,t){const n=[];function r(i){if(t!=null&&n.length>=t||!i)return n;if(Sn(i)&&i.scrollingElement!=null&&!n.includes(i.scrollingElement))return n.push(i.scrollingElement),n;if(!At(i)||uo(i)||n.includes(i))return n;const a=oe(e).getComputedStyle(i);return i!==e&&ri(i,a)&&n.push(i),oi(i,a)?n:r(i.parentNode)}return e?r(e):n}function xo(e){const[t]=Vt(e,1);return t??null}function sn(e){return!Jt||!e?null:et(e)?e:wn(e)?Sn(e)||e===tt(e).scrollingElement?window:At(e)?e:null:null}function yo(e){return et(e)?e.scrollX:e.scrollLeft}function vo(e){return et(e)?e.scrollY:e.scrollTop}function mn(e){return{x:yo(e),y:vo(e)}}var V;(function(e){e[e.Forward=1]="Forward",e[e.Backward=-1]="Backward"})(V||(V={}));function wo(e){return!Jt||!e?!1:e===document.scrollingElement}function So(e){const t={x:0,y:0},n=wo(e)?{height:window.innerHeight,width:window.innerWidth}:{height:e.clientHeight,width:e.clientWidth},r={x:e.scrollWidth-n.width,y:e.scrollHeight-n.height},i=e.scrollTop<=t.y,a=e.scrollLeft<=t.x,s=e.scrollTop>=r.y,d=e.scrollLeft>=r.x;return{isTop:i,isLeft:a,isBottom:s,isRight:d,maxScroll:r,minScroll:t}}const ii={x:.2,y:.2};function ai(e,t,n,r,i){let{top:a,left:s,right:d,bottom:l}=n;r===void 0&&(r=10),i===void 0&&(i=ii);const{isTop:c,isBottom:m,isLeft:p,isRight:f}=So(e),b={x:0,y:0},j={x:0,y:0},x={height:t.height*i.y,width:t.width*i.x};return!c&&a<=t.top+x.height?(b.y=V.Backward,j.y=r*Math.abs((t.top+x.height-a)/x.height)):!m&&l>=t.bottom-x.height&&(b.y=V.Forward,j.y=r*Math.abs((t.bottom-x.height-l)/x.height)),!f&&d>=t.right-x.width?(b.x=V.Forward,j.x=r*Math.abs((t.right-x.width-d)/x.width)):!p&&s<=t.left+x.width&&(b.x=V.Backward,j.x=r*Math.abs((t.left+x.width-s)/x.width)),{direction:b,speed:j}}function si(e){if(e===document.scrollingElement){const{innerWidth:a,innerHeight:s}=window;return{top:0,left:0,right:a,bottom:s,width:a,height:s}}const{top:t,left:n,right:r,bottom:i}=e.getBoundingClientRect();return{top:t,left:n,right:r,bottom:i,width:e.clientWidth,height:e.clientHeight}}function ko(e){return e.reduce((t,n)=>Ke(t,mn(n)),fe)}function li(e){return e.reduce((t,n)=>t+yo(n),0)}function di(e){return e.reduce((t,n)=>t+vo(n),0)}function ci(e,t){if(t===void 0&&(t=nt),!e)return;const{top:n,left:r,bottom:i,right:a}=t(e);xo(e)&&(i<=0||a<=0||n>=window.innerHeight||r>=window.innerWidth)&&e.scrollIntoView({block:"center",inline:"center"})}const ui=[["x",["left","right"],li],["y",["top","bottom"],di]];class Tn{constructor(t,n){this.rect=void 0,this.width=void 0,this.height=void 0,this.top=void 0,this.bottom=void 0,this.right=void 0,this.left=void 0;const r=Vt(n),i=ko(r);this.rect={...t},this.width=t.width,this.height=t.height;for(const[a,s,d]of ui)for(const l of s)Object.defineProperty(this,l,{get:()=>{const c=d(r),m=i[a]-c;return this.rect[l]+m},enumerable:!0});Object.defineProperty(this,"rect",{enumerable:!1})}}class vt{constructor(t){this.target=void 0,this.listeners=[],this.removeAll=()=>{this.listeners.forEach(n=>{var r;return(r=this.target)==null?void 0:r.removeEventListener(...n)})},this.target=t}add(t,n,r){var i;(i=this.target)==null||i.addEventListener(t,n,r),this.listeners.push([t,n,r])}}function gi(e){const{EventTarget:t}=oe(e);return e instanceof t?e:tt(e)}function ln(e,t){const n=Math.abs(e.x),r=Math.abs(e.y);return typeof t=="number"?Math.sqrt(n**2+r**2)>t:"x"in t&&"y"in t?n>t.x&&r>t.y:"x"in t?n>t.x:"y"in t?r>t.y:!1}var me;(function(e){e.Click="click",e.DragStart="dragstart",e.Keydown="keydown",e.ContextMenu="contextmenu",e.Resize="resize",e.SelectionChange="selectionchange",e.VisibilityChange="visibilitychange"})(me||(me={}));function Yn(e){e.preventDefault()}function pi(e){e.stopPropagation()}var L;(function(e){e.Space="Space",e.Down="ArrowDown",e.Right="ArrowRight",e.Left="ArrowLeft",e.Up="ArrowUp",e.Esc="Escape",e.Enter="Enter",e.Tab="Tab"})(L||(L={}));const Co={start:[L.Space,L.Enter],cancel:[L.Esc],end:[L.Space,L.Enter,L.Tab]},mi=(e,t)=>{let{currentCoordinates:n}=t;switch(e.code){case L.Right:return{...n,x:n.x+25};case L.Left:return{...n,x:n.x-25};case L.Down:return{...n,y:n.y+25};case L.Up:return{...n,y:n.y-25}}};class jn{constructor(t){this.props=void 0,this.autoScrollEnabled=!1,this.referenceCoordinates=void 0,this.listeners=void 0,this.windowListeners=void 0,this.props=t;const{event:{target:n}}=t;this.props=t,this.listeners=new vt(tt(n)),this.windowListeners=new vt(oe(n)),this.handleKeyDown=this.handleKeyDown.bind(this),this.handleCancel=this.handleCancel.bind(this),this.attach()}attach(){this.handleStart(),this.windowListeners.add(me.Resize,this.handleCancel),this.windowListeners.add(me.VisibilityChange,this.handleCancel),setTimeout(()=>this.listeners.add(me.Keydown,this.handleKeyDown))}handleStart(){const{activeNode:t,onStart:n}=this.props,r=t.node.current;r&&ci(r),n(fe)}handleKeyDown(t){if(Cn(t)){const{active:n,context:r,options:i}=this.props,{keyboardCodes:a=Co,coordinateGetter:s=mi,scrollBehavior:d="smooth"}=i,{code:l}=t;if(a.end.includes(l)){this.handleEnd(t);return}if(a.cancel.includes(l)){this.handleCancel(t);return}const{collisionRect:c}=r.current,m=c?{x:c.left,y:c.top}:fe;this.referenceCoordinates||(this.referenceCoordinates=m);const p=s(t,{active:n,context:r.current,currentCoordinates:m});if(p){const f=Ct(p,m),b={x:0,y:0},{scrollableAncestors:j}=r.current;for(const x of j){const S=t.code,{isTop:w,isRight:C,isLeft:N,isBottom:k,maxScroll:z,minScroll:D}=So(x),E=si(x),B={x:Math.min(S===L.Right?E.right-E.width/2:E.right,Math.max(S===L.Right?E.left:E.left+E.width/2,p.x)),y:Math.min(S===L.Down?E.bottom-E.height/2:E.bottom,Math.max(S===L.Down?E.top:E.top+E.height/2,p.y))},P=S===L.Right&&!C||S===L.Left&&!N,W=S===L.Down&&!k||S===L.Up&&!w;if(P&&B.x!==p.x){const $=x.scrollLeft+f.x,K=S===L.Right&&$<=z.x||S===L.Left&&$>=D.x;if(K&&!f.y){x.scrollTo({left:$,behavior:d});return}K?b.x=x.scrollLeft-$:b.x=S===L.Right?x.scrollLeft-z.x:x.scrollLeft-D.x,b.x&&x.scrollBy({left:-b.x,behavior:d});break}else if(W&&B.y!==p.y){const $=x.scrollTop+f.y,K=S===L.Down&&$<=z.y||S===L.Up&&$>=D.y;if(K&&!f.x){x.scrollTo({top:$,behavior:d});return}K?b.y=x.scrollTop-$:b.y=S===L.Down?x.scrollTop-z.y:x.scrollTop-D.y,b.y&&x.scrollBy({top:-b.y,behavior:d});break}}this.handleMove(t,Ke(Ct(p,this.referenceCoordinates),b))}}}handleMove(t,n){const{onMove:r}=this.props;t.preventDefault(),r(n)}handleEnd(t){const{onEnd:n}=this.props;t.preventDefault(),this.detach(),n()}handleCancel(t){const{onCancel:n}=this.props;t.preventDefault(),this.detach(),n()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll()}}jn.activators=[{eventName:"onKeyDown",handler:(e,t,n)=>{let{keyboardCodes:r=Co,onActivation:i}=t,{active:a}=n;const{code:s}=e.nativeEvent;if(r.start.includes(s)){const d=a.activatorNode.current;return d&&e.target!==d?!1:(e.preventDefault(),i?.({event:e.nativeEvent}),!0)}return!1}}];function qn(e){return!!(e&&"distance"in e)}function Jn(e){return!!(e&&"delay"in e)}class Bn{constructor(t,n,r){var i;r===void 0&&(r=gi(t.event.target)),this.props=void 0,this.events=void 0,this.autoScrollEnabled=!0,this.document=void 0,this.activated=!1,this.initialCoordinates=void 0,this.timeoutId=null,this.listeners=void 0,this.documentListeners=void 0,this.windowListeners=void 0,this.props=t,this.events=n;const{event:a}=t,{target:s}=a;this.props=t,this.events=n,this.document=tt(s),this.documentListeners=new vt(this.document),this.listeners=new vt(r),this.windowListeners=new vt(oe(s)),this.initialCoordinates=(i=pn(a))!=null?i:fe,this.handleStart=this.handleStart.bind(this),this.handleMove=this.handleMove.bind(this),this.handleEnd=this.handleEnd.bind(this),this.handleCancel=this.handleCancel.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.removeTextSelection=this.removeTextSelection.bind(this),this.attach()}attach(){const{events:t,props:{options:{activationConstraint:n,bypassActivationConstraint:r}}}=this;if(this.listeners.add(t.move.name,this.handleMove,{passive:!1}),this.listeners.add(t.end.name,this.handleEnd),t.cancel&&this.listeners.add(t.cancel.name,this.handleCancel),this.windowListeners.add(me.Resize,this.handleCancel),this.windowListeners.add(me.DragStart,Yn),this.windowListeners.add(me.VisibilityChange,this.handleCancel),this.windowListeners.add(me.ContextMenu,Yn),this.documentListeners.add(me.Keydown,this.handleKeydown),n){if(r!=null&&r({event:this.props.event,activeNode:this.props.activeNode,options:this.props.options}))return this.handleStart();if(Jn(n)){this.timeoutId=setTimeout(this.handleStart,n.delay),this.handlePending(n);return}if(qn(n)){this.handlePending(n);return}}this.handleStart()}detach(){this.listeners.removeAll(),this.windowListeners.removeAll(),setTimeout(this.documentListeners.removeAll,50),this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}handlePending(t,n){const{active:r,onPending:i}=this.props;i(r,t,this.initialCoordinates,n)}handleStart(){const{initialCoordinates:t}=this,{onStart:n}=this.props;t&&(this.activated=!0,this.documentListeners.add(me.Click,pi,{capture:!0}),this.removeTextSelection(),this.documentListeners.add(me.SelectionChange,this.removeTextSelection),n(t))}handleMove(t){var n;const{activated:r,initialCoordinates:i,props:a}=this,{onMove:s,options:{activationConstraint:d}}=a;if(!i)return;const l=(n=pn(t))!=null?n:fe,c=Ct(i,l);if(!r&&d){if(qn(d)){if(d.tolerance!=null&&ln(c,d.tolerance))return this.handleCancel();if(ln(c,d.distance))return this.handleStart()}if(Jn(d)&&ln(c,d.tolerance))return this.handleCancel();this.handlePending(d,c);return}t.cancelable&&t.preventDefault(),s(l)}handleEnd(){const{onAbort:t,onEnd:n}=this.props;this.detach(),this.activated||t(this.props.active),n()}handleCancel(){const{onAbort:t,onCancel:n}=this.props;this.detach(),this.activated||t(this.props.active),n()}handleKeydown(t){t.code===L.Esc&&this.handleCancel()}removeTextSelection(){var t;(t=this.document.getSelection())==null||t.removeAllRanges()}}const hi={cancel:{name:"pointercancel"},move:{name:"pointermove"},end:{name:"pointerup"}};class Rn extends Bn{constructor(t){const{event:n}=t,r=tt(n.target);super(t,hi,r)}}Rn.activators=[{eventName:"onPointerDown",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return!n.isPrimary||n.button!==0?!1:(r?.({event:n}),!0)}}];const fi={move:{name:"mousemove"},end:{name:"mouseup"}};var hn;(function(e){e[e.RightClick=2]="RightClick"})(hn||(hn={}));class bi extends Bn{constructor(t){super(t,fi,tt(t.event.target))}}bi.activators=[{eventName:"onMouseDown",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;return n.button===hn.RightClick?!1:(r?.({event:n}),!0)}}];const dn={cancel:{name:"touchcancel"},move:{name:"touchmove"},end:{name:"touchend"}};class xi extends Bn{constructor(t){super(t,dn)}static setup(){return window.addEventListener(dn.move.name,t,{capture:!1,passive:!1}),function(){window.removeEventListener(dn.move.name,t)};function t(){}}}xi.activators=[{eventName:"onTouchStart",handler:(e,t)=>{let{nativeEvent:n}=e,{onActivation:r}=t;const{touches:i}=n;return i.length>1?!1:(r?.({event:n}),!0)}}];var wt;(function(e){e[e.Pointer=0]="Pointer",e[e.DraggableRect=1]="DraggableRect"})(wt||(wt={}));var Gt;(function(e){e[e.TreeOrder=0]="TreeOrder",e[e.ReversedTreeOrder=1]="ReversedTreeOrder"})(Gt||(Gt={}));function yi(e){let{acceleration:t,activator:n=wt.Pointer,canScroll:r,draggingRect:i,enabled:a,interval:s=5,order:d=Gt.TreeOrder,pointerCoordinates:l,scrollableAncestors:c,scrollableAncestorRects:m,delta:p,threshold:f}=e;const b=wi({delta:p,disabled:!a}),[j,x]=Er(),S=g.useRef({x:0,y:0}),w=g.useRef({x:0,y:0}),C=g.useMemo(()=>{switch(n){case wt.Pointer:return l?{top:l.y,bottom:l.y,left:l.x,right:l.x}:null;case wt.DraggableRect:return i}},[n,i,l]),N=g.useRef(null),k=g.useCallback(()=>{const D=N.current;if(!D)return;const E=S.current.x*w.current.x,B=S.current.y*w.current.y;D.scrollBy(E,B)},[]),z=g.useMemo(()=>d===Gt.TreeOrder?[...c].reverse():c,[d,c]);g.useEffect(()=>{if(!a||!c.length||!C){x();return}for(const D of z){if(r?.(D)===!1)continue;const E=c.indexOf(D),B=m[E];if(!B)continue;const{direction:P,speed:W}=ai(D,B,C,t,f);for(const $ of["x","y"])b[$][P[$]]||(W[$]=0,P[$]=0);if(W.x>0||W.y>0){x(),N.current=D,j(k,s),S.current=W,w.current=P;return}}S.current={x:0,y:0},w.current={x:0,y:0},x()},[t,k,r,x,a,s,JSON.stringify(C),JSON.stringify(b),j,c,z,m,JSON.stringify(f)])}const vi={x:{[V.Backward]:!1,[V.Forward]:!1},y:{[V.Backward]:!1,[V.Forward]:!1}};function wi(e){let{delta:t,disabled:n}=e;const r=gn(t);return Nt(i=>{if(n||!r||!i)return vi;const a={x:Math.sign(t.x-r.x),y:Math.sign(t.y-r.y)};return{x:{[V.Backward]:i.x[V.Backward]||a.x===-1,[V.Forward]:i.x[V.Forward]||a.x===1},y:{[V.Backward]:i.y[V.Backward]||a.y===-1,[V.Forward]:i.y[V.Forward]||a.y===1}}},[n,t,r])}function Si(e,t){const n=t!=null?e.get(t):void 0,r=n?n.node.current:null;return Nt(i=>{var a;return t==null?null:(a=r??i)!=null?a:null},[r,t])}function ki(e,t){return g.useMemo(()=>e.reduce((n,r)=>{const{sensor:i}=r,a=i.activators.map(s=>({eventName:s.eventName,handler:t(s.handler,r)}));return[...n,...a]},[]),[e,t])}var jt;(function(e){e[e.Always=0]="Always",e[e.BeforeDragging=1]="BeforeDragging",e[e.WhileDragging=2]="WhileDragging"})(jt||(jt={}));var fn;(function(e){e.Optimized="optimized"})(fn||(fn={}));const Vn=new Map;function Ci(e,t){let{dragging:n,dependencies:r,config:i}=t;const[a,s]=g.useState(null),{frequency:d,measure:l,strategy:c}=i,m=g.useRef(e),p=S(),f=kt(p),b=g.useCallback(function(w){w===void 0&&(w=[]),!f.current&&s(C=>C===null?w:C.concat(w.filter(N=>!C.includes(N))))},[f]),j=g.useRef(null),x=Nt(w=>{if(p&&!n)return Vn;if(!w||w===Vn||m.current!==e||a!=null){const C=new Map;for(let N of e){if(!N)continue;if(a&&a.length>0&&!a.includes(N.id)&&N.rect.current){C.set(N.id,N.rect.current);continue}const k=N.node.current,z=k?new Tn(l(k),k):null;N.rect.current=z,z&&C.set(N.id,z)}return C}return w},[e,a,n,p,l]);return g.useEffect(()=>{m.current=e},[e]),g.useEffect(()=>{p||b()},[n,p]),g.useEffect(()=>{a&&a.length>0&&s(null)},[JSON.stringify(a)]),g.useEffect(()=>{p||typeof d!="number"||j.current!==null||(j.current=setTimeout(()=>{b(),j.current=null},d))},[d,p,b,...r]),{droppableRects:x,measureDroppableContainers:b,measuringScheduled:a!=null};function S(){switch(c){case jt.Always:return!1;case jt.BeforeDragging:return n;default:return!n}}}function To(e,t){return Nt(n=>e?n||(typeof t=="function"?t(e):e):null,[t,e])}function Ti(e,t){return To(e,t)}function ji(e){let{callback:t,disabled:n}=e;const r=kn(t),i=g.useMemo(()=>{if(n||typeof window>"u"||typeof window.MutationObserver>"u")return;const{MutationObserver:a}=window;return new a(r)},[r,n]);return g.useEffect(()=>()=>i?.disconnect(),[i]),i}function Xt(e){let{callback:t,disabled:n}=e;const r=kn(t),i=g.useMemo(()=>{if(n||typeof window>"u"||typeof window.ResizeObserver>"u")return;const{ResizeObserver:a}=window;return new a(r)},[n]);return g.useEffect(()=>()=>i?.disconnect(),[i]),i}function Bi(e){return new Tn(nt(e),e)}function Xn(e,t,n){t===void 0&&(t=Bi);const[r,i]=g.useState(null);function a(){i(l=>{if(!e)return null;if(e.isConnected===!1){var c;return(c=l??n)!=null?c:null}const m=t(e);return JSON.stringify(l)===JSON.stringify(m)?l:m})}const s=ji({callback(l){if(e)for(const c of l){const{type:m,target:p}=c;if(m==="childList"&&p instanceof HTMLElement&&p.contains(e)){a();break}}}}),d=Xt({callback:a});return Se(()=>{a(),e?(d?.observe(e),s?.observe(document.body,{childList:!0,subtree:!0})):(d?.disconnect(),s?.disconnect())},[e]),r}function Ri(e){const t=To(e);return bo(e,t)}const Kn=[];function Ai(e){const t=g.useRef(e),n=Nt(r=>e?r&&r!==Kn&&e&&t.current&&e.parentNode===t.current.parentNode?r:Vt(e):Kn,[e]);return g.useEffect(()=>{t.current=e},[e]),n}function Ni(e){const[t,n]=g.useState(null),r=g.useRef(e),i=g.useCallback(a=>{const s=sn(a.target);s&&n(d=>d?(d.set(s,mn(s)),new Map(d)):null)},[]);return g.useEffect(()=>{const a=r.current;if(e!==a){s(a);const d=e.map(l=>{const c=sn(l);return c?(c.addEventListener("scroll",i,{passive:!0}),[c,mn(c)]):null}).filter(l=>l!=null);n(d.length?new Map(d):null),r.current=e}return()=>{s(e),s(a)};function s(d){d.forEach(l=>{const c=sn(l);c?.removeEventListener("scroll",i)})}},[i,e]),g.useMemo(()=>e.length?t?Array.from(t.values()).reduce((a,s)=>Ke(a,s),fe):ko(e):fe,[e,t])}function Qn(e,t){t===void 0&&(t=[]);const n=g.useRef(null);return g.useEffect(()=>{n.current=null},t),g.useEffect(()=>{const r=e!==fe;r&&!n.current&&(n.current=e),!r&&n.current&&(n.current=null)},[e]),n.current?Ct(e,n.current):fe}function Ei(e){g.useEffect(()=>{if(!Jt)return;const t=e.map(n=>{let{sensor:r}=n;return r.setup==null?void 0:r.setup()});return()=>{for(const n of t)n?.()}},e.map(t=>{let{sensor:n}=t;return n}))}function zi(e,t){return g.useMemo(()=>e.reduce((n,r)=>{let{eventName:i,handler:a}=r;return n[i]=s=>{a(s,t)},n},{}),[e,t])}function jo(e){return g.useMemo(()=>e?ni(e):null,[e])}const Zn=[];function Pi(e,t){t===void 0&&(t=nt);const[n]=e,r=jo(n?oe(n):null),[i,a]=g.useState(Zn);function s(){a(()=>e.length?e.map(l=>wo(l)?r:new Tn(t(l),l)):Zn)}const d=Xt({callback:s});return Se(()=>{d?.disconnect(),s(),e.forEach(l=>d?.observe(l))},[e]),i}function Di(e){if(!e)return null;if(e.children.length>1)return e;const t=e.children[0];return At(t)?t:e}function Fi(e){let{measure:t}=e;const[n,r]=g.useState(null),i=g.useCallback(c=>{for(const{target:m}of c)if(At(m)){r(p=>{const f=t(m);return p?{...p,width:f.width,height:f.height}:f});break}},[t]),a=Xt({callback:i}),s=g.useCallback(c=>{const m=Di(c);a?.disconnect(),m&&a?.observe(m),r(m?t(m):null)},[t,a]),[d,l]=Ht(s);return g.useMemo(()=>({nodeRef:d,rect:n,setRef:l}),[n,d,l])}const Li=[{sensor:Rn,options:{}},{sensor:jn,options:{}}],Mi={current:{}},_t={draggable:{measure:Gn},droppable:{measure:Gn,strategy:jt.WhileDragging,frequency:fn.Optimized},dragOverlay:{measure:nt}};class St extends Map{get(t){var n;return t!=null&&(n=super.get(t))!=null?n:void 0}toArray(){return Array.from(this.values())}getEnabled(){return this.toArray().filter(t=>{let{disabled:n}=t;return!n})}getNodeFor(t){var n,r;return(n=(r=this.get(t))==null?void 0:r.node.current)!=null?n:void 0}}const Ii={activatorEvent:null,active:null,activeNode:null,activeNodeRect:null,collisions:null,containerNodeRect:null,draggableNodes:new Map,droppableRects:new Map,droppableContainers:new St,over:null,dragOverlay:{nodeRef:{current:null},rect:null,setRef:Ut},scrollableAncestors:[],scrollableAncestorRects:[],measuringConfiguration:_t,measureDroppableContainers:Ut,windowRect:null,measuringScheduled:!1},$i={activatorEvent:null,activators:[],active:null,activeNodeRect:null,ariaDescribedById:{draggable:""},dispatch:Ut,draggableNodes:new Map,over:null,measureDroppableContainers:Ut},Kt=g.createContext($i),Bo=g.createContext(Ii);function Oi(){return{draggable:{active:null,initialCoordinates:{x:0,y:0},nodes:new Map,translate:{x:0,y:0}},droppable:{containers:new St}}}function _i(e,t){switch(t.type){case J.DragStart:return{...e,draggable:{...e.draggable,initialCoordinates:t.initialCoordinates,active:t.active}};case J.DragMove:return e.draggable.active==null?e:{...e,draggable:{...e.draggable,translate:{x:t.coordinates.x-e.draggable.initialCoordinates.x,y:t.coordinates.y-e.draggable.initialCoordinates.y}}};case J.DragEnd:case J.DragCancel:return{...e,draggable:{...e.draggable,active:null,initialCoordinates:{x:0,y:0},translate:{x:0,y:0}}};case J.RegisterDroppable:{const{element:n}=t,{id:r}=n,i=new St(e.droppable.containers);return i.set(r,n),{...e,droppable:{...e.droppable,containers:i}}}case J.SetDroppableDisabled:{const{id:n,key:r,disabled:i}=t,a=e.droppable.containers.get(n);if(!a||r!==a.key)return e;const s=new St(e.droppable.containers);return s.set(n,{...a,disabled:i}),{...e,droppable:{...e.droppable,containers:s}}}case J.UnregisterDroppable:{const{id:n,key:r}=t,i=e.droppable.containers.get(n);if(!i||r!==i.key)return e;const a=new St(e.droppable.containers);return a.delete(n),{...e,droppable:{...e.droppable,containers:a}}}default:return e}}function Wi(e){let{disabled:t}=e;const{active:n,activatorEvent:r,draggableNodes:i}=g.useContext(Kt),a=gn(r),s=gn(n?.id);return g.useEffect(()=>{if(!t&&!r&&a&&s!=null){if(!Cn(a)||document.activeElement===a.target)return;const d=i.get(s);if(!d)return;const{activatorNode:l,node:c}=d;if(!l.current&&!c.current)return;requestAnimationFrame(()=>{for(const m of[l.current,c.current]){if(!m)continue;const p=Dr(m);if(p){p.focus();break}}})}},[r,t,i,s,a]),null}function Hi(e,t){let{transform:n,...r}=t;return e!=null&&e.length?e.reduce((i,a)=>a({transform:i,...r}),n):n}function Ui(e){return g.useMemo(()=>({draggable:{..._t.draggable,...e?.draggable},droppable:{..._t.droppable,...e?.droppable},dragOverlay:{..._t.dragOverlay,...e?.dragOverlay}}),[e?.draggable,e?.droppable,e?.dragOverlay])}function Gi(e){let{activeNode:t,measure:n,initialRect:r,config:i=!0}=e;const a=g.useRef(!1),{x:s,y:d}=typeof i=="boolean"?{x:i,y:i}:i;Se(()=>{if(!s&&!d||!t){a.current=!1;return}if(a.current||!r)return;const c=t?.node.current;if(!c||c.isConnected===!1)return;const m=n(c),p=bo(m,r);if(s||(p.x=0),d||(p.y=0),a.current=!0,Math.abs(p.x)>0||Math.abs(p.y)>0){const f=xo(c);f&&f.scrollBy({top:p.y,left:p.x})}},[t,s,d,r,n])}const Ro=g.createContext({...fe,scaleX:1,scaleY:1});var $e;(function(e){e[e.Uninitialized=0]="Uninitialized",e[e.Initializing=1]="Initializing",e[e.Initialized=2]="Initialized"})($e||($e={}));const Yi=g.memo(function(t){var n,r,i,a;let{id:s,accessibility:d,autoScroll:l=!0,children:c,sensors:m=Li,collisionDetection:p=Vr,measuring:f,modifiers:b,...j}=t;const x=g.useReducer(_i,void 0,Oi),[S,w]=x,[C,N]=Or(),[k,z]=g.useState($e.Uninitialized),D=k===$e.Initialized,{draggable:{active:E,nodes:B,translate:P},droppable:{containers:W}}=S,$=E!=null?B.get(E):null,K=g.useRef({initial:null,translated:null}),Q=g.useMemo(()=>{var ee;return E!=null?{id:E,data:(ee=$?.data)!=null?ee:Mi,rect:K}:null},[E,$]),be=g.useRef(null),[lt,Pt]=g.useState(null),[re,Dt]=g.useState(null),Ce=kt(j,Object.values(j)),dt=Et("DndDescribedBy",s),Ft=g.useMemo(()=>W.getEnabled(),[W]),te=Ui(f),{droppableRects:Te,measureDroppableContainers:Oe,measuringScheduled:ct}=Ci(Ft,{dragging:D,dependencies:[P.x,P.y],config:te.droppable}),ue=Si(B,E),Lt=g.useMemo(()=>re?pn(re):null,[re]),ze=Xo(),je=Ti(ue,te.draggable.measure);Gi({activeNode:E!=null?B.get(E):null,config:ze.layoutShiftCompensation,initialRect:je,measure:te.draggable.measure});const _=Xn(ue,te.draggable.measure,je),ut=Xn(ue?ue.parentElement:null),xe=g.useRef({activatorEvent:null,active:null,activeNode:ue,collisionRect:null,collisions:null,droppableRects:Te,draggableNodes:B,draggingNode:null,draggingNodeRect:null,droppableContainers:W,over:null,scrollableAncestors:[],scrollAdjustedTranslate:null}),We=W.getNodeFor((n=xe.current.over)==null?void 0:n.id),Be=Fi({measure:te.dragOverlay.measure}),He=(r=Be.nodeRef.current)!=null?r:ue,Ue=D?(i=Be.rect)!=null?i:_:null,Nn=!!(Be.nodeRef.current&&Be.rect),En=Ri(Nn?null:_),Zt=jo(He?oe(He):null),Pe=Ai(D?We??ue:null),Mt=Pi(Pe),It=Hi(b,{transform:{x:P.x-En.x,y:P.y-En.y,scaleX:1,scaleY:1},activatorEvent:re,active:Q,activeNodeRect:_,containerNodeRect:ut,draggingNodeRect:Ue,over:xe.current.over,overlayNodeRect:Be.rect,scrollableAncestors:Pe,scrollableAncestorRects:Mt,windowRect:Zt}),zn=Lt?Ke(Lt,P):null,Pn=Ni(Pe),Ho=Qn(Pn),Uo=Qn(Pn,[_]),Ge=Ke(It,Ho),Ye=Ue?Qr(Ue,It):null,gt=Q&&Ye?p({active:Q,collisionRect:Ye,droppableRects:Te,droppableContainers:Ft,pointerCoordinates:zn}):null,Dn=fo(gt,"id"),[De,Fn]=g.useState(null),Go=Nn?It:Ke(It,Uo),Yo=Xr(Go,(a=De?.rect)!=null?a:null,_),en=g.useRef(null),Ln=g.useCallback((ee,ie)=>{let{sensor:ae,options:Fe}=ie;if(be.current==null)return;const ge=B.get(be.current);if(!ge)return;const se=ee.nativeEvent,ye=new ae({active:be.current,activeNode:ge,event:se,options:Fe,context:xe,onAbort(Z){if(!B.get(Z))return;const{onDragAbort:ve}=Ce.current,Re={id:Z};ve?.(Re),C({type:"onDragAbort",event:Re})},onPending(Z,Le,ve,Re){if(!B.get(Z))return;const{onDragPending:mt}=Ce.current,Me={id:Z,constraint:Le,initialCoordinates:ve,offset:Re};mt?.(Me),C({type:"onDragPending",event:Me})},onStart(Z){const Le=be.current;if(Le==null)return;const ve=B.get(Le);if(!ve)return;const{onDragStart:Re}=Ce.current,pt={activatorEvent:se,active:{id:Le,data:ve.data,rect:K}};xt.unstable_batchedUpdates(()=>{Re?.(pt),z($e.Initializing),w({type:J.DragStart,initialCoordinates:Z,active:Le}),C({type:"onDragStart",event:pt}),Pt(en.current),Dt(se)})},onMove(Z){w({type:J.DragMove,coordinates:Z})},onEnd:qe(J.DragEnd),onCancel:qe(J.DragCancel)});en.current=ye;function qe(Z){return async function(){const{active:ve,collisions:Re,over:pt,scrollAdjustedTranslate:mt}=xe.current;let Me=null;if(ve&&mt){const{cancelDrop:ht}=Ce.current;Me={activatorEvent:se,active:ve,collisions:Re,delta:mt,over:pt},Z===J.DragEnd&&typeof ht=="function"&&await Promise.resolve(ht(Me))&&(Z=J.DragCancel)}be.current=null,xt.unstable_batchedUpdates(()=>{w({type:Z}),z($e.Uninitialized),Fn(null),Pt(null),Dt(null),en.current=null;const ht=Z===J.DragEnd?"onDragEnd":"onDragCancel";if(Me){const tn=Ce.current[ht];tn?.(Me),C({type:ht,event:Me})}})}}},[B]),qo=g.useCallback((ee,ie)=>(ae,Fe)=>{const ge=ae.nativeEvent,se=B.get(Fe);if(be.current!==null||!se||ge.dndKit||ge.defaultPrevented)return;const ye={active:se};ee(ae,ie.options,ye)===!0&&(ge.dndKit={capturedBy:ie.sensor},be.current=Fe,Ln(ae,ie))},[B,Ln]),Mn=ki(m,qo);Ei(m),Se(()=>{_&&k===$e.Initializing&&z($e.Initialized)},[_,k]),g.useEffect(()=>{const{onDragMove:ee}=Ce.current,{active:ie,activatorEvent:ae,collisions:Fe,over:ge}=xe.current;if(!ie||!ae)return;const se={active:ie,activatorEvent:ae,collisions:Fe,delta:{x:Ge.x,y:Ge.y},over:ge};xt.unstable_batchedUpdates(()=>{ee?.(se),C({type:"onDragMove",event:se})})},[Ge.x,Ge.y]),g.useEffect(()=>{const{active:ee,activatorEvent:ie,collisions:ae,droppableContainers:Fe,scrollAdjustedTranslate:ge}=xe.current;if(!ee||be.current==null||!ie||!ge)return;const{onDragOver:se}=Ce.current,ye=Fe.get(Dn),qe=ye&&ye.rect.current?{id:ye.id,rect:ye.rect.current,data:ye.data,disabled:ye.disabled}:null,Z={active:ee,activatorEvent:ie,collisions:ae,delta:{x:ge.x,y:ge.y},over:qe};xt.unstable_batchedUpdates(()=>{Fn(qe),se?.(Z),C({type:"onDragOver",event:Z})})},[Dn]),Se(()=>{xe.current={activatorEvent:re,active:Q,activeNode:ue,collisionRect:Ye,collisions:gt,droppableRects:Te,draggableNodes:B,draggingNode:He,draggingNodeRect:Ue,droppableContainers:W,over:De,scrollableAncestors:Pe,scrollAdjustedTranslate:Ge},K.current={initial:Ue,translated:Ye}},[Q,ue,gt,Ye,B,He,Ue,Te,W,De,Pe,Ge]),yi({...ze,delta:P,draggingRect:Ye,pointerCoordinates:zn,scrollableAncestors:Pe,scrollableAncestorRects:Mt});const Jo=g.useMemo(()=>({active:Q,activeNode:ue,activeNodeRect:_,activatorEvent:re,collisions:gt,containerNodeRect:ut,dragOverlay:Be,draggableNodes:B,droppableContainers:W,droppableRects:Te,over:De,measureDroppableContainers:Oe,scrollableAncestors:Pe,scrollableAncestorRects:Mt,measuringConfiguration:te,measuringScheduled:ct,windowRect:Zt}),[Q,ue,_,re,gt,ut,Be,B,W,Te,De,Oe,Pe,Mt,te,ct,Zt]),Vo=g.useMemo(()=>({activatorEvent:re,activators:Mn,active:Q,activeNodeRect:_,ariaDescribedById:{draggable:dt},dispatch:w,draggableNodes:B,over:De,measureDroppableContainers:Oe}),[re,Mn,Q,_,w,dt,B,De,Oe]);return g.createElement(po.Provider,{value:N},g.createElement(Kt.Provider,{value:Vo},g.createElement(Bo.Provider,{value:Jo},g.createElement(Ro.Provider,{value:Yo},c)),g.createElement(Wi,{disabled:d?.restoreFocus===!1})),g.createElement(Hr,{...d,hiddenTextDescribedById:dt}));function Xo(){const ee=lt?.autoScrollEnabled===!1,ie=typeof l=="object"?l.enabled===!1:l===!1,ae=D&&!ee&&!ie;return typeof l=="object"?{...l,enabled:ae}:{enabled:ae}}}),qi=g.createContext(null),eo="button",Ji="Draggable";function Vi(e){let{id:t,data:n,disabled:r=!1,attributes:i}=e;const a=Et(Ji),{activators:s,activatorEvent:d,active:l,activeNodeRect:c,ariaDescribedById:m,draggableNodes:p,over:f}=g.useContext(Kt),{role:b=eo,roleDescription:j="draggable",tabIndex:x=0}=i??{},S=l?.id===t,w=g.useContext(S?Ro:qi),[C,N]=Ht(),[k,z]=Ht(),D=zi(s,t),E=kt(n);Se(()=>(p.set(t,{id:t,key:a,node:C,activatorNode:k,data:E}),()=>{const P=p.get(t);P&&P.key===a&&p.delete(t)}),[p,t]);const B=g.useMemo(()=>({role:b,tabIndex:x,"aria-disabled":r,"aria-pressed":S&&b===eo?!0:void 0,"aria-roledescription":j,"aria-describedby":m.draggable}),[r,b,x,S,j,m.draggable]);return{active:l,activatorEvent:d,activeNodeRect:c,attributes:B,isDragging:S,listeners:r?void 0:D,node:C,over:f,setNodeRef:N,setActivatorNodeRef:z,transform:w}}function Xi(){return g.useContext(Bo)}const Ki="Droppable",Qi={timeout:25};function Zi(e){let{data:t,disabled:n=!1,id:r,resizeObserverConfig:i}=e;const a=Et(Ki),{active:s,dispatch:d,over:l,measureDroppableContainers:c}=g.useContext(Kt),m=g.useRef({disabled:n}),p=g.useRef(!1),f=g.useRef(null),b=g.useRef(null),{disabled:j,updateMeasurementsFor:x,timeout:S}={...Qi,...i},w=kt(x??r),C=g.useCallback(()=>{if(!p.current){p.current=!0;return}b.current!=null&&clearTimeout(b.current),b.current=setTimeout(()=>{c(Array.isArray(w.current)?w.current:[w.current]),b.current=null},S)},[S]),N=Xt({callback:C,disabled:j||!s}),k=g.useCallback((B,P)=>{N&&(P&&(N.unobserve(P),p.current=!1),B&&N.observe(B))},[N]),[z,D]=Ht(k),E=kt(t);return g.useEffect(()=>{!N||!z.current||(N.disconnect(),p.current=!1,N.observe(z.current))},[z,N]),g.useEffect(()=>(d({type:J.RegisterDroppable,element:{id:r,key:a,disabled:n,node:z,rect:f,data:E}}),()=>d({type:J.UnregisterDroppable,key:a,id:r})),[r]),g.useEffect(()=>{n!==m.current.disabled&&(d({type:J.SetDroppableDisabled,id:r,key:a,disabled:n}),m.current.disabled=n)},[r,a,n,d]),{active:s,rect:f,isOver:l?.id===r,node:z,over:l,setNodeRef:D}}function Ao(e,t,n){const r=e.slice();return r.splice(n<0?r.length+n:n,0,r.splice(t,1)[0]),r}function ea(e,t){return e.reduce((n,r,i)=>{const a=t.get(r);return a&&(n[i]=a),n},Array(e.length))}function $t(e){return e!==null&&e>=0}function ta(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function na(e){return typeof e=="boolean"?{draggable:e,droppable:e}:e}const No=e=>{let{rects:t,activeIndex:n,overIndex:r,index:i}=e;const a=Ao(t,r,n),s=t[i],d=a[i];return!d||!s?null:{x:d.left-s.left,y:d.top-s.top,scaleX:d.width/s.width,scaleY:d.height/s.height}},Ot={scaleX:1,scaleY:1},oa=e=>{var t;let{activeIndex:n,activeNodeRect:r,index:i,rects:a,overIndex:s}=e;const d=(t=a[n])!=null?t:r;if(!d)return null;if(i===n){const c=a[s];return c?{x:0,y:n<s?c.top+c.height-(d.top+d.height):c.top-d.top,...Ot}:null}const l=ra(a,i,n);return i>n&&i<=s?{x:0,y:-d.height-l,...Ot}:i<n&&i>=s?{x:0,y:d.height+l,...Ot}:{x:0,y:0,...Ot}};function ra(e,t,n){const r=e[t],i=e[t-1],a=e[t+1];return r?n<t?i?r.top-(i.top+i.height):a?a.top-(r.top+r.height):0:a?a.top-(r.top+r.height):i?r.top-(i.top+i.height):0:0}const Eo="Sortable",zo=g.createContext({activeIndex:-1,containerId:Eo,disableTransforms:!1,items:[],overIndex:-1,useDragOverlay:!1,sortedRects:[],strategy:No,disabled:{draggable:!1,droppable:!1}});function ia(e){let{children:t,id:n,items:r,strategy:i=No,disabled:a=!1}=e;const{active:s,dragOverlay:d,droppableRects:l,over:c,measureDroppableContainers:m}=Xi(),p=Et(Eo,n),f=d.rect!==null,b=g.useMemo(()=>r.map(D=>typeof D=="object"&&"id"in D?D.id:D),[r]),j=s!=null,x=s?b.indexOf(s.id):-1,S=c?b.indexOf(c.id):-1,w=g.useRef(b),C=!ta(b,w.current),N=S!==-1&&x===-1||C,k=na(a);Se(()=>{C&&j&&m(b)},[C,b,j,m]),g.useEffect(()=>{w.current=b},[b]);const z=g.useMemo(()=>({activeIndex:x,containerId:p,disabled:k,disableTransforms:N,items:b,overIndex:S,useDragOverlay:f,sortedRects:ea(b,l),strategy:i}),[x,p,k.draggable,k.droppable,N,b,S,l,f,i]);return g.createElement(zo.Provider,{value:z},t)}const aa=e=>{let{id:t,items:n,activeIndex:r,overIndex:i}=e;return Ao(n,r,i).indexOf(t)},sa=e=>{let{containerId:t,isSorting:n,wasDragging:r,index:i,items:a,newIndex:s,previousItems:d,previousContainerId:l,transition:c}=e;return!c||!r||d!==a&&i===s?!1:n?!0:s!==i&&t===l},la={duration:200,easing:"ease"},Po="transform",da=Tt.Transition.toString({property:Po,duration:0,easing:"linear"}),ca={roleDescription:"sortable"};function ua(e){let{disabled:t,index:n,node:r,rect:i}=e;const[a,s]=g.useState(null),d=g.useRef(n);return Se(()=>{if(!t&&n!==d.current&&r.current){const l=i.current;if(l){const c=nt(r.current,{ignoreTransform:!0}),m={x:l.left-c.left,y:l.top-c.top,scaleX:l.width/c.width,scaleY:l.height/c.height};(m.x||m.y)&&s(m)}}n!==d.current&&(d.current=n)},[t,n,r,i]),g.useEffect(()=>{a&&s(null)},[a]),a}function ga(e){let{animateLayoutChanges:t=sa,attributes:n,disabled:r,data:i,getNewIndex:a=aa,id:s,strategy:d,resizeObserverConfig:l,transition:c=la}=e;const{items:m,containerId:p,activeIndex:f,disabled:b,disableTransforms:j,sortedRects:x,overIndex:S,useDragOverlay:w,strategy:C}=g.useContext(zo),N=pa(r,b),k=m.indexOf(s),z=g.useMemo(()=>({sortable:{containerId:p,index:k,items:m},...i}),[p,i,k,m]),D=g.useMemo(()=>m.slice(m.indexOf(s)),[m,s]),{rect:E,node:B,isOver:P,setNodeRef:W}=Zi({id:s,data:z,disabled:N.droppable,resizeObserverConfig:{updateMeasurementsFor:D,...l}}),{active:$,activatorEvent:K,activeNodeRect:Q,attributes:be,setNodeRef:lt,listeners:Pt,isDragging:re,over:Dt,setActivatorNodeRef:Ce,transform:dt}=Vi({id:s,data:z,attributes:{...ca,...n},disabled:N.draggable}),Ft=Nr(W,lt),te=!!$,Te=te&&!j&&$t(f)&&$t(S),Oe=!w&&re,ct=Oe&&Te?dt:null,Lt=Te?ct??(d??C)({rects:x,activeNodeRect:Q,activeIndex:f,overIndex:S,index:k}):null,ze=$t(f)&&$t(S)?a({id:s,items:m,activeIndex:f,overIndex:S}):k,je=$?.id,_=g.useRef({activeId:je,items:m,newIndex:ze,containerId:p}),ut=m!==_.current.items,xe=t({active:$,containerId:p,isDragging:re,isSorting:te,id:s,index:k,items:m,newIndex:_.current.newIndex,previousItems:_.current.items,previousContainerId:_.current.containerId,transition:c,wasDragging:_.current.activeId!=null}),We=ua({disabled:!xe,index:k,node:B,rect:E});return g.useEffect(()=>{te&&_.current.newIndex!==ze&&(_.current.newIndex=ze),p!==_.current.containerId&&(_.current.containerId=p),m!==_.current.items&&(_.current.items=m)},[te,ze,p,m]),g.useEffect(()=>{if(je===_.current.activeId)return;if(je&&!_.current.activeId){_.current.activeId=je;return}const He=setTimeout(()=>{_.current.activeId=je},50);return()=>clearTimeout(He)},[je]),{active:$,activeIndex:f,attributes:be,data:z,rect:E,index:k,newIndex:ze,items:m,isOver:P,isSorting:te,isDragging:re,listeners:Pt,node:B,overIndex:S,over:Dt,setNodeRef:Ft,setActivatorNodeRef:Ce,setDroppableNodeRef:W,setDraggableNodeRef:lt,transform:We??Lt,transition:Be()};function Be(){if(We||ut&&_.current.newIndex===k)return da;if(!(Oe&&!Cn(K)||!c)&&(te||xe))return Tt.Transition.toString({...c,property:Po})}}function pa(e,t){var n,r;return typeof e=="boolean"?{draggable:e,droppable:!1}:{draggable:(n=e?.draggable)!=null?n:t.draggable,droppable:(r=e?.droppable)!=null?r:t.droppable}}function Yt(e){if(!e)return!1;const t=e.data.current;return!!(t&&"sortable"in t&&typeof t.sortable=="object"&&"containerId"in t.sortable&&"items"in t.sortable&&"index"in t.sortable)}const ma=[L.Down,L.Right,L.Up,L.Left],ha=(e,t)=>{let{context:{active:n,collisionRect:r,droppableRects:i,droppableContainers:a,over:s,scrollableAncestors:d}}=t;if(ma.includes(e.code)){if(e.preventDefault(),!n||!r)return;const l=[];a.getEnabled().forEach(p=>{if(!p||p!=null&&p.disabled)return;const f=i.get(p.id);if(f)switch(e.code){case L.Down:r.top<f.top&&l.push(p);break;case L.Up:r.top>f.top&&l.push(p);break;case L.Left:r.left>f.left&&l.push(p);break;case L.Right:r.left<f.left&&l.push(p);break}});const c=qr({collisionRect:r,droppableRects:i,droppableContainers:l});let m=fo(c,"id");if(m===s?.id&&c.length>1&&(m=c[1].id),m!=null){const p=a.get(n.id),f=a.get(m),b=f?i.get(f.id):null,j=f?.node.current;if(j&&b&&p&&f){const S=Vt(j).some((D,E)=>d[E]!==D),w=Do(p,f),C=fa(p,f),N=S||!w?{x:0,y:0}:{x:C?r.width-b.width:0,y:C?r.height-b.height:0},k={x:b.left,y:b.top};return N.x&&N.y?k:Ct(k,N)}}}};function Do(e,t){return!Yt(e)||!Yt(t)?!1:e.data.current.sortable.containerId===t.data.current.sortable.containerId}function fa(e,t){return!Yt(e)||!Yt(t)||!Do(e,t)?!1:e.data.current.sortable.index<t.data.current.sortable.index}const ba=375;function ot(e,t){const n=e??{};if(t!=="mobile")return n;const r=n.mobile??{};return{...n,...r}}function xa(){const{doc:e,selection:t,setSelection:n,reorderModules:r,deleteModule:i,duplicateModule:a,deleteElement:s,moveElement:d,viewMode:l}=O(),c=Ur(Wn(Rn,{activationConstraint:{distance:5}}),Wn(jn,{coordinateGetter:ha})),m=x=>{const{active:S,over:w}=x;if(!w||S.id===w.id)return;const C=e.modules.findIndex(k=>k.id===S.id),N=e.modules.findIndex(k=>k.id===w.id);C===-1||N===-1||r(C,N)};g.useEffect(()=>{const x=S=>{if(S.key!=="Delete"&&S.key!=="Backspace")return;const w=S.target;w.tagName==="INPUT"||w.tagName==="TEXTAREA"||w.isContentEditable||(t?.kind==="module"?i(t.moduleId):t?.kind==="element"&&s(t.moduleId,t.elementId))};return window.addEventListener("keydown",x),()=>window.removeEventListener("keydown",x)},[t,i,s]);const p=_e(e.settings.backgroundColor,e.theme),f=_e(e.settings.contentBackgroundColor,e.theme),b=e.modules.map(x=>x.id),j=l==="mobile"?ba:e.settings.width;return o.jsx("div",{className:"flex-1 overflow-y-auto",style:{background:p},onClick:()=>n({kind:"email"}),children:o.jsx("div",{className:"py-8 flex justify-center",children:o.jsxs("div",{className:`shadow-lg transition-all duration-200 ${l==="mobile"?"rounded-[28px] border-[10px] border-gray-800":""}`,style:{width:j,background:f,minHeight:300},onClick:x=>x.stopPropagation(),children:[e.modules.length===0&&o.jsx("div",{className:"p-12 text-center text-gray-400 text-sm",children:"Add modules from the left sidebar to start building your email."}),o.jsx(Yi,{sensors:c,collisionDetection:Yr,onDragEnd:m,children:o.jsx(ia,{items:b,strategy:oa,children:e.modules.map((x,S)=>o.jsx(ya,{mod:x,index:S,viewMode:l,selected:t?.kind==="module"&&t.moduleId===x.id,selectionEl:t?.kind==="element"&&t.moduleId===x.id?t.elementId:null,theme:e.theme,onSelectModule:()=>n({kind:"module",moduleId:x.id}),onSelectElement:w=>n({kind:"element",moduleId:x.id,elementId:w}),onDuplicate:()=>a(x.id),onDelete:()=>i(x.id)},x.id))})})]})})})}function ya(e){const{attributes:t,listeners:n,setNodeRef:r,transform:i,transition:a,isDragging:s}=ga({id:e.mod.id}),d={transform:Tt.Transform.toString(i),transition:a,opacity:s?.5:1,position:"relative"};return o.jsx("div",{ref:r,style:d,children:o.jsx(va,{mod:e.mod,viewMode:e.viewMode,selected:e.selected,selectionEl:e.selectionEl,theme:e.theme,onSelectModule:e.onSelectModule,onSelectElement:e.onSelectElement,onDuplicate:e.onDuplicate,onDelete:e.onDelete,dragHandle:o.jsx("button",{...t,...n,className:"bg-blue-600 text-white p-1 rounded cursor-grab active:cursor-grabbing",title:"Drag to reorder",onClick:l=>l.stopPropagation(),children:o.jsx(R.GripVertical,{size:14})})})})}function va({mod:e,viewMode:t,selected:n,selectionEl:r,theme:i,onSelectModule:a,onSelectElement:s,onDuplicate:d,onDelete:l,dragHandle:c}){const m=e.style??{};if(m.hideOn===t)return null;const f=ot(m,t),b=ce(f,i),[j,x]=g.useState(!1),S={backgroundColor:b.backgroundColor,paddingTop:b.paddingTop??0,paddingBottom:b.paddingBottom??0,paddingLeft:b.paddingLeft??0,paddingRight:b.paddingRight??0,borderRadius:b.borderRadius,position:"relative",outline:n?"2px solid #2563eb":j?"1px dashed #93c5fd":"1px dashed transparent",outlineOffset:-2,cursor:"pointer"};return o.jsxs("div",{style:S,onClick:w=>{w.stopPropagation(),a()},onMouseEnter:()=>x(!0),onMouseLeave:()=>x(!1),children:[!n&&j&&o.jsxs("div",{className:"absolute top-0 right-0 z-10 bg-blue-600 text-white text-[10px] px-1.5 py-0.5 rounded-bl pointer-events-none",children:["Click to select: ",e.name]}),n&&o.jsxs("div",{className:"absolute -top-3 left-2 z-10 flex gap-1",children:[c,o.jsx("button",{onClick:w=>{w.stopPropagation(),d()},className:"bg-blue-600 text-white p-1 rounded",title:"Duplicate",children:o.jsx(R.Copy,{size:14})}),o.jsx("button",{onClick:w=>{w.stopPropagation(),l()},className:"bg-red-600 text-white p-1 rounded",title:"Delete",children:o.jsx(R.Trash2,{size:14})}),o.jsx("span",{className:"bg-blue-600 text-white text-[10px] px-1.5 py-0.5 rounded",children:e.name})]}),e.children.map((w,C)=>o.jsx(wa,{el:w,index:C,totalElements:e.children.length,viewMode:t,theme:i,moduleId:e.id,moduleSelected:n,selected:r===w.id,onSelect:()=>s(w.id),onSelectModule:a},w.id))]})}function wa({el:e,index:t,totalElements:n,viewMode:r,theme:i,moduleId:a,moduleSelected:s,selected:d,onSelect:l,onSelectModule:c}){const m=O(C=>C.moveElement),p=O(C=>C.deleteElement);if(e.style?.hideOn===r)return null;const j={outline:d?"2px solid #f59e0b":"1px dashed transparent",outlineOffset:-2,position:"relative"},x=C=>{if(C.stopPropagation(),!s&&!d){c();return}l()},S=d&&o.jsxs("div",{className:"absolute -top-3 right-2 z-20 flex gap-1",onClick:C=>C.stopPropagation(),children:[o.jsx("button",{onClick:()=>c(),className:"bg-blue-600 text-white p-1 rounded",title:"Select parent block",children:o.jsx(R.MousePointer2,{size:12})}),o.jsx("button",{disabled:t===0,onClick:()=>m(a,e.id,-1),className:"bg-amber-500 text-white p-1 rounded disabled:opacity-40",title:"Move up",children:o.jsx(R.ArrowUp,{size:12})}),o.jsx("button",{disabled:t===n-1,onClick:()=>m(a,e.id,1),className:"bg-amber-500 text-white p-1 rounded disabled:opacity-40",title:"Move down",children:o.jsx(R.ArrowDown,{size:12})}),o.jsx("button",{onClick:()=>p(a,e.id),className:"bg-red-600 text-white p-1 rounded",title:"Delete element",children:o.jsx(R.Trash2,{size:12})}),o.jsx("span",{className:"bg-amber-500 text-white text-[10px] px-1.5 py-0.5 rounded",children:e.type})]}),w=C=>o.jsxs("div",{style:j,onClick:x,children:[S,C]});switch(e.type){case"text":return w(o.jsx(Sa,{el:e,viewMode:r,theme:i,moduleId:a}));case"image":return w(o.jsx(ka,{el:e,viewMode:r,theme:i}));case"button":return w(o.jsx(Ca,{el:e,viewMode:r,theme:i}));case"spacer":return w(o.jsx(Ta,{el:e}));case"divider":return w(o.jsx(ja,{el:e,viewMode:r,theme:i}));case"productGrid":return w(o.jsx(Ba,{el:e,viewMode:r,theme:i}))}}function Sa({el:e,viewMode:t,theme:n,moduleId:r}){const i=O(l=>l.updateElement),a=ot(e.style,t),s=ce(a,n),d={fontFamily:s.fontFamily,fontSize:s.fontSize,lineHeight:s.lineHeight,letterSpacing:s.letterSpacing,fontWeight:s.fontWeight,color:s.color,textAlign:s.align,paddingTop:s.paddingTop??8,paddingBottom:s.paddingBottom??8,paddingLeft:s.paddingLeft??16,paddingRight:s.paddingRight??16,margin:0,minHeight:"1.5em"};return o.jsx("div",{style:d,contentEditable:!0,suppressContentEditableWarning:!0,onBlur:l=>{const c=l.currentTarget.innerHTML;c!==e.content&&i(r,e.id,{content:c})},dangerouslySetInnerHTML:{__html:e.content}})}function ka({el:e,viewMode:t,theme:n}){const r=ot(e.style,t),i=ce(r,n),a={textAlign:i.align??"center",paddingTop:i.paddingTop??0,paddingBottom:i.paddingBottom??0,paddingLeft:i.paddingLeft??0,paddingRight:i.paddingRight??0},s={display:"inline-block",maxWidth:"100%",width:i.width,height:i.height||"auto",borderRadius:i.borderRadius};return o.jsx("div",{style:a,children:o.jsx("img",{src:e.src,alt:e.alt??"",style:s})})}function Ca({el:e,viewMode:t,theme:n}){const r=ot(e.style,t),i=ce(r,n),a={textAlign:i.align??"center",paddingTop:i.paddingTop??12,paddingBottom:i.paddingBottom??12,paddingLeft:i.paddingLeft??16,paddingRight:i.paddingRight??16},s={display:"inline-block",backgroundColor:i.backgroundColor??"#3A7D52",color:i.color??"#fff",fontFamily:i.fontFamily,fontSize:i.fontSize??16,fontWeight:i.fontWeight??"bold",borderRadius:i.borderRadius??6,padding:"12px 24px",textDecoration:"none"};return o.jsx("div",{style:a,children:o.jsx("span",{style:s,children:e.label})})}function Ta({el:e}){return o.jsx("div",{style:{height:e.height,background:"rgba(0,0,0,0.02)"}})}function ja({el:e,viewMode:t,theme:n}){const r=ot(e.style,t),i=ce(r,n);return o.jsx("div",{style:{paddingTop:i.paddingTop??8,paddingBottom:i.paddingBottom??8},children:o.jsx("hr",{style:{border:0,borderTop:`${i.thickness??1}px solid ${i.color??"#E5E7EB"}`,margin:0}})})}function Ba({el:e,viewMode:t,theme:n}){const r=ot(e.style,t),i=ce(r,n),a=t==="mobile",s=e.columns,d=i.cardBackgroundColor??i.backgroundColor??"transparent",l=i.nameColor??"#111827",c=i.finalPriceColor??"#3A7D52",m=i.oldPriceColor??"#9CA3AF",p=i.buttonBackgroundColor??"#3A7D52",f=i.buttonColor??"#FFFFFF",b=i.borderRadius??0,j={paddingTop:i.paddingTop??16,paddingBottom:i.paddingBottom??16,paddingLeft:i.paddingLeft??16,paddingRight:i.paddingRight??16,display:"flex",flexWrap:"wrap",gap:8};return o.jsx("div",{style:j,children:e.products.map(x=>{const S={width:a?"100%":`calc(${100/s}% - 8px)`,background:d,borderRadius:b,overflow:"hidden",display:"flex",flexDirection:"column"};return o.jsxs("div",{style:S,children:[o.jsx("img",{src:x.image,alt:x.imageAlt??x.name,style:{display:"block",width:"100%",height:"auto",borderRadius:b}}),o.jsx("div",{style:{padding:"12px 12px 4px 12px",fontFamily:"Arial, Helvetica, sans-serif",fontSize:15,fontWeight:"bold",color:l,lineHeight:1.3},children:x.name}),o.jsxs("div",{style:{padding:"0 12px 8px 12px",fontFamily:"Arial, Helvetica, sans-serif"},children:[e.showOldPrice&&x.oldPrice&&o.jsx("span",{className:"old_price",style:{color:m,textDecoration:"line-through",fontSize:14,marginRight:8},children:x.oldPrice}),o.jsx("span",{className:"final_price",style:{color:c,fontWeight:"bold",fontSize:18},children:x.finalPrice})]}),e.showDescription&&x.description&&o.jsx("div",{style:{padding:"0 12px 8px 12px",fontFamily:"Arial, Helvetica, sans-serif",fontSize:13,color:"#6B7280",lineHeight:1.5},children:x.description}),e.showButton&&o.jsx("div",{style:{padding:"4px 12px 12px 12px",textAlign:"center",marginTop:"auto"},children:o.jsx("span",{style:{display:"inline-block",padding:"10px 18px",fontFamily:"Arial, Helvetica, sans-serif",fontSize:13,fontWeight:"bold",color:f,backgroundColor:p,borderRadius:6},children:x.buttonLabel??e.buttonLabel??"Shop now"})})]},x.id)})})}const Ra=[];let Fo=null;const Lo={registerModule:e=>Ze.register(e),registerTheme:e=>Ra.push(e),registerAssetProvider:e=>{Fo=e},setAIProvider:e=>{}};function Aa(e){e.setup(Lo)}function Na(){return Fo}const cn={key:"days",label:"Time window",type:"select",default:7,options:[{value:7,label:"Last 7 days"},{value:14,label:"Last 14 days"},{value:30,label:"Last 30 days"}]},An=[{id:"abandoned-cart",label:"Abandoned basket products",group:"behavioral"},{id:"bestseller-conversion",label:"Best seller by Conversion",group:"catalog",params:[cn]},{id:"bestseller-units",label:"Best seller by Units",group:"catalog",params:[cn]},{id:"new-products",label:"New items added",group:"catalog",params:[cn]},{id:"cross-sell",label:"Products Cross-Sell",group:"contextual"},{id:"upsell",label:"Products Upsell",group:"contextual"},{id:"viewed-categories",label:"Items from viewed categories",group:"behavioral"},{id:"viewed-items",label:"Items viewed",group:"behavioral"},{id:"similar-basket",label:"Similar to basket items",group:"behavioral"},{id:"bought-together",label:"Items bought together",group:"contextual"},{id:"best-discount",label:"Items with the best discount",group:"catalog"},{id:"match-data",label:"Items matching specific attributes",group:"catalog"},{id:"last-purchased",label:"Last purchased items",group:"personal"},{id:"similar-to-purchased",label:"Similar to last purchase",group:"personal"},{id:"cross-sell-purchased",label:"Cross-sell to last purchase",group:"personal"},{id:"similar-items",label:"Similar items",group:"contextual"}],Mo=Object.fromEntries(An.map(e=>[e.id,e])),bn=[{value:"smart-reccs",label:"Smart Recommendations",description:"Best generic algorithm — recommended default."},{value:"random",label:"Random items (strict filters)",description:"Random items that still pass include/exclude filters."},{value:"ignore",label:"Ignore position",description:"Skip the slot if no items found."},{value:"stop",label:"Don't display",description:"Don't render the email if the slot can't be filled."}],to=3;function Io(e=2){return{mode:"recommender",noProducts:e,sourceFeed:"",manualProducts:[],stack:[{algorithm:"abandoned-cart"}],fallback:"smart-reccs",filters:{includeProducts:[],excludeProducts:[],includeCategories:[],excludeCategories:[],minStock:0,minPrice:0,mainOnly:!1,higherPrice:!1,salesPrice:!1,sameCategory:!1,matchTitle:!1,sameField:""}}}function $o(e){if(!e)return null;const t=e.recommendations;return!t||typeof t!="object"?null:t}function Ea(e){return e?.children?e.children.some(t=>t.type==="productGrid"):!1}function za(e){if(!e?.children)return 0;let t=0;for(const n of e.children)n.type==="productGrid"&&(t+=n.products.length);return t}function Pa(e){return{params:{selection:e.mode==="manual"?"manual":"recommender",include:{item:e.filters.includeProducts,category:e.filters.includeCategories},exclude:{item:e.filters.excludeProducts,category:e.filters.excludeCategories},higherPrice:e.filters.higherPrice??!1,salesPrice:e.filters.salesPrice??!1,sameCategory:e.filters.sameCategory??!1,matchTitle:e.filters.matchTitle??!1,sameField:e.filters.sameField??"",mainOnly:e.filters.mainOnly??!1},noProducts:String(e.noProducts),fallback:e.fallback,stack:e.mode==="manual"?[]:e.stack,minStock:String(e.filters.minStock??0),minPrice:String(e.filters.minPrice??0),sourceFeed:e.sourceFeed??"",manualProducts:e.manualProducts}}function Da({mod:e}){const t=O(s=>s.updateModule),n=za(e)||2,r=$o(e.data)??Io(n),i=s=>{const d={...r,...s};t(e.id,{data:{...e.data??{},recommendations:d}})},a=s=>i({filters:{...r.filters,...s}});return o.jsxs("div",{className:"border border-blue-200 rounded-lg bg-blue-50/40 mt-4 overflow-hidden",children:[o.jsxs("div",{className:"px-3 py-2 flex items-center gap-2 border-b border-blue-200 bg-blue-50",children:[o.jsx(R.Sparkles,{size:14,className:"text-blue-700"}),o.jsx("div",{className:"text-xs font-semibold text-blue-900 uppercase tracking-wide",children:"Products Source"})]}),o.jsx("div",{className:"p-3 bg-white border-b border-blue-100",children:o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(no,{active:r.mode==="manual",title:"Select Items",subtitle:"Hand-pick from a feed",onClick:()=>i({mode:"manual"})}),o.jsx(no,{active:r.mode==="recommender",title:"Recommender",subtitle:"Algorithms + filters",onClick:()=>i({mode:"recommender"})})]})}),o.jsxs("div",{className:"p-3 bg-white space-y-3",children:[o.jsxs(pe,{label:"Number of products",children:[o.jsx("input",{type:"number",min:1,max:20,value:r.noProducts,onChange:s=>i({noProducts:Number(s.target.value)||1}),className:Ve}),o.jsxs("div",{className:"text-[11px] text-gray-500 mt-1",children:["Block has ",n," slot",n===1?"":"s"," in the design."]})]}),r.mode==="manual"?o.jsx(Fa,{logic:r,update:i}):o.jsx(La,{logic:r,update:i,updateFilters:a}),o.jsxs("details",{className:"border border-gray-200 rounded",children:[o.jsx("summary",{className:"px-2 py-1.5 text-[11px] font-medium text-gray-600 cursor-pointer select-none",children:"View saved JSON"}),o.jsx("pre",{className:"text-[10px] bg-gray-900 text-gray-100 p-2 overflow-auto max-h-60 leading-tight",children:JSON.stringify(r,null,2)})]})]})]})}function Fa({logic:e,update:t}){return o.jsxs(o.Fragment,{children:[o.jsx(pe,{label:"Source feed",children:o.jsx("input",{type:"text",placeholder:"e.g. main-catalog",value:e.sourceFeed??"",onChange:n=>t({sourceFeed:n.target.value}),className:Ve})}),o.jsx(pe,{label:"Items to include (product IDs / SKUs)",children:o.jsx(yt,{value:e.manualProducts,onChange:n=>t({manualProducts:n}),placeholder:"Add product id"})}),o.jsx("div",{className:"text-[11px] text-gray-500",children:"Items are sent to the renderer as-is in the order shown."})]})}function La({logic:e,update:t,updateFilters:n}){const[r,i]=g.useState(!1);return o.jsxs(o.Fragment,{children:[o.jsxs("div",{children:[o.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[o.jsxs("label",{className:"text-xs font-medium text-gray-700",children:["Algorithms (max ",to,")"]}),o.jsx($a,{disabled:e.stack.length>=to,existing:e.stack.map(a=>a.algorithm),onPick:a=>t({stack:[...e.stack,{algorithm:a}]})})]}),o.jsx(Ia,{stack:e.stack,onChange:a=>t({stack:a})})]}),o.jsxs(pe,{label:"Fallback",children:[o.jsx("select",{value:e.fallback,onChange:a=>t({fallback:a.target.value}),className:Ve,children:bn.map(a=>o.jsx("option",{value:a.value,children:a.label},a.value))}),o.jsx("div",{className:"text-[11px] text-gray-500 mt-1",children:bn.find(a=>a.value===e.fallback)?.description})]}),o.jsx(Ma,{title:"Include & Exclude filters",right:o.jsxs("div",{className:"flex items-center gap-1",children:[o.jsx(oo,{active:!r,onClick:()=>i(!1),children:"Basic"}),o.jsx(oo,{active:r,onClick:()=>i(!0),children:"Advanced"})]})}),o.jsx(pe,{label:"Exclude products",children:o.jsx(yt,{value:e.filters.excludeProducts,onChange:a=>n({excludeProducts:a}),placeholder:"Add product id"})}),o.jsx(pe,{label:"Include products",children:o.jsx(yt,{value:e.filters.includeProducts,onChange:a=>n({includeProducts:a}),placeholder:"Add product id"})}),o.jsx(pe,{label:"Exclude categories",children:o.jsx(yt,{value:e.filters.excludeCategories,onChange:a=>n({excludeCategories:a}),placeholder:"Add category"})}),o.jsx(pe,{label:"Include categories",children:o.jsx(yt,{value:e.filters.includeCategories,onChange:a=>n({includeCategories:a}),placeholder:"Add category"})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(pe,{label:"Minimum stock",children:o.jsx("input",{type:"number",min:0,value:e.filters.minStock??0,onChange:a=>n({minStock:Number(a.target.value)||0}),className:Ve})}),o.jsx(pe,{label:"Minimum price",children:o.jsx("input",{type:"number",min:0,value:e.filters.minPrice??0,onChange:a=>n({minPrice:Number(a.target.value)||0}),className:Ve})})]}),o.jsx(bt,{label:"Only main items",checked:!!e.filters.mainOnly,onChange:a=>n({mainOnly:a})}),o.jsx(bt,{label:"Higher price than current item (upsell)",checked:!!e.filters.higherPrice,onChange:a=>n({higherPrice:a})}),o.jsx(bt,{label:"On sale only",checked:!!e.filters.salesPrice,onChange:a=>n({salesPrice:a})}),o.jsx(bt,{label:"Same category as current",checked:!!e.filters.sameCategory,onChange:a=>n({sameCategory:a})}),o.jsx(bt,{label:"Match title keywords",checked:!!e.filters.matchTitle,onChange:a=>n({matchTitle:a})}),o.jsx(pe,{label:"Match same fields (comma-separated)",children:o.jsx("input",{type:"text",placeholder:"brand, color",value:e.filters.sameField??"",onChange:a=>n({sameField:a.target.value}),className:Ve})}),r&&o.jsx(pe,{label:"Advanced JSON overrides",children:o.jsx(Oa,{value:e.filters.advanced??{},onChange:a=>n({advanced:a})})})]})}const Ve="w-full px-2 py-1.5 text-sm border border-gray-200 rounded focus:border-blue-500 focus:outline-none bg-white";function no({active:e,icon:t,title:n,subtitle:r,onClick:i}){return o.jsxs("button",{onClick:i,className:"flex flex-col items-start gap-0.5 p-2.5 rounded border text-left transition "+(e?"border-teal-600 bg-teal-50 ring-1 ring-teal-600":"border-gray-200 bg-white hover:border-gray-300"),children:[o.jsxs("div",{className:"flex items-center gap-1.5 "+(e?"text-teal-700":"text-gray-700"),children:[t,o.jsx("span",{className:"text-xs font-semibold",children:n})]}),o.jsx("span",{className:"text-[10px] text-gray-500",children:r})]})}function Ma({title:e,right:t}){return o.jsxs("div",{className:"flex items-center justify-between border-t border-gray-200 pt-3 mt-3",children:[o.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wide text-gray-600",children:e}),t]})}function pe({label:e,children:t}){return o.jsxs("div",{children:[o.jsx("label",{className:"block text-xs font-medium text-gray-700 mb-1",children:e}),t]})}function oo({active:e,onClick:t,children:n}){return o.jsx("button",{onClick:t,className:"px-2 py-0.5 rounded text-[10px] font-semibold uppercase tracking-wide "+(e?"bg-teal-600 text-white":"bg-gray-100 text-gray-600 hover:bg-gray-200"),children:n})}function bt({label:e,checked:t,onChange:n}){return o.jsxs("label",{className:"flex items-center justify-between gap-2 text-xs text-gray-700 py-1",children:[o.jsx("span",{children:e}),o.jsx("input",{type:"checkbox",checked:t,onChange:r=>n(r.target.checked),className:"h-4 w-4 accent-teal-600"})]})}function Ia({stack:e,onChange:t}){if(e.length===0)return o.jsxs("div",{className:"text-[11px] text-gray-500 italic border border-dashed border-gray-300 rounded px-2 py-3 text-center",children:["No algorithms yet. Click ",o.jsx("b",{children:"Add algorithm"})," to start."]});const n=(a,s)=>{const d=a+s;if(d<0||d>=e.length)return;const l=e.slice();[l[a],l[d]]=[l[d],l[a]],t(l)},r=a=>t(e.filter((s,d)=>d!==a)),i=(a,s,d)=>{const l=e.slice();l[a]={...l[a],params:{...l[a].params??{},[s]:d}},t(l)};return o.jsx("div",{className:"space-y-1.5",children:e.map((a,s)=>{const d=Mo[a.algorithm];return o.jsxs("div",{className:"border border-gray-200 rounded px-2 py-1.5 bg-white flex flex-col gap-1",children:[o.jsxs("div",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"flex-1 text-xs text-gray-800 truncate",children:d?.label??a.algorithm}),o.jsx("button",{title:"Move up",onClick:()=>n(s,-1),disabled:s===0,className:"p-1 text-gray-400 hover:text-gray-700 disabled:opacity-30",children:o.jsx(R.ChevronUp,{size:13})}),o.jsx("button",{title:"Move down",onClick:()=>n(s,1),disabled:s===e.length-1,className:"p-1 text-gray-400 hover:text-gray-700 disabled:opacity-30",children:o.jsx(R.ChevronDown,{size:13})}),o.jsx("button",{title:"Remove",onClick:()=>r(s),className:"p-1 text-gray-400 hover:text-red-600",children:o.jsx(R.Trash2,{size:13})})]}),d?.params?.map(l=>o.jsxs("div",{className:"flex items-center gap-2",children:[o.jsx("span",{className:"text-[10px] text-gray-500 w-20 shrink-0",children:l.label}),l.type==="select"?o.jsx("select",{value:String(a.params?.[l.key]??l.default??""),onChange:c=>i(s,l.key,c.target.value),className:"flex-1 text-xs border border-gray-200 rounded px-1.5 py-1 bg-white",children:l.options?.map(c=>o.jsx("option",{value:String(c.value),children:c.label},String(c.value)))}):o.jsx("input",{type:l.type==="number"?"number":"text",value:String(a.params?.[l.key]??l.default??""),onChange:c=>i(s,l.key,l.type==="number"?Number(c.target.value):c.target.value),className:"flex-1 text-xs border border-gray-200 rounded px-1.5 py-1"})]},l.key))]},s)})})}function $a({disabled:e,existing:t,onPick:n}){const[r,i]=g.useState(!1);return o.jsxs("div",{className:"relative",children:[o.jsxs("button",{disabled:e,onClick:()=>i(a=>!a),className:"flex items-center gap-1 px-2 py-1 rounded text-[11px] font-semibold uppercase "+(e?"bg-gray-200 text-gray-400 cursor-not-allowed":"bg-teal-600 text-white hover:bg-teal-700"),children:[o.jsx(R.Plus,{size:12})," Add"]}),r&&!e&&o.jsxs(o.Fragment,{children:[o.jsx("div",{className:"fixed inset-0 z-10",onClick:()=>i(!1)}),o.jsx("div",{className:"absolute right-0 top-full mt-1 w-64 max-h-80 overflow-auto bg-white border border-gray-200 rounded shadow-lg z-20",children:An.map(a=>{const s=t.includes(a.id);return o.jsxs("button",{disabled:s,onClick:()=>{n(a.id),i(!1)},className:"block w-full text-left px-2.5 py-1.5 text-xs "+(s?"text-gray-400 cursor-not-allowed":"text-gray-700 hover:bg-teal-50 hover:text-teal-700"),children:[a.label,s&&o.jsx("span",{className:"ml-1 text-[10px]",children:"· added"})]},a.id)})})]})]})}function yt({value:e,onChange:t,placeholder:n}){const[r,i]=g.useState(""),a=()=>{const s=r.trim();s&&(e.includes(s)||(t([...e,s]),i("")))};return o.jsxs("div",{className:"border border-gray-200 rounded bg-white p-1 flex flex-wrap items-center gap-1 focus-within:border-blue-500",children:[e.map(s=>o.jsxs("span",{className:"inline-flex items-center gap-1 bg-gray-100 text-gray-800 text-[11px] rounded px-1.5 py-0.5",children:[s,o.jsx("button",{onClick:()=>t(e.filter(d=>d!==s)),className:"text-gray-500 hover:text-red-600",children:o.jsx(R.X,{size:10})})]},s)),o.jsx("input",{value:r,onChange:s=>i(s.target.value),onKeyDown:s=>{s.key==="Enter"||s.key===","?(s.preventDefault(),a()):s.key==="Backspace"&&!r&&e.length&&t(e.slice(0,-1))},onBlur:a,placeholder:e.length===0?n:"",className:"flex-1 min-w-20 outline-none text-xs bg-transparent px-1 py-0.5"})]})}function Oa({value:e,onChange:t}){const[n,r]=g.useState(()=>JSON.stringify(e,null,2)),[i,a]=g.useState(null);return o.jsxs("div",{children:[o.jsx("textarea",{value:n,onChange:s=>{const d=s.target.value;r(d);try{const l=JSON.parse(d||"{}");a(null),t(l)}catch(l){a(String(l.message))}},rows:6,spellCheck:!1,className:"w-full font-mono text-[11px] border border-gray-200 rounded p-2 bg-gray-50 focus:border-blue-500 focus:outline-none"}),i&&o.jsx("div",{className:"text-[10px] text-red-600 mt-1",children:i})]})}function _a(){const{selection:e,doc:t,viewMode:n}=O();return o.jsxs("div",{className:"w-72 bg-white border-l border-gray-200 shrink-0 overflow-y-auto",children:[o.jsxs("div",{className:`px-4 py-2 text-[11px] flex items-center gap-1.5 border-b ${n==="mobile"?"bg-amber-50 text-amber-800 border-amber-200":"bg-blue-50 text-blue-800 border-blue-100"}`,children:[n==="mobile"?o.jsx(R.Smartphone,{size:12}):o.jsx(R.Monitor,{size:12}),"Editing ",n," styles"]}),o.jsx("div",{className:"p-4",children:!e||e.kind==="email"?o.jsx(Wa,{}):e.kind==="module"?(()=>{const r=t.modules.find(i=>i.id===e.moduleId);return r?o.jsx(Ha,{mod:r}):o.jsx(ro,{})})():(()=>{const r=t.modules.find(a=>a.id===e.moduleId),i=r?.children.find(a=>a.id===e.elementId);return r&&i?o.jsx(Ua,{mod:r,el:i}):o.jsx(ro,{})})()})]})}function ro(){return o.jsx("div",{className:"text-xs text-gray-400",children:"Nothing selected."})}function rt(e,t){if(t!=="mobile")return e;const n=e.mobile??{};return{...e,...n}}function it(e,t,n){if(n!=="mobile")return{...e,...t};const r=e.mobile??{};return{...e,mobile:{...r,...t}}}function Bt({overridden:e}){return e?o.jsx("span",{className:"ml-1 text-[9px] uppercase tracking-wide bg-amber-100 text-amber-800 px-1 rounded",children:"mobile"}):null}function zt({hideOn:e,onChange:t}){return o.jsx(T,{label:"Visibility",children:o.jsxs(Qt,{value:e??"",onChange:n=>{const r=n.target.value;t(r===""?void 0:r)},children:[o.jsx("option",{value:"",children:"Show on all"}),o.jsx("option",{value:"mobile",children:"Hide on mobile"}),o.jsx("option",{value:"desktop",children:"Hide on desktop"})]})})}function he({children:e}){return o.jsx("h3",{className:"text-xs font-semibold uppercase tracking-wide text-gray-500 mb-3",children:e})}function T({label:e,children:t}){return o.jsxs("label",{className:"block mb-3",children:[o.jsx("span",{className:"flex items-center text-xs text-gray-600 mb-1",children:e}),t]})}function X(e){return o.jsx("input",{...e,className:"w-full px-2 py-1.5 text-sm border border-gray-200 rounded focus:border-blue-500 focus:outline-none"})}function ne(e){return o.jsx(X,{type:"number",...e})}function Oo({value:e,onChange:t,onAlt:n}){const r=Na(),i=g.useRef(null),[a,s]=g.useState(!1),[d,l]=g.useState(null),c=async m=>{if(r){s(!0),l(null);try{const p=await r.upload(m);t(p.url),p.alt&&n&&n(p.alt)}catch(p){l(p instanceof Error?p.message:String(p))}finally{s(!1),i.current&&(i.current.value="")}}};return o.jsxs("div",{children:[o.jsxs("div",{className:"flex gap-1",children:[o.jsx(X,{value:e??"",onChange:m=>t(m.target.value)}),r&&o.jsxs(o.Fragment,{children:[o.jsx("input",{ref:i,type:"file",accept:"image/*",className:"hidden",onChange:m=>{const p=m.target.files?.[0];p&&c(p)}}),o.jsx("button",{type:"button",disabled:a,onClick:()=>i.current?.click(),className:"shrink-0 px-2 py-1.5 text-xs border border-gray-200 rounded hover:bg-gray-50 disabled:opacity-50 flex items-center gap-1",title:"Upload image",children:a?o.jsx(R.Loader2,{size:12,className:"animate-spin"}):o.jsx(R.Upload,{size:12})})]})]}),d&&o.jsx("p",{className:"text-[10px] text-red-600 mt-1",children:d}),!r&&o.jsx("p",{className:"text-[10px] text-gray-400 mt-1",children:"Tip: register an image uploader plugin to enable file uploads."})]})}function de({value:e,onChange:t,defaultValue:n}){const r=O(p=>p.doc.theme),i=typeof e=="string"&&e.startsWith("{"),a=g.useRef(n&&n.startsWith("{")?n:i?e:void 0);g.useEffect(()=>{i?a.current=e:n&&n.startsWith("{")&&(a.current=n)},[e,i,n]);const s=(()=>{const p=_e(e,r);return typeof p=="string"&&/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(p)?p.length===4?"#"+p.slice(1).split("").map(f=>f+f).join(""):p:"#000000"})(),d=n??a.current,l=!!d&&d!==e,[c,m]=g.useState(e??"");return g.useEffect(()=>m(e??""),[e]),o.jsxs("div",{className:"flex gap-1 items-center",children:[o.jsxs("label",{className:"relative w-9 h-8 border border-gray-200 rounded cursor-pointer overflow-hidden shrink-0",title:i?`Token → ${s} (click to override)`:"Pick color",style:{background:s},children:[o.jsx("input",{type:"color",value:s,onChange:p=>t(p.target.value),className:"absolute inset-0 opacity-0 cursor-pointer"}),i&&o.jsx("span",{className:"absolute inset-0 pointer-events-none border-2 border-dashed rounded",style:{borderColor:"rgba(255,255,255,0.6)"}})]}),o.jsx("input",{value:c,onChange:p=>m(p.target.value),onBlur:()=>c!==e&&t(c),onKeyDown:p=>{p.key==="Enter"&&p.target.blur()},className:"w-full px-2 py-1.5 text-sm border border-gray-200 rounded focus:border-blue-500 focus:outline-none font-mono"}),l&&o.jsx("button",{type:"button",onClick:()=>t(d),className:"shrink-0 p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded",title:`Reset to ${d}`,children:o.jsx(R.RotateCcw,{size:12})})]})}function Qt(e){return o.jsx("select",{...e,className:"w-full px-2 py-1.5 text-sm border border-gray-200 rounded focus:border-blue-500 focus:outline-none bg-white"})}function Wa(){const{doc:e,updateMeta:t,updateSettings:n}=O();return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Email"}),o.jsx(T,{label:"Name",children:o.jsx(X,{value:e.meta.name,onChange:r=>t({name:r.target.value})})}),o.jsx(T,{label:"Preview text",children:o.jsx(X,{value:e.meta.previewText,onChange:r=>t({previewText:r.target.value})})}),o.jsx(T,{label:"Width (px)",children:o.jsx(ne,{value:e.settings.width,onChange:r=>n({width:Number(r.target.value)||600})})}),o.jsx(T,{label:"Background color",children:o.jsx(de,{value:e.settings.backgroundColor,onChange:r=>n({backgroundColor:r})})}),o.jsx(T,{label:"Content background color",children:o.jsx(de,{value:e.settings.contentBackgroundColor,onChange:r=>n({contentBackgroundColor:r})})}),o.jsxs("div",{className:"mt-6 pt-4 border-t border-gray-100",children:[o.jsx(he,{children:"Theme tokens (read-only preview)"}),o.jsxs("div",{className:"text-xs space-y-1",children:[o.jsx("div",{className:"font-medium",children:e.theme.name}),o.jsx("div",{className:"grid grid-cols-2 gap-1 text-gray-500",children:Object.entries(e.theme.tokens.colors).map(([r,i])=>o.jsxs("div",{className:"flex items-center gap-1",children:[o.jsx("span",{className:"w-3 h-3 rounded",style:{background:i}}),o.jsx("span",{className:"truncate",children:r})]},r))})]})]})]})}function Ha({mod:e}){const t=O(d=>d.updateModule),n=O(d=>d.viewMode),r=e.style??{},i=rt(r,n),a=new Set(Object.keys(r.mobile??{})),s=d=>t(e.id,{style:it(r,d,n)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:e.name}),o.jsx(T,{label:o.jsxs(o.Fragment,{children:["Background color",o.jsx(Bt,{overridden:a.has("backgroundColor")})]}),children:o.jsx(de,{value:i.backgroundColor??"",onChange:d=>s({backgroundColor:d})})}),o.jsx(at,{style:i,mobileKeys:a,onSet:s}),o.jsx(T,{label:o.jsxs(o.Fragment,{children:["Border radius",o.jsx(Bt,{overridden:a.has("borderRadius")})]}),children:o.jsx(ne,{value:i.borderRadius??0,onChange:d=>s({borderRadius:Number(d.target.value)})})}),o.jsx(zt,{hideOn:r.hideOn,onChange:d=>t(e.id,{style:{...r,hideOn:d}})}),Ea(e)&&o.jsx(Da,{mod:e})]})}function Ua({mod:e,el:t}){switch(t.type){case"text":return o.jsx(Ga,{mod:e,el:t});case"image":return o.jsx(Ya,{mod:e,el:t});case"button":return o.jsx(qa,{mod:e,el:t});case"spacer":return o.jsx(Ja,{mod:e,el:t});case"divider":return o.jsx(Va,{mod:e,el:t});case"productGrid":return o.jsx(Xa,{mod:e,el:t})}}function at({style:e,mobileKeys:t,onSet:n}){return o.jsx("div",{className:"grid grid-cols-2 gap-2 mb-3",children:["paddingTop","paddingBottom","paddingLeft","paddingRight"].map(r=>o.jsx(T,{label:o.jsxs(o.Fragment,{children:[r.replace("padding","Pad "),o.jsx(Bt,{overridden:!!t?.has(r)})]}),children:o.jsx(ne,{value:e[r]??0,onChange:i=>n({[r]:Number(i.target.value)})})},r))})}function st(e,t){const n=O(r=>r.updateElement);return r=>n(e.id,t.id,r)}function Ga({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Text"}),o.jsx(T,{label:"Content",children:o.jsx("textarea",{value:t.content.replace(/<br\s*\/?>/g,`
|
|
79
|
-
`),onChange:l=>n({content:l.target.value.replace(/\n/g,"<br/>")}),rows:3,className:"w-full px-2 py-1.5 text-sm border border-gray-200 rounded focus:border-blue-500 focus:outline-none"})}),o.jsx(T,{label:"Font family",children:o.jsx(X,{value:a.fontFamily??"",onChange:l=>d({fontFamily:l.target.value})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:"Font size",children:o.jsx(ne,{value:a.fontSize??16,onChange:l=>d({fontSize:Number(l.target.value)})})}),o.jsx(T,{label:"Weight",children:o.jsx(X,{value:String(a.fontWeight??""),onChange:l=>d({fontWeight:l.target.value||void 0})})}),o.jsx(T,{label:"Line height",children:o.jsx(ne,{step:.1,value:a.lineHeight??1.5,onChange:l=>d({lineHeight:Number(l.target.value)})})}),o.jsx(T,{label:"Letter spacing",children:o.jsx(ne,{value:a.letterSpacing??0,onChange:l=>d({letterSpacing:Number(l.target.value)})})})]}),o.jsx(T,{label:"Color",children:o.jsx(de,{value:a.color??"#000000",onChange:l=>d({color:l})})}),o.jsx(T,{label:"Align",children:o.jsxs(Qt,{value:a.align??"left",onChange:l=>d({align:l.target.value}),children:[o.jsx("option",{value:"left",children:"Left"}),o.jsx("option",{value:"center",children:"Center"}),o.jsx("option",{value:"right",children:"Right"})]})}),o.jsx(T,{label:"Link URL",children:o.jsx(X,{value:a.link??"",onChange:l=>d({link:l.target.value})})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})}),o.jsx("button",{onClick:()=>n({content:`${t.content} ✨`}),className:"w-full mt-2 px-3 py-2 text-xs bg-purple-50 text-purple-700 border border-purple-200 rounded hover:bg-purple-100",children:"✨ AI rewrite (mock)"})]})}function Ya({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Image"}),o.jsx(T,{label:"Image URL",children:o.jsx(Oo,{value:t.src,onChange:l=>n({src:l}),onAlt:l=>n({alt:l})})}),o.jsx(T,{label:"Alt text",children:o.jsx(X,{value:t.alt??"",onChange:l=>n({alt:l.target.value})})}),o.jsx(T,{label:"Link",children:o.jsx(X,{value:t.link??"",onChange:l=>n({link:l.target.value})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:o.jsxs(o.Fragment,{children:["Width",o.jsx(Bt,{overridden:s.has("width")})]}),children:o.jsx(ne,{value:a.width??0,onChange:l=>d({width:Number(l.target.value)})})}),o.jsx(T,{label:o.jsxs(o.Fragment,{children:["Height",o.jsx(Bt,{overridden:s.has("height")})]}),children:o.jsx(ne,{value:a.height??0,onChange:l=>d({height:Number(l.target.value)||void 0})})})]}),o.jsx(T,{label:"Border radius",children:o.jsx(ne,{value:a.borderRadius??0,onChange:l=>d({borderRadius:Number(l.target.value)})})}),o.jsx(T,{label:"Align",children:o.jsxs(Qt,{value:a.align??"center",onChange:l=>d({align:l.target.value}),children:[o.jsx("option",{value:"left",children:"Left"}),o.jsx("option",{value:"center",children:"Center"}),o.jsx("option",{value:"right",children:"Right"})]})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})})]})}function qa({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Button"}),o.jsx(T,{label:"Label",children:o.jsx(X,{value:t.label,onChange:l=>n({label:l.target.value})})}),o.jsx(T,{label:"Link",children:o.jsx(X,{value:t.link,onChange:l=>n({link:l.target.value})})}),o.jsx(T,{label:"Background color",children:o.jsx(de,{value:a.backgroundColor??"",onChange:l=>d({backgroundColor:l})})}),o.jsx(T,{label:"Text color",children:o.jsx(de,{value:a.color??"#FFFFFF",onChange:l=>d({color:l})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:"Font size",children:o.jsx(ne,{value:a.fontSize??16,onChange:l=>d({fontSize:Number(l.target.value)})})}),o.jsx(T,{label:"Border radius",children:o.jsx(ne,{value:a.borderRadius??6,onChange:l=>d({borderRadius:Number(l.target.value)})})})]}),o.jsx(T,{label:"Align",children:o.jsxs(Qt,{value:a.align??"center",onChange:l=>d({align:l.target.value}),children:[o.jsx("option",{value:"left",children:"Left"}),o.jsx("option",{value:"center",children:"Center"}),o.jsx("option",{value:"right",children:"Right"})]})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})})]})}function Ja({mod:e,el:t}){const n=st(e,t);return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Spacer"}),o.jsx(T,{label:"Height (px)",children:o.jsx(ne,{value:t.height,onChange:r=>n({height:Number(r.target.value)||0})})})]})}function Va({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Divider"}),o.jsx(T,{label:"Color",children:o.jsx(de,{value:a.color??"#E5E7EB",onChange:l=>d({color:l})})}),o.jsx(T,{label:"Thickness",children:o.jsx(ne,{value:a.thickness??1,onChange:l=>d({thickness:Number(l.target.value)})})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})})]})}function io(e=0){const t=e+1;return{id:`p_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,image:`https://placehold.co/400x400?text=Product+${t}`,imageAlt:`Product ${t}`,name:`Product ${t}`,oldPrice:"$59",finalPrice:"$39",description:"Short product description.",link:"#"}}function Xa({mod:e,el:t}){const n=st(e,t),r=O(c=>c.viewMode),i=t.style??{},a=rt(i,r),s=c=>n({style:it(i,c,r)}),d=c=>n({products:c}),l=c=>{const m=c;let p=t.products.slice();if(p.length<m)for(;p.length<m;)p.push(io(p.length));n({columns:c,products:p})};return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Product Grid"}),o.jsxs(T,{label:"Columns (desktop)",children:[o.jsx("div",{className:"inline-flex bg-gray-100 rounded p-0.5 w-full",children:[1,2,3].map(c=>o.jsxs("button",{onClick:()=>l(c),className:`flex-1 px-2 py-1 text-xs rounded ${t.columns===c?"bg-white shadow text-gray-900":"text-gray-500 hover:text-gray-700"}`,children:[c," ",c===1?"col":"cols"]},c))}),o.jsx("p",{className:"text-[10px] text-gray-400 mt-1",children:"Always stacks to 1 column on mobile."})]}),o.jsx(T,{label:"Show old price",children:o.jsx(un,{checked:t.showOldPrice,onChange:c=>n({showOldPrice:c})})}),o.jsx(T,{label:"Show description",children:o.jsx(un,{checked:t.showDescription,onChange:c=>n({showDescription:c})})}),o.jsx(T,{label:"Show button",children:o.jsx(un,{checked:t.showButton,onChange:c=>n({showButton:c})})}),t.showButton&&o.jsx(T,{label:"Default button label",children:o.jsx(X,{value:t.buttonLabel??"",placeholder:"Shop now",onChange:c=>n({buttonLabel:c.target.value})})}),o.jsxs("div",{className:"mt-4 pt-3 border-t border-gray-100",children:[o.jsxs("div",{className:"flex items-center justify-between mb-2",children:[o.jsxs(he,{children:["Products (",t.products.length,")"]}),o.jsxs("button",{onClick:()=>d([...t.products,io(t.products.length)]),className:"flex items-center gap-1 px-1.5 py-0.5 text-[11px] text-blue-600 hover:bg-blue-50 rounded",title:"Add product",children:[o.jsx(R.Plus,{size:12})," Add"]})]}),t.products.map((c,m)=>o.jsx(Ka,{index:m,product:c,showOldPrice:t.showOldPrice,showDescription:t.showDescription,showButton:t.showButton,onChange:p=>{const f=[...t.products];f[m]=p,d(f)},onDelete:()=>d(t.products.filter((p,f)=>f!==m))},c.id))]}),o.jsxs("div",{className:"mt-4 pt-3 border-t border-gray-100",children:[o.jsx(he,{children:"Style"}),o.jsx(T,{label:"Card background",children:o.jsx(de,{value:a.cardBackgroundColor??"",onChange:c=>s({cardBackgroundColor:c})})}),o.jsx(T,{label:"Name color",children:o.jsx(de,{value:a.nameColor??"",onChange:c=>s({nameColor:c})})}),o.jsx(T,{label:"Final price color",children:o.jsx(de,{value:a.finalPriceColor??"",onChange:c=>s({finalPriceColor:c})})}),o.jsx(T,{label:"Old price color",children:o.jsx(de,{value:a.oldPriceColor??"",onChange:c=>s({oldPriceColor:c})})}),o.jsx(T,{label:"Button background",children:o.jsx(de,{value:a.buttonBackgroundColor??"",onChange:c=>s({buttonBackgroundColor:c})})}),o.jsx(T,{label:"Button text color",children:o.jsx(de,{value:a.buttonColor??"",onChange:c=>s({buttonColor:c})})}),o.jsx(T,{label:"Card radius",children:o.jsx(ne,{value:a.borderRadius??0,onChange:c=>s({borderRadius:Number(c.target.value)})})}),o.jsx(at,{style:a,onSet:s})]})]})}function un({checked:e,onChange:t}){return o.jsx("button",{onClick:()=>t(!e),className:`relative inline-flex h-5 w-9 items-center rounded-full transition-colors ${e?"bg-blue-600":"bg-gray-300"}`,children:o.jsx("span",{className:`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${e?"translate-x-4":"translate-x-0.5"}`})})}function Ka({index:e,product:t,showOldPrice:n,showDescription:r,showButton:i,onChange:a,onDelete:s}){const d=l=>a({...t,...l});return o.jsxs("div",{className:"border border-gray-200 rounded p-2 mb-2 bg-gray-50",children:[o.jsxs("div",{className:"flex items-center justify-between mb-2",children:[o.jsxs("span",{className:"text-[11px] font-semibold text-gray-600",children:["#",e+1]}),o.jsx("button",{onClick:s,className:"text-gray-400 hover:text-red-600",title:"Remove product",children:o.jsx(R.Trash2,{size:12})})]}),o.jsx(T,{label:"Name",children:o.jsx(X,{value:t.name,onChange:l=>d({name:l.target.value})})}),o.jsx(T,{label:"Image URL",children:o.jsx(Oo,{value:t.image,onChange:l=>d({image:l}),onAlt:l=>d({imageAlt:l})})}),o.jsx(T,{label:"Link",children:o.jsx(X,{value:t.link??"",onChange:l=>d({link:l.target.value})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:"Final price",children:o.jsx(X,{value:t.finalPrice,onChange:l=>d({finalPrice:l.target.value})})}),n&&o.jsx(T,{label:"Old price",children:o.jsx(X,{value:t.oldPrice??"",onChange:l=>d({oldPrice:l.target.value})})})]}),r&&o.jsx(T,{label:"Description",children:o.jsx(X,{value:t.description??"",onChange:l=>d({description:l.target.value})})}),i&&o.jsx(T,{label:"Button label (override)",children:o.jsx(X,{value:t.buttonLabel??"",placeholder:"Inherit default",onChange:l=>d({buttonLabel:l.target.value||void 0})})})]})}const Qa=[{type:"basic.text",category:"basic",name:"Text Block",description:"Single editable paragraph of body copy. Use for short notes, intros, or filler text between sections.",tags:["text","paragraph","body"],create:()=>h("basic.text","Text Block",[u("Write your text here.",{role:"body"})])},{type:"basic.heading",category:"basic",name:"Heading",description:"Bold standalone heading using the theme heading font. Use to introduce a section without other elements.",tags:["heading","title","section"],create:()=>h("basic.heading","Heading",[u("A clear section heading",{role:"headline",fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",paddingTop:16,paddingBottom:8,lineHeight:1.25})])},{type:"basic.image",category:"basic",name:"Image",description:"Single full-width image, centered. Use for hero photography, illustrations, or screenshots.",tags:["image","media","photo"],create:()=>h("basic.image","Image",[M(A(600,300),"Placeholder")])},{type:"basic.image_caption",category:"basic",name:"Image with Caption",description:"Image followed by a small italicized caption underneath. Editorial style for newsletters.",tags:["image","caption","editorial"],create:()=>h("basic.image_caption","Image + Caption",[M(A(600,360),"Photo"),u("Photo: caption goes here.",{color:"{colors.muted}",fontSize:13,align:"center",paddingTop:4,paddingBottom:16})])},{type:"basic.spacer",category:"basic",name:"Spacer",description:"Empty vertical space. Use to separate modules with breathing room.",tags:["spacer","spacing","gap"],create:()=>h("basic.spacer","Spacer",[F(32)])},{type:"basic.divider",category:"basic",name:"Divider",description:"Thin horizontal rule across the email. Use to visually separate sections.",tags:["divider","separator","rule"],create:()=>h("basic.divider","Divider",[U()])}],Za=[{type:"header.logo",category:"header",name:"Logo Centered",description:"Centered brand logo. The simplest header used at the top of almost every newsletter.",tags:["logo","brand","centered"],create:()=>h("header.logo","Logo Header",[M(A(180,56,"LOGO"),"Logo",{width:180,paddingTop:24,paddingBottom:24})])},{type:"header.logo_left_date_right",category:"header",name:"Logo Left + Date Right",description:"Two-column header with logo on the left and a date or issue label on the right. Common for periodical newsletters and digests.",tags:["logo","date","issue","publication","newsletter"],create:()=>h("header.logo_left_date_right","Logo + Date",[M(A(140,36,"LOGO"),"Logo",{width:140,align:"left",paddingTop:16,paddingBottom:16}),u("Issue #128 · April 29, 2026",{color:"{colors.muted}",fontSize:13,align:"right",paddingTop:0,paddingBottom:16}),U({paddingTop:0,paddingBottom:0})])},{type:"header.publication",category:"header",name:"Publication Masthead",description:"Editorial masthead with publication name in serif type, tagline, and a divider. Mimics print magazine and newspaper newsletters.",tags:["masthead","publication","editorial","serif","newspaper","magazine"],create:()=>h("header.publication","Masthead",[u("THE WEEKLY",{fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",letterSpacing:6,paddingTop:32,paddingBottom:4}),u("Curated reading for thoughtful people",{color:"{colors.muted}",align:"center",fontSize:13,paddingBottom:16}),U({paddingTop:0,paddingBottom:0})])},{type:"header.hero",category:"header",name:"Hero with Headline & Image",description:"Big headline, subtitle and a wide hero image. Use for the lead story or campaign announcement.",tags:["hero","headline","image","lead","feature"],create:()=>h("header.hero","Hero",[u("Steps Towards a Greener World",{role:"headline",fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",paddingTop:32,lineHeight:1.2}),u("Small actions, big impact.",{color:"{colors.muted}",align:"center",paddingBottom:16}),M(A(560,280,"Hero"),"Hero",{width:560})])},{type:"header.hero_text_only",category:"header",name:"Hero Text Only",description:"Centered eyebrow + large headline + supporting paragraph, no image. Editorial intro for opinion or essay newsletters.",tags:["hero","text","essay","editorial","minimal"],create:()=>h("header.hero_text_only","Hero Text",[u("ESSAY · ISSUE 42",{fontSize:12,fontWeight:"bold",color:"{colors.primary}",letterSpacing:3,align:"center",paddingTop:32,paddingBottom:8}),u("On building things slowly",{role:"headline",fontFamily:"{fonts.heading}",fontSize:40,fontWeight:"bold",align:"center",lineHeight:1.15,paddingBottom:8}),u("Why patience and craft still win in a world of shortcuts.",{color:"{colors.muted}",align:"center",fontSize:16,paddingBottom:32})])},{type:"header.announcement",category:"header",name:"Announcement Bar",description:"Thin colored top bar with a single line of promotional text. Use for free shipping, sales, or alerts.",tags:["announcement","bar","promo","alert"],create:()=>h("header.announcement","Announcement",[u("✨ Free shipping on orders over $50",{color:"{colors.buttonText}",align:"center",fontSize:14,paddingTop:12,paddingBottom:12})],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"header.logo_with_view_browser",category:"header",name:"Logo + View in Browser",description:"Logo with a small 'View in browser' link above it. Standard for marketing newsletters that may render poorly.",tags:["logo","view-in-browser","marketing","preheader"],create:()=>h("header.logo_with_view_browser","Logo + Browser Link",[u("View in browser",{color:"{colors.muted}",fontSize:11,align:"right",paddingTop:8,paddingBottom:0,link:"#"}),M(A(160,48,"LOGO"),"Logo",{width:160,paddingTop:8,paddingBottom:16})])},{type:"header.welcome",category:"header",name:"Welcome Header",description:"Friendly greeting with first name placeholder, used at the top of welcome and onboarding emails.",tags:["welcome","onboarding","greeting","personalized"],create:()=>h("header.welcome","Welcome",[u("👋 Welcome aboard, {{first_name}}",{fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",align:"center",paddingTop:32,paddingBottom:8}),u("We're glad you're here. Here's what to do next.",{color:"{colors.muted}",align:"center",paddingBottom:16})])},{type:"header.logo_with_tagline",category:"header",name:"Logo + Tagline",description:"Centered logo above a one-line tagline. Friendly brand-forward header.",tags:["logo","tagline","brand"],create:()=>h("header.logo_with_tagline","Logo + Tagline",[M(A(160,48,"LOGO"),"Logo",{width:160,paddingTop:24,paddingBottom:4}),u("Newsletters that respect your time.",{align:"center",color:"{colors.muted}",fontSize:14,paddingBottom:24})])},{type:"header.story_label",category:"header",name:"Story Label Header",description:"Small category label (e.g. 'Top story', 'Deep dive') above the masthead. Used by The Hustle, Morning Brew style newsletters.",tags:["label","category","story","newsletter","topic"],create:()=>h("header.story_label","Story Label",[u("TODAY'S TOP STORY",{color:"{colors.primary}",fontSize:12,fontWeight:"bold",letterSpacing:3,align:"center",paddingTop:24,paddingBottom:4}),u("AI editing tools come for the inbox",{fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",align:"center",paddingBottom:16,lineHeight:1.2})])}],es=[{type:"menu.horizontal",category:"menu",name:"Horizontal Nav",description:"Horizontal menu with 3-5 inline links separated by dots. Common publication navigation under the masthead.",tags:["menu","nav","horizontal","publication"],create:()=>h("menu.horizontal","Horizontal Menu",[u("Home · Articles · Podcast · About · Subscribe",{align:"center",color:"{colors.text}",fontSize:13,paddingTop:12,paddingBottom:12})])},{type:"menu.sections",category:"menu",name:"Section Tabs",description:"Linked section labels representing the contents of today's issue (e.g. News · Markets · Tech · Culture). Used by daily digests.",tags:["menu","sections","tabs","digest","daily"],create:()=>h("menu.sections","Section Tabs",[U({paddingTop:0,paddingBottom:8}),u("NEWS · MARKETS · TECH · CULTURE · WEEKEND",{align:"center",color:"{colors.primary}",fontSize:11,fontWeight:"bold",letterSpacing:2,paddingTop:0,paddingBottom:8}),U({paddingTop:0,paddingBottom:8})])},{type:"menu.in_this_issue",category:"menu",name:"In This Issue",description:"Table-of-contents box listing the items in this newsletter issue with anchor links. Helps readers scan long emails.",tags:["toc","menu","issue","summary","table of contents"],create:()=>h("menu.in_this_issue","In This Issue",[u("IN THIS ISSUE",{fontSize:11,fontWeight:"bold",color:"{colors.muted}",letterSpacing:2,paddingTop:16,paddingBottom:8}),u("→ Lead story: AI in the inbox",{fontSize:14,paddingTop:2,paddingBottom:2,link:"#lead"}),u("→ 3 things worth your time",{fontSize:14,paddingTop:2,paddingBottom:2,link:"#picks"}),u("→ Reader question of the week",{fontSize:14,paddingTop:2,paddingBottom:2,link:"#qa"}),u("→ Upcoming events",{fontSize:14,paddingTop:2,paddingBottom:16,link:"#events"})],{backgroundColor:"{colors.background}",paddingTop:8,paddingBottom:8,paddingLeft:16,paddingRight:16})},{type:"menu.cta_strip",category:"menu",name:"Linked Action Strip",description:"Three short text actions in a row (e.g. 'Read · Share · Reply'). Light alternative to a button bar.",tags:["menu","actions","links","strip"],create:()=>h("menu.cta_strip","Action Strip",[u("Read online · Share · Reply with feedback",{align:"center",color:"{colors.primary}",fontSize:13,paddingTop:12,paddingBottom:12})])}],ts=[{type:"content.headline_body",category:"content",name:"Headline + Body",description:"Section title with one paragraph of body text. The most generic written content block.",tags:["headline","body","paragraph","article"],create:()=>h("content.headline_body","Headline + Body",[I("A compelling headline",{paddingTop:24}),u("Tell your story with a clear, concise paragraph. Keep readers engaged with short sentences and meaningful detail.",{paddingBottom:24})])},{type:"content.lead_story",category:"content",name:"Lead Story",description:"Top story of the issue: eyebrow label, big headline, hero image, lead paragraph and a 'Continue reading' link. Used by news and editorial newsletters.",tags:["lead","story","feature","news","editorial","long-form"],create:()=>h("content.lead_story","Lead Story",[Y("Lead story"),I("Inside the new wave of indie publishers",{level:1,paddingBottom:4}),v("By Jane Doe · 6 min read",{fontSize:13}),M(A(560,320,"Lead"),"Lead",{width:560,paddingTop:12}),u("A growing group of writers are leaving big media to build their own readerships, betting that quality and a direct relationship beat scale.",{paddingTop:16}),u("Continue reading →",{color:"{colors.primary}",fontWeight:"bold",paddingTop:4,paddingBottom:24,link:"#"})])},{type:"content.article_summary",category:"content",name:"Article Summary Card",description:"Compact link-out card: image on top, category label, title, one-line summary, and 'Read more'. Use repeatedly to list secondary articles.",tags:["article","summary","card","link-out","newsletter"],create:()=>h("content.article_summary","Article Card",[M(A(560,280,"Article"),"Article",{width:560}),u("CULTURE",{color:"{colors.primary}",fontSize:11,fontWeight:"bold",letterSpacing:2,paddingTop:12,paddingBottom:4}),I("How long-form writing made a comeback",{paddingTop:0,paddingBottom:4}),u("Why subscribers are paying for slower, deeper coverage — and what it means for publishers.",{paddingBottom:8}),u("Read more →",{color:"{colors.primary}",fontWeight:"bold",paddingBottom:24,link:"#"})])},{type:"content.image_text",category:"content",name:"Image + Text Beside",description:"Image with article title and short summary stacked below. Standard editorial card.",tags:["image","text","article","stacked"],create:()=>h("content.image_text","Image + Text",[M(A(560,300,"Article"),"Article",{width:560}),I("Article title",{paddingTop:16,paddingBottom:4}),u("A short summary of the article goes here, two or three lines is plenty.")])},{type:"content.two_column_articles",category:"content",name:"Two Column Stories",description:"Two short article previews shown side-by-side as stacked blocks (renders as full-width on mobile). Use to tease two related stories.",tags:["two-column","articles","side-by-side","preview"],create:()=>h("content.two_column_articles","Two Stories",[Y("More to read"),M(A(272,180,"Story A"),"Story A",{width:272}),u("Story A title",{fontWeight:"bold",paddingTop:4,paddingBottom:2}),u("One sentence about story A.",{fontSize:14,paddingBottom:16}),M(A(272,180,"Story B"),"Story B",{width:272}),u("Story B title",{fontWeight:"bold",paddingTop:4,paddingBottom:2}),u("One sentence about story B.",{fontSize:14,paddingBottom:16})])},{type:"content.three_picks",category:"content",name:"Three Picks (Numbered)",description:"Numbered list of three short recommendations or links. Used by curators ('3 things to read this week').",tags:["list","picks","curated","links","recommendations"],create:()=>h("content.three_picks","Three Picks",[Y("Three picks"),u("01 / How to stay focused in 2026",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:8,paddingBottom:4,link:"#"}),v("Notes on attention, deep work, and the slow internet.",{fontSize:14}),U({paddingTop:12,paddingBottom:8}),u("02 / The case for boring software",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:8,paddingBottom:4,link:"#"}),v("Why teams are returning to simpler, predictable tools.",{fontSize:14}),U({paddingTop:12,paddingBottom:8}),u("03 / A short history of the inbox",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:8,paddingBottom:4,link:"#"}),v("From memos to MIME, and what comes next.",{fontSize:14,paddingBottom:24})])},{type:"content.quote",category:"content",name:"Pull Quote",description:"Centered serif pull quote with attribution. Adds rhythm to long editorial newsletters.",tags:["quote","pull-quote","editorial","attribution"],create:()=>h("content.quote","Pull Quote",[u("“The best way to predict the future is to create it.”",{fontFamily:"{fonts.heading}",fontSize:22,align:"center",paddingTop:24,lineHeight:1.4}),u("— Peter Drucker",{color:"{colors.muted}",align:"center",paddingBottom:24})])},{type:"content.author_byline",category:"content",name:"Author Byline",description:"Round avatar + author name + role on one line. Drop above or below an article body for personal newsletters.",tags:["author","byline","avatar","personal"],create:()=>h("content.author_byline","Byline",[M(A(64,64,"👤"),"Author",{width:64,borderRadius:32,paddingTop:16,paddingBottom:0}),u("Jane Doe",{align:"center",fontWeight:"bold",paddingTop:8,paddingBottom:0}),v("Editor, The Weekly",{align:"center",fontSize:13}),F(16)])},{type:"content.editor_note",category:"content",name:"Editor's Note",description:"Personal letter-style block: 'Hi {{first_name}}', a few paragraphs and a sign-off. Ideal for newsletters with a strong author voice.",tags:["editor","note","letter","personal","voice"],create:()=>h("content.editor_note","Editor's Note",[u("Hi {{first_name}},",{paddingTop:24,paddingBottom:8}),u("This week I've been thinking about what makes a newsletter feel like a letter rather than a broadcast. Spoiler: it's not the format, it's the tone.",{paddingBottom:8,lineHeight:1.7}),u("Let me know what you think — just hit reply.",{paddingBottom:8,lineHeight:1.7}),u("— Jane",{fontFamily:"{fonts.heading}",paddingBottom:24})])},{type:"content.tip_box",category:"content",name:"Tip / Callout Box",description:"Highlighted background box with an icon, short title and one-paragraph tip. Use for 'pro tips', notes, and warnings.",tags:["tip","callout","box","highlight","note"],create:()=>h("content.tip_box","Tip Box",[u("💡 PRO TIP",{color:"{colors.primary}",fontSize:12,fontWeight:"bold",letterSpacing:2,paddingTop:16,paddingBottom:4}),u("Always preview your email on mobile before sending — most opens happen there.",{paddingBottom:16})],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0,paddingLeft:16,paddingRight:16})},{type:"content.numbered_list",category:"content",name:"Numbered List",description:"Vertical numbered list of 4-5 short items with optional sub-text. Use for tutorials, checklists and 'how-to' newsletters.",tags:["list","numbered","tutorial","checklist","how-to"],create:()=>h("content.numbered_list","Numbered List",[I("How to do it in 4 steps",{paddingTop:16,paddingBottom:12}),u("1. Define the goal",{fontWeight:"bold",paddingTop:4,paddingBottom:2}),v("Write down the outcome in one sentence."),u("2. List constraints",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("Time, budget, scope. Be specific."),u("3. Plan the smallest version",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("What can you ship this week?"),u("4. Ship it",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("Refine after real feedback.",{fontSize:14}),F(16)])},{type:"content.bullet_list",category:"content",name:"Bullet List",description:"Simple unordered list of takeaways or facts. Concise summary block.",tags:["list","bullets","takeaways","summary"],create:()=>h("content.bullet_list","Bullets",[I("Key takeaways",{paddingTop:16,paddingBottom:8}),u("• Newsletters are growing 20% YoY",{paddingTop:2,paddingBottom:2}),u("• Mobile opens crossed 70%",{paddingTop:2,paddingBottom:2}),u("• Plain-text emails outperform image-heavy ones in B2B",{paddingTop:2,paddingBottom:2}),u("• Personalization drives 2x click-through",{paddingTop:2,paddingBottom:16})])},{type:"content.qa",category:"content",name:"Q&A Block",description:"Question in bold followed by an answer paragraph. Use for FAQ, reader mailbags, or AMAs.",tags:["qa","faq","ama","mailbag","reader-questions"],create:()=>h("content.qa","Q&A",[Y("Reader question"),u("Q: How do I get my first 100 subscribers?",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:4,paddingBottom:8,lineHeight:1.3}),u("A: Tell ten people who already know you. Then ask each of them to forward to one friend. The first 100 don't come from algorithms — they come from your network.",{paddingBottom:24,lineHeight:1.7})])},{type:"content.stats_row",category:"content",name:"Stat Row",description:"Big numbers with short labels (e.g. '12k readers · 4.8★ rating · 96% open rate'). Used for impact summaries and social proof.",tags:["stats","numbers","metrics","social-proof"],create:()=>h("content.stats_row","Stat Row",[Y("By the numbers",{align:"center"}),u("12,400",{fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",color:"{colors.primary}",paddingTop:4,paddingBottom:0}),v("active readers this month",{align:"center",fontSize:13}),F(8),u("96% · 4.8★ · 32 issues shipped",{align:"center",color:"{colors.text}",fontSize:14,paddingBottom:24})])},{type:"content.timeline",category:"content",name:"Timeline / What Happened",description:"Chronological list of recent events with dates. Used by news roundups and changelog newsletters.",tags:["timeline","changelog","news","events","what-happened"],create:()=>h("content.timeline","Timeline",[Y("This week"),u("Mon · Acme launches plan B",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("After 6 months of beta testing.",{fontSize:14}),u("Wed · New funding round announced",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("$24M Series A led by Foundry.",{fontSize:14}),u("Fri · Industry report drops",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("Open rates up across the board.",{fontSize:14,paddingBottom:24})])},{type:"content.podcast_episode",category:"content",name:"Podcast Episode",description:"Episode artwork, episode number, title, short description and a 'Listen' button. For shows that announce episodes by email.",tags:["podcast","episode","audio","listen","show"],create:()=>h("content.podcast_episode","Podcast Episode",[M(A(220,220,"Cover"),"Cover",{width:220,borderRadius:12}),u("EPISODE 042",{color:"{colors.primary}",fontSize:11,fontWeight:"bold",letterSpacing:2,align:"center",paddingTop:12,paddingBottom:4}),I("Why publishers are betting on email",{align:"center",paddingTop:0,paddingBottom:4}),v("With Jane Doe · 38 min",{align:"center",fontSize:13}),H("Listen now","https://example.com"),F(16)])},{type:"content.video_thumbnail",category:"content",name:"Video Thumbnail",description:"Video thumbnail with overlay-feeling play button (image only, links to a hosted player). Title and duration below.",tags:["video","thumbnail","watch","play","media"],create:()=>h("content.video_thumbnail","Video",[M(A(560,315,"▶ Watch"),"Video",{width:560,link:"#",borderRadius:8}),I("Watch: a guided tour of our 2026 launches",{paddingTop:12,paddingBottom:4}),v("4 min watch",{fontSize:13,paddingBottom:16})])},{type:"content.event_card",category:"content",name:"Event Card",description:"Date badge with event title, location, time and an RSVP button. For event-driven newsletters and community digests.",tags:["event","rsvp","community","date","card"],create:()=>h("content.event_card","Event",[u("MAY",{align:"center",color:"{colors.buttonText}",fontSize:12,fontWeight:"bold",letterSpacing:2,paddingTop:12,paddingBottom:0}),u("12",{align:"center",color:"{colors.buttonText}",fontSize:36,fontWeight:"bold",paddingTop:0,paddingBottom:12})],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"content.code_block",category:"content",name:"Code Snippet",description:"Monospaced code block on a tinted background. For developer newsletters and changelog excerpts.",tags:["code","snippet","developer","monospace","changelog"],create:()=>h("content.code_block","Code",[u("npm install openpostcards-builder",{fontFamily:"Menlo, Consolas, monospace",fontSize:13,color:"{colors.text}",paddingTop:16,paddingBottom:16,paddingLeft:16,paddingRight:16})],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0,paddingLeft:16,paddingRight:16})}],ns=[{type:"feature.list",category:"feature",name:"Checkmark Feature List",description:"Centered title with 3-4 short checkmarked benefits. Good for product newsletters and onboarding emails.",tags:["features","benefits","checkmarks","list"],create:()=>h("feature.list","Feature List",[I("Why people love it",{align:"center",paddingTop:24}),u("✓ Fast and reliable",{align:"center"}),u("✓ Beautiful out of the box",{align:"center"}),u("✓ Backed by humans, not bots",{align:"center",paddingBottom:24})])},{type:"feature.icon_three",category:"feature",name:"Three Icon Features",description:"Three stacked feature blocks with an emoji/icon, short title and one-line description. Use to highlight 3 product capabilities.",tags:["features","icons","three-up","product"],create:()=>h("feature.icon_three","Three Features",[u("⚡",{align:"center",fontSize:32,paddingTop:24,paddingBottom:4}),u("Fast",{align:"center",fontWeight:"bold",paddingBottom:2}),v("Built to render in milliseconds.",{align:"center",fontSize:14}),F(16),u("🧩",{align:"center",fontSize:32,paddingBottom:4}),u("Modular",{align:"center",fontWeight:"bold",paddingBottom:2}),v("Compose any layout from blocks.",{align:"center",fontSize:14}),F(16),u("🤖",{align:"center",fontSize:32,paddingBottom:4}),u("AI-ready",{align:"center",fontWeight:"bold",paddingBottom:2}),v("Edit emails as JSON, not HTML.",{align:"center",fontSize:14,paddingBottom:24})])},{type:"feature.before_after",category:"feature",name:"Before / After",description:"Two stacked images labeled 'Before' and 'After'. For product transformations, redesigns and case studies.",tags:["before-after","comparison","case-study","transformation"],create:()=>h("feature.before_after","Before / After",[Y("Before"),M(A(560,280,"Before"),"Before",{width:560}),F(8),Y("After"),M(A(560,280,"After"),"After",{width:560}),F(16)])},{type:"feature.benefit_pair",category:"feature",name:"Image + Benefit Pair",description:"Repeat-use block: one supporting image plus a title and benefit paragraph beside it. Stack 2-3 of these for a feature tour.",tags:["benefit","feature","image-text","pair"],create:()=>h("feature.benefit_pair","Benefit Pair",[M(A(560,240,"Feature"),"Feature",{width:560,paddingTop:16}),I("Send 10x faster",{paddingTop:12,paddingBottom:4}),u("Reusable modules and theme tokens let teams ship campaigns in minutes, not days.",{paddingBottom:24})])},{type:"feature.testimonial",category:"feature",name:"Testimonial",description:"Customer quote in large type with avatar and attribution. Social proof block.",tags:["testimonial","review","social-proof","customer"],create:()=>h("feature.testimonial","Testimonial",[u("“This cut our email production from a week to an afternoon.”",{fontFamily:"{fonts.heading}",fontSize:22,align:"center",paddingTop:24,paddingBottom:12,lineHeight:1.4}),M(A(56,56,"👤"),"Customer",{width:56,borderRadius:28}),u("Alex Kim · Head of Lifecycle, Acme",{align:"center",color:"{colors.muted}",fontSize:13,paddingTop:4,paddingBottom:24})])},{type:"feature.logo_strip",category:"feature",name:"Customer Logo Strip",description:"Small horizontal row implying customer logos for credibility ('Trusted by'). Logos shown as a placeholder image.",tags:["logos","trusted-by","social-proof","strip"],create:()=>h("feature.logo_strip","Logo Strip",[v("TRUSTED BY",{align:"center",fontSize:11}),M(A(520,60,"LOGOS"),"Customer logos",{width:520,paddingTop:8,paddingBottom:16})])}],os=[{type:"cta.simple",category:"call_to_action",name:"Simple CTA",description:"Centered headline + body + primary button. The default call-to-action block for any newsletter or promo.",tags:["cta","primary","centered","button"],create:()=>h("cta.simple","Simple CTA",[I("Ready to get started?",{align:"center",paddingTop:24}),v("Create better emails faster.",{align:"center"}),H("Start now","https://example.com"),F(16)])},{type:"cta.banner",category:"call_to_action",name:"Colored Banner CTA",description:"Full-width colored band with eyebrow, big headline and a contrasting button. Use to draw attention to sales or launches.",tags:["cta","banner","colored","promo","sale"],create:()=>h("cta.banner","CTA Banner",[u("Limited time offer",{color:"{colors.buttonText}",align:"center",fontSize:14,paddingTop:24,paddingBottom:4}),u("Save 30% this week only",{color:"{colors.buttonText}",align:"center",fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",paddingBottom:16}),H("Shop the sale"),F(24)],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"cta.button_only",category:"call_to_action",name:"Button Only",description:"Single primary button on a clean background. Use as a follow-up CTA after a content block.",tags:["cta","button","minimal"],create:()=>h("cta.button_only","Button",[H("Click here","https://example.com")])},{type:"cta.dual_button",category:"call_to_action",name:"Two Button Choice",description:"Two side-by-side actions: a primary and a ghost-styled secondary. Use when offering 'Learn more' vs 'Get started'.",tags:["cta","buttons","two-options","choice"],create:()=>h("cta.dual_button","Two Buttons",[I("Pick your path",{align:"center",paddingTop:24}),v("Choose what fits your team.",{align:"center"}),H("Get started","https://example.com"),H("Learn more","https://example.com",{backgroundColor:"transparent",color:"{colors.primary}"}),F(16)])},{type:"cta.image_overlay",category:"call_to_action",name:"Image + Overlay CTA",description:"Lead image with a headline, supporting text, and a button immediately below. Strong visual call to action.",tags:["cta","image","visual","hero"],create:()=>h("cta.image_overlay","Image CTA",[M(A(560,280,"Visual"),"Visual",{width:560,paddingTop:16}),I("Stop guessing. Start measuring.",{align:"center",paddingTop:16}),v("Free for 14 days. No credit card.",{align:"center"}),H("Try it free"),F(16)])},{type:"cta.subscribe",category:"call_to_action",name:"Subscribe / Forward",description:"Friendly 'Was this forwarded? Subscribe' block that grows the list virally. Common at the end of newsletters.",tags:["cta","subscribe","forward","growth","newsletter"],create:()=>h("cta.subscribe","Subscribe",[Y("Was this forwarded?",{align:"center"}),I("Get the next issue in your inbox",{align:"center",paddingTop:0,paddingBottom:8}),H("Subscribe free"),F(16)],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0})},{type:"cta.referral",category:"call_to_action",name:"Referral / Share",description:"Encourages readers to share the newsletter with a unique referral link. Includes a 'Share' button and a personalized URL.",tags:["cta","referral","share","viral","growth"],create:()=>h("cta.referral","Referral",[Y("Tell a friend",{align:"center"}),I("Share & earn perks",{align:"center",paddingTop:0,paddingBottom:8}),v("Refer 3 friends and unlock the bonus issue.",{align:"center"}),u("yourname.com/r/abc123",{align:"center",color:"{colors.primary}",fontFamily:"Menlo, Consolas, monospace",fontSize:14,paddingTop:8,paddingBottom:8}),H("Share now"),F(16)])},{type:"cta.upgrade",category:"call_to_action",name:"Upgrade / Paid",description:"Conversion block that promotes a paid plan or premium tier. Includes price, benefits and an upgrade button.",tags:["cta","upgrade","paid","premium","conversion"],create:()=>h("cta.upgrade","Upgrade",[Y("Become a member",{align:"center"}),I("$5 / month",{align:"center",level:1}),v("Unlock the archive, weekly bonus and member chat.",{align:"center",fontSize:14}),H("Upgrade"),F(16)],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0})},{type:"cta.feedback",category:"call_to_action",name:"Feedback Reply",description:"Asks the reader to reply with feedback ('Hit reply and let me know'). Personal, no button.",tags:["cta","feedback","reply","personal"],create:()=>h("cta.feedback","Feedback",[u("How did this issue land for you? Just hit reply — I read every message.",{align:"center",paddingTop:24,paddingBottom:24,lineHeight:1.6})])}],rs=[{type:"ecom.product_single",category:"ecommerce",name:"Single Product",description:"One product with image, title, price, short description and Buy button. Use to feature a hero product. Supports old/final price and per-product link.",tags:["product","single","buy","hero"],create:()=>h("ecom.product_single","Single Product",[Ee([q({name:"Linen Tote Bag",image:A(560,400,"Product"),oldPrice:"$59.00",finalPrice:"$39.00",description:"Heavyweight natural linen, made in Portugal."})],{columns:1,showOldPrice:!0,showDescription:!0,buttonLabel:"Buy now"})])},{type:"ecom.product_grid_2",category:"ecommerce",name:"Product Grid (2 up)",description:"Two products side-by-side on desktop, stacked on mobile. Each card has image, name, old/final price, optional description and Shop button. Curated picks layout.",tags:["product","grid","two-up","curated","responsive"],create:()=>h("ecom.product_grid_2","Product Grid 2",[Ee([q({name:"Product A",finalPrice:"$29",oldPrice:"$39"}),q({name:"Product B",finalPrice:"$34",oldPrice:"$45"})],{columns:2,showOldPrice:!0})])},{type:"ecom.product_grid_3",category:"ecommerce",name:"Product Grid (3 up)",description:"Three product cards in a row on desktop, stacked on mobile. Use for 'New arrivals' or 'Bestsellers' rows.",tags:["product","grid","three-up","bestsellers","new-arrivals","responsive"],create:()=>h("ecom.product_grid_3","Product Grid 3",[Y("New arrivals",{align:"center"}),Ee([q({name:"Product 1",finalPrice:"$19"}),q({name:"Product 2",finalPrice:"$24"}),q({name:"Product 3",finalPrice:"$32"})],{columns:3,showOldPrice:!1})])},{type:"ecom.collection_banner",category:"ecommerce",name:"Collection Banner",description:"Wide collection banner with title and 'Shop the collection' button overlaying or under an image. Use for category drops.",tags:["collection","banner","category","drop"],create:()=>h("ecom.collection_banner","Collection",[M(A(560,300,"Collection"),"Collection",{width:560}),I("Spring Collection 2026",{align:"center",paddingTop:16}),v("Lighter fabrics, brighter colors.",{align:"center"}),H("Shop the collection"),F(16)])},{type:"ecom.discount",category:"ecommerce",name:"Discount Code",description:"Big discount code in monospaced caps with 'Your code' label and a Redeem button.",tags:["discount","promo","code","coupon"],create:()=>h("ecom.discount","Discount Code",[v("Your code",{align:"center"}),u("SAVE20",{fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",color:"{colors.primary}",letterSpacing:4,paddingTop:4,paddingBottom:16}),H("Redeem"),F(24)])},{type:"ecom.flash_sale",category:"ecommerce",name:"Flash Sale Banner",description:"Urgency-driven banner with countdown-style copy ('Ends in 24h'), discount value and a shop button.",tags:["flash-sale","urgency","promo","banner","countdown"],create:()=>h("ecom.flash_sale","Flash Sale",[u("⏰ FLASH SALE — ENDS IN 24H",{color:"{colors.buttonText}",align:"center",fontWeight:"bold",letterSpacing:2,paddingTop:16,paddingBottom:4}),u("Up to 50% off everything",{color:"{colors.buttonText}",align:"center",fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",paddingBottom:12}),H("Shop now","#",{backgroundColor:"{colors.surface}",color:"{colors.primary}"}),F(16)],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"ecom.abandoned_cart",category:"ecommerce",name:"Abandoned Cart Reminder",description:"Friendly reminder showing the items left in the cart with a return-to-cart button. For cart recovery automations.",tags:["abandoned-cart","recovery","automation","reminder"],create:()=>h("ecom.abandoned_cart","Abandoned Cart",[I("You left something behind",{align:"center",paddingTop:16}),v("Pick up where you left off.",{align:"center"}),F(8),Ee([q({name:"Linen Tote Bag",image:A(400,400,"Item"),finalPrice:"$39",oldPrice:"$49"})],{columns:1,showOldPrice:!0,buttonLabel:"Return to cart"})])},{type:"ecom.review_request",category:"ecommerce",name:"Review Request",description:"Post-purchase block asking for a 1-5 star rating with stacked star buttons. For review-collection emails.",tags:["review","rating","post-purchase","feedback"],create:()=>h("ecom.review_request","Review",[I("How did we do?",{align:"center",paddingTop:24}),v("Tap a star to leave a quick review.",{align:"center"}),u("☆ ☆ ☆ ☆ ☆",{align:"center",fontSize:32,color:"{colors.primary}",paddingTop:12,paddingBottom:24,link:"#"})])},{type:"ecom.gift_guide",category:"ecommerce",name:"Gift Guide Pick",description:"Editorial gift-guide pick: persona eyebrow + a single product card with full details (image, name, old/final price, description, CTA).",tags:["gift-guide","curated","editorial","holiday"],create:()=>h("ecom.gift_guide","Gift Pick",[Y("For the home cook"),Ee([q({name:"Cast Iron Skillet",image:A(560,300,"Pick"),oldPrice:"$119",finalPrice:"$89",description:"Pre-seasoned, lifetime-guarantee. Made in USA."})],{columns:1,showOldPrice:!0,showDescription:!0,buttonLabel:"View product"})])},{type:"ecom.bestseller_list",category:"ecommerce",name:"Bestseller Grid",description:"Top products grid (3 up) with old/final prices. Used by retailers for weekly bestsellers.",tags:["bestsellers","grid","ranking","top"],create:()=>h("ecom.bestseller_list","Bestsellers",[Y("Top 3 this week"),Ee([q({name:"Linen Tote",finalPrice:"$39",oldPrice:"$49"}),q({name:"Ceramic Mug",finalPrice:"$24"}),q({name:"Brass Lamp",finalPrice:"$129",oldPrice:"$149"})],{columns:3,showOldPrice:!0})])}],is=[{type:"tx.order_summary",category:"transactional",name:"Order Summary",description:"Order confirmation summary: order number, line items with thumbnails and totals row. Used in post-purchase emails.",tags:["order","summary","receipt","post-purchase","ecommerce"],create:()=>h("tx.order_summary","Order Summary",[Y("Order #1024"),I("Thanks for your order",{paddingTop:0}),v("We'll email you again when it ships."),U({paddingTop:16,paddingBottom:8}),u("Linen Tote Bag · 1 × $39.00",{paddingTop:4,paddingBottom:4}),u("Ceramic Mug · 2 × $24.00",{paddingTop:4,paddingBottom:4}),U({paddingTop:8,paddingBottom:8}),u("Subtotal: $87.00",{paddingTop:2,paddingBottom:2}),u("Shipping: $5.00",{paddingTop:2,paddingBottom:2}),u("Total: $92.00",{fontWeight:"bold",paddingTop:2,paddingBottom:16})])},{type:"tx.shipping_update",category:"transactional",name:"Shipping Update",description:"Shipping confirmation with tracking number, carrier, expected delivery date and a Track button.",tags:["shipping","tracking","delivery","post-purchase"],create:()=>h("tx.shipping_update","Shipping Update",[u("📦",{align:"center",fontSize:40,paddingTop:24}),I("Your order is on the way",{align:"center",paddingTop:8}),v("Carrier: USPS · Expected: May 4, 2026",{align:"center"}),u("Tracking: 9400 1108 ...",{align:"center",color:"{colors.muted}",fontFamily:"Menlo, Consolas, monospace",fontSize:13}),H("Track package"),F(16)])},{type:"tx.invoice",category:"transactional",name:"Invoice",description:"Itemized invoice with billing period, services and totals. Used by SaaS and B2B billing emails.",tags:["invoice","billing","saas","b2b","receipt"],create:()=>h("tx.invoice","Invoice",[Y("Invoice INV-2026-04"),I("April 2026 invoice"),v("Billed to: Acme Inc · Period: Apr 1 – Apr 30"),U({paddingTop:16,paddingBottom:8}),u("Pro plan · $49.00",{paddingTop:4,paddingBottom:4}),u("Add-on seats (3) · $36.00",{paddingTop:4,paddingBottom:4}),U({paddingTop:8,paddingBottom:8}),u("Total due: $85.00",{fontWeight:"bold",paddingBottom:16}),H("Download invoice (PDF)"),F(16)])},{type:"tx.password_reset",category:"transactional",name:"Password Reset",description:"Authentication email with a reset button and a fallback link. Includes 'expires in X minutes' notice.",tags:["auth","password","reset","security"],create:()=>h("tx.password_reset","Password Reset",[I("Reset your password",{align:"center",paddingTop:16}),u("Click the button below to set a new password. This link expires in 30 minutes.",{align:"center",paddingBottom:16}),H("Reset password"),v("If the button doesn't work, paste this link in your browser:",{align:"center",fontSize:12}),u("https://example.com/reset/abc123",{align:"center",color:"{colors.primary}",fontSize:12,paddingBottom:24})])},{type:"tx.verify_email",category:"transactional",name:"Verify Email",description:"Single-purpose 'verify your email' transactional with one centered button.",tags:["auth","verify","email-confirmation"],create:()=>h("tx.verify_email","Verify Email",[I("One last step",{align:"center",paddingTop:16}),u("Confirm your email address to activate your account.",{align:"center",paddingBottom:8}),H("Verify email"),F(24)])},{type:"tx.appointment",category:"transactional",name:"Appointment Confirmation",description:"Booking/meeting confirmation with date, time, location and add-to-calendar links.",tags:["appointment","booking","calendar","meeting"],create:()=>h("tx.appointment","Appointment",[Y("Confirmed",{align:"center"}),I("Your appointment is set",{align:"center",paddingTop:0}),u("Tuesday, May 12 · 10:00 AM",{align:"center",fontWeight:"bold",paddingTop:8}),v("123 Main St, Suite 4 · Brooklyn, NY",{align:"center"}),H("Add to calendar"),F(16)])}],as=[{type:"social.icons",category:"social",name:"Social Icons Row",description:"Centered 'Follow us' label with text-link icons in a row. Light footer-style social block.",tags:["social","follow","icons","row"],create:()=>h("social.icons","Social Icons",[v("Follow us",{align:"center"}),u("Twitter · Instagram · LinkedIn · YouTube",{align:"center",color:"{colors.primary}",paddingBottom:16})])},{type:"social.share",category:"social",name:"Share This Email",description:"'Share this email' bar with Forward · Tweet · Share text links. Used at the end of newsletters.",tags:["social","share","forward","viral"],create:()=>h("social.share","Share Bar",[u("Share this email",{align:"center",paddingTop:8}),u("Forward · Tweet · Share",{align:"center",color:"{colors.primary}",paddingBottom:8})])},{type:"social.featured_post",category:"social",name:"Featured Social Post",description:"Embed-style preview of a single social post: avatar, name, post text and a link to view it on the platform.",tags:["social","post","embed","twitter","instagram"],create:()=>h("social.featured_post","Social Post",[Y("From the community"),M(A(48,48,"👤"),"Avatar",{width:48,borderRadius:24}),u("@maker · 2h",{color:"{colors.muted}",fontSize:13,paddingTop:4,paddingBottom:4}),u(`"Just shipped my newsletter using OpenPostcards. Honestly the smoothest email build I've ever done."`,{paddingBottom:8,lineHeight:1.6}),u("View on Twitter →",{color:"{colors.primary}",paddingBottom:16,link:"#"})])},{type:"social.instagram_grid",category:"social",name:"Instagram Grid",description:"3 small square thumbnails in a row representing recent Instagram posts, with handle and link.",tags:["social","instagram","grid","thumbnails"],create:()=>h("social.instagram_grid","IG Grid",[v("@youraccount on Instagram",{align:"center"}),M(A(180,180,"1"),"Post 1",{width:180}),M(A(180,180,"2"),"Post 2",{width:180}),M(A(180,180,"3"),"Post 3",{width:180}),u("View profile →",{align:"center",color:"{colors.primary}",paddingTop:8,paddingBottom:16,link:"#"})])},{type:"social.community_stats",category:"social",name:"Community Stats",description:"Short '12k Twitter · 4k IG · 2k YT' style row used to show following sizes.",tags:["social","stats","community","following"],create:()=>h("social.community_stats","Community Stats",[Y("Join the community",{align:"center"}),u("12k Twitter · 4k Instagram · 2k YouTube",{align:"center",paddingBottom:16}),F(8)])}],Ie={backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0},ss=[{type:"footer.simple",category:"footer",name:"Simple Footer",description:"Minimal footer with copyright, address and unsubscribe links. The default for any newsletter.",tags:["footer","simple","copyright","unsubscribe"],create:()=>h("footer.simple","Simple Footer",[v("© 2026 Your Company. All rights reserved.",{align:"center",fontSize:12}),v("123 Main St · City · Country",{align:"center",fontSize:12}),u("Unsubscribe · View in browser",{align:"center",color:"{colors.muted}",fontSize:12,paddingTop:4,paddingBottom:24})],{...Ie,paddingTop:24})},{type:"footer.social",category:"footer",name:"Footer with Social",description:"Footer with social links row above the legal text.",tags:["footer","social","links"],create:()=>h("footer.social","Social Footer",[u("Follow us",{align:"center",paddingTop:24}),u("Twitter · Instagram · LinkedIn",{align:"center",color:"{colors.primary}",paddingBottom:12}),U(),v("© 2026 Your Company · Unsubscribe",{align:"center",fontSize:12}),u(" ",{align:"center",paddingBottom:24})],Ie)},{type:"footer.legal",category:"footer",name:"Legal Footer",description:"Long-form footer with explanation of why the user is receiving the email plus privacy/terms/unsubscribe links. Used by enterprise and finance newsletters.",tags:["footer","legal","compliance","enterprise"],create:()=>h("footer.legal","Legal Footer",[u("You are receiving this email because you signed up for our newsletter. If you no longer wish to receive emails, you can unsubscribe at any time.",{align:"center",color:"{colors.muted}",fontSize:11,lineHeight:1.6,paddingTop:24}),u("Privacy Policy · Terms · Unsubscribe",{align:"center",color:"{colors.muted}",fontSize:11,paddingBottom:24})],Ie)},{type:"footer.publisher",category:"footer",name:"Publisher Footer",description:"Magazine-style sign-off with logo, publication name, masthead credits, address and links.",tags:["footer","publisher","magazine","masthead","editorial"],create:()=>h("footer.publisher","Publisher Footer",[M(A(120,36,"LOGO"),"Logo",{width:120,paddingTop:24,paddingBottom:8}),u("THE WEEKLY",{align:"center",fontFamily:"{fonts.heading}",fontWeight:"bold",letterSpacing:4,paddingTop:0,paddingBottom:4}),v("Editor: Jane Doe · Producer: Alex Kim",{align:"center",fontSize:12}),U({paddingTop:12,paddingBottom:12}),v("© 2026 The Weekly · 350 Madison Ave · NY 10017",{align:"center",fontSize:11}),u("Manage preferences · Unsubscribe",{align:"center",color:"{colors.muted}",fontSize:11,paddingTop:4,paddingBottom:24})],Ie)},{type:"footer.app_links",category:"footer",name:"Footer with App Store Badges",description:"Footer including 'Get the app' app-store and play-store badge images. For consumer brand newsletters.",tags:["footer","app","download","ios","android"],create:()=>h("footer.app_links","App Footer",[u("Get the app",{align:"center",fontWeight:"bold",paddingTop:24,paddingBottom:8}),M(A(135,40,"App Store"),"App Store",{width:135,align:"center",paddingTop:0,paddingBottom:4}),M(A(135,40,"Google Play"),"Google Play",{width:135,align:"center",paddingTop:0,paddingBottom:16}),U(),v("© 2026 Your Brand · Unsubscribe",{align:"center",fontSize:11}),u(" ",{align:"center",paddingBottom:24})],Ie)},{type:"footer.address_only",category:"footer",name:"Address Only",description:"Just a centered postal address line — required for CAN-SPAM compliance when other footers are minimal.",tags:["footer","address","compliance","can-spam"],create:()=>h("footer.address_only","Address",[v("Your Company · 123 Main St · Brooklyn, NY 11201 · USA",{align:"center",fontSize:11}),u(" ",{align:"center",paddingBottom:16})],{...Ie,paddingTop:16})},{type:"footer.preferences",category:"footer",name:"Manage Preferences",description:"Footer that emphasizes preference management ('Update your preferences', 'Send less often'). Reduces unsubscribes.",tags:["footer","preferences","frequency","retention"],create:()=>h("footer.preferences","Preferences",[u("Getting too many emails?",{align:"center",paddingTop:24,paddingBottom:4}),u("Update your preferences · Send less often · Unsubscribe",{align:"center",color:"{colors.primary}",fontSize:13,paddingBottom:16}),U(),v("© 2026 Your Company",{align:"center",fontSize:11}),u(" ",{align:"center",paddingBottom:24})],Ie)},{type:"footer.signature",category:"footer",name:"Signature Sign-off",description:"Personal hand-signed style sign-off with author name and tiny legal block. For solo creator newsletters.",tags:["footer","signature","personal","creator","sign-off"],create:()=>h("footer.signature","Signature",[u("Until next week,",{paddingTop:24,paddingBottom:4}),u("— Jane",{fontFamily:"{fonts.heading}",fontSize:22,paddingBottom:16}),U(),v("Reply directly · Unsubscribe · 123 Main St, Brooklyn",{fontSize:11,align:"center"}),u(" ",{align:"center",paddingBottom:24})],{...Ie,paddingTop:0})}],ls=[...Qa,...Za,...es,...ts,...ns,...os,...rs,...is,...as,...ss];let ao=!1;function _o(){if(!ao){for(const e of ls)Ze.register(e);ao=!0}}_o();function ds(){const{doc:e,addModule:t,loadFromLocalStorage:n}=O();return g.useEffect(()=>{if(n(),O.getState().doc.modules.length===0){const r=["header.hero","content.headline_body","cta.simple","footer.simple"];for(const i of r){const a=Ze.get(i);a&&t(a.create())}O.setState({selection:{kind:"email"},past:[],future:[]})}},[]),g.useEffect(()=>{const r=setTimeout(()=>O.getState().saveToLocalStorage(),500);return()=>clearTimeout(r)},[e]),o.jsxs("div",{className:"h-screen w-screen flex flex-col bg-gray-100",children:[o.jsx(Tr,{}),o.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[o.jsx(Rr,{}),o.jsx(xa,{}),o.jsx(_a,{})]})]})}const cs=e=>{if(e&&typeof e=="object"&&"url"in e&&typeof e.url=="string"){const t=e;return{url:t.url,alt:typeof t.alt=="string"?t.alt:void 0}}throw new Error('Server response missing "url" string field.')};function us(e){const t=e.fieldName??"file",n=(e.maxSizeMB??10)*1024*1024,r=e.transformResponse??cs;return{upload(i){return i.type.startsWith("image/")?i.size>n?Promise.reject(new Error(`File too large: ${(i.size/1024/1024).toFixed(2)} MB > ${e.maxSizeMB??10} MB`)):new Promise((a,s)=>{const d=new XMLHttpRequest,l=new FormData;if(l.append(t,i,i.name),d.open("POST",e.endpoint,!0),d.withCredentials=!!e.withCredentials,e.headers)for(const[c,m]of Object.entries(e.headers))d.setRequestHeader(c,m);e.onProgress&&d.upload&&(d.upload.onprogress=c=>{c.lengthComputable&&e.onProgress(Math.round(c.loaded/c.total*100))}),d.onload=()=>{const c=d.status>=200&&d.status<300;let m=null;try{m=d.responseText?JSON.parse(d.responseText):null}catch{}if(!c){const p=(m&&typeof m=="object"&&"error"in m&&typeof m.error=="string"?m.error:null)??`Upload failed (HTTP ${d.status})`;return s(new Error(p))}try{a(r(m))}catch(p){s(p instanceof Error?p:new Error(String(p)))}},d.onerror=()=>s(new Error("Network error during upload")),d.onabort=()=>s(new Error("Upload aborted")),d.send(l)}):Promise.reject(new Error(`Not an image: ${i.type||"unknown"}`))}}}function gs(e){return{name:"image-uploader",type:"asset-provider",setup(t){t.registerAssetProvider(us(e))}}}function Wo(e){return g.useEffect(()=>{if(_o(),e.modules)for(const n of e.modules)Ze.register(n);if(e.themes&&O.setState({themes:e.themes}),e.aiProvider&&Lo.setAIProvider(e.aiProvider),e.initialDocument){const n=Wt.safeParse(e.initialDocument);n.success&&O.getState().applyDoc(n.data,!1)}const t=O.subscribe((n,r)=>{n.doc!==r.doc&&e.onChange?.(n.doc)});return()=>t()},[]),g.useEffect(()=>{if(e.onExportHtml)return O.subscribe((t,n)=>{t.doc!==n.doc&&e.onExportHtml?.(xn(t.doc))})},[e.onExportHtml]),g.createElement(ds)}function ps(e){const t=Ko.createRoot(e.container);return t.render(g.createElement(Wo,e)),{destroy:()=>t.unmount(),getDocument:()=>O.getState().doc,exportHtml:()=>O.getState().exportHtml(),exportJson:()=>O.getState().exportJson()}}exports.ALGORITHMS=An;exports.ALGORITHM_BY_ID=Mo;exports.EmailBuilder=Wo;exports.FALLBACK_OPTIONS=bn;exports.TEMPLATE_CATEGORY_LABELS=vn;exports.createEmailBuilder=ps;exports.defaultRecommendationsLogic=Io;exports.documentSchema=Wt;exports.imageUploaderPlugin=gs;exports.readRecommendationsLogic=$o;exports.recommendationsToLegacyShape=Pa;exports.registerPlugin=Aa;exports.renderEmailHtml=xn;exports.templateRegistry=ke;
|
|
79
|
+
`),onChange:l=>n({content:l.target.value.replace(/\n/g,"<br/>")}),rows:3,className:"w-full px-2 py-1.5 text-sm border border-gray-200 rounded focus:border-blue-500 focus:outline-none"})}),o.jsx(T,{label:"Font family",children:o.jsx(X,{value:a.fontFamily??"",onChange:l=>d({fontFamily:l.target.value})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:"Font size",children:o.jsx(ne,{value:a.fontSize??16,onChange:l=>d({fontSize:Number(l.target.value)})})}),o.jsx(T,{label:"Weight",children:o.jsx(X,{value:String(a.fontWeight??""),onChange:l=>d({fontWeight:l.target.value||void 0})})}),o.jsx(T,{label:"Line height",children:o.jsx(ne,{step:.1,value:a.lineHeight??1.5,onChange:l=>d({lineHeight:Number(l.target.value)})})}),o.jsx(T,{label:"Letter spacing",children:o.jsx(ne,{value:a.letterSpacing??0,onChange:l=>d({letterSpacing:Number(l.target.value)})})})]}),o.jsx(T,{label:"Color",children:o.jsx(de,{value:a.color??"#000000",onChange:l=>d({color:l})})}),o.jsx(T,{label:"Align",children:o.jsxs(Qt,{value:a.align??"left",onChange:l=>d({align:l.target.value}),children:[o.jsx("option",{value:"left",children:"Left"}),o.jsx("option",{value:"center",children:"Center"}),o.jsx("option",{value:"right",children:"Right"})]})}),o.jsx(T,{label:"Link URL",children:o.jsx(X,{value:a.link??"",onChange:l=>d({link:l.target.value})})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})}),o.jsx("button",{onClick:()=>n({content:`${t.content} ✨`}),className:"w-full mt-2 px-3 py-2 text-xs bg-purple-50 text-purple-700 border border-purple-200 rounded hover:bg-purple-100",children:"✨ AI rewrite (mock)"})]})}function Ya({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Image"}),o.jsx(T,{label:"Image URL",children:o.jsx(Oo,{value:t.src,onChange:l=>n({src:l}),onAlt:l=>n({alt:l})})}),o.jsx(T,{label:"Alt text",children:o.jsx(X,{value:t.alt??"",onChange:l=>n({alt:l.target.value})})}),o.jsx(T,{label:"Link",children:o.jsx(X,{value:t.link??"",onChange:l=>n({link:l.target.value})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:o.jsxs(o.Fragment,{children:["Width",o.jsx(Bt,{overridden:s.has("width")})]}),children:o.jsx(ne,{value:a.width??0,onChange:l=>d({width:Number(l.target.value)})})}),o.jsx(T,{label:o.jsxs(o.Fragment,{children:["Height",o.jsx(Bt,{overridden:s.has("height")})]}),children:o.jsx(ne,{value:a.height??0,onChange:l=>d({height:Number(l.target.value)||void 0})})})]}),o.jsx(T,{label:"Border radius",children:o.jsx(ne,{value:a.borderRadius??0,onChange:l=>d({borderRadius:Number(l.target.value)})})}),o.jsx(T,{label:"Align",children:o.jsxs(Qt,{value:a.align??"center",onChange:l=>d({align:l.target.value}),children:[o.jsx("option",{value:"left",children:"Left"}),o.jsx("option",{value:"center",children:"Center"}),o.jsx("option",{value:"right",children:"Right"})]})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})})]})}function qa({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Button"}),o.jsx(T,{label:"Label",children:o.jsx(X,{value:t.label,onChange:l=>n({label:l.target.value})})}),o.jsx(T,{label:"Link",children:o.jsx(X,{value:t.link,onChange:l=>n({link:l.target.value})})}),o.jsx(T,{label:"Background color",children:o.jsx(de,{value:a.backgroundColor??"",onChange:l=>d({backgroundColor:l})})}),o.jsx(T,{label:"Text color",children:o.jsx(de,{value:a.color??"#FFFFFF",onChange:l=>d({color:l})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:"Font size",children:o.jsx(ne,{value:a.fontSize??16,onChange:l=>d({fontSize:Number(l.target.value)})})}),o.jsx(T,{label:"Border radius",children:o.jsx(ne,{value:a.borderRadius??6,onChange:l=>d({borderRadius:Number(l.target.value)})})})]}),o.jsx(T,{label:"Align",children:o.jsxs(Qt,{value:a.align??"center",onChange:l=>d({align:l.target.value}),children:[o.jsx("option",{value:"left",children:"Left"}),o.jsx("option",{value:"center",children:"Center"}),o.jsx("option",{value:"right",children:"Right"})]})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})})]})}function Ja({mod:e,el:t}){const n=st(e,t);return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Spacer"}),o.jsx(T,{label:"Height (px)",children:o.jsx(ne,{value:t.height,onChange:r=>n({height:Number(r.target.value)||0})})})]})}function Va({mod:e,el:t}){const n=st(e,t),r=O(l=>l.viewMode),i=t.style??{},a=rt(i,r),s=new Set(Object.keys(i.mobile??{})),d=l=>n({style:it(i,l,r)});return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Divider"}),o.jsx(T,{label:"Color",children:o.jsx(de,{value:a.color??"#E5E7EB",onChange:l=>d({color:l})})}),o.jsx(T,{label:"Thickness",children:o.jsx(ne,{value:a.thickness??1,onChange:l=>d({thickness:Number(l.target.value)})})}),o.jsx(at,{style:a,mobileKeys:s,onSet:d}),o.jsx(zt,{hideOn:i.hideOn,onChange:l=>n({style:{...i,hideOn:l}})})]})}function io(e=0){const t=e+1;return{id:`p_${Date.now()}_${Math.random().toString(36).slice(2,7)}`,image:`https://placehold.co/400x400?text=Product+${t}`,imageAlt:`Product ${t}`,name:`Product ${t}`,oldPrice:"$59",finalPrice:"$39",description:"Short product description.",link:"#"}}function Xa({mod:e,el:t}){const n=st(e,t),r=O(c=>c.viewMode),i=t.style??{},a=rt(i,r),s=c=>n({style:it(i,c,r)}),d=c=>n({products:c}),l=c=>{const m=c;let p=t.products.slice();if(p.length<m)for(;p.length<m;)p.push(io(p.length));n({columns:c,products:p})};return o.jsxs(o.Fragment,{children:[o.jsx(he,{children:"Product Grid"}),o.jsxs(T,{label:"Columns (desktop)",children:[o.jsx("div",{className:"inline-flex bg-gray-100 rounded p-0.5 w-full",children:[1,2,3].map(c=>o.jsxs("button",{onClick:()=>l(c),className:`flex-1 px-2 py-1 text-xs rounded ${t.columns===c?"bg-white shadow text-gray-900":"text-gray-500 hover:text-gray-700"}`,children:[c," ",c===1?"col":"cols"]},c))}),o.jsx("p",{className:"text-[10px] text-gray-400 mt-1",children:"Always stacks to 1 column on mobile."})]}),o.jsx(T,{label:"Show old price",children:o.jsx(un,{checked:t.showOldPrice,onChange:c=>n({showOldPrice:c})})}),o.jsx(T,{label:"Show description",children:o.jsx(un,{checked:t.showDescription,onChange:c=>n({showDescription:c})})}),o.jsx(T,{label:"Show button",children:o.jsx(un,{checked:t.showButton,onChange:c=>n({showButton:c})})}),t.showButton&&o.jsx(T,{label:"Default button label",children:o.jsx(X,{value:t.buttonLabel??"",placeholder:"Shop now",onChange:c=>n({buttonLabel:c.target.value})})}),o.jsxs("div",{className:"mt-4 pt-3 border-t border-gray-100",children:[o.jsxs("div",{className:"flex items-center justify-between mb-2",children:[o.jsxs(he,{children:["Products (",t.products.length,")"]}),o.jsxs("button",{onClick:()=>d([...t.products,io(t.products.length)]),className:"flex items-center gap-1 px-1.5 py-0.5 text-[11px] text-blue-600 hover:bg-blue-50 rounded",title:"Add product",children:[o.jsx(R.Plus,{size:12})," Add"]})]}),t.products.map((c,m)=>o.jsx(Ka,{index:m,product:c,showOldPrice:t.showOldPrice,showDescription:t.showDescription,showButton:t.showButton,onChange:p=>{const f=[...t.products];f[m]=p,d(f)},onDelete:()=>d(t.products.filter((p,f)=>f!==m))},c.id))]}),o.jsxs("div",{className:"mt-4 pt-3 border-t border-gray-100",children:[o.jsx(he,{children:"Style"}),o.jsx(T,{label:"Card background",children:o.jsx(de,{value:a.cardBackgroundColor??"",onChange:c=>s({cardBackgroundColor:c})})}),o.jsx(T,{label:"Name color",children:o.jsx(de,{value:a.nameColor??"",onChange:c=>s({nameColor:c})})}),o.jsx(T,{label:"Final price color",children:o.jsx(de,{value:a.finalPriceColor??"",onChange:c=>s({finalPriceColor:c})})}),o.jsx(T,{label:"Old price color",children:o.jsx(de,{value:a.oldPriceColor??"",onChange:c=>s({oldPriceColor:c})})}),o.jsx(T,{label:"Button background",children:o.jsx(de,{value:a.buttonBackgroundColor??"",onChange:c=>s({buttonBackgroundColor:c})})}),o.jsx(T,{label:"Button text color",children:o.jsx(de,{value:a.buttonColor??"",onChange:c=>s({buttonColor:c})})}),o.jsx(T,{label:"Card radius",children:o.jsx(ne,{value:a.borderRadius??0,onChange:c=>s({borderRadius:Number(c.target.value)})})}),o.jsx(at,{style:a,onSet:s})]})]})}function un({checked:e,onChange:t}){return o.jsx("button",{onClick:()=>t(!e),className:`relative inline-flex h-5 w-9 items-center rounded-full transition-colors ${e?"bg-blue-600":"bg-gray-300"}`,children:o.jsx("span",{className:`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${e?"translate-x-4":"translate-x-0.5"}`})})}function Ka({index:e,product:t,showOldPrice:n,showDescription:r,showButton:i,onChange:a,onDelete:s}){const d=l=>a({...t,...l});return o.jsxs("div",{className:"border border-gray-200 rounded p-2 mb-2 bg-gray-50",children:[o.jsxs("div",{className:"flex items-center justify-between mb-2",children:[o.jsxs("span",{className:"text-[11px] font-semibold text-gray-600",children:["#",e+1]}),o.jsx("button",{onClick:s,className:"text-gray-400 hover:text-red-600",title:"Remove product",children:o.jsx(R.Trash2,{size:12})})]}),o.jsx(T,{label:"Name",children:o.jsx(X,{value:t.name,onChange:l=>d({name:l.target.value})})}),o.jsx(T,{label:"Image URL",children:o.jsx(Oo,{value:t.image,onChange:l=>d({image:l}),onAlt:l=>d({imageAlt:l})})}),o.jsx(T,{label:"Link",children:o.jsx(X,{value:t.link??"",onChange:l=>d({link:l.target.value})})}),o.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[o.jsx(T,{label:"Final price",children:o.jsx(X,{value:t.finalPrice,onChange:l=>d({finalPrice:l.target.value})})}),n&&o.jsx(T,{label:"Old price",children:o.jsx(X,{value:t.oldPrice??"",onChange:l=>d({oldPrice:l.target.value})})})]}),r&&o.jsx(T,{label:"Description",children:o.jsx(X,{value:t.description??"",onChange:l=>d({description:l.target.value})})}),i&&o.jsx(T,{label:"Button label (override)",children:o.jsx(X,{value:t.buttonLabel??"",placeholder:"Inherit default",onChange:l=>d({buttonLabel:l.target.value||void 0})})})]})}const Qa=[{type:"basic.text",category:"basic",name:"Text Block",description:"Single editable paragraph of body copy. Use for short notes, intros, or filler text between sections.",tags:["text","paragraph","body"],create:()=>h("basic.text","Text Block",[u("Write your text here.",{role:"body"})])},{type:"basic.heading",category:"basic",name:"Heading",description:"Bold standalone heading using the theme heading font. Use to introduce a section without other elements.",tags:["heading","title","section"],create:()=>h("basic.heading","Heading",[u("A clear section heading",{role:"headline",fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",paddingTop:16,paddingBottom:8,lineHeight:1.25})])},{type:"basic.image",category:"basic",name:"Image",description:"Single full-width image, centered. Use for hero photography, illustrations, or screenshots.",tags:["image","media","photo"],create:()=>h("basic.image","Image",[M(A(600,300),"Placeholder")])},{type:"basic.image_caption",category:"basic",name:"Image with Caption",description:"Image followed by a small italicized caption underneath. Editorial style for newsletters.",tags:["image","caption","editorial"],create:()=>h("basic.image_caption","Image + Caption",[M(A(600,360),"Photo"),u("Photo: caption goes here.",{color:"{colors.muted}",fontSize:13,align:"center",paddingTop:4,paddingBottom:16})])},{type:"basic.spacer",category:"basic",name:"Spacer",description:"Empty vertical space. Use to separate modules with breathing room.",tags:["spacer","spacing","gap"],create:()=>h("basic.spacer","Spacer",[F(32)])},{type:"basic.divider",category:"basic",name:"Divider",description:"Thin horizontal rule across the email. Use to visually separate sections.",tags:["divider","separator","rule"],create:()=>h("basic.divider","Divider",[U()])}],Za=[{type:"header.logo",category:"header",name:"Logo Centered",description:"Centered brand logo. The simplest header used at the top of almost every newsletter.",tags:["logo","brand","centered"],create:()=>h("header.logo","Logo Header",[M(A(180,56,"LOGO"),"Logo",{width:180,paddingTop:24,paddingBottom:24})])},{type:"header.logo_left_date_right",category:"header",name:"Logo Left + Date Right",description:"Two-column header with logo on the left and a date or issue label on the right. Common for periodical newsletters and digests.",tags:["logo","date","issue","publication","newsletter"],create:()=>h("header.logo_left_date_right","Logo + Date",[M(A(140,36,"LOGO"),"Logo",{width:140,align:"left",paddingTop:16,paddingBottom:16}),u("Issue #128 · April 29, 2026",{color:"{colors.muted}",fontSize:13,align:"right",paddingTop:0,paddingBottom:16}),U({paddingTop:0,paddingBottom:0})])},{type:"header.publication",category:"header",name:"Publication Masthead",description:"Editorial masthead with publication name in serif type, tagline, and a divider. Mimics print magazine and newspaper newsletters.",tags:["masthead","publication","editorial","serif","newspaper","magazine"],create:()=>h("header.publication","Masthead",[u("THE WEEKLY",{fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",letterSpacing:6,paddingTop:32,paddingBottom:4}),u("Curated reading for thoughtful people",{color:"{colors.muted}",align:"center",fontSize:13,paddingBottom:16}),U({paddingTop:0,paddingBottom:0})])},{type:"header.hero",category:"header",name:"Hero with Headline & Image",description:"Big headline, subtitle and a wide hero image. Use for the lead story or campaign announcement.",tags:["hero","headline","image","lead","feature"],create:()=>h("header.hero","Hero",[u("Steps Towards a Greener World",{role:"headline",fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",paddingTop:32,lineHeight:1.2}),u("Small actions, big impact.",{color:"{colors.muted}",align:"center",paddingBottom:16}),M(A(560,280,"Hero"),"Hero",{width:560})])},{type:"header.hero_text_only",category:"header",name:"Hero Text Only",description:"Centered eyebrow + large headline + supporting paragraph, no image. Editorial intro for opinion or essay newsletters.",tags:["hero","text","essay","editorial","minimal"],create:()=>h("header.hero_text_only","Hero Text",[u("ESSAY · ISSUE 42",{fontSize:12,fontWeight:"bold",color:"{colors.primary}",letterSpacing:3,align:"center",paddingTop:32,paddingBottom:8}),u("On building things slowly",{role:"headline",fontFamily:"{fonts.heading}",fontSize:40,fontWeight:"bold",align:"center",lineHeight:1.15,paddingBottom:8}),u("Why patience and craft still win in a world of shortcuts.",{color:"{colors.muted}",align:"center",fontSize:16,paddingBottom:32})])},{type:"header.announcement",category:"header",name:"Announcement Bar",description:"Thin colored top bar with a single line of promotional text. Use for free shipping, sales, or alerts.",tags:["announcement","bar","promo","alert"],create:()=>h("header.announcement","Announcement",[u("✨ Free shipping on orders over $50",{color:"{colors.buttonText}",align:"center",fontSize:14,paddingTop:12,paddingBottom:12})],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"header.logo_with_view_browser",category:"header",name:"Logo + View in Browser",description:"Logo with a small 'View in browser' link above it. Standard for marketing newsletters that may render poorly.",tags:["logo","view-in-browser","marketing","preheader"],create:()=>h("header.logo_with_view_browser","Logo + Browser Link",[u("View in browser",{color:"{colors.muted}",fontSize:11,align:"right",paddingTop:8,paddingBottom:0,link:"#"}),M(A(160,48,"LOGO"),"Logo",{width:160,paddingTop:8,paddingBottom:16})])},{type:"header.welcome",category:"header",name:"Welcome Header",description:"Friendly greeting with first name placeholder, used at the top of welcome and onboarding emails.",tags:["welcome","onboarding","greeting","personalized"],create:()=>h("header.welcome","Welcome",[u("👋 Welcome aboard, {{first_name}}",{fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",align:"center",paddingTop:32,paddingBottom:8}),u("We're glad you're here. Here's what to do next.",{color:"{colors.muted}",align:"center",paddingBottom:16})])},{type:"header.logo_with_tagline",category:"header",name:"Logo + Tagline",description:"Centered logo above a one-line tagline. Friendly brand-forward header.",tags:["logo","tagline","brand"],create:()=>h("header.logo_with_tagline","Logo + Tagline",[M(A(160,48,"LOGO"),"Logo",{width:160,paddingTop:24,paddingBottom:4}),u("Newsletters that respect your time.",{align:"center",color:"{colors.muted}",fontSize:14,paddingBottom:24})])},{type:"header.story_label",category:"header",name:"Story Label Header",description:"Small category label (e.g. 'Top story', 'Deep dive') above the masthead. Used by The Hustle, Morning Brew style newsletters.",tags:["label","category","story","newsletter","topic"],create:()=>h("header.story_label","Story Label",[u("TODAY'S TOP STORY",{color:"{colors.primary}",fontSize:12,fontWeight:"bold",letterSpacing:3,align:"center",paddingTop:24,paddingBottom:4}),u("AI editing tools come for the inbox",{fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",align:"center",paddingBottom:16,lineHeight:1.2})])}],es=[{type:"menu.horizontal",category:"menu",name:"Horizontal Nav",description:"Horizontal menu with 3-5 inline links separated by dots. Common publication navigation under the masthead.",tags:["menu","nav","horizontal","publication"],create:()=>h("menu.horizontal","Horizontal Menu",[u("Home · Articles · Podcast · About · Subscribe",{align:"center",color:"{colors.text}",fontSize:13,paddingTop:12,paddingBottom:12})])},{type:"menu.sections",category:"menu",name:"Section Tabs",description:"Linked section labels representing the contents of today's issue (e.g. News · Markets · Tech · Culture). Used by daily digests.",tags:["menu","sections","tabs","digest","daily"],create:()=>h("menu.sections","Section Tabs",[U({paddingTop:0,paddingBottom:8}),u("NEWS · MARKETS · TECH · CULTURE · WEEKEND",{align:"center",color:"{colors.primary}",fontSize:11,fontWeight:"bold",letterSpacing:2,paddingTop:0,paddingBottom:8}),U({paddingTop:0,paddingBottom:8})])},{type:"menu.in_this_issue",category:"menu",name:"In This Issue",description:"Table-of-contents box listing the items in this newsletter issue with anchor links. Helps readers scan long emails.",tags:["toc","menu","issue","summary","table of contents"],create:()=>h("menu.in_this_issue","In This Issue",[u("IN THIS ISSUE",{fontSize:11,fontWeight:"bold",color:"{colors.muted}",letterSpacing:2,paddingTop:16,paddingBottom:8}),u("→ Lead story: AI in the inbox",{fontSize:14,paddingTop:2,paddingBottom:2,link:"#lead"}),u("→ 3 things worth your time",{fontSize:14,paddingTop:2,paddingBottom:2,link:"#picks"}),u("→ Reader question of the week",{fontSize:14,paddingTop:2,paddingBottom:2,link:"#qa"}),u("→ Upcoming events",{fontSize:14,paddingTop:2,paddingBottom:16,link:"#events"})],{backgroundColor:"{colors.background}",paddingTop:8,paddingBottom:8,paddingLeft:16,paddingRight:16})},{type:"menu.cta_strip",category:"menu",name:"Linked Action Strip",description:"Three short text actions in a row (e.g. 'Read · Share · Reply'). Light alternative to a button bar.",tags:["menu","actions","links","strip"],create:()=>h("menu.cta_strip","Action Strip",[u("Read online · Share · Reply with feedback",{align:"center",color:"{colors.primary}",fontSize:13,paddingTop:12,paddingBottom:12})])}],ts=[{type:"content.headline_body",category:"content",name:"Headline + Body",description:"Section title with one paragraph of body text. The most generic written content block.",tags:["headline","body","paragraph","article"],create:()=>h("content.headline_body","Headline + Body",[I("A compelling headline",{paddingTop:24}),u("Tell your story with a clear, concise paragraph. Keep readers engaged with short sentences and meaningful detail.",{paddingBottom:24})])},{type:"content.lead_story",category:"content",name:"Lead Story",description:"Top story of the issue: eyebrow label, big headline, hero image, lead paragraph and a 'Continue reading' link. Used by news and editorial newsletters.",tags:["lead","story","feature","news","editorial","long-form"],create:()=>h("content.lead_story","Lead Story",[Y("Lead story"),I("Inside the new wave of indie publishers",{level:1,paddingBottom:4}),v("By Jane Doe · 6 min read",{fontSize:13}),M(A(560,320,"Lead"),"Lead",{width:560,paddingTop:12}),u("A growing group of writers are leaving big media to build their own readerships, betting that quality and a direct relationship beat scale.",{paddingTop:16}),u("Continue reading →",{color:"{colors.primary}",fontWeight:"bold",paddingTop:4,paddingBottom:24,link:"#"})])},{type:"content.article_summary",category:"content",name:"Article Summary Card",description:"Compact link-out card: image on top, category label, title, one-line summary, and 'Read more'. Use repeatedly to list secondary articles.",tags:["article","summary","card","link-out","newsletter"],create:()=>h("content.article_summary","Article Card",[M(A(560,280,"Article"),"Article",{width:560}),u("CULTURE",{color:"{colors.primary}",fontSize:11,fontWeight:"bold",letterSpacing:2,paddingTop:12,paddingBottom:4}),I("How long-form writing made a comeback",{paddingTop:0,paddingBottom:4}),u("Why subscribers are paying for slower, deeper coverage — and what it means for publishers.",{paddingBottom:8}),u("Read more →",{color:"{colors.primary}",fontWeight:"bold",paddingBottom:24,link:"#"})])},{type:"content.image_text",category:"content",name:"Image + Text Beside",description:"Image with article title and short summary stacked below. Standard editorial card.",tags:["image","text","article","stacked"],create:()=>h("content.image_text","Image + Text",[M(A(560,300,"Article"),"Article",{width:560}),I("Article title",{paddingTop:16,paddingBottom:4}),u("A short summary of the article goes here, two or three lines is plenty.")])},{type:"content.two_column_articles",category:"content",name:"Two Column Stories",description:"Two short article previews shown side-by-side as stacked blocks (renders as full-width on mobile). Use to tease two related stories.",tags:["two-column","articles","side-by-side","preview"],create:()=>h("content.two_column_articles","Two Stories",[Y("More to read"),M(A(272,180,"Story A"),"Story A",{width:272}),u("Story A title",{fontWeight:"bold",paddingTop:4,paddingBottom:2}),u("One sentence about story A.",{fontSize:14,paddingBottom:16}),M(A(272,180,"Story B"),"Story B",{width:272}),u("Story B title",{fontWeight:"bold",paddingTop:4,paddingBottom:2}),u("One sentence about story B.",{fontSize:14,paddingBottom:16})])},{type:"content.three_picks",category:"content",name:"Three Picks (Numbered)",description:"Numbered list of three short recommendations or links. Used by curators ('3 things to read this week').",tags:["list","picks","curated","links","recommendations"],create:()=>h("content.three_picks","Three Picks",[Y("Three picks"),u("01 / How to stay focused in 2026",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:8,paddingBottom:4,link:"#"}),v("Notes on attention, deep work, and the slow internet.",{fontSize:14}),U({paddingTop:12,paddingBottom:8}),u("02 / The case for boring software",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:8,paddingBottom:4,link:"#"}),v("Why teams are returning to simpler, predictable tools.",{fontSize:14}),U({paddingTop:12,paddingBottom:8}),u("03 / A short history of the inbox",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:8,paddingBottom:4,link:"#"}),v("From memos to MIME, and what comes next.",{fontSize:14,paddingBottom:24})])},{type:"content.quote",category:"content",name:"Pull Quote",description:"Centered serif pull quote with attribution. Adds rhythm to long editorial newsletters.",tags:["quote","pull-quote","editorial","attribution"],create:()=>h("content.quote","Pull Quote",[u("“The best way to predict the future is to create it.”",{fontFamily:"{fonts.heading}",fontSize:22,align:"center",paddingTop:24,lineHeight:1.4}),u("— Peter Drucker",{color:"{colors.muted}",align:"center",paddingBottom:24})])},{type:"content.author_byline",category:"content",name:"Author Byline",description:"Round avatar + author name + role on one line. Drop above or below an article body for personal newsletters.",tags:["author","byline","avatar","personal"],create:()=>h("content.author_byline","Byline",[M(A(64,64,"👤"),"Author",{width:64,borderRadius:32,paddingTop:16,paddingBottom:0}),u("Jane Doe",{align:"center",fontWeight:"bold",paddingTop:8,paddingBottom:0}),v("Editor, The Weekly",{align:"center",fontSize:13}),F(16)])},{type:"content.editor_note",category:"content",name:"Editor's Note",description:"Personal letter-style block: 'Hi {{first_name}}', a few paragraphs and a sign-off. Ideal for newsletters with a strong author voice.",tags:["editor","note","letter","personal","voice"],create:()=>h("content.editor_note","Editor's Note",[u("Hi {{first_name}},",{paddingTop:24,paddingBottom:8}),u("This week I've been thinking about what makes a newsletter feel like a letter rather than a broadcast. Spoiler: it's not the format, it's the tone.",{paddingBottom:8,lineHeight:1.7}),u("Let me know what you think — just hit reply.",{paddingBottom:8,lineHeight:1.7}),u("— Jane",{fontFamily:"{fonts.heading}",paddingBottom:24})])},{type:"content.tip_box",category:"content",name:"Tip / Callout Box",description:"Highlighted background box with an icon, short title and one-paragraph tip. Use for 'pro tips', notes, and warnings.",tags:["tip","callout","box","highlight","note"],create:()=>h("content.tip_box","Tip Box",[u("💡 PRO TIP",{color:"{colors.primary}",fontSize:12,fontWeight:"bold",letterSpacing:2,paddingTop:16,paddingBottom:4}),u("Always preview your email on mobile before sending — most opens happen there.",{paddingBottom:16})],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0,paddingLeft:16,paddingRight:16})},{type:"content.numbered_list",category:"content",name:"Numbered List",description:"Vertical numbered list of 4-5 short items with optional sub-text. Use for tutorials, checklists and 'how-to' newsletters.",tags:["list","numbered","tutorial","checklist","how-to"],create:()=>h("content.numbered_list","Numbered List",[I("How to do it in 4 steps",{paddingTop:16,paddingBottom:12}),u("1. Define the goal",{fontWeight:"bold",paddingTop:4,paddingBottom:2}),v("Write down the outcome in one sentence."),u("2. List constraints",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("Time, budget, scope. Be specific."),u("3. Plan the smallest version",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("What can you ship this week?"),u("4. Ship it",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("Refine after real feedback.",{fontSize:14}),F(16)])},{type:"content.bullet_list",category:"content",name:"Bullet List",description:"Simple unordered list of takeaways or facts. Concise summary block.",tags:["list","bullets","takeaways","summary"],create:()=>h("content.bullet_list","Bullets",[I("Key takeaways",{paddingTop:16,paddingBottom:8}),u("• Newsletters are growing 20% YoY",{paddingTop:2,paddingBottom:2}),u("• Mobile opens crossed 70%",{paddingTop:2,paddingBottom:2}),u("• Plain-text emails outperform image-heavy ones in B2B",{paddingTop:2,paddingBottom:2}),u("• Personalization drives 2x click-through",{paddingTop:2,paddingBottom:16})])},{type:"content.qa",category:"content",name:"Q&A Block",description:"Question in bold followed by an answer paragraph. Use for FAQ, reader mailbags, or AMAs.",tags:["qa","faq","ama","mailbag","reader-questions"],create:()=>h("content.qa","Q&A",[Y("Reader question"),u("Q: How do I get my first 100 subscribers?",{fontFamily:"{fonts.heading}",fontSize:18,fontWeight:"bold",paddingTop:4,paddingBottom:8,lineHeight:1.3}),u("A: Tell ten people who already know you. Then ask each of them to forward to one friend. The first 100 don't come from algorithms — they come from your network.",{paddingBottom:24,lineHeight:1.7})])},{type:"content.stats_row",category:"content",name:"Stat Row",description:"Big numbers with short labels (e.g. '12k readers · 4.8★ rating · 96% open rate'). Used for impact summaries and social proof.",tags:["stats","numbers","metrics","social-proof"],create:()=>h("content.stats_row","Stat Row",[Y("By the numbers",{align:"center"}),u("12,400",{fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",color:"{colors.primary}",paddingTop:4,paddingBottom:0}),v("active readers this month",{align:"center",fontSize:13}),F(8),u("96% · 4.8★ · 32 issues shipped",{align:"center",color:"{colors.text}",fontSize:14,paddingBottom:24})])},{type:"content.timeline",category:"content",name:"Timeline / What Happened",description:"Chronological list of recent events with dates. Used by news roundups and changelog newsletters.",tags:["timeline","changelog","news","events","what-happened"],create:()=>h("content.timeline","Timeline",[Y("This week"),u("Mon · Acme launches plan B",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("After 6 months of beta testing.",{fontSize:14}),u("Wed · New funding round announced",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("$24M Series A led by Foundry.",{fontSize:14}),u("Fri · Industry report drops",{fontWeight:"bold",paddingTop:8,paddingBottom:2}),v("Open rates up across the board.",{fontSize:14,paddingBottom:24})])},{type:"content.podcast_episode",category:"content",name:"Podcast Episode",description:"Episode artwork, episode number, title, short description and a 'Listen' button. For shows that announce episodes by email.",tags:["podcast","episode","audio","listen","show"],create:()=>h("content.podcast_episode","Podcast Episode",[M(A(220,220,"Cover"),"Cover",{width:220,borderRadius:12}),u("EPISODE 042",{color:"{colors.primary}",fontSize:11,fontWeight:"bold",letterSpacing:2,align:"center",paddingTop:12,paddingBottom:4}),I("Why publishers are betting on email",{align:"center",paddingTop:0,paddingBottom:4}),v("With Jane Doe · 38 min",{align:"center",fontSize:13}),H("Listen now","https://example.com"),F(16)])},{type:"content.video_thumbnail",category:"content",name:"Video Thumbnail",description:"Video thumbnail with overlay-feeling play button (image only, links to a hosted player). Title and duration below.",tags:["video","thumbnail","watch","play","media"],create:()=>h("content.video_thumbnail","Video",[M(A(560,315,"▶ Watch"),"Video",{width:560,link:"#",borderRadius:8}),I("Watch: a guided tour of our 2026 launches",{paddingTop:12,paddingBottom:4}),v("4 min watch",{fontSize:13,paddingBottom:16})])},{type:"content.event_card",category:"content",name:"Event Card",description:"Date badge with event title, location, time and an RSVP button. For event-driven newsletters and community digests.",tags:["event","rsvp","community","date","card"],create:()=>h("content.event_card","Event",[u("MAY",{align:"center",color:"{colors.buttonText}",fontSize:12,fontWeight:"bold",letterSpacing:2,paddingTop:12,paddingBottom:0}),u("12",{align:"center",color:"{colors.buttonText}",fontSize:36,fontWeight:"bold",paddingTop:0,paddingBottom:12})],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"content.code_block",category:"content",name:"Code Snippet",description:"Monospaced code block on a tinted background. For developer newsletters and changelog excerpts.",tags:["code","snippet","developer","monospace","changelog"],create:()=>h("content.code_block","Code",[u("npm install @one-million-lines/email-builder",{fontFamily:"Menlo, Consolas, monospace",fontSize:13,color:"{colors.text}",paddingTop:16,paddingBottom:16,paddingLeft:16,paddingRight:16})],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0,paddingLeft:16,paddingRight:16})}],ns=[{type:"feature.list",category:"feature",name:"Checkmark Feature List",description:"Centered title with 3-4 short checkmarked benefits. Good for product newsletters and onboarding emails.",tags:["features","benefits","checkmarks","list"],create:()=>h("feature.list","Feature List",[I("Why people love it",{align:"center",paddingTop:24}),u("✓ Fast and reliable",{align:"center"}),u("✓ Beautiful out of the box",{align:"center"}),u("✓ Backed by humans, not bots",{align:"center",paddingBottom:24})])},{type:"feature.icon_three",category:"feature",name:"Three Icon Features",description:"Three stacked feature blocks with an emoji/icon, short title and one-line description. Use to highlight 3 product capabilities.",tags:["features","icons","three-up","product"],create:()=>h("feature.icon_three","Three Features",[u("⚡",{align:"center",fontSize:32,paddingTop:24,paddingBottom:4}),u("Fast",{align:"center",fontWeight:"bold",paddingBottom:2}),v("Built to render in milliseconds.",{align:"center",fontSize:14}),F(16),u("🧩",{align:"center",fontSize:32,paddingBottom:4}),u("Modular",{align:"center",fontWeight:"bold",paddingBottom:2}),v("Compose any layout from blocks.",{align:"center",fontSize:14}),F(16),u("🤖",{align:"center",fontSize:32,paddingBottom:4}),u("AI-ready",{align:"center",fontWeight:"bold",paddingBottom:2}),v("Edit emails as JSON, not HTML.",{align:"center",fontSize:14,paddingBottom:24})])},{type:"feature.before_after",category:"feature",name:"Before / After",description:"Two stacked images labeled 'Before' and 'After'. For product transformations, redesigns and case studies.",tags:["before-after","comparison","case-study","transformation"],create:()=>h("feature.before_after","Before / After",[Y("Before"),M(A(560,280,"Before"),"Before",{width:560}),F(8),Y("After"),M(A(560,280,"After"),"After",{width:560}),F(16)])},{type:"feature.benefit_pair",category:"feature",name:"Image + Benefit Pair",description:"Repeat-use block: one supporting image plus a title and benefit paragraph beside it. Stack 2-3 of these for a feature tour.",tags:["benefit","feature","image-text","pair"],create:()=>h("feature.benefit_pair","Benefit Pair",[M(A(560,240,"Feature"),"Feature",{width:560,paddingTop:16}),I("Send 10x faster",{paddingTop:12,paddingBottom:4}),u("Reusable modules and theme tokens let teams ship campaigns in minutes, not days.",{paddingBottom:24})])},{type:"feature.testimonial",category:"feature",name:"Testimonial",description:"Customer quote in large type with avatar and attribution. Social proof block.",tags:["testimonial","review","social-proof","customer"],create:()=>h("feature.testimonial","Testimonial",[u("“This cut our email production from a week to an afternoon.”",{fontFamily:"{fonts.heading}",fontSize:22,align:"center",paddingTop:24,paddingBottom:12,lineHeight:1.4}),M(A(56,56,"👤"),"Customer",{width:56,borderRadius:28}),u("Alex Kim · Head of Lifecycle, Acme",{align:"center",color:"{colors.muted}",fontSize:13,paddingTop:4,paddingBottom:24})])},{type:"feature.logo_strip",category:"feature",name:"Customer Logo Strip",description:"Small horizontal row implying customer logos for credibility ('Trusted by'). Logos shown as a placeholder image.",tags:["logos","trusted-by","social-proof","strip"],create:()=>h("feature.logo_strip","Logo Strip",[v("TRUSTED BY",{align:"center",fontSize:11}),M(A(520,60,"LOGOS"),"Customer logos",{width:520,paddingTop:8,paddingBottom:16})])}],os=[{type:"cta.simple",category:"call_to_action",name:"Simple CTA",description:"Centered headline + body + primary button. The default call-to-action block for any newsletter or promo.",tags:["cta","primary","centered","button"],create:()=>h("cta.simple","Simple CTA",[I("Ready to get started?",{align:"center",paddingTop:24}),v("Create better emails faster.",{align:"center"}),H("Start now","https://example.com"),F(16)])},{type:"cta.banner",category:"call_to_action",name:"Colored Banner CTA",description:"Full-width colored band with eyebrow, big headline and a contrasting button. Use to draw attention to sales or launches.",tags:["cta","banner","colored","promo","sale"],create:()=>h("cta.banner","CTA Banner",[u("Limited time offer",{color:"{colors.buttonText}",align:"center",fontSize:14,paddingTop:24,paddingBottom:4}),u("Save 30% this week only",{color:"{colors.buttonText}",align:"center",fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",paddingBottom:16}),H("Shop the sale"),F(24)],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"cta.button_only",category:"call_to_action",name:"Button Only",description:"Single primary button on a clean background. Use as a follow-up CTA after a content block.",tags:["cta","button","minimal"],create:()=>h("cta.button_only","Button",[H("Click here","https://example.com")])},{type:"cta.dual_button",category:"call_to_action",name:"Two Button Choice",description:"Two side-by-side actions: a primary and a ghost-styled secondary. Use when offering 'Learn more' vs 'Get started'.",tags:["cta","buttons","two-options","choice"],create:()=>h("cta.dual_button","Two Buttons",[I("Pick your path",{align:"center",paddingTop:24}),v("Choose what fits your team.",{align:"center"}),H("Get started","https://example.com"),H("Learn more","https://example.com",{backgroundColor:"transparent",color:"{colors.primary}"}),F(16)])},{type:"cta.image_overlay",category:"call_to_action",name:"Image + Overlay CTA",description:"Lead image with a headline, supporting text, and a button immediately below. Strong visual call to action.",tags:["cta","image","visual","hero"],create:()=>h("cta.image_overlay","Image CTA",[M(A(560,280,"Visual"),"Visual",{width:560,paddingTop:16}),I("Stop guessing. Start measuring.",{align:"center",paddingTop:16}),v("Free for 14 days. No credit card.",{align:"center"}),H("Try it free"),F(16)])},{type:"cta.subscribe",category:"call_to_action",name:"Subscribe / Forward",description:"Friendly 'Was this forwarded? Subscribe' block that grows the list virally. Common at the end of newsletters.",tags:["cta","subscribe","forward","growth","newsletter"],create:()=>h("cta.subscribe","Subscribe",[Y("Was this forwarded?",{align:"center"}),I("Get the next issue in your inbox",{align:"center",paddingTop:0,paddingBottom:8}),H("Subscribe free"),F(16)],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0})},{type:"cta.referral",category:"call_to_action",name:"Referral / Share",description:"Encourages readers to share the newsletter with a unique referral link. Includes a 'Share' button and a personalized URL.",tags:["cta","referral","share","viral","growth"],create:()=>h("cta.referral","Referral",[Y("Tell a friend",{align:"center"}),I("Share & earn perks",{align:"center",paddingTop:0,paddingBottom:8}),v("Refer 3 friends and unlock the bonus issue.",{align:"center"}),u("yourname.com/r/abc123",{align:"center",color:"{colors.primary}",fontFamily:"Menlo, Consolas, monospace",fontSize:14,paddingTop:8,paddingBottom:8}),H("Share now"),F(16)])},{type:"cta.upgrade",category:"call_to_action",name:"Upgrade / Paid",description:"Conversion block that promotes a paid plan or premium tier. Includes price, benefits and an upgrade button.",tags:["cta","upgrade","paid","premium","conversion"],create:()=>h("cta.upgrade","Upgrade",[Y("Become a member",{align:"center"}),I("$5 / month",{align:"center",level:1}),v("Unlock the archive, weekly bonus and member chat.",{align:"center",fontSize:14}),H("Upgrade"),F(16)],{backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0})},{type:"cta.feedback",category:"call_to_action",name:"Feedback Reply",description:"Asks the reader to reply with feedback ('Hit reply and let me know'). Personal, no button.",tags:["cta","feedback","reply","personal"],create:()=>h("cta.feedback","Feedback",[u("How did this issue land for you? Just hit reply — I read every message.",{align:"center",paddingTop:24,paddingBottom:24,lineHeight:1.6})])}],rs=[{type:"ecom.product_single",category:"ecommerce",name:"Single Product",description:"One product with image, title, price, short description and Buy button. Use to feature a hero product. Supports old/final price and per-product link.",tags:["product","single","buy","hero"],create:()=>h("ecom.product_single","Single Product",[Ee([q({name:"Linen Tote Bag",image:A(560,400,"Product"),oldPrice:"$59.00",finalPrice:"$39.00",description:"Heavyweight natural linen, made in Portugal."})],{columns:1,showOldPrice:!0,showDescription:!0,buttonLabel:"Buy now"})])},{type:"ecom.product_grid_2",category:"ecommerce",name:"Product Grid (2 up)",description:"Two products side-by-side on desktop, stacked on mobile. Each card has image, name, old/final price, optional description and Shop button. Curated picks layout.",tags:["product","grid","two-up","curated","responsive"],create:()=>h("ecom.product_grid_2","Product Grid 2",[Ee([q({name:"Product A",finalPrice:"$29",oldPrice:"$39"}),q({name:"Product B",finalPrice:"$34",oldPrice:"$45"})],{columns:2,showOldPrice:!0})])},{type:"ecom.product_grid_3",category:"ecommerce",name:"Product Grid (3 up)",description:"Three product cards in a row on desktop, stacked on mobile. Use for 'New arrivals' or 'Bestsellers' rows.",tags:["product","grid","three-up","bestsellers","new-arrivals","responsive"],create:()=>h("ecom.product_grid_3","Product Grid 3",[Y("New arrivals",{align:"center"}),Ee([q({name:"Product 1",finalPrice:"$19"}),q({name:"Product 2",finalPrice:"$24"}),q({name:"Product 3",finalPrice:"$32"})],{columns:3,showOldPrice:!1})])},{type:"ecom.collection_banner",category:"ecommerce",name:"Collection Banner",description:"Wide collection banner with title and 'Shop the collection' button overlaying or under an image. Use for category drops.",tags:["collection","banner","category","drop"],create:()=>h("ecom.collection_banner","Collection",[M(A(560,300,"Collection"),"Collection",{width:560}),I("Spring Collection 2026",{align:"center",paddingTop:16}),v("Lighter fabrics, brighter colors.",{align:"center"}),H("Shop the collection"),F(16)])},{type:"ecom.discount",category:"ecommerce",name:"Discount Code",description:"Big discount code in monospaced caps with 'Your code' label and a Redeem button.",tags:["discount","promo","code","coupon"],create:()=>h("ecom.discount","Discount Code",[v("Your code",{align:"center"}),u("SAVE20",{fontFamily:"{fonts.heading}",fontSize:36,fontWeight:"bold",align:"center",color:"{colors.primary}",letterSpacing:4,paddingTop:4,paddingBottom:16}),H("Redeem"),F(24)])},{type:"ecom.flash_sale",category:"ecommerce",name:"Flash Sale Banner",description:"Urgency-driven banner with countdown-style copy ('Ends in 24h'), discount value and a shop button.",tags:["flash-sale","urgency","promo","banner","countdown"],create:()=>h("ecom.flash_sale","Flash Sale",[u("⏰ FLASH SALE — ENDS IN 24H",{color:"{colors.buttonText}",align:"center",fontWeight:"bold",letterSpacing:2,paddingTop:16,paddingBottom:4}),u("Up to 50% off everything",{color:"{colors.buttonText}",align:"center",fontFamily:"{fonts.heading}",fontSize:28,fontWeight:"bold",paddingBottom:12}),H("Shop now","#",{backgroundColor:"{colors.surface}",color:"{colors.primary}"}),F(16)],{backgroundColor:"{colors.primary}",paddingTop:0,paddingBottom:0})},{type:"ecom.abandoned_cart",category:"ecommerce",name:"Abandoned Cart Reminder",description:"Friendly reminder showing the items left in the cart with a return-to-cart button. For cart recovery automations.",tags:["abandoned-cart","recovery","automation","reminder"],create:()=>h("ecom.abandoned_cart","Abandoned Cart",[I("You left something behind",{align:"center",paddingTop:16}),v("Pick up where you left off.",{align:"center"}),F(8),Ee([q({name:"Linen Tote Bag",image:A(400,400,"Item"),finalPrice:"$39",oldPrice:"$49"})],{columns:1,showOldPrice:!0,buttonLabel:"Return to cart"})])},{type:"ecom.review_request",category:"ecommerce",name:"Review Request",description:"Post-purchase block asking for a 1-5 star rating with stacked star buttons. For review-collection emails.",tags:["review","rating","post-purchase","feedback"],create:()=>h("ecom.review_request","Review",[I("How did we do?",{align:"center",paddingTop:24}),v("Tap a star to leave a quick review.",{align:"center"}),u("☆ ☆ ☆ ☆ ☆",{align:"center",fontSize:32,color:"{colors.primary}",paddingTop:12,paddingBottom:24,link:"#"})])},{type:"ecom.gift_guide",category:"ecommerce",name:"Gift Guide Pick",description:"Editorial gift-guide pick: persona eyebrow + a single product card with full details (image, name, old/final price, description, CTA).",tags:["gift-guide","curated","editorial","holiday"],create:()=>h("ecom.gift_guide","Gift Pick",[Y("For the home cook"),Ee([q({name:"Cast Iron Skillet",image:A(560,300,"Pick"),oldPrice:"$119",finalPrice:"$89",description:"Pre-seasoned, lifetime-guarantee. Made in USA."})],{columns:1,showOldPrice:!0,showDescription:!0,buttonLabel:"View product"})])},{type:"ecom.bestseller_list",category:"ecommerce",name:"Bestseller Grid",description:"Top products grid (3 up) with old/final prices. Used by retailers for weekly bestsellers.",tags:["bestsellers","grid","ranking","top"],create:()=>h("ecom.bestseller_list","Bestsellers",[Y("Top 3 this week"),Ee([q({name:"Linen Tote",finalPrice:"$39",oldPrice:"$49"}),q({name:"Ceramic Mug",finalPrice:"$24"}),q({name:"Brass Lamp",finalPrice:"$129",oldPrice:"$149"})],{columns:3,showOldPrice:!0})])}],is=[{type:"tx.order_summary",category:"transactional",name:"Order Summary",description:"Order confirmation summary: order number, line items with thumbnails and totals row. Used in post-purchase emails.",tags:["order","summary","receipt","post-purchase","ecommerce"],create:()=>h("tx.order_summary","Order Summary",[Y("Order #1024"),I("Thanks for your order",{paddingTop:0}),v("We'll email you again when it ships."),U({paddingTop:16,paddingBottom:8}),u("Linen Tote Bag · 1 × $39.00",{paddingTop:4,paddingBottom:4}),u("Ceramic Mug · 2 × $24.00",{paddingTop:4,paddingBottom:4}),U({paddingTop:8,paddingBottom:8}),u("Subtotal: $87.00",{paddingTop:2,paddingBottom:2}),u("Shipping: $5.00",{paddingTop:2,paddingBottom:2}),u("Total: $92.00",{fontWeight:"bold",paddingTop:2,paddingBottom:16})])},{type:"tx.shipping_update",category:"transactional",name:"Shipping Update",description:"Shipping confirmation with tracking number, carrier, expected delivery date and a Track button.",tags:["shipping","tracking","delivery","post-purchase"],create:()=>h("tx.shipping_update","Shipping Update",[u("📦",{align:"center",fontSize:40,paddingTop:24}),I("Your order is on the way",{align:"center",paddingTop:8}),v("Carrier: USPS · Expected: May 4, 2026",{align:"center"}),u("Tracking: 9400 1108 ...",{align:"center",color:"{colors.muted}",fontFamily:"Menlo, Consolas, monospace",fontSize:13}),H("Track package"),F(16)])},{type:"tx.invoice",category:"transactional",name:"Invoice",description:"Itemized invoice with billing period, services and totals. Used by SaaS and B2B billing emails.",tags:["invoice","billing","saas","b2b","receipt"],create:()=>h("tx.invoice","Invoice",[Y("Invoice INV-2026-04"),I("April 2026 invoice"),v("Billed to: Acme Inc · Period: Apr 1 – Apr 30"),U({paddingTop:16,paddingBottom:8}),u("Pro plan · $49.00",{paddingTop:4,paddingBottom:4}),u("Add-on seats (3) · $36.00",{paddingTop:4,paddingBottom:4}),U({paddingTop:8,paddingBottom:8}),u("Total due: $85.00",{fontWeight:"bold",paddingBottom:16}),H("Download invoice (PDF)"),F(16)])},{type:"tx.password_reset",category:"transactional",name:"Password Reset",description:"Authentication email with a reset button and a fallback link. Includes 'expires in X minutes' notice.",tags:["auth","password","reset","security"],create:()=>h("tx.password_reset","Password Reset",[I("Reset your password",{align:"center",paddingTop:16}),u("Click the button below to set a new password. This link expires in 30 minutes.",{align:"center",paddingBottom:16}),H("Reset password"),v("If the button doesn't work, paste this link in your browser:",{align:"center",fontSize:12}),u("https://example.com/reset/abc123",{align:"center",color:"{colors.primary}",fontSize:12,paddingBottom:24})])},{type:"tx.verify_email",category:"transactional",name:"Verify Email",description:"Single-purpose 'verify your email' transactional with one centered button.",tags:["auth","verify","email-confirmation"],create:()=>h("tx.verify_email","Verify Email",[I("One last step",{align:"center",paddingTop:16}),u("Confirm your email address to activate your account.",{align:"center",paddingBottom:8}),H("Verify email"),F(24)])},{type:"tx.appointment",category:"transactional",name:"Appointment Confirmation",description:"Booking/meeting confirmation with date, time, location and add-to-calendar links.",tags:["appointment","booking","calendar","meeting"],create:()=>h("tx.appointment","Appointment",[Y("Confirmed",{align:"center"}),I("Your appointment is set",{align:"center",paddingTop:0}),u("Tuesday, May 12 · 10:00 AM",{align:"center",fontWeight:"bold",paddingTop:8}),v("123 Main St, Suite 4 · Brooklyn, NY",{align:"center"}),H("Add to calendar"),F(16)])}],as=[{type:"social.icons",category:"social",name:"Social Icons Row",description:"Centered 'Follow us' label with text-link icons in a row. Light footer-style social block.",tags:["social","follow","icons","row"],create:()=>h("social.icons","Social Icons",[v("Follow us",{align:"center"}),u("Twitter · Instagram · LinkedIn · YouTube",{align:"center",color:"{colors.primary}",paddingBottom:16})])},{type:"social.share",category:"social",name:"Share This Email",description:"'Share this email' bar with Forward · Tweet · Share text links. Used at the end of newsletters.",tags:["social","share","forward","viral"],create:()=>h("social.share","Share Bar",[u("Share this email",{align:"center",paddingTop:8}),u("Forward · Tweet · Share",{align:"center",color:"{colors.primary}",paddingBottom:8})])},{type:"social.featured_post",category:"social",name:"Featured Social Post",description:"Embed-style preview of a single social post: avatar, name, post text and a link to view it on the platform.",tags:["social","post","embed","twitter","instagram"],create:()=>h("social.featured_post","Social Post",[Y("From the community"),M(A(48,48,"👤"),"Avatar",{width:48,borderRadius:24}),u("@maker · 2h",{color:"{colors.muted}",fontSize:13,paddingTop:4,paddingBottom:4}),u(`"Just shipped my newsletter using OpenPostcards. Honestly the smoothest email build I've ever done."`,{paddingBottom:8,lineHeight:1.6}),u("View on Twitter →",{color:"{colors.primary}",paddingBottom:16,link:"#"})])},{type:"social.instagram_grid",category:"social",name:"Instagram Grid",description:"3 small square thumbnails in a row representing recent Instagram posts, with handle and link.",tags:["social","instagram","grid","thumbnails"],create:()=>h("social.instagram_grid","IG Grid",[v("@youraccount on Instagram",{align:"center"}),M(A(180,180,"1"),"Post 1",{width:180}),M(A(180,180,"2"),"Post 2",{width:180}),M(A(180,180,"3"),"Post 3",{width:180}),u("View profile →",{align:"center",color:"{colors.primary}",paddingTop:8,paddingBottom:16,link:"#"})])},{type:"social.community_stats",category:"social",name:"Community Stats",description:"Short '12k Twitter · 4k IG · 2k YT' style row used to show following sizes.",tags:["social","stats","community","following"],create:()=>h("social.community_stats","Community Stats",[Y("Join the community",{align:"center"}),u("12k Twitter · 4k Instagram · 2k YouTube",{align:"center",paddingBottom:16}),F(8)])}],Ie={backgroundColor:"{colors.background}",paddingTop:0,paddingBottom:0},ss=[{type:"footer.simple",category:"footer",name:"Simple Footer",description:"Minimal footer with copyright, address and unsubscribe links. The default for any newsletter.",tags:["footer","simple","copyright","unsubscribe"],create:()=>h("footer.simple","Simple Footer",[v("© 2026 Your Company. All rights reserved.",{align:"center",fontSize:12}),v("123 Main St · City · Country",{align:"center",fontSize:12}),u("Unsubscribe · View in browser",{align:"center",color:"{colors.muted}",fontSize:12,paddingTop:4,paddingBottom:24})],{...Ie,paddingTop:24})},{type:"footer.social",category:"footer",name:"Footer with Social",description:"Footer with social links row above the legal text.",tags:["footer","social","links"],create:()=>h("footer.social","Social Footer",[u("Follow us",{align:"center",paddingTop:24}),u("Twitter · Instagram · LinkedIn",{align:"center",color:"{colors.primary}",paddingBottom:12}),U(),v("© 2026 Your Company · Unsubscribe",{align:"center",fontSize:12}),u(" ",{align:"center",paddingBottom:24})],Ie)},{type:"footer.legal",category:"footer",name:"Legal Footer",description:"Long-form footer with explanation of why the user is receiving the email plus privacy/terms/unsubscribe links. Used by enterprise and finance newsletters.",tags:["footer","legal","compliance","enterprise"],create:()=>h("footer.legal","Legal Footer",[u("You are receiving this email because you signed up for our newsletter. If you no longer wish to receive emails, you can unsubscribe at any time.",{align:"center",color:"{colors.muted}",fontSize:11,lineHeight:1.6,paddingTop:24}),u("Privacy Policy · Terms · Unsubscribe",{align:"center",color:"{colors.muted}",fontSize:11,paddingBottom:24})],Ie)},{type:"footer.publisher",category:"footer",name:"Publisher Footer",description:"Magazine-style sign-off with logo, publication name, masthead credits, address and links.",tags:["footer","publisher","magazine","masthead","editorial"],create:()=>h("footer.publisher","Publisher Footer",[M(A(120,36,"LOGO"),"Logo",{width:120,paddingTop:24,paddingBottom:8}),u("THE WEEKLY",{align:"center",fontFamily:"{fonts.heading}",fontWeight:"bold",letterSpacing:4,paddingTop:0,paddingBottom:4}),v("Editor: Jane Doe · Producer: Alex Kim",{align:"center",fontSize:12}),U({paddingTop:12,paddingBottom:12}),v("© 2026 The Weekly · 350 Madison Ave · NY 10017",{align:"center",fontSize:11}),u("Manage preferences · Unsubscribe",{align:"center",color:"{colors.muted}",fontSize:11,paddingTop:4,paddingBottom:24})],Ie)},{type:"footer.app_links",category:"footer",name:"Footer with App Store Badges",description:"Footer including 'Get the app' app-store and play-store badge images. For consumer brand newsletters.",tags:["footer","app","download","ios","android"],create:()=>h("footer.app_links","App Footer",[u("Get the app",{align:"center",fontWeight:"bold",paddingTop:24,paddingBottom:8}),M(A(135,40,"App Store"),"App Store",{width:135,align:"center",paddingTop:0,paddingBottom:4}),M(A(135,40,"Google Play"),"Google Play",{width:135,align:"center",paddingTop:0,paddingBottom:16}),U(),v("© 2026 Your Brand · Unsubscribe",{align:"center",fontSize:11}),u(" ",{align:"center",paddingBottom:24})],Ie)},{type:"footer.address_only",category:"footer",name:"Address Only",description:"Just a centered postal address line — required for CAN-SPAM compliance when other footers are minimal.",tags:["footer","address","compliance","can-spam"],create:()=>h("footer.address_only","Address",[v("Your Company · 123 Main St · Brooklyn, NY 11201 · USA",{align:"center",fontSize:11}),u(" ",{align:"center",paddingBottom:16})],{...Ie,paddingTop:16})},{type:"footer.preferences",category:"footer",name:"Manage Preferences",description:"Footer that emphasizes preference management ('Update your preferences', 'Send less often'). Reduces unsubscribes.",tags:["footer","preferences","frequency","retention"],create:()=>h("footer.preferences","Preferences",[u("Getting too many emails?",{align:"center",paddingTop:24,paddingBottom:4}),u("Update your preferences · Send less often · Unsubscribe",{align:"center",color:"{colors.primary}",fontSize:13,paddingBottom:16}),U(),v("© 2026 Your Company",{align:"center",fontSize:11}),u(" ",{align:"center",paddingBottom:24})],Ie)},{type:"footer.signature",category:"footer",name:"Signature Sign-off",description:"Personal hand-signed style sign-off with author name and tiny legal block. For solo creator newsletters.",tags:["footer","signature","personal","creator","sign-off"],create:()=>h("footer.signature","Signature",[u("Until next week,",{paddingTop:24,paddingBottom:4}),u("— Jane",{fontFamily:"{fonts.heading}",fontSize:22,paddingBottom:16}),U(),v("Reply directly · Unsubscribe · 123 Main St, Brooklyn",{fontSize:11,align:"center"}),u(" ",{align:"center",paddingBottom:24})],{...Ie,paddingTop:0})}],ls=[...Qa,...Za,...es,...ts,...ns,...os,...rs,...is,...as,...ss];let ao=!1;function _o(){if(!ao){for(const e of ls)Ze.register(e);ao=!0}}_o();function ds(){const{doc:e,addModule:t,loadFromLocalStorage:n}=O();return g.useEffect(()=>{if(n(),O.getState().doc.modules.length===0){const r=["header.hero","content.headline_body","cta.simple","footer.simple"];for(const i of r){const a=Ze.get(i);a&&t(a.create())}O.setState({selection:{kind:"email"},past:[],future:[]})}},[]),g.useEffect(()=>{const r=setTimeout(()=>O.getState().saveToLocalStorage(),500);return()=>clearTimeout(r)},[e]),o.jsxs("div",{className:"oml-email-builder h-full w-full flex flex-col bg-gray-100",children:[o.jsx(Tr,{}),o.jsxs("div",{className:"flex flex-1 overflow-hidden",children:[o.jsx(Rr,{}),o.jsx(xa,{}),o.jsx(_a,{})]})]})}const cs=e=>{if(e&&typeof e=="object"&&"url"in e&&typeof e.url=="string"){const t=e;return{url:t.url,alt:typeof t.alt=="string"?t.alt:void 0}}throw new Error('Server response missing "url" string field.')};function us(e){const t=e.fieldName??"file",n=(e.maxSizeMB??10)*1024*1024,r=e.transformResponse??cs;return{upload(i){return i.type.startsWith("image/")?i.size>n?Promise.reject(new Error(`File too large: ${(i.size/1024/1024).toFixed(2)} MB > ${e.maxSizeMB??10} MB`)):new Promise((a,s)=>{const d=new XMLHttpRequest,l=new FormData;if(l.append(t,i,i.name),d.open("POST",e.endpoint,!0),d.withCredentials=!!e.withCredentials,e.headers)for(const[c,m]of Object.entries(e.headers))d.setRequestHeader(c,m);e.onProgress&&d.upload&&(d.upload.onprogress=c=>{c.lengthComputable&&e.onProgress(Math.round(c.loaded/c.total*100))}),d.onload=()=>{const c=d.status>=200&&d.status<300;let m=null;try{m=d.responseText?JSON.parse(d.responseText):null}catch{}if(!c){const p=(m&&typeof m=="object"&&"error"in m&&typeof m.error=="string"?m.error:null)??`Upload failed (HTTP ${d.status})`;return s(new Error(p))}try{a(r(m))}catch(p){s(p instanceof Error?p:new Error(String(p)))}},d.onerror=()=>s(new Error("Network error during upload")),d.onabort=()=>s(new Error("Upload aborted")),d.send(l)}):Promise.reject(new Error(`Not an image: ${i.type||"unknown"}`))}}}function gs(e){return{name:"image-uploader",type:"asset-provider",setup(t){t.registerAssetProvider(us(e))}}}function Wo(e){return g.useEffect(()=>{if(_o(),e.modules)for(const n of e.modules)Ze.register(n);if(e.themes&&O.setState({themes:e.themes}),e.aiProvider&&Lo.setAIProvider(e.aiProvider),e.initialDocument){const n=Wt.safeParse(e.initialDocument);n.success&&O.getState().applyDoc(n.data,!1)}const t=O.subscribe((n,r)=>{n.doc!==r.doc&&e.onChange?.(n.doc)});return()=>t()},[]),g.useEffect(()=>{if(e.onExportHtml)return O.subscribe((t,n)=>{t.doc!==n.doc&&e.onExportHtml?.(xn(t.doc))})},[e.onExportHtml]),g.createElement(ds)}function ps(e){const t=Ko.createRoot(e.container);return t.render(g.createElement(Wo,e)),{destroy:()=>t.unmount(),getDocument:()=>O.getState().doc,exportHtml:()=>O.getState().exportHtml(),exportJson:()=>O.getState().exportJson()}}exports.ALGORITHMS=An;exports.ALGORITHM_BY_ID=Mo;exports.EmailBuilder=Wo;exports.FALLBACK_OPTIONS=bn;exports.TEMPLATE_CATEGORY_LABELS=vn;exports.createEmailBuilder=ps;exports.defaultRecommendationsLogic=Io;exports.documentSchema=Wt;exports.imageUploaderPlugin=gs;exports.readRecommendationsLogic=$o;exports.recommendationsToLegacyShape=Pa;exports.registerPlugin=Aa;exports.renderEmailHtml=xn;exports.templateRegistry=ke;
|
|
80
80
|
//# sourceMappingURL=email-builder.cjs.map
|