phlex-reactive 0.11.5 → 0.11.6

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 Xj}from"@hotwired/stimulus";import{confirmResolver as w}from"phlex/reactive/confirm";import{computeReducer as Zj}from"phlex/reactive/compute";import{confirmPredicate as $j}from"phlex/reactive/confirm_predicate";function Jj(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:visit"])return;j["reactive:visit"]=function(){let X=this.getAttribute("data-url");if(X)window.Turbo.visit(X,{action:"advance"})}}function Qj(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:token"])return;j["reactive:token"]=function(){let X=this.getAttribute("data-reactive-token-value"),Z=this.getAttribute("target");if(!X||!Z)return;let $=document.getElementById(Z);if($)$.setAttribute("data-reactive-token-value",X)}}function Gj(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:js"])return;j["reactive:js"]=function(){let X=e(this.getAttribute("data-reactive-ops"));if(!X.length)return;let Z=this.getAttribute("target"),$=Z?document.getElementById(Z):null;if(Z&&!$)return;jj(X,(J)=>bj(J,$))}}var N=new Map;function p(j,X){let Z=!N.has(j);if(N.set(j,X),Z)l()}function x(j){if(N.delete(j))o()}function fj(){N.clear(),T=!1}function pj(j){return N.get(j)?.via}var T=!1;function zj(){let j=window.Turbo?.StreamActions;if(!j||j["reactive:defer"])return;if(j["reactive:defer"]=function(){let X=this.getAttribute("target");if(!X)return;if(this.getAttribute("data-reactive-defer-via")==="stream"){qj(X,this);return}let Z=this.getAttribute("data-reactive-defer-token");if(!Z)return;P(X,Z)},!T&&typeof document<"u"&&document.addEventListener)T=!0,document.addEventListener("turbo:before-stream-render",Kj)}function Kj(j){let Z=j.target?.getAttribute?.("target");if(!Z)return;let $=Z.startsWith("reactive-defer-src-")?Z.slice(19):Z;if(N.get($)?.via==="stream")x($)}function P(j,X){let Z=document.getElementById(j);if(!Z){console.warn(`[phlex-reactive] reactive:defer target #${j} is not on the page — skipped`);return}m(j),g(Z);let $={via:"fetch",abort:new AbortController,timedOut:!1};p(j,$),Yj(j,$,X)}function qj(j,X){let Z=document.getElementById(j);if(!Z){console.warn(`[phlex-reactive] reactive:defer target #${j} is not on the page — skipped`);return}let $=X.getAttribute("data-reactive-defer-src");if(!$)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let Q=X.getAttribute("data-reactive-defer-token");if(Q){P(j,Q);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}m(j),g(Z);let J=document.createElement("pgbus-stream-source");J.id=u(j),J.setAttribute("src",$),J.setAttribute("since-id",X.getAttribute("data-reactive-defer-since-id")??"0"),J.setAttribute("hidden",""),document.body.appendChild(J),p(j,{via:"stream"})}function u(j){return`reactive-defer-src-${j}`}async function Yj(j,X,Z){let $=setTimeout(()=>{X.timedOut=!0,X.abort.abort()},Wj()),J;try{J=await fetch(Uj(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":Hj()},body:JSON.stringify({token:Z}),credentials:"same-origin",signal:X.abort.signal})}catch(G){if(clearTimeout($),N.get(j)!==X)return;console.error("[phlex-reactive] deferred render failed",G),F(j,Z);return}if(N.get(j)!==X){clearTimeout($);return}if(J.status===204){clearTimeout($),h(j);return}if(!J.ok){clearTimeout($),console.error(`[phlex-reactive] deferred render failed: HTTP ${J.status}`),F(j,Z,J.status);return}let Q;try{Q=await J.text()}catch(G){if(clearTimeout($),N.get(j)!==X)return;console.error("[phlex-reactive] deferred render failed reading the body",G),F(j,Z);return}if(clearTimeout($),N.get(j)!==X)return;h(j),window.Turbo.renderStreamMessage(Q)}function m(j){let X=N.get(j);if(!X)return;if(x(j),X.via==="fetch")X.abort.abort();else document.getElementById(u(j))?.remove?.()}function g(j){j.setAttribute("data-reactive-defer-pending","true"),j.setAttribute("aria-busy","true")}function c(j){j.removeAttribute("data-reactive-defer-pending"),j.removeAttribute("aria-busy")}function h(j){x(j);let X=document.getElementById(j);if(!X)return;c(X),X.removeAttribute("data-reactive-error")}function F(j,X,Z){x(j);let $=document.getElementById(j);if(!$)return;c($),$.setAttribute("data-reactive-error","defer");let J=()=>{let Q=document.getElementById(j);if(!Q){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}Q.removeAttribute("data-reactive-error"),P(j,X)};$.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:j,status:Z,retry:J}}))}function Uj(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function Hj(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function Wj(){let j=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,X=Number(j);return Number.isFinite(X)&&X>0?X:30000}var I=!1;function _j(){if(I)return;if(typeof document>"u"||!document.addEventListener)return;I=!0,document.addEventListener("turbo:before-stream-render",Lj)}function Lj(j){let X=j.detail,Z=X?.render;if(typeof Z!=="function"||Z.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(C);else setTimeout(C,0);return}let $=async(J)=>{await Z(J),C()};$.__reactiveDismissWrapped=!0,X.render=$}function C(){let j=document.querySelectorAll("[data-reactive-dismiss-after]");for(let X of j){if(X.hasAttribute("data-reactive-dismiss-scheduled"))continue;let Z=Number(X.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite(Z)||Z<=0)continue;X.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>X.remove(),Z)}}function uj(){I=!1}var k=!1;function Vj(){if(k)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;k=!0;let j=()=>{let X=document.documentElement;if(typeof X?.toggleAttribute!=="function")return;X.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};j(),window.addEventListener("online",j),window.addEventListener("offline",j)}function mj(){k=!1}var S="phlex-reactive:latency",O=!1;function Nj(j){if(typeof sessionStorage>"u")return;sessionStorage.setItem(S,String(j))}function Mj(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem(S),O=!1}function Aj(){if(typeof window>"u"||typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content!=="development")return;window.PhlexReactive={enableLatencySim:Nj,disableLatencySim:Mj}}function gj(){O=!1}var d="data-reactive-active",M=0;function l(){if(M++,M===1)s("reactive:busy")}function o(){if(M===0)return;if(M--,M===0)s("reactive:idle")}function cj(){return M}function dj(){M=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(d)}function s(j){if(typeof document>"u")return;let X=document.documentElement;if(typeof X?.toggleAttribute==="function")X.toggleAttribute(d,M>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(j,{detail:{count:M}}))}function y(){Jj(),Qj(),Gj(),zj(),_j(),Vj(),Aj()}function Bj(j){return j.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}if(typeof window<"u")if(window.Turbo)y();else document.addEventListener("turbo:load",y,{once:!0});var E=!1;function Oj(){if(E)return;if(typeof document>"u")return;let j=document.querySelectorAll('[data-controller~="reactive"]');if(!j||j.length===0)return;console.warn("[phlex-reactive] found "+j.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 lj(){E=!1}function oj(){E=!0}if(typeof window<"u"&&typeof document<"u"){let j=()=>setTimeout(Oj,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",j,{once:!0});else j()}var xj=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function Pj(j){let X=String(j).toLowerCase();return X.startsWith("on")||xj.has(X)}function Ej(j,X,Z){let[$,J,Q]=X;j.classList.add($,J),Z(),requestAnimationFrame(()=>{j.classList.remove(J),j.classList.add(Q)});let G=!1,K=()=>{if(G)return;G=!0,j.classList.remove($,Q)};j.addEventListener("animationend",K,{once:!0}),setTimeout(K,350)}var v=Object.freeze({show:(j,X)=>R(j,!1,X),hide:(j,X)=>R(j,!0,X),toggle:(j,X)=>R(j,!j.hidden,X),add_class:(j,X)=>j.classList.add(...X.classes??[]),remove_class:(j,X)=>j.classList.remove(...X.classes??[]),toggle_class:(j,X)=>(X.classes??[]).forEach((Z)=>j.classList.toggle(Z)),set_attr:(j,X)=>{if(D(X.name))j.setAttribute(X.name,X.value??"")},remove_attr:(j,X)=>{if(D(X.name))j.removeAttribute(X.name)},toggle_attr:(j,X)=>{if(!D(X.name))return;if(j.hasAttribute(X.name))j.removeAttribute(X.name);else j.setAttribute(X.name,"")},focus:(j)=>j.focus?.(),focus_first:(j)=>Sj(j)?.focus?.(),text:(j,X)=>{let Z=String(X.value??"");if(j.textContent!==Z)j.textContent=Z},dispatch:(j,X)=>{j.dispatchEvent(new CustomEvent(X.name,{bubbles:!0,composed:!0,detail:X.detail??{}}))}});function R(j,X,Z){if(Z?.transition)Ej(j,Z.transition,()=>j.hidden=X);else j.hidden=X}function D(j){if(!Pj(j))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(j)} — skipped`),!1}var i=/^#[A-Za-z_][\w-]*$/;function Fj(j){if(typeof j==="string"&&i.test(j))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(j)} — skipped`),!1}function Cj(j,X){let Z=j.getAttribute("data-reactive-show-equals");if(Z!==null)return X===Z;let $=j.getAttribute("data-reactive-show-not");if($!==null)return X!==$;let J=j.getAttribute("data-reactive-show-in");if(J!==null){try{let Q=JSON.parse(J);if(Array.isArray(Q))return Q.includes(X)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(J)} — skipped`),null}for(let Q of n){let G=j.getAttribute(`data-reactive-show-${Q}`);if(G!==null)return a(Q,G,X)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}var n=["gte","gt","lte","lt"];function a(j,X,Z){let $=Number(X);if(Number.isNaN($))return console.warn(`[phlex-reactive] reactive_show ${j}: needs a numeric literal, got ${JSON.stringify(X)} — skipped`),null;let J=Z==null?"":String(Z).trim(),Q=J===""?NaN:Number(J);if(Number.isNaN(Q))return!1;switch(j){case"gte":return Q>=$;case"gt":return Q>$;case"lte":return Q<=$;case"lt":return Q<$;default:return null}}function r(j,X){if(!j||typeof j!=="object")return null;if(typeof j.equals==="string")return X===j.equals;if(typeof j.not==="string")return X!==j.not;if(Array.isArray(j.in))return j.in.includes(X);for(let Z of n)if(Z in j)return a(Z,j[Z],X);return null}var f="[data-reactive-show-field], [data-reactive-show]";function Rj(j){try{let X=JSON.parse(j);if(X&&typeof X==="object"&&!Array.isArray(X))return X}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(j)} — skipped`),null}function b(j,X){if(!j||typeof j!=="object"||typeof j.field!=="string")return!1;let Z=X(j.field)??"";return r(j,Z)===!0}function t(j,X){if(!Array.isArray(j)||j.length===0)return null;return j.some((Z)=>Array.isArray(Z)&&Z.length>0&&Z.every(($)=>b($,X)))}function Dj(j,X){if(!j||typeof j!=="object")return null;let Z=j.any;if(Array.isArray(Z)&&(Z.length===0||Array.isArray(Z[0])))return t(Z,X);return Tj(j,X)}function Tj(j,X){let Z=Array.isArray(j.all)?"all":Array.isArray(j.any)?"any":null;if(!Z)return null;let $=j[Z];if($.length===0)return null;let J=$.map((Q)=>b(Q,X));return Z==="all"?J.every(Boolean):J.some(Boolean)}function Ij(j){if(typeof j==="string"&&i.test(j))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(j)} — skipped`),!1}var kj='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Sj(j){return j.querySelectorAll?.(kj)?.[0]??null}function e(j){if(Array.isArray(j))return j;if(typeof j!=="string")return[];try{let X=JSON.parse(j);return Array.isArray(X)?X:[]}catch{return[]}}function jj(j,X){for(let Z of j){if(!Array.isArray(Z))continue;let[$,J={}]=Z;if(!Object.hasOwn(v,$)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify($)} — skipped`);continue}for(let Q of X(J))v[$](Q,J)}}function bj(j,X){let Z=j.to;if(X){if(Z==="@root")return[X];if(typeof Z!=="string"||Z==="")return[];if(j.global)return[...document.querySelectorAll(Z)];return[...X.querySelectorAll(Z)]}if(typeof Z!=="string"||Z===""||Z==="@root")return[];return[...document.querySelectorAll(Z)]}class sj extends Xj{static values={token:String};#h;#N=new Map;#q=new Map;#Yj;#F;#y;#C=0;#Y=new Map;#R=new WeakMap;#M=new Map;#v=new WeakSet;#U;#H;#W;#j;#$;#_;#f=!1;#D=0;#p=!1;#L;#A;connect(){if(E=!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.#u(),this.#A=()=>this.#u(),this.element.addEventListener?.("turbo:morph-element",this.#A);if(this.#Uj()){if(this.#U=()=>this.#I(),this.element.addEventListener?.("turbo:morph-element",this.#U),this.#I(),this.element.getAttribute?.("data-reactive-warn-unsaved")==="true")this.#kj()}if(this.#bj())this.#j=()=>this.#t(),this.element.addEventListener?.("input",this.#j),this.element.addEventListener?.("change",this.#j),this.element.addEventListener?.("turbo:morph-element",this.#j),this.#t();if(this.#P())this.#$=(j)=>{if(j?.type==="input"&&!this.#fj(j))return;this.#V()},this.element.addEventListener?.("input",this.#$),this.element.addEventListener?.("turbo:morph-element",this.#$),this.#V();if(this.#E())this.#_=()=>this.#b(),this.element.addEventListener?.("turbo:morph-element",this.#_),this.#b();if(this.#vj())this.#L=()=>this.recompute(),this.element.addEventListener?.("turbo:morph-element",this.#L),this.recompute()}#Uj(){if((this.element.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let j=this.element.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let X of j)if(this.#Z(X))return!0;return!1}disconnect(){if(this.#Bj(),this.#xj(),this.#Sj(),this.#yj(),this.#pj(),this.#oj(),this.#sj(),this.#A)this.element.removeEventListener?.("turbo:morph-element",this.#A)}#u(){let j=this.element;if(!j?.id)return;let X=j.getAttribute?.("data-reactive-defer-token");if(!X)return;if(j.getAttribute?.("data-reactive-defer-pending")!=="true")return;P(j.id,X)}dispatch(j){let{action:X,params:Z,debounce:$,throttle:J,confirm:Q,confirmWhen:G,outside:K,window:z,optimistic:Y}=j.params;if(!X)return;let H=j.params.busy??this.#$X(j.params.loading);if(K&&this.element.contains(j.target))return;let L=j.currentTarget??j.target;if(!z&&!this.#aj(Y,L))j.preventDefault();let W=this.#n(Q,G);if(!W)return this.#d(L,X,Z,$,J,Y,H);Promise.resolve().then(()=>w(W)).catch(()=>!1).then((_)=>{if(_)this.#d(L,X,Z,$,J,Y,H)})}runOps(j){let{ops:X,confirm:Z,confirmWhen:$,outside:J,window:Q}=j.params;if(J&&this.element.contains(j.target))return;if(!Q)j.preventDefault();let G=this.#n(Z,$);if(!G)return this.#Qj(this.#Jj(X));Promise.resolve().then(()=>w(G)).catch(()=>!1).then((K)=>{if(K)this.#Qj(this.#Jj(X))})}trackDirty(){this.#I()}recompute(j){if(j&&this.#v.has(j))return;let X=this.#Wj(),Z=X.map(([q])=>q),$=this.element.getAttribute?.("data-reactive-scope")||null,J=(q)=>$&&!q.includes("[")?`${$}[${q}]`:q,Q=this.#X(),G=new Map,K=(q)=>{if(G.has(q))return G.get(q);let U=null;for(let A of this.element.querySelectorAll(`[name="${J(q)}"]`))if(Q(A)){U=A;break}return G.set(q,U),U};for(let q of Z)this.#g(q,K(q)?.value??"");let z=this.element.getAttribute("data-reactive-compute-reducer-param"),Y=z?Zj(z):null;if(!Y){this.#c({},K);return}let H=this.#Hj("data-reactive-compute-outputs-param"),L={};for(let[q,U]of X){let A=K(q);if(U==="string")L[q]=A?.value??"";else{let V=Number(A?.value);L[q]=Number.isFinite(V)?V:0}}let W=Y(L,{changed:this.#_j(j,Z,$)})||{},_=[];for(let q of H){if(!(q in W))continue;let U=K(q);if(!U)continue;if(String(W[q])===U.value)continue;U.value=W[q],_.push(U)}for(let q of Object.keys(W)){let U=W[q];if(U===void 0||U===null)continue;this.#g(q,U)}this.#c(W,K);for(let q of _){let U=new Event("input",{bubbles:!0});this.#v.add(U),q.dispatchEvent(U)}}listnavNext(j){this.#m(j,1)}listnavPrev(j){this.#m(j,-1)}listnavPick(j){let X=this.#B(j),Z=X.findIndex(($)=>$.hasAttribute("data-reactive-highlighted"));if(Z<0)return;j.preventDefault(),X[Z].click()}listnavClose(j){for(let X of this.#B(j))X.removeAttribute("data-reactive-highlighted")}#m(j,X){let Z=this.#B(j);if(!Z.length)return;j.preventDefault();let $=Z.findIndex((G)=>G.hasAttribute("data-reactive-highlighted")),J=$<0?X>0?0:Z.length-1:($+X+Z.length)%Z.length;for(let G of Z)G.removeAttribute("data-reactive-highlighted");let Q=Z[J];Q.setAttribute("data-reactive-highlighted","true"),Q.scrollIntoView?.({block:"nearest"})}#B(j){let Z=(j?.currentTarget??j?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!Z)return[];let $=this.#X();return Array.from(this.element.querySelectorAll(Z)).filter((J)=>!J.hidden&&$(J))}tagsAdd(j){if(!this.#E())return;if(j?.defaultPrevented)return;if(this.#B(j).some(($)=>$.hasAttribute?.("data-reactive-highlighted")))return;j?.preventDefault?.();let X=j?.currentTarget??j?.target;if(!X)return;if(!this.#Xj(String(X.value??"").split(",")))return;if(X.value="",this.#P())this.#V()}tagsPick(j){if(!this.#E())return;j?.preventDefault?.();let Z=(j?.currentTarget??j?.target)?.getAttribute?.("data-reactive-tag-param");if(!Z)return;if(!this.#Xj([Z]))return;let $=this.#uj();if(!$)return;$.value="",this.#V(),$.focus?.()}tagsRemove(j){if(!this.#E())return;j?.preventDefault?.();let Z=(j?.currentTarget??j?.target)?.getAttribute?.("data-reactive-tag-param");if(!Z)return;let $=this.#k();if(!$)return;let J=this.#S($),Q=J.filter((G)=>G.toLowerCase()!==Z.toLowerCase());if(Q.length===J.length)return;this.#Zj($,Q)}nestedAdd(j){j?.preventDefault?.();let Z=(j?.currentTarget??j?.target)?.getAttribute?.("data-reactive-association-param");if(!Z)return;if(typeof this.element?.querySelectorAll!=="function")return;let $=this.#X(),J=[...this.element.querySelectorAll(`[data-reactive-nested-list="${Z}"]`)].find($),G=[...this.element.querySelectorAll(`[data-reactive-nested-template="${Z}"]`)].find($)?.content?.firstElementChild;if(!J||!G){this.#lj(Z);return}let K=G.cloneNode(!0);this.#dj(K,this.#cj()),J.appendChild(K),[...K.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.()}nestedRemove(j){j?.preventDefault?.();let Z=(j?.currentTarget??j?.target)?.closest?.("[data-reactive-nested-row]");if(!Z)return;if(Z.closest?.('[data-controller~="reactive"]')!==this.element)return;let $=[...Z.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if($){if($.value="1",typeof $.dispatchEvent==="function")$.dispatchEvent(new Event("input",{bubbles:!0}));Z.hidden=!0}else Z.parentNode?.removeChild?.(Z)}#Hj(j){let X=this.element.getAttribute(j);if(!X)return[];try{let Z=JSON.parse(X);return Array.isArray(Z)?Z:[]}catch{return[]}}#Wj(){let j=this.element.getAttribute("data-reactive-compute-inputs-param");if(!j)return[];try{let X=JSON.parse(j);if(Array.isArray(X))return X.map((Z)=>[Z,"number"]);if(X&&typeof X==="object")return Object.entries(X);return[]}catch{return[]}}#_j(j,X,Z){let $=j?.target;if(!$?.name||typeof $.closest!=="function")return null;let J=this.#Lj($.name,Z);if(!X.includes(J))return null;return this.#Z($)?J:null}#Lj(j,X){if(!X)return j;let Z=`${X}[`;return j.startsWith(Z)&&j.endsWith("]")?j.slice(Z.length,-1):j}#g(j,X){let Z=String(X);for(let $ of this.#Vj(j)){if($.textContent===Z)continue;$.textContent=Z}}#Vj(j){let X=this.element.querySelectorAll(`[data-reactive-text="${j}"]`);return Array.from(X).filter((Z)=>this.#Z(Z))}#c(j,X){let Z=this.#Nj();for(let[$,J]of Object.entries(Z)){let Q=$ in j?j[$]:X($)?.value;if(Q===void 0||Q===null)continue;let G=String(Q);for(let K of Array.isArray(J)?J:[J]){if(!Fj(K))continue;for(let z of document.querySelectorAll(K)){if(z.textContent===G)continue;z.textContent=G}}}}#Nj(){let j=this.element.getAttribute("data-reactive-compute-mirror-param");if(!j)return{};try{let X=JSON.parse(j);return X&&typeof X==="object"&&!Array.isArray(X)?X:{}}catch{return{}}}#d(j,X,Z,$,J,Q,G){if(this.#x("reactive:before-dispatch",{action:X,params:this.#$j(Z),element:this.element},{cancelable:!0}).defaultPrevented)return;let z=Number($)||0;if(z>0)return this.#Aj(j,z,X,Z,Q,G);let Y=Number(J)||0;if(Y>0)return this.#Oj(j,Y,X,Z,Q,G);return this.#O(X,Z,Q,j,G)}#O(j,X,Z,$,J){let Q=this.#rj(Z,$),G=this.#tj(j,$,J),K=this.#l()?this.#Mj(Z,$):null;return this.queue=(this.queue??Promise.resolve()).then(()=>this.#Dj(j,X,Q,G,K)),this.queue}#Mj(j,X){if(!j?.hide)return null;let Z=this.#Kj(j,X);if(!Z.length)return null;return()=>{let $=Z.filter((J)=>J.isConnected&&!J.hidden);if(!$.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.",$)}}#Aj(j,X,Z,$,J,Q){this.#T(j);let G=()=>{this.#T(j),this.#O(Z,$,J,j,Q)},K=setTimeout(G,X);j?.addEventListener?.("blur",G,{once:!0}),this.#N.set(j,{timer:K,flush:G})}#T(j){let X=this.#N.get(j);if(!X)return;clearTimeout(X.timer),j?.removeEventListener?.("blur",X.flush),this.#N.delete(j)}#Bj(){for(let j of[...this.#N.keys()])this.#T(j)}#Oj(j,X,Z,$,J,Q){let G=this.#q.get(j)??new Map;if(G.has(Z))return;let K=setTimeout(()=>{if(G.delete(Z),G.size===0)this.#q.delete(j)},X);return G.set(Z,K),this.#q.set(j,G),this.#O(Z,$,J,j,Q)}#xj(){for(let j of this.#q.values())for(let X of j.values())clearTimeout(X);this.#q.clear()}#x(j,X,{cancelable:Z=!1}={}){let $=new CustomEvent(j,{bubbles:!0,composed:!0,cancelable:Z,detail:X});return(this.element.isConnected?this.element:document).dispatchEvent($),$}#J(j,X,Z,$){let J=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#O(j,X)};this.#x("reactive:error",{action:j,params:Z,...$,retry:J})}#Q(j){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",j)}#Pj(){this.element?.removeAttribute?.("data-reactive-error")}#Ej(){let j=document.querySelector("[data-reactive-error-flash]");if(!j?.content)return;let X=j.getAttribute("data-reactive-error-flash")||"flash",Z=document.getElementById(X);if(!Z)return;Z.appendChild(j.content.cloneNode(!0))}#Fj(){if(typeof sessionStorage>"u")return Promise.resolve();let j=Number(sessionStorage.getItem(S));if(!Number.isFinite(j)||j<=0)return Promise.resolve();if(!O)O=!0,console.warn(`[phlex-reactive] latency simulator ACTIVE — every action is delayed by ${j}ms. Call PhlexReactive.disableLatencySim() (or clear sessionStorage) to turn it off.`);return new Promise((X)=>setTimeout(X,j))}#l(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#o(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}#Cj(j){if(!j)return[];let X=[],Z=/<turbo-stream\b([^>]*)>/g,$;while(($=Z.exec(j))!==null){let J=$[1],Q=J.match(/\baction="([^"]*)"/)?.[1]??"?",G=J.match(/\btarget="([^"]*)"/)?.[1];X.push(G?`${Q} → #${G}`:Q)}return X}#Rj(j){let{action:X,status:Z,ms:$}=j,Q=`reactive ${this.element?.id?`#${this.element.id} `:""}${X} → ${Z??"—"} (${Math.round($)}ms)`;if(console.groupCollapsed(Q),console.log(`params: [${j.paramNames.join(", ")}] + collected: [${j.fieldNames.join(", ")}]`),console.log(`encoding: ${j.encoding}`),j.streams.length)console.log(`streams: ${j.streams.join(" ")}`);console.log(`token: ${j.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}async#Dj(j,X,Z,$,J){let{fields:Q,files:G}=this.#a(),K=this.#$j(X),z={...Q,...K},Y=this.#G,H=G.length>0,L=H?this.#ij(Y,j,z,G):JSON.stringify({token:Y,act:j,params:z}),W=this.#l()?{action:j,paramNames:Object.keys(K),fieldNames:Object.keys(Q),encoding:H?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#o()}:null;await this.#Fj();try{if(navigator.onLine===!1){this.#z(Z),this.#Q("offline"),this.#J(j,X,z,{kind:"offline"});return}let _;try{let V={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#GX()};if(!H)V["Content-Type"]="application/json";let B=this.#zX();if(B)V["X-Pgbus-Connection"]=B;_=await fetch(this.#JX(),{method:"POST",headers:V,body:L,credentials:"same-origin",signal:AbortSignal.timeout(this.#QX())})}catch(V){if(console.error("[phlex-reactive] action error",V),this.#z(Z),V?.name==="TimeoutError"||V?.name==="AbortError"){this.#Q("timeout"),this.#J(j,X,z,{kind:"timeout"});return}this.#Ej(),this.#Q("network"),this.#J(j,X,z,{kind:"network"});return}if(W)W.status=_.status;if(_.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#z(Z),this.#Q("redirected"),this.#J(j,X,z,{kind:"redirected",status:_.status});return}if(!_.ok){let V=await _.text();if(console.error(`[phlex-reactive] action failed: HTTP ${_.status}`,V),this.#z(Z),(_.headers.get("Content-Type")||"").includes("turbo-stream")){let B=this.#i(V);if(this.#G=B??this.#G,W)this.#s(W,V,B);window.Turbo.renderStreamMessage(V)}this.#Q("http"),this.#J(j,X,z,{kind:"http",status:_.status,body:V});return}let q=_.headers.get("Content-Type")||"";if(!q.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${q}" — no update applied`),this.#z(Z),this.#Q("content-type"),this.#J(j,X,z,{kind:"content-type",status:_.status});return}let U=await _.text(),A=this.#i(U);if(this.#G=A??this.#G,W)this.#s(W,U,A);if(window.Turbo.renderStreamMessage(U),J)queueMicrotask(J);this.#Pj(),this.#x("reactive:applied",{action:j,params:z,html:U})}catch(_){console.error("[phlex-reactive] action error",_),this.#z(Z),this.#x("reactive:error",{action:j,params:z,kind:"apply"})}finally{if($?.(),W)this.#Rj({...W,ms:this.#o()-W.started})}}#s(j,X,Z){j.streams=this.#Cj(X),j.tokenRefreshed=Z!=null}get#G(){return this.#h??this.tokenValue}set#G(j){this.#h=j}#i(j){let X=this.element.id;if(!X)return j.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:Z,self:$}=this.#Tj(X),J=j.match(Z);if(J)return J[1];let Q=j.match($);if(Q)return Q[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#Tj(j){let X=this.#y;if(X&&X.id===j)return X;let Z=Bj(j);return this.#y={id:j,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${Z}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${Z}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#Z(j){return j.closest('[data-controller~="reactive"]')===this.element}#X(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(X)=>this.#Z(X)}#n(j,X){if(j)return j;if(!X)return null;let Z=X;if(typeof X==="string")try{Z=JSON.parse(X)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(X)} — skipped`),null}if(!Z||typeof Z!=="object")return null;let{fields:$}=this.#a(),J=(G)=>$[G],Q;if(typeof Z.predicate==="string"){let G=$j(Z.predicate);if(!G)return console.warn(`[phlex-reactive] confirm predicate "${Z.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;Q=!!G($)}else Q=t(Z.groups?.any,J)===!0;return Q?Z.message:null}#a(){let j={},X=[],Z=this.#X();return this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach(($)=>{if(!Z($))return;if($.type==="file")for(let J of $.files??[])X.push({name:$.name,file:J,multiple:$.multiple});else if($.type==="checkbox")j[$.name]=$.checked;else if($.type==="radio"){if($.checked)j[$.name]=$.value}else j[$.name]=$.value}),this.element.querySelectorAll("[name]:is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])").forEach(($)=>{if(!Z($))return;let J=$.getAttribute("name");if(!J)return;let Q=j[J];if(Q==null||Q==="")j[J]=$.value??$.textContent??$.innerHTML??""}),{fields:j,files:X}}#I(){if(typeof this.element?.querySelectorAll!=="function")return;let j=0;if(this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((X)=>{if(!this.#Z(X))return;if(X.type==="file")return;if(this.#Ij(X))X.setAttribute("data-reactive-dirty","true"),j++;else X.removeAttribute("data-reactive-dirty")}),j>0)this.element.setAttribute("data-reactive-dirty",String(j));else this.element.removeAttribute("data-reactive-dirty")}#Ij(j){if(j.type==="checkbox"||j.type==="radio")return j.checked!==j.defaultChecked;if(j.tag==="select"||j.options)return Array.from(j.options??[]).some((X)=>X.selected!==X.defaultSelected);return j.value!==j.defaultValue}#r(){let j=this.element.getAttribute?.("data-reactive-dirty"),X=Number(j);return Number.isFinite(X)&&X>0?X:0}#kj(){if(typeof window>"u"||typeof window.addEventListener!=="function")return;this.#H=(j)=>{if(this.#r()===0)return;return j.preventDefault(),j.returnValue="You have unsaved changes.",j.returnValue},this.#W=(j)=>{if(this.#r()===0)return;if(!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))j.preventDefault?.()},window.addEventListener("beforeunload",this.#H),window.addEventListener("turbo:before-visit",this.#W)}#Sj(){if(this.#U)this.element.removeEventListener?.("turbo:morph-element",this.#U),this.#U=void 0;if(typeof window<"u"&&typeof window.removeEventListener==="function"){if(this.#H)window.removeEventListener("beforeunload",this.#H);if(this.#W)window.removeEventListener("turbo:before-visit",this.#W)}this.#H=void 0,this.#W=void 0}#bj(){if(this.element.getAttribute?.("data-reactive-show-targets"))return!0;let j=this.element.querySelectorAll?.(f)??[];for(let X of j)if(this.#Z(X))return!0;return!1}#t(){if(typeof this.element?.querySelectorAll!=="function")return;let j=this.#X(),X=this.element.getAttribute?.("data-reactive-scope")||null,Z=new Map,$=(J)=>{if(!Z.has(J))Z.set(J,this.#jj(J,j,X));return Z.get(J)};for(let J of this.element.querySelectorAll(f)){if(!j(J))continue;let Q=J.getAttribute("data-reactive-show");if(Q!==null){let Y=Dj(Rj(Q),$);if(Y!==null)this.#e(J,Y,j,X);continue}let G=J.getAttribute("data-reactive-show-field");if(!G)continue;let K=$(G);if(K===null)continue;let z=Cj(J,K);if(z===null)continue;this.#e(J,z,j,X)}this.#wj(j,Z,X)}#e(j,X,Z,$){if(j.hidden=!X,j.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof j.querySelectorAll!=="function")return;for(let J of j.querySelectorAll("input[name], select[name], textarea[name]"))if(Z(J))J.disabled=!X;if(j.name&&Z(j))j.disabled=!X}#wj(j,X,Z){let $=this.#hj();for(let[J,Q]of Object.entries($)){if(!Q||typeof Q!=="object"||Array.isArray(Q))continue;if(!X.has(J))X.set(J,this.#jj(J,j,Z));let G=X.get(J);if(G===null)continue;let K=()=>G;for(let[z,Y]of Object.entries(Q)){if(!Ij(z))continue;let H;if(Array.isArray(Y)){if(Y.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${z} — skipped`);continue}H=Y.every((L)=>b(L,K))}else{let L=r(Y,G);if(L===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${z} — skipped`);continue}H=L}for(let L of document.querySelectorAll(z))L.hidden=!H}}}#hj(){let j=this.element.getAttribute?.("data-reactive-show-targets");if(!j)return{};try{let X=JSON.parse(j);if(X&&typeof X==="object"&&!Array.isArray(X))return X}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: { ... })"),{}}#jj(j,X,Z){let $=Z&&!j.includes("[")?`${Z}[${j}]`:j,J=!1,Q=null;for(let G of this.element.querySelectorAll(`[name="${$}"]`)){if(!X(G))continue;if(G.type==="checkbox")return G.checked?"true":"false";if(G.type==="radio"){if(G.checked)return G.value??"";J=!0;continue}Q??=G}if(Q)return Q.value??"";return J?"":null}#yj(){if(!this.#j)return;this.element.removeEventListener?.("input",this.#j),this.element.removeEventListener?.("change",this.#j),this.element.removeEventListener?.("turbo:morph-element",this.#j),this.#j=void 0}#P(){return!!(this.element.getAttribute?.("data-reactive-filter-input")&&this.element.getAttribute?.("data-reactive-filter-option"))}#vj(){return this.element.getAttribute?.("data-reactive-compute-seed")==="true"}#fj(j){let X=this.element.getAttribute("data-reactive-filter-input");return!!X&&typeof j.target?.matches==="function"&&j.target.matches(X)}#V(){if(typeof this.element?.querySelectorAll!=="function")return;let j=this.element.getAttribute("data-reactive-filter-input"),X=this.element.getAttribute("data-reactive-filter-option");if(!j||!X)return;let Z=this.#X(),$=[...this.element.querySelectorAll(j)].find(Z);if(!$)return;let J=($.value??"").trim().toLowerCase(),Q=0;for(let z of this.element.querySelectorAll(X)){if(!Z(z))continue;let Y=(z.getAttribute("data-reactive-filter-text")??z.textContent??"").toLowerCase(),H=z.hasAttribute?.("data-reactive-tags-selected")||J!==""&&!Y.includes(J);if(z.hidden=H,H)z.removeAttribute("data-reactive-highlighted");else Q++}let G=this.element.getAttribute("data-reactive-filter-group");if(G)for(let z of this.element.querySelectorAll(G)){if(!Z(z))continue;let Y=[...z.querySelectorAll(X)].filter(Z);if(Y.length===0)continue;z.hidden=Y.every((H)=>H.hidden)}let K=this.element.getAttribute("data-reactive-filter-empty");if(K){for(let z of this.element.querySelectorAll(K))if(Z(z))z.hidden=Q>0}}#pj(){if(!this.#$)return;this.element.removeEventListener?.("input",this.#$),this.element.removeEventListener?.("turbo:morph-element",this.#$),this.#$=void 0}#E(){return!!this.element.getAttribute?.("data-reactive-tags-field")}#k(){if(typeof this.element?.querySelectorAll!=="function")return null;let j=this.element.getAttribute("data-reactive-tags-field");if(!j)return null;let X=this.#X();return[...this.element.querySelectorAll(j)].find(X)??null}#S(j){let X=new Set,Z=[];for(let $ of String(j.value??"").split(",")){let J=$.trim();if(J===""||X.has(J.toLowerCase()))continue;X.add(J.toLowerCase()),Z.push(J)}return Z}#Xj(j){let X=this.#k();if(!X)return!1;let Z=this.#S(X),$=new Set(Z.map((Q)=>Q.toLowerCase())),J=!1;for(let Q of j){let G=String(Q??"").trim();if(G===""||$.has(G.toLowerCase()))continue;$.add(G.toLowerCase()),Z.push(G),J=!0}if(J)this.#Zj(X,Z);return J}#Zj(j,X){if(j.value=X.join(","),typeof j.dispatchEvent==="function")j.dispatchEvent(new Event("input",{bubbles:!0}));this.#b()}#uj(){if(typeof this.element?.querySelectorAll!=="function")return null;let j=this.element.getAttribute("data-reactive-filter-input");if(!j)return null;let X=this.#X();return[...this.element.querySelectorAll(j)].find(X)??null}#b(){let j=this.#k();if(!j)return;let X=this.#S(j),Z=this.#X();this.#mj(X,Z),this.#gj(X,Z)}#mj(j,X){let Z=[...this.element.querySelectorAll("[data-reactive-tags-list]")].find(X);if(!Z)return;let J=[...this.element.querySelectorAll("[data-reactive-tags-template]")].find(X)?.content?.firstElementChild;if(!J){if(!this.#f)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.#f=!0;return}while(Z.firstChild)Z.removeChild(Z.firstChild);for(let Q of j){let G=J.cloneNode(!0);G.setAttribute?.("data-reactive-tag",Q);let K=G.matches?.("[data-reactive-tag-text]")?G:(G.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(K)K.textContent=Q;let z=[...G.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(G.matches?.('[data-action*="reactive#tagsRemove"]'))z.push(G);for(let Y of z)Y.setAttribute?.("data-reactive-tag-param",Q);Z.appendChild(G)}}#gj(j,X){let Z=new Set(j.map(($)=>$.toLowerCase()));for(let $ of this.element.querySelectorAll("[role=option]")){if(!X($))continue;let J=$.getAttribute?.("data-reactive-tag-param");if(!J)continue;if(Z.has(J.toLowerCase()))$.setAttribute("data-reactive-tags-selected","true"),$.hidden=!0,$.removeAttribute?.("data-reactive-highlighted");else if($.hasAttribute?.("data-reactive-tags-selected")){if($.removeAttribute("data-reactive-tags-selected"),!this.#P())$.hidden=!1}}if(this.#P())this.#V()}#cj(){return this.#D=Math.max(this.#D+1,Date.now()),this.#D}#dj(j,X){let Z=[j,...j.querySelectorAll?.("*")??[]];for(let $ of Z)for(let J of["name","id","for"]){let Q=$.getAttribute?.(J);if(Q&&Q.includes("NEW_ROW"))$.setAttribute?.(J,Q.replaceAll("NEW_ROW",String(X)))}}#lj(j){if(this.#p)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${j}"] container + <template data-reactive-nested-template="${j}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),this.#p=!0}#oj(){if(!this.#_)return;this.element.removeEventListener?.("turbo:morph-element",this.#_),this.#_=void 0}#sj(){if(!this.#L)return;this.element.removeEventListener?.("turbo:morph-element",this.#L),this.#L=void 0}#ij(j,X,Z,$){let J=new FormData;J.append("token",j),J.append("act",X);for(let[G,K]of Object.entries(Z))this.#w(J,`params[${G}]`,K);let Q=this.#nj($);for(let{name:G,file:K,multiple:z}of $){let H=z||Q.has(G)?`params[${G}][]`:`params[${G}]`;J.append(H,K,K.name)}return J}#w(j,X,Z){if(Z==null)j.append(X,"");else if(Array.isArray(Z))Z.forEach(($,J)=>this.#w(j,`${X}[${J}]`,$));else if(typeof Z==="object")for(let[$,J]of Object.entries(Z))this.#w(j,`${X}[${$}]`,J);else j.append(X,String(Z))}#nj(j){let X=new Map;for(let{name:Z}of j)X.set(Z,(X.get(Z)??0)+1);return new Set([...X].filter(([,Z])=>Z>1).map(([Z])=>Z))}#$j(j){if(!j)return{};try{return typeof j==="string"?JSON.parse(j):j}catch{return{}}}#Jj(j){return e(j)}#Qj(j){jj(j,(X)=>this.#Gj(X))}#Gj(j){let X=j.to;if(X==="@root")return[this.element];if(typeof X!=="string"||X==="")return[];if(j.global)return[...document.querySelectorAll(X)];return[...this.element.querySelectorAll(X)].filter((Z)=>this.#Z(Z))}#aj(j,X){if(j?.checked!=="keep")return!1;let Z=X?.type;return Z==="checkbox"||Z==="radio"}#rj(j,X){if(!j)return null;let Z=this.#zj(j,X,!0);return Z.length?Z:null}#z(j){if(!j)return;if(!this.element.isConnected)return;for(let X of j)X()}#tj(j,X,Z){this.#jX(j,X);let $=Z?this.#zj(Z,X,!1):[];l();let J=!1;return()=>{if(J)return;J=!0,this.#XX(j,X),o();for(let Q of $)Q()}}#zj(j,X,Z){let $=[];for(let J of this.#Kj(j,X)){if(j.add_class){let Q=j.add_class.filter((G)=>!J.classList.contains(G));if(J.classList.add(...Q),Q.length)$.push(()=>J.classList.remove(...Q))}if(j.remove_class){let Q=j.remove_class.filter((G)=>J.classList.contains(G));if(J.classList.remove(...Q),Q.length)$.push(()=>J.classList.add(...Q))}if(j.toggle_class)j.toggle_class.forEach((Q)=>J.classList.toggle(Q)),$.push(()=>j.toggle_class.forEach((Q)=>J.classList.toggle(Q)));if(j.hide)J.hidden=!0,$.push(()=>J.hidden=!1);if(j.show)J.hidden=!1,$.push(()=>J.hidden=!0)}if(X&&(j.disable||j.text!=null))$.push(this.#ej(j,X));if(Z&&j.checked==="keep"&&X&&"checked"in X){let J=X.checked;$.push(()=>X.checked=!J)}return $}#Kj(j,X){if(j.to==null)return X?[X]:[];return this.#Gj({to:j.to})}#ej(j,X){let Z=this.#M.get(X);if(Z)Z.count++;else this.#M.set(X,{count:1,disabled:X.disabled,html:X.innerHTML,hadText:j.text!=null,swappedTo:j.text});if(j.disable)X.disabled=!0;if(j.text!=null)X.innerHTML=j.text;return()=>this.#ZX(X,j)}#jX(j,X){if(this.#K(X,j,1),this.#K(this.element,j,1),this.#Y.set(j,(this.#Y.get(j)??0)+1),this.#C++===0)this.element.setAttribute("aria-busy","true");for(let Z of this.#qj(j))this.#K(Z,j,1)}#XX(j,X){this.#K(X,j,-1),this.#K(this.element,j,-1);let Z=(this.#Y.get(j)??1)-1;if(Z<=0)this.#Y.delete(j);else this.#Y.set(j,Z);if(--this.#C<=0)this.#C=0,this.element.removeAttribute("aria-busy");for(let $ of this.#qj(j))this.#K($,j,-1)}#K(j,X,Z){if(!j||typeof j.getAttribute!=="function")return;let $=this.#R.get(j)??new Map,J=($.get(X)??0)+Z;if(J<=0)$.delete(X);else $.set(X,J);if($.size===0){this.#R.delete(j),j.removeAttribute("data-reactive-busy");return}this.#R.set(j,$),j.setAttribute("data-reactive-busy",[...$.keys()].join(" "))}#qj(j){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((Z)=>Z.getAttribute("data-reactive-busy-on")===j&&this.#Z(Z))}#ZX(j,X){let Z=this.#M.get(j);if(!Z)return;if(--Z.count>0)return;if(this.#M.delete(j),!j.isConnected)return;if(X.disable)j.disabled=Z.disabled;if(Z.hadText&&j.innerHTML===Z.swappedTo)j.innerHTML=Z.html}#$X(j){if(!j||typeof j!=="object")return null;let{class:X,...Z}=j;return X==null?j:{...Z,add_class:X}}#JX(){return this.#Yj??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#QX(){if(this.#F!=null)return this.#F;let j=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,X=Number(j);return this.#F=Number.isFinite(X)&&X>0?X:30000}#GX(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#zX(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}export{fj as resetReactiveDefers,dj as resetReactiveActivity,Jj as registerReactiveVisit,Qj as registerReactiveToken,Vj as registerReactiveOffline,Gj as registerReactiveJs,_j as registerReactiveDismiss,zj as registerReactiveDefer,y as registerReactiveActions,cj as reactiveActivityCount,pj as pendingDeferVia,o as exitReactiveActivity,Bj as escapeRegExp,l as enterReactiveActivity,Nj as enableLatencySim,Mj as disableLatencySim,sj as default,Oj as checkReactiveRegistration,lj as __resetReactiveRegistrationForTest,mj as __resetReactiveOfflineForTest,gj as __resetReactiveLatencyForTest,uj as __resetReactiveDismissForTest,oj as __markReactiveConnectedForTest,S as LATENCY_KEY,d as ACTIVE_ATTR};
1
+ import{Controller as $X}from"@hotwired/stimulus";import{confirmResolver as h}from"phlex/reactive/confirm";import{computeReducer as QX}from"phlex/reactive/compute";import{confirmPredicate as jX}from"phlex/reactive/confirm_predicate";function GX(){let X=window.Turbo?.StreamActions;if(!X||X["reactive:visit"])return;X["reactive:visit"]=function(){let Z=this.getAttribute("data-url");if(Z)window.Turbo.visit(Z,{action:"advance"})}}function zX(){let X=window.Turbo?.StreamActions;if(!X||X["reactive:token"])return;X["reactive:token"]=function(){let Z=this.getAttribute("data-reactive-token-value"),$=this.getAttribute("target");if(!Z||!$)return;let Q=document.getElementById($);if(Q)Q.setAttribute("data-reactive-token-value",Z)}}function KX(){let X=window.Turbo?.StreamActions;if(!X||X["reactive:js"])return;X["reactive:js"]=function(){let Z=XX(this.getAttribute("data-reactive-ops"));if(!Z.length)return;let $=this.getAttribute("target"),Q=$?document.getElementById($):null;if($&&!Q)return;ZX(Z,(j)=>bX(j,Q))}}var M=new Map;function u(X,Z){let $=!M.has(X);if(M.set(X,Z),$)i()}function x(X){if(M.delete(X))s()}function pX(){M.clear(),T=!1}function mX(X){return M.get(X)?.via}var T=!1;function qX(){let X=window.Turbo?.StreamActions;if(!X||X["reactive:defer"])return;if(X["reactive:defer"]=function(){let Z=this.getAttribute("target");if(!Z)return;if(this.getAttribute("data-reactive-defer-via")==="stream"){UX(Z,this);return}let $=this.getAttribute("data-reactive-defer-token");if(!$)return;P(Z,$)},!T&&typeof document<"u"&&document.addEventListener)T=!0,document.addEventListener("turbo:before-stream-render",YX)}function YX(X){let $=X.target?.getAttribute?.("target");if(!$)return;let Q=$.startsWith("reactive-defer-src-")?$.slice(19):$;if(M.get(Q)?.via==="stream")x(Q)}function P(X,Z){let $=document.getElementById(X);if(!$){console.warn(`[phlex-reactive] reactive:defer target #${X} is not on the page — skipped`);return}c(X),d($);let Q={via:"fetch",abort:new AbortController,timedOut:!1};u(X,Q),HX(X,Q,Z)}function UX(X,Z){let $=document.getElementById(X);if(!$){console.warn(`[phlex-reactive] reactive:defer target #${X} is not on the page — skipped`);return}let Q=Z.getAttribute("data-reactive-defer-src");if(!Q)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let G=Z.getAttribute("data-reactive-defer-token");if(G){P(X,G);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}c(X),d($);let j=document.createElement("pgbus-stream-source");j.id=g(X),j.setAttribute("src",Q),j.setAttribute("since-id",Z.getAttribute("data-reactive-defer-since-id")??"0"),j.setAttribute("hidden",""),document.body.appendChild(j),u(X,{via:"stream"})}function g(X){return`reactive-defer-src-${X}`}async function HX(X,Z,$){let Q=setTimeout(()=>{Z.timedOut=!0,Z.abort.abort()},JX()),j;try{j=await fetch(WX(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":_X()},body:JSON.stringify({token:$}),credentials:"same-origin",signal:Z.abort.signal})}catch(z){if(clearTimeout(Q),M.get(X)!==Z)return;console.error("[phlex-reactive] deferred render failed",z),C(X,$);return}if(M.get(X)!==Z){clearTimeout(Q);return}if(j.status===204){clearTimeout(Q),v(X);return}if(!j.ok){clearTimeout(Q),console.error(`[phlex-reactive] deferred render failed: HTTP ${j.status}`),C(X,$,j.status);return}let G;try{G=await j.text()}catch(z){if(clearTimeout(Q),M.get(X)!==Z)return;console.error("[phlex-reactive] deferred render failed reading the body",z),C(X,$);return}if(clearTimeout(Q),M.get(X)!==Z)return;v(X),window.Turbo.renderStreamMessage(G)}function c(X){let Z=M.get(X);if(!Z)return;if(x(X),Z.via==="fetch")Z.abort.abort();else document.getElementById(g(X))?.remove?.()}function d(X){X.setAttribute("data-reactive-defer-pending","true"),X.setAttribute("aria-busy","true")}function l(X){X.removeAttribute("data-reactive-defer-pending"),X.removeAttribute("aria-busy")}function v(X){x(X);let Z=document.getElementById(X);if(!Z)return;l(Z),Z.removeAttribute("data-reactive-error")}function C(X,Z,$){x(X);let Q=document.getElementById(X);if(!Q)return;l(Q),Q.setAttribute("data-reactive-error","defer");let j=()=>{let G=document.getElementById(X);if(!G){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}G.removeAttribute("data-reactive-error"),P(X,Z)};Q.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:X,status:$,retry:j}}))}function WX(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function _X(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function JX(){let X=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,Z=Number(X);return Number.isFinite(Z)&&Z>0?Z:30000}var I=!1;function LX(){if(I)return;if(typeof document>"u"||!document.addEventListener)return;I=!0,document.addEventListener("turbo:before-stream-render",MX)}function MX(X){let Z=X.detail,$=Z?.render;if(typeof $!=="function"||$.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(F);else setTimeout(F,0);return}let Q=async(j)=>{await $(j),F()};Q.__reactiveDismissWrapped=!0,Z.render=Q}function F(){let X=document.querySelectorAll("[data-reactive-dismiss-after]");for(let Z of X){if(Z.hasAttribute("data-reactive-dismiss-scheduled"))continue;let $=Number(Z.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite($)||$<=0)continue;Z.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>Z.remove(),$)}}function uX(){I=!1}var k=!1;function AX(){if(k)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;k=!0;let X=()=>{let Z=document.documentElement;if(typeof Z?.toggleAttribute!=="function")return;Z.toggleAttribute("data-reactive-offline",globalThis.navigator?.onLine===!1)};X(),window.addEventListener("online",X),window.addEventListener("offline",X)}function gX(){k=!1}var w="phlex-reactive:latency",N=!1;function BX(X){if(typeof sessionStorage>"u")return;sessionStorage.setItem(w,String(X))}function VX(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem(w),N=!1}function OX(){if(typeof window>"u"||typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content!=="development")return;window.PhlexReactive={enableLatencySim:BX,disableLatencySim:VX}}function cX(){N=!1}var o="data-reactive-active",B=0;function i(){if(B++,B===1)n("reactive:busy")}function s(){if(B===0)return;if(B--,B===0)n("reactive:idle")}function dX(){return B}function lX(){B=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(o)}function n(X){if(typeof document>"u")return;let Z=document.documentElement;if(typeof Z?.toggleAttribute==="function")Z.toggleAttribute(o,B>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(X,{detail:{count:B}}))}function y(){GX(),zX(),KX(),qX(),LX(),AX(),OX()}function NX(X){return X.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}if(typeof window<"u")if(window.Turbo)y();else document.addEventListener("turbo:load",y,{once:!0});var E=!1;function xX(){if(E)return;if(typeof document>"u")return;let X=document.querySelectorAll('[data-controller~="reactive"]');if(!X||X.length===0)return;console.warn("[phlex-reactive] found "+X.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 oX(){E=!1}function iX(){E=!0}if(typeof window<"u"&&typeof document<"u"){let X=()=>setTimeout(xX,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",X,{once:!0});else X()}var PX=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function EX(X){let Z=String(X).toLowerCase();return Z.startsWith("on")||PX.has(Z)}function CX(X,Z,$){let[Q,j,G]=Z;X.classList.add(Q,j),$(),requestAnimationFrame(()=>{X.classList.remove(j),X.classList.add(G)});let z=!1,K=()=>{if(z)return;z=!0,X.classList.remove(Q,G)};X.addEventListener("animationend",K,{once:!0}),setTimeout(K,350)}var f=Object.freeze({show:(X,Z)=>R(X,!1,Z),hide:(X,Z)=>R(X,!0,Z),toggle:(X,Z)=>R(X,!X.hidden,Z),add_class:(X,Z)=>X.classList.add(...Z.classes??[]),remove_class:(X,Z)=>X.classList.remove(...Z.classes??[]),toggle_class:(X,Z)=>(Z.classes??[]).forEach(($)=>X.classList.toggle($)),set_attr:(X,Z)=>{if(D(Z.name))X.setAttribute(Z.name,Z.value??"")},remove_attr:(X,Z)=>{if(D(Z.name))X.removeAttribute(Z.name)},toggle_attr:(X,Z)=>{if(!D(Z.name))return;if(X.hasAttribute(Z.name))X.removeAttribute(Z.name);else X.setAttribute(Z.name,"")},focus:(X)=>X.focus?.(),focus_first:(X)=>wX(X)?.focus?.(),text:(X,Z)=>{let $=String(Z.value??"");if(X.textContent!==$)X.textContent=$},dispatch:(X,Z)=>{X.dispatchEvent(new CustomEvent(Z.name,{bubbles:!0,composed:!0,detail:Z.detail??{}}))}});function R(X,Z,$){if($?.transition)CX(X,$.transition,()=>X.hidden=Z);else X.hidden=Z}function D(X){if(!EX(X))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(X)} — skipped`),!1}var a=/^#[A-Za-z_][\w-]*$/;function FX(X){if(typeof X==="string"&&a.test(X))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(X)} — skipped`),!1}function RX(X,Z){let $=X.getAttribute("data-reactive-show-equals");if($!==null)return Z===$;let Q=X.getAttribute("data-reactive-show-not");if(Q!==null)return Z!==Q;let j=X.getAttribute("data-reactive-show-in");if(j!==null){try{let G=JSON.parse(j);if(Array.isArray(G))return G.includes(Z)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(j)} — skipped`),null}for(let G of r){let z=X.getAttribute(`data-reactive-show-${G}`);if(z!==null)return t(G,z,Z)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}var r=["gte","gt","lte","lt"];function t(X,Z,$){let Q=Number(Z);if(Number.isNaN(Q))return console.warn(`[phlex-reactive] reactive_show ${X}: needs a numeric literal, got ${JSON.stringify(Z)} — skipped`),null;let j=$==null?"":String($).trim(),G=j===""?NaN:Number(j);if(Number.isNaN(G))return!1;switch(X){case"gte":return G>=Q;case"gt":return G>Q;case"lte":return G<=Q;case"lt":return G<Q;default:return null}}function e(X,Z){if(!X||typeof X!=="object")return null;if(typeof X.equals==="string")return Z===X.equals;if(typeof X.not==="string")return Z!==X.not;if(Array.isArray(X.in))return X.in.includes(Z);for(let $ of r)if($ in X)return t($,X[$],Z);return null}var p="[data-reactive-show-field], [data-reactive-show]";function DX(X){try{let Z=JSON.parse(X);if(Z&&typeof Z==="object"&&!Array.isArray(Z))return Z}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(X)} — skipped`),null}function b(X,Z){if(!X||typeof X!=="object"||typeof X.field!=="string")return!1;let $=Z(X.field)??"";return e(X,$)===!0}function S(X,Z){if(!Array.isArray(X)||X.length===0)return null;return X.some(($)=>Array.isArray($)&&$.length>0&&$.every((Q)=>b(Q,Z)))}function TX(X){if(!Array.isArray(X)||X.length===0)return null;let Z=new Set;for(let $ of X){if(!Array.isArray($))continue;for(let Q of $)if(Q&&typeof Q==="object"&&typeof Q.field==="string")Z.add(Q.field)}return Z.size>0?[...Z]:null}function IX(X,Z){if(!X||typeof X!=="object")return null;let $=X.any;if(Array.isArray($)&&($.length===0||Array.isArray($[0])))return S($,Z);return kX(X,Z)}function kX(X,Z){let $=Array.isArray(X.all)?"all":Array.isArray(X.any)?"any":null;if(!$)return null;let Q=X[$];if(Q.length===0)return null;let j=Q.map((G)=>b(G,Z));return $==="all"?j.every(Boolean):j.some(Boolean)}function m(X){if(typeof X==="string"&&a.test(X))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(X)} — skipped`),!1}var SX='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function wX(X){return X.querySelectorAll?.(SX)?.[0]??null}function XX(X){if(Array.isArray(X))return X;if(typeof X!=="string")return[];try{let Z=JSON.parse(X);return Array.isArray(Z)?Z:[]}catch{return[]}}function ZX(X,Z){for(let $ of X){if(!Array.isArray($))continue;let[Q,j={}]=$;if(!Object.hasOwn(f,Q)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(Q)} — skipped`);continue}for(let G of Z(j))f[Q](G,j)}}function bX(X,Z){let $=X.to;if(Z){if($==="@root")return[Z];if(typeof $!=="string"||$==="")return[];if(X.global)return[...document.querySelectorAll($)];return[...Z.querySelectorAll($)]}if(typeof $!=="string"||$===""||$==="@root")return[];return[...document.querySelectorAll($)]}class sX extends $X{static values={token:String};#f;#V=new Map;#U=new Map;#_X;#D;#p;#T=0;#H=new Map;#I=new WeakMap;#O=new Map;#m=new WeakSet;#W;#_;#J;#Z;#Q;#L;#u=!1;#k=0;#g=!1;#j;#M;#A;#N;connect(){if(E=!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.#c(),this.#N=()=>this.#c(),this.element.addEventListener?.("turbo:morph-element",this.#N);if(this.#JX()){if(this.#W=()=>this.#w(),this.element.addEventListener?.("turbo:morph-element",this.#W),this.#w(),this.element.getAttribute?.("data-reactive-warn-unsaved")==="true")this.#fX()}if(this.#mX())this.#Z=()=>this.#$X(),this.element.addEventListener?.("input",this.#Z),this.element.addEventListener?.("change",this.#Z),this.element.addEventListener?.("turbo:morph-element",this.#Z),this.#$X();if(this.#F())this.#Q=(X)=>{if(X?.type==="input"&&!this.#iX(X))return;this.#B()},this.element.addEventListener?.("input",this.#Q),this.element.addEventListener?.("turbo:morph-element",this.#Q),this.#B();if(this.#R())this.#L=()=>this.#v(),this.element.addEventListener?.("turbo:morph-element",this.#L),this.#v();if(this.#nX())this.#j=(X)=>this.syncNestedJson(X),this.#M=()=>this.#P(),this.element.addEventListener?.("input",this.#j),this.element.addEventListener?.("change",this.#j),this.element.addEventListener?.("turbo:morph-element",this.#M),this.#P();if(this.#oX())this.#A=()=>this.recompute(),this.element.addEventListener?.("turbo:morph-element",this.#A),this.recompute()}#JX(){if((this.element.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let X=this.element.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let Z of X)if(this.#$(Z))return!0;return!1}disconnect(){if(this.#RX(),this.#TX(),this.#pX(),this.#lX(),this.#sX(),this.#$Z(),this.#QZ(),this.#jZ(),this.#N)this.element.removeEventListener?.("turbo:morph-element",this.#N)}#c(){let X=this.element;if(!X?.id)return;let Z=X.getAttribute?.("data-reactive-defer-token");if(!Z)return;if(X.getAttribute?.("data-reactive-defer-pending")!=="true")return;P(X.id,Z)}dispatch(X){let{action:Z,params:$,debounce:Q,throttle:j,confirm:G,confirmWhen:z,outside:K,window:q,optimistic:Y}=X.params;if(!Z)return;let L=X.params.busy??this.#JZ(X.params.loading);if(K&&this.element.contains(X.target))return;let A=X.currentTarget??X.target;if(!q&&!this.#KZ(Y,A))X.preventDefault();let W=this.#e(G,z);if(!W)return this.#s(A,Z,$,Q,j,Y,L);Promise.resolve().then(()=>h(W)).catch(()=>!1).then((_)=>{if(_)this.#s(A,Z,$,Q,j,Y,L)})}runOps(X){let{ops:Z,confirm:$,confirmWhen:Q,outside:j,window:G}=X.params;if(j&&this.element.contains(X.target))return;if(!G)X.preventDefault();let z=this.#e($,Q);if(!z)return this.#qX(this.#KX(Z));Promise.resolve().then(()=>h(z)).catch(()=>!1).then((K)=>{if(K)this.#qX(this.#KX(Z))})}trackDirty(){this.#w()}recompute(X){if(X&&this.#m.has(X))return;let Z=this.#OX(),$=Z.map(([U])=>U),Q=this.element.getAttribute?.("data-reactive-scope")||null,j=(U)=>Q&&!U.includes("[")?`${Q}[${U}]`:U,G=this.#X(),z=new Map,K=(U)=>{if(z.has(U))return z.get(U);let H=null;for(let V of this.element.querySelectorAll(`[name="${j(U)}"]`))if(G(V)){H=V;break}return z.set(U,H),H};for(let U of $)this.#o(U,K(U)?.value??"");let q=this.element.getAttribute("data-reactive-compute-reducer-param"),Y=q?QX(q):null;if(!Y){this.#i({},K);return}let L=this.#VX("data-reactive-compute-outputs-param"),A={};for(let[U,H]of Z){let V=K(U);if(H==="string")A[U]=V?.value??"";else{let J=Number(V?.value);A[U]=Number.isFinite(J)?J:0}}let W=Y(A,{changed:this.#NX(X,$,Q)})||{},_=[];for(let U of L){if(!(U in W))continue;let H=K(U);if(!H)continue;if(String(W[U])===H.value)continue;H.value=W[U],_.push(H)}for(let U of Object.keys(W)){let H=W[U];if(H===void 0||H===null)continue;this.#o(U,H)}this.#i(W,K);for(let U of _){let H=new Event("input",{bubbles:!0});this.#m.add(H),U.dispatchEvent(H)}}listnavNext(X){this.#d(X,1)}listnavPrev(X){this.#d(X,-1)}listnavPick(X){let Z=this.#x(X),$=Z.findIndex((Q)=>Q.hasAttribute("data-reactive-highlighted"));if($<0)return;X.preventDefault(),Z[$].click()}listnavClose(X){for(let Z of this.#x(X))Z.removeAttribute("data-reactive-highlighted")}#d(X,Z){let $=this.#x(X);if(!$.length)return;X.preventDefault();let Q=$.findIndex((z)=>z.hasAttribute("data-reactive-highlighted")),j=Q<0?Z>0?0:$.length-1:(Q+Z+$.length)%$.length;for(let z of $)z.removeAttribute("data-reactive-highlighted");let G=$[j];G.setAttribute("data-reactive-highlighted","true"),G.scrollIntoView?.({block:"nearest"})}#x(X){let $=(X?.currentTarget??X?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!$)return[];let Q=this.#X();return Array.from(this.element.querySelectorAll($)).filter((j)=>!j.hidden&&Q(j))}tagsAdd(X){if(!this.#R())return;if(X?.defaultPrevented)return;if(this.#x(X).some((Q)=>Q.hasAttribute?.("data-reactive-highlighted")))return;X?.preventDefault?.();let Z=X?.currentTarget??X?.target;if(!Z)return;if(!this.#jX(String(Z.value??"").split(",")))return;if(Z.value="",this.#F())this.#B()}tagsPick(X){if(!this.#R())return;X?.preventDefault?.();let $=(X?.currentTarget??X?.target)?.getAttribute?.("data-reactive-tag-param");if(!$)return;if(!this.#jX([$]))return;let Q=this.#aX();if(!Q)return;Q.value="",this.#B(),Q.focus?.()}tagsRemove(X){if(!this.#R())return;X?.preventDefault?.();let $=(X?.currentTarget??X?.target)?.getAttribute?.("data-reactive-tag-param");if(!$)return;let Q=this.#b();if(!Q)return;let j=this.#h(Q),G=j.filter((z)=>z.toLowerCase()!==$.toLowerCase());if(G.length===j.length)return;this.#GX(Q,G)}nestedAdd(X){X?.preventDefault?.();let $=(X?.currentTarget??X?.target)?.getAttribute?.("data-reactive-association-param");if(!$)return;if(typeof this.element?.querySelectorAll!=="function")return;let Q=this.#X(),j=[...this.element.querySelectorAll(`[data-reactive-nested-list="${$}"]`)].find(Q),z=[...this.element.querySelectorAll(`[data-reactive-nested-template="${$}"]`)].find(Q)?.content?.firstElementChild;if(!j||!z){this.#ZZ($);return}let K=z.cloneNode(!0);if(this.#XZ(K,this.#eX()),j.appendChild(K),[...K.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.(),j.getAttribute?.("data-reactive-nested-json")===$)this.#l($)}nestedRemove(X){X?.preventDefault?.();let $=(X?.currentTarget??X?.target)?.closest?.("[data-reactive-nested-row]");if(!$)return;if($.closest?.('[data-controller~="reactive"]')!==this.element)return;let Q=[...$.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(Q){if(Q.value="1",typeof Q.dispatchEvent==="function")Q.dispatchEvent(new Event("input",{bubbles:!0}));$.hidden=!0}else $.parentNode?.removeChild?.($);this.#P()}syncNestedJson(X){let Z=X?.target;if(!Z||!this.#$(Z))return;this.#P()}#P(){if(typeof this.element?.querySelectorAll!=="function")return;let X=this.#X();for(let Z of[...this.element.querySelectorAll("[data-reactive-nested-json]")].filter(X))this.#l(Z.getAttribute("data-reactive-nested-json"))}#l(X){let Z=this.#X(),$=[...this.element.querySelectorAll(`[data-reactive-nested-list="${X}"]`)].find(Z);if(!$)return;let Q=this.#LX($);if(!Q)return;let j=[];for(let z of[...$.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!Z(z)||z.hidden)continue;j.push(this.#MX(z))}let G=JSON.stringify(j);if(Q.value===G)return;if(Q.value=G,typeof Q.dispatchEvent==="function")Q.dispatchEvent(new Event("input",{bubbles:!0}))}#LX(X){let Z=X.getAttribute?.("data-reactive-nested-json-field");if(!Z)return null;let $=this.#X();return[...this.element.querySelectorAll(Z)].find($)??null}#MX(X){let Z={};for(let $ of[...X.querySelectorAll?.("input, select, textarea")??[]]){let Q=this.#AX($.getAttribute?.("name"));if(Q===null||Q==="_destroy")continue;Z[Q]=this.#BX($)}return Z}#AX(X){if(!X)return null;let Z=X.match(/\[([^\][]+)\]$/);return Z?Z[1]:X}#BX(X){if(X.type==="checkbox")return X.checked?X.value||"on":"";return X.value??""}#VX(X){let Z=this.element.getAttribute(X);if(!Z)return[];try{let $=JSON.parse(Z);return Array.isArray($)?$:[]}catch{return[]}}#OX(){let X=this.element.getAttribute("data-reactive-compute-inputs-param");if(!X)return[];try{let Z=JSON.parse(X);if(Array.isArray(Z))return Z.map(($)=>[$,"number"]);if(Z&&typeof Z==="object")return Object.entries(Z);return[]}catch{return[]}}#NX(X,Z,$){let Q=X?.target;if(!Q?.name||typeof Q.closest!=="function")return null;let j=this.#xX(Q.name,$);if(!Z.includes(j))return null;return this.#$(Q)?j:null}#xX(X,Z){if(!Z)return X;let $=`${Z}[`;return X.startsWith($)&&X.endsWith("]")?X.slice($.length,-1):X}#o(X,Z){let $=String(Z);for(let Q of this.#PX(X)){if(Q.textContent===$)continue;Q.textContent=$}}#PX(X){let Z=this.element.querySelectorAll(`[data-reactive-text="${X}"]`);return Array.from(Z).filter(($)=>this.#$($))}#i(X,Z){let $=this.#EX();for(let[Q,j]of Object.entries($)){let G=Q in X?X[Q]:Z(Q)?.value;if(G===void 0||G===null)continue;let z=String(G);for(let K of Array.isArray(j)?j:[j]){if(!FX(K))continue;for(let q of document.querySelectorAll(K)){if(q.textContent===z)continue;q.textContent=z}}}}#EX(){let X=this.element.getAttribute("data-reactive-compute-mirror-param");if(!X)return{};try{let Z=JSON.parse(X);return Z&&typeof Z==="object"&&!Array.isArray(Z)?Z:{}}catch{return{}}}#s(X,Z,$,Q,j,G,z){if(this.#C("reactive:before-dispatch",{action:Z,params:this.#zX($),element:this.element},{cancelable:!0}).defaultPrevented)return;let q=Number(Q)||0;if(q>0)return this.#FX(X,q,Z,$,G,z);let Y=Number(j)||0;if(Y>0)return this.#DX(X,Y,Z,$,G,z);return this.#E(Z,$,G,X,z)}#E(X,Z,$,Q,j){let G=this.#qZ($,Q),z=this.#YZ(X,Q,j),K=this.#n()?this.#CX($,Q):null;return this.queue=(this.queue??Promise.resolve()).then(()=>this.#hX(X,Z,G,z,K)),this.queue}#CX(X,Z){if(!X?.hide)return null;let $=this.#HX(X,Z);if(!$.length)return null;return()=>{let Q=$.filter((j)=>j.isConnected&&!j.hidden);if(!Q.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.",Q)}}#FX(X,Z,$,Q,j,G){this.#S(X);let z=()=>{this.#S(X),this.#E($,Q,j,X,G)},K=setTimeout(z,Z);X?.addEventListener?.("blur",z,{once:!0}),this.#V.set(X,{timer:K,flush:z})}#S(X){let Z=this.#V.get(X);if(!Z)return;clearTimeout(Z.timer),X?.removeEventListener?.("blur",Z.flush),this.#V.delete(X)}#RX(){for(let X of[...this.#V.keys()])this.#S(X)}#DX(X,Z,$,Q,j,G){let z=this.#U.get(X)??new Map;if(z.has($))return;let K=setTimeout(()=>{if(z.delete($),z.size===0)this.#U.delete(X)},Z);return z.set($,K),this.#U.set(X,z),this.#E($,Q,j,X,G)}#TX(){for(let X of this.#U.values())for(let Z of X.values())clearTimeout(Z);this.#U.clear()}#C(X,Z,{cancelable:$=!1}={}){let Q=new CustomEvent(X,{bubbles:!0,composed:!0,cancelable:$,detail:Z});return(this.element.isConnected?this.element:document).dispatchEvent(Q),Q}#G(X,Z,$,Q){let j=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#E(X,Z)};this.#C("reactive:error",{action:X,params:$,...Q,retry:j})}#z(X){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",X)}#IX(){this.element?.removeAttribute?.("data-reactive-error")}#kX(){let X=document.querySelector("[data-reactive-error-flash]");if(!X?.content)return;let Z=X.getAttribute("data-reactive-error-flash")||"flash",$=document.getElementById(Z);if(!$)return;$.appendChild(X.content.cloneNode(!0))}#SX(){if(typeof sessionStorage>"u")return Promise.resolve();let X=Number(sessionStorage.getItem(w));if(!Number.isFinite(X)||X<=0)return Promise.resolve();if(!N)N=!0,console.warn(`[phlex-reactive] latency simulator ACTIVE — every action is delayed by ${X}ms. Call PhlexReactive.disableLatencySim() (or clear sessionStorage) to turn it off.`);return new Promise((Z)=>setTimeout(Z,X))}#n(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#a(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}#wX(X){if(!X)return[];let Z=[],$=/<turbo-stream\b([^>]*)>/g,Q;while((Q=$.exec(X))!==null){let j=Q[1],G=j.match(/\baction="([^"]*)"/)?.[1]??"?",z=j.match(/\btarget="([^"]*)"/)?.[1];Z.push(z?`${G} → #${z}`:G)}return Z}#bX(X){let{action:Z,status:$,ms:Q}=X,G=`reactive ${this.element?.id?`#${this.element.id} `:""}${Z} → ${$??"—"} (${Math.round(Q)}ms)`;if(console.groupCollapsed(G),console.log(`params: [${X.paramNames.join(", ")}] + collected: [${X.fieldNames.join(", ")}]`),console.log(`encoding: ${X.encoding}`),X.streams.length)console.log(`streams: ${X.streams.join(" ")}`);console.log(`token: ${X.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}async#hX(X,Z,$,Q,j){let{fields:G,files:z}=this.#XX(),K=this.#zX(Z),q={...G,...K},Y=this.#K,L=z.length>0,A=L?this.#GZ(Y,X,q,z):JSON.stringify({token:Y,act:X,params:q}),W=this.#n()?{action:X,paramNames:Object.keys(K),fieldNames:Object.keys(G),encoding:L?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#a()}:null;await this.#SX();try{if(navigator.onLine===!1){this.#q($),this.#z("offline"),this.#G(X,Z,q,{kind:"offline"});return}let _;try{let J={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#AZ()};if(!L)J["Content-Type"]="application/json";let O=this.#BZ();if(O)J["X-Pgbus-Connection"]=O;_=await fetch(this.#LZ(),{method:"POST",headers:J,body:A,credentials:"same-origin",signal:AbortSignal.timeout(this.#MZ())})}catch(J){if(console.error("[phlex-reactive] action error",J),this.#q($),J?.name==="TimeoutError"||J?.name==="AbortError"){this.#z("timeout"),this.#G(X,Z,q,{kind:"timeout"});return}this.#kX(),this.#z("network"),this.#G(X,Z,q,{kind:"network"});return}if(W)W.status=_.status;if(_.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#q($),this.#z("redirected"),this.#G(X,Z,q,{kind:"redirected",status:_.status});return}if(!_.ok){let J=await _.text();if(console.error(`[phlex-reactive] action failed: HTTP ${_.status}`,J),this.#q($),(_.headers.get("Content-Type")||"").includes("turbo-stream")){let O=this.#t(J);if(this.#K=O??this.#K,W)this.#r(W,J,O);window.Turbo.renderStreamMessage(J)}this.#z("http"),this.#G(X,Z,q,{kind:"http",status:_.status,body:J});return}let U=_.headers.get("Content-Type")||"";if(!U.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${U}" — no update applied`),this.#q($),this.#z("content-type"),this.#G(X,Z,q,{kind:"content-type",status:_.status});return}let H=await _.text(),V=this.#t(H);if(this.#K=V??this.#K,W)this.#r(W,H,V);if(window.Turbo.renderStreamMessage(H),j)queueMicrotask(j);this.#IX(),this.#C("reactive:applied",{action:X,params:q,html:H})}catch(_){console.error("[phlex-reactive] action error",_),this.#q($),this.#C("reactive:error",{action:X,params:q,kind:"apply"})}finally{if(Q?.(),W)this.#bX({...W,ms:this.#a()-W.started})}}#r(X,Z,$){X.streams=this.#wX(Z),X.tokenRefreshed=$!=null}get#K(){return this.#f??this.tokenValue}set#K(X){this.#f=X}#t(X){let Z=this.element.id;if(!Z)return X.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:$,self:Q}=this.#vX(Z),j=X.match($);if(j)return j[1];let G=X.match(Q);if(G)return G[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#vX(X){let Z=this.#p;if(Z&&Z.id===X)return Z;let $=NX(X);return this.#p={id:X,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${$}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${$}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#$(X){return X.closest('[data-controller~="reactive"]')===this.element}#X(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(Z)=>this.#$(Z)}#e(X,Z){if(X)return X;if(!Z)return null;let $=Z;if(typeof Z==="string")try{$=JSON.parse(Z)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(Z)} — skipped`),null}if(!$||typeof $!=="object")return null;let{fields:Q}=this.#XX(),j=(z)=>Q[z],G;if(typeof $.predicate==="string"){let z=jX($.predicate);if(!z)return console.warn(`[phlex-reactive] confirm predicate "${$.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;G=!!z(Q)}else G=S($.groups?.any,j)===!0;return G?$.message:null}#XX(){let X={},Z=[],$=this.#X();return this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((Q)=>{if(!$(Q))return;if(Q.type==="file")for(let j of Q.files??[])Z.push({name:Q.name,file:j,multiple:Q.multiple});else if(Q.type==="checkbox")X[Q.name]=Q.checked;else if(Q.type==="radio"){if(Q.checked)X[Q.name]=Q.value}else X[Q.name]=Q.value}),this.element.querySelectorAll("[name]:is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])").forEach((Q)=>{if(!$(Q))return;let j=Q.getAttribute("name");if(!j)return;let G=X[j];if(G==null||G==="")X[j]=Q.value??Q.textContent??Q.innerHTML??""}),{fields:X,files:Z}}#w(){if(typeof this.element?.querySelectorAll!=="function")return;let X=0;if(this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((Z)=>{if(!this.#$(Z))return;if(Z.type==="file")return;if(this.#yX(Z))Z.setAttribute("data-reactive-dirty","true"),X++;else Z.removeAttribute("data-reactive-dirty")}),X>0)this.element.setAttribute("data-reactive-dirty",String(X));else this.element.removeAttribute("data-reactive-dirty")}#yX(X){if(X.type==="checkbox"||X.type==="radio")return X.checked!==X.defaultChecked;if(X.tag==="select"||X.options)return Array.from(X.options??[]).some((Z)=>Z.selected!==Z.defaultSelected);return X.value!==X.defaultValue}#ZX(){let X=this.element.getAttribute?.("data-reactive-dirty"),Z=Number(X);return Number.isFinite(Z)&&Z>0?Z:0}#fX(){if(typeof window>"u"||typeof window.addEventListener!=="function")return;this.#_=(X)=>{if(this.#ZX()===0)return;return X.preventDefault(),X.returnValue="You have unsaved changes.",X.returnValue},this.#J=(X)=>{if(this.#ZX()===0)return;if(!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))X.preventDefault?.()},window.addEventListener("beforeunload",this.#_),window.addEventListener("turbo:before-visit",this.#J)}#pX(){if(this.#W)this.element.removeEventListener?.("turbo:morph-element",this.#W),this.#W=void 0;if(typeof window<"u"&&typeof window.removeEventListener==="function"){if(this.#_)window.removeEventListener("beforeunload",this.#_);if(this.#J)window.removeEventListener("turbo:before-visit",this.#J)}this.#_=void 0,this.#J=void 0}#mX(){if(this.element.getAttribute?.("data-reactive-show-targets"))return!0;let X=this.element.querySelectorAll?.(p)??[];for(let Z of X)if(this.#$(Z))return!0;return!1}#$X(){if(typeof this.element?.querySelectorAll!=="function")return;let X=this.#X(),Z=this.element.getAttribute?.("data-reactive-scope")||null,$=new Map,Q=(j)=>{if(!$.has(j))$.set(j,this.#dX(j,X,Z));return $.get(j)};for(let j of this.element.querySelectorAll(p)){if(!X(j))continue;let G=j.getAttribute("data-reactive-show");if(G!==null){let Y=IX(DX(G),Q);if(Y!==null)this.#QX(j,Y,X,Z);continue}let z=j.getAttribute("data-reactive-show-field");if(!z)continue;let K=Q(z);if(K===null)continue;let q=RX(j,K);if(q===null)continue;this.#QX(j,q,X,Z)}this.#uX(Q)}#QX(X,Z,$,Q){if(X.hidden=!Z,X.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof X.querySelectorAll!=="function")return;for(let j of X.querySelectorAll("input[name], select[name], textarea[name]"))if($(j))j.disabled=!Z;if(X.name&&$(X))X.disabled=!Z}#uX(X){let Z=this.#cX();for(let[$,Q]of Object.entries(Z)){if($.startsWith("#")){this.#gX($,Q,X);continue}if(!Q||typeof Q!=="object"||Array.isArray(Q))continue;let j=X($);if(j===null)continue;let G=()=>j;for(let[z,K]of Object.entries(Q)){if(!m(z))continue;let q;if(Array.isArray(K)){if(K.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${z} — skipped`);continue}q=K.every((Y)=>b(Y,G))}else{let Y=e(K,j);if(Y===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${z} — skipped`);continue}q=Y}for(let Y of document.querySelectorAll(z))Y.hidden=!q}}}#gX(X,Z,$){if(!m(X))return;let Q=Z&&typeof Z==="object"&&!Array.isArray(Z)?Z.any:null,j=TX(Q);if(j===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${X} — skipped`);return}if(j.every((z)=>$(z)===null))return;let G=S(Q,$);if(G===null)return;for(let z of document.querySelectorAll(X))z.hidden=!G}#cX(){let X=this.element.getAttribute?.("data-reactive-show-targets");if(!X)return{};try{let Z=JSON.parse(X);if(Z&&typeof Z==="object"&&!Array.isArray(Z))return Z}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: { ... })"),{}}#dX(X,Z,$){let Q=$&&!X.includes("[")?`${$}[${X}]`:X,j=!1,G=null;for(let z of this.element.querySelectorAll(`[name="${Q}"]`)){if(!Z(z))continue;if(z.type==="checkbox")return z.checked?"true":"false";if(z.type==="radio"){if(z.checked)return z.value??"";j=!0;continue}G??=z}if(G)return G.value??"";return j?"":null}#lX(){if(!this.#Z)return;this.element.removeEventListener?.("input",this.#Z),this.element.removeEventListener?.("change",this.#Z),this.element.removeEventListener?.("turbo:morph-element",this.#Z),this.#Z=void 0}#F(){return!!(this.element.getAttribute?.("data-reactive-filter-input")&&this.element.getAttribute?.("data-reactive-filter-option"))}#oX(){return this.element.getAttribute?.("data-reactive-compute-seed")==="true"}#iX(X){let Z=this.element.getAttribute("data-reactive-filter-input");return!!Z&&typeof X.target?.matches==="function"&&X.target.matches(Z)}#B(){if(typeof this.element?.querySelectorAll!=="function")return;let X=this.element.getAttribute("data-reactive-filter-input"),Z=this.element.getAttribute("data-reactive-filter-option");if(!X||!Z)return;let $=this.#X(),Q=[...this.element.querySelectorAll(X)].find($);if(!Q)return;let j=(Q.value??"").trim().toLowerCase(),G=0;for(let q of this.element.querySelectorAll(Z)){if(!$(q))continue;let Y=(q.getAttribute("data-reactive-filter-text")??q.textContent??"").toLowerCase(),L=q.hasAttribute?.("data-reactive-tags-selected")||j!==""&&!Y.includes(j);if(q.hidden=L,L)q.removeAttribute("data-reactive-highlighted");else G++}let z=this.element.getAttribute("data-reactive-filter-group");if(z)for(let q of this.element.querySelectorAll(z)){if(!$(q))continue;let Y=[...q.querySelectorAll(Z)].filter($);if(Y.length===0)continue;q.hidden=Y.every((L)=>L.hidden)}let K=this.element.getAttribute("data-reactive-filter-empty");if(K){for(let q of this.element.querySelectorAll(K))if($(q))q.hidden=G>0}}#sX(){if(!this.#Q)return;this.element.removeEventListener?.("input",this.#Q),this.element.removeEventListener?.("turbo:morph-element",this.#Q),this.#Q=void 0}#R(){return!!this.element.getAttribute?.("data-reactive-tags-field")}#nX(){if(typeof this.element?.querySelector!=="function")return!1;return!!this.element.querySelector("[data-reactive-nested-json]")}#b(){if(typeof this.element?.querySelectorAll!=="function")return null;let X=this.element.getAttribute("data-reactive-tags-field");if(!X)return null;let Z=this.#X();return[...this.element.querySelectorAll(X)].find(Z)??null}#h(X){let Z=new Set,$=[];for(let Q of String(X.value??"").split(",")){let j=Q.trim();if(j===""||Z.has(j.toLowerCase()))continue;Z.add(j.toLowerCase()),$.push(j)}return $}#jX(X){let Z=this.#b();if(!Z)return!1;let $=this.#h(Z),Q=new Set($.map((G)=>G.toLowerCase())),j=!1;for(let G of X){let z=String(G??"").trim();if(z===""||Q.has(z.toLowerCase()))continue;Q.add(z.toLowerCase()),$.push(z),j=!0}if(j)this.#GX(Z,$);return j}#GX(X,Z){if(X.value=Z.join(","),typeof X.dispatchEvent==="function")X.dispatchEvent(new Event("input",{bubbles:!0}));this.#v()}#aX(){if(typeof this.element?.querySelectorAll!=="function")return null;let X=this.element.getAttribute("data-reactive-filter-input");if(!X)return null;let Z=this.#X();return[...this.element.querySelectorAll(X)].find(Z)??null}#v(){let X=this.#b();if(!X)return;let Z=this.#h(X),$=this.#X();this.#rX(Z,$),this.#tX(Z,$)}#rX(X,Z){let $=[...this.element.querySelectorAll("[data-reactive-tags-list]")].find(Z);if(!$)return;let j=[...this.element.querySelectorAll("[data-reactive-tags-template]")].find(Z)?.content?.firstElementChild;if(!j){if(!this.#u)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.#u=!0;return}while($.firstChild)$.removeChild($.firstChild);for(let G of X){let z=j.cloneNode(!0);z.setAttribute?.("data-reactive-tag",G);let K=z.matches?.("[data-reactive-tag-text]")?z:(z.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(K)K.textContent=G;let q=[...z.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(z.matches?.('[data-action*="reactive#tagsRemove"]'))q.push(z);for(let Y of q)Y.setAttribute?.("data-reactive-tag-param",G);$.appendChild(z)}}#tX(X,Z){let $=new Set(X.map((Q)=>Q.toLowerCase()));for(let Q of this.element.querySelectorAll("[role=option]")){if(!Z(Q))continue;let j=Q.getAttribute?.("data-reactive-tag-param");if(!j)continue;if($.has(j.toLowerCase()))Q.setAttribute("data-reactive-tags-selected","true"),Q.hidden=!0,Q.removeAttribute?.("data-reactive-highlighted");else if(Q.hasAttribute?.("data-reactive-tags-selected")){if(Q.removeAttribute("data-reactive-tags-selected"),!this.#F())Q.hidden=!1}}if(this.#F())this.#B()}#eX(){return this.#k=Math.max(this.#k+1,Date.now()),this.#k}#XZ(X,Z){let $=[X,...X.querySelectorAll?.("*")??[]];for(let Q of $)for(let j of["name","id","for"]){let G=Q.getAttribute?.(j);if(G&&G.includes("NEW_ROW"))Q.setAttribute?.(j,G.replaceAll("NEW_ROW",String(Z)))}}#ZZ(X){if(this.#g)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${X}"] container + <template data-reactive-nested-template="${X}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),this.#g=!0}#$Z(){if(!this.#L)return;this.element.removeEventListener?.("turbo:morph-element",this.#L),this.#L=void 0}#QZ(){if(this.#j)this.element.removeEventListener?.("input",this.#j),this.element.removeEventListener?.("change",this.#j),this.#j=void 0;if(this.#M)this.element.removeEventListener?.("turbo:morph-element",this.#M),this.#M=void 0}#jZ(){if(!this.#A)return;this.element.removeEventListener?.("turbo:morph-element",this.#A),this.#A=void 0}#GZ(X,Z,$,Q){let j=new FormData;j.append("token",X),j.append("act",Z);for(let[z,K]of Object.entries($))this.#y(j,`params[${z}]`,K);let G=this.#zZ(Q);for(let{name:z,file:K,multiple:q}of Q){let L=q||G.has(z)?`params[${z}][]`:`params[${z}]`;j.append(L,K,K.name)}return j}#y(X,Z,$){if($==null)X.append(Z,"");else if(Array.isArray($))$.forEach((Q,j)=>this.#y(X,`${Z}[${j}]`,Q));else if(typeof $==="object")for(let[Q,j]of Object.entries($))this.#y(X,`${Z}[${Q}]`,j);else X.append(Z,String($))}#zZ(X){let Z=new Map;for(let{name:$}of X)Z.set($,(Z.get($)??0)+1);return new Set([...Z].filter(([,$])=>$>1).map(([$])=>$))}#zX(X){if(!X)return{};try{return typeof X==="string"?JSON.parse(X):X}catch{return{}}}#KX(X){return XX(X)}#qX(X){ZX(X,(Z)=>this.#YX(Z))}#YX(X){let Z=X.to;if(Z==="@root")return[this.element];if(typeof Z!=="string"||Z==="")return[];if(X.global)return[...document.querySelectorAll(Z)];return[...this.element.querySelectorAll(Z)].filter(($)=>this.#$($))}#KZ(X,Z){if(X?.checked!=="keep")return!1;let $=Z?.type;return $==="checkbox"||$==="radio"}#qZ(X,Z){if(!X)return null;let $=this.#UX(X,Z,!0);return $.length?$:null}#q(X){if(!X)return;if(!this.element.isConnected)return;for(let Z of X)Z()}#YZ(X,Z,$){this.#HZ(X,Z);let Q=$?this.#UX($,Z,!1):[];i();let j=!1;return()=>{if(j)return;j=!0,this.#WZ(X,Z),s();for(let G of Q)G()}}#UX(X,Z,$){let Q=[];for(let j of this.#HX(X,Z)){if(X.add_class){let G=X.add_class.filter((z)=>!j.classList.contains(z));if(j.classList.add(...G),G.length)Q.push(()=>j.classList.remove(...G))}if(X.remove_class){let G=X.remove_class.filter((z)=>j.classList.contains(z));if(j.classList.remove(...G),G.length)Q.push(()=>j.classList.add(...G))}if(X.toggle_class)X.toggle_class.forEach((G)=>j.classList.toggle(G)),Q.push(()=>X.toggle_class.forEach((G)=>j.classList.toggle(G)));if(X.hide)j.hidden=!0,Q.push(()=>j.hidden=!1);if(X.show)j.hidden=!1,Q.push(()=>j.hidden=!0)}if(Z&&(X.disable||X.text!=null))Q.push(this.#UZ(X,Z));if($&&X.checked==="keep"&&Z&&"checked"in Z){let j=Z.checked;Q.push(()=>Z.checked=!j)}return Q}#HX(X,Z){if(X.to==null)return Z?[Z]:[];return this.#YX({to:X.to})}#UZ(X,Z){let $=this.#O.get(Z);if($)$.count++;else this.#O.set(Z,{count:1,disabled:Z.disabled,html:Z.innerHTML,hadText:X.text!=null,swappedTo:X.text});if(X.disable)Z.disabled=!0;if(X.text!=null)Z.innerHTML=X.text;return()=>this.#_Z(Z,X)}#HZ(X,Z){if(this.#Y(Z,X,1),this.#Y(this.element,X,1),this.#H.set(X,(this.#H.get(X)??0)+1),this.#T++===0)this.element.setAttribute("aria-busy","true");for(let $ of this.#WX(X))this.#Y($,X,1)}#WZ(X,Z){this.#Y(Z,X,-1),this.#Y(this.element,X,-1);let $=(this.#H.get(X)??1)-1;if($<=0)this.#H.delete(X);else this.#H.set(X,$);if(--this.#T<=0)this.#T=0,this.element.removeAttribute("aria-busy");for(let Q of this.#WX(X))this.#Y(Q,X,-1)}#Y(X,Z,$){if(!X||typeof X.getAttribute!=="function")return;let Q=this.#I.get(X)??new Map,j=(Q.get(Z)??0)+$;if(j<=0)Q.delete(Z);else Q.set(Z,j);if(Q.size===0){this.#I.delete(X),X.removeAttribute("data-reactive-busy");return}this.#I.set(X,Q),X.setAttribute("data-reactive-busy",[...Q.keys()].join(" "))}#WX(X){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter(($)=>$.getAttribute("data-reactive-busy-on")===X&&this.#$($))}#_Z(X,Z){let $=this.#O.get(X);if(!$)return;if(--$.count>0)return;if(this.#O.delete(X),!X.isConnected)return;if(Z.disable)X.disabled=$.disabled;if($.hadText&&X.innerHTML===$.swappedTo)X.innerHTML=$.html}#JZ(X){if(!X||typeof X!=="object")return null;let{class:Z,...$}=X;return Z==null?X:{...$,add_class:Z}}#LZ(){return this.#_X??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#MZ(){if(this.#D!=null)return this.#D;let X=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,Z=Number(X);return this.#D=Number.isFinite(Z)&&Z>0?Z:30000}#AZ(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#BZ(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}export{pX as resetReactiveDefers,lX as resetReactiveActivity,GX as registerReactiveVisit,zX as registerReactiveToken,AX as registerReactiveOffline,KX as registerReactiveJs,LX as registerReactiveDismiss,qX as registerReactiveDefer,y as registerReactiveActions,dX as reactiveActivityCount,mX as pendingDeferVia,s as exitReactiveActivity,NX as escapeRegExp,i as enterReactiveActivity,BX as enableLatencySim,VX as disableLatencySim,sX as default,xX as checkReactiveRegistration,oX as __resetReactiveRegistrationForTest,gX as __resetReactiveOfflineForTest,cX as __resetReactiveLatencyForTest,uX as __resetReactiveDismissForTest,iX as __markReactiveConnectedForTest,w as LATENCY_KEY,o as ACTIVE_ATTR};
2
2
 
3
- //# debugId=C019D09F55CE970764756E2164756E21
3
+ //# debugId=01D39E17DBA3F0CE64756E2164756E21
4
4
  //# sourceMappingURL=reactive_controller.min.js.map