phlex-reactive 0.13.3 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{Controller as Ve}from"@hotwired/stimulus";import{confirmResolver as D}from"phlex/reactive/confirm";import{computeReducer as ze}from"phlex/reactive/compute";import{confirmPredicate as Ge}from"phlex/reactive/confirm_predicate";function Ue(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:visit"])return;e["reactive:visit"]=function(){let t=this.getAttribute("data-url");if(t)window.Turbo.visit(t,{action:"advance"})}}function Ke(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:token"])return;e["reactive:token"]=function(){let t=this.getAttribute("data-reactive-token-value"),n=this.getAttribute("target");if(!t||!n)return;let r=document.getElementById(n);if(r)r.setAttribute("data-reactive-token-value",t)}}function Ye(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=We(this.getAttribute("data-reactive-ops"));if(!t.length)return;let n=this.getAttribute("target"),r=this.getAttribute("data-reactive-verbose")==="true",i=n?document.getElementById(n):null;if(n&&!i){if(r&&!Ie(`missing-root|#${n}`))console.warn(`[phlex-reactive] reactive:js stream target root #${n} is not in the DOM — its ops were dropped`);return}N(t,(s)=>rn(s,i),r?(s,o)=>nn(s,o,i):void 0)}}var y=new Map;function ye(e,t){let n=!y.has(e);if(y.set(e,t),n)Te()}function C(e){if(y.delete(e))Ne()}function un(){y.clear(),W=!1}function ln(e){return y.get(e)?.via}var W=!1;function Xe(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;if(e["reactive:defer"]=function(){let t=this.getAttribute("target");if(!t)return;if(this.getAttribute("data-reactive-defer-via")==="stream"){Qe(t,this);return}let n=this.getAttribute("data-reactive-defer-token");if(!n)return;O(t,n)},!W&&typeof document<"u"&&document.addEventListener)W=!0,document.addEventListener("turbo:before-stream-render",Ze)}function Ze(e){let n=e.target?.getAttribute?.("target");if(!n)return;let r=n.startsWith("reactive-defer-src-")?n.slice(19):n;if(y.get(r)?.via==="stream")C(r)}function O(e,t){let n=document.getElementById(e);if(!n){console.warn(`[phlex-reactive] reactive:defer target #${e} is not on the page — skipped`);return}be(e),Ae(n);let r={via:"fetch",abort:new AbortController,timedOut:!1};ye(e,r),et(e,r,t)}function Qe(e,t){let n=document.getElementById(e);if(!n){console.warn(`[phlex-reactive] reactive:defer target #${e} is not on the page — skipped`);return}let r=t.getAttribute("data-reactive-defer-src");if(!r)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let s=t.getAttribute("data-reactive-defer-token");if(s){O(e,s);return}console.error("[phlex-reactive] reactive:defer via=stream but <pgbus-stream-source> is not registered "+"and no fallback token was provided — is the pgbus client loaded on this page?");return}be(e),Ae(n);let i=document.createElement("pgbus-stream-source");i.id=ge(e),i.setAttribute("src",r),i.setAttribute("since-id",t.getAttribute("data-reactive-defer-since-id")??"0"),i.setAttribute("hidden",""),document.body.appendChild(i),ye(e,{via:"stream"})}function ge(e){return`reactive-defer-src-${e}`}async function et(e,t,n){let r=setTimeout(()=>{t.timedOut=!0,t.abort.abort()},rt()),i;try{i=await fetch(tt(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":nt()},body:JSON.stringify({token:n}),credentials:"same-origin",signal:t.abort.signal})}catch(o){if(clearTimeout(r),y.get(e)!==t)return;console.error("[phlex-reactive] deferred render failed",o),F(e,n);return}if(y.get(e)!==t){clearTimeout(r);return}if(i.status===204){clearTimeout(r),oe(e);return}if(!i.ok){clearTimeout(r),console.error(`[phlex-reactive] deferred render failed: HTTP ${i.status}`),F(e,n,i.status);return}let s;try{s=await i.text()}catch(o){if(clearTimeout(r),y.get(e)!==t)return;console.error("[phlex-reactive] deferred render failed reading the body",o),F(e,n);return}if(clearTimeout(r),y.get(e)!==t)return;oe(e),window.Turbo.renderStreamMessage(s)}function be(e){let t=y.get(e);if(!t)return;if(C(e),t.via==="fetch")t.abort.abort();else document.getElementById(ge(e))?.remove?.()}function Ae(e){e.setAttribute("data-reactive-defer-pending","true"),e.setAttribute("aria-busy","true")}function we(e){e.removeAttribute("data-reactive-defer-pending"),e.removeAttribute("aria-busy")}function oe(e){C(e);let t=document.getElementById(e);if(!t)return;we(t),t.removeAttribute("data-reactive-error")}function F(e,t,n){C(e);let r=document.getElementById(e);if(!r)return;we(r),r.setAttribute("data-reactive-error","defer");let i=()=>{let s=document.getElementById(e);if(!s){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}s.removeAttribute("data-reactive-error"),O(e,t)};r.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:e,status:n,retry:i}}))}function tt(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function nt(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function rt(){let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return Number.isFinite(t)&&t>0?t:30000}var B=!1;function it(){if(B)return;if(typeof document>"u"||!document.addEventListener)return;B=!0,document.addEventListener("turbo:before-stream-render",st)}function st(e){let t=e.detail,n=t?.render;if(typeof n!=="function"||n.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(M);else setTimeout(M,0);return}let r=async(i)=>{await n(i),M()};r.__reactiveDismissWrapped=!0,t.render=r}function M(){let e=document.querySelectorAll("[data-reactive-dismiss-after]");for(let t of e){if(t.hasAttribute("data-reactive-dismiss-scheduled"))continue;let n=Number(t.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite(n)||n<=0)continue;t.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>t.remove(),n)}}function fn(){B=!1}var ot=Object.freeze({append:"enter",prepend:"enter",replace:"update",update:"update",remove:"exit"}),P=Object.freeze(["fade","slide","scale","highlight","shake"]),I="data-reactive-fx-pending",Se=1000,H=!1;function at(){if(H)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;H=!0,document.addEventListener("turbo:before-stream-render",ct)}function dn(){H=!1}function ct(e){let t=e.detail,n=t?.render;if(typeof n!=="function"||n.__reactiveEffectsWrapped)return;let r=t?.newStream??e.target,i=ot[r?.getAttribute?.("action")];if(!i||ft())return;let s=ut(r,i);if(!s)return;let o=i==="exit"?async(a)=>{await mt(L(r),s),await n(a)}:async(a)=>{let c=i==="enter"?dt(r):null;if(await n(a),i==="enter")ht(c,s);else Ee(L(r),s)};o.__reactiveEffectsWrapped=!0,t.render=o}function ut(e,t){let n=e.getAttribute?.("data-reactive-effect");if(n==="off")return null;if(n)return ae(n,t);let i=(t==="enter"?lt(e):L(e))?.getAttribute?.(`data-reactive-effect-${t}`);return i?ae(i,t):null}function L(e){let t=e.getAttribute?.("target");return t?document.getElementById?.(t)??null:null}function lt(e){return e.querySelector?.("template")?.content?.firstElementChild??null}function ae(e,t){if(e.startsWith("[")){let r=null;try{let i=JSON.parse(e);if(Array.isArray(i)&&i.length===3)r=i.map(String)}catch{}if(r)return{legs:r};return console.warn(`[phlex-reactive] malformed effect legs ${JSON.stringify(e)} — skipped`),null}let n=e==="random"?P[Math.floor(Math.random()*P.length)]:e;if(!P.includes(n))return console.warn(`[phlex-reactive] unknown effect ${JSON.stringify(e)} — skipped`),null;return{className:`reactive-fx--${n}-${t}`}}function ft(){try{return typeof matchMedia==="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function dt(e){let t=e.querySelector?.("template")?.content;if(!t)return null;for(let n of Array.from(t.children??[]))n.setAttribute?.(I,"");return L(e)}function ht(e,t){if(typeof e?.querySelectorAll!=="function")return;for(let n of Array.from(e.querySelectorAll(`[${I}]`)))n.removeAttribute(I),Ee(n,t)}async function mt(e,t){if(!e?.classList)return;if(t.legs){await xe(e,t.legs);return}e.classList.add(t.className);let n=U(e);if(n<=0){e.classList.remove(t.className);return}await K(e,n),e.classList.remove(t.className)}function Ee(e,t){if(!e?.classList)return;if(t.legs){xe(e,t.legs);return}if(e.classList.contains(t.className))e.classList.remove(t.className),e.offsetWidth;e.classList.add(t.className);let n=U(e);if(n<=0){e.classList.remove(t.className);return}let r=e.__reactiveFxToken=(e.__reactiveFxToken??0)+1;K(e,n).then(()=>{if(e.__reactiveFxToken===r)e.classList.remove(t.className)})}async function xe(e,t){let[n,r,i]=t.map(pt),s=e.__reactiveFxToken=(e.__reactiveFxToken??0)+1;if(e.classList.remove(...n,...r,...i),e.classList.add(...n,...r),await vt(),e.__reactiveFxToken!==s)return;e.classList.remove(...r),e.classList.add(...i);let o=U(e);if(o>0)await K(e,o);if(e.__reactiveFxToken!==s)return;e.classList.remove(...n,...i)}function pt(e){return String(e??"").split(/\s+/).filter(Boolean)}function U(e){if(typeof getComputedStyle!=="function")return 0;try{let t=getComputedStyle(e),n=(s)=>String(s??"").split(",").reduce((o,a)=>Math.max(o,parseFloat(a)||0),0),r=n(t.animationDuration)+n(t.animationDelay),i=n(t.transitionDuration)+n(t.transitionDelay);return Math.min(Math.max(r,i)*1000,Se)}catch{return 0}}function K(e,t){return new Promise((n)=>{let r=!1,i=()=>{if(r)return;r=!0,n()};e.addEventListener?.("animationend",i,{once:!0}),e.addEventListener?.("transitionend",i,{once:!0}),setTimeout(i,Math.min(t+50,Se))})}function vt(){return new Promise((e)=>{if(typeof requestAnimationFrame==="function")requestAnimationFrame(()=>e());else setTimeout(e,16)})}var V=!1;function yt(){if(V)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;V=!0;let e=()=>{let t=document.documentElement;if(typeof t?.toggleAttribute!=="function")return;t.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};e(),window.addEventListener("online",e),window.addEventListener("offline",e)}function hn(){V=!1}var Y="phlex-reactive:latency",_=!1;function gt(e){if(typeof sessionStorage>"u")return;sessionStorage.setItem(Y,String(e))}function bt(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem(Y),_=!1}function At(){if(typeof window>"u"||typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content!=="development")return;window.PhlexReactive={enableLatencySim:gt,disableLatencySim:bt}}function mn(){_=!1}var ke="data-reactive-active",b=0;function Te(){if(b++,b===1)Le("reactive:busy")}function Ne(){if(b===0)return;if(b--,b===0)Le("reactive:idle")}function pn(){return b}function vn(){b=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(ke)}function Le(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(ke,b>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:b}}))}function ce(){Ue(),Ke(),Ye(),Xe(),it(),at(),yt(),At()}function wt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}if(typeof window<"u")if(window.Turbo)ce();else document.addEventListener("turbo:load",ce,{once:!0});var R=!1;function St(){if(R)return;if(typeof document>"u")return;let e=document.querySelectorAll('[data-controller~="reactive"]');if(!e||e.length===0)return;console.warn("[phlex-reactive] found "+e.length+' element(s) with data-controller="reactive" '+"but the reactive controller never connected. It is loaded but not registered — "+'add `application.register("reactive", ReactiveController)` (importmap) or import it into app/javascript/controllers/ for lazyLoadControllersFrom apps. See the README.')}function yn(){R=!1}function gn(){R=!0}if(typeof window<"u"&&typeof document<"u"){let e=()=>setTimeout(St,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var Et=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function xt(e){let t=String(e).toLowerCase();return t.startsWith("on")||Et.has(t)}function kt(e,t,n){let[r,i,s]=t;e.classList.add(r,i),n(),requestAnimationFrame(()=>{e.classList.remove(i),e.classList.add(s)});let o=!1,a=()=>{if(o)return;o=!0,e.classList.remove(r,s)};e.addEventListener("animationend",a,{once:!0}),setTimeout(a,350)}var _e=1,Tt="phlex-reactive:persist:",Nt=new Set(["hidden","file","password","submit","button","reset","image"]),X=Symbol("persist-no-value"),Z="data-reactive-persist-state",Ce=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",Oe=new Set(["lexxy-editor","trix-editor"]),Lt="lexxy-editor, trix-editor, trix-toolbar",ue=["lexxy:change","trix-change"],_t=new Set(["","<p></p>","<p><br></p>","<div><br></div>"]),le=new WeakSet,fe=new WeakSet,de=new WeakSet;function Q(e){let t=e?.getAttribute?.("data-reactive-persist");if(!t||t==="off")return null;try{let n=JSON.parse(t);if(n&&typeof n==="object"&&typeof n.key==="string"&&n.key!=="")return n}catch{}if(!le.has(e))le.add(e),console.warn(`[phlex-reactive] malformed reactive_persist payload ${JSON.stringify(t)} — persistence disabled`);return null}function ee(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function te(e,t){if(e?.getAttribute?.("data-reactive-debug")!=="true"||fe.has(e))return;fe.add(e),console.info(`[phlex-reactive] reactive_persist: storage unavailable — draft skipped (${t?.name??t})`)}function ne(e){return Tt+e.key}function z(e,t){let n=ee();if(!n)return null;let r;try{r=n.getItem(ne(t))}catch(c){return te(e,c),null}if(!r)return null;let i;try{i=JSON.parse(r)}catch{return null}if(!i||typeof i!=="object"||i.v!==_e)return null;let s=Number(t.ttl)*1000;if(!(Number(i.savedAt)+s>Date.now()))return re(e,t),null;let o=i.fields&&typeof i.fields==="object"?i.fields:{},a=i.state&&typeof i.state==="object"?i.state:null;return{fields:o,state:a}}function Re(e,t,{fields:n,state:r}){let i=ee();if(!i)return!1;let s={v:_e,savedAt:Date.now(),fields:n};if(r)s.state=r;try{return i.setItem(ne(t),JSON.stringify(s)),!0}catch(o){return te(e,o),!1}}function re(e,t){e?.removeAttribute?.(Z);let n=ee();if(!n)return;try{n.removeItem(ne(t))}catch(r){te(e,r)}}function ie(e,t){let n=Array.isArray(t.fields)?new Set(t.fields):null,r=[],i=(s)=>s.closest('[data-controller~="reactive"]')===e&&s.getAttribute("data-reactive-persist")!=="off";for(let s of e.querySelectorAll("input[name], select[name], textarea[name]")){if(!i(s)||Nt.has(s.type)||s.closest(Lt))continue;if(n&&!n.has(s.name))continue;r.push({el:s,name:s.name,kind:"native"})}for(let s of e.querySelectorAll(Ce)){if(!i(s))continue;let o=Ct(s);if(!o||n&&!n.has(o))continue;r.push({el:s,name:o,kind:Oe.has(s.localName)?"editor":"contenteditable"})}return r}function Ct(e){return e.getAttribute("name")||typeof e.name==="string"&&e.name||null}function q(e){return typeof e.value==="string"}function Ot(e){return Oe.has(e.localName)?q(e):!0}function Rt(e){if(typeof e.isEmpty==="boolean")return e.isEmpty;let t=e.editor?.getDocument?.();if(typeof t?.isEmpty==="function")return t.isEmpty();return _t.has(e.value.trim())}function $t(e,t,n){if(e?.getAttribute?.("data-reactive-debug")!=="true"||de.has(e))return;de.add(e),console.info(`[phlex-reactive] reactive_persist: could not restore editor ${JSON.stringify(t)} — ${n?.message??n}`)}function E(e){return e.tagName==="SELECT"&&e.multiple}function $e(e){let t=new Map;for(let{el:n,name:r}of e){if(n.type==="radio"||!String(r).endsWith("[]"))continue;t.set(r,(t.get(r)??0)+1)}return t}function qe(e,t,n){if(!Array.isArray(e))return e;if(n.get(t)!==1||e.length!==1)return X;return e[0]}function De(e,t){let n={},r=(i)=>{let s=n[i];return Array.isArray(s)?s:n[i]=[]};for(let{el:i,name:s,kind:o}of ie(e,t)){let a=String(s).endsWith("[]");if(o==="editor"){if(q(i))if(a)r(s).push(i.value);else n[s]=i.value}else if(o==="contenteditable"){let c=i.textContent??"";if(a)r(s).push(c);else n[s]=c}else if(i.type==="radio"){if(i.checked)n[s]=i.value;else if(!Object.hasOwn(n,s))n[s]=null}else if(i.type==="checkbox")if(a){let c=r(s);if(i.checked)c.push(i.value)}else n[s]=i.checked;else if(E(i)){let c=[...i.options].filter((u)=>u.selected).map((u)=>u.value);if(a)r(s).push(...c);else n[s]=c}else if(a)r(s).push(i.value);else n[s]=i.value}return n}function qt(e,t,n){let r=t.restore==="always",i=ie(e,t),s=$e(i),o=new Set;for(let a of i)if(a.kind==="native"&&a.el.type==="checkbox"&&a.el.checked)o.add(a.name);for(let{el:a,name:c,kind:u}of i){if(!Object.hasOwn(n,c))continue;let l=n[c];if(l===null||l===void 0)continue;if(Array.isArray(l)&&E(a)&&(s.get(c)??0)>1)continue;if(Array.isArray(l)&&!(a.type==="checkbox"||E(a))){if(l=qe(l,c,s),l===X)continue}if((a.type==="checkbox"||E(a))&&String(c).endsWith("[]")&&!Array.isArray(l))continue;if(u==="editor")Fe(e,a,c,l,r);else if(u==="contenteditable"){if(!r&&(a.textContent??"").trim()!=="")continue;a.textContent=String(l)}else if(a.type==="radio"){if(!r&&i.some((h)=>h.kind==="native"&&h.el.type==="radio"&&h.name===c&&h.el.checked))continue;a.checked=a.value===String(l)}else if(a.type==="checkbox"&&Array.isArray(l)){if(!r&&o.has(c))continue;a.checked=l.map(String).includes(a.value)}else if(a.type==="checkbox"){if(!r&&a.checked)continue;a.checked=Boolean(l)}else if(E(a)){if(!r&&[...a.options].some((d)=>d.selected))continue;let h=new Set((Array.isArray(l)?l:[l]).map(String));for(let d of a.options)d.selected=h.has(d.value)}else{if(!r&&a.value!=="")continue;a.value=String(l)}}Dt(e,t,n)}function Fe(e,t,n,r,i){if(Array.isArray(r))return;if(!q(t))return;if(!i&&!Rt(t))return;try{t.value=String(r)}catch(s){$t(e,n,s)}}function Dt(e,t,n){let r=globalThis.customElements;if(typeof r?.whenDefined!=="function")return;let i=new Set;for(let o of e.querySelectorAll("lexxy-editor, trix-editor"))if(!q(o)&&!r.get?.(o.localName))i.add(o.localName);let s=t.restore==="always";for(let o of i)r.whenDefined(o).then(()=>{if(!e.isConnected)return;let a=ie(e,t),c=$e(a);for(let{el:u,name:l,kind:h}of a){if(h!=="editor"||u.localName!==o||!Object.hasOwn(n,l))continue;let d=qe(n[l],l,c);if(d===null||d===void 0||d===X)continue;Fe(e,u,l,d,s)}})}function Ft(e,t){let n=Q(e);if(!n){console.warn("[phlex-reactive] persist_state on a root without reactive_persist — skipped");return}if(!t||typeof t!=="object")return;let i={...z(e,n)?.state??{},...t};if(Re(e,n,{fields:De(e,n),state:i}))e.setAttribute?.(Z,JSON.stringify(i))}function Mt(e){let t=Q(e);if(t)re(e,t)}var he=Object.freeze({show:(e,t)=>j(e,!1,t),hide:(e,t)=>j(e,!0,t),toggle:(e,t)=>j(e,!e.hidden,t),add_class:(e,t)=>e.classList.add(...t.classes??[]),remove_class:(e,t)=>e.classList.remove(...t.classes??[]),toggle_class:(e,t)=>(t.classes??[]).forEach((n)=>e.classList.toggle(n)),set_attr:(e,t)=>{if(J(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(J(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!J(t.name))return;if(e.hasAttribute(t.name))e.removeAttribute(t.name);else e.setAttribute(t.name,"")},focus:(e)=>e.focus?.(),focus_first:(e)=>Yt(e)?.focus?.(),text:(e,t)=>{let n=String(t.value??"");if(e.textContent!==n)e.textContent=n},dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e)=>Pt(e)?.requestSubmit?.(),paste_into:(e)=>jt(e),persist_state:(e,t)=>Ft(e,t.state),persist_clear:(e)=>Mt(e)});function Pt(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function jt(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((n)=>{if(!n)return;if(e.value=n,typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));e.focus?.()}).catch(()=>{})}function j(e,t,n){if(n?.transition)kt(e,n.transition,()=>e.hidden=t);else e.hidden=t}function J(e){if(!xt(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}var Me=/^#[A-Za-z_][\w-]*$/;function Jt(e){if(typeof e==="string"&&Me.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(e)} — skipped`),!1}function Wt(e,t){let n=e.getAttribute("data-reactive-show-equals");if(n!==null)return t===n;let r=e.getAttribute("data-reactive-show-not");if(r!==null)return t!==r;let i=e.getAttribute("data-reactive-show-in");if(i!==null){try{let s=JSON.parse(i);if(Array.isArray(s))return s.includes(t)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(i)} — skipped`),null}for(let s of Pe){let o=e.getAttribute(`data-reactive-show-${s}`);if(o!==null)return je(s,o,t)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}var Pe=["gte","gt","lte","lt"],Bt=["len_eq","len_gte","len_gt","len_lte","len_lt"];function It(e,t,n){if(!Number.isInteger(t))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(t)} — skipped`),null;let r=[...String(n??"")].length;switch(e){case"len_eq":return r===t;case"len_gte":return r>=t;case"len_gt":return r>t;case"len_lte":return r<=t;case"len_lt":return r<t;default:return null}}function je(e,t,n){let r=Number(t);if(Number.isNaN(r))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(t)} — skipped`),null;let i=n==null?"":String(n).trim(),s=i===""?NaN:Number(i);if(Number.isNaN(s))return!1;switch(e){case"gte":return s>=r;case"gt":return s>r;case"lte":return s<=r;case"lt":return s<r;default:return null}}function Je(e,t){if(!e||typeof e!=="object")return null;if(typeof e.equals==="string")return t===e.equals;if(typeof e.not==="string")return t!==e.not;if(Array.isArray(e.in))return e.in.includes(t);for(let n of Pe)if(n in e)return je(n,e[n],t);for(let n of Bt)if(n in e)return It(n,e[n],t);return null}var me="[data-reactive-show-field], [data-reactive-show]";function Ht(e){try{let t=JSON.parse(e);if(t&&typeof t==="object"&&!Array.isArray(t))return t}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(e)} — skipped`),null}function Vt(e){try{let t=JSON.parse(e);if(Array.isArray(t)&&t.every((n)=>n&&typeof n==="object"&&Array.isArray(n.any)&&Array.isArray(n.ops)))return t}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function se(e,t){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let n=t(e.field)??"";return Je(e,n)===!0}function T(e,t){if(!Array.isArray(e)||e.length===0)return null;return e.some((n)=>Array.isArray(n)&&n.length>0&&n.every((r)=>se(r,t)))}function zt(e){if(!Array.isArray(e)||e.length===0)return null;let t=new Set;for(let n of e){if(!Array.isArray(n))continue;for(let r of n)if(r&&typeof r==="object"&&typeof r.field==="string")t.add(r.field)}return t.size>0?[...t]:null}function Gt(e,t){if(!e||typeof e!=="object")return null;let n=e.any;if(Array.isArray(n)&&(n.length===0||Array.isArray(n[0])))return T(n,t);return Ut(e,t)}function Ut(e,t){let n=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!n)return null;let r=e[n];if(r.length===0)return null;let i=r.map((s)=>se(s,t));return n==="all"?i.every(Boolean):i.some(Boolean)}function pe(e){if(typeof e==="string"&&Me.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(e)} — skipped`),!1}var Kt='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Yt(e){return e.querySelectorAll?.(Kt)?.[0]??null}function We(e){if(Array.isArray(e))return e;if(typeof e!=="string")return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}function x({el:e,kind:t}){if(!e)return"";if(t==="checkbox")return e.checked?"true":"false";if(t==="radio")return e.checked?e.value??"":"";return e.value??""}var Xt=Object.freeze({el:null,kind:""});function Be(e){if(typeof e==="boolean")return e;if(e==null)return!1;let t=String(e);return t!==""&&t!=="0"&&t!=="false"}function Zt(e,t){if(t==="string")return x(e);let n=e.kind==="checkbox";if(t==="boolean")return n?Boolean(e.el.checked):Be(x(e));if(n)return e.el.checked?1:0;let r=Number(x(e));return Number.isFinite(r)?r:0}function Qt(e,t,{el:n,kind:r},i,s){if(r==="checkbox"){let o=Be(s);if(Boolean(n.checked)===o)return null;return n.checked=o,n}if(r==="radio")return en(e,t,i,String(s));if(String(s)===n.value)return null;return n.value=s,n}function en(e,t,n,r){let i=null;for(let s of e.querySelectorAll(`[name="${n}"]`)){if(s.type!=="radio"||!t(s))continue;let o=s.value===r;if(Boolean(s.checked)===o)continue;if(s.checked=o,o)i=s;else i??=s}return i}function tn(e){if(e==null)return null;let t=Array.isArray(e)?e:e.ops;if(Array.isArray(t))return t.length>0?t:null;return console.warn("[phlex-reactive] $ops must be an ops chain or a [[op, args], ...] list — skipped"),null}function N(e,t,n){for(let r of e){if(!Array.isArray(r))continue;let[i,s={}]=r;if(!Object.hasOwn(he,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let o=t(s);if(o.length===0&&n)n(i,s);for(let a of o)he[i](a,s)}}var ve=new WeakMap;function Ie(e){let t=globalThis.document;if(!t)return!0;let n=ve.get(t);if(!n)n=new Set,ve.set(t,n);if(n.has(e))return!0;return n.add(e),!1}function G(e,t){try{return e?.querySelectorAll?.(t)?.length??0}catch{return 0}}function He(e,t,n,r){if(Ie(`${e}|${t}|${n}`))return;console.warn(`[phlex-reactive] ${e} matched zero targets for selector "${t}" (${n})${r}`)}function nn(e,t,n){let r=t.to;if(typeof r!=="string"||r===""||r==="@root")return;let i="";if(n&&!t.global){let s=G(globalThis.document,r);if(s>0)i=` — it matches ${s} element(s) outside the stream's target root; use global: true`}He(`client op "${e}"`,r,n?`scoped to #${n.id||"?"}`:"document-scoped",i)}function rn(e,t){let n=e.to;if(t){if(n==="@root")return[t];if(typeof n!=="string"||n==="")return[];if(e.global)return[...document.querySelectorAll(n)];return[...t.querySelectorAll(n)]}if(typeof n!=="string"||n===""||n==="@root")return[];return[...document.querySelectorAll(n)]}class bn extends Ve{static values={token:String};#re;#T=new Map;#m=new Map;#Fe;#J;#ie;#W=0;#p=new Map;#B=new WeakMap;#N=new Map;#se=new WeakSet;#oe=null;#v;#y;#g;#r;#a;#I;#ae;#H;#V;#s;#b;#ce=!1;#z=0;#ue=!1;#o;#A;#w;#L;#S;#i=null;#E=!1;#t=null;#c;#_;#C;connect(){if(R=!0,this.element.id==="")console.warn("[phlex-reactive] a reactive root has no id; its next-action token can't self-match "+"and may fall back to the first token in the response → a silent HTTP 403 on the NEXT action. "+"Put id: on the SAME element as reactive_attrs — use div(**reactive_root) (emits id + token together), "+"or div(id:, **reactive_attrs). The id: must NOT be on a child. See the README.");if(this.element.getAttribute?.("data-reactive-defer-token"))this.#le(),this.#L=()=>this.#le(),this.element.addEventListener?.("turbo:morph-element",this.#L);if(this.#i=Q(this.element),this.#i)this.#St();if(this.#Me()){if(this.#v=()=>this.#X(),this.element.addEventListener?.("turbo:morph-element",this.#v),this.#X(),this.element.getAttribute?.("data-reactive-warn-unsaved")==="true")this.#ft()}if(this.#ht())this.#r=()=>this.#ke(),this.element.addEventListener?.("input",this.#r),this.element.addEventListener?.("change",this.#r),this.element.addEventListener?.("turbo:morph-element",this.#r),this.#ke();if(this.#mt())this.#a=(e)=>this.#Z(e),this.#I=()=>this.#Z(null),this.element.addEventListener?.("input",this.#a),this.element.addEventListener?.("change",this.#a),this.element.addEventListener?.("turbo:morph-element",this.#I),this.#Z(null);if(this.#D())this.#s=(e)=>{if(e?.type==="input"&&!this.#Lt(e))return;this.#k()},this.element.addEventListener?.("input",this.#s),this.element.addEventListener?.("turbo:morph-element",this.#s),this.#k();if(this.#F())this.#b=()=>this.#te(),this.element.addEventListener?.("turbo:morph-element",this.#b),this.#te();if(this.#Ct())this.#o=(e)=>this.syncNestedJson(e),this.#A=()=>this.#R(),this.element.addEventListener?.("input",this.#o),this.element.addEventListener?.("change",this.#o),this.element.addEventListener?.("turbo:morph-element",this.#A),this.#R();if(this.#Nt())this.#w=()=>this.recompute(),this.element.addEventListener?.("turbo:morph-element",this.#w),this.recompute();if(this.#pt())this.#S=()=>this.#xe(),this.element.addEventListener?.("turbo:morph-element",this.#S),this.#xe()}#Me(){if((this.element.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let e=this.element.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let t of e)if(this.#n(t))return!0;return!1}disconnect(){if(this.#kt(),this.#Ze(),this.#et(),this.#dt(),this.#Tt(),this.#gt(),this.#_t(),this.#Mt(),this.#Pt(),this.#jt(),this.#vt(),this.#L)this.element.removeEventListener?.("turbo:morph-element",this.#L)}#le(){let e=this.element;if(!e?.id)return;let t=e.getAttribute?.("data-reactive-defer-token");if(!t)return;if(e.getAttribute?.("data-reactive-defer-pending")!=="true")return;O(e.id,t)}dispatch(e){let{action:t,params:n,debounce:r,throttle:i,confirm:s,confirmWhen:o,outside:a,window:c,optimistic:u}=e.params;if(!t)return;let l=e.params.busy??this.#Yt(e.params.loading);if(a&&this.element.contains(e.target))return;let h=e.currentTarget??e.target;if(!c&&!this.#It(u,h))e.preventDefault();let d=this.#Y(s,o);if(!d)return this.#ge(h,t,n,r,i,u,l);Promise.resolve().then(()=>D(d,{el:h})).catch(()=>!1).then((p)=>{if(p)this.#ge(h,t,n,r,i,u,l)})}runOps(e){let{ops:t,confirm:n,confirmWhen:r,outside:i,window:s}=e.params,o=e.currentTarget??e.target;if(i&&this.element.contains(e.target))return;if(!s)e.preventDefault();let a=this.#Y(n,r);if(!a)return this.#Re(this.#Oe(t));Promise.resolve().then(()=>D(a,{el:o})).catch(()=>!1).then((c)=>{if(c)this.#Re(this.#Oe(t))})}trackDirty(){this.#X()}recompute(e){if(e&&this.#se.has(e))return;let t=this.#Ve(),n=t.map(([f])=>f),r=this.element.getAttribute?.("data-reactive-scope")||null,i=(f)=>r&&!f.includes("[")?`${r}[${f}]`:f,s=this.#e(),o=new Map,a=(f)=>{let v=o.get(f);if(v)return v;let m=null,g=null,A=null;for(let w of this.element.querySelectorAll(`[name="${i(f)}"]`)){if(!s(w))continue;let k=w.type;if(k==="checkbox"||k==="radio"&&w.checked){A={el:w,kind:k};break}if(k==="radio")m??=w;else g??=w}if(!A)if(m)A={el:m,kind:"radio"};else A=g?{el:g,kind:""}:Xt;return o.set(f,A),A};for(let f of n)this.#ve(f,x(a(f)));let c=this.element.getAttribute("data-reactive-compute-reducer-param"),u=c?ze(c):null;if(!u){this.#ye({},a);return}let l=this.#He("data-reactive-compute-outputs-param"),h={};for(let[f,v]of t)h[f]=Zt(a(f),v);let d=u(h,{changed:this.#ze(e,n,r)})||{},p=tn(d.$ops),S=[];for(let f of l){if(f==="$ops"||!(f in d))continue;let v=a(f);if(!v.el)continue;let m=Qt(this.element,s,v,i(f),d[f]);if(m)S.push(m)}for(let f of Object.keys(d)){if(f==="$ops")continue;let v=d[f];if(v===void 0||v===null)continue;this.#ve(f,v)}this.#ye(d,a);for(let f of S){let v=new Event("input",{bubbles:!0});this.#se.add(v),f.dispatchEvent(v)}this.#Pe(p,Boolean(e))}#Pe(e,t){let n=e===null?null:JSON.stringify(e),r=n!==null&&n!==this.#oe&&t;if(this.#oe=n,!r)return;N(e,(i)=>this.#j(i.to==null?{...i,to:"@root"}:i),(i,s)=>this.#P(`client op "${i}"`,s))}listnavNext(e){this.#fe(e,1)}listnavPrev(e){this.#fe(e,-1)}listnavPick(e){let t=this.#O(e),n=t.findIndex((r)=>r.hasAttribute("data-reactive-highlighted"));if(n<0)return;e.preventDefault(),t[n].click()}listnavClose(e){for(let t of this.#O(e))t.removeAttribute("data-reactive-highlighted")}#fe(e,t){let n=this.#O(e);if(!n.length)return;e.preventDefault();let r=n.findIndex((o)=>o.hasAttribute("data-reactive-highlighted")),i=r<0?t>0?0:n.length-1:(r+t+n.length)%n.length;for(let o of n)o.removeAttribute("data-reactive-highlighted");let s=n[i];s.setAttribute("data-reactive-highlighted","true"),s.scrollIntoView?.({block:"nearest"})}#O(e){let n=(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!n)return[];let r=this.#e();return Array.from(this.element.querySelectorAll(n)).filter((i)=>!i.hidden&&r(i))}tagsAdd(e){if(!this.#F())return;if(e?.defaultPrevented)return;if(this.#O(e).some((r)=>r.hasAttribute?.("data-reactive-highlighted")))return;e?.preventDefault?.();let t=e?.currentTarget??e?.target;if(!t)return;if(!this.#Le(String(t.value??"").split(",")))return;if(t.value="",this.#D())this.#k()}tagsPick(e){if(!this.#F())return;e?.preventDefault?.();let n=(e?.currentTarget??e?.target)?.getAttribute?.("data-reactive-tag-param");if(!n)return;if(!this.#Le([n]))return;let r=this.#Ot();if(!r)return;r.value="",this.#k(),r.focus?.()}tagsRemove(e){if(!this.#F())return;e?.preventDefault?.();let n=(e?.currentTarget??e?.target)?.getAttribute?.("data-reactive-tag-param");if(!n)return;let r=this.#Q();if(!r)return;let i=this.#ee(r),s=i.filter((o)=>o.toLowerCase()!==n.toLowerCase());if(s.length===i.length)return;this.#_e(r,s)}nestedAdd(e){e?.preventDefault?.();let t=e?.currentTarget??e?.target,n=t?.getAttribute?.("data-reactive-association-param");if(!n)return;if(typeof this.element?.querySelectorAll!=="function")return;let r=this.#e(),i=[...this.element.querySelectorAll(`[data-reactive-nested-list="${n}"]`)].find(r),o=[...this.element.querySelectorAll(`[data-reactive-nested-template="${n}"]`)].find(r)?.content?.firstElementChild;if(!i||!o){this.#Ft(n);return}let a=o.cloneNode(!0);this.#Dt(a,this.#qt()),i.appendChild(a);let c=t?.getAttribute?.("data-reactive-nested-from-param"),u=t?.getAttribute?.("data-reactive-nested-clear-param")==="true",l=this.#je(a,c,u);if(c)l?.focus?.();else[...a.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(i.getAttribute?.("data-reactive-nested-json")===n)this.#he(n)}#je(e,t,n){if(!t)return null;let r;try{r=JSON.parse(t)}catch{return null}if(!r||typeof r!=="object")return null;let i=this.#e(),s=[...e.querySelectorAll?.("input, select, textarea")??[]],o=[];for(let[a,c]of Object.entries(r)){let u=[...this.element.querySelectorAll?.(c)??[]].find(i);if(!u)continue;let l=s.find((h)=>this.#pe(h.getAttribute?.("name"))===a);if(!l)continue;this.#Je(l,u),o.push(u)}if(n)for(let a of o)this.#We(a);return o[0]??null}#Je(e,t){if(e.type==="checkbox")e.checked=t.type==="checkbox"?!!t.checked:this.#G(t)!=="";else e.value=this.#G(t);if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}#We(e){if(e.type==="checkbox")e.checked=!1;else e.value="";if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}nestedRemove(e){e?.preventDefault?.();let t=e?.currentTarget??e?.target,n=t?.closest?.("[data-reactive-nested-row]");if(!n)return;if(n.closest?.('[data-controller~="reactive"]')!==this.element)return;let r=t?.getAttribute?.("data-reactive-confirm-param"),i=t?.getAttribute?.("data-reactive-confirm-when-param"),s=this.#Y(r,i);if(!s)return this.#de(n);let o=this.#me(n),a=this.#Be(s,o);return Promise.resolve().then(()=>D(a,{el:t,row:n,fields:o})).catch(()=>!1).then((c)=>{if(c)this.#de(n)})}#Be(e,t){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(n,r)=>Object.prototype.hasOwnProperty.call(t,r)?t[r]:n)}#de(e){let t=[...e.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t){if(t.value="1",typeof t.dispatchEvent==="function")t.dispatchEvent(new Event("input",{bubbles:!0}));e.hidden=!0}else e.parentNode?.removeChild?.(e);this.#R()}syncNestedJson(e){let t=e?.target;if(!t||!this.#n(t))return;this.#R()}#R(){if(typeof this.element?.querySelectorAll!=="function")return;let e=this.#e();for(let t of[...this.element.querySelectorAll("[data-reactive-nested-json]")].filter(e))this.#he(t.getAttribute("data-reactive-nested-json"))}#he(e){let t=this.#e(),n=[...this.element.querySelectorAll(`[data-reactive-nested-list="${e}"]`)].find(t);if(!n)return;let r=this.#Ie(n);if(!r)return;let i=[];for(let o of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(o)||o.hidden)continue;i.push(this.#me(o))}let s=JSON.stringify(i);if(r.value===s)return;if(r.value=s,typeof r.dispatchEvent==="function")r.dispatchEvent(new Event("input",{bubbles:!0}))}#Ie(e){let t=e.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let n=this.#e();return[...this.element.querySelectorAll(t)].find(n)??null}#me(e){let t={};for(let n of[...e.querySelectorAll?.("input, select, textarea")??[]]){let r=this.#pe(n.getAttribute?.("name"));if(r===null||r==="_destroy")continue;t[r]=this.#G(n)}return t}#pe(e){if(!e)return null;let t=e.match(/\[([^\][]+)\]$/);return t?t[1]:e}#G(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}#He(e){let t=this.element.getAttribute(e);if(!t)return[];try{let n=JSON.parse(t);return Array.isArray(n)?n:[]}catch{return[]}}#Ve(){let e=this.element.getAttribute("data-reactive-compute-inputs-param");if(!e)return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map((n)=>[n,"number"]);if(t&&typeof t==="object")return Object.entries(t);return[]}catch{return[]}}#ze(e,t,n){let r=e?.target;if(!r?.name||typeof r.closest!=="function")return null;let i=this.#Ge(r.name,n);if(!t.includes(i))return null;return this.#n(r)?i:null}#Ge(e,t){if(!t)return e;let n=`${t}[`;return e.startsWith(n)&&e.endsWith("]")?e.slice(n.length,-1):e}#ve(e,t){let n=String(t);for(let r of this.#Ue(e)){if(r.textContent===n)continue;r.textContent=n}}#Ue(e){let t=this.element.querySelectorAll(`[data-reactive-text="${e}"]`);return Array.from(t).filter((n)=>this.#n(n))}#ye(e,t){let n=this.#Ke();for(let[r,i]of Object.entries(n)){let s=r in e?null:t(r),o=r in e?e[r]:s.el?x(s):void 0;if(o===void 0||o===null)continue;let a=String(o);for(let c of Array.isArray(i)?i:[i]){if(!Jt(c))continue;for(let u of document.querySelectorAll(c)){if(u.textContent===a)continue;u.textContent=a}}}}#Ke(){let e=this.element.getAttribute("data-reactive-compute-mirror-param");if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return{}}}#ge(e,t,n,r,i,s,o){if(this.#x("reactive:before-dispatch",{action:t,params:this.#Ce(n),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(r)||0;if(c>0)return this.#Xe(e,c,t,n,s,o);let u=Number(i)||0;if(u>0)return this.#Qe(e,u,t,n,s,o);return this.#$(t,n,s,e,o)}#$(e,t,n,r,i){let s=this.#Ht(n,r),o=this.#Vt(e,r,i),a=this.#K()?this.#Ye(n,r):null;return this.queue=(this.queue??Promise.resolve()).then(()=>this.#ot(e,t,s,o,a)),this.queue}#Ye(e,t){if(!e?.hide)return null;let n=this.#qe(e,t);if(!n.length)return null;return()=>{let r=n.filter((i)=>i.isConnected&&!i.hidden);if(!r.length)return;console.warn("[phlex-reactive] optimistic: { hide: true } was undone by the reply's re-render — "+"the element is visible again. For an instant delete, return reply.remove so the server removes it; otherwise the hide only flashes.",r)}}#Xe(e,t,n,r,i,s){this.#U(e);let o=()=>{this.#U(e),this.#$(n,r,i,e,s)},a=setTimeout(o,t);e?.addEventListener?.("blur",o,{once:!0}),this.#T.set(e,{timer:a,flush:o})}#U(e){let t=this.#T.get(e);if(!t)return;clearTimeout(t.timer),e?.removeEventListener?.("blur",t.flush),this.#T.delete(e)}#Ze(){for(let e of[...this.#T.keys()])this.#U(e)}#Qe(e,t,n,r,i,s){let o=this.#m.get(e)??new Map;if(o.has(n))return;let a=setTimeout(()=>{if(o.delete(n),o.size===0)this.#m.delete(e)},t);return o.set(n,a),this.#m.set(e,o),this.#$(n,r,i,e,s)}#et(){for(let e of this.#m.values())for(let t of e.values())clearTimeout(t);this.#m.clear()}#x(e,t,{cancelable:n=!1}={}){let r=new CustomEvent(e,{bubbles:!0,composed:!0,cancelable:n,detail:t});return(this.element.isConnected?this.element:document).dispatchEvent(r),r}#u(e,t,n,r){let i=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#$(e,t)};this.#x("reactive:error",{action:e,params:n,...r,retry:i})}#l(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#tt(){this.element?.removeAttribute?.("data-reactive-error")}#nt(){let e=document.querySelector("[data-reactive-error-flash]");if(!e?.content)return;let t=e.getAttribute("data-reactive-error-flash")||"flash",n=document.getElementById(t);if(!n)return;n.appendChild(e.content.cloneNode(!0))}#rt(){if(typeof sessionStorage>"u")return Promise.resolve();let e=Number(sessionStorage.getItem(Y));if(!Number.isFinite(e)||e<=0)return Promise.resolve();if(!_)_=!0,console.warn(`[phlex-reactive] latency simulator ACTIVE — every action is delayed by ${e}ms. Call PhlexReactive.disableLatencySim() (or clear sessionStorage) to turn it off.`);return new Promise((t)=>setTimeout(t,e))}#K(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#be(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}#it(e){if(!e)return[];let t=[],n=/<turbo-stream\b([^>]*)>/g,r;while((r=n.exec(e))!==null){let i=r[1],s=i.match(/\baction="([^"]*)"/)?.[1]??"?",o=i.match(/\btarget="([^"]*)"/)?.[1];t.push(o?`${s} → #${o}`:s)}return t}#st(e){let{action:t,status:n,ms:r}=e,s=`reactive ${this.element?.id?`#${this.element.id} `:""}${t} → ${n??"—"} (${Math.round(r)}ms)`;if(console.groupCollapsed(s),console.log(`params: [${e.paramNames.join(", ")}] + collected: [${e.fieldNames.join(", ")}]`),console.log(`encoding: ${e.encoding}`),e.streams.length)console.log(`streams: ${e.streams.join(" ")}`);console.log(`token: ${e.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}async#ot(e,t,n,r,i){let{fields:s,files:o}=this.#Se(),a=this.#Ce(t),c={...s,...a},u=this.#f,l=o.length>0,h=l?this.#Jt(u,e,c,o):JSON.stringify({token:u,act:e,params:c}),d=this.#K()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(s),encoding:l?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#be()}:null;await this.#rt();try{if(navigator.onLine===!1){this.#d(n),this.#l("offline"),this.#u(e,t,c,{kind:"offline"});return}let p;try{let m={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#Qt()};if(!l)m["Content-Type"]="application/json";let g=this.#en();if(g)m["X-Pgbus-Connection"]=g;p=await fetch(this.#Xt(),{method:"POST",headers:m,body:h,credentials:"same-origin",signal:AbortSignal.timeout(this.#Zt())})}catch(m){if(console.error("[phlex-reactive] action error",m),this.#d(n),m?.name==="TimeoutError"||m?.name==="AbortError"){this.#l("timeout"),this.#u(e,t,c,{kind:"timeout"});return}this.#nt(),this.#l("network"),this.#u(e,t,c,{kind:"network"});return}if(d)d.status=p.status;if(p.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#d(n),this.#l("redirected"),this.#u(e,t,c,{kind:"redirected",status:p.status});return}if(!p.ok){let m=await p.text();if(console.error(`[phlex-reactive] action failed: HTTP ${p.status}`,m),this.#d(n),(p.headers.get("Content-Type")||"").includes("turbo-stream")){let g=this.#we(m);if(this.#f=g??this.#f,d)this.#Ae(d,m,g);window.Turbo.renderStreamMessage(m)}this.#l("http"),this.#u(e,t,c,{kind:"http",status:p.status,body:m});return}let S=p.headers.get("Content-Type")||"";if(!S.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${S}" — no update applied`),this.#d(n),this.#l("content-type"),this.#u(e,t,c,{kind:"content-type",status:p.status});return}let f=await p.text(),v=this.#we(f);if(this.#f=v??this.#f,d)this.#Ae(d,f,v);if(window.Turbo.renderStreamMessage(f),i)queueMicrotask(i);this.#tt(),this.#x("reactive:applied",{action:e,params:c,html:f})}catch(p){console.error("[phlex-reactive] action error",p),this.#d(n),this.#x("reactive:error",{action:e,params:c,kind:"apply"})}finally{if(r?.(),d)this.#st({...d,ms:this.#be()-d.started})}}#Ae(e,t,n){e.streams=this.#it(t),e.tokenRefreshed=n!=null}get#f(){return this.#re??this.tokenValue}set#f(e){this.#re=e}#we(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:n,self:r}=this.#at(t),i=e.match(n);if(i)return i[1];let s=e.match(r);if(s)return s[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#at(e){let t=this.#ie;if(t&&t.id===e)return t;let n=wt(e);return this.#ie={id:e,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${n}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${n}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#n(e){return e.closest('[data-controller~="reactive"]')===this.element}#e(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#n(t)}#Y(e,t){if(e)return e;if(!t)return null;let n=t;if(typeof t==="string")try{n=JSON.parse(t)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(t)} — skipped`),null}if(!n||typeof n!=="object")return null;let{fields:r}=this.#Se(),i=(o)=>r[o],s;if(typeof n.predicate==="string"){let o=Ge(n.predicate);if(!o)return console.warn(`[phlex-reactive] confirm predicate "${n.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;s=!!o(r)}else s=T(n.groups?.any,i)===!0;return s?n.message:null}#Se(){let e={},t=[],n=this.#e(),r=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((a)=>{if(!n(a))return;if(a.type==="file")for(let c of a.files??[])t.push({name:a.name,file:c,multiple:a.multiple});else r.push(a)});let i=[];this.element.querySelectorAll(`[name]${Ce}`).forEach((a)=>{if(n(a))i.push(a)});let s=this.#ct(r),o=this.#ut(r);for(let a of r)if(s.has(a.name)){let c=e[a.name]??(e[a.name]=[]);if(a.type==="checkbox"||a.type==="radio"){if(a.checked)c.push(a.value)}else if(a.type==="hidden"){if(!o.has(a.name))c.push(a.value)}else if(a.multiple&&a.options){for(let u of a.options)if(u.selected)c.push(u.value)}else c.push(a.value)}else if(a.type==="checkbox")e[a.name]=a.checked;else if(a.type==="radio"){if(a.checked)e[a.name]=a.value}else e[a.name]=a.value;return i.forEach((a)=>{let c=a.getAttribute("name");if(!c)return;let u=a.value??a.textContent??a.innerHTML??"",l=e[c];if(String(c).endsWith("[]")&&!Ot(a))return;if(String(c).endsWith("[]")&&(l===void 0||Array.isArray(l))){(Array.isArray(l)?l:e[c]=[]).push(u);return}if(l==null||l==="")e[c]=u}),{fields:e,files:t}}#ct(e){let t=new Set;for(let n of e){if(n.type==="radio")continue;if(String(n.name).endsWith("[]"))t.add(n.name)}return t}#ut(e){let t=new Set;for(let n of e)if(n.type==="checkbox")t.add(n.name);return t}#X(){if(typeof this.element?.querySelectorAll!=="function")return;let e=0;if(this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((t)=>{if(!this.#n(t))return;if(t.type==="file")return;if(this.#lt(t))t.setAttribute("data-reactive-dirty","true"),e++;else t.removeAttribute("data-reactive-dirty")}),e>0)this.element.setAttribute("data-reactive-dirty",String(e));else this.element.removeAttribute("data-reactive-dirty")}#lt(e){if(e.type==="checkbox"||e.type==="radio")return e.checked!==e.defaultChecked;if(e.tag==="select"||e.options)return Array.from(e.options??[]).some((t)=>t.selected!==t.defaultSelected);return e.value!==e.defaultValue}#Ee(){let e=this.element.getAttribute?.("data-reactive-dirty"),t=Number(e);return Number.isFinite(t)&&t>0?t:0}#ft(){if(typeof window>"u"||typeof window.addEventListener!=="function")return;this.#y=(e)=>{if(this.#Ee()===0)return;return e.preventDefault(),e.returnValue="You have unsaved changes.",e.returnValue},this.#g=(e)=>{if(this.#Ee()===0)return;if(!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))e.preventDefault?.()},window.addEventListener("beforeunload",this.#y),window.addEventListener("turbo:before-visit",this.#g)}#dt(){if(this.#v)this.element.removeEventListener?.("turbo:morph-element",this.#v),this.#v=void 0;if(typeof window<"u"&&typeof window.removeEventListener==="function"){if(this.#y)window.removeEventListener("beforeunload",this.#y);if(this.#g)window.removeEventListener("turbo:before-visit",this.#g)}this.#y=void 0,this.#g=void 0}#ht(){if(this.element.getAttribute?.("data-reactive-show-targets"))return!0;let e=this.element.querySelectorAll?.(me)??[];for(let t of e)if(this.#n(t))return!0;return!1}#mt(){return!!this.element.getAttribute?.("data-reactive-on-complete")}#pt(){if(this.element.getAttribute?.("data-reactive-clipboard"))return!0;let e=this.element.querySelectorAll?.("[data-reactive-clipboard]")??[];for(let t of e)if(this.#n(t))return!0;return!1}#xe(){let e=typeof globalThis.navigator?.clipboard?.readText==="function";if(this.element.getAttribute?.("data-reactive-clipboard"))this.element.hidden=!e;for(let t of this.element.querySelectorAll?.("[data-reactive-clipboard]")??[])if(this.#n(t))t.hidden=!e}#vt(){if(!this.#S)return;this.element.removeEventListener?.("turbo:morph-element",this.#S),this.#S=void 0}#yt(){let e=this.element.getAttribute?.("data-reactive-on-complete")??null;if(e!==this.#ae)this.#ae=e,this.#H=e==null?[]:Vt(e),this.#V=this.#H.map(()=>!1);return this.#H}#Z(e){let t=this.#yt();if(!t.length)return;let n=this.#e(),r=this.element.getAttribute?.("data-reactive-scope")||null,i=new Map,s=(o)=>{if(!i.has(o))i.set(o,this.#Ne(o,n,r));return i.get(o)};t.forEach((o,a)=>{let c=T(o.any,s);if(c===null)return;let u=c&&!this.#V[a]&&Boolean(e);if(this.#V[a]=c,u)N(o.ops,(l)=>this.#j(l.to==null?{...l,to:"@root"}:l),(l,h)=>this.#P(`client op "${l}"`,h))})}#gt(){if(!this.#a)return;this.element.removeEventListener?.("input",this.#a),this.element.removeEventListener?.("change",this.#a),this.element.removeEventListener?.("turbo:morph-element",this.#I)}#ke(){if(typeof this.element?.querySelectorAll!=="function")return;let e=this.#e(),t=this.element.getAttribute?.("data-reactive-scope")||null,n=new Map,r=(i)=>{if(!n.has(i))n.set(i,this.#Ne(i,e,t));return n.get(i)};for(let i of this.element.querySelectorAll(me)){if(!e(i))continue;let s=i.getAttribute("data-reactive-show");if(s!==null){let u=Gt(Ht(s),r);if(u!==null)this.#Te(i,u,e,t);continue}let o=i.getAttribute("data-reactive-show-field");if(!o)continue;let a=r(o);if(a===null)continue;let c=Wt(i,a);if(c===null)continue;this.#Te(i,c,e,t)}this.#bt(r)}#Te(e,t,n,r){if(e.hidden=!t,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let i of e.querySelectorAll("input[name], select[name], textarea[name]"))if(n(i))i.disabled=!t;if(e.name&&n(e))e.disabled=!t}#bt(e){let t=this.#wt();for(let[n,r]of Object.entries(t)){if(n.startsWith("#")){this.#At(n,r,e);continue}if(!r||typeof r!=="object"||Array.isArray(r))continue;let i=e(n);if(i===null)continue;let s=()=>i;for(let[o,a]of Object.entries(r)){if(!pe(o))continue;let c;if(Array.isArray(a)){if(a.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${o} — skipped`);continue}c=a.every((u)=>se(u,s))}else{let u=Je(a,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${o} — skipped`);continue}c=u}for(let u of document.querySelectorAll(o))u.hidden=!c}}}#At(e,t,n){if(!pe(e))return;let r=t&&typeof t==="object"&&!Array.isArray(t)?t.any:null,i=zt(r);if(i===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(i.every((o)=>n(o)===null))return;let s=T(r,n);if(s===null)return;for(let o of document.querySelectorAll(e))o.hidden=!s}#wt(){let e=this.element.getAttribute?.("data-reactive-show-targets");if(!e)return{};try{let t=JSON.parse(e);if(t&&typeof t==="object"&&!Array.isArray(t))return t}catch{}return console.warn("[phlex-reactive] malformed data-reactive-show-targets — ignored. "+"Did two reactive_show_targets calls collide on one root? Declare every field in ONE call: reactive_show_targets(mode: { ... }, kind: { ... })"),{}}#Ne(e,t,n){let r=n&&!e.includes("[")?`${n}[${e}]`:e,i=!1,s=null;for(let o of this.element.querySelectorAll(`[name="${r}"]`)){if(!t(o))continue;if(o.type==="checkbox")return o.checked?"true":"false";if(o.type==="radio"){if(o.checked)return o.value??"";i=!0;continue}s??=o}if(s)return s.value??"";return i?"":null}#St(){let e=this.#i;this.#E=!1;let t=z(this.element,e);if(t){if(qt(this.element,e,t.fields),t.state)this.element.setAttribute?.(Z,JSON.stringify(t.state));this.#x("reactive:persist-restored",{key:e.key,fields:t.fields,state:t.state??{}})}this.#E=!0,this.#c=()=>this.#Et(),this.#_=()=>this.#q(),this.#C=(n)=>this.#xt(n),this.element.addEventListener?.("input",this.#c),this.element.addEventListener?.("change",this.#_);for(let n of ue)this.element.addEventListener?.(n,this.#c);document.addEventListener?.("turbo:submit-end",this.#C)}#Et(){if(!this.#E)return;let e=Number(this.#i?.debounce)||0;if(e<=0)return this.#q();if(this.#t!==null)clearTimeout(this.#t);this.#t=setTimeout(()=>{this.#t=null,this.#q()},e)}#q(){if(!this.#E||!this.#i)return;if(this.#t!==null)clearTimeout(this.#t),this.#t=null;let e=this.#i,t=z(this.element,e);Re(this.element,e,{fields:De(this.element,e),state:t?.state??null})}#xt(e){if(!e?.detail?.success)return;let t=e.target;if(t?.tagName!=="FORM"||typeof t.contains!=="function")return;if(!t.contains(this.element))return;if(this.#t!==null)clearTimeout(this.#t),this.#t=null;re(this.element,this.#i)}#kt(){if(!this.#i)return;if(this.#t!==null)this.#q();this.element.removeEventListener?.("input",this.#c),this.element.removeEventListener?.("change",this.#_);for(let e of ue)this.element.removeEventListener?.(e,this.#c);document.removeEventListener?.("turbo:submit-end",this.#C),this.#c=this.#_=this.#C=void 0,this.#i=null,this.#E=!1}#Tt(){if(!this.#r)return;this.element.removeEventListener?.("input",this.#r),this.element.removeEventListener?.("change",this.#r),this.element.removeEventListener?.("turbo:morph-element",this.#r),this.#r=void 0}#D(){return!!(this.element.getAttribute?.("data-reactive-filter-input")&&this.element.getAttribute?.("data-reactive-filter-option"))}#Nt(){return this.element.getAttribute?.("data-reactive-compute-seed")==="true"}#Lt(e){let t=this.element.getAttribute("data-reactive-filter-input");return!!t&&typeof e.target?.matches==="function"&&e.target.matches(t)}#k(){if(typeof this.element?.querySelectorAll!=="function")return;let e=this.element.getAttribute("data-reactive-filter-input"),t=this.element.getAttribute("data-reactive-filter-option");if(!e||!t)return;let n=this.#e(),r=[...this.element.querySelectorAll(e)].find(n);if(!r)return;let i=(r.value??"").trim().toLowerCase(),s=0;for(let c of this.element.querySelectorAll(t)){if(!n(c))continue;let u=(c.getAttribute("data-reactive-filter-text")??c.textContent??"").toLowerCase(),l=c.hasAttribute?.("data-reactive-tags-selected")||i!==""&&!u.includes(i);if(c.hidden=l,l)c.removeAttribute("data-reactive-highlighted");else s++}let o=this.element.getAttribute("data-reactive-filter-group");if(o)for(let c of this.element.querySelectorAll(o)){if(!n(c))continue;let u=[...c.querySelectorAll(t)].filter(n);if(u.length===0)continue;c.hidden=u.every((l)=>l.hidden)}let a=this.element.getAttribute("data-reactive-filter-empty");if(a){for(let c of this.element.querySelectorAll(a))if(n(c))c.hidden=s>0}}#_t(){if(!this.#s)return;this.element.removeEventListener?.("input",this.#s),this.element.removeEventListener?.("turbo:morph-element",this.#s),this.#s=void 0}#F(){return!!this.element.getAttribute?.("data-reactive-tags-field")}#Ct(){if(typeof this.element?.querySelector!=="function")return!1;return!!this.element.querySelector("[data-reactive-nested-json]")}#Q(){if(typeof this.element?.querySelectorAll!=="function")return null;let e=this.element.getAttribute("data-reactive-tags-field");if(!e)return null;let t=this.#e();return[...this.element.querySelectorAll(e)].find(t)??null}#ee(e){let t=new Set,n=[];for(let r of String(e.value??"").split(",")){let i=r.trim();if(i===""||t.has(i.toLowerCase()))continue;t.add(i.toLowerCase()),n.push(i)}return n}#Le(e){let t=this.#Q();if(!t)return!1;let n=this.#ee(t),r=new Set(n.map((s)=>s.toLowerCase())),i=!1;for(let s of e){let o=String(s??"").trim();if(o===""||r.has(o.toLowerCase()))continue;r.add(o.toLowerCase()),n.push(o),i=!0}if(i)this.#_e(t,n);return i}#_e(e,t){if(e.value=t.join(","),typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));this.#te()}#Ot(){if(typeof this.element?.querySelectorAll!=="function")return null;let e=this.element.getAttribute("data-reactive-filter-input");if(!e)return null;let t=this.#e();return[...this.element.querySelectorAll(e)].find(t)??null}#te(){let e=this.#Q();if(!e)return;let t=this.#ee(e),n=this.#e();this.#Rt(t,n),this.#$t(t,n)}#Rt(e,t){let n=[...this.element.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!n)return;let i=[...this.element.querySelectorAll("[data-reactive-tags-template]")].find(t)?.content?.firstElementChild;if(!i){if(!this.#ce)console.warn("[phlex-reactive] reactive_tags: no chip <template data-reactive-tags-template> found in this root — "+"chips will not render (the hidden field still updates). Add a template with a [data-reactive-tag-text] node and a reactive_tags_remove button."),this.#ce=!0;return}while(n.firstChild)n.removeChild(n.firstChild);for(let s of e){let o=i.cloneNode(!0);o.setAttribute?.("data-reactive-tag",s);let a=o.matches?.("[data-reactive-tag-text]")?o:(o.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(a)a.textContent=s;let c=[...o.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(o.matches?.('[data-action*="reactive#tagsRemove"]'))c.push(o);for(let u of c)u.setAttribute?.("data-reactive-tag-param",s);n.appendChild(o)}}#$t(e,t){let n=new Set(e.map((r)=>r.toLowerCase()));for(let r of this.element.querySelectorAll("[role=option]")){if(!t(r))continue;let i=r.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))r.setAttribute("data-reactive-tags-selected","true"),r.hidden=!0,r.removeAttribute?.("data-reactive-highlighted");else if(r.hasAttribute?.("data-reactive-tags-selected")){if(r.removeAttribute("data-reactive-tags-selected"),!this.#D())r.hidden=!1}}if(this.#D())this.#k()}#qt(){return this.#z=Math.max(this.#z+1,Date.now()),this.#z}#Dt(e,t){let n=[e,...e.querySelectorAll?.("*")??[]];for(let r of n)for(let i of["name","id","for"]){let s=r.getAttribute?.(i);if(s&&s.includes("NEW_ROW"))r.setAttribute?.(i,s.replaceAll("NEW_ROW",String(t)))}}#Ft(e){if(this.#ue)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${e}"] container + <template data-reactive-nested-template="${e}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),this.#ue=!0}#Mt(){if(!this.#b)return;this.element.removeEventListener?.("turbo:morph-element",this.#b),this.#b=void 0}#Pt(){if(this.#o)this.element.removeEventListener?.("input",this.#o),this.element.removeEventListener?.("change",this.#o),this.#o=void 0;if(this.#A)this.element.removeEventListener?.("turbo:morph-element",this.#A),this.#A=void 0}#jt(){if(!this.#w)return;this.element.removeEventListener?.("turbo:morph-element",this.#w),this.#w=void 0}#Jt(e,t,n,r){let i=new FormData;i.append("token",e),i.append("act",t);let s=[];for(let[a,c]of Object.entries(n))if(Array.isArray(c)&&String(a).endsWith("[]"))if(c.length===0)s.push(String(a).slice(0,-2));else{let u=`${this.#M(a)}[]`;for(let l of c)i.append(u,String(l))}else this.#ne(i,this.#M(a),c);for(let a of s)i.append("empty_groups[]",a);let o=this.#Wt(r);for(let{name:a,file:c,multiple:u}of r){let h=u||o.has(a)?`${this.#M(a)}[]`:this.#M(a);i.append(h,c,c.name)}return i}#M(e){let t=String(e),n=t.indexOf("[");if(n===-1)return`params[${t}]`;return`params${[t.slice(0,n),...t.slice(n).match(/[^\[\]]+/g)??[]].map((i)=>`[${i}]`).join("")}`}#ne(e,t,n){if(n==null)e.append(t,"");else if(Array.isArray(n))n.forEach((r,i)=>this.#ne(e,`${t}[${i}]`,r));else if(typeof n==="object")for(let[r,i]of Object.entries(n))this.#ne(e,`${t}[${r}]`,i);else e.append(t,String(n))}#Wt(e){let t=new Map;for(let{name:n}of e)t.set(n,(t.get(n)??0)+1);return new Set([...t].filter(([,n])=>n>1).map(([n])=>n))}#Ce(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Oe(e){return We(e)}#Re(e){N(e,(t)=>this.#j(t),(t,n)=>this.#P(`client op "${t}"`,n))}#Bt(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#K()}#P(e,t){if(!this.#Bt())return;let n=t.to;if(typeof n!=="string"||n===""||n==="@root")return;let r="";if(!t.global)if(this.element?.matches?.(n))r=" — the selector matches this component's own root, which root-scoped resolution never includes; use to: :root";else if(G(this.element,n)>0)r=" — it matches only inside a nested reactive root (excluded by ownership scoping); use global: true";else{let i=G(globalThis.document,n);if(i>0)r=` — it matches ${i} element(s) outside this scope; use global: true`}He(e,n,`scoped to #${this.element?.id||"?"}`,r)}#j(e){let t=e.to;if(t==="@root")return[this.element];if(typeof t!=="string"||t==="")return[];if(e.global)return[...document.querySelectorAll(t)];return[...this.element.querySelectorAll(t)].filter((n)=>this.#n(n))}#It(e,t){if(e?.checked!=="keep")return!1;let n=t?.type;return n==="checkbox"||n==="radio"}#Ht(e,t){if(!e)return null;let n=this.#$e(e,t,!0);return n.length?n:null}#d(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Vt(e,t,n){this.#Gt(e,t);let r=n?this.#$e(n,t,!1):[];Te();let i=!1;return()=>{if(i)return;i=!0,this.#Ut(e,t),Ne();for(let s of r)s()}}#$e(e,t,n){let r=[];for(let i of this.#qe(e,t)){if(e.add_class){let s=e.add_class.filter((o)=>!i.classList.contains(o));if(i.classList.add(...s),s.length)r.push(()=>i.classList.remove(...s))}if(e.remove_class){let s=e.remove_class.filter((o)=>i.classList.contains(o));if(i.classList.remove(...s),s.length)r.push(()=>i.classList.add(...s))}if(e.toggle_class)e.toggle_class.forEach((s)=>i.classList.toggle(s)),r.push(()=>e.toggle_class.forEach((s)=>i.classList.toggle(s)));if(e.hide)i.hidden=!0,r.push(()=>i.hidden=!1);if(e.show)i.hidden=!1,r.push(()=>i.hidden=!0)}if(t&&(e.disable||e.text!=null))r.push(this.#zt(e,t));if(n&&e.checked==="keep"&&t&&"checked"in t){let i=t.checked;r.push(()=>t.checked=!i)}return r}#qe(e,t){if(e.to==null)return t?[t]:[];let n=this.#j({to:e.to});if(n.length===0)this.#P("busy/optimistic hint",{to:e.to});return n}#zt(e,t){let n=this.#N.get(t);if(n)n.count++;else this.#N.set(t,{count:1,disabled:t.disabled,html:t.innerHTML,hadText:e.text!=null,swappedTo:e.text});if(e.disable)t.disabled=!0;if(e.text!=null)t.innerHTML=e.text;return()=>this.#Kt(t,e)}#Gt(e,t){if(this.#h(t,e,1),this.#h(this.element,e,1),this.#p.set(e,(this.#p.get(e)??0)+1),this.#W++===0)this.element.setAttribute("aria-busy","true");for(let n of this.#De(e))this.#h(n,e,1)}#Ut(e,t){this.#h(t,e,-1),this.#h(this.element,e,-1);let n=(this.#p.get(e)??1)-1;if(n<=0)this.#p.delete(e);else this.#p.set(e,n);if(--this.#W<=0)this.#W=0,this.element.removeAttribute("aria-busy");for(let r of this.#De(e))this.#h(r,e,-1)}#h(e,t,n){if(!e||typeof e.getAttribute!=="function")return;let r=this.#B.get(e)??new Map,i=(r.get(t)??0)+n;if(i<=0)r.delete(t);else r.set(t,i);if(r.size===0){this.#B.delete(e),e.removeAttribute("data-reactive-busy");return}this.#B.set(e,r),e.setAttribute("data-reactive-busy",[...r.keys()].join(" "))}#De(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((n)=>n.getAttribute("data-reactive-busy-on")===e&&this.#n(n))}#Kt(e,t){let n=this.#N.get(e);if(!n)return;if(--n.count>0)return;if(this.#N.delete(e),!e.isConnected)return;if(t.disable)e.disabled=n.disabled;if(n.hadText&&e.innerHTML===n.swappedTo)e.innerHTML=n.html}#Yt(e){if(!e||typeof e!=="object")return null;let{class:t,...n}=e;return t==null?e:{...n,add_class:t}}#Xt(){return this.#Fe??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#Zt(){if(this.#J!=null)return this.#J;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#J=Number.isFinite(t)&&t>0?t:30000}#Qt(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#en(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}export{ke as ACTIVE_ATTR,Y as LATENCY_KEY,gn as __markReactiveConnectedForTest,fn as __resetReactiveDismissForTest,dn as __resetReactiveEffectsForTest,mn as __resetReactiveLatencyForTest,hn as __resetReactiveOfflineForTest,yn as __resetReactiveRegistrationForTest,St as checkReactiveRegistration,bn as default,bt as disableLatencySim,gt as enableLatencySim,Te as enterReactiveActivity,wt as escapeRegExp,Ne as exitReactiveActivity,ln as pendingDeferVia,pn as reactiveActivityCount,ce as registerReactiveActions,Xe as registerReactiveDefer,it as registerReactiveDismiss,at as registerReactiveEffects,Ye as registerReactiveJs,yt as registerReactiveOffline,Ke as registerReactiveToken,Ue as registerReactiveVisit,vn as resetReactiveActivity,un as resetReactiveDefers};
1
+ import{Controller as Ye}from"@hotwired/stimulus";import{confirmResolver as D}from"phlex/reactive/confirm";import{computeReducer as Xe}from"phlex/reactive/compute";import{confirmPredicate as Ze}from"phlex/reactive/confirm_predicate";function Qe(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:visit"])return;e["reactive:visit"]=function(){let t=this.getAttribute("data-url");if(t)window.Turbo.visit(t,{action:"advance"})}}function et(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:token"])return;e["reactive:token"]=function(){let t=this.getAttribute("data-reactive-token-value"),n=this.getAttribute("target");if(!t||!n)return;let r=document.getElementById(n);if(r)r.setAttribute("data-reactive-token-value",t)}}function tt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=oe(this.getAttribute("data-reactive-ops"));if(!t.length)return;let n=this.getAttribute("target"),r=this.getAttribute("data-reactive-verbose")==="true",i=n?document.getElementById(n):null;if(n&&!i){if(r&&!ae(`missing-root|#${n}`))console.warn(`[phlex-reactive] reactive:js stream target root #${n} is not in the DOM — its ops were dropped`);return}_(t,(s)=>mn(s,i),r?(s,o)=>hn(s,o,i):void 0)}}var g=new Map;function ke(e,t){let n=!g.has(e);if(g.set(e,t),n)$e()}function C(e){if(g.delete(e))qe()}function bn(){g.clear(),W=!1}function An(e){return g.get(e)?.via}var W=!1;function nt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;if(e["reactive:defer"]=function(){let t=this.getAttribute("target");if(!t)return;if(this.getAttribute("data-reactive-defer-via")==="stream"){it(t,this);return}let n=this.getAttribute("data-reactive-defer-token");if(!n)return;O(t,n)},!W&&typeof document<"u"&&document.addEventListener)W=!0,document.addEventListener("turbo:before-stream-render",rt)}function rt(e){let n=e.target?.getAttribute?.("target");if(!n)return;let r=n.startsWith("reactive-defer-src-")?n.slice(19):n;if(g.get(r)?.via==="stream")C(r)}function O(e,t){let n=document.getElementById(e);if(!n){console.warn(`[phlex-reactive] reactive:defer target #${e} is not on the page — skipped`);return}Te(e),_e(n);let r={via:"fetch",abort:new AbortController,timedOut:!1};ke(e,r),st(e,r,t)}function it(e,t){let n=document.getElementById(e);if(!n){console.warn(`[phlex-reactive] reactive:defer target #${e} is not on the page — skipped`);return}let r=t.getAttribute("data-reactive-defer-src");if(!r)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let s=t.getAttribute("data-reactive-defer-token");if(s){O(e,s);return}console.error("[phlex-reactive] reactive:defer via=stream but <pgbus-stream-source> is not registered "+"and no fallback token was provided — is the pgbus client loaded on this page?");return}Te(e),_e(n);let i=document.createElement("pgbus-stream-source");i.id=xe(e),i.setAttribute("src",r),i.setAttribute("since-id",t.getAttribute("data-reactive-defer-since-id")??"0"),i.setAttribute("hidden",""),document.body.appendChild(i),ke(e,{via:"stream"})}function xe(e){return`reactive-defer-src-${e}`}async function st(e,t,n){let r=setTimeout(()=>{t.timedOut=!0,t.abort.abort()},ct()),i;try{i=await fetch(ot(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":at()},body:JSON.stringify({token:n}),credentials:"same-origin",signal:t.abort.signal})}catch(o){if(clearTimeout(r),g.get(e)!==t)return;console.error("[phlex-reactive] deferred render failed",o),F(e,n);return}if(g.get(e)!==t){clearTimeout(r);return}if(i.status===204){clearTimeout(r),ce(e);return}if(!i.ok){clearTimeout(r),console.error(`[phlex-reactive] deferred render failed: HTTP ${i.status}`),F(e,n,i.status);return}let s;try{s=await i.text()}catch(o){if(clearTimeout(r),g.get(e)!==t)return;console.error("[phlex-reactive] deferred render failed reading the body",o),F(e,n);return}if(clearTimeout(r),g.get(e)!==t)return;ce(e),window.Turbo.renderStreamMessage(s)}function Te(e){let t=g.get(e);if(!t)return;if(C(e),t.via==="fetch")t.abort.abort();else document.getElementById(xe(e))?.remove?.()}function _e(e){e.setAttribute("data-reactive-defer-pending","true"),e.setAttribute("aria-busy","true")}function Ne(e){e.removeAttribute("data-reactive-defer-pending"),e.removeAttribute("aria-busy")}function ce(e){C(e);let t=document.getElementById(e);if(!t)return;Ne(t),t.removeAttribute("data-reactive-error")}function F(e,t,n){C(e);let r=document.getElementById(e);if(!r)return;Ne(r),r.setAttribute("data-reactive-error","defer");let i=()=>{let s=document.getElementById(e);if(!s){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}s.removeAttribute("data-reactive-error"),O(e,t)};r.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:e,status:n,retry:i}}))}function ot(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function at(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function ct(){let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return Number.isFinite(t)&&t>0?t:30000}var B=!1;function ut(){if(B)return;if(typeof document>"u"||!document.addEventListener)return;B=!0,document.addEventListener("turbo:before-stream-render",lt)}function lt(e){let t=e.detail,n=t?.render;if(typeof n!=="function"||n.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(M);else setTimeout(M,0);return}let r=async(i)=>{await n(i),M()};r.__reactiveDismissWrapped=!0,t.render=r}function M(){let e=document.querySelectorAll("[data-reactive-dismiss-after]");for(let t of e){if(t.hasAttribute("data-reactive-dismiss-scheduled"))continue;let n=Number(t.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite(n)||n<=0)continue;t.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>t.remove(),n)}}function wn(){B=!1}var ft=Object.freeze({append:"enter",prepend:"enter",replace:"update",update:"update",remove:"exit"}),P=Object.freeze(["fade","slide","scale","highlight","shake"]),I="data-reactive-fx-pending",Le=1000,z=!1;function dt(){if(z)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;z=!0,document.addEventListener("turbo:before-stream-render",ht)}function Sn(){z=!1}function ht(e){let t=e.detail,n=t?.render;if(typeof n!=="function"||n.__reactiveEffectsWrapped)return;let r=t?.newStream??e.target,i=ft[r?.getAttribute?.("action")];if(!i||yt())return;let s=mt(r,i);if(!s)return;let o=i==="exit"?async(a)=>{await bt(N(r),s),await n(a)}:async(a)=>{let c=i==="enter"?gt(r):null;if(await n(a),i==="enter")vt(c,s);else Ce(N(r),s)};o.__reactiveEffectsWrapped=!0,t.render=o}function mt(e,t){let n=e.getAttribute?.("data-reactive-effect");if(n==="off")return null;if(n)return ue(n,t);let i=(t==="enter"?pt(e):N(e))?.getAttribute?.(`data-reactive-effect-${t}`);return i?ue(i,t):null}function N(e){let t=e.getAttribute?.("target");return t?document.getElementById?.(t)??null:null}function pt(e){return e.querySelector?.("template")?.content?.firstElementChild??null}function ue(e,t){if(e.startsWith("[")){let r=null;try{let i=JSON.parse(e);if(Array.isArray(i)&&i.length===3)r=i.map(String)}catch{}if(r)return{legs:r};return console.warn(`[phlex-reactive] malformed effect legs ${JSON.stringify(e)} — skipped`),null}let n=e==="random"?P[Math.floor(Math.random()*P.length)]:e;if(!P.includes(n))return console.warn(`[phlex-reactive] unknown effect ${JSON.stringify(e)} — skipped`),null;return{className:`reactive-fx--${n}-${t}`}}function yt(){try{return typeof matchMedia==="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function gt(e){let t=e.querySelector?.("template")?.content;if(!t)return null;for(let n of Array.from(t.children??[]))n.setAttribute?.(I,"");return N(e)}function vt(e,t){if(typeof e?.querySelectorAll!=="function")return;for(let n of Array.from(e.querySelectorAll(`[${I}]`)))n.removeAttribute(I),Ce(n,t)}async function bt(e,t){if(!e?.classList)return;if(t.legs){await Oe(e,t.legs);return}e.classList.add(t.className);let n=G(e);if(n<=0){e.classList.remove(t.className);return}await K(e,n),e.classList.remove(t.className)}function Ce(e,t){if(!e?.classList)return;if(t.legs){Oe(e,t.legs);return}if(e.classList.contains(t.className))e.classList.remove(t.className),e.offsetWidth;e.classList.add(t.className);let n=G(e);if(n<=0){e.classList.remove(t.className);return}let r=e.__reactiveFxToken=(e.__reactiveFxToken??0)+1;K(e,n).then(()=>{if(e.__reactiveFxToken===r)e.classList.remove(t.className)})}async function Oe(e,t){let[n,r,i]=t.map(At),s=e.__reactiveFxToken=(e.__reactiveFxToken??0)+1;if(e.classList.remove(...n,...r,...i),e.classList.add(...n,...r),await wt(),e.__reactiveFxToken!==s)return;e.classList.remove(...r),e.classList.add(...i);let o=G(e);if(o>0)await K(e,o);if(e.__reactiveFxToken!==s)return;e.classList.remove(...n,...i)}function At(e){return String(e??"").split(/\s+/).filter(Boolean)}function G(e){if(typeof getComputedStyle!=="function")return 0;try{let t=getComputedStyle(e),n=(s)=>String(s??"").split(",").reduce((o,a)=>Math.max(o,parseFloat(a)||0),0),r=n(t.animationDuration)+n(t.animationDelay),i=n(t.transitionDuration)+n(t.transitionDelay);return Math.min(Math.max(r,i)*1000,Le)}catch{return 0}}function K(e,t){return new Promise((n)=>{let r=!1,i=()=>{if(r)return;r=!0,n()};e.addEventListener?.("animationend",i,{once:!0}),e.addEventListener?.("transitionend",i,{once:!0}),setTimeout(i,Math.min(t+50,Le))})}function wt(){return new Promise((e)=>{if(typeof requestAnimationFrame==="function")requestAnimationFrame(()=>e());else setTimeout(e,16)})}var H=!1;function St(){if(H)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;H=!0;let e=()=>{let t=document.documentElement;if(typeof t?.toggleAttribute!=="function")return;t.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};e(),window.addEventListener("online",e),window.addEventListener("offline",e)}function En(){H=!1}var Y="phlex-reactive:latency",L=!1;function Et(e){if(typeof sessionStorage>"u")return;sessionStorage.setItem(Y,String(e))}function kt(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem(Y),L=!1}function xt(){if(typeof window>"u"||typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content!=="development")return;window.PhlexReactive={enableLatencySim:Et,disableLatencySim:kt}}function kn(){L=!1}var Re="data-reactive-active",b=0;function $e(){if(b++,b===1)De("reactive:busy")}function qe(){if(b===0)return;if(b--,b===0)De("reactive:idle")}function xn(){return b}function Tn(){b=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(Re)}function De(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(Re,b>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:b}}))}function le(){Qe(),et(),tt(),nt(),ut(),dt(),St(),xt()}function Tt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}if(typeof window<"u")if(window.Turbo)le();else document.addEventListener("turbo:load",le,{once:!0});var R=!1;function _t(){if(R)return;if(typeof document>"u")return;let e=document.querySelectorAll('[data-controller~="reactive"]');if(!e||e.length===0)return;console.warn("[phlex-reactive] found "+e.length+' element(s) with data-controller="reactive" '+"but the reactive controller never connected. It is loaded but not registered — "+'add `application.register("reactive", ReactiveController)` (importmap) or import it into app/javascript/controllers/ for lazyLoadControllersFrom apps. See the README.')}function _n(){R=!1}function Nn(){R=!0}if(typeof window<"u"&&typeof document<"u"){let e=()=>setTimeout(_t,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var Nt=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function Lt(e){let t=String(e).toLowerCase();return t.startsWith("on")||Nt.has(t)}function Ct(e,t,n){let[r,i,s]=t;e.classList.add(r,i),n(),requestAnimationFrame(()=>{e.classList.remove(i),e.classList.add(s)});let o=!1,a=()=>{if(o)return;o=!0,e.classList.remove(r,s)};e.addEventListener("animationend",a,{once:!0}),setTimeout(a,350)}var Fe=1,Ot="phlex-reactive:persist:",Rt=new Set(["hidden","file","password","submit","button","reset","image"]),X=Symbol("persist-no-value"),Z="data-reactive-persist-state",Me=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",Pe=new Set(["lexxy-editor","trix-editor"]),$t="lexxy-editor, trix-editor, trix-toolbar",fe=["lexxy:change","trix-change"],qt=new Set(["","<p></p>","<p><br></p>","<div><br></div>"]),de=new WeakSet,he=new WeakSet,me=new WeakSet;function Q(e){let t=e?.getAttribute?.("data-reactive-persist");if(!t||t==="off")return null;try{let n=JSON.parse(t);if(n&&typeof n==="object"&&typeof n.key==="string"&&n.key!=="")return n}catch{}if(!de.has(e))de.add(e),console.warn(`[phlex-reactive] malformed reactive_persist payload ${JSON.stringify(t)} — persistence disabled`);return null}function ee(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function te(e,t){if(e?.getAttribute?.("data-reactive-debug")!=="true"||he.has(e))return;he.add(e),console.info(`[phlex-reactive] reactive_persist: storage unavailable — draft skipped (${t?.name??t})`)}function ne(e){return Ot+e.key}function V(e,t){let n=ee();if(!n)return null;let r;try{r=n.getItem(ne(t))}catch(c){return te(e,c),null}if(!r)return null;let i;try{i=JSON.parse(r)}catch{return null}if(!i||typeof i!=="object"||i.v!==Fe)return null;let s=Number(t.ttl)*1000;if(!(Number(i.savedAt)+s>Date.now()))return re(e,t),null;let o=i.fields&&typeof i.fields==="object"?i.fields:{},a=i.state&&typeof i.state==="object"?i.state:null;return{fields:o,state:a}}function je(e,t,{fields:n,state:r}){let i=ee();if(!i)return!1;let s={v:Fe,savedAt:Date.now(),fields:n};if(r)s.state=r;try{return i.setItem(ne(t),JSON.stringify(s)),!0}catch(o){return te(e,o),!1}}function re(e,t){e?.removeAttribute?.(Z);let n=ee();if(!n)return;try{n.removeItem(ne(t))}catch(r){te(e,r)}}function ie(e,t){let n=Array.isArray(t.fields)?new Set(t.fields):null,r=[],i=(s)=>s.closest('[data-controller~="reactive"]')===e&&s.getAttribute("data-reactive-persist")!=="off";for(let s of e.querySelectorAll("input[name], select[name], textarea[name]")){if(!i(s)||Rt.has(s.type)||s.closest($t))continue;if(n&&!n.has(s.name))continue;r.push({el:s,name:s.name,kind:"native"})}for(let s of e.querySelectorAll(Me)){if(!i(s))continue;let o=Dt(s);if(!o||n&&!n.has(o))continue;r.push({el:s,name:o,kind:Pe.has(s.localName)?"editor":"contenteditable"})}return r}function Dt(e){return e.getAttribute("name")||typeof e.name==="string"&&e.name||null}function q(e){return typeof e.value==="string"}function Ft(e){return Pe.has(e.localName)?q(e):!0}function Mt(e){if(typeof e.isEmpty==="boolean")return e.isEmpty;let t=e.editor?.getDocument?.();if(typeof t?.isEmpty==="function")return t.isEmpty();return qt.has(e.value.trim())}function Pt(e,t,n){if(e?.getAttribute?.("data-reactive-debug")!=="true"||me.has(e))return;me.add(e),console.info(`[phlex-reactive] reactive_persist: could not restore editor ${JSON.stringify(t)} — ${n?.message??n}`)}function E(e){return e.tagName==="SELECT"&&e.multiple}function Je(e){let t=new Map;for(let{el:n,name:r}of e){if(n.type==="radio"||!String(r).endsWith("[]"))continue;t.set(r,(t.get(r)??0)+1)}return t}function We(e,t,n){if(!Array.isArray(e))return e;if(n.get(t)!==1||e.length!==1)return X;return e[0]}function Be(e,t){let n={},r=(i)=>{let s=n[i];return Array.isArray(s)?s:n[i]=[]};for(let{el:i,name:s,kind:o}of ie(e,t)){let a=String(s).endsWith("[]");if(o==="editor"){if(q(i))if(a)r(s).push(i.value);else n[s]=i.value}else if(o==="contenteditable"){let c=i.textContent??"";if(a)r(s).push(c);else n[s]=c}else if(i.type==="radio"){if(i.checked)n[s]=i.value;else if(!Object.hasOwn(n,s))n[s]=null}else if(i.type==="checkbox")if(a){let c=r(s);if(i.checked)c.push(i.value)}else n[s]=i.checked;else if(E(i)){let c=[...i.options].filter((u)=>u.selected).map((u)=>u.value);if(a)r(s).push(...c);else n[s]=c}else if(a)r(s).push(i.value);else n[s]=i.value}return n}function jt(e,t,n){let r=t.restore==="always",i=ie(e,t),s=Je(i),o=new Set;for(let a of i)if(a.kind==="native"&&a.el.type==="checkbox"&&a.el.checked)o.add(a.name);for(let{el:a,name:c,kind:u}of i){if(!Object.hasOwn(n,c))continue;let l=n[c];if(l===null||l===void 0)continue;if(Array.isArray(l)&&E(a)&&(s.get(c)??0)>1)continue;if(Array.isArray(l)&&!(a.type==="checkbox"||E(a))){if(l=We(l,c,s),l===X)continue}if((a.type==="checkbox"||E(a))&&String(c).endsWith("[]")&&!Array.isArray(l))continue;if(u==="editor")Ie(e,a,c,l,r);else if(u==="contenteditable"){if(!r&&(a.textContent??"").trim()!=="")continue;a.textContent=String(l)}else if(a.type==="radio"){if(!r&&i.some((h)=>h.kind==="native"&&h.el.type==="radio"&&h.name===c&&h.el.checked))continue;a.checked=a.value===String(l)}else if(a.type==="checkbox"&&Array.isArray(l)){if(!r&&o.has(c))continue;a.checked=l.map(String).includes(a.value)}else if(a.type==="checkbox"){if(!r&&a.checked)continue;a.checked=Boolean(l)}else if(E(a)){if(!r&&[...a.options].some((d)=>d.selected))continue;let h=new Set((Array.isArray(l)?l:[l]).map(String));for(let d of a.options)d.selected=h.has(d.value)}else{if(!r&&a.value!=="")continue;a.value=String(l)}}Jt(e,t,n)}function Ie(e,t,n,r,i){if(Array.isArray(r))return;if(!q(t))return;if(!i&&!Mt(t))return;try{t.value=String(r)}catch(s){Pt(e,n,s)}}function Jt(e,t,n){let r=globalThis.customElements;if(typeof r?.whenDefined!=="function")return;let i=new Set;for(let o of e.querySelectorAll("lexxy-editor, trix-editor"))if(!q(o)&&!r.get?.(o.localName))i.add(o.localName);let s=t.restore==="always";for(let o of i)r.whenDefined(o).then(()=>{if(!e.isConnected)return;let a=ie(e,t),c=Je(a);for(let{el:u,name:l,kind:h}of a){if(h!=="editor"||u.localName!==o||!Object.hasOwn(n,l))continue;let d=We(n[l],l,c);if(d===null||d===void 0||d===X)continue;Ie(e,u,l,d,s)}})}function Wt(e,t){let n=Q(e);if(!n){console.warn("[phlex-reactive] persist_state on a root without reactive_persist — skipped");return}if(!t||typeof t!=="object")return;let i={...V(e,n)?.state??{},...t};if(je(e,n,{fields:Be(e,n),state:i}))e.setAttribute?.(Z,JSON.stringify(i))}function Bt(e){let t=Q(e);if(t)re(e,t)}var pe=Object.freeze({show:(e,t,n)=>j(e,!1,t,n),hide:(e,t,n)=>j(e,!0,t,n),toggle:(e,t,n)=>j(e,!e.hidden,t,n),add_class:(e,t)=>e.classList.add(...t.classes??[]),remove_class:(e,t)=>e.classList.remove(...t.classes??[]),toggle_class:(e,t)=>(t.classes??[]).forEach((n)=>e.classList.toggle(n)),set_attr:(e,t)=>{if(J(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(J(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!J(t.name))return;if(Array.isArray(t.values)){let[n,r]=t.values;e.setAttribute(t.name,e.getAttribute(t.name)===n?r:n)}else if(e.hasAttribute(t.name))e.removeAttribute(t.name);else e.setAttribute(t.name,"")},focus:(e)=>e.focus?.(),focus_first:(e)=>nn(e)?.focus?.(),text:(e,t)=>{let n=String(t.value??"");if(e.textContent!==n)e.textContent=n},dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e)=>It(e)?.requestSubmit?.(),paste_into:(e)=>zt(e),persist_state:(e,t)=>Wt(e,t.state),persist_clear:(e)=>Bt(e)});function It(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function zt(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((n)=>{if(!n)return;if(e.value=n,typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));e.focus?.()}).catch(()=>{})}function Ht(e,t,n){if(n?.transition)Ct(e,n.transition,()=>e.hidden=t);else e.hidden=t}function j(e,t,n,r){if(Ht(e,t,n),n?.expanded==null||typeof r!=="function")return;for(let i of r({...n,to:n.expanded}))i.setAttribute?.("aria-expanded",String(!t))}function J(e){if(!Lt(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}var ze=/^#[A-Za-z_][\w-]*$/;function Vt(e){if(typeof e==="string"&&ze.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(e)} — skipped`),!1}function Ut(e,t){let n=e.getAttribute("data-reactive-show-equals");if(n!==null)return t===n;let r=e.getAttribute("data-reactive-show-not");if(r!==null)return t!==r;let i=e.getAttribute("data-reactive-show-in");if(i!==null){try{let s=JSON.parse(i);if(Array.isArray(s))return s.includes(t)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(i)} — skipped`),null}for(let s of He){let o=e.getAttribute(`data-reactive-show-${s}`);if(o!==null)return Ve(s,o,t)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}var He=["gte","gt","lte","lt"],Gt=["len_eq","len_gte","len_gt","len_lte","len_lt"];function Kt(e,t,n){if(!Number.isInteger(t))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(t)} — skipped`),null;let r=[...String(n??"")].length;switch(e){case"len_eq":return r===t;case"len_gte":return r>=t;case"len_gt":return r>t;case"len_lte":return r<=t;case"len_lt":return r<t;default:return null}}function Ve(e,t,n){let r=Number(t);if(Number.isNaN(r))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(t)} — skipped`),null;let i=n==null?"":String(n).trim(),s=i===""?NaN:Number(i);if(Number.isNaN(s))return!1;switch(e){case"gte":return s>=r;case"gt":return s>r;case"lte":return s<=r;case"lt":return s<r;default:return null}}function Ue(e,t){if(!e||typeof e!=="object")return null;if(typeof e.equals==="string")return t===e.equals;if(typeof e.not==="string")return t!==e.not;if(Array.isArray(e.in))return e.in.includes(t);for(let n of He)if(n in e)return Ve(n,e[n],t);for(let n of Gt)if(n in e)return Kt(n,e[n],t);return null}var ye="[data-reactive-show-field], [data-reactive-show]";function Yt(e){try{let t=JSON.parse(e);if(t&&typeof t==="object"&&!Array.isArray(t))return t}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(e)} — skipped`),null}function Xt(e){try{let t=JSON.parse(e);if(Array.isArray(t)&&t.every((n)=>n&&typeof n==="object"&&Array.isArray(n.any)&&Array.isArray(n.ops)))return t}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function se(e,t){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let n=t(e.field)??"";return Ue(e,n)===!0}function T(e,t){if(!Array.isArray(e)||e.length===0)return null;return e.some((n)=>Array.isArray(n)&&n.length>0&&n.every((r)=>se(r,t)))}function Zt(e){if(!Array.isArray(e)||e.length===0)return null;let t=new Set;for(let n of e){if(!Array.isArray(n))continue;for(let r of n)if(r&&typeof r==="object"&&typeof r.field==="string")t.add(r.field)}return t.size>0?[...t]:null}function Qt(e,t){if(!e||typeof e!=="object")return null;let n=e.any;if(Array.isArray(n)&&(n.length===0||Array.isArray(n[0])))return T(n,t);return en(e,t)}function en(e,t){let n=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!n)return null;let r=e[n];if(r.length===0)return null;let i=r.map((s)=>se(s,t));return n==="all"?i.every(Boolean):i.some(Boolean)}function ge(e){if(typeof e==="string"&&ze.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(e)} — skipped`),!1}var tn='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function nn(e){return e.querySelectorAll?.(tn)?.[0]??null}function oe(e){if(Array.isArray(e))return e;if(typeof e!=="string")return[];try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}}var ve=Object.freeze({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"}),be=Object.freeze(["meta","ctrl","alt","shift"]);function rn(e,t,n){let r=e.split("+");for(let o of be)if(r.includes(o)!==Boolean(t[`${o}Key`]))return!1;let i=r.find((o)=>!be.includes(o));if(i===void 0||typeof t.key!=="string")return!0;let s=n&&Object.hasOwn(n,i)?n[i]:Object.hasOwn(ve,i)?ve[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof s==="string"&&s.toLowerCase()===t.key.toLowerCase()}function sn(e){if(Array.isArray(e))return[{ops:e,legacy:!0}];if(e&&typeof e==="object")return[e];if(typeof e!=="string")return[];let t=e.trim();if(t.startsWith("["))return[{ops:oe(t),legacy:!0}];let n=[];for(let r of t.split(" ")){if(r==="")continue;let i=null;try{i=JSON.parse(r)}catch{i=null}if(i&&typeof i==="object"&&!Array.isArray(i))n.push(i);else console.warn(`[phlex-reactive] malformed on_client binding record ${JSON.stringify(r)} — skipped`)}return n}function Ae(e,t,n){if(e.legacy)return!0;let r=e.on;if(typeof r!=="string"||r==="")return!1;let i=r.indexOf(".");if(t.type!==(i<0?r:r.slice(0,i)))return!1;let s=globalThis.window,o=s!=null&&t.currentTarget===s;if(Boolean(e.window)!==o)return!1;return i<0||n===null||rn(r.slice(i+1),t,n)}var we=new WeakMap;function on(e,t,n){if(!n.once)return!1;let r=t.currentTarget??e.element,i=we.get(e);if(!i)i=new WeakMap,we.set(e,i);let s=i.get(r);if(!s)s=new Set,i.set(r,s);let o=t.params?.ops,c=(r===globalThis.window?`${typeof o==="string"?o:JSON.stringify(o??null)}|`:"")+JSON.stringify(n);if(s.has(c))return!0;return s.add(c),!1}var Se=new WeakMap;function an(e,t){if(e===null||typeof e!=="object")return!1;let n=e.params?.ops,r=typeof n==="string"?n:JSON.stringify(n??null),i=Se.get(e);if(!i)i=new WeakMap,Se.set(e,i);let s=i.get(t);if(!s)s=new Map,i.set(t,s);let o=s.get(e.currentTarget);if(!o)o=new Set,s.set(e.currentTarget,o);if(o.has(r))return!0;return o.add(r),!1}function k({el:e,kind:t}){if(!e)return"";if(t==="checkbox")return e.checked?"true":"false";if(t==="radio")return e.checked?e.value??"":"";return e.value??""}var cn=Object.freeze({el:null,kind:""});function Ge(e){if(typeof e==="boolean")return e;if(e==null)return!1;let t=String(e);return t!==""&&t!=="0"&&t!=="false"}function un(e,t){if(t==="string")return k(e);let n=e.kind==="checkbox";if(t==="boolean")return n?Boolean(e.el.checked):Ge(k(e));if(n)return e.el.checked?1:0;let r=Number(k(e));return Number.isFinite(r)?r:0}function ln(e,t,{el:n,kind:r},i,s){if(r==="checkbox"){let o=Ge(s);if(Boolean(n.checked)===o)return null;return n.checked=o,n}if(r==="radio")return fn(e,t,i,String(s));if(String(s)===n.value)return null;return n.value=s,n}function fn(e,t,n,r){let i=null;for(let s of e.querySelectorAll(`[name="${n}"]`)){if(s.type!=="radio"||!t(s))continue;let o=s.value===r;if(Boolean(s.checked)===o)continue;if(s.checked=o,o)i=s;else i??=s}return i}function dn(e){if(e==null)return null;let t=Array.isArray(e)?e:e.ops;if(Array.isArray(t))return t.length>0?t:null;return console.warn("[phlex-reactive] $ops must be an ops chain or a [[op, args], ...] list — skipped"),null}function _(e,t,n){for(let r of e){if(!Array.isArray(r))continue;let[i,s={}]=r;if(!Object.hasOwn(pe,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let o=t(s);if(o.length===0&&n)n(i,s);for(let a of o)pe[i](a,s,t)}}var Ee=new WeakMap;function ae(e){let t=globalThis.document;if(!t)return!0;let n=Ee.get(t);if(!n)n=new Set,Ee.set(t,n);if(n.has(e))return!0;return n.add(e),!1}function U(e,t){try{return e?.querySelectorAll?.(t)?.length??0}catch{return 0}}function Ke(e,t,n,r){if(ae(`${e}|${t}|${n}`))return;console.warn(`[phlex-reactive] ${e} matched zero targets for selector "${t}" (${n})${r}`)}function hn(e,t,n){let r=t.to;if(typeof r!=="string"||r===""||r==="@root")return;let i="";if(n&&!t.global){let s=U(globalThis.document,r);if(s>0)i=` — it matches ${s} element(s) outside the stream's target root; use global: true`}Ke(`client op "${e}"`,r,n?`scoped to #${n.id||"?"}`:"document-scoped",i)}function mn(e,t){let n=e.to;if(t){if(n==="@root")return[t];if(typeof n!=="string"||n==="")return[];if(e.global)return[...document.querySelectorAll(n)];return[...t.querySelectorAll(n)]}if(typeof n!=="string"||n===""||n==="@root")return[];return[...document.querySelectorAll(n)]}class Ln extends Ye{static values={token:String};#ie;#T=new Map;#m=new Map;#Me;#W;#se;#B=0;#p=new Map;#I=new WeakMap;#_=new Map;#oe=new WeakSet;#ae=null;#y;#g;#v;#r;#a;#z;#ce;#H;#V;#s;#b;#ue=!1;#U=0;#le=!1;#o;#A;#w;#N;#S;#i=null;#E=!1;#t=null;#c;#L;#C;connect(){if(R=!0,this.element.id==="")console.warn("[phlex-reactive] a reactive root has no id; its next-action token can't self-match "+"and may fall back to the first token in the response → a silent HTTP 403 on the NEXT action. "+"Put id: on the SAME element as reactive_attrs — use div(**reactive_root) (emits id + token together), "+"or div(id:, **reactive_attrs). The id: must NOT be on a child. See the README.");if(this.element.getAttribute?.("data-reactive-defer-token"))this.#fe(),this.#N=()=>this.#fe(),this.element.addEventListener?.("turbo:morph-element",this.#N);if(this.#i=Q(this.element),this.#i)this.#Tt();if(this.#Pe()){if(this.#y=()=>this.#Z(),this.element.addEventListener?.("turbo:morph-element",this.#y),this.#Z(),this.element.getAttribute?.("data-reactive-warn-unsaved")==="true")this.#pt()}if(this.#gt())this.#r=()=>this.#xe(),this.element.addEventListener?.("input",this.#r),this.element.addEventListener?.("change",this.#r),this.element.addEventListener?.("turbo:morph-element",this.#r),this.#xe();if(this.#vt())this.#a=(e)=>this.#Q(e),this.#z=()=>this.#Q(null),this.element.addEventListener?.("input",this.#a),this.element.addEventListener?.("change",this.#a),this.element.addEventListener?.("turbo:morph-element",this.#z),this.#Q(null);if(this.#F())this.#s=(e)=>{if(e?.type==="input"&&!this.#Rt(e))return;this.#x()},this.element.addEventListener?.("input",this.#s),this.element.addEventListener?.("turbo:morph-element",this.#s),this.#x();if(this.#M())this.#b=()=>this.#ne(),this.element.addEventListener?.("turbo:morph-element",this.#b),this.#ne();if(this.#qt())this.#o=(e)=>this.syncNestedJson(e),this.#A=()=>this.#$(),this.element.addEventListener?.("input",this.#o),this.element.addEventListener?.("change",this.#o),this.element.addEventListener?.("turbo:morph-element",this.#A),this.#$();if(this.#Ot())this.#w=()=>this.recompute(),this.element.addEventListener?.("turbo:morph-element",this.#w),this.recompute();if(this.#bt())this.#S=()=>this.#ke(),this.element.addEventListener?.("turbo:morph-element",this.#S),this.#ke()}#Pe(){if((this.element.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let e=this.element.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let t of e)if(this.#n(t))return!0;return!1}disconnect(){if(this.#Lt(),this.#nt(),this.#it(),this.#yt(),this.#Ct(),this.#St(),this.#$t(),this.#Wt(),this.#Bt(),this.#It(),this.#At(),this.#N)this.element.removeEventListener?.("turbo:morph-element",this.#N)}#fe(){let e=this.element;if(!e?.id)return;let t=e.getAttribute?.("data-reactive-defer-token");if(!t)return;if(e.getAttribute?.("data-reactive-defer-pending")!=="true")return;O(e.id,t)}dispatch(e){let{action:t,params:n,debounce:r,throttle:i,confirm:s,confirmWhen:o,outside:a,window:c,optimistic:u}=e.params;if(!t)return;let l=e.params.busy??this.#Qt(e.params.loading);if(a&&this.element.contains(e.target))return;let h=e.currentTarget??e.target;if(!c&&!this.#Vt(u,h))e.preventDefault();let d=this.#X(s,o);if(!d)return this.#ve(h,t,n,r,i,u,l);Promise.resolve().then(()=>D(d,{el:h})).catch(()=>!1).then((p)=>{if(p)this.#ve(h,t,n,r,i,u,l)})}runOps(e){if(an(e,this))return;let t=e.params??{},n=e.currentTarget??e.target,r=sn(t.ops),i=r.filter((o)=>Ae(o,e,null)),s=i.length<=1?i:i.filter((o)=>Ae(o,e,this.application?.schema?.keyMappings));if(s.length===0&&r.length>0)return this.#Je(e);for(let o of s){if(on(this,e,o))continue;this.#je(o.legacy?{...t,ops:o.ops}:o,e,n)}}#je({ops:e,confirm:t,confirmWhen:n,outside:r,window:i},s,o){if(r&&this.element.contains(s.target))return;if(!i)s.preventDefault();let a=this.#X(t,n);if(!a)return this.#Re(this.#Oe(e));Promise.resolve().then(()=>D(a,{el:o})).catch(()=>!1).then((c)=>{if(c)this.#Re(this.#Oe(e))})}#Je(e){if(!this.#$e())return;let t=`no-binding|${e.type}|${this.element?.id||"?"}`;if(ae(t))return;console.warn(`[phlex-reactive] runOps on #${this.element?.id||"?"} found no on_client binding matching a "${e.type}" event — nothing ran`)}trackDirty(){this.#Z()}recompute(e){if(e&&this.#oe.has(e))return;let t=this.#Ke(),n=t.map(([f])=>f),r=this.element.getAttribute?.("data-reactive-scope")||null,i=(f)=>r&&!f.includes("[")?`${r}[${f}]`:f,s=this.#e(),o=new Map,a=(f)=>{let y=o.get(f);if(y)return y;let m=null,v=null,A=null;for(let w of this.element.querySelectorAll(`[name="${i(f)}"]`)){if(!s(w))continue;let x=w.type;if(x==="checkbox"||x==="radio"&&w.checked){A={el:w,kind:x};break}if(x==="radio")m??=w;else v??=w}if(!A)if(m)A={el:m,kind:"radio"};else A=v?{el:v,kind:""}:cn;return o.set(f,A),A};for(let f of n)this.#ye(f,k(a(f)));let c=this.element.getAttribute("data-reactive-compute-reducer-param"),u=c?Xe(c):null;if(!u){this.#ge({},a);return}let l=this.#Ge("data-reactive-compute-outputs-param"),h={};for(let[f,y]of t)h[f]=un(a(f),y);let d=u(h,{changed:this.#Ye(e,n,r)})||{},p=dn(d.$ops),S=[];for(let f of l){if(f==="$ops"||!(f in d))continue;let y=a(f);if(!y.el)continue;let m=ln(this.element,s,y,i(f),d[f]);if(m)S.push(m)}for(let f of Object.keys(d)){if(f==="$ops")continue;let y=d[f];if(y===void 0||y===null)continue;this.#ye(f,y)}this.#ge(d,a);for(let f of S){let y=new Event("input",{bubbles:!0});this.#oe.add(y),f.dispatchEvent(y)}this.#We(p,Boolean(e))}#We(e,t){let n=e===null?null:JSON.stringify(e),r=n!==null&&n!==this.#ae&&t;if(this.#ae=n,!r)return;_(e,(i)=>this.#J(i.to==null?{...i,to:"@root"}:i),(i,s)=>this.#j(`client op "${i}"`,s))}listnavNext(e){this.#O(e,(t,n)=>t<0?0:(t+1)%n)}listnavPrev(e){this.#O(e,(t,n)=>t<0?n-1:(t-1+n)%n)}listnavFirst(e){this.#O(e,()=>0)}listnavLast(e){this.#O(e,(t,n)=>n-1)}listnavPick(e){let t=this.#R(e),n=t.findIndex((r)=>r.hasAttribute("data-reactive-highlighted"));if(n<0)return;e.preventDefault(),t[n].click()}listnavClose(e){for(let t of this.#R(e))t.removeAttribute("data-reactive-highlighted")}#O(e,t){let n=this.#R(e);if(!n.length)return;e.preventDefault();let r=this.#Be(e),i=globalThis.document?.activeElement,s=r?n.findIndex((a)=>a===i||i!=null&&a.contains?.(i)):n.findIndex((a)=>a.hasAttribute("data-reactive-highlighted")),o=n[t(s,n.length)];if(r)o.focus?.();else{for(let a of n)a.removeAttribute("data-reactive-highlighted");o.setAttribute("data-reactive-highlighted","true")}o.scrollIntoView?.({block:"nearest"})}#Be(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#R(e){let n=(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!n)return[];let r=this.#e();return Array.from(this.element.querySelectorAll(n)).filter((i)=>!i.hidden&&r(i))}tagsAdd(e){if(!this.#M())return;if(e?.defaultPrevented)return;if(this.#R(e).some((r)=>r.hasAttribute?.("data-reactive-highlighted")))return;e?.preventDefault?.();let t=e?.currentTarget??e?.target;if(!t)return;if(!this.#Ne(String(t.value??"").split(",")))return;if(t.value="",this.#F())this.#x()}tagsPick(e){if(!this.#M())return;e?.preventDefault?.();let n=(e?.currentTarget??e?.target)?.getAttribute?.("data-reactive-tag-param");if(!n)return;if(!this.#Ne([n]))return;let r=this.#Dt();if(!r)return;r.value="",this.#x(),r.focus?.()}tagsRemove(e){if(!this.#M())return;e?.preventDefault?.();let n=(e?.currentTarget??e?.target)?.getAttribute?.("data-reactive-tag-param");if(!n)return;let r=this.#ee();if(!r)return;let i=this.#te(r),s=i.filter((o)=>o.toLowerCase()!==n.toLowerCase());if(s.length===i.length)return;this.#Le(r,s)}nestedAdd(e){e?.preventDefault?.();let t=e?.currentTarget??e?.target,n=t?.getAttribute?.("data-reactive-association-param");if(!n)return;if(typeof this.element?.querySelectorAll!=="function")return;let r=this.#e(),i=[...this.element.querySelectorAll(`[data-reactive-nested-list="${n}"]`)].find(r),o=[...this.element.querySelectorAll(`[data-reactive-nested-template="${n}"]`)].find(r)?.content?.firstElementChild;if(!i||!o){this.#Jt(n);return}let a=o.cloneNode(!0);this.#jt(a,this.#Pt()),i.appendChild(a);let c=t?.getAttribute?.("data-reactive-nested-from-param"),u=t?.getAttribute?.("data-reactive-nested-clear-param")==="true",l=this.#Ie(a,c,u);if(c)l?.focus?.();else[...a.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(i.getAttribute?.("data-reactive-nested-json")===n)this.#he(n)}#Ie(e,t,n){if(!t)return null;let r;try{r=JSON.parse(t)}catch{return null}if(!r||typeof r!=="object")return null;let i=this.#e(),s=[...e.querySelectorAll?.("input, select, textarea")??[]],o=[];for(let[a,c]of Object.entries(r)){let u=[...this.element.querySelectorAll?.(c)??[]].find(i);if(!u)continue;let l=s.find((h)=>this.#pe(h.getAttribute?.("name"))===a);if(!l)continue;this.#ze(l,u),o.push(u)}if(n)for(let a of o)this.#He(a);return o[0]??null}#ze(e,t){if(e.type==="checkbox")e.checked=t.type==="checkbox"?!!t.checked:this.#G(t)!=="";else e.value=this.#G(t);if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}#He(e){if(e.type==="checkbox")e.checked=!1;else e.value="";if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}nestedRemove(e){e?.preventDefault?.();let t=e?.currentTarget??e?.target,n=t?.closest?.("[data-reactive-nested-row]");if(!n)return;if(n.closest?.('[data-controller~="reactive"]')!==this.element)return;let r=t?.getAttribute?.("data-reactive-confirm-param"),i=t?.getAttribute?.("data-reactive-confirm-when-param"),s=this.#X(r,i);if(!s)return this.#de(n);let o=this.#me(n),a=this.#Ve(s,o);return Promise.resolve().then(()=>D(a,{el:t,row:n,fields:o})).catch(()=>!1).then((c)=>{if(c)this.#de(n)})}#Ve(e,t){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(n,r)=>Object.prototype.hasOwnProperty.call(t,r)?t[r]:n)}#de(e){let t=[...e.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t){if(t.value="1",typeof t.dispatchEvent==="function")t.dispatchEvent(new Event("input",{bubbles:!0}));e.hidden=!0}else e.parentNode?.removeChild?.(e);this.#$()}syncNestedJson(e){let t=e?.target;if(!t||!this.#n(t))return;this.#$()}#$(){if(typeof this.element?.querySelectorAll!=="function")return;let e=this.#e();for(let t of[...this.element.querySelectorAll("[data-reactive-nested-json]")].filter(e))this.#he(t.getAttribute("data-reactive-nested-json"))}#he(e){let t=this.#e(),n=[...this.element.querySelectorAll(`[data-reactive-nested-list="${e}"]`)].find(t);if(!n)return;let r=this.#Ue(n);if(!r)return;let i=[];for(let o of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(o)||o.hidden)continue;i.push(this.#me(o))}let s=JSON.stringify(i);if(r.value===s)return;if(r.value=s,typeof r.dispatchEvent==="function")r.dispatchEvent(new Event("input",{bubbles:!0}))}#Ue(e){let t=e.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let n=this.#e();return[...this.element.querySelectorAll(t)].find(n)??null}#me(e){let t={};for(let n of[...e.querySelectorAll?.("input, select, textarea")??[]]){let r=this.#pe(n.getAttribute?.("name"));if(r===null||r==="_destroy")continue;t[r]=this.#G(n)}return t}#pe(e){if(!e)return null;let t=e.match(/\[([^\][]+)\]$/);return t?t[1]:e}#G(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}#Ge(e){let t=this.element.getAttribute(e);if(!t)return[];try{let n=JSON.parse(t);return Array.isArray(n)?n:[]}catch{return[]}}#Ke(){let e=this.element.getAttribute("data-reactive-compute-inputs-param");if(!e)return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map((n)=>[n,"number"]);if(t&&typeof t==="object")return Object.entries(t);return[]}catch{return[]}}#Ye(e,t,n){let r=e?.target;if(!r?.name||typeof r.closest!=="function")return null;let i=this.#Xe(r.name,n);if(!t.includes(i))return null;return this.#n(r)?i:null}#Xe(e,t){if(!t)return e;let n=`${t}[`;return e.startsWith(n)&&e.endsWith("]")?e.slice(n.length,-1):e}#ye(e,t){let n=String(t);for(let r of this.#Ze(e)){if(r.textContent===n)continue;r.textContent=n}}#Ze(e){let t=this.element.querySelectorAll(`[data-reactive-text="${e}"]`);return Array.from(t).filter((n)=>this.#n(n))}#ge(e,t){let n=this.#Qe();for(let[r,i]of Object.entries(n)){let s=r in e?null:t(r),o=r in e?e[r]:s.el?k(s):void 0;if(o===void 0||o===null)continue;let a=String(o);for(let c of Array.isArray(i)?i:[i]){if(!Vt(c))continue;for(let u of document.querySelectorAll(c)){if(u.textContent===a)continue;u.textContent=a}}}}#Qe(){let e=this.element.getAttribute("data-reactive-compute-mirror-param");if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return{}}}#ve(e,t,n,r,i,s,o){if(this.#k("reactive:before-dispatch",{action:t,params:this.#Ce(n),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(r)||0;if(c>0)return this.#tt(e,c,t,n,s,o);let u=Number(i)||0;if(u>0)return this.#rt(e,u,t,n,s,o);return this.#q(t,n,s,e,o)}#q(e,t,n,r,i){let s=this.#Ut(n,r),o=this.#Gt(e,r,i),a=this.#Y()?this.#et(n,r):null;return this.queue=(this.queue??Promise.resolve()).then(()=>this.#lt(e,t,s,o,a)),this.queue}#et(e,t){if(!e?.hide)return null;let n=this.#De(e,t);if(!n.length)return null;return()=>{let r=n.filter((i)=>i.isConnected&&!i.hidden);if(!r.length)return;console.warn("[phlex-reactive] optimistic: { hide: true } was undone by the reply's re-render — "+"the element is visible again. For an instant delete, return reply.remove so the server removes it; otherwise the hide only flashes.",r)}}#tt(e,t,n,r,i,s){this.#K(e);let o=()=>{this.#K(e),this.#q(n,r,i,e,s)},a=setTimeout(o,t);e?.addEventListener?.("blur",o,{once:!0}),this.#T.set(e,{timer:a,flush:o})}#K(e){let t=this.#T.get(e);if(!t)return;clearTimeout(t.timer),e?.removeEventListener?.("blur",t.flush),this.#T.delete(e)}#nt(){for(let e of[...this.#T.keys()])this.#K(e)}#rt(e,t,n,r,i,s){let o=this.#m.get(e)??new Map;if(o.has(n))return;let a=setTimeout(()=>{if(o.delete(n),o.size===0)this.#m.delete(e)},t);return o.set(n,a),this.#m.set(e,o),this.#q(n,r,i,e,s)}#it(){for(let e of this.#m.values())for(let t of e.values())clearTimeout(t);this.#m.clear()}#k(e,t,{cancelable:n=!1}={}){let r=new CustomEvent(e,{bubbles:!0,composed:!0,cancelable:n,detail:t});return(this.element.isConnected?this.element:document).dispatchEvent(r),r}#u(e,t,n,r){let i=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#q(e,t)};this.#k("reactive:error",{action:e,params:n,...r,retry:i})}#l(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#st(){this.element?.removeAttribute?.("data-reactive-error")}#ot(){let e=document.querySelector("[data-reactive-error-flash]");if(!e?.content)return;let t=e.getAttribute("data-reactive-error-flash")||"flash",n=document.getElementById(t);if(!n)return;n.appendChild(e.content.cloneNode(!0))}#at(){if(typeof sessionStorage>"u")return Promise.resolve();let e=Number(sessionStorage.getItem(Y));if(!Number.isFinite(e)||e<=0)return Promise.resolve();if(!L)L=!0,console.warn(`[phlex-reactive] latency simulator ACTIVE — every action is delayed by ${e}ms. Call PhlexReactive.disableLatencySim() (or clear sessionStorage) to turn it off.`);return new Promise((t)=>setTimeout(t,e))}#Y(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#be(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}#ct(e){if(!e)return[];let t=[],n=/<turbo-stream\b([^>]*)>/g,r;while((r=n.exec(e))!==null){let i=r[1],s=i.match(/\baction="([^"]*)"/)?.[1]??"?",o=i.match(/\btarget="([^"]*)"/)?.[1];t.push(o?`${s} → #${o}`:s)}return t}#ut(e){let{action:t,status:n,ms:r}=e,s=`reactive ${this.element?.id?`#${this.element.id} `:""}${t} → ${n??"—"} (${Math.round(r)}ms)`;if(console.groupCollapsed(s),console.log(`params: [${e.paramNames.join(", ")}] + collected: [${e.fieldNames.join(", ")}]`),console.log(`encoding: ${e.encoding}`),e.streams.length)console.log(`streams: ${e.streams.join(" ")}`);console.log(`token: ${e.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}async#lt(e,t,n,r,i){let{fields:s,files:o}=this.#Se(),a=this.#Ce(t),c={...s,...a},u=this.#f,l=o.length>0,h=l?this.#zt(u,e,c,o):JSON.stringify({token:u,act:e,params:c}),d=this.#Y()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(s),encoding:l?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#be()}:null;await this.#at();try{if(navigator.onLine===!1){this.#d(n),this.#l("offline"),this.#u(e,t,c,{kind:"offline"});return}let p;try{let m={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#nn()};if(!l)m["Content-Type"]="application/json";let v=this.#rn();if(v)m["X-Pgbus-Connection"]=v;p=await fetch(this.#en(),{method:"POST",headers:m,body:h,credentials:"same-origin",signal:AbortSignal.timeout(this.#tn())})}catch(m){if(console.error("[phlex-reactive] action error",m),this.#d(n),m?.name==="TimeoutError"||m?.name==="AbortError"){this.#l("timeout"),this.#u(e,t,c,{kind:"timeout"});return}this.#ot(),this.#l("network"),this.#u(e,t,c,{kind:"network"});return}if(d)d.status=p.status;if(p.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#d(n),this.#l("redirected"),this.#u(e,t,c,{kind:"redirected",status:p.status});return}if(!p.ok){let m=await p.text();if(console.error(`[phlex-reactive] action failed: HTTP ${p.status}`,m),this.#d(n),(p.headers.get("Content-Type")||"").includes("turbo-stream")){let v=this.#we(m);if(this.#f=v??this.#f,d)this.#Ae(d,m,v);window.Turbo.renderStreamMessage(m)}this.#l("http"),this.#u(e,t,c,{kind:"http",status:p.status,body:m});return}let S=p.headers.get("Content-Type")||"";if(!S.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${S}" — no update applied`),this.#d(n),this.#l("content-type"),this.#u(e,t,c,{kind:"content-type",status:p.status});return}let f=await p.text(),y=this.#we(f);if(this.#f=y??this.#f,d)this.#Ae(d,f,y);if(window.Turbo.renderStreamMessage(f),i)queueMicrotask(i);this.#st(),this.#k("reactive:applied",{action:e,params:c,html:f})}catch(p){console.error("[phlex-reactive] action error",p),this.#d(n),this.#k("reactive:error",{action:e,params:c,kind:"apply"})}finally{if(r?.(),d)this.#ut({...d,ms:this.#be()-d.started})}}#Ae(e,t,n){e.streams=this.#ct(t),e.tokenRefreshed=n!=null}get#f(){return this.#ie??this.tokenValue}set#f(e){this.#ie=e}#we(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:n,self:r}=this.#ft(t),i=e.match(n);if(i)return i[1];let s=e.match(r);if(s)return s[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#ft(e){let t=this.#se;if(t&&t.id===e)return t;let n=Tt(e);return this.#se={id:e,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${n}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${n}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#n(e){return e.closest('[data-controller~="reactive"]')===this.element}#e(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#n(t)}#X(e,t){if(e)return e;if(!t)return null;let n=t;if(typeof t==="string")try{n=JSON.parse(t)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(t)} — skipped`),null}if(!n||typeof n!=="object")return null;let{fields:r}=this.#Se(),i=(o)=>r[o],s;if(typeof n.predicate==="string"){let o=Ze(n.predicate);if(!o)return console.warn(`[phlex-reactive] confirm predicate "${n.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;s=!!o(r)}else s=T(n.groups?.any,i)===!0;return s?n.message:null}#Se(){let e={},t=[],n=this.#e(),r=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((a)=>{if(!n(a))return;if(a.type==="file")for(let c of a.files??[])t.push({name:a.name,file:c,multiple:a.multiple});else r.push(a)});let i=[];this.element.querySelectorAll(`[name]${Me}`).forEach((a)=>{if(n(a))i.push(a)});let s=this.#dt(r),o=this.#ht(r);for(let a of r)if(s.has(a.name)){let c=e[a.name]??(e[a.name]=[]);if(a.type==="checkbox"||a.type==="radio"){if(a.checked)c.push(a.value)}else if(a.type==="hidden"){if(!o.has(a.name))c.push(a.value)}else if(a.multiple&&a.options){for(let u of a.options)if(u.selected)c.push(u.value)}else c.push(a.value)}else if(a.type==="checkbox")e[a.name]=a.checked;else if(a.type==="radio"){if(a.checked)e[a.name]=a.value}else e[a.name]=a.value;return i.forEach((a)=>{let c=a.getAttribute("name");if(!c)return;let u=a.value??a.textContent??a.innerHTML??"",l=e[c];if(String(c).endsWith("[]")&&!Ft(a))return;if(String(c).endsWith("[]")&&(l===void 0||Array.isArray(l))){(Array.isArray(l)?l:e[c]=[]).push(u);return}if(l==null||l==="")e[c]=u}),{fields:e,files:t}}#dt(e){let t=new Set;for(let n of e){if(n.type==="radio")continue;if(String(n.name).endsWith("[]"))t.add(n.name)}return t}#ht(e){let t=new Set;for(let n of e)if(n.type==="checkbox")t.add(n.name);return t}#Z(){if(typeof this.element?.querySelectorAll!=="function")return;let e=0;if(this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((t)=>{if(!this.#n(t))return;if(t.type==="file")return;if(this.#mt(t))t.setAttribute("data-reactive-dirty","true"),e++;else t.removeAttribute("data-reactive-dirty")}),e>0)this.element.setAttribute("data-reactive-dirty",String(e));else this.element.removeAttribute("data-reactive-dirty")}#mt(e){if(e.type==="checkbox"||e.type==="radio")return e.checked!==e.defaultChecked;if(e.tag==="select"||e.options)return Array.from(e.options??[]).some((t)=>t.selected!==t.defaultSelected);return e.value!==e.defaultValue}#Ee(){let e=this.element.getAttribute?.("data-reactive-dirty"),t=Number(e);return Number.isFinite(t)&&t>0?t:0}#pt(){if(typeof window>"u"||typeof window.addEventListener!=="function")return;this.#g=(e)=>{if(this.#Ee()===0)return;return e.preventDefault(),e.returnValue="You have unsaved changes.",e.returnValue},this.#v=(e)=>{if(this.#Ee()===0)return;if(!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))e.preventDefault?.()},window.addEventListener("beforeunload",this.#g),window.addEventListener("turbo:before-visit",this.#v)}#yt(){if(this.#y)this.element.removeEventListener?.("turbo:morph-element",this.#y),this.#y=void 0;if(typeof window<"u"&&typeof window.removeEventListener==="function"){if(this.#g)window.removeEventListener("beforeunload",this.#g);if(this.#v)window.removeEventListener("turbo:before-visit",this.#v)}this.#g=void 0,this.#v=void 0}#gt(){if(this.element.getAttribute?.("data-reactive-show-targets"))return!0;let e=this.element.querySelectorAll?.(ye)??[];for(let t of e)if(this.#n(t))return!0;return!1}#vt(){return!!this.element.getAttribute?.("data-reactive-on-complete")}#bt(){if(this.element.getAttribute?.("data-reactive-clipboard"))return!0;let e=this.element.querySelectorAll?.("[data-reactive-clipboard]")??[];for(let t of e)if(this.#n(t))return!0;return!1}#ke(){let e=typeof globalThis.navigator?.clipboard?.readText==="function";if(this.element.getAttribute?.("data-reactive-clipboard"))this.element.hidden=!e;for(let t of this.element.querySelectorAll?.("[data-reactive-clipboard]")??[])if(this.#n(t))t.hidden=!e}#At(){if(!this.#S)return;this.element.removeEventListener?.("turbo:morph-element",this.#S),this.#S=void 0}#wt(){let e=this.element.getAttribute?.("data-reactive-on-complete")??null;if(e!==this.#ce)this.#ce=e,this.#H=e==null?[]:Xt(e),this.#V=this.#H.map(()=>!1);return this.#H}#Q(e){let t=this.#wt();if(!t.length)return;let n=this.#e(),r=this.element.getAttribute?.("data-reactive-scope")||null,i=new Map,s=(o)=>{if(!i.has(o))i.set(o,this.#_e(o,n,r));return i.get(o)};t.forEach((o,a)=>{let c=T(o.any,s);if(c===null)return;let u=c&&!this.#V[a]&&Boolean(e);if(this.#V[a]=c,u)_(o.ops,(l)=>this.#J(l.to==null?{...l,to:"@root"}:l),(l,h)=>this.#j(`client op "${l}"`,h))})}#St(){if(!this.#a)return;this.element.removeEventListener?.("input",this.#a),this.element.removeEventListener?.("change",this.#a),this.element.removeEventListener?.("turbo:morph-element",this.#z)}#xe(){if(typeof this.element?.querySelectorAll!=="function")return;let e=this.#e(),t=this.element.getAttribute?.("data-reactive-scope")||null,n=new Map,r=(i)=>{if(!n.has(i))n.set(i,this.#_e(i,e,t));return n.get(i)};for(let i of this.element.querySelectorAll(ye)){if(!e(i))continue;let s=i.getAttribute("data-reactive-show");if(s!==null){let u=Qt(Yt(s),r);if(u!==null)this.#Te(i,u,e,t);continue}let o=i.getAttribute("data-reactive-show-field");if(!o)continue;let a=r(o);if(a===null)continue;let c=Ut(i,a);if(c===null)continue;this.#Te(i,c,e,t)}this.#Et(r)}#Te(e,t,n,r){if(e.hidden=!t,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let i of e.querySelectorAll("input[name], select[name], textarea[name]"))if(n(i))i.disabled=!t;if(e.name&&n(e))e.disabled=!t}#Et(e){let t=this.#xt();for(let[n,r]of Object.entries(t)){if(n.startsWith("#")){this.#kt(n,r,e);continue}if(!r||typeof r!=="object"||Array.isArray(r))continue;let i=e(n);if(i===null)continue;let s=()=>i;for(let[o,a]of Object.entries(r)){if(!ge(o))continue;let c;if(Array.isArray(a)){if(a.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${o} — skipped`);continue}c=a.every((u)=>se(u,s))}else{let u=Ue(a,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${o} — skipped`);continue}c=u}for(let u of document.querySelectorAll(o))u.hidden=!c}}}#kt(e,t,n){if(!ge(e))return;let r=t&&typeof t==="object"&&!Array.isArray(t)?t.any:null,i=Zt(r);if(i===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(i.every((o)=>n(o)===null))return;let s=T(r,n);if(s===null)return;for(let o of document.querySelectorAll(e))o.hidden=!s}#xt(){let e=this.element.getAttribute?.("data-reactive-show-targets");if(!e)return{};try{let t=JSON.parse(e);if(t&&typeof t==="object"&&!Array.isArray(t))return t}catch{}return console.warn("[phlex-reactive] malformed data-reactive-show-targets — ignored. "+"Did two reactive_show_targets calls collide on one root? Declare every field in ONE call: reactive_show_targets(mode: { ... }, kind: { ... })"),{}}#_e(e,t,n){let r=n&&!e.includes("[")?`${n}[${e}]`:e,i=!1,s=null;for(let o of this.element.querySelectorAll(`[name="${r}"]`)){if(!t(o))continue;if(o.type==="checkbox")return o.checked?"true":"false";if(o.type==="radio"){if(o.checked)return o.value??"";i=!0;continue}s??=o}if(s)return s.value??"";return i?"":null}#Tt(){let e=this.#i;this.#E=!1;let t=V(this.element,e);if(t){if(jt(this.element,e,t.fields),t.state)this.element.setAttribute?.(Z,JSON.stringify(t.state));this.#k("reactive:persist-restored",{key:e.key,fields:t.fields,state:t.state??{}})}this.#E=!0,this.#c=()=>this.#_t(),this.#L=()=>this.#D(),this.#C=(n)=>this.#Nt(n),this.element.addEventListener?.("input",this.#c),this.element.addEventListener?.("change",this.#L);for(let n of fe)this.element.addEventListener?.(n,this.#c);document.addEventListener?.("turbo:submit-end",this.#C)}#_t(){if(!this.#E)return;let e=Number(this.#i?.debounce)||0;if(e<=0)return this.#D();if(this.#t!==null)clearTimeout(this.#t);this.#t=setTimeout(()=>{this.#t=null,this.#D()},e)}#D(){if(!this.#E||!this.#i)return;if(this.#t!==null)clearTimeout(this.#t),this.#t=null;let e=this.#i,t=V(this.element,e);je(this.element,e,{fields:Be(this.element,e),state:t?.state??null})}#Nt(e){if(!e?.detail?.success)return;let t=e.target;if(t?.tagName!=="FORM"||typeof t.contains!=="function")return;if(!t.contains(this.element))return;if(this.#t!==null)clearTimeout(this.#t),this.#t=null;re(this.element,this.#i)}#Lt(){if(!this.#i)return;if(this.#t!==null)this.#D();this.element.removeEventListener?.("input",this.#c),this.element.removeEventListener?.("change",this.#L);for(let e of fe)this.element.removeEventListener?.(e,this.#c);document.removeEventListener?.("turbo:submit-end",this.#C),this.#c=this.#L=this.#C=void 0,this.#i=null,this.#E=!1}#Ct(){if(!this.#r)return;this.element.removeEventListener?.("input",this.#r),this.element.removeEventListener?.("change",this.#r),this.element.removeEventListener?.("turbo:morph-element",this.#r),this.#r=void 0}#F(){return!!(this.element.getAttribute?.("data-reactive-filter-input")&&this.element.getAttribute?.("data-reactive-filter-option"))}#Ot(){return this.element.getAttribute?.("data-reactive-compute-seed")==="true"}#Rt(e){let t=this.element.getAttribute("data-reactive-filter-input");return!!t&&typeof e.target?.matches==="function"&&e.target.matches(t)}#x(){if(typeof this.element?.querySelectorAll!=="function")return;let e=this.element.getAttribute("data-reactive-filter-input"),t=this.element.getAttribute("data-reactive-filter-option");if(!e||!t)return;let n=this.#e(),r=[...this.element.querySelectorAll(e)].find(n);if(!r)return;let i=(r.value??"").trim().toLowerCase(),s=0;for(let c of this.element.querySelectorAll(t)){if(!n(c))continue;let u=(c.getAttribute("data-reactive-filter-text")??c.textContent??"").toLowerCase(),l=c.hasAttribute?.("data-reactive-tags-selected")||i!==""&&!u.includes(i);if(c.hidden=l,l)c.removeAttribute("data-reactive-highlighted");else s++}let o=this.element.getAttribute("data-reactive-filter-group");if(o)for(let c of this.element.querySelectorAll(o)){if(!n(c))continue;let u=[...c.querySelectorAll(t)].filter(n);if(u.length===0)continue;c.hidden=u.every((l)=>l.hidden)}let a=this.element.getAttribute("data-reactive-filter-empty");if(a){for(let c of this.element.querySelectorAll(a))if(n(c))c.hidden=s>0}}#$t(){if(!this.#s)return;this.element.removeEventListener?.("input",this.#s),this.element.removeEventListener?.("turbo:morph-element",this.#s),this.#s=void 0}#M(){return!!this.element.getAttribute?.("data-reactive-tags-field")}#qt(){if(typeof this.element?.querySelector!=="function")return!1;return!!this.element.querySelector("[data-reactive-nested-json]")}#ee(){if(typeof this.element?.querySelectorAll!=="function")return null;let e=this.element.getAttribute("data-reactive-tags-field");if(!e)return null;let t=this.#e();return[...this.element.querySelectorAll(e)].find(t)??null}#te(e){let t=new Set,n=[];for(let r of String(e.value??"").split(",")){let i=r.trim();if(i===""||t.has(i.toLowerCase()))continue;t.add(i.toLowerCase()),n.push(i)}return n}#Ne(e){let t=this.#ee();if(!t)return!1;let n=this.#te(t),r=new Set(n.map((s)=>s.toLowerCase())),i=!1;for(let s of e){let o=String(s??"").trim();if(o===""||r.has(o.toLowerCase()))continue;r.add(o.toLowerCase()),n.push(o),i=!0}if(i)this.#Le(t,n);return i}#Le(e,t){if(e.value=t.join(","),typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));this.#ne()}#Dt(){if(typeof this.element?.querySelectorAll!=="function")return null;let e=this.element.getAttribute("data-reactive-filter-input");if(!e)return null;let t=this.#e();return[...this.element.querySelectorAll(e)].find(t)??null}#ne(){let e=this.#ee();if(!e)return;let t=this.#te(e),n=this.#e();this.#Ft(t,n),this.#Mt(t,n)}#Ft(e,t){let n=[...this.element.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!n)return;let i=[...this.element.querySelectorAll("[data-reactive-tags-template]")].find(t)?.content?.firstElementChild;if(!i){if(!this.#ue)console.warn("[phlex-reactive] reactive_tags: no chip <template data-reactive-tags-template> found in this root — "+"chips will not render (the hidden field still updates). Add a template with a [data-reactive-tag-text] node and a reactive_tags_remove button."),this.#ue=!0;return}while(n.firstChild)n.removeChild(n.firstChild);for(let s of e){let o=i.cloneNode(!0);o.setAttribute?.("data-reactive-tag",s);let a=o.matches?.("[data-reactive-tag-text]")?o:(o.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(a)a.textContent=s;let c=[...o.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(o.matches?.('[data-action*="reactive#tagsRemove"]'))c.push(o);for(let u of c)u.setAttribute?.("data-reactive-tag-param",s);n.appendChild(o)}}#Mt(e,t){let n=new Set(e.map((r)=>r.toLowerCase()));for(let r of this.element.querySelectorAll("[role=option]")){if(!t(r))continue;let i=r.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))r.setAttribute("data-reactive-tags-selected","true"),r.hidden=!0,r.removeAttribute?.("data-reactive-highlighted");else if(r.hasAttribute?.("data-reactive-tags-selected")){if(r.removeAttribute("data-reactive-tags-selected"),!this.#F())r.hidden=!1}}if(this.#F())this.#x()}#Pt(){return this.#U=Math.max(this.#U+1,Date.now()),this.#U}#jt(e,t){let n=[e,...e.querySelectorAll?.("*")??[]];for(let r of n)for(let i of["name","id","for"]){let s=r.getAttribute?.(i);if(s&&s.includes("NEW_ROW"))r.setAttribute?.(i,s.replaceAll("NEW_ROW",String(t)))}}#Jt(e){if(this.#le)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${e}"] container + <template data-reactive-nested-template="${e}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),this.#le=!0}#Wt(){if(!this.#b)return;this.element.removeEventListener?.("turbo:morph-element",this.#b),this.#b=void 0}#Bt(){if(this.#o)this.element.removeEventListener?.("input",this.#o),this.element.removeEventListener?.("change",this.#o),this.#o=void 0;if(this.#A)this.element.removeEventListener?.("turbo:morph-element",this.#A),this.#A=void 0}#It(){if(!this.#w)return;this.element.removeEventListener?.("turbo:morph-element",this.#w),this.#w=void 0}#zt(e,t,n,r){let i=new FormData;i.append("token",e),i.append("act",t);let s=[];for(let[a,c]of Object.entries(n))if(Array.isArray(c)&&String(a).endsWith("[]"))if(c.length===0)s.push(String(a).slice(0,-2));else{let u=`${this.#P(a)}[]`;for(let l of c)i.append(u,String(l))}else this.#re(i,this.#P(a),c);for(let a of s)i.append("empty_groups[]",a);let o=this.#Ht(r);for(let{name:a,file:c,multiple:u}of r){let h=u||o.has(a)?`${this.#P(a)}[]`:this.#P(a);i.append(h,c,c.name)}return i}#P(e){let t=String(e),n=t.indexOf("[");if(n===-1)return`params[${t}]`;return`params${[t.slice(0,n),...t.slice(n).match(/[^\[\]]+/g)??[]].map((i)=>`[${i}]`).join("")}`}#re(e,t,n){if(n==null)e.append(t,"");else if(Array.isArray(n))n.forEach((r,i)=>this.#re(e,`${t}[${i}]`,r));else if(typeof n==="object")for(let[r,i]of Object.entries(n))this.#re(e,`${t}[${r}]`,i);else e.append(t,String(n))}#Ht(e){let t=new Map;for(let{name:n}of e)t.set(n,(t.get(n)??0)+1);return new Set([...t].filter(([,n])=>n>1).map(([n])=>n))}#Ce(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Oe(e){return oe(e)}#Re(e){_(e,(t)=>this.#J(t),(t,n)=>this.#j(`client op "${t}"`,n))}#$e(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#Y()}#j(e,t){if(!this.#$e())return;let n=t.to;if(typeof n!=="string"||n===""||n==="@root")return;let r="";if(!t.global)if(this.element?.matches?.(n))r=" — the selector matches this component's own root, which root-scoped resolution never includes; use to: :root";else if(U(this.element,n)>0)r=" — it matches only inside a nested reactive root (excluded by ownership scoping); use global: true";else{let i=U(globalThis.document,n);if(i>0)r=` — it matches ${i} element(s) outside this scope; use global: true`}Ke(e,n,`scoped to #${this.element?.id||"?"}`,r)}#J(e){let t=e.to;if(t==="@root")return[this.element];if(typeof t!=="string"||t==="")return[];if(e.global)return[...document.querySelectorAll(t)];return[...this.element.querySelectorAll(t)].filter((n)=>this.#n(n))}#Vt(e,t){if(e?.checked!=="keep")return!1;let n=t?.type;return n==="checkbox"||n==="radio"}#Ut(e,t){if(!e)return null;let n=this.#qe(e,t,!0);return n.length?n:null}#d(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Gt(e,t,n){this.#Yt(e,t);let r=n?this.#qe(n,t,!1):[];$e();let i=!1;return()=>{if(i)return;i=!0,this.#Xt(e,t),qe();for(let s of r)s()}}#qe(e,t,n){let r=[];for(let i of this.#De(e,t)){if(e.add_class){let s=e.add_class.filter((o)=>!i.classList.contains(o));if(i.classList.add(...s),s.length)r.push(()=>i.classList.remove(...s))}if(e.remove_class){let s=e.remove_class.filter((o)=>i.classList.contains(o));if(i.classList.remove(...s),s.length)r.push(()=>i.classList.add(...s))}if(e.toggle_class)e.toggle_class.forEach((s)=>i.classList.toggle(s)),r.push(()=>e.toggle_class.forEach((s)=>i.classList.toggle(s)));if(e.hide)i.hidden=!0,r.push(()=>i.hidden=!1);if(e.show)i.hidden=!1,r.push(()=>i.hidden=!0)}if(t&&(e.disable||e.text!=null))r.push(this.#Kt(e,t));if(n&&e.checked==="keep"&&t&&"checked"in t){let i=t.checked;r.push(()=>t.checked=!i)}return r}#De(e,t){if(e.to==null)return t?[t]:[];let n=this.#J({to:e.to});if(n.length===0)this.#j("busy/optimistic hint",{to:e.to});return n}#Kt(e,t){let n=this.#_.get(t);if(n)n.count++;else this.#_.set(t,{count:1,disabled:t.disabled,html:t.innerHTML,hadText:e.text!=null,swappedTo:e.text});if(e.disable)t.disabled=!0;if(e.text!=null)t.innerHTML=e.text;return()=>this.#Zt(t,e)}#Yt(e,t){if(this.#h(t,e,1),this.#h(this.element,e,1),this.#p.set(e,(this.#p.get(e)??0)+1),this.#B++===0)this.element.setAttribute("aria-busy","true");for(let n of this.#Fe(e))this.#h(n,e,1)}#Xt(e,t){this.#h(t,e,-1),this.#h(this.element,e,-1);let n=(this.#p.get(e)??1)-1;if(n<=0)this.#p.delete(e);else this.#p.set(e,n);if(--this.#B<=0)this.#B=0,this.element.removeAttribute("aria-busy");for(let r of this.#Fe(e))this.#h(r,e,-1)}#h(e,t,n){if(!e||typeof e.getAttribute!=="function")return;let r=this.#I.get(e)??new Map,i=(r.get(t)??0)+n;if(i<=0)r.delete(t);else r.set(t,i);if(r.size===0){this.#I.delete(e),e.removeAttribute("data-reactive-busy");return}this.#I.set(e,r),e.setAttribute("data-reactive-busy",[...r.keys()].join(" "))}#Fe(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((n)=>n.getAttribute("data-reactive-busy-on")===e&&this.#n(n))}#Zt(e,t){let n=this.#_.get(e);if(!n)return;if(--n.count>0)return;if(this.#_.delete(e),!e.isConnected)return;if(t.disable)e.disabled=n.disabled;if(n.hadText&&e.innerHTML===n.swappedTo)e.innerHTML=n.html}#Qt(e){if(!e||typeof e!=="object")return null;let{class:t,...n}=e;return t==null?e:{...n,add_class:t}}#en(){return this.#Me??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#tn(){if(this.#W!=null)return this.#W;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#W=Number.isFinite(t)&&t>0?t:30000}#nn(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#rn(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}export{Re as ACTIVE_ATTR,Y as LATENCY_KEY,Nn as __markReactiveConnectedForTest,wn as __resetReactiveDismissForTest,Sn as __resetReactiveEffectsForTest,kn as __resetReactiveLatencyForTest,En as __resetReactiveOfflineForTest,_n as __resetReactiveRegistrationForTest,_t as checkReactiveRegistration,Ln as default,kt as disableLatencySim,Et as enableLatencySim,$e as enterReactiveActivity,Tt as escapeRegExp,qe as exitReactiveActivity,An as pendingDeferVia,xn as reactiveActivityCount,le as registerReactiveActions,nt as registerReactiveDefer,ut as registerReactiveDismiss,dt as registerReactiveEffects,tt as registerReactiveJs,St as registerReactiveOffline,et as registerReactiveToken,Qe as registerReactiveVisit,Tn as resetReactiveActivity,bn as resetReactiveDefers};
2
2
 
3
- //# debugId=434E66D6BA5767A464756E2164756E21
3
+ //# debugId=A13F2ADCE2F81E9564756E2164756E21
4
4
  //# sourceMappingURL=reactive_controller.min.js.map