phlex-reactive 0.13.4 → 0.14.0

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1050 -630
  3. data/README.md +561 -14
  4. data/app/controllers/phlex/reactive/actions_controller.rb +85 -16
  5. data/app/controllers/phlex/reactive/fragments_controller.rb +310 -0
  6. data/app/javascript/phlex/reactive/core.js +181 -0
  7. data/app/javascript/phlex/reactive/core.min.js +4 -0
  8. data/app/javascript/phlex/reactive/core.min.js.map +11 -0
  9. data/app/javascript/phlex/reactive/early.js +175 -0
  10. data/app/javascript/phlex/reactive/early.min.js +4 -0
  11. data/app/javascript/phlex/reactive/early.min.js.map +10 -0
  12. data/app/javascript/phlex/reactive/features/bindings.js +1511 -0
  13. data/app/javascript/phlex/reactive/features/bindings.min.js +4 -0
  14. data/app/javascript/phlex/reactive/features/bindings.min.js.map +10 -0
  15. data/app/javascript/phlex/reactive/features/compute.js +541 -0
  16. data/app/javascript/phlex/reactive/features/compute.min.js +4 -0
  17. data/app/javascript/phlex/reactive/features/compute.min.js.map +10 -0
  18. data/app/javascript/phlex/reactive/features/defer.js +726 -0
  19. data/app/javascript/phlex/reactive/features/defer.min.js +4 -0
  20. data/app/javascript/phlex/reactive/features/defer.min.js.map +10 -0
  21. data/app/javascript/phlex/reactive/features/devtools.js +242 -0
  22. data/app/javascript/phlex/reactive/features/devtools.min.js +4 -0
  23. data/app/javascript/phlex/reactive/features/devtools.min.js.map +10 -0
  24. data/app/javascript/phlex/reactive/features/effects.js +362 -0
  25. data/app/javascript/phlex/reactive/features/effects.min.js +4 -0
  26. data/app/javascript/phlex/reactive/features/effects.min.js.map +10 -0
  27. data/app/javascript/phlex/reactive/features/form.js +216 -0
  28. data/app/javascript/phlex/reactive/features/form.min.js +4 -0
  29. data/app/javascript/phlex/reactive/features/form.min.js.map +10 -0
  30. data/app/javascript/phlex/reactive/features/hints.js +193 -0
  31. data/app/javascript/phlex/reactive/features/hints.min.js +4 -0
  32. data/app/javascript/phlex/reactive/features/hints.min.js.map +10 -0
  33. data/app/javascript/phlex/reactive/features/persist.js +663 -0
  34. data/app/javascript/phlex/reactive/features/persist.min.js +4 -0
  35. data/app/javascript/phlex/reactive/features/persist.min.js.map +10 -0
  36. data/app/javascript/phlex/reactive/reactive_controller.js +85 -5821
  37. data/app/javascript/phlex/reactive/reactive_controller.min.js +2 -2
  38. data/app/javascript/phlex/reactive/reactive_controller.min.js.map +13 -4
  39. data/app/javascript/phlex/reactive/runtime.js +3690 -0
  40. data/lib/generators/phlex/reactive/install/templates/phlex_reactive.rb.erb +18 -0
  41. data/lib/phlex/reactive/claude/skills/phlex-reactive-debugging/SKILL.md +5 -3
  42. data/lib/phlex/reactive/component/dsl.rb +74 -2
  43. data/lib/phlex/reactive/component/helpers.rb +39 -9
  44. data/lib/phlex/reactive/component/lazy.rb +138 -2
  45. data/lib/phlex/reactive/component/registry.rb +2 -0
  46. data/lib/phlex/reactive/component/selection.rb +71 -0
  47. data/lib/phlex/reactive/doctor/fiber_isolation.rb +86 -0
  48. data/lib/phlex/reactive/doctor.rb +166 -8
  49. data/lib/phlex/reactive/dormant.rb +66 -0
  50. data/lib/phlex/reactive/engine.rb +63 -3
  51. data/lib/phlex/reactive/fragment.rb +233 -0
  52. data/lib/phlex/reactive/inspector/report.rb +24 -3
  53. data/lib/phlex/reactive/inspector.rb +23 -2
  54. data/lib/phlex/reactive/js.rb +17 -2
  55. data/lib/phlex/reactive/mcp/tools/actions_tool.rb +3 -1
  56. data/lib/phlex/reactive/mcp/tools/find_tool.rb +4 -1
  57. data/lib/phlex/reactive/param_schema.rb +68 -54
  58. data/lib/phlex/reactive/show_conditions.rb +84 -56
  59. data/lib/phlex/reactive/streamable.rb +20 -2
  60. data/lib/phlex/reactive/test_helpers/system/reactive_requests_matcher.rb +120 -0
  61. data/lib/phlex/reactive/test_helpers/system.rb +62 -0
  62. data/lib/phlex/reactive/version.rb +1 -1
  63. data/lib/phlex/reactive.rb +84 -0
  64. data/lib/tasks/phlex_reactive.rake +6 -2
  65. metadata +38 -1
@@ -1,4 +1,4 @@
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};
1
+ import{Controller as ti}from"@hotwired/stimulus";import{confirmResolver as Ir}from"phlex/reactive/confirm";import{confirmPredicate as dn}from"phlex/reactive/confirm_predicate";var k=new WeakMap;function A(e,t){let r=k.get(e);if(!r)k.set(e,r={root:e.element,core:t,nestedIndex:0});return r}function E(e,t,r){for(let n of t.split(" "))e.root.addEventListener?.(n,r),e.offs.push(()=>e.root.removeEventListener?.(n,r))}function T(e,t){E(e,"turbo:morph-element",t),e.seeds.push(t),t()}function re(e,t){let r=A(e,t);if(r.offs=[],r.seeds=[],yn(r))r.show=(n)=>{if(r.flipping)return;if(n?.type==="input"||n?.type==="change")En(r,n.target);else r.groups=Tn(r),Ft(r);wn(r)},E(r,"input change",r.show),T(r,r.show);if(vn(r))E(r,"input change",(n)=>Et(r,n)),T(r,r.arm=()=>{Et(r,null),Ft(r)});if(D(r))E(r,"input",(n)=>Fn(r,n)&&F(r)),T(r,()=>F(r));if(j(r))T(r,()=>qt(r));if(Ln(r))E(r,"input change",(n)=>Bt(r,n)),T(r,()=>le(r))}function ne(e){let t=k.get(e);if(!t)return;k.delete(e);for(let r of t.offs??[])r();t.groupObserver?.disconnect()}function oe(e){for(let t of k.get(e)?.seeds??[])t()}function L(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function ie(e,t,r){return Bt(A(e,t),r)}function se(e,t,r){return Kt(A(e,t),r)}var pn=/^#[A-Za-z_][\w-]*$/,Rt="[data-reactive-show-field], [data-reactive-show]";function hn(e,t){let r=e.getAttribute("data-reactive-show-equals");if(r!==null)return t===r;let n=e.getAttribute("data-reactive-show-not");if(n!==null)return t!==n;let o=e.getAttribute("data-reactive-show-in");if(o!==null){try{let i=JSON.parse(o);if(Array.isArray(i))return i.includes(t)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(o)} — skipped`),null}for(let i of Jt){let a=e.getAttribute(`data-reactive-show-${i}`);if(a!==null)return zt(i,a,t)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function Nt(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 mn(e){try{let t=JSON.parse(e);if(Array.isArray(t)&&t.every((r)=>r&&typeof r==="object"&&Array.isArray(r.any)&&Array.isArray(r.ops)))return t}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function Ot(e,t){if(!e||typeof e!=="object")return null;let r=e.any;if(Array.isArray(r)&&(r.length===0||Array.isArray(r[0])))return B(r,t);return gn(e,t)}function gn(e,t){let r=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!r)return null;let n=e[r];if(n.length===0)return null;let o=n.map((i)=>ge(i,t));return r==="all"?o.every(Boolean):o.some(Boolean)}function Ct(e){if(typeof e==="string"&&pn.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root show target ${JSON.stringify(e)} — skipped`),!1}function yn(e){if(e.root.getAttribute?.("data-reactive-show-targets"))return!0;let t=e.root.querySelectorAll?.(Rt)??[];for(let r of t)if(e.core.owns(r))return!0;for(let r of e.root.querySelectorAll?.(W)??[])if(e.core.owns(r))return!0;return!1}function vn(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function bn(e){let t=e.root.getAttribute?.("data-reactive-on-complete")??null;if(t!==e.onCompleteRaw)e.onCompleteRaw=t,e.onCompleteParsed=t==null?[]:mn(t),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function Et(e,t){let r=bn(e);if(!r.length)return;let n=Pt(e,e.core.ownership());r.forEach((o,i)=>{let a=B(o.any,n);if(a===null)return;let s=a&&!e.onCompleteStates[i]&&Boolean(t);if(e.onCompleteStates[i]=a,s)e.core.applyOps(o.ops,"@root")})}function wn(e){if(typeof e.root?.querySelectorAll!=="function")return;let t=e.core.ownership(),r=e.root.getAttribute?.("data-reactive-scope")||null,n=Pt(e,t);for(let o of e.root.querySelectorAll(Rt)){if(!t(o))continue;let i=o.getAttribute("data-reactive-show");if(i!==null){let u=Ot(Nt(i),n);if(u!==null)kt(o,u,t,r);continue}let a=o.getAttribute("data-reactive-show-field");if(!a)continue;let s=n(a);if(s===null)continue;let c=hn(o,s);if(c===null)continue;kt(o,c,t,r)}if(e.groups)kn(e,n,t,r);An(e,n)}function kt(e,t,r,n){if(e.hidden=!t,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let o of e.querySelectorAll("input[name], select[name], textarea[name]"))if(r(o))o.disabled=!t;if(e.name&&r(e))e.disabled=!t}function An(e,t){let r=_n(e);for(let[n,o]of Object.entries(r)){if(n.startsWith("#")){Sn(n,o,t);continue}if(!o||typeof o!=="object"||Array.isArray(o))continue;let i=t(n);if(i===null)continue;let a=(s,c)=>c?t(n,!0):i;for(let[s,c]of Object.entries(o)){if(!Ct(s))continue;let u;if(Array.isArray(c)){if(c.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${s} — skipped`);continue}u=c.every((l)=>ge(l,a))}else{let l=Ht(c,i);if(l===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${s} — skipped`);continue}u=l}for(let l of document.querySelectorAll(s))l.hidden=!u}}}function Sn(e,t,r){if(!Ct(e))return;let n=t&&typeof t==="object"&&!Array.isArray(t)?t.any:null,o=Jn(n);if(o===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(o.every((a)=>r(a)===null))return;let i=B(n,r);if(i===null)return;for(let a of document.querySelectorAll(e))a.hidden=!i}function _n(e){let t=e.root.getAttribute?.("data-reactive-show-targets");if(!t)return{};try{let r=JSON.parse(t);if(r&&typeof r==="object"&&!Array.isArray(r))return r}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: { ... })"),{}}function xn(e,t,r,n){let o=!1,i=null;for(let a of e.root.querySelectorAll(Mt(t,n))){if(!r(a))continue;if(a.type==="checkbox")return a.checked?"true":"false";if(a.type==="radio"){if(a.checked)return a.value??"";o=!0;continue}i??=a}if(i)return i.value??"";return o?"":null}function Mt(e,t){return`[name="${t&&!e.includes("[")?`${t}[${e}]`:e}"]`}function Pt(e,t){let r=e.root.getAttribute?.("data-reactive-scope")||null,n=new Map;return(o,i)=>{let a=i?`#${o}`:o;if(!n.has(a))n.set(a,i?ae(e,o,t,r).filter((s)=>s.checked).length:xn(e,o,t,r));return n.get(a)}}var W="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function Tn(e){return!!e.root.querySelector?.(W)}function ae(e,t,r,n){return[...e.root.querySelectorAll(Mt(t,n))].filter((o)=>o.type==="checkbox"&&r(o))}function En(e,t){let r=t?.getAttribute?.("data-reactive-select-all");if(!r||!e.core.owns(t))return;let n=e.root.getAttribute?.("data-reactive-scope")||null,o=ae(e,r,e.core.ownership(),n).filter((i)=>i!==t&&i.checked!==t.checked);for(let i of o)i.checked=t.checked;e.flipping=!0;try{for(let i of o)for(let a of["input","change"])i.dispatchEvent?.(new Event(a,{bubbles:!0}))}finally{e.flipping=!1}}function kn(e,t,r,n){for(let o of e.root.querySelectorAll(W)){if(!r(o))continue;let i=o.getAttribute("data-reactive-enable");if(i!==null){let c=Ot(Nt(i),t);if(c!==null)o.disabled=!c}let a=o.getAttribute("data-reactive-count");if(a){let c=String(t(a,!0));if(o.textContent!==c)o.textContent=c}let s=o.getAttribute("data-reactive-select-all");if(s){let c=ae(e,s,r,n).filter((l)=>l!==o),u=c.filter((l)=>l.checked).length;o.checked=u>0&&u===c.length,o.indeterminate=u>0&&u<c.length}}}function Ft(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let t=(n)=>e.root.getAttribute?.(`data-reactive-${n}`)?.includes("checked_");if(!e.root.querySelector?.(`${W}, [data-reactive-show*=checked_]`)&&!t("show-targets")&&!t("on-complete"))return;let r=(n)=>n.nodeType===1&&(n.matches('input[type="checkbox"]')||!!n.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((n)=>{if(!n.some((o)=>[...o.addedNodes,...o.removedNodes].some(r)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function D(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function Fn(e,t){let r=e.root.getAttribute("data-reactive-filter-input");return!!r&&typeof t.target?.matches==="function"&&t.target.matches(r)}function F(e){if(typeof e.root?.querySelectorAll!=="function")return;let t=e.root.getAttribute("data-reactive-filter-input"),r=e.root.getAttribute("data-reactive-filter-option");if(!t||!r)return;let n=e.core.ownership(),o=[...e.root.querySelectorAll(t)].find(n);if(!o)return;let i=(o.value??"").trim().toLowerCase(),a=0;for(let u of e.root.querySelectorAll(r)){if(!n(u))continue;let l=(u.getAttribute("data-reactive-filter-text")??u.textContent??"").toLowerCase(),f=u.hasAttribute?.("data-reactive-tags-selected")||i!==""&&!l.includes(i);if(u.hidden=f,f)u.removeAttribute("data-reactive-highlighted");else a++}let s=e.root.getAttribute("data-reactive-filter-group");if(s)for(let u of e.root.querySelectorAll(s)){if(!n(u))continue;let l=[...u.querySelectorAll(r)].filter(n);if(l.length===0)continue;u.hidden=l.every((f)=>f.hidden)}let c=e.root.getAttribute("data-reactive-filter-empty");if(c){for(let u of e.root.querySelectorAll(c))if(n(u))u.hidden=a>0}}function j(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function Ln(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function ce(e){if(typeof e.root?.querySelectorAll!=="function")return null;let t=e.root.getAttribute("data-reactive-tags-field");if(!t)return null;let r=e.core.ownership();return[...e.root.querySelectorAll(t)].find(r)??null}function ue(e){let t=new Set,r=[];for(let n of String(e.value??"").split(",")){let o=n.trim();if(o===""||t.has(o.toLowerCase()))continue;t.add(o.toLowerCase()),r.push(o)}return r}function $t(e,t){let r=ce(e);if(!r)return!1;let n=ue(r),o=new Set(n.map((a)=>a.toLowerCase())),i=!1;for(let a of t){let s=String(a??"").trim();if(s===""||o.has(s.toLowerCase()))continue;o.add(s.toLowerCase()),n.push(s),i=!0}if(i)It(e,r,n);return i}function It(e,t,r){t.value=r.join(","),L(t),qt(e)}function Rn(e){if(typeof e.root?.querySelectorAll!=="function")return null;let t=e.root.getAttribute("data-reactive-filter-input");if(!t)return null;let r=e.core.ownership();return[...e.root.querySelectorAll(t)].find(r)??null}function qt(e){let t=ce(e);if(!t)return;let r=ue(t),n=e.core.ownership();Nn(e,r,n),On(e,r,n)}function Nn(e,t,r){let n=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(r);if(!n)return;let i=[...e.root.querySelectorAll("[data-reactive-tags-template]")].find(r)?.content?.firstElementChild;if(!i){if(!e.tagsWarnedTemplate)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."),e.tagsWarnedTemplate=!0;return}while(n.firstChild)n.removeChild(n.firstChild);for(let a of t){let s=i.cloneNode(!0);s.setAttribute?.("data-reactive-tag",a);let c=s.matches?.("[data-reactive-tag-text]")?s:(s.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(c)c.textContent=a;let u=[...s.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(s.matches?.('[data-action*="reactive#tagsRemove"]'))u.push(s);for(let l of u)l.setAttribute?.("data-reactive-tag-param",a);n.appendChild(s)}}function On(e,t,r){let n=new Set(t.map((o)=>o.toLowerCase()));for(let o of e.root.querySelectorAll("[role=option]")){if(!r(o))continue;let i=o.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))o.setAttribute("data-reactive-tags-selected","true"),o.hidden=!0,o.removeAttribute?.("data-reactive-highlighted");else if(o.hasAttribute?.("data-reactive-tags-selected")){if(o.removeAttribute("data-reactive-tags-selected"),!D(e))o.hidden=!1}}if(D(e))F(e)}function Cn(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Mn(e,t){let r=[e,...e.querySelectorAll?.("*")??[]];for(let n of r)for(let o of["name","id","for"]){let i=n.getAttribute?.(o);if(i&&i.includes("NEW_ROW"))n.setAttribute?.(o,i.replaceAll("NEW_ROW",String(t)))}}function Pn(e,t){if(e.nestedWarned)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${t}"] container + <template data-reactive-nested-template="${t}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),e.nestedWarned=!0}function $n(e,t,r,n){if(!r)return null;let o;try{o=JSON.parse(r)}catch{return null}if(!o||typeof o!=="object")return null;let i=e.core.ownership(),a=[...t.querySelectorAll?.("input, select, textarea")??[]],s=[];for(let[c,u]of Object.entries(o)){let l=[...e.root.querySelectorAll?.(u)??[]].find(i);if(!l)continue;let f=a.find((d)=>Wt(d.getAttribute?.("name"))===c);if(!f)continue;In(f,l),s.push(l)}if(n)for(let c of s)qn(c);return s[0]??null}function In(e,t){if(e.type==="checkbox")e.checked=t.type==="checkbox"?!!t.checked:te(t)!=="";else e.value=te(t);L(e)}function qn(e){if(e.type==="checkbox")e.checked=!1;else e.value="";L(e)}function Dn(e,t){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(r,n)=>Object.prototype.hasOwnProperty.call(t,n)?t[n]:r)}function Lt(e,t){let r=[...t.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(r)r.value="1",L(r),t.hidden=!0;else t.parentNode?.removeChild?.(t);le(e)}function le(e){if(typeof e.root?.querySelectorAll!=="function")return;let t=e.core.ownership();for(let r of[...e.root.querySelectorAll("[data-reactive-nested-json]")].filter(t))jt(e,r.getAttribute("data-reactive-nested-json"))}function Wn(e,t){let r=t.getAttribute?.("data-reactive-nested-json-field");if(!r)return null;let n=e.core.ownership();return[...e.root.querySelectorAll(r)].find(n)??null}function Dt(e,t){let r={},n=e.core.ownership();for(let o of[...t.querySelectorAll?.("input, select, textarea")??[]]){if(o.matches(":disabled")||o.type==="radio"&&!o.checked||!n(o))continue;let i=Wt(o.getAttribute?.("name"));if(i===null||i==="_destroy")continue;r[i]=te(o)}return r}function Wt(e){if(!e)return null;let t=e.match(/\[([^\][]+)\]$/);return t?t[1]:e}function te(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function jt(e,t){let r=e.core.ownership(),n=[...e.root.querySelectorAll(`[data-reactive-nested-list="${t}"]`)].find(r);if(!n)return;let o=Wn(e,n);if(!o)return;let i=[];for(let s of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!r(s)||s.hidden)continue;i.push(Dt(e,s))}let a=JSON.stringify(i);if(o.value===a)return;o.value=a,L(o)}function fe(e,t,r){let n=A(e,t);if(!j(n))return;if(r?.defaultPrevented)return;if(n.core.listnavOptions(r).some((a)=>a.hasAttribute?.("data-reactive-highlighted")))return;r?.preventDefault?.();let o=r?.currentTarget??r?.target;if(!o)return;if(!$t(n,String(o.value??"").split(",")))return;if(o.value="",D(n))F(n)}function de(e,t,r){let n=A(e,t);if(!j(n))return;r?.preventDefault?.();let i=(r?.currentTarget??r?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!$t(n,[i]))return;let a=Rn(n);if(!a)return;a.value="",F(n),a.focus?.()}function pe(e,t,r){let n=A(e,t);if(!j(n))return;r?.preventDefault?.();let i=(r?.currentTarget??r?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let a=ce(n);if(!a)return;let s=ue(a),c=s.filter((u)=>u.toLowerCase()!==i.toLowerCase());if(c.length===s.length)return;It(n,a,c)}function he(e,t,r){let n=A(e,t);r?.preventDefault?.();let o=r?.currentTarget??r?.target,i=o?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof n.root?.querySelectorAll!=="function")return;let a=n.core.ownership(),s=[...n.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(a),u=[...n.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(a)?.content?.firstElementChild;if(!s||!u){Pn(n,i);return}let l=u.cloneNode(!0);Mn(l,Cn(n)),s.appendChild(l);let f=o?.getAttribute?.("data-reactive-nested-from-param"),d=o?.getAttribute?.("data-reactive-nested-clear-param")==="true",h=$n(n,l,f,d);if(f)h?.focus?.();else[...l.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(s.getAttribute?.("data-reactive-nested-json")===i)jt(n,i)}function me(e,t,r){let n=A(e,t);r?.preventDefault?.();let o=r?.currentTarget??r?.target,i=o?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==n.root)return;let a=o?.getAttribute?.("data-reactive-confirm-param"),s=o?.getAttribute?.("data-reactive-confirm-when-param"),c=a||(s?Kt(n,s):null);if(!c)return Lt(n,i);let u=Dt(n,i),l=Dn(c,u);return n.core.confirm(l,{el:o,row:i,fields:u}).then((f)=>{if(f)Lt(n,i)})}function Bt(e,t){let r=t?.target;if(!r||!e.core.owns(r))return;le(e)}var Jt=["gte","gt","lte","lt"],jn=["len_eq","len_gte","len_gt","len_lte","len_lt"],Bn=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"];function Ut(e,t,r){if(!Number.isInteger(t))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(t)} — skipped`),null;switch(e.slice(e.indexOf("_")+1)){case"eq":return r===t;case"gte":return r>=t;case"gt":return r>t;case"lte":return r<=t;case"lt":return r<t;default:return null}}function zt(e,t,r){let n=Number(t);if(Number.isNaN(n))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(t)} — skipped`),null;let o=r==null?"":String(r).trim(),i=o===""?NaN:Number(o);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=n;case"gt":return i>n;case"lte":return i<=n;case"lt":return i<n;default:return null}}function Ht(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 r of Jt)if(r in e)return zt(r,e[r],t);for(let r of jn)if(r in e)return Ut(r,e[r],[...String(t??"")].length);return null}function ge(e,t){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let r=Bn.find((o)=>(o in e));if(r){let o=t(e.field,!0);return Ut(r,e[r],Array.isArray(o)?o.length:Number(o)||0)===!0}let n=t(e.field)??"";return Ht(e,n)===!0}function B(e,t){if(!Array.isArray(e)||e.length===0)return null;return e.some((r)=>Array.isArray(r)&&r.length>0&&r.every((n)=>ge(n,t)))}function Jn(e){if(!Array.isArray(e)||e.length===0)return null;let t=new Set;for(let r of e){if(!Array.isArray(r))continue;for(let n of r)if(n&&typeof n==="object"&&typeof n.field==="string")t.add(n.field)}return t.size>0?[...t]:null}function Kt(e,t){let r=t;if(typeof t==="string")try{r=JSON.parse(t)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(t)} — skipped`),null}if(!r||typeof r!=="object")return null;let{fields:n}=e.core.collectFields(),o=(a)=>n[a],i;if(typeof r.predicate==="string"){let a=dn(r.predicate);if(!a)return console.warn(`[phlex-reactive] confirm predicate "${r.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!a(n)}else i=B(r.groups?.any,o)===!0;return i?r.message:null}import{computeReducer as Un}from"phlex/reactive/compute";var N=new WeakMap;function Zt(e,t){let r=N.get(e);if(!r)N.set(e,r={root:e.element,core:t,ours:new WeakSet,opsSig:null});return r}function ve(e,t,r,n){let o=Zt(e,t),i=io(o);if(i)o.seed=()=>ye(o),o.root.addEventListener?.("turbo:morph-element",o.seed);if(i||n?.edited)ye(o)}function be(e){let t=N.get(e);if(!t)return;if(N.delete(e),t.seed)t.root.removeEventListener?.("turbo:morph-element",t.seed)}function we(e){N.get(e)?.seed?.()}function Ae(e,t,r){return ye(Zt(e,t),r)}var zn=Object.freeze({el:null,kind:""}),Hn=/^#[A-Za-z_][\w-]*$/;function R({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??""}function Xt(e){if(typeof e==="boolean")return e;if(e==null)return!1;let t=String(e);return t!==""&&t!=="0"&&t!=="false"}function Kn(e,t){if(t==="string")return R(e);let r=e.kind==="checkbox";if(t==="boolean")return r?Boolean(e.el.checked):Xt(R(e));if(r)return e.el.checked?1:0;let n=Number(R(e));return Number.isFinite(n)?n:0}function Yn(e,t,{el:r,kind:n},o,i){if(n==="checkbox"){let a=Xt(i);if(Boolean(r.checked)===a)return null;return r.checked=a,r}if(n==="radio")return Gn(e,t,o,String(i));if(String(i)===r.value)return null;return r.value=i,r}function Gn(e,t,r,n){let o=null;for(let i of e.querySelectorAll(`[name="${r}"]`)){if(i.type!=="radio"||!t(i))continue;let a=i.value===n;if(Boolean(i.checked)===a)continue;if(i.checked=a,a)o=i;else o??=i}return o}function Vn(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 Zn(e){if(typeof e==="string"&&Hn.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root mirror target ${JSON.stringify(e)} — skipped`),!1}function Xn(e,t,r){let n=t===null?null:JSON.stringify(t),o=n!==null&&n!==e.opsSig&&r;if(e.opsSig=n,!o)return;e.core.applyOps(t,"@root")}function Qn(e,t){let r=e.root.getAttribute(t);if(!r)return[];try{let n=JSON.parse(r);return Array.isArray(n)?n:[]}catch{return[]}}function eo(e){let t=e.root.getAttribute("data-reactive-compute-inputs-param");if(!t)return[];try{let r=JSON.parse(t);if(Array.isArray(r))return r.map((n)=>[n,"number"]);if(r&&typeof r==="object")return Object.entries(r);return[]}catch{return[]}}function to(e,t,r,n){let o=t?.target;if(!o?.name||typeof o.closest!=="function")return null;let i=ro(o.name,n);if(!r.includes(i))return null;return e.core.owns(o)?i:null}function ro(e,t){if(!t)return e;let r=`${t}[`;return e.startsWith(r)&&e.endsWith("]")?e.slice(r.length,-1):e}function Gt(e,t,r){let n=String(r);for(let o of no(e,t)){if(o.textContent===n)continue;o.textContent=n}}function no(e,t){let r=e.root.querySelectorAll(`[data-reactive-text="${t}"]`);return Array.from(r).filter((n)=>e.core.owns(n))}function Vt(e,t,r){let n=oo(e);for(let[o,i]of Object.entries(n)){let a=o in t?null:r(o),s=o in t?t[o]:a.el?R(a):void 0;if(s===void 0||s===null)continue;let c=String(s);for(let u of Array.isArray(i)?i:[i]){if(!Zn(u))continue;for(let l of document.querySelectorAll(u)){if(l.textContent===c)continue;l.textContent=c}}}}function oo(e){let t=e.root.getAttribute("data-reactive-compute-mirror-param");if(!t)return{};try{let r=JSON.parse(t);return r&&typeof r==="object"&&!Array.isArray(r)?r:{}}catch{return{}}}function io(e){return e.root.getAttribute?.("data-reactive-compute-seed")==="true"}function ye(e,t){if(t&&e.ours.has(t))return;let r=eo(e),n=r.map(([p])=>p),o=e.root.getAttribute?.("data-reactive-scope")||null,i=(p)=>o&&!p.includes("[")?`${o}[${p}]`:p,a=e.core.ownership(),s=new Map,c=(p)=>{let m=s.get(p);if(m)return m;let y=null,w=null,_=null;for(let x of e.root.querySelectorAll(`[name="${i(p)}"]`)){if(!a(x))continue;let q=x.type;if(q==="checkbox"||q==="radio"&&x.checked){_={el:x,kind:q};break}if(q==="radio")y??=x;else w??=x}if(!_)if(y)_={el:y,kind:"radio"};else _=w?{el:w,kind:""}:zn;return s.set(p,_),_};for(let p of n)Gt(e,p,R(c(p)));let u=e.root.getAttribute("data-reactive-compute-reducer-param"),l=u?Un(u):null;if(!l){Vt(e,{},c);return}let f=Qn(e,"data-reactive-compute-outputs-param"),d={};for(let[p,m]of r)d[p]=Kn(c(p),m);let h=l(d,{changed:to(e,t,n,o)})||{},g=Vn(h.$ops),S=[];for(let p of f){if(p==="$ops"||!(p in h))continue;let m=c(p);if(!m.el)continue;let y=Yn(e.root,a,m,i(p),h[p]);if(y)S.push(y)}for(let p of Object.keys(h)){if(p==="$ops")continue;let m=h[p];if(m===void 0||m===null)continue;Gt(e,p,m)}Vt(e,h,c);for(let p of S){let m=new Event("input",{bubbles:!0});e.ours.add(m),p.dispatchEvent(m)}Xn(e,g,Boolean(t))}var nr;function xe(e){nr=e}var or=1,so="phlex-reactive:persist:",ao=new Set(["hidden","file","password","submit","button","reset","image"]),Te=Symbol("persist-no-value"),Ee="data-reactive-persist-state",co=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",uo=new Set(["lexxy-editor","trix-editor"]),lo="lexxy-editor, trix-editor, trix-toolbar",fo=["lexxy:change","trix-change"],po=new Set(["","<p></p>","<p><br></p>","<div><br></div>"]),er=new WeakSet,tr=new WeakSet,rr=new WeakSet;function U(e){let t=e?.getAttribute?.("data-reactive-persist");if(!t||t==="off")return null;try{let r=JSON.parse(t);if(r&&typeof r==="object"&&typeof r.key==="string"&&r.key!=="")return r}catch{}if(!er.has(e))er.add(e),console.warn(`[phlex-reactive] malformed reactive_persist payload ${JSON.stringify(t)} — persistence disabled`);return null}function ke(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function Fe(e,t){if(e?.getAttribute?.("data-reactive-debug")!=="true"||tr.has(e))return;tr.add(e),console.info(`[phlex-reactive] reactive_persist: storage unavailable — draft skipped (${t?.name??t})`)}function Le(e){return so+e.key}function Se(e,t){let r=ke();if(!r)return null;let n;try{n=r.getItem(Le(t))}catch(c){return Fe(e,c),null}if(!n)return null;let o;try{o=JSON.parse(n)}catch{return null}if(!o||typeof o!=="object"||o.v!==or)return null;let i=Number(t.ttl)*1000;if(!(Number(o.savedAt)+i>Date.now()))return J(e,t),null;let a=o.fields&&typeof o.fields==="object"?o.fields:{},s=o.state&&typeof o.state==="object"?o.state:null;return{fields:a,state:s}}function ir(e,t,{fields:r,state:n}){let o=ke();if(!o)return!1;let i={v:or,savedAt:Date.now(),fields:r};if(n)i.state=n;try{return o.setItem(Le(t),JSON.stringify(i)),!0}catch(a){return Fe(e,a),!1}}function J(e,t){e?.removeAttribute?.(Ee);let r=ke();if(!r)return;try{r.removeItem(Le(t))}catch(n){Fe(e,n)}}function Re(e,t){let r=Array.isArray(t.fields)?new Set(t.fields):null,n=[],o=(i)=>i.closest('[data-controller~="reactive"]')===e&&i.getAttribute("data-reactive-persist")!=="off";for(let i of e.querySelectorAll("input[name], select[name], textarea[name]")){if(!o(i)||ao.has(i.type)||i.closest(lo))continue;if(r&&!r.has(i.name))continue;n.push({el:i,name:i.name,kind:"native"})}for(let i of e.querySelectorAll(co)){if(!o(i))continue;let a=ho(i);if(!a||r&&!r.has(a))continue;n.push({el:i,name:a,kind:uo.has(i.localName)?"editor":"contenteditable"})}return n}function ho(e){return e.getAttribute("name")||typeof e.name==="string"&&e.name||null}function Ne(e){return typeof e.value==="string"}function mo(e){if(typeof e.isEmpty==="boolean")return e.isEmpty;let t=e.editor?.getDocument?.();if(typeof t?.isEmpty==="function")return t.isEmpty();return po.has(e.value.trim())}function go(e,t,r){if(e?.getAttribute?.("data-reactive-debug")!=="true"||rr.has(e))return;rr.add(e),console.info(`[phlex-reactive] reactive_persist: could not restore editor ${JSON.stringify(t)} — ${r?.message??r}`)}function O(e){return e.tagName==="SELECT"&&e.multiple}function sr(e){let t=new Map;for(let{el:r,name:n}of e){if(r.type==="radio"||!String(n).endsWith("[]"))continue;t.set(n,(t.get(n)??0)+1)}return t}function ar(e,t,r){if(!Array.isArray(e))return e;if(r.get(t)!==1||e.length!==1)return Te;return e[0]}function cr(e,t){let r={},n=(o)=>{let i=r[o];return Array.isArray(i)?i:r[o]=[]};for(let{el:o,name:i,kind:a}of Re(e,t)){let s=String(i).endsWith("[]");if(a==="editor"){if(Ne(o))if(s)n(i).push(o.value);else r[i]=o.value}else if(a==="contenteditable"){let c=o.textContent??"";if(s)n(i).push(c);else r[i]=c}else if(o.type==="radio"){if(o.checked)r[i]=o.value;else if(!Object.hasOwn(r,i))r[i]=null}else if(o.type==="checkbox")if(s){let c=n(i);if(o.checked)c.push(o.value)}else r[i]=o.checked;else if(O(o)){let c=[...o.options].filter((u)=>u.selected).map((u)=>u.value);if(s)n(i).push(...c);else r[i]=c}else if(s)n(i).push(o.value);else r[i]=o.value}return r}function yo(e,t,r){let n=t.restore==="always",o=Re(e,t),i=sr(o),a=new Set;for(let s of o)if(s.kind==="native"&&s.el.type==="checkbox"&&s.el.checked)a.add(s.name);for(let{el:s,name:c,kind:u}of o){if(!Object.hasOwn(r,c))continue;let l=r[c];if(l===null||l===void 0)continue;if(Array.isArray(l)&&O(s)&&(i.get(c)??0)>1)continue;if(Array.isArray(l)&&!(s.type==="checkbox"||O(s))){if(l=ar(l,c,i),l===Te)continue}if((s.type==="checkbox"||O(s))&&String(c).endsWith("[]")&&!Array.isArray(l))continue;if(u==="editor")ur(e,s,c,l,n);else if(u==="contenteditable"){if(!n&&(s.textContent??"").trim()!=="")continue;s.textContent=String(l)}else if(s.type==="radio"){if(!n&&o.some((f)=>f.kind==="native"&&f.el.type==="radio"&&f.name===c&&f.el.checked))continue;s.checked=s.value===String(l)}else if(s.type==="checkbox"&&Array.isArray(l)){if(!n&&a.has(c))continue;s.checked=l.map(String).includes(s.value)}else if(s.type==="checkbox"){if(!n&&s.checked)continue;s.checked=Boolean(l)}else if(O(s)){if(!n&&[...s.options].some((d)=>d.selected))continue;let f=new Set((Array.isArray(l)?l:[l]).map(String));for(let d of s.options)d.selected=f.has(d.value)}else{if(!n&&s.value!=="")continue;s.value=String(l)}}vo(e,t,r)}function ur(e,t,r,n,o){if(Array.isArray(n))return;if(!Ne(t))return;if(!o&&!mo(t))return;try{t.value=String(n)}catch(i){go(e,r,i)}}function vo(e,t,r){let n=globalThis.customElements;if(typeof n?.whenDefined!=="function")return;let o=new Set;for(let a of e.querySelectorAll("lexxy-editor, trix-editor"))if(!Ne(a)&&!n.get?.(a.localName))o.add(a.localName);let i=t.restore==="always";for(let a of o)n.whenDefined(a).then(()=>{if(!e.isConnected)return;let s=Re(e,t),c=sr(s);for(let{el:u,name:l,kind:f}of s){if(f!=="editor"||u.localName!==a||!Object.hasOwn(r,l))continue;let d=ar(r[l],l,c);if(d===null||d===void 0||d===Te)continue;ur(e,u,l,d,i)}})}function bo(e,t,r=!0){let n=U(e);if(!n){console.warn("[phlex-reactive] persist_state on a root without reactive_persist — skipped");return}if(!t||typeof t!=="object")return;let o=Se(e,n),i={...o?.state??{},...t},a=r?cr(e,n):o?.fields??{};if(ir(e,n,{fields:a,state:i}))e.setAttribute?.(Ee,JSON.stringify(i))}function wo(e){let t=U(e);if(t)J(e,t)}var _e=new WeakMap;function Oe(e,t,r,n){let o=e.element,i=U(o);if(!i)return;if(n?.submitted)J(o,i);let a=Se(o,i);if(a){if(yo(o,i,a.fields),a.state)o.setAttribute?.(Ee,JSON.stringify(a.state));t.emit("reactive:persist-restored",{key:i.key,fields:a.fields,state:a.state??{}}),t.reseed()}let s=null,c=()=>{if(s!==null)clearTimeout(s),s=null},u=()=>{c();let h=Se(o,i);ir(o,i,{fields:cr(o,i),state:h?.state??null})},l=()=>{let h=Number(i.debounce)||0;if(h<=0)return u();if(s!==null)clearTimeout(s);s=setTimeout(()=>{s=null,u()},h)},f=(h)=>{if(!h?.detail?.success)return;let g=h.target;if(g?.tagName!=="FORM"||typeof g.contains!=="function")return;if(!g.contains(o))return;c(),J(o,i)},d=["input",...fo];for(let h of d)o.addEventListener?.(h,l);if(o.addEventListener?.("change",u),document.addEventListener?.("turbo:submit-end",f),_e.set(e,()=>{if(s!==null)u();for(let h of d)o.removeEventListener?.(h,l);o.removeEventListener?.("change",u),document.removeEventListener?.("turbo:submit-end",f)}),n?.edited&&!n.submitted)u();for(let h of n?.ops??[])h(!0)}function Ce(e){let t=_e.get(e);_e.delete(e),t?.()}function lr(e,t){let r=nr?.waiting.get(e)?.persist;if(!r||!U(e))return t(!0);(r.ops??=[]).push(t)}function Me(e,t){lr(e,(r)=>bo(e,t,r))}function Pe(e){lr(e,()=>wo(e))}var $e=new WeakMap,dr=new WeakSet;function Ie(e,t){let r=e.element,n=[];$e.set(e,n);let o=(i,a,s)=>{i.addEventListener?.(a,s),n.push(()=>i.removeEventListener?.(a,s))};if(Ao(r,t)){let i=()=>C(e,t);if(o(r,"turbo:morph-element",i),i(),r.getAttribute?.("data-reactive-warn-unsaved")==="true")_o(r,o)}if(xo(r,t)){let i=()=>To(r,t);o(r,"turbo:morph-element",i),i()}}function qe(e){for(let t of $e.get(e)??[])t();$e.delete(e)}function Ao(e,t){if((e.getAttribute?.("data-action")??"").includes("reactive#trackDirty"))return!0;let r=e.querySelectorAll?.('[data-action*="reactive#trackDirty"]')??[];for(let n of r)if(t.owns(n))return!0;return!1}function C(e,t){let r=e.element;if(typeof r?.querySelectorAll!=="function")return;let n=0;if(r.querySelectorAll("input[name], select[name], textarea[name]").forEach((o)=>{if(!t.owns(o))return;if(o.type==="file")return;if(So(o))o.setAttribute("data-reactive-dirty","true"),n++;else o.removeAttribute("data-reactive-dirty")}),n>0)r.setAttribute("data-reactive-dirty",String(n));else r.removeAttribute("data-reactive-dirty")}function So(e){if(e.type==="checkbox"||e.type==="radio")return e.checked!==e.defaultChecked;if(e.tag==="select"||e.options){let t=Array.from(e.options??[]),r=!e.multiple&&!(e.size>1),n=t.filter((o)=>o.defaultSelected).pop()??t.find((o)=>!o.closest?.("optgroup")?.disabled&&!o.disabled);return t.some((o)=>o.selected!==(r?o===n:o.defaultSelected))}return e.value!==e.defaultValue}function pr(e){let t=e.getAttribute?.("data-reactive-dirty"),r=Number(t);return Number.isFinite(r)&&r>0?r:0}function _o(e,t){if(typeof window>"u"||typeof window.addEventListener!=="function")return;t(window,"beforeunload",(r)=>{if(pr(e)===0)return;return r.preventDefault(),r.returnValue="You have unsaved changes.",r.returnValue}),t(window,"turbo:before-visit",(r)=>{if(pr(e)===0||dr.has(r))return;if(dr.add(r),!(typeof window.confirm==="function"?window.confirm("You have unsaved changes. Leave anyway?"):!0))r.preventDefault?.()})}function xo(e,t){if(e.getAttribute?.("data-reactive-clipboard"))return!0;let r=e.querySelectorAll?.("[data-reactive-clipboard]")??[];for(let n of r)if(t.owns(n))return!0;return!1}function To(e,t){let r=typeof globalThis.navigator?.clipboard?.readText==="function";if(e.getAttribute?.("data-reactive-clipboard"))e.hidden=!r;for(let n of e.querySelectorAll?.("[data-reactive-clipboard]")??[])if(t.owns(n))n.hidden=!r}function Be(e){Eo(e),Fo(e)}function Eo(e){let t=e.detail,r=t?.render;if(typeof r!=="function"||r.__reactiveDismissWrapped){if(typeof requestAnimationFrame==="function")requestAnimationFrame(De);else setTimeout(De,0);return}let n=async(o)=>{await r(o),De()};n.__reactiveDismissWrapped=!0,t.render=n}function De(){let e=document.querySelectorAll("[data-reactive-dismiss-after]");for(let t of e){if(t.hasAttribute("data-reactive-dismiss-scheduled"))continue;let r=Number(t.getAttribute("data-reactive-dismiss-after"));if(!Number.isFinite(r)||r<=0)continue;t.setAttribute("data-reactive-dismiss-scheduled",""),setTimeout(()=>t.remove(),r)}}var ko=Object.freeze({append:"enter",prepend:"enter",replace:"update",update:"update",remove:"exit"}),We=Object.freeze(["fade","slide","scale","highlight","shake"]),je="data-reactive-fx-pending",Je=1000;function Fo(e){let t=e.detail,r=t?.render;if(typeof r!=="function"||r.__reactiveEffectsWrapped)return;let n=t?.newStream??e.target,o=ko[n?.getAttribute?.("action")];if(!o||No())return;let i=Lo(n,o);if(!i)return;let a=o==="exit"?async(s)=>{await Mo(z(n),i),await r(s)}:async(s)=>{let c=o==="enter"?Oo(n):null;if(await r(s),o==="enter")Co(c,i);else gr(z(n),i)};a.__reactiveEffectsWrapped=!0,t.render=a}function Lo(e,t){let r=e.getAttribute?.("data-reactive-effect");if(r==="off")return null;if(r)return mr(r,t);let o=(t==="enter"?Ro(e):z(e))?.getAttribute?.(`data-reactive-effect-${t}`);return o?mr(o,t):null}function z(e){let t=e.getAttribute?.("target");return t?document.getElementById?.(t)??null:null}function Ro(e){return e.querySelector?.("template")?.content?.firstElementChild??null}function mr(e,t){if(e.startsWith("[")){let n=null;try{let o=JSON.parse(e);if(Array.isArray(o)&&o.length===3)n=o.map(String)}catch{}if(n)return{legs:n};return console.warn(`[phlex-reactive] malformed effect legs ${JSON.stringify(e)} — skipped`),null}let r=e==="random"?We[Math.floor(Math.random()*We.length)]:e;if(!We.includes(r))return console.warn(`[phlex-reactive] unknown effect ${JSON.stringify(e)} — skipped`),null;return{className:`reactive-fx--${r}-${t}`}}function No(){try{return typeof matchMedia==="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches}catch{return!1}}function Oo(e){let t=e.querySelector?.("template")?.content;if(!t)return null;for(let r of Array.from(t.children??[]))r.setAttribute?.(je,"");return z(e)}function Co(e,t){if(typeof e?.querySelectorAll!=="function")return;for(let r of Array.from(e.querySelectorAll(`[${je}]`)))r.removeAttribute(je),gr(r,t)}async function Mo(e,t){if(!e?.classList)return;if(t.legs){await yr(e,t.legs);return}e.classList.add(t.className);let r=Ue(e);if(r<=0){e.classList.remove(t.className);return}await ze(e,r),e.classList.remove(t.className)}function gr(e,t){if(!e?.classList)return;if(t.legs){yr(e,t.legs);return}if(e.classList.contains(t.className))e.classList.remove(t.className),e.offsetWidth;e.classList.add(t.className);let r=Ue(e);if(r<=0){e.classList.remove(t.className);return}let n=e.__reactiveFxToken=(e.__reactiveFxToken??0)+1;ze(e,r).then(()=>{if(e.__reactiveFxToken===n)e.classList.remove(t.className)})}async function yr(e,t){let[r,n,o]=t.map(Po),i=e.__reactiveFxToken=(e.__reactiveFxToken??0)+1;if(e.classList.remove(...r,...n,...o),e.classList.add(...r,...n),await $o(),e.__reactiveFxToken!==i)return;e.classList.remove(...n),e.classList.add(...o);let a=Ue(e);if(a>0)await ze(e,a);if(e.__reactiveFxToken!==i)return;e.classList.remove(...r,...o)}function Po(e){return String(e??"").split(/\s+/).filter(Boolean)}function Ue(e){if(typeof getComputedStyle!=="function")return 0;try{let t=getComputedStyle(e),r=(i)=>String(i??"").split(",").reduce((a,s)=>Math.max(a,parseFloat(s)||0),0),n=r(t.animationDuration)+r(t.animationDelay),o=r(t.transitionDuration)+r(t.transitionDelay);return Math.min(Math.max(n,o)*1000,Je)}catch{return 0}}function ze(e,t){return new Promise((r)=>{let n=(o)=>{if(o&&o.target!==e)return;e.removeEventListener?.("animationend",n),e.removeEventListener?.("transitionend",n),r()};e.addEventListener?.("animationend",n),e.addEventListener?.("transitionend",n),setTimeout(n,Math.min(t+50,Je))})}function $o(){return new Promise((e)=>{if(typeof requestAnimationFrame!=="function")return setTimeout(e,16);let t=setTimeout(()=>{globalThis.cancelAnimationFrame?.(r),e()},Je),r=requestAnimationFrame(()=>{clearTimeout(t),e()})})}var Io="phlex-reactive:latency",He=!1;function wr(e){if(typeof sessionStorage>"u")return;sessionStorage.setItem("phlex-reactive:latency",String(e))}function Ar(){if(typeof sessionStorage>"u")return;sessionStorage.removeItem("phlex-reactive:latency"),He=!1}function Ye(){if(typeof window<"u")window.PhlexReactive={enableLatencySim:wr,disableLatencySim:Ar}}function Ge(){if(typeof sessionStorage>"u")return Promise.resolve();let e=Number(sessionStorage.getItem("phlex-reactive:latency"));if(!Number.isFinite(e)||e<=0)return Promise.resolve();if(!He)He=!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))}var br=new WeakMap;function Ve(e){let t=globalThis.document;if(!t)return!0;let r=br.get(t);if(!r)r=new Set,br.set(t,r);if(r.has(e))return!0;return r.add(e),!1}function Ke(e,t){try{return e?.querySelectorAll?.(t)?.length??0}catch{return 0}}function Sr(e,t,r,n){if(Ve(`${e}|${t}|${r}`))return;console.warn(`[phlex-reactive] ${e} matched zero targets for selector "${t}" (${r})${n}`)}function Ze(e,t,r){let n=t.to;if(typeof n!=="string"||n===""||n==="@root")return;let o="";if(r&&!t.global){let i=Ke(globalThis.document,n);if(i>0)o=` — it matches ${i} element(s) outside the stream's target root; use global: true`}Sr(`client op "${e}"`,n,r?`scoped to #${r.id||"?"}`:"document-scoped",o)}function Xe(e){if(!Ve(`missing-root|#${e}`))console.warn(`[phlex-reactive] reactive:js stream target root #${e} is not in the DOM — its ops were dropped`)}function Qe(e,t,r){let n=e.element,o=r.to;if(typeof o!=="string"||o===""||o==="@root")return;let i="";if(!r.global)if(n?.matches?.(o))i=" — the selector matches this component's own root, which root-scoped resolution never includes; use to: :root";else if(Ke(n,o)>0)i=" — it matches only inside a nested reactive root (excluded by ownership scoping); use global: true";else{let a=Ke(globalThis.document,o);if(a>0)i=` — it matches ${a} element(s) outside this scope; use global: true`}Sr(t,o,`scoped to #${n?.id||"?"}`,i)}function et(e,t){let r=e.element?.id||"?";if(Ve(`no-binding|${t.type}|${r}`))return;console.warn(`[phlex-reactive] runOps on #${r} found no on_client binding matching a "${t.type}" event — nothing ran`)}function qo(e){if(!e)return[];let t=[],r=/<turbo-stream\b([^>]*)>/g,n;while((n=r.exec(e))!==null){let o=n[1],i=o.match(/\baction="([^"]*)"/)?.[1]??"?",a=o.match(/\btarget="([^"]*)"/)?.[1];t.push(a?`${i} → #${a}`:i)}return t}function tt(e,t){let{action:r,status:n,ms:o}=t,i=e.element?.id,s=`reactive ${i?`#${i} `:""}${r} → ${n??"—"} (${Math.round(o)}ms)`;if(console.groupCollapsed(s),console.log(`params: [${t.paramNames.join(", ")}] + collected: [${t.fieldNames.join(", ")}]`),console.log(`encoding: ${t.encoding}`),t.streams.length)console.log(`streams: ${t.streams.join(" ")}`);console.log(`token: ${t.tokenRefreshed?"refreshed ✓":"unchanged"}`),console.groupEnd()}function H(e,t,r){e.streams=qo(t),e.tokenRefreshed=r!=null}var K=new WeakMap;function rt(e,t,r,n){let o=r&&typeof r==="object"?jo(r):r;return o?xr(t,o,n,!1):[]}function nt(e,t,r,n){if(!r)return null;let o=xr(t,r,n,!0);return o.length?o:null}function xr(e,t,r,n){let o=[];for(let i of Tr(e,t,r)){if(t.add_class){let a=t.add_class.filter((s)=>!i.classList.contains(s));if(i.classList.add(...a),a.length)o.push(()=>i.classList.remove(...a))}if(t.remove_class){let a=t.remove_class.filter((s)=>i.classList.contains(s));if(i.classList.remove(...a),a.length)o.push(()=>i.classList.add(...a))}if(t.toggle_class)t.toggle_class.forEach((a)=>i.classList.toggle(a)),o.push(()=>t.toggle_class.forEach((a)=>i.classList.toggle(a)));if(t.hide&&!i.hidden)i.hidden=!0,o.push(()=>i.hidden=!1);if(t.show&&i.hidden)i.hidden=!1,o.push(()=>i.hidden=!0)}if(r&&(t.disable||t.text!=null))o.push(Do(t,r));if(n&&t.checked==="keep"&&r&&"checked"in r){let i=r.checked;o.push(()=>r.checked=!i)}return o}function Tr(e,t,r){if(t.to==null)return r?[r]:[];let n=e.opTargets({to:t.to});if(n.length===0)e.diagnose("busy/optimistic hint",{to:t.to});return n}function Do(e,t){let r=K.get(t);if(r)r.count++;else K.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()=>Wo(t,e)}function Wo(e,t){let r=K.get(e);if(!r)return;if(--r.count>0)return;if(K.delete(e),!e.isConnected)return;if(t.disable)e.disabled=r.disabled;if(r.hadText&&e.innerHTML===r.swappedTo)e.innerHTML=r.html}function jo(e){if(!e||typeof e!=="object")return null;let{class:t,...r}=e;return t==null?e:{...r,add_class:t}}function ot(e,t,r,n){if(!r?.hide)return null;let o=Tr(t,r,n);if(!o.length)return null;return()=>{let i=o.filter((a)=>a.isConnected&&!a.hidden);if(!i.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.",i)}}var V;function at(e){V=e}var v=new Map;function Lr(e,t){let r=!v.has(e);if(v.set(e,t),r)V.enter()}function Z(e){if(v.delete(e))V.exit()}var kr=!1;function ct(e){Rr();let t=e.getAttribute("target");if(!t)return;if(e.getAttribute("data-reactive-defer-via")==="stream"){Ko(t,e);return}let r=e.getAttribute("data-reactive-defer-token");if(!r)return;P(t,r)}function Rr(){if(kr||typeof document>"u"||!document.addEventListener)return;kr=!0,document.addEventListener("turbo:before-stream-render",Go,!0),document.addEventListener("turbo:before-stream-render",Bo)}function Bo(e){let t=e.target?.getAttribute?.("target");if(!t?.startsWith("reactive-defer-src-"))return;let r=t.slice(19);if(v.get(r)?.via==="stream")Z(r)}function P(e,t){let r=document.getElementById(e);if(!r){console.warn(`[phlex-reactive] reactive:defer target #${e} is not on the page — skipped`);return}lt(e),Mr(r);let n={via:"fetch",abort:new AbortController,timedOut:!1};return Lr(e,n),Yo(e,n,t)}function Jo(e,t){if(typeof e!=="string"){let r={headers:{Accept:"text/vnd.turbo-stream.html"},credentials:"same-origin",signal:t};if(e.fallback)r.cache="no-store";return[e.src,r]}return[Zo(),{method:"POST",headers:{Accept:"text/vnd.turbo-stream.html","Content-Type":"application/json","X-CSRF-Token":Xo()},body:JSON.stringify({token:e}),credentials:"same-origin",signal:t}]}function Nr(e){let t=e.getAttribute?.("data-reactive-defer-src");if(!t)return;if(Or(t))return{src:t};return console.error(Uo(t)),zo(t)||Ho(e)}function Uo(e){return`[phlex-reactive] refused data-reactive-defer-src="${e}" — it is not under this app's fragment path `+`(${ut()}). If you changed Phlex::Reactive.fragment_path, add `+'<meta name="phlex-reactive-fragment-path" content="…your path…"> to the layout <head>.'}function zo(e){let t;try{t=new URL(e,window.location.href)}catch{return}let r=t.pathname.split("/").pop(),n=`${ut()}/${r}${t.search}`;if(/^[\w-]+$/.test(r)&&Or(n))return{src:n,fallback:!0}}function Ho(e){lt(e.id),ft(e),e.setAttribute("data-reactive-error","defer"),e.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:e.id,reason:"refused-url"}}))}function Or(e){try{let t=new URL(window.location.href),r=new URL(e,t);return r.origin===t.origin&&r.pathname.startsWith(`${ut()}/`)}catch{return!1}}function ut(){return document.head?.querySelector?.('meta[name="phlex-reactive-fragment-path"]')?.content||"/reactive/fragment"}function Ko(e,t){let r=document.getElementById(e);if(!r){console.warn(`[phlex-reactive] reactive:defer target #${e} is not on the page — skipped`);return}let n=t.getAttribute("data-reactive-defer-src");if(!n)return;if(!globalThis.customElements?.get?.("pgbus-stream-source")){let i=t.getAttribute("data-reactive-defer-token");if(i){P(e,i);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}lt(e),Mr(r);let o=document.createElement("pgbus-stream-source");o.id=Cr(e),o.setAttribute("src",n),o.setAttribute("since-id",t.getAttribute("data-reactive-defer-since-id")??"0"),o.setAttribute("hidden",""),document.body.appendChild(o),Lr(e,{via:"stream"})}function Cr(e){return`reactive-defer-src-${e}`}async function Yo(e,t,r){let n=setTimeout(()=>{t.timedOut=!0,t.abort.abort()},Qo()),o;try{V.count("defer"),o=await fetch(...Jo(r,t.abort.signal))}catch(s){if(clearTimeout(n),v.get(e)!==t)return;console.error("[phlex-reactive] deferred render failed",s),M(e,r);return}if(v.get(e)!==t){clearTimeout(n);return}if(o.redirected){clearTimeout(n),console.error(`[phlex-reactive] deferred render failed: redirected to ${o.url??"another URL"}`),M(e,r,o.status);return}if(o.status===204){clearTimeout(n),Fr(e);return}if(!o.ok){clearTimeout(n),console.error(`[phlex-reactive] deferred render failed: HTTP ${o.status}`),M(e,r,o.status);return}let i=o.headers?.get?.("Content-Type")||"";if(!i.includes("turbo-stream")){clearTimeout(n),console.error(`[phlex-reactive] deferred render failed: expected a turbo-stream, got "${i}"`),M(e,r,o.status);return}let a;try{a=await o.text()}catch(s){if(clearTimeout(n),v.get(e)!==t)return;console.error("[phlex-reactive] deferred render failed reading the body",s),M(e,r);return}if(clearTimeout(n),v.get(e)!==t)return;Fr(e),Vo(a)}var st=null,Go=(e)=>st?.push(e);function Vo(e){let t=st=[];try{window.Turbo.renderStreamMessage(e)}finally{st=null}for(let r of t){if(r.defaultPrevented)continue;let n=r.detail,o=n.render;n.render=()=>{},new Promise((i)=>i(o(n.newStream))).catch(console.error)}}function lt(e){let t=v.get(e);if(!t)return;if(Z(e),t.via==="fetch")t.abort.abort();else document.getElementById(Cr(e))?.remove?.()}function Mr(e){e.setAttribute("data-reactive-defer-pending","true"),e.setAttribute("aria-busy","true")}function ft(e){e.removeAttribute("data-reactive-defer-pending"),e.removeAttribute("aria-busy")}function Fr(e){Z(e);let t=document.getElementById(e);if(!t)return;ft(t),t.removeAttribute("data-reactive-error")}function M(e,t,r){Z(e);let n=document.getElementById(e);if(!n)return;ft(n),n.setAttribute("data-reactive-error","defer");let o=()=>{let i=document.getElementById(e);if(!i){console.warn("[phlex-reactive] defer retry() ignored — the target left the DOM");return}i.removeAttribute("data-reactive-error"),P(e,t)};n.dispatchEvent(new CustomEvent("reactive:error",{bubbles:!0,composed:!0,detail:{kind:"defer",target:e,status:r,retry:o}}))}function Zo(){return document.querySelector('meta[name="phlex-reactive-defer-path"]')?.content||"/reactive/defer"}function Xo(){return document.querySelector('meta[name="csrf-token"]')?.content??""}function Qo(){let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return Number.isFinite(t)&&t>0?t:30000}var Pr="__materialize",G=new WeakMap;function Y(e){if(e.getAttribute?.("data-reactive-lazy-visible")!=null)return"visible";if(e.getAttribute?.("data-reactive-lazy-on"))return"event";return null}function dt(e,t,r){Rr();let n=e.element,o=!1,i=!1,a=null,s=null,c,u,l=()=>X(e),f=(m)=>{if(Y(n)==="visible"){if(!a)h()}else if(m){let y=n.getAttribute("data-reactive-lazy-on");if(s===y)return;d(),n.addEventListener?.(y,l),s=y}},d=()=>{if(a?.disconnect(),a=null,s)n.removeEventListener?.(s,l);s=null},h=()=>{if(typeof IntersectionObserver>"u")return queueMicrotask(l);let m=n.getAttribute("data-reactive-lazy-visible")||"0px";a=new IntersectionObserver((y)=>{if(y.some((w)=>w.isIntersecting))l()},{rootMargin:m}),a.observe(n)},g=()=>{let m=Y(n)!==null,y=o;if(o=m,!m)return d();if(i)return;if(t.forgetToken(),!y)return l();f(!0)};if(G.set(e,{load(){if(i)return;let m=Nr(n);if(!m&&n.getAttribute("data-reactive-defer-src")!=null)return;if(m&&ei(n,t))return;let y=m?P(n.id,m):t.proceed(n,Pr,"{}");if(!y)return;i=!0,d();let w=()=>{i=!1};return y.then(w,w),y},off(){if(c)n.removeEventListener?.("turbo:morph-element",c);if(u)n.removeEventListener?.("turbo:morph-element",u);d()}}),(n.getAttribute?.("data-reactive-defer-token")||n.getAttribute?.("data-reactive-defer-src"))&&Y(n)===null)it(n),c=(m)=>m.target===n&&it(n),n.addEventListener?.("turbo:morph-element",c);if(n.getAttribute?.("data-reactive-token-value")==null&&n.getAttribute?.("data-reactive-defer-src")==null)return;if(u=(m)=>{if(m.target!==n)return;if(!c)it(n);g()},n.addEventListener?.("turbo:morph-element",u),r)return g();if(o=Y(n)!==null,o)f(!1)}function pt(e){let t=G.get(e);G.delete(e),t?.off()}function X(e){return G.get(e)?.load()}function ei(e,t){return t.emit("reactive:before-dispatch",{action:Pr,params:{},element:e},{cancelable:!0}).defaultPrevented}function it(e){if(!e?.id)return;if(e.getAttribute?.("data-reactive-defer-pending")!=="true")return;let t=e.getAttribute?.("data-reactive-defer-token")||Nr(e);if(t)P(e.id,t)}function ri(){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 ni(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:token"])return;e["reactive:token"]=function(){let t=this.getAttribute("data-reactive-token-value"),r=this.getAttribute("target");if(!t||!r)return;let n=document.getElementById(r);if(n)n.setAttribute("data-reactive-token-value",t)}}function oi(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=xt(this.getAttribute("data-reactive-ops"));if(!t.length)return;let r=this.getAttribute("target"),n=this.getAttribute("data-reactive-verbose")==="true",o=r?document.getElementById(r):null;if(r&&!o){if(n)Xe(r);return}St(t,(i)=>Ri(i,o),n?(i,a)=>Ze(i,a,o):void 0)}}function ii(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){ct(this)}}var qr=!1,si=null;function ai(){if(qr)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;qr=!0,document.addEventListener("turbo:before-stream-render",(e)=>{Be(e)})}function Gi(e){si=e}var Dr=!1;function Wr(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea")&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function ci(){if(Dr)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Dr=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented||t.localName!=="input"||!Wr(t))return;let n=r.getAttribute("value");if(n==null)t.removeAttribute("value");else if(t.getAttribute("value")!==n)t.setAttribute("value",n)}),document.addEventListener("turbo:before-morph-attribute",(e)=>{if(e.detail?.attributeName==="value"&&Wr(e.target))e.preventDefault()})}var ui="__materialize",jr=!1;function li(){if(jr)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;jr=!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 _t(){if(typeof document>"u")return;if(document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development")Ye()}var tn="data-reactive-active",b=0;function rn(){if(b++,b===1)on("reactive:busy")}function nn(){if(b===0)return;if(b--,b===0)on("reactive:idle")}function Vi(){return b}function Zi(){b=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(tn)}function on(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(tn,b>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:b}}))}var sn="data-reactive-requests";function an(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!fi(t))return;let r=di(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(sn,JSON.stringify(r))}function fi(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function di(e){try{let t=JSON.parse(e.getAttribute(sn));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function Br(){ri(),ni(),oi(),ii(),ai(),ci(),li(),_t()}function pi(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var cn=Symbol.for("phlex-reactive.core");if(globalThis[cn])console.error("[phlex-reactive] the client was loaded twice. Import EITHER phlex/reactive/reactive_controller (the default, "+"everything in one file) OR phlex/reactive/core (features on demand), not both — each carries its own state.");globalThis[cn]=!0;var un=!1;function hi(){if(un)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.')}if(typeof window<"u"&&typeof document<"u"){let e=()=>setTimeout(hi,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var mi=new Set(["href","src","srcdoc","action","formaction","xlink:href","style"]);function gi(e){let t=String(e).toLowerCase();return t.startsWith("on")||mi.has(t)}var ht=new WeakMap;function yi(e,t,r){let[n,o,i]=t;ht.get(e)?.(),e.classList.add(n,o),r();let a=!1,s=requestAnimationFrame(()=>{if(a)return;e.classList.remove(o),e.classList.add(i)}),c=(l)=>{if(a||l&&l.target!==e)return;a=!0,ht.delete(e),clearTimeout(u),globalThis.cancelAnimationFrame?.(s),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,o,i)};ht.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let u=setTimeout(c,vi(e))}function vi(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[o,i]=["Duration","Delay"].map((s)=>String(r[n+s]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((s)=>/inf/.test(s)?1/0:parseFloat(s)>=0?parseFloat(s):1);for(let s=0;s<o.length||s<i.length||s<a.length;s++){let c=o[s%o.length]*a[s%a.length]||0;t=Math.max(t,c+i[s%i.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var bi=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",wi=new Set(["lexxy-editor","trix-editor"]);function Ai(e){return wi.has(e.localName)?typeof e.value==="string":!0}var Jr=Object.freeze({show:(e,t,r)=>mt(e,!1,t,r),hide:(e,t,r)=>mt(e,!0,t,r),toggle:(e,t,r)=>mt(e,!e.hidden,t,r),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((r)=>e.classList.toggle(r)),set_attr:(e,t)=>{if(gt(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(gt(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!gt(t.name))return;if(Array.isArray(t.values)){let[r,n]=t.values;e.setAttribute(t.name,e.getAttribute(t.name)===r?n:r)}else if(e.hasAttribute(t.name))e.removeAttribute(t.name);else e.setAttribute(t.name,"")},focus:(e)=>e.focus?.(),focus_first:(e)=>Ei(e)?.focus?.(),text:(e,t)=>{let r=String(t.value??"");if(e.textContent!==r)e.textContent=r},dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e,t,r)=>{let n=Si(e);if(!n)return;let o=null;if(t?.submitter!=null&&typeof r==="function"){if(o=r({...t,to:t.submitter})[0]??null,!(o?.form===n&&(o.type==="submit"||o.type==="image")))console.warn(`[phlex-reactive] submitter ${t.submitter} is not a submit control of the form — ignored`),o=null}o?n.requestSubmit?.(o):n.requestSubmit?.()},paste_into:(e)=>_i(e),persist_state:(e,t)=>Me(e,t.state),persist_clear:(e)=>Pe(e)});function Si(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function _i(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((r)=>{if(!r)return;if(e.value=r,typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}));e.focus?.()}).catch(()=>{})}function xi(e,t,r){if(r?.transition)yi(e,r.transition,()=>e.hidden=t);else e.hidden=t}function mt(e,t,r,n){if(xi(e,t,r),r?.expanded==null||typeof n!=="function")return;for(let o of n({...r,to:r.expanded}))o.setAttribute?.("aria-expanded",String(!t))}function gt(e){if(!gi(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}var Ti='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ei(e){return e.querySelectorAll?.(Ti)?.[0]??null}function xt(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 Ur=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"}),zr=Object.freeze(["meta","ctrl","alt","shift"]);function Tt(e,t,r){let n=e.split("+");for(let a of zr)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let o=n.find((a)=>!zr.includes(a));if(o===void 0||typeof t.key!=="string")return!0;let i=r&&Object.hasOwn(r,o)?r[o]:Object.hasOwn(Ur,o)?Ur[o]:/^[a-z0-9]$/.test(o)?o:null;return typeof i==="string"&&i.toLowerCase()===t.key.toLowerCase()}function ki(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:xt(t),legacy:!0}];let r=[];for(let n of t.split(" ")){if(n==="")continue;let o=null;try{o=JSON.parse(n)}catch{o=null}if(o&&typeof o==="object"&&!Array.isArray(o))r.push(o);else console.warn(`[phlex-reactive] malformed on_client binding record ${JSON.stringify(n)} — skipped`)}return r}function Hr(e,t,r){if(e.legacy)return!0;let n=e.on;if(typeof n!=="string"||n==="")return!1;let o=n.indexOf(".");if(t.type!==(o<0?n:n.slice(0,o)))return!1;if(Boolean(e.window)!==ln(t.currentTarget))return!1;return o<0||r===null||Tt(n.slice(o+1),t,r)}var Kr=new WeakMap;function Fi(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,o=Kr.get(e);if(!o)o=new WeakMap,Kr.set(e,o);let i=o.get(n);if(!i)i=new Set,o.set(n,i);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(i.has(c))return!0;return i.add(c),!1}var Yr=new WeakMap;function Li(e,t){if(e===null||typeof e!=="object")return!1;let r=e.params?.ops,n=typeof r==="string"?r:JSON.stringify(r??null),o=Yr.get(e);if(!o)o=new WeakMap,Yr.set(e,o);let i=o.get(t);if(!i)i=new Map,o.set(t,i);let a=i.get(e.currentTarget);if(!a)a=new Set,i.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function St(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[o,i={}]=n;if(!Object.hasOwn(Jr,o)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(o)} — skipped`);continue}let a=t(i);if(a.length===0&&r)r(o,i);for(let s of a)Jr[o](s,i,t)}}function Ri(e,t){let r=e.to;if(t){if(r==="@root")return[t];if(typeof r!=="string"||r==="")return[];if(e.global)return[...document.querySelectorAll(r)];return[...t.querySelectorAll(r)]}if(typeof r!=="string"||r===""||r==="@root")return[];return[...document.querySelectorAll(r)]}function Ni(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function Gr(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}function Oi(e){return(e.getAttribute?.("data-action")??"").includes("reactive#trackDirty")||e.getAttribute?.("data-reactive-clipboard")!=null||e.querySelector?.('[data-action*="reactive#trackDirty"],[data-reactive-clipboard]')!=null}function Ci(e){return["show-targets","on-complete","filter-input","tags-field"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)||(e.querySelectorAll?.("[data-reactive-show-field], [data-reactive-show]")??[]).length>0||e.querySelector?.("[data-reactive-nested-json], [data-reactive-nested-list], [data-reactive-confirm-when-param], [data-reactive-enable], [data-reactive-select-all], [data-reactive-count]")!=null}function Mi(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}function Xi(e,t,r){}function Pi(e,t){}function Qi(e){return[]}function es(e){return Promise.resolve()}var Vr=new Set;function $i(e,t,r){let n=e+t;if(Vr.has(n))return;Vr.add(n),console.error(`[phlex-reactive] the "${e}" feature module (phlex/reactive/features/${e}) is unavailable: ${t}. If you bundle or vendor the client, alias or pin phlex/reactive/features/* (README: esbuild / webpack / bun).`,r)}function ts(){return["persist","defer","form","bindings","compute","effects","hints","devtools"]}var Zr=Promise.resolve();var Xr={enter:rn,exit:nn,count:an,waiting:new WeakMap},Qr=1,yt=2,vt=4,bt=8,wt=16;xe(Xr),at(Xr);var I=Symbol.for("phlex-reactive.early"),Ii=1e4,qi=1500,ln=(e)=>e!=null&&(e===globalThis.window||e.window===e);function At(){return globalThis[I]??={queue:[],connected:new WeakSet},globalThis[I]}function Di(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:Ii}function Wi(e){let t={};for(let{name:r,value:n}of Array.from(e.attributes??[])){let o=/^data-reactive-(.+)-param$/i.exec(r);if(!o)continue;let i;try{i=JSON.parse(n)}catch{i=n}t[o[1].replace(/[-_]([a-z0-9])/g,(a,s)=>s.toUpperCase())]=i}return t}function ji(e,t,r){return{[I]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:Wi(t),key:e.key,code:e.code,metaKey:e.metaKey,ctrlKey:e.ctrlKey,altKey:e.altKey,shiftKey:e.shiftKey,button:e.button,submitter:e.submitter,bubbles:e.bubbles,timeStamp:e.timeStamp,defaultPrevented:e.defaultPrevented,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var ee=new WeakMap;function Bi(e,{token:t,type:r,method:n,filter:o,win:i},a){let s=ee.get(e);if(!s)ee.set(e,s=new Map);let c=i?`${t} ${a}`:t;if(s.has(c))return!1;return s.set(c,{type:r,method:n,filter:o,win:i,params:a,armed:!0}),!0}function en(e,t,r,n){if(e?.[I])return!1;let o=ln(e?.currentTarget),i=o?n:e?.currentTarget,a=Ui(e,i,o?`@${t}`:t),s=ee.get(i),c=o&&JSON.stringify(e.params);for(let u of s?.values()??[]){if(!u.armed||u.method!==t||u.type!==e.type||Boolean(u.win)!==o)continue;if(o&&u.params!==c)continue;if(u.filter&&!Tt(u.filter,e,r))continue;return u.armed=!1,!0}return a}var Q=new WeakMap;function Ji(e,t,r){let n=Q.get(e);if(!n)Q.set(e,n=new Map),setTimeout(()=>Q.delete(e));let o=n.get(t)??{};n.set(t,o),o[r]=(o[r]??0)+1}function Ui(e,t,r){let n=e&&Q.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class fn extends ti{static values={token:String};#p;#h=new Map;#c=new Map;#z;#A;#M;#S=0;#u=new Map;#_=new WeakMap;#m;featuresReady=Zr;#Te=new Map;#Ee=new Set;#H=!1;#P=null;#ke=new Map;#Fe=new Map;#Le=new Map;#K=0;#$;#x=0;#t=0;connect(){if(un=!0,At().connected.add(this.element),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-token-value")!=null||Gr(this.element))this.#m=(e)=>{if(e.target!==this.element)return;this.#I(!0)},this.element.addEventListener?.("turbo:morph-element",this.#m);this.#K++,this.featuresReady=Zr,this.#I(),this.#V()}#I(e){this.#l(Qr,"persist",Ni,(t)=>Oe(this,t,e)),this.#l(yt,"defer",Gr,(t)=>dt(this,t,e)),this.#l(vt,"form",Oi,(t)=>Ie(this,t,e)),this.#l(bt,"bindings",Ci,(t)=>re(this,t,e)),this.#l(wt,"compute",Mi,(t)=>ve(this,t,e))}#l(e,t,r,n){if(this.#x&e)return;try{if(!r(this.element))return}catch(o){return this.#q(t,"detect",o)}this.#x|=e;try{n(this.#e()),this.#t|=e}catch(o){this.#q(t,"connect",o)}}#Y(){{let e=this.#t;this.#x=this.#t=0;let t=this.#e();if(e&Qr)this.#f("persist",()=>Ce(this,t));if(e&yt)this.#f("defer",()=>pt(this,t));if(e&vt)this.#f("form",()=>qe(this,t));if(e&bt)this.#f("bindings",()=>ne(this,t));if(e&wt)this.#f("compute",()=>be(this,t))}}#f(e,t){try{t()}catch(r){console.error(`[phlex-reactive] the "${e}" feature module failed to disconnect`,r)}}#Re(e){}#Ne(e,t){}#Oe(e){}#Ce(e,t){}#Me(e,t,r,n){}#e(){return this.#$??={emit:(e,t,r)=>this.#n(e,t,r),reseed:()=>this.#G(),proceed:(e,t,r)=>this.#E(e,t,r),forgetToken:()=>{this.#p=void 0},owns:(e)=>this.#b(e),ownership:()=>this.#L(),opTargets:(e)=>this.#C(e),diagnose:(e,t)=>this.#O(e,t),applyOps:(e,t)=>St(e,(r)=>this.#C(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#O(`client op "${r}"`,n)),listnavOptions:(e)=>this.#d(e),collectFields:()=>this.#B(),confirm:(e,t)=>Promise.resolve().then(()=>Ir(e,t)).catch(()=>!1)},this.#$}#G(){if(this.#t&vt)C(this,this.#e());if(this.#t&bt)oe(this);if(this.#t&wt)we(this)}#q(e,t,r){if($i(e,t,r),this.#r("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#n("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#Pe(){}#V(){if(this.element.setAttribute?.("data-reactive-connected",""),this.element.isConnected)this.element.dispatchEvent?.(new CustomEvent("reactive:connect",{bubbles:!0,composed:!0,detail:{id:this.element.id}}));this.#Z()}#T=new Set;#Z(){let{queue:e}=At();if(e.length===0)return;let t=[];for(let o=e.length-1;o>=0;o--){let{root:i}=e[o];if(i===this.element||!i.isConnected)t.unshift(...e.splice(o,1))}let r=Di(),n=new Map;for(let o of t){let i=n.get(o.event)??[new Set,new Set];n.set(o.event,i);let a=i[+!!o.win];if(a.has(o.el))continue;a.add(o.el);let s=o.win?Math.min(qi,r):r,c=o.root!==this.element?"its root left the page before a controller connected":performance.now()-o.at>s?`it is older than the ${s} ms ${o.win?"window-trigger":"early-event"} TTL`:o.el.isConnected&&this.element.contains(o.el)?null:"its element left the root before the controller connected";if(c){if(this.#N())console.warn(`[phlex-reactive] dropped an early "${o.event.type}" trigger: ${c}`);continue}this.#X(o)}}#X({event:e,el:t,descs:r,win:n}){let o=ji(e,t,n),i=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),s=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!Tt(c.filter,e,i))continue;if(/#\w+.*:once\b/.test(c.token)){if(!Bi(s,c,n&&JSON.stringify(o.params)))continue;this.#T.add(s)}if(Ji(e,s,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(o);else this.dispatch(o)}}disconnect(){if(this.#Y(),this.#ne(),this.#ie(),this.#m)this.element.removeEventListener?.("turbo:morph-element",this.#m);At().connected.delete(this.element),this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#T)ee.delete(e);this.#T.clear()}dispatch(e){if(en(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:t,params:r,debounce:n,throttle:o,confirm:i,confirmWhen:a,outside:s,window:c,optimistic:u}=e.params;if(!t)return;let l=e.params.busy??e.params.loading;if(s&&this.element.contains(e.target))return;let f=e.currentTarget??e.target;if(!c&&!this.#ye(u,f))e.preventDefault();if(t===ui){let g=()=>{if(this.#t&yt)return X(this);if(this.tokenValue)return this.#E(f,t,"{}")};return this.#H?this.featuresReady.then(g):g()}let d=this.#D(i,a),h=()=>this.#E(f,t,r,n,o,u,l);if(!d)return h();if(d instanceof Promise)return d.then((g)=>g?this.#g(g,f,h):h());this.#g(d,f,h)}#g(e,t,r){return Promise.resolve().then(()=>Ir(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#D(e,t){if(e)return e;if(!t)return null;return se(this,this.#e(),t)}#Q(e){}runOps(e){if(en(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(Li(e,this))return;let t=e.params??{},r=e.currentTarget??e.target,n=ki(t.ops),o=n.filter((a)=>Hr(a,e,null)),i=o.length<=1?o:o.filter((a)=>Hr(a,e,this.application?.schema?.keyMappings));if(i.length===0&&n.length>0){if(this.#N())et(this,e);return}for(let a of i){if(a.outside&&e[I])continue;if(Fi(this,e,a))continue;this.#ee(a.legacy?{...t,ops:a.ops}:a,e,r)}}#ee({ops:e,confirm:t,confirmWhen:r,outside:n,window:o},i,a){if(n&&this.element.contains(i.target))return;if(!o)i.preventDefault();let s=this.#D(t,r),c=()=>this.#ge(this.#me(e));if(!s)return c();if(s instanceof Promise)return s.then((u)=>u?this.#g(u,a,c):c());this.#g(s,a,c)}recompute(e){return Ae(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#d(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return fe(this,this.#e(),e)}tagsPick(e){return de(this,this.#e(),e)}tagsRemove(e){return pe(this,this.#e(),e)}nestedAdd(e){return he(this,this.#e(),e)}nestedRemove(e){return me(this,this.#e(),e)}syncNestedJson(e){return ie(this,this.#e(),e)}#$e(e,t){}trackDirty(){C(this,this.#e())}listnavNext(e){this.#y(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#y(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#y(e,()=>0)}listnavLast(e){this.#y(e,(t,r)=>r-1)}listnavPick(e){let t=this.#d(e),r=t.findIndex((n)=>n.hasAttribute("data-reactive-highlighted"));if(r<0)return;e.preventDefault(),t[r].click()}listnavClose(e){for(let t of this.#d(e))t.removeAttribute("data-reactive-highlighted")}#y(e,t){let r=this.#d(e);if(!r.length)return;e.preventDefault();let n=this.#te(e),o=globalThis.document?.activeElement,i=n?r.findIndex((s)=>s===o||o!=null&&s.contains?.(o)):r.findIndex((s)=>s.hasAttribute("data-reactive-highlighted")),a=r[t(i,r.length)];if(n)a.focus?.();else{for(let s of r)s.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#te(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#d(e){let r=(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-option-param")??this.element.getAttribute("data-reactive-listnav-option-param");if(!r)return[];let n=this.#L();return Array.from(this.element.querySelectorAll(r)).filter((o)=>!o.hidden&&n(o))}#E(e,t,r,n,o,i,a){if(this.#n("reactive:before-dispatch",{action:t,params:this.#J(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#re(e,c,t,r,i,a);let u=Number(o)||0;if(u>0)return this.#oe(e,u,t,r,i,a);return this.#v(t,r,i,e,a)}#v(e,t,r,n,o){let i={inverse:null,undo:[],resurrect:null},a=this.#ve(e,n,i),s=Boolean(r||o),c=(d)=>{if(!s||!d)return;let h=this.#e();if(i.inverse=nt(this,h,r,n),i.undo.push(...rt(this,h,o,n)),this.#F())i.resurrect=ot(this,h,r,n)},u=!0;c(!0);let l=()=>this.#ue(e,t,i,a),f=()=>this.#P?this.#P.then(l):l();return this.queue=(this.queue??Promise.resolve()).then(()=>f()),this.queue}#Ie(){return this.#Q("hints")}#re(e,t,r,n,o,i){this.#k(e);let a=()=>{this.#k(e),this.#v(r,n,o,e,i)},s=setTimeout(a,t);e?.addEventListener?.("blur",a,{once:!0}),this.#h.set(e,{timer:s,flush:a})}#k(e){let t=this.#h.get(e);if(!t)return;clearTimeout(t.timer),e?.removeEventListener?.("blur",t.flush),this.#h.delete(e)}#ne(){for(let e of[...this.#h.keys()])this.#k(e)}#oe(e,t,r,n,o,i){let a=this.#c.get(e)??new Map;if(a.has(r))return;let s=setTimeout(()=>{if(a.delete(r),a.size===0)this.#c.delete(e)},t);return a.set(r,s),this.#c.set(e,a),this.#v(r,n,o,e,i)}#ie(){for(let e of this.#c.values())for(let t of e.values())clearTimeout(t);this.#c.clear()}#n(e,t,{cancelable:r=!1}={}){let n=new CustomEvent(e,{bubbles:!0,composed:!0,cancelable:r,detail:t});return(this.element.isConnected?this.element:document).dispatchEvent(n),n}#o(e,t,r,n){let o=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#v(e,t)};this.#n("reactive:error",{action:e,params:r,...n,retry:o})}#r(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#se(){this.element?.removeAttribute?.("data-reactive-error")}#ae(){let e=document.querySelector("[data-reactive-error-flash]");if(!e?.content)return;let t=e.getAttribute("data-reactive-error-flash")||"flash",r=document.getElementById(t);if(!r)return;r.appendChild(e.content.cloneNode(!0))}#ce(){return Ge()}#F(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#W(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#ue(e,t,r,n){let{fields:o,files:i}=this.#B(),a=this.#J(t),s={...o,...a},c=this.#i,u=i.length>0,l=u?this.#pe(c,e,s,i):JSON.stringify({token:c,act:e,params:s}),f=this.#F()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(o),encoding:u?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#W()}:null;await this.#ce();try{if(navigator.onLine===!1){this.#s(r.inverse),this.#r("offline"),this.#o(e,t,s,{kind:"offline"});return}let d;try{let p={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#_e()};if(!u)p["Content-Type"]="application/json";let m=this.#xe();if(m)p["X-Pgbus-Connection"]=m;an("action"),d=await fetch(this.#Ae(),{method:"POST",headers:p,body:l,credentials:"same-origin",signal:AbortSignal.timeout(this.#Se())})}catch(p){if(console.error("[phlex-reactive] action error",p),this.#s(r.inverse),p?.name==="TimeoutError"||p?.name==="AbortError"){this.#r("timeout"),this.#o(e,t,s,{kind:"timeout"});return}this.#ae(),this.#r("network"),this.#o(e,t,s,{kind:"network"});return}if(f)f.status=d.status;if(d.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#s(r.inverse),this.#r("redirected"),this.#o(e,t,s,{kind:"redirected",status:d.status});return}if(!d.ok){let p=await d.text();if(console.error(`[phlex-reactive] action failed: HTTP ${d.status}`,p),this.#s(r.inverse),(d.headers.get("Content-Type")||"").includes("turbo-stream")){let m=this.#j(p);if(this.#i=m??this.#i,f)H(f,p,m);window.Turbo.renderStreamMessage(p)}this.#r("http"),this.#o(e,t,s,{kind:"http",status:d.status,body:p});return}let h=d.headers.get("Content-Type")||"";if(!h.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${h}" — no update applied`),this.#s(r.inverse),this.#r("content-type"),this.#o(e,t,s,{kind:"content-type",status:d.status});return}let g=await d.text(),S=this.#j(g);if(this.#i=S??this.#i,f)H(f,g,S);if(window.Turbo.renderStreamMessage(g),r.resurrect)queueMicrotask(r.resurrect);this.#se(),this.#n("reactive:applied",{action:e,params:s,html:g})}catch(d){console.error("[phlex-reactive] action error",d),this.#s(r.inverse),this.#n("reactive:error",{action:e,params:s,kind:"apply"})}finally{if(n?.(),f)tt(this,{...f,ms:this.#W()-f.started})}}get#i(){return this.#p??this.tokenValue}set#i(e){this.#p=e}tokenValueChanged(){this.#p=void 0}#j(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#le(t),o=e.match(r);if(o)return o[1];let i=e.match(n);if(i)return i[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#le(e){let t=this.#M;if(t&&t.id===e)return t;let r=pi(e);return this.#M={id:e,token:new RegExp(`<turbo-stream\\b[^>]*\\baction="reactive:token"[^>]*\\btarget="${r}"[^>]*\\bdata-reactive-token-value="([^"]+)"`),self:new RegExp(`<turbo-stream\\b[^>]*\\baction="(?:replace|update)"[^>]*\\btarget="${r}"[^>]*>([\\s\\S]*?)</turbo-stream>`)}}#b(e){return e.closest('[data-controller~="reactive"]')===this.element}#L(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#b(t)}#B(){let e={},t=[],r=this.#L(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((s)=>{if(!r(s))return;if(s.type==="file")for(let c of s.files??[])t.push({name:s.name,file:c,multiple:s.multiple});else n.push(s)});let o=[];this.element.querySelectorAll(`[name]${bi}`).forEach((s)=>{if(r(s))o.push(s)});let i=this.#fe(n),a=this.#de(n);for(let s of n)if(i.has(s.name)){let c=e[s.name]??(e[s.name]=[]);if(s.type==="checkbox"||s.type==="radio"){if(s.checked)c.push(s.value)}else if(s.type==="hidden"){if(!a.has(s.name))c.push(s.value)}else if(s.multiple&&s.options){for(let u of s.options)if(u.selected)c.push(u.value)}else c.push(s.value)}else if(s.type==="checkbox")e[s.name]=s.checked;else if(s.type==="radio"){if(s.checked)e[s.name]=s.value}else e[s.name]=s.value;return o.forEach((s)=>{let c=s.getAttribute("name");if(!c)return;let u=s.value??s.textContent??s.innerHTML??"",l=e[c];if(String(c).endsWith("[]")&&!Ai(s))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}}#fe(e){let t=new Set;for(let r of e){if(r.type==="radio")continue;if(String(r.name).endsWith("[]"))t.add(r.name)}return t}#de(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#pe(e,t,r,n){let o=new FormData;o.append("token",e),o.append("act",t);let i=[];for(let[s,c]of Object.entries(r))if(Array.isArray(c)&&String(s).endsWith("[]"))if(c.length===0)i.push(String(s).slice(0,-2));else{let u=`${this.#w(s)}[]`;for(let l of c)o.append(u,String(l))}else this.#R(o,this.#w(s),c);for(let s of i)o.append("empty_groups[]",s);let a=this.#he(n);for(let{name:s,file:c,multiple:u}of n){let f=u||a.has(s)?`${this.#w(s)}[]`:this.#w(s);o.append(f,c,c.name)}return o}#w(e){let t=String(e),r=t.indexOf("[");if(r===-1)return`params[${t}]`;return`params${[t.slice(0,r),...t.slice(r).match(/[^\[\]]+/g)??[]].map((o)=>`[${o}]`).join("")}`}#R(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,o)=>this.#R(e,`${t}[${o}]`,n));else if(typeof r==="object")for(let[n,o]of Object.entries(r))this.#R(e,`${t}[${n}]`,o);else e.append(t,String(r))}#he(e){let t=new Map;for(let{name:r}of e)t.set(r,(t.get(r)??0)+1);return new Set([...t].filter(([,r])=>r>1).map(([r])=>r))}#J(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#me(e){return xt(e)}#ge(e){St(e,(t)=>this.#C(t),(t,r)=>this.#O(`client op "${t}"`,r))}#N(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#F()}#O(e,t){if(!this.#N())return;Qe(this,e,t)}#qe(e){}#C(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((r)=>this.#b(r))}#ye(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#s(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#ve(e,t,r){this.#be(e,t),rn();let n=!1;return()=>{if(n)return;n=!0,this.#we(e,t),nn();for(let o of r.undo)o()}}#be(e,t){if(this.#a(t,e,1),this.#a(this.element,e,1),this.#u.set(e,(this.#u.get(e)??0)+1),this.#S++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#U(e))this.#a(r,e,1)}#we(e,t){this.#a(t,e,-1),this.#a(this.element,e,-1);let r=(this.#u.get(e)??1)-1;if(r<=0)this.#u.delete(e);else this.#u.set(e,r);if(--this.#S<=0)this.#S=0,this.element.removeAttribute("aria-busy");for(let n of this.#U(e))this.#a(n,e,-1)}#a(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#_.get(e)??new Map,o=(n.get(t)??0)+r;if(o<=0)n.delete(t);else n.set(t,o);if(n.size===0){this.#_.delete(e),e.removeAttribute("data-reactive-busy");return}this.#_.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#U(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#b(r))}#Ae(){return this.#z??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#Se(){if(this.#A!=null)return this.#A;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#A=Number.isFinite(t)&&t>0?t:30000}#_e(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#xe(){return document.querySelector("pgbus-stream-source[connection-id]")?.getAttribute("connection-id")||document.querySelector('meta[name="pgbus-connection-id"]')?.content||null}}if(typeof window<"u")if(window.Turbo)Br();else document.addEventListener("turbo:load",Br,{once:!0});_t();var ls=fn;export{tn as ACTIVE_ATTR,bi as EDITOR_SELECTOR,wi as EDITOR_TAGS,Io as LATENCY_KEY,sn as REQUESTS_ATTR,hi as checkReactiveRegistration,an as countReactiveRequest,ls as default,Ar as disableLatencySim,wr as enableLatencySim,rn as enterReactiveActivity,pi as escapeRegExp,nn as exitReactiveActivity,es as loadReactiveFeature,Gi as onReactiveStreamWithoutEffects,Vi as reactiveActivityCount,ts as reactiveFeatureNames,Br as registerReactiveActions,ii as registerReactiveDefer,_t as registerReactiveDev,ai as registerReactiveDismiss,ai as registerReactiveEffects,Pi as registerReactiveFeature,Xi as registerReactiveFeatureLoader,oi as registerReactiveJs,ci as registerReactiveMorphFocus,li as registerReactiveOffline,ai as registerReactiveStreamRender,ni as registerReactiveToken,ri as registerReactiveVisit,Zi as resetReactiveActivity,Qi as unloadedFeaturesFor};
2
2
 
3
- //# debugId=A13F2ADCE2F81E9564756E2164756E21
3
+ //# debugId=445A810E3AB2B25864756E2164756E21
4
4
  //# sourceMappingURL=reactive_controller.min.js.map