phlex-reactive 0.16.10 → 0.16.12
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -1
- data/README.md +58 -13
- data/app/javascript/phlex/reactive/core.min.js +4 -4
- data/app/javascript/phlex/reactive/core.min.js.map +3 -3
- data/app/javascript/phlex/reactive/reactive_controller.min.js +4 -4
- data/app/javascript/phlex/reactive/reactive_controller.min.js.map +3 -3
- data/app/javascript/phlex/reactive/runtime.js +80 -5
- data/lib/phlex/reactive/component/dsl.rb +3 -1
- data/lib/phlex/reactive/component/helpers.rb +15 -0
- data/lib/phlex/reactive/js.rb +48 -9
- data/lib/phlex/reactive/param_schema.rb +34 -9
- data/lib/phlex/reactive/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f176f438a8cddf912348d8c6d0ddf095fa3a6fa1ae2b52b109a8be514a48139
|
|
4
|
+
data.tar.gz: 49f4e78d5e21ea343fe5bfb6d77d1a3f58e3cb0d592a018536bc9ae52d5c827d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6027a094e3dc14403d914c2f9406396b75fef0b4ea68615480b6d1c6a8e6e0b061c5f3e0df4b18ddc7e54642d54a0caf2490b5fe3d088b430864699106de6858
|
|
7
|
+
data.tar.gz: 87dd2ef191e0faf521bd869defc0cf645ed25466d1abadfae1db9641f74a6d9c8a6e9ca015834f81a29492e1c14c43eccc21d580478151f6d0d00506fa1473bd
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,71 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`:strict_integer` and `:strict_float` param types (#460).** `:integer` and
|
|
12
|
+
`:float` cast with `to_i`/`to_f`, so a cleared number field reaches the action
|
|
13
|
+
as `0` and `"12abc"` as `12`, and an action cannot tell a blank field from a
|
|
14
|
+
typed `0`. The two new built-ins follow the drop contract instead: a blank or
|
|
15
|
+
unparsable value is dropped, so the keyword default applies. `:strict_integer`
|
|
16
|
+
is `Integer(value, 10)`, so `"1.5"`, a JSON `1.0` and `"0x10"` drop and `"010"`
|
|
17
|
+
is `10`; `:strict_float` reads decimal notation, so it also drops hex and a
|
|
18
|
+
string too large or too small for a Float (`"1e400"`, `"1e-400"`). Both take a JSON number
|
|
19
|
+
as well as a string,
|
|
20
|
+
and work in nested and array schemas, where a dropped element follows the
|
|
21
|
+
existing array rule. `:integer` and `:float` are unchanged.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **The docs now say what `:integer` and `:float` do (#460).** The Actions &
|
|
26
|
+
events guide and the counter example said a non-numeric value is dropped; it
|
|
27
|
+
never was. Both pages, and the README, now describe `to_i`/`to_f` and point at
|
|
28
|
+
the strict types.
|
|
29
|
+
|
|
30
|
+
## [0.16.11] - 2026-10-19
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
- **`js.preview_file(…, rejected: "#refused")` names each refused file in the
|
|
35
|
+
page (#445).** A `reactive:file-rejected` handler could react to the reason,
|
|
36
|
+
but no op could put the refused file's name into the page, so a picker that
|
|
37
|
+
refused two of five files could only say "a file was too large". `rejected:`
|
|
38
|
+
is a CSS selector for a container holding an app-authored `<template>`: for
|
|
39
|
+
each refused file, in pick order and before any `reactive:file-rejected`
|
|
40
|
+
fires, the client deep-clones the template, writes the file's name as
|
|
41
|
+
`textContent` into every `[data-reactive-file="name"]`, keeps only the
|
|
42
|
+
`[data-reactive-file-reason]` parts for that file's reason, marks each
|
|
43
|
+
top-level element `data-reactive-file-rejected` and appends it. Every run
|
|
44
|
+
removes the marked entries first (a heading and the `<template>` stay), so the
|
|
45
|
+
next pick replaces the list and a pick with no refusal empties it; a morph
|
|
46
|
+
that reaches the container (the upload action's `reply.morph`) keeps them, a
|
|
47
|
+
Turbo cache restore included. Works for one file and with `per_file: true`. A
|
|
48
|
+
container that is not on the page, or has no `<template>`, warns on a verbose
|
|
49
|
+
root and the rejections still fire. The keyword is serialized only when given,
|
|
50
|
+
so every existing op is byte-identical; `broadcast_to(js:)` still refuses
|
|
51
|
+
`preview_file`.
|
|
52
|
+
|
|
53
|
+
### Fixed
|
|
54
|
+
|
|
55
|
+
- **`dispatch(…, detail_from:)` refuses a `detail:` that is no Hash (#442).** The
|
|
56
|
+
browser merges the reads over `detail:` as an object, so a String or an Array
|
|
57
|
+
`detail:` was spread into the event detail one character or element per key.
|
|
58
|
+
It now raises at render; a Hash or `nil` `detail:` is unchanged. The client
|
|
59
|
+
refuses the same in a hand-built record (warned, the dispatch skipped, its
|
|
60
|
+
siblings run), and reads nothing off an empty `detail_from`, so that dispatch
|
|
61
|
+
fires with its literal `detail:` (before, it waited for a trigger and a
|
|
62
|
+
server-pushed one was skipped; the server no longer refuses it either).
|
|
63
|
+
- **`preview_file` refuses `@trigger` as its `into:`, `name:` and `wrap:`
|
|
64
|
+
(#442),** the sentinel string as `:trigger` already was, and `reply.js` refuses
|
|
65
|
+
it there in a raw list.
|
|
66
|
+
- **`on_client(…, within:)` raises on an event that does not bubble (#442)**
|
|
67
|
+
(`focus`, `blur`, `mouseenter`, `mouseleave`, `pointerenter`, `pointerleave`,
|
|
68
|
+
`load`, `error`, `scroll`, `toggle`, `beforetoggle`, `invalid`, a dialog's
|
|
69
|
+
`close`/`cancel`, media `play`/`pause`/`ended`): the bound element never hears
|
|
70
|
+
it from a row, so the binding was dead. The message says to bind it on the
|
|
71
|
+
rows, or names the bubbling twin where there is one (`focusin`/`focusout`,
|
|
72
|
+
`mouseover`/`mouseout`, `pointerover`/`pointerout`).
|
|
73
|
+
|
|
9
74
|
## [0.16.10] - 2026-10-19
|
|
10
75
|
|
|
11
76
|
### Fixed
|
|
@@ -4426,7 +4491,8 @@ room for dogfood fixes.
|
|
|
4426
4491
|
scaffolds a reactive component (and an RSpec spec when the app uses RSpec),
|
|
4427
4492
|
state-backed by default or record-backed with `--record`.
|
|
4428
4493
|
|
|
4429
|
-
[Unreleased]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.
|
|
4494
|
+
[Unreleased]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.11...HEAD
|
|
4495
|
+
[0.16.11]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.10...v0.16.11
|
|
4430
4496
|
[0.16.10]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.9...v0.16.10
|
|
4431
4497
|
[0.16.9]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.8...v0.16.9
|
|
4432
4498
|
[0.16.8]: https://github.com/mhenrixon/phlex-reactive/compare/v0.16.7...v0.16.8
|
data/README.md
CHANGED
|
@@ -722,14 +722,32 @@ Use in controllers: `render turbo_stream: Counter.replace(counter)`.
|
|
|
722
722
|
| `reply.pending(records, in:, job:) { … }` + `include Phlex::Reactive::Settles` / `reactive_settle` | For an action that **enqueues** work: mark targets pending, let your job settle them (row + count + empty-state) when it finishes. See [Async actions](#async-actions-replypending--reactive_settle). |
|
|
723
723
|
| `Container.broadcast_collection_to(*keys, container:, in:, append:/prepend:/remove:)` | The broadcast-side `reply.append`/`reply.remove`: the row **plus** the count companion **plus** the empty-state toggle, to peers. |
|
|
724
724
|
|
|
725
|
-
Param types: `:string` (default), `:integer`, `:float`, `:
|
|
726
|
-
`:date`, `:datetime`, `:decimal`. Anything
|
|
727
|
-
reaching your method. `:date`/`:datetime`
|
|
728
|
-
parse is dropped — the keyword default
|
|
729
|
-
`BigDecimal` (dropped on a non-numeric
|
|
730
|
-
declaration**: a typo'd type symbol
|
|
731
|
-
`Phlex::Reactive::UnknownParamType` at
|
|
732
|
-
string at click time.
|
|
725
|
+
Param types: `:string` (default), `:integer`, `:float`, `:strict_integer`,
|
|
726
|
+
`:strict_float`, `:boolean`, `:file`, `:date`, `:datetime`, `:decimal`. Anything
|
|
727
|
+
not in the schema is dropped before reaching your method. `:date`/`:datetime`
|
|
728
|
+
parse ISO8601 (a value that won't parse is dropped — the keyword default
|
|
729
|
+
applies); `:decimal` parses through `BigDecimal` (dropped on a non-numeric
|
|
730
|
+
value). The schema is **compiled once at declaration**: a typo'd type symbol
|
|
731
|
+
(`params: { count: :interger }`) raises `Phlex::Reactive::UnknownParamType` at
|
|
732
|
+
class load, not silently coercing to a string at click time.
|
|
733
|
+
|
|
734
|
+
`:integer` and `:float` cast with `to_i`/`to_f` and never drop, so a cleared
|
|
735
|
+
number field arrives as `0` and `"12abc"` as `12`. When `0` means something,
|
|
736
|
+
declare `:strict_integer` (`Integer(value, 10)`) or `:strict_float`
|
|
737
|
+
(decimal notation only): a blank or unparsable value is dropped, so the keyword default
|
|
738
|
+
applies and a typed `0` stays `0`. `:strict_integer` also drops a fraction, even
|
|
739
|
+
a JSON `1.0`; `:strict_float` also drops hex and a string too large or too small
|
|
740
|
+
for a Float (`"1e400"`, `"1e-400"`). A bare `1e-400` in a JSON body is already
|
|
741
|
+
`0.0` when the parser hands it over, so it arrives as zero.
|
|
742
|
+
|
|
743
|
+
```ruby
|
|
744
|
+
action :save, params: { quantity: :strict_integer, weight: :strict_float }
|
|
745
|
+
|
|
746
|
+
def save(quantity: nil, weight: nil) # nil when blank or unparsable; a typed 0 stays 0
|
|
747
|
+
authorize! @widget, :update?
|
|
748
|
+
@widget.update!(quantity:, weight:)
|
|
749
|
+
end
|
|
750
|
+
```
|
|
733
751
|
|
|
734
752
|
**Custom param types (`Phlex::Reactive.param_type`).** Register your own type in
|
|
735
753
|
an initializer — the block receives the raw client value and returns the coerced
|
|
@@ -1395,11 +1413,14 @@ end
|
|
|
1395
1413
|
selector that does not parse runs nothing, warned under `verbose_errors`. The
|
|
1396
1414
|
list is not forced to `type="button"`. It raises with
|
|
1397
1415
|
`window:`, `outside:`, `shortcut:` and `once:` (Stimulus drops a `:once`
|
|
1398
|
-
listener on its first event, a miss included)
|
|
1416
|
+
listener on its first event, a miss included), and on an event that does not
|
|
1417
|
+
bubble (`focus`, `blur`, `mouseenter`, `mouseleave`, …: the list never hears
|
|
1418
|
+
it from a row; use `focusin`, `focusout`, `mouseover`, `mouseout`).
|
|
1399
1419
|
- **`:trigger`** is accepted wherever an op takes a target, and by `expanded:`,
|
|
1400
1420
|
`submit(submitter:)` and `copy_media(from:)`. Without `within:` it is the
|
|
1401
1421
|
element the binding is on. `set_value`, `paste_into` and `preview_file` refuse
|
|
1402
|
-
it as the field they write
|
|
1422
|
+
it as the field they write, and `preview_file` as its `into:`, `name:` and
|
|
1423
|
+
`wrap:`.
|
|
1403
1424
|
- **`from:` + `attr:`** on `set_value`, `text` and `set_attr` replace the literal
|
|
1404
1425
|
value: `from:` is `:trigger`, `:root` or a selector (the op's own scoping,
|
|
1405
1426
|
`global:` included, first match); `attr:` is a `data-*` attribute or `:text`
|
|
@@ -1409,7 +1430,7 @@ end
|
|
|
1409
1430
|
allowlist, `text`'s `textContent`, `set_value`'s `.value`).
|
|
1410
1431
|
- **`dispatch(…, detail_from: { key => attr })`** builds the event's detail off
|
|
1411
1432
|
the trigger, every value a String, merged over `detail:` (a key in both
|
|
1412
|
-
raises).
|
|
1433
|
+
raises, and so does a `detail:` that is no Hash).
|
|
1413
1434
|
- A server-pushed op has no trigger: `reply.js`, `broadcast_to(js:)` and
|
|
1414
1435
|
`reactive_on_complete` raise on `:trigger`, `from: :trigger` and
|
|
1415
1436
|
`detail_from:`. Nor does a window-bound `on_client` (`window:`, `outside:`,
|
|
@@ -1527,8 +1548,8 @@ button(**on_client(:click, js
|
|
|
1527
1548
|
(a broadcast that reads every subscriber's clipboard would be hostile). The
|
|
1528
1549
|
op is async fire-and-forget — chained siblings apply immediately, never
|
|
1529
1550
|
waiting for the read.
|
|
1530
|
-
- **`preview_file(to, into:, name: nil, global: false, valid: false, wrap: nil, max_bytes: nil, accept: nil, per_file: false)`** (#375; `global: true`
|
|
1531
|
-
resolves `to`, `into:` and `
|
|
1551
|
+
- **`preview_file(to, into:, name: nil, global: false, valid: false, wrap: nil, max_bytes: nil, accept: nil, per_file: false, rejected: nil)`** (#375; `global: true`
|
|
1552
|
+
resolves `to`, `into:`, `name:`, `wrap:` and `rejected:` document-wide, for an `img` outside the
|
|
1532
1553
|
root) paints the file a file input
|
|
1533
1554
|
holds onto an `img` **before any upload**:
|
|
1534
1555
|
`input(type: "file", id: "photo-file", accept: "image/*", **on_client(:change,
|
|
@@ -1579,6 +1600,30 @@ button(**on_client(:click, js
|
|
|
1579
1600
|
input keeps every file (`remaining` counts them all). A single input, and
|
|
1580
1601
|
`per_file:` omitted, keep the one-file check above; `per_file:` takes only
|
|
1581
1602
|
`true`, `false` or `nil`.
|
|
1603
|
+
**Name each refused file (#445):** `rejected: "#refused"` is a CSS selector
|
|
1604
|
+
for a container holding an app-authored `<template>`. For each refused file,
|
|
1605
|
+
in pick order and **before** any `reactive:file-rejected` fires, the client
|
|
1606
|
+
deep-clones the template, writes the file's name as `textContent` (never
|
|
1607
|
+
HTML) into every `[data-reactive-file="name"]`, removes every
|
|
1608
|
+
`[data-reactive-file-reason]` part whose value is not that file's reason
|
|
1609
|
+
(`"size"` or `"type"`), marks each top-level element
|
|
1610
|
+
`data-reactive-file-rejected` and appends it: `ul(id: "refused") { template
|
|
1611
|
+
{ li { span(data: { reactive_file_reason: "size" }) { b(data: { reactive_file:
|
|
1612
|
+
"name" }); plain " is too large." } } } }`. A reason with no part of its own
|
|
1613
|
+
keeps only the entry's unmarked parts (here an empty `li`), so give every
|
|
1614
|
+
reason a part, or put `data-reactive-file-reason` on a top-level element of
|
|
1615
|
+
the template to list only the reasons it has a sentence for. Every run of
|
|
1616
|
+
the op removes the marked entries first (and only those: a heading and the
|
|
1617
|
+
`<template>` stay), so the next pick replaces the list and a pick with no
|
|
1618
|
+
refusal empties it. A
|
|
1619
|
+
morph that reaches the container (the action's `reply.morph` of the component,
|
|
1620
|
+
on the same `change`) keeps the entries, after whatever the server renders
|
|
1621
|
+
(so never render `data-reactive-file-rejected` children yourself); a plain
|
|
1622
|
+
replace, or an update stream aimed at the container itself, renders it
|
|
1623
|
+
afresh. It works
|
|
1624
|
+
for one file and with `per_file: true`. A container that is not on the page,
|
|
1625
|
+
or has no `<template>` child, warns on a verbose root; the rejections still
|
|
1626
|
+
fire.
|
|
1582
1627
|
- **`expanded:`** on `show`/`hide`/`toggle` (#271) keeps a disclosure trigger's
|
|
1583
1628
|
`aria-expanded` honest: `js.toggle("#menu", expanded: "#trigger")` writes the
|
|
1584
1629
|
op's **intended** state (`show` → `"true"`, `hide` → `"false"`, `toggle` → the
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import{Controller as Nt}from"@hotwired/stimulus";import{confirmResolver as Oe}from"phlex/reactive/confirm";function Ot(){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 It(){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)}}var Pt=["focus","focus_first","blur"];function Mt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=ke(this.getAttribute("data-reactive-ops"));if(!t.length)return;let r=this.getAttribute("target"),n=this.getAttribute("data-reactive-verbose")==="true",i=r?document.getElementById(r):null;if(r&&!i){if(n)v("devtools",(o)=>o.missingRoot(r));return}let s=(o)=>pe(o,(c)=>Fr(c,i),n?(c,u)=>v("devtools",(d)=>d.diagnoseStream(c,u,i)):void 0),a=t.findIndex((o)=>Pt.includes(o?.[0]));if(a<0||typeof requestAnimationFrame!=="function")return s(t);s(t.slice(0,a)),requestAnimationFrame(()=>s(t.slice(a)))}}function Ct(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){v("defer",(t)=>t.streamAction(this))}}var Ie=!1,de=null;function Dt(){if(Ie)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ie=!0,document.addEventListener("turbo:before-stream-render",(e)=>{if(Yt(e),$t(e),Wt(e),de)de(e,g.get("effects"));else g.get("effects")?.wrap(e)})}var J="reactive:streamed";function $t(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target,i=n?.getAttribute?.("action"),s=/^(append|prepend|update)$/.test(i);if(typeof r!=="function"||!(s||/^(before|after|replace)$/.test(i)))return;let a=n.getAttribute("target"),o=n.getAttribute("targets"),c=new Set;for(let u of a?[document.getElementById(a)]:o?document.querySelectorAll(o):[]){let d=(s?u:u?.parentElement)?.closest?.('[data-controller~="reactive"]');if(d)c.add(d)}if(c.size===0)return;t.render=async(u)=>{await r(u);for(let d of c)if(d.isConnected)d.dispatchEvent(new Event(J))}}function be(e){return e?.tagName==="DIALOG"&&typeof e.showModal==="function"}function ye(e){try{return e.matches(":modal")}catch{return!1}}function rt(e){if(!be(e)){if(e?.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] show_modal targets a <dialog>, not <${e.localName}> — skipped`);return}if(!e.isConnected||ye(e))return;if(e.open)e.close();e.showModal()}function qt(e){if(be(e)&&e.open)e.close()}function Y(e){let r=[...e?.querySelectorAll?.("dialog[data-reactive-modal]")??[]];if(e?.matches?.("dialog[data-reactive-modal]"))r.push(e);for(let n of r)if(n.open&&!ye(n))rt(n)}function Wt(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target;if(typeof r!=="function"||!n?.querySelector?.("template")?.content?.querySelector?.("dialog"))return;t.render=async(i)=>{await r(i),Y(document)}}var Pe=!1;function Bt(){if(Pe)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Pe=!0,document.addEventListener("turbo:morph-element",(t)=>{if(t.target?.matches?.('[data-controller~="reactive"]'))Y(t.target)}),document.addEventListener("turbo:morph",()=>Y(document));let e=new WeakSet;document.addEventListener("turbo:before-morph-element",(t)=>{let r=t.target,n=t.detail?.newElement;if(!be(r)||!n)return;if(n.hasAttribute?.("open"))e.delete(r);else e.add(r)}),document.addEventListener("turbo:before-morph-attribute",(t)=>{let{target:r,detail:n}=t;if(n?.attributeName!=="open"||n.mutationType!=="remove")return;if(!e.has(r)||!r.open||!ye(r))return;e.delete(r),t.preventDefault(),r.close()})}var fe=new WeakMap;function nt(e,t,r,n){let i=fe.get(e)??new Map;fe.set(e,i);let s=(a,o)=>{i.delete(a),i.set(a,o)};if(t.endsWith("_class"))for(let a of r.classes??[])s(`.${a}`,e.classList.contains(a));else if(t.endsWith("_attr"))_t(r.name)||s(r.name,e.getAttribute(r.name));else if(t==="show"||t==="hide"||t==="toggle"){if(s("hidden",e.getAttribute("hidden")),r.expanded!=null)for(let a of n({...r,to:r.expanded}))nt(a,"set_attr",{name:"aria-expanded"})}}var Me=!1;function jt(){if(Me)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Me=!0,document.addEventListener("turbo:morph-element",(e)=>{let t=e.target;for(let[r,n]of fe.get(t)??[])if(r[0]===".")t.classList.toggle(r.slice(1),n);else if(n==null)t.removeAttribute(r);else if(t.getAttribute(r)!==n)t.setAttribute(r,n)})}var ve="data-reactive-image-fallback",L="data-reactive-image-state",he="data-reactive-image-hidden",ie=null,me="data-reactive-wrap-hidden";function it(e){if(e.hasAttribute("hidden"))return;e.setAttribute("hidden",""),e.setAttribute(me,"")}function ot(e){if(!e.hasAttribute(me))return;e.removeAttribute("hidden"),e.removeAttribute(me)}function P(e){if(e?.localName!=="img")return null;let t=e.getAttribute(ve);if(t==null)return null;try{return JSON.parse(t)||{}}catch{return{}}}var st=(e)=>e.getAttribute("src")||e.getAttribute("srcset");function _e(e,t){if(typeof t!=="string"||!t)return null;try{return e.closest('[data-controller~="reactive"]')?.querySelector(t)??null}catch{return null}}function at(e,t){let r=_e(e,t.alt);return r&&!r.contains(e)?r:null}function X(e,t,r){if(r==="error"){if(t.hide&&!e.hasAttribute("hidden"))e.setAttribute("hidden",""),e.setAttribute(he,"");if(t.wrap){let i=_e(e,t.wrap);if(i)it(i);else console.warn(`[phlex-reactive] reactive_image_fallback wrap: ${JSON.stringify(t.wrap)} is not in the root — skipped`)}let n=at(e,t);if(n)n.textContent=e.getAttribute("alt")??"",n.hidden=!1}else te(e,t);e.setAttribute(L,r)}function te(e,t=P(e)){if(!t||e.getAttribute(L)==null)return;if(e.getAttribute(L)==="error"){if(e.hasAttribute(he))e.removeAttribute("hidden");let r=_e(e,t.wrap);if(r)ot(r);let n=at(e,t);if(n)n.hidden=!0}e.removeAttribute(L),e.removeAttribute(he)}function Ce(e){let t=e.target,r=P(t);if(!r)return;if(e.type==="load")X(t,r,"loaded");else if(st(t))X(t,r,"error");else te(t,r)}function Ut(){if(ie)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;let e=new WeakMap;ie={error:Ce,load:Ce,"turbo:before-morph-element":(t)=>{let r=t.target,n=t.detail?.newElement,i=r?.getAttribute?.(L);if(i==null||!n||!P(r))return;let s=(a)=>r.getAttribute(a)===n.getAttribute?.(a);if(s("src")&&s("srcset"))e.set(r,i)},"turbo:morph-element":(t)=>{let r=t.target,n=e.get(r);if(n===void 0)return;e.delete(r),queueMicrotask(()=>{let i=P(r);if(i)X(r,i,n)})},"turbo:frame-render":(t)=>q(t.target),"turbo:render":()=>q(document),"turbo:before-stream-render":(t)=>{let r=t.detail,n=r?.render,i=r?.newStream??t.target;if(typeof n!=="function"||!i?.querySelector?.("template")?.content?.querySelector?.(`img[${ve}]`))return;r.render=async(s)=>{await n(s),q(document)}}};for(let[t,r]of Object.entries(ie))document.addEventListener(t,r,!0);q(document)}function q(e){for(let t of e?.querySelectorAll?.(`img[${ve}]`)??[]){if(t.getAttribute(L)!=null||!t.complete||!st(t))continue;let r=`${t.getAttribute("src")} ${t.getAttribute("srcset")}`,n=(i)=>`${t.getAttribute("src")} ${t.getAttribute("srcset")}`===r&&X(t,P(t)??{},i);if(t.naturalWidth>0)n("loaded");else if(typeof t.decode==="function")t.decode().then(()=>n("loaded"),()=>n("error"));else n("error")}}function ct(e){de=e}var W,oe=null,De="[data-reactive-editable][contenteditable=plaintext-only]";function ut(){if(W===void 0)try{let e=document.createElement("div");e.contentEditable="plaintext-only",W=e.contentEditable==="plaintext-only"}catch{W=!1}return W}function z(e){if(e.matches?.(De))e.setAttribute("contenteditable","true");e.querySelectorAll?.(De).forEach(z)}function Jt(){if(oe||typeof document>"u"||typeof document.createElement!=="function")return;if(ut())return;z(document),oe=new MutationObserver((e)=>{for(let t of e)if(t.type==="attributes")z(t.target);else t.addedNodes.forEach(z)}),oe.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["contenteditable","data-reactive-editable"]})}var $e=!1;function qe(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea"||e.hasAttribute("data-reactive-editable"))&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function zt(){if($e)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;$e=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented)return;let n=qe(t);if(n)Kt(t,r);if(t.hasAttribute?.("data-reactive-editable")){if(Q.set(t,T(r)),!n)return;for(let{name:s}of[...t.attributes])if(!r.hasAttribute(s)&&s!=="contenteditable"&&s!==_)t.removeAttribute(s);for(let{name:s,value:a}of r.attributes)if(s!=="contenteditable"&&t.getAttribute(s)!==a)t.setAttribute(s,a);return e.preventDefault()}if(t.localName!=="input"||!n)return;let i=r.getAttribute("value");if(i==null)t.removeAttribute("value");else if(t.getAttribute("value")!==i)t.setAttribute("value",i)}),document.addEventListener("focusin",(e)=>Te(e.target)),document.addEventListener("turbo:before-morph-attribute",(e)=>{let t=e.detail?.attributeName;if((t==="value"||t===_)&&qe(e.target))e.preventDefault()}),document.addEventListener("input",(e)=>{let t=e.target;if(t?.hasAttribute?.(_)&&Ae(t)===Se(t))t.removeAttribute(_)})}var _="data-reactive-held",we='[data-controller~="reactive"]',H=null,k=new Map;function Ae(e){return e.hasAttribute("data-reactive-editable")?T(e):e.value}function Se(e){return e.hasAttribute("data-reactive-editable")?Fe(e):e.defaultValue}function Ht(e){if(e.hasAttribute("data-reactive-editable"))return T(e);return e.localName==="textarea"?e.textContent:e.getAttribute("value")??""}function Kt(e,t){let r=e.getAttribute("name");if(!r||/^(checkbox|radio)$/.test(e.type)||k.has(e.closest(we)))return;let n=Ht(t);if(n===Ae(e))return e.removeAttribute(_);if(n===Se(e))return;e.setAttribute(_,""),e.dispatchEvent(new CustomEvent("reactive:held",{bubbles:!0,detail:{name:r,theirs:n}}))}function Vt(e){let t=[];for(let r of e.querySelectorAll(`[${_}]`)){if(r.closest(we)!==e)continue;let n=r.getAttribute("name");if(Ae(r)===Se(r))r.removeAttribute(_);else if(n&&!t.includes(n))t.push(n)}if(t.length===0)return null;return JSON.stringify(t).replace(/[\u007f-]/g,(r)=>`\\u${r.charCodeAt(0).toString(16).padStart(4,"0")}`)}function lt(e,t){if(t===!0)return;for(let r of e.querySelectorAll(`[${_}]`))if(r.closest(we)===e&&!t?.includes(r.getAttribute("name")))r.removeAttribute(_)}function Gt(e){let t=e.headers.get("X-Reactive-Refused");if(t==="*")return!0;try{let r=JSON.parse(t);return Array.isArray(r)?r:null}catch{return null}}function We(e,t,r=null){let n={root:e,streams:0,keep:r},i=H;H=n;try{window.Turbo.renderStreamMessage(t)}finally{H=i}if(n.streams===0)lt(e,r)}function Yt(e){let t=H,r=e.detail,n=r?.render;if(!t||typeof n!=="function")return;t.streams++,r.render=async(i)=>{k.set(t.root,(k.get(t.root)||0)+1);try{return await n(i)}finally{let s=k.get(t.root)-1;if(s)k.set(t.root,s);else k.delete(t.root);lt(t.root,t.keep)}}}var Be="__materialize",je=!1;function Xt(){if(je)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;je=!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)}var Qt="phlex-reactive:latency";function dt(){return typeof sessionStorage<"u"&&Boolean(sessionStorage.getItem(Qt))}function Ee(){if(typeof document>"u")return;if(!g.has("devtools")&&!w.get("devtools")[1])return;let e=document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development";if(e||dt())v("devtools",(t)=>e&&t.attach())}var ft="data-reactive-active",A=0;function ht(){if(A++,A===1)pt("reactive:busy")}function mt(){if(A===0)return;if(A--,A===0)pt("reactive:idle")}function nn(){return A}function on(){A=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(ft)}function pt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(ft,A>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:A}}))}var gt="data-reactive-requests";function bt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!Zt(t))return;let r=er(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(gt,JSON.stringify(r))}function Zt(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function er(e){try{let t=JSON.parse(e.getAttribute(gt));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function Ue(){Ot(),It(),Mt(),Ct(),Dt(),zt(),Bt(),jt(),Ut(),Jt(),Xt(),Ee()}function tr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var yt=Symbol.for("phlex-reactive.core");if(globalThis[yt])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[yt]=!0;var vt=!1;function rr(){if(vt)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(rr,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var nr=new Set(["href","src","srcset","srcdoc","action","formaction","xlink:href","style"]);function _t(e){let t=String(e).toLowerCase();return t.startsWith("on")||nr.has(t)}var se=new WeakMap;function ir(e,t,r){let[n,i,s]=t;se.get(e)?.(),e.classList.add(n,i),r();let a=!1,o=requestAnimationFrame(()=>{if(a)return;e.classList.remove(i),e.classList.add(s)}),c=(d)=>{if(a||d&&d.target!==e)return;a=!0,se.delete(e),clearTimeout(u),globalThis.cancelAnimationFrame?.(o),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,i,s)};se.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let u=setTimeout(c,or(e))}function or(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[i,s]=["Duration","Delay"].map((o)=>String(r[n+o]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((o)=>/inf/.test(o)?1/0:parseFloat(o)>=0?parseFloat(o):1);for(let o=0;o<i.length||o<s.length||o<a.length;o++){let c=i[o%i.length]*a[o%a.length]||0;t=Math.max(t,c+s[o%s.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var sr=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",ar=new Set(["lexxy-editor","trix-editor"]);function T(e){let t="",r=!1,n=(s)=>{if(r&&t&&!t.endsWith(`
|
|
1
|
+
import{Controller as It}from"@hotwired/stimulus";import{confirmResolver as Ie}from"phlex/reactive/confirm";function Mt(){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 Ct(){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)}}var Dt=["focus","focus_first","blur"];function $t(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:js"])return;e["reactive:js"]=function(){let t=Le(this.getAttribute("data-reactive-ops"));if(!t.length)return;let r=this.getAttribute("target"),n=this.getAttribute("data-reactive-verbose")==="true",i=r?document.getElementById(r):null;if(r&&!i){if(n)v("devtools",(o)=>o.missingRoot(r));return}let s=(o)=>be(o,(c)=>Nr(c,i),n?(c,u)=>v("devtools",(d)=>d.diagnoseStream(c,u,i)):void 0),a=t.findIndex((o)=>Dt.includes(o?.[0]));if(a<0||typeof requestAnimationFrame!=="function")return s(t);s(t.slice(0,a)),requestAnimationFrame(()=>s(t.slice(a)))}}function qt(){let e=window.Turbo?.StreamActions;if(!e||e["reactive:defer"])return;e["reactive:defer"]=function(){v("defer",(t)=>t.streamAction(this))}}var Me=!1,fe=null;function Wt(){if(Me)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Me=!0,document.addEventListener("turbo:before-stream-render",(e)=>{if(Zt(e),Bt(e),Jt(e),fe)fe(e,g.get("effects"));else g.get("effects")?.wrap(e)})}var U="reactive:streamed";function Bt(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target,i=n?.getAttribute?.("action"),s=/^(append|prepend|update)$/.test(i);if(typeof r!=="function"||!(s||/^(before|after|replace)$/.test(i)))return;let a=n.getAttribute("target"),o=n.getAttribute("targets"),c=new Set;for(let u of a?[document.getElementById(a)]:o?document.querySelectorAll(o):[]){let d=(s?u:u?.parentElement)?.closest?.('[data-controller~="reactive"]');if(d)c.add(d)}if(c.size===0)return;t.render=async(u)=>{await r(u);for(let d of c)if(d.isConnected)d.dispatchEvent(new Event(U))}}function ve(e){return e?.tagName==="DIALOG"&&typeof e.showModal==="function"}function we(e){try{return e.matches(":modal")}catch{return!1}}function ot(e){if(!ve(e)){if(e?.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] show_modal targets a <dialog>, not <${e.localName}> — skipped`);return}if(!e.isConnected||we(e))return;if(e.open)e.close();e.showModal()}function jt(e){if(ve(e)&&e.open)e.close()}function Y(e){let r=[...e?.querySelectorAll?.("dialog[data-reactive-modal]")??[]];if(e?.matches?.("dialog[data-reactive-modal]"))r.push(e);for(let n of r)if(n.open&&!we(n))ot(n)}function Jt(e){let t=e.detail,r=t?.render,n=t?.newStream??e.target;if(typeof r!=="function"||!n?.querySelector?.("template")?.content?.querySelector?.("dialog"))return;t.render=async(i)=>{await r(i),Y(document)}}var Ce=!1;function Ut(){if(Ce)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ce=!0,document.addEventListener("turbo:morph-element",(t)=>{if(t.target?.matches?.('[data-controller~="reactive"]'))Y(t.target)}),document.addEventListener("turbo:morph",()=>Y(document));let e=new WeakSet;document.addEventListener("turbo:before-morph-element",(t)=>{let r=t.target,n=t.detail?.newElement;if(!ve(r)||!n)return;if(n.hasAttribute?.("open"))e.delete(r);else e.add(r)}),document.addEventListener("turbo:before-morph-attribute",(t)=>{let{target:r,detail:n}=t;if(n?.attributeName!=="open"||n.mutationType!=="remove")return;if(!e.has(r)||!r.open||!we(r))return;e.delete(r),t.preventDefault(),r.close()})}var he=new WeakMap;function st(e,t,r,n){let i=he.get(e)??new Map;he.set(e,i);let s=(a,o)=>{i.delete(a),i.set(a,o)};if(t.endsWith("_class"))for(let a of r.classes??[])s(`.${a}`,e.classList.contains(a));else if(t.endsWith("_attr"))St(r.name)||s(r.name,e.getAttribute(r.name));else if(t==="show"||t==="hide"||t==="toggle"){if(s("hidden",e.getAttribute("hidden")),r.expanded!=null)for(let a of n({...r,to:r.expanded}))st(a,"set_attr",{name:"aria-expanded"})}}var De=!1;function zt(){if(De)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;De=!0,document.addEventListener("turbo:morph-element",(e)=>{let t=e.target;for(let[r,n]of he.get(t)??[])if(r[0]===".")t.classList.toggle(r.slice(1),n);else if(n==null)t.removeAttribute(r);else if(t.getAttribute(r)!==n)t.setAttribute(r,n)})}var _e="data-reactive-image-fallback",x="data-reactive-image-state",me="data-reactive-image-hidden",oe=null,pe="data-reactive-wrap-hidden";function at(e){if(e.hasAttribute("hidden"))return;e.setAttribute("hidden",""),e.setAttribute(pe,"")}function ct(e){if(!e.hasAttribute(pe))return;e.removeAttribute("hidden"),e.removeAttribute(pe)}function I(e){if(e?.localName!=="img")return null;let t=e.getAttribute(_e);if(t==null)return null;try{return JSON.parse(t)||{}}catch{return{}}}var ut=(e)=>e.getAttribute("src")||e.getAttribute("srcset");function Ae(e,t){if(typeof t!=="string"||!t)return null;try{return e.closest('[data-controller~="reactive"]')?.querySelector(t)??null}catch{return null}}function lt(e,t){let r=Ae(e,t.alt);return r&&!r.contains(e)?r:null}function X(e,t,r){if(r==="error"){if(t.hide&&!e.hasAttribute("hidden"))e.setAttribute("hidden",""),e.setAttribute(me,"");if(t.wrap){let i=Ae(e,t.wrap);if(i)at(i);else console.warn(`[phlex-reactive] reactive_image_fallback wrap: ${JSON.stringify(t.wrap)} is not in the root — skipped`)}let n=lt(e,t);if(n)n.textContent=e.getAttribute("alt")??"",n.hidden=!1}else re(e,t);e.setAttribute(x,r)}function re(e,t=I(e)){if(!t||e.getAttribute(x)==null)return;if(e.getAttribute(x)==="error"){if(e.hasAttribute(me))e.removeAttribute("hidden");let r=Ae(e,t.wrap);if(r)ct(r);let n=lt(e,t);if(n)n.hidden=!0}e.removeAttribute(x),e.removeAttribute(me)}function $e(e){let t=e.target,r=I(t);if(!r)return;if(e.type==="load")X(t,r,"loaded");else if(ut(t))X(t,r,"error");else re(t,r)}function Ht(){if(oe)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;let e=new WeakMap;oe={error:$e,load:$e,"turbo:before-morph-element":(t)=>{let r=t.target,n=t.detail?.newElement,i=r?.getAttribute?.(x);if(i==null||!n||!I(r))return;let s=(a)=>r.getAttribute(a)===n.getAttribute?.(a);if(s("src")&&s("srcset"))e.set(r,i)},"turbo:morph-element":(t)=>{let r=t.target,n=e.get(r);if(n===void 0)return;e.delete(r),queueMicrotask(()=>{let i=I(r);if(i)X(r,i,n)})},"turbo:frame-render":(t)=>q(t.target),"turbo:render":()=>q(document),"turbo:before-stream-render":(t)=>{let r=t.detail,n=r?.render,i=r?.newStream??t.target;if(typeof n!=="function"||!i?.querySelector?.("template")?.content?.querySelector?.(`img[${_e}]`))return;r.render=async(s)=>{await n(s),q(document)}}};for(let[t,r]of Object.entries(oe))document.addEventListener(t,r,!0);q(document)}function q(e){for(let t of e?.querySelectorAll?.(`img[${_e}]`)??[]){if(t.getAttribute(x)!=null||!t.complete||!ut(t))continue;let r=`${t.getAttribute("src")} ${t.getAttribute("srcset")}`,n=(i)=>`${t.getAttribute("src")} ${t.getAttribute("srcset")}`===r&&X(t,I(t)??{},i);if(t.naturalWidth>0)n("loaded");else if(typeof t.decode==="function")t.decode().then(()=>n("loaded"),()=>n("error"));else n("error")}}function dt(e){fe=e}var W,se=null,qe="[data-reactive-editable][contenteditable=plaintext-only]";function ft(){if(W===void 0)try{let e=document.createElement("div");e.contentEditable="plaintext-only",W=e.contentEditable==="plaintext-only"}catch{W=!1}return W}function z(e){if(e.matches?.(qe))e.setAttribute("contenteditable","true");e.querySelectorAll?.(qe).forEach(z)}function Kt(){if(se||typeof document>"u"||typeof document.createElement!=="function")return;if(ft())return;z(document),se=new MutationObserver((e)=>{for(let t of e)if(t.type==="attributes")z(t.target);else t.addedNodes.forEach(z)}),se.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["contenteditable","data-reactive-editable"]})}var We=!1;function Be(e){return e===document.activeElement&&(e.localName==="input"||e.localName==="textarea"||e.hasAttribute("data-reactive-editable"))&&!e.hasAttribute("data-reactive-morph-value")&&!!e.closest('[data-controller~="reactive"]')}function Vt(){if(We)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;We=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented)return;let n=Be(t);if(n)Yt(t,r);if(t.hasAttribute?.("data-reactive-editable")){if(Q.set(t,T(r)),!n)return;for(let{name:s}of[...t.attributes])if(!r.hasAttribute(s)&&s!=="contenteditable"&&s!==w)t.removeAttribute(s);for(let{name:s,value:a}of r.attributes)if(s!=="contenteditable"&&t.getAttribute(s)!==a)t.setAttribute(s,a);return e.preventDefault()}if(t.localName!=="input"||!n)return;let i=r.getAttribute("value");if(i==null)t.removeAttribute("value");else if(t.getAttribute("value")!==i)t.setAttribute("value",i)}),document.addEventListener("focusin",(e)=>ke(e.target)),document.addEventListener("turbo:before-morph-attribute",(e)=>{let t=e.detail?.attributeName;if((t==="value"||t===w)&&Be(e.target))e.preventDefault()}),document.addEventListener("input",(e)=>{let t=e.target;if(t?.hasAttribute?.(w)&&Ee(t)===Te(t))t.removeAttribute(w)})}var w="data-reactive-held",Se='[data-controller~="reactive"]',H=null,k=new Map;function Ee(e){return e.hasAttribute("data-reactive-editable")?T(e):e.value}function Te(e){return e.hasAttribute("data-reactive-editable")?xe(e):e.defaultValue}function Gt(e){if(e.hasAttribute("data-reactive-editable"))return T(e);return e.localName==="textarea"?e.textContent:e.getAttribute("value")??""}function Yt(e,t){let r=e.getAttribute("name");if(!r||/^(checkbox|radio)$/.test(e.type)||k.has(e.closest(Se)))return;let n=Gt(t);if(n===Ee(e))return e.removeAttribute(w);if(n===Te(e))return;e.setAttribute(w,""),e.dispatchEvent(new CustomEvent("reactive:held",{bubbles:!0,detail:{name:r,theirs:n}}))}function Xt(e){let t=[];for(let r of e.querySelectorAll(`[${w}]`)){if(r.closest(Se)!==e)continue;let n=r.getAttribute("name");if(Ee(r)===Te(r))r.removeAttribute(w);else if(n&&!t.includes(n))t.push(n)}if(t.length===0)return null;return JSON.stringify(t).replace(/[\u007f-]/g,(r)=>`\\u${r.charCodeAt(0).toString(16).padStart(4,"0")}`)}function ht(e,t){if(t===!0)return;for(let r of e.querySelectorAll(`[${w}]`))if(r.closest(Se)===e&&!t?.includes(r.getAttribute("name")))r.removeAttribute(w)}function Qt(e){let t=e.headers.get("X-Reactive-Refused");if(t==="*")return!0;try{let r=JSON.parse(t);return Array.isArray(r)?r:null}catch{return null}}function je(e,t,r=null){let n={root:e,streams:0,keep:r},i=H;H=n;try{window.Turbo.renderStreamMessage(t)}finally{H=i}if(n.streams===0)ht(e,r)}function Zt(e){let t=H,r=e.detail,n=r?.render;if(!t||typeof n!=="function")return;t.streams++,r.render=async(i)=>{k.set(t.root,(k.get(t.root)||0)+1);try{return await n(i)}finally{let s=k.get(t.root)-1;if(s)k.set(t.root,s);else k.delete(t.root);ht(t.root,t.keep)}}}var Je="__materialize",Ue=!1;function er(){if(Ue)return;if(typeof window>"u"||typeof document>"u")return;if(typeof window.addEventListener!=="function")return;Ue=!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)}var tr="phlex-reactive:latency";function mt(){return typeof sessionStorage<"u"&&Boolean(sessionStorage.getItem(tr))}function Fe(){if(typeof document>"u")return;if(!g.has("devtools")&&!_.get("devtools")[1])return;let e=document.querySelector?.('meta[name="phlex-reactive-env"]')?.content==="development";if(e||mt())v("devtools",(t)=>e&&t.attach())}var pt="data-reactive-active",A=0;function gt(){if(A++,A===1)yt("reactive:busy")}function bt(){if(A===0)return;if(A--,A===0)yt("reactive:idle")}function un(){return A}function ln(){A=0,(typeof document<"u"?document.documentElement:null)?.removeAttribute?.(pt)}function yt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.toggleAttribute==="function")t.toggleAttribute(pt,A>0);if(typeof document.dispatchEvent==="function"&&typeof CustomEvent==="function")document.dispatchEvent(new CustomEvent(e,{detail:{count:A}}))}var vt="data-reactive-requests";function wt(e){if(typeof document>"u")return;let t=document.documentElement;if(typeof t?.setAttribute!=="function"||!rr(t))return;let r=nr(t);r[e]=(Number(r[e])||0)+1,t.setAttribute(vt,JSON.stringify(r))}function rr(e){return e.hasAttribute?.("data-reactive-verbose")||!!document.querySelector?.('[data-reactive-verbose="true"]')}function nr(e){try{let t=JSON.parse(e.getAttribute(vt));if(t&&typeof t==="object")return{action:0,defer:0,...t}}catch{}return{action:0,defer:0}}function ze(){Mt(),Ct(),$t(),qt(),Wt(),Vt(),Ut(),zt(),gr(),Ht(),Kt(),er(),Fe()}function ir(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var _t=Symbol.for("phlex-reactive.core");if(globalThis[_t])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[_t]=!0;var At=!1;function or(){if(At)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(or,0);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",e,{once:!0});else e()}var sr=new Set(["href","src","srcset","srcdoc","action","formaction","xlink:href","style"]);function St(e){let t=String(e).toLowerCase();return t.startsWith("on")||sr.has(t)}var ae=new WeakMap;function ar(e,t,r){let[n,i,s]=t;ae.get(e)?.(),e.classList.add(n,i),r();let a=!1,o=requestAnimationFrame(()=>{if(a)return;e.classList.remove(i),e.classList.add(s)}),c=(d)=>{if(a||d&&d.target!==e)return;a=!0,ae.delete(e),clearTimeout(u),globalThis.cancelAnimationFrame?.(o),e.removeEventListener("animationend",c),e.removeEventListener("transitionend",c),e.classList.remove(n,i,s)};ae.set(e,c),e.addEventListener("animationend",c),e.addEventListener("transitionend",c);let u=setTimeout(c,cr(e))}function cr(e){let t=0;try{let r=getComputedStyle(e);for(let n of["transition","animation"]){let[i,s]=["Duration","Delay"].map((o)=>String(r[n+o]).split(",").map((c)=>parseFloat(c)*(/ms/.test(c)?1:1000)||0)),a=String(r[n+"IterationCount"]).split(",").map((o)=>/inf/.test(o)?1/0:parseFloat(o)>=0?parseFloat(o):1);for(let o=0;o<i.length||o<s.length||o<a.length;o++){let c=i[o%i.length]*a[o%a.length]||0;t=Math.max(t,c+s[o%s.length])}}}catch{}return Math.min(Math.max(t+50,350),5000)}var ur=":is(lexxy-editor, trix-editor, [contenteditable=''], [contenteditable=true], [contenteditable=plaintext-only])",lr=new Set(["lexxy-editor","trix-editor"]);function T(e){let t="",r=!1,n=(s)=>{if(r&&t&&!t.endsWith(`
|
|
2
2
|
`))t+=`
|
|
3
3
|
`;r=!1,t+=s},i=(s)=>{for(let a of s.childNodes){let o=/^(div|p|li)$/.test(a.localName);if(o)r=!0;if(a.nodeType===3)a.data&&n(a.data);else if(a.localName==="br")n(`
|
|
4
4
|
`);else if(a.nodeType===1)i(a);if(o)r=!0}};return i(e),t=t.replace(/\r\n?/g,`
|
|
5
|
-
`).replace(/\n$/,""),e.getAttribute("data-reactive-editable")==="multi"?t:t.replace(/\n/g," ")}var Q=new WeakMap;function
|
|
6
|
-
`):e.value}function pr(e,t,r){if(r?.transition)ir(e,r.transition,()=>e.hidden=t);else e.hidden=t}function ae(e,t,r,n){if(pr(e,t,r),r?.expanded==null||typeof n!=="function")return;for(let i of n({...r,to:r.expanded}))i.setAttribute?.("aria-expanded",String(!t))}function ce(e){if(!_t(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}function Et(e,t){if(e?.localName!=="img")return console.warn(`[phlex-reactive] copy_media targets an <img>, not <${e?.localName}> — skipped`),null;let r=t?.localName==="img"?t:null,n=r?.getAttribute("src"),i=!1;for(let a of["srcset","src"]){let o=n?r.getAttribute(a):null;if(o==null){if(e.hasAttribute(a))i=e.removeAttribute(a)??!0}else if(e.getAttribute(a)!==o)i=e.setAttribute(a,o)??!0}if(i)te(e);let s=r?.getAttribute("alt")??"";if(e.getAttribute("alt")!==s)e.setAttribute("alt",s);return r?s:!1}var gr='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function br(e){return e.querySelectorAll?.(gr)?.[0]??null}function ke(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 He=Object.freeze({backspace:"Backspace",delete:"Delete",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"}),Ke=Object.freeze(["meta","ctrl","alt","shift"]);function re(e,t,r){let n=e.split("+");for(let a of Ke)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let i=n.find((a)=>!Ke.includes(a));if(i===void 0||typeof t.key!=="string")return!0;let s=r&&Object.hasOwn(r,i)?r[i]:Object.hasOwn(He,i)?He[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof s==="string"&&s.toLowerCase()===t.key.toLowerCase()}var yr=(e)=>e&&typeof e==="object"?e.keys:String(e),Le=()=>V().prevented??=new WeakSet;function ue(e,t){if(t!=null&&!e.defaultPrevented)Le().add(e);e.preventDefault()}function B(e,t,r){if(t.defaultPrevented&&e?.handled!==!0&&!Le().has(t))return!1;let n=t.target;if(e?.inEditable!==!0&&(n?.isContentEditable||/^(input|textarea|select)$/.test(n?.localName)))return!1;let i=/[Mm]ac|iP/.test(navigator.userAgentData?.platform??navigator.platform)?"meta":"ctrl";return re(yr(e).replace(/^mod\+/,`${i}+`),t,r)}function vr(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:ke(t),legacy:!0}];let r=[];for(let n of t.split(" ")){if(n==="")continue;let i=null;try{i=JSON.parse(n)}catch{i=null}if(i&&typeof i==="object"&&!Array.isArray(i))r.push(i);else console.warn(`[phlex-reactive] malformed on_client binding record ${JSON.stringify(n)} — skipped`)}return r}function Ve(e,t,r){if(e.legacy)return!0;let n=e.on;if(typeof n!=="string"||n==="")return!1;let i=n.indexOf(".");if(t.type!==(i<0?n:n.slice(0,i)))return!1;if(Boolean(e.window)!==Re(t.currentTarget))return!1;return i<0||r===null||re(n.slice(i+1),t,r)}function _r(e,t){let r=e.detail;if(r===void 0)return!0;if(r===null||typeof r!=="object"||Array.isArray(r))return!1;let n=t.detail;if(n===null||typeof n!=="object")return!1;return Object.keys(r).every((i)=>n[i]===r[i])}var Ge=new WeakMap;function wr(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,i=Ge.get(e);if(!i)i=new WeakMap,Ge.set(e,i);let s=i.get(n);if(!s)s=new Set,i.set(n,s);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(s.has(c))return!0;return s.add(c),!1}var Ye=new WeakMap;function Ar(e,t){if(e===null||typeof e!=="object")return!1;let r=e.params?.ops,n=typeof r==="string"?r:JSON.stringify(r??null),i=Ye.get(e);if(!i)i=new WeakMap,Ye.set(e,i);let s=i.get(t);if(!s)s=new Map,i.set(t,s);let a=s.get(e.currentTarget);if(!a)a=new Set,s.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function pe(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[i,s={}]=n;if(!Object.hasOwn(Je,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let a=t(s);if(a.length===0&&r)r(i,s);if(a.length>0)s=Er(i,s,t,r);if(!s)continue;for(let o of a)if(Je[i](o,s,t),s?.keep===!0)nt(o,i,s,t)}}var Sr=new Set(["set_value","text","set_attr"]);function Er(e,t,r,n){let i=e==="dispatch",s=i?t.detail_from:Sr.has(e)&&t.from!=null&&{value:t.attr};if(!s)return t;let a=i?"@trigger":t.from,o;try{o=r({...t,to:a})[0]}catch{}if(!o)return n?.(e,{...t,to:a}),null;let c=i?{...t.detail}:{};for(let[u,d]of Object.entries(s)){let f=Tr(o,d);if(f==null)return null;c[u]=f}return i?{...t,detail:c}:{...t,...c}}function Tr(e,t){if(t==="@text")return e.textContent??"";if(typeof t==="string"&&/^data-[a-z][a-z0-9-]*$/i.test(t))return e.getAttribute(t)??"";return console.warn(`[phlex-reactive] refused client read of ${JSON.stringify(t)} — skipped`),null}function Fr(e,t){let r=e.to;if(r==="@trigger")return[];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 kr(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function xe(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}var F='[data-controller~="reactive"]',Lr='[data-controller~="reactive"],[data-reactive-dormant~="reactive"]',ge=(e)=>e.getAttribute?.("data-reactive-token-value")==null&&!xe(e);function R(e,t,r){let n=e?.closest?.(t);while(n&&n!==r&&ge(n))n=n.parentElement?.closest?.(t);return n??null}var j=new WeakMap,U=new WeakMap;function xr(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 Rr(e){return["show-targets","group-targets","on-complete","filter-input","tags-field","css-vars"].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], [data-reactive-editable], [data-reactive-media], [data-reactive-css-vars]")!=null}function Nr(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}function Or(e){return Boolean(e.matches?.("[data-reactive-sortable],[data-reactive-sortable-source]")||e.querySelector?.("[data-reactive-sortable],[data-reactive-sortable-source]"))}function Ir(e){return Boolean(e.matches?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]")||e.querySelector?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]"))}function Tt(e){return e.getAttribute?.("data-reactive-presence")!=null}function Pr(e){return Boolean(e.matches?.("[data-reactive-countdown]")||e.querySelector?.("[data-reactive-countdown]"))}var Mr=[["persist",[kr,null,null,!0]],["defer",[xe,null]],["form",[xr,null]],["bindings",[Rr,null,null,!0]],["compute",[Nr,null,null,!0]],["sortable",[Or,null]],["drag",[Ir,null]],["presence",[Tt,null]],["countdown",[Pr,null]],["effects",[(e)=>["enter","update","exit"].some((t)=>e.getAttribute?.(`data-reactive-effect-${t}`)!=null),null]],["hints",[(e)=>e.querySelector?.("[data-reactive-optimistic-param], [data-reactive-busy-param], [data-reactive-loading-param]")!=null,null]],["devtools",[(e)=>e.getAttribute?.("data-reactive-debug")==="true",null]]],w=new Map(Mr),Xe=new Map,g=new Map,Cr=new Map;function y(e,t,r){Ft.set(e,[t,r]),Dr(e)}var Ft=new Map;function Dr(e){let t=w.get(e),[r,n]=Ft.get(e);t[1]=r,t[2]=n}function sn(e,t){t.install?.(M),g.set(e,t),Cr.set(e,t)}function kt(e){let t=[];for(let[r,[n]]of w){if(!n||g.has(r))continue;try{if(e.some((i)=>n(i)))t.push(r)}catch{}}return t}function Lt(e){return I(e).catch((t)=>Z(e,"load",t))}function I(e){let t=Xe.get(e);if(!t)t=(w.get(e)[1]??(()=>Promise.reject(Error("this entry has no way to import it"))))().then((n)=>(n.install?.(M),g.set(e,n),n)),Xe.set(e,t);return t}var Qe=new Set;function Z(e,t,r){let n=e+t;if(Qe.has(n))return;Qe.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 v(e,t){let r=g.get(e);if(r)return t(r);I(e).then(t,(n)=>Z(e,"load",n))}var $r=1e4;function le(){let e=Number(globalThis.document?.head?.querySelector?.('meta[name="phlex-reactive-feature-timeout"]')?.content);return Number.isFinite(e)&&e>0?e:$r}function an(){return[...w.keys()]}var Ze=Promise.resolve();function et(e,t,r){let n=M.waiting.get(e);if(n&&n[t]===r)delete n[t]}var M={enter:ht,exit:mt,count:bt,text:T,served:Fe,waiting:new WeakMap};var C=Symbol.for("phlex-reactive.early"),qr=1e4,Wr=1500,Re=(e)=>e!=null&&(e===globalThis.window||e.window===e),Br="dispatch";function V(){return globalThis[C]??={queue:[],connected:new WeakSet},globalThis[C]}function jr(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:qr}function Ur(e){let t={};for(let{name:r,value:n}of Array.from(e.attributes??[])){let i=/^data-reactive-(.+)-param$/i.exec(r);if(!i)continue;let s;try{s=JSON.parse(n)}catch{s=n}t[i[1].replace(/[-_]([a-z0-9])/g,(a,o)=>o.toUpperCase())]=s}return t}function Jr(e,t,r){return{[C]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:Ur(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&&!Le().has(e),preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var ee=new WeakMap;function zr(e,{token:t,type:r,method:n,filter:i,win:s},a){let o=ee.get(e);if(!o)ee.set(e,o=new Map);let c=s?`${t} ${a}`:t;if(o.has(c))return!1;return o.set(c,{type:r,method:n,filter:i,win:s,params:a,armed:!0}),!0}function tt(e,t,r,n){if(e?.[C])return!1;let i=Re(e?.currentTarget),s=i?n:e?.currentTarget,a=Kr(e,s,i?`@${t}`:t),o=ee.get(s),c=i&&JSON.stringify(e.params);for(let u of o?.values()??[]){if(!u.armed||u.method!==t||u.type!==e.type||Boolean(u.win)!==i)continue;if(i&&u.params!==c)continue;if(u.filter&&!re(u.filter,e,r))continue;return u.armed=!1,!0}return a}var G=new WeakMap;function Hr(e,t,r){let n=G.get(e);if(!n)G.set(e,n=new Map),setTimeout(()=>G.delete(e));let i=n.get(t)??{};n.set(t,i),i[r]=(i[r]??0)+1}function Kr(e,t,r){let n=e&&G.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class xt extends Nt{static values={token:String};#A;#d=new Map;#f=new Map;#ie;#x;#B;#R=0;#h=new Map;#N=new WeakMap;#t;featuresReady=Ze;#r=new Map;#O=new Set;#m=!1;#n=null;#p=new Map;#S=new Map;#g=new Map;#b=0;#j;#je=0;#Ue=0;connect(){if(vt=!0,V().connected.add(this.element),j.set(this.element,this),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||xe(this.element))this.#t=(e)=>{if(e.type==="focusin"?!e.target.hasAttribute?.("data-reactive-editable"):e.target!==this.element)return;if(e.type===J)this.#z();this.#U(!0)},this.element.addEventListener?.("turbo:morph-element",this.#t),this.element.addEventListener?.("focusin",this.#t),this.element.addEventListener?.(J,this.#t);this.element.querySelectorAll?.("[data-reactive-editable]").forEach(Te),this.#b++,this.featuresReady=Ze,this.#U(),Y(this.element),this.#ce()}#Je(e){}#ze(e,t,r,n){}#He(){}#Ke(e,t){}#U(e){{let t=this.#b,r=[];for(let[s,[a]]of w){if(!a||this.#O.has(s))continue;let o=g.get(s);if(o&&!o.connect)continue;try{if(a(this.element))r.push(s)}catch(c){this.#y(s,"detect",c)}}if(r.length===0)return;for(let s of r)this.#O.add(s);if(!this.#m&&r.every((s)=>g.has(s))){for(let s of r)this.#I(t,s,g.get(s),e);return}for(let s of r){let a=this.#oe(t,s),o=[];for(let u of w.keys()){if(u===s)break;if(this.#g.has(u))o.push(this.#g.get(u))}let c=Promise.all(o).then(()=>a).then((u)=>u&&this.#I(t,s,u,e));if(this.#g.set(s,c),w.get(s)[3])this.#n=c}let n=this.#n;n?.then(()=>{if(this.#n===n)this.#n=null}),this.#m=!0;let i=Promise.all(this.#g.values()).then(()=>{if(this.featuresReady===i)this.#m=!1});this.featuresReady=i}}#oe(e,t){{let r=()=>e===this.#b;return this.#se(t),new Promise((n)=>{let i=!1,s=setTimeout(()=>{if(this.#p.delete(s),i=!0,r())this.#y(t,"timeout",Error(`not loaded after ${le()} ms`));n(null)},le());this.#p.set(s,n);let a=()=>{clearTimeout(s),this.#p.delete(s)};I(t).then((o)=>{if(a(),i)queueMicrotask(()=>this.#I(e,t,o));else n(o)},(o)=>{if(a(),r())this.#y(t,"load",o);n(null)})})}}#se(e){{let t=w.get(e)[2];if(!t)return;let r={};try{this.#S.set(e,[t(this.element,r),r]),M.waiting.set(this.element,{...M.waiting.get(this.element),[e]:r})}catch(n){this.#y(e,"detect",n)}}}#J(e,t){{let[r,n]=this.#S.get(e)??[];if(this.#S.delete(e),!t)et(this.element,e,n);try{r?.()}catch(i){console.error(`[phlex-reactive] the "${e}" feature module failed to stop waiting`,i)}return n}}#I(e,t,r,n){{if(e!==this.#b)return;let i=this.#J(t);try{r.connect?.(this,this.#e(),n,i),this.#r.set(t,r)}catch(s){this.#y(t,"connect",s)}}}#e(){return this.#j??={emit:(e,t,r)=>this.#o(e,t,r),reseed:()=>this.#z(),proceed:(e,t,r,n)=>this.#M(e,t,r,0,0,null,n),forgetToken:()=>{this.#A=void 0},owns:(e)=>this.#c(e),ownership:()=>this.#Q(),bindingOwns:(e)=>this.#Z(e),bindingOwnership:()=>this.#Le(),opTargets:(e)=>this.#W(e),diagnose:(e,t)=>this.#q(e,t),applyOps:(e,t)=>pe(e,(r)=>this.#W(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#q(`client op "${r}"`,n)),listnavOptions:(e)=>this.#_(e),collectFields:()=>this.#ee(),plain:ut,text:T,served:Fe,copyMedia:Et,setValue:St,confirm:(e,t)=>Promise.resolve().then(()=>Oe(e,t)).catch(()=>!1)},this.#j}#z(){this.#r.get("form")?.reseed(this),this.#r.get("bindings")?.reseed(this),this.#r.get("compute")?.seed(this)}#y(e,t,r){if(Z(e,t,r),this.#i("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#o("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#ae(){{this.#b++;for(let[t,r]of this.#p)clearTimeout(t),r(null);this.#p.clear();for(let t of[...this.#S.keys()]){let r=this.#J(t,!0),n=this.element;v(t,(i)=>{i.abandon?.(n,r),et(n,t,r)})}this.#O.clear(),this.#g.clear(),this.#m=!1,this.#n=null;let e=[...this.#r];this.#r.clear();for(let[t,r]of e)try{r.disconnect?.(this,this.#e())}catch(n){console.error(`[phlex-reactive] the "${t}" feature module failed to disconnect`,n)}}}#ce(){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.#ue();for(let[e,t]of U.get(this.element)??[]){if(e.currentTarget!==t)Object.defineProperty(e,"currentTarget",{value:t,configurable:!0});this.dispatch(e)}U.delete(this.element)}#P=new Set;#ue(){let{queue:e}=V();if(e.length===0)return;let t=[];for(let i=e.length-1;i>=0;i--){let{root:s}=e[i];if(s===this.element||!s.isConnected)t.unshift(...e.splice(i,1))}let r=jr(),n=new Map;for(let i of t){let s=n.get(i.event)??[new Set,new Set];n.set(i.event,s);let a=s[+!!i.win];if(a.has(i.el))continue;a.add(i.el);let o=i.win?Math.min(Wr,r):r,c=i.root!==this.element?"its root left the page before a controller connected":performance.now()-i.at>o?`it is older than the ${o} ms ${i.win?"window-trigger":"early-event"} TTL`:i.el.isConnected&&this.element.contains(i.el)?null:"its element left the root before the controller connected";if(c){if(this.#L())console.warn(`[phlex-reactive] dropped an early "${i.event.type}" trigger: ${c}`);continue}this.#le(i)}}#le({event:e,el:t,descs:r,win:n}){let i=Jr(e,t,n),s=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),o=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!re(c.filter,e,s))continue;if(/#\w+.*:once\b/.test(c.token)){if(!zr(o,c,n&&JSON.stringify(i.params)))continue;this.#P.add(o)}if(Hr(e,o,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(i);else this.dispatch(i)}}disconnect(){if(this.#ae(),this.#ve(),this.#we(),this.#t)this.element.removeEventListener?.("turbo:morph-element",this.#t),this.element.removeEventListener?.("focusin",this.#t),this.element.removeEventListener?.(J,this.#t);if(V().connected.delete(this.element),j.get(this.element)===this)j.delete(this.element);this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#P)ee.delete(e);this.#P.clear()}dispatch(e){if(e.params?.action&&e.params.action!==Be&&this.#de())return this.#fe(e);let t=e.params?.shortcut;if(t!=null&&!B(t,e,this.application?.schema?.keyMappings))return;if(tt(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:r,params:n,debounce:i,throttle:s,confirm:a,confirmWhen:o,outside:c,window:u,optimistic:d,prevent:f}=e.params;if(!r)return;let h=e.params.busy??e.params.loading;if(c&&this.element.contains(e.target))return;let p=e.currentTarget??e.target;if((t!=null||!u&&f!==!1)&&!this.#re(d,p))ue(e,t);if(r===Be){let m=()=>{{let S=this.#r.get("defer");if(S)return S.materialize(this)}if(this.tokenValue)return this.#M(p,r,"{}")};return this.#m?this.featuresReady.then(m):m()}let b=this.#H(a,o),E=()=>this.#M(p,r,n,i,s,d,h);if(!b)return E();if(b instanceof Promise)return b.then((m)=>m?this.#E(m,p,E):E());this.#E(b,p,E)}#E(e,t,r){return Promise.resolve().then(()=>Oe(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#H(e,t){if(e)return e;if(!t)return null;{let r=g.get("bindings");if(r)return r.confirmMessage(this,this.#e(),t);return this.#K("bindings").then((n)=>n&&n.confirmMessage(this,this.#e(),t))}}#K(e){{let t;return Promise.race([I(e).catch((r)=>(Z(e,"load",r),null)),new Promise((r)=>t=setTimeout(()=>r(null),le()))]).finally(()=>clearTimeout(t))}}#de(){return!this.tokenValue&&ge(this.element)}#fe(e){let t=R(this.element.parentElement,Lr);if(!t){if(this.element.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] "${e.params.action}": no token on this root or above, nothing sent`);return}let r=j.get(t);if(r)return r.dispatch(e);let{shortcut:n,window:i,optimistic:s,prevent:a}=e.params;if(n!=null&&!B(n,e,this.application?.schema?.keyMappings))return;let o=e.currentTarget??e.target;if((n!=null||!i&&a!==!1)&&!this.#re(s,o))ue(e,n);U.set(t,[...U.get(t)??[],[e,o]]);let c=t.dataset;if(c.reactiveDormant)c.controller=`${c.controller??""} ${c.reactiveDormant}`.trim(),delete c.reactiveDormant}runOps(e){let t=e.params?.ops;if(t?.shortcut!=null&&!B(t.shortcut,e,this.application?.schema?.keyMappings))return;if(tt(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(Ar(e,this))return;let r=e.params??{},n=e.currentTarget??e.target,i=vr(r.ops),s=i.filter((o)=>Ve(o,e,null)),a=s.length<=1?s:s.filter((o)=>Ve(o,e,this.application?.schema?.keyMappings));if(a.length===0&&i.length>0){if(this.#L())this.#w((o)=>o.noBinding(this,e));return}for(let o of a){if(o.outside&&e[C])continue;if(!_r(o,e))continue;let c=o.within==null?n:this.#he(o.within,e);if(o.within!=null&&!c)continue;if(o.shortcut!=null&&!B(o.shortcut,e,this.application?.schema?.keyMappings))continue;if(wr(this,e,o))continue;this.#me(o.legacy?{...r,ops:o.ops,debounce:void 0,throttle:void 0,prevent:void 0}:o,e,c,i.indexOf(o),n)}}#he(e,t){let r=t.currentTarget,n=null;try{n=t.target?.closest?.(e)}catch{if(this.#L())console.warn(`[phlex-reactive] on_client within: ${JSON.stringify(e)} is not a selector — nothing ran`)}return n&&n!==r&&r?.contains?.(n)&&this.#c(n)?n:null}#me(e,t,r,n,i=r){let{ops:s,confirm:a,confirmWhen:o,outside:c,window:u,shortcut:d,prevent:f}=e;if(c&&this.element.contains(t.target))return;if(d!=null||!u&&f!==!1)ue(t,d);let h=this.#H(a,o),p=this.#pe(e,n,i,()=>this.#Pe(this.#Ie(s),r));if(!h)return p();if(h instanceof Promise)return h.then((b)=>b?this.#E(b,r,p):p());this.#E(h,r,p)}#pe(e,t,r,n){let i=Number(e.debounce)||0,s=Number(e.throttle)||0;if(i<=0&&s<=0)return n;let a=JSON.stringify([t,e]);if(i>0)return()=>this.#V(r,a,i,n);return()=>this.#G(r,a,s,n)}recompute(e){return g.get("compute")?.recompute(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#_(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return this.#v("tagsAdd",e)}tagsPick(e){return this.#v("tagsPick",e)}tagsRemove(e){return this.#v("tagsRemove",e)}nestedAdd(e){return this.#v("nestedAdd",e)}nestedRemove(e){return this.#v("nestedRemove",e)}syncNestedJson(e){return g.get("bindings")?.syncNestedJson(this,this.#e(),e)}#v(e,t){{let r=g.get("bindings");if(r)return r[e](this,this.#e(),t);t?.preventDefault?.();let n={currentTarget:t?.currentTarget??null,target:t?.target??null,preventDefault(){}};return v("bindings",(i)=>i[e](this,this.#e(),n))}}trackDirty(){(this.#r.get("form")??g.get("form"))?.scan(this,this.#e())}listnavNext(e){this.#T(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#T(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#T(e,()=>0)}listnavLast(e){this.#T(e,(t,r)=>r-1)}listnavPick(e){let t=this.#_(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.#_(e))t.removeAttribute("data-reactive-highlighted")}#T(e,t){let r=this.#_(e);if(!r.length)return;e.preventDefault();let n=this.#ge(e),i=globalThis.document?.activeElement,s=n?r.findIndex((o)=>o===i||i!=null&&o.contains?.(i)):r.findIndex((o)=>o.hasAttribute("data-reactive-highlighted")),a=r[t(s,r.length)];if(n)a.focus?.();else{for(let o of r)o.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#ge(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#_(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.#Q();return Array.from(this.element.querySelectorAll(r)).filter((i)=>!i.hidden&&n(i))}#M(e,t,r,n,i,s,a){if(this.#o("reactive:before-dispatch",{action:t,params:this.#te(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#ye(e,c,t,r,s,a);let u=Number(i)||0;if(u>0)return this.#_e(e,u,t,r,s,a);return this.#F(t,r,s,e,a)}#F(e,t,r,n,i){let s={inverse:null,undo:[],resurrect:null},a=this.#Me(e,n,s),o=Boolean(r||i),c=(h)=>{if(!o||!h)return;let p=this.#e();if(s.inverse=h.optimistic(this,p,r,n),s.undo.push(...h.busy(this,p,i,n)),this.#D())s.resurrect=h.resurrection(this,p,r,n)},u=g.get("hints");if(!o||u)c(u);let d=()=>this.#Te(e,t,s,a),f=()=>this.#n?this.#n.then(d):d();return this.queue=(this.queue??Promise.resolve()).then(()=>o&&!u?this.#be().then(c).then(f):f()),this.queue}#be(){return this.#K("hints")}#ye(e,t,r,n,i,s){this.#V(e,Br,t,()=>this.#F(r,n,i,e,s))}#V(e,t,r,n){this.#C(e,t);let i=()=>{this.#C(e,t),n()},s=setTimeout(i,r);if(!Re(e))e?.addEventListener?.("blur",i,{once:!0});let a=this.#d.get(e);if(!a)this.#d.set(e,a=new Map);a.set(t,{timer:s,flush:i})}#C(e,t){let r=this.#d.get(e),n=r?.get(t);if(!n)return;if(clearTimeout(n.timer),e?.removeEventListener?.("blur",n.flush),r.delete(t),r.size===0)this.#d.delete(e)}#ve(){for(let[e,t]of[...this.#d])for(let r of[...t.keys()])this.#C(e,r)}#_e(e,t,r,n,i,s){return this.#G(e,r,t,()=>this.#F(r,n,i,e,s))}#G(e,t,r,n){let i=this.#f.get(e)??new Map;if(i.has(t))return;let s=setTimeout(()=>{if(i.delete(t),i.size===0)this.#f.delete(e)},r);return i.set(t,s),this.#f.set(e,i),n()}#we(){for(let e of this.#f.values())for(let t of e.values())clearTimeout(t);this.#f.clear()}#o(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}#s(e,t,r,n){let i=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#F(e,t)};this.#o("reactive:error",{action:e,params:r,...n,retry:i})}#i(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#Ae(){this.element?.removeAttribute?.("data-reactive-error")}#Se(){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))}#Ee(){{let e=g.get("devtools");if(e)return e.delay();if(dt())return I("devtools").then((t)=>t.delay(),()=>{})}}#D(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#Y(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#Te(e,t,r,n){let{fields:i,files:s}=this.#ee(),a=this.#te(t),o={...i,...a},c=this.#a,u=s.length>0,d=u?this.#Ne(c,e,o,s):JSON.stringify({token:c,act:e,params:o}),f=this.#D()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(i),encoding:u?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#Y()}:null;await this.#Ee();try{if(navigator.onLine===!1){this.#u(r.inverse),this.#i("offline"),this.#s(e,t,o,{kind:"offline"});return}let h;try{let m={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#We()};if(!u)m["Content-Type"]="application/json";let S=this.#Be();if(S)m["X-Pgbus-Connection"]=S;let D=Tt(this.element)&&document.getElementById(`reactive-presence-src-${this.element.id}`)?.getAttribute("connection-id");if(D)m["X-Reactive-Presence"]=D;let Ne=Vt(this.element);if(Ne)m["X-Reactive-Held"]=Ne;bt("action"),h=await fetch(this.#$e(),{method:"POST",headers:m,body:d,credentials:"same-origin",signal:AbortSignal.timeout(this.#qe())})}catch(m){if(console.error("[phlex-reactive] action error",m),this.#u(r.inverse),m?.name==="TimeoutError"||m?.name==="AbortError"){this.#i("timeout"),this.#s(e,t,o,{kind:"timeout"});return}this.#Se(),this.#i("network"),this.#s(e,t,o,{kind:"network"});return}if(f)f.status=h.status;if(h.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#u(r.inverse),this.#i("redirected"),this.#s(e,t,o,{kind:"redirected",status:h.status});return}if(!h.ok){let m=await h.text();if(console.error(`[phlex-reactive] action failed: HTTP ${h.status}`,m),this.#u(r.inverse),(h.headers.get("Content-Type")||"").includes("turbo-stream")){let S=this.#X(m);if(this.#a=S??this.#a,f)this.#w((D)=>D.recordBody(f,m,S));We(this.element,m,!0)}this.#i("http"),this.#s(e,t,o,{kind:"http",status:h.status,body:m});return}let p=h.headers.get("Content-Type")||"";if(!p.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${p}" — no update applied`),this.#u(r.inverse),this.#i("content-type"),this.#s(e,t,o,{kind:"content-type",status:h.status});return}let b=await h.text(),E=this.#X(b);if(this.#a=E??this.#a,f)this.#w((m)=>m.recordBody(f,b,E));if(We(this.element,b,Gt(h)),r.resurrect)queueMicrotask(r.resurrect);return this.#Ae(),this.#o("reactive:applied",{action:e,params:o,html:b}),b}catch(h){console.error("[phlex-reactive] action error",h),this.#u(r.inverse),this.#o("reactive:error",{action:e,params:o,kind:"apply"})}finally{if(n?.(),f)this.#w((h)=>h.trace(this,{...f,ms:this.#Y()-f.started}))}}get#a(){return this.#A??this.tokenValue}set#a(e){this.#A=e}tokenValueChanged(){this.#A=void 0}#X(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#Fe(t),i=e.match(r);if(i)return i[1];let s=e.match(n);if(s)return s[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#Fe(e){let t=this.#B;if(t&&t.id===e)return t;let r=tr(e);return this.#B={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>`)}}#c(e){return e.closest('[data-controller~="reactive"]')===this.element}#Q(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#c(t)}#ke(){let e=this.element.querySelectorAll(F);if(e.length===0||[...e].every(ge))return()=>!0;return(t)=>{let r=R(t,F,this.element);if(r===this.element)return!0;return t.getAttribute("data-reactive-shared-field")!=null&&R(r.parentElement,F,this.element)===this.element}}#Z(e){if(this.#c(e))return!0;if(e.getAttribute?.("data-reactive-shared-field")==null)return!1;let t=R(e,F,this.element);return t===this.element||R(t?.parentElement,F,this.element)===this.element}#Le(){if(this.element.querySelectorAll(F).length===0)return()=>!0;return(e)=>this.#Z(e)}#ee(){let e={},t=[],r=this.#ke(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((o)=>{if(!r(o))return;if(o.type==="file")for(let c of o.files??[])t.push({name:o.name,file:c,multiple:o.multiple});else n.push(o)});let i=[];this.element.querySelectorAll(`[name]${sr}`).forEach((o)=>{if(r(o))i.push(o)});let s=this.#xe(n),a=this.#Re(n);for(let o of n)if(s.has(o.name)){let c=e[o.name]??(e[o.name]=[]);if(o.type==="checkbox"||o.type==="radio"){if(o.checked)c.push(o.value)}else if(o.type==="hidden"){if(!a.has(o.name))c.push(o.value)}else if(o.multiple&&o.options){for(let u of o.options)if(u.selected)c.push(u.value)}else c.push(o.value)}else if(o.type==="checkbox")e[o.name]=o.checked;else if(o.type==="radio"){if(o.checked)e[o.name]=o.value}else e[o.name]=o.value;return i.forEach((o)=>{let c=o.getAttribute("name");if(!c)return;let u=o.getAttribute("data-reactive-editable")!=null?T(o):o.value??o.textContent??o.innerHTML??"",d=e[c];if(String(c).endsWith("[]")&&!cr(o))return;if(String(c).endsWith("[]")&&(d===void 0||Array.isArray(d))){(Array.isArray(d)?d:e[c]=[]).push(u);return}if(d==null||d==="")e[c]=u}),{fields:e,files:t}}#xe(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}#Re(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#Ne(e,t,r,n){let i=new FormData;i.append("token",e),i.append("act",t);let s=[];for(let[o,c]of Object.entries(r))if(Array.isArray(c)&&String(o).endsWith("[]"))if(c.length===0)s.push(String(o).slice(0,-2));else{let u=`${this.#k(o)}[]`;for(let d of c)i.append(u,String(d))}else this.#$(i,this.#k(o),c);for(let o of s)i.append("empty_groups[]",o);let a=this.#Oe(n);for(let{name:o,file:c,multiple:u}of n){let f=u||a.has(o)?`${this.#k(o)}[]`:this.#k(o);i.append(f,c,c.name)}return i}#k(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((i)=>`[${i}]`).join("")}`}#$(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,i)=>this.#$(e,`${t}[${i}]`,n));else if(typeof r==="object")for(let[n,i]of Object.entries(r))this.#$(e,`${t}[${n}]`,i);else e.append(t,String(r))}#Oe(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))}#te(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Ie(e){return ke(e)}#Pe(e,t){pe(e,(r)=>this.#W(r,t),(r,n)=>this.#q(`client op "${r}"`,n))}#L(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#D()}#q(e,t){if(!this.#L())return;this.#w((r)=>r.diagnose(this,e,t))}#w(e){v("devtools",e)}#W(e,t){let r=e.to;if(r==="@root")return[this.element];if(r==="@trigger")return t?.nodeType===1?[t]:[];if(typeof r!=="string"||r==="")return[];if(e.global)return[...document.querySelectorAll(r)];return[...this.element.querySelectorAll(r)].filter((n)=>this.#c(n))}#re(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#u(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Me(e,t,r){this.#Ce(e,t),ht();let n=!1;return()=>{if(n)return;n=!0,this.#De(e,t),mt();for(let i of r.undo)i()}}#Ce(e,t){if(this.#l(t,e,1),this.#l(this.element,e,1),this.#h.set(e,(this.#h.get(e)??0)+1),this.#R++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#ne(e))this.#l(r,e,1)}#De(e,t){this.#l(t,e,-1),this.#l(this.element,e,-1);let r=(this.#h.get(e)??1)-1;if(r<=0)this.#h.delete(e);else this.#h.set(e,r);if(--this.#R<=0)this.#R=0,this.element.removeAttribute("aria-busy");for(let n of this.#ne(e))this.#l(n,e,-1)}#l(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#N.get(e)??new Map,i=(n.get(t)??0)+r;if(i<=0)n.delete(t);else n.set(t,i);if(n.size===0){this.#N.delete(e),e.removeAttribute("data-reactive-busy");return}this.#N.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#ne(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#c(r))}#$e(){return this.#ie??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#qe(){if(this.#x!=null)return this.#x;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#x=Number.isFinite(t)&&t>0?t:30000}#We(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#Be(){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)Ue();else document.addEventListener("turbo:load",Ue,{once:!0});y("persist",()=>import("phlex/reactive/features/persist"),Vr);y("defer",()=>import("phlex/reactive/features/defer"));y("form",()=>import("phlex/reactive/features/form"));y("bindings",()=>import("phlex/reactive/features/bindings"));y("compute",()=>import("phlex/reactive/features/compute"),Gr);y("sortable",()=>import("phlex/reactive/features/sortable"));y("drag",()=>import("phlex/reactive/features/drag"));y("presence",()=>import("phlex/reactive/features/presence"));y("countdown",()=>import("phlex/reactive/features/countdown"));y("effects",()=>import("phlex/reactive/features/effects"));y("hints",()=>import("phlex/reactive/features/hints"));y("devtools",()=>import("phlex/reactive/features/devtools"));Ee();function Vr(e,t){let r=()=>{t.edited=!0},n=(s)=>{let a=s.target;if(s.detail?.success&&a?.tagName==="FORM"&&a.contains?.(e))t.submitted=!0},i=["input","change","lexxy:change","trix-change"];for(let s of i)e.addEventListener?.(s,r);return document.addEventListener("turbo:submit-end",n),()=>{for(let s of i)e.removeEventListener?.(s,r);document.removeEventListener("turbo:submit-end",n)}}function Gr(e,t){let r=()=>{t.edited=!0};return e.addEventListener?.("input",r),e.addEventListener?.("change",r),()=>{e.removeEventListener?.("input",r),e.removeEventListener?.("change",r)}}var Yr=1000,x=null,Rt,ne=new Set;function Xr(e){return Lt(e).then((t)=>{if(e!=="effects")return;Rt=t,t?.sweep()})}ct((e,t)=>{let r=e.detail,n=r?.render;if(typeof n!=="function")return;let i=r.newStream??e.target,s=kt(Qr(i)).filter((o)=>!ne.has(o));if(!t&&!ne.has("effects")&&Zr(i))s.push("effects");if(s.length===0&&!x)return t?.wrap(e);if(s.length>0){for(let c of s)ne.add(c);let o=x=Promise.race([Promise.all([x,...s.map(Xr)]),new Promise((c)=>setTimeout(c,Yr))]).then(()=>{if(x!==o)return;x=null,ne.clear()})}let a=x;r.render=async(o)=>{await a;let c={target:e.target,detail:{newStream:r.newStream,render:n}};(t??Rt)?.wrap(c),await c.detail.render(o)}});function Qr(e){let t=e?.querySelector?.("template")?.content;if(!t)return[];let r=[...t.querySelectorAll?.('[data-controller~="reactive"]')??[]];for(let n of t.children??[])if(n.matches?.('[data-controller~="reactive"]')&&!r.includes(n))r.unshift(n);return r.push(t),r}function Zr(e){return Boolean(e?.hasAttribute?.("data-reactive-effect")||document.getElementById?.(e?.getAttribute?.("target"))?.matches?.("[data-reactive-effect-update],[data-reactive-effect-exit]")||e?.querySelector?.("template")?.content?.querySelector?.("[data-reactive-effect-enter],[data-reactive-dismiss-after]")||document.querySelector?.("[data-reactive-dismiss-after]:not([data-reactive-dismiss-scheduled])"))}var hn=xt;export{ft as ACTIVE_ATTR,sr as EDITOR_SELECTOR,ar as EDITOR_TAGS,gt as REQUESTS_ATTR,rr as checkReactiveRegistration,bt as countReactiveRequest,hn as default,T as editableValue,ht as enterReactiveActivity,tr as escapeRegExp,mt as exitReactiveActivity,Lt as loadReactiveFeature,ct as onReactiveStreamWithoutEffects,nn as reactiveActivityCount,an as reactiveFeatureNames,Ue as registerReactiveActions,Ct as registerReactiveDefer,Ee as registerReactiveDev,Dt as registerReactiveDismiss,Dt as registerReactiveEffects,sn as registerReactiveFeature,y as registerReactiveFeatureLoader,Ut as registerReactiveImageFallback,Mt as registerReactiveJs,jt as registerReactiveKeep,Bt as registerReactiveModals,zt as registerReactiveMorphFocus,Xt as registerReactiveOffline,Jt as registerReactivePlaintext,Dt as registerReactiveStreamRender,It as registerReactiveToken,Ot as registerReactiveVisit,on as resetReactiveActivity,Fe as serverText,kt as unloadedFeaturesFor};
|
|
5
|
+
`).replace(/\n$/,""),e.getAttribute("data-reactive-editable")==="multi"?t:t.replace(/\n/g," ")}var Q=new WeakMap;function ke(e){if(e?.hasAttribute?.("data-reactive-editable")&&!Q.has(e))Q.set(e,T(e))}function xe(e){return ke(e),Q.get(e)}function dr(e){return lr.has(e.localName)?typeof e.value==="string":!0}var He=Object.freeze({show:(e,t,r)=>ce(e,!1,t,r),hide:(e,t,r)=>ce(e,!0,t,r),toggle:(e,t,r)=>ce(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(ue(t.name))e.setAttribute(t.name,t.value??"")},remove_attr:(e,t)=>{if(ue(t.name))e.removeAttribute(t.name)},toggle_attr:(e,t)=>{if(!ue(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)=>Ar(e)?.focus?.(),blur:(e)=>{let t=e.ownerDocument?.activeElement??globalThis.document?.activeElement;if(t&&(t===e||e.contains?.(t)))t.blur?.()},show_modal:(e)=>ot(e),close_dialog:(e)=>jt(e),text:(e,t)=>{let r=String(t.value??"");if(e.textContent!==r)e.textContent=r},copy_media:(e,t,r)=>{let n=null;try{n=r({...t,to:t.from})[0]??null}catch{}kt(e,n)},check_group:(e,t)=>{let r=t.global?document.querySelectorAll('[data-controller~="reactive"]'):[e];for(let n of r)v("bindings",(i)=>i.checkGroup(n,t.group,t.checked))},presence:(e,t)=>v("presence",(r)=>r.set(e,t.state)),dispatch:(e,t)=>{e.dispatchEvent(new CustomEvent(t.name,{bubbles:!0,composed:!0,detail:t.detail??{}}))},submit:(e,t,r)=>{let n=fr(e);if(!n)return;let i=null;if(t?.submitter!=null&&typeof r==="function"){if(i=r({...t,to:t.submitter})[0]??null,!(i?.form===n&&(i.type==="submit"||i.type==="image")))console.warn(`[phlex-reactive] submitter ${t.submitter} is not a submit control of the form — ignored`),i=null}i?n.requestSubmit?.(i):n.requestSubmit?.()},paste_into:(e)=>hr(e),preview_file:(e,t,r)=>mr(e,t,r),set_value:(e,t)=>Ft(e,String(t.value??"")),persist_state:(e,t)=>v("persist",(r)=>r.writeState(e,t.state)),persist_clear:(e)=>v("persist",(t)=>t.clearRoot(e))});function fr(e){if(e?.tagName==="FORM")return e;return e?.form??e?.closest?.("form")??null}function hr(e){let t=globalThis.navigator?.clipboard;if(typeof t?.readText!=="function")return;t.readText().then((r)=>{if(!r)return;e.value=r,Tt(e),e.focus?.()}).catch(()=>{})}var N=new Map,O=null;function mr(e,t,r){if(e?.tagName!=="INPUT"||e.type!=="file")return K(`reads an input[type=file], not <${e?.localName}>`);let n=typeof r==="function"?r({...t,to:t.into})[0]:null;if(n?.tagName!=="IMG")return K(`paints an <img>, and ${JSON.stringify(t.into)} is ${n?`a <${n.localName}>`:"not on the page"}`);let i=[...t.valid===!0&&e.validity?.valid===!1?[]:e.files??[]],s=yr(e,t.accept),a=(u)=>Number.isInteger(t.max_bytes)&&u.size>t.max_bytes,o=[],c;if(t.per_file===!0&&e.multiple){let u=i.filter((f,h)=>{let p=typeof f?.type==="string"&&s(f)?a(f)&&"size":"type";if(p)o.push({reason:p,file:f,index:h});return!p}),d=o.length>0&&!br(e,u)?i.length:u.length;for(let f of o)f.remaining=d;c=u.find((f)=>f.type.startsWith("image/"))}else{let u=i.filter((f)=>typeof f?.type==="string"&&s(f));c=u.find((f)=>f.type.startsWith("image/"));let d=i.length>0&&u.length===0?"type":null;if(c&&a(c))d="size";if(d)o.push({reason:d,file:d==="size"?c:i[0]}),c=null}if(Et(n),c){let u=URL.createObjectURL(c);N.set(n,u),n.setAttribute("src",u),vr()}else n.removeAttribute("src");if(re(n),t.wrap!=null){let u=r({...t,to:t.wrap});if(u.length===0)K(`wrap: ${JSON.stringify(t.wrap)} is not on the page`);for(let d of u)c?ct(d):at(d)}if(t.name!=null)for(let u of r({...t,to:t.name}))u.textContent=c?c.name:"";if(t.rejected!=null)pr(e,r({...t,to:t.rejected}),o,t.rejected);for(let u of o)e.dispatchEvent(new CustomEvent("reactive:file-rejected",{bubbles:!0,detail:u}))}var Z="data-reactive-file-rejected";function pr(e,t,r,n){if(t.length===0)return ge(e,`rejected: ${JSON.stringify(n)} is not on the page`);for(let i of t){for(let a of[...i.children])if(a.hasAttribute(Z))a.remove();let s=[...i.children].find((a)=>a.localName==="template");if(!s){ge(e,`rejected: ${JSON.stringify(n)} has no <template> child`);continue}for(let{reason:a,file:o}of r){let c=s.content.cloneNode(!0);for(let u of c.querySelectorAll("[data-reactive-file-reason]"))if(u.getAttribute("data-reactive-file-reason")!==a)u.remove();for(let u of c.querySelectorAll('[data-reactive-file="name"]'))u.textContent=o.name;for(let u of[...c.childNodes]){if(u.nodeType!==1)continue;u.setAttribute(Z,""),i.append(u)}}}}var Ke=!1;function gr(){if(Ke)return;if(typeof document>"u"||typeof document.addEventListener!=="function")return;Ke=!0,document.addEventListener("turbo:before-morph-element",(e)=>{let t=e.target,r=e.detail?.newElement;if(!r||e.defaultPrevented||!t.lastElementChild?.hasAttribute(Z))return;for(let n of t.children)if(n.hasAttribute(Z))r.append(n.cloneNode(!0))})}function br(e,t){if(typeof DataTransfer!=="function")return ge(e,"per_file: has no DataTransfer to drop the refused files from the input"),!1;let r=new DataTransfer;for(let n of t)r.items.add(n);return e.files=r.files,!0}function yr(e,t){let r=String((t===!0?e.getAttribute("accept"):typeof t==="string"&&t)||"").toLowerCase().split(",").map((n)=>n.trim()).filter(Boolean);if(r.length===0)return(n)=>n.type.startsWith("image/");return(n)=>{let i=n.type.toLowerCase();return r.some((s)=>s[0]==="."?String(n.name).toLowerCase().endsWith(s):s.endsWith("/*")?i.startsWith(s.slice(0,-1)):i===s)}}function K(e){console.warn(`[phlex-reactive] preview_file ${e} — skipped`)}function ge(e,t){if(e.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))K(t)}function Et(e){let t=N.get(e);if(t===void 0)return;if(N.delete(e),URL.revokeObjectURL(t),N.size===0)O?.disconnect(),O=null}function vr(){if(O||typeof MutationObserver!=="function"||!document?.documentElement)return;O=new MutationObserver(()=>{for(let[e,t]of N)if(!e.isConnected||e.getAttribute("src")!==t)Et(e)}),O.observe(document.documentElement,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src"]})}function Tt(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function Ft(e,t){if(!/^(input|textarea|select)$/.test(e.localName)||e.type==="file"&&t!==""){console.warn("[phlex-reactive] set_value skipped: not a field it can write",e);return}let r=Ve(e);if(e.value=t,Ve(e)!==r)Tt(e)}function Ve(e){return e.type==="select-multiple"?[...e.selectedOptions].map((t)=>t.value).join(`
|
|
6
|
+
`):e.value}function wr(e,t,r){if(r?.transition)ar(e,r.transition,()=>e.hidden=t);else e.hidden=t}function ce(e,t,r,n){if(wr(e,t,r),r?.expanded==null||typeof n!=="function")return;for(let i of n({...r,to:r.expanded}))i.setAttribute?.("aria-expanded",String(!t))}function ue(e){if(!St(e))return!0;return console.warn(`[phlex-reactive] refused client attr op on ${JSON.stringify(e)} — skipped`),!1}function kt(e,t){if(e?.localName!=="img")return console.warn(`[phlex-reactive] copy_media targets an <img>, not <${e?.localName}> — skipped`),null;let r=t?.localName==="img"?t:null,n=r?.getAttribute("src"),i=!1;for(let a of["srcset","src"]){let o=n?r.getAttribute(a):null;if(o==null){if(e.hasAttribute(a))i=e.removeAttribute(a)??!0}else if(e.getAttribute(a)!==o)i=e.setAttribute(a,o)??!0}if(i)re(e);let s=r?.getAttribute("alt")??"";if(e.getAttribute("alt")!==s)e.setAttribute("alt",s);return r?s:!1}var _r='a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ar(e){return e.querySelectorAll?.(_r)?.[0]??null}function Le(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 Ge=Object.freeze({backspace:"Backspace",delete:"Delete",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"}),Ye=Object.freeze(["meta","ctrl","alt","shift"]);function ne(e,t,r){let n=e.split("+");for(let a of Ye)if(n.includes(a)!==Boolean(t[`${a}Key`]))return!1;let i=n.find((a)=>!Ye.includes(a));if(i===void 0||typeof t.key!=="string")return!0;let s=r&&Object.hasOwn(r,i)?r[i]:Object.hasOwn(Ge,i)?Ge[i]:/^[a-z0-9]$/.test(i)?i:null;return typeof s==="string"&&s.toLowerCase()===t.key.toLowerCase()}var Sr=(e)=>e&&typeof e==="object"?e.keys:String(e),Re=()=>V().prevented??=new WeakSet;function le(e,t){if(t!=null&&!e.defaultPrevented)Re().add(e);e.preventDefault()}function B(e,t,r){if(t.defaultPrevented&&e?.handled!==!0&&!Re().has(t))return!1;let n=t.target;if(e?.inEditable!==!0&&(n?.isContentEditable||/^(input|textarea|select)$/.test(n?.localName)))return!1;let i=/[Mm]ac|iP/.test(navigator.userAgentData?.platform??navigator.platform)?"meta":"ctrl";return ne(Sr(e).replace(/^mod\+/,`${i}+`),t,r)}function Er(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:Le(t),legacy:!0}];let r=[];for(let n of t.split(" ")){if(n==="")continue;let i=null;try{i=JSON.parse(n)}catch{i=null}if(i&&typeof i==="object"&&!Array.isArray(i))r.push(i);else console.warn(`[phlex-reactive] malformed on_client binding record ${JSON.stringify(n)} — skipped`)}return r}function Xe(e,t,r){if(e.legacy)return!0;let n=e.on;if(typeof n!=="string"||n==="")return!1;let i=n.indexOf(".");if(t.type!==(i<0?n:n.slice(0,i)))return!1;if(Boolean(e.window)!==Oe(t.currentTarget))return!1;return i<0||r===null||ne(n.slice(i+1),t,r)}function Tr(e,t){let r=e.detail;if(r===void 0)return!0;if(r===null||typeof r!=="object"||Array.isArray(r))return!1;let n=t.detail;if(n===null||typeof n!=="object")return!1;return Object.keys(r).every((i)=>n[i]===r[i])}var Qe=new WeakMap;function Fr(e,t,r){if(!r.once)return!1;let n=t.currentTarget??e.element,i=Qe.get(e);if(!i)i=new WeakMap,Qe.set(e,i);let s=i.get(n);if(!s)s=new Set,i.set(n,s);let a=t.params?.ops,c=(n===globalThis.window?`${typeof a==="string"?a:JSON.stringify(a??null)}|`:"")+JSON.stringify(r);if(s.has(c))return!0;return s.add(c),!1}var Ze=new WeakMap;function kr(e,t){if(e===null||typeof e!=="object")return!1;let r=e.params?.ops,n=typeof r==="string"?r:JSON.stringify(r??null),i=Ze.get(e);if(!i)i=new WeakMap,Ze.set(e,i);let s=i.get(t);if(!s)s=new Map,i.set(t,s);let a=s.get(e.currentTarget);if(!a)a=new Set,s.set(e.currentTarget,a);if(a.has(n))return!0;return a.add(n),!1}function be(e,t,r){for(let n of e){if(!Array.isArray(n))continue;let[i,s={}]=n;if(!Object.hasOwn(He,i)){console.warn(`[phlex-reactive] unknown client op ${JSON.stringify(i)} — skipped`);continue}let a=t(s);if(a.length===0&&r)r(i,s);if(a.length>0)s=Lr(i,s,t,r);if(!s)continue;for(let o of a)if(He[i](o,s,t),s?.keep===!0)st(o,i,s,t)}}var xr=new Set(["set_value","text","set_attr"]);function Lr(e,t,r,n){let i=e==="dispatch",s=i?t.detail_from:xr.has(e)&&t.from!=null&&{value:t.attr};if(!s||i&&!Object.keys(s).length)return t;let a=i?t.detail??{}:{};if(typeof a!="object"||Array.isArray(a))return console.warn(`[phlex-reactive] refused client read over detail ${JSON.stringify(a)} — skipped`),null;let o=i?"@trigger":t.from,c;try{c=r({...t,to:o})[0]}catch{}if(!c)return n?.(e,{...t,to:o}),null;let u={...a};for(let[d,f]of Object.entries(s)){let h=Rr(c,f);if(h==null)return null;u[d]=h}return i?{...t,detail:u}:{...t,...u}}function Rr(e,t){if(t==="@text")return e.textContent??"";if(typeof t==="string"&&/^data-[a-z][a-z0-9-]*$/i.test(t))return e.getAttribute(t)??"";return console.warn(`[phlex-reactive] refused client read of ${JSON.stringify(t)} — skipped`),null}function Nr(e,t){let r=e.to;if(r==="@trigger")return[];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 Or(e){let t=e.getAttribute?.("data-reactive-persist");return Boolean(t)&&t!=="off"}function Ne(e){return["defer-token","defer-src","lazy-on","lazy-visible"].some((t)=>e.getAttribute?.(`data-reactive-${t}`)!=null)}var F='[data-controller~="reactive"]',Pr='[data-controller~="reactive"],[data-reactive-dormant~="reactive"]',ye=(e)=>e.getAttribute?.("data-reactive-token-value")==null&&!Ne(e);function R(e,t,r){let n=e?.closest?.(t);while(n&&n!==r&&ye(n))n=n.parentElement?.closest?.(t);return n??null}var j=new WeakMap,J=new WeakMap;function Ir(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 Mr(e){return["show-targets","group-targets","on-complete","filter-input","tags-field","css-vars"].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], [data-reactive-editable], [data-reactive-media], [data-reactive-css-vars]")!=null}function Cr(e){return e.getAttribute?.("data-reactive-compute-inputs-param")!=null}function Dr(e){return Boolean(e.matches?.("[data-reactive-sortable],[data-reactive-sortable-source]")||e.querySelector?.("[data-reactive-sortable],[data-reactive-sortable-source]"))}function $r(e){return Boolean(e.matches?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]")||e.querySelector?.("[data-reactive-frame],[data-reactive-box],[data-reactive-point]"))}function xt(e){return e.getAttribute?.("data-reactive-presence")!=null}function qr(e){return Boolean(e.matches?.("[data-reactive-countdown]")||e.querySelector?.("[data-reactive-countdown]"))}var Wr=[["persist",[Or,null,null,!0]],["defer",[Ne,null]],["form",[Ir,null]],["bindings",[Mr,null,null,!0]],["compute",[Cr,null,null,!0]],["sortable",[Dr,null]],["drag",[$r,null]],["presence",[xt,null]],["countdown",[qr,null]],["effects",[(e)=>["enter","update","exit"].some((t)=>e.getAttribute?.(`data-reactive-effect-${t}`)!=null),null]],["hints",[(e)=>e.querySelector?.("[data-reactive-optimistic-param], [data-reactive-busy-param], [data-reactive-loading-param]")!=null,null]],["devtools",[(e)=>e.getAttribute?.("data-reactive-debug")==="true",null]]],_=new Map(Wr),et=new Map,g=new Map,Br=new Map;function y(e,t,r){Lt.set(e,[t,r]),jr(e)}var Lt=new Map;function jr(e){let t=_.get(e),[r,n]=Lt.get(e);t[1]=r,t[2]=n}function dn(e,t){t.install?.(M),g.set(e,t),Br.set(e,t)}function Rt(e){let t=[];for(let[r,[n]]of _){if(!n||g.has(r))continue;try{if(e.some((i)=>n(i)))t.push(r)}catch{}}return t}function Nt(e){return P(e).catch((t)=>ee(e,"load",t))}function P(e){let t=et.get(e);if(!t)t=(_.get(e)[1]??(()=>Promise.reject(Error("this entry has no way to import it"))))().then((n)=>(n.install?.(M),g.set(e,n),n)),et.set(e,t);return t}var tt=new Set;function ee(e,t,r){let n=e+t;if(tt.has(n))return;tt.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 v(e,t){let r=g.get(e);if(r)return t(r);P(e).then(t,(n)=>ee(e,"load",n))}var Jr=1e4;function de(){let e=Number(globalThis.document?.head?.querySelector?.('meta[name="phlex-reactive-feature-timeout"]')?.content);return Number.isFinite(e)&&e>0?e:Jr}function fn(){return[..._.keys()]}var rt=Promise.resolve();function nt(e,t,r){let n=M.waiting.get(e);if(n&&n[t]===r)delete n[t]}var M={enter:gt,exit:bt,count:wt,text:T,served:xe,waiting:new WeakMap};var C=Symbol.for("phlex-reactive.early"),Ur=1e4,zr=1500,Oe=(e)=>e!=null&&(e===globalThis.window||e.window===e),Hr="dispatch";function V(){return globalThis[C]??={queue:[],connected:new WeakSet},globalThis[C]}function Kr(){let e=Number(globalThis.document?.querySelector?.('meta[name="phlex-reactive-early-ttl"]')?.content);return Number.isFinite(e)&&e>0?e:Ur}function Vr(e){let t={};for(let{name:r,value:n}of Array.from(e.attributes??[])){let i=/^data-reactive-(.+)-param$/i.exec(r);if(!i)continue;let s;try{s=JSON.parse(n)}catch{s=n}t[i[1].replace(/[-_]([a-z0-9])/g,(a,o)=>o.toUpperCase())]=s}return t}function Gr(e,t,r){return{[C]:!0,type:e.type,detail:e.detail,target:e.target,currentTarget:r?t.ownerDocument.defaultView:t,params:Vr(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&&!Re().has(e),preventDefault(){},stopPropagation(){},stopImmediatePropagation(){}}}var te=new WeakMap;function Yr(e,{token:t,type:r,method:n,filter:i,win:s},a){let o=te.get(e);if(!o)te.set(e,o=new Map);let c=s?`${t} ${a}`:t;if(o.has(c))return!1;return o.set(c,{type:r,method:n,filter:i,win:s,params:a,armed:!0}),!0}function it(e,t,r,n){if(e?.[C])return!1;let i=Oe(e?.currentTarget),s=i?n:e?.currentTarget,a=Qr(e,s,i?`@${t}`:t),o=te.get(s),c=i&&JSON.stringify(e.params);for(let u of o?.values()??[]){if(!u.armed||u.method!==t||u.type!==e.type||Boolean(u.win)!==i)continue;if(i&&u.params!==c)continue;if(u.filter&&!ne(u.filter,e,r))continue;return u.armed=!1,!0}return a}var G=new WeakMap;function Xr(e,t,r){let n=G.get(e);if(!n)G.set(e,n=new Map),setTimeout(()=>G.delete(e));let i=n.get(t)??{};n.set(t,i),i[r]=(i[r]??0)+1}function Qr(e,t,r){let n=e&&G.get(e)?.get(t);if(!n?.[r])return!1;return n[r]-=1,!0}class Ot extends It{static values={token:String};#A;#d=new Map;#f=new Map;#ie;#L;#B;#R=0;#h=new Map;#N=new WeakMap;#t;featuresReady=rt;#r=new Map;#O=new Set;#m=!1;#n=null;#p=new Map;#S=new Map;#g=new Map;#b=0;#j;#je=0;#Je=0;connect(){if(At=!0,V().connected.add(this.element),j.set(this.element,this),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||Ne(this.element))this.#t=(e)=>{if(e.type==="focusin"?!e.target.hasAttribute?.("data-reactive-editable"):e.target!==this.element)return;if(e.type===U)this.#z();this.#J(!0)},this.element.addEventListener?.("turbo:morph-element",this.#t),this.element.addEventListener?.("focusin",this.#t),this.element.addEventListener?.(U,this.#t);this.element.querySelectorAll?.("[data-reactive-editable]").forEach(ke),this.#b++,this.featuresReady=rt,this.#J(),Y(this.element),this.#ce()}#Ue(e){}#ze(e,t,r,n){}#He(){}#Ke(e,t){}#J(e){{let t=this.#b,r=[];for(let[s,[a]]of _){if(!a||this.#O.has(s))continue;let o=g.get(s);if(o&&!o.connect)continue;try{if(a(this.element))r.push(s)}catch(c){this.#y(s,"detect",c)}}if(r.length===0)return;for(let s of r)this.#O.add(s);if(!this.#m&&r.every((s)=>g.has(s))){for(let s of r)this.#P(t,s,g.get(s),e);return}for(let s of r){let a=this.#oe(t,s),o=[];for(let u of _.keys()){if(u===s)break;if(this.#g.has(u))o.push(this.#g.get(u))}let c=Promise.all(o).then(()=>a).then((u)=>u&&this.#P(t,s,u,e));if(this.#g.set(s,c),_.get(s)[3])this.#n=c}let n=this.#n;n?.then(()=>{if(this.#n===n)this.#n=null}),this.#m=!0;let i=Promise.all(this.#g.values()).then(()=>{if(this.featuresReady===i)this.#m=!1});this.featuresReady=i}}#oe(e,t){{let r=()=>e===this.#b;return this.#se(t),new Promise((n)=>{let i=!1,s=setTimeout(()=>{if(this.#p.delete(s),i=!0,r())this.#y(t,"timeout",Error(`not loaded after ${de()} ms`));n(null)},de());this.#p.set(s,n);let a=()=>{clearTimeout(s),this.#p.delete(s)};P(t).then((o)=>{if(a(),i)queueMicrotask(()=>this.#P(e,t,o));else n(o)},(o)=>{if(a(),r())this.#y(t,"load",o);n(null)})})}}#se(e){{let t=_.get(e)[2];if(!t)return;let r={};try{this.#S.set(e,[t(this.element,r),r]),M.waiting.set(this.element,{...M.waiting.get(this.element),[e]:r})}catch(n){this.#y(e,"detect",n)}}}#U(e,t){{let[r,n]=this.#S.get(e)??[];if(this.#S.delete(e),!t)nt(this.element,e,n);try{r?.()}catch(i){console.error(`[phlex-reactive] the "${e}" feature module failed to stop waiting`,i)}return n}}#P(e,t,r,n){{if(e!==this.#b)return;let i=this.#U(t);try{r.connect?.(this,this.#e(),n,i),this.#r.set(t,r)}catch(s){this.#y(t,"connect",s)}}}#e(){return this.#j??={emit:(e,t,r)=>this.#o(e,t,r),reseed:()=>this.#z(),proceed:(e,t,r,n)=>this.#M(e,t,r,0,0,null,n),forgetToken:()=>{this.#A=void 0},owns:(e)=>this.#c(e),ownership:()=>this.#Q(),bindingOwns:(e)=>this.#Z(e),bindingOwnership:()=>this.#xe(),opTargets:(e)=>this.#W(e),diagnose:(e,t)=>this.#q(e,t),applyOps:(e,t)=>be(e,(r)=>this.#W(t!=null&&r.to==null?{...r,to:t}:r),(r,n)=>this.#q(`client op "${r}"`,n)),listnavOptions:(e)=>this.#w(e),collectFields:()=>this.#ee(),plain:ft,text:T,served:xe,copyMedia:kt,setValue:Ft,confirm:(e,t)=>Promise.resolve().then(()=>Ie(e,t)).catch(()=>!1)},this.#j}#z(){this.#r.get("form")?.reseed(this),this.#r.get("bindings")?.reseed(this),this.#r.get("compute")?.seed(this)}#y(e,t,r){if(ee(e,t,r),this.#i("feature"),t==="load"&&this.element.getAttribute?.("data-reactive-defer-pending"))this.element.removeAttribute("data-reactive-defer-pending"),this.element.removeAttribute("aria-busy");this.#o("reactive:error",{kind:"feature",feature:e,phase:t,error:r})}#ae(){{this.#b++;for(let[t,r]of this.#p)clearTimeout(t),r(null);this.#p.clear();for(let t of[...this.#S.keys()]){let r=this.#U(t,!0),n=this.element;v(t,(i)=>{i.abandon?.(n,r),nt(n,t,r)})}this.#O.clear(),this.#g.clear(),this.#m=!1,this.#n=null;let e=[...this.#r];this.#r.clear();for(let[t,r]of e)try{r.disconnect?.(this,this.#e())}catch(n){console.error(`[phlex-reactive] the "${t}" feature module failed to disconnect`,n)}}}#ce(){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.#ue();for(let[e,t]of J.get(this.element)??[]){if(e.currentTarget!==t)Object.defineProperty(e,"currentTarget",{value:t,configurable:!0});this.dispatch(e)}J.delete(this.element)}#I=new Set;#ue(){let{queue:e}=V();if(e.length===0)return;let t=[];for(let i=e.length-1;i>=0;i--){let{root:s}=e[i];if(s===this.element||!s.isConnected)t.unshift(...e.splice(i,1))}let r=Kr(),n=new Map;for(let i of t){let s=n.get(i.event)??[new Set,new Set];n.set(i.event,s);let a=s[+!!i.win];if(a.has(i.el))continue;a.add(i.el);let o=i.win?Math.min(zr,r):r,c=i.root!==this.element?"its root left the page before a controller connected":performance.now()-i.at>o?`it is older than the ${o} ms ${i.win?"window-trigger":"early-event"} TTL`:i.el.isConnected&&this.element.contains(i.el)?null:"its element left the root before the controller connected";if(c){if(this.#x())console.warn(`[phlex-reactive] dropped an early "${i.event.type}" trigger: ${c}`);continue}this.#le(i)}}#le({event:e,el:t,descs:r,win:n}){let i=Gr(e,t,n),s=this.application?.schema?.keyMappings,a=(t.getAttribute("data-action")??"").split(/\s+/),o=n?this.element:t;for(let c of r){if(!a.includes(c.token))continue;if(c.filter&&!ne(c.filter,e,s))continue;if(/#\w+.*:once\b/.test(c.token)){if(!Yr(o,c,n&&JSON.stringify(i.params)))continue;this.#I.add(o)}if(Xr(e,o,n?`@${c.method}`:c.method),c.method==="runOps")this.runOps(i);else this.dispatch(i)}}disconnect(){if(this.#ae(),this.#ve(),this.#_e(),this.#t)this.element.removeEventListener?.("turbo:morph-element",this.#t),this.element.removeEventListener?.("focusin",this.#t),this.element.removeEventListener?.(U,this.#t);if(V().connected.delete(this.element),j.get(this.element)===this)j.delete(this.element);this.element.removeAttribute?.("data-reactive-connected");for(let e of this.#I)te.delete(e);this.#I.clear()}dispatch(e){if(e.params?.action&&e.params.action!==Je&&this.#de())return this.#fe(e);let t=e.params?.shortcut;if(t!=null&&!B(t,e,this.application?.schema?.keyMappings))return;if(it(e,"dispatch",this.application?.schema?.keyMappings,this.element))return;let{action:r,params:n,debounce:i,throttle:s,confirm:a,confirmWhen:o,outside:c,window:u,optimistic:d,prevent:f}=e.params;if(!r)return;let h=e.params.busy??e.params.loading;if(c&&this.element.contains(e.target))return;let p=e.currentTarget??e.target;if((t!=null||!u&&f!==!1)&&!this.#re(d,p))le(e,t);if(r===Je){let m=()=>{{let S=this.#r.get("defer");if(S)return S.materialize(this)}if(this.tokenValue)return this.#M(p,r,"{}")};return this.#m?this.featuresReady.then(m):m()}let b=this.#H(a,o),E=()=>this.#M(p,r,n,i,s,d,h);if(!b)return E();if(b instanceof Promise)return b.then((m)=>m?this.#E(m,p,E):E());this.#E(b,p,E)}#E(e,t,r){return Promise.resolve().then(()=>Ie(e,{el:t})).catch(()=>!1).then((n)=>{if(n)r()})}#H(e,t){if(e)return e;if(!t)return null;{let r=g.get("bindings");if(r)return r.confirmMessage(this,this.#e(),t);return this.#K("bindings").then((n)=>n&&n.confirmMessage(this,this.#e(),t))}}#K(e){{let t;return Promise.race([P(e).catch((r)=>(ee(e,"load",r),null)),new Promise((r)=>t=setTimeout(()=>r(null),de()))]).finally(()=>clearTimeout(t))}}#de(){return!this.tokenValue&&ye(this.element)}#fe(e){let t=R(this.element.parentElement,Pr);if(!t){if(this.element.closest?.('[data-reactive-verbose="true"], [data-reactive-debug="true"]'))console.warn(`[phlex-reactive] "${e.params.action}": no token on this root or above, nothing sent`);return}let r=j.get(t);if(r)return r.dispatch(e);let{shortcut:n,window:i,optimistic:s,prevent:a}=e.params;if(n!=null&&!B(n,e,this.application?.schema?.keyMappings))return;let o=e.currentTarget??e.target;if((n!=null||!i&&a!==!1)&&!this.#re(s,o))le(e,n);J.set(t,[...J.get(t)??[],[e,o]]);let c=t.dataset;if(c.reactiveDormant)c.controller=`${c.controller??""} ${c.reactiveDormant}`.trim(),delete c.reactiveDormant}runOps(e){let t=e.params?.ops;if(t?.shortcut!=null&&!B(t.shortcut,e,this.application?.schema?.keyMappings))return;if(it(e,"runOps",this.application?.schema?.keyMappings,this.element))return;if(kr(e,this))return;let r=e.params??{},n=e.currentTarget??e.target,i=Er(r.ops),s=i.filter((o)=>Xe(o,e,null)),a=s.length<=1?s:s.filter((o)=>Xe(o,e,this.application?.schema?.keyMappings));if(a.length===0&&i.length>0){if(this.#x())this.#_((o)=>o.noBinding(this,e));return}for(let o of a){if(o.outside&&e[C])continue;if(!Tr(o,e))continue;let c=o.within==null?n:this.#he(o.within,e);if(o.within!=null&&!c)continue;if(o.shortcut!=null&&!B(o.shortcut,e,this.application?.schema?.keyMappings))continue;if(Fr(this,e,o))continue;this.#me(o.legacy?{...r,ops:o.ops,debounce:void 0,throttle:void 0,prevent:void 0}:o,e,c,i.indexOf(o),n)}}#he(e,t){let r=t.currentTarget,n=null;try{n=t.target?.closest?.(e)}catch{if(this.#x())console.warn(`[phlex-reactive] on_client within: ${JSON.stringify(e)} is not a selector — nothing ran`)}return n&&n!==r&&r?.contains?.(n)&&this.#c(n)?n:null}#me(e,t,r,n,i=r){let{ops:s,confirm:a,confirmWhen:o,outside:c,window:u,shortcut:d,prevent:f}=e;if(c&&this.element.contains(t.target))return;if(d!=null||!u&&f!==!1)le(t,d);let h=this.#H(a,o),p=this.#pe(e,n,i,()=>this.#Ie(this.#Pe(s),r));if(!h)return p();if(h instanceof Promise)return h.then((b)=>b?this.#E(b,r,p):p());this.#E(h,r,p)}#pe(e,t,r,n){let i=Number(e.debounce)||0,s=Number(e.throttle)||0;if(i<=0&&s<=0)return n;let a=JSON.stringify([t,e]);if(i>0)return()=>this.#V(r,a,i,n);return()=>this.#G(r,a,s,n)}recompute(e){return g.get("compute")?.recompute(this,this.#e(),e)}tagsAdd(e){if(e?.defaultPrevented)return;if(this.#w(e).some((t)=>t.hasAttribute?.("data-reactive-highlighted")))return;return this.#v("tagsAdd",e)}tagsPick(e){return this.#v("tagsPick",e)}tagsRemove(e){return this.#v("tagsRemove",e)}nestedAdd(e){return this.#v("nestedAdd",e)}nestedRemove(e){return this.#v("nestedRemove",e)}syncNestedJson(e){return g.get("bindings")?.syncNestedJson(this,this.#e(),e)}#v(e,t){{let r=g.get("bindings");if(r)return r[e](this,this.#e(),t);t?.preventDefault?.();let n={currentTarget:t?.currentTarget??null,target:t?.target??null,preventDefault(){}};return v("bindings",(i)=>i[e](this,this.#e(),n))}}trackDirty(){(this.#r.get("form")??g.get("form"))?.scan(this,this.#e())}listnavNext(e){this.#T(e,(t,r)=>t<0?0:(t+1)%r)}listnavPrev(e){this.#T(e,(t,r)=>t<0?r-1:(t-1+r)%r)}listnavFirst(e){this.#T(e,()=>0)}listnavLast(e){this.#T(e,(t,r)=>r-1)}listnavPick(e){let t=this.#w(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.#w(e))t.removeAttribute("data-reactive-highlighted")}#T(e,t){let r=this.#w(e);if(!r.length)return;e.preventDefault();let n=this.#ge(e),i=globalThis.document?.activeElement,s=n?r.findIndex((o)=>o===i||i!=null&&o.contains?.(i)):r.findIndex((o)=>o.hasAttribute("data-reactive-highlighted")),a=r[t(s,r.length)];if(n)a.focus?.();else{for(let o of r)o.removeAttribute("data-reactive-highlighted");a.setAttribute("data-reactive-highlighted","true")}a.scrollIntoView?.({block:"nearest"})}#ge(e){return(e?.currentTarget??e?.target??this.element).getAttribute?.("data-reactive-listnav-focus-param")==="true"}#w(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.#Q();return Array.from(this.element.querySelectorAll(r)).filter((i)=>!i.hidden&&n(i))}#M(e,t,r,n,i,s,a){if(this.#o("reactive:before-dispatch",{action:t,params:this.#te(r),element:this.element},{cancelable:!0}).defaultPrevented)return;let c=Number(n)||0;if(c>0)return this.#ye(e,c,t,r,s,a);let u=Number(i)||0;if(u>0)return this.#we(e,u,t,r,s,a);return this.#F(t,r,s,e,a)}#F(e,t,r,n,i){let s={inverse:null,undo:[],resurrect:null},a=this.#Me(e,n,s),o=Boolean(r||i),c=(h)=>{if(!o||!h)return;let p=this.#e();if(s.inverse=h.optimistic(this,p,r,n),s.undo.push(...h.busy(this,p,i,n)),this.#D())s.resurrect=h.resurrection(this,p,r,n)},u=g.get("hints");if(!o||u)c(u);let d=()=>this.#Te(e,t,s,a),f=()=>this.#n?this.#n.then(d):d();return this.queue=(this.queue??Promise.resolve()).then(()=>o&&!u?this.#be().then(c).then(f):f()),this.queue}#be(){return this.#K("hints")}#ye(e,t,r,n,i,s){this.#V(e,Hr,t,()=>this.#F(r,n,i,e,s))}#V(e,t,r,n){this.#C(e,t);let i=()=>{this.#C(e,t),n()},s=setTimeout(i,r);if(!Oe(e))e?.addEventListener?.("blur",i,{once:!0});let a=this.#d.get(e);if(!a)this.#d.set(e,a=new Map);a.set(t,{timer:s,flush:i})}#C(e,t){let r=this.#d.get(e),n=r?.get(t);if(!n)return;if(clearTimeout(n.timer),e?.removeEventListener?.("blur",n.flush),r.delete(t),r.size===0)this.#d.delete(e)}#ve(){for(let[e,t]of[...this.#d])for(let r of[...t.keys()])this.#C(e,r)}#we(e,t,r,n,i,s){return this.#G(e,r,t,()=>this.#F(r,n,i,e,s))}#G(e,t,r,n){let i=this.#f.get(e)??new Map;if(i.has(t))return;let s=setTimeout(()=>{if(i.delete(t),i.size===0)this.#f.delete(e)},r);return i.set(t,s),this.#f.set(e,i),n()}#_e(){for(let e of this.#f.values())for(let t of e.values())clearTimeout(t);this.#f.clear()}#o(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}#s(e,t,r,n){let i=()=>{if(!this.element.isConnected){console.warn("[phlex-reactive] retry() ignored — the reactive root left the DOM");return}return this.#F(e,t)};this.#o("reactive:error",{action:e,params:r,...n,retry:i})}#i(e){if(this.element?.isConnected===!1)return;this.element?.setAttribute?.("data-reactive-error",e)}#Ae(){this.element?.removeAttribute?.("data-reactive-error")}#Se(){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))}#Ee(){{let e=g.get("devtools");if(e)return e.delay();if(mt())return P("devtools").then((t)=>t.delay(),()=>{})}}#D(){return this.element?.getAttribute?.("data-reactive-debug")==="true"}#Y(){return typeof performance<"u"&&typeof performance.now==="function"?performance.now():Date.now()}async#Te(e,t,r,n){let{fields:i,files:s}=this.#ee(),a=this.#te(t),o={...i,...a},c=this.#a,u=s.length>0,d=u?this.#Ne(c,e,o,s):JSON.stringify({token:c,act:e,params:o}),f=this.#D()?{action:e,paramNames:Object.keys(a),fieldNames:Object.keys(i),encoding:u?"multipart":"json",status:null,streams:[],tokenRefreshed:!1,started:this.#Y()}:null;await this.#Ee();try{if(navigator.onLine===!1){this.#u(r.inverse),this.#i("offline"),this.#s(e,t,o,{kind:"offline"});return}let h;try{let m={Accept:"text/vnd.turbo-stream.html","X-CSRF-Token":this.#We()};if(!u)m["Content-Type"]="application/json";let S=this.#Be();if(S)m["X-Pgbus-Connection"]=S;let D=xt(this.element)&&document.getElementById(`reactive-presence-src-${this.element.id}`)?.getAttribute("connection-id");if(D)m["X-Reactive-Presence"]=D;let Pe=Xt(this.element);if(Pe)m["X-Reactive-Held"]=Pe;wt("action"),h=await fetch(this.#$e(),{method:"POST",headers:m,body:d,credentials:"same-origin",signal:AbortSignal.timeout(this.#qe())})}catch(m){if(console.error("[phlex-reactive] action error",m),this.#u(r.inverse),m?.name==="TimeoutError"||m?.name==="AbortError"){this.#i("timeout"),this.#s(e,t,o,{kind:"timeout"});return}this.#Se(),this.#i("network"),this.#s(e,t,o,{kind:"network"});return}if(f)f.status=h.status;if(h.redirected){console.error("[phlex-reactive] action was redirected (auth/CSRF?) — no update applied"),this.#u(r.inverse),this.#i("redirected"),this.#s(e,t,o,{kind:"redirected",status:h.status});return}if(!h.ok){let m=await h.text();if(console.error(`[phlex-reactive] action failed: HTTP ${h.status}`,m),this.#u(r.inverse),(h.headers.get("Content-Type")||"").includes("turbo-stream")){let S=this.#X(m);if(this.#a=S??this.#a,f)this.#_((D)=>D.recordBody(f,m,S));je(this.element,m,!0)}this.#i("http"),this.#s(e,t,o,{kind:"http",status:h.status,body:m});return}let p=h.headers.get("Content-Type")||"";if(!p.includes("turbo-stream")){console.error(`[phlex-reactive] expected a turbo-stream, got "${p}" — no update applied`),this.#u(r.inverse),this.#i("content-type"),this.#s(e,t,o,{kind:"content-type",status:h.status});return}let b=await h.text(),E=this.#X(b);if(this.#a=E??this.#a,f)this.#_((m)=>m.recordBody(f,b,E));if(je(this.element,b,Qt(h)),r.resurrect)queueMicrotask(r.resurrect);return this.#Ae(),this.#o("reactive:applied",{action:e,params:o,html:b}),b}catch(h){console.error("[phlex-reactive] action error",h),this.#u(r.inverse),this.#o("reactive:error",{action:e,params:o,kind:"apply"})}finally{if(n?.(),f)this.#_((h)=>h.trace(this,{...f,ms:this.#Y()-f.started}))}}get#a(){return this.#A??this.tokenValue}set#a(e){this.#A=e}tokenValueChanged(){this.#A=void 0}#X(e){let t=this.element.id;if(!t)return e.match(/data-reactive-token-value="([^"]+)"/)?.[1];let{token:r,self:n}=this.#Fe(t),i=e.match(r);if(i)return i[1];let s=e.match(n);if(s)return s[1].match(/data-reactive-token-value="([^"]+)"/)?.[1];return}#Fe(e){let t=this.#B;if(t&&t.id===e)return t;let r=ir(e);return this.#B={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>`)}}#c(e){return e.closest('[data-controller~="reactive"]')===this.element}#Q(){if(this.element.querySelectorAll('[data-controller~="reactive"]').length===0)return()=>!0;return(t)=>this.#c(t)}#ke(){let e=this.element.querySelectorAll(F);if(e.length===0||[...e].every(ye))return()=>!0;return(t)=>{let r=R(t,F,this.element);if(r===this.element)return!0;return t.getAttribute("data-reactive-shared-field")!=null&&R(r.parentElement,F,this.element)===this.element}}#Z(e){if(this.#c(e))return!0;if(e.getAttribute?.("data-reactive-shared-field")==null)return!1;let t=R(e,F,this.element);return t===this.element||R(t?.parentElement,F,this.element)===this.element}#xe(){if(this.element.querySelectorAll(F).length===0)return()=>!0;return(e)=>this.#Z(e)}#ee(){let e={},t=[],r=this.#ke(),n=[];this.element.querySelectorAll("input[name], select[name], textarea[name]").forEach((o)=>{if(!r(o))return;if(o.type==="file")for(let c of o.files??[])t.push({name:o.name,file:c,multiple:o.multiple});else n.push(o)});let i=[];this.element.querySelectorAll(`[name]${ur}`).forEach((o)=>{if(r(o))i.push(o)});let s=this.#Le(n),a=this.#Re(n);for(let o of n)if(s.has(o.name)){let c=e[o.name]??(e[o.name]=[]);if(o.type==="checkbox"||o.type==="radio"){if(o.checked)c.push(o.value)}else if(o.type==="hidden"){if(!a.has(o.name))c.push(o.value)}else if(o.multiple&&o.options){for(let u of o.options)if(u.selected)c.push(u.value)}else c.push(o.value)}else if(o.type==="checkbox")e[o.name]=o.checked;else if(o.type==="radio"){if(o.checked)e[o.name]=o.value}else e[o.name]=o.value;return i.forEach((o)=>{let c=o.getAttribute("name");if(!c)return;let u=o.getAttribute("data-reactive-editable")!=null?T(o):o.value??o.textContent??o.innerHTML??"",d=e[c];if(String(c).endsWith("[]")&&!dr(o))return;if(String(c).endsWith("[]")&&(d===void 0||Array.isArray(d))){(Array.isArray(d)?d:e[c]=[]).push(u);return}if(d==null||d==="")e[c]=u}),{fields:e,files:t}}#Le(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}#Re(e){let t=new Set;for(let r of e)if(r.type==="checkbox")t.add(r.name);return t}#Ne(e,t,r,n){let i=new FormData;i.append("token",e),i.append("act",t);let s=[];for(let[o,c]of Object.entries(r))if(Array.isArray(c)&&String(o).endsWith("[]"))if(c.length===0)s.push(String(o).slice(0,-2));else{let u=`${this.#k(o)}[]`;for(let d of c)i.append(u,String(d))}else this.#$(i,this.#k(o),c);for(let o of s)i.append("empty_groups[]",o);let a=this.#Oe(n);for(let{name:o,file:c,multiple:u}of n){let f=u||a.has(o)?`${this.#k(o)}[]`:this.#k(o);i.append(f,c,c.name)}return i}#k(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((i)=>`[${i}]`).join("")}`}#$(e,t,r){if(r==null)e.append(t,"");else if(Array.isArray(r))r.forEach((n,i)=>this.#$(e,`${t}[${i}]`,n));else if(typeof r==="object")for(let[n,i]of Object.entries(r))this.#$(e,`${t}[${n}]`,i);else e.append(t,String(r))}#Oe(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))}#te(e){if(!e)return{};try{return typeof e==="string"?JSON.parse(e):e}catch{return{}}}#Pe(e){return Le(e)}#Ie(e,t){be(e,(r)=>this.#W(r,t),(r,n)=>this.#q(`client op "${r}"`,n))}#x(){return this.element?.getAttribute?.("data-reactive-verbose")==="true"||this.#D()}#q(e,t){if(!this.#x())return;this.#_((r)=>r.diagnose(this,e,t))}#_(e){v("devtools",e)}#W(e,t){let r=e.to;if(r==="@root")return[this.element];if(r==="@trigger")return t?.nodeType===1?[t]:[];if(typeof r!=="string"||r==="")return[];if(e.global)return[...document.querySelectorAll(r)];return[...this.element.querySelectorAll(r)].filter((n)=>this.#c(n))}#re(e,t){if(e?.checked!=="keep")return!1;let r=t?.type;return r==="checkbox"||r==="radio"}#u(e){if(!e)return;if(!this.element.isConnected)return;for(let t of e)t()}#Me(e,t,r){this.#Ce(e,t),gt();let n=!1;return()=>{if(n)return;n=!0,this.#De(e,t),bt();for(let i of r.undo)i()}}#Ce(e,t){if(this.#l(t,e,1),this.#l(this.element,e,1),this.#h.set(e,(this.#h.get(e)??0)+1),this.#R++===0)this.element.setAttribute("aria-busy","true");for(let r of this.#ne(e))this.#l(r,e,1)}#De(e,t){this.#l(t,e,-1),this.#l(this.element,e,-1);let r=(this.#h.get(e)??1)-1;if(r<=0)this.#h.delete(e);else this.#h.set(e,r);if(--this.#R<=0)this.#R=0,this.element.removeAttribute("aria-busy");for(let n of this.#ne(e))this.#l(n,e,-1)}#l(e,t,r){if(!e||typeof e.getAttribute!=="function")return;let n=this.#N.get(e)??new Map,i=(n.get(t)??0)+r;if(i<=0)n.delete(t);else n.set(t,i);if(n.size===0){this.#N.delete(e),e.removeAttribute("data-reactive-busy");return}this.#N.set(e,n),e.setAttribute("data-reactive-busy",[...n.keys()].join(" "))}#ne(e){return[...this.element.querySelectorAll?.("[data-reactive-busy-on]")??[]].filter((r)=>r.getAttribute("data-reactive-busy-on")===e&&this.#c(r))}#$e(){return this.#ie??=document.querySelector('meta[name="phlex-reactive-action-path"]')?.content||"/reactive/actions"}#qe(){if(this.#L!=null)return this.#L;let e=document.querySelector('meta[name="phlex-reactive-timeout"]')?.content,t=Number(e);return this.#L=Number.isFinite(t)&&t>0?t:30000}#We(){return document.querySelector('meta[name="csrf-token"]')?.content??""}#Be(){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)ze();else document.addEventListener("turbo:load",ze,{once:!0});y("persist",()=>import("phlex/reactive/features/persist"),Zr);y("defer",()=>import("phlex/reactive/features/defer"));y("form",()=>import("phlex/reactive/features/form"));y("bindings",()=>import("phlex/reactive/features/bindings"));y("compute",()=>import("phlex/reactive/features/compute"),en);y("sortable",()=>import("phlex/reactive/features/sortable"));y("drag",()=>import("phlex/reactive/features/drag"));y("presence",()=>import("phlex/reactive/features/presence"));y("countdown",()=>import("phlex/reactive/features/countdown"));y("effects",()=>import("phlex/reactive/features/effects"));y("hints",()=>import("phlex/reactive/features/hints"));y("devtools",()=>import("phlex/reactive/features/devtools"));Fe();function Zr(e,t){let r=()=>{t.edited=!0},n=(s)=>{let a=s.target;if(s.detail?.success&&a?.tagName==="FORM"&&a.contains?.(e))t.submitted=!0},i=["input","change","lexxy:change","trix-change"];for(let s of i)e.addEventListener?.(s,r);return document.addEventListener("turbo:submit-end",n),()=>{for(let s of i)e.removeEventListener?.(s,r);document.removeEventListener("turbo:submit-end",n)}}function en(e,t){let r=()=>{t.edited=!0};return e.addEventListener?.("input",r),e.addEventListener?.("change",r),()=>{e.removeEventListener?.("input",r),e.removeEventListener?.("change",r)}}var tn=1000,L=null,Pt,ie=new Set;function rn(e){return Nt(e).then((t)=>{if(e!=="effects")return;Pt=t,t?.sweep()})}dt((e,t)=>{let r=e.detail,n=r?.render;if(typeof n!=="function")return;let i=r.newStream??e.target,s=Rt(nn(i)).filter((o)=>!ie.has(o));if(!t&&!ie.has("effects")&&on(i))s.push("effects");if(s.length===0&&!L)return t?.wrap(e);if(s.length>0){for(let c of s)ie.add(c);let o=L=Promise.race([Promise.all([L,...s.map(rn)]),new Promise((c)=>setTimeout(c,tn))]).then(()=>{if(L!==o)return;L=null,ie.clear()})}let a=L;r.render=async(o)=>{await a;let c={target:e.target,detail:{newStream:r.newStream,render:n}};(t??Pt)?.wrap(c),await c.detail.render(o)}});function nn(e){let t=e?.querySelector?.("template")?.content;if(!t)return[];let r=[...t.querySelectorAll?.('[data-controller~="reactive"]')??[]];for(let n of t.children??[])if(n.matches?.('[data-controller~="reactive"]')&&!r.includes(n))r.unshift(n);return r.push(t),r}function on(e){return Boolean(e?.hasAttribute?.("data-reactive-effect")||document.getElementById?.(e?.getAttribute?.("target"))?.matches?.("[data-reactive-effect-update],[data-reactive-effect-exit]")||e?.querySelector?.("template")?.content?.querySelector?.("[data-reactive-effect-enter],[data-reactive-dismiss-after]")||document.querySelector?.("[data-reactive-dismiss-after]:not([data-reactive-dismiss-scheduled])"))}var yn=Ot;export{pt as ACTIVE_ATTR,ur as EDITOR_SELECTOR,lr as EDITOR_TAGS,vt as REQUESTS_ATTR,or as checkReactiveRegistration,wt as countReactiveRequest,yn as default,T as editableValue,gt as enterReactiveActivity,ir as escapeRegExp,bt as exitReactiveActivity,Nt as loadReactiveFeature,dt as onReactiveStreamWithoutEffects,un as reactiveActivityCount,fn as reactiveFeatureNames,ze as registerReactiveActions,qt as registerReactiveDefer,Fe as registerReactiveDev,Wt as registerReactiveDismiss,Wt as registerReactiveEffects,dn as registerReactiveFeature,y as registerReactiveFeatureLoader,Ht as registerReactiveImageFallback,$t as registerReactiveJs,zt as registerReactiveKeep,Ut as registerReactiveModals,Vt as registerReactiveMorphFocus,er as registerReactiveOffline,Kt as registerReactivePlaintext,gr as registerReactiveRejectedFiles,Wt as registerReactiveStreamRender,Ct as registerReactiveToken,Mt as registerReactiveVisit,ln as resetReactiveActivity,xe as serverText,Rt as unloadedFeaturesFor};
|
|
7
7
|
|
|
8
|
-
//# debugId=
|
|
8
|
+
//# debugId=461386F5E173C8F964756E2164756E21
|
|
9
9
|
//# sourceMappingURL=core.min.js.map
|