diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da0a3cb4..bbbbeb0aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Each tagged version of Datastar is accompanied by a release note. Read the [rele - Whitespace is now maintained in merged fragments ([#658](https://github.com/starfederation/datastar/issues/658)). - Attribute plugins now define a hash of their contents, preventing duplicate applies ([#691](https://github.com/starfederation/datastar/issues/691)). - Attribute plugins are now applied to the `html` element instead of the `body` element ([#691](https://github.com/starfederation/datastar/issues/691)). +- Removed Datastar singleton and export functions directly for `setAlias`, `load`, `apply` ### Fixed diff --git a/README.md b/README.md index 82bac51e3..a115c0f4c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Datastar helps you build reactive web applications with the simplicity of server-side rendering and the power of a full-stack SPA framework. -Getting started is as easy as adding a single 14.4 KiB script tag to your HTML. +Getting started is as easy as adding a single 14.3 KiB script tag to your HTML. ```html diff --git a/bundles/datastar-aliased.js b/bundles/datastar-aliased.js index 5770599f8..e389a8dfc 100644 --- a/bundles/datastar-aliased.js +++ b/bundles/datastar-aliased.js @@ -1,13 +1,13 @@ // Datastar v1.0.0-beta.7 -var $e=/🖕JS_DS🚀/.source,he=$e.slice(0,5),Pe=$e.slice(4),D="datastar";var Ge="Datastar-Request",ve=300,Ue=1e3,Be="type module",ye=!1,je=!1,Ke=!0,W={Morph:"morph",Inner:"inner",Outer:"outer",Prepend:"prepend",Append:"append",Before:"before",After:"after",UpsertAttributes:"upsertAttributes"},Je=W.Morph,k={MergeFragments:"datastar-merge-fragments",MergeSignals:"datastar-merge-signals",RemoveFragments:"datastar-remove-fragments",RemoveSignals:"datastar-remove-signals",ExecuteScript:"datastar-execute-script"};var w=(r=>(r[r.Attribute=1]="Attribute",r[r.Watcher=2]="Watcher",r[r.Action=3]="Action",r))(w||{});var ae=`${D}-signals`;var K=t=>t.trim()==="true",le=t=>t.replace(/[A-Z]+(?![a-z])|[A-Z]/g,(e,n)=>(n?"-":"")+e.toLowerCase()),Y=t=>le(t).replace(/-./g,e=>e[1].toUpperCase()),Ce=t=>le(t).replace(/-/g,"_"),hn=t=>Y(t).replace(/^./,e=>e[0].toUpperCase()),be=t=>new Function(`return Object.assign({}, ${t})`)(),J=t=>t.startsWith("$")?t.slice(1):t,vn={kebab:le,snake:Ce,pascal:hn};function V(t,e){for(let n of e.get("case")||[]){let r=vn[n];r&&(t=r(t))}return t}var yn="computed",ze={type:1,name:yn,keyReq:1,valReq:1,onLoad:({key:t,mods:e,signals:n,genRX:r})=>{t=V(t,e);let i=r();n.setComputed(t,i)}};var Ye={type:1,name:"signals",removeOnLoad:()=>!0,onLoad:t=>{let{key:e,mods:n,signals:r,value:i,genRX:s}=t,l=n.has("ifmissing");if(e!==""){let o=V(e,n),m=i===""?i:s()();l?r.upsertIfMissing(o,m):r.setValue(o,m)}else{let o=be(t.value);t.value=JSON.stringify(o);let S=s()();r.merge(S,l)}}};var Xe={type:1,name:"star",keyReq:2,valReq:2,onLoad:()=>{alert("YOU ARE PROBABLY OVERCOMPLICATING IT")}};var Z=class{#e=0;#t;constructor(e=D){this.#t=e}with(e){if(typeof e=="string")for(let n of e.split(""))this.with(n.charCodeAt(0));else typeof e=="boolean"?this.with(1<<(e?7:3)):this.#e=(this.#e<<5)-this.#e+e;return this}get value(){return this.#e}get string(){return this.#t+Math.abs(this.#e).toString(36)}};function Qe(t){if(t.id)return t.id;let e=new Z,n=t;for(;n;){if(e.with(n.tagName||""),n.id){e.with(n.id);break}let r=n?.parentNode;r&&e.with([...r.children].indexOf(n)),n=r}return e.string}function Ze(t,e){return new Z().with(t).with(e).value}function Ie(t,e){if(!t||!(t instanceof HTMLElement||t instanceof SVGElement))return null;let n=t.dataset;if("starIgnore"in n)return null;"starIgnore__self"in n||e(t);let r=t.firstElementChild;for(;r;)Ie(r,e),r=r.nextElementSibling}var bn="https://data-star.dev/errors";function Le(t,e,n={}){let r=new Error;r.name=`${D} ${t} error`;let i=Ce(e),s=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),l=JSON.stringify(n,null,2);return r.message=`${e} -More info: ${bn}/${t}/${i}?${s} -Context: ${l}`,r}function $(t,e,n={}){return Le("internal",e,Object.assign({from:t},n))}function H(t,e,n={}){let r={plugin:{name:e.plugin.name,type:w[e.plugin.type]}};return Le("init",t,Object.assign(r,n))}function M(t,e,n={}){let r={plugin:{name:e.plugin.name,type:w[e.plugin.type]},element:{id:e.el.id,tag:e.el.tagName},expression:{rawKey:e.rawKey,key:e.key,value:e.value,validSignals:e.signals.paths(),fnContent:e.fnContent}};return Le("runtime",t,Object.assign(r,n))}var ee="preact-signals",Sn=Symbol.for("preact-signals"),G=1,te=2,ce=4,re=8,Se=16,ne=32;function De(){Te++}function ke(){if(Te>1){Te--;return}let t,e=!1;for(;ue!==void 0;){let n=ue;for(ue=void 0,Ve++;n!==void 0;){let r=n._nextBatchedEffect;if(n._nextBatchedEffect=void 0,n._flags&=~te,!(n._flags&re)&&tt(n))try{n._callback()}catch(i){e||(t=i,e=!0)}n=r}}if(Ve=0,Te--,e)throw t}var P;var ue,Te=0,Ve=0,Ae=0;function et(t){if(P===void 0)return;let e=t._node;if(e===void 0||e._target!==P)return e={_version:0,_source:t,_prevSource:P._sources,_nextSource:void 0,_target:P,_prevTarget:void 0,_nextTarget:void 0,_rollbackNode:e},P._sources!==void 0&&(P._sources._nextSource=e),P._sources=e,t._node=e,P._flags&ne&&t._subscribe(e),e;if(e._version===-1)return e._version=0,e._nextSource!==void 0&&(e._nextSource._prevSource=e._prevSource,e._prevSource!==void 0&&(e._prevSource._nextSource=e._nextSource),e._prevSource=P._sources,e._nextSource=void 0,P._sources._nextSource=e,P._sources=e),e}function C(t){this._value=t,this._version=0,this._node=void 0,this._targets=void 0}C.prototype.brand=Sn;C.prototype._refresh=()=>!0;C.prototype._subscribe=function(t){this._targets!==t&&t._prevTarget===void 0&&(t._nextTarget=this._targets,this._targets!==void 0&&(this._targets._prevTarget=t),this._targets=t)};C.prototype._unsubscribe=function(t){if(this._targets!==void 0){let e=t._prevTarget,n=t._nextTarget;e!==void 0&&(e._nextTarget=n,t._prevTarget=void 0),n!==void 0&&(n._prevTarget=e,t._nextTarget=void 0),t===this._targets&&(this._targets=n)}};C.prototype.subscribe=function(t){return Ee(()=>{let e=this.value,n=P;P=void 0;try{t(e)}finally{P=n}})};C.prototype.valueOf=function(){return this.value};C.prototype.toString=function(){return`${this.value}`};C.prototype.toJSON=function(){return this.value};C.prototype.peek=function(){let t=P;P=void 0;try{return this.value}finally{P=t}};Object.defineProperty(C.prototype,"value",{get(){let t=et(this);return t!==void 0&&(t._version=this._version),this._value},set(t){if(t!==this._value){if(Ve>100)throw $(ee,"SignalCycleDetected");let e=this._value,n=t;this._value=t,this._version++,Ae++,De();try{for(let r=this._targets;r!==void 0;r=r._nextTarget)r._target._notify()}finally{ke()}this?._onChange({old:e,revised:n})}}});function tt(t){for(let e=t._sources;e!==void 0;e=e._nextSource)if(e._source._version!==e._version||!e._source._refresh()||e._source._version!==e._version)return!0;return!1}function nt(t){for(let e=t._sources;e!==void 0;e=e._nextSource){let n=e._source._node;if(n!==void 0&&(e._rollbackNode=n),e._source._node=e,e._version=-1,e._nextSource===void 0){t._sources=e;break}}}function rt(t){let e=t._sources,n;for(;e!==void 0;){let r=e._prevSource;e._version===-1?(e._source._unsubscribe(e),r!==void 0&&(r._nextSource=e._nextSource),e._nextSource!==void 0&&(e._nextSource._prevSource=r)):n=e,e._source._node=e._rollbackNode,e._rollbackNode!==void 0&&(e._rollbackNode=void 0),e=r}t._sources=n}function X(t){C.call(this,void 0),this._fn=t,this._sources=void 0,this._globalVersion=Ae-1,this._flags=ce}X.prototype=new C;X.prototype._refresh=function(){if(this._flags&=~te,this._flags&G)return!1;if((this._flags&(ce|ne))===ne||(this._flags&=~ce,this._globalVersion===Ae))return!0;if(this._globalVersion=Ae,this._flags|=G,this._version>0&&!tt(this))return this._flags&=~G,!0;let t=P;try{nt(this),P=this;let e=this._fn();(this._flags&Se||this._value!==e||this._version===0)&&(this._value=e,this._flags&=~Se,this._version++)}catch(e){this._value=e,this._flags|=Se,this._version++}return P=t,rt(this),this._flags&=~G,!0};X.prototype._subscribe=function(t){if(this._targets===void 0){this._flags|=ce|ne;for(let e=this._sources;e!==void 0;e=e._nextSource)e._source._subscribe(e)}C.prototype._subscribe.call(this,t)};X.prototype._unsubscribe=function(t){if(this._targets!==void 0&&(C.prototype._unsubscribe.call(this,t),this._targets===void 0)){this._flags&=~ne;for(let e=this._sources;e!==void 0;e=e._nextSource)e._source._unsubscribe(e)}};X.prototype._notify=function(){if(!(this._flags&te)){this._flags|=ce|te;for(let t=this._targets;t!==void 0;t=t._nextTarget)t._target._notify()}};Object.defineProperty(X.prototype,"value",{get(){if(this._flags&G)throw $(ee,"SignalCycleDetected");let t=et(this);if(this._refresh(),t!==void 0&&(t._version=this._version),this._flags&Se)throw $(ee,"GetComputedError",{value:this._value});return this._value}});function it(t){return new X(t)}function st(t){let e=t._cleanup;if(t._cleanup=void 0,typeof e=="function"){De();let n=P;P=void 0;try{e()}catch(r){throw t._flags&=~G,t._flags|=re,Oe(t),$(ee,"CleanupEffectError",{error:r})}finally{P=n,ke()}}}function Oe(t){for(let e=t._sources;e!==void 0;e=e._nextSource)e._source._unsubscribe(e);t._fn=void 0,t._sources=void 0,st(t)}function Tn(t){if(P!==this)throw $(ee,"EndEffectError");rt(this),P=t,this._flags&=~G,this._flags&re&&Oe(this),ke()}function fe(t){this._fn=t,this._cleanup=void 0,this._sources=void 0,this._nextBatchedEffect=void 0,this._flags=ne}fe.prototype._callback=function(){let t=this._start();try{if(this._flags&re||this._fn===void 0)return;let e=this._fn();typeof e=="function"&&(this._cleanup=e)}finally{t()}};fe.prototype._start=function(){if(this._flags&G)throw $(ee,"SignalCycleDetected");this._flags|=G,this._flags&=~re,st(this),nt(this),De();let t=P;return P=this,Tn.bind(this,t)};fe.prototype._notify=function(){this._flags&te||(this._flags|=te,this._nextBatchedEffect=ue,ue=this)};fe.prototype._dispose=function(){this._flags|=re,this._flags&G||Oe(this)};function Ee(t){let e=new fe(t);try{e._callback()}catch(n){throw e._dispose(),n}return e._dispose.bind(e)}var ot="namespacedSignals",ie=t=>{document.dispatchEvent(new CustomEvent(ae,{detail:Object.assign({added:[],removed:[],updated:[]},t)}))};function at(t,e=!1){let n={};for(let r in t)if(Object.hasOwn(t,r)){if(e&&r.startsWith("_"))continue;let i=t[r];i instanceof C?n[r]=i.value:n[r]=at(i)}return n}function lt(t,e,n=!1){let r={added:[],removed:[],updated:[]};for(let i in e)if(Object.hasOwn(e,i)){if(i.match(/\_\_+/))throw $(ot,"InvalidSignalKey",{key:i});let s=e[i];if(s instanceof Object&&!Array.isArray(s)){t[i]||(t[i]={});let l=lt(t[i],s,n);r.added.push(...l.added.map(o=>`${i}.${o}`)),r.removed.push(...l.removed.map(o=>`${i}.${o}`)),r.updated.push(...l.updated.map(o=>`${i}.${o}`))}else{if(Object.hasOwn(t,i)){if(n)continue;let m=t[i];if(m instanceof C){let S=m.value;m.value=s,S!==s&&r.updated.push(i);continue}}let o=new C(s);o._onChange=()=>{ie({updated:[i]})},t[i]=o,r.added.push(i)}}return r}function ut(t,e){for(let n in t)if(Object.hasOwn(t,n)){let r=t[n];r instanceof C?e(n,r):ut(r,(i,s)=>{e(`${n}.${i}`,s)})}}function An(t,...e){let n={};for(let r of e){let i=r.split("."),s=t,l=n;for(let m=0;mn());this.setSignal(e,r)}value(e){return this.signal(e)?.value}setValue(e,n){let{signal:r}=this.upsertIfMissing(e,n),i=r.value;r.value=n,i!==n&&ie({updated:[e]})}upsertIfMissing(e,n){let r=e.split("."),i=this.#e;for(let m=0;m{ie({updated:[e]})},i[s]=o,ie({added:[e]}),{signal:o,inserted:!0}}remove(...e){if(!e.length){this.#e={};return}let n=Array();for(let r of e){let i=r.split("."),s=this.#e;for(let o=0;oe.push(n)),e}values(e=!1){return at(this.#e,e)}JSON(e=!0,n=!1){let r=this.values(n);return e?JSON.stringify(r,null,2):JSON.stringify(r)}toString(){return this.JSON()}};var xe=class{constructor(){this.aliasPrefix="";this.#e=new _e;this.#t=[];this.#r={};this.#s=[];this.#i=null;this.#n=new Map}#e;#t;#r;#s;#i;#n;get signals(){return this.#e}load(...e){let n=this;for(let r of e){let i={get signals(){return n.#e},effect:l=>Ee(l),actions:this.#r,plugin:r,apply:n.apply.bind(n)},s;switch(r.type){case 2:{let l=r;this.#s.push(l),s=l.onGlobalInit;break}case 3:{this.#r[r.name]=r;break}case 1:{let l=r;this.#t.push(l),s=l.onGlobalInit;break}default:throw H("InvalidPluginType",i)}s&&s(i)}this.#t.sort((r,i)=>{let s=i.name.length-r.name.length;return s!==0?s:r.name.localeCompare(i.name)})}apply(e=document.documentElement){Ie(e,n=>{let r=new Array,i=this.#n.get(n)||new Map,s=new Map([...i]),l=new Map;for(let o of Object.keys(n.dataset)){if(!o.startsWith(this.aliasPrefix))break;let m=n.dataset[o]||"",S=Ze(o,m);l.set(o,S),i.has(S)?s.delete(S):r.push(o)}for(let[o,m]of s)m();for(let o of r){let m=l.get(o);this.#a(n,o,m)}}),this.#o()}#o(){this.#i||(this.#i=new MutationObserver(e=>{let n=new Set,r=new Set;for(let{target:i,type:s,addedNodes:l,removedNodes:o}of e)switch(s){case"childList":{for(let m of o)n.add(m);for(let m of l)r.add(m)}break;case"attributes":{r.add(i);break}}for(let i of n){let s=this.#n.get(i);if(s){for(let[l,o]of s)o(),s.delete(l);s.size===0&&this.#n.delete(i)}}for(let i of r)this.apply(i)}),this.#i.observe(document.body,{attributes:!0,attributeOldValue:!0,childList:!0,subtree:!0}))}#a(e,n,r){let i=Y(n.slice(this.aliasPrefix.length)),s=this.#t.find(A=>i.startsWith(A.name));if(!s)return;e.id.length||(e.id=Qe(e));let[l,...o]=i.slice(s.name.length).split(/\_\_+/),m=l.length>0;m&&(l=Y(l));let S=e.dataset[n]||"",T=S.length>0,N=this,v={get signals(){return N.#e},apply:N.apply.bind(N),effect:A=>Ee(A),actions:this.#r,genRX:()=>this.#l(v,...s.argNames||[]),plugin:s,el:e,rawKey:i,key:l,value:S,mods:new Map},R=s.keyReq||0;if(m){if(R===2)throw M(`${s.name}KeyNotAllowed`,v)}else if(R===1)throw M(`${s.name}KeyRequired`,v);let y=s.valReq||0;if(T){if(y===2)throw M(`${s.name}ValueNotAllowed`,v)}else if(y===1)throw M(`${s.name}ValueRequired`,v);if(R===3||y===3){if(m&&T)throw M(`${s.name}KeyAndValueProvided`,v);if(!m&&!T)throw M(`${s.name}KeyOrValueRequired`,v)}for(let A of o){let[h,...a]=A.split(".");v.mods.set(Y(h),new Set(a.map(c=>c.toLowerCase())))}let E=s.onLoad(v);if(E){let A=this.#n.get(e);A||(A=new Map,this.#n.set(e,A)),A.set(r,E)}}#l(e,...n){let r="",i=/(\/(\\\/|[^\/])*\/|"(\\"|[^\"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|[^;])+/gm,s=e.value.trim().match(i);if(s){let y=s.length-1,E=s[y].trim();E.startsWith("return")||(s[y]=`return (${E});`),r=s.join(`; -`)}let l=new Map,o=new RegExp(`(?:${he})(.*?)(?:${Pe})`,"gm");for(let y of r.matchAll(o)){let E=y[1],A=new Z("dsEscaped").with(E).string;l.set(A,E),r=r.replace(he+E+Pe,A)}let m=/@(\w*)\(/gm,S=r.matchAll(m),T=new Set;for(let y of S)T.add(y[1]);let N=new RegExp(`@(${Object.keys(this.#r).join("|")})\\(`,"gm");r=r.replaceAll(N,"ctx.actions.$1.fn(ctx,");let v=e.signals.paths();if(v.length){let y=new RegExp(`\\$(${v.join("|")})(\\W|$)`,"gm");r=r.replaceAll(y,"ctx.signals.signal('$1').value$2")}for(let[y,E]of l)r=r.replace(y,E);let R=`return (()=> { -${r} -})()`;e.fnContent=R;try{let y=new Function("ctx",...n,R);return(...E)=>{try{return y(e,...E)}catch(A){throw M("ExecuteExpression",e,{error:A.message})}}}catch(y){throw M("GenerateExpression",e,{error:y.message})}}};var ct=new xe;ct.load(Xe,Ye,ze);var de=ct;async function En(t,e){let n=t.getReader(),r;for(;!(r=await n.read()).done;)e(r.value)}function _n(t){let e,n,r,i=!1;return function(l){e===void 0?(e=l,n=0,r=-1):e=Rn(e,l);let o=e.length,m=0;for(;n0){let m=i.decode(l.subarray(0,o)),S=o+(l[o+1]===32?2:1),T=i.decode(l.subarray(S));switch(m){case"data":r.data=r.data?`${r.data} -${T}`:T;break;case"event":r.event=T;break;case"id":t(r.id=T);break;case"retry":{let N=Number.parseInt(T,10);Number.isNaN(N)||e(r.retry=N);break}}}}}function Rn(t,e){let n=new Uint8Array(t.length+e.length);return n.set(t),n.set(e,t.length),n}function ft(){return{data:"",event:"",id:"",retry:void 0}}var wn="text/event-stream",dt="last-event-id";function pt(t,e,{signal:n,headers:r,onopen:i,onmessage:s,onclose:l,onerror:o,openWhenHidden:m,fetch:S,retryInterval:T=1e3,retryScaler:N=2,retryMaxWaitMs:v=3e4,retryMaxCount:R=10,...y}){return new Promise((E,A)=>{let h=0,a={...r};a.accept||(a.accept=wn);let c;function u(){c.abort(),document.hidden||b()}m||document.addEventListener("visibilitychange",u);let d=0;function g(){document.removeEventListener("visibilitychange",u),window.clearTimeout(d),c.abort()}n?.addEventListener("abort",()=>{g(),E()});let p=S??window.fetch,f=i??function(){};async function b(){c=new AbortController;try{let _=await p(e,{...y,headers:a,signal:c.signal});await f(_),await En(_.body,_n(xn(x=>{x?a[dt]=x:delete a[dt]},x=>{T=x},s))),l?.(),g(),E()}catch(_){if(!c.signal.aborted)try{let x=o?.(_)??T;window.clearTimeout(d),d=window.setTimeout(b,x),T*=N,T=Math.min(T,v),h++,h>=R?(g(),A(M("SseMaxRetries",t,{retryMaxCount:R}))):console.error(`Datastar failed to reach ${y.method}: ${e.toString()} retry in ${x}ms`)}catch(x){g(),A(x)}}}b()})}var se=`${D}-sse`,He=`${D}-settling`,Q=`${D}-swapping`,Re="started",we="finished",mt="error",gt="retrying";function U(t,e){document.addEventListener(se,n=>{if(n.detail.type!==t)return;let{argsRaw:r}=n.detail;e(r)})}function pe(t,e){document.dispatchEvent(new CustomEvent(se,{detail:{type:t,argsRaw:e}}))}var ht=t=>`${t}`.includes("text/event-stream"),B=async(t,e,n,r)=>{let{el:{id:i},el:s,signals:l}=t,{headers:o,contentType:m,includeLocal:S,selector:T,openWhenHidden:N,retryInterval:v,retryScaler:R,retryMaxWaitMs:y,retryMaxCount:E,abort:A}=Object.assign({headers:{},contentType:"json",includeLocal:!1,selector:null,openWhenHidden:!1,retryInterval:Ue,retryScaler:2,retryMaxWaitMs:3e4,retryMaxCount:10,abort:void 0},r),h=e.toLowerCase(),a=()=>{};try{if(pe(Re,{elId:i}),!n?.length)throw M("SseNoUrlProvided",t,{action:h});let c={};c[Ge]=!0,m==="json"&&(c["Content-Type"]="application/json");let u=Object.assign({},c,o),d={method:e,headers:u,openWhenHidden:N,retryInterval:v,retryScaler:R,retryMaxWaitMs:y,retryMaxCount:E,signal:A,onopen:async f=>{if(f.status>=400){let b=f.status.toString();pe(mt,{status:b})}},onmessage:f=>{if(!f.event.startsWith(D))return;let b=f.event,_={},x=f.data.split(` -`);for(let F of x){let L=F.indexOf(" "),q=F.slice(0,L),j=_[q];j||(j=[],_[q]=j);let gn=F.slice(L+1);j.push(gn)}let I={};for(let[F,L]of Object.entries(_))I[F]=L.join(` -`);pe(b,I)},onerror:f=>{if(ht(f))throw M("InvalidContentType",t,{url:n});f&&(console.error(f.message),pe(gt,{message:f.message}))}},g=new URL(n,window.location.origin),p=new URLSearchParams(g.search);if(m==="json"){let f=l.JSON(!1,!S);e==="GET"?p.set(D,f):d.body=f}else if(m==="form"){let f=T?document.querySelector(T):s.closest("form");if(f===null)throw T?M("SseFormNotFound",t,{action:h,selector:T}):M("SseClosestFormNotFound",t,{action:h});if(s!==f){let _=x=>x.preventDefault();f.addEventListener("submit",_),a=()=>f.removeEventListener("submit",_)}if(!f.checkValidity()){f.reportValidity(),a();return}let b=new FormData(f);if(e==="GET"){let _=new URLSearchParams(b);for(let[x,I]of _)p.set(x,I)}else d.body=b}else throw M("SseInvalidContentType",t,{action:h,contentType:m});g.search=p.toString();try{await pt(t,g.toString(),d)}catch(f){if(!ht(f))throw M("SseFetchFailed",t,{method:e,url:n,error:f})}}finally{pe(we,{elId:i}),a()}};var vt={type:3,name:"delete",fn:async(t,e,n)=>B(t,"DELETE",e,{...n})};var yt={type:3,name:"get",fn:async(t,e,n)=>B(t,"GET",e,{...n})};var bt={type:3,name:"patch",fn:async(t,e,n)=>B(t,"PATCH",e,{...n})};var St={type:3,name:"post",fn:async(t,e,n)=>B(t,"POST",e,{...n})};var Tt={type:3,name:"put",fn:async(t,e,n)=>B(t,"PUT",e,{...n})};var At={type:1,name:"indicator",keyReq:3,valReq:3,onLoad:({el:t,key:e,mods:n,signals:r,value:i})=>{let s=e?V(e,n):J(i),{signal:l}=r.upsertIfMissing(s,!1),o=m=>{let{type:S,argsRaw:{elId:T}}=m.detail;if(T===t.id)switch(S){case Re:l.value=!0;break;case we:l.value=!1;break}};return document.addEventListener(se,o),()=>{document.removeEventListener(se,o)}}};var Et={type:2,name:k.ExecuteScript,onGlobalInit:async t=>{U(k.ExecuteScript,({autoRemove:e=`${Ke}`,attributes:n=Be,script:r})=>{let i=K(e);if(!r?.length)throw H("NoScriptProvided",t);let s=document.createElement("script");for(let l of n.split(` -`)){let o=l.indexOf(" "),m=o?l.slice(0,o):l,S=o?l.slice(o):"";s.setAttribute(m.trim(),S.trim())}s.text=r,document.head.appendChild(s),i&&s.remove()})}};var me=document,z=!!me.startViewTransition;var _t=function(){"use strict";let t=()=>{},e={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:t,afterNodeAdded:t,beforeNodeMorphed:t,afterNodeMorphed:t,beforeNodeRemoved:t,afterNodeRemoved:t,beforeAttributeUpdated:t},head:{style:"merge",shouldPreserve:v=>v.getAttribute("im-preserve")==="true",shouldReAppend:v=>v.getAttribute("im-re-append")==="true",shouldRemove:t,afterHeadMorphed:t},restoreFocus:!0};function n(v,R,y={}){v=T(v);let E=N(R),A=S(v,E,y),h=i(A,()=>o(A,v,E,a=>a.morphStyle==="innerHTML"?(s(a,v,E),Array.from(v.childNodes)):r(a,v,E)));return A.pantry.remove(),h}function r(v,R,y){let E=N(R),A=Array.from(E.childNodes),h=A.indexOf(R),a=A.length-(h+1);return s(v,E,y,R,R.nextSibling),A=Array.from(E.childNodes),A.slice(h,A.length-a)}function i(v,R){if(!v.config.restoreFocus)return R();let y=document.activeElement;if(!(y instanceof HTMLInputElement||y instanceof HTMLTextAreaElement))return R();let{id:E,selectionStart:A,selectionEnd:h}=y,a=R();return E&&E!==document.activeElement?.id&&(y=v.target.querySelector(`#${E}`),y?.focus()),y&&!y.selectionEnd&&h&&y.setSelectionRange(A,h),a}let s=function(){function v(u,d,g,p=null,f=null){d instanceof HTMLTemplateElement&&g instanceof HTMLTemplateElement&&(d=d.content,g=g.content),p||=d.firstChild;for(let b of g.childNodes){if(p&&p!=f){let x=y(u,b,p,f);if(x){x!==p&&A(u,p,x),l(x,b,u),p=x.nextSibling;continue}}if(b instanceof Element&&u.persistentIds.has(b.id)){let x=h(d,b.id,p,u);l(x,b,u),p=x.nextSibling;continue}let _=R(d,b,p,u);_&&(p=_.nextSibling)}for(;p&&p!=f;){let b=p;p=p.nextSibling,E(u,b)}}function R(u,d,g,p){if(p.callbacks.beforeNodeAdded(d)===!1)return null;if(p.idMap.has(d)){let f=document.createElement(d.tagName);return u.insertBefore(f,g),l(f,d,p),p.callbacks.afterNodeAdded(f),f}else{let f=document.importNode(d,!0);return u.insertBefore(f,g),p.callbacks.afterNodeAdded(f),f}}let y=function(){function u(p,f,b,_){let x=null,I=f.nextSibling,F=0,L=b;for(;L&&L!=_;){if(g(L,f)){if(d(p,L,f))return L;x===null&&(p.idMap.has(L)||(x=L))}if(x===null&&I&&g(L,I)&&(F++,I=I.nextSibling,F>=2&&(x=void 0)),L.contains(document.activeElement))break;L=L.nextSibling}return x||null}function d(p,f,b){let _=p.idMap.get(f),x=p.idMap.get(b);if(!x||!_)return!1;for(let I of _)if(x.has(I))return!0;return!1}function g(p,f){let b=p,_=f;return b.nodeType===_.nodeType&&b.tagName===_.tagName&&(!b.id||b.id===_.id)}return u}();function E(u,d){if(u.idMap.has(d))c(u.pantry,d,null);else{if(u.callbacks.beforeNodeRemoved(d)===!1)return;d.parentNode?.removeChild(d),u.callbacks.afterNodeRemoved(d)}}function A(u,d,g){let p=d;for(;p&&p!==g;){let f=p;p=p.nextSibling,E(u,f)}return p}function h(u,d,g,p){let f=p.target.querySelector(`#${d}`)||p.pantry.querySelector(`#${d}`);return a(f,p),c(u,f,g),f}function a(u,d){let g=u.id;for(;u=u.parentNode;){let p=d.idMap.get(u);p&&(p.delete(g),p.size||d.idMap.delete(u))}}function c(u,d,g){if(u.moveBefore)try{u.moveBefore(d,g)}catch{u.insertBefore(d,g)}else u.insertBefore(d,g)}return v}(),l=function(){function v(a,c,u){return u.ignoreActive&&a===document.activeElement?null:(u.callbacks.beforeNodeMorphed(a,c)===!1||(a instanceof HTMLHeadElement&&u.head.ignore||(a instanceof HTMLHeadElement&&u.head.style!=="morph"?m(a,c,u):(R(a,c,u),h(a,u)||s(u,a,c))),u.callbacks.afterNodeMorphed(a,c)),a)}function R(a,c,u){let d=c.nodeType;if(d===1){let g=a,p=c,f=g.attributes,b=p.attributes;for(let _ of b)A(_.name,g,"update",u)||g.getAttribute(_.name)!==_.value&&g.setAttribute(_.name,_.value);for(let _=f.length-1;0<=_;_--){let x=f[_];if(x&&!p.hasAttribute(x.name)){if(A(x.name,g,"remove",u))continue;g.removeAttribute(x.name)}}h(g,u)||y(g,p,u)}(d===8||d===3)&&a.nodeValue!==c.nodeValue&&(a.nodeValue=c.nodeValue)}function y(a,c,u){if(a instanceof HTMLInputElement&&c instanceof HTMLInputElement&&c.type!=="file"){let d=c.value,g=a.value;E(a,c,"checked",u),E(a,c,"disabled",u),c.hasAttribute("value")?g!==d&&(A("value",a,"update",u)||(a.setAttribute("value",d),a.value=d)):A("value",a,"remove",u)||(a.value="",a.removeAttribute("value"))}else if(a instanceof HTMLOptionElement&&c instanceof HTMLOptionElement)E(a,c,"selected",u);else if(a instanceof HTMLTextAreaElement&&c instanceof HTMLTextAreaElement){let d=c.value,g=a.value;if(A("value",a,"update",u))return;d!==g&&(a.value=d),a.firstChild&&a.firstChild.nodeValue!==d&&(a.firstChild.nodeValue=d)}}function E(a,c,u,d){let g=c[u],p=a[u];if(g!==p){let f=A(u,a,"update",d);f||(a[u]=c[u]),g?f||a.setAttribute(u,""):A(u,a,"remove",d)||a.removeAttribute(u)}}function A(a,c,u,d){return a==="value"&&d.ignoreActiveValue&&c===document.activeElement?!0:d.callbacks.beforeAttributeUpdated(a,c,u)===!1}function h(a,c){return!!c.ignoreActiveValue&&a===document.activeElement&&a!==document.body}return v}();function o(v,R,y,E){if(v.head.block){let A=R.querySelector("head"),h=y.querySelector("head");if(A&&h){let a=m(A,h,v);return Promise.all(a).then(()=>{let c=Object.assign(v,{head:{block:!1,ignore:!0}});return E(c)})}}return E(v)}function m(v,R,y){let E=[],A=[],h=[],a=[],c=new Map;for(let d of R.children)c.set(d.outerHTML,d);for(let d of v.children){let g=c.has(d.outerHTML),p=y.head.shouldReAppend(d),f=y.head.shouldPreserve(d);g||f?p?A.push(d):(c.delete(d.outerHTML),h.push(d)):y.head.style==="append"?p&&(A.push(d),a.push(d)):y.head.shouldRemove(d)!==!1&&A.push(d)}a.push(...c.values());let u=[];for(let d of a){let g=document.createRange().createContextualFragment(d.outerHTML).firstChild;if(y.callbacks.beforeNodeAdded(g)!==!1){if("href"in g&&g.href||"src"in g&&g.src){let p,f=new Promise(function(b){p=b});g.addEventListener("load",function(){p()}),u.push(f)}v.appendChild(g),y.callbacks.afterNodeAdded(g),E.push(g)}}for(let d of A)y.callbacks.beforeNodeRemoved(d)!==!1&&(v.removeChild(d),y.callbacks.afterNodeRemoved(d));return y.head.afterHeadMorphed(v,{added:E,kept:h,removed:A}),u}let S=function(){function v(c,u,d){let{persistentIds:g,idMap:p}=h(c,u),f=R(d),b=f.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(b))throw`Do not understand how to morph style ${b}`;return{target:c,newContent:u,config:f,morphStyle:b,ignoreActive:f.ignoreActive,ignoreActiveValue:f.ignoreActiveValue,restoreFocus:f.restoreFocus,idMap:p,persistentIds:g,pantry:y(),callbacks:f.callbacks,head:f.head}}function R(c){let u=Object.assign({},e);return Object.assign(u,c),u.callbacks=Object.assign({},e.callbacks,c.callbacks),u.head=Object.assign({},e.head,c.head),u}function y(){let c=document.createElement("div");return c.hidden=!0,document.body.insertAdjacentElement("afterend",c),c}function E(c){let u=Array.from(c.querySelectorAll("[id]"));return c.id&&u.push(c),u}function A(c,u,d,g){for(let p of g)if(u.has(p.id)){let f=p;for(;f;){let b=c.get(f);if(b==null&&(b=new Set,c.set(f,b)),b.add(p.id),f===d)break;f=f.parentElement}}}function h(c,u){let d=E(c),g=E(u),p=a(d,g),f=new Map;A(f,p,c,d);let b=u.__idiomorphRoot||u;return A(f,p,b,g),{persistentIds:p,idMap:f}}function a(c,u){let d=new Set,g=new Map;for(let{id:f,tagName:b}of c)g.has(f)?d.add(f):g.set(f,b);let p=new Set;for(let{id:f,tagName:b}of u)p.has(f)?d.add(f):g.get(f)===b&&p.add(f);for(let f of d)p.delete(f);return p}return v}(),{normalizeElement:T,normalizeParent:N}=function(){let v=new WeakSet;function R(h){return h instanceof Document?h.documentElement:h}function y(h){if(h==null)return document.createElement("div");if(typeof h=="string")return y(A(h));if(v.has(h))return h;if(h instanceof Node){if(h.parentNode)return E(h);{let a=document.createElement("div");return a.append(h),a}}else{let a=document.createElement("div");for(let c of[...h])a.append(c);return a}}function E(h){return{childNodes:[h],querySelectorAll:a=>{let c=h.querySelectorAll(a);return h.matches(a)?[h,...c]:c},insertBefore:(a,c)=>h.parentNode.insertBefore(a,c),moveBefore:(a,c)=>h.parentNode.moveBefore(a,c),get __idiomorphRoot(){return h}}}function A(h){let a=new DOMParser,c=h.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");if(c.match(/<\/html>/)||c.match(/<\/head>/)||c.match(/<\/body>/)){let u=a.parseFromString(h,"text/html");if(c.match(/<\/html>/))return v.add(u),u;{let d=u.firstChild;return d&&v.add(d),d}}else{let d=a.parseFromString("","text/html").body.querySelector("template").content;return v.add(d),d}}return{normalizeElement:R,normalizeParent:y}}();return{morph:n,defaults:e}}();var Rt={type:2,name:k.MergeFragments,onGlobalInit:async t=>{let e=document.createElement("template");U(k.MergeFragments,({fragments:n="
",selector:r="",mergeMode:i=Je,settleDuration:s=`${ve}`,useViewTransition:l=`${ye}`})=>{let o=Number.parseInt(s),m=K(l);e.innerHTML=n.trim();let S=[...e.content.children];for(let T of S){if(!(T instanceof Element))throw H("NoFragmentsFound",t);let N=r||`#${T.getAttribute("id")}`,v=[...document.querySelectorAll(N)||[]];if(!v.length)throw H("NoTargetsFound",t,{selectorOrID:N});m&&z?me.startViewTransition(()=>xt(t,i,o,T,v)):xt(t,i,o,T,v)}})}};function xt(t,e,n,r,i){for(let s of i){s.classList.add(Q);let l=s.outerHTML,o=s;switch(e){case W.Morph:{_t.morph(o,r.cloneNode(!0));break}case W.Inner:o.innerHTML=r.outerHTML;break;case W.Outer:o.replaceWith(r);break;case W.Prepend:o.prepend(r);break;case W.Append:o.append(r);break;case W.Before:o.before(r);break;case W.After:o.after(r);break;case W.UpsertAttributes:for(let T of r.getAttributeNames()){let N=r.getAttribute(T);o.setAttribute(T,N)}break;default:throw H("InvalidMergeMode",t,{mergeMode:e})}let m=o.classList;m?.add(Q),setTimeout(()=>{s.classList.remove(Q),m?.remove(Q)},n);let S=o.outerHTML;m&&l!==S&&(m.add(He),setTimeout(()=>{m.remove(He)},n))}}var wt={type:2,name:k.MergeSignals,onGlobalInit:async t=>{U(k.MergeSignals,({signals:e="{}",onlyIfMissing:n=`${je}`})=>{let{signals:r}=t,i=K(n);r.merge(be(e),i)})}};var Mt={type:2,name:k.RemoveFragments,onGlobalInit:async t=>{U(k.RemoveFragments,({selector:e,settleDuration:n=`${ve}`,useViewTransition:r=`${ye}`})=>{if(!e.length)throw H("NoSelectorProvided",t);let i=Number.parseInt(n),s=K(r),l=document.querySelectorAll(e),o=()=>{for(let m of l)m.classList.add(Q);setTimeout(()=>{for(let m of l)m.remove()},i)};s&&z?me.startViewTransition(()=>o()):o()})}};var Nt={type:2,name:k.RemoveSignals,onGlobalInit:async t=>{U(k.RemoveSignals,({paths:e=""})=>{let n=e.split(` -`).map(r=>r.trim());if(!n?.length)throw H("NoPathsProvided",t);t.signals.remove(...n)})}};var Pt={type:3,name:"clipboard",fn:(t,e)=>{if(!navigator.clipboard)throw M("ClipboardNotAvailable",t);navigator.clipboard.writeText(e)}};var Ct={type:1,name:"customValidity",keyReq:2,valReq:1,onLoad:t=>{let{el:e,genRX:n,effect:r}=t;if(!(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement))throw M("CustomValidityInvalidElement",t);let i=n();return r(()=>{let s=i();if(typeof s!="string")throw M("CustomValidityInvalidExpression",t,{result:s});e.setCustomValidity(s)})}};var It="once",Lt="half",Vt="full",Dt={type:1,name:"intersects",keyReq:2,mods:new Set([It,Lt,Vt]),onLoad:({el:t,rawKey:e,mods:n,genRX:r})=>{let i={threshold:0};n.has(Vt)?i.threshold=1:n.has(Lt)&&(i.threshold=.5);let s=r(),l=new IntersectionObserver(o=>{for(let m of o)m.isIntersecting&&(s(),n.has(It)&&(l.disconnect(),delete t.dataset[e]))},i);return l.observe(t),()=>l.disconnect()}};var kt="session",Ot={type:1,name:"persist",mods:new Set([kt]),onLoad:({key:t,effect:e,mods:n,signals:r,value:i})=>{t=V(t,n),t===""&&(t=D);let s=n.has(kt)?sessionStorage:localStorage,l=i.split(/\s+/).filter(S=>S!=="");l=l.map(S=>J(S));let o=()=>{let S=s.getItem(t)||"{}",T=JSON.parse(S);r.merge(T)},m=()=>{let S;l.length?S=r.subset(...l):S=r.values(),s.setItem(t,JSON.stringify(S))};return o(),e(()=>{m()})}};var Ht={type:1,name:"replaceUrl",keyReq:2,valReq:1,onLoad:({effect:t,genRX:e})=>{let n=e();return t(()=>{let r=n(),i=window.location.href,s=new URL(r,i).toString();window.history.replaceState({},"",s)})}};var Me="smooth",Fe="instant",qe="auto",Ft="hstart",qt="hcenter",Wt="hend",$t="hnearest",Gt="vstart",Ut="vcenter",Bt="vend",jt="vnearest",Mn="focus",Ne="center",Kt="start",Jt="end",zt="nearest",Yt={type:1,name:"scrollIntoView",keyReq:2,valReq:2,mods:new Set([Me,Fe,qe,Ft,qt,Wt,$t,Gt,Ut,Bt,jt,Mn]),onLoad:t=>{let{el:e,mods:n,rawKey:r}=t;e.tabIndex||e.setAttribute("tabindex","0");let i={behavior:Me,block:Ne,inline:Ne};if(n.has(Me)&&(i.behavior=Me),n.has(Fe)&&(i.behavior=Fe),n.has(qe)&&(i.behavior=qe),n.has(Ft)&&(i.inline=Kt),n.has(qt)&&(i.inline=Ne),n.has(Wt)&&(i.inline=Jt),n.has($t)&&(i.inline=zt),n.has(Gt)&&(i.block=Kt),n.has(Ut)&&(i.block=Ne),n.has(Bt)&&(i.block=Jt),n.has(jt)&&(i.block=zt),!(e instanceof HTMLElement||e instanceof SVGElement))throw M("ScrollIntoViewInvalidElement",t);return e.tabIndex||e.setAttribute("tabindex","0"),e.scrollIntoView(i),n.has("focus")&&e.focus(),delete e.dataset[r],()=>{}}};var Xt="none",Qt="display",Zt={type:1,name:"show",keyReq:2,valReq:1,onLoad:({el:{style:t},genRX:e,effect:n})=>{let r=e();return n(async()=>{r()?t.display===Xt&&t.removeProperty(Qt):t.setProperty(Qt,Xt)})}};var en="view-transition",tn={type:1,name:"viewTransition",keyReq:2,valReq:1,onGlobalInit(){let t=!1;for(let e of document.head.childNodes)e instanceof HTMLMetaElement&&e.name===en&&(t=!0);if(!t){let e=document.createElement("meta");e.name=en,e.content="same-origin",document.head.appendChild(e)}},onLoad:({effect:t,el:e,genRX:n})=>{if(!z){console.error("Browser does not support view transitions");return}let r=n();return t(()=>{let i=r();if(!i?.length)return;let s=e.style;s.viewTransitionName=i})}};var nn={type:1,name:"attr",valReq:1,onLoad:({el:t,key:e,effect:n,genRX:r})=>{let i=r();return e===""?n(async()=>{let s=i();for(let[l,o]of Object.entries(s))o===!1?t.removeAttribute(l):t.setAttribute(l,o)}):(e=le(e),n(async()=>{let s=!1;try{s=i()}catch{}let l;typeof s=="string"?l=s:l=JSON.stringify(s),!l||l==="false"||l==="null"||l==="undefined"?t.removeAttribute(e):t.setAttribute(e,l)}))}};var Nn=/^data:(?[^;]+);base64,(?.*)$/,rn=["change","input","keydown"],sn={type:1,name:"bind",keyReq:3,valReq:3,onLoad:t=>{let{el:e,key:n,mods:r,signals:i,value:s,effect:l}=t,o=n?V(n,r):J(s),m=e.tagName.toLowerCase(),S="",T=m.includes("input"),N=e.getAttribute("type"),v=m.includes("checkbox")||T&&N==="checkbox";v&&(S=!1),T&&N==="number"&&(S=0);let y=m.includes("select"),E=m.includes("radio")||T&&N==="radio",A=T&&N==="file";E&&(e.getAttribute("name")?.length||e.setAttribute("name",o));let h=()=>{let g="value"in e,p=i.value(o),f=`${p}`;if(v||E){let b=e;Array.isArray(p)?b.checked=p.includes(b.value):typeof p=="boolean"?b.checked=!!p:b.checked=f===b.value}else if(y){let b=e;if(b.multiple)for(let _ of b.options){if(_?.disabled)return;Array.isArray(p)||typeof p=="string"?_.selected=p.includes(_.value):typeof p=="number"?_.selected=p===Number(_.value):_.selected=p}else b.value=f}else A||(g?e.value=f:e.setAttribute("value",f))},a=async()=>{if(A){let b=[...e?.files||[]],_=[],x=[],I=[];await Promise.all(b.map(F=>new Promise(L=>{let q=new FileReader;q.onload=()=>{if(typeof q.result!="string")throw M("InvalidFileResultType",t,{resultType:typeof q.result});let j=q.result.match(Nn);if(!j?.groups)throw M("InvalidDataUri",t,{result:q.result});_.push(j.groups.contents),x.push(j.groups.mime),I.push(F.name)},q.onloadend=()=>L(void 0),q.readAsDataURL(F)}))),i.setValue(o,_),i.setValue(`${o}Mimes`,x),i.setValue(`${o}Names`,I);return}let g=i.value(o),p=e||e,f=p.value||p.getAttribute("value")||"";if(v){let b=p.checked||p.getAttribute("checked")==="true";if(Array.isArray(g)){let _=new Set(g);b?_.add(p.value):_.delete(p.value),i.setValue(o,[..._])}else if(p.getAttribute("value")){let x=b?f:!1;i.setValue(o,x)}else i.setValue(o,b);return}if(typeof g=="number")i.setValue(o,Number(f));else if(typeof g=="string")i.setValue(o,f||"");else if(typeof g=="boolean")i.setValue(o,!!f);else if(Array.isArray(g))if(y){let x=[...e.selectedOptions].filter(I=>I.selected).map(I=>I.value);i.setValue(o,x)}else i.setValue(o,JSON.stringify(f.split(",")));else if(!(typeof g>"u"))throw M("BindUnsupportedSignalType",t,{signalType:typeof g})},{inserted:c}=i.upsertIfMissing(o,S);c&&a();for(let g of rn)e.addEventListener(g,a);let u=l(()=>h()),d=g=>{g.persisted&&a()};return window.addEventListener("pageshow",d),()=>{u();for(let g of rn)e.removeEventListener(g,a);window.removeEventListener("pageshow",d)}}};var on={type:1,name:"class",valReq:1,onLoad:({el:t,key:e,mods:n,effect:r,genRX:i})=>{let s=t.classList,l=i();return r(()=>{if(e===""){let o=l();for(let[m,S]of Object.entries(o)){let T=m.split(/\s+/);S?s.add(...T):s.remove(...T)}}else e=V(e,n),l()?s.add(e):s.remove(e)})}};function ge(t){if(!t||t.size<=0)return 0;for(let e of t){if(e.endsWith("ms"))return Number(e.replace("ms",""));if(e.endsWith("s"))return Number(e.replace("s",""))*1e3;try{return Number.parseFloat(e)}catch{}}return 0}function oe(t,e,n=!1){return t?t.has(e.toLowerCase()):n}function an(t,e,n=!1,r=!0){let i=-1,s=()=>i&&clearTimeout(i);return(...l)=>{s(),n&&!i&&t(...l),i=setTimeout(()=>{r&&t(...l),s()},e)}}function ln(t,e,n=!0,r=!1){let i=!1;return(...s)=>{i||(n&&t(...s),i=!0,setTimeout(()=>{i=!1,r&&t(...s)},e))}}var Pn="evt",We="signalsChange",Cn=We.length,un={type:1,name:"on",keyReq:1,valReq:1,argNames:[Pn],onLoad:({el:t,key:e,mods:n,rawKey:r,signals:i,value:s,effect:l,genRX:o})=>{let m=o(),S=t;n.has("window")&&(S=window);let T=h=>{h&&((n.has("prevent")||e==="submit")&&h.preventDefault(),n.has("stop")&&h.stopPropagation()),m(h)},N=n.get("delay");if(N){let h=ge(N);setTimeout(()=>{T()},h)}let v=n.get("debounce");if(v){let h=ge(v),a=oe(v,"leading",!1),c=!oe(v,"notrail",!1);T=an(T,h,a,c)}let R=n.get("throttle");if(R){let h=ge(R),a=!oe(R,"noleading",!1),c=oe(R,"trail",!1);T=ln(T,h,a,c)}if(n.has("viewtransition")&&z){let h=T;T=(...a)=>document.startViewTransition(()=>h(...a))}let y={capture:!0,passive:!1,once:!1};if(n.has("capture")||(y.capture=!1),n.has("passive")&&(y.passive=!0),n.has("once")&&(y.once=!0),e==="load")return setTimeout(()=>T(),0),()=>{};if(e==="interval"){let h=1e3,a=n.get("duration");a&&(h=ge(a),oe(a,"leading",!1)&&(t.dataset[r.replace(".leading","")]=s,delete t.dataset[r],T()));let c=setInterval(T,h);return()=>{clearInterval(c)}}if(e==="raf"){let h,a=()=>{T(),h=requestAnimationFrame(a)};return h=requestAnimationFrame(a),()=>{h&&cancelAnimationFrame(h)}}if(e.startsWith(We)){if(e===We){T();let c=u=>T(u);return document.addEventListener(ae,c),()=>{document.removeEventListener(ae,c)}}let h=V(Y(e.slice(Cn)),n),a=new Map;return i.walk((c,u)=>{c.startsWith(h)&&a.set(u,u.value)}),l(()=>{for(let[c,u]of a)u!==c.value&&(T(),a.set(c,c.value))})}if(n.has("outside")){S=document;let h=T;T=c=>{let u=c?.target;t.contains(u)||h(c)}}let A=V(e,n);return S.addEventListener(A,T,y),()=>{S.removeEventListener(A,T)}}};var cn={type:1,name:"ref",keyReq:3,valReq:3,onLoad:({el:t,key:e,mods:n,signals:r,value:i})=>{let s=e?V(e,n):J(i);r.setValue(s,t)}};var fn={type:1,name:"text",keyReq:2,valReq:1,onLoad:t=>{let{el:e,effect:n,genRX:r}=t,i=r();return e instanceof HTMLElement||M("TextInvalidElement",t),n(()=>{let s=i(t);e.textContent=`${s}`})}};var{round:In,max:Ln,min:Vn}=Math,dn={type:3,name:"fit",fn:(t,e,n,r,i,s,l=!1,o=!1)=>{let m=(e-n)/(r-n)*(s-i)+i;return o&&(m=In(m)),l&&(m=Ln(i,Vn(s,m))),m}};var pn={type:3,name:"setAll",fn:({signals:t},e,n)=>{t.walk((r,i)=>{r.startsWith(e)&&(i.value=n)})}};var mn={type:3,name:"toggleAll",fn:({signals:t},e)=>{t.walk((n,r)=>{n.startsWith(e)&&(r.value=!r.value)})}};de.aliasPrefix="ds";de.load(nn,sn,on,un,cn,Zt,fn,At,yt,St,Tt,bt,vt,Rt,wt,Mt,Nt,Et,Pt,Ct,Dt,Ot,Ht,Yt,tn,dn,pn,mn);de.apply();var Zs=de;export{Zs as Datastar}; +var Je=/🖕JS_DS🚀/.source,ve=Je.slice(0,5),Ie=Je.slice(4),D="datastar";var ze="Datastar-Request",ye=300,Ye=1e3,Xe="type module",Se=!1,Qe=!1,Ze=!0,W={Morph:"morph",Inner:"inner",Outer:"outer",Prepend:"prepend",Append:"append",Before:"before",After:"after",UpsertAttributes:"upsertAttributes"},et=W.Morph,k={MergeFragments:"datastar-merge-fragments",MergeSignals:"datastar-merge-signals",RemoveFragments:"datastar-remove-fragments",RemoveSignals:"datastar-remove-signals",ExecuteScript:"datastar-execute-script"};var w=(r=>(r[r.Attribute=1]="Attribute",r[r.Watcher=2]="Watcher",r[r.Action=3]="Action",r))(w||{});var le=`${D}-signals`;var K=t=>t.trim()==="true",ue=t=>t.replace(/[A-Z]+(?![a-z])|[A-Z]/g,(e,n)=>(n?"-":"")+e.toLowerCase()),Y=t=>ue(t).replace(/-./g,e=>e[1].toUpperCase()),Le=t=>ue(t).replace(/-/g,"_"),An=t=>Y(t).replace(/^./,e=>e[0].toUpperCase()),be=t=>new Function(`return Object.assign({}, ${t})`)(),J=t=>t.startsWith("$")?t.slice(1):t,En={kebab:ue,snake:Le,pascal:An};function V(t,e){for(let n of e.get("case")||[]){let r=En[n];r&&(t=r(t))}return t}var _n="computed",tt={type:1,name:_n,keyReq:1,valReq:1,onLoad:({key:t,mods:e,signals:n,genRX:r})=>{t=V(t,e);let i=r();n.setComputed(t,i)}};var nt={type:1,name:"signals",removeOnLoad:()=>!0,onLoad:t=>{let{key:e,mods:n,signals:r,value:i,genRX:s}=t,u=n.has("ifmissing");if(e!==""){let o=V(e,n),h=i===""?i:s()();u?r.upsertIfMissing(o,h):r.setValue(o,h)}else{let o=be(t.value);t.value=JSON.stringify(o);let b=s()();r.merge(b,u)}}};var rt={type:1,name:"star",keyReq:2,valReq:2,onLoad:()=>{alert("YOU ARE PROBABLY OVERCOMPLICATING IT")}};var Z=class{#e=0;#t;constructor(e=D){this.#t=e}with(e){if(typeof e=="string")for(let n of e.split(""))this.with(n.charCodeAt(0));else typeof e=="boolean"?this.with(1<<(e?7:3)):this.#e=this.#e*33^e;return this}get value(){return this.#e}get string(){return this.#t+Math.abs(this.#e).toString(36)}};function it(t){if(t.id)return t.id;let e=new Z,n=t;for(;n;){if(e.with(n.tagName||""),n.id){e.with(n.id);break}let r=n?.parentNode;r&&e.with([...r.children].indexOf(n)),n=r}return e.string}function ot(t,e){return new Z().with(t).with(e).value}function Ve(t,e){if(!t||!(t instanceof HTMLElement||t instanceof SVGElement))return null;let n=t.dataset;if("starIgnore"in n)return null;"starIgnore__self"in n||e(t);let r=t.firstElementChild;for(;r;)Ve(r,e),r=r.nextElementSibling}var xn="https://data-star.dev/errors";function De(t,e,n={}){let r=new Error;r.name=`${D} ${t} error`;let i=Le(e),s=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),u=JSON.stringify(n,null,2);return r.message=`${e} +More info: ${xn}/${t}/${i}?${s} +Context: ${u}`,r}function $(t,e,n={}){return De("internal",e,Object.assign({from:t},n))}function H(t,e,n={}){let r={plugin:{name:e.plugin.name,type:w[e.plugin.type]}};return De("init",t,Object.assign(r,n))}function M(t,e,n={}){let r={plugin:{name:e.plugin.name,type:w[e.plugin.type]},element:{id:e.el.id,tag:e.el.tagName},expression:{rawKey:e.rawKey,key:e.key,value:e.value,validSignals:e.signals.paths(),fnContent:e.fnContent}};return De("runtime",t,Object.assign(r,n))}var ee="preact-signals",Rn=Symbol.for("preact-signals"),G=1,te=2,fe=4,re=8,Te=16,ne=32;function Oe(){Ae++}function He(){if(Ae>1){Ae--;return}let t,e=!1;for(;ce!==void 0;){let n=ce;for(ce=void 0,ke++;n!==void 0;){let r=n._nextBatchedEffect;if(n._nextBatchedEffect=void 0,n._flags&=~te,!(n._flags&re)&&at(n))try{n._callback()}catch(i){e||(t=i,e=!0)}n=r}}if(ke=0,Ae--,e)throw t}var C;var ce,Ae=0,ke=0,Ee=0;function st(t){if(C===void 0)return;let e=t._node;if(e===void 0||e._target!==C)return e={_version:0,_source:t,_prevSource:C._sources,_nextSource:void 0,_target:C,_prevTarget:void 0,_nextTarget:void 0,_rollbackNode:e},C._sources!==void 0&&(C._sources._nextSource=e),C._sources=e,t._node=e,C._flags&ne&&t._subscribe(e),e;if(e._version===-1)return e._version=0,e._nextSource!==void 0&&(e._nextSource._prevSource=e._prevSource,e._prevSource!==void 0&&(e._prevSource._nextSource=e._nextSource),e._prevSource=C._sources,e._nextSource=void 0,C._sources._nextSource=e,C._sources=e),e}function P(t){this._value=t,this._version=0,this._node=void 0,this._targets=void 0}P.prototype.brand=Rn;P.prototype._refresh=()=>!0;P.prototype._subscribe=function(t){this._targets!==t&&t._prevTarget===void 0&&(t._nextTarget=this._targets,this._targets!==void 0&&(this._targets._prevTarget=t),this._targets=t)};P.prototype._unsubscribe=function(t){if(this._targets!==void 0){let e=t._prevTarget,n=t._nextTarget;e!==void 0&&(e._nextTarget=n,t._prevTarget=void 0),n!==void 0&&(n._prevTarget=e,t._nextTarget=void 0),t===this._targets&&(this._targets=n)}};P.prototype.subscribe=function(t){return _e(()=>{let e=this.value,n=C;C=void 0;try{t(e)}finally{C=n}})};P.prototype.valueOf=function(){return this.value};P.prototype.toString=function(){return`${this.value}`};P.prototype.toJSON=function(){return this.value};P.prototype.peek=function(){let t=C;C=void 0;try{return this.value}finally{C=t}};Object.defineProperty(P.prototype,"value",{get(){let t=st(this);return t!==void 0&&(t._version=this._version),this._value},set(t){if(t!==this._value){if(ke>100)throw $(ee,"SignalCycleDetected");let e=this._value,n=t;this._value=t,this._version++,Ee++,Oe();try{for(let r=this._targets;r!==void 0;r=r._nextTarget)r._target._notify()}finally{He()}this?._onChange({old:e,revised:n})}}});function at(t){for(let e=t._sources;e!==void 0;e=e._nextSource)if(e._source._version!==e._version||!e._source._refresh()||e._source._version!==e._version)return!0;return!1}function lt(t){for(let e=t._sources;e!==void 0;e=e._nextSource){let n=e._source._node;if(n!==void 0&&(e._rollbackNode=n),e._source._node=e,e._version=-1,e._nextSource===void 0){t._sources=e;break}}}function ut(t){let e=t._sources,n;for(;e!==void 0;){let r=e._prevSource;e._version===-1?(e._source._unsubscribe(e),r!==void 0&&(r._nextSource=e._nextSource),e._nextSource!==void 0&&(e._nextSource._prevSource=r)):n=e,e._source._node=e._rollbackNode,e._rollbackNode!==void 0&&(e._rollbackNode=void 0),e=r}t._sources=n}function X(t){P.call(this,void 0),this._fn=t,this._sources=void 0,this._globalVersion=Ee-1,this._flags=fe}X.prototype=new P;X.prototype._refresh=function(){if(this._flags&=~te,this._flags&G)return!1;if((this._flags&(fe|ne))===ne||(this._flags&=~fe,this._globalVersion===Ee))return!0;if(this._globalVersion=Ee,this._flags|=G,this._version>0&&!at(this))return this._flags&=~G,!0;let t=C;try{lt(this),C=this;let e=this._fn();(this._flags&Te||this._value!==e||this._version===0)&&(this._value=e,this._flags&=~Te,this._version++)}catch(e){this._value=e,this._flags|=Te,this._version++}return C=t,ut(this),this._flags&=~G,!0};X.prototype._subscribe=function(t){if(this._targets===void 0){this._flags|=fe|ne;for(let e=this._sources;e!==void 0;e=e._nextSource)e._source._subscribe(e)}P.prototype._subscribe.call(this,t)};X.prototype._unsubscribe=function(t){if(this._targets!==void 0&&(P.prototype._unsubscribe.call(this,t),this._targets===void 0)){this._flags&=~ne;for(let e=this._sources;e!==void 0;e=e._nextSource)e._source._unsubscribe(e)}};X.prototype._notify=function(){if(!(this._flags&te)){this._flags|=fe|te;for(let t=this._targets;t!==void 0;t=t._nextTarget)t._target._notify()}};Object.defineProperty(X.prototype,"value",{get(){if(this._flags&G)throw $(ee,"SignalCycleDetected");let t=st(this);if(this._refresh(),t!==void 0&&(t._version=this._version),this._flags&Te)throw $(ee,"GetComputedError",{value:this._value});return this._value}});function ct(t){return new X(t)}function ft(t){let e=t._cleanup;if(t._cleanup=void 0,typeof e=="function"){Oe();let n=C;C=void 0;try{e()}catch(r){throw t._flags&=~G,t._flags|=re,Fe(t),$(ee,"CleanupEffectError",{error:r})}finally{C=n,He()}}}function Fe(t){for(let e=t._sources;e!==void 0;e=e._nextSource)e._source._unsubscribe(e);t._fn=void 0,t._sources=void 0,ft(t)}function wn(t){if(C!==this)throw $(ee,"EndEffectError");ut(this),C=t,this._flags&=~G,this._flags&re&&Fe(this),He()}function de(t){this._fn=t,this._cleanup=void 0,this._sources=void 0,this._nextBatchedEffect=void 0,this._flags=ne}de.prototype._callback=function(){let t=this._start();try{if(this._flags&re||this._fn===void 0)return;let e=this._fn();typeof e=="function"&&(this._cleanup=e)}finally{t()}};de.prototype._start=function(){if(this._flags&G)throw $(ee,"SignalCycleDetected");this._flags|=G,this._flags&=~re,ft(this),lt(this),Oe();let t=C;return C=this,wn.bind(this,t)};de.prototype._notify=function(){this._flags&te||(this._flags|=te,this._nextBatchedEffect=ce,ce=this)};de.prototype._dispose=function(){this._flags|=re,this._flags&G||Fe(this)};function _e(t){let e=new de(t);try{e._callback()}catch(n){throw e._dispose(),n}return e._dispose.bind(e)}var dt="namespacedSignals",ie=t=>{document.dispatchEvent(new CustomEvent(le,{detail:Object.assign({added:[],removed:[],updated:[]},t)}))};function pt(t,e=!1){let n={};for(let r in t)if(Object.hasOwn(t,r)){if(e&&r.startsWith("_"))continue;let i=t[r];i instanceof P?n[r]=i.value:n[r]=pt(i)}return n}function mt(t,e,n=!1){let r={added:[],removed:[],updated:[]};for(let i in e)if(Object.hasOwn(e,i)){if(i.match(/\_\_+/))throw $(dt,"InvalidSignalKey",{key:i});let s=e[i];if(s instanceof Object&&!Array.isArray(s)){t[i]||(t[i]={});let u=mt(t[i],s,n);r.added.push(...u.added.map(o=>`${i}.${o}`)),r.removed.push(...u.removed.map(o=>`${i}.${o}`)),r.updated.push(...u.updated.map(o=>`${i}.${o}`))}else{if(Object.hasOwn(t,i)){if(n)continue;let h=t[i];if(h instanceof P){let b=h.value;h.value=s,b!==s&&r.updated.push(i);continue}}let o=new P(s);o._onChange=()=>{ie({updated:[i]})},t[i]=o,r.added.push(i)}}return r}function gt(t,e){for(let n in t)if(Object.hasOwn(t,n)){let r=t[n];r instanceof P?e(n,r):gt(r,(i,s)=>{e(`${n}.${i}`,s)})}}function Mn(t,...e){let n={};for(let r of e){let i=r.split("."),s=t,u=n;for(let h=0;hn());this.setSignal(e,r)}value(e){return this.signal(e)?.value}setValue(e,n){let{signal:r}=this.upsertIfMissing(e,n),i=r.value;r.value=n,i!==n&&ie({updated:[e]})}upsertIfMissing(e,n){let r=e.split("."),i=this.#e;for(let h=0;h{ie({updated:[e]})},i[s]=o,ie({added:[e]}),{signal:o,inserted:!0}}remove(...e){if(!e.length){this.#e={};return}let n=Array();for(let r of e){let i=r.split("."),s=this.#e;for(let o=0;oe.push(n)),e}values(e=!1){return pt(this.#e,e)}JSON(e=!0,n=!1){let r=this.values(n);return e?JSON.stringify(r,null,2):JSON.stringify(r)}toString(){return this.JSON()}};var ht=new xe,We=[],Re={},Nn=[],$e="";function Ge(t){$e=t}var qe=null,pe=new Map;function we(...t){for(let e of t){let n={signals:ht,effect:i=>_e(i),actions:Re,plugin:e,apply:oe},r;switch(e.type){case 2:{let i=e;Nn.push(i),r=i.onGlobalInit;break}case 3:{Re[e.name]=e;break}case 1:{let i=e;We.push(i),r=i.onGlobalInit;break}default:throw H("InvalidPluginType",n)}r&&r(n)}We.sort((e,n)=>{let r=n.name.length-e.name.length;return r!==0?r:e.name.localeCompare(n.name)})}function oe(t=document.documentElement){Ve(t,e=>{let n=new Array,r=pe.get(e)||new Map,i=new Map([...r]),s=new Map;for(let u of Object.keys(e.dataset)){if(!u.startsWith($e))break;let o=e.dataset[u]||"",h=ot(u,o);s.set(u,h),r.has(h)?i.delete(h):n.push(u)}for(let[u,o]of i)o();for(let u of n){let o=s.get(u);Pn(e,u,o)}}),Cn()}function Cn(){qe||(qe=new MutationObserver(t=>{let e=new Set,n=new Set;for(let{target:r,type:i,addedNodes:s,removedNodes:u}of t)switch(i){case"childList":{for(let o of u)e.add(o);for(let o of s)n.add(o)}break;case"attributes":{n.add(r);break}}for(let r of e){let i=pe.get(r);if(i){for(let[s,u]of i)u(),i.delete(s);i.size===0&&pe.delete(r)}}for(let r of n)oe(r)}),qe.observe(document.body,{attributes:!0,attributeOldValue:!0,childList:!0,subtree:!0}))}function Pn(t,e,n){let r=Y(e.slice($e.length)),i=We.find(y=>r.startsWith(y.name));if(!i)return;t.id.length||(t.id=it(t));let[s,...u]=r.slice(i.name.length).split(/\_\_+/),o=s.length>0;o&&(s=Y(s));let h=t.dataset[e]||"",b=h.length>0,v={signals:ht,apply:oe,effect:y=>_e(y),actions:Re,genRX:()=>In(v,...i.argNames||[]),plugin:i,el:t,rawKey:r,key:s,value:h,mods:new Map},N=i.keyReq||0;if(o){if(N===2)throw M(`${i.name}KeyNotAllowed`,v)}else if(N===1)throw M(`${i.name}KeyRequired`,v);let T=i.valReq||0;if(b){if(T===2)throw M(`${i.name}ValueNotAllowed`,v)}else if(T===1)throw M(`${i.name}ValueRequired`,v);if(N===3||T===3){if(o&&b)throw M(`${i.name}KeyAndValueProvided`,v);if(!o&&!b)throw M(`${i.name}KeyOrValueRequired`,v)}for(let y of u){let[x,..._]=y.split(".");v.mods.set(Y(x),new Set(_.map(g=>g.toLowerCase())))}let E=i.onLoad(v);if(E){let y=pe.get(t);y||(y=new Map,pe.set(t,y)),y.set(n,E)}}function In(t,...e){let n="",r=/(\/(\\\/|[^\/])*\/|"(\\"|[^\"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|[^;])+/gm,i=t.value.trim().match(r);if(i){let E=i.length-1,y=i[E].trim();y.startsWith("return")||(i[E]=`return (${y});`),n=i.join(`; +`)}let s=new Map,u=new RegExp(`(?:${ve})(.*?)(?:${Ie})`,"gm");for(let E of n.matchAll(u)){let y=E[1],x=new Z("dsEscaped").with(y).string;s.set(x,y),n=n.replace(ve+y+Ie,x)}let o=/@(\w*)\(/gm,h=n.matchAll(o),b=new Set;for(let E of h)b.add(E[1]);let v=new RegExp(`@(${Object.keys(Re).join("|")})\\(`,"gm");n=n.replaceAll(v,"ctx.actions.$1.fn(ctx,");let N=t.signals.paths();if(N.length){let E=new RegExp(`\\$(${N.join("|")})(\\W|$)`,"gm");n=n.replaceAll(E,"ctx.signals.signal('$1').value$2")}for(let[E,y]of s)n=n.replace(E,y);let T=`return (()=> { +${n} +})()`;t.fnContent=T;try{let E=new Function("ctx",...e,T);return(...y)=>{try{return E(t,...y)}catch(x){throw M("ExecuteExpression",t,{error:x.message})}}}catch(E){throw M("GenerateExpression",t,{error:E.message})}}we(rt,nt,tt);async function Ln(t,e){let n=t.getReader(),r;for(;!(r=await n.read()).done;)e(r.value)}function Vn(t){let e,n,r,i=!1;return function(u){e===void 0?(e=u,n=0,r=-1):e=kn(e,u);let o=e.length,h=0;for(;n0){let h=i.decode(u.subarray(0,o)),b=o+(u[o+1]===32?2:1),v=i.decode(u.subarray(b));switch(h){case"data":r.data=r.data?`${r.data} +${v}`:v;break;case"event":r.event=v;break;case"id":t(r.id=v);break;case"retry":{let N=Number.parseInt(v,10);Number.isNaN(N)||e(r.retry=N);break}}}}}function kn(t,e){let n=new Uint8Array(t.length+e.length);return n.set(t),n.set(e,t.length),n}function vt(){return{data:"",event:"",id:"",retry:void 0}}var On="text/event-stream",yt="last-event-id";function St(t,e,{signal:n,headers:r,onopen:i,onmessage:s,onclose:u,onerror:o,openWhenHidden:h,fetch:b,retryInterval:v=1e3,retryScaler:N=2,retryMaxWaitMs:T=3e4,retryMaxCount:E=10,...y}){return new Promise((x,_)=>{let g=0,a={...r};a.accept||(a.accept=On);let c;function l(){c.abort(),document.hidden||S()}h||document.addEventListener("visibilitychange",l);let d=0;function m(){document.removeEventListener("visibilitychange",l),window.clearTimeout(d),c.abort()}n?.addEventListener("abort",()=>{m(),x()});let p=b??window.fetch,f=i??function(){};async function S(){c=new AbortController;try{let A=await p(e,{...y,headers:a,signal:c.signal});await f(A),await Ln(A.body,Vn(Dn(R=>{R?a[yt]=R:delete a[yt]},R=>{v=R},s))),u?.(),m(),x()}catch(A){if(!c.signal.aborted)try{let R=o?.(A)??v;window.clearTimeout(d),d=window.setTimeout(S,R),v*=N,v=Math.min(v,T),g++,g>=E?(m(),_(M("SseMaxRetries",t,{retryMaxCount:E}))):console.error(`Datastar failed to reach ${y.method}: ${e.toString()} retry in ${R}ms`)}catch(R){m(),_(R)}}}S()})}var se=`${D}-sse`,Ue=`${D}-settling`,Q=`${D}-swapping`,Me="started",Ne="finished",bt="error",Tt="retrying";function U(t,e){document.addEventListener(se,n=>{if(n.detail.type!==t)return;let{argsRaw:r}=n.detail;e(r)})}function me(t,e){document.dispatchEvent(new CustomEvent(se,{detail:{type:t,argsRaw:e}}))}var At=t=>`${t}`.includes("text/event-stream"),B=async(t,e,n,r)=>{let{el:{id:i},el:s,signals:u}=t,{headers:o,contentType:h,includeLocal:b,selector:v,openWhenHidden:N,retryInterval:T,retryScaler:E,retryMaxWaitMs:y,retryMaxCount:x,abort:_}=Object.assign({headers:{},contentType:"json",includeLocal:!1,selector:null,openWhenHidden:!1,retryInterval:Ye,retryScaler:2,retryMaxWaitMs:3e4,retryMaxCount:10,abort:void 0},r),g=e.toLowerCase(),a=()=>{};try{if(me(Me,{elId:i}),!n?.length)throw M("SseNoUrlProvided",t,{action:g});let c={};c[ze]=!0,h==="json"&&(c["Content-Type"]="application/json");let l=Object.assign({},c,o),d={method:e,headers:l,openWhenHidden:N,retryInterval:T,retryScaler:E,retryMaxWaitMs:y,retryMaxCount:x,signal:_,onopen:async f=>{if(f.status>=400){let S=f.status.toString();me(bt,{status:S})}},onmessage:f=>{if(!f.event.startsWith(D))return;let S=f.event,A={},R=f.data.split(` +`);for(let F of R){let L=F.indexOf(" "),q=F.slice(0,L),j=A[q];j||(j=[],A[q]=j);let Tn=F.slice(L+1);j.push(Tn)}let I={};for(let[F,L]of Object.entries(A))I[F]=L.join(` +`);me(S,I)},onerror:f=>{if(At(f))throw M("InvalidContentType",t,{url:n});f&&(console.error(f.message),me(Tt,{message:f.message}))}},m=new URL(n,window.location.origin),p=new URLSearchParams(m.search);if(h==="json"){let f=u.JSON(!1,!b);e==="GET"?p.set(D,f):d.body=f}else if(h==="form"){let f=v?document.querySelector(v):s.closest("form");if(f===null)throw v?M("SseFormNotFound",t,{action:g,selector:v}):M("SseClosestFormNotFound",t,{action:g});if(s!==f){let A=R=>R.preventDefault();f.addEventListener("submit",A),a=()=>f.removeEventListener("submit",A)}if(!f.checkValidity()){f.reportValidity(),a();return}let S=new FormData(f);if(e==="GET"){let A=new URLSearchParams(S);for(let[R,I]of A)p.set(R,I)}else d.body=S}else throw M("SseInvalidContentType",t,{action:g,contentType:h});m.search=p.toString();try{await St(t,m.toString(),d)}catch(f){if(!At(f))throw M("SseFetchFailed",t,{method:e,url:n,error:f})}}finally{me(Ne,{elId:i}),a()}};var Et={type:3,name:"delete",fn:async(t,e,n)=>B(t,"DELETE",e,{...n})};var _t={type:3,name:"get",fn:async(t,e,n)=>B(t,"GET",e,{...n})};var xt={type:3,name:"patch",fn:async(t,e,n)=>B(t,"PATCH",e,{...n})};var Rt={type:3,name:"post",fn:async(t,e,n)=>B(t,"POST",e,{...n})};var wt={type:3,name:"put",fn:async(t,e,n)=>B(t,"PUT",e,{...n})};var Mt={type:1,name:"indicator",keyReq:3,valReq:3,onLoad:({el:t,key:e,mods:n,signals:r,value:i})=>{let s=e?V(e,n):J(i),{signal:u}=r.upsertIfMissing(s,!1),o=h=>{let{type:b,argsRaw:{elId:v}}=h.detail;if(v===t.id)switch(b){case Me:u.value=!0;break;case Ne:u.value=!1;break}};return document.addEventListener(se,o),()=>{document.removeEventListener(se,o)}}};var Nt={type:2,name:k.ExecuteScript,onGlobalInit:async t=>{U(k.ExecuteScript,({autoRemove:e=`${Ze}`,attributes:n=Xe,script:r})=>{let i=K(e);if(!r?.length)throw H("NoScriptProvided",t);let s=document.createElement("script");for(let u of n.split(` +`)){let o=u.indexOf(" "),h=o?u.slice(0,o):u,b=o?u.slice(o):"";s.setAttribute(h.trim(),b.trim())}s.text=r,document.head.appendChild(s),i&&s.remove()})}};var ge=document,z=!!ge.startViewTransition;var Ct=function(){"use strict";let t=()=>{},e={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:t,afterNodeAdded:t,beforeNodeMorphed:t,afterNodeMorphed:t,beforeNodeRemoved:t,afterNodeRemoved:t,beforeAttributeUpdated:t},head:{style:"merge",shouldPreserve:T=>T.getAttribute("im-preserve")==="true",shouldReAppend:T=>T.getAttribute("im-re-append")==="true",shouldRemove:t,afterHeadMorphed:t},restoreFocus:!0};function n(T,E,y={}){T=v(T);let x=N(E),_=b(T,x,y),g=i(_,()=>o(_,T,x,a=>a.morphStyle==="innerHTML"?(s(a,T,x),Array.from(T.childNodes)):r(a,T,x)));return _.pantry.remove(),g}function r(T,E,y){let x=N(E),_=Array.from(x.childNodes),g=_.indexOf(E),a=_.length-(g+1);return s(T,x,y,E,E.nextSibling),_=Array.from(x.childNodes),_.slice(g,_.length-a)}function i(T,E){if(!T.config.restoreFocus)return E();let y=document.activeElement;if(!(y instanceof HTMLInputElement||y instanceof HTMLTextAreaElement))return E();let{id:x,selectionStart:_,selectionEnd:g}=y,a=E();return x&&x!==document.activeElement?.id&&(y=T.target.querySelector(`#${x}`),y?.focus()),y&&!y.selectionEnd&&g&&y.setSelectionRange(_,g),a}let s=function(){function T(l,d,m,p=null,f=null){d instanceof HTMLTemplateElement&&m instanceof HTMLTemplateElement&&(d=d.content,m=m.content),p||=d.firstChild;for(let S of m.childNodes){if(p&&p!=f){let R=y(l,S,p,f);if(R){R!==p&&_(l,p,R),u(R,S,l),p=R.nextSibling;continue}}if(S instanceof Element&&l.persistentIds.has(S.id)){let R=g(d,S.id,p,l);u(R,S,l),p=R.nextSibling;continue}let A=E(d,S,p,l);A&&(p=A.nextSibling)}for(;p&&p!=f;){let S=p;p=p.nextSibling,x(l,S)}}function E(l,d,m,p){if(p.callbacks.beforeNodeAdded(d)===!1)return null;if(p.idMap.has(d)){let f=document.createElement(d.tagName);return l.insertBefore(f,m),u(f,d,p),p.callbacks.afterNodeAdded(f),f}else{let f=document.importNode(d,!0);return l.insertBefore(f,m),p.callbacks.afterNodeAdded(f),f}}let y=function(){function l(p,f,S,A){let R=null,I=f.nextSibling,F=0,L=S;for(;L&&L!=A;){if(m(L,f)){if(d(p,L,f))return L;R===null&&(p.idMap.has(L)||(R=L))}if(R===null&&I&&m(L,I)&&(F++,I=I.nextSibling,F>=2&&(R=void 0)),L.contains(document.activeElement))break;L=L.nextSibling}return R||null}function d(p,f,S){let A=p.idMap.get(f),R=p.idMap.get(S);if(!R||!A)return!1;for(let I of A)if(R.has(I))return!0;return!1}function m(p,f){let S=p,A=f;return S.nodeType===A.nodeType&&S.tagName===A.tagName&&(!S.id||S.id===A.id)}return l}();function x(l,d){if(l.idMap.has(d))c(l.pantry,d,null);else{if(l.callbacks.beforeNodeRemoved(d)===!1)return;d.parentNode?.removeChild(d),l.callbacks.afterNodeRemoved(d)}}function _(l,d,m){let p=d;for(;p&&p!==m;){let f=p;p=p.nextSibling,x(l,f)}return p}function g(l,d,m,p){let f=p.target.querySelector(`#${d}`)||p.pantry.querySelector(`#${d}`);return a(f,p),c(l,f,m),f}function a(l,d){let m=l.id;for(;l=l.parentNode;){let p=d.idMap.get(l);p&&(p.delete(m),p.size||d.idMap.delete(l))}}function c(l,d,m){if(l.moveBefore)try{l.moveBefore(d,m)}catch{l.insertBefore(d,m)}else l.insertBefore(d,m)}return T}(),u=function(){function T(a,c,l){return l.ignoreActive&&a===document.activeElement?null:(l.callbacks.beforeNodeMorphed(a,c)===!1||(a instanceof HTMLHeadElement&&l.head.ignore||(a instanceof HTMLHeadElement&&l.head.style!=="morph"?h(a,c,l):(E(a,c,l),g(a,l)||s(l,a,c))),l.callbacks.afterNodeMorphed(a,c)),a)}function E(a,c,l){let d=c.nodeType;if(d===1){let m=a,p=c,f=m.attributes,S=p.attributes;for(let A of S)_(A.name,m,"update",l)||m.getAttribute(A.name)!==A.value&&m.setAttribute(A.name,A.value);for(let A=f.length-1;0<=A;A--){let R=f[A];if(R&&!p.hasAttribute(R.name)){if(_(R.name,m,"remove",l))continue;m.removeAttribute(R.name)}}g(m,l)||y(m,p,l)}(d===8||d===3)&&a.nodeValue!==c.nodeValue&&(a.nodeValue=c.nodeValue)}function y(a,c,l){if(a instanceof HTMLInputElement&&c instanceof HTMLInputElement&&c.type!=="file"){let d=c.value,m=a.value;x(a,c,"checked",l),x(a,c,"disabled",l),c.hasAttribute("value")?m!==d&&(_("value",a,"update",l)||(a.setAttribute("value",d),a.value=d)):_("value",a,"remove",l)||(a.value="",a.removeAttribute("value"))}else if(a instanceof HTMLOptionElement&&c instanceof HTMLOptionElement)x(a,c,"selected",l);else if(a instanceof HTMLTextAreaElement&&c instanceof HTMLTextAreaElement){let d=c.value,m=a.value;if(_("value",a,"update",l))return;d!==m&&(a.value=d),a.firstChild&&a.firstChild.nodeValue!==d&&(a.firstChild.nodeValue=d)}}function x(a,c,l,d){let m=c[l],p=a[l];if(m!==p){let f=_(l,a,"update",d);f||(a[l]=c[l]),m?f||a.setAttribute(l,""):_(l,a,"remove",d)||a.removeAttribute(l)}}function _(a,c,l,d){return a==="value"&&d.ignoreActiveValue&&c===document.activeElement?!0:d.callbacks.beforeAttributeUpdated(a,c,l)===!1}function g(a,c){return!!c.ignoreActiveValue&&a===document.activeElement&&a!==document.body}return T}();function o(T,E,y,x){if(T.head.block){let _=E.querySelector("head"),g=y.querySelector("head");if(_&&g){let a=h(_,g,T);return Promise.all(a).then(()=>{let c=Object.assign(T,{head:{block:!1,ignore:!0}});return x(c)})}}return x(T)}function h(T,E,y){let x=[],_=[],g=[],a=[],c=new Map;for(let d of E.children)c.set(d.outerHTML,d);for(let d of T.children){let m=c.has(d.outerHTML),p=y.head.shouldReAppend(d),f=y.head.shouldPreserve(d);m||f?p?_.push(d):(c.delete(d.outerHTML),g.push(d)):y.head.style==="append"?p&&(_.push(d),a.push(d)):y.head.shouldRemove(d)!==!1&&_.push(d)}a.push(...c.values());let l=[];for(let d of a){let m=document.createRange().createContextualFragment(d.outerHTML).firstChild;if(y.callbacks.beforeNodeAdded(m)!==!1){if("href"in m&&m.href||"src"in m&&m.src){let p,f=new Promise(function(S){p=S});m.addEventListener("load",function(){p()}),l.push(f)}T.appendChild(m),y.callbacks.afterNodeAdded(m),x.push(m)}}for(let d of _)y.callbacks.beforeNodeRemoved(d)!==!1&&(T.removeChild(d),y.callbacks.afterNodeRemoved(d));return y.head.afterHeadMorphed(T,{added:x,kept:g,removed:_}),l}let b=function(){function T(c,l,d){let{persistentIds:m,idMap:p}=g(c,l),f=E(d),S=f.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(S))throw`Do not understand how to morph style ${S}`;return{target:c,newContent:l,config:f,morphStyle:S,ignoreActive:f.ignoreActive,ignoreActiveValue:f.ignoreActiveValue,restoreFocus:f.restoreFocus,idMap:p,persistentIds:m,pantry:y(),callbacks:f.callbacks,head:f.head}}function E(c){let l=Object.assign({},e);return Object.assign(l,c),l.callbacks=Object.assign({},e.callbacks,c.callbacks),l.head=Object.assign({},e.head,c.head),l}function y(){let c=document.createElement("div");return c.hidden=!0,document.body.insertAdjacentElement("afterend",c),c}function x(c){let l=Array.from(c.querySelectorAll("[id]"));return c.id&&l.push(c),l}function _(c,l,d,m){for(let p of m)if(l.has(p.id)){let f=p;for(;f;){let S=c.get(f);if(S==null&&(S=new Set,c.set(f,S)),S.add(p.id),f===d)break;f=f.parentElement}}}function g(c,l){let d=x(c),m=x(l),p=a(d,m),f=new Map;_(f,p,c,d);let S=l.__idiomorphRoot||l;return _(f,p,S,m),{persistentIds:p,idMap:f}}function a(c,l){let d=new Set,m=new Map;for(let{id:f,tagName:S}of c)m.has(f)?d.add(f):m.set(f,S);let p=new Set;for(let{id:f,tagName:S}of l)p.has(f)?d.add(f):m.get(f)===S&&p.add(f);for(let f of d)p.delete(f);return p}return T}(),{normalizeElement:v,normalizeParent:N}=function(){let T=new WeakSet;function E(g){return g instanceof Document?g.documentElement:g}function y(g){if(g==null)return document.createElement("div");if(typeof g=="string")return y(_(g));if(T.has(g))return g;if(g instanceof Node){if(g.parentNode)return x(g);{let a=document.createElement("div");return a.append(g),a}}else{let a=document.createElement("div");for(let c of[...g])a.append(c);return a}}function x(g){return{childNodes:[g],querySelectorAll:a=>{let c=g.querySelectorAll(a);return g.matches(a)?[g,...c]:c},insertBefore:(a,c)=>g.parentNode.insertBefore(a,c),moveBefore:(a,c)=>g.parentNode.moveBefore(a,c),get __idiomorphRoot(){return g}}}function _(g){let a=new DOMParser,c=g.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");if(c.match(/<\/html>/)||c.match(/<\/head>/)||c.match(/<\/body>/)){let l=a.parseFromString(g,"text/html");if(c.match(/<\/html>/))return T.add(l),l;{let d=l.firstChild;return d&&T.add(d),d}}else{let d=a.parseFromString("","text/html").body.querySelector("template").content;return T.add(d),d}}return{normalizeElement:E,normalizeParent:y}}();return{morph:n,defaults:e}}();var It={type:2,name:k.MergeFragments,onGlobalInit:async t=>{let e=document.createElement("template");U(k.MergeFragments,({fragments:n="
",selector:r="",mergeMode:i=et,settleDuration:s=`${ye}`,useViewTransition:u=`${Se}`})=>{let o=Number.parseInt(s),h=K(u);e.innerHTML=n.trim();let b=[...e.content.children];for(let v of b){if(!(v instanceof Element))throw H("NoFragmentsFound",t);let N=r||`#${v.getAttribute("id")}`,T=[...document.querySelectorAll(N)||[]];if(!T.length)throw H("NoTargetsFound",t,{selectorOrID:N});h&&z?ge.startViewTransition(()=>Pt(t,i,o,v,T)):Pt(t,i,o,v,T)}})}};function Pt(t,e,n,r,i){for(let s of i){s.classList.add(Q);let u=s.outerHTML,o=s;switch(e){case W.Morph:{Ct.morph(o,r.cloneNode(!0));break}case W.Inner:o.innerHTML=r.outerHTML;break;case W.Outer:o.replaceWith(r);break;case W.Prepend:o.prepend(r);break;case W.Append:o.append(r);break;case W.Before:o.before(r);break;case W.After:o.after(r);break;case W.UpsertAttributes:for(let v of r.getAttributeNames()){let N=r.getAttribute(v);o.setAttribute(v,N)}break;default:throw H("InvalidMergeMode",t,{mergeMode:e})}let h=o.classList;h?.add(Q),setTimeout(()=>{s.classList.remove(Q),h?.remove(Q)},n);let b=o.outerHTML;h&&u!==b&&(h.add(Ue),setTimeout(()=>{h.remove(Ue)},n))}}var Lt={type:2,name:k.MergeSignals,onGlobalInit:async t=>{U(k.MergeSignals,({signals:e="{}",onlyIfMissing:n=`${Qe}`})=>{let{signals:r}=t,i=K(n);r.merge(be(e),i)})}};var Vt={type:2,name:k.RemoveFragments,onGlobalInit:async t=>{U(k.RemoveFragments,({selector:e,settleDuration:n=`${ye}`,useViewTransition:r=`${Se}`})=>{if(!e.length)throw H("NoSelectorProvided",t);let i=Number.parseInt(n),s=K(r),u=document.querySelectorAll(e),o=()=>{for(let h of u)h.classList.add(Q);setTimeout(()=>{for(let h of u)h.remove()},i)};s&&z?ge.startViewTransition(()=>o()):o()})}};var Dt={type:2,name:k.RemoveSignals,onGlobalInit:async t=>{U(k.RemoveSignals,({paths:e=""})=>{let n=e.split(` +`).map(r=>r.trim());if(!n?.length)throw H("NoPathsProvided",t);t.signals.remove(...n)})}};var kt={type:3,name:"clipboard",fn:(t,e)=>{if(!navigator.clipboard)throw M("ClipboardNotAvailable",t);navigator.clipboard.writeText(e)}};var Ot={type:1,name:"customValidity",keyReq:2,valReq:1,onLoad:t=>{let{el:e,genRX:n,effect:r}=t;if(!(e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement))throw M("CustomValidityInvalidElement",t);let i=n();return r(()=>{let s=i();if(typeof s!="string")throw M("CustomValidityInvalidExpression",t,{result:s});e.setCustomValidity(s)})}};var Ht="once",Ft="half",qt="full",Wt={type:1,name:"intersects",keyReq:2,mods:new Set([Ht,Ft,qt]),onLoad:({el:t,rawKey:e,mods:n,genRX:r})=>{let i={threshold:0};n.has(qt)?i.threshold=1:n.has(Ft)&&(i.threshold=.5);let s=r(),u=new IntersectionObserver(o=>{for(let h of o)h.isIntersecting&&(s(),n.has(Ht)&&(u.disconnect(),delete t.dataset[e]))},i);return u.observe(t),()=>u.disconnect()}};var $t="session",Gt={type:1,name:"persist",mods:new Set([$t]),onLoad:({key:t,effect:e,mods:n,signals:r,value:i})=>{t=V(t,n),t===""&&(t=D);let s=n.has($t)?sessionStorage:localStorage,u=i.split(/\s+/).filter(b=>b!=="");u=u.map(b=>J(b));let o=()=>{let b=s.getItem(t)||"{}",v=JSON.parse(b);r.merge(v)},h=()=>{let b;u.length?b=r.subset(...u):b=r.values(),s.setItem(t,JSON.stringify(b))};return o(),e(()=>{h()})}};var Ut={type:1,name:"replaceUrl",keyReq:2,valReq:1,onLoad:({effect:t,genRX:e})=>{let n=e();return t(()=>{let r=n(),i=window.location.href,s=new URL(r,i).toString();window.history.replaceState({},"",s)})}};var Ce="smooth",Be="instant",je="auto",Bt="hstart",jt="hcenter",Kt="hend",Jt="hnearest",zt="vstart",Yt="vcenter",Xt="vend",Qt="vnearest",Hn="focus",Pe="center",Zt="start",en="end",tn="nearest",nn={type:1,name:"scrollIntoView",keyReq:2,valReq:2,mods:new Set([Ce,Be,je,Bt,jt,Kt,Jt,zt,Yt,Xt,Qt,Hn]),onLoad:t=>{let{el:e,mods:n,rawKey:r}=t;e.tabIndex||e.setAttribute("tabindex","0");let i={behavior:Ce,block:Pe,inline:Pe};if(n.has(Ce)&&(i.behavior=Ce),n.has(Be)&&(i.behavior=Be),n.has(je)&&(i.behavior=je),n.has(Bt)&&(i.inline=Zt),n.has(jt)&&(i.inline=Pe),n.has(Kt)&&(i.inline=en),n.has(Jt)&&(i.inline=tn),n.has(zt)&&(i.block=Zt),n.has(Yt)&&(i.block=Pe),n.has(Xt)&&(i.block=en),n.has(Qt)&&(i.block=tn),!(e instanceof HTMLElement||e instanceof SVGElement))throw M("ScrollIntoViewInvalidElement",t);return e.tabIndex||e.setAttribute("tabindex","0"),e.scrollIntoView(i),n.has("focus")&&e.focus(),delete e.dataset[r],()=>{}}};var rn="none",on="display",sn={type:1,name:"show",keyReq:2,valReq:1,onLoad:({el:{style:t},genRX:e,effect:n})=>{let r=e();return n(async()=>{r()?t.display===rn&&t.removeProperty(on):t.setProperty(on,rn)})}};var an="view-transition",ln={type:1,name:"viewTransition",keyReq:2,valReq:1,onGlobalInit(){let t=!1;for(let e of document.head.childNodes)e instanceof HTMLMetaElement&&e.name===an&&(t=!0);if(!t){let e=document.createElement("meta");e.name=an,e.content="same-origin",document.head.appendChild(e)}},onLoad:({effect:t,el:e,genRX:n})=>{if(!z){console.error("Browser does not support view transitions");return}let r=n();return t(()=>{let i=r();if(!i?.length)return;let s=e.style;s.viewTransitionName=i})}};var un={type:1,name:"attr",valReq:1,onLoad:({el:t,key:e,effect:n,genRX:r})=>{let i=r();return e===""?n(async()=>{let s=i();for(let[u,o]of Object.entries(s))o===!1?t.removeAttribute(u):t.setAttribute(u,o)}):(e=ue(e),n(async()=>{let s=!1;try{s=i()}catch{}let u;typeof s=="string"?u=s:u=JSON.stringify(s),!u||u==="false"||u==="null"||u==="undefined"?t.removeAttribute(e):t.setAttribute(e,u)}))}};var Fn=/^data:(?[^;]+);base64,(?.*)$/,cn=["change","input","keydown"],fn={type:1,name:"bind",keyReq:3,valReq:3,onLoad:t=>{let{el:e,key:n,mods:r,signals:i,value:s,effect:u}=t,o=n?V(n,r):J(s),h=e.tagName.toLowerCase(),b="",v=h.includes("input"),N=e.getAttribute("type"),T=h.includes("checkbox")||v&&N==="checkbox";T&&(b=!1),v&&N==="number"&&(b=0);let y=h.includes("select"),x=h.includes("radio")||v&&N==="radio",_=v&&N==="file";x&&(e.getAttribute("name")?.length||e.setAttribute("name",o));let g=()=>{let m="value"in e,p=i.value(o),f=`${p}`;if(T||x){let S=e;Array.isArray(p)?S.checked=p.includes(S.value):typeof p=="boolean"?S.checked=!!p:S.checked=f===S.value}else if(y){let S=e;if(S.multiple)for(let A of S.options){if(A?.disabled)return;Array.isArray(p)||typeof p=="string"?A.selected=p.includes(A.value):typeof p=="number"?A.selected=p===Number(A.value):A.selected=p}else S.value=f}else _||(m?e.value=f:e.setAttribute("value",f))},a=async()=>{if(_){let S=[...e?.files||[]],A=[],R=[],I=[];await Promise.all(S.map(F=>new Promise(L=>{let q=new FileReader;q.onload=()=>{if(typeof q.result!="string")throw M("InvalidFileResultType",t,{resultType:typeof q.result});let j=q.result.match(Fn);if(!j?.groups)throw M("InvalidDataUri",t,{result:q.result});A.push(j.groups.contents),R.push(j.groups.mime),I.push(F.name)},q.onloadend=()=>L(void 0),q.readAsDataURL(F)}))),i.setValue(o,A),i.setValue(`${o}Mimes`,R),i.setValue(`${o}Names`,I);return}let m=i.value(o),p=e||e,f=p.value||p.getAttribute("value")||"";if(T){let S=p.checked||p.getAttribute("checked")==="true";if(Array.isArray(m)){let A=new Set(m);S?A.add(p.value):A.delete(p.value),i.setValue(o,[...A])}else if(p.getAttribute("value")){let R=S?f:!1;i.setValue(o,R)}else i.setValue(o,S);return}if(typeof m=="number")i.setValue(o,Number(f));else if(typeof m=="string")i.setValue(o,f||"");else if(typeof m=="boolean")i.setValue(o,!!f);else if(Array.isArray(m))if(y){let R=[...e.selectedOptions].filter(I=>I.selected).map(I=>I.value);i.setValue(o,R)}else i.setValue(o,JSON.stringify(f.split(",")));else if(!(typeof m>"u"))throw M("BindUnsupportedSignalType",t,{signalType:typeof m})},{inserted:c}=i.upsertIfMissing(o,b);c&&a();for(let m of cn)e.addEventListener(m,a);let l=u(()=>g()),d=m=>{m.persisted&&a()};return window.addEventListener("pageshow",d),()=>{l();for(let m of cn)e.removeEventListener(m,a);window.removeEventListener("pageshow",d)}}};var dn={type:1,name:"class",valReq:1,onLoad:({el:t,key:e,mods:n,effect:r,genRX:i})=>{let s=t.classList,u=i();return r(()=>{if(e===""){let o=u();for(let[h,b]of Object.entries(o)){let v=h.split(/\s+/);b?s.add(...v):s.remove(...v)}}else e=V(e,n),u()?s.add(e):s.remove(e)})}};function he(t){if(!t||t.size<=0)return 0;for(let e of t){if(e.endsWith("ms"))return Number(e.replace("ms",""));if(e.endsWith("s"))return Number(e.replace("s",""))*1e3;try{return Number.parseFloat(e)}catch{}}return 0}function ae(t,e,n=!1){return t?t.has(e.toLowerCase()):n}function pn(t,e,n=!1,r=!0){let i=-1,s=()=>i&&clearTimeout(i);return(...u)=>{s(),n&&!i&&t(...u),i=setTimeout(()=>{r&&t(...u),s()},e)}}function mn(t,e,n=!0,r=!1){let i=!1;return(...s)=>{i||(n&&t(...s),i=!0,setTimeout(()=>{i=!1,r&&t(...s)},e))}}var qn="evt",Ke="signalsChange",Wn=Ke.length,gn={type:1,name:"on",keyReq:1,valReq:1,argNames:[qn],onLoad:({el:t,key:e,mods:n,rawKey:r,signals:i,value:s,effect:u,genRX:o})=>{let h=o(),b=t;n.has("window")&&(b=window);let v=g=>{g&&((n.has("prevent")||e==="submit")&&g.preventDefault(),n.has("stop")&&g.stopPropagation()),h(g)},N=n.get("delay");if(N){let g=he(N);setTimeout(()=>{v()},g)}let T=n.get("debounce");if(T){let g=he(T),a=ae(T,"leading",!1),c=!ae(T,"notrail",!1);v=pn(v,g,a,c)}let E=n.get("throttle");if(E){let g=he(E),a=!ae(E,"noleading",!1),c=ae(E,"trail",!1);v=mn(v,g,a,c)}if(n.has("viewtransition")&&z){let g=v;v=(...a)=>document.startViewTransition(()=>g(...a))}let y={capture:!0,passive:!1,once:!1};if(n.has("capture")||(y.capture=!1),n.has("passive")&&(y.passive=!0),n.has("once")&&(y.once=!0),e==="load")return setTimeout(()=>v(),0),()=>{};if(e==="interval"){let g=1e3,a=n.get("duration");a&&(g=he(a),ae(a,"leading",!1)&&(t.dataset[r.replace(".leading","")]=s,delete t.dataset[r],v()));let c=setInterval(v,g);return()=>{clearInterval(c)}}if(e==="raf"){let g,a=()=>{v(),g=requestAnimationFrame(a)};return g=requestAnimationFrame(a),()=>{g&&cancelAnimationFrame(g)}}if(e.startsWith(Ke)){if(e===Ke){v();let c=l=>v(l);return document.addEventListener(le,c),()=>{document.removeEventListener(le,c)}}let g=V(Y(e.slice(Wn)),n),a=new Map;return i.walk((c,l)=>{c.startsWith(g)&&a.set(l,l.value)}),u(()=>{for(let[c,l]of a)l!==c.value&&(v(),a.set(c,c.value))})}if(n.has("outside")){b=document;let g=v;v=c=>{let l=c?.target;t.contains(l)||g(c)}}let _=V(e,n);return b.addEventListener(_,v,y),()=>{b.removeEventListener(_,v)}}};var hn={type:1,name:"ref",keyReq:3,valReq:3,onLoad:({el:t,key:e,mods:n,signals:r,value:i})=>{let s=e?V(e,n):J(i);r.setValue(s,t)}};var vn={type:1,name:"text",keyReq:2,valReq:1,onLoad:t=>{let{el:e,effect:n,genRX:r}=t,i=r();return e instanceof HTMLElement||M("TextInvalidElement",t),n(()=>{let s=i(t);e.textContent=`${s}`})}};var{round:$n,max:Gn,min:Un}=Math,yn={type:3,name:"fit",fn:(t,e,n,r,i,s,u=!1,o=!1)=>{let h=(e-n)/(r-n)*(s-i)+i;return o&&(h=$n(h)),u&&(h=Gn(i,Un(s,h))),h}};var Sn={type:3,name:"setAll",fn:({signals:t},e,n)=>{t.walk((r,i)=>{r.startsWith(e)&&(i.value=n)})}};var bn={type:3,name:"toggleAll",fn:({signals:t},e)=>{t.walk((n,r)=>{n.startsWith(e)&&(r.value=!r.value)})}};Ge("ds");we(un,fn,dn,gn,hn,sn,vn,Mt,_t,Rt,wt,xt,Et,It,Lt,Vt,Dt,Nt,kt,Ot,Wt,Gt,Ut,nn,ln,yn,Sn,bn);oe();export{oe as apply,we as load,Ge as setAlias}; //# sourceMappingURL=datastar-aliased.js.map diff --git a/bundles/datastar-aliased.js.map b/bundles/datastar-aliased.js.map index 483ac3baf..2bcce97a6 100644 --- a/bundles/datastar-aliased.js.map +++ b/bundles/datastar-aliased.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../library/src/engine/consts.ts", "../library/src/engine/types.ts", "../library/src/utils/text.ts", "../library/src/plugins/official/core/attributes/computed.ts", "../library/src/plugins/official/core/attributes/signals.ts", "../library/src/plugins/official/core/attributes/star.ts", "../library/src/utils/dom.ts", "../library/src/engine/errors.ts", "../library/src/vendored/preact-core.ts", "../library/src/engine/signals.ts", "../library/src/engine/engine.ts", "../library/src/engine/index.ts", "../library/src/vendored/fetch-event-source.ts", "../library/src/plugins/official/backend/shared.ts", "../library/src/plugins/official/backend/actions/sse.ts", "../library/src/plugins/official/backend/actions/delete.ts", "../library/src/plugins/official/backend/actions/get.ts", "../library/src/plugins/official/backend/actions/patch.ts", "../library/src/plugins/official/backend/actions/post.ts", "../library/src/plugins/official/backend/actions/put.ts", "../library/src/plugins/official/backend/attributes/indicator.ts", "../library/src/plugins/official/backend/watchers/executeScript.ts", "../library/src/utils/view-transtions.ts", "../library/src/vendored/idiomorph.esm.js", "../library/src/plugins/official/backend/watchers/mergeFragments.ts", "../library/src/plugins/official/backend/watchers/mergeSignals.ts", "../library/src/plugins/official/backend/watchers/removeFragments.ts", "../library/src/plugins/official/backend/watchers/removeSignals.ts", "../library/src/plugins/official/browser/actions/clipboard.ts", "../library/src/plugins/official/browser/attributes/customValidity.ts", "../library/src/plugins/official/browser/attributes/intersects.ts", "../library/src/plugins/official/browser/attributes/persist.ts", "../library/src/plugins/official/browser/attributes/replaceUrl.ts", "../library/src/plugins/official/browser/attributes/scrollIntoView.ts", "../library/src/plugins/official/browser/attributes/show.ts", "../library/src/plugins/official/browser/attributes/viewTransition.ts", "../library/src/plugins/official/dom/attributes/attr.ts", "../library/src/plugins/official/dom/attributes/bind.ts", "../library/src/plugins/official/dom/attributes/class.ts", "../library/src/utils/tags.ts", "../library/src/utils/timing.ts", "../library/src/plugins/official/dom/attributes/on.ts", "../library/src/plugins/official/dom/attributes/ref.ts", "../library/src/plugins/official/dom/attributes/text.ts", "../library/src/plugins/official/logic/actions/fit.ts", "../library/src/plugins/official/logic/actions/setAll.ts", "../library/src/plugins/official/logic/actions/toggleAll.ts", "../library/src/bundles/datastar-aliased.ts"], - "sourcesContent": ["// This is auto-generated by Datastar. DO NOT EDIT.\nconst lol = /\uD83D\uDD95JS_DS\uD83D\uDE80/.source\nexport const DSP = lol.slice(0, 5)\nexport const DSS = lol.slice(4)\n\nexport const DATASTAR = \"datastar\";\nexport const DATASTAR_EVENT = \"datastar-event\";\nexport const DATASTAR_REQUEST = \"Datastar-Request\";\n\n// #region Defaults\n\n// #region Default durations\n\n// The default duration for settling during fragment merges. Allows for CSS transitions to complete.\nexport const DefaultFragmentsSettleDurationMs = 300;\n// The default duration for retrying SSE on connection reset. This is part of the underlying retry mechanism of SSE.\nexport const DefaultSseRetryDurationMs = 1000;\n\n// #endregion\n\n\n// #region Default strings\n\n// The default attributes for diff --git a/library/src/bundles/datastar-aliased.ts b/library/src/bundles/datastar-aliased.ts index 88fe4796e..a683522a3 100644 --- a/library/src/bundles/datastar-aliased.ts +++ b/library/src/bundles/datastar-aliased.ts @@ -1,4 +1,4 @@ -import { Datastar as DS } from '../engine' +import { apply, load, setAlias } from '../engine' import { DELETE } from '../plugins/official/backend/actions/delete' import { GET } from '../plugins/official/backend/actions/get' import { PATCH } from '../plugins/official/backend/actions/patch' @@ -28,9 +28,9 @@ import { Fit } from '../plugins/official/logic/actions/fit' import { SetAll } from '../plugins/official/logic/actions/setAll' import { ToggleAll } from '../plugins/official/logic/actions/toggleAll' -DS.aliasPrefix = 'ds' +setAlias('ds') -DS.load( +load( // DOM Attr, Bind, @@ -65,6 +65,6 @@ DS.load( ToggleAll, ) -DS.apply() +apply() -export const Datastar = DS +export { apply, load, setAlias } diff --git a/library/src/bundles/datastar-core.ts b/library/src/bundles/datastar-core.ts index 9089f2e3f..734c0430a 100644 --- a/library/src/bundles/datastar-core.ts +++ b/library/src/bundles/datastar-core.ts @@ -1,5 +1,5 @@ -import { Datastar as DS } from '../engine' +import { apply, load, setAlias } from '../engine' -DS.apply() +apply() -export const Datastar = DS +export { apply, load, setAlias } diff --git a/library/src/bundles/datastar.ts b/library/src/bundles/datastar.ts index 674860b6d..172ca9339 100644 --- a/library/src/bundles/datastar.ts +++ b/library/src/bundles/datastar.ts @@ -1,4 +1,4 @@ -import { Datastar as DS } from '../engine' +import { apply, load, setAlias } from '../engine' import { DELETE } from '../plugins/official/backend/actions/delete' import { GET } from '../plugins/official/backend/actions/get' import { PATCH } from '../plugins/official/backend/actions/patch' @@ -28,7 +28,7 @@ import { Fit } from '../plugins/official/logic/actions/fit' import { SetAll } from '../plugins/official/logic/actions/setAll' import { ToggleAll } from '../plugins/official/logic/actions/toggleAll' -DS.load( +load( // DOM Attr, Bind, @@ -63,6 +63,6 @@ DS.load( ToggleAll, ) -DS.apply() +apply() -export const Datastar = DS +export { apply, load, setAlias } diff --git a/library/src/engine/engine.ts b/library/src/engine/engine.ts index ef8f3424b..c70d80116 100644 --- a/library/src/engine/engine.ts +++ b/library/src/engine/engine.ts @@ -20,356 +20,342 @@ import { type WatcherPlugin, } from './types' -export class Engine { - aliasPrefix = '' - #signals: SignalsRoot = new SignalsRoot() - #plugins: AttributePlugin[] = [] - #actions: ActionPlugins = {} - #watchers: WatcherPlugin[] = [] - #mutationObserver: MutationObserver | null = null - - // Map of cleanup functions by element, keyed by the dataset key and value - #removals = new Map>() - - get signals() { - return this.#signals - } +const signals: SignalsRoot = new SignalsRoot() +const plugins: AttributePlugin[] = [] +const actions: ActionPlugins = {} +const watchers: WatcherPlugin[] = [] + +let aliasPrefix = '' +export function setAlias(prefix: string) { + aliasPrefix = prefix +} +let mutationObserver: MutationObserver | null = null - public load(...pluginsToLoad: DatastarPlugin[]) { - const that = this // I hate javascript - for (const plugin of pluginsToLoad) { - const ctx: InitContext = { - get signals() { - return that.#signals - }, - effect: (cb: () => void): OnRemovalFn => effect(cb), - actions: this.#actions, - plugin, - apply: that.apply.bind(that), - } +// Map of cleanup functions by element, keyed by the dataset key and value +const removals = new Map>() - let globalInitializer: GlobalInitializer | undefined - switch (plugin.type) { - case PluginType.Watcher: { - const wp = plugin as WatcherPlugin - this.#watchers.push(wp) - globalInitializer = wp.onGlobalInit - break - } - case PluginType.Action: { - this.#actions[plugin.name] = plugin as ActionPlugin - break - } - case PluginType.Attribute: { - const ap = plugin as AttributePlugin - this.#plugins.push(ap) - globalInitializer = ap.onGlobalInit - break - } - default: { - throw initErr('InvalidPluginType', ctx) - } +export function load(...pluginsToLoad: DatastarPlugin[]) { + for (const plugin of pluginsToLoad) { + const ctx: InitContext = { + signals, + effect: (cb: () => void): OnRemovalFn => effect(cb), + actions: actions, + plugin, + apply, + } + + let globalInitializer: GlobalInitializer | undefined + switch (plugin.type) { + case PluginType.Watcher: { + const wp = plugin as WatcherPlugin + watchers.push(wp) + globalInitializer = wp.onGlobalInit + break + } + case PluginType.Action: { + actions[plugin.name] = plugin as ActionPlugin + break + } + case PluginType.Attribute: { + const ap = plugin as AttributePlugin + plugins.push(ap) + globalInitializer = ap.onGlobalInit + break } - if (globalInitializer) { - globalInitializer(ctx) + default: { + throw initErr('InvalidPluginType', ctx) } } - - // Sort attribute plugins by descending length then alphabetically - this.#plugins.sort((a, b) => { - const lenDiff = b.name.length - a.name.length - if (lenDiff !== 0) return lenDiff - return a.name.localeCompare(b.name) - }) + if (globalInitializer) { + globalInitializer(ctx) + } } - // Apply all plugins to the element and its children - apply(rootElement: HTMLorSVGElement = document.documentElement) { - walkDOM(rootElement, (el) => { - // Check if the element has any data attributes already - const toApply = new Array() - const elCleanups = this.#removals.get(el) || new Map() - const toCleanup = new Map([...elCleanups]) - const hashes = new Map() - - // Apply the plugins to the element in order of application - // since DOMStringMap is ordered, we can be deterministic - for (const datasetKey of Object.keys(el.dataset)) { - // Ignore data attributes that don’t start with the alias prefix - if (!datasetKey.startsWith(this.aliasPrefix)) { - break - } - - const datasetValue = el.dataset[datasetKey] || '' - const currentHash = attrHash(datasetKey, datasetValue) - hashes.set(datasetKey, currentHash) + // Sort attribute plugins by descending length then alphabetically + plugins.sort((a, b) => { + const lenDiff = b.name.length - a.name.length + if (lenDiff !== 0) return lenDiff + return a.name.localeCompare(b.name) + }) +} - // If the hash hasn't changed, ignore - // otherwise keep the old cleanup and add new to applys - if (elCleanups.has(currentHash)) { - toCleanup.delete(currentHash) - } else { - toApply.push(datasetKey) - } +// Apply all plugins to the element and its children +export function apply( + rootElement: HTMLorSVGElement = document.documentElement, +) { + walkDOM(rootElement, (el) => { + // Check if the element has any data attributes already + const toApply = new Array() + const elCleanups = removals.get(el) || new Map() + const toCleanup = new Map([...elCleanups]) + const hashes = new Map() + + // Apply the plugins to the element in order of application + // since DOMStringMap is ordered, we can be deterministic + for (const datasetKey of Object.keys(el.dataset)) { + // Ignore data attributes that don’t start with the alias prefix + if (!datasetKey.startsWith(aliasPrefix)) { + break } - // Clean up any old plugins and apply the new ones - for (const [_, cleanup] of toCleanup) cleanup() - for (const key of toApply) { - const h = hashes.get(key)! - this.#applyAttributePlugin(el, key, h) - } - }) + const datasetValue = el.dataset[datasetKey] || '' + const currentHash = attrHash(datasetKey, datasetValue) + hashes.set(datasetKey, currentHash) - this.#observe() - } + // If the hash hasn't changed, ignore + // otherwise keep the old cleanup and add new to applys + if (elCleanups.has(currentHash)) { + toCleanup.delete(currentHash) + } else { + toApply.push(datasetKey) + } + } - // Set up a mutation observer to run plugin removal and apply functions - #observe() { - if (this.#mutationObserver) { - return + // Clean up any old plugins and apply the new ones + for (const [_, cleanup] of toCleanup) cleanup() + for (const key of toApply) { + const h = hashes.get(key)! + applyAttributePlugin(el, key, h) } + }) - this.#mutationObserver = new MutationObserver((mutations) => { - const toRemove = new Set() - const toApply = new Set() - for (const { - target, - type, - addedNodes, - removedNodes, - } of mutations) { - switch (type) { - case 'childList': - { - for (const node of removedNodes) { - toRemove.add(node as HTMLorSVGElement) - } - for (const node of addedNodes) { - toApply.add(node as HTMLorSVGElement) - } - } - break - case 'attributes': { - toApply.add(target as HTMLorSVGElement) + observe() +} - break +// Set up a mutation observer to run plugin removal and apply functions +function observe() { + if (mutationObserver) { + return + } + + mutationObserver = new MutationObserver((mutations) => { + const toRemove = new Set() + const toApply = new Set() + for (const { target, type, addedNodes, removedNodes } of mutations) { + switch (type) { + case 'childList': + { + for (const node of removedNodes) { + toRemove.add(node as HTMLorSVGElement) + } + for (const node of addedNodes) { + toApply.add(node as HTMLorSVGElement) + } } + break + case 'attributes': { + toApply.add(target as HTMLorSVGElement) + + break } } - for (const el of toRemove) { - const elTracking = this.#removals.get(el) - if (elTracking) { - for (const [h, cleanup] of elTracking) { - cleanup() - elTracking.delete(h) - } - if (elTracking.size === 0) { - this.#removals.delete(el) - } + } + for (const el of toRemove) { + const elTracking = removals.get(el) + if (elTracking) { + for (const [h, cleanup] of elTracking) { + cleanup() + elTracking.delete(h) + } + if (elTracking.size === 0) { + removals.delete(el) } } - for (const el of toApply) { - this.apply(el) - } - }) + } + for (const el of toApply) { + apply(el) + } + }) + + mutationObserver.observe(document.body, { + attributes: true, + attributeOldValue: true, + childList: true, + subtree: true, + }) +} - this.#mutationObserver.observe(document.body, { - attributes: true, - attributeOldValue: true, - childList: true, - subtree: true, - }) - } +function applyAttributePlugin( + el: HTMLorSVGElement, + camelCasedKey: string, + hash: number, +) { + // Extract the raw key from the dataset + const rawKey = camel(camelCasedKey.slice(aliasPrefix.length)) - #applyAttributePlugin( - el: HTMLorSVGElement, - camelCasedKey: string, - hash: number, - ) { - // Extract the raw key from the dataset - const rawKey = camel(camelCasedKey.slice(this.aliasPrefix.length)) + // Find the plugin that matches, since the plugins are sorted by length descending and alphabetically. The first match will be the most specific. + const plugin = plugins.find((p) => rawKey.startsWith(p.name)) - // Find the plugin that matches, since the plugins are sorted by length descending and alphabetically. The first match will be the most specific. - const plugin = this.#plugins.find((p) => rawKey.startsWith(p.name)) + // Skip if no plugin is found + if (!plugin) return - // Skip if no plugin is found - if (!plugin) return + // Ensure the element has an id + if (!el.id.length) el.id = elUniqId(el) - // Ensure the element has an id - if (!el.id.length) el.id = elUniqId(el) + // Extract the key and modifiers + let [key, ...rawModifiers] = rawKey.slice(plugin.name.length).split(/\_\_+/) - // Extract the key and modifiers - let [key, ...rawModifiers] = rawKey.slice(plugin.name.length).split(/\_\_+/) + const hasKey = key.length > 0 + if (hasKey) { + key = camel(key) + } + const value = el.dataset[camelCasedKey] || '' + const hasValue = value.length > 0 + + // Create the runtime context + const ctx: RuntimeContext = { + signals, + apply, + effect: (cb: () => void): OnRemovalFn => effect(cb), + actions: actions, + genRX: () => genRX(ctx, ...(plugin.argNames || [])), + plugin, + el, + rawKey, + key, + value, + mods: new Map(), + } - const hasKey = key.length > 0 - if (hasKey) { - key = camel(key) - } - const value = el.dataset[camelCasedKey] || '' - const hasValue = value.length > 0 - - // Create the runtime context - const that = this // I hate javascript - const ctx: RuntimeContext = { - get signals() { - return that.#signals - }, - apply: that.apply.bind(that), - effect: (cb: () => void): OnRemovalFn => effect(cb), - actions: this.#actions, - genRX: () => this.#genRX(ctx, ...(plugin.argNames || [])), - plugin, - el, - rawKey, - key, - value, - mods: new Map(), + // Check the requirements + const keyReq = plugin.keyReq || Requirement.Allowed + if (hasKey) { + if (keyReq === Requirement.Denied) { + throw runtimeErr(`${plugin.name}KeyNotAllowed`, ctx) } + } else if (keyReq === Requirement.Must) { + throw runtimeErr(`${plugin.name}KeyRequired`, ctx) + } - // Check the requirements - const keyReq = plugin.keyReq || Requirement.Allowed - if (hasKey) { - if (keyReq === Requirement.Denied) { - throw runtimeErr(`${plugin.name}KeyNotAllowed`, ctx) - } - } else if (keyReq === Requirement.Must) { - throw runtimeErr(`${plugin.name}KeyRequired`, ctx) + const valReq = plugin.valReq || Requirement.Allowed + if (hasValue) { + if (valReq === Requirement.Denied) { + throw runtimeErr(`${plugin.name}ValueNotAllowed`, ctx) } + } else if (valReq === Requirement.Must) { + throw runtimeErr(`${plugin.name}ValueRequired`, ctx) + } - const valReq = plugin.valReq || Requirement.Allowed - if (hasValue) { - if (valReq === Requirement.Denied) { - throw runtimeErr(`${plugin.name}ValueNotAllowed`, ctx) - } - } else if (valReq === Requirement.Must) { - throw runtimeErr(`${plugin.name}ValueRequired`, ctx) + // Check for exclusive requirements + if (keyReq === Requirement.Exclusive || valReq === Requirement.Exclusive) { + if (hasKey && hasValue) { + throw runtimeErr(`${plugin.name}KeyAndValueProvided`, ctx) } - - // Check for exclusive requirements - if (keyReq === Requirement.Exclusive || valReq === Requirement.Exclusive) { - if (hasKey && hasValue) { - throw runtimeErr(`${plugin.name}KeyAndValueProvided`, ctx) - } - if (!hasKey && !hasValue) { - throw runtimeErr(`${plugin.name}KeyOrValueRequired`, ctx) - } + if (!hasKey && !hasValue) { + throw runtimeErr(`${plugin.name}KeyOrValueRequired`, ctx) } + } - for (const rawMod of rawModifiers) { - const [label, ...mod] = rawMod.split('.') - ctx.mods.set(camel(label), new Set(mod.map((t) => t.toLowerCase()))) - } + for (const rawMod of rawModifiers) { + const [label, ...mod] = rawMod.split('.') + ctx.mods.set(camel(label), new Set(mod.map((t) => t.toLowerCase()))) + } - // Load the plugin and store any cleanup functions - const cleanup = plugin.onLoad(ctx) - if (cleanup) { - let elTracking = this.#removals.get(el) - if (!elTracking) { - elTracking = new Map() - this.#removals.set(el, elTracking) - } - elTracking.set(hash, cleanup) + // Load the plugin and store any cleanup functions + const cleanup = plugin.onLoad(ctx) + if (cleanup) { + let elTracking = removals.get(el) + if (!elTracking) { + elTracking = new Map() + removals.set(el, elTracking) } + elTracking.set(hash, cleanup) } +} - #genRX( - ctx: RuntimeContext, - ...argNames: string[] - ): RuntimeExpressionFunction { - let userExpression = '' - - // This regex allows Datastar expressions to support nested - // regex and strings that contain ; without breaking. - // - // Each of these regex defines a block type we want to match - // (importantly we ignore the content within these blocks): - // - // regex \/(\\\/|[^\/])*\/ - // double quotes "(\\"|[^\"])*" - // single quotes '(\\'|[^'])*' - // ticks `(\\`|[^`])*` - // - // We also want to match the non delimiter part of statements - // note we only support ; statement delimiters: - // - // [^;] - // - const statementRe = - /(\/(\\\/|[^\/])*\/|"(\\"|[^\"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|[^;])+/gm - const statements = ctx.value.trim().match(statementRe) - if (statements) { - const lastIdx = statements.length - 1 - const last = statements[lastIdx].trim() - if (!last.startsWith('return')) { - statements[lastIdx] = `return (${last});` - } - userExpression = statements.join(';\n') +function genRX( + ctx: RuntimeContext, + ...argNames: string[] +): RuntimeExpressionFunction { + let userExpression = '' + + // This regex allows Datastar expressions to support nested + // regex and strings that contain ; without breaking. + // + // Each of these regex defines a block type we want to match + // (importantly we ignore the content within these blocks): + // + // regex \/(\\\/|[^\/])*\/ + // double quotes "(\\"|[^\"])*" + // single quotes '(\\'|[^'])*' + // ticks `(\\`|[^`])*` + // + // We also want to match the non delimiter part of statements + // note we only support ; statement delimiters: + // + // [^;] + // + const statementRe = + /(\/(\\\/|[^\/])*\/|"(\\"|[^\"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|[^;])+/gm + const statements = ctx.value.trim().match(statementRe) + if (statements) { + const lastIdx = statements.length - 1 + const last = statements[lastIdx].trim() + if (!last.startsWith('return')) { + statements[lastIdx] = `return (${last});` } + userExpression = statements.join(';\n') + } - // Ignore any escaped values - const escaped = new Map() - const escapeRe = new RegExp(`(?:${DSP})(.*?)(?:${DSS})`, 'gm') - for (const match of userExpression.matchAll(escapeRe)) { - const k = match[1] - const v = new Hash('dsEscaped').with(k).string - escaped.set(v, k) - userExpression = userExpression.replace(DSP + k + DSS, v) - } + // Ignore any escaped values + const escaped = new Map() + const escapeRe = new RegExp(`(?:${DSP})(.*?)(?:${DSS})`, 'gm') + for (const match of userExpression.matchAll(escapeRe)) { + const k = match[1] + const v = new Hash('dsEscaped').with(k).string + escaped.set(v, k) + userExpression = userExpression.replace(DSP + k + DSS, v) + } - const fnCall = /@(\w*)\(/gm - const matches = userExpression.matchAll(fnCall) - const methodsCalled = new Set() - for (const match of matches) { - methodsCalled.add(match[1]) - } + const fnCall = /@(\w*)\(/gm + const matches = userExpression.matchAll(fnCall) + const methodsCalled = new Set() + for (const match of matches) { + methodsCalled.add(match[1]) + } - // Replace any action calls - const actionsRe = new RegExp( - `@(${Object.keys(this.#actions).join('|')})\\(`, - 'gm', - ) + // Replace any action calls + const actionsRe = new RegExp(`@(${Object.keys(actions).join('|')})\\(`, 'gm') + + // Add ctx to action calls + userExpression = userExpression.replaceAll( + actionsRe, + 'ctx.actions.$1.fn(ctx,', + ) - // Add ctx to action calls + // Replace any signal calls + const signalNames = ctx.signals.paths() + if (signalNames.length) { + // Match any valid `$signalName` followed by a non-word character or end of string + const signalsRe = new RegExp(`\\$(${signalNames.join('|')})(\\W|$)`, 'gm') userExpression = userExpression.replaceAll( - actionsRe, - 'ctx.actions.$1.fn(ctx,', + signalsRe, + `ctx.signals.signal('$1').value$2`, ) + } - // Replace any signal calls - const signalNames = ctx.signals.paths() - if (signalNames.length) { - // Match any valid `$signalName` followed by a non-word character or end of string - const signalsRe = new RegExp(`\\$(${signalNames.join('|')})(\\W|$)`, 'gm') - userExpression = userExpression.replaceAll( - signalsRe, - `ctx.signals.signal('$1').value$2`, - ) - } - - // Replace any escaped values - for (const [k, v] of escaped) { - userExpression = userExpression.replace(k, v) - } + // Replace any escaped values + for (const [k, v] of escaped) { + userExpression = userExpression.replace(k, v) + } - const fnContent = `return (()=> {\n${userExpression}\n})()` // Wrap in IIFE - ctx.fnContent = fnContent - - try { - const fn = new Function('ctx', ...argNames, fnContent) - return (...args: any[]) => { - try { - return fn(ctx, ...args) - } catch (error: any) { - throw runtimeErr('ExecuteExpression', ctx, { - error: error.message, - }) - } + const fnContent = `return (()=> {\n${userExpression}\n})()` // Wrap in IIFE + ctx.fnContent = fnContent + + try { + const fn = new Function('ctx', ...argNames, fnContent) + return (...args: any[]) => { + try { + return fn(ctx, ...args) + } catch (error: any) { + throw runtimeErr('ExecuteExpression', ctx, { + error: error.message, + }) } - } catch (error: any) { - throw runtimeErr('GenerateExpression', ctx, { - error: error.message, - }) } + } catch (error: any) { + throw runtimeErr('GenerateExpression', ctx, { + error: error.message, + }) } } diff --git a/library/src/engine/index.ts b/library/src/engine/index.ts index 9cfabfcb0..8e9305671 100644 --- a/library/src/engine/index.ts +++ b/library/src/engine/index.ts @@ -5,8 +5,8 @@ const _ = DSP // This is to force the import of DSP first in the compiled code import { Computed } from '../plugins/official/core/attributes/computed' import { Signals } from '../plugins/official/core/attributes/signals' import { Star } from '../plugins/official/core/attributes/star' -import { Engine } from './engine' +import { apply, load, setAlias } from './engine' -const DS = new Engine() -DS.load(Star, Signals, Computed) -export const Datastar = DS +load(Star, Signals, Computed) + +export { apply, load, setAlias } diff --git a/library/src/utils/dom.ts b/library/src/utils/dom.ts index fc1d9630a..d704f90e9 100644 --- a/library/src/utils/dom.ts +++ b/library/src/utils/dom.ts @@ -17,7 +17,8 @@ export class Hash { } else if (typeof x === 'boolean') { this.with(1 << (x ? 7 : 3)) } else { - this.#value = (this.#value << 5) - this.#value + x + // use djb2 favored by bernstein http://www.cse.yorku.ca/~oz/hash.html + this.#value = (this.#value * 33) ^ x } return this } diff --git a/sdk/go/consts.go b/sdk/go/consts.go index 689a7df79..68bdcd662 100644 --- a/sdk/go/consts.go +++ b/sdk/go/consts.go @@ -7,8 +7,8 @@ import "time" const ( DatastarKey = "datastar" Version = "1.0.0-beta.7" - VersionClientByteSize = 39819 - VersionClientByteSizeGzip = 14767 + VersionClientByteSize = 39523 + VersionClientByteSizeGzip = 14661 //region Default durations diff --git a/site/routes_bundler.qtpl b/site/routes_bundler.qtpl index 67c8c3ec2..06b35511f 100644 --- a/site/routes_bundler.qtpl +++ b/site/routes_bundler.qtpl @@ -1,5 +1,5 @@ {% func bundlerContent(manifest PluginManifest) %} -import { Datastar as DS } from "../engine" +import { apply, load, setAlias } from '../engine' {%- for _, p := range manifest.Plugins -%} import { {%s p.Name %} } from "{%s p.Path %}" {%- endfor -%} @@ -7,15 +7,15 @@ import { {%s p.Name %} } from "{%s p.Path %}" {%- if manifest.Alias != "" -%} // You included an alias in your manifest // Please use this as a last resort as you will have to convert any issues or errors back to the original form before reporting them if you want help. -DS.aliasPrefix = "{%s manifest.Alias %}" +setAlias('{%s manifest.Alias %}') {%- endif -%} -DS.load( +load( {%- for _, p := range manifest.Plugins -%} {%s p.Name %}, {%- endfor -%} ) -DS.apply() -export const Datastar = DS +apply() +export { apply, load, setAlias } {% endfunc %} \ No newline at end of file diff --git a/site/routes_reference.go b/site/routes_reference.go index dc44fcfd7..c7f4c987b 100644 --- a/site/routes_reference.go +++ b/site/routes_reference.go @@ -22,9 +22,10 @@ func setupReferences(ctx context.Context, router chi.Router) error { Links: []*SidebarLink{ {ID: "attribute_plugins"}, {ID: "action_plugins"}, + {ID: "expression_context"}, {ID: "sse_events"}, - {ID: "javascript_api"}, {ID: "sdks"}, + {ID: "security"}, }, }, } @@ -62,6 +63,11 @@ func setupReferences(ctx context.Context, router chi.Router) error { }) } + // Redirect legacy “JavaScript APIs” page. + referenceRouter.Get("/javascript_api", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/reference/expression_context", http.StatusMovedPermanently) + }) + referenceRouter.Get("/{name}", func(w http.ResponseWriter, r *http.Request) { name := chi.URLParam(r, "name") mdData, ok := mdDataset[name] diff --git a/site/static/md/guide/datastar_expressions.md b/site/static/md/guide/datastar_expressions.md index 83e3570e7..1b56323c2 100644 --- a/site/static/md/guide/datastar_expressions.md +++ b/site/static/md/guide/datastar_expressions.md @@ -10,7 +10,7 @@ The following example outputs `1` not because `$foo` is defined in the global sc ``` -When Datastar evaluates the expression `$foo`, it first converts it to `ctx.signals.signal('foo').value`, and then evaluates that expression in a sandboxed context, in which `ctx` represents the Datastar context. +When Datastar evaluates the expression `$foo`, it first converts it to `ctx.signals.signal('foo').value`, and then evaluates that expression in a sandboxed context, in which `ctx` represents the current [expression context](/reference/expression_context). This means that JavaScript can be used in Datastar expressions. @@ -66,30 +66,4 @@ Expressions may span multiple lines, but a semicolon must be used to separate st ``` -## `ctx.signals` - -Every expression is evaluated in the context of `ctx`, which is the Datastar context. This means that `ctx` can be used in expressions to access the `signals` object. - -Here is the equivalent of the first example using `ctx.signals`. - -```html -
-
-
-``` - -And here is how you can output the existing signals in JSON format. - -```html -

-```
-
-## Security
-
-When using a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP), `unsafe-eval` must be allowed for scripts, since Datastar evaluates expressions inline. 
-
-```html
-
-```
+See the [Expression Context reference](/reference/expression_context) for more advanced usage of Datastar expressions.
\ No newline at end of file
diff --git a/site/static/md/reference/attribute_plugins.md b/site/static/md/reference/attribute_plugins.md
index 5cf90aa03..13d87c41c 100644
--- a/site/static/md/reference/attribute_plugins.md
+++ b/site/static/md/reference/attribute_plugins.md
@@ -421,7 +421,7 @@ The signal name can be specified in the key (as above), or in the value (as belo
 
 ### `data-star-ignore`
 
-Datastar walks the entire DOM and applies plugins to each element it encounters. It's possible to tell Datastar to ignore an element and its descendants by placing a `data-star-ignore` attribute on it. This can be useful for preventing naming conflicts with third-party libraries.
+Datastar walks the entire DOM and applies plugins to each element it encounters. It's possible to tell Datastar to ignore an element and its descendants by placing a `data-star-ignore` attribute on it. This can be useful for preventing naming conflicts with third-party libraries, or when you are unable to [escape user input](/reference/security#escape-user-input).
 
 ```html
 
diff --git a/site/static/md/reference/expression_context.md b/site/static/md/reference/expression_context.md new file mode 100644 index 000000000..bb8b880d6 --- /dev/null +++ b/site/static/md/reference/expression_context.md @@ -0,0 +1,31 @@ +# Expression Context + +Datastar is _not_ exposed in the global scope. Everything you need to do should be possible via Datastar expressions in [attribute plugins](/reference/attribute_plugins) and [`datastar-execute-script`](/reference/sse_events#datastar-execute-script) SSE events. + +Every Datastar expression is evaluated using a context `ctx`. This means that `ctx` is exposed in expressions and can be used to access properties and methods within the current context. + +You should use `ctx` sparingly, and only when you can't achieve the desired behavior using signals. + +### `ctx.el` + +The current element being processed. + +### `ctx.plugin` + +The current plugin being processed. + +### `ctx.signals` + +The signals root object that contains functions for accessing and modifying signals. Signals can be accessed using the `signal` method. The following is the equivalent of an expression containing only `$foo`. + +```html +
+
+
+``` + +Here is how you can output the existing signals in JSON format, which can be useful when troubleshooting an issue. + +```html +

+```
diff --git a/site/static/md/reference/javascript_api.md b/site/static/md/reference/javascript_api.md
deleted file mode 100644
index fb7b744f7..000000000
--- a/site/static/md/reference/javascript_api.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# JavaScript API
-
-Datastar is intentional about not (indecently) exposing itself in the global scope – you _should_ be able to do everything you need via Datastar expressions in [attribute plugins](/reference/attribute_plugins) and [`datastar-execute-script`](/reference/sse_events#datastar-execute-script) SSE events.
-
-When troubleshooting an issue, it may be useful to see the current state of the signals. The easiest way to do this is by outputting them in JSON format using `data-text`.
-
-```html
-

-```
-
-## Importing Datastar
-
-While it is generally recommended against, you can manually import the Datastar object and access its public methods and properties.
-
-```html
-
-```
-
-### Public Methods
-
-The Datastar object exposes the following methods.
-
-#### `load()`
-
-Loads all plugins and applies them to the DOM.
-
-```js
-Datastar.load()
-```
-
-### Public Properties
-
-The Datastar object exposes the following properties.
-
-#### `signals`
-
-The signal root, on which you can access signal methods. Beware that you should avoid using this for anything other than troubleshooting.
-
-```js
-Datastar.signals.values()
-```
\ No newline at end of file
diff --git a/site/static/md/reference/security.md b/site/static/md/reference/security.md
new file mode 100644
index 000000000..387e123d3
--- /dev/null
+++ b/site/static/md/reference/security.md
@@ -0,0 +1,23 @@
+# Security
+
+[Datastar expressions](/guide/datastar_expressions) are strings that are evaluated in a sandboxed context, in which `ctx` represents the Datastar context. This means that JavaScript can be used in Datastar expressions. 
+
+## Escape User Input
+
+The first rule of security is to never trust user input. This is especially true when using Datastar expressions, which can execute arbitrary JavaScript. 
+
+When using Datastar expressions, you should always escape user input. This is to prevent, among other issues, Cross Site Scripting (XSS) attacks.
+
+## Ignore Unsafe Input
+
+If, for some reason, you cannot escape unsafe user input, you should ignore it using the [`data-star-ignore`](/reference/attribute_plugins#data-star-ignore) attribute. This tells Datastar to ignore an element and its descendants when processing DOM nodes.
+
+## Content Security Policy
+
+When using a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) (CSP), `unsafe-eval` must be allowed for scripts, since Datastar evaluates expressions inline. 
+
+```html
+
+```