@kaeawc/auto-mobile 0.0.92 → 0.0.94
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.
- package/dist/build-info.json +12 -12
- package/dist/schemas/test-plan.schema.json +370 -52
- package/dist/src/ble-peripheral.py +153 -0
- package/dist/src/{chunk-r14wwk37.js → chunk-026y62r9.js} +12 -12
- package/dist/src/chunk-0jyfg947.js +4 -0
- package/dist/src/{chunk-950qcq1e.js → chunk-0zfpp1wh.js} +4 -4
- package/dist/src/chunk-13qxf7ym.js +7 -0
- package/dist/src/chunk-1scenrk7.js +4 -0
- package/dist/src/chunk-1vb5ph1k.js +4 -0
- package/dist/src/chunk-20g565q7.js +5 -0
- package/dist/src/chunk-21h6dhdm.js +5 -0
- package/dist/src/{chunk-2e6s75qv.js → chunk-25mfpthk.js} +8 -8
- package/dist/src/{chunk-9rkfyt6q.js → chunk-2b39zyxc.js} +3 -3
- package/dist/src/chunk-2gzd6wbd.js +4 -0
- package/dist/src/{chunk-eka89q3k.js → chunk-3dntffy9.js} +1 -1
- package/dist/src/chunk-3gfczcsn.js +4 -0
- package/dist/src/chunk-3h5jz1vb.js +9 -0
- package/dist/src/chunk-41zcy6b3.js +5 -0
- package/dist/src/chunk-47n9m2de.js +4 -0
- package/dist/src/chunk-4vxeq0vd.js +58 -0
- package/dist/src/chunk-59dx6qaf.js +4 -0
- package/dist/src/chunk-5sdf9y92.js +4 -0
- package/dist/src/chunk-5wk1t46v.js +5 -0
- package/dist/src/chunk-661c50hh.js +17 -0
- package/dist/src/chunk-68n6bjjd.js +21 -0
- package/dist/src/{chunk-zg67wjkh.js → chunk-69pmjdf2.js} +3 -3
- package/dist/src/chunk-6hrj3jt6.js +145 -0
- package/dist/src/{chunk-b4cxdzwy.js → chunk-6myr26wx.js} +8 -8
- package/dist/src/chunk-6n96k09n.js +4 -0
- package/dist/src/chunk-6vwrbkre.js +4 -0
- package/dist/src/chunk-6wk0yrab.js +4 -0
- package/dist/src/chunk-6yhm9een.js +4 -0
- package/dist/src/chunk-7k7gjg2t.js +7 -0
- package/dist/src/chunk-7n5fz68h.js +4 -0
- package/dist/src/chunk-8cvnpnbp.js +4 -0
- package/dist/src/chunk-8kzv7rk7.js +4 -0
- package/dist/src/chunk-8nj68t1v.js +167 -0
- package/dist/src/{chunk-r20pe1nv.js → chunk-96r3bpg7.js} +3 -3
- package/dist/src/chunk-97x887te.js +4 -0
- package/dist/src/{chunk-sz1a7p43.js → chunk-99a6tbvd.js} +1 -1
- package/dist/src/chunk-9p5d2994.js +5 -0
- package/dist/src/{chunk-w7zsh13a.js → chunk-9q265er0.js} +4 -4
- package/dist/src/chunk-9xgnrv5w.js +5 -0
- package/dist/src/chunk-9xgsmshb.js +5 -0
- package/dist/src/chunk-a02d1wgv.js +4 -0
- package/dist/src/{chunk-km0dy5vc.js → chunk-a9ps00a1.js} +10 -10
- package/dist/src/chunk-aewdveet.js +5 -0
- package/dist/src/chunk-b3tdtq7r.js +9 -0
- package/dist/src/chunk-bn7jx7a2.js +4 -0
- package/dist/src/chunk-bnyw27ja.js +4 -0
- package/dist/src/{chunk-s1zq65ny.js → chunk-bpwsg76p.js} +2 -2
- package/dist/src/chunk-bvranw3g.js +4 -0
- package/dist/src/chunk-c25a84zb.js +4 -0
- package/dist/src/chunk-c27yv1dx.js +5 -0
- package/dist/src/chunk-c3ewxm4x.js +5 -0
- package/dist/src/chunk-cb1ga9rd.js +7 -0
- package/dist/src/chunk-cn7fwy7k.js +4 -0
- package/dist/src/chunk-cnvy4a64.js +4 -0
- package/dist/src/chunk-cqhw4yr6.js +5 -0
- package/dist/src/{chunk-v90es00d.js → chunk-ctmfshjc.js} +2 -2
- package/dist/src/chunk-ctwmhz13.js +4 -0
- package/dist/src/{chunk-qv2918jt.js → chunk-d3jx9bz5.js} +2 -2
- package/dist/src/{chunk-wry6skrm.js → chunk-d6rb08ga.js} +1 -1
- package/dist/src/chunk-ddqhj4eg.js +5 -0
- package/dist/src/{chunk-d57432wq.js → chunk-ddrhs1c3.js} +2 -2
- package/dist/src/chunk-dnjnh9p6.js +4 -0
- package/dist/src/{chunk-ajsrz473.js → chunk-dw5rwgya.js} +3 -3
- package/dist/src/chunk-e0870khr.js +5 -0
- package/dist/src/chunk-ea3k10kj.js +4 -0
- package/dist/src/chunk-emv82m1w.js +7 -0
- package/dist/src/chunk-f3m6pdnx.js +4 -0
- package/dist/src/chunk-f84z32cb.js +4 -0
- package/dist/src/chunk-fpczgf0z.js +4 -0
- package/dist/src/chunk-g2js4c2v.js +971 -0
- package/dist/src/chunk-g3af2qbk.js +5 -0
- package/dist/src/chunk-gadtna7s.js +11 -0
- package/dist/src/{chunk-c9nk1r78.js → chunk-gcyx407v.js} +3 -3
- package/dist/src/{chunk-jdqvcq0a.js → chunk-gfpntwc1.js} +3 -3
- package/dist/src/chunk-gmnm5e3e.js +4 -0
- package/dist/src/chunk-gp6vb5gf.js +4 -0
- package/dist/src/chunk-gppgy7pa.js +4 -0
- package/dist/src/chunk-hegfz0ae.js +5 -0
- package/dist/src/chunk-hpzxdp1k.js +17 -0
- package/dist/src/{chunk-2v7tw1nj.js → chunk-j69g8b50.js} +3 -3
- package/dist/src/chunk-jvstjnqm.js +19 -0
- package/dist/src/chunk-jzqrv78s.js +4 -0
- package/dist/src/chunk-k2948b8d.js +4 -0
- package/dist/src/chunk-k4ftd40d.js +4 -0
- package/dist/src/chunk-kd9vfaxh.js +5 -0
- package/dist/src/{chunk-34zxqcmq.js → chunk-kdczmgwk.js} +3 -3
- package/dist/src/chunk-ke3wn14v.js +4 -0
- package/dist/src/chunk-kh5n7m6w.js +4 -0
- package/dist/src/{chunk-0dfnyfkh.js → chunk-khejfph4.js} +3 -3
- package/dist/src/chunk-kny2xemh.js +4 -0
- package/dist/src/chunk-knyzw9md.js +4 -0
- package/dist/src/chunk-mbzpt2hp.js +4 -0
- package/dist/src/chunk-mm8rcxad.js +4 -0
- package/dist/src/chunk-nc4516tx.js +4 -0
- package/dist/src/{chunk-stfzjr9y.js → chunk-ntfrqrqn.js} +5 -5
- package/dist/src/chunk-nz5h2j52.js +4 -0
- package/dist/src/chunk-p22s97qy.js +4 -0
- package/dist/src/chunk-p9kt1sgr.js +6 -0
- package/dist/src/{chunk-9y5bcy28.js → chunk-pf282r5g.js} +4 -4
- package/dist/src/chunk-pnd4mrxy.js +4 -0
- package/dist/src/chunk-pqqteyj6.js +4 -0
- package/dist/src/chunk-qj1tbnv2.js +8 -0
- package/dist/src/chunk-qnh9egwr.js +4 -0
- package/dist/src/chunk-qy3khhf8.js +8 -0
- package/dist/src/chunk-r0vp315h.js +11 -0
- package/dist/src/chunk-r4j43b9s.js +237 -0
- package/dist/src/{chunk-4pfftt07.js → chunk-r54cxxze.js} +3 -3
- package/dist/src/chunk-r6pvhj33.js +325 -0
- package/dist/src/chunk-rb7aa5gr.js +54 -0
- package/dist/src/chunk-rdj50kb4.js +4 -0
- package/dist/src/chunk-rnd4vcas.js +4 -0
- package/dist/src/chunk-s3y3zfcx.js +14 -0
- package/dist/src/chunk-s4g43k75.js +5 -0
- package/dist/src/chunk-sfqe223f.js +311 -0
- package/dist/src/chunk-sqdrxjw5.js +7 -0
- package/dist/src/{chunk-0w1spptt.js → chunk-t54k47em.js} +4 -4
- package/dist/src/chunk-tek4pnvv.js +26 -0
- package/dist/src/chunk-tn74y7af.js +4 -0
- package/dist/src/chunk-tvq0nzam.js +5 -0
- package/dist/src/chunk-tx4f0h9c.js +6 -0
- package/dist/src/chunk-vdqag3fj.js +5 -0
- package/dist/src/chunk-vz5zzs57.js +4 -0
- package/dist/src/chunk-w4s2vfpj.js +4 -0
- package/dist/src/chunk-w5yypt53.js +42 -0
- package/dist/src/{chunk-r0f1q783.js → chunk-w68v64vh.js} +3 -3
- package/dist/src/chunk-whwj0pdk.js +5 -0
- package/dist/src/chunk-wnmqt1dc.js +4 -0
- package/dist/src/{chunk-8en08r7q.js → chunk-wpe46vsa.js} +3 -3
- package/dist/src/chunk-wxdjeb4k.js +27 -0
- package/dist/src/chunk-xcqzwf9j.js +247 -0
- package/dist/src/chunk-xezekwwn.js +5 -0
- package/dist/src/chunk-xf19m15s.js +4 -0
- package/dist/src/chunk-xghbxha4.js +4 -0
- package/dist/src/{chunk-jhnbfj19.js → chunk-xn9m3xc2.js} +5 -5
- package/dist/src/{chunk-a4k9rt7z.js → chunk-yqfz4vts.js} +3 -3
- package/dist/src/chunk-z8tvs8nk.js +5 -0
- package/dist/src/chunk-zm2rehqb.js +5 -0
- package/dist/src/chunk-zs6dqm35.js +4 -0
- package/dist/src/daemon/processEntry.js +2 -2
- package/dist/src/index.js +4 -4
- package/dist/src/runtime/bunRuntimeGuard.js +2 -2
- package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -2
- package/ios/CameraPosterInjection/Injection/CameraPosterInjection.m +466 -0
- package/package.json +4 -3
- package/schemas/test-plan.schema.json +370 -52
- package/dist/src/chunk-09442h7v.js +0 -4
- package/dist/src/chunk-0e4gm1kj.js +0 -5
- package/dist/src/chunk-0eb8576f.js +0 -4
- package/dist/src/chunk-0rjm4nx7.js +0 -5
- package/dist/src/chunk-1zmh2eak.js +0 -4
- package/dist/src/chunk-28k63ha3.js +0 -5
- package/dist/src/chunk-2d4wmp8b.js +0 -4
- package/dist/src/chunk-32jpxz2y.js +0 -323
- package/dist/src/chunk-3jmvqygr.js +0 -238
- package/dist/src/chunk-3swvfhqt.js +0 -5
- package/dist/src/chunk-44bt78m9.js +0 -5
- package/dist/src/chunk-488vt2bp.js +0 -4
- package/dist/src/chunk-4fgdhcwx.js +0 -5
- package/dist/src/chunk-4jp2se4w.js +0 -4
- package/dist/src/chunk-4vhr9e4t.js +0 -4
- package/dist/src/chunk-4xd6zs3y.js +0 -15
- package/dist/src/chunk-51567pg8.js +0 -4
- package/dist/src/chunk-5agqsfev.js +0 -4
- package/dist/src/chunk-5d706gmr.js +0 -4
- package/dist/src/chunk-5kd4rqk7.js +0 -5
- package/dist/src/chunk-61t538bm.js +0 -4
- package/dist/src/chunk-6d3mmqxt.js +0 -54
- package/dist/src/chunk-6hyt398x.js +0 -5
- package/dist/src/chunk-6mnr8kpm.js +0 -4
- package/dist/src/chunk-79q5xsdc.js +0 -42
- package/dist/src/chunk-7bdgand3.js +0 -4
- package/dist/src/chunk-84cp9dw5.js +0 -4
- package/dist/src/chunk-86f2h5ww.js +0 -5
- package/dist/src/chunk-8cghfzb2.js +0 -19
- package/dist/src/chunk-9tf2p9y9.js +0 -5
- package/dist/src/chunk-a2sc4jm0.js +0 -5
- package/dist/src/chunk-aa5ng3d1.js +0 -4
- package/dist/src/chunk-b3h0a6ca.js +0 -4
- package/dist/src/chunk-b6a737qt.js +0 -4
- package/dist/src/chunk-bn64x5z5.js +0 -5
- package/dist/src/chunk-bvh649za.js +0 -12
- package/dist/src/chunk-c9tyfg4j.js +0 -26
- package/dist/src/chunk-cfsdfqnm.js +0 -4
- package/dist/src/chunk-cxyf04jc.js +0 -7
- package/dist/src/chunk-da08tx5v.js +0 -4
- package/dist/src/chunk-f2tc08m2.js +0 -4
- package/dist/src/chunk-f8tnk179.js +0 -5
- package/dist/src/chunk-f9s1kkhx.js +0 -5
- package/dist/src/chunk-fbp8a4rx.js +0 -4
- package/dist/src/chunk-fd2z0sze.js +0 -4
- package/dist/src/chunk-fk927f4q.js +0 -54
- package/dist/src/chunk-fxmr3a0f.js +0 -4
- package/dist/src/chunk-gaqwhd44.js +0 -4
- package/dist/src/chunk-ggtd5x5a.js +0 -5
- package/dist/src/chunk-gndcfrm7.js +0 -4
- package/dist/src/chunk-h3n4adc6.js +0 -310
- package/dist/src/chunk-h5pjbb83.js +0 -4
- package/dist/src/chunk-hgnnh302.js +0 -4
- package/dist/src/chunk-hmke8nhx.js +0 -5
- package/dist/src/chunk-j2bx12hn.js +0 -4
- package/dist/src/chunk-j70y1a2g.js +0 -4
- package/dist/src/chunk-js1jpyxp.js +0 -6
- package/dist/src/chunk-kbjq0qvb.js +0 -4
- package/dist/src/chunk-kfwx57xd.js +0 -4
- package/dist/src/chunk-kzwctna2.js +0 -4
- package/dist/src/chunk-m9ehyehy.js +0 -4
- package/dist/src/chunk-mct91p1f.js +0 -4
- package/dist/src/chunk-mf9spd4g.js +0 -5
- package/dist/src/chunk-mgrcansb.js +0 -4
- package/dist/src/chunk-mqc1d0eb.js +0 -6
- package/dist/src/chunk-n1zmpk0z.js +0 -4
- package/dist/src/chunk-ncyjf63g.js +0 -4
- package/dist/src/chunk-nr64d21q.js +0 -973
- package/dist/src/chunk-nwm2pq5v.js +0 -168
- package/dist/src/chunk-pm06b05d.js +0 -9
- package/dist/src/chunk-q50s00ry.js +0 -4
- package/dist/src/chunk-qwye1958.js +0 -14
- package/dist/src/chunk-r8z9pfve.js +0 -5
- package/dist/src/chunk-rdpgkjf6.js +0 -4
- package/dist/src/chunk-rkr0dks9.js +0 -5
- package/dist/src/chunk-rn84t3sf.js +0 -11
- package/dist/src/chunk-s123kn7n.js +0 -4
- package/dist/src/chunk-s73qn3fx.js +0 -4
- package/dist/src/chunk-sjn0nj4p.js +0 -5
- package/dist/src/chunk-sns0c35v.js +0 -7
- package/dist/src/chunk-t4dr5c8v.js +0 -8
- package/dist/src/chunk-tc8k9c1j.js +0 -4
- package/dist/src/chunk-teznhase.js +0 -4
- package/dist/src/chunk-ty9xgmz4.js +0 -4
- package/dist/src/chunk-tyazf3sk.js +0 -145
- package/dist/src/chunk-v6npjrjm.js +0 -5
- package/dist/src/chunk-vbvtzkwz.js +0 -5
- package/dist/src/chunk-vefd8qee.js +0 -8
- package/dist/src/chunk-vs9r72ta.js +0 -17
- package/dist/src/chunk-w2mwa0jk.js +0 -4
- package/dist/src/chunk-w88k0bgr.js +0 -4
- package/dist/src/chunk-wzdt0enk.js +0 -4
- package/dist/src/chunk-xhhv854c.js +0 -4
- package/dist/src/chunk-y58270hd.js +0 -4
- package/dist/src/chunk-yk0hmbex.js +0 -4
- package/dist/src/chunk-ympy4fdz.js +0 -28
- package/dist/src/chunk-yw436axy.js +0 -4
- package/dist/src/chunk-z04jrpjy.js +0 -5
- package/dist/src/chunk-z2xznczw.js +0 -4
- package/dist/src/chunk-z4xnrgps.js +0 -4
- package/dist/src/chunk-z7csyszv.js +0 -4
- package/dist/src/chunk-z8t0v07j.js +0 -11
- package/dist/src/chunk-z916af47.js +0 -228
- package/dist/src/chunk-zcr8he8q.js +0 -5
- package/dist/src/chunk-zd9vmkzn.js +0 -9
- package/dist/src/chunk-zj939v0h.js +0 -5
- package/dist/src/chunk-zkdjwtc1.js +0 -4
- package/dist/src/chunk-zkv5kzt6.js +0 -4
|
@@ -1,973 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
import{gu,Zre,V,c,mp,ld,JB,cr,or,X,Ok,Mk,HD,ws,Ig,Pt,Xm,vY,Fk,xg,Wj,yu,vie,a$,ua,Kie,jD}from"./chunk-79q5xsdc.js";import{e}from"./chunk-z8t0v07j.js";import"./chunk-mf9spd4g.js";import{gq,J6,X6}from"./chunk-86f2h5ww.js";import{Qe,Im,VC,bk}from"./chunk-h3n4adc6.js";import{df,Fg,K2,lf,Y$,sE,Tp,oK,Bg,Sb,wb,$g,dE,lE}from"./chunk-z916af47.js";import{Hx,tF,FA}from"./chunk-w7zsh13a.js";import{r,t}from"./chunk-9rkfyt6q.js";import{Lt}from"./chunk-2v7tw1nj.js";var Xo='## Destinations of device requests\n\nA `request` action with `via: "device"` is checked on the device before it connects. It is refused\nwith `blocked_destination` when the URL names `localhost` (or a `*.localhost` name), or when the\ndestination resolves to a loopback, unspecified or link-local address. On Android this also covers\nthe emulator\'s addresses for the host machine (`10.0.2.2` and the other `10.0.2.x` aliases), and\nports 3000-3010 and 8765 on a private address are refused too. No `adb reverse` is made for a\nprototype, so a device request cannot reach a server on the host machine through `localhost`: use\n`via: "host"` for a host-local server, or call it by an address the device can reach that is not\nloopback. On iOS, call a Mac-local service by the Mac\'s LAN address.\n\n## Mock backends (no server code)\n\nBuild a backend-driven prototype without running a server. `defineBackend {backendId, backend}`\nregisters an in-process backend for this daemon session (`backendId` is lowercase letters, digits\nand hyphens); a `request` with `via: "host"` to `https://<backendId>.mock.automobile.invalid/<path>`\nis answered by it, with no network, DNS lookup or egress policy. The host must be connected, so it\ndoes not apply to `via: "device"` requests or saved prototypes. `backendLog {backendId, since?}` lists the requests it\nanswered and `clearBackend {backendId}` removes it; defining the same id again replaces it and resets\nits data. Requests to a backend that is not defined fail with `network`.\n\n```json\n{"action":"defineBackend","backendId":"shop","backend":{\n "collections":{"products":[{"id":1,"title":"Mug","price":12},{"id":2,"title":"Tote","price":20}]},\n "routes":[{"method":"GET","path":"/greeting/:name","body":{"text":"Hello {params.name}"}}],\n "latencyMs":{"min":200,"max":600},"faults":[{"path":"/products","method":"POST","status":500,"every":3}],\n "seed":7}}\n```\n\nA `show` can define backends itself: `mock` is `{backendId: definition}` (the same definition shape),\nor `mockPath` names an absolute local JSON file holding that object (up to 2 MiB; the path never\nreaches the device). They are defined, all or none, once the spec is accepted and before it is\nsent, replacing backends of the same id, and a saved prototype does not carry them.\n\n- **Collections** are REST over `{name: [items]}`; every item needs an `id` (a number, or a non-empty\n string other than `.` and `..`). `GET /products?title=Mug`, `q=mug` (case-insensitive substring over\n string and number members), `_sort=price` or `-price`, `_page` and `_limit` (an\n `x-total-count` header reports the total), or `after=<id>&size=<n>` for `{items, next}` cursor paging.\n `GET /products/1`, `POST` (201; the id is generated when absent, 409 if it exists), `PATCH` (merge),\n `PUT` (replace) and `DELETE`. Writes persist for the session; a backend holds at most 1 MiB.\n- **Routes** are canned responses that win over collections. Paths are literal segments and\n `:name` parameters. A body string that is exactly `{params.x}`, `{query.x}` or `{body:/pointer}`\n takes that value\'s type; inside longer text it is inserted as text; an unbound one is `null` or empty.\n- **Latency and faults** replay identically for the same `seed`: `latencyMs {min,max}` delays every\n answer, and a fault `{path, method?, status, every | rate}` fails every nth matching request or\n that fraction of them with `{error:"mock fault"}`.\n- **Actors** play the other side (at most 16, each up to 64 steps). An actor fires on a matching\n successful request (`on: {route: "POST /messages/:id"}`) or every N ms (`every` with `maxRuns`),\n after an optional `afterMs` lead, and runs `do` in order: `{append: collection, value}`,\n `{update: collection, id, value}` (merge), `{remove: collection, id}`, each with an optional\n `afterMs` after the previous step. `value` and `id` bind `{params.x}`, `{query.x}` and\n `{body:/pointer}` from the triggering request. A failed step is skipped and the run goes on;\n redefining or clearing the backend cancels pending steps. Poll the collection to see the result.\n `publish`, `advance` and `notify` steps are not supported yet.\n- A request\'s `timeoutMs` applies to the mock too, and a response over the 262144-byte cap fails\n with `too_large`.\n- **Rooms** serve realtime channels with `via: "host"`: a WebSocket to\n `wss://<backendId>.mock.automobile.invalid/rooms/general` or an SSE stream to the `https://` form\n joins the first room whose `path` (`/rooms/:roomId`) matches; no match is `handshake_failed`\n with status 404. A room `{path, onConnect?, echo?, relay?, timeline?}` sends its `onConnect` frames\n to each new connection, `timeline [{afterMs, frame}]` frames that long after each connection\n opened, returns a send to its sender with `echo`, and passes it to the room\'s other connections\n with `relay`. Frames bind `{params.x}` and `{query.x}` from the channel URL; a string frame is sent\n as written, other JSON as JSON text.\n- **Broadcasts** `{collection: {room, frame, on?}}` send a successful collection write (`POST` by\n default; `on` takes `POST`, `PUT`, `PATCH`) to a room. `{item}` and `{item:/pointer}` bind the\n stored item, so `{"messages":{"room":"/rooms/{item:/roomId}","frame":{"message":"{item}"}}}` makes a\n message one device posts appear on every device in that room.\n- `publish {backendId, room, frame}` speaks as the other side to every connection in `room` and\n returns `delivered`. `backendLog` lists room frames (`{room, from, data}`, `from` is `client`,\n `publish` or `broadcast`) beside requests. Redefining or clearing a backend closes its channels\n with code 1001.\n\n## Value formatters (#14227)\n\nUse top-level `derive: {priceText: {of: {data: "/price"}, format: {currency: {code: "USD"}}}}`\nand read `{derived:priceText}` in text node text, contentDescription, rich-text spans,\nbutton/FAB labels, topAppBar title, badge text, dialog title/text, and snackbar text.\nOther text-kind fields (request url/headers/body, check messages, and\nselect/segmented/menu/searchBar labels) validate unknown names but show tokens literally on devices.\nThere are at most 32 names (state-key syntax); unknown reads fail validation.\n`of` chooses exactly one data pointer, state key or literal `{value: number|string}`.\nInside a repeat, `repeat.derive` supports at most 8 names, with `of: {item: "field"}`\nor a literal value; the resulting strings bind as `{item.priceText}` using your alias.\nNames cannot collide with original row fields; derived fields cannot reference each other.\nHost validation checks field references; device-dependent key and emit-name value checks wait for the renderer.\n\n`format` has exactly one key with an object: `number {minFraction?,maxFraction?,grouping?}`,\n`compact {style?:short|long}`, `currency {code:USD}`, `percent {minFraction?,maxFraction?}`,\n`date {style?:short|medium|long}`, `time {style?:short|medium|long}`, or\n`relative {style?:narrow|short|long}`. Fraction digits are integers 0..20;\nmin cannot exceed max. Grouping true/default respects locale minimum grouping digits;\nfalse disables grouping entirely. Compact, currency, and percent respect locale minimum grouping digits.\nCompact defaults short, date medium,\ntime short, relative long. Currency codes are three uppercase letters and use CLDR minor units.\nNumber kinds require finite numbers; percent inputs are ratios (0.256 means 25.6%).\nDate/time/relative accept integer epoch milliseconds, YYYY-MM-DD (midnight UTC),\nor ISO date-times with seconds and Z or an explicit +hh:mm offset; fractional seconds work.\nInvalid or missing inputs display empty text. Optional entry `locale` (BCP 47, <=35 characters)\nand `timeZone` (IANA id, <=128) override device defaults.\n\nRelative time uses an injected clock snapshot, truncates toward zero, and picks the largest\nelapsed unit: seconds, minutes (60 s), hours (60 min), days (24 h), months (30 d), years (365 d).\nUnder one second uses localized now. Exact English fixtures normalize U+202F/U+00A0 to spaces;\nforeign currency symbols, narrow relative text, now wording and non-English CLDR data can vary\nby engine and use structural comparisons. Set locale, zone and clock for deterministic previews.\nBoth derive maps require `prototype_format_v1`; use literal strings with older renderers.\n`dateTime`, `duration`, `plural`, and `fileSize` are unsupported follow-ups.\n',Jo='### Timers\n\nTimer actions and `onAppear` require `prototype_timers_v1`.\nThe root and nodes declaring `visibleWhen` may set `onAppear` to 1..32 ordinary actions.\nThey run on first show if visible, and on each hidden-to-visible edge; visible-to-visible\nand a same-id show without reset do not run them again. Repeat placeholders bind as in onTap.\nEach list is atomic, validates like a tap, and emits change for a net state change, without\nrestarting idle TTL. A handler runs at most once per interaction, bounded by the action-depth limit.\nFor a splash, put `onAppear:[{type:"startTimer",id:"splash",afterMs:2000,\nactions:[{type:"setState",key:"loading",value:false}]}]` on the root and use\n`visibleWhen:{key:"loading",equals:false}` on content. Hiding a node does not cancel its timer.\nStart a timer from any action list:\n`{type:"startTimer",id:"tick",afterMs:100,everyMs:1000,maxRuns:10,actions:[{type:"emit",name:"tick"}]}`.\n`afterMs` is required; it and optional `everyMs` are integers 100..3600000 ms.\n`maxRuns` is 1..10000 total fires, including the first, and requires `everyMs`.\nWithout maxRuns, repeats continue until cancelled or dismissed. Actions contain 1..32 entries,\nwith the same validation and nesting limit as request follow-ups. IDs are literal strings of\n1..64 characters, never repeat-bound; at most eight distinct startTimer ids per spec.\n`{type:"cancelTimer",id:"tick"}` removes a timer; unknown ids are no-ops. The host warns\non show and patch if no startTimer declares the cancelled id; devices do not validate that advisory.\n\nStarting a live id replaces its schedule and resets runs. Each fire is one atomic interaction:\ninvalid planned writes drop the whole fire but count the run; a net state change emits one change.\nSelf-cancellation stops repeats, and a replacement started during a fire wins. Repeats schedule\nfrom planned fire time without drift. Timers pause while hidden or inactive, retaining remaining\ntime (screenshot capture does not pause); dismiss, teardown and any replacing show cancel them.\nPatch preserves them. Fires never restart idle TTL.\n\n`prototype {action:"simulate",id,advanceTimeMs:1000}` advances without waiting (integer\n1..3600000), requiring the same capability. It returns `fired`; paused timers fire zero times.\nDue timers run chronologically, ties by start order, including timers started during advancement.\nExactly 10000 due fires succeed. If another fire is still due, advance stops at the last fire with\nan error and fired=10000, keeping pending timers for the next call. Real scheduling continues from the shifted clock.\nInspect reports `timers:[{id,nextFireInMs,runs}]`, ordered by remaining time then start order;\nremaining time is nonnegative and frozen while paused. A capable device yields an empty array\nwhen no timers are live.\n',Zo='## Strings and semantics\n\nTop-level `strings` requires `prototype_strings_v1`: `{default: {title: "Cart", items: {one: "{#} item", other: "{#} items"}}, fr: {title: "Panier"}}`.\nUse `{t:title}` or `{t:items|2}` in display text, spans, semantics.label or semantics.hint.\nCounts are non-negative integer literals (1\u20139 digits) or `{data:/pointer}`; state-key counts are unsupported.\nPipeline: data substitution, then translation, then state binding. Translation values may contain state bindings; translated text is never scanned again for translations. `{#}` inserts the decimal count in a plural form. Invalid runtime counts use other.\nshow `locale` (locale tag, max 35 characters) overrides device preferred locales for that show; omitted follows device locales, which re-resolve live.\nEach requested locale tries its full tag then shorter prefixes, deduplicated, then default. Tags match case-insensitively with underscores normalized to hyphens. Lookup is per key; the supplying table language decides plurals (default uses the first requested language, else en).\nInteger plural groups: ja/zh/ko/vi/th/id/ms/lo/km/my use other; fr/pt/hi/bn/fa/gu/kn/am use one for 0\u20131; ru/uk/be and pl use one/few/many; cs/sk use one/few/other; ar uses zero/one/two/few/many/other; remaining languages use one at 1, other otherwise. Missing forms use other; million-multiple Romance many is outside v1.\nLimits: 16 tables, 512 keys per table, 2048 characters per nonempty value; default and every plural other form are required. Keys use letters/underscore followed by letters/digits/underscore/dot/hyphen, at most 64 characters. Values cannot contain translation, data or platform placeholders.\nWith an explicit locale, `platformNotes` construct `strings.fallback` (platform all) lists up to 20 referenced keys reaching default. Advisory lint reports missing-translation and unknown-translation-key.\nPseudo-localisation transforms each table value and plural form while preserving keys, tags, category names and bindings; strings is opaque to node walking. Node translation placeholders stay intact; semantics label and hint are display text.\n\nEvery node accepts `semantics {heading?,liveRegion?: "polite"|"assertive",group?,label?,hint?,traits?: ["button"|"image"|"selected"]}`, requiring `prototype_semantics_v1`. At least one field is required; traits are unique (1\u20133). Label/hint are nonempty and accept translations, data and state bindings. Label conflicts with contentDescription.\nHeading enables screen-reader navigation; empty-heading lint flags headings without text/label. Group contains child traversal. Android maps heading/liveRegion/traversal group, label to contentDescription, hint to onClickLabel for tap actions else stateDescription, and traits to Role.Button/Role.Image/selected. iOS maps header/button/image/selected traits, contain grouping, label/hint, and live-region change announcements (not initial render; assertive has high speech priority).\nAndroid observe exposes heading as the string "true" and live-region as polite/assertive; iOS snapshots currently expose no SwiftUI traits. Logical RTL swipe sides are outside this capability.\n',Qo='## User-testing sessions\n\nCall `prototype {action:"testSessionBegin", id, goal?, cohort?}` after showing a prototype.\nThe host records accepted events without consuming `awaitEvent`. A goal is a screen label\nsuch as `checkout/done`; reaching it marks completion. Cohort is a free label, with no\ncross-session aggregation. `testSessionEnd {id}` stops recording and returns JSON plus\nMarkdown. Dismissal or session release also ends recording. `testSessionReport {id}`\nreads the latest session for this scope, or pass `testSessionId` for a stored one.\nOnly one session may be active per device and prototype.\n\nReports include screen visits, time, abandonment, validation failures and pager changes.\nLabels use the deepest stack\'s top screen as `stack/screen` (ties use the lowest stack id),\nor `(root)`. Text values, payloads, context and state snapshots are never stored;\nnon-secure changes retain only keys, string lengths or value types and validity.\nSecure fields are excluded. Up to 5,000 sanitized events are retained per session; extra\nevents are counted as dropped and the report is marked truncated. The newest 50 ended\nsessions are kept per device/prototype.\n\nTo record dead taps, show with `window.deadTaps: true` on a device advertising\n`prototype_dead_tap_v1`; an older agent is refused. Dead taps are single-pointer taps\ninside the prototype window that no interactive node handled, excluding drags, scrolling\nand app taps outside the window. Their payload has only screen ids and coordinates,\nrounded to one decimal in window-local dp (points on iOS). Reports include counts,\nup to 200 points per screen and a 48-unit grid. There is no screenshot overlay yet.\n\nStack transition patterns: `sharedAxisX`, `sharedAxisY`, `fadeThrough` and `zoom` (and a push/replace\n`source`) require `prototype_stack_patterns_v1`; zoom needs a source naming exactly one shared key inside the target stack\'s screens.\nWith `prototype_zoom_transition_v1`, zoom morphs source-to-root on Android and uses native\ninteractive zoom on iOS 18+. Older agents keep fadeThrough (Android) or platform push (iOS 17);\nplatformNotes reports the fallback. The new capability reports rendering, not spec acceptance.\nReduced motion crossfades and motion off snaps; composed iOS patterns pop non-interactively.\n',Pr='### Data actions\n\nA tap can change `/data` on the device without the agent answering it. Data actions write a\nmember of `data`; each `path` is `/data` plus a non-empty data pointer (the same syntax and\n`MAX_PROTOTYPE_DATA_POINTER_LENGTH` as `{data: pointer}`), so the whole document cannot be\nwritten:\n\n- `{type: "setData", path, value}` creates or replaces an object member, or replaces an existing\n array element. A missing parent is an error.\n- `{type: "appendData", path, value}` appends to the existing array at `path`.\n- `{type: "prependData", path, value}` inserts one row at the start; list maxItems trims from the end.\n- `{type: "removeData", path}` removes an existing member or element; later elements shift down.\n\n`value` uses the emit.context binding forms except `page`: `{value: json}` is the literal,\n`{state: key}` reads state, `{data: pointer}` reads data, and `{item: field}` and\n`{index: true}` read the repeat row (repeat only). A written value must be data: strings, booleans,\nfinite numbers, arrays and objects, without null. Inside a repeat, a whole `{index}` segment of\n`path`, as in `/data/cart/{index}`, is bound to the current row; `{index}` anywhere else, or\n`{alias.field}`, is rejected.\n\nThe host validates pointer syntax and `{index}` use, rejects a literal value data cannot hold, and\nrejects an `appendData` or `prependData` whose target resolves in the spec\'s own `data` to something other than an\narray. A target that only exists after earlier writes is checked by the device. A write that would\nleave `data` over `MAX_PROTOTYPE_DATA_WRITE_BYTES` (or over a depth or array limit), or whose\ntarget is missing or not an array, changes nothing.\nActions run in order, so a later action sees an earlier write.\n\nEach write is a `change` event with `name` the written `/data/...` path and `payload`\n`{op: "set"|"append"|"remove", value?, revision}`; `awaitEvent` with `kind: "change"` returns it.\n`revision` is the device revision after the write, the same counter as a patch result\'s. The host\napplies each write to its own copy of the spec and to `status` data, so both stay current. The\nagent\'s `/data` patches and a device\'s writes never silently lose each other: once the device\nhas written a prototype\'s data, a patch with `/data` ops needs `baseRevision` (the latest\n`revision` the agent has seen) and is refused with `conflict: {revision, state, data}` when a write\nnewer than that revision touched an overlapping path (`data` lists those paths). A `show` makes its\nown `data` authoritative again and clears the history.\n\nData actions require `prototype_data_actions_v1`. A show or patch result that contains one is\nrefused on a device without it, before anything is shown or sent.\n\n\n### Realtime channels\n\nThe validated contract requires `prototype_platform_realtime_v1`; current Android and iOS\nruntimes do not advertise it. A root `channels` map holds at most four named channels and\nrequires `requires.platform:["realtime"]`. Each channel declares `kind:"websocket"|"sse"`\nand `url` (ws/wss or http/https respectively), using request URL placeholders and length rules.\nOptional fields: `protocols` (WebSocket only, up to four), `headers` (up to 16, request rules\nplus refusing Sec-WebSocket-* and Last-Event-ID), `via:"host"|"device"` (host default),\n`connect:"onShow"|"manual"` (onShow default), declared string `statusKey`,\n`decode:"json"|"text"` (json default), `reconnect`, `routes`, `onOpen/onClose/onError`.\nDevice routing additionally requires `prototype_platform_realtime_device_v1`.\nReconnect fields are integer `maxAttempts:0..20`, `initialDelayMs>=100`,\n`maxDelayMs<=60000`, with initial <= max. Up to 16 routes use `when:{pointer,equals}`,\n`{pointer,exists:boolean}`, `{event:SSE-name}`, or omit when. Their actions are state/data\nwrites; request and navigation are refused. In channel callbacks and platform handlers,\n`{event:"/message"}` reads decoded event data and `{event:""}` reads the whole event.\nCalls use `{type:"platform",call:"realtime.connect"|"realtime.disconnect",args:{channel:"chat"}}`\nand `realtime.send` with `args:{channel:"chat",body:{value:json}}` (WebSocket only).\nRead live counters with `{platform:"/realtime/chat/framesIn"}`; state keys are status, attempt,\nframesIn, framesDropped, closeCode, closeReason and error. Events are realtime.status and realtime.frame.\nThe same capability gates `appendData.maxItems` and `upsertData {path,key,value,maxItems?}`.\nUpsert replaces the first row whose key pointer matches the incoming value, otherwise appends;\nmissing incoming identity is an error. maxItems is 1..2000 and drops oldest rows before limits apply.\nFrame/send budgets are 65536/16384 bytes, with eight open channels per device and a 50 ms flush budget.\nTransport, lifecycle and routing execution remain unavailable. Flush-window coalescing is an open\ndecision; no coalescing behavior is implemented.\n',ei="\n### Adaptive panes and navigation\n\n`adaptive` needs `prototype_adaptive_v1` and a closed `kind`:\n- `listDetail`: `list` and `detail` node slots, `selectionKey` naming a declared string state key. Empty string means no selection; selecting pushes detail in compact layout and Back clears the key.\n- `navigationSuite`: 1\u20138 unique `items: [{value,label}]`, `stateKey` naming a declared string whose value matches an item, and a `content` node slot. Item taps write that value. Use conditions on the key to choose content.\n- `supporting`: `main` and `supporting` node slots, `openKey` naming a declared boolean. Close clears the key.\n\nWidths are native per platform. Android Material adaptive scaffolds split panes at expanded and use bar/rail/drawer at compact/medium/expanded. iOS horizontalSizeClass regular uses split/sidebar/inspector, compact uses stack/bottom bar/sheet. There is no shared breakpoint or `minWidth`; `platformNotes` reports the different rules on show. iOS draws Material-styled containers under every design until native platform containers are available.\n",ti='## Platform namespaces\n\nChoose styling in this order:\n1. Portable node/window fields express behavior on both platforms: use `button.variant: "outlined"`\n for an outlined button, or `style.cornerRadius` for an authored corner.\n2. Portable theme tokens express a shared visual system: set `theme.colors.primary` once rather\n than repeating a color on each button; use theme typography and corner tokens for shared styles.\n3. `theme.design: "platform"` chooses native platform treatment for covered controls (the default);\n `"material"` keeps the shared Material appearance. Check design fallback notes for custom controls.\n4. Use `ios`/`android` only for semantics with no portable meaning, such as\n `ios: {buttonStyle: "glass"}` or `android: {predictiveBack: {style: "none"}}` on a stack.\n\nNamespaces are closed objects on nodes, window and theme; each field has a contract `why`.\nOwn-platform blocks require `prototype_platform_namespace_v1`, except the four node glass fields,\nwhich require only `prototype_glass_v1` on iOS; mixing another iOS key requires both.\nForeign blocks are accepted and\nignored with paths in `platformNotes`; unknown fields are rejected even in foreign blocks.\niOS glass buttons need 26 and otherwise use bordered buttons; hover needs 17 and is render-only\n(no pointer input). Custom tab bars, app bars and sheets cannot apply `tab.role`,\n`bottomAccessory` (node-only), `navigationTitle` or `sheet.sizing`; these are reported as ignored.\nWindow/theme namespace fields likewise have no applicable node and are reported as ignored.\nAndroid `indication: "ripple"|"none"` controls the node\'s clickable feedback; motion-off still wins.\nStack `predictiveBack.style` uses the existing pop for `default`, horizontal movement with fade\nfor `crossActivity` within the prototype activity, or snaps without predictive scrubbing for `none`.\nUse notes to confirm what the current renderer can apply before relying on a namespace field.',ni='## Platform features\n\nA spec reaches a platform feature through a module. Declare every module it uses in a root `requires: {platform: [<module>], permissions?: [{name, purpose}], background?: [...]}`; a call, handler or read of an undeclared module fails validation with a path, and a call\'s permissions must appear in `requires.permissions`. The host reads `requires` before show and refuses a device that lacks a module\'s capability, before anything is drawn.\n\n- **Call.** `{type:"platform", call:"<module>.<op>", args, into?, statusKey?, timeoutMs?, onSuccess?, onError?}` in any action list. `args` are strict per call; values are `{value}`, `{state}`, `{data}`, `{platform}`, `{item}`/`{index}` in a repeat, or `{event}` in a handler. `into` (a `/data` path) and `statusKey` (a declared string state key that moves loading, then success or error) behave as for `request`. A failure writes one of unsupported, unavailable, permission_denied, invalid_args, cancelled, timeout, too_many_in_flight or platform_error to `<into>__meta.error`. Each finished call is an emit event `prototype_platform` (`{callId, call, outcome, error?, durationMs}`).\n- **Handler.** A root `platform: {on: {"<module>.<event>": [actions]}}`. Inside a handler only, `{event: "/pointer"}` reads the event\'s data. Handlers run atomically like a tap and may use `push`, `pop`, data actions and further calls. A delivered event is an emit event `prototype_platform_event` (`{event, data, truncated?}`).\n- **Read.** `/platform/<module>/<key>` is device-owned, read-only JSON: `{platform:/device/os}` in text, `{platform: "/device/widthClass", equals: "expanded"}` as a condition, `{platform: pointer}` as a value. It is not patchable or stored and is not part of the `/data` revision log.\n- **Names.** Authored emit names cannot start with `prototype_`.\n\nEach module needs `prototype_platform_v1` plus its own capability; a device without either refuses show, patch and `replaceNode` and names the capability. The table below is generated from the contract, so it lists every module, call, event and key a spec may name; a device can run only the modules whose capabilities it advertises:\n',ri=`Example: a podcast posts a "new episode" notification, and tapping it deep-links to the episode through a handler \`push\`.
|
|
3
|
-
|
|
4
|
-
\`\`\`json
|
|
5
|
-
{
|
|
6
|
-
"id": "podcast",
|
|
7
|
-
"window": {"placement": {"type": "fullscreen"}},
|
|
8
|
-
"state": {"postStatus": "idle"},
|
|
9
|
-
"data": {"opened": {"title": ""}},
|
|
10
|
-
"requires": {
|
|
11
|
-
"platform": ["notifications"],
|
|
12
|
-
"permissions": [{"name": "notifications", "purpose": "Tell you when a new episode is out"}]
|
|
13
|
-
},
|
|
14
|
-
"notifications": {"channels": [{"id": "episodes", "name": "New episodes", "importance": "default"}]},
|
|
15
|
-
"platform": {"on": {"notifications.opened": [
|
|
16
|
-
{"type": "setData", "path": "/data/opened/title", "value": {"event": "/data/title"}},
|
|
17
|
-
{"type": "push", "stack": "nav", "screen": "episode"}
|
|
18
|
-
]}},
|
|
19
|
-
"root": {
|
|
20
|
-
"type": "stack", "id": "nav", "start": "home",
|
|
21
|
-
"screens": {
|
|
22
|
-
"home": {"type": "button", "label": "Simulate release", "onTap": [{"type": "platform", "call": "notifications.post", "statusKey": "postStatus", "args": {
|
|
23
|
-
"id": {"value": "ep-42"}, "channel": {"value": "episodes"},
|
|
24
|
-
"title": {"value": "New episode"}, "body": {"value": "42: Shipping on Fridays"},
|
|
25
|
-
"data": {"value": {"title": "42: Shipping on Fridays"}}
|
|
26
|
-
}}]},
|
|
27
|
-
"episode": {"type": "text", "text": "Now playing {data:/opened/title}"}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
\`\`\`
|
|
32
|
-
|
|
33
|
-
Drive it for real with \`systemTray\` (find and tap the notification), then \`awaitEvent\` for \`prototype_platform_event\` and \`observe\` the episode screen.
|
|
34
|
-
|
|
35
|
-
`,oi='### Notifications\n\n`notifications.post|cancel|setBadge|schedule` need `requires.platform:["notifications"]` and\n`prototype_platform_notifications_v1`; all but `cancel` also need the `notifications` permission. Declare channels in a root block:\n`"notifications": {"channels": [{"id": "messages", "name": "Messages", "importance": "high"}]}`\n(1 to 8 channels, unique ids; `importance` is min, low, default or high, and iOS maps min and low to\npassive, default and high to active; optional `description` and `showBadge`). The block needs\n`notifications` in `requires.platform`.\n\n- `post` takes `id`, `channel`, `title` and optional `body`, `largeImage`, `style`, `group`,\n `badge`, `data` and up to 3 `actions`. A literal `channel` must name a declared channel, and\n action ids are unique. Posting an `id` that is already shown updates it in place.\n- `schedule` takes the `post` arguments plus `delaySeconds` (1 to 604800) and also needs\n `prototype_platform_notifications_scheduled_v1`; its firing is the `notifications.scheduledFired`\n event. Delivery is inexact.\n- A `notifications.push` handler receives a simulated server push and also needs\n `prototype_platform_push_v1`; read `{event: "/type"}` and `{event: "/data/..."}` there.\n- `cancel` takes exactly one of `id`, `group` or `all: true`.\n- Taps, action buttons and inline replies arrive at `platform.on` handlers\n (`notifications.opened|action|reply|dismissed`); read `{event: "/notificationId"}`,\n `"/actionId"`, `"/reply"` and `"/data"` there.\n- `/platform/notifications/channels/<id>/blocked` is true when the user turned a declared channel\n off; a post to it fails with `unavailable`. A read of an undeclared channel fails validation.',ii='### Media actions\n\n`mediaLibrary.pick` opens the system photo picker and `camera.capture` opens the system camera.\nNeither needs `requires.permissions`. Declare the module in `requires.platform`. A pick needs\n`prototype_platform_mediaLibrary_v1`. A capture needs `prototype_platform_camera_v1` and\n`prototype_platform_camera_capture_v1`. An iOS Simulator has the picker but no system camera, so\nit advertises `mediaLibrary` without the capture capability.\n\n- `pick` takes `media` (`images`, `videos` or `imagesAndVideos`) and optional `maxItems` (1 to 64,\n default 1). With `maxItems` 1, `into` receives one media item. With more, it receives an array.\n Android clamps `maxItems` to the system picker\'s limit.\n- `capture` takes `media` (`image` or `video`) and optional `maxDurationMs` (1 to 600000, video only).\n- A media item is `{asset: "media:\u2026", kind, mimeType, width?, height?, durationMs?, bytes, source,\n createdAt, thumbnail?}`; `source` is `library` for a pick and `camera` for a capture. Bind it to an image with `{data: "/pointer"}`; that needs\n `prototype_platform_media_items_v1`.\n- Cancelling leaves `into` untouched and runs `onError` with `cancelled`. A device without a camera\n fails with `unavailable` (detail `missing_usage_description` when the iOS plist key is missing), and\n storage failures are `platform_error` (detail `media_limit` or `io`). Only one system-UI call can run\n per prototype at a time; a second fails with `too_many_in_flight`.\n- Current runtimes advertise neither module, so the host refuses such a spec before show.\n `platformMode` and simulated outcomes through `prototype simulate` are not accepted yet.\n\n```json\n{\n "id": "photo-draft",\n "window": {"placement": {"type": "fullscreen"}},\n "state": {"pickStatus": "idle", "camStatus": "idle"},\n "data": {"draft": {}},\n "requires": {"platform": ["mediaLibrary", "camera"]},\n "root": {\n "type": "column",\n "children": [\n {"type": "text", "text": "Picker: {pickStatus}, camera: {camStatus}"},\n {"type": "button", "label": "Choose photos", "onTap": [{"type": "platform", "call": "mediaLibrary.pick", "args": {"media": {"value": "imagesAndVideos"}, "maxItems": {"value": 4}}, "into": "/data/draft/picked", "statusKey": "pickStatus"}]},\n {"type": "button", "label": "Take photo", "onTap": [{"type": "platform", "call": "camera.capture", "args": {"media": {"value": "image"}}, "into": "/data/draft/photo", "statusKey": "camStatus"}]}\n ]\n }\n}\n```';var np=["standard","expressive"].flatMap((n)=>["spatial","effects"].map((o)=>{let i=["fast","default","slow"].map((a)=>V.motionTokens[n][o][a]);return`| ${n} ${o} | ${i.map((a)=>a.dampingRatio).join(" / ")} | ${i.map((a)=>a.stiffness).join(" / ")} |`})).join(`
|
|
36
|
-
`),ai=`## Expressive and layout motion
|
|
37
|
-
|
|
38
|
-
(needs \`prototype_motion_v3\`, Android only) \`motion: "expressive"\` uses Material expressive
|
|
39
|
-
springs for visibility, container size, press feedback and \`animate\` with \`easing: "spring"\`.
|
|
40
|
-
Spatial changes use the spatial spring; color and alpha use the effects spring. Standard remains
|
|
41
|
-
the default. Under \`animate\`, border color/width, cornerRadius, elevation, shadowColor, padding
|
|
42
|
-
and dp width/height also tween; fill/wrap/token, text, font and gradient swaps stay instant.
|
|
43
|
-
Node \`press: {scale?, alpha?}\` needs at least one field: scale 0.85\u20131, alpha 0.5\u20131, on a node
|
|
44
|
-
with a tap/long-press/double-tap or an inherently pressable control. Its scale overrides style
|
|
45
|
-
\`pressScale\`; drawing changes without shrinking the touch target or reported bounds.
|
|
46
|
-
With motion none or Android animator scale 0, controls settle instantly and ripples are disabled.
|
|
47
|
-
The host refuses these features against the iOS agent until #14684.
|
|
48
|
-
|
|
49
|
-
Text nodes accept \`contentTransition: "numeric" | "crossfade" | "none"\` (default \`none\`). Non-\`none\` requires \`prototype_content_transition_v1\`. Numeric changes roll only changed characters up for an increase and down for a decrease; formatting is stripped to digits, the first decimal point and a leading minus. Missing or equal numeric values crossfade; identical text stays still. Spans crossfade as a whole. Roll uses a spring (Android damping 0.8, stiffness 380; iOS duration 0.35 s, bounce 0.15); fades take 200 ms. Accessibility and observe expose the new text immediately. Android reduced motion uses fades and motion off snaps; iOS content transitions snap under reduced motion or motion off.
|
|
50
|
-
|
|
51
|
-
\`animate.tempo: "fast" | "default" | "slow"\` requires \`prototype_motion_tokens_v1\`
|
|
52
|
-
and cannot be combined with \`durationMs\` or \`easing\`. The contract's \`motionTokens\`
|
|
53
|
-
table selects a physical spring by scheme (\`motion: "standard"\` by default, or
|
|
54
|
-
\`"expressive"\`), property role and tempo. \`easing: "spring"\` selects the default
|
|
55
|
-
tempo of that scheme. Spatial properties are offset, scale, rotation, cornerRadius,
|
|
56
|
-
elevation, shadowColor, padding, border width and dp width/height; alpha, background,
|
|
57
|
-
color and border color use critically damped effects springs.
|
|
58
|
-
|
|
59
|
-
| Scheme / role | Damping ratio (fast / default / slow) | Stiffness (fast / default / slow) |
|
|
60
|
-
| --- | --- | --- |
|
|
61
|
-
${np}
|
|
62
|
-
|
|
63
|
-
Compose uses \`spring(dampingRatio, stiffness)\`. SwiftUI uses
|
|
64
|
-
\`interpolatingSpring(mass: 1, stiffness: k, damping: 2 * dampingRatio * sqrt(k))\`,
|
|
65
|
-
so both renderers use the same physical spring. Reduced motion snaps spatial
|
|
66
|
-
changes and retains effects; motion off snaps everything. Existing motion v2/v3
|
|
67
|
-
capability requirements still apply; iOS advertises the token capability but
|
|
68
|
-
continues to refuse those broader features until its corresponding capabilities
|
|
69
|
-
are available.
|
|
70
|
-
|
|
71
|
-
## Attention loops
|
|
72
|
-
|
|
73
|
-
(Android only, requires \`prototype_loops_v1\`) Any node accepts
|
|
74
|
-
\`attentionLoop: {effect: "pulse" | "spin", periodMs: 400\u20134000, iterations?: 1\u201320 | "infinite"}\`.
|
|
75
|
-
The period and finite count are integers; omitted iterations means infinite. Pulse scales
|
|
76
|
-
1 \u2192 1.08 \u2192 1 per period; spin turns 0 \u2192 360 degrees. Drawing changes without changing
|
|
77
|
-
layout, reported bounds or touch targets. A pulse node must omit \`style.scale\`; a spin node
|
|
78
|
-
must omit \`style.rotation\`, including every \`styleWhen\` style. At most eight expanded nodes
|
|
79
|
-
may carry loops, including repeat instances; shimmer does not consume that limit.
|
|
80
|
-
Finite loops settle at identity and contribute to settling motion while running. Infinite
|
|
81
|
-
loops and shimmer contribute only to the intentional loop count. Reduced motion, motion
|
|
82
|
-
none and animator scale 0 leave loops at rest. On Android each observe metadata read renews
|
|
83
|
-
a 1500 ms capture hold: attention loops draw identity and shimmer draws no band during it,
|
|
84
|
-
so captures within the hold are identical when the rest of the scene is unchanged.
|
|
85
|
-
`;var Ir='## Starter templates\n\nThe repository ships eight validated multi-screen specs, each a `stack` with a `testTag` on every\ninteractive node. In a checkout, show one with `specPath` (an absolute path) from\n`test/fixtures/prototype-spec/valid/`, or copy its shape when writing a spec:\n\n- `template-onboarding.json`: welcome, sign-up form with `checks`, a button gated by\n `enabledWhen {valid}`, `emit` with `requireValid`, done.\n- `template-feed-detail.json`: a `repeat` over `{path: "/posts"}` inside a refreshable `scroll`; a\n tap stores the row in state and `push`es the detail screen.\n- `template-tabbed-home.json`: a `pager` driven by a `bottomNav {pager}`, plus a pushed screen.\n- `template-checkout.json`: quantity stepper, form with `select` and `datePicker`, and a\n `bottomSheet` confirmation.\n- `template-settings.json`: `listItem` switches, `radioGroup`, `slider`, `dialog`, `snackbar` and\n a `storage` block.\n- `template-search.json`: docked `searchBar` whose child lists `/results` and shows an empty\n state with `{data, empty: true}`.\n- `template-chat.json`: reversed `scroll` with `stickToEnd`, quick-reply chips that\n `appendData`, and a composer that `emit`s `message_sent` with the draft as context (Android only).\n- `template-dashboard.json`: `chart` line, bar and ring over `/data`, and a `startTimer` clock.\n';var si=`${ti}
|
|
86
|
-
|
|
87
|
-
## Gestures
|
|
88
|
-
|
|
89
|
-
\`onLongPress\` and \`onDoubleTap\` run their action lists exactly like \`onTap\`, with no new
|
|
90
|
-
event kind. A node with either list is interactive even without \`onTap\`. All three may coexist;
|
|
91
|
-
a node with only \`onLongPress\` and/or \`onDoubleTap\` does not consume single taps:
|
|
92
|
-
the nearest ancestor's \`onTap\` runs. The single-tap delay applies only to nodes declaring
|
|
93
|
-
\`onDoubleTap\`; \`onTap\` with only \`onLongPress\` fires immediately.
|
|
94
|
-
Repeat item and component prop placeholders bind in these lists just as they do in \`onTap\`.
|
|
95
|
-
Use \`tapOn\` with \`action: "longPress"|"doubleTap"\` and \`layer: "prototype"\` to drive them
|
|
96
|
-
by coordinate gesture; no new MCP tool is needed. Long-press uses the platform default threshold
|
|
97
|
-
(about 0.5 s on iOS versus the Android long-press timeout, about 0.4 s); the double-tap window is
|
|
98
|
-
the system's. The host refuses unsupported agents before sending a show.
|
|
99
|
-
Each declared list is also a named accessibility action on both platforms, so TalkBack and
|
|
100
|
-
VoiceOver users reach it without the touch gesture: \`Long press\` and \`Double tap\` (fixed English
|
|
101
|
-
names). A single \`onTap\` is the default activation and adds none.
|
|
102
|
-
|
|
103
|
-
### Swipe actions
|
|
104
|
-
|
|
105
|
-
A \`row\` or \`listItem\` may declare \`swipeActions: {start?, end?, fullSwipe?}\` (needs
|
|
106
|
-
\`prototype_swipe_actions_v1\`). \`start\` is revealed by swiping right and \`end\` by swiping left
|
|
107
|
-
(mirrored in right-to-left layouts is not done: sides are physical). Each side holds 1-3 entries
|
|
108
|
-
\`{label, icon?, role?, color?, onTap}\`: \`label\` is the button text and its accessibility name,
|
|
109
|
-
\`icon\` a built-in icon name (an SF Symbol on iOS), \`role\` \`default\` (primary colours) or
|
|
110
|
-
\`destructive\` (error colours), \`color\` a hex or theme role that overrides the background, and
|
|
111
|
-
\`onTap\` 1-32 actions. The first entry of a side sits at the screen edge. A release past 40% of
|
|
112
|
-
the revealed width, or a fling past the open velocity, leaves the row open; a drag beyond the
|
|
113
|
-
revealed width resists (rubber-band). With \`fullSwipe: true\` a drag past 60% of the row (or a hard
|
|
114
|
-
fling) runs the swiped side's first entry and closes the row. Only one row is open at a time, and a
|
|
115
|
-
tap on an open row closes it instead of running its \`onTap\`. Revealed buttons get the test tag
|
|
116
|
-
\`<rowTestTag>.swipe.<index>\`, counting \`start\` entries first and then \`end\`; they exist only while
|
|
117
|
-
the row is open. Every entry is also an accessibility action (TalkBack custom action, VoiceOver
|
|
118
|
-
action) on the row, so assistive technology can run it without swiping. The reduced profile snaps row settling; spec
|
|
119
|
-
\`motion: "none"\` snaps instead of animating. Put swipeActions on repeated rows; a row inside a
|
|
120
|
-
horizontal \`pager\` or a \`carousel\` is refused because their drag would compete.
|
|
121
|
-
|
|
122
|
-
### Pull-to-refresh
|
|
123
|
-
|
|
124
|
-
A vertical \`scroll\` may declare \`refresh: {stateKey, onRefresh}\` (needs
|
|
125
|
-
\`prototype_refresh_v1\`). \`stateKey\` names a boolean state key: the platform's refresh indicator
|
|
126
|
-
shows while it is true. A pull sets the key to true and runs \`onRefresh\` like a tap; the prototype
|
|
127
|
-
(an \`onRefresh\` \`setState\`, or the agent through \`patch\` on \`/state/<key>\` with a
|
|
128
|
-
\`baseRevision\`) sets it back to false to hide the indicator. Declare the key in \`state\` as a
|
|
129
|
-
boolean; a horizontal scroll with \`refresh\` is rejected. The pull is a swipe down from the top of
|
|
130
|
-
the scroll (\`swipeOn\` with the prototype layer) and \`observe\` reports the scroll as usual.
|
|
131
|
-
|
|
132
|
-
### Chat lists
|
|
133
|
-
|
|
134
|
-
A vertical \`scroll\` can be a conversation view (needs \`prototype_chat_scroll_v1\`, Android only for
|
|
135
|
-
now): \`reverse: true\` anchors it at the end of its content, so the newest row sits at the bottom;
|
|
136
|
-
\`stickToEnd: true\` follows rows appended while it is at the end; \`atEndKey\` names a declared
|
|
137
|
-
boolean state key the runtime keeps true while it is at the end (show a "new messages" pill with
|
|
138
|
-
\`visibleWhen {key, equals: false}\`); \`onStartReached\` runs each time the start is reached, to load
|
|
139
|
-
older history. \`scrollTo {scroll, to: "start" | "end" | {key: <repeat.key value>}, animated?}\` moves
|
|
140
|
-
the scroll whose \`id\` is \`scroll\` (exactly one); \`{key}\` scrolls to that repeat row. A composer is a
|
|
141
|
-
row with a \`textField\` (\`imeAction: "send"\`, \`onSubmit\`) and a send \`iconButton\`, with
|
|
142
|
-
\`safeAreaPadding {edges: ["bottom"], types: ["ime", "systemBars"]}\`. Rows off screen are absent from
|
|
143
|
-
\`observe\`; \`swipeOn lookFor\` still finds them.
|
|
144
|
-
`,di=`# Prototype authoring guide
|
|
145
|
-
|
|
146
|
-
Use the \`prototype\` tool with \`action: "show"\` and a full \`spec\`. A show with the id of the
|
|
147
|
-
prototype already on screen replaces it. Use show for a new screen or a window, theme or root
|
|
148
|
-
change; patch for content (\`/data\`), state (\`/state\`) or one node by id (\`replaceNode\`). A large or script-generated spec can be written to a local JSON file and
|
|
149
|
-
shown with \`specPath\` (an absolute path the daemon reads) in place of \`spec\`; give exactly one of
|
|
150
|
-
the two. The spec is
|
|
151
|
-
\`{id, window, theme?, data?, state?, motion?, root}\`. State values are flat scalars (string, finite
|
|
152
|
-
number, boolean). State keys match \`[A-Za-z_][A-Za-z0-9_]{0,63}\`. Read
|
|
153
|
-
\`automobile:prototype/spec-schema\` for the JSON Schema of every node, action and field; the tool
|
|
154
|
-
definition lists only the spec's top-level fields unless AUTOMOBILE_PROTOTYPE_FULL_SCHEMA=1 inlines it.
|
|
155
|
-
|
|
156
|
-
Screen navigation: \`{type:"stack", id, start, screens:{home: node, detail: node}}\` starts with
|
|
157
|
-
path [start] and renders only the top screen. Screen names and id are non-empty; start names an
|
|
158
|
-
existing screen. Actions \`push {stack, screen}\`, \`pop {stack}\`, \`popToRoot {stack}\`, and
|
|
159
|
-
\`replace {stack, screen}\` append, remove the top, reset to [start], and swap the top respectively.
|
|
160
|
-
Push is ignored at depth 32; pop at depth 1 does nothing. \`screen_changed\` has name = stack id
|
|
161
|
-
and payload \`{screen, depth}\`, emitted only when the top screen or depth changes. Requires
|
|
162
|
-
\`prototype_stack_v1\`; every screen counts toward node limits, including hidden screens.
|
|
163
|
-
Routes (requires \`prototype_routes_v1\`; older devices refuse them):
|
|
164
|
-
keep \`screens\` as bare nodes and optionally add \`routes:{screen:{params?,onEnter?,onBack?}}\`.
|
|
165
|
-
Declare up to 16 params per screen as string|number|boolean; names match [A-Za-z_][A-Za-z0-9_]*.
|
|
166
|
-
Push/replace accept a flat \`params\` map of scalars or {state}/{data}/{item}/{index:true} bindings;
|
|
167
|
-
all declared params are required, literals must match their types, and extra names are refused.
|
|
168
|
-
\`setStack {stack,path:[{screen,params?}]}\` takes 1-32 entries and replaces the whole path.
|
|
169
|
-
Each back-stack entry keeps its own params, so Back shows the previous entry as it was.
|
|
170
|
-
In a screen and its lifecycle actions, \`{route.name}\` binds the top entry's params in the same
|
|
171
|
-
fields as repeat placeholders, condition operands and whole /data pointer segments.
|
|
172
|
-
onEnter/onBack each take 1-32 actions with normal nesting limits. onEnter runs after the
|
|
173
|
-
\`screen_changed\` event whenever the screen becomes top, and once on show (a same-id show skips it
|
|
174
|
-
for stacks whose path it kept). onBack replaces the pop
|
|
175
|
-
for system Back, the iOS edge swipe and a plain \`pop\`; \`pop {force:true}\` always pops, so a
|
|
176
|
-
dialog confirm that leaves uses force (a direct same-stack pop in onBack needs it too).
|
|
177
|
-
Storage key \`stack:<id>\` persists the path with params; a stored path whose screens or params no
|
|
178
|
-
longer fit is dropped and the stack starts at \`start\`. Status and inspect keep \`path:string[]\`
|
|
179
|
-
and add parallel \`params:object[]\`; screen_changed payloads add \`params\` when the top has any.
|
|
180
|
-
Android Back and the iOS edge swipe pop a stack above depth 1. A stack's optional
|
|
181
|
-
\`transition: "platform" | "slide" | "fade" | "none"\` selects screen navigation animation
|
|
182
|
-
(default \`platform\`); \`push\` and \`replace\` can override it with their own \`transition\`.
|
|
183
|
-
Any explicit value needs \`prototype_stack_transitions_v1\`; pop/popToRoot take no override.
|
|
184
|
-
Transitions snap under \`motion: "none"\` or Android animator/transition scale 0, and fade under
|
|
185
|
-
\`motion: "reduced"\` or iOS Reduce Motion. A stack's
|
|
186
|
-
\`transition\` accepts only those navigation values and no longer animates the stack's own visibility
|
|
187
|
-
(earlier specs using \`expand\`, \`scale\`, \`slideStart\`, \`slideEnd\` or \`blurReplace\` on a stack
|
|
188
|
-
are now refused): wrap the stack in a \`box\` with \`visibleWhen\` and a visibility transition for
|
|
189
|
-
that. Each entry's scroll position is restored on pop. A stack cannot appear inside a repeat template.
|
|
190
|
-
|
|
191
|
-
On Android, \`show replaceOthers: false\` retains other prototype windows, up to four distinct ids
|
|
192
|
-
(requires \`prototype_multi_surface_v1\`); a fifth is refused listing the shown ids. A same-id show
|
|
193
|
-
with false replaces only that prototype; omitted or true replaces other ids. \`dismiss {id}\` removes
|
|
194
|
-
one, \`dismiss {all: true}\` removes all, and \`status\` lists every shown id. \`inspect\` reconciles
|
|
195
|
-
the full list. iOS refuses false and shows one prototype at a time.
|
|
196
|
-
|
|
197
|
-
Minimal spec:
|
|
198
|
-
|
|
199
|
-
\`\`\`json
|
|
200
|
-
{
|
|
201
|
-
"id": "demo",
|
|
202
|
-
"window": { "placement": { "type": "fullscreen" } },
|
|
203
|
-
"state": { "name": "Ada" },
|
|
204
|
-
"root": { "type": "text", "text": "Hello {name}" }
|
|
205
|
-
}
|
|
206
|
-
\`\`\`
|
|
207
|
-
|
|
208
|
-
A \`{key}\` placeholder in a \`text\` node reads the state value of that key.
|
|
209
|
-
|
|
210
|
-
## Text field options
|
|
211
|
-
|
|
212
|
-
\`textField\` binds an initialized string state key. Optional \`label\` is a nonempty floating
|
|
213
|
-
label; \`variant\` is \`filled\` (default) or \`outlined\`; nonempty \`supportingText\` appears below
|
|
214
|
-
the field. \`keyboardType\` is \`text\` (default), \`number\`, \`decimal\`, \`email\`, \`phone\`, \`url\`,
|
|
215
|
-
or \`password\`. \`secure\` masks text; \`multiline\` enables multiple lines. \`minLines\` and
|
|
216
|
-
\`maxLines\` are integers in 1..20, permitted only with \`multiline: true\`; \`minLines\` cannot
|
|
217
|
-
exceed \`maxLines\`. Multiline text cannot use \`secure: true\` or \`keyboardType: "password"\`.
|
|
218
|
-
\`maxLength\` is an integer in 1..10000 and shows a character counter; the initial bound
|
|
219
|
-
value cannot exceed it (UTF-16 length).
|
|
220
|
-
|
|
221
|
-
All these options require \`prototype_text_field_options_v1\`. A device without the capability
|
|
222
|
-
is refused before uploads or show; nothing is shown. Update CtrlProxy, or relaunch the iOS
|
|
223
|
-
app with \`launchApp prototype: true\`, or drop the textField options.
|
|
224
|
-
|
|
225
|
-
\`textField.errorWhen\` accepts any condition and forces error styling immediately, independently of checks/validateOn. Optional nonempty \`errorText\` (max 256 UTF-16 units) requires errorWhen. Caption precedence while forced: errorText, currently shown check message, supportingText, then no caption. Both options require \`prototype_string_conditions_v1\`. They do not affect change-event validity, \`{valid}\` or \`requireValid\`, which remain checks-only. Fields without checks do not track validation blur.
|
|
226
|
-
|
|
227
|
-
A \`textField\` may also declare \`trailingIcon: {icon, label, onTap?}\` (a built-in icon, its
|
|
228
|
-
nonempty accessible \`label\` and optional 1-32 \`onTap\` actions, for example a clear button that
|
|
229
|
-
\`setState\`s the field's key to an empty string; without \`onTap\` it is decoration),
|
|
230
|
-
\`imeAction\` (\`done\`, \`next\`, \`search\`, \`send\` or \`go\`: the keyboard's action key) and
|
|
231
|
-
\`onSubmit\` (1-32 actions run when that key is pressed; without \`imeAction\` the key is
|
|
232
|
-
\`done\`). Multiline text has no IME action, so \`imeAction\` and \`onSubmit\` are refused with
|
|
233
|
-
\`multiline: true\`. These need \`prototype_text_field_actions_v1\`, with the same refusal.
|
|
234
|
-
\`leadingIcon\` is a built-in icon name drawn before the text (decoration, no actions; iOS maps it to
|
|
235
|
-
an SF Symbol) and needs \`prototype_text_field_leading_icon_v1\`, with the same refusal.
|
|
236
|
-
|
|
237
|
-
Open question: a \`secure\` field's value still lives in state and in \`change\` events/\`inspect\`;
|
|
238
|
-
this slice does not redact it.
|
|
239
|
-
|
|
240
|
-
## Search field and results
|
|
241
|
-
|
|
242
|
-
\`searchBar.stateKey\` names an initialized string query. Editing uses the same state write
|
|
243
|
-
and \`change\` event as a text field; keyboard search runs \`onSubmit\`. A visible search bar
|
|
244
|
-
is an editable text target for \`sendKeys\` and makes the window focusable for the keyboard.
|
|
245
|
-
\`placeholder\` follows text-field rules. \`leadingIcon\` and each trailing action's required
|
|
246
|
-
\`icon\` use the icon catalog; its required nonempty \`label\` is the accessibility label,
|
|
247
|
-
and \`onTap\` runs ordinary actions.
|
|
248
|
-
\`activeKey\` names an initialized boolean: true shows the optional single \`child\`.
|
|
249
|
-
A child requires activeKey; activeKey without a child is allowed.
|
|
250
|
-
\`variant: "bar"\` (default) expands to fill its parent when active; \`"docked"\` stays in
|
|
251
|
-
place and draws results directly underneath. Results are ordinary nodes inside the prototype
|
|
252
|
-
window, so \`observe\` sees every row; use a column of literal rows rather than a lazy list.
|
|
253
|
-
Child nodes and submit/trailing actions participate in all normal validation and template walks;
|
|
254
|
-
repeat placeholders bind in the placeholder, trailing labels and actions as in other controls.
|
|
255
|
-
Show and patches producing a search bar require \`prototype_search_bar_v1\` and are refused
|
|
256
|
-
before device requests when it is absent. The Android and iOS implementations ship in later passes.
|
|
257
|
-
iOS uses a drawn field with SF Symbol icons, not SwiftUI \`.searchable\`; these differences
|
|
258
|
-
are reported in \`platformNotes\`.
|
|
259
|
-
|
|
260
|
-
## Loading, empty and error states
|
|
261
|
-
|
|
262
|
-
State-key \`contains\`/\`startsWith\` compare UTF-16 substrings/prefixes, case-sensitive with no Unicode normalization. Literal operands are nonempty strings up to 256 UTF-16 units; repeat placeholders always bind as text (a numeric item renders as its text), and an empty substituted operand holds for every string. \`lengthGt\`/\`lengthLt\` compare UTF-16 length strictly against literal integers 0..100000 (\`\uD83D\uDE00\` has length 2). Missing or non-string state values fail all four. They are valid only with \`key\`, wherever a condition is accepted, and require \`prototype_string_conditions_v1\`.
|
|
263
|
-
|
|
264
|
-
(needs \`prototype_loading_states_v1\`) \`{data: "/feed", empty: true}\` holds when the value is
|
|
265
|
-
missing, \`[]\`, \`{}\` or \`""\`; \`empty: false\` is its inverse. It replaces the comparison, so
|
|
266
|
-
it cannot be combined with another comparison, and it applies to data
|
|
267
|
-
conditions only. Style \`shimmer: true\` on a \`box\`, \`row\`, \`column\` or \`card\` sweeps an
|
|
268
|
-
animated highlight over its background and reads "Loading" to accessibility; it stays at its rest pose under
|
|
269
|
-
\`motion: "reduced"\`, iOS Reduce Motion, \`motion: "none"\` or Android animator/transition scale 0. The canonical trio uses a request's \`statusKey\`:
|
|
270
|
-
|
|
271
|
-
- **Loading:** a column with \`visibleWhen: {key: "feedStatus", equals: "loading"}\` that repeats a
|
|
272
|
-
few literal placeholder rows styled \`{shimmer: true, height: {dp: 56}, background:
|
|
273
|
-
"surfaceVariant", cornerRadius: "medium"}\`.
|
|
274
|
-
- **Empty:** \`visibleWhen: {all: [{key: "feedStatus", equals: "success"}, {data: "/feed",
|
|
275
|
-
empty: true}]}\`, with the "No posts yet" copy.
|
|
276
|
-
- **Error:** \`visibleWhen: {key: "feedStatus", equals: "error"}\`, with a retry button that runs
|
|
277
|
-
the request again.
|
|
278
|
-
|
|
279
|
-
The rows themselves repeat over \`{path: "/feed"}\`. The iOS agent draws shimmer too.
|
|
280
|
-
|
|
281
|
-
## Style effects
|
|
282
|
-
|
|
283
|
-
(needs \`prototype_effects_v1\`; no connected device advertises it yet, so the host refuses a spec
|
|
284
|
-
with \`style.effects\` until a renderer ships) \`style.effects\` is 1 to 4 paint-only looks drawn in
|
|
285
|
-
order inside the node's own bounds: \`noise\`, \`gradientMesh\`, \`shimmer\`, \`glow\`,
|
|
286
|
-
\`vignette\`, \`blur\`, \`pixelate\`, \`chromaticAberration\`, \`wave\` and \`ripple\`, each with typed,
|
|
287
|
-
bounded params. Shader source is never accepted. Any effect may loop with \`animate:
|
|
288
|
-
{periodMs: 400-20000}\` and start at \`phase\` 0-1; a spec has at most 64 effects and 8 animated ones
|
|
289
|
-
across its expanded \`repeat\` tree, counting every \`styleWhen\` style's list too.
|
|
290
|
-
|
|
291
|
-
## Scroll-driven motion
|
|
292
|
-
|
|
293
|
-
(needs \`prototype_scroll_motion_v1\`) A node under a scroll, pager, carousel or repeat takes
|
|
294
|
-
\`scrollTransition: {axis: "horizontal" | "vertical", edge: {scale?, alpha?, rotation?}}\`.
|
|
295
|
-
It interpolates from the edge values to identity at the viewport centre. Any node can take
|
|
296
|
-
\`scrollLinked: {source: "feed", range: [0, 160], alpha: [1, 0], offsetY: [0, -40]}\`:
|
|
297
|
-
\`source\` names a scroll in the same screen; the input endpoints increase, and each output
|
|
298
|
-
is a two-number range. Outputs are \`alpha\`, \`scale\`, \`offsetX\`, \`offsetY\` and \`blur\`.
|
|
299
|
-
They interpolate linearly and clamp outside the input range. At most 16 bindings are allowed
|
|
300
|
-
across the expanded tree; each field counts once per instance. These effects change drawing,
|
|
301
|
-
not layout, hit targets or observed bounds. \`motion: "reduced"\` keeps alpha only;
|
|
302
|
-
\`motion: "none"\` keeps all scroll-driven outputs. Android blur requires Android 12 or later.
|
|
303
|
-
|
|
304
|
-
## Style effects
|
|
305
|
-
|
|
306
|
-
(needs \`prototype_effects_v1\`; no connected device advertises it yet, so the host refuses a spec
|
|
307
|
-
with \`style.effects\` until a renderer ships) \`style.effects\` is 1 to 4 paint-only looks drawn in
|
|
308
|
-
order inside the node's own bounds: \`noise\`, \`gradientMesh\`, \`shimmer\`, \`glow\`,
|
|
309
|
-
\`vignette\`, \`blur\`, \`pixelate\`, \`chromaticAberration\`, \`wave\` and \`ripple\`, each with typed,
|
|
310
|
-
bounded params. Shader source is never accepted. Any effect may loop with \`animate:
|
|
311
|
-
{periodMs: 400-20000}\` and start at \`phase\` 0-1; a spec has at most 64 effects and 8 animated ones
|
|
312
|
-
across its expanded \`repeat\` tree, counting every \`styleWhen\` style's list too.
|
|
313
|
-
|
|
314
|
-
## Motion profiles and shared elements
|
|
315
|
-
|
|
316
|
-
\`motion\` is \`standard\` (default), \`reduced\` or \`none\`. Explicit \`motion: "reduced"\`
|
|
317
|
-
requires \`prototype_reduced_motion_v1\`. iOS Reduce Motion selects the reduced profile;
|
|
318
|
-
Android animator scale or transition scale 0 selects off. Spec \`none\` or system off wins over
|
|
319
|
-
reduced. Reduced replaces spatial animation (slides, scale, container size, presses, swipe-row
|
|
320
|
-
settling, pager scrolling and shared morphs) with a crossfade or snap with fade. Shimmer and
|
|
321
|
-
other ambient/attention loops stop at rest and report no loop; color, alpha and fades still animate.
|
|
322
|
-
Off makes every change instant.
|
|
323
|
-
|
|
324
|
-
\`shared: {key, as: "element" | "bounds"}\` requires \`prototype_shared_element_v2\` and
|
|
325
|
-
\`visibleWhen\` on the same node (zoom sources exempt). Element shares identical content (a hero image); bounds shares
|
|
326
|
-
a container with changing content and crossfades both sides. \`sharedKey\` remains the
|
|
327
|
-
\`prototype_shared_element_v1\` bounds alias; a node cannot set both. Literal v2 keys allow
|
|
328
|
-
letters, digits, underscore and hyphen, starting with a letter or underscore (1-64 characters).
|
|
329
|
-
A spec has at most 16 resolved keys, including unmatched feed items. Literal keys pair exactly two nodes, neither nested in the
|
|
330
|
-
other. Inside repeat children, use \`shared: {key: "story-{item.id}", as: "bounds"}\` with
|
|
331
|
-
\`repeat.key: "id"\`: placeholders must name that same field; index and constant keys are refused.
|
|
332
|
-
Each item resolves a distinct key, used at most twice; unmatched feed items remain ordinary cards.
|
|
333
|
-
The pair must use the same as value and cannot cross a dialog or bottomSheet boundary.
|
|
334
|
-
Choose visibility conditions so the pair is not visible together. Full motion morphs geometry;
|
|
335
|
-
reduced uses ordinary visibility crossfades and off swaps instantly.
|
|
336
|
-
|
|
337
|
-
## One-shot keyframes
|
|
338
|
-
|
|
339
|
-
Every node supports \`keyframes: {trigger: {key: "liked"}, durationMs: 600,
|
|
340
|
-
tracks: {scale: [[0,1],[0.35,1.3],[1,1]]}}\` with \`prototype_keyframes_v1\`
|
|
341
|
-
(iOS 17+). Alternatively trigger with \`{data: "/liked"}\`, relative to data.
|
|
342
|
-
It plays once on each value change, never on first show; another change restarts it.
|
|
343
|
-
Use 100\u20133000 ms and 1\u20137 tracks: scale, scaleX, scaleY, rotation (degrees), offsetX,
|
|
344
|
-
offsetY (dp), alpha. Each track has 2\u20138 [fraction,value] points, strictly increasing
|
|
345
|
-
from 0 to 1, or \`{points, curve: "linear" | "standard" | "spring"}\` (default standard).
|
|
346
|
-
Start and end at rest (scale/alpha 1, rotation/offsets 0); scales must be positive,
|
|
347
|
-
alpha 0\u20131. At most 16 expanded nodes may carry keyframes. These are draw transforms:
|
|
348
|
-
layout and observed semantics stay unchanged. Reduced keeps alpha only; none disables playback.
|
|
349
|
-
|
|
350
|
-
## Motion v2
|
|
351
|
-
|
|
352
|
-
(needs \`prototype_motion_v2\`) A node's \`animate: {durationMs?, easing?}\` (0-2000 ms, default
|
|
353
|
-
300; \`standard\`, \`emphasized\`, \`linear\` or \`spring\`) animates changes to its \`alpha\`,
|
|
354
|
-
\`offset\`, \`scale\`, \`rotation\`, \`background\` and \`color\`, typically from \`styleWhen\`; without
|
|
355
|
-
it they are instant. Style \`scale\` (0-4) and \`rotation\` (degrees, -360..360) draw about the
|
|
356
|
-
node's centre without moving siblings. \`transition\` also takes \`slideStart\` / \`slideEnd\`
|
|
357
|
-
(slide in from that edge, mirrored right to left: drawers) and \`scale\`. An \`image\` with
|
|
358
|
-
\`zoomable: {maxScale}\` (1-8) pinches, pans when zoomed and toggles 1x/2x on a double tap, with
|
|
359
|
-
accessibility zoom actions; it cannot also have \`onDoubleTap\`. Everything snaps under
|
|
360
|
-
\`motion: "none"\` or Android animator/transition scale 0. In the reduced profile spatial changes
|
|
361
|
-
snap or crossfade; color and alpha still animate. The iOS agent does not support Motion v2 yet (#14684).
|
|
362
|
-
|
|
363
|
-
## Icon effects
|
|
364
|
-
|
|
365
|
-
(needs \`prototype_icon_effects_v1\`, iOS 17+) An icon accepts \`effect: {type, trigger?, repeat?}\`.
|
|
366
|
-
Types: bounce, pulse, scale, variableColor, wiggle, rotate, breathe, replace, drawOn.
|
|
367
|
-
Use \`trigger: {key: "flag"}\` or \`{data: "/revision"}\` for one play per value change;
|
|
368
|
-
omit both controls for one play on appearance. \`repeat\` is \`"infinite"\` or 1\u201320 and
|
|
369
|
-
cannot coexist with trigger. Repeats count as loops and share the eight animated-effect budget.
|
|
370
|
-
Scale holds while its trigger is truthy; replace follows icon name changes. Reduced/off rest,
|
|
371
|
-
except reduced replace crossfades. Android approximates effects with scale/alpha/rotation and
|
|
372
|
-
crossfades. iOS 17 uses bounce for wiggle, none for rotate and pulse for breathe; drawOn needs
|
|
373
|
-
26 and otherwise uses replace. \`platformNotes\` reports approximations/fallbacks with node paths.
|
|
374
|
-
|
|
375
|
-
${ai}
|
|
376
|
-
|
|
377
|
-
## Choreography
|
|
378
|
-
|
|
379
|
-
(needs \`prototype_choreography_v1\`) On nodes other than stacks, \`transition\` also takes \`{type, delayMs?}\` (\`delayMs\` 0-600 ms, the wait
|
|
380
|
-
before the enter starts) besides the plain names, and \`blurReplace\`: a blur-and-fade enter and exit
|
|
381
|
-
(iOS \`.blurReplace\`; Android 12 and later blur, Android 11 and earlier fade only). A \`box\`, \`row\` or \`column\` takes \`stagger: {ms, order?}\` (\`ms\` 0-100 per child;
|
|
382
|
-
\`order\` \`forward\` (default), \`reverse\` or \`center\`): its direct children with \`visibleWhen\`
|
|
383
|
-
enter one after another in layout order, each \`ms\` apart, including the children a \`repeat\` makes.
|
|
384
|
-
A child's own \`transition.delayMs\` adds to its stagger wait, and no child may wait more than 600 ms
|
|
385
|
-
in all (a literal \`repeat\` is counted; a data-bound one is clamped on the device). Delays are zero
|
|
386
|
-
under \`motion: "none"\` or Android animator/transition scale 0. In the reduced profile spatial
|
|
387
|
-
transitions become fades. Delays apply to enters only. The iOS agent does not
|
|
388
|
-
support it yet.
|
|
389
|
-
|
|
390
|
-
## Lazy lists
|
|
391
|
-
|
|
392
|
-
\`list {repeat:{items:{path},as,key},children:[row],axis?,header?,footer?,spacing?,contentPadding?,onEndReached?,endThreshold?,refresh?,maxItems?}\`
|
|
393
|
-
is a lazy scrolling collection (needs \`prototype_lazy_list_v1\` and \`prototype_data_model_v1\`).
|
|
394
|
-
The path resolves to at most ${jD} objects; \`key\` is required, projected and unique. Empty arrays
|
|
395
|
-
are valid. Axis defaults to vertical; spacing/padding are nonnegative dp. One row template and
|
|
396
|
-
optional header/footer each count once toward node/image limits, while per-item binding and text
|
|
397
|
-
budgets still apply. Header/footer are ordinary nodes outside the row scope. Never nest lists,
|
|
398
|
-
put a list in a repeat, or put a same-axis scroll above/below a list. Rows cannot nest repeats/pagers.
|
|
399
|
-
Only composed rows are in \`observe\`; use \`swipeOn\` to reach more. Row keys preserve identity.
|
|
400
|
-
\`onEndReached\` fires for nonempty rows within \`endThreshold\` of the end (1\u201350, default 3), once
|
|
401
|
-
per \`(rowCount,lastRowKey)\` signature; empty/no-change pages never refire. Signature state survives
|
|
402
|
-
recomposition and resets on show. \`endThreshold\` needs \`onEndReached\`. Vertical \`refresh\` uses
|
|
403
|
-
scroll.refresh semantics and a declared boolean key (also needs \`prototype_refresh_v1\`).
|
|
404
|
-
\`maxItems\` (1\u2013${jD}) requires initial data to fit; appending trims oldest rows atomically before
|
|
405
|
-
final data limits. The smallest cap among lists sharing the exact data path wins.
|
|
406
|
-
\`request.append:{from,to}\` (same lazy-list capability) extracts a response array from an object
|
|
407
|
-
member at \`from\`, extends the existing \`/data/...\` array \`to\`, and writes the remaining response
|
|
408
|
-
to optional \`into\`. These paths must not overlap. Any failure rolls back all writes and returns
|
|
409
|
-
\`invalid_response\`. Extend events precede into/meta/status/request/onSuccess events; change
|
|
410
|
-
payloads are \`{op:"append"|"extend"|"prepend",value,maxItems?,revision}\`. \`prependData {path,value}\` resolves one row and sends writer op \`prepend\` with \`value:[row]\`;
|
|
411
|
-
it requires the lazy-list, data-actions and data-model capabilities. It uses the smallest matching
|
|
412
|
-
list cap and trims from the end, keeping the first maxItems rows. A missing event value means the
|
|
413
|
-
page exceeded the byte budget and the host stops tracking the spec.
|
|
414
|
-
Renderers keep the first visible row key and offset across writes, even at the top; new rows sit
|
|
415
|
-
above it. Headers/footers are not anchors; a trimmed key uses the renderer default. Each stack
|
|
416
|
-
entry restores its list key/offset after push/pop; a missing key falls back to the nearest surviving
|
|
417
|
-
index or top. Prepend, anchoring and per-stack-entry list scroll restore are not device-verified
|
|
418
|
-
until the acceptance run; benchmark qualification remains unverified.
|
|
419
|
-
|
|
420
|
-
## Charts
|
|
421
|
-
|
|
422
|
-
\`{type: "chart", variant, series, yRange?, xLabels?, goal?}\` draws a \`line\`, \`area\`, \`bar\` or
|
|
423
|
-
\`ring\` chart (needs \`prototype_chart_v1\`). \`series\` holds 1-4 \`{path, x?, y, label, color?}\`
|
|
424
|
-
entries: \`path\` is a \`/data\` pointer to an array of objects (empty is valid, at most ${Kie} items as
|
|
425
|
-
for any data array), \`y\` names each point's numeric member and \`x\` its optional label member;
|
|
426
|
-
\`color\` is a hex or theme role, or a \`{light, dark}\` pair. Points are drawn in array order, so
|
|
427
|
-
\`appendData\`, a \`request\` \`into\` or a \`/data\` patch re-renders the chart. \`yRange {min, max}\`
|
|
428
|
-
fixes the axis (max above min); otherwise it spans the values and the goal, and bars rise from zero.
|
|
429
|
-
\`xLabels\` is \`none\` (default), \`ends\` or \`all\` of the first series' x labels. \`goal\` draws a
|
|
430
|
-
dashed reference line; a \`ring\` takes exactly one series and a positive \`goal\`, and draws that
|
|
431
|
-
series' latest value against it. The chart is one accessible node labelled with its summary, such as
|
|
432
|
-
"Line chart, Heart rate, 24 points, min 58, max 141, latest 72" or "Ring chart, Steps, 6500 of
|
|
433
|
-
10000"; \`observe\` reports it, and an authored \`contentDescription\` replaces it. A literal path that
|
|
434
|
-
does not resolve to an array, a point that is not an object, or a point whose \`y\` is not a number
|
|
435
|
-
fails at \`<path>.series[i].path\` or \`.y\`. The iOS agent draws charts with Swift Charts.
|
|
436
|
-
|
|
437
|
-
## Rich text
|
|
438
|
-
|
|
439
|
-
A text node has exactly one of \`text\` or \`spans\`; plain \`text: ""\` remains valid.
|
|
440
|
-
Spans are strict \`{text, style?, onTap?}\` objects with nonempty, untrimmed text; whitespace is valid.
|
|
441
|
-
Span style accepts only color, fontWeight, fontStyle, textDecoration, textSize, letterSpacing,
|
|
442
|
-
fontFamily and background, with the same ranges as node style; background is a colour, never a gradient.
|
|
443
|
-
There are no span ids, testTags, visibility conditions, nested spans or URLs.
|
|
444
|
-
Each span uses the same state \`{key}\`, data \`{data:/pointer}\`, repeat \`{item.field}\` / \`{index}\`
|
|
445
|
-
and component \`{props.x}\` binding as node text; span actions bind like node onTap actions.
|
|
446
|
-
The resolved texts concatenate in order without separators: observe and accessibility show the
|
|
447
|
-
full plain text (an explicit node contentDescription still overrides its accessible label).
|
|
448
|
-
Spans do not count as nodes and require \`prototype_rich_text_v1\`; older devices are refused before show.
|
|
449
|
-
A tappable span is part of the text node, not a separate accessibility node, and runs actions without opening URLs.
|
|
450
|
-
On Android, activate it with \`tapOn {accessibilityLink:"<span text>"}\` or
|
|
451
|
-
\`tapOn {text:"<full plain text>", subtext:{text:"<span text>"}}\` without \`layer\`:
|
|
452
|
-
these selectors act across windows because tapOn refuses layer with accessibilityLink/subtext (#9305).
|
|
453
|
-
Use \`tapAt\` on the span bounds as the fallback.
|
|
454
|
-
On iOS, links are drawn as links and tap-through is by \`tapAt\` only; show reports the
|
|
455
|
-
\`rich-text-links\` platform note for tappable spans because there are no separate accessibility elements or semantic links.
|
|
456
|
-
|
|
457
|
-
### Linkify
|
|
458
|
-
|
|
459
|
-
\`linkify: {kinds, style?, onTap}\` on a text node with \`text\` (not \`spans\`) turns @mentions,
|
|
460
|
-
#hashtags and URLs in the resolved text (for example \`{item.body}\`) into links. \`kinds\` lists 1-3 of
|
|
461
|
-
\`mention\`, \`hashtag\`, \`url\`; \`style\` takes the span style fields. A match starts at the start of
|
|
462
|
-
the text or after whitespace: a mention is \`@\` + 1-30 of \`[A-Za-z0-9_]\` (\`ana@example.com\` is not
|
|
463
|
-
one), a hashtag \`#\` + up to 100 letters, digits or \`_\` (not all digits), a URL \`http(s)://\` up to
|
|
464
|
-
whitespace without trailing punctuation. Inside \`onTap\` only, \`{match: "text"}\` (the tapped
|
|
465
|
-
\`@ana\`) and \`{match: "kind"}\` work as a \`setState\` value, a \`setData\`/\`appendData\` value or an emit
|
|
466
|
-
context entry: \`[{type:"setState",key:"profileHandle",value:{match:"text"}},{type:"push",stack:"nav",screen:"profile"}]\`.
|
|
467
|
-
Repeat bindings are refused inside linkify \`onTap\`. URL taps never open a browser. Requires
|
|
468
|
-
\`prototype_linkify_v1\`.
|
|
469
|
-
|
|
470
|
-
## Saved prototypes
|
|
471
|
-
|
|
472
|
-
Use \`save\` with \`spec\`, optional \`assets\`, \`label\` (defaults to \`spec.id\`) and
|
|
473
|
-
\`icon\` (an asset id uploaded in \`assets\` in that same call). Android needs
|
|
474
|
-
\`prototype_saved_v1\`. On iOS this is simulator only and needs no prototype agent:
|
|
475
|
-
the viewer template is resolved from the verified release asset, or from
|
|
476
|
-
\`AUTOMOBILE_IOS_PROTOTYPE_VIEWER\` (build it with \`scripts/ios/prototype-viewer-build.sh\`).
|
|
477
|
-
Omit \`icon\` for the default app icon. Pinning returns \`pinned:"unsupported"\`; the iOS
|
|
478
|
-
app icon is already on the home screen. \`listSaved\` on iOS returns bundle ids accepted by
|
|
479
|
-
\`deleteSaved\`, with \`pinned:false\` and no \`savedAt\` (the save time cannot be recovered).
|
|
480
|
-
\`deleteSaved\` also accepts the authored id; it removes the iOS app icon, so
|
|
481
|
-
\`removeIcon:true\` is ignored with a warning.
|
|
482
|
-
|
|
483
|
-
On Android or an iOS simulator with the ProtoViewer app installed, \`save\` without \`pin\` or \`icon\` imports
|
|
484
|
-
the prototype into the ProtoViewer library instead, and does not need CtrlProxy or
|
|
485
|
-
\`prototype_saved_v1\`. It returns \`viewer\` \`{app, libraryId, label}\` (plus \`display\` {key, role}, the panel it landed on, on an iPhone Duo); every save is a new
|
|
486
|
-
library entry, which \`listSaved\` and \`deleteSaved\` do not see. ProtoViewer treats the entry
|
|
487
|
-
as imported: its requests stay off until the user allows network in ProtoViewer, and it is not
|
|
488
|
-
attached to this host (no \`awaitEvent\`, \`patch\` or \`inspect\`). \`{action:"open",id}\` with
|
|
489
|
-
that \`libraryId\` launches it on Android or an iOS simulator. It needs ProtoViewer installed.
|
|
490
|
-
If ProtoViewer is absent, too old for this route, or its inbox cannot be used, \`save\`
|
|
491
|
-
keeps the platform save path. A timeout after delivery may still have saved the entry; check
|
|
492
|
-
ProtoViewer before retrying.
|
|
493
|
-
|
|
494
|
-
## Fullscreen host chrome
|
|
495
|
-
|
|
496
|
-
\`window.chrome\` is \`"none"\` (default) or \`"bar"\`, fullscreen only, on a device advertising
|
|
497
|
-
\`prototype_window_chrome_v1\`. With \`none\` there is no host dismiss bar: content starts at the
|
|
498
|
-
very top of the screen, including under the status bar. A \`topAppBar\` or top content needs
|
|
499
|
-
\`safeAreaPadding\` on the top edge; relative sheet detents use the full window height.
|
|
500
|
-
A host-owned two-finger long press (about 1 s) anywhere on the window reveals a dismiss pill for
|
|
501
|
-
5 s; tapping it dismisses with reason \`user\`. Agent dismiss, a replacing show, authored dismiss,
|
|
502
|
-
the session's five-minute idle TTL and last-client disconnect still work.
|
|
503
|
-
\`window.transition\` (auto|none|fade|slide|scale) and \`repeat.stagger\` (0-100 ms per instance, capped at 600 ms) require \`prototype_window_motion_v1\` on Android.
|
|
504
|
-
\`window.persistence: "device"\` defaults to \`bar\` and keeps its existing persistence behaviour.
|
|
505
|
-
The device implementations ship separately: without the capability a device keeps the bar,
|
|
506
|
-
explicit \`none\` is refused, and omitted chrome or \`bar\` succeeds. A successful fullscreen
|
|
507
|
-
show and subsequent host-local status report the effective value as \`lastResult.chrome\`;
|
|
508
|
-
it is absent for sheet/floating windows, dismiss, failed show and adopted prototypes.
|
|
509
|
-
|
|
510
|
-
## Frosted backdrop
|
|
511
|
-
|
|
512
|
-
\`window.backdrop\` is \`{material, blur?, tint?}\` and blurs what is behind the window on any
|
|
513
|
-
placement (not the prototype's own content). \`material\` is one of \`ultraThin\`, \`thin\`,
|
|
514
|
-
\`regular\`, \`thick\` or \`glass\` (Liquid Glass, iOS 26+ only). \`blur\` is an optional whole radius in
|
|
515
|
-
dp (points on iOS), 0-150. \`tint\` is one hex or role colour, not a light/dark pair. The host refuses
|
|
516
|
-
the show on a device without \`prototype_backdrop_v1\`. Where the platform cannot blur, the device
|
|
517
|
-
draws a tonal fill (\`tint\` at 85% alpha, else the \`surfaceContainer\` role at 85%) and \`lastResult.backdrop\` is
|
|
518
|
-
\`fallback\`; otherwise it is \`blur\`.
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
## Tooltip and drawer
|
|
522
|
-
|
|
523
|
-
\`tooltip\` requires \`prototype_tooltip_v1\`, boolean \`openWhen: {key, equals}\`, nonblank \`text\`, and exactly one of \`anchorTo\` (a unique node id in the same spec, other than itself) or \`anchor\` (the existing element selector or bounds anchor). Element anchors are resolved by the host to a target rect; native renderers hoist the tooltip as an overlay, not ordinary anchored content. IDs are literal: repeated targets with multiple instances and duplicate component-instance ids are ambiguous and rejected; a repeat with no items supplies no target.
|
|
524
|
-
|
|
525
|
-
Optional \`caret\` is \`auto\` (default), \`top\`, \`bottom\`, \`start\` or \`end\`: it names the bubble edge pointing at the target, so \`top\` places the bubble below the target. Auto chooses a side with room; auto and explicit sides flip to the opposite side when needed to stay inside the window. Optional strict \`spotlight: {padding?, cornerRadius?}\` draws the scrim role with a rounded hole around the target: integer dp 0..64, defaults 8 and 12 respectively. Without spotlight there is no scrim. Tapping outside the bubble on the spotlight scrim, or tapping the bubble without \`onTap\`, writes \`!equals\` to the open key, then runs optional \`onDismiss\` (1..32 actions). Bubble and scrim tags are \`<testTag>\` and \`<testTag>.close\`. Use one boolean per step for a coach-mark tour; a step's \`onTap\` uses \`setState\` to close its key and open the next step's key. Numeric equality is not supported by \`openWhen\`.
|
|
526
|
-
|
|
527
|
-
\`drawer\` requires \`prototype_drawer_v1\`, \`edge: "start"|"end"\`, boolean \`openWhen: {key, equals}\` and a \`child\` node. Start/end follow layout direction. The renderer fixes panel width; there is no width field. Optional \`scrim\` accepts the same color value (including mode pairs) as bottomSheet and defaults to the scrim role. Optional \`dismissOnSwipe\` defaults to true, as for bottomSheet. Both nodes accept the common node fields, including \`onTap\`, but no long-press or double-tap handlers.
|
|
528
|
-
|
|
529
|
-
## Menu and select
|
|
530
|
-
|
|
531
|
-
\`menu\` and \`select\` require \`prototype_menus_v1\`; the host refuses them before showing or uploading assets when the connected renderer lacks it.
|
|
532
|
-
|
|
533
|
-
A \`menu\` requires \`openWhen: {key, equals}\` with a boolean equality and 1\u201316 strict \`items\`. Each item is \`{label, icon?, trailingText?, enabled?, onTap?}\` or exactly \`{type:"divider"}\`. Labels and trailing text are nonempty, icons use the existing icon names, and \`onTap\` has 1\u201332 existing actions. A disabled item is dimmed, cannot be tapped and does not close the menu. Dividers are neither focusable nor tappable. The elevated surface is anchored to its parent\u2019s bottom end and clamped inside the window; it opens above its anchor when it does not fit below. An enabled item or outside tap writes \`!equals\` to the open key; item actions run after closing.
|
|
534
|
-
|
|
535
|
-
A \`select\` requires a string \`stateKey\` and 2\u201332 \`{value,label}\` options with unique nonempty values and nonempty labels; its optional label is nonempty. It shows the current option\u2019s label, or empty text when no option matches, and a trailing expand indicator. Expansion is local view state. Choosing an option writes the string key, emits the same \`change\` payload as \`radioGroup\`, and collapses the list. Tapping the field again or outside also collapses it. Both nodes support repeat templates and reusable \`use\` components: state keys, menu item labels/trailing text/actions and select labels/option labels bind placeholders.
|
|
536
|
-
|
|
537
|
-
Rendering stays inside the prototype window on both platforms so \`observe\` and \`tapOn\` reach the normal hierarchy. Android uses an in-window surface rather than a separate DropdownMenu/Popup window. iOS uses an in-window list rather than system SwiftUI Menu/Picker popups; successful iOS shows report this substitution in \`platformNotes\`. Menu icons use the existing SF Symbols mapping on iOS.
|
|
538
|
-
|
|
539
|
-
The select field and menu surface carry the node \`testTag\`. Select option rows use \`<testTag>.<value>\`; menu item rows use \`<testTag>.<index>\`, with zero-based positions including dividers. Android adds row tags only when \`testTag\` is set; iOS falls back to \`(testTag ?? id).<value>\` or \`(testTag ?? id).<index>\`.
|
|
540
|
-
|
|
541
|
-
`,li="## Lists: repeat\n\nWrapping containers require `prototype_flow_grid_v1`. A `flow` is a wrapping row:\n`style.spacing` is the item gap, and `style.runSpacing` is the line gap (finite dp >= 0,\nwith the same bounds as spacing). Optional `maxLines` is an integer >= 1; overflow is\nclipped visually, while all children stay in the hierarchy and count toward node/depth budgets.\nA `grid` requires `columns`: an integer 1..12 or `{minWidth: dp}` with finite dp > 0.\nSpacing applies to both axes unless runSpacing overrides the row gap. runSpacing is meaningful\nonly on flow/grid. Grid is always non-lazy and never scrolls itself; wrap it in `scroll`.\nChildren are placed row-major; a span that does not fit the row starts a new row. Optional\n`span` is an integer >= 1 on any node shape, but is valid only on a direct grid child;\nit must not exceed fixed columns. Adaptive runtime spans are clamped to the resolved count.\n\nA `carousel` (`prototype_carousel_v1`) is a horizontally scrolling row of items, one per child\n(at least one), that snaps to items and may declare `repeat` like `row`. `itemWidth` (dp, > 0)\nis required. `variant` is `multiBrowse` (default; items change width as they scroll, Android\nMaterial), `hero` (centered large item) or `uncontained` (fixed-width items). `itemSpacing`\nis dp >= 0. iOS draws every variant as fixed-width snapping items.\nA pager's optional `stateKey` binds a declared nonnegative integer number key both ways\n(requires `prototype_pager_state_key_v1`). Swipes write the key and emit `page_changed`\nand `change`; state writes and patches move the pager, clamped to its page range, animated\nunless `motion: \"none\"`. Initial/replacing-show state wins over retained pages. Use the\nsame key on a tabBar/bottomNav for simple shared selection, and read it in `styleWhen`\non a row of dot boxes outside the pager. Two pagers cannot share a key; binding inside\nrepeat templates is refused. `setPage` writes the same selection.\nA pager may also declare\n`indicator: \"dots\"` (default `none`): page dots with the current page filled.\n`indicatorPlacement` is `over` or `below` and applies only with `indicator: \"dots\"`.\nWhen omitted, Android defaults to `over` and iOS to `below`. `below` places a row under\nhorizontal pages or a column beside vertical pages; `over` overlays the bottom or end edge.\nBoth fields need the same capability. A carousel has no page index, event or `setPage` target; use a\n`pager` when the page matters.\n\nA `box`, `row`, `column`, `flow`, `grid` or `carousel` may declare `repeat: {items, as}`. Its `children` are the template and\nare instantiated once per item, in order, as siblings inside the same container (the container\nitself is not repeated). For eagerly composed rows use a `column` with `repeat`; for lazy rows use the `list` node.\n\n```json\n{\n \"type\": \"column\",\n \"repeat\": {\n \"items\": [\n { \"name\": \"Alpha\", \"tag\": \"a\" },\n { \"name\": \"Beta\", \"tag\": \"b\" }\n ],\n \"as\": \"item\"\n },\n \"children\": [\n {\n \"type\": \"text\",\n \"text\": \"{index}: {item.name}\",\n \"onTap\": [{ \"type\": \"setState\", \"key\": \"picked\", \"value\": \"{item.tag}\" }]\n }\n ]\n}\n```\n\nGrammar:\n\n- `{index}` is the zero-based position; `{<as>.<field>}` reads a field of the current item.\n- Literal items are objects of scalar fields (no nesting); `as` is a state-key-shaped identifier.\n A state key cannot hold a list.\n- Placeholders are bound in a template child's `text`, the label/title/text fields of components\n (button, fab, segmentedButton options, topAppBar, dialog, menu item labels/trailingText, select labels/options, snackbar), state condition operands\n (`equals`/`notEquals` strings), `setState.value` and `emit.name`. `emit.payload` is not bound.\n Anything else, including a `{key}` state placeholder and other braces, is left untouched. A show or patch lists a placeholder\n in such a field as `placeholderFindings` (for example `chip.label` or `badge.text`).\n (`equals`/`notEquals`/`contains`/`startsWith` strings, including inside `errorWhen`) and `textField.errorText`, `setState.value` and `emit.name`. `emit.payload` is not bound.\n Anything else, including a `{key}` state placeholder and other braces, is left untouched.\n- State keys bind too: `stateKey`, `hourKey`/`minuteKey`, a list item's trailing `stateKey`,\n `openWhen.key`, condition `key`s and the `key` of `setState`, `toggle`, `increment` and\n `decrement`, so `\"key\": \"liked_{item.id}\"` gives each row its own state. Every bound key must\n be a literal state key and, like any key, be initialised in `state` with the type it binds.\n- A string that is exactly one placeholder keeps the item field's own type (so\n `equals: \"{item.id}\"` matches a numeric state value when `id` is a number); inside a longer\n string it renders as text.\n\nRejected (same paths in TypeScript and Kotlin):\n\n- a placeholder naming a field missing from any item (`Unknown repeat field \"nme\"`)\n- a template that contains another `repeat` or a `pager`\n- `repeat` on a leaf node\n- an `emit.name` that binds to an empty string for any item\n- a state key that binds to an invalid key for some item (fails at `<container>.repeat.items[i]`),\n or a state-key placeholder outside every template\n- an expanded tree that exceeds the node or image limit (fails at the container's `repeat`);\n depth is unaffected because instances are siblings\n",ci="### Emit context\n\nUse a stable `emit.name` such as `pick` and `context: {id: {item: \"id\"}}` to report a\nrepeat item's id, instead of encoding the id into the event name. `emit.payload` stays literal\nand uninterpolated; context is resolved on the device when the emit action runs, after earlier\nactions in the same atomic `onTap` list. For example, setState then emit reads the new state.\n\nEach nonempty context name has a strict binding object with exactly one key:\n\n- `{state: key}` reads state; repeat placeholders such as `liked_{item.id}` bind to concrete keys.\n- `{item: field}` reads a typed repeat field; `{index: true}` reads its zero-based numeric index.\n Both require a repeat template. The field must exist in every item; data-path repeats use the\n same scalar projection as text placeholders. Expansion replaces these bindings with `{value: ...}`.\n- `{page: pagerId}` reads an existing pager's current numeric page.\n- `{data: pointer}` reads any JSON value via the existing data pointer syntax and\n `MAX_PROTOTYPE_DATA_POINTER_LENGTH`; it also requires `prototype_data_model_v1`.\n- `{value: json}` is literal JSON, subject to the emit payload depth limit.\n\nMissing state keys and data paths resolve to null. `MAX_PROTOTYPE_EMIT_CONTEXT_ENTRIES` bounds the\nnumber of entries. The resolved object's compact JSON UTF-8 bytes\nare bounded by `MAX_PROTOTYPE_EMIT_PAYLOAD_BYTES`; this runtime count includes multibyte strings\nand compact JSON numbers, rather than the payload validator's conservative numeric cost.\nIf over budget, sort entries by ascending name (byte-wise UTF-8 order), keep the longest prefix\nthat fits and omit all remaining entries. An oversized first entry produces `{}`. The tap succeeds.\n\nA show or patch replacement using `emit.context` requires `prototype_emit_context_v1`; older\ndevices are refused before upload, display or patch dispatch. The `prototype_event` wire has `context` next to the unchanged\n`payload` only if the emit declared context (including an empty object). It has\n`contextTruncated: true` only when truncated; otherwise the field is omitted, never false.\n`awaitEvent` and host status preserve these fields.\n\n",pi='### Storage\n\nA show resets `state` and `data` to the spec\'s values, so what the user typed or a data action\nchanged is lost on the next show, and saved prototypes keep the spec but no user data. A root-level\n`storage` block keeps chosen values on the device, for example\n`"storage": {"version": 1, "keys": ["state:darkMode", "data:/cart"]}`.\n\n`version` is an integer from 1; `keys` holds 1 to `MAX_PROTOTYPE_STORAGE_KEYS` unique entries.\n`state:<key>` names a key declared in `state`. `data:<pointer>` is an RFC 6901 pointer to a member of\n`data` (the pointer is relative to `data`: `data:/cart` is `/data/cart`, the path a data action\nuses; the whole document is refused). Listing a pointer and its ancestor or descendant is rejected,\nand the values the spec itself holds for the listed keys must fit `MAX_PROTOTYPE_STORAGE_BYTES`\n(counted as the UTF-8 bytes of each storage key plus its compact JSON value).\n\nThe device saves each listed key, keyed by the spec `id`, after every write: a user edit, a device\ndata action or a request response. A write that would take the stored total over\n`MAX_PROTOTYPE_STORAGE_BYTES` still applies on screen but is not stored (`skippedKeys` in inspect).\nStored values survive a dismiss, a process restart and a saved prototype\'s relaunch.\n\nPrecedence on the next show of the same `id` (the adopted decision of #12522):\n\n- Stored values replace the spec\'s values for the listed keys. The spec\'s `state` is otherwise still\n authoritative.\n- A different `storage.version` than the values were stored under discards all of them: the spec\'s\n values stand. Bump `version` when you change what a key means.\n- A stored key the spec no longer lists is dropped, and a show without a `storage` block drops every\n stored value of that id.\n- A stored value that no longer fits the spec is dropped and the spec\'s value stands: a `state` value\n whose type (string, number, boolean) differs from the spec\'s, a state key the spec no longer\n declares, a `data` value of another JSON kind than the spec\'s value at that pointer, or one that\n cannot be written there (missing parent, a data limit).\n- Restoring happens before the first draw and emits no `change` event. After a show, read the real\n values with inspect: the show result and the host\'s cached copy carry the spec\'s values.\n- A host `patch` against a stored key wins: it applies under the usual `baseRevision` conflict rules\n and the device then stores the new value.\n\n`inspect` reports `storage: {version, keys: [{key, bytes}], totalBytes, skippedKeys?}` per prototype\nfor the keys that currently hold a stored value, or omits it when the device does not report it.\n`{action: "clearStorage", id}` wipes the stored values of an id (the next show starts from the spec;\nthe result has `cleared`, the number of keys removed). `deleteSaved` also clears that id\'s storage.\n`storage`, `clearStorage` and the report need `prototype_storage_v1`: a spec with `storage` is refused\nbefore anything is shown, and `clearStorage` before anything is sent, on a device without it.\n\n\n',ui='### Sharing\n\n`{type:"platform", call:"share.open", args:{text:{value:"Hi {name}"}}}` requires\n`requires.platform:["share"]` and `prototype_platform_share_v1`. Current runtimes do not\nadvertise it; the host refuses the spec before show. Arguments are value bindings: at least one\nof `text|url|images|files|contact`, plus optional `subject`. URLs use literal http(s) schemes; prototype deep links are unavailable. Images accept up to 10 uploaded IDs\n(or `{asset:id}` / `{data:"/pointer"}` holding an uploaded ID), files up to 4\n`{asset,name,mimeType}` entries. File names have no leading dot, separators or controls and\nfit 128 UTF-8 bytes; MIME types are type/subtype tokens. Contact fields are `name` (required),\n`phone,email,org,url,note`, serialized as vCard 3.0. Strings take ordinary placeholders and\nfit 65536 UTF-8 bytes. `into` receives `{outcome:"shared"|"unknown",target?,items}`;\nits text summary keeps 2048 Unicode scalars. `statusKey,onSuccess,onError` use platform-call\nsemantics. Real system sheets, cancellation callbacks and queued fake outcomes are owed;\n`platformMode` and `prototype simulate` are not accepted yet.\n\n### Requests\n\n`{type: "request", url, method?, headers?, query?, body?, into?, statusKey?, via?, timeoutMs?, onSuccess?, onError?}`\ncalls an HTTP endpoint from a tap and writes the answer into `/data`, so a prototype can load and\npost real content without the agent answering each tap. It requires `prototype_network_v1`\n(`prototype_network_device_v1` as well for `via: "device"`); a show or patch result containing\none is refused on a device without them.\n\n- `url` is an absolute `http` or `https` URL (at most 2048 characters). Host and device requests\n apply an egress policy: local destinations and daemon ports on private addresses are not permitted.\n It takes the text placeholders of any text field (`{key}` state, `{data:/pointer}`, repeat `{item.field}` / `{index}`). Without a\n placeholder it must parse as an http(s) URL; with one, it must start with a literal `http://` or\n `https://`. (`{state:key}` is not a placeholder: write `{key}`.)\n- `method` is GET (default), POST, PUT, PATCH, DELETE or HEAD. A GET or HEAD cannot have a `body`.\n- `headers` and `query` (up to 16 entries each) map a name to a literal string or to a value\n binding: `{state: key}`, `{data: pointer}`, `{value: scalar}`, `{item: field}` / `{index: true}`\n (repeat only). A bound value must be a string, number or boolean. `query` entries are set on the URL\n in order (a key already in the URL is replaced). Literal header and query strings take the same\n text placeholders as `url`.\n- `body` is a value binding, so a literal body is `{value: json}`; `{state: key}` sends the state\n value and `{data: pointer}` the data subtree. A non-string body is sent as JSON with\n `Content-Type: application/json` unless a header sets one; a string body is sent as is.\n- `into` is a `/data/<pointer>` path with the data-action rules (a whole `{index}` segment inside a\n repeat); it must name an object member, not an array element, and its parent must exist. Without\n `into` nothing is written to data.\n- `statusKey` names a declared **string** state key. The device sets it to `"loading"` when the\n request starts and to `"success"` or `"error"` when it ends, so `visibleWhen` can show a spinner\n (`{key: "feedStatus", equals: "loading"}`) or an error. Do not bind it to a control with fixed options.\n- `via` is `"host"` (default: the host runs the call and the device sends only the resolved request\n frame) or `"device"` (the device makes the call itself and cannot use `localhost` for the\n host machine, see below).\n- `timeoutMs` is optional, 1 to `MAX_PROTOTYPE_REQUEST_TIMEOUT_MS`; the default is\n `DEFAULT_PROTOTYPE_REQUEST_TIMEOUT_MS`.\n- `onSuccess` and `onError` are action lists (1 to 32) run after the request ends, for example\n `setState`, `push` or another `request`. Requests nest up to `MAX_PROTOTYPE_ACTION_DEPTH` levels.\n\n**Response.** A 2xx response is parsed: JSON is written to `into` exactly as `setData` would write it,\nanything else as a string, an empty body (and a HEAD) as `""`. The response must be data (no null,\nwithin the data limits) or the request fails with `invalid_response`. Metadata goes to `<into>__meta`,\na sibling whose key is the last segment of `into` plus `__meta` (`/data/feed` writes\n`/data/feed__meta`): `{status?, headers?, durationMs, error?: {code, message}}`. `status` and\n`headers` (names lower-cased) are present once a response arrived; `error` is present for every\nfailure. A non-2xx status leaves `into` untouched, writes the metadata with\n`error: {code: "http_error", message: "HTTP 404"}` and counts as an error. If the metadata would not fit\nthe data write limit, `headers` is dropped. Other `error.code` values: `timeout`, `too_large`,\n`connection_refused`, `blocked_destination` (the destination is not permitted), `cancelled`, `invalid_url`, `invalid_request`, `network`, `too_many_in_flight`,\n`invalid_response`.\n\n**Order.** On completion the device writes `into`, then `<into>__meta`, then `statusKey`, then sends the\nrequest event, then runs `onSuccess` or `onError`. Each `/data` write is a `change` event as for data\nactions. The request event is an `emit` with `name` `prototype_request` (reserved: an authored\n`emit` cannot use it) and `payload`\n`{requestId, method, url, via, into?, outcome: "success"|"error", status?, durationMs, error?: {code, message}}`,\nwhere `url` is the resolved URL cut to 2048 characters. Await it with\n`awaitEvent {kind: "emit", eventName: "prototype_request"}`.\n\n**Limits.** A response body over `MAX_PROTOTYPE_RESPONSE_BYTES` fails with `too_large` (the value never\nexceeds `MAX_PROTOTYPE_DATA_WRITE_BYTES`, so an accepted response fits one `/data` write). At most\n`MAX_PROTOTYPE_REQUESTS_IN_FLIGHT` requests run per device; another fails with `too_many_in_flight`.\nA request to an `into` that already has one in flight cancels the first: the latest request wins. The\ncancelled one writes nothing, does not touch `statusKey`, runs no follow-up and reports a\n`cancelled` event. Dismissing the prototype cancels all its requests.\n\n',mi="## Data\n\n`data` is agent-owned, read-only content: nested objects, arrays, strings, finite numbers and\nbooleans, without null. `state` remains the user-owned scalar map; actions only write declared\nstate keys. A full show replaces data; a capability-gated patch can change data. See the generated Limits table.\nThe data byte limit uses the `emit.payload` cost: every number costs 32 bytes regardless of\nits digits, so numeric-heavy data reaches the limit before its serialized size does.\n\n`MAX_PROTOTYPE_REPEAT_PATH_CELLS` bounds all path-bound repeats after component expansion,\nincluding empty templates. An instantiated object item costs one cell per projected scalar member,\nwith a minimum of one cell. Literal repeats do not count. Containers are checked in pre-order;\na crossing container fails at `repeat.items.path` with `Repeat path cell limit exceeded`, after\nits three path-source checks and before template projection.\n\nPointers are nonempty RFC 6901 paths relative to data, beginning with `/`; decode `~1` as `/`\nand `~0` as `~`. Object keys are exact own members; array indices are `0` or a positive decimal\nwithout leading zeros. An empty key uses a trailing slash. Invalid escapes and overlong pointers\nare rejected; a missing text path renders empty.\n\n```json\n{\n \"id\": \"orders\",\n \"window\": { \"placement\": { \"type\": \"fullscreen\" } },\n \"data\": { \"orders\": [{ \"id\": 7, \"title\": \"Latte\", \"total\": 4.5 }], \"cartCount\": 1 },\n \"state\": { \"liked_7\": false },\n \"root\": {\n \"type\": \"column\",\n \"repeat\": { \"items\": { \"path\": \"/orders\" }, \"as\": \"item\", \"key\": \"id\" },\n \"children\": [{ \"type\": \"text\", \"text\": \"{item.title} ({data:/cartCount})\",\n \"visibleWhen\": { \"data\": \"/cartCount\", \"gt\": 0 },\n \"onTap\": [{ \"type\": \"toggle\", \"key\": \"liked_{item.id}\" }] }]\n }\n}\n```\n\n- `repeat.items: {path}` must resolve to an array of objects (empty is valid). Only scalar members\n with field-shaped names are projected into items. `repeat.key` names a field every item has;\n its rendered values must be unique, for literal lists too.\n- `{data:/pointer}` binds only the text-kind fields repeat already binds: text, button/FAB labels,\n segmented option labels, app bar title/navigation/action labels, dialog title/text/button labels,\n menu item labels/trailing text, select labels/option labels, and snackbar text/action label. Missing, object or array values become empty text. Other braces\n stay literal. A data string is inserted as plain text before repeat and state binding, so\n `{item.x}`, `{index}` or `{key}` inside it bind afterwards exactly like authored text.\n Data values cannot be escaped; inserted strings are never scanned again for data placeholders.\n Pointers are untouched by component props.\n- `MAX_PROTOTYPE_SUBSTITUTED_TEXT_LENGTH` (16384) bounds the sum of replacement UTF-16\n lengths per bindable field at each stage: data in text-kind fields, then repeat in all bindable\n fields for every item, including repeat placeholders inserted by data. Literal characters and\n unresolved repeat placeholders contribute zero. State placeholders are not validated because\n state can change after show. Exceeding the cap fails at the authored field path with\n `Substituted text length limit exceeded`.\n `MAX_PROTOTYPE_SUBSTITUTED_TEXT_TOTAL` (4194304) also bounds rebuilt text per validation: each\n recognized data stage and each repeat item charges authored stage length plus replacement length,\n including literal units and placeholder tokens. Inside a repeat, a data-resolved field is also\n charged once per item, even without repeat placeholders. Purely literal fields and state\n placeholders are not charged. Crossing the total fails at that field with `Substituted text total limit exceeded`.\n During state interpolation, a replacement that would exceed the per-call substitution limit stays\n as written, and later placeholders may still substitute.\n- A condition uses exactly one of `key`, `data`, `platform`, `valid`, `all`, `any`, `not`. A data condition has exactly\n one comparison: `equals` (same scalar type and value), `notEquals` (its inverse, including missing\n or non-scalar), `gt` or `lt` (numbers only, otherwise false), or `empty` (data only). `equals`/`notEquals` operands are\n literals; repeat placeholders there are rejected. Key forms also accept `contains`, `startsWith`, `lengthGt` or `lengthLt` (see string conditions). `bottomSheet.openWhen` remains boolean state.\n\nThe host validates data and repeat paths; the device resolves bindings once per show before\nrepeat expansion. All data uses require `prototype_data_model_v1`; an older device is refused\nbefore uploads or show, with an update/relaunch hint. `status` reports the last successful show's\ndata next to state; `inspect` reports and adopts device data. Absent data is omitted; dismiss\nclears it. Events carry data only as the value of a device data write (see Data actions).\n",hi=`## Reuse: components
|
|
542
|
-
|
|
543
|
-
A top-level \`components\` map names node templates; a \`use\` node places one anywhere a node goes.
|
|
544
|
-
The host expands every \`use\` before validating and sending, so devices only see plain nodes and
|
|
545
|
-
every limit counts the expanded tree.
|
|
546
|
-
|
|
547
|
-
\`\`\`json
|
|
548
|
-
{
|
|
549
|
-
"id": "feed",
|
|
550
|
-
"window": { "placement": { "type": "fullscreen" } },
|
|
551
|
-
"state": { "liked_a": false, "liked_b": true },
|
|
552
|
-
"components": {
|
|
553
|
-
"postCard": {
|
|
554
|
-
"root": {
|
|
555
|
-
"type": "card",
|
|
556
|
-
"children": [
|
|
557
|
-
{ "type": "text", "text": "{props.name}" },
|
|
558
|
-
{ "type": "button", "label": "Like", "onTap": [{ "type": "toggle", "key": "{props.likeKey}" }] }
|
|
559
|
-
]
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
},
|
|
563
|
-
"root": {
|
|
564
|
-
"type": "column",
|
|
565
|
-
"children": [
|
|
566
|
-
{ "type": "use", "component": "postCard", "props": { "name": "Alexey", "likeKey": "liked_a" } },
|
|
567
|
-
{ "type": "use", "component": "postCard", "props": { "name": "Bea", "likeKey": "liked_b" } }
|
|
568
|
-
]
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
\`\`\`
|
|
572
|
-
|
|
573
|
-
- A \`use\` node has only \`type\`, \`component\` and \`props\`; props are scalars (string, number,
|
|
574
|
-
boolean). \`{props.<field>}\` binds in the same fields as repeat placeholders, state keys included,
|
|
575
|
-
and a string that is exactly one placeholder keeps the prop's type.
|
|
576
|
-
- A component may contain \`repeat\` and other \`use\` nodes. A \`use\` inside a repeat template may
|
|
577
|
-
pass item placeholders as props (\`"likeKey": "liked_{item.id}"\`); the repeat binds them later.
|
|
578
|
-
- Rejected: an unknown component, a missing or unused prop, a non-scalar prop, a cycle (including
|
|
579
|
-
a component that uses itself) and \`use\` nesting deeper than its limit (see Limits).
|
|
580
|
-
- An error inside an expansion names each \`use\` it went through, for example
|
|
581
|
-
\`root.children[2] (use postCard) \u2192 components.postCard.root.children[1].label\`.
|
|
582
|
-
`,fi=`## Style polish
|
|
583
|
-
|
|
584
|
-
Glass: style.surface "glass" and strict style.glass {variant?:regular|clear,tint?:colour,interactive?:boolean} need prototype_glass_v1 (iOS 26+ only today; older iOS and Android refuse it). glass requires surface "glass" in the same style, including styleWhen; cornerRadius shapes it, absent means capsule. ios.glassGroup {spacing:0..200} is for column/row/box/flow/grid/list/listItem; descendant glass shared keys morph in their nearest group, must be unique there, cannot collide with visibility-pair keys, and require repeat.key templates under repeat (including the repeated node). ios.glassUnion (ASCII id, 1..64), ios.glassTransition matchedGeometry|materialize|identity need a base glass surface; ios.backgroundExtension:true is image-only. All four ios glass keys are node-only, invalid in window.ios/theme.ios. All four need only the glass gate on iOS; other ios keys still need the unadvertised platform namespace gate; Android ignores ios fields with platformNotes paths. Android rendering is deferred, with real blur required at API 31+ and no glass below API 31. scroll.edgeEffect soft|hard|none needs prototype_scroll_edge_effect_v1: iOS 26 native; older iOS shares fadeEdges (24/8 dp defaults, authored lengths win, none disables only the edge effect and its default fallback; explicit fadeEdges still apply). System accessibility settings control glass appearance; assert structure/bounds.
|
|
585
|
-
|
|
586
|
-
Layered style.shadows (1-3 strict {color,radius,spread?,offset?,inner?}, radius 0-1000 dp, spread and offset axes -1000..1000; omitted spread/offset/inner mean 0/{x:0,y:0}/false), style.cornerStyle circular|continuous (default circular), style.border {width,color? ,gradient?} with exactly one of color or gradient, scroll.fadeEdges {top?,bottom?,start?,end?} (0-1000 dp, at least one), and image.filter {saturation?,tint?} (saturation 0-2, at least one) require prototype_style_polish_v2. shadows excludes elevation and shadowColor. Fades appear only where scrolling remains; start/end mirror in RTL. Colour pairs in shadows and tint, and pairs or role names in border gradient stops also require prototype_theme_modes_v1.
|
|
587
|
-
|
|
588
|
-
Rendering order: transform, press scale, size, alpha, drop shadows (shadows/elevation before the clip), clip (cornerRadius + cornerStyle), background, gradient, shimmer, border (color or gradient), inner shadows.
|
|
589
|
-
|
|
590
|
-
## Light and dark mode
|
|
591
|
-
|
|
592
|
-
Theme design: \`theme.design\` accepts \`material\` or \`platform\` (default). Explicit platform
|
|
593
|
-
requires \`prototype_design_platform_v1\`; omission silently keeps today's drawing on older renderers.
|
|
594
|
-
Android platform look is Material. On iOS button, slider, datePicker and timePicker already use
|
|
595
|
-
native controls; layout/content nodes are neutral and other nodes retain Material drawing.
|
|
596
|
-
Explicit platform requests report \`design.fallback\` notes for those nodes (first 20 paths, plus
|
|
597
|
-
\`total\` beyond); omitted design and material do not. See the contract's \`designCoverage\` table.
|
|
598
|
-
|
|
599
|
-
A shown prototype has exactly one resolved mode, light or dark. Roles, per-mode values and the
|
|
600
|
-
scheme all read that one mode, on Android and on iOS.
|
|
601
|
-
|
|
602
|
-
Authoring, in order of preference:
|
|
603
|
-
|
|
604
|
-
- **Roles.** Use a colour role name instead of a hex value wherever a colour goes. A role already
|
|
605
|
-
has a light and a dark value, so nothing else is needed.
|
|
606
|
-
- **\`{light, dark}\` pairs.** For a brand literal that needs a hand-picked dark value, a colour
|
|
607
|
-
field, gradient stop or scrim takes \`{"light": "#FFFFFF", "dark": "surfaceContainer"}\`: both
|
|
608
|
-
sides required, each a hex value or a role. An image takes \`{"light": assetId, "dark": assetId}\`;
|
|
609
|
-
upload both assets.
|
|
610
|
-
- **Theme maps.** \`theme.colors.<role>\` overrides a role in both modes. \`theme.colors.light\` and
|
|
611
|
-
\`theme.colors.dark\` are \`{<role>: hex}\` maps applied after the flat overrides, for the resolved
|
|
612
|
-
mode only.
|
|
613
|
-
- **Scrims.** In a scrim slot (\`window.placement.scrim\`, a bottomSheet \`scrim\`) only the \`scrim\`
|
|
614
|
-
role is drawn translucent, at 0.4 alpha. Any other role is drawn unchanged, so it covers what is
|
|
615
|
-
behind it.
|
|
616
|
-
|
|
617
|
-
Pairs, theme maps and role names in gradient stops and scrims need a device advertising
|
|
618
|
-
\`prototype_theme_modes_v1\`; a show that uses them on an older device is refused.
|
|
619
|
-
|
|
620
|
-
How the mode is resolved. The first step that applies decides, and is reported as \`source\`:
|
|
621
|
-
|
|
622
|
-
1. \`theme.mode\` \`light\` or \`dark\` (\`explicit\`).
|
|
623
|
-
2. The luminance of the flat \`theme.colors.background\` override, else \`theme.colors.surface\`
|
|
624
|
-
(\`roleLuminance\`). The per-mode maps never take part.
|
|
625
|
-
3. The first opaque hex background on the root's leading chain (\`authoredBackground\`). A role or
|
|
626
|
-
a pair depends on the mode, so it cannot decide it.
|
|
627
|
-
4. The system setting: the show's \`appearance\` when it is \`light\` or \`dark\` (\`override\`), else
|
|
628
|
-
the device's own setting (\`system\`).
|
|
629
|
-
|
|
630
|
-
\`theme.mode: "system"\` asks for the system setting outright and skips steps 2 and 3.
|
|
631
|
-
|
|
632
|
-
Checking both modes without touching the device: \`show\` takes \`appearance: "device" | "light" |
|
|
633
|
-
"dark"\` (default \`device\`).
|
|
634
|
-
|
|
635
|
-
\`\`\`json
|
|
636
|
-
{ "action": "show", "appearance": "dark", "spec": { "id": "demo", "window": { "placement": { "type": "fullscreen" } }, "root": { "type": "text", "text": "Hello" } } }
|
|
637
|
-
\`\`\`
|
|
638
|
-
|
|
639
|
-
- The override replaces the system setting only (step 4). It does not beat an explicit
|
|
640
|
-
\`theme.mode\`, a flat \`background\`/\`surface\` override or an opaque authored background; the
|
|
641
|
-
reported \`source\` says which step won.
|
|
642
|
-
- It belongs to that show: a later show of the same id without \`appearance\` follows the device
|
|
643
|
-
again. The device and the app behind the prototype are not changed.
|
|
644
|
-
- \`light\` and \`dark\` need a device advertising \`prototype_appearance_v1\` and are refused, with
|
|
645
|
-
nothing shown, on one that does not. \`device\` works everywhere.
|
|
646
|
-
|
|
647
|
-
To test a spec: show it with \`appearance: "dark"\`, \`observe\`, then show it again with
|
|
648
|
-
\`appearance: "light"\` and \`observe\`. To put the app behind the prototype into the same mode as
|
|
649
|
-
well, set the device with \`displayConfig\` and restore the \`previous\` value it returns when done.
|
|
650
|
-
|
|
651
|
-
What the device reports (\`prototype_appearance_v1\`; absent on a device without it):
|
|
652
|
-
|
|
653
|
-
- A successful show returns \`lastResult.appearance: {mode, source, deviceDark}\`, and \`inspect\`
|
|
654
|
-
carries the same object on each prototype; after a show crossed by an \`appearance_changed\`
|
|
655
|
-
event, the status entry has no appearance until a later event or \`inspect\` states it.
|
|
656
|
-
\`deviceDark\` is the device's own setting whatever
|
|
657
|
-
decided \`mode\`. Only a device answer states it, and only for the moment it answered: the show
|
|
658
|
-
result and \`inspect\`. \`status\` is host-local, so it reports \`mode\` and \`source\` (kept current by
|
|
659
|
-
\`appearance_changed\` events) and never \`deviceDark\`, because the device can flip while a pinned
|
|
660
|
-
mode stays put and then no event arrives. Call \`inspect\` when you need it now.
|
|
661
|
-
- While a prototype is shown it follows the device live. Any change of the resolved mode (the
|
|
662
|
-
device flipping, or prototype state changing a background the mode is inferred from) sends one
|
|
663
|
-
\`appearance_changed\` event with a null \`name\` and the payload \`{mode, source}\`, and refreshes
|
|
664
|
-
\`status\`. Wait for it with \`awaitEvent\` and \`kind: "appearance_changed"\`. Nothing is sent when
|
|
665
|
-
the mode stays the same, nor for the show itself, whose result already carries the mode.
|
|
666
|
-
|
|
667
|
-
Input and state changes (text input, toggles, sliders etc.) arrive as kind \`emit\` with \`eventName\` \`change\` (there is no separate \`change\` kind), with payload \`{key,value}\` for one changed key or \`{keys,values}\` for several.
|
|
668
|
-
`,yi=`## Runtime cost
|
|
669
|
-
|
|
670
|
-
What each construct costs on a device, so a large prototype can pick the cheap form. This is
|
|
671
|
-
guidance read from the renderer code, not measurement: the Android renderer (Jetpack Compose) and
|
|
672
|
-
the iOS agent (SwiftUI) were read, and no statement below has been measured on a device. The only
|
|
673
|
-
measurement behind it is epic #12127: a prototype of several hundred nodes on a debug build of the
|
|
674
|
-
Android renderer dropped frames on tab switches, section collapses and page swipes. It predates
|
|
675
|
-
the fixes noted below and gives no per-construct cost. A row marked *being changed* describes
|
|
676
|
-
today's behaviour; the issue it names is open and the row will shrink when it lands.
|
|
677
|
-
|
|
678
|
-
What one state change costs:
|
|
679
|
-
|
|
680
|
-
- **Android.** Every state write publishes one new snapshot. The render tree is mapped once per
|
|
681
|
-
snapshot: every node is visited, hidden ones included, and its \`visibleWhen\`, \`styleWhen\` and
|
|
682
|
-
\`{key}\` text are evaluated against the new state. A node whose result equals the previous one
|
|
683
|
-
is reused as the same object, so only the nodes that changed recompose (#12162). The mapping is
|
|
684
|
-
proportional to the node count; the recomposition to the nodes that changed.
|
|
685
|
-
- **Android, validation.** A state write is validated by re-checking the new state and the nodes
|
|
686
|
-
that bind a key, not by re-encoding and re-validating the whole spec (#12162). The whole spec is
|
|
687
|
-
checked once, on the first write after a \`show\` or a replace. A tap with several
|
|
688
|
-
\`setState\`, \`toggle\` or \`increment\` actions validates each of them in turn before anything
|
|
689
|
-
is applied.
|
|
690
|
-
- **iOS.** Every node view reads the prototype's state, so a state change re-evaluates the body of
|
|
691
|
-
each node on screen and SwiftUI's diffing decides what is redrawn. Each write also re-validates
|
|
692
|
-
the whole tree (every node, in several passes) and re-encodes the state to check the size cap;
|
|
693
|
-
iOS has no equivalent of the Android state-only validation.
|
|
694
|
-
- A tap's action list sends one \`change\` event with the final state, however many keys it wrote.
|
|
695
|
-
|
|
696
|
-
Authoring choices:
|
|
697
|
-
|
|
698
|
-
- **Writes.** Each \`setState\` in a tap is its own validation and its own state snapshot on
|
|
699
|
-
Android. Prefer one key that several nodes read (a selected tab index that \`visibleWhen\` and
|
|
700
|
-
\`styleWhen\` compare against) over several keys set together. Whether snapshots published in
|
|
701
|
-
one frame are mapped separately depends on frame timing; one key avoids the question.
|
|
702
|
-
- **\`styleWhen\` over two \`visibleWhen\` siblings.** On Android a node with \`visibleWhen\` is
|
|
703
|
-
wrapped in an animation container while motion is on; iOS keeps an equivalent container. Two
|
|
704
|
-
siblings with opposite \`visibleWhen\` conditions that cross-fade cost two such wrappers; one
|
|
705
|
-
node whose look changes with \`styleWhen\` costs none, because the style is merged into the
|
|
706
|
-
node's own modifiers.
|
|
707
|
-
- **\`visibleWhen\` transition.** The default transition (no \`transition\`, or \`expand\`) animates
|
|
708
|
-
the node's size, which re-measures its siblings while it runs. Use \`transition: "fade"\`,
|
|
709
|
-
\`"slide"\` or \`"none"\` unless the size change is the point. *Being changed (#12136):* every
|
|
710
|
-
\`box\`, \`row\`, \`column\`, \`flow\` and \`grid\` also animates its own size whenever its children change while
|
|
711
|
-
motion is on, so a size change below a container is animated by that container whatever
|
|
712
|
-
transition the child chose. iOS does the same per container, from a layout signature computed
|
|
713
|
-
from the container's children on each state change.
|
|
714
|
-
- **Hidden subtrees.** A node hidden by \`visibleWhen\` costs nothing at rest on either platform:
|
|
715
|
-
its subtree is not composed (Android) or not built (iOS). It is built in the frame in which it
|
|
716
|
-
becomes visible, so a large subtree behind \`visibleWhen\` can make that one frame slow; keep
|
|
717
|
-
such subtrees small, or split the prototype. *Being changed (#12133):* on Android a hidden
|
|
718
|
-
subtree is disposed when hidden and rebuilt when shown, and a pager page other than the current
|
|
719
|
-
one is not composed until it is swiped to.
|
|
720
|
-
- **\`pressScale\`.** On Android it adds an animated press state and a graphics layer to each
|
|
721
|
-
tappable node that sets it, so put it on buttons, not on every row. On iOS every node with
|
|
722
|
-
\`onTap\`, \`onLongPress\` or \`onDoubleTap\` already has the press gesture, a minimum touch target and a scale effect whether or
|
|
723
|
-
not it sets \`pressScale\`, so \`pressScale\` adds nothing there.
|
|
724
|
-
- **Images.** On Android each \`image\` node is a sub-composition that asks the image cache for a
|
|
725
|
-
bitmap sized to the node, so many small images in a list cost more than one strip image. Decode
|
|
726
|
-
is cached and runs off the main thread. Further per-recomposition work in images and icons is
|
|
727
|
-
*being changed (#12138)*. The iOS image path was not checked.
|
|
728
|
-
- **Accessibility nodes.** On Android a decorative \`icon\` or \`image\` (not tappable,
|
|
729
|
-
no \`testTag\`, no \`contentDescription\`) reports no node, except inside a tappable node with
|
|
730
|
-
no text of its own and no \`contentDescription\`, where icons and images keep their node and label
|
|
731
|
-
because they are the only way to find it. A tappable \`box\`,
|
|
732
|
-
\`row\`, \`column\`, \`flow\`, \`grid\` or \`card\` whose only text is one \`text\` node is one node
|
|
733
|
-
labelled by that text when its descendants have no independent tags, actions, descriptions,
|
|
734
|
-
controls or visibility conditions. Other non-tappable text, icon and image nodes are never labelled
|
|
735
|
-
with their kind; empty tappable ones keep the kind as their only selector handle. An unlabelled,
|
|
736
|
-
non-tappable layout container (\`box\`, \`row\`, \`column\`, \`flow\`, \`grid\`, \`scroll\`, \`pager\`, \`card\`,
|
|
737
|
-
\`divider\`, \`spacer\`) with no text, \`testTag\`, content description or state also reports
|
|
738
|
-
no node. Every text, tagged node and tappable node stays targetable. Give a \`testTag\` only to
|
|
739
|
-
nodes you will look up. Every accessibility node is work whenever \`observe\` or a screen reader
|
|
740
|
-
reads the tree.
|
|
741
|
-
- **Reserved \`testTag\` prefix.** A \`testTag\` cannot start with \`automobile-\`: the host's own dismiss
|
|
742
|
-
controls use \`automobile-prototype-dismiss\`, and a spec that takes one is rejected with the node's path.
|
|
743
|
-
\`tapOn\` keeps its point off those controls, or fails naming one that covers the whole target.
|
|
744
|
-
- **Long lists.** A \`scroll\` node builds all of its children up front on both platforms, so a
|
|
745
|
-
long list inside \`scroll\` pays for every row when it is shown. *Being changed on Android
|
|
746
|
-
(#12139).* \`repeat\` expands to real nodes that count against the node limit.
|
|
747
|
-
- **\`motion: "none"\`.** It removes the visibility animations, size animations and press springs
|
|
748
|
-
(changes become instant) and a hidden \`visibleWhen\` node is simply absent, so it is the right
|
|
749
|
-
choice for automated checks. Motion is also off when Android animator or transition scale is 0. The reduced profile
|
|
750
|
-
keeps fades and color/alpha animation while removing spatial movement and ambient loops.
|
|
751
|
-
- **Layout direction.** Set \`window.layoutDirection\` to \`rtl\` or \`ltr\` on iOS to override the prototype layout without changing the system locale or translating text. Omit it to follow the host. Requires \`prototype_layout_direction_v1\`; Android refuses specs that set it.
|
|
752
|
-
- **Window format.** On Android an opaque fullscreen prototype is still composited as a
|
|
753
|
-
translucent layer, whatever the spec says. *Being changed (#12140).*
|
|
754
|
-
- **Accessibility events.** The Android accessibility service resolves an event's window type once
|
|
755
|
-
per window rather than once per event (#12160), so a prototype that changes a lot no longer
|
|
756
|
-
pays that lookup on every change event. Throttling the events a prototype's own window emits is
|
|
757
|
-
*being changed (#12134)*.
|
|
758
|
-
- **Size.** The node count and the spec bytes are both limited (see Limits) and both drive the
|
|
759
|
-
per-change work above. No tested budget exists yet; for a prototype of several hundred nodes
|
|
760
|
-
every rule above matters, so split it well before it nears the limits.
|
|
761
|
-
`,gi='## Common validation errors\n\n| Message | Fix |\n| --- | --- |\n| `Unknown prototype icon name` | Look the name up with `automobile:prototype/icons?query=<word>`. |\n| `Expected object` / `Invalid data value` | Data must be an object of nested JSON values without null or nonfinite numbers. |\n| `Data depth limit exceeded` / `Data array limit exceeded` / `Data byte limit exceeded` | Reduce data to the generated limits. |\n| `Invalid pointer value` | Use a nonempty RFC 6901 pointer within the pointer limit. |\n| `Repeat path does not resolve to an array` / `Repeat path resolves to more than 128 items` / `Repeat path item <i> is not an object` | Point to an array of objects within the repeat item limit. |\n| `Duplicate repeat key "x" (items <i> and <j>)` | Give every item a unique rendered identity. |\n| `Bound state key "x" is invalid (repeat item <i>)` | A path-bound key must form a valid state key; error is at repeat.items.path. |\n| `Requires key or data or platform` | Supply one condition source with exactly one comparison. |\n| `Repeat path cell limit exceeded` | Reduce path-bound repeats or the scalar members projected per item; see `MAX_PROTOTYPE_REPEAT_PATH_CELLS`. |\n| `Substituted text total limit exceeded` | Reduce bindable fields, replacement lengths or repeat items; see `MAX_PROTOTYPE_SUBSTITUTED_TEXT_TOTAL`. |\n| `Repeat placeholder in a data condition operand is not supported` | Use a literal operand; state conditions still bind repeat operands. |\n| `Unknown repeat field "x"` | Every item needs the field the placeholder names. |\n| `Missing component prop "x"` / `Unused component prop` | Pass exactly the props the component\'s `{props.*}` placeholders name. |\n| `Expanded node limit exceeded` | Fewer items or a smaller template; ordinary repeats count every instance; lazy list templates count once. |\n| `maxRuns requires everyMs` | Supply everyMs or remove maxRuns. |\n| `Too many distinct timer ids` | Use at most eight distinct startTimer ids, including nested actions and components. |\n| a `stateKey` rejected | The key must be initialised in `state` with the type the node binds (string, boolean, number). |\n| an unknown property | Nodes and actions are strict: only the fields listed above are accepted. |\n\nPaths in errors (for example `root.children[0].text`) point at the offending value in the spec.\n',bi=`### Patch (#11675)
|
|
762
|
-
|
|
763
|
-
Use \`show\` for a new screen or a window, theme or root change. Use \`patch\` for
|
|
764
|
-
content (\`/data\`), state (\`/state\`) or one node by id (\`replaceNode\`). Android CtrlProxy advertises
|
|
765
|
-
\`prototype_patch_v1\` and applies patches in place; the iOS prototype agent advertises it too
|
|
766
|
-
(a relaunched app loads the current agent), so an older agent still needs the whole spec with \`show\`.
|
|
767
|
-
|
|
768
|
-
\`{action:"patch", id, ops, baseRevision?}\` sends a \`patch_prototype\` frame
|
|
769
|
-
\`{requestId, id, baseRevision?, ops}\` only to a device advertising
|
|
770
|
-
\`prototype_patch_v1\`. Android and iOS use \`prototype_result\` replies. Success
|
|
771
|
-
carries \`revision\`; a state conflict carries
|
|
772
|
-
\`{success:false,error,conflict:{revision,state:{key:scalar}}}\`. Revisions are
|
|
773
|
-
non-negative safe integers; conflict values are strings, booleans or finite
|
|
774
|
-
numbers with valid state keys. Malformed reply fields are dropped. Status and
|
|
775
|
-
inspect entries carry \`revision\` (the newest from a landed patch or a device
|
|
776
|
-
/data write, absent until one arrives) and \`lastAction: "patch"\` once a patch lands.
|
|
777
|
-
|
|
778
|
-
Ops apply in order, completely or not at all. \`add\`, \`replace\`, \`remove\` and
|
|
779
|
-
\`test\` address \`/data\` or \`/data\` followed by an RFC 6901 JSON pointer: \`~0\`
|
|
780
|
-
escapes \`~\`, \`~1\` escapes \`/\`; array indices are canonical non-negative decimal
|
|
781
|
-
integers, and \`-\` appends for \`add\` only. Parent paths must exist. \`replace\`,
|
|
782
|
-
\`remove\` and \`test\` require the addressed value to exist. \`add\`, \`replace\` and
|
|
783
|
-
\`test\` carry \`value\`; \`remove\` does not. State ops address exactly
|
|
784
|
-
\`/state/<key>\`, where keys match \`[A-Za-z_][A-Za-z0-9_]{0,63}\` and values are
|
|
785
|
-
strings, booleans or finite numbers.
|
|
786
|
-
|
|
787
|
-
\`replaceNode\` carries \`{op:"replaceNode",id,node}\`. The id must identify exactly
|
|
788
|
-
one node in the tree, cannot be the root or inside a repeat, and the replacement
|
|
789
|
-
must keep that id. Replacement nodes cannot contain \`use\` nodes or element
|
|
790
|
-
anchors. Inline the component, use a bounds anchor, or use \`show\`.
|
|
791
|
-
|
|
792
|
-
The agent writes data; the user writes state. Data-only patches and patches
|
|
793
|
-
containing only data ops and \`replaceNode\` ignore \`baseRevision\`, until the device has
|
|
794
|
-
written the prototype's data with a data action (\`prototype_data_actions_v1\`): from then on a
|
|
795
|
-
\`/data\` op also needs \`baseRevision\` and conflicts with newer overlapping device writes (see
|
|
796
|
-
Data actions). Any state op, including \`test\`, requires \`baseRevision\`. A device supporting the capability
|
|
797
|
-
must refuse the whole patch with \`conflict\` if the user changed a touched state
|
|
798
|
-
key since that revision, returning the current revision and those keys' values.
|
|
799
|
-
|
|
800
|
-
There are at most ${Fk} ops, the frame is capped at ${ua/1048576} MiB, and the resulting whole
|
|
801
|
-
spec must satisfy every spec/data limit, including node count and depth. The
|
|
802
|
-
host tracks a cloned copy of each id's device spec from its last acknowledged show,
|
|
803
|
-
with components expanded and anchors resolved. It applies ops to a copy and
|
|
804
|
-
runs the full validator before sending. Errors preserve deterministic paths.
|
|
805
|
-
The host validates state ops against the agent-declared state and leaves value
|
|
806
|
-
comparison for \`/state\` \`test\` to the device; its copy cannot know user edits.
|
|
807
|
-
|
|
808
|
-
Patches are FIFO per device, with one in flight at a time. A pending show makes
|
|
809
|
-
patch refuse as busy. Shows are not delayed by patches. If a dispatched show
|
|
810
|
-
and an acknowledged patch overlap, their device-side order is unknown: the host
|
|
811
|
-
forgets its spec, warns, and requires a further successful show before patching.
|
|
812
|
-
A failed dispatched show, dismissed event, successful dismiss, session release,
|
|
813
|
-
device removal or unbinding also ends tracking. Inspect retains each reported tracked id
|
|
814
|
-
and drops missing ids; adopted siblings do not end its tracking. A fifth-surface refusal
|
|
815
|
-
with \`replaceOthers: false\` also retains the acknowledged specs. A transport failure after
|
|
816
|
-
patch dispatch is indeterminate and requires a new show. An atomic device
|
|
817
|
-
refusal leaves the tracked copy unchanged. A successful patch refreshes shown
|
|
818
|
-
status data without changing \`lastResult\`, timestamps or event snapshots.
|
|
819
|
-
`,_r='## Checks\n\nDevices advertising `prototype_checks_v1` evaluate declarative checks locally. The host refuses\nshow and patch results using this feature on older devices. Inputs `textField`, `slider`,\n`checkbox`, `switch`, `radioGroup`, `datePicker` and `timePicker` accept `checks` (1\u20138 entries)\nand `validateOn: "change" | "blur" | "submit"` (omitted means blur). Each check contains a\nnonempty `message` and exactly one rule. `validateOn` controls error display, never validity.\nThe first failing message is displayed.\n\n- `required: true`: trimmed nonempty text, true for checkbox/switch, nonempty selection for\n radioGroup/datePicker, present number for slider/timePicker.\n- `minLength` / `maxLength`: nonnegative integer UTF-16 lengths, textField only.\n- `min` / `max`: finite numeric inclusive bounds, slider and pickers only. Text fields hold\n strings and have no numeric subtype. Date state remains YYYY-MM-DD; bounds are UTC epoch\n milliseconds. Time pickers retain hourKey/minuteKey; checks apply independently to both keys.\n- `format`: textField only, one of email, phone, digits, decimal, url.\n- `pattern`: textField only, the restricted grammar below, at most 128 UTF-16 units.\n\nEmpty string, null or missing value passes all rules except required. Whitespace is only empty\nfor required. Pattern and format matching use at most 4096 UTF-16 units. Required and length checks inspect the complete value.\nEvery validity reference must name declared state with at least one check. Multiple checked\ncontrols sharing a key must all pass. Numeric/length lower bounds must not exceed upper bounds.\n\nFormats use these exact whole-value expressions (ASCII digits):\n\n- email: `[^\\s@]+@[^\\s@]+\\.[^\\s@]+` (Unicode names allowed).\n- phone: optional leading +, then 7\u201315 characters from ASCII digits, space, hyphen and parentheses;\n at least seven digits. The leading + is outside the character count. Punctuation need not balance.\n- digits: `[0-9]+`.\n- decimal: `-?[0-9]+(\\.[0-9]+)?` (no exponent or leading +).\n- url: `https?://[^\\s/?#]+([/?#]\\S*)?` (lowercase scheme, Unicode hosts allowed).\n\nFormat whitespace follows JavaScript whitespace (including NBSP); no format trims its value.\nPatterns use ASCII `\\d`, `\\w`, `\\s` and their complements `\\D`, `\\W`, `\\S`; `\\w` is\n`[A-Za-z0-9_]` and `\\s` is space, tab, CR, LF, FF, VT. Dot matches one Unicode scalar except\nCR, LF, U+2028 and U+2029. Matching consumes the entire value, even with a final newline.\nAllowed: literals, dot, classes `[abc]` / `[^abc]`, literal ranges, those six shorthand escapes,\nescaped metacharacters, anchors ^ $, groups `(\u2026)` / `(?:\u2026)`, alternation |, and quantifiers\n`? * + {n} {n,} {n,m}`. Every written bound is <=100 and n<=m; open upper bounds are unbounded.\nReject backreferences, lookahead/behind, named groups, lazy/possessive quantifiers, Unicode\nproperties, inline flags, word boundaries `\\b` / `\\B`, and every other escape (including\n`\\n`, `\\x`, `\\u`; use literal characters). Empty classes are rejected. A group repeated more\nthan once cannot contain alternation or any variable quantifier (maximum > minimum), transitively.\nAt most two variable quantifiers are allowed in the entire pattern: ? * + {n,} and {n,m} when\nm>n. Fixed {n} quantifiers inside repeated groups remain allowed.\nThus `(a|b)+`, `(a+)+`, `(a*)*` and `((ab)+)+` are rejected. Optional groups remain allowed.\nThese exact rules and error substrings are pinned in the language-neutral checks fixtures.\n\nConditions `{valid: "email"}` and `{valid: ["email", "password"]}` mean all referenced keys\nare valid, including fields whose errors are not yet shown. They compose with all/any/not in\nvisibleWhen, styleWhen and enabledWhen. enabledWhen is supported on the seven input types plus\nbutton, iconButton, fab, chip and listItem; false disables the control and skips its onTap.\n`emit` may specify `requireValid: ["email", "password"]` (1\u20138 keys). Any failing key aborts the\nwhole action list atomically, shows errors on every listed field, and sends\n`{kind:"validation_failed", keys:[\u2026]}` naming only the failing keys. `change` events carry\n`validity: {key:boolean}` for checked keys. Both event kinds retain the usual event envelope.\n';var rp={device:{tools:["rotate","displayConfig","setPosture","windowMode"],note:"orientation, window size, posture and windowing mode update `/platform/device`; `device.changed` fires only when a size class, posture or idiom changes (on iOS, only width class or idiom), so a rotation that keeps the size class sends no event"},realtime:{tools:[],note:"the channel's server drives frames and status; no device tool"},haptics:{tools:[],note:"assert the call's `prototype_platform` outcome"},sound:{tools:[],note:"assert the call's `prototype_platform` outcome"},clipboard:{tools:["clipboard"],note:"set the clipboard before `paste`/`hasText`; read it after `copy`"},share:{tools:["observe","tapOn"],note:"drive the system share sheet"},battery:{tools:["setDeviceState"],note:"`power.battery` level and charging (Android)"},power:{tools:["setDeviceState"],note:"`power.batterySaver` and `power.thermalStatus` (Android)"},audio:{tools:["mediaSession"],note:"stream volume (Android)"},connectivity:{tools:["setDeviceState"],note:"`connectivity` toggles and `networkCondition`"},biometric:{tools:["biometricAuth","setDeviceState"],note:"match or fail a prompt; `biometrics.enrollment` on an iOS Simulator"},settings:{tools:["observe","pressButton"],note:"confirm the settings screen, then go back"},contacts:{tools:["observe","tapOn"],note:"pick in the system picker"},calendar:{tools:["observe","tapOn"],note:"save or cancel in the system editor"},links:{tools:["observe"],note:"confirm the opened app or browser"},mediaLibrary:{tools:["putAppFile","setAppPermissions"],note:"stage photos in the `media_library` domain; grant or revoke access"},camera:{tools:["setDeviceState","setAppPermissions"],note:"`cameraPoster` sets what the emulated camera sees"},auth:{tools:["observe","tapOn"],note:"complete the provider's sign-in screen"},location:{tools:["setDeviceState","setAppPermissions","systemAlerts"],note:"`location` fix or route; grant access or answer the prompt"},commerce:{tools:["observe","tapOn"],note:"complete the store purchase sheet"},secureStorage:{tools:[],note:"read `/platform/secureStorage/locked`; no device tool"},sensors:{tools:["setSensor","shake"],note:"emulator sensor values and a shake gesture"},map:{tools:["tapOn","swipeOn"],note:"tap markers and pan the map"},webview:{tools:["observe","tapOn"],note:"page content is in the accessibility tree; tap a link to navigate"},audioRecorder:{tools:["injectAudioInput","setAppPermissions"],note:"feed known audio into the microphone"},notifications:{tools:["systemTray","setAppPermissions"],note:"open, act on, reply to or dismiss a posted notification; `notificationsEnabled` blocks the whole app, while a single channel is blocked only in system Settings (`observe`, `tapOn`)"},permissions:{tools:["setAppPermissions","systemAlerts"],note:"grant or revoke before reading `/platform/permissions`; answer the prompt a `request` raises"},media:{tools:["mediaSession"],note:"headset transport keys and session state (Android)"},cast:{tools:[],note:"needs a real receiver on the network; no device tool"}};function wi(n=rp){return["To test a module for real, drive the device with these tools, then assert with `awaitEvent` and `observe`:","","| Module | Tools | What they drive |","| --- | --- | --- |",...Object.entries(n).map(([i,a])=>{let s=a.tools.map((d)=>`\`${d}\``).join(", ")||"-";return`| \`${i}\` | ${s} | ${a.note} |`})].join(`
|
|
820
|
-
`)}var Ce=V.definitions;function op(n){let i=n.min!==void 0||n.max!==void 0?` ${n.min??0}..${n.max??"n"}`:"";return`${xn(n.item??{kind:"value"})}[]${i}`}function xn(n){switch(n.kind){case"enum":return(n.values??[]).join("|");case"ref":return n.name??"ref";case"boundKey":return"key";case"strings":return"strings";case"screenMap":return`screen-name \u2192 node (${n.min}..${n.max} entries)`;case"array":return op(n);case"choice":return(n.options??[]).map(xn).join(" or ");default:return n.kind}}function Cr(n,o){return`${n}${o.optional?"":"*"}: ${xn(o.rule)}`}function ip(n){let o=Object.values(n),[i,...a]=o,s=new Map;for(let[d,l]of Object.entries(i?.fields??{}))if(a.every((u)=>JSON.stringify(u.fields?.[d])===JSON.stringify(l))&&d!=="type")s.set(d,l);return s}function vi(n,o){return Object.entries(n).map(([i,a])=>{let s=Object.entries(a.fields??{}).filter(([d])=>d!=="type"&&!o.has(d)).map(([d,l])=>Cr(d,l));return`- \`${i}\`${s.length>0?`: ${s.join(", ")}`:""}`})}var $e=(n)=>n.map((o)=>`\`${o}\``).join(", ");function vn(n,o){return(Ce[n]?.fields?.[o]?.rule.values??[]).map(String)}function ap(){let n=Object.entries(V.limits).map(([a,s])=>`| \`${a}\` | ${s} |`),o=["onTap","onLongPress","onDoubleTap","onAppear"],i=Ce.repeat.fields?.items.rule??{};for(let a of o){let s=Ce.node.variants?.box.fields?.[a].rule??{};n.push(`| actions per \`${a}\` | ${s.min}..${s.max} |`)}return n.push(`| \`repeat.items\` | ${i.min}..${i.max} |`),n.push(`| \`use\` nesting (host-expanded components) | ${HD} |`),["| Limit | Value |","| --- | --- |",...n].join(`
|
|
821
|
-
`)}function sp(){let n=Ce.node.variants??{},o=ip(n);return["## Nodes","","`*` marks a required field. Fields shared by every node:","",[...o].map(([a,s])=>Cr(a,s)).join(", "),"",...vi(n,o),"",`Pager options require \`${Mk}\` whenever any is explicitly present (including default values): \`axis\` is horizontal (default) or vertical; \`pageSpacing\` is the dp gap (default 0); \`peek: {start?, end?}\` leaves neighbouring pages visible along the main axis (default 0 on each side, \`{}\` is a no-op); \`pageSize\` is fill (default) or \`{dp}\` for fixed-size pages. Distances are finite, spacing and peek are 0..${V.limits.MAX_PROTOTYPE_PAGER_DP}, and fixed page size is 1e-6..${V.limits.MAX_PROTOTYPE_PAGER_DP} (\`MAX_PROTOTYPE_PAGER_DP\`). Objects are strict. On iOS dp means points. A vertical pager cannot have any vertical scroll ancestor, including a scroll with omitted axis; a horizontal scroll ancestor is allowed. Every visible page (including partly visible peek and fixed-size pages) is exposed to accessibility, observe and tapOn; Android marks the current page selected only for pagers with positive peek or a fixed pageSize; iOS marks it selected on the options path (a pager with any non-default option) and not on the legacy paged pager; plain pagers expose only the current page on both. Pages fully off-screen are not exposed.`,"Bar scrolling requires `prototype_bar_scroll_v1` when `onScroll` or `scroll` is explicit. `topAppBar.onScroll` defaults to pinned; enterAlways hides and reveals with scroll direction; exitUntilCollapsed collapses medium/large titles to the small height. `bottomNav` and `tabBar` default to none; hide slides away and minimize draws icons only. Set `scroll` to exactly one scroll id in the same screen for an active behavior. Hidden bars leave hit testing and observation; partial bars expose drawn bounds. Reduced motion snaps between states. iOS uses custom Material bars; native platform bars are deferred.","The current page is the first fully visible page (fixed-size pages snap at Start; fill uses the usual settled page). page_changed, {page}/{pageCount}, setPage and tabBar/bottomNav pager bindings keep their meaning. Fully off-screen retained neighbours stay outside the semantics tree; stable keys and neighbour retention are unchanged. Indicator and carousel remain deferred."].join(`
|
|
822
|
-
`)}function dp(){let n=Ce.action.variants??{};return["## Actions","","Used in `onTap`, `onLongPress`, `onDoubleTap`, `onAppear` and searchBar `onSubmit` lists.","",`Gesture fields are available only on ${$e(Object.entries(Ce.node.variants??{}).filter(([,o])=>o.fields?.onLongPress!==void 0).map(([o])=>o))}; they require \`prototype_gestures_v1\`.`,"",...vi(n,new Map)].join(`
|
|
823
|
-
`)}function lp(){let n=Ce.colorRole.values??[];return["## Theme and style","",`Theme: \`{${Object.keys(Ce.theme.fields??{}).join(", ")}}\`; mode is ${$e(vn("theme","mode"))}.`,"",`Material colour roles (a colour field takes a hex value or one of these): ${$e(n)}.`,"",`Per-mode values, refused unless the device advertises \`${Ok}\`: every colour field (style colours, \`border.color\`, gradient stops, \`window.placement.scrim\`, a bottomSheet or drawer \`scrim\`) also takes \`{light, dark}\`, each a hex value or a role, both required; gradient stops and scrims take a role name too. \`theme.colors.light\` and \`theme.colors.dark\` are \`{<role>: hex}\` maps applied after the flat role overrides for the resolved mode. \`image.asset\` and a tabBar or bottomNav item \`image\` take \`{light: assetId, dark: assetId}\`: upload both, and a pair naming two different assets counts as two images. Prefer a role name, which already follows the mode; use a pair for a brand literal that needs a hand-picked dark value.`,"",`Text style roles (\`style.textStyle\`): ${$e(vn("style","textStyle"))}.`,"",`Corner shapes: ${$e(vn("themeShapes","corner"))}. Font families: ${$e(vn("themeTypography","fontFamily"))}.`,"",`Style properties: ${$e(Object.keys(Ce.style.fields??{}))}.`].join(`
|
|
824
|
-
`)}function cp(){return["## Icons","",`Icon names are a closed set of ${xi().length} Material names; variants: ${$e(V.definitions.iconVariant.values)}.`,`Look names up with \`${tF}?query=<substring>\` (at most ${FA} matches per read).`].join(`
|
|
825
|
-
`)}function pp(){return["## Embedding in an app","",`Read \`${Bg}?id=<id>\` (optional \`platform=android|ios\`, \`deviceId\`) for a shown or saved prototype as app code: the spec, its assets, a Jetpack Compose or SwiftUI host file that renders it with the published renderer library, the library coordinate to add, and the capabilities the spec needs. Asset bytes for saved prototypes come from \`${Sb}?id=<id>&assetId=<asset>\`.`,"","For one file to paste instead, read `automobile:prototype/<id>/compose` (Kotlin) or `automobile:prototype/<id>/swiftui` (Swift) for a shown prototype: the same host file with the spec inlined as a string constant, a header naming the library coordinate, required capabilities and each asset's URI (assets are not inlined), and a preview sized to `frame` (default `pixel-9` / `iphone-16`). `revision` picks a kept revision as for the web page.","",`To graduate a prototype to screens the app owns, read \`${wb}?id=<id>\` (same parameters). It returns a one-shot Compose or SwiftUI file with no renderer dependency: layout, text, buttons, text fields, lists and stack navigation become real code, every other node becomes a \`TODO(eject)\` stub that keeps its \`testTag\` and children, and \`remaining\` lists each node, action and binding left to do. It is not round-trip.`].join(`
|
|
826
|
-
`)}function up(){return["## Web preview and alternatives","",`Read \`automobile:prototype/<id>/web\` for a shown prototype as one self-contained HTML page: the prototype in a device frame with rotate, zoom, a variant switcher and its revision history. Optional \`frame\` (a device frame id; default the showing platform's), \`revision\` (default the latest) and \`variant\`. Revision 1 is the first acknowledged show; each later show of the id and each landed patch adds one; device state edits do not. The last ${oK} revisions per id are kept. Subscribe to the URI without parameters to hear every new revision. The \`exportPrototypeWeb\` tool writes the same page to an HTML file and returns its path and sha256.`,"","To present design alternatives side by side, show each under its own id with `variant: {group, label}` using one `group` (host-side only; the device shows whatever was shown last). The web page of any id in the group offers every alternative by `label`. Describe them in chat and ask the user which they prefer."].join(`
|
|
827
|
-
`)}function hp(){let n=Ce.placement.variants??{};return["## Window","",`Placement types: ${$e(Object.keys(n))}. Window fields: ${Object.entries(Ce.window.fields??{}).map(([o,i])=>Cr(o,i)).join(", ")}.`].join(`
|
|
828
|
-
`)}function xi(){return V.definitions.iconName.values}function Si(n){let o=n.trim().toLowerCase();if(o==="")return{total:0,names:[]};let i=xi().filter((a)=>a.includes(o));return{total:i.length,names:i.slice(0,FA)}}function fp(n,o){return`${n}${o.optional?"?":""}: ${xn(o.value)}`}function yp(n=yu){return["| Module | Capabilities | Calls | Events | `/platform` state |","| --- | --- | --- | --- | --- |",...Object.entries(n).filter(([,i])=>i.placeholder!==!0).map(([i,a])=>{let s=Object.entries(a.calls).map(([u,h])=>{let f=Object.entries(h.args).map(([g,b])=>fp(g,b)),y=[...h.permissions.map((g)=>`permission ${g}`),...h.background.map((g)=>`background ${g}`),...h.capability?[`capability \`${h.capability}\``]:[]];return`\`${i}.${u}\`(${f.join(", ")})${y.length>0?` needs ${y.join(", ")}`:""}`}),d=Object.keys(a.events).map((u)=>`\`${i}.${u}\``),l=Object.keys(a.state??{}).map((u)=>`\`/${i}/${gp(i,u)}${u}\``),p=[a.capability,a.deviceCapability,...Object.values(a.backends??{}).map((u)=>u.capability)].filter(Boolean);return`| \`${i}\` | ${$e(p)} | ${s.join("<br>")||"-"} | ${d.join(", ")||"-"} | ${l.join(", ")||"-"} |`})].join(`
|
|
829
|
-
`)}function gp(n,o){if(n==="media")return"players/<id>/";return n==="notifications"&&Wj.has(o)?"channels/<id>/":""}function bp(){return["## Platform differences","",`iOS draws SF Symbols: ${Object.keys(gq.mapped).length} of ${V.definitions.iconName.values.length} contract names are mapped in schemas/prototype-ios-icon-symbols.json. Unmapped names draw a placeholder symbol. Agents advertise prototype_icon_sf_symbols_v1; older agents should be relaunched with a current agent.`,'With no variant, iOS draws the name\'s default SF Symbol, which is often the outline form; pass `variant: "filled"` on an `icon` node for the closest match to Android where the table has a filled form.',"","- `icon.name`: unmapped names draw a placeholder; a successful show lists affected paths under `platformNotes`. Material parity remains a future option behind `prototype_icon_set_material_v1`.","- `icon.variant`: filled/outlined map where a form exists; rounded/sharp/twoTone and forms absent from the table draw the default symbol. A successful show lists affected paths under `platformNotes`. Material parity remains a future option behind `prototype_icon_variant_v1`.",...X6.filter(({construct:n})=>!n.startsWith("icon.")).map(({construct:n,platform:o,effect:i,capability:a,detail:s})=>`- \`${n}\`: ${o}, ${i}. ${s} A successful show lists affected paths under \`platformNotes\`${a?`; lifted by \`${a}\``:""}.`),...J6.map(({construct:n,detail:o})=>`- \`${n}\`: ${o}`)].join(`
|
|
830
|
-
`)}function Ri(){return[di,Zo,Ir,`## Limits
|
|
831
|
-
|
|
832
|
-
Generated from \`schemas/prototype-spec-contract.json\`.
|
|
833
|
-
|
|
834
|
-
`+ap(),hp(),sp(),dp(),si,li,mi,Pr,pi,Jo,ei,Qo,ui,ci,_r,bi,hi,lp(),fi,_r,Xo,cp(),bp(),pp(),up(),`${ni}
|
|
835
|
-
|
|
836
|
-
${yp()}
|
|
837
|
-
|
|
838
|
-
${wi()}
|
|
839
|
-
|
|
840
|
-
${ri}
|
|
841
|
-
|
|
842
|
-
${oi}
|
|
843
|
-
|
|
844
|
-
${ii}`,yi,gi].join(`
|
|
845
|
-
|
|
846
|
-
`)}import{createHash as Ep}from"crypto";function Se(n,o){return`"${Ai(n,o).join("")}"`}function Ai(n,o){return[...n.toWellFormed()].map((i)=>{if(i==='"'||i==="\\"||i==="$"&&o==="kotlin")return`\\${i}`;let a=i.codePointAt(0)??0;if(a>=32&&a<127)return i;if(o==="swift")return`\\u{${a.toString(16)}}`;return[...Array.from({length:i.length},(s,d)=>i.charCodeAt(d))].map((s)=>`\\u${s.toString(16).padStart(4,"0")}`).join("")})}function Sn(n){return Se(n,"kotlin")}function Ut(n){return Se(n,"swift")}var wp=16384;function vp(n){let o=[],i="";for(let a of Ai(n,"kotlin")){if(i.length+a.length>wp)o.push(`"${i}"`),i="";i+=a}return[...o,`"${i}"`]}function xp(n){let o=vp(n);if(o.length===1)return`private const val SPEC = ${o[0]}`;return`private val SPEC =
|
|
847
|
-
listOf(
|
|
848
|
-
${o.map((i)=>` ${i},`).join(`
|
|
849
|
-
`)}
|
|
850
|
-
)
|
|
851
|
-
.joinToString("")`}function ki(n){return n?n.header.map((o)=>o?`// ${o}`:"//").join(`
|
|
852
|
-
`)+`
|
|
853
|
-
|
|
854
|
-
`:""}function Wi(n){return n.slice(n.lastIndexOf("/")+1)}function Rn(n){return n.kind==="font"}function Ei(n){if(n.length===0)return" emptyMap()";return`
|
|
855
|
-
listOfNotNull(
|
|
856
|
-
${n.map((i)=>` read(${Sn(`$DIRECTORY/${Wi(i.path)}`).replace("\\$DIRECTORY","$DIRECTORY")})?.let { ${Sn(i.id)} to it },`).join(`
|
|
857
|
-
`)}
|
|
858
|
-
)
|
|
859
|
-
.toMap()`}function En(n){let o=n.assets.filter((d)=>!Rn(d)),i=n.assets.filter(Rn),a=n.storage?"remember(context) { PrototypeStorage.fileBacked(context) }":"PrototypeStorage.None",{inline:s}=n;return`${ki(s)}package prototypes
|
|
860
|
-
|
|
861
|
-
import android.content.Context
|
|
862
|
-
import androidx.compose.runtime.Composable
|
|
863
|
-
import androidx.compose.runtime.remember
|
|
864
|
-
import androidx.compose.ui.Modifier
|
|
865
|
-
import androidx.compose.ui.platform.LocalContext
|
|
866
|
-
${s?`import androidx.compose.ui.tooling.preview.Preview
|
|
867
|
-
`:""}import dev.jasonpearson.automobile.protocol.PrototypeEvent
|
|
868
|
-
import dev.jasonpearson.automobile.prototype.AutoMobilePrototype
|
|
869
|
-
import dev.jasonpearson.automobile.prototype.PrototypeAssets
|
|
870
|
-
import dev.jasonpearson.automobile.prototype.PrototypeDismissReason
|
|
871
|
-
import dev.jasonpearson.automobile.prototype.PrototypeNetwork
|
|
872
|
-
import dev.jasonpearson.automobile.prototype.PrototypeStorage
|
|
873
|
-
|
|
874
|
-
/** The app assets directory holding this prototype's spec.json and asset files. */
|
|
875
|
-
private const val DIRECTORY = ${Sn(`prototypes/${n.directory}`)}
|
|
876
|
-
${s?`
|
|
877
|
-
/** The prototype spec JSON, compiled in. */
|
|
878
|
-
${xp(s.spec)}
|
|
879
|
-
`:""}
|
|
880
|
-
/**
|
|
881
|
-
* The ${n.directory} prototype, drawn by the AutoMobile prototype renderer. Generated by
|
|
882
|
-
* ${s?`${s.generatedBy}: the spec is inlined above and the assets live under
|
|
883
|
-
* assets/prototypes/${n.directory}.`:`automobile:prototype/native: the spec and assets live under assets/prototypes/${n.directory}.`}
|
|
884
|
-
*/
|
|
885
|
-
@Composable
|
|
886
|
-
fun ${n.typeName}(
|
|
887
|
-
modifier: Modifier = Modifier,
|
|
888
|
-
network: PrototypeNetwork = remember { PrototypeNetwork() },
|
|
889
|
-
onEvent: (PrototypeEvent) -> Unit = {},
|
|
890
|
-
onDismiss: (PrototypeDismissReason) -> Unit = {},
|
|
891
|
-
) {
|
|
892
|
-
val context = LocalContext.current
|
|
893
|
-
val read = { path: String -> context.readAsset(path) }
|
|
894
|
-
${s?" val spec = SPEC":` // An empty spec (missing file) shows the renderer's load-error view instead of crashing.
|
|
895
|
-
val spec = remember(context) { read("$DIRECTORY/spec.json")?.decodeToString().orEmpty() }`}
|
|
896
|
-
val assets =
|
|
897
|
-
remember(context) {
|
|
898
|
-
PrototypeAssets(
|
|
899
|
-
images =${Ei(o)},
|
|
900
|
-
fonts =${Ei(i)},
|
|
901
|
-
)
|
|
902
|
-
}
|
|
903
|
-
AutoMobilePrototype(
|
|
904
|
-
spec = spec,
|
|
905
|
-
modifier = modifier,
|
|
906
|
-
assets = assets,
|
|
907
|
-
storage = ${a},
|
|
908
|
-
network = network,
|
|
909
|
-
onEvent = onEvent,
|
|
910
|
-
onDismiss = onDismiss,
|
|
911
|
-
)
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
/** A bundled file's bytes, or null when the app does not ship it. */
|
|
915
|
-
private fun Context.readAsset(path: String): ByteArray? = runCatching {
|
|
916
|
-
assets.open(path).use { it.readBytes() }
|
|
917
|
-
}
|
|
918
|
-
.getOrNull()
|
|
919
|
-
${s?Sp(n.typeName,s):""}`}function Sp(n,o){let{name:i,widthDp:a,heightDp:s}=o.preview;return`
|
|
920
|
-
@Preview(name = ${Sn(i)}, widthDp = ${Math.round(a)}, heightDp = ${Math.round(s)})
|
|
921
|
-
@Composable
|
|
922
|
-
private fun ${n}Preview() {
|
|
923
|
-
${n}()
|
|
924
|
-
}
|
|
925
|
-
`}function Ti(n){if(n.length===0)return"[:]";return`[${n.map((i)=>`${Ut(i.id)}: resource(${Ut(Wi(i.path))})`).join(", ")}]`}function Tn(n){let o=n.assets.filter((s)=>!Rn(s)),i=n.assets.filter(Rn),{inline:a}=n;return`${ki(a)}import AutoMobilePrototype
|
|
926
|
-
import Foundation
|
|
927
|
-
import SwiftUI
|
|
928
|
-
|
|
929
|
-
/// The ${n.directory} prototype, drawn by the AutoMobile prototype renderer. Generated by
|
|
930
|
-
${a?`/// ${a.generatedBy}: the spec is inlined below and the assets live in
|
|
931
|
-
/// Prototypes/${n.directory}.`:`/// automobile:prototype/native: the spec and assets live in Prototypes/${n.directory}.`}
|
|
932
|
-
struct ${n.typeName}: View {
|
|
933
|
-
var network: PrototypeNetworkConfiguration = .default
|
|
934
|
-
var onEvent: @MainActor (PrototypeEvent) -> Void = { _ in }
|
|
935
|
-
var onDismiss: @MainActor (PrototypeDismissReason) -> Void = { _ in }
|
|
936
|
-
|
|
937
|
-
// Read once per process, not on every body evaluation.
|
|
938
|
-
private static let spec = ${a?`Data(${Ut(a.spec)}.utf8)`:'resource("spec.json")'}
|
|
939
|
-
private static let assets = PrototypeAssets(images: ${Ti(o)}, fonts: ${Ti(i)})
|
|
940
|
-
|
|
941
|
-
var body: some View {
|
|
942
|
-
AutoMobilePrototypeView(
|
|
943
|
-
spec: Self.spec,
|
|
944
|
-
assets: Self.assets,
|
|
945
|
-
storage: ${n.storage?".fileBacked":".none"},
|
|
946
|
-
network: network,
|
|
947
|
-
onEvent: onEvent,
|
|
948
|
-
onDismiss: onDismiss
|
|
949
|
-
)
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
/// Bundled file bytes; a missing spec shows the renderer's load-error view instead of a blank screen.
|
|
953
|
-
private static func resource(_ name: String) -> Data {
|
|
954
|
-
let url = Bundle.main.bundleURL
|
|
955
|
-
.appendingPathComponent(${Ut(`Prototypes/${n.directory}`)})
|
|
956
|
-
.appendingPathComponent(name)
|
|
957
|
-
return (try? Data(contentsOf: url)) ?? Data()
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
${a?Rp(n.typeName,a):""}`}function Rp(n,o){let{name:i,widthDp:a,heightDp:s}=o.preview;return`
|
|
961
|
-
#Preview(${Ut(i)}) {
|
|
962
|
-
${n}()
|
|
963
|
-
.frame(width: ${a}, height: ${s})
|
|
964
|
-
}
|
|
965
|
-
`}var Ap="dev.jasonpearson.auto-mobile:auto-mobile-prototype-compose",kp="https://github.com/kaeawc/auto-mobile",Wp="AutoMobilePrototype",Pp={"image/png":"png","image/jpeg":"jpg","image/webp":"webp","font/ttf":"ttf","font/otf":"otf","application/vnd.automobile.agsl":"agsl"};function Or(n,o,i=Bg){if(n===void 0||n.length===0)throw new t(`${i} needs ${o}.`);return n}function Ip(n){if(n===void 0||n==="android"||n==="ios")return n;throw new t(`Unsupported platform "${n}"; use android or ios.`)}function Pi(n){return Ep("sha256").update(n,"utf8").digest("hex").slice(0,8)}function _p(n){return n.replace(/[^A-Za-z0-9_-]/g,"_")}var An=64;function kn(n){let o=_p(n);if(o===n&&o.length<=An)return o;return`${o.slice(0,An-9)}-${Pi(n)}`}function Ht(n){return kn(n)}function jt(n){let i=n.split(/[^A-Za-z0-9]+/).filter((s)=>s.length>0).map((s)=>s[0].toUpperCase()+s.slice(1)).join(""),a=/^[A-Za-z]/.test(i)?i:`P${i}`;if(/^[A-Za-z][A-Za-z0-9]*$/.test(n)&&a.length<=An)return`${a}Prototype`;return`${a.slice(0,An-8)}Prototype${Pi(n)}`}function Dr(n){let{images:o,fonts:i}=VC(n);return[...[...o].sort().map((a)=>({id:a,kind:"image"})),...[...i].sort().map((a)=>({id:a,kind:"font"}))]}async function Ii(n,o,i){return(await n.savedPrototypes(o)).find((s)=>s.id===i)}function _i(n,o){let i=n.devicesShowing(o);if(i.length===1)return i[0];if(i.length===0)throw new t(`No device is showing prototype "${o}". Show it first, or pass deviceId for a saved prototype.`);throw new t(`Prototype "${o}" is shown on ${i.length} devices (${i.join(", ")}); pass deviceId.`)}async function Cp(n,o,i){let a=i??_i(n,o),s=await Ii(n,a,o),d=n.shownSpec(a,o);if(d.kind==="known")return{deviceId:a,spec:d.spec,saved:s};if(d.kind==="busy")throw new t(`A prototype show is in flight on ${a}; read ${Bg} again once it finishes.`);if(s)return{deviceId:a,spec:s.spec,saved:s};throw new t(`Unknown prototype "${o}" on ${a}: it is neither shown nor saved there.`)}async function Op(n,o,i){let a=o??await n.platformOf(i.deviceId)??(i.saved?"android":void 0);if(!a)throw new t(`Cannot tell the platform of ${i.deviceId}; pass platform=android or platform=ios.`);return a}function Wn(n,o,i){return n==="android"?`app/src/main/assets/prototypes/${o}/${i}`:`Prototypes/${o}/${i}`}function Dp(n,o,i){let a=new URLSearchParams({id:n,assetId:o,deviceId:i});return`${Sb}?${a.toString()}`}function Np(n,o,i){let a=Ht(o),s=new Map((i.saved?.assets??[]).map((d)=>[d.id,d]));return Dr(i.spec).map(({id:d,kind:l})=>{let p=s.get(d),u=p?.mimeType?`.${Pp[p.mimeType]}`:"";return{id:d,kind:l,...p?.mimeType?{mimeType:p.mimeType}:{},path:Wn(n,a,`${kn(d)}${u}`),uri:Dp(o,d,i.deviceId),available:p?.bytes!==void 0}})}function Nr(n,o){return n==="android"?{gradle:`${Ap}:${o}`}:{swiftPackage:{url:kp,from:o,product:Wp}}}function Mp(n,o,i){let a=[];if(o.includes("prototype_network_v1"))a.push(n==="android"?'`request` actions fail until the app passes PrototypeNetwork(device = ...); host-routed requests (omitted or via:"host") then use it unless a hostHandler takes them over.':'`request` actions use the renderer\'s URLSession client by default; pass PrototypeNetworkConfiguration(hostHandler:) to take over host-routed requests (omitted or via:"host").');let s=i.filter((d)=>!d.available).map((d)=>d.id);if(s.length>0)a.push(`The host has no bytes for asset(s) ${s.join(", ")} (only saved prototypes keep them); add those files yourself.`);if(n==="ios")a.push("Add the Prototypes folder to the app target as a folder reference so Bundle.main finds files by subdirectory.");return a}function Lp(n,o,i,a){let s=Ht(o),d=jt(o),l={id:o,directory:s,typeName:d,assets:a,storage:i.storage!==void 0},p={path:Wn(n,s,"spec.json"),content:JSON.stringify(i,null,2)};return n==="android"?[p,{path:`app/src/main/java/prototypes/${d}.kt`,content:En(l)}]:[p,{path:`${d}.swift`,content:Tn(l)}]}function Mr(n){let o=new Map;for(let i of n){let a=`${i.kind}:${i.id.normalize("NFC")}`,s=o.get(a);if(s!==void 0)throw new t(`Asset ids ${JSON.stringify(s)} and ${JSON.stringify(i.id)} are the same string in Swift (canonically equivalent); rename one before exporting for iOS.`);o.set(a,i.id)}}function Lr(n,o){if(Tp(n).includes("prototype_custom_shaders_v1"))throw new t(o==="ios"?"Custom AGSL shaders are Android only; remove style.shader before exporting for iOS.":"Native prototype export does not support style.shader yet; the Compose renderer has no custom shader runtime. Remove style.shader before exporting.")}async function $r(n,o,i=Bg){let a=Or(n.id,"id",i),s=Ip(n.platform),d=await Cp(o,a,n.deviceId),l=await Op(o,s,d);return{id:a,platform:l,resolved:d}}async function Ci(n,o){let{id:i,platform:a,resolved:s}=await $r(n,o);Lr(s.spec,a);let d=o.libraryVersion(),l=Tp(s.spec),p=Np(a,i,s);if(a==="ios")Mr(p);return{id:i,platform:a,library:Nr(a,d),requiredCapabilities:l,minimumLibraryVersion:d,files:Lp(a,i,s.spec,p),assets:p,notes:Mp(a,l,p)}}async function Oi(n,o){let i=Or(n.id,"id"),a=Or(n.assetId,"assetId"),s=n.deviceId??_i(o,i),d=(await Ii(o,s,i))?.assets.find((l)=>l.id===a);if(!d?.bytes||!d.mimeType)throw new t(`No bytes for asset "${a}" of prototype "${i}" on ${s}: the host keeps asset bytes only for saved prototypes. Supply the file yourself.`);return{mimeType:d.mimeType,bytes:d.bytes}}var Ni=V.definitions;function $p(n,o){let i=c(n);return i?.kind==="ref"&&i.name===o}function Fp(n,o,i){let a=c(o);return a?Object.entries(c(n)??{}).flatMap(([s,d])=>(s in a)?ot(c(d)?.rule,a[s],`${i}.${s}`):[]):[]}function Bp(n,o,i){if(!Array.isArray(o))return[];return $p(n,"action")?[{path:i,actions:o}]:o.flatMap((a,s)=>ot(n,a,`${i}[${s}]`))}var Di={ref:(n,o,i)=>n.name==="node"||n.name==="action"?[]:ot(Ni[String(n.name)],o,i),array:(n,o,i)=>Bp(n.item,o,i),map:(n,o,i)=>Object.entries(c(o)??{}).flatMap(([a,s])=>ot(n.item,s,`${i}[${JSON.stringify(a)}]`)),object:(n,o,i)=>Fp(n.fields,o,i),tagged:(n,o,i)=>ot(c(n.variants)?.[String(c(o)?.type)],o,i),choice:(n,o,i)=>Array.isArray(n.options)?n.options.flatMap((a)=>ot(a,o,i)):[]};function ot(n,o,i){let a=c(n),s=a?.kind,d=typeof s==="string"&&Object.hasOwn(Di,s)?Di[s]:void 0;return a&&d?d(a,o,i):[]}function Mi(n,o){let i=ot(Ni.node,n,o).filter((a)=>a.path!==`${o}.onTap`);return[...new Map(i.map((a)=>[a.path,a])).values()]}var Li={box:{compose:"Box",swiftUi:"ZStack"},row:{compose:"Row",swiftUi:"HStack"},column:{compose:"Column",swiftUi:"VStack"},flow:"stub",grid:"stub",carousel:"stub",text:{compose:"Text",swiftUi:"Text"},image:"stub",icon:"stub",spacer:{compose:"Spacer",swiftUi:"Spacer"},textField:{compose:"TextField / OutlinedTextField",swiftUi:"TextField / SecureField"},searchBar:"stub",switch:"stub",checkbox:"stub",button:{compose:"Button (by variant)",swiftUi:"Button"},pasteButton:"stub",radioGroup:"stub",select:"stub",listItem:{compose:"ListItem",swiftUi:"HStack"},slider:"stub",chip:"stub",card:{compose:"Card",swiftUi:"VStack"},iconButton:"stub",fab:"stub",segmentedButton:"stub",topAppBar:"stub",divider:{compose:"HorizontalDivider / VerticalDivider",swiftUi:"Divider"},badge:"stub",progress:"stub",chart:"stub",dialog:"stub",menu:"stub",snackbar:"stub",timePicker:"stub",datePicker:"stub",list:{compose:"LazyColumn / LazyRow",swiftUi:"ScrollView + LazyVStack / LazyHStack"},scroll:{compose:"Column / Row + scroll modifier",swiftUi:"ScrollView"},pager:"stub",stack:{compose:"when over a back stack",swiftUi:"switch over a back stack"},tabBar:"stub",bottomNav:"stub",bottomSheet:"stub",tooltip:"stub",adaptive:"stub",drawer:"stub",videoPlayer:"stub",map:"stub",castButton:"stub",cameraPreview:"stub",webView:"stub"};function $i(n){return typeof n==="string"&&Object.hasOwn(Li,n)&&Li[n]!=="stub"}var Up=/\{[^{}]+\}/,Hp=new Set(["push","replace"]),jp=new Set(["pop","popToRoot"]);function Gp(n,o){let i=String(n?.type);if(typeof n?.stack!=="string")return;let a=Se(n.stack,o);if(Hp.has(i)&&typeof n.screen==="string")return`ui.${i}(${a}, ${Se(n.screen,o)})`;return jp.has(i)?`ui.${i}(${a})`:void 0}class Fr{writer;node;path;index;constructor(n,o,i,a){this.writer=n;this.node=o;this.path=i;this.index=a}get language(){return this.writer.dialect.language}string(n){let o=this.node[n];return typeof o==="string"?o:void 0}text(n){let o=this.index===void 0?n:n.replaceAll("{index}","");if(Up.test(o))this.writer.todos.push({path:this.path,kind:"binding",type:n});if(this.index===void 0||!n.includes("{index}"))return Se(n,this.language);let i=this.writer.dialect.indexed(this.index),[a,...s]=n.split("{index}");return s.reduce((d,l)=>l.length>0?`${d} + ${i} + ${Se(l,this.language)}`:`${d} + ${i}`,Se(a,this.language))}testTag(){let n=this.string("testTag");return n===void 0?void 0:this.text(n)}actions(n){let o=this.node[n];if(!Array.isArray(o))return[];return o.map((i,a)=>this.action(c(i),`${this.path}.${n}[${a}]`))}action(n,o){let i=Gp(n,this.language);if(i!==void 0)return i;let a=String(n?.type);return this.writer.todos.push({path:o,kind:"action",type:a}),`/* TODO(eject): ${a.replace(/[^A-Za-z0-9_]/g,"")} action */`}children(n="children"){let o=this.node[n];if(Array.isArray(o))return o.flatMap((i,a)=>this.writer.emit(i,`${this.path}.${n}[${a}]`,this.index));return this.writer.emit(o,`${this.path}.${n}`,this.index)}row(n){let o=this.node.children,i=Array.isArray(o)?o[0]:void 0;return this.writer.emit(i,`${this.path}.children[0]`,n)}rowCount(){let n=c(this.node.repeat),o=c(n?.items)?.path,i=typeof o==="string"?Pt(this.writer.data,o):[];return this.writer.todos.push({path:`${this.path}.repeat`,kind:"binding",type:String(o)}),Array.isArray(i)?i.length:0}stackScreens(){let n=this.string("id")??"",o=c(this.node.screens)??{},i=this.string("start")??Object.keys(o)[0]??"";return this.writer.stackStarts.set(n,i),Object.entries(o).map(([a,s])=>[a,this.writer.screen(n,a,s,`${this.path}.screens[${JSON.stringify(a)}]`)])}literal(n){return Se(n,this.language)}}var zp=" ";function Vp(n){return n.map((o)=>o.length>0?`${zp}${o}`:o)}function In(n){let o=(i)=>i.startsWith("/*");return[n.filter((i)=>!o(i)).join("; "),...n.filter(o)].filter((i)=>i.length>0).join(" ")}function F(n,o,i="}"){return[n,...Vp(o),i]}function Pn(n){let i=n.split(/[^A-Za-z0-9]+/).filter((a)=>a.length>0).map((a)=>a[0].toUpperCase()+a.slice(1)).join("");return/^[A-Za-z]/.test(i)?i:`S${i}`}class Br{dialect;data;prefix;todos=[];screens=[];stackStarts=new Map;scaffolded=new Set;screenNames=new Set;constructor(n,o,i){this.dialect=n;this.data=o;this.prefix=i}emit(n,o,i){let a=c(n);if(!a)return[];let s=new Fr(this,a,o,i),d=a.type;if($i(d)){this.scaffolded.add(d);let p=this.dialect.emitters[d](a,s);return[...this.untranslated(a,o),...p]}this.todos.push({path:o,kind:"node",type:String(d)});let l=or(a).flatMap(({value:p,suffix:u})=>this.emit(p,`${o}${u}`,i));return[...this.untranslated(a,o),...this.dialect.todoStub(a,s,l)]}untranslated(n,o){return[...this.untranslatedActions(n,o),...this.untranslatedRepeat(n,o)]}untranslatedActions(n,o){let i=Mi(n,o);this.todos.push(...i.flatMap((s)=>s.actions.map((d,l)=>({path:`${s.path}[${l}]`,kind:"action",type:String(c(d)?.type)}))));let a=i.map((s)=>s.path.slice(o.length+1));return a.length===0?[]:[`// TODO(eject): ${a.join(", ")} actions at ${o} are not translated.`]}untranslatedRepeat(n,o){let i=c(n.repeat);if(!i||n.type==="list")return[];let a=c(i.items)?.path;return this.todos.push({path:`${o}.repeat`,kind:"binding",type:typeof a==="string"?a:"repeat"}),[`// TODO(eject): repeat at ${o} is not translated; its children are written once.`]}screen(n,o,i,a){let s=`${this.prefix}${Pn(n)}${Pn(o)}Screen`;for(let l=2;this.screenNames.has(s);l+=1)s=`${this.prefix}${Pn(n)}${Pn(o)}Screen${l}`;this.screenNames.add(s);let d=this.screens.length;return this.screens.push({name:s,body:[]}),this.screens[d]={name:s,body:this.emit(i,a)},s}}function Oe(n,o="",i=!0){let a=["Modifier",o],s=n.testTag();if(s!==void 0)a.push(`.testTag(${s})`);let d=i?n.actions("onTap"):[];if(d.length>0)a.push(`.clickable { ${In(d)} }`);return a.join("")}function _n(n,o=""){return(i,a)=>F(`${n}(modifier = ${Oe(a)}${o}) {`,a.children())}function Kp(n){return(Array.isArray(n.spans)?n.spans:[]).map((i)=>typeof i==="object"&&i!==null&&("text"in i)?String(i.text):"").join("")}function qp(n,o){return o.text(o.string("text")??Kp(n))}var Yp={filled:"Button",tonal:"FilledTonalButton",elevated:"ElevatedButton",outlined:"OutlinedButton",text:"TextButton"},Xp=(n,o)=>[`${Yp[o.string("variant")??"filled"]??"Button"}(`,...F(" onClick = {",o.actions("onTap").map((i)=>` ${i}`)," },"),` modifier = ${Oe(o,"",!1)},`,...F(") {",[`Text(text = ${o.text(o.string("label")??"")})`])];function Cn(n,o,i){let a=n.string(i);return a===void 0?[]:[` ${o} = { Text(text = ${n.text(a)}) },`]}var Jp=(n,o)=>{let i=o.text(o.string("stateKey")??""),a=n.secure===!0||n.keyboardType==="password";return[`${n.variant==="filled"?"TextField":"OutlinedTextField"}(`,` value = ui.text(${i}),`,` onValueChange = { ui.setText(${i}, it) },`,` modifier = ${Oe(o)},`,...Cn(o,"label","label"),...Cn(o,"placeholder","placeholder"),...Cn(o,"supportingText","supportingText"),...n.multiline===!0?[]:[" singleLine = true,"],...a?[" visualTransformation = PasswordVisualTransformation(),"]:[],")"]},Zp=(n,o)=>{let i=n.axis==="horizontal"?"LazyRow":"LazyColumn",a=o.children("header"),s=o.children("footer");return F(`${i}(modifier = ${Oe(o)}) {`,[...a.length>0?F("item {",a):[],...F(`items(${o.rowCount()}) { index ->`,o.row("index")),...s.length>0?F("item {",s):[]])},Qp=(n,o)=>["ListItem(",` headlineContent = { Text(text = ${o.text(o.string("headline")??"")}) },`,...Cn(o,"supportingContent","supporting"),` modifier = ${Oe(o)},`,")"],eu=(n,o)=>{let i=o.literal(o.string("id")??""),a=o.stackScreens().map(([s,d])=>`${o.literal(s)} -> ${d}(ui)`);return F(`Box(modifier = ${Oe(o)}) {`,F(`when (ui.top(${i})) {`,a))},tu=(n,o)=>{let i=n.axis==="horizontal";return F(`${i?"Row":"Column"}(modifier = ${Oe(o,`${i?".horizontalScroll":".verticalScroll"}(rememberScrollState())`)}) {`,o.children("child"))},Fi={language:"kotlin",emitters:{box:_n("Box"),row:_n("Row",", verticalAlignment = Alignment.CenterVertically"),column:_n("Column"),card:_n("Card"),scroll:tu,spacer:(n,o)=>[`Spacer(modifier = ${Oe(o,".size(8.dp)")})`],divider:(n,o)=>[`${n.orientation==="vertical"?"VerticalDivider":"HorizontalDivider"}(modifier = ${Oe(o)})`],text:(n,o)=>[`Text(text = ${qp(n,o)}, modifier = ${Oe(o)})`],button:Xp,textField:Jp,list:Zp,listItem:Qp,stack:eu},todoStub:(n,o,i)=>[`// TODO(eject): ${String(n.type)} at ${o.path} has no scaffold mapping; build it by hand.`,...F(`Column(modifier = ${Oe(o)}) {`,[`Text(text = ${o.literal(`TODO: ${String(n.type)}`)})`,...i])],indexed:(n)=>n},Bi=["androidx.compose.foundation.*","androidx.compose.foundation.layout.*","androidx.compose.foundation.lazy.*","androidx.compose.material3.*","androidx.compose.runtime.*","androidx.compose.ui.Alignment","androidx.compose.ui.Modifier","androidx.compose.ui.graphics.Color","androidx.compose.ui.platform.testTag","androidx.compose.ui.text.input.PasswordVisualTransformation","androidx.compose.ui.unit.dp"];var Gi=Object.keys(V.definitions.themeModeColors.fields);function Ui(...n){let o=new Map;for(let i of n){let a=c(i)??{};for(let s of Gi){let d=a[s];if(typeof d==="string"&&df(d))o.set(s,d)}}return o}function zi(n){let o=c(n),i=c(o?.colors),a=o?.mode==="light"||o?.mode==="dark"?o.mode:void 0;return{...a?{mode:a}:{},light:Ui(i,i?.light),dark:Ui(i,i?.dark),seeded:i?.seed!==void 0||i?.source!==void 0}}function Vi(n){return df(n)??{r:0,g:0,b:0,a:1}}function On(n){return Math.round(n).toString(16).padStart(2,"0").toUpperCase()}function nu(n){let{r:o,g:i,b:a,a:s}=Vi(n);return`Color(0x${On(s*255)}${On(o)}${On(i)}${On(a)})`}function Hi(n,o,i){let a=[...i].map(([s,d])=>` ${s} = ${nu(d)},`);return a.length===0?[`private val ${n} = ${o}()`]:[`private val ${n} = ${o}(`,...a,")"]}function ru(n){if(n==="dark")return"true";return n==="light"?"false":"isSystemInDarkTheme()"}function Ki(n,o){return[...["@Composable",`fun ${o}(content: @Composable () -> Unit) {`,` val dark = ${ru(n.mode)}`,` MaterialTheme(colorScheme = if (dark) ${o}Dark else ${o}Light, content = content)`,"}",""],...Hi(`${o}Light`,"lightColorScheme",n.light),...Hi(`${o}Dark`,"darkColorScheme",n.dark)]}function ji(n){let{r:o,g:i,b:a,a:s}=Vi(n),d=(l)=>(l/255).toFixed(3);return`UIColor(red: ${d(o)}, green: ${d(i)}, blue: ${d(a)}, alpha: ${s.toFixed(3)})`}function qi(n,o){let a=Gi.filter((s)=>n.light.has(s)||n.dark.has(s)).map((s)=>{let d=n.light.get(s)??n.dark.get(s)??"#000000",l=n.dark.get(s)??d;return` static let ${s} = Color(UIColor { $0.userInterfaceStyle == .dark ? ${ji(l)} : ${ji(d)} })`});return[`enum ${o} {`,...a,"}"]}function We(n,o=!0){let i=[],a=n.testTag();if(a!==void 0)i.push(`.accessibilityIdentifier(${a})`);let s=o?n.actions("onTap"):[];if(s.length>0)i.push(`.onTapGesture { ${In(s)} }`);return i}function Dn(n,o=[]){return(i,a)=>[...F(`${n} {`,a.children()),...o,...We(a)]}function ou(n){return(Array.isArray(n.spans)?n.spans:[]).map((i)=>typeof i==="object"&&i!==null&&("text"in i)?String(i.text):"").join("")}var iu={filled:".borderedProminent",tonal:".bordered",elevated:".bordered",outlined:".bordered",text:".borderless"},au=(n,o)=>[...F("Button {",o.actions("onTap"),"} label: {"),` Text(verbatim: ${o.text(o.string("label")??"")})`,"}",`.buttonStyle(${iu[o.string("variant")??"filled"]??".borderedProminent"})`,...We(o,!1)];function su(n,o){let i=`ui.text(${o.text(o.string("stateKey")??"")})`,a=o.string("placeholder"),s=a===void 0?"":`, prompt: Text(verbatim: ${o.text(a)})`,d=`Text(verbatim: ${o.text(o.string("label")??a??"")})`;if(n.secure===!0||n.keyboardType==="password")return`SecureField(text: ${i}${s}) { ${d} }`;let l=n.multiline===!0?", axis: .vertical":"";return`TextField(text: ${i}${s}${l}) { ${d} }`}var du=(n,o)=>{let i=o.string("supportingText"),a=[su(n,o),".textFieldStyle(.roundedBorder)"];if(i===void 0)return[...a,...We(o)];return[...F("VStack(alignment: .leading) {",[...a,`Text(verbatim: ${o.text(i)})`," .font(.caption)"]),...We(o)]},lu=(n,o)=>{let i=n.axis==="horizontal",a=F(`ForEach(0..<${o.rowCount()}, id: \\.self) { index in`,o.row("index")),s=F(`${i?"LazyHStack":"LazyVStack(alignment: .leading)"} {`,[...o.children("header"),...a,...o.children("footer")]);return[...F(`ScrollView(${i?".horizontal":".vertical"}) {`,s),...We(o)]},cu=(n,o)=>{let i=o.string("supporting"),a=[`Text(verbatim: ${o.text(o.string("headline")??"")})`,...i===void 0?[]:[`Text(verbatim: ${o.text(i)})`," .font(.subheadline)"," .foregroundStyle(.secondary)"]];return[...F("HStack {",[...F("VStack(alignment: .leading) {",a),"Spacer()"]),".contentShape(Rectangle())",...We(o)]},pu=(n,o)=>{let i=o.stackScreens().flatMap(([d,l])=>[`case ${o.literal(d)}:`,` ${l}(ui: ui)`]),s=[`switch ui.top(${o.literal(o.string("id")??"")}) {`,...i,"default:"," EmptyView()","}"];return[...F("Group {",s),...We(o)]},uu=(n,o)=>[...F(`ScrollView(${n.axis==="horizontal"?".horizontal":".vertical"}) {`,o.children("child")),...We(o)],Yi={language:"swift",emitters:{box:Dn("ZStack"),row:Dn("HStack"),column:Dn("VStack(alignment: .leading)"),card:Dn("VStack(alignment: .leading)",[".padding()",".background(Color(UIColor.secondarySystemBackground), in: RoundedRectangle(cornerRadius: 12))"]),scroll:uu,spacer:(n,o)=>["Spacer()",".frame(width: 8, height: 8)",...We(o)],divider:(n,o)=>["Divider()",...We(o)],text:(n,o)=>[`Text(verbatim: ${o.text(o.string("text")??ou(n))})`,...We(o)],button:au,textField:du,list:lu,listItem:cu,stack:pu},todoStub:(n,o,i)=>[`// TODO(eject): ${String(n.type)} at ${o.path} has no scaffold mapping; build it by hand.`,...F("VStack(alignment: .leading) {",[`Text(verbatim: ${o.literal(`TODO: ${String(n.type)}`)})`,...i]),...We(o)],indexed:(n)=>`String(${n})`};function mu(n){let o=ws(n),i=o.success?c(o.spec):void 0;if(!i)throw new t(`Cannot eject prototype "${String(n.id)}": its components do not expand. Show it again to see the error.`);return i}function hu(n){return Object.entries(c(n.state)??{}).filter((o)=>typeof o[1]==="string")}function fu(n,o,i){let a=new URLSearchParams({id:n,platform:o}).toString();return[`// Generated once by ${wb}?${a}.`,"// This file is yours: edit it freely. It is never regenerated or synced back to the spec.",`// ${i} TODO(eject) item(s) remain; search for TODO(eject).`]}function bu(n,o,i){let s=new Br(o==="android"?Fi:Yi,i.data,""),d=s.emit(i.root,"root");return{writer:s,root:d,typeName:jt(n),theme:zi(i.theme),texts:hu(i),header:fu(n,o,s.todos.length)}}function Xi(n){return`mapOf<String, String>(${n.map(([i,a])=>`${Se(i,"kotlin")} to ${Se(a,"kotlin")}`).join(", ")})`}function wu(n){return F(`class ${n.typeName}State {`,[`private val starts: Map<String, String> = ${Xi([...n.writer.stackStarts])}`,"private val stacks = mutableStateMapOf<String, List<String>>()",`private val texts = mutableStateMapOf<String, String>().apply { putAll(${Xi(n.texts)}) }`,"","fun top(stack: String): String = path(stack).last()","fun push(stack: String, screen: String) { stacks[stack] = path(stack) + screen }","fun pop(stack: String) { val p = path(stack); if (p.size > 1) stacks[stack] = p.dropLast(1) }",'fun popToRoot(stack: String) { stacks[stack] = listOf(starts[stack] ?: "") }',"fun replace(stack: String, screen: String) { stacks[stack] = path(stack).dropLast(1) + screen }",'fun text(key: String): String = texts[key] ?: ""',"fun setText(key: String, value: String) { texts[key] = value }","",'private fun path(stack: String): List<String> = stacks[stack] ?: listOf(starts[stack] ?: "")'])}function vu(n){let o=n.typeName,i=n.writer.screens.flatMap((s)=>["","@Composable",...F(`private fun ${s.name}(ui: ${o}State) {`,s.body)]);return`${[...n.header,"package prototypes.eject","",...Bi.map((s)=>`import ${s}`),"","@Composable",...F(`fun ${o}() {`,[`val ui = remember { ${o}State() }`,...F(`${o}Theme {`,n.root)]),...i,"",...wu(n),"",...Ki(n.theme,`${o}Theme`)].join(`
|
|
966
|
-
`)}
|
|
967
|
-
`}function Ji(n){if(n.length===0)return"[:]";return`Dictionary([${n.map(([i,a])=>`(${Se(i,"swift")}, ${Se(a,"swift")})`).join(", ")}], uniquingKeysWith: { first, _ in first })`}function xu(n){return F(`final class ${n.typeName}State: ObservableObject {`,["@Published private var stacks: [String: [String]] = [:]","@Published private var texts: [String: String]","private let starts: [String: String]","",...F("init() {",[`starts = ${Ji([...n.writer.stackStarts])}`,`texts = ${Ji(n.texts)}`]),"",'func top(_ stack: String) -> String { path(stack).last ?? "" }',"func push(_ stack: String, _ screen: String) { stacks[stack] = path(stack) + [screen] }","func pop(_ stack: String) { let p = path(stack); if p.count > 1 { stacks[stack] = Array(p.dropLast()) } }",'func popToRoot(_ stack: String) { stacks[stack] = [starts[stack] ?? ""] }',"func replace(_ stack: String, _ screen: String) { stacks[stack] = Array(path(stack).dropLast()) + [screen] }",...F("func text(_ key: String) -> Binding<String> {",['Binding(get: { self.texts[key] ?? "" }, set: { self.texts[key] = $0 })']),"",'private func path(_ stack: String) -> [String] { stacks[stack] ?? [starts[stack] ?? ""] }'])}function Su(n){return[...n.theme.light.has("primary")||n.theme.dark.has("primary")?[`.tint(${n.typeName}Theme.primary)`]:[],...n.theme.mode?[`.preferredColorScheme(.${n.theme.mode})`]:[]]}function Ru(n){let o=n.typeName,i=n.writer.screens.flatMap((s)=>["",...F(`private struct ${s.name}: View {`,[`@ObservedObject var ui: ${o}State`,"",...F("var body: some View {",F("Group {",s.body))])]);return`${[...n.header,"import SwiftUI","import UIKit","",...F(`struct ${o}: View {`,[`@StateObject private var ui = ${o}State()`,"",...F("var body: some View {",[...F("Group {",n.root),...Su(n)])]),...i,"",...xu(n),"",...qi(n.theme,`${o}Theme`)].join(`
|
|
968
|
-
`)}
|
|
969
|
-
`}function Eu(n){let o=["One-shot scaffold, not round-trip: re-reading this resource never merges with code you changed.","Only layout, text, buttons, text fields, lists and stack navigation are translated; styles, conditions, state other than text, and data bindings are TODOs.","Every testTag is kept (Modifier.testTag / .accessibilityIdentifier), so flows recorded on the prototype can target the ejected screens."];if(n.theme.seeded)o.push("The spec seeds its color scheme (theme.colors.seed or source); only explicit color roles are exported.");return o}async function Zi(n,o){let{id:i,platform:a,resolved:s}=await $r(n,o,wb),d=bu(i,a,mu(s.spec)),l=a==="android"?{path:`app/src/main/java/prototypes/eject/${d.typeName}.kt`,content:vu(d)}:{path:`${d.typeName}.swift`,content:Ru(d)};return{id:i,platform:a,files:[l],scaffolded:[...d.writer.scaffolded].sort(),remaining:d.writer.todos,notes:Eu(d)}}import{createHash as Ov}from"crypto";class le extends Error{name="PrototypeWebInputError"}var Qi={frames:[{id:"pixel-9",platform:"android",label:"Pixel 9",screen:{widthDp:411,heightDp:923,density:2.625},cornerRadiusDp:40,cutout:{type:"punchHole",centerXDp:205.5,centerYDp:24,radiusDp:12},statusBarDp:48,navBar:{type:"gesture",heightDp:24},safeArea:{portrait:{top:48,bottom:24,left:0,right:0},landscape:{top:48,bottom:24,left:48,right:0}},frame:{bezelDp:10,color:"#1b1b1b"}},{id:"small-phone",platform:"android",label:"Small Android phone",screen:{widthDp:360,heightDp:640,density:2},cornerRadiusDp:0,cutout:{type:"none"},statusBarDp:24,navBar:{type:"buttons",heightDp:48},safeArea:{portrait:{top:24,bottom:48,left:0,right:0},landscape:{top:24,bottom:0,left:0,right:48}},frame:{bezelDp:12,color:"#202124"}},{id:"medium-tablet",platform:"android",label:"Android tablet",screen:{widthDp:800,heightDp:1280,density:2},cornerRadiusDp:16,cutout:{type:"none"},statusBarDp:24,navBar:{type:"gesture",heightDp:24},safeArea:{portrait:{top:24,bottom:24,left:0,right:0},landscape:{top:24,bottom:24,left:0,right:0}},frame:{bezelDp:16,color:"#202124"}},{id:"iphone-16",platform:"ios",label:"iPhone 16",screen:{widthDp:393,heightDp:852,density:3},cornerRadiusDp:55,cutout:{type:"island",centerXDp:196.5,centerYDp:29,widthDp:126,heightDp:37},statusBarDp:54,navBar:{type:"gesture",heightDp:34},safeArea:{portrait:{top:59,bottom:34,left:0,right:0},landscape:{top:0,bottom:21,left:59,right:59}},frame:{bezelDp:12,color:"#1c1c1e"}},{id:"iphone-16-pro-max",platform:"ios",label:"iPhone 16 Pro Max",screen:{widthDp:440,heightDp:956,density:3},cornerRadiusDp:62,cutout:{type:"island",centerXDp:220,centerYDp:30,widthDp:126,heightDp:37},statusBarDp:54,navBar:{type:"gesture",heightDp:34},safeArea:{portrait:{top:62,bottom:34,left:0,right:0},landscape:{top:0,bottom:21,left:62,right:62}},frame:{bezelDp:12,color:"#1c1c1e"}},{id:"iphone-se-3",platform:"ios",label:"iPhone SE (3rd generation)",screen:{widthDp:375,heightDp:667,density:2},cornerRadiusDp:0,cutout:{type:"none"},statusBarDp:20,navBar:{type:"none"},safeArea:{portrait:{top:20,bottom:0,left:0,right:0},landscape:{top:0,bottom:0,left:0,right:0}},frame:{bezelDp:14,color:"#1c1c1e"}},{id:"ipad-10",platform:"ios",label:"iPad (10th generation)",screen:{widthDp:820,heightDp:1180,density:2},cornerRadiusDp:18,cutout:{type:"none"},statusBarDp:24,navBar:{type:"gesture",heightDp:20},safeArea:{portrait:{top:24,bottom:20,left:0,right:0},landscape:{top:24,bottom:20,left:0,right:0}},frame:{bezelDp:20,color:"#1c1c1e"}},{id:"wearos-small-round",platform:"android",label:"Wear OS small round",formFactor:"watch",screen:{widthDp:192,heightDp:192,density:2},cornerRadiusDp:96,cutout:{type:"none"},statusBarDp:0,navBar:{type:"none"},safeArea:{portrait:{top:0,bottom:0,left:0,right:0},landscape:{top:0,bottom:0,left:0,right:0}},mask:"round",input:"rotary",frame:{bezelDp:14,color:"#202124"}},{id:"apple-watch",platform:"ios",label:"Apple Watch Series 10 (46mm)",formFactor:"watch",screen:{widthDp:208,heightDp:248,density:2},cornerRadiusDp:42,cutout:{type:"none"},statusBarDp:0,navBar:{type:"none"},safeArea:{portrait:{top:0,bottom:0,left:0,right:0},landscape:{top:0,bottom:0,left:0,right:0}},input:"rotary",frame:{bezelDp:14,color:"#1c1c1e"}},{id:"android-tv-1080p",platform:"android",label:"Android TV (1080p)",formFactor:"tv",screen:{widthDp:540,heightDp:960,density:2},cornerRadiusDp:0,cutout:{type:"none"},statusBarDp:0,navBar:{type:"none"},safeArea:{portrait:{top:48,bottom:48,left:27,right:27},landscape:{top:27,bottom:27,left:48,right:48}},input:"dpad",frame:{bezelDp:6,color:"#111111"}},{id:"apple-tv",platform:"ios",label:"Apple TV 4K",formFactor:"tv",screen:{widthDp:1080,heightDp:1920,density:2},cornerRadiusDp:0,cutout:{type:"none"},statusBarDp:0,navBar:{type:"none"},safeArea:{portrait:{top:80,bottom:80,left:60,right:60},landscape:{top:60,bottom:60,left:80,right:80}},input:"dpad",frame:{bezelDp:8,color:"#111111"}},{id:"car-1024p-landscape",platform:"android",label:"Car (1024p landscape)",formFactor:"automotive",screen:{widthDp:768,heightDp:1024,density:1},cornerRadiusDp:0,cutout:{type:"none"},statusBarDp:48,navBar:{type:"buttons",heightDp:64},safeArea:{portrait:{top:48,bottom:64,left:0,right:0},landscape:{top:48,bottom:64,left:0,right:0}},frame:{bezelDp:10,color:"#202124"}},{id:"pixel-fold",platform:"android",label:"Pixel Fold",formFactor:"foldable",screen:{widthDp:841,heightDp:701,density:2.625},cornerRadiusDp:20,cutout:{type:"none"},statusBarDp:32,navBar:{type:"gesture",heightDp:24},safeArea:{portrait:{top:32,bottom:24,left:0,right:0},landscape:{top:32,bottom:24,left:0,right:0}},panels:[{role:"cover",screen:{widthDp:411,heightDp:797,density:2.625},cornerRadiusDp:32,cutout:{type:"punchHole",centerXDp:205.5,centerYDp:24,radiusDp:12},statusBarDp:48,navBar:{type:"gesture",heightDp:24},safeArea:{portrait:{top:48,bottom:24,left:0,right:0},landscape:{top:48,bottom:24,left:48,right:0}}}],hinge:{axis:"vertical",positionDp:420.5,widthDp:0,occluding:!1},postures:[{posture:"closed",panel:"cover",hingeDegrees:0},{posture:"half_opened",panel:"inner",hingeDegrees:90},{posture:"opened",panel:"inner",hingeDegrees:180}],frame:{bezelDp:10,color:"#1b1b1b"}},{id:"flip-foldable",platform:"android",label:"Flip foldable",formFactor:"foldable",screen:{widthDp:411,heightDp:1004,density:2.625},cornerRadiusDp:24,cutout:{type:"punchHole",centerXDp:205.5,centerYDp:24,radiusDp:12},statusBarDp:48,navBar:{type:"gesture",heightDp:24},safeArea:{portrait:{top:48,bottom:24,left:0,right:0},landscape:{top:48,bottom:24,left:48,right:0}},panels:[{role:"cover",screen:{widthDp:262,heightDp:272,density:2.75},cornerRadiusDp:24,cutout:{type:"none"},statusBarDp:24,navBar:{type:"none"},safeArea:{portrait:{top:24,bottom:0,left:0,right:0},landscape:{top:24,bottom:0,left:0,right:0}}}],hinge:{axis:"horizontal",positionDp:502,widthDp:0,occluding:!1},postures:[{posture:"closed",panel:"cover",hingeDegrees:0},{posture:"half_opened",panel:"inner",hingeDegrees:90},{posture:"opened",panel:"inner",hingeDegrees:180}],frame:{bezelDp:10,color:"#1b1b1b"}}]};function Au(n){let{hinge:o,...i}=n;return{...i,formFactor:n.formFactor??"phone",...o===void 0?{}:{hinge:{...o,panel:o.panel??"inner"}},postures:n.postures??[],mask:n.mask??"rect",input:n.input??"touch",panels:[{role:"inner",screen:n.screen,cornerRadiusDp:n.cornerRadiusDp,cutout:n.cutout,statusBarDp:n.statusBarDp,navBar:n.navBar,safeArea:n.safeArea},...n.panels??[]]}}var ea=Qi.frames.map(Au),ku={android:"pixel-9",ios:"iphone-16"};function Fe(n){return ku[n]}function Re(n){let o=ea.find((i)=>i.id===n);if(!o)throw new le(`Unknown device frame "${n}". Valid frames: ${ea.map((i)=>i.id).join(", ")}`);return o}var T="align-items",G="align-self",Ke="aria-checked",ae="aria-hidden",z="aria-label",qe="aria-selected",Gt="aspect-ratio",k="background-color",A="border-radius",Be="box-shadow",K="box-sizing",Ye="data-chrome",Nn="data-level",P="data-part",zt="data-status",it="data-testid",Mn="data-window",Vt="flex-basis",D="flex-direction",q="flex-shrink",Kt="font-family",oe="font-size",De="font-weight",qt="grid-area",ut="grid-template-columns",N="justify-content",mt="justify-self",Xe="line-height",ht="margin-inline-start",Je="max-height",ce="max-width",U="min-height",te="min-width",Pe="padding-bottom",we="padding-inline",ft="padding-top",Ee="pointer-events",yt="text-align",Ie="white-space",at="z-index",L="absolute",Y="border-box",w="center",M="column",R="flex",de="inline-flex",Z="relative",ne="stretch";function m(n,o={},i=[]){return{tag:n,attrs:o.attrs??{},style:o.style??{},children:i}}var Wu=new Set(["img","br","hr","input","meta","link"]),na=/^[a-z][a-z0-9-]*$/,Pu=new Set(["viewBox","preserveAspectRatio"]);function ra(n){return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Yt(n){return ra(n).replace(/"/g,""")}function ta(n){return Object.entries(n).sort(([o],[i])=>o<i?-1:o>i?1:0)}function Iu(n){let o=ta(n.style).map(([a,s])=>`${a}:${s}`).join(";"),i={...n.attrs,...o?{style:o}:{}};return ta(i).map(([a,s])=>{if(!na.test(a)&&!Pu.has(a))throw Error(`Invalid attribute name: ${a}`);if(a.toLowerCase().startsWith("on"))throw Error(`Event handler attributes are not allowed: ${a}`);return` ${a}="${Yt(s)}"`}).join("")}function Ue(n){if(typeof n==="string")return ra(n);if(!na.test(n.tag))throw Error(`Invalid element name: ${n.tag}`);let o=`<${n.tag}${Iu(n)}>`;if(Wu.has(n.tag))return o;return`${o}${n.children.map(Ue).join("")}</${n.tag}>`}function _u(n,o){let i=n;for(let a=0;a<8&&i.includes("var(");a++){let s=!1;if(i=i.replace(/var\(\s*(--[\w-]+)\s*\)/g,(d,l)=>{let p=o[l];return s||=p===void 0,p??""}),s)return}return i.includes("var(")?void 0:i}function oa(n,o){let i=/^(-?\d+(?:\.\d+)?|-?\.\d+)(px|%)?$/.exec(n.trim());if(!i)return;let a=Number(i[1]);if(i[2]==="%")return o===void 0?void 0:a*o/100;return i[2]==="px"||a===0?a:void 0}function Cu(n,o){let i=n.trim().split(/\s+([+-])\s+/),a=oa(i[0]??"",o);for(let s=1;s<i.length&&a!==void 0;s+=2){let d=oa(i[s+1]??"",o);a=d===void 0?void 0:a+(i[s]==="-"?-d:d)}return a}function Ou(n){let o=[],i=0,a=0;for(let s=0;s<n.length;s++){let d=n[s];if(i+=d==="("?1:d===")"?-1:0,d===","&&i===0)o.push(n.slice(a,s)),a=s+1}return o.push(n.slice(a)),o}function Du(n,o,i,a){let s=Ou(o).map((l)=>Q(l,i,a)),d=s.filter((l)=>l!==void 0);if(d.length!==s.length)return;return n==="min"?Math.min(...d):Math.max(...d)}function Q(n,o,i){if(n===void 0)return;let a=_u(n.trim(),o);if(a===void 0)return;let s=/^(min|max)\((.*)\)$/.exec(a);if(s)return Du(s[1],s[2],o,i);if(/-\s*(?:calc)?\(/.test(a))return;let d=/^calc\((.*)\)$/.exec(a.trim()),l=(d?d[1]:a).replace(/calc\(|\(|\)/g,"");return Cu(l,i)}var J=(n,o)=>n===void 0||o===void 0?void 0:n+o,_e=(n,o)=>n===void 0||o===void 0?void 0:n-o;function Ze(n,o,i,a){let s=n.style[o];if(s===void 0||s==="auto"||/content/.test(s))return"auto";return Q(s,a,i)}function gt(n,o,i,a){let s=Q(o.style[`min-${i}`],a.vars,a.base),d=Q(o.style[`max-${i}`],a.vars,a.base);if(n===void 0)return s!==void 0&&s>0?s:void 0;return Math.max(s??-1/0,Math.min(d??1/0,n))}function Ln(n,o,i,a){return n===void 0?void 0:gt(n,o,i,a)}var Nu=new Set([void 0,"start","flex-start","self-start","left","top","normal","stretch","baseline"]),Mu=new Set(["end","flex-end","self-end","right","bottom"]);function $n(n,o,i){if(Nu.has(n))return 0;let a=_e(o,i);if(a===void 0)return;if(Mu.has(n))return a;return n==="center"?a/2:0}function He(n){if(n===void 0)return[];let o=[],i=0,a="";for(let s of n.trim())if(i+=s==="("?1:s===")"?-1:0,/\s/.test(s)&&i===0)o.push(a),a="";else a+=s;return[...o,a].filter((s)=>s!=="")}function Ur(n){let[o,i=o,a=o,s=i]=He(n);return[o,i,a,s]}var Lu=[["top",["padding-top","padding-block-start"]],["right",["padding-right","padding-inline-end"]],["bottom",["padding-bottom","padding-block-end"]],["left",["padding-left","padding-inline-start"]]];function $u(n,o){return He(n.style.border).map((a)=>Q(a,o)).find((a)=>a!==void 0)??0}function Fn(n,o,i){let a=Ur(n.style.padding),s=$u(n,i),d=(f,y)=>{let b=y.map((v)=>n.style[v]).find((v)=>v!==void 0)??a[f]??"0";return J(Q(b,i,o),s)},[l,p,u,h]=Lu.map(([,f],y)=>d(y,f));return{top:l,right:p,bottom:u,left:h}}function ia(n,o,i){let a=Fn(n,o.width,i);return{left:J(o.left,a.left),top:J(o.top,a.top),width:_e(_e(o.width,a.left),a.right),height:_e(_e(o.height,a.top),a.bottom)}}function Xt(n){let[o,i="1"]=(n.style["aspect-ratio"]??"").split("/"),a=Number(o)/Number(i);return Number.isFinite(a)&&a>0?a:void 0}function et(n,o,i,a){let s=Xt(n),{width:d,height:l}=o;if(s!==void 0&&l===void 0&&d!==void 0)l=d/s;else if(s!==void 0&&d===void 0&&l!==void 0)d=l*s;let p=(u,h)=>gt(h,n,u,{base:i[u],vars:a});return{...o,width:p("width",d),height:p("height",l)}}var Fu={topLeft:"border-top-left-radius",topRight:"border-top-right-radius",bottomRight:"border-bottom-right-radius",bottomLeft:"border-bottom-left-radius"},Bu={topLeft:"border-start-start-radius",topRight:"border-start-end-radius",bottomRight:"border-end-end-radius",bottomLeft:"border-end-start-radius"},Uu={topLeft:"topRight",topRight:"topLeft",bottomRight:"bottomLeft",bottomLeft:"bottomRight"},aa=["topLeft","topRight","bottomRight","bottomLeft"];function Hu(n,o){let[i="",a]=(n??"").split("/"),s=(d)=>{let[l,p=l,u=l,h=p]=He(d);return[l,p,u,h][o]};return[s(i),a===void 0?void 0:s(a)]}function ju(n,o,i){let[a,s=a]=n,d=Q(a,i,o.width)??0,l=Q(s,i,o.height)??0;return d>0&&l>0?{x:d,y:l}:{x:0,y:0}}function Gu(n,o){let{topLeft:i,topRight:a,bottomRight:s,bottomLeft:d}=n,l=[[o.width,i.x+a.x],[o.width,d.x+s.x],[o.height,i.y+d.y],[o.height,a.y+s.y]],p=Math.min(1,...l.map(([h,f])=>h===void 0||f<=0?1:h/f));if(p>=1)return n;let u=({x:h,y:f})=>({x:h*p,y:f*p});return{topLeft:u(i),topRight:u(a),bottomRight:u(s),bottomLeft:u(d)}}function sa(n,o,i,a=!1){if(o.height===void 0)return;let s=(l)=>{let p=Bu[a?Uu[l]:l],u=n.style[Fu[l]]??n.style[p],[h,f]=He(u),y=u===void 0?Hu(n.style["border-radius"],aa.indexOf(l)):[h,f];return ju(y,o,i)},d={topLeft:s("topLeft"),topRight:s("topRight"),bottomRight:s("bottomRight"),bottomLeft:s("bottomLeft")};return aa.every((l)=>d[l].x===0)?void 0:Gu(d,o)}function da(n,o,i,a){let s=o.left+o.width,d=o.height===void 0?void 0:o.top+o.height,l=({x:p,y:u},[h,f],[y,g])=>{if(p<=0||u<=0||y===void 0)return!1;let b=(i-(h+f*p))*f,v=(a-(y+g*u))*g;return b<0&&v<0&&(b/p)**2+(v/u)**2>1};return l(n.topLeft,[o.left,1],[o.top,1])||l(n.topRight,[s,-1],[o.top,1])||l(n.bottomRight,[s,-1],[d,-1])||l(n.bottomLeft,[o.left,1],[d,-1])}function pa(n){let o=/^repeat\(\s*(\d+)\s*,/.exec(n.style["grid-template-columns"]?.trim()??"");return o?Number(o[1]):void 0}function ma(n){let{display:o}=n.style;if(o==="grid"||o==="inline-grid")return pa(n)===void 0?"box":"tracks";if(o==="flex"||o==="inline-flex")return n.style["flex-direction"]?.startsWith("column")?"column":"row";return"flow"}var zu=(n)=>n.style["flex-direction"]?.trim().endsWith("-reverse")===!0,Un=(n)=>n.style.position==="absolute"||n.style.position==="fixed",Hn=(n)=>n==="width"?"height":"width";function Gr(n,o,i){return n==="width"?{left:o[0],top:o[1],width:i[0],height:i[1]}:{left:o[1],top:o[0],width:i[1],height:i[0]}}var la=(n,o)=>o==="width"?n.left:n.top;function bt(n,o,i,a){let s=a.content[o],d=Ze(n,o,s,a.vars),p=d!=="auto"?d:i==="stretch"||i==="normal"?s:Xt(n)===void 0?ha(n,o,a.vars,0):void 0;return Ln(p,n,o,{base:s,vars:a.vars})}var Vu=32;function Ku(n,o,i,a){let s=Ze(n,o,void 0,i),d=s!=="auto"?s:Xt(n)===void 0?ha(n,o,i,a):void 0;return Ln(d,n,o,{base:void 0,vars:i})}function qu(n,o){let i=n.children.filter((d)=>typeof d!=="string"?!Un(d)&&d.style.display!=="none":d.trim()!==""),a=jr(i);return o==="tracks"||a.length===0||a.length<i.length||a.some((d)=>o==="flow"&&ya(d)||Object.keys(d.style).some((l)=>l.startsWith("margin")))?void 0:a}function ha(n,o,i,a){let s=ma(n),d=a>=Vu?void 0:qu(n,s),l=(d??[]).map((b)=>Ku(b,o,i,a+1)),p=l.filter((b)=>b!==void 0);if(d===void 0||p.length<l.length)return;let u=s===(o==="width"?"row":"column")||s==="flow"&&o==="height",f=s==="flow"?0:ba(o,{parent:n,content:{left:0,top:0,width:void 0,height:void 0},vars:i}),y=u?p.reduce((b,v)=>b+v,f*(p.length-1)):Math.max(...p),g=Fn(n,void 0,i);return o==="width"?J(J(y,g.left),g.right):J(J(y,g.top),g.bottom)}function Yu(n,o){let i=Number(/^span\s+(\d+)$/.exec(n.style["grid-column"]?.trim()??"")?.[1]??1);return Math.min(Math.max(1,i),o)}function Xu(n,o,i){let{content:a,vars:s}=i,[d,l=d]=He(i.parent.style.gap),p=Q(i.parent.style["column-gap"]??l,s,a.width)??0,u=a.width===void 0?void 0:(a.width-p*(o-1))/o,h=[],f=0,y=0;for(let g of n){let b=Yu(g,o);if(f+b>o)f=0,y+=1;let v=u===void 0?void 0:J(a.left,f*(u+p)),x=u===void 0?void 0:b*u+(b-1)*p,E={...i,content:{left:v,top:y===0?a.top:void 0,width:x,height:void 0}};h.push(fa(g,E)),f+=b}return h}function fa(n,o){let i=n.style["justify-self"]??o.parent.style["justify-items"],a=n.style["align-self"]??o.parent.style["align-items"],s=et(n,{left:0,top:0,width:bt(n,"width",i,o),height:bt(n,"height",a,o)},o.content,o.vars),{content:d}=o;return{element:n,rect:{...s,left:J(d.left,$n(i,d.width,s.width)),top:J(d.top,$n(a,d.height,s.height))}}}var Ju=new Set(["span","a","img","svg","i","b","em","strong","label"]);function ya(n){let{display:o}=n.style;return o===void 0?Ju.has(n.tag):o.startsWith("inline")}function Zu(n,o,i){let a=i.content[o],s=Ze(n,o,a,i.vars);return Ln(s==="auto"?void 0:s,n,o,{base:a,vars:i.vars})}function Qu(n,o){let{content:i}=o,a=[],s=i.top;for(let d of n){if(typeof d==="string"){s=d.trim()===""?s:void 0;continue}let l=ya(d)?"start":"stretch",p=et(d,{left:i.left,top:s,width:bt(d,"width",l,o),height:Zu(d,"height",o)},i,o.vars);a.push({element:d,rect:p}),s=J(s,p.height)}return a}function em(n){let o=He(n.style.flex),i=(p)=>p!==void 0&&/^\d*\.?\d+$/.test(p),a=0,s=1,d="auto";if(o[0]==="none")s=0;else if(o[0]==="auto")a=1;else if(o.length>0&&o[0]!=="initial"){let p=o.filter(i);a=p.length>0?Number(p[0]):1,s=p.length>1?Number(p[1]):1,d=o.find((u)=>!i(u))??"0"}let l=(p,u)=>{let h=Number(n.style[p]);return n.style[p]&&Number.isFinite(h)?h:u};return{grow:l("flex-grow",a),shrink:l("flex-shrink",s),basis:n.style["flex-basis"]??d}}function zr(n,o){let i=n.style["align-self"];return i===void 0||i==="auto"?o.parent.style["align-items"]:i}function tm(n,o,i){let a=Xt(n),s=bt(n,Hn(o),zr(n,i),i);if(a===void 0||s===void 0)return;return o==="width"?s*a:s/a}function nm(n,o,i){let a=bt(n,Hn(o),zr(n,i),i),s=Gr(o,[0,0],[void 0,a]);return et(n,s,i.content,i.vars)[o]}var rm=new Set(["img","svg","video","canvas","iframe","input"]);function om(n,o,i){let a=n.style.overflow??n.style[o==="width"?"overflow-x":"overflow-y"];if(a!==void 0&&a!=="visible")return 0;let s=!rm.has(n.tag)&&n.children.every((u)=>typeof u==="string"&&u.trim()===""),d=nm(n,o,i)??(s?0:void 0),l=Ze(n,o,i.content[o],i.vars),p=l==="auto"?void 0:l;if(p===void 0||d===void 0)return d;return Math.min(p,d)}function ga(n,o,i){let a=Fn(n,i.content[o],i.vars);return(o==="width"?J(a.left,a.right):J(a.top,a.bottom))??0}function im(n,o,i){let a=Q(n.style[`min-${o}`],i.vars,i.content[o]),s=a===void 0?om(n,o,i):void 0,d=ga(n,o,i),l=a??s;return{min:l===void 0&&d===0?void 0:Math.max(l??0,d),minUnknown:a===void 0&&s===void 0}}function am(n,o,i){if(typeof n==="string")return{...{basis:void 0,base:void 0,grow:0,shrink:0,min:void 0,max:void 0},minUnknown:!0,edges:0};let a=i.content[o],{grow:s,shrink:d,basis:l}=em(n),p=l==="auto"?Ze(n,o,a,i.vars):Q(l,i.vars,a),u=Q(n.style[`max-${o}`],i.vars,a),{min:h,minUnknown:f}=im(n,o,i),y=p==="auto"?tm(n,o,i):p,g=ga(n,o,i),b=s>0?y??g:y,v=b===void 0?gt(void 0,n,o,{base:a,vars:i.vars}):Math.max(h??0,Math.min(u??1/0,b));return{element:n,basis:b,base:v,grow:s,shrink:d,min:h,max:u,minUnknown:f,edges:g}}function sm(n,o,i){let a=n.reduce((s,d)=>s+i.get(d)-o.get(d),0);if(a===0)return n;return n.filter((s)=>a>0?i.get(s)>o.get(s):i.get(s)<o.get(s))}function Bn(n,o){if(n.basis===void 0||n.base===void 0)return!1;return o==="grow"?n.grow>0&&n.basis<=n.base:n.shrink>0&&n.basis>=n.base&&!n.minUnknown}function dm(n,o,i,a){let s=n.basis??0;if(a==="grow"){let p=o.reduce((u,h)=>u+h.grow,0);return s+i*n.grow/p}let d=(p)=>p.shrink*Math.max(0,(p.basis??0)-p.edges),l=o.reduce((p,u)=>p+d(u),0);return l===0?s:s+i*d(n)/l}function lm(n,o,i){let a=n.map((u)=>Bn(u,i)?u.basis:u.base??0),s=[...a],d=new Set(n.flatMap((u,h)=>Bn(u,i)?[]:[h])),l=()=>s.reduce((u,h,f)=>u+h-a[f],0);while(d.size<n.length){let u=n.flatMap((x,E)=>d.has(E)?[]:[E]),h=u.map((x)=>n[x]),f=h.reduce((x,E)=>x+E[i],0),y=o-l(),g=f<1&&Math.abs(o*f)<Math.abs(y)?o*f:y,b=new Map(u.map((x)=>[x,dm(n[x],h,g,i)])),v=new Map(u.map((x)=>{let{min:E,max:W}=n[x];return[x,Math.max(E??0,Math.min(W??1/0,b.get(x)))]}));for(let x of sm(u,b,v))s[x]=v.get(x),d.add(x)}let p=o-l();return{sizes:s,remaining:i==="grow"?Math.max(0,p):p}}function cm(n,o,i){let a=n.map((h)=>h.base);if(o===void 0)return{sizes:a,remaining:0};let s=a.reduce((h,f)=>J(h,f),i),d=n.filter((h)=>h.grow>0);if(s===void 0){let h=d.every((f)=>f.max!==void 0);return{sizes:n.map((f)=>f.grow>0?void 0:f.base),remaining:d.length>0&&!h?0:void 0}}if(s===o)return{sizes:a,remaining:0};let l=s<o?"grow":"shrink";if(n.filter((h)=>Bn(h,l)).length===0)return{sizes:a,remaining:o-s};let u=n.reduce((h,f)=>h+(Bn(f,l)?f.basis:f.base),i);return lm(n,o-u,l)}var pm=new Set([void 0,"normal","start","flex-start","stretch","left"]),um={"space-between":(n,o)=>[0,n/(o-1)],"space-around":(n,o)=>[n/(2*o),n/o],"space-evenly":(n,o)=>[n/(o+1),n/(o+1)]},mm=new Set(["end","flex-end","right"]);function hm(n,o,i){if(pm.has(n)||n==="space-between"&&i<2)return[0,0];if(o===void 0)return n==="space-between"?[0,void 0]:[void 0,void 0];if(mm.has(n))return[o,0];let a=n===void 0?void 0:um[n];if(a&&o>=0)return a(o,i);return n==="space-between"?[0,0]:[o/2,0]}function ba(n,o){let{style:i}=o.parent,[a,s=a]=He(i.gap),d=n==="width"?i["column-gap"]??s:i["row-gap"]??a;return Q(d,o.vars,o.content[n])??0}function fm(n,o,i,a){let s=Hn(o),d=zr(n,a),l=et(n,Gr(o,[0,0],[i,bt(n,s,d,a)]),a.content,a.vars)[s];return[$n(d,a.content[s],l),l]}var ym={start:"end",end:"start",left:"right",right:"left"};function gm(n,o,i){let a=o==="height"&&(n==="left"||n==="right")?"start":n;if(!i)return a;return a===void 0?void 0:ym[a]??a}function Hr(n,o,[i,a]){let s=i;return n.map((d)=>{let l=s;return s=J(J(J(s,d),o),a),l})}function bm(n,o,i,a){if(i!==void 0)return Hr(n,o,a).map((s,d)=>_e(i,J(s,n[d])));return Hr([...n].reverse(),o,[0,0]).reverse()}function ca(n,o,i){let a=Hn(o),s=n.map((x)=>am(x,o,i)),d=ba(o,i),l=i.content[o],p=d*Math.max(0,s.length-1),{sizes:u,remaining:h}=cm(s,l,p),f=zu(i.parent),y=gm(i.parent.style["justify-content"],o,f),g=hm(y,h,s.length),b=f?bm(u,d,l,g):Hr(u,d,g),v=[];for(let[x,E]of s.entries()){let W=u[x];if(E.element){let[ee,_]=fm(E.element,o,W,i),ye=[J(la(i.content,o),b[x]),J(la(i.content,a),ee)],C=Gr(o,ye,[W,_]);v.push({element:E.element,rect:et(E.element,C,i.content,i.vars)})}}return v}var jr=(n)=>n.filter((o)=>typeof o!=="string");function wa(n,o,i){let a=n.children.filter((d)=>typeof d==="string"||!Un(d)&&d.style.display!=="none"),s={parent:n,content:o,vars:i};switch(ma(n)){case"box":return jr(a).map((d)=>fa(d,s));case"tracks":return Xu(jr(a),pa(n)??1,s);case"row":return ca(a,"width",s);case"column":return ca(a,"height",s);case"flow":return Qu(a,s)}}var wm=64;function vm(n){let o=Number(n.style.opacity);return n.style.opacity===void 0||!Number.isFinite(o)?1:o}function xm(n,o){let i=Object.entries(n.style).filter(([a])=>a.startsWith("--"));return i.length===0?o:{...o,...Object.fromEntries(i)}}var Sm=/^translate(X|Y|3d)?\(([^()]*)\)$/;function Rm(n,o,i){let a=n.style.transform?.trim();if(a===void 0||a==="none")return[0,0];let s=Sm.exec(a);if(!s)return;let d=s[2].split(",").map((u)=>u.trim()),l=s[1]==="Y"?"0":d[0],p=s[1]==="Y"?d[0]:s[1]==="X"?"0":d[1]??"0";return[Q(l,i,o.width),Q(p,i,o.height)]}function Em(n,o,i){if(n.style.position!=="relative")return[0,0];let a=(s,d,l)=>{let{style:p}=n;if(p[s]!==void 0&&p[s]!=="auto")return Q(p[s],i,l);let u=p[d]===void 0||p[d]==="auto"?0:Q(p[d],i,l);return u===void 0?void 0:-u};return[a("left","right",o.width),a("top","bottom",o.height)]}function Tm(n,o,i){let a=Rm(n,o,i);if(!a)return{...o,left:void 0,top:void 0};let[s,d]=Em(n,o,i);return{...o,left:J(J(o.left,s),a[0]),top:J(J(o.top,d),a[1])}}var jn=(n)=>n!==void 0&&n!=="auto";function Ra(n,o){let[i,a,s,d]=Ur(n.style.inset),{style:l}=n;return o==="width"?[l.left??d,l.right??a]:[l.top??i,l.bottom??s]}function va(n,o,i,a){let[s,d]=Ra(n,o),l=i[o],p=Ze(n,o,l,a),u=jn(s)&&jn(d)?_e(_e(l,Q(s,a,l)),Q(d,a,l)):void 0;return gt(p==="auto"?u:p,n,o,{base:l,vars:a})}function xa(n,o,i,a){let[s,d]=Ra(n,o),l=i[o],p=o==="width"?i.left:i.top;if(jn(s))return J(p,Q(s,a.vars,l));return jn(d)?_e(J(p,_e(l,Q(d,a.vars,l))),a.size):p}function Am(n,o,i){let{width:a,height:s}=et(n,{left:0,top:0,width:va(n,"width",o,i),height:va(n,"height",o,i)},o,i),d=xa(n,"width",o,{size:a,vars:i}),l=xa(n,"height",o,{size:s,vars:i});return{element:n,rect:{left:d,top:l,width:a,height:s}}}function km(n){let o=Number(n.style["z-index"]),i=n.style.position!==void 0&&n.style.position!=="static",a=Number.isFinite(o)&&n.style["z-index"]!==void 0?o:0;return a<0?a:a+(i?0.5:0)}function Wm(n,o,i){let a=n.children.filter((d)=>typeof d!=="string"),s=new Map([...wa(n,ia(n,o,i),i),...a.filter(Un).map((d)=>Am(d,o,i))].map((d)=>[d.element,d.rect]));return a.flatMap((d,l)=>{let p=s.get(d);return p?[{element:d,rect:p,index:l,layer:km(d)}]:[]}).sort((d,l)=>d.layer-l.layer||d.index-l.index).map(({element:d,rect:l})=>({element:d,rect:l}))}var Ea=(n)=>["overflow","overflow-x","overflow-y"].some((o)=>{let i=n.style[o];return i!==void 0&&i!=="visible"}),Pm=(n,o)=>o.left!==void 0&&o.top!==void 0&&(o.top<=0||!Ea(n));function _m(n,o){let i=n.attrs.dir??n.style.direction;return i==="rtl"?!0:i==="ltr"?!1:o}function Ta(n,o,i){let a=o.opacity*vm(n);if(a<=0||n.style.display==="none")return;let s=xm(n,o.vars),d=Tm(n,o.rect,s),l=_m(n,o.rtl),p=sa(n,d,s,l);if(i.push({element:n,rect:d,radii:p,opacity:a,clips:o.clips}),o.depth>=wm||!Pm(n,d))return;let u=Ea(n)?[...o.clips,{rect:d,radii:p}]:o.clips;for(let h of Wm(n,d,s)){let f={rect:h.rect,opacity:a,vars:s,clips:u,rtl:l,depth:o.depth+1};Ta(h.element,f,i)}}function Aa(n,o,i={}){let a=[],s={left:0,top:0,width:o.width,height:o.height};return Ta(n,{rect:s,opacity:1,vars:i,clips:[],rtl:!1,depth:0},a),a}function Sa({rect:n,radii:o},i){let{left:a,top:s,width:d,height:l}=n;if(a===void 0||s===void 0||d===void 0)return!1;return a<=i&&i<a+d&&s<=0&&(l===void 0||s+l>0)&&(o===void 0||!da(o,{left:a,top:s,width:d,height:l},i,0))}function ka(n,o){return Sa(n,o)&&n.clips.every((i)=>Sa(i,o))}var Cm={clock:"9:41",batteryPercent:100,wifi:!0,cellularBars:4},Om=/^rgba?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*(?:,\s*([\d.]+)\s*)?\)$/,Dm=/^#([0-9a-fA-F]{6})$/;function Kr(n){let o=n===void 0?null:Om.exec(n.trim());if(o){let[,a,s,d,l]=o;return{r:Number(a),g:Number(s),b:Number(d),a:l===void 0?1:Number(l)}}let i=n===void 0?null:Dm.exec(n.trim());if(i){let a=Number.parseInt(i[1],16);return{r:a>>16&255,g:a>>8&255,b:a&255,a:1}}return}function Vr(n){let o=n/255;return o<=0.03928?o/12.92:((o+0.055)/1.055)**2.4}function Nm(n){return 0.2126*Vr(n.r)+0.7152*Vr(n.g)+0.0722*Vr(n.b)}function Pa(n,o){let i=Kr(n);if(!i)return o;return Nm(i)>0.179?"dark":"light"}function Mm(n,o){let i=n.style[k],a=Kr(i)?.a;return a!==void 0&&a*o===1?i:void 0}var Wa=64,Lm=(()=>{let{widthDp:n,heightDp:o}=Re(Fe("android")).screen;return{width:n,height:o}})();function Ia(n,o,i=Lm,a={}){if(typeof n==="string")return o;let s=Aa(n,i,a).flatMap((u)=>{let h=Mm(u.element,u.opacity);return h===void 0?[]:[{box:u,color:h}]}),d=new Map;for(let u=0;u<Wa;u++){let h=(u+0.5)*i.width/Wa,f=s.filter(({box:b})=>ka(b,h)).at(-1)?.color??o,y=$m(f),g=d.get(y)??{color:f,count:0};d.set(y,{...g,count:g.count+1})}let l=o,p=0;for(let{color:u,count:h}of d.values())if(h>p)l=u,p=h;return l}function $m(n){let o=Kr(n);return o?`rgba(${o.r},${o.g},${o.b},${o.a})`:n}var qr=(n)=>`${Number(n.toFixed(3))}px`;function Fm(n,o){return m("span",{attrs:{[zt]:"wifi",[Nn]:n?"on":"off"},style:{display:"inline-block",width:"15px",height:"11px",[k]:o,"clip-path":"polygon(0 30%, 50% 0, 100% 30%, 50% 100%)",opacity:n?"1":"0.35"}})}function Bm(n,o){let i=Math.max(0,Math.min(4,Math.round(n)));return m("span",{attrs:{[zt]:"cellular",[Nn]:String(i)},style:{display:de,[T]:"flex-end",gap:"1.5px",height:"11px"}},[0,1,2,3].map((a)=>m("span",{style:{display:"inline-block",width:"3px",height:qr(4+a*2.33),[A]:"1px",[k]:o,opacity:a<i?"1":"0.35"}})))}function Um(n,o){let i=Math.max(0,Math.min(100,Math.round(n)));return m("span",{attrs:{[zt]:"battery",[Nn]:String(i)},style:{display:de,[T]:w,gap:"1px"}},[m("span",{style:{display:de,width:"22px",height:"11px",padding:"1px",border:`1px solid ${o}`,[A]:"3px",[K]:Y}},[m("span",{style:{width:`${i}%`,[A]:"1.5px",[k]:o}})]),m("span",{style:{width:"1.5px",height:"4px",[A]:"0 1px 1px 0",[k]:o}})])}function Hm(n,o,i){let{cutout:a}=n;if(n.platform==="ios"&&!i&&a.type!=="none"&&a.type!=="punchHole"){let s=qr(Math.max(0,(o-a.widthDp)/2));return{container:{padding:"0"},side:{width:s,[N]:w}}}return{container:{padding:"0 16px"},side:{}}}function _a(n){let{frame:o,content:i}=n,a=n.state??Cm,s=i==="light"?"#ffffff":"#000000",d=o.platform==="ios",l=Hm(o,n.width,n.landscape),p=(u)=>m("span",{style:{display:R,[T]:w,gap:"5px",...l.side}},u);return m("div",{attrs:{[Ye]:"statusBar","data-status-content":i,[ae]:"true"},style:{position:L,left:"0",right:"0",top:"0",height:qr(o.statusBarDp),display:R,[T]:w,[N]:"space-between",...l.container,[K]:Y,color:s,[oe]:d?"16px":"14px",[De]:d?"600":"500",[at]:"2",[Ee]:"none"}},[p([m("span",{attrs:{[zt]:"clock"}},[a.clock])]),p([Bm(a.cellularBars,s),Fm(a.wifi,s),Um(a.batteryPercent,s)])])}var ie=(n)=>`${Number(n.toFixed(3))}px`,jm=["portrait","landscape"],Gm=["portrait"],zm=["landscape"];function wt(n){switch(n.formFactor){case"watch":return Gm;case"tv":case"automotive":return zm;default:return jm}}function Ca(n,o){return n.mask==="round"?"50%":ie(o)}function je(n,o){let{widthDp:i,heightDp:a}=n.screen;return o==="portrait"?{width:i,height:a}:{width:a,height:i}}function Da(n,o){return Na(n.safeArea[o])}function Na(n){return{"--safe-top":ie(n.top),"--safe-bottom":ie(n.bottom),"--safe-left":ie(n.left),"--safe-right":ie(n.right),"--safe-start":"var(--safe-left)","--safe-end":"var(--safe-right)"}}function Vm(n,o,i,a){return a==="portrait"?{x:n,y:o}:{x:o,y:i.screen.widthDp-n}}function Km(n,o){let i=n.cutout;if(i.type==="none")return[];let a=Vm(i.centerXDp,i.centerYDp,n,o),[s,d]=i.type==="punchHole"?[i.radiusDp*2,i.radiusDp*2]:[i.widthDp,i.heightDp],[l,p]=o==="portrait"?[s,d]:[d,s];return[m("div",{attrs:{[Ye]:"cutout",[ae]:"true"},style:{position:L,left:ie(a.x-l/2),top:ie(a.y-p/2),width:ie(l),height:ie(p),[A]:i.type==="notch"?"0 0 16px 16px":ie(Math.min(l,p)/2),[k]:"#000",[at]:"3"}})]}function qm(n,o,i){if(n.statusBarDp===0||o==="landscape"&&n.safeArea.landscape.top===0)return[];let{width:a}=je(n,o);return[_a({frame:n,width:a,landscape:o==="landscape",content:i})]}function Ym(n,o){let i=(a)=>m("span",{style:{display:"inline-block",width:"14px",height:"14px",border:`2px solid ${n}`,[A]:a,opacity:"0.6"}});return m("span",{attrs:{"data-nav":"buttons"},style:{display:R,gap:"64px",[D]:o?"column":"row"}},[i("2px 50% 50% 2px"),i("50%"),i("2px")])}function Oa(n,o){return n.navBar.type==="buttons"&&o==="landscape"&&n.safeArea.landscape.right>0}function Jm(n,o){let i=ie(n);return o?{top:"0",bottom:"0",right:"0",width:i,[D]:M}:{left:"0",right:"0",bottom:"0",height:i}}function Zm(n,o){let i=n==="ios";return m("span",{attrs:{"data-nav":i?"homeIndicator":"handle"},style:{width:i?"134px":"108px",height:i?"5px":"4px",[A]:i?"2.5px":"2px",[k]:o?"#ffffff":"#000000",opacity:i?"0.9":"0.6"}})}function Qm(n,o,i){if(n.navBar.type==="none")return[];let a=n.navBar.type==="gesture"?Zm(n.platform,i):Ym(i?"#ffffff":"#000000",Oa(n,o));return[m("div",{attrs:{[Ye]:"navBar",[ae]:"true"},style:{position:L,...Jm(n.navBar.heightDp,Oa(n,o)),display:R,[T]:w,[N]:w,[at]:"2",[Ee]:"none"}},[a])]}function Yr(n,o,i){return n==="vertical"?{left:ie(o),top:"0",width:ie(i),height:"100%"}:{top:ie(o),left:"0",height:ie(i),width:"100%"}}function eh(n){if(!n)return[];let{band:o,hingeDegrees:i,occluding:a}=n,s={"aria-hidden":"true","data-posture":n.posture,"data-hinge-degrees":String(i)};if(a)return[m("div",{attrs:{"data-chrome":"hinge",...s},style:{position:"absolute",...Yr(o.axis,o.startDp,o.widthDp),"background-color":"#000","z-index":"3"}})];let d=Math.min(1,Math.max(0,(180-i)/180));if(d===0)return[];let l=24,p=`rgba(0,0,0,${Number((d*0.5).toFixed(3))})`,u=o.axis==="vertical"?"to right":"to bottom";return[m("div",{attrs:{"data-chrome":"fold",...s},style:{position:"absolute",...Yr(o.axis,o.startDp-l/2,l),background:`linear-gradient(${u}, transparent, ${p}, transparent)`,"z-index":"1","pointer-events":"none"}})]}function th(n,o,i){if(!o?.occluding)return[n];let{axis:a,startDp:s,widthDp:d}=o.band,l=a==="vertical",p=l?i.width:i.height,u=(f)=>m("div",{style:{position:"absolute",[l?"left":"top"]:ie(f),[l?"top":"left"]:"0",width:ie(l?p-d:i.width),height:ie(l?i.height:p-d)}},[n]),h=(f,y,g,b)=>m("div",{attrs:{"data-segment":b?"after":"before",...b?{"aria-hidden":"true",inert:""}:{}},style:{position:"absolute",overflow:"hidden",...Yr(a,f,y)}},[u(g)]);return[h(0,s,0,!1),h(s+d,p-s-d,-s,!0)]}var nh={closed:"closed",half_opened:"half opened",opened:"opened",rear_display:"rear display",flipped:"flipped",tent:"tent"},rh={top:0,bottom:0,left:0,right:0};function Ma(n,o,i,a){return{position:Z,width:ie(n.width),height:ie(n.height),overflow:"hidden",[A]:o,[k]:a.background,color:a.textColor,[Kt]:"system-ui, -apple-system, Roboto, sans-serif",[oe]:a.fontSize??"14px",...Na(i)}}function La(n,o,i,a){return m("div",{attrs:{[Ye]:"screen","data-frame":n.id,"data-orientation":o},style:Ma(je(n,o),ie(0),rh,{...i,background:"transparent"})},[a])}function $a(n,o,i,a){let s=m("div",{attrs:{[Ye]:"screen"},style:Ma(je(n,o),Ca(n,n.cornerRadiusDp),n.safeArea[o],i)},[...th(a,i.fold,je(n,o)),...eh(i.fold),...qm(n,o,i.statusBarContent??(i.dark?"light":"dark")),...Km(n,o),...Qm(n,o,i.dark)]);return m("div",{attrs:{[Ye]:"frame","data-frame":n.id,"data-orientation":o,...i.posture?{"data-posture":i.posture}:{},...n.mask==="round"?{"data-mask":"round"}:{},[z]:`${n.label} (${[o,...i.posture?[nh[i.posture]]:[]].join(", ")})`},style:{display:"inline-block",padding:ie(n.frame.bezelDp),[k]:n.frame.color,[A]:Ca(n,n.cornerRadiusDp+n.frame.bezelDp)}},[s])}function Gn(n){try{return n()}catch(o){if(o instanceof le)throw new t(o.message,{cause:o});throw o}}async function Fa(n){try{return await n()}catch(o){if(o instanceof le)throw new t(o.message,{cause:o});throw o}}import{createHash as Gc}from"crypto";var Ha=Lt(Im());import{readFileSync as oh}from"fs";import{dirname as ih,join as ah}from"path";import{fileURLToPath as sh}from"url";var dh={filled:"filled",outlined:"outlined",rounded:"round",sharp:"sharp",twoTone:"two-tone"},lh=/^[a-z0-9]+(_[a-z0-9]+)*$/,ch=new Set(["path","circle","ellipse","g"]),ph=new Set(["d","cx","cy","r","rx","ry","opacity","fill-opacity","fill-rule"]),uh=new Ha.Parser({explicitChildren:!0,preserveChildrenOrder:!0,explicitRoot:!1,async:!1});function mh(n){let o;try{uh.parseString(n,(i,a)=>{if(i)throw i;o=a})}catch(i){e.warn(`Material icon SVG did not parse: ${r(i)}`);return}return o}function ja(n){let o=n.$??{};if(!ch.has(n["#name"])||Object.keys(o).some((a)=>!ph.has(a)))return;let i=(n.$$??[]).map(ja);if(i.some((a)=>a===void 0))return;return m(n["#name"],{attrs:{...o}},i)}function hh(n){let o=mh(n);if(o?.["#name"]!=="svg"||o.$?.viewBox!=="0 0 24 24")return;let i=(o.$$??[]).map(ja);return i.length>0&&i.every((a)=>a!==void 0)?i:void 0}class Ga{read;cache=new Map;constructor(n=gh){this.read=n}glyph(n,o){if(!lh.test(n))return;return this.styled(n,o)??(o==="filled"?void 0:this.styled(n,"filled"))}styled(n,o){let i=`${o}/${n}`;if(!this.cache.has(i)){let a;try{a=this.read(dh[o],n)}catch(s){e.warn(`Material icon ${i} could not be read: ${r(s)}`);return}this.cache.set(i,a===void 0?void 0:hh(a))}return this.cache.get(i)}}var Ba;function fh(){return Ba??=ih(sh(import.meta.resolve("@material-design-icons/svg/package.json"))),Ba}function yh(n){return typeof n==="object"&&n!==null&&"code"in n&&n.code==="ENOENT"}function gh(n,o){try{return oh(ah(fh(),n,`${o}.svg`),"utf8")}catch(i){if(!yh(i))throw i;e.debug(`Material icon ${n}/${o} not found: ${r(i)}`);return}}var Ua;function zn(){return Ua??=new Ga,Ua}var Va={yaw:0,pitch:0},Ka={yaw:30,pitch:14};function qa(n){return{yaw:n.yaw,pitch:Math.max(-80,Math.min(80,n.pitch))}}function Ya(n,o){if(o!=="landscape")return n;return n.axis==="vertical"?{axis:"horizontal",at:1-n.at}:{axis:"vertical",at:n.at}}function Xa(n,o,i){let a=Math.max(-80,Math.min(80,n.pitch)),s=180-Math.max(0,Math.min(360,o));return{device:`rotateX(${-a}deg) rotateY(${n.yaw}deg)`,leaf:i==="vertical"?`rotateY(${-s}deg)`:`rotateX(${s}deg)`}}function Xr(n,o){let i=Math.max(0,Math.min(360,n)),a;for(let s of o)if(!a||Math.abs(s.hingeDegrees-i)<Math.abs(a.hingeDegrees-i))a=s;return a?.posture}function Ja(n){let{hinge:o}=n,i=o&&n.panels.find((d)=>d.role===o.panel);if(!o||!i||n.postures.length===0)return;let a=o.axis==="vertical"?i.screen.widthDp:i.screen.heightDp,s=Math.round((o.positionDp+o.widthDp/2)/a*1e4)/1e4;return{hinge:{axis:o.axis,at:s},postures:n.postures.map((d)=>({posture:d.posture,hingeDegrees:d.hingeDegrees}))}}var za=180;function Za(n){let o=m("button",{attrs:{type:"button","data-control":"3d","data-3d-control":"","aria-pressed":"false","aria-label":"3D view",hidden:""}},["3D"]);if(!n)return[o];let i=Xr(za,n.postures);return[o,m("select",{attrs:{"data-control":"posture","data-3d-control":"","aria-label":"Posture",hidden:""}},n.postures.map((a)=>m("option",{attrs:{value:a.posture,"data-hinge":String(a.hingeDegrees),...a.posture===i?{selected:""}:{}}},[a.posture]))),m("label",{attrs:{"data-3d-control":"",hidden:""}},["Hinge ",m("input",{attrs:{type:"range",min:"0",max:"360",step:"5",value:String(za),"data-control":"hinge"}},[])]),m("span",{attrs:{"data-control":"status3d","data-3d-control":"",role:"status"}},[])]}function Qa(n){return n?` data-hinge-axis="${n.hinge.axis}" data-hinge-at="${n.hinge.at}"`:""}var es=["@supports not (transform-style:preserve-3d){[data-3d-control]{display:none!important}}","[data-device3d] [data-viewport]{perspective:2400px}","[data-orbit]{position:absolute;left:0;top:0;transform-style:preserve-3d}","[data-device3d] [data-stage],[data-wrapped]{transform-style:preserve-3d}","[data-wrapped]>*,[data-face],[data-back]{backface-visibility:hidden}","[data-back]{background:linear-gradient(135deg,#3a3a3e,#1c1c1f)}","[data-orbit],[data-leaf]{transition:transform .45s cubic-bezier(.2,.7,.2,1)}","@media (prefers-reduced-motion:reduce){[data-orbit],[data-leaf]{transition:none}}"].join("");function ts(n,o,i){let a=(d)=>`${d}px`;if(i.axis==="vertical"){let d=n*i.at;return{flip:"rotateY(180deg)",clip:`inset(0 ${a(n-d)} 0 0)`,fixed:{width:a(d),height:a(o)},fixedCorners:"0 R R 0",moving:{left:a(d),width:a(n-d),height:a(o)},origin:"0 50%",movingCorners:"R 0 0 R",clone:{left:a(-d)}}}let s=o*i.at;return{flip:"rotateX(180deg)",clip:`inset(0 0 ${a(o-s)} 0)`,fixed:{width:a(n),height:a(s)},fixedCorners:"0 0 R R",moving:{top:a(s),width:a(n),height:a(o-s)},origin:"50% 0",movingCorners:"R R 0 0",clone:{top:a(-s)}}}function ns(n,o,i){let a=n.firstElementChild;if(!a)return;let s=(b,v)=>{let x=document.createElement("div");return x.setAttribute(`data-${b}`,""),x.setAttribute("aria-hidden","true"),Object.assign(x.style,{position:"absolute",left:"0",top:"0",...v}),x},[d,l]=[a.offsetWidth,a.offsetHeight],p=getComputedStyle(a).borderTopLeftRadius,u=(b)=>b.replaceAll("R",p),h=a.getAttribute("style"),f={width:`${d}px`,height:`${l}px`},y=[s("back",{...f,transform:"rotateY(180deg)",borderRadius:p})],g;if(o){let b=i(d,l,o);a.style.clipPath=b.clip;let v=a.cloneNode(!0);v.inert=!0,v.setAttribute("aria-hidden","true"),Object.assign(v.style,{position:"absolute",left:"0",top:"0",clipPath:"none"}),Object.assign(v.style,b.clone);let x=s("face",{...b.moving,left:"0",top:"0",overflow:"hidden"});x.append(v),g=s("leaf",{...b.moving,transformOrigin:b.origin,transformStyle:"preserve-3d"});let E={left:"0",top:"0",transform:b.flip,borderRadius:u(b.movingCorners)};g.append(x,s("back",{...b.moving,...E}));let W={transform:b.flip,borderRadius:u(b.fixedCorners)};y=[s("back",{...b.fixed,...W}),g]}return n.append(...y),n.setAttribute("data-wrapped",""),{view:n,frame:a,frameStyle:h,extras:y,leaf:g,axis:o?.axis??"vertical"}}function rs(n){let o=(i,a)=>{if(i.getAttribute("style"),a===null)i.removeAttribute("style");else i.setAttribute("style",a)};n.extras.forEach((i)=>i.remove()),o(n.frame,n.frameStyle),n.view.removeAttribute("data-wrapped")}function os(n,o,i){let a,s={capture:!0};n.addEventListener("pointerdown",(l)=>{if(o()&&l.shiftKey)l.stopImmediatePropagation(),a={id:l.pointerId,x:l.clientX,y:l.clientY},n.setPointerCapture(l.pointerId)},s),n.addEventListener("pointermove",(l)=>{if(a?.id===l.pointerId){l.stopImmediatePropagation();let p={yaw:(l.clientX-a.x)*0.4,pitch:(a.y-l.clientY)*0.4};a={id:l.pointerId,x:l.clientX,y:l.clientY},i(p)}},s);let d=(l)=>{a=a?.id===l.pointerId?void 0:a};n.addEventListener("pointerup",d),n.addEventListener("pointercancel",d)}function is(n){let o=Number(n.dataset.hingeAt),i=n.dataset.hingeAxis;if(i!=="vertical"&&i!=="horizontal"||!Number.isFinite(o))return;return{axis:i,at:o}}function as(n,o){let i=o?15:5;return{ArrowLeft:{yaw:-i,pitch:0},ArrowRight:{yaw:i,pitch:0},ArrowUp:{yaw:0,pitch:i},ArrowDown:{yaw:0,pitch:-i}}[n]}function ss(n){let o=document,i=o.querySelector("[data-viewport]"),a=o.querySelector("[data-stage]"),s=o.querySelector('[data-control="3d"]'),d=globalThis.CSS?.supports?.("transform-style","preserve-3d")===!0;if(!i||!a||!s||!d)return;let l=o.querySelector('[data-control="posture"]'),p=o.querySelector('[data-control="hinge"]'),u=o.querySelector('[data-control="status3d"]'),h=Array.from(l?.options??[]).map((O)=>({posture:O.value,hingeDegrees:Number(O.dataset.hinge)})),f=n.bodyHinge(o.body),y={on:!1,orbit:n.flat,hinge:180},g,b,v=0;o.querySelectorAll("[data-3d-control]").forEach((O)=>{O.hidden=!1}),i.tabIndex=0,globalThis.dispatchEvent(new Event("resize"));let x=()=>{if(g)n.unwrap(g),g=void 0,o.body.removeAttribute("data-device3d")},E=()=>{let O=Array.from(o.querySelectorAll("[data-view]")).find((j)=>!j.hidden);if(!O||g?.view===O)return;if(x(),!b){b=o.createElement("div"),b.setAttribute("data-orbit","");let j=Array.from(a.children);a.append(b),b.append(...j)}g=n.wrap(O,f&&n.hingeLine(f,O.dataset.orientation??""),n.leaves),o.body.toggleAttribute("data-device3d",g!==void 0)},W=()=>{if(y.on)E();let O=f&&n.postureAt(y.hinge,h);if(u)u.textContent=y.on&&O?`Hinge ${y.hinge}\xB0, ${O} layout`:"";if(g){let j=n.pose(y.orbit,y.hinge,g.axis);b?.style.setProperty("transform",j.device),g.leaf?.style.setProperty("transform",j.leaf)}},ee=(O)=>{if(y.hinge=Math.max(0,Math.min(360,O)),p)p.value=String(y.hinge);let j=n.postureAt(y.hinge,h);if(l&&j)l.value=j},_=()=>{y.on=!0,s.setAttribute("aria-pressed","true"),y.orbit=n.flat,W(),requestAnimationFrame(()=>requestAnimationFrame(()=>{y.orbit=y.on?n.start:y.orbit,W()}))},ye=()=>{y.on=!1,s.setAttribute("aria-pressed","false"),y.orbit=n.flat,ee(180),W();let O=b,j=++v,I=()=>{if(j===v&&!y.on&&b===O&&O)x(),a.append(...Array.from(O.children)),O.remove(),b=void 0};if(globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches===!0){I();return}let ge=[O,g?.leaf].flatMap((ke)=>ke?.getAnimations()??[]);Promise.allSettled(ge.map((ke)=>ke.finished)).then(I)},C=(O)=>{if(ee(O),y.on)W();else _()};s.addEventListener("click",()=>y.on?ye():_()),l?.addEventListener("change",()=>C(Number(l.selectedOptions[0]?.dataset.hinge??180))),p?.addEventListener("input",()=>C(Number(p.value)));let me=(O)=>{y.orbit=n.orbit({yaw:y.orbit.yaw+O.yaw,pitch:y.orbit.pitch+O.pitch}),W()};i.addEventListener("keydown",(O)=>{let j=n.orbitKey(O.key,O.shiftKey);if(y.on&&j)O.preventDefault(),me(j)}),n.dragOrbit(i,()=>y.on,me),new MutationObserver(()=>{if(g?.view.hidden)x(),W()}).observe(a,{attributes:!0,attributeFilter:["hidden"],subtree:!0})}function Vn(n){return n.postures.map((o)=>o.posture)}function Jr(n){let o=Vn(n);return o.includes("opened")?"opened":o[0]}function bh(n,o){let{screen:i,cornerRadiusDp:a,cutout:s,statusBarDp:d,navBar:l,safeArea:p}=o;return{...n,screen:i,cornerRadiusDp:a,cutout:s,statusBarDp:d,navBar:l,safeArea:p}}function ds(n,o){let i=o??Jr(n);if(i===void 0)return{frame:n,panel:"inner"};let a=n.postures.find((l)=>l.posture===i);if(!a){let l=Vn(n);throw new le(l.length===0?`Device frame "${n.id}" has no postures; omit posture.`:`Device frame "${n.id}" has no posture "${i}". Valid postures: ${l.join(", ")}`)}let s=n.panels.find((l)=>l.role===a.panel),d=n.hinge?.panel===a.panel?n.hinge:void 0;return{frame:bh(n,s),posture:a.posture,panel:a.panel,...d?{hinge:d,hingeDegrees:a.hingeDegrees}:{}}}function wh(n,o){let{hinge:i}=n;if(!i)return;if(o==="portrait")return{axis:i.axis,startDp:i.positionDp,widthDp:i.widthDp};return i.axis==="vertical"?{axis:"horizontal",startDp:n.frame.screen.widthDp-i.positionDp-i.widthDp,widthDp:i.widthDp}:{axis:"vertical",startDp:i.positionDp,widthDp:i.widthDp}}function ls(n,o){let i=wh(n,o);if(!i||!n.hinge||n.posture===void 0)return;return{posture:n.posture,band:i,occluding:n.hinge.occluding&&i.widthDp>0,hingeDegrees:n.hingeDegrees??180}}function cs(n,o){if(!o?.occluding)return{width:n.width,height:n.height};return o.band.axis==="vertical"?{width:n.width-o.band.widthDp,height:n.height}:{width:n.width,height:n.height-o.band.widthDp}}function ps(n,o){let i=Math.min(0.5,n);return Math.max(i,Math.min(4,o))}function us(n,o){let i=Math.min(n.width/o.width,n.height/o.height);return Number.isFinite(i)&&i>0?Math.min(4,i*0.95):1}function ms(n){if(n===0)return;return n<0?1.1:0.9090909090909091}function hs(n,o){return n.find((i)=>i.dataset.screen===o)??n[0]}function fs(n,o){return n.variant===o.variant&&n.revision===o.revision&&n.orientation===o.orientation&&(n.posture??"")===o.posture}function ys(n,o){let i=o==="landscape"?1:-1,a=(l)=>`translate(-50%, -50%) rotate(${l}deg)`,s=n==="ios",d=s?0.25:1;return{durationMs:s?400:500,easing:s?"ease-in-out":"cubic-bezier(0.4, 0, 0.2, 1)",outgoing:[{transform:a(0),opacity:1,offset:0},...s?[{transform:a(i*-22.5),opacity:0,offset:d}]:[],{transform:a(i*-90),opacity:0,offset:1}],incoming:[{transform:a(i*90),opacity:0,offset:0},...s?[{transform:a(i*67.5),opacity:1,offset:d}]:[],{transform:a(0),opacity:1,offset:1}]}}function gs(n){return`${n.getHours()%12||12}:${String(n.getMinutes()).padStart(2,"0")}`}function bs(n){return 60000-(n%60000+60000)%60000}function vs(){return{now:()=>Date.now(),schedule:(n,o)=>void globalThis.setTimeout(n,o)}}function xs(n,o,i){let a=Array.from(n.querySelectorAll('[data-status="clock"]'));if(a.length===0)return;let s=()=>{let d=o.now(),l=i.clockText(new Date(d));a.forEach((p)=>{p.textContent=l}),o.schedule(s,i.clockDelay(d))};s()}function Ss(n,o){let{from:i,shown:a,stage:s,stageFrom:d,current:l}=o,p=globalThis.matchMedia?.("(prefers-reduced-motion: reduce)").matches===!0;if(!i||!a||i===a||p||!a.animate)return[];let u={duration:n.durationMs,easing:n.easing};i.hidden=!1;let h=i.animate(n.outgoing,u);return h.onfinish=()=>{i.hidden=i!==l()},[h,a.animate(n.incoming,u),s.animate([{transform:d},{transform:s.style.transform}],u)]}function Rs(n){let{zoomScale:o,fitScale:i,wheelFactor:a,screenView:s,viewMatches:d}=n,{rotation:l,animateTurn:p}=n,u=document,h=u.querySelector("[data-stage]"),f=u.querySelector("[data-viewport]");if(!h||!f)return;let y=Array.from(u.querySelectorAll("[data-view]")),g=(H)=>u.querySelector(`[data-control="${H}"]`),b=g("variant"),v=g("screen"),x=g("layout-posture"),E=g("revisions"),W=g("zoom-level"),ee=(H)=>u.body.dataset[H]??"",_={variant:ee("variant"),revision:ee("revision"),orientation:ee("orientation"),posture:ee("posture"),screen:"",scale:1,x:0,y:0,fit:!0},ye=()=>y.filter((H)=>d(H.dataset,_)),C=()=>s(ye(),_.screen),me="",O=(H)=>{if(_.screen=H?.dataset.screen??_.screen,!v)return;let re=`${_.variant} ${_.revision} ${_.orientation} ${_.posture}`;if(re!==me){me=re;let wn=ye().flatMap((pt)=>pt.dataset.screen??[]);v.replaceChildren(...wn.map((pt)=>new Option(pt,pt))),v.hidden=wn.length<2}v.value=_.screen},j=(H)=>{let re=H.firstElementChild;if(!re)return 1;return i({width:f.clientWidth,height:f.clientHeight},{width:re.offsetWidth,height:re.offsetHeight})},I=()=>{let H=C();if(O(H),y.forEach((re)=>{re.hidden=re!==H}),H&&_.fit)_.scale=j(H),_.x=0,_.y=0;if(h.style.transform=`translate(${_.x}px, ${_.y}px) scale(${_.scale})`,W)W.textContent=`${Math.round(_.scale*100)}%`;E?.querySelectorAll("[data-revision-for]").forEach((re)=>{re.hidden=re.dataset.revisionFor!==_.variant,re.setAttribute("aria-pressed",String(re.dataset.revisionValue===_.revision))})},ge=(H)=>{_.fit=!1,_.scale=o(_.scale,H),I()},ke=()=>{_.fit=!0,I()},Yo=[];g("rotate")?.addEventListener("click",()=>{Yo.forEach((pt)=>pt.finish());let[H,re]=[C(),h.style.transform];_.orientation=_.orientation==="portrait"?"landscape":"portrait",ke();let wn=l(u.body.dataset.platform??"",_.orientation);Yo=p(wn,{from:H,shown:C(),stage:h,stageFrom:re,current:C})}),g("zoom-in")?.addEventListener("click",()=>ge(_.scale*1.25)),g("zoom-out")?.addEventListener("click",()=>ge(_.scale/1.25)),g("zoom-fit")?.addEventListener("click",ke),b?.addEventListener("change",()=>{_.variant=b.value;let H=b.selectedOptions[0];_.revision=H?.dataset.latest??_.revision,ke()}),x?.addEventListener("change",()=>{_.posture=x.value,ke()}),v?.addEventListener("change",()=>{_.screen=v.value,I()}),E?.addEventListener("click",(H)=>{let re=H.target.closest("[data-revision-value]");if(re?.dataset.revisionValue)_.revision=re.dataset.revisionValue,I()}),f.addEventListener("wheel",(H)=>{let re=a(H.deltaY);if(re===void 0)return;H.preventDefault(),ge(_.scale*re)},{passive:!1});let Bt;f.addEventListener("pointerdown",(H)=>{Bt={x:H.clientX-_.x,y:H.clientY-_.y},f.setPointerCapture(H.pointerId)}),f.addEventListener("pointermove",(H)=>{if(Bt)_.fit=!1,_.x=H.clientX-Bt.x,_.y=H.clientY-Bt.y,I()}),f.addEventListener("pointerup",()=>{Bt=void 0}),f.addEventListener("dblclick",ke),globalThis.addEventListener("resize",I),n.startClock(u,n.browserClock(),n),I()}var Zr=360,vh=60,xh=0.06,Sh=0.25,Rh=0.85,Eh=3,Es=0.02,Th=0.05,Ah=0.95,Ts=(n)=>Math.min(1,Math.max(0,n)),Qr=(n)=>Math.trunc(Ts(n)*255+0.5);function Jt(n,o,i){let a=(n%Zr+Zr)%Zr/60,s=Ts(o),d=(1-Math.abs(2*i-1))*s,l=d*(1-Math.abs(a%2-1)),p=i-d/2,u=Math.floor(a)%6,[h,f,y]=[[d,l,0],[l,d,0],[0,d,l],[0,l,d],[l,0,d],[d,0,l]][u];return{r:Qr(h+p),g:Qr(f+p),b:Qr(y+p),a:1}}function kh(n){let[o,i,a]=[n.r/255,n.g/255,n.b/255],s=Math.max(o,i,a),d=Math.min(o,i,a),l=s-d;if(l===0)return{hue:0,saturation:0};let p=l/(1-Math.abs(s+d-1));return{hue:(s===o?((f)=>(f%6+6)%6)((i-a)/l):s===i?(a-o)/l+2:(o-i)/l+4)*60,saturation:p}}function Wh(n,o){let i=o==="dark",{hue:a,saturation:s}=kh(n),d=s===0?0:Math.min(Rh,Math.max(Sh,s)),l=(C,me,O,j)=>Jt(C,me,i?j:O),p=xh,u=l(a,p,0.98,0.07),h=(C,me)=>{let O=i?Es:-Es,j=i?0.8:0.4,I=Jt(C,me,j);while(sE(I,u)<Eh&&j+O>=Th&&j+O<=Ah)j+=O,I=Jt(C,me,j);return I},f=(C,me,O)=>{let j=Jt(me,O,0.98),I=Jt(me,O,0.04);return sE(C,j)>=sE(C,I)?j:I},y=d*0.35,g=a+vh,b=d*0.6,v=h(a,d),x=h(a,y),E=h(g,b),W=l(a,d,0.9,0.3),ee=l(a,y,0.9,0.3),_=l(g,b,0.9,0.3),ye=l(a,p,0.1,0.9);return{primary:v,onPrimary:f(v,a,d),primaryContainer:W,onPrimaryContainer:f(W,a,d),secondary:x,onSecondary:f(x,a,y),secondaryContainer:ee,onSecondaryContainer:f(ee,a,y),tertiary:E,onTertiary:f(E,g,b),tertiaryContainer:_,onTertiaryContainer:f(_,g,b),background:u,onBackground:ye,surface:u,onSurface:ye,surfaceVariant:l(a,p*2,0.9,0.25),onSurfaceVariant:l(a,p*2,0.3,0.8),surfaceContainerLowest:l(a,p,1,0.04),surfaceContainerLow:l(a,p,0.96,0.1),surfaceContainer:l(a,p,0.94,0.12),surfaceContainerHigh:l(a,p,0.92,0.17),surfaceContainerHighest:l(a,p,0.9,0.22),outline:l(a,p*2,0.46,0.6),outlineVariant:l(a,p*2,0.8,0.3)}}function eo(n,o,i){let a=c(c(c(n)?.theme)?.colors),s=a?.seed!==void 0||a?.source!==void 0,d=Fg({},o,s?void 0:i),l=a?.seed,p=typeof l==="string"?df(l):void 0;if(p)for(let[u,h]of Object.entries(Wh(p,o)))d.set(u,h);for(let[u,h]of K2(n,o))d.set(u,h);return d}var Ph=new Set(["button","checkbox","switch","slider","tab","textbox"]),Ih={outline:"3px solid #ffffff","outline-offset":"2px"};function _h(n,o){return(o||n.attrs["data-node"]!==void 0)&&Ph.has(n.attrs.role??"")}var Ch=(n)=>n.attrs["data-part"]==="dialogLayer";function As(n){let o;return n.children.forEach((i,a)=>{if(typeof i==="string")return;let s=As(i);if(s)o=[a,...s];else if(Ch(i))o=[a]}),o}function Oh(n){return{...n,attrs:{...n.attrs,"data-focus":"ring"},style:{...n.style,...Ih,"box-shadow":n.style["box-shadow"]?`0 0 0 5px rgba(0, 0, 0, 0.6), ${n.style["box-shadow"]}`:"0 0 0 5px rgba(0, 0, 0, 0.6)"}}}function ks(n,o,i=!1){if(typeof n==="string"||o.found||n.attrs["aria-disabled"]==="true")return n;if(_h(n,i))return o.found=!0,Oh(n);let a=i||n.attrs["data-node"]!==void 0,s=n.children.map((d)=>ks(d,o,a));return o.found?{...n,children:s}:n}function Ws(n,o,i){let[a,...s]=o;if(a===void 0)return ks(n,i);let d=n.children[a],l=Ws(d,s,i);return l===d?n:{...n,children:n.children.map((p,u)=>u===a?l:p)}}function Ps(n){return Ws(n,As(n)??[],{found:!1})}var Dh=Zre,Nh=600,Mh=896;function Lh(n){let[o=600,i=840]=Dh;if(n<o)return"compact";return n<i?"medium":"expanded"}function $h(n,o){return Math.min(n,o)>=Nh||n>=Mh?"regular":"compact"}function Fh(n){if(n?.posture==="opened")return"flat";if(n?.posture==="half_opened")return n.hinge==="horizontal"?"tabletop":"book";return}function Is(n){let o=Math.round(n.widthDp),i=Math.round(n.heightDp);return{"/device/os":n.platform,"/device/widthClass":n.platform==="android"?Lh(o):$h(o,i),"/device/posture":n.platform==="android"?Fh(n.fold):void 0}}function _s(n,o,i,a){let s=[],d=0;for(let l of Xm(n,"platform:")){let p=i(l.pointer);if(o&&Object.hasOwn(o,p)){let u=o[p];s.push(n.slice(d,l.start),typeof u==="string"?a(u):""),d=l.end}}return d===0?n:s.join("")+n.slice(d)}var tt=(n)=>`${Number(n.toFixed(3))}px`,Bh=(n)=>`${Number((n*100).toFixed(3))}%`;function be(n){return`rgba(${n.r},${n.g},${n.b},${Number(n.a.toFixed(3))})`}function S(n,o){let i=lf(n,o.mode,o.palette);return i?be(i):void 0}function Uh(n,o){let i=n.map((d)=>S(c(d)?.color,o)??"rgba(0,0,0,0)"),a=n.map((d)=>c(d)?.position);if(!a.every((d)=>typeof d==="number"))return i;let s=0;return i.map((d,l)=>(s=Math.max(s,a[l]),`${d} ${Bh(s)}`))}function to(n,o){let i=c(n);if(!i||!Array.isArray(i.stops)||i.stops.length<2)return;let a=Uh(i.stops,o).join(",");if(i.type==="linear"&&typeof i.angle==="number")return`linear-gradient(${Number((i.angle+90).toFixed(3))}deg,${a})`;return i.type==="radial"?`radial-gradient(circle farthest-corner at 50% 50%,${a})`:void 0}function Hh(n,o){let i=S(n.color,o);if(!i||typeof n.radius!=="number")return;let a=c(n.offset),s=typeof n.spread==="number"?n.spread:0,d=[tt(typeof a?.x==="number"?a.x:0),tt(typeof a?.y==="number"?a.y:0),tt(n.radius),tt(s),i];return(n.inner===!0?["inset",...d]:d).join(" ")}function no(n,o,i){let s=(Array.isArray(n.shadows)?n.shadows:[]).map((d)=>c(d)).filter((d)=>d!==void 0&&d.inner===!0===o).map((d)=>Hh(d,i)).filter((d)=>d!==void 0).reverse();return s.length>0?s.join(","):void 0}function Ds(n,o){if(typeof n.elevation!=="number"||n.elevation<=0||n.shadows!==void 0)return;let i=lf(n.shadowColor,o.mode,o.palette),a=i?be({...i,a:i.a*0.25}):"rgba(0,0,0,0.25)";return`0 ${tt(n.elevation/2)} ${tt(n.elevation)} ${a}`}var jh=0.85;function Ns(n,o){if(n.surface!=="glass")return{};let i=c(n.glass),a=lf(i?.tint,o.mode,o.palette),s=n.cornerRadius===void 0?{[A]:"9999px",overflow:"hidden"}:{},d=o.platform==="ios"?zh(a,i?.variant==="clear",o):Gh(a,o);return{...s,...d}}function Gh(n,o){let i=n??lf("surfaceContainer",o.mode,o.palette);return i?{[k]:be({...i,a:jh})}:{}}function zh(n,o,i){let a=n??{r:255,g:255,b:255,a:1},s=!n&&i.mode==="dark"?0.5:1;return{[k]:be({...a,a:(o?0.12:0.32)*s}),"backdrop-filter":`blur(${o?6:16}px) saturate(1.8)`,[Be]:"inset 0 0 0 1px rgba(255,255,255,0.35)"}}var Cs={position:L,inset:"0",[A]:"inherit",[K]:Y,[Ee]:"none"};function Vh(n,o){let i=c(n);if(!i)return[];let a=[],s=c(i.border),d=to(s?.gradient,o);if(d&&typeof s?.width==="number"&&s.width>0)a.push(m("span",{attrs:{[ae]:"true","data-layer":"border"},style:{...Cs,padding:tt(s.width),"background-image":d,"mask-image":"linear-gradient(#000,#000),linear-gradient(#000,#000)","mask-clip":"content-box,border-box","mask-composite":"exclude"}}));let l=no(i,!0,o);if(l)a.push(m("span",{attrs:{[ae]:"true","data-layer":"innerShadow"},style:{...Cs,[Be]:l}}));return a}function nt(n,o,i){let a=Vh(o,i);if(a.length===0)return n;return{...n,style:{position:Z,...n.style},children:[...n.children,...a]}}var Os={attrs:{},style:{}};function Ms(n,o){let i=c(n.fadeEdges);if(!i)return Os;let a=n.axis==="horizontal",s=n.reverse===!0,d=a?s?"start":"end":s?"top":"bottom",l=i[d];if(typeof l!=="number"||l<=0)return Os;let p=a&&d==="end"!==(o.rtl===!0);return{attrs:{"data-fade":a?"x":"y"},style:{"--fade-mask":`linear-gradient(${a?p?"to left":"to right":d==="bottom"?"to top":"to bottom"},rgba(0,0,0,0) 0,#000 min(${tt(l)},100%))`}}}var Ls="@keyframes prototype-fade{from,to{mask-image:var(--fade-mask)}}@supports (animation-timeline:scroll()){[data-fade]{animation-name:prototype-fade;animation-duration:auto;animation-timing-function:linear;animation-fill-mode:both;animation-timeline:scroll(self y)}[data-fade=x]{animation-timeline:scroll(self x)}}@supports not (animation-timeline:scroll()){[data-fade]{mask-image:var(--fade-mask)}}";function Kn(n,o){if(c(n.style)?.shader===void 0)return;let i=typeof n.id==="string"?n.id:void 0;return{type:String(n.type),...i?{id:i}:{},path:o,reason:"shaderFallback"}}var Kh={sans:"sans-serif",serif:"serif",mono:"monospace"};function Us(n){let o=c(c(c(n)?.theme)?.typography);if(!o)return;let i=typeof o.scale==="number"?o.scale:1,a=Kh[String(o.fontFamily)];return{scale:i,...a?{fontFamily:a}:{}}}var Zt="webRowMeasure",ro="webRowBound",vt="webIncomingHeight",qn="webIncomingAllocated",Yn="webSafeInset";function qh(n,o,i){if(typeof i==="number")n["flex-grow"]="0",n[Vt]=se(i),n.width=se(i);n[q]=String(o)}function Yh(n,o,i,a){n[te]="0";let s=c(o.width)?.dp;if(typeof a==="number"||typeof s==="number"){let d=se(Math.max(typeof a==="number"?a:s,i));if(n.width=d,typeof a==="number")n[Vt]=d}}function Hs(n,o){let i=c(n),a=c(i?.[Zt]);if(o.parentAxis!=="row"||a?.later!==!0||typeof i?.minWidth!=="number")return;return typeof a.basis==="number"||typeof c(i.width)?.dp==="number"?void 0:i.minWidth}function Xh(n,o,i){let a=c(o[Zt]);if(i.parentAxis!=="row"||!a)return;if(a.take===!0)n.flex="1 1 0";if(typeof a.shrink==="number")qh(n,a.shrink,a.basis);if(a.later===!0&&typeof o.minWidth==="number"){Yh(n,o,o.minWidth,a.basis);return}if(typeof o.minWidth!=="number"&&(a.take===!0||("shrink"in a)))n[te]="0";if(a.zero===!0)n[te]="0",n[ce]="0px"}var se=(n)=>`${Number(n.toFixed(3))}px`;function pe(n,o){return se(o.textScale?o.textScale.font(n):n)}function Jh(n,o){return se(o.textScale?o.textScale.tracking(n):n)}var $s={none:0,extraSmall:4,small:8,medium:12,large:16,extraLarge:28,full:9999};function Fs(n,o,i,a){let s=a.parentAxis===(o==="width"?"row":"column");if(i==="fill")if(s)n.flex="1 1 auto";else if(a.parentAxis)n[G]="stretch",n[o]="100%";else n[o==="width"?"justify-self":"align-self"]="stretch",n[o]="100%";else if(typeof c(i)?.dp==="number")n[o]=se(c(i).dp),n[q]="0"}function Zh(n){if(typeof n==="number")return{[A]:se(n)};if(typeof n==="string")return $s[n]===void 0?void 0:{[A]:se($s[n])};let o=c(n);if(!o)return;let i=(a)=>se(typeof o[a]==="number"?o[a]:0);return{"border-start-start-radius":i("topStart"),"border-start-end-radius":i("topEnd"),"border-end-end-radius":i("bottomEnd"),"border-end-start-radius":i("bottomStart")}}function Qh(n,o,i){let a=c(o.padding);for(let[l,p]of[["top","padding-top"],["bottom","padding-bottom"],["start","padding-inline-start"],["end","padding-inline-end"]])if(typeof a?.[l]==="number")n[p]=se(a[l]);let s=S(o.background,i);if(s)n[k]=s;let d=Zh(o.cornerRadius);if(d)Object.assign(n,d),n.overflow="hidden";if(ef(n,o,i),typeof o.alpha==="number")n.opacity=String(o.alpha)}function ef(n,o,i){let a=to(o.gradient,i);if(a)n["background-image"]=a,n["background-origin"]="border-box";let s=c(o.border);if(typeof s?.width==="number"&&s.gradient===void 0)n.border=`${se(s.width)} solid ${S(s.color,i)??"currentColor"}`;let{[k]:d,[Be]:l,...p}=Ns(o,i);if(Object.assign(n,p),d&&!n[k])n[k]=d;let u=[Ds(o,i),no(o,!1,i),l].filter((h)=>h!==void 0).join(",");if(u)n[Be]=u}var tf=[["minWidth","min-width","row"],["maxWidth","max-width","row"],["minHeight","min-height","column"],["maxHeight","max-height","column"]];function nf(n,o,i){for(let[a,s,d]of tf)if(typeof o[a]==="number"&&d!==i)n[s]=se(o[a])}function rf(n,o,i,a){if(o[ro]!==!0||i.unboundedWidth===!0)return;let s=typeof o.maxWidth==="number"&&a!=="row"?se(o.maxWidth):void 0;n[ce]=s?`min(100%, ${s})`:"100%"}function of(n,o,i){Fs(n,"width",o.width,i),Fs(n,"height",o.height,i);let a=typeof o.weight==="number"&&i.parentAxis!==void 0;if(a)n.flex=`${o.weight} ${o.weight} 0`,n[i.parentAxis==="row"?"min-width":"min-height"]="0";let s=a&&i.weightsChildren===!0?i.parentAxis:void 0;if(nf(n,o,s),rf(n,o,i,s),Xh(n,o,i),typeof o.aspectRatio==="number")n[Gt]=String(o.aspectRatio),af(n,o,o.aspectRatio,i)}function af(n,o,i,a){if(o.width!==void 0||o.height!==void 0||typeof o.weight==="number"||i<=0||a.parentAxis==="row")return;if(n.width="100%",typeof o.maxHeight==="number"){let d=o.maxHeight*i,l=typeof o.maxWidth==="number"?o.maxWidth:1/0;n[ce]=se(Math.min(d,l))}}var Bs={start:"start",center:w,end:"end",justify:"justify"},sf={displayLarge:[57,64,400],displayMedium:[45,52,400],displaySmall:[36,44,400],headlineLarge:[32,40,400],headlineMedium:[28,36,400],headlineSmall:[24,32,400],titleLarge:[22,28,400],titleMedium:[16,24,500],titleSmall:[14,20,500],bodyLarge:[16,24,400],bodyMedium:[14,20,400],bodySmall:[12,16,400],labelLarge:[14,20,500],labelMedium:[12,16,500],labelSmall:[11,16,500]};function cf(n,o){let i=typeof n.textStyle==="string"?sf[n.textStyle]:void 0;if(!i)return{};let a=o.typography?.scale??1,s=o.typography?.fontFamily;return{[oe]:pe(i[0]*a,o),[Xe]:pe(i[1]*a,o),[De]:String(i[2]),...s?{[Kt]:s}:{}}}var pf={sansSerif:"sans-serif",serif:"serif",monospace:"monospace"},uf={italic:"italic",normal:"normal"},mf={none:"none",underline:"underline",lineThrough:"line-through",underlineLineThrough:"underline line-through"};function B(n,o){if(!n)return{};let i=cf(n,o),a=S(n.color,o);if(a)i.color=a;if(typeof n.textSize==="number")i[oe]=pe(n.textSize,o);if(typeof n.fontWeight==="number")i[De]=String(n.fontWeight);if(typeof n.textAlign==="string"&&Bs[n.textAlign])i[yt]=Bs[n.textAlign];if(typeof n.lineHeight==="number")i[Xe]=pe(n.lineHeight,o);if(typeof n.letterSpacing==="number")i["letter-spacing"]=Jh(n.letterSpacing,o);let s=uf[String(n.fontStyle)];if(s)i["font-style"]=s;let d=pf[String(n.fontFamily)];if(d)i[Kt]=d;let l=mf[String(n.textDecoration)];if(l)i["text-decoration"]=l;return i}function js(n,o){let i={[K]:Y},a=c(n);if(a)of(i,a,o),Qh(i,a,o),hf(i,a,o);return i}function oo(n,o){return o==="row"&&c(n[Zt])?.zero===!0}function hf(n,o,i){if(!oo(o,i.parentAxis))return;if(n["padding-inline-start"]="0px",n["padding-inline-end"]="0px",n.border!==void 0)n["border-inline-width"]="0px"}var ff={start:"flex-start",center:w,end:"flex-end",spaceBetween:"space-between",spaceAround:"space-around",spaceEvenly:"space-evenly"},yf=new Set(["row","column","card"]);function Ge(n,o,i){return{...n.style,parentAxis:i,weightsChildren:i!==void 0&&yf.has(o.type),unboundedWidth:n.style.unboundedWidth===!0&&!io(o.style)}}function io(n){let o=c(n);return typeof c(o?.width)?.dp==="number"||typeof o?.maxWidth==="number"}function Gs(n,o){let i=o.axis==="horizontal",a=Ge(n,o,i?"row":"column");return i?{...a,unboundedWidth:!0}:a}function Xn(n,o){let i=c(o),a={display:R,[D]:n},s=typeof i?.arrangement==="string"?ff[i.arrangement]:void 0;if(s)a[N]=s;if(typeof i?.spacing==="number")a.gap=se(i.spacing);let d=typeof i?.alignment==="string"?i.alignment:"topStart";return a[T]=n==="row"?zs(d):Vs(d),a}function zs(n){if(n.startsWith("top"))return"flex-start";return n.startsWith("bottom")?"flex-end":"center"}function Vs(n){if(n.endsWith("Start"))return"flex-start";return n.endsWith("End")?"flex-end":"center"}function Qt(n){let o=c(n)?.alignment,i=typeof o==="string"?o:"topStart";return{display:"grid","grid-template-areas":'"cell"',[T]:zs(i).replace("flex-",""),"justify-items":Vs(i).replace("flex-","")}}function Ks(n,o){if(n.multiline!==!0)return{};let i=o.textScale?o.textScale.font(24):24,a={[Ie]:"pre-wrap",[Xe]:se(i)};if(typeof n.minLines==="number")a[U]=se(n.minLines*i);if(typeof n.maxLines==="number")a[Je]=se(n.maxLines*i),a.overflow="hidden";return a}function xt(n,o,i){let a={},s=S(o,n.style),d=S(i,n.style);if(s)a[k]=s;if(d)a.color=d;return a}function gf(n,o){let i=S("outline",o.style)??"currentColor",a=m("span",{attrs:{[P]:"thumb"},style:{width:n?"24px":"16px",height:n?"24px":"16px",[A]:"50%",[k]:n?S("onPrimary",o.style)??"#fff":i,...n?{[ht]:"auto"}:{}}});return m("span",{style:{display:R,[T]:w,[K]:Y,width:"52px",height:"32px",padding:n?"0 4px":"0 6px",[A]:"16px",[q]:"0",border:`2px solid ${n?"transparent":i}`,...xt(o,n?"primary":"surfaceContainerHighest","onPrimary")}},[a])}function ao(n,o,i){return n==="switch"?gf(o,i):m("span",{style:{width:"18px",height:"18px",[A]:"2px",[q]:"0",border:`2px solid ${S(o?"primary":"onSurfaceVariant",i.style)??"currentColor"}`,...o?xt(i,"primary","onPrimary"):{}}})}var qs=[[31536000000,"year"],[2592000000,"month"],[86400000,"day"],[3600000,"hour"],[60000,"minute"],[1000,"second"]];function bf(n){if(typeof n==="number")return Number.isFinite(n)&&Number.isInteger(n)&&Math.abs(n)<=8640000000000000?n:void 0;if(typeof n!=="string"||!/^\d{4}-\d{2}-\d{2}(?:T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2}))?$/.test(n))return;let o=n.slice(0,10),i=Date.parse(`${o}T00:00:00Z`);if(!Number.isFinite(i)||new Date(i).toISOString().slice(0,10)!==o)return;let a=Date.parse(n);return Number.isFinite(a)?a:void 0}function Ys(n){return{minimumFractionDigits:n.minFraction,maximumFractionDigits:n.maxFraction}}function wf(n,o,i){if(typeof o!=="number"||!Number.isFinite(o))return;let a;if("number"in n)a={...Ys(n.number),useGrouping:n.number.grouping===!1?!1:"auto"};else if("compact"in n)a={notation:"compact",compactDisplay:n.compact.style??"short",useGrouping:"auto"};else if("currency"in n)a={style:"currency",currency:n.currency.code,useGrouping:"auto"};else if("percent"in n)a={style:"percent",...Ys(n.percent),useGrouping:"auto"};else return;return new Intl.NumberFormat(i,a).format(o)}function vf(n,o,i){if(!Number.isFinite(i.nowMs))return;let a=n-i.nowMs,s=new Intl.RelativeTimeFormat(i.locale,{style:o,numeric:Math.abs(a)<1000?"auto":"always"}),[d,l]=qs.find(([p])=>Math.abs(a)>=p)??qs[5];return s.format(Math.trunc(a/d)||0,l)}function xf(n,o,i){let a=bf(o);if(a===void 0)return;if("relative"in n)return vf(a,n.relative.style??"long",i);let s="date"in n?{dateStyle:n.date.style??"medium"}:("time"in n)?{timeStyle:n.time.style??"short"}:{};return new Intl.DateTimeFormat(i.locale,{...s,timeZone:i.timeZone}).format(a)}function Xs(n,o,i){try{return"date"in n||"time"in n||"relative"in n?xf(n,o,i):wf(n,o,i.locale)}catch(a){i.logger?.debug(`Prototype formatter rejected input: ${String(a)}`);return}}function Js(n,o){return{...o,locale:n.locale??o.locale,timeZone:n.timeZone??o.timeZone}}function Zs(n,o,i){let a=n.derive&&Object.hasOwn(n.derive,o)?n.derive[o]:void 0;if(!a)return"";let s="value"in a.of?a.of.value:("data"in a.of)?Pt(i.data,a.of.data):i.state&&Object.hasOwn(i.state,a.of.state)?i.state[a.of.state]:void 0;return Xs(a.format,s,Js(a,i.env))??""}function Qs(n,o,i){let a={...o};for(let[s,d]of Object.entries(n)){let l="value"in d.of?d.of.value:Object.hasOwn(o,d.of.item)?o[d.of.item]:void 0;Object.defineProperty(a,s,{value:Xs(d.format,l,Js(d,i))??"",enumerable:!0,configurable:!0,writable:!0})}return a}var ze=(n)=>`${Number(n.toFixed(3))}px`,St=(n)=>typeof n==="number"&&n>0?n:0,Jn=22,Sf={pager:["width","height"],grid:["width"],carousel:["width"],slider:["width"],tabBar:["width"],bottomNav:["width"],radioGroup:["width"],select:["width"],searchBar:["width"]};function Te(n){let o=c(n.style)??{};return(Sf[String(n.type)]??[]).filter((a)=>o[a]===void 0)}function he(n,o){let i=c(n.style)??{},a=Object.fromEntries(o.map((s)=>[s,"fill"]));return{...n,style:{...a,...i}}}function so(n){let o=c(n),i=c(o?.style)??{};return o?.type==="spacer"&&i.width===void 0&&i.height===void 0&&i.weight===void 0}function ed(n){return so(n)?he(n,["width","height"]):n}function td(n){return n.type==="row"?"width":n.type==="column"?"height":void 0}function en(n,o,i){let a=Array.isArray(n.children)?n.children.length:0,s=typeof n.stateKey==="string"?i.bound(n.stateKey,o):void 0,d=s===void 0?void 0:o.condition.state[s];if(typeof d!=="number"||!Number.isFinite(d)||a===0)return 0;return Math.trunc(Math.min(Math.max(d,0),a-1))}function nd(n,o,i){if(n.type!=="pager")return o;let a=Array.isArray(n.children)?n.children.length:0,s=en(n,o,i)+1;return{...o,textLocals:{...o.textLocals,page:s,pageCount:a}}}function rd(n,o,i){let a;return X(o.spec,(s)=>{if(!a&&s.type==="pager"&&s.id===n)a=s}),a?en(a,o,i):void 0}function Rf(n,o){let i=c(n.style)??{},a=typeof c(n.pageSize)?.dp==="number";return{width:i.width!=="wrap"&&(!a||o),height:i.height!=="wrap"&&(!a||!o)}}function Ef(n,o){let i=Rf(n,o),a=c(n.pageSize)?.dp,s={...Qt(void 0),[te]:"0",[U]:"0"};if(o?i.width:i.height)s.flex="1 1 auto";if(o?i.height:i.width)s[G]="stretch";else if(typeof a==="number")s[o?"height":"width"]=ze(a),s[G]="flex-start";return s}function Tf(n,o){let i=c(n.peek),a=St(i?.start),s=St(i?.end),d={};if(a>0)d[o?"padding-top":"padding-inline-start"]=ze(a);if(s>0)d[o?"padding-bottom":"padding-inline-end"]=ze(s);return d}function Af(n,o,i,a){let s=S("onSurface",a.style)??"currentColor",d=Array.from({length:n},(u,h)=>m("span",{attrs:{[P]:"dot"},style:{width:"6px",height:"6px",[A]:"50%",[k]:s,...h===o?{}:{opacity:"0.38"}}})),l={display:R,[D]:i.vertical?"column":"row",[T]:w,[N]:w,gap:"8px"},p=i.over?i.vertical?{position:L,top:"0",bottom:"0",right:"8px"}:{position:L,left:"0",right:"0",bottom:"8px"}:i.vertical?{width:ze(Jn),[G]:ne,[q]:"0"}:{height:ze(Jn),[G]:ne,[q]:"0"};return m("div",{attrs:{[P]:"indicator",[ae]:"true"},style:{...l,...p,[Ee]:"none"}},d)}function kf(n,o){let i=c(c(n.style)?.[o?"width":"height"])?.dp;return typeof i!=="number"||i-Jn>=Jn}var Wf=(n)=>(o,i,a)=>{let s=he(o,Te(o)),d=s.axis==="vertical",l=Array.isArray(s.children)?s.children:[],p=en(s,i,n),u=s.indicator==="dots"&&l.length>0,h=s.indicatorPlacement!=="below"||!kf(s,d),{attrs:f,style:y}=n.base(s,i,{display:R,[D]:d?"row":"column",overflow:"hidden",position:Z}),g=n.child(i,{inBox:!0,style:Ge(i,s,void 0)}),b=n.renderNode(l[p],g,`${a}.children[${p}]`),v=m("div",{attrs:{[P]:"page"},style:Ef(s,d)},b?[b]:[]),x=m("div",{attrs:{[P]:"viewport"},style:{display:R,[D]:d?"row":"column",flex:"1 1 auto",[G]:ne,[te]:"0",[U]:"0",...Tf(s,d)}},[v]),E=u?[Af(l.length,p,{vertical:d,over:h},i)]:[];return m("div",{attrs:f,style:y},[x,...E])};function Pf(n,o,i){if(typeof n==="number")return Math.max(1,Math.trunc(n));let a=c(n)?.minWidth;return typeof a==="number"?Math.max(1,Math.floor((o+i)/(a+i))):1}var If=(n)=>(o,i)=>{if(!o)return;let a=typeof i.span==="number"?Math.trunc(i.span):1,s={...o.style};if(delete s.width,delete s[ce],delete s.flex,s.height==="100%")delete s.height;return{...o,style:{...s,"grid-column":`span ${Math.min(Math.max(1,a),n)}`,[mt]:ne,[G]:"start",[te]:"0"}}},_f=(n)=>(o,i,a)=>{let s=he(o,Te(o)),d=c(s.style)??{},l=St(d.spacing),p=typeof d.runSpacing==="number"?St(d.runSpacing):l,u=Pf(s.columns,i.screenWidth,l),h=n.base(s,i,{display:"grid",[ut]:`repeat(${u}, minmax(0, 1fr))`,"column-gap":ze(l),"row-gap":ze(p),[T]:"start","align-content":"start"}),f=n.child(i,{inBox:!1,style:Ge(i,s,void 0)});return m("div",h,n.children(s,f,a,If(u)))},Cf=(n)=>(o,i,a)=>{let s=he(o,Te(o)),{attrs:d,style:l}=n.base(s,i,{display:R,[D]:"row",overflow:"hidden",gap:ze(St(s.itemSpacing))}),p=n.child(i,{inBox:!0,style:Ge(i,s,void 0)}),u=(f)=>m("div",{attrs:{[P]:"item"},style:{...Qt(void 0),flex:`0 0 ${ze(St(s.itemWidth))}`,[A]:"28px",overflow:"hidden"}},f?[f]:[]),h=n.children(s,p,a,u);return m("div",{attrs:d,style:l},h)};function od(n){return{pager:Wf(n),grid:_f(n),carousel:Cf(n)}}function id(n,o){if("equals"in o)return n===o.equals;if("notEquals"in o)return n!==o.notEquals;if(typeof o.gt==="number")return typeof n==="number"&&n>o.gt;if(typeof o.lt==="number")return typeof n==="number"&&n<o.lt;if(typeof o.empty==="boolean")return(n===void 0||n===""||Array.isArray(n)&&n.length===0)===o.empty;return}function Of(n){if(n.includes(!1))return!1;return n.includes(void 0)?void 0:!0}function Df(n){if(n.includes(!0))return!0;return n.includes(void 0)?void 0:!1}function st(n,o){let i=c(n);if(!i)return;if(Array.isArray(i.all))return Of(i.all.map((s)=>st(s,o)));if(Array.isArray(i.any))return Df(i.any.map((s)=>st(s,o)));if(i.not!==void 0){let s=st(i.not,o);return s===void 0?void 0:!s}if(typeof i.key==="string"&&Object.hasOwn(o.state,i.key))return id(o.state[i.key],i);let a=o.platformState??{};if(typeof i.platform==="string"&&Object.hasOwn(a,i.platform))return id(a[i.platform],i);return}function lo(n,o){return st(n,o)??!0}var Nf={filled:["primary","onPrimary"],tonal:["secondaryContainer","onSecondaryContainer"],elevated:["surfaceContainerLow","primary"]},ad=(n)=>(o,i)=>{let a=n.disabledState(o,i),s=typeof o.variant==="string"?o.variant:"filled",d=Nf[s],l=s==="outlined"?{border:`1px solid ${S("outline",i.style)??"currentColor"}`}:{},{attrs:p,style:u}=n.base(o,i,{display:"inline-flex","align-items":"center","justify-content":"center","min-height":"40px",padding:"0 24px","border-radius":"20px","font-weight":"500",...d?n.roleCss(i,d[0],d[1]):n.roleCss(i,"transparent","primary"),gap:"8px",...l,...a.css}),h=typeof o.icon==="string"?[n.icon({type:"icon",name:o.icon},i,"")]:[];return m("div",{attrs:{...p,role:"button",...a.attrs},style:u},[...h,n.bound(o.label,i)])};function po(n,o,i){return typeof n==="string"?o.condition.state[i.bound(n,o)]:void 0}function Mf(n,o,i,a){let s=a.icon({type:"icon",name:n},i,"");return{...s,style:{...s.style,width:`${o}px`,height:`${o}px`}}}var sd={standard:[void 0,"onSurfaceVariant"],filled:["primary","onPrimary"],tonal:["secondaryContainer","onSecondaryContainer"],outlined:[void 0,"onSurfaceVariant"]},Lf=(n)=>(o,i)=>{let a=typeof o.variant==="string"?o.variant:"standard",[s,d]=sd[a]??sd.standard,l=n.disabledState(o,i),p=S(d,i.style),{attrs:u,style:h}=n.base(o,i,{display:de,[T]:w,[N]:w,width:"48px",height:"48px",[q]:"0",...p?{color:p}:{},...l.css}),f=s?S(s,i.style):void 0,y=S("outlineVariant",i.style)??"currentColor",g=m("span",{attrs:{[P]:"container"},style:{display:de,[T]:w,[N]:w,width:"40px",height:"40px",[A]:"50%",...f?{[k]:f}:{},...a==="outlined"?{border:`1px solid ${y}`}:{}}},typeof o.icon==="string"?[n.icon({type:"icon",name:o.icon},i,"")]:[]),b=u[z]??String(o.icon??"");return m("span",{attrs:{...u,role:"button",[z]:b,...l.attrs},style:h},[g])};function $f(n,o,i){let{selected:a,label:s,color:d}=n,l=S("outlineVariant",o.style)??"currentColor",p=a?i.roleCss(o,"secondaryContainer","onSecondaryContainer"):i.roleCss(o,"transparent","onSurface");return m("span",{attrs:{[P]:"chip"},style:{display:de,[T]:w,gap:"8px",height:"32px",[we]:a?"8px 16px":"16px",[A]:"8px",...B({textStyle:"labelLarge"},o.style),border:a?"1px solid transparent":`1px solid ${l}`,...p,...d?{color:d}:{}}},[...a?[Mf("check",18,o,i)]:[],s])}var Ff=(n)=>(o,i)=>{let a=typeof o.stateKey==="string",s=a&&po(o.stateKey,i,n)===!0,d=n.disabledState(o,i),{attrs:l,style:p}=n.base(o,i,{display:de,[T]:w,[U]:"48px",[q]:"0",...d.css}),u=a?{role:"checkbox",[Ke]:String(s)}:{role:"button"};return m("div",{attrs:{...l,...u,...d.attrs},style:p},[$f({selected:s,label:n.bound(o.label,i),color:p.color},i,n)])};function Bf(n,o,i){let a=typeof n.min==="number"?n.min:0,s=typeof n.max==="number"?Math.max(n.max,a):a,d=po(n.stateKey,o,i),l=Math.min(Math.max(typeof d==="number"?d:0,a),s),p=typeof n.step==="number"&&n.step>0?n.step:void 0;if(p===void 0)return l;let u=a+Math.round((l-a)/p)*p;return Math.min(Math.max(Math.round(u*1e6)/1e6,a),s)}var co=(n)=>`${Number((n*100).toFixed(3))}%`;function dd(n,o,i){return m("span",{attrs:{[P]:n},style:{position:L,top:"14px",height:"16px",width:`max(0px, calc(${o} - 6px))`,[A]:"8px",[n==="active"?"inset-inline-start":"inset-inline-end"]:"0",...i?{[k]:i}:{}}})}function Uf(n,o){let i=S("primary",o.style),a=S("secondaryContainer",o.style),s=i?{[k]:i}:{};return m("span",{style:{position:Z,display:"block",height:"44px"}},[dd("active",co(n),i),dd("inactive",co(1-n),a),m("span",{attrs:{[P]:"stop"},style:{position:L,top:"20px","inset-inline-end":"6px",width:"4px",height:"4px",[A]:"50%",...s}}),m("span",{attrs:{[P]:"thumb"},style:{position:L,top:"0","inset-inline-start":`calc(${co(n)} - 2px)`,width:"4px",height:"44px",[A]:"2px",...s}})])}var Hf=(n)=>(o,i)=>{let a=he(o,Te(o)),s=typeof a.min==="number"?a.min:0,d=typeof a.max==="number"?a.max:s,l=Bf(a,i,n),p=d>s?(l-s)/(d-s):0,u=n.disabledState(a,i),{attrs:h,style:f}=n.base(a,i,{display:R,[D]:M,...u.css}),y={role:"slider","aria-valuenow":String(l),"aria-valuemin":String(s),"aria-valuemax":String(d)},g=typeof a.label==="string"?[m("span",{style:B({textStyle:"bodyLarge"},i.style)},[n.bound(a.label,i)])]:[];return m("div",{attrs:{...h,...y,...u.attrs},style:f},[...g,Uf(p,i)])};function tn(n,o,i){return(Array.isArray(n.items)?n.items:[]).map((s)=>{let d=c(s)??{};return{label:i.bound(d.label,o),...typeof d.icon==="string"?{icon:d.icon}:{},image:d.image!==void 0}})}function nn(n,o,i,a){let s=typeof n.pager==="string"?rd(n.pager,i,a):void 0,d=po(n.stateKey,i,a),l=s??(typeof d==="number"&&Number.isFinite(d)?Math.trunc(d):0);return Math.min(Math.max(l,0),Math.max(o-1,0))}function rn(n,o,i){if(n.icon!==void 0)return i.icon({type:"icon",name:n.icon},o,"");let a=S("surfaceVariant",o.style);return m("span",{attrs:{[P]:"placeholder"},style:{display:"block",width:"24px",height:"24px",[q]:"0",...a?{[k]:a}:{}}})}function on(n,o,i,a){return i.base(he(n,Te(n)),o,{display:R,...a})}function jf(n,o,i,a){let s=o?S("secondaryContainer",i.style):void 0,d=S(o?"onSecondaryContainer":"onSurfaceVariant",i.style),l=S(o?"onSurface":"onSurfaceVariant",i.style),p=m("span",{attrs:{[P]:"indicator"},style:{display:R,[T]:w,[N]:w,width:"64px",height:"32px",[A]:"16px",...s?{[k]:s}:{},...d?{color:d}:{}}},[rn(n,i,a)]),u=m("span",{style:{...B({textStyle:"labelMedium"},i.style),...l?{color:l}:{}}},[n.label]);return m("div",{attrs:{role:"tab",[qe]:String(o)},style:{display:R,[D]:M,[T]:w,gap:"4px",flex:"1 1 0",[te]:"0",[ft]:"12px",[Pe]:"16px"}},[p,u])}function uo(n,o,i,a){if((o.consumedInsets??[]).includes("bottom")||i.safeAreaEdges(n).includes("bottom"))return a;return{...a,[Pe]:`calc(${a[Pe]??"0px"} + var(--safe-bottom))`}}var Gf=(n)=>(o,i)=>{let a=tn(o,i,n),s=nn(o,a.length,i,n),{attrs:d,style:l}=on(o,i,n,{[U]:"80px",gap:"8px",[we]:"8px",...n.roleCss(i,"surfaceContainer","onSurface")}),p=uo(o,i,n,l);return m("div",{attrs:{...d,role:"tablist"},style:p},a.map((u,h)=>jf(u,h===s,i,n)))};function zf(n,o,i){let{scope:a,kit:s}=i,d=S("primary",a.style)??"currentColor",l=o?d:S("onSurfaceVariant",a.style),p=n.icon!==void 0||n.image?[rn(n,a,s)]:[];return m("div",{attrs:{role:"tab",[qe]:String(o)},style:{display:R,[D]:M,[T]:w,[N]:w,gap:"2px",[U]:i.icons?"72px":"48px",[we]:"16px",...B({textStyle:"titleSmall"},a.style),...i.scrollable?{flex:"0 0 auto",[te]:"90px"}:{flex:"1 1 0",[te]:"0"},...l?{color:l}:{},...o?{[Be]:`inset 0 -3px 0 0 ${d}`}:{}}},[...p,n.label])}var Vf=(n)=>(o,i)=>{let a=tn(o,i,n),s=nn(o,a.length,i,n),d={scrollable:o.scrollable===!0,icons:a.some((h)=>h.icon!==void 0||h.image),scope:i,kit:n},l=S("outlineVariant",i.style)??"currentColor",{attrs:p,style:u}=on(o,i,n,{[U]:d.icons?"72px":"48px","border-bottom":`1px solid ${l}`,...d.scrollable?{"padding-inline-start":"52px",overflow:"hidden"}:{},...n.roleCss(i,"surface","onSurface")});return m("div",{attrs:{...p,role:"tablist"},style:u},a.map((h,f)=>zf(h,f===s,d)))};function cd(n){return{iconButton:Lf(n),chip:Ff(n),slider:Hf(n),bottomNav:Gf(n),tabBar:Vf(n)}}var Kf=600,qf=840,pd=360,ud=24;function an(n){if(n<Kf)return"compact";return n<qf?"medium":"expanded"}function mo(n,o){return typeof n==="string"?o.scope.condition.state[o.kit.bound(n,o.scope)]:void 0}function Rt(n,o){let i=o.kit.child(o.scope,{inBox:!1,style:{...o.scope.style,parentAxis:"column",weightsChildren:!1}}),a=o.kit.renderNode(o.node[n],i,`${o.path}.${n}`);return a?[a]:[]}function Et(n,o,i){return m("div",{attrs:{"data-pane":n},style:{display:"flex","flex-direction":"column","min-width":"0",...o}},i)}function md(n,o,i){return m("div",{attrs:{role:"button","data-testid":o},style:{display:"inline-flex","align-items":"center","align-self":"flex-start","min-height":"40px",padding:"0 12px",...B({textStyle:"labelLarge"},i.scope.style),color:S("primary",i.scope.style)??"currentColor"}},[n])}var ho=(n,o)=>typeof n.node.testTag==="string"?n.node.testTag:o;function Yf(n,o){return[{...n,style:{...n.style,flex:`0 0 ${pd}px`}},m("div",{attrs:{"data-part":"spacer"},style:{flex:`0 0 ${ud}px`}}),{...o,style:{...o.style,flex:"1 1 0"}}]}function Xf(n){let o=mo(n.node.selectionKey,n),i=o!==void 0&&o!==null&&o!=="",a=()=>Et("list",{},Rt("list",n));if(an(n.scope.screenWidth)==="expanded")return Yf(a(),Et("detail",{},Rt("detail",n)));if(!i){let d=a();return[{...d,style:{...d.style,flex:"1 1 auto"}}]}let s=md("Back",`${ho(n,n.path)}.back`,n);return[Et("detail",{flex:"1 1 auto"},[s,...Rt("detail",n)])]}function Jf(n){let o=mo(n.node.openKey,n)===!0,i=()=>Et("main",{},Rt("main",n));if(!o){let p=i();return[{...p,style:{...p.style,flex:"1 1 auto"}}]}let a=md("Close",`${ho(n,n.path)}.close`,n),s=an(n.scope.screenWidth)==="expanded",d=s?[i()]:[],l=Et("supporting",{},[a,...Rt("supporting",n)]);if(s)return[{...d[0],style:{...d[0].style,flex:"1 1 0"}},m("div",{attrs:{"data-part":"spacer"},style:{flex:`0 0 ${ud}px`}}),{...l,style:{...l.style,flex:`0 0 ${pd}px`}}];return[{...l,style:{...l.style,flex:"1 1 auto"}}]}function Zf(n){return(Array.isArray(n.node.items)?n.node.items:[]).flatMap((o)=>{let i=c(o);return i?[{value:String(i.value),label:n.kit.bound(i.label,n.scope)}]:[]})}function Qf(n,o,i,a){let s=mo(a.node.stateKey,a)===n.value,d=a.scope.style,l=s?{"background-color":S("secondaryContainer",d)??"transparent"}:{},p=i==="expanded",u=m("span",{attrs:{"data-part":"icon"},style:{display:"inline-flex","align-items":"center","justify-content":"center",width:p?"24px":"56px",height:p?"24px":"32px","border-radius":"16px",...p?{}:l}},[n.label.slice(0,1)]);return m("div",{attrs:{role:"tab","aria-selected":String(s),"data-testid":`${ho(a,a.path)}.item-${o}`},style:{display:"flex","flex-direction":p?"row":"column","align-items":"center",gap:p?"12px":"4px",...B({textStyle:p?"labelLarge":"labelMedium"},d),...p?{height:"56px",padding:"0 16px","border-radius":"28px",...l}:{flex:i==="compact"?"1 1 0":"0 0 auto",padding:"12px 0 16px"}}},[u,n.label])}function ey(n){let o=an(n.scope.screenWidth),i=Zf(n).map((l,p)=>Qf(l,p,o,n)),a=o==="expanded"?"surfaceContainerLow":"surfaceContainer",s=m("div",{attrs:{role:"tablist","data-part":"navigation","data-layout":o},style:{display:"flex","flex-direction":o==="compact"?"row":"column",...o==="compact"?{"min-height":"80px"}:{width:o==="medium"?"80px":"360px",padding:"12px",gap:"4px"},"box-sizing":"border-box","flex-shrink":"0",...n.kit.roleCss(n.scope,a,"onSurface")}},i),d=Et("content",{flex:"1 1 auto"},Rt("content",n));return o==="compact"?[d,s]:[s,d]}var ty={listDetail:Xf,supporting:Jf,navigationSuite:ey},ny=(n)=>(o,i,a)=>{let s={node:o,scope:i,path:a,kit:n},d=o.kind==="navigationSuite"&&an(i.screenWidth)==="compact",{attrs:l,style:p}=n.base(o,i,{display:"flex","flex-direction":d?"column":"row","align-self":"stretch",flex:"1 1 auto","min-height":"0"}),u=ty[String(o.kind)];return m("div",{attrs:{...l,"data-kind":String(o.kind),"data-width-class":an(i.screenWidth)},style:p},u?u(s):[])};function hd(n){return{adaptive:ny(n)}}var ln=100,At=160,Tt=120,fd=12,yd=0.7,gd=["primary","tertiary","secondary","error"],dn=(n)=>typeof n==="number"&&Number.isFinite(n),Ne=(n)=>String(Number(n.toFixed(3)));function sn(n){let o=Number(n.toFixed(2));return Object.is(o,-0)?"0":String(o)}function ry(n){if(typeof n==="string")return n;return dn(n)?sn(n):void 0}function oy(n,o){let i=typeof n.path==="string"?Pt(o,n.path):[];return(Array.isArray(i)?i:[]).flatMap((a)=>{let s=c(a),d=s?.[String(n.y)];if(!s||!dn(d))return[];let l=typeof n.x==="string"?ry(s[n.x]):void 0;return[l===void 0?{y:d}:{x:l,y:d}]})}function iy(n,o,i){let a=[...o.flatMap((l)=>l.points.map((p)=>p.y)),...i===void 0?[]:[i],...n==="bar"?[0]:[]],s=a.length?Math.min(...a):0,d=a.length?Math.max(...a):1;return d>s?{yMin:s,yMax:d}:{yMin:s-1,yMax:d+1}}function ay(n,o,i){let a=`${n.charAt(0).toUpperCase()}${n.slice(1)} chart`;if(n==="ring"){let l=o[0],p=l?.points.at(-1)?.y??0,u=i===void 0?"0":sn(i);return`${a}, ${l?.label??""}, ${sn(p)} of ${u}`}let s=o.map((l)=>{let p=l.points.map((g)=>g.y);if(!p.length)return`${l.label}, no points`;let u=p.length===1?"point":"points",[h,f,y]=[Math.min(...p),Math.max(...p),p.at(-1)].map(sn);return`${l.label}, ${p.length} ${u}, min ${h}, max ${f}, latest ${y}`}),d=i===void 0?"":`, goal ${sn(i)}`;return`${a}, ${s.join("; ")}${d}`}function sy(n,o){let i=String(n.variant),a=(Array.isArray(n.series)?n.series:[]).map((u,h)=>{let f=c(u)??{},y=gd[h%gd.length];return{label:typeof f.label==="string"?f.label:"",points:oy(f,o.data),color:S(f.color,o.style)??S(y,o.style)??"currentColor"}}),s=dn(n.goal)?n.goal:void 0,d=c(n.yRange),{yMin:l,yMax:p}=d&&dn(d.min)&&dn(d.max)?{yMin:d.min,yMax:d.max}:iy(i,a,s);return{variant:i,series:a,yMin:l,yMax:p,...s===void 0?{}:{goal:s},summary:ay(i,a,s)}}function Zn(n,o){let i=n.yMax-n.yMin,a=i===0?0:(o-n.yMin)/i;return At-Math.min(Math.max(a,0),1)*At}var fo=(n,o)=>o<=1?ln/2:n*ln/(o-1),bd={"vector-effect":"non-scaling-stroke"};function dy(n,o){if(n.goal===void 0)return[];let i=Ne(Zn(n,n.goal));return[m("line",{attrs:{"data-part":"goal",x1:"0",x2:String(ln),y1:i,y2:i,stroke:S("outline",o.style)??"currentColor","stroke-width":"1","stroke-dasharray":"6 6",...bd}})]}function ly(n,o,i){let a=o.points.map((l)=>l.y);if(!a.length)return[];let s=a.map((l,p)=>`${Ne(fo(p,a.length))},${Ne(Zn(n,l))}`);return[...i?[m("polygon",{attrs:{"data-part":"area",points:[...s,`${Ne(fo(a.length-1,a.length))},${At}`,`${Ne(fo(0,a.length))},${At}`].join(" "),fill:o.color,"fill-opacity":"0.25"}})]:[],m("polyline",{attrs:{"data-part":"line",points:s.join(" "),fill:"none",stroke:o.color,"stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",...bd}})]}function cy(n){let o=Math.max(0,...n.series.map((d)=>d.points.length));if(!o)return[];let i=ln/o,a=i*yd/n.series.length,s=Zn(n,Math.min(Math.max(0,n.yMin),n.yMax));return n.series.flatMap((d,l)=>d.points.map((p,u)=>{let h=Zn(n,p.y);return m("rect",{attrs:{"data-part":"bar",x:Ne(u*i+i*(1-yd)/2+l*a),y:Ne(Math.min(h,s)),width:Ne(a),height:Ne(Math.abs(s-h)),fill:d.color}})}))}function py(n,o,i){let a=(o.series[0]?.points??[]).flatMap((l)=>l.x===void 0?[]:[l.x]),s=n.xLabels==="all"?a:n.xLabels==="ends"&&a.length>1?[a[0],a.at(-1)]:n.xLabels==="ends"?a:[];if(!s.length)return[];let d=S("onSurfaceVariant",i.style);return[m("div",{attrs:{"data-part":"x-labels","aria-hidden":"true"},style:{display:"flex","justify-content":"space-between",...B({textStyle:"labelSmall"},i.style),...d?{color:d}:{}}},s.map((l)=>m("span",{style:{"white-space":"nowrap"}},[l])))]}function uy(n,o){let i=n.series[0]?.points.at(-1)?.y??0,a=n.goal??1,s=a===0?0:Math.min(Math.max(i/a,0),1),d=String(Tt/2),l=(u,h,f)=>m("circle",{attrs:{"data-part":f,cx:d,cy:d,r:Ne((Tt-fd)/2),fill:"none",stroke:u,"stroke-width":String(fd),"stroke-linecap":"round",pathlength:"100","stroke-dasharray":`${Ne(h*100)} 100`,transform:`rotate(-90 ${d} ${d})`}}),p=s>0?[l(n.series[0].color,s,"ring")]:[];return[l(S("surfaceVariant",o.style)??"#e7e0ec",1,"track"),...p]}var my=(n)=>(o,i)=>{let a=sy(o,i),s=a.variant==="ring",{attrs:d,style:l}=n.base(o,i,s?{display:"block",width:`${Tt}px`,height:`${Tt}px`,"flex-shrink":"0"}:{display:"flex","flex-direction":"column","align-self":"stretch"}),p={role:"img","aria-label":d["aria-label"]??a.summary,"data-chart":a.variant};if(s){let f=m("svg",{attrs:{viewbox:`0 0 ${Tt} ${Tt}`,width:"100%",height:"100%"},style:{display:"block"}},uy(a,i));return m("div",{attrs:{...d,...p},style:l},[f])}let u=a.variant==="bar"?cy(a):a.series.flatMap((f)=>ly(a,f,a.variant==="area")),h=m("svg",{attrs:{viewbox:`0 0 ${ln} ${At}`,preserveaspectratio:"none",width:"100%",height:String(At)},style:{display:"block",overflow:"visible"}},[...dy(a,i),...u]);return m("div",{attrs:{...d,...p},style:l},[h,...py(o,a,i)])};function wd(n){return{chart:my(n)}}var Me=(n)=>`${Number(n.toFixed(3))}px`,Qn=(n)=>typeof n==="number"&&Number.isFinite(n)?Math.max(0,n):0;function kt(n,o){return S(n,o.style)??"currentColor"}function xd(n,o,i,a){let s=a.icon({type:"icon",name:n},i,"");return{...s,style:{...s.style,width:Me(o),height:Me(o)}}}var hy=(n)=>(o,i)=>{let a=typeof o.text==="string"?n.bound(o.text,i):"",s=a?{"min-width":"16px",height:"16px",padding:"0 4px","box-sizing":"border-box",...B({textStyle:"labelSmall"},i.style)}:{width:"6px",height:"6px"},{attrs:d,style:l}=n.base(o,i,{display:"inline-flex","align-items":"center","justify-content":"center","border-radius":"999px","flex-shrink":"0",...n.roleCss(i,"error","onError"),...s});return m("span",{attrs:{...d,"data-badge":a?"large":"small"},style:l},[a])},fy=0.3;function yy(n,o,i){if(typeof n.stateKey!=="string")return;let a=o.condition.state[i.bound(n.stateKey,o)],s=typeof n.max==="number"&&n.max!==0?n.max:1,d=(typeof a==="number"&&Number.isFinite(a)?a:0)/s;return Math.min(Math.max(Number.isFinite(d)?d:0,0),1)}var gy=(n)=>`${Number((n*100).toFixed(3))}%`;function by(n,o){return[m("span",{attrs:{"data-part":"indicator"},style:{display:"block",width:gy(n),height:"100%","border-radius":"2px","background-color":kt("primary",o)}})]}function wy(n,o){let i=(s,d,l)=>m("circle",{attrs:{"data-part":l,cx:"20",cy:"20",r:"18",fill:"none",stroke:s,"stroke-width":"4","stroke-linecap":"round",pathlength:"100","stroke-dasharray":`${Number((d*100).toFixed(3))} 100`,transform:"rotate(-90 20 20)"}}),a=n>0?[i(kt("primary",o),n,"indicator")]:[];return[m("svg",{attrs:{viewbox:"0 0 40 40",width:"100%",height:"100%","aria-hidden":"true"},style:{display:"block"}},[i(kt("secondaryContainer",o),1,"track"),...a])]}var vy=(n)=>(o,i)=>{let a=yy(o,i,n),s=a??fy,d=o.variant==="circular",l=d?{display:"inline-flex",width:"40px",height:"40px"}:{display:"block",width:"240px",height:"4px","border-radius":"2px",overflow:"hidden","background-color":kt("secondaryContainer",i)},{attrs:p,style:u}=n.base(o,i,{"flex-shrink":"0",...l}),h=a===void 0?{"data-indeterminate":"true"}:{"aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":String(Math.round(a*100))},f=d?wy(s,i):by(s,i);return m("div",{attrs:{...p,role:"progressbar",...h},style:u},f)},vd={small:[40,12,24],regular:[56,16,24],large:[96,28,36]};function xy(n,o){if(!o)return{padding:"16px",gap:"8px","border-radius":"16px"};if(typeof n.label==="string")return{height:"56px","padding-inline":"16px 20px",gap:"12px","border-radius":"16px","box-sizing":"border-box"};let[i,a]=vd[String(n.size)]??vd.regular;return{width:Me(i),height:Me(i),"border-radius":Me(a)}}var Sy=(n)=>(o,i)=>{let a=n.disabledState(o,i),s=a.attrs["aria-disabled"]===void 0,d=kt("onSurface",i),l=s?n.roleCss(i,"primaryContainer","onPrimaryContainer"):{"background-color":`color-mix(in srgb, ${d} 12%, transparent)`,color:`color-mix(in srgb, ${d} 38%, transparent)`},{attrs:p,style:u}=n.base(o,i,{display:"inline-flex","align-items":"center","justify-content":"center","flex-shrink":"0",...B({textStyle:"labelLarge"},i.style),...l,...s?{"box-shadow":"0 3px 6px rgba(0,0,0,0.3)"}:{},...xy(o,s)}),h=o.size==="large"&&o.label===void 0?36:24,f=typeof o.label==="string"?[n.bound(o.label,i)]:[];return m("div",{attrs:{...p,role:"button",...a.attrs},style:u},[xd(o.icon,h,i,n),...f])},Ry=(n)=>(o,i,a)=>{let s=c(o.style)??{},d=Qn(s.spacing),l=Qn(s.runSpacing),{attrs:p,style:u}=n.base(o,i,{display:"block",width:"fit-content","max-width":"100%",overflow:"hidden","flex-shrink":"0"}),h=typeof o.maxLines==="number"&&o.maxLines>=1?o.maxLines:0,f=h?{display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":String(h),overflow:"hidden"}:{display:"block"},y=n.child(i,{inBox:!1,style:{...i.style,parentAxis:void 0,weightsChildren:!1}}),g=(v)=>v&&m("span",{attrs:{"data-part":"item"},style:{display:"inline-block","vertical-align":"top","margin-inline-end":Me(d),"margin-bottom":Me(l)}},[v]),b=m("div",{attrs:{"data-part":"lines"},style:{...f,"margin-inline-end":Me(-d),"margin-bottom":Me(-l)}},n.children(o,y,a,g));return m("div",{attrs:p,style:u},[b])},Ey=(n)=>(o,i,a)=>{let s=o.axis==="horizontal",{attrs:d,style:l}=n.base(o,i,{display:"flex","flex-direction":s?"row":"column","align-items":Xn(s?"row":"column",o.style)["align-items"],gap:Me(Qn(o.spacing)),padding:Me(Qn(o.contentPadding)),[s?"overflow-x":"overflow-y"]:"auto","align-self":"stretch",...s?{}:{flex:"1 1 auto","min-height":"0"}}),p=n.child(i,{inBox:!1,style:{...i.style,parentAxis:s?"row":"column",weightsChildren:!1}}),u=typeof o.maxItems==="number"?o.maxItems:Number.POSITIVE_INFINITY,h=0,f=(g)=>h++<u?g:void 0,y=(g)=>{let b=n.renderNode(o[g],p,`${a}.${g}`);return b?[b]:[]};return m("div",{attrs:{...d,role:"list"},style:l},[...y("header"),...n.children(o,p,a,f),...y("footer")])},Ty={default:["secondaryContainer","onSecondaryContainer"],destructive:["errorContainer","onErrorContainer"]};function Ay(n,o,i){let a=c(n);if(!a)return[];let s=a.role==="destructive"?"destructive":"default",[d,l]=Ty[s],p=S(a.color??d,o.style),u=i.bound(a.label,o),h=a.icon===void 0?[]:[xd(a.icon,24,o,i)];return[m("div",{attrs:{role:"button","aria-label":u,"data-swipe-role":s},style:{display:"flex","flex-direction":"column","align-items":"center","justify-content":"center",gap:"4px","min-width":"72px",padding:"0 12px",...B({textStyle:"labelMedium"},o.style),...p?{"background-color":p}:{},color:kt(l,o)}},[...h,u])]}function Sd(n,o,i,a){let s=c(o.swipeActions);if(!s)return n;let d=["start","end"].flatMap((p)=>{let h=(Array.isArray(s[p])?s[p]:[]).flatMap((f)=>Ay(f,i,a));return h.length?[m("div",{attrs:{"data-swipe-edge":p,hidden:""}},h)]:[]}),l={...n.attrs,...s.fullSwipe===!0?{"data-full-swipe":"true"}:{}};return{...n,attrs:l,children:[...n.children,...d]}}function Rd(n){return{badge:hy(n),progress:vy(n),fab:Sy(n),flow:Ry(n),list:Ey(n),...wd(n),...hd(n)}}var Ed={bearing:0,tilt:0},ky=1.5,er=256,Td=85.05112878,bo=200,Wy=15,Ad=0.8,kd=0.000000001;function Py(n,o){let i=Math.max(-Td,Math.min(Td,n)),a=Math.sin(i*Math.PI/180);return{x:(o+180)/360,y:0.5-Math.log((1+a)/(1-a))/(4*Math.PI)}}function wo(n){let o=c(n),i=Number(o?.lat),a=Number(o?.lng);return o&&o.lat!==""&&o.lng!==""&&Number.isFinite(i)&&Number.isFinite(a)?Py(i,a):void 0}function _d(n,o){let i=typeof n==="string"?Pt(o.data,n):[];return Array.isArray(i)?i:[]}function Iy(n,o){let i=c(n.markers);if(!i||typeof i.as!=="string")return[];let a={alias:i.as,index:!1};return _d(i.path,o).flatMap((s)=>{let d=c(s);if(!d)return[];let l=(u)=>typeof u==="string"?ld(u,{binding:a,values:d}):"",p=wo({lat:l(i.lat),lng:l(i.lng)});return p?[{point:p,title:l(i.title)}]:[]})}function _y(n,o){let i=Array.isArray(n.polylines)?n.polylines.map(c):[],a=S("primary",o.style)??"#6750a4";return i.flatMap((s)=>{let d=_d(s?.path,o).flatMap((l)=>{let p=wo(l);return p?[p]:[]});return d.length>0?[{points:d,width:typeof s?.width==="number"?s.width:4,color:S(s?.color,o.style)??a}]:[]})}function nr(n){return n-Math.floor(n+0.5)}function Cd(n){let o,i=0;return n.map((a)=>(i=o?i+nr(a.x-o.x):a.x,o=a,i))}function Cy(n){let o=[];for(let i of n.toSorted((a,s)=>a.start-s.start)){let a=o.at(-1);if(a&&i.start<=a.end)o[o.length-1]={start:a.start,end:Math.max(a.end,i.end)};else o.push(i)}return o}function Oy(n){let o=n.map(({start:d,end:l})=>{let p=d-Math.floor(d);return{start:p,end:p+l-d}}),i=Cy([0,1,2].flatMap((d)=>o.map(({start:l,end:p})=>({start:l+d,end:p+d})))),s=i.slice(1).flatMap((d,l)=>{let p=i[l].end;return p>=1&&p<2?[{width:d.start-p,start:d.start-1,end:p}]:[]}).reduce((d,l)=>d&&d.width>=l.width?d:l,void 0);if(s)return{start:s.start,end:s.end};return Dy(n)}function Wd(n,o){let i=(n.start+n.end)/2,a=o+nr(i-o)-i;return{start:n.start+a,end:n.end+a}}function Pd(n){return{start:Math.min(...n.map((o)=>o.start)),end:Math.max(...n.map((o)=>o.end))}}function Dy(n){let o=n.reduce((l,p)=>p.end-p.start>l.end-l.start?p:l),i=Pd(n.map((l)=>Wd(l,(o.start+o.end)/2))),a=(i.start+i.end)/2,s=Pd(n.map((l)=>Wd(l,a))),d=Math.max(0.5,a-s.start,s.end-a);return{start:a-d,end:a+d}}function yo(n,o,i=[]){let a=i.filter((x)=>x.length>0),s=[...n,...a.flat()].map((x)=>x.y);if(s.length===0)return;let d=[...n.map((x)=>({start:x.x,end:x.x})),...a.map((x)=>{let E=Cd(x);return{start:Math.min(...E),end:Math.max(...E)}})],{start:l,end:p}=Oy(d),[u,h]=[Math.min(...s),Math.max(...s)],f=(l+p)/2,y={x:f-Math.floor(f),y:(u+h)/2},g=[p-l>kd?o.width*Ad/(p-l):1/0,h-u>kd?o.height*Ad/(h-u):1/0],b=Math.min(...g),v=Math.min(Number.isFinite(b)?b:er*2**Wy,er*4194304);return{center:y,worldSize:v}}function Od(n,o){let i=c(n.camera);return typeof i?.data==="string"?c(Pt(o.data,i.data)):i}function Id(n,o){return typeof n==="number"&&Number.isFinite(n)?Math.max(0,Math.min(o,n))%360:0}function Ny(n){return{bearing:Id(n?.bearing,360),tilt:Id(n?.tilt,60)}}function My(n,o){let i=Od(n,o),a=wo(i),s=Number(i?.zoom);return a&&Number.isFinite(s)?{center:a,worldSize:er*2**Math.max(0,Math.min(22,s))}:void 0}function Ly(n,o,i,a){let s=n.fit==="markers"?yo(i.markers,a):n.fit==="route"?yo([],a,i.lines):void 0;if(s)return{view:s,orientation:Ed,fitted:!0};let d=My(n,o);if(d)return{view:d,orientation:Ny(Od(n,o)),fitted:!1};let l=yo(i.markers,a,i.lines);return{view:l??{center:{x:0.5,y:0.5},worldSize:er},orientation:Ed,fitted:l!==void 0}}function cn(n){return Number(n.toFixed(3))+0}function Dd(n,o){return{x:o.center.x+nr(n.x-o.center.x),y:n.y}}function $y(n,o){if(n.length===0)return[];let i=Cd(n),a=(Math.min(...i)+Math.max(...i))/2,s=o.center.x+nr(a-o.center.x)-a;return n.map((d,l)=>({x:i[l]+s,y:d.y}))}function Nd(n,o){return{x:cn((n.x-o.center.x)*o.worldSize),y:cn((n.y-o.center.y)*o.worldSize)}}function Fy(n,o){return Nd(Dd(n,o),o)}var By=0.1;function Wt(n){return n*Math.PI/180}function vo(n){return ky*n}function Md(n,o,i){let a=(n.x-o.center.x)*o.worldSize,s=(n.y-o.center.y)*o.worldSize,d=Wt(-i);return{x:a*Math.cos(d)-s*Math.sin(d),y:a*Math.sin(d)+s*Math.cos(d)}}function Ld(n,o){let i=Math.sin(Wt(n));return i>0?o*(1-By)/i:1/0}function $d(n,o,i){let a=o/(o-n.y*Math.sin(Wt(i)));return{x:cn(n.x*a),y:cn(n.y*Math.cos(Wt(i))*a)}}function Uy(n,o,i,a){if(a.bearing===0&&a.tilt===0)return Fy(n,o);let s=Md(Dd(n,o),o,a.bearing);return s.y>Ld(a.tilt,i)?void 0:$d(s,i,a.tilt)}function Hy(n,o,i,a){let s=$y(n,o);if(a.bearing===0&&a.tilt===0)return s.length>0?[s.map((f)=>Nd(f,o))]:[];let d=Ld(a.tilt,i),l=s.map((f)=>Md(f,o,a.bearing)),p=[],u=[],h=(f,y)=>{let g=(d-f.y)/(y.y-f.y);return{x:f.x+(y.x-f.x)*g,y:d}};for(let[f,y]of l.entries()){let g=l[f-1],b=y.y<=d;if(g&&g.y<=d!==b){if(u.push(h(g,y)),!b)p.push(u),u=[]}if(b)u.push(y)}return p.push(u),p.filter((f)=>f.length>0).map((f)=>f.map((y)=>$d(y,i,a.tilt)))}function jy(n,o){let i=vo(n.height),[a,s]=[Math.sin(Wt(o)),Math.cos(Wt(o))],d=[-1,1].flatMap((l)=>[-1,1].map((p)=>({X:l*n.width/2,Y:p*n.height/2})));return Math.max(...d.map(({X:l,Y:p})=>{let u=p*i/(i*s+p*a),h=l*(i-u*a)/i;return Math.hypot(h,u)}))}function Gy(n,o){return`perspective(${cn(vo(o))}px) rotateX(${n.tilt}deg) rotate(${-n.bearing}deg)`}function zy(n){return n===0?"50%":`calc(50% ${n<0?"-":"+"} ${Math.abs(n)}px)`}function Vy(n,o){if(n===0)return"50%";let i=(a)=>Number((Math.abs(n)/a*100).toFixed(4));return`calc(50% ${n<0?"-":"+"} min(${i(o.width)}cqw, ${i(o.height)}cqh))`}function Fd(n){let o=c(n)?.dp;return typeof o==="number"&&o>=0?o:void 0}function pn(n){return typeof n==="number"&&n>0?n:void 0}function tr(n,o,i){let a=pn(o?.[`max${i}`])??Number.POSITIVE_INFINITY;return Math.max(pn(o?.[`min${i}`])??0,Math.min(a,n))}function Bd(n,o){let i=n?.height===void 0||n.height==="wrap",a=typeof n?.weight==="number";return o==="column"&&pn(n?.aspectRatio)!==void 0&&i&&!a}function Ky(n,o,i){let a=pn(n?.aspectRatio),s=qy(n,a),{width:d,height:l,openWidth:p}=Yy(n,o,i,s??1/0);if(a!==void 0&&Bd(n,i))return{width:d,height:tr(d/a,n,"Height")};if(a!==void 0&&p&&s===void 0&&i!=="column")return{width:tr(l*a,n,"Width"),height:l};return{width:d,height:l}}function qy(n,o){let i=n?.width===void 0&&n?.height===void 0;if(o===void 0||!i||typeof n?.weight==="number")return;return(pn(n?.maxHeight)??1/0)*o}function Yy(n,o,i,a){let s=typeof n?.weight==="number"?i:void 0,d=s==="row"?void 0:Fd(n?.width),l=tr(Xy(n,o.height,s==="column"),n,"Height");return{width:tr(d??Math.min(o.width,a),n,"Width")||o.width,height:l||bo,openWidth:d===void 0&&n?.width!=="fill"&&s!=="row"}}function Xy(n,o,i){if(i||n?.height==="fill")return o;return Fd(n?.height)??bo}function Jy(n,o,i){let a=i?{attrs:{viewBox:`${-i.width/2} ${-i.height/2} ${i.width} ${i.height}`,preserveAspectRatio:"xMidYMid meet",[ae]:"true"},style:{position:L,left:"50%",top:"50%",width:"100cqw",height:"100cqh",transform:"translate(-50%,-50%)",overflow:"visible"}}:{attrs:{width:"1",height:"1",[ae]:"true"},style:{position:L,left:"50%",top:"50%",overflow:"visible"}};return m("svg",a,n.flatMap((s)=>o(s.points).map((d)=>m("polyline",{attrs:{points:d.map(({x:l,y:p})=>`${l},${p}`).join(" "),fill:"none",stroke:s.color,"stroke-width":String(s.width),"stroke-linecap":"round","stroke-linejoin":"round",...i?{"vector-effect":"non-scaling-stroke"}:{}}}))))}function Zy(n,o,i,a){return m("span",{attrs:{role:"img",[z]:n.title,title:n.title,[P]:"marker"},style:{position:L,left:a(o.x),top:a(o.y),width:"20px",height:"20px",transform:"translate(-50%,-100%) rotate(-45deg)","transform-origin":"50% 100%",[A]:"50% 50% 50% 0",[k]:i,border:"2px solid #fff",[K]:Y}})}function Qy(n,o,i){let s=`max(${(Math.ceil(jy(i,o.tilt))+1)*2}px,300cqmax)`;return m("div",{attrs:{[ae]:"true",[P]:"ground"},style:{position:L,left:"50%",top:"50%",width:s,height:s,margin:`calc(${s} / -2) 0 0 calc(${s} / -2)`,background:n,transform:Gy(o,i.height)}})}var go={plain:"#e8eaed",streets:"repeating-linear-gradient(0deg,transparent 0 46px,#fff 46px 50px),repeating-linear-gradient(90deg,transparent 0 46px,#fff 46px 50px),#ebe7df"},eg=(n)=>(o,i)=>{let a=c(o.style),s=Ky(a,{width:i.screenWidth,height:i.screenHeight},i.style.parentAxis),d=vo(s.height),l=Iy(o,i),p=_y(o,i),{view:u,orientation:h,fitted:f}=Ly(o,i,{markers:l.map((W)=>W.point),lines:p.map((W)=>W.points)},s),y=h.bearing!==0||h.tilt!==0,g=go[String(o.mapStyle)]??go.streets,{attrs:b,style:v}=n.base(o,i,{position:Z,overflow:"hidden",background:y?go.plain:g,...y||f?{"container-type":"size"}:{},[G]:ne,...Bd(a,i.style.parentAxis)?{}:{height:`${bo}px`}}),x=S("error",i.style)??"#b3261e",E=f?(W)=>Vy(W,s):zy;return m("div",{attrs:{[z]:"Map",...b,role:"img"},style:v},[...y?[Qy(g,h,s)]:[],...p.length>0?[Jy(p,(W)=>Hy(W,u,d,h),f?s:void 0)]:[],...l.flatMap((W)=>{let ee=Uy(W.point,u,d,h);return ee?[Zy(W,ee,x,E)]:[]})])};function Ud(n){return{map:eg(n)}}var tg={play:"M8 5v14l11-7z",fullscreen:"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z",cast:"M21 3H3c-1.1 0-2 .9-2 2v3h2V5h18v14h-7v2h7c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM1 18v3h3c0-1.66-1.34-3-3-3zm0-4v2c2.76 0 5 2.24 5 5h2c0-3.87-3.13-7-7-7zm0-4v2c4.97 0 9 4.03 9 9h2c0-6.08-4.93-11-11-11z",airplay:"M6 22h12l-6-6zM21 3H3c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h4v-2H3V5h18v12h-4v2h4c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"};function rr(n,o){return m("svg",{attrs:{viewBox:"0 0 24 24",width:String(o),height:String(o),[ae]:"true"},style:{display:"block",[q]:"0"}},[m("path",{attrs:{d:tg[n],fill:"currentColor"}})])}var ng=["#c0c0c0","#c0c000","#00c0c0","#00c000","#c000c0","#c00000","#0000c0"],Gd=`linear-gradient(to right,${ng.map((n,o)=>`${n} ${(o*100/7).toFixed(3)}% ${((o+1)*100/7).toFixed(3)}%`).join(",")})`;function rg(n){let o=Math.floor(n/1000);return`${Math.floor(o/60)}:${String(o%60).padStart(2,"0")}`}var Hd={position:L,inset:"0"};function og(n,o){if(n.source!==void 0)return n.source;let i=c(c(o.spec.media)?.players);return typeof n.player==="string"&&i&&Object.hasOwn(i,n.player)?c(i[n.player])?.source:void 0}function ig(n,o){let i=c(og(n,o))?.sample;if(i==="colorBars")return m("div",{attrs:{[P]:"frame"},style:{...Hd,background:Gd}});let a=i==="countdown"?[m("span",{style:{[oe]:"48px",[De]:"700"}},["3"])]:[];return m("div",{attrs:{[P]:"frame"},style:{...Hd,display:R,[T]:w,[N]:w,color:"#fff"}},a)}function ag(n){let i=(Array.isArray(n.captions)?n.captions.map(c):[]).flatMap((a)=>typeof a?.label==="string"?[a.label]:[]);if(i.length===0)return[];return[m("span",{attrs:{role:"button",[z]:`Captions: ${i.join(", ")}`,[P]:"captions"},style:{border:"1.5px solid currentColor",[A]:"3px",padding:"0 3px",[oe]:"10px",[De]:"700"}},["CC"])]}function sg(n){return m("span",{attrs:{[P]:"scrubber"},style:{flex:"1 1 auto",height:"4px",[A]:"2px",background:`linear-gradient(to right,#fff ${n},rgba(255,255,255,0.35) ${n})`}})}function dg(n,o){let i=typeof n.startMs==="number"?n.startMs:0;return m("div",{attrs:{[P]:"controls"},style:{position:L,left:o?"8px":"0",right:o?"8px":"0",bottom:o?"8px":"0",display:R,[T]:w,gap:"8px",padding:"6px 12px",color:"#fff",[oe]:"12px",...o?{[k]:"rgba(60,60,67,0.6)",[A]:"12px"}:{background:"linear-gradient(to top,rgba(0,0,0,0.6),transparent)"}}},[...o?[rr("play",20)]:[],m("span",{attrs:{[P]:"time"}},[rg(i)]),sg(i>0?"2%":"0%"),...ag(n),rr("fullscreen",20)])}function lg(){return m("span",{attrs:{role:"button",[z]:"Play",[P]:"play"},style:{position:L,left:"50%",top:"50%",transform:"translate(-50%,-50%)",width:"56px",height:"56px",[A]:"50%",[k]:"rgba(0,0,0,0.5)",color:"#fff",display:R,[T]:w,[N]:w}},[rr("play",32)])}var cg=(n)=>(o,i,a)=>{if(typeof o.poster==="string")i.unsupported.push({type:"videoPlayer",...typeof o.id==="string"?{id:o.id}:{},path:a,reason:"assetNotInlined"});let s=i.condition.platform==="ios",{attrs:d,style:l}=n.base(o,i,{position:Z,overflow:"hidden",[k]:"#000",[Gt]:"16 / 9",[G]:ne}),p=o.controls==="none"?[]:[...s?[]:[lg()],dg(o,s)];return m("div",{attrs:{[z]:"Video player",...d,role:"region"},style:l},[ig(o,i),...p])},jd={"4:3":"3 / 4","16:9":"9 / 16","1:1":"1 / 1"},pg=(n)=>(o,i)=>{let a=jd[String(o.aspectRatio)]??jd["4:3"],{attrs:s,style:d}=n.base(o,i,{position:Z,overflow:"hidden",[k]:"#000",[Gt]:a,[G]:ne}),l=o.mode==="video"?"video":"photo",p=m("div",{attrs:{[P]:"test-pattern"},style:{position:L,left:"0",right:"0",top:"20%",height:"60%",background:Gd}}),u=m("span",{attrs:{[P]:"label"},style:{position:L,left:"8px",top:"8px",padding:"2px 8px",[A]:"10px",[k]:"rgba(0,0,0,0.6)",color:"#fff",[oe]:"12px"}},[`Camera preview \xB7 ${l}`]);return m("div",{attrs:{[z]:"Camera preview",...s,role:"img"},style:d},[p,u])},ug=(n)=>(o,i)=>{let a=i.condition.platform==="ios",s=S("onSurfaceVariant",i.style),{attrs:d,style:l}=n.base(o,i,{position:Z,display:"inline-block",[q]:"0",...s?{color:s}:{}}),p=a?"AirPlay":"Cast",u=m("summary",{attrs:{[z]:d[z]??p},style:{display:R,[T]:w,[N]:w,width:"48px",height:"48px",cursor:"pointer"}},[rr(a?"airplay":"cast",24)]);return m("details",{attrs:{...d},style:l},[u,mg(p,i)])};function mg(n,o){let i=S("surfaceContainerHigh",o.style)??"#ece6f0",a=S("onSurface",o.style)??"#1d1b20";return m("div",{attrs:{role:"dialog",[z]:`${n} devices`,[P]:"device-picker"},style:{position:L,top:"48px",right:"0",[at]:"10",[te]:"200px",padding:"16px",[A]:"16px",[k]:i,color:a,[Be]:"0 2px 6px rgba(0,0,0,0.3)"}},[m("div",{style:{[De]:"500","margin-bottom":"8px"}},[n==="Cast"?"Cast to":"AirPlay"]),m("div",{style:{[oe]:"14px",opacity:"0.7"}},["No devices found"])])}function zd(n){return{videoPlayer:cg(n),cameraPreview:pg(n),castButton:ug(n)}}var hg=0.4,ir={position:L,inset:"0",display:R,[D]:M,[N]:"flex-end"};function It(n,o){return o.palette.get(n)??Fg({},o.mode).get(n)}function fg(n,o){let i=c(n)?.[o.mode]??n??"scrim",a=be({...It("scrim",o),a:hg});return i==="scrim"?a:S(i,o)??a}function yg(n){let o=Array.isArray(n)?n[0]:void 0;if(o==="full")return"100%";let i=c(o)?.dp;return typeof i==="number"?`min(${Number(i.toFixed(3))}px, 100%)`:"50%"}function xo(n,o){let i=c(n.openWhen);if(typeof i?.key!=="string"||typeof i.equals!=="boolean")return!1;return o.condition.state[i.key]===i.equals}function ar(n){return{...n,inBox:!1,consumedInsets:[],style:{...n.style,parentAxis:M,weightsChildren:!1}}}function sr(n){return(o,i,a)=>{if(!xo(o,i))return;let s=Kn(o,a);if(s)i.unsupported.push(s);let d=i.layers.length,l=n(o,i,a);i.layers.splice(d,0,l)}}function gg(n){return m("div",{attrs:{[P]:"handle"},style:{width:"32px",height:"4px",margin:"8px",[A]:"2px",[G]:w,[q]:"0",[k]:be(It("onSurfaceVariant",n))}})}function bg(n){let o=n.mode==="dark"?"rgba(235,235,245,0.3)":"rgba(60,60,67,0.3)";return m("div",{attrs:{[P]:"handle"},style:{width:"36px",height:"5px","margin-top":"6px",[A]:"2.5px",[G]:w,[q]:"0",[k]:S("onSurfaceVariant",n)??o}})}function wg(n){if(n.skin==="ios"){let o=n.style.mode==="dark"?"rgba(0,0,0,1)":"rgba(255,255,255,1)";return{css:{[T]:w,gap:"8px",[A]:"16px",overflow:"hidden"},surface:S("surface",n.style)??o,handle:bg(n.style)}}return{css:{[T]:"flex-start"},surface:be(It("surface",n.style)),handle:gg(n.style)}}function vg(n,o,i,a){let s=ar(o),d=wg(o),{attrs:l,style:p}=a.base(n,s,{display:R,[D]:M,...d.css,position:Z,width:"100%",height:yg(n.detents),[Je]:"100%",[q]:"0"}),u=p[k]?p:{...p,[k]:d.surface},h=a.child(s,{style:{...s.style,parentAxis:M,weightsChildren:!1}}),f=a.renderNode(n.child,h,`${i}.child`),y=m("div",{attrs:{[P]:"scrim"},style:{position:L,inset:"0",[k]:fg(n.scrim,o.style)}}),g=nt(m("div",{attrs:{...l,[P]:"sheet"},style:u},[...n.dragHandle===!1?[]:[d.handle],...f?[f]:[]]),n.style,o.style);return m("div",{attrs:{[P]:"sheetLayer"},style:{...ir}},[y,g])}function Vd(n){return{bottomSheet:sr((i,a,s)=>vg(i,a,s,n))}}var Sg=0.32,_t=(n,o)=>be(It(n,o.style));function Rg(n,o){return typeof n.testTag==="string"?{[it]:`${n.testTag}.${o}`}:{}}function So(n,{part:o,colorRole:i},{node:a,scope:s,kit:d}){let l=c(n)?.label;if(typeof l!=="string")return[];return[m("span",{attrs:{role:"button",[P]:o,...Rg(a,o)},style:{display:de,[T]:w,[N]:w,[U]:"40px",padding:"0 12px",[A]:"20px",[q]:"0",...B({textStyle:"labelLarge"},s.style),color:_t(i,s)}},[d.bound(l,s)])]}function Eg(n,o,i){if(typeof n.icon!=="string")return[];let a=i.icon({type:"icon",name:n.icon},o,"");return[{...a,style:{...a.style,[G]:w,color:_t("secondary",o)}}]}function Kd(n,{part:o,colorRole:i},{scope:a,kit:s}){if(typeof n!=="string")return[];let d={...B({textStyle:o},a.style),color:_t(i,a),[Ie]:"pre-wrap"};return[m("div",{attrs:{[P]:o},style:d},[s.bound(n,a)])]}function Tg(n,o,i,a){let s={node:n,scope:o,kit:a},d=ar(o),{attrs:l,style:p}=a.base(n,d,{display:R,[D]:M,gap:"16px",position:Z,[K]:Y,margin:"24px",padding:"24px",[te]:"min(280px, calc(100% - 48px))",[ce]:"min(560px, calc(100% - 48px))",[Je]:"calc(100% - 48px)",[A]:"28px",[k]:_t("surfaceContainerHigh",o)}),u=a.child(d,{style:{...d.style,parentAxis:M,weightsChildren:!1}}),h=a.renderNode(n.child,u,`${i}.child`),f=h?[m("div",{attrs:{[P]:"content"},style:{display:R,[D]:M,gap:"16px",flex:"0 1 auto",[U]:"0","overflow-y":"auto"}},[h])]:[],y=m("div",{attrs:{[P]:"buttons"},style:{display:R,[N]:"flex-end",gap:"8px",width:"100%"}},[...So(n.dismiss,{part:"dismiss",colorRole:"primary"},s),...So(n.confirm,{part:"confirm",colorRole:"primary"},s)]),g=nt(m("div",{attrs:{...l,[P]:"dialog"},style:p},[...Eg(n,o,a),...Kd(n.title,{part:"headlineSmall",colorRole:"onSurface"},s),...Kd(n.text,{part:"bodyMedium",colorRole:"onSurfaceVariant"},s),...f,y]),n.style,o.style),b=m("div",{attrs:{[P]:"scrim"},style:{position:L,inset:"0",[k]:be({...It("scrim",o.style),a:Sg})}});return m("div",{attrs:{[P]:"dialogLayer"},style:{...ir,[N]:w,[T]:w}},[b,g])}function Ag(n,o,i,a){let s=ar(o),d={node:n,scope:o,kit:a},l=So(n.action,{part:"action",colorRole:"inversePrimary"},d),{attrs:p,style:u}=a.base(n,s,{display:R,[T]:w,position:Z,[K]:Y,margin:"12px",width:"calc(100% - 24px)",[ce]:"600px",[U]:"48px",[we]:l.length>0?"16px 8px":"16px",[A]:"4px",[k]:_t("inverseSurface",o),color:_t("inverseOnSurface",o),...B({textStyle:"bodyMedium"},o.style),[Ee]:"auto"}),h=m("span",{attrs:{[P]:"text"},style:{flex:"1 1 auto",padding:"14px 0",[Ie]:"pre-wrap"}},[a.bound(n.text,o)]),f=nt(m("div",{attrs:{...p,[P]:"snackbar"},style:u},[h,...l]),n.style,o.style);return m("div",{attrs:{[P]:"snackbarLayer"},style:{...ir,[T]:w,[Ee]:"none"}},[f])}function qd(n){return{dialog:sr((o,i,a)=>Tg(o,i,a,n)),snackbar:sr((o,i,a)=>Ag(o,i,a,n))}}var kg=200;function Yd(n){if(n.type!=="list")return kg;let o=gu.MAX_PROTOTYPE_LIST_ITEMS,i=n.maxItems;return typeof i==="number"&&Number.isInteger(i)&&i>=0?Math.min(i,o):o}function Xd(n,o,i){let a=c(n.items)?.path,s=Array.isArray(n.items)?n.items:typeof a==="string"?Pt(o,a):void 0;return(Array.isArray(s)?s.filter((l)=>c(l)!==void 0):[]).slice(0,i)}var Le=(n)=>`${Number(n.toFixed(3))}px`;function Jd(n,o,i,a){let s=typeof n==="string"?i.condition.state[a.bound(n,i)]:void 0;return typeof s==="number"&&Number.isFinite(s)?Math.min(Math.max(Math.trunc(s),0),o):0}var dr=(n)=>String(n).padStart(2,"0");function Wg(n,o){if(typeof n.is24Hour==="boolean")return n.is24Hour;let i=new Intl.DateTimeFormat(o.format.locale,{hour:"numeric"}).resolvedOptions().hourCycle;return i==="h23"||i==="h24"}var rt=256,Ro=101,tl=69,lr=48;function Zd(n,o,i,a){return m("span",{style:{display:de,[T]:w,[N]:w,width:"96px",height:"80px",[A]:"8px",...B({textStyle:"displayLarge"},i.style),...a.roleCss(i,o?"primaryContainer":"surfaceContainerHighest",o?"onPrimaryContainer":"onSurface")}},[n])}function Pg(n,o,i){let a=(d,l)=>m("span",{style:{display:R,flex:"1 1 0",[T]:w,[N]:w,...i.roleCss(o,l?"tertiaryContainer":"transparent",l?"onTertiaryContainer":"onSurfaceVariant")}},[d]),s=i.roleCss(o,"transparent","outline").color??"currentColor";return m("span",{attrs:{[P]:"period"},style:{display:R,[D]:M,width:"52px",height:"80px",[ht]:"12px",overflow:"hidden",[K]:Y,[A]:"8px",border:`1px solid ${s}`,...B({textStyle:"titleMedium"},o.style)}},[a("AM",!n),a("PM",n)])}function Qd(n,o){let i=n/12*2*Math.PI,a=rt/2+o*Math.sin(i)-lr/2,s=rt/2-o*Math.cos(i)-lr/2;return{position:L,left:Le(a),top:Le(s),width:Le(lr),height:Le(lr)}}function _g(n){let o=Array.from({length:12},(i,a)=>a);if(!n)return[{labels:o.map((i)=>String(i===0?12:i)),radius:Ro}];return[{labels:o.map((i)=>i===0?"00":String(i)),radius:Ro},{labels:o.map((i)=>String(i+12)),radius:tl}]}function Cg(n,o,i,a){let s=n%12,d=o&&n>=12?tl:Ro,l=a.roleCss(i,"primary","onPrimary"),p=m("span",{attrs:{[P]:"hand"},style:{position:L,left:Le(rt/2-1),top:Le(rt/2-d),width:"2px",height:Le(d),"transform-origin":"50% 100%",transform:`rotate(${s*30}deg)`,...l}}),u=m("span",{attrs:{[P]:"selector"},style:{...Qd(s,d),[A]:"50%",...l}}),h=m("span",{style:{position:L,left:Le(rt/2-4),top:Le(rt/2-4),width:"8px",height:"8px",[A]:"50%",...l}}),f=_g(o).flatMap((y)=>y.labels.map((g,b)=>{let v=b===s&&y.radius===d;return m("span",{style:{...Qd(b,y.radius),display:R,[T]:w,[N]:w,...v?{color:l.color??"inherit"}:{}}},[g])}));return m("div",{attrs:{[P]:"dial"},style:{position:Z,width:Le(rt),height:Le(rt),[A]:"50%",...B({textStyle:"bodyLarge"},i.style),...a.roleCss(i,"surfaceContainerHighest","onSurface")}},[p,u,h,...f])}var Og=(n)=>(o,i)=>{let a=Jd(o.hourKey,23,i,n),s=Jd(o.minuteKey,59,i,n),d=Wg(o,i),l=n.disabledState(o,i),{attrs:p,style:u}=n.base(o,i,{display:R,[D]:M,[T]:w,gap:"36px",...n.roleCss(i,"transparent","onSurface"),...l.css}),h=d?a:a%12===0?12:a%12,f=m("div",{attrs:{[P]:"clock"},style:{display:R,[T]:w}},[Zd(dr(h),!0,i,n),m("span",{style:{width:"24px",[yt]:w,...B({textStyle:"displayLarge"},i.style)}},[":"]),Zd(dr(s),!1,i,n),...d?[]:[Pg(a>=12,i,n)]]),y=`${dr(a)}:${dr(s)}`;return m("div",{attrs:{[z]:y,...p,role:"group",...l.attrs},style:u},[f,Cg(a,d,i,n)])};function nl(n){if(typeof n!=="string"||!/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(n))return;let[o,i,a]=n.split("-").map(Number),s=new Date(Date.UTC(o,i-1,a));return s.getUTCMonth()===i-1&&s.getUTCDate()===a?{year:o,month:i-1,day:a}:void 0}function rl(n){let o=new Intl.DateTimeFormat("en-CA",{timeZone:n.format.timeZone,year:"numeric",month:"2-digit",day:"2-digit"}).format(n.format.nowMs);return nl(o)??{year:1970,month:0,day:1}}var el=(n,o)=>n!==void 0&&n.year===o.year&&n.month===o.month&&n.day===o.day;function Eo(n,o,i){return new Intl.DateTimeFormat(i.format.locale,{...o,timeZone:"UTC"}).format(Date.UTC(n.year,n.month,n.day))}function Dg(n,o,i,a){let s=a.roleCss(i,"primary","onPrimary"),d=o.today&&!o.selected?{border:`1px solid ${s[k]??"currentColor"}`,color:s[k]??"inherit"}:{},l=m("span",{style:{display:R,[T]:w,[N]:w,[K]:Y,width:"40px",height:"40px",[A]:"50%",...o.selected?s:{},...d}},[String(n.day)]);return m("span",{attrs:{role:"gridcell",[qe]:String(o.selected)},style:{display:R,[T]:w,[N]:w,height:"48px"}},[l])}function Ng(n,o,i,a){let s=new Date(Date.UTC(n.year,n.month,1)).getUTCDay(),d=new Date(Date.UTC(n.year,n.month+1,0)).getUTCDate(),l=rl(i),p=Array.from({length:7},(f,y)=>m("span",{style:{display:R,[T]:w,[N]:w,height:"48px"}},[Eo({year:1970,month:0,day:4+y},{weekday:"narrow"},i)])),u=Array.from({length:s},()=>m("span")),h=Array.from({length:d},(f,y)=>{let g={year:n.year,month:n.month,day:y+1};return Dg(g,{selected:el(o,g),today:el(g,l)},i,a)});return m("div",{attrs:{role:"grid",[P]:"month"},style:{display:"grid",[ut]:"repeat(7, 48px)",[we]:"12px",...B({textStyle:"bodyLarge"},i.style)}},[...p,...u,...h])}function Mg(n,o,i){let a=n?Eo(n,{month:"short",day:"numeric",year:"numeric"},o):"Selected date";return[m("span",{style:{padding:"16px 12px 0 24px",...B({textStyle:"labelLarge"},o.style),...i.roleCss(o,"transparent","onSurfaceVariant")}},["Select date"]),m("span",{attrs:{[P]:"headline"},style:{padding:"36px 12px 12px 24px",...B({textStyle:"headlineLarge"},o.style)}},[a]),m("span",{style:{height:"1px",...i.roleCss(o,"outlineVariant","onSurface")}})]}function Lg(n,o,i){let a=(d)=>i.icon({type:"icon",name:d},o,""),s=(d)=>m("span",{attrs:{role:"button",[z]:d},style:{padding:"12px"}},[a(d)]);return m("div",{style:{display:R,[T]:w,height:"56px",[we]:"16px 12px",...B({textStyle:"titleSmall"},o.style),...i.roleCss(o,"transparent","onSurfaceVariant")}},[m("span",{style:{display:R,[T]:w,gap:"8px",flex:"1 1 auto"}},[Eo(n,{month:"long",year:"numeric"},o),a("arrow_drop_down")]),s("chevron_left"),s("chevron_right")])}var Ug=(n)=>(o,i)=>{let a=typeof o.stateKey==="string"?n.bound(o.stateKey,i):void 0,s=a===void 0?void 0:nl(i.condition.state[a]),d=n.disabledState(o,i),{attrs:l,style:p}=n.base(o,i,{display:R,[D]:M,width:"360px",[ce]:"100%",[Pe]:"8px",...n.roleCss(i,"surfaceContainerHigh","onSurface"),...d.css}),u=s??rl(i);return m("div",{attrs:{...l,role:"group",...d.attrs},style:p},[...Mg(s,i,n),Lg(u,i,n),Ng(u,s,i,n)])};function ol(n){return{timePicker:Og(n),datePicker:Ug(n)}}function To(n,o,i){return(Array.isArray(n.options)?n.options:[]).flatMap((s)=>{let d=c(s);return typeof d?.value==="string"?[{value:d.value,label:i.bound(d.label,o)}]:[]})}function pr(n,o,i){return typeof n.stateKey==="string"?o.condition.state[i.bound(n.stateKey,o)]:void 0}function il(n,o){return typeof n.testTag==="string"?{[it]:`${n.testTag}.${o}`}:{}}function Hg(n,o,i,a){let s=a.icon({type:"icon",name:n},i,"");return{...s,style:{...s.style,width:`${o}px`,height:`${o}px`}}}function jg(n,o){let i=S(n?"primary":"onSurfaceVariant",o.style)??"currentColor",a=m("span",{style:{width:"10px",height:"10px",[A]:"50%",[k]:i}});return m("span",{attrs:{[P]:"radio"},style:{display:de,[T]:w,[N]:w,[K]:Y,width:"20px",height:"20px",margin:"2px",[A]:"50%",border:`2px solid ${i}`,[q]:"0"}},n?[a]:[])}var Gg=(n)=>(o,i)=>{let a=pr(o,i,n),s=n.disabledState(o,i),{attrs:d,style:l}=n.base(he(o,Te(o)),i,{display:R,[D]:M,...n.roleCss(i,"transparent","onSurface"),...s.css}),p=To(o,i,n).map((u)=>m("div",{attrs:{role:"radio",[Ke]:String(u.value===a),[z]:u.label,...il(o,u.value)},style:{display:R,[T]:w,gap:"12px",[U]:"48px"}},[jg(u.value===a,i),u.label]));return m("div",{attrs:{...d,role:"radiogroup",...s.attrs},style:l},p)},zg=(n)=>(o,i)=>{let a=pr(o,i,n),s=To(o,i,n).find((h)=>h.value===a),{attrs:d,style:l}=n.base(he(o,Te(o)),i,{display:R,[T]:w,gap:"12px",[K]:Y,[U]:"48px",padding:"16px",[A]:"4px",...n.roleCss(i,"surfaceContainerLow","onSurface")}),p=typeof o.label==="string"?[m("span",{style:B({textStyle:"labelSmall"},i.style)},[n.bound(o.label,i)])]:[],u=m("span",{style:{display:R,[D]:M,flex:"1 1 auto"}},[...p,m("span",{attrs:{[P]:"value"}},[s?.label??""])]);return m("div",{attrs:{...d,role:"button","aria-haspopup":"listbox"},style:l},[u,n.icon({type:"icon",name:"expand_more"},i,"")])};function Vg(n,o,i,a){let{selected:s,index:d,count:l}=o,p=S("outline",i.style)??"currentColor",u=d===0?"20px":"0",h=d===l-1?"20px":"0";return m("div",{attrs:{role:"radio",[Ke]:String(s),[z]:n.label,...o.tag},style:{display:R,[T]:w,[N]:w,gap:"8px",[K]:Y,[U]:"40px",padding:"0 12px",border:`1px solid ${p}`,...d>0?{[ht]:"-1px"}:{},"border-start-start-radius":u,"border-end-start-radius":u,"border-start-end-radius":h,"border-end-end-radius":h,...a.roleCss(i,s?"secondaryContainer":"transparent",s?"onSecondaryContainer":"onSurface")}},[...s?[Hg("check",18,i,a)]:[],n.label])}var Kg=(n)=>(o,i)=>{let a=pr(o,i,n),s=To(o,i,n),{attrs:d,style:l}=n.base(o,i,{display:"inline-grid","grid-auto-flow":"column","grid-auto-columns":"1fr",[U]:"48px",[T]:w,...B({textStyle:"labelLarge"},i.style)});return m("div",{attrs:{...d,role:"radiogroup"},style:l},s.map((p,u)=>Vg(p,{selected:p.value===a,index:u,count:s.length,tag:il(o,p.value)},i,n)))};function al(n,o,i){return typeof n.activeKey==="string"&&o.condition.state[i.bound(n.activeKey,o)]===!0}function Ao(n,o,i){let a=c(n.style)??{};return(al(n,o,i)&&n.variant!=="docked"?["width","height"]:["width"]).filter((d)=>a[d]===void 0)}function qg(n,o,i){return(Array.isArray(n.trailingActions)?n.trailingActions:[]).flatMap((s,d)=>{let l=c(s);if(typeof l?.icon!=="string")return[];let p=typeof l.label==="string"?i.bound(l.label,o):l.icon,u=typeof n.testTag==="string"?{[it]:`${n.testTag}.actions.${d}`}:{};return[m("span",{attrs:{role:"button",[z]:p,...u},style:{padding:"12px"}},[i.icon({type:"icon",name:l.icon},o,"")])]})}function Yg(n,o,i){let a=pr(n,o,i),s=typeof a==="string"?a:"",d=s===""?i.bound(n.placeholder,o):s,l=s===""?i.roleCss(o,"transparent","onSurfaceVariant"):{},p=typeof n.leadingIcon==="string"?[i.icon({type:"icon",name:n.leadingIcon},o,"")]:[];return m("div",{attrs:{role:"searchbox",[P]:"input"},style:{display:R,[T]:w,[G]:ne,gap:"16px",[K]:Y,[U]:"56px",[we]:p.length>0?"16px 4px":"24px 4px",[A]:"28px",...B({textStyle:"bodyLarge"},o.style),...i.roleCss(o,"surfaceContainerHigh","onSurface")}},[...p,m("span",{style:{flex:"1 1 auto",...l}},[d]),...qg(n,o,i)])}var Xg=(n)=>(o,i,a)=>{let s=al(o,i,n),{attrs:d,style:l}=n.base(he(o,Ao(o,i,n)),i,{display:R,[D]:M,[T]:"flex-start",...n.roleCss(i,"surface","onSurface")}),p=[];if(s&&o.child!==void 0){let u=n.child(i,{inBox:!1,style:{...i.style,parentAxis:M,weightsChildren:!1}}),h=n.renderNode(o.child,u,`${a}.child`);p.push(...h?[h]:[])}return m("div",{attrs:{...d,"aria-expanded":String(s)},style:l},[Yg(o,i,n),...p])};function sl(n,o){return{radioGroup:Gg(n),select:zg(n),segmentedButton:Kg(n),searchBar:Xg(n),pasteButton:(i,a,s)=>o({...i,label:"Paste"},a,s),...ol(n)}}var Jg={largeTitle:[34,41],title:[28,34],title3:[20,25],body:[17,22],subheadline:[15,20],footnote:[13,18],caption:[12,16]};function ve(n,o,i=400){let[a,s]=Jg[n];return{"font-size":pe(a,o.style),"line-height":pe(s,o.style),"font-weight":String(i)}}function ue(n,o,i){return S(n,i.style)??o}function ko(n,o,i){let a=typeof n==="string"?i.bound(n,o):void 0;return a!==void 0&&o.condition.state[a]===!0}function Ct(n,o,i){return i.icon({type:"icon",name:n},o,"")}function ll(n,o){let i=m("span",{attrs:{"data-part":"thumb"},style:{width:"27px",height:"27px","border-radius":"50%","background-color":ue("onPrimary","#ffffff",o),"box-shadow":"0 1px 1px rgba(0,0,0,0.2)"}}),a=n?ue("primary","rgba(52,199,89,1)",o):ue("surfaceContainerHighest","rgba(120,120,128,0.16)",o);return m("span",{attrs:{"data-part":"track"},style:{display:"flex","align-items":"center","justify-content":n?"flex-end":"flex-start",width:"51px",height:"31px",padding:"2px","border-radius":"15.5px","flex-shrink":"0","background-color":a}},[i])}function cl(n){return m("span",{attrs:{"data-part":"box"},style:{width:"17px",height:"17px","border-radius":"4px","flex-shrink":"0",border:"1.5px solid currentColor",...n?{"background-color":"currentColor"}:{}}})}var Wo=(n,o)=>(i,a)=>{let s=ko(i.stateKey,a,o),d=o.disabledState(i,a),{attrs:l,style:p}=o.base(i,a,{display:"flex","align-items":"center",gap:"8px","min-height":"44px",...ve("body",a),...d.css}),u={...l,role:n,"aria-checked":String(s),...d.attrs},h=typeof i.label==="string"?o.bound(i.label,a):void 0;if(n==="checkbox")return m("div",{attrs:u,style:p},[cl(s),...h?[h]:[]]);let f=h?[m("span",{style:{flex:"1 1 auto"}},[h])]:[];return m("div",{attrs:u,style:p},[...f,ll(s,a)])};function Zg(n,o,i){let a=c(n.trailing);if(a?.type==="switch"||a?.type==="checkbox"){let s=ko(a.stateKey,o,i),d=a.type==="switch"?ll(s,o):cl(s);return[m("span",{attrs:{role:a.type,"aria-checked":String(s)},style:{display:"flex"}},[d])]}if(a?.type==="icon"&&typeof a.name==="string")return[m("span",{style:pl(o)},[Ct(a.name,o,i)])];return[]}function pl(n){let o=S("onSurfaceVariant",n.style);return o?{color:o}:{}}var ul=(n)=>(o,i)=>{let a=n.disabledState(o,i),{attrs:s,style:d}=n.base(o,i,{display:"flex","align-items":"center",gap:"16px","min-height":o.supporting===void 0?"56px":"72px",padding:"8px 16px","align-self":"stretch",...a.css}),l=S(c(o.style)?.color,i.style)?{}:pl(i),p=typeof o.leadingIcon==="string"?[m("span",{style:{display:"flex",...l}},[Ct(o.leadingIcon,i,n)])]:[],u=o.supporting===void 0?[]:[m("span",{style:{...ve("subheadline",i),...l}},[n.bound(o.supporting,i)])],h=m("div",{style:{display:"flex","flex-direction":"column",gap:"2px",flex:"1 1 auto"}},[m("span",{style:ve("body",i)},[n.bound(o.headline,i)]),...u]);return m("div",{attrs:{...s,role:"listitem",...a.attrs},style:d},[...p,h,...Zg(o,i,n)])},ml=(n)=>(o,i)=>{let a=typeof o.stateKey==="string",s=a&&ko(o.stateKey,i,n),d=n.disabledState(o,i),{attrs:l,style:p}=n.base(o,i,{display:"inline-flex","align-items":"center","min-height":"44px","flex-shrink":"0",color:ue("onSurface","currentColor",i),...d.css}),u=m("span",{attrs:{"data-part":"chip"},style:{display:"inline-flex","align-items":"center",gap:"8px",height:"32px","padding-inline":"12px","border-radius":"8px",...ve("subheadline",i,500),border:`1px solid ${s?"transparent":ue("outlineVariant","rgba(60,60,67,0.29)",i)}`,...s?{"background-color":ue("secondaryContainer","transparent",i)}:{}}},[...s?[Ct("check",i,n)]:[],n.bound(o.label,i)]),h=a?{role:"checkbox","aria-checked":String(s)}:{role:"button"};return m("div",{attrs:{...l,...h,...d.attrs},style:p},[u])};function dl(n,o,i){return n.flatMap((a)=>{let s=c(a);if(typeof s?.icon!=="string")return[];let d=typeof s.label==="string"?i.bound(s.label,o):s.icon;return[m("span",{attrs:{role:"button","aria-label":d},style:{display:"inline-flex","align-items":"center","justify-content":"center",width:"48px",height:"48px","flex-shrink":"0"}},[Ct(s.icon,o,i)])]})}var hl={"white-space":"nowrap",overflow:"hidden","text-overflow":"ellipsis"};function Qg(n,o,i){let a=typeof n.variant==="string"?n.variant:"small",s={...ve("title3",o,600),...hl};if(a==="small"){let d=n.navigationIcon===void 0?"12px":"4px";return[m("span",{style:{...s,flex:"1 1 auto","padding-inline-start":d}},[i])]}if(a==="centerAligned")return[m("span",{style:{...s,...{position:"absolute",left:"0",right:"0","padding-inline":"56px","text-align":"center","pointer-events":"none"}}},[i])];return[]}var eb=new Set(["enterAlways","exitUntilCollapsed"]);function tb(n,o,i){let a=typeof n.variant==="string"?n.variant:"small";if(a!=="medium"&&a!=="large")return[];let s=a==="large",d=m("span",{style:{...ve(s?"largeTitle":"title",o),...hl,padding:`0 16px ${s?28:20}px`}},[i]);if(!eb.has(n.onScroll))return[d];return[m("div",{attrs:{"data-part":"expanded-title"},style:{display:"flex","flex-direction":"column","justify-content":"flex-end",height:s?"88px":"48px"}},[d])]}var fl=(n)=>(o,i)=>{let a=typeof o.variant==="string"?o.variant:"small",{attrs:s,style:d}=n.base(o,i,{display:"flex","flex-direction":"column","align-self":"stretch",...n.roleCss(i,"surface","onSurface")}),l=n.bound(o.title,i),p=Array.isArray(o.actions)?o.actions:[],u=m("div",{style:{display:"flex","align-items":"center","min-height":"64px","padding-inline":"4px",position:"relative"}},[...dl([o.navigationIcon],i,n),...Qg(o,i,l),...a==="small"?[]:[m("span",{style:{flex:"1 1 auto"}})],...dl(p,i,n)]);return m("div",{attrs:{...s,role:"heading"},style:d},[u,...tb(o,i,l)])};function yl(n,o){let a=n===void 0||n==="filled"?ue("surfaceContainerHigh","rgba(242,242,247,1)",o):ue("surface","rgba(255,255,255,1)",o),s=S("onSurface",o.style);return{"background-color":a,...s?{color:s}:{},...n==="outlined"?{border:`1px solid ${ue("outlineVariant","rgba(60,60,67,0.29)",o)}`}:{},...n==="elevated"?{"box-shadow":"0 1px 2px rgba(0,0,0,0.2)"}:{}}}function un(n,o,i){return n.style.mode==="dark"?i:o}function vl(n){return un(n,"rgba(255,59,48,1)","rgba(255,69,58,1)")}function gl(n){return un(n,"rgba(60,60,67,0.29)","rgba(84,84,88,0.6)")}function nb(n,o){if(o===void 0)return n;let i="";for(let a of n){if(i.length+a.length>o)break;i+=a}return i}function rb(n,o,i){let a=typeof n.maxLength==="number"?n.maxLength:void 0,s=typeof n.stateKey==="string"?i.bound(n.stateKey,o):void 0,d=s===void 0?void 0:o.condition.state[s],l=nb(typeof d==="string"?d:"",a),p=a===void 0?{}:{counter:`${l.length}/${a}`};if(l==="")return{shown:i.bound(n.placeholder,o),empty:!0,...p};return{shown:n.secure===!0||n.keyboardType==="password"?"\u2022".repeat([...l].length):l,empty:!1,...p}}function xl(n){return n.label!==void 0||n.variant!==void 0||n.supportingText!==void 0||n.maxLength!==void 0}function ob(n,o,i){if(!xl(n))return{padding:"6px 7px",[A]:"5px",border:`0.5px solid ${gl(i)}`,[k]:un(i,"rgba(255,255,255,1)","rgba(0,0,0,1)")};let a=o?vl(i):ue("outline",gl(i),i);if(n.variant==="outlined")return{padding:"12px",[A]:"4px",border:`1px solid ${a}`};return{padding:"12px",[A]:"4px 4px 0 0","border-bottom":`1px solid ${a}`,[k]:ue("surfaceContainerHighest","rgba(120,120,128,0.2)",i)}}function ib(n,o){let i=ve("body",o)[Xe],a=(l)=>l===1?i:`calc(${l} * ${i})`;if(n.multiline!==!0)return{[U]:i,[Ie]:"nowrap",overflow:"hidden","text-overflow":"ellipsis"};let s=typeof n.minLines==="number"?Math.max(n.minLines,1):1,d=typeof n.maxLines==="number"?{[Je]:a(n.maxLines),overflow:"hidden"}:{};return{[Ie]:"pre-wrap",[U]:a(s),...d}}function bl(n,o,i,a){let s=un(a,"rgba(60,60,67,0.3)","rgba(235,235,245,0.3)");return m("div",{attrs:{role:"textbox",...i?{"aria-invalid":"true"}:{}},style:{display:R,[K]:Y,...ve("body",a),...ob(n,i,a),...o.empty?{color:s}:{}}},[m("span",{style:{flex:"1 1 auto",[te]:"0",...ib(n,a)}},[o.shown])])}function ab(n){return{display:R,gap:"8px",...ve("caption",n)}}function sb(n,o,i,a){let s=rb(n,i,a),d=ue("onSurfaceVariant",un(i,"rgba(60,60,67,0.6)","rgba(235,235,245,0.6)"),i),l=typeof n.label==="string"?[m("span",{attrs:{"data-slot":"label"},style:{...ve("footnote",i),color:d}},[a.bound(n.label,i)])]:[],p=typeof n.supportingText==="string"&&!o?[a.bound(n.supportingText,i)]:[],u=n.supportingText===void 0&&s.counter===void 0?[]:[m("div",{attrs:{"data-slot":"caption"},style:{...ab(i),color:d}},[m("span",{style:{flex:"1 1 auto"}},p),...s.counter===void 0?[]:[m("span",{},[s.counter])]])];if(!xl(n))return[bl(n,s,o,i)];return[...l,bl(n,s,o,i),...u]}function wl(n,o,i){let a=typeof n==="string"?{icon:n}:c(n);if(typeof a?.icon!=="string")return[];let s=Array.isArray(a.onTap)&&a.onTap.length>0,d=s?{width:"48px",height:"48px",[N]:w}:{},l=typeof a.label==="string"?{[z]:i.bound(a.label,o)}:{};return[m("span",{attrs:s?{role:"button",...l}:{},style:{display:de,[T]:w,[q]:"0",...d}},[Ct(a.icon,o,i)])]}function db(n,o,i,a){let s=n.errorText??n.supportingText;if(!o||typeof s!=="string")return[];return[m("span",{attrs:{role:"alert"},style:{...ve("caption",i),color:vl(i)}},[a.bound(s,i)])]}var Sl=(n)=>(o,i)=>{let a=n.fieldErrored(o,i),s=n.disabledState(o,i),{attrs:d,style:l}=n.base(o,i,{display:R,[D]:M,gap:"4px",...s.css}),p=sb(o,a,i,n),u=wl(o.leadingIcon,i,n),h=wl(o.trailingIcon,i,n),f=u.length+h.length===0?p:[m("div",{style:{display:R,[T]:w,gap:"4px"}},[...u,m("div",{style:{display:R,[D]:M,gap:"4px",flex:"1 1 auto"}},p),...h])];return m("div",{attrs:{...d,...s.attrs},style:l},[...f,...db(o,a,i,n)])};function Rl(n,o){let i=o.style.mode==="dark";return n?ue("onSecondaryContainer",i?"rgba(10,132,255,1)":"rgba(0,122,255,1)",o):ue("onSurfaceVariant",i?"rgba(235,235,245,0.6)":"rgba(60,60,67,0.6)",o)}function El(n,o){return n?{[k]:ue("secondaryContainer","transparent",o)}:{}}function lb(n,o,i,a){let s=m("span",{attrs:{[P]:"indicator"},style:{display:R,[T]:w,[N]:w,width:"64px",height:"32px",[A]:"16px",...El(o,i)}},[rn(n,i,a)]),d=m("span",{style:{...ve("caption",i,o?600:500),[Ie]:"nowrap",overflow:"hidden","text-overflow":"ellipsis",[ce]:"100%"}},[n.label]);return m("div",{attrs:{role:"tab",[qe]:String(o)},style:{display:R,[D]:M,[T]:w,[N]:w,gap:"4px",flex:"1 1 0",[te]:"0",[U]:"64px",color:Rl(o,i)}},[s,d])}var Tl=(n)=>(o,i)=>{let a=tn(o,i,n),s=nn(o,a.length,i,n),d=i.style.mode==="dark",{attrs:l,style:p}=on(o,i,n,{[U]:"80px",gap:"8px",[we]:"8px",[ft]:"12px",[Pe]:"4px",[K]:Y,[k]:ue("surfaceContainer",d?"rgba(28,28,30,1)":"rgba(242,242,247,1)",i)}),u=uo(o,i,n,p);return m("div",{attrs:{...l,role:"tablist"},style:u},a.map((h,f)=>lb(h,f===s,i,n)))};function cb(n,o,{minHeight:i,scope:a,kit:s}){let d=n.icon!==void 0||n.image?[rn(n,a,s)]:[];return m("div",{attrs:{role:"tab",[qe]:String(o)},style:{display:R,[D]:M,[T]:w,[N]:w,gap:"2px",flex:"1 1 0",[te]:"0",[U]:i,[A]:"9999px",...ve("caption",a),color:Rl(o,a),...El(o,a)}},[...d,n.label])}var Al=(n)=>(o,i)=>{let a=tn(o,i,n),s=nn(o,a.length,i,n),d={minHeight:o.onScroll==="minimize"?"64px":"44px",scope:i,kit:n},{attrs:l,style:p}=on(o,i,n,{}),u=a.map((h,f)=>cb(h,f===s,d));return m("div",{attrs:{...l,role:"tablist"},style:p},u)};function pb(n,o){return c(n[o.skin??"android"])}function kl(n){return{"font-size":pe(17,n.style),"line-height":pe(22,n.style),"font-weight":"400"}}function Wl(n){return n.style.mode==="dark"?"rgba(10,132,255,1)":"rgba(0,122,255,1)"}function ub(n){return n.style.mode==="dark"?"rgba(120,120,128,0.36)":"rgba(120,120,128,0.2)"}function Po(n,o){let i=n.style.palette.get("primary");return i?be({...i,a:i.a*o}):"transparent"}function mb(n,o,i){let a=S("primary",i.style)??Wl(i),s={padding:"7px 12px","min-height":"34px","border-radius":"6px"};if(o==="glassProminent")return{...s,"border-radius":"9999px","background-color":a,color:"#ffffff"};if(o==="glass")return{...s,"border-radius":"9999px","background-color":Po(i,0.15),color:a};switch(n){case"outlined":return{padding:"8px 16px","border-radius":"9999px",border:`1px solid ${a}`,color:a};case"tonal":return{...s,"background-color":Po(i,0.15),color:a};case"elevated":return{...s,"background-color":Po(i,0.15),color:a,"box-shadow":"0 1px 2px rgba(0,0,0,0.2)"};case"text":return{color:a};default:return{...s,"background-color":a,color:"#ffffff"}}}var hb=(n)=>(o,i)=>{let a=n.disabledState(o,i),s=typeof o.variant==="string"?o.variant:"filled",d=pb(o,i)?.buttonStyle,{attrs:l,style:p}=n.base(o,i,{display:"inline-flex","align-items":"center","justify-content":"center","box-sizing":"border-box","text-align":"center",gap:"6px",...kl(i),...mb(s,typeof d==="string"?d:void 0,i),...a.css}),u=typeof o.icon==="string"?[n.icon({type:"icon",name:o.icon},i,"")]:[];return m("div",{attrs:{...l,role:"button",...a.attrs},style:p},[...u,n.bound(o.label,i)])};function fb(n,o,i){let a=typeof n.min==="number"?n.min:0,s=Math.max(typeof n.max==="number"?n.max:1,a+0.000001),d=typeof n.stateKey==="string"?i.bound(n.stateKey,o):void 0,l=d===void 0?void 0:o.condition.state[d],p=Math.min(Math.max(typeof l==="number"?l:a,a),s);return{min:a,max:s,value:p,fraction:(p-a)/(s-a)}}function yb(n,o){let i=`calc(14px + (100% - 28px) * ${Number(n.toFixed(6))})`,a={position:"absolute",top:"12px",height:"4px","border-radius":"2px"};return m("span",{style:{position:"relative",display:"block",height:"28px"}},[m("span",{attrs:{"data-part":"inactive"},style:{...a,"inset-inline":"0","background-color":ub(o)}}),m("span",{attrs:{"data-part":"active"},style:{...a,"inset-inline-start":"0",width:i,"background-color":Wl(o)}}),m("span",{attrs:{"data-part":"thumb"},style:{position:"absolute",top:"0","inset-inline-start":`calc(${i} - 14px)`,width:"28px",height:"28px","border-radius":"50%","background-color":"#ffffff","box-shadow":"0 0.5px 4px rgba(0,0,0,0.12),0 6px 13px rgba(0,0,0,0.12)"}})])}var gb=(n)=>(o,i)=>{let a=he(o,Te(o)),{min:s,max:d,value:l,fraction:p}=fb(a,i,n),u=n.disabledState(a,i),{attrs:h,style:f}=n.base(a,i,{display:"flex","flex-direction":"column",gap:"4px",...u.css}),y={role:"slider","aria-valuenow":String(l),"aria-valuemin":String(s),"aria-valuemax":String(d)},g=S(c(a.style)?.color,i.style)??S("onSurface",i.style),b=typeof a.label==="string"?[m("span",{style:{...kl(i),...g?{color:g}:{}}},[n.bound(a.label,i)])]:[];return m("div",{attrs:{...h,...y,...u.attrs},style:f},[...b,yb(p,i)])};function Pl(n){return{android:{id:"android",renderers:{}},ios:{id:"ios",renderers:{button:hb(n),slider:gb(n),switch:Wo("switch",n),checkbox:Wo("checkbox",n),listItem:ul(n),chip:ml(n),topAppBar:fl(n),textField:Sl(n),bottomNav:Tl(n),tabBar:Al(n)}}}}function ur(n,o,i){let a=c(n.screens)??{},s=typeof n.start==="string"?n.start:Object.keys(a)[0],d=o.screen;return i&&s!==void 0&&d!==void 0&&Object.hasOwn(a,d)?d:s}function bb(n,o){let i=o.stacks,a=i!==void 0&&i.length===0,s=ur(n,o,a);if(!a||s===void 0)return s;let d=ur(n,o,!1);return i.push({start:d,screens:Object.keys(c(n.screens)??{}),screen:s}),s}function Il(n){return{stack:(i,a,s)=>{let d=c(i.screens)??{},l=bb(i,a),{attrs:p,style:u}=n.base(i,a,{display:R,[D]:M}),h=n.child(a,{inBox:!1,style:{...a.style,parentAxis:M,weightsChildren:!1}}),f=l===void 0?void 0:d[l],y=n.renderNode(f,h,`${s}.screens[${JSON.stringify(l)}]`),g=y?[{...y,style:{...y.style,flex:"1 1 auto",[U]:"0",[G]:ne}}]:[];return m("div",{attrs:p,style:u},g)}}}var vb=/^(flex|flex-grow|flex-shrink|flex-basis|align-self|order|margin.*)$/;function _l(n,o,i){let a=Hs(o,i);if(a===void 0)return n;let s={},d={};for(let[u,h]of Object.entries(n.style))(vb.test(u)?s:d)[u]=h;if(delete d.width,n.style[ce]!==void 0)s[ce]=n.style[ce];let l={[qt]:"1 / 1",[te]:"0",[mt]:ne},p=m("div",{attrs:{[ae]:"true"},style:{[qt]:"1 / 1",width:se(a),[ce]:"100%",height:"0"}});return m("div",{style:{...s,display:"grid",[ut]:"minmax(0, auto)",[te]:"0",[K]:Y}},[{...n,style:{...d,...l}},p])}var Cl={top:["padding-top","--safe-top"],bottom:["padding-bottom","--safe-bottom"],start:["padding-inline-start","--safe-start"],end:["padding-inline-end","--safe-end"]};function Ot(n){let o=c(n.safeAreaPadding),i=Array.isArray(o?.types)?o.types:[];if(!o||!Array.isArray(o.edges)||!i.some((a)=>a!=="ime"))return[];return o.edges.map(String).filter((a)=>Cl[a]!==void 0)}function xb(n){let o=n.padding;if(o===void 0)return{...n};let i=o.trim().split(/\s+/),[a,s=a,d=a,l=s]=i,p=Object.fromEntries(Object.entries(n).filter(([u])=>u!=="padding"));return{[ft]:a,"padding-inline-end":s,[Pe]:d,"padding-inline-start":l,...p}}function Ol(n,o,i){let a=o.consumedInsets??[],s=Ot(n).length>0?xb(i):{...i};for(let d of Ot(n)){let l=Cl[d];if(l&&!a.includes(d))s[l[0]]=`calc(${s[l[0]]??"0px"} + var(${l[1]}))`}return s}function Dl(n,o,i){let a=i.consumedInsets??[],s=Ot(o).filter((p)=>!a.includes(p)),d=s.includes("top")?i.safeInsets?.top??0:0,l=s.includes("bottom")?i.safeInsets?.bottom??0:0;return d>0||l>0?{...n,[Yn]:{top:d,bottom:l}}:n}var Rb={fit:"contain",crop:"cover",fill:"100% 100%"};function $l(n){return n==="crop"||n==="fill"?n:"fit"}function Ve(n,o=""){return`--pa-${n}${o}`}function Eb(n,o,i){let a=c(n),s=a?o==="dark"?a.dark:a.light:n;if(typeof s!=="string")return;let d=i(s);return d.length>0?d:void 0}function mn(n){let o=c(n)?.dp;return typeof o==="number"?o:void 0}var Io=(n)=>n==="fill"||mn(n)!==void 0,hn=(n)=>!Io(n);function Fl(n){return{...mn(n.width)===void 0?{"min-width":"48px"}:{},...mn(n.height)===void 0?{"min-height":"48px"}:{}}}function mr(n,o){let i=c(n.padding)?.[o];return typeof i==="number"?i:0}function Tb(n,o,i){let a=Ul(n,o);if(a!==void 0)return Math.max(0,a-_o(n,o));let s=i===void 0?Ab(n,o):void 0;return s===void 0?void 0:Math.max(s-_o(n,o),Hl(n,o)??zl)}function _o(n,o){return o==="width"?mr(n,"start")+mr(n,"end"):mr(n,"top")+mr(n,"bottom")}function Bl(n,o,i){let a=(d)=>typeof n[d]==="number"?n[d]:void 0,s=o==="width"?"Width":"Height";return Math.max(Math.min(i,a(`max${s}`)??1/0),a(`min${s}`)??0)}function Ul(n,o){let i=mn(n[o]);return i===void 0?void 0:Bl(n,o,i)}function Ab(n,o){let i=n.aspectRatio;if(typeof i!=="number"||i<=0||!hn(n[o]))return;let a=Ul(n,o==="width"?"height":"width");return a===void 0?void 0:Bl(n,o,o==="width"?a*i:a/i)}function Hl(n,o){let i=n[o==="width"?"minWidth":"minHeight"];if(!hn(n[o])||typeof i!=="number")return;return Math.max(0,i-_o(n,o))}function kb(n,o,i){let a=Wb(c(o.style)??{},i),s=typeof a.weight==="number"?i:void 0;return{asset:n,...Ml(a,"width",Nl(s)),...Ml(a,"height",Nl(s)),scale:$l(o.contentScale)}}function Wb(n,o){if(!oo(n,o))return n;return{...n,padding:{...c(n.padding),start:0,end:0}}}var Nl=(n)=>n===void 0?void 0:n==="row"?"width":"height";function Ml(n,o,i){let a=i===o,s=a?void 0:Tb(n,o,i),d=Hl(n,o);return{...s===void 0?{}:{[`${o}Dp`]:s},...n[o]==="fill"||a?{[`${o}Fill`]:!0}:{},...d===void 0?{}:{[o==="width"?"minWidthDp":"minHeightDp"]:d}}}function Pb(n,o,i){let a=c(o.style)??{};return{"background-color":`var(${Ve(n,"-bg")}, ${i})`,...Fl(a),position:"relative",isolation:"isolate",display:"flex","flex-direction":"column"}}function jl(n){return Object.entries(n).some(([o,i])=>o.startsWith("padding")&&!/^0(px)?$/.test(i.trim()))}function Ib(n,o,i){let a=c(o.style)??{},s=Io(a.width)&&Io(a.height);return jl(i)||s||"aspect-ratio"in i?{}:{"aspect-ratio":`var(${Ve(n,"-ar")}, auto)`}}var _b=[["width","minWidth","min-width","max-width","padding-inline-start","padding-inline-end"],["height","minHeight","min-height","max-height","padding-top","padding-bottom"]];function Cb(n,o){let i={};for(let[a,s,d,l,p,u]of _b){let h=hn(n[a])&&typeof n[s]!=="number"&&o[d]!=="0",f=o[l]&&`calc(${o[l]} - ${o[p]??"0px"} - ${o[u]??"0px"})`;i[d]=!h?"0":f?`min(48px, ${f})`:"48px"}return i}function Ob(n,o,i){if(!jl(i))return{position:"absolute",inset:"0"};let a=c(o.style)??{},s=hn(a.width)||hn(a.height);return{position:"relative",flex:"1 1 auto","align-self":"stretch",...mn(a.height)===void 0?{}:{height:"100%"},...s&&typeof a.aspectRatio!=="number"?{"aspect-ratio":`var(${Ve(n,"-ar")}, auto)`}:{},...Cb(a,i)}}function Db(n,o,i){let a=`var(${Ve(n)})`,s=Rb[$l(o.contentScale)],d=c(o.filter),l=typeof d?.saturation==="number"?d.saturation:1,p=[m("div",{attrs:{"data-image":""},style:{position:"absolute",inset:"0","background-image":a,"background-size":s,"background-position":"center","background-repeat":"no-repeat",...l===1?{}:{filter:`saturate(${l})`}}})],u=d?.tint===void 0?void 0:lf(d.tint,i.mode,i.palette);if(u)p.push(m("div",{attrs:{"data-image-tint":""},style:{position:"absolute",inset:"0","background-color":be({...u,a:1}),"mix-blend-mode":"multiply","mask-image":a,"mask-size":s,"mask-position":"center","mask-repeat":"no-repeat",opacity:`var(${Ve(n,"-on")}, 0)`}}));if(u&&u.a<1){let h={position:"absolute",inset:"0",opacity:String(Number(u.a.toFixed(3)))};return[m("div",{attrs:{"data-image-alpha":""},style:h},p)]}return p}function Gl(n,o){let i=Buffer.from(o.bytes.buffer,o.bytes.byteOffset,o.bytes.byteLength).toString("base64");return`:root{${Ve(n)}:url(data:image/webp;base64,${i});${Ve(n,"-bg")}:transparent;${Ve(n,"-ar")}:${o.width}/${o.height};${Ve(n,"-on")}:1}`}function Ll(n,o,i,a){return n??(o?a:i??zl)}var zl=48;function Vl(n,o,i="long"){let a=Math.max(o.widthDp,o.heightDp),s=i==="long"?a:Math.min(o.widthDp,o.heightDp),d=(p)=>Math.ceil(p*o.density),l=n.widthDp!==void 0||n.heightDp!==void 0||n.widthFill===!0||n.heightFill===!0;if(n.scale!=="fit"&&l){let p=Ll(n.widthDp,n.widthFill,n.minWidthDp,s),u=Ll(n.heightDp,n.heightFill,n.minHeightDp,s);return{...p===void 0?{}:{width:d(p)},...u===void 0?{}:{height:d(u)},cover:!0}}return{width:d(n.widthDp??a),height:d(n.heightDp??a),cover:!1}}function Kl(n,o){let i=o.map((a)=>{let s=[...a.width===void 0?[]:[a.width/n.width],...a.height===void 0?[]:[a.height/n.height]];return a.cover?Math.max(...s):Math.min(...s)});return Math.min(1,Math.max(0,...i))}function ql({base:n,bound:o}){return(i,a,s)=>{let d=Eb(i.asset,a.style.mode,(g)=>o(g,a)),l=d===void 0?void 0:a.imageSlots?.get(d);if(a.unsupported.push({type:"image",...typeof i.id==="string"?{id:i.id}:{},path:s,reason:l===void 0?"assetNotInlined":"assetOverBudget",...d===void 0?{}:{asset:d}}),d!==void 0)a.imageDraws?.push(kb(d,i,a.style.parentAxis));let p=S("surfaceVariant",a.style)??"#e7e0ec";if(d===void 0||l===void 0){let{attrs:g,style:b}=n(i,a,{"background-color":p,...Fl(c(i.style)??{})});return m("div",{attrs:{...g,role:"img"},style:b})}let{attrs:u,style:h}=n(i,a,Pb(l,i,p)),f={...h,...Ib(l,i,h)},y=m("div",{attrs:{"data-image-content":""},style:Ob(l,i,f)},Db(l,i,a.style));return m("div",{attrs:{...u,role:"img"},style:f},[y])}}function Yl(n,o,i,a){let s=S(o?.background,a),d={...B(o,a),...s?{[k]:s}:{}};return m("span",{attrs:i?{"data-link":"true"}:{},style:d},[n])}function Nb(n,o,i){let a=Array.isArray(o.kinds)?o.kinds:[],s=a$(n,a);if(s.length===0)return[n];let d=[],l=0;for(let p of s){if(p.start>l)d.push(n.slice(l,p.start));d.push(Yl(p.text,c(o.style),!0,i)),l=p.end}return l<n.length?[...d,n.slice(l)]:d}function Xl(n,o,i){if(!Array.isArray(n.spans)){let a=c(n.linkify),s=o(n.text);return a?Nb(s,a,i):[s]}return n.spans.map((a)=>{let s=c(a)??{},d=Array.isArray(s.onTap)&&s.onTap.length>0;return Yl(o(s.text),c(s.style),d,i)})}var Mb=new Set(["filled","outlined","rounded","sharp","twoTone"]);function fn(n){return typeof n==="string"&&Mb.has(n)?n:"filled"}var Co={display:de,width:"24px",height:"24px",[q]:"0"},Jl={...Co,[T]:w,[N]:w,border:"2px solid currentColor",[A]:"6px",[oe]:"11px",[De]:"700",[Xe]:"1"};function Zl(n){let o=typeof n==="string"?/[a-z0-9]/i.exec(n)?.[0]:void 0;return o?o.toUpperCase():""}function Ql(n){return m("svg",{attrs:{...{viewbox:"0 0 24 24",width:"100%",height:"100%",fill:"currentColor"},[ae]:"true"}},n)}function ec(n){let o=c(n?.style);if(!o||typeof o.aspectRatio!=="number"||o.aspectRatio<=0)return;return o.width!==void 0||o.height!==void 0||typeof o.weight==="number"?void 0:o.aspectRatio}function tc(n,o=1/0){return ec(n)!==void 0&&fr(n,o)===void 0}function fr(n,o=1/0){let i=ec(n),a=c(n?.style);if(i===void 0||!a)return;let s=[typeof a.maxWidth==="number"?a.maxWidth:1/0,typeof a.maxHeight==="number"?a.maxHeight*i:1/0,o*i],d=Math.min(...s);return d===1/0?void 0:d}var nc=(n,o)=>`${n}.children[${o}]`,hr=(n,o)=>typeof n?.[o]==="number"?n[o]:0;function yr(n){let o=c(n?.height)?.dp;return Lb(n,typeof o==="number"?o:1/0)}function Lb(n,o){let i=typeof n?.maxHeight==="number"?n.maxHeight:1/0,a=typeof n?.minHeight==="number"?n.minHeight:0;return Math.max(Math.min(o,i),a)}function Do(n,o=1/0){let i=yr(n),a=n?.[vt],s=typeof a==="number"?a:1/0,l=n?.[qn]===!0&&s!==1/0?s:Math.min(i,o,s);return Math.max(0,l-No(n))}function No(n){let o=c(n?.padding),i=c(n?.[Yn]);return hr(o,"top")+hr(o,"bottom")+hr(i,"top")+hr(i,"bottom")}function rc(n,o){let a=o.axis==="horizontal"?Dt(o.style,n.heightBound):void 0;return{inBox:!1,style:Gs(n,o),heightBound:a}}function Dt(n,o){let i=Do(c(n),o??1/0);return i===1/0?void 0:i}var oc=(n)=>typeof n==="number"?{height:n,unboundedWidth:!1}:{height:n.heightBound,unboundedWidth:n.style?.unboundedWidth===!0};function ic(n,o,i,a=1/0){let{height:s=1/0,unboundedWidth:d}=oc(a);return n.type==="row"&&n.repeat===void 0&&(d!==!0||io(n.style))&&Array.isArray(n.children)&&n.children.some((p,u)=>tc(i(p,nc(o,u)),Do(c(n.style),s)))?["width"]:[]}function ac(n,o,i,a=1/0){if(n.type!=="row"||n.repeat!==void 0||!Array.isArray(n.children))return n;let{height:s=1/0,unboundedWidth:d}=oc(a),l=n.children.map((y,g)=>i(y,nc(o,g))),p=Do(c(n.style),s),u=Ub(n.children,(y,g)=>l[g],p,d);if(u===n.children)return n;let f=l.some((y)=>fr(y,p)!==void 0)?{...c(n.style),[ro]:!0}:n.style;return{...n,children:u,...f===void 0?{}:{style:f}}}function $b(n,o){let i=c(n);return i?{...i,style:{...c(i.style),...o}}:n}var Fb=1000,Bb=1e9,Oo=(n,o)=>$b(n,{[Zt]:o});function Ub(n,o,i=1/0,a=!1){let s=n.map(o),d=a?-1:s.findIndex((p)=>tc(p,i)),l=s.findIndex((p)=>fr(p,i)!==void 0);if(d<0&&l<0)return n;return n.map((p,u)=>{let h=s[u];if(!h)return p;if(u===d)return Oo(p,{take:!0});let f=typeof c(h.style)?.weight==="number";if(d>=0&&(u>d||f))return Oo(p,{zero:!0});return l<0||u<l||f?p:Hb(p,fr(h,i),u===l)})}function Hb(n,o,i){let a=i?{shrink:Fb}:{shrink:Bb,later:!0};return Oo(n,o===void 0?a:{...a,basis:o})}var jb=new Set(["bottomSheet","dialog","snackbar"]);function gr(n){return jb.has(String(n))}var dt=(n)=>{let o=c(n?.style)?.weight;return typeof o==="number"&&o>0?o:void 0},Gb=(n,o)=>{let i=c(n.style);if(i?.height==="fill")return Math.min(o,yr(i));let a=typeof i?.minHeight==="number"?i.minHeight:0;return typeof c(i?.height)?.dp==="number"?yr(i):a};function zb(n){let o=c(n?.border),i=typeof o?.width==="number"&&o.gradient===void 0?o.width:0;return No(n)+2*i}function Vb(n,o){let i=new Map,a=n.filter((l)=>dt(l)!==void 0),s=(l)=>zb(c(l.style)),d=o-a.reduce((l,p)=>l+s(p),0);while(a.length>0){let l=a.reduce((v,x)=>v+(dt(x)??0),0),p=[...i.values()].reduce((v,x)=>v+x,0),u=o-p-a.reduce((v,x)=>v+s(x),0),h=d*l,f=l<1&&Math.abs(h)<Math.abs(u)?h:u,y=a.map((v)=>{let x=s(v)+f*(dt(v)??0)/l,E=Math.max(s(v),x);return{node:v,share:x,height:E}}),g=y.reduce((v,x)=>v+x.height-x.share,0),b=y.filter(({share:v,height:x})=>g===0||(g>0?x>v:x<v));for(let{node:v,height:x}of b)i.set(v,x);a=a.filter((v)=>!i.has(v))}return i}function sc(n,o,i){let a=n.filter((h)=>h!==void 0),s=i*Math.max(0,a.length-1),d=[],l=0,p=0;for(let h of n){if(!h||dt(h)!==void 0){d.push(void 0);continue}let f=Math.max(0,o-l),y=Gb(h,f);d.push(f),l+=y+i,p+=y}let u=Vb(a,Math.max(0,o-p-s));return n.map((h,f)=>h&&u.has(h)?u.get(h):d[f])}function dc(n){return n.every((o)=>{let i=c(o?.style)?.height;return o===void 0||dt(o)!==void 0||i==="fill"||typeof c(i)?.dp==="number"})}var lc=(n,o)=>`${n}.children[${o}]`,cc=(n)=>(o,i)=>{let a=n(o,i);return a&&gr(a.type)?void 0:a};function pc(n,o,i){let a=c(n);if(!a||o===void 0||o===1/0)return n;let s={...c(a.style),[vt]:o};return{...a,style:i?{...s,[qn]:!0}:s}}var Kb=new Map([["column",{spacing:!0}],["card",{spacing:!1}]]);function uc(n,o,i,a){let{children:s}=n,d=Kb.get(n.type);if(!d||n.repeat!==void 0||!Array.isArray(s)||a===void 0)return n;let l=c(n.style)?.spacing,p=s.map((f,y)=>cc(i)(f,lc(o,y))),u=sc(p,a,d.spacing&&typeof l==="number"?l:0),h=dc(p);return{...n,children:s.map((f,y)=>pc(f,u[y],h&&dt(p[y])!==void 0))}}function mc(n,o,i,a){let s=Array.isArray(n.children)?n.children:[];if(n.type!=="column"||n.repeat===void 0||a===void 0)return i.map(()=>s);let d=i.flatMap((h)=>s.map((f,y)=>cc(h)(f,lc(o,y)))),l=c(n.style)?.spacing,p=sc(d,a,typeof l==="number"?l:0),u=dc(d);return i.map((h,f)=>s.map((y,g)=>{let b=f*s.length+g;return pc(y,p[b],u&&dt(d[b])!==void 0)}))}function qb(n,o){return n.replace(/\{([^{}]+)\}/g,(i,a)=>{if(!a.startsWith("derived:")){let l=br(a),p=o.textLocals??{};if(Object.hasOwn(p,l))return Nt(mp(p[l]));return Object.hasOwn(o.condition.state,l)?Nt(mp(o.condition.state[l])):i}let s=a.slice(8),d=c(o.spec.derive);return d&&Object.hasOwn(d,s)?Nt(Zs(o.spec,s,{data:o.data,state:o.condition.state,env:o.format})):i})}function fe(n,o){if(typeof n!=="string")return"";let i=vY(bc(n),(d)=>{let l=Pt(o.data,br(d));return typeof l==="string"||typeof l==="number"||typeof l==="boolean"?Nt(mp(l)):""}),a=_s(i,o.condition.platformState,br,Nt),s=[...o.instances].reverse().reduce((d,l)=>ld(d,Xb(l)),a);return br(qb(s,o))}var yn="\uE000",bc=(n)=>n.replaceAll(yn,`${yn}e`),Nt=(n)=>bc(n).replaceAll("{",`${yn}o`).replaceAll("}",`${yn}c`),Yb={e:yn,o:"{",c:"}"},br=(n)=>n.replace(/\uE000([eoc])/g,(o,i)=>Yb[i]);function Xb(n){let o=Object.fromEntries(Object.entries(n.values).map(([i,a])=>[i,typeof a==="string"?Nt(a):a]));return{...n,values:o}}function xe(n,o,i={}){let a={"data-node":String(n.type)};if(typeof n.testTag==="string")a[it]=n.testTag;let s=c(n.semantics)?.label??n.contentDescription;if(typeof s==="string")a[z]=fe(s,o);let d={...i,...js(n.style,o.style),...B(c(n.style),o.style),...o.inBox?{[qt]:"cell"}:{}};if("border-start-start-radius"in d)delete d[A];return{attrs:a,style:Ol(n,o,d)}}function lt(n,o){return{...n,...o,style:{...n.style,...o.style},consumedInsets:[...n.consumedInsets??[],...n.ownInsets??[]],ownInsets:[],heightBound:o.heightBound}}function Lo(n,o,i){let a=wc(n,o),s=mc(n,i,a.map(xr),o.heightBound);return a.flatMap((d,l)=>s[l].map((p,u)=>({node:p,scope:d,path:`${i}.children[${u}]`})))}function wc(n,o){let i=c(n.repeat);if(!i)return[o];let a=typeof i.as==="string"?i.as:"item",s=c(i.derive);return Xd(i,o.data,Yd(n)).map((d,l)=>{let p=c(d)??{},u={binding:{alias:a,index:!0},values:s?Qs(s,p,o.format):p,index:l};return lt(o,{instances:[...o.instances,u],heightBound:o.heightBound})})}function wr(n,o,i,a){return Lo(n,o,i).flatMap((s)=>vc(s.node,s.scope,s.path,a))}function vc(n,o,i,a){let s=Er(n,o,i),d=a?a(s,c(n)??{}):s;return d?[d]:[]}function Jb(n,o,i){let a=Mt(n,o,i);if(!a)return[];let{styled:s,scope:d}=a;if(so(s))return["width","height"];let l=c(s.style)??{},p=["width","height"].filter((h)=>l[h]==="fill"),u=Qb.has(String(s.type))?vr(s,d,i,td(s)).filter((h)=>l[h]===void 0):s.type==="searchBar"?Ao(s,d,{bound:fe}):Te(s);return[...p,...u]}var Zb=new Set(["row","column","box"]),Qb=new Set(["row","column","box","card"]);function ew(n,o,i){let a=c(Mt(n,o,i)?.styled.style)?.weight;return typeof a==="number"&&a>0}function vr(n,o,i,a){let s=wc(n,o),d=$o(n,o,i);if(!Array.isArray(d.children)||s.length===0)return[];let l=d.children,p=ic(n,i,xr(o),o),u=Zb.has(String(n.type))?Dt(n.style,o.heightBound):void 0,h=s.flatMap((y)=>l.map((g)=>[g,{...y,heightBound:u}])),f=new Set([...p,...h.flatMap(([y,g])=>Jb(y,g,i))]);if(a&&h.some(([y,g])=>ew(y,g,i)))f.add(a);return["width","height"].filter((y)=>f.has(y))}var xr=(n)=>(o,i)=>Mt(o,n,i)?.styled,$o=(n,o,i)=>{let a=Dt(n.style,o.heightBound);return uc(n,i,xr(lt(o,{})),a)},hc=(n)=>(o,i,a)=>{let s=$o(o,i,a),d=he(s,vr(s,i,a,n==="row"?"width":"height")),l=lt(i,{inBox:!1,style:Ge(i,d,n),heightBound:Dt(d.style,i.heightBound)}),p=ac(d,a,xr(l),{...i,style:l.style}),{attrs:u,style:h}=xe(p,i,Xn(n,p.style));return m("div",{attrs:u,style:h},wr(p,l,a))},tw=(n,o,i)=>{let a=he(n,vr(n,o,i)),{attrs:s,style:d}=xe(a,o,Qt(a.style)),l=lt(o,{inBox:!0,style:Ge(o,a,void 0),heightBound:Dt(a.style,o.heightBound)});return m("div",{attrs:s,style:d},wr(a,l,i))},nw=(n,o)=>{let i=c(n.style)?.maxLines,a=typeof i==="number"?{display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":String(i),overflow:"hidden"}:{},{attrs:s,style:d}=xe(n,o,{...a,[Ie]:"pre-wrap"});return m("span",{attrs:s,style:d},Xl(n,(l)=>fe(l,o),o.style))},rw=(n,o,i)=>{let a=n.axis==="horizontal",s=Ms(n,o.style),{attrs:d,style:l}=xe(n,o,{display:R,[D]:`${a?"row":"column"}${n.reverse===!0?"-reverse":""}`,[T]:"flex-start",[a?"overflow-x":"overflow-y"]:"auto",...s.style}),p=lt(o,rc(o,n)),u={...d,...s.attrs};return m("div",{attrs:u,style:l},vc(n.child,p,`${i}.child`))},ow=(n,o)=>m("div",xe(ed(n),o)),iw=(n,o)=>{let i=n.orientation==="vertical",a=S(c(n.style)?.color,o.style)??S("outlineVariant",o.style)??"rgba(0,0,0,0.12)";return m("div",xe(n,o,i?{width:"1px",[G]:ne,[k]:a}:{height:"1px",[G]:ne,[mt]:ne,[k]:a}))},gn=(n,o,i)=>{let a=typeof n.name==="string"?n.name:void 0,s=a?o.glyphs?.glyph(a,fn(n.variant)):void 0;if(!s&&o.glyphs){let p=typeof n.id==="string"?{id:n.id}:{};o.unsupported.push({type:"icon",...p,path:i,reason:"iconMissing"})}let{attrs:d,style:l}=xe(n,o,s?Co:Jl);return m("span",{attrs:{...d,title:a??"",role:"img"},style:l},[s?Ql(s):Zl(n.name)])},aw=ql({base:xe,bound:fe});function Sr(n,o){return n.enabledWhen===void 0||lo(n.enabledWhen,Rr(o))?{css:{},attrs:{}}:{css:{opacity:"0.38"},attrs:{"aria-disabled":"true"}}}function Mo(n,o,i){return n.flatMap((a)=>{let s=c(a);if(typeof s?.icon!=="string")return[];let d=gn({type:"icon",name:s.icon},o,i),l=typeof s.label==="string"?fe(s.label,o):s.icon;return[m("span",{attrs:{role:"button",[z]:l},style:{padding:"12px"}},[d])]})}var fc={small:{height:64,title:22},centerAligned:{height:64,title:22},medium:{height:112,title:28},large:{height:152,title:36}};function sw(n,o){if(o)return{order:"1",[Vt]:"100%",[Pe]:"16px"};return n==="centerAligned"?{position:L,left:"0",right:"0",[yt]:w,[Ee]:"none"}:{flex:"1 1 auto"}}var dw=(n,o,i)=>{let a=typeof n.variant==="string"?n.variant:"small",s=fc[a]??fc.small,d=a==="medium"||a==="large",{attrs:l,style:p}=xe(n,o,{display:R,"flex-wrap":d?"wrap":"nowrap",[T]:w,"align-content":"space-between",[U]:`${s.height}px`,[we]:"16px",[oe]:pe(s.title,o.style),[G]:ne,position:Z,...xt(o,"surface","onSurface")}),u=Array.isArray(n.actions)?n.actions:[],h=m("span",{style:sw(a,d)},[fe(n.title,o)]);return m("div",{attrs:{...l,role:"heading"},style:p},[...Mo([n.navigationIcon],o,i),h,...d||a==="centerAligned"?[m("span",{style:{flex:"1 1 auto"}})]:[],...Mo(u,o,i)])};function lw(n,o){let i=typeof n.stateKey==="string"?fe(n.stateKey,o):void 0,a=i===void 0?void 0:o.condition.state[i];if(typeof a!=="string"||a==="")return{shown:fe(n.placeholder??n.label,o),empty:!0};return{shown:n.secure===!0||n.keyboardType==="password"?"\u2022".repeat([...a].length):a,empty:!1}}function cw(n,o,i){if(typeof n.label!=="string"||o&&n.placeholder===void 0)return[];return[m("span",{attrs:{"data-slot":"label"},style:{[oe]:pe(12,i.style),opacity:"0.8"}},[fe(n.label,i)])]}var pw=new Set(["width","height","flex","flex-shrink","align-self","grid-area","min-width","max-width","margin"]);function uw(n){let o={},i={};for(let[a,s]of Object.entries(n))(pw.has(a)?o:i)[a]=s;return[o,i]}function mw(n,o,i){let a=o?n.errorText??n.supportingText:n.supportingText;if(typeof a!=="string")return[];let s=S(o?"error":"onSurfaceVariant",i.style);return[m("span",{attrs:o?{role:"alert"}:{},style:{[oe]:pe(12,i.style),padding:"0 16px",...s?{color:s}:{}}},[fe(a,i)])]}function xc(n,o){return n.errorWhen!==void 0&&st(n.errorWhen,Rr(o))===!0}var hw=(n,o,i)=>{let{shown:a,empty:s}=lw(n,o),d=xc(n,o),l=Sr(n,o),{attrs:p,style:u}=xe(n,o,{display:R,[T]:w,[U]:"56px",padding:"0 16px",gap:"12px",...fw(n,d,o),...s?{opacity:"0.7"}:{},...l.css}),h=mw(n,d,o),[f,y]=h.length===0?[{},u]:uw(u),g=m("div",{attrs:{...p,role:"textbox",...l.attrs},style:y},[...Rc(n.leadingIcon,o),m("span",{style:{display:R,[D]:M,flex:"1 1 auto"}},[...cw(n,s,o),m("span",{style:Ks(n,o.style)},[a])]),...Mo([n.trailingIcon],o,i)]),b=h.length===0?g:nt(g,n.style,o.style);return h.length===0?b:m("div",{style:{...f,display:R,[D]:M,gap:"4px"}},[b,...h])};function fw(n,o,i){if(n.variant==="outlined"){let d=S(o?"error":"outline",i.style)??"currentColor";return{[A]:"4px",border:`1px solid ${d}`}}let a=S(o?"error":"onSurfaceVariant",i.style)??"currentColor",s=S("surfaceContainerHighest",i.style);return{[A]:"4px 4px 0 0","border-bottom":`1px solid ${a}`,...s?{[k]:s}:{}}}function Sc(n,o){let i=typeof n==="string"?fe(n,o):void 0;return i!==void 0&&o.condition.state[i]===!0}var yc=(n)=>(o,i)=>{let a=Sc(o.stateKey,i),s=Sr(o,i),{attrs:d,style:l}=xe(o,i,{display:R,[T]:w,gap:"12px",[U]:"48px",...s.css}),p={...d,role:n,[Ke]:String(a),...s.attrs},u=typeof o.label==="string"?[fe(o.label,i)]:[],h=ao(n,a,i);return m("div",{attrs:p,style:l},n==="switch"?[...u,h]:[h,...u])},yw=(n,o,i)=>{let a=$o(n,o,i),s=he(a,vr(a,o,i)),{attrs:d,style:l}=xe(s,o,{display:R,[D]:M,[T]:"flex-start",[A]:"12px",...o.skin==="ios"?yl(s.variant,o):xt(o,s.variant==="outlined"?"surface":"surfaceContainerHighest","onSurface")}),p=lt(o,{inBox:!1,style:Ge(o,s,"column")});return m("div",{attrs:d,style:l},wr(s,p,i))};function Rc(n,o){return typeof n==="string"?[gn({type:"icon",name:n},o,"")]:[]}function gw(n,o,i){let a=c(n.trailing);if(a?.type==="switch"||a?.type==="checkbox"){let s=Sc(a.stateKey,o);return[m("span",{attrs:{role:a.type,[Ke]:String(s),...i},style:{display:R}},[ao(a.type,s,o)])]}if(a?.type==="icon")return[gn({type:"icon",name:a.name},o,"")];return[]}var bw=(n,o)=>{let i=Sr(n,o),{attrs:a,style:s}=xe(n,o,{display:R,[T]:w,gap:"16px",[U]:"56px",padding:"8px 16px",[G]:ne,...i.css}),d=n.supporting===void 0?[]:[m("span",{style:{[oe]:pe(14,o.style),opacity:"0.7"}},[fe(n.supporting,o)])],l=m("div",{style:{display:R,[D]:M,flex:"1 1 auto"}},[m("span",{style:{[oe]:pe(16,o.style)}},[fe(n.headline,o)]),...d]);return m("div",{attrs:{...a,role:"listitem",...i.attrs},style:s},[...Rc(n.leadingIcon,o),l,...gw(n,o,i.attrs)])},Ae={base:xe,child:lt,children:wr,bound:fe,icon:gn,roleCss:xt,disabledState:Sr,renderNode:Er,safeAreaEdges:Ot,fieldErrored:xc},gc=ad(Ae),ww={box:tw,row:hc("row"),column:hc("column"),scroll:rw,text:nw,spacer:ow,divider:iw,icon:gn,image:aw,topAppBar:dw,textField:hw,switch:yc("switch"),checkbox:yc("checkbox"),card:yw,listItem:bw,button:gc,...od(Ae),...cd(Ae),...sl(Ae,gc),...zd(Ae),...Ud(Ae),...Il(Ae),...Rd(Ae)},Ec={...Vd(Ae),...qd(Ae)},AT=Object.keys(Ec),vw=Pl(Ae);function xw(n,o,i){let a=String(n.type),s=typeof n.id==="string"?n.id:void 0;o.unsupported.push({type:a,...s?{id:s}:{},path:i,reason:"unsupportedType"});let{attrs:d,style:l}=xe(n,o,{border:"1px dashed currentColor",padding:"4px",[oe]:"11px",opacity:"0.7"});return m("div",{attrs:{...d,"data-unsupported":a},style:l},[s?`${a} #${s}`:a])}function Sw(n,o,i){return cr(n,o,(a,s,d)=>{if(d==="text"||typeof a!=="string")return a;return d==="operand"?JB(a,i):ld(a,i)})}function Rr(n){return n.textLocals?{...n.condition,state:{...n.condition.state,...n.textLocals}}:n.condition}function Rw(n,o){return(Array.isArray(n.styleWhen)?n.styleWhen:[]).reduce((a,s)=>{let d=c(s);return d&&st(d.when,Rr(o))===!0?{...a,...c(d.style)}:a},c(n.style))}function Mt(n,o,i){let a=c(n);if(!a||typeof a.type!=="string")return;let s=o.instances.reduce((p,u)=>Sw(p,i,u),a),d=nd(s,o,Ae);if(s.visibleWhen!==void 0&&!lo(s.visibleWhen,Rr(d)))return;let l=Dl(Rw(s,d),s,d);return{styled:{...s,style:l},scope:d}}function Er(n,o,i){let a=Mt(n,o,i);if(!a)return;let{styled:s,scope:d}=a,l={...d,ownInsets:Ot(s)},p=Ec[String(s.type)];if(p){p(s,l,i);return}let u=String(s.type),h=vw[l.skin??"android"].renderers[u]??ww[u],f=h?Sd(h(s,l,i),s,l,Ae):xw(s,l,i),y=Kn(s,i);if(y)l.unsupported.push(y);let g=f.attrs["data-node"]===void 0?f:nt(f,s.style,l.style);return _l(g,s.style,l.style)}var Ew=0.179,Tw=0.99;function Fo(n){return Y$(n)<Ew?"dark":"light"}function Aw(n){let o=typeof n==="string"?df(n):void 0;return o&&o.a>=Tw?o:void 0}function kw(n){let o=c(n?.colors),i=o?.background??o?.surface;return typeof i==="string"?df(i):void 0}function Tc(n,o,i){let a=c(c(n)?.theme),s=Ww(a,o,i);return o&&Fo(o)===s.mode?{...s,surface:o}:s}function Ww(n,o,i){let a=n?.mode;if(a==="light"||a==="dark")return{mode:a,source:"explicit"};if(a==="system")return{mode:i,source:"system"};let s=kw(n);if(s)return{mode:Fo(s),source:"roleLuminance"};if(o)return{mode:Fo(o),source:"authoredBackground"};return{mode:i,source:"system"}}function Ac(n,o,i){let a=bn({node:n,scope:o,path:i});return a?kc(a,o.stacks?.length===0):void 0}function kc({prepared:n,path:o},i){let{styled:a,scope:s}=n,d=Aw(c(a.style)?.background);if(d)return d;let l=Iw(a,s,o,i),p=i&&a.type!=="stack";return l?kc(l,p):void 0}function Pw(n,o,i){let a=Mt(n,o,i);return a&&gr(a.styled.type)&&!xo(a.styled,a.scope)?void 0:a}function bn(n){let o=Pw(n.node,n.scope,n.path);return o?{prepared:o,path:n.path}:void 0}function Iw(n,o,i,a){switch(n.type){case"pager":{let s=Array.isArray(n.children)?n.children:[],d=en(n,o,{bound:fe});return bn({node:s[d],scope:o,path:`${i}.children[${d}]`})}case"scroll":case"bottomSheet":case"dialog":return bn({node:n.child,scope:o,path:`${i}.child`});case"stack":{let s=ur(n,o,a);return s===void 0?void 0:bn({node:c(n.screens)?.[s],scope:o,path:`${i}.screens[${JSON.stringify(s)}]`})}default:for(let s of Lo(n,o,i)){let d=bn(s);if(d)return d}return}}var _w="en-US",Cw=new Set(["ar","ckb","dv","fa","he","iw","ks","ps","sd","ug","ur","yi"]),Ow=new Set(["adlm","arab","hebr","nkoo","rohg","syrc","thaa"]);function Wc(n){if(n===void 0)return _w;try{let[o]=Intl.getCanonicalLocales(n);if(o)return o}catch(o){if(!(o instanceof Error))throw o;throw new le(`locale "${n}" is not a valid BCP 47 tag: ${o.message}`,{cause:o})}throw new le(`locale "${n}" is not a valid BCP 47 tag.`)}function Pc(n){let o=new Intl.Locale(n);if(o.script!==void 0)return Ow.has(o.script.toLowerCase())?"rtl":"ltr";return Cw.has(o.language.toLowerCase())?"rtl":"ltr"}var Ic=["extra-small","small","medium","large","extra-large","extra-extra-large","extra-extra-extra-large","accessibility-medium","accessibility-large","accessibility-extra-large","accessibility-extra-extra-large","accessibility-extra-extra-extra-large"],_c=0.85,Cc=2,Oc={"extra-small":14,small:15,medium:16,large:17,"extra-large":19,"extra-extra-large":21,"extra-extra-extra-large":23,"accessibility-medium":28,"accessibility-large":33,"accessibility-extra-large":40,"accessibility-extra-extra-large":47,"accessibility-extra-extra-extra-large":53},ct=[8,10,12,14,18,20,24,30,100],Tr=[[1,ct],[1.15,[9.2,11.5,13.8,16.4,19.8,21.8,25.2,30,100]],[1.3,[10.4,13,15.6,18.8,21.6,23.6,26.4,30,100]],[1.5,[12,15,18,22,24,26,28,30,100]],[1.8,[14.4,18,21.6,24.4,27.6,30.8,32.8,34.8,100]],[2,[16,20,24,26,30,34,36,38,100]]],Dw=1.03,Dc=(n,o,i)=>n+(o-n)*i;function Nw(n){let o=Tr.find(([u])=>u===n);if(o)return o[1];let i=Tr.findIndex(([u])=>u>n),[a,s]=Tr[i-1],[d,l]=Tr[i],p=(n-a)/(d-a);return s.map((u,h)=>Dc(u,l[h],p))}function Mw(n,o){let i=Math.abs(n),a=Math.sign(n),s=ct.length-1;if(i>=ct[s])return n*(o[s]/ct[s]);let d=ct.findIndex((h)=>h>=i),l=d===0?0:ct[d-1],p=d===0?0:o[d-1],u=(i-l)/(ct[d]-l);return a*Dc(p,o[d],u)}function Lw(n){if(n<Dw){let a=(s)=>s*n;return{font:a,tracking:a}}let o=Nw(n),i=(a)=>Mw(a,o);return{font:i,tracking:i}}function $w(n){let o=Oc[n]/Oc.large;return{font:(i)=>i*o,tracking:(i)=>i}}function Fw(n){if(!Number.isFinite(n)||n<_c||n>Cc)throw new le(`fontScale ${n} is outside Android's range ${_c} to ${Cc}.`);return n}function Bw(n){let o=Ic.find((i)=>i===n);if(!o)throw new le(`Unknown contentSize "${n}". Valid sizes: ${Ic.join(", ")}.`);return o}function Uw(n,o){if(n==="android"&&o.contentSize!==void 0)throw new le("contentSize is iOS Dynamic Type; use fontScale for an Android frame.");if(n==="ios"&&o.fontScale!==void 0)throw new le("fontScale is Android's; use contentSize for an iOS frame.")}function Nc(n,o){if(!o)return;if(Uw(n,o),o.fontScale!==void 0&&Fw(o.fontScale)!==1)return Lw(o.fontScale);if(o.contentSize!==void 0&&Bw(o.contentSize)!=="large")return $w(o.contentSize);return}var Hw={topStart:["start","start"],topCenter:["start","center"],topEnd:["start","end"],centerStart:["center","start"],center:["center","center"],centerEnd:["center","end"],bottomStart:["end","start"],bottomCenter:["end","center"],bottomEnd:["end","end"]},Bo={position:L,inset:"0",display:R,[D]:M,[T]:"flex-start"};function jw(n,o,i){let a=typeof n.height==="number"?n.height:0,s=m("div",{style:{display:R,[D]:M,[T]:"flex-start",[G]:ne,height:`${a}px`,...i?{position:Z}:{}}},o),d=n.edge==="top"?"flex-start":"flex-end";return m("div",{attrs:{[Mn]:"sheet"},style:{...Bo,[N]:d}},[s])}function Gw(n,o){let[i,a]=Hw[String(n.gravity)]??["center","center"],s=c(n.offset),d=typeof s?.x==="number"?s.x:0,l=typeof s?.y==="number"?s.y:0,p=m("div",{style:{transform:`translate(${d}px, ${l}px)`}},o);return m("div",{attrs:{[Mn]:"floating"},style:{...Bo,display:"grid",[T]:i,"justify-items":a}},[p])}function zw(n){let o=n?.type==="sheet"?n.height:void 0;return typeof o==="number"&&Number.isFinite(o)&&o>=0?{[vt]:o}:{}}function Vw(n){let o=c(c(n)?.root),i=c(c(c(n)?.window)?.placement);if(!o||i?.type==="floating")return o;let a=c(o.style)??{};return{...o,style:{width:"fill",height:"fill",...a,...zw(i)}}}function Mc(n,o){let i=c(c(n)?.window)?.layoutDirection;if(i==="rtl"||i==="ltr")return i;return Pc(o)==="rtl"?"rtl":void 0}function Kw(n,o,i,a){let s=qw(n,o,i),d=Mc(n,a);if(d===void 0)return s;let l=d==="rtl"?{"--safe-start":"var(--safe-right)","--safe-end":"var(--safe-left)"}:{};return{...s,attrs:{...s.attrs,dir:d},style:{...s.style,...l}}}function qw(n,o,i){let a=c(c(c(n)?.window)?.placement)??{},s=[...o?[o]:[],...i];if(a.type==="sheet")return jw(a,s,i.length>0);if(a.type==="floating")return Gw(a,s);return m("div",{attrs:{[Mn]:"fullscreen"},style:Bo},s)}function Yw(n,o){return n.glyphs&&o.platform==="android"?{glyphs:n.glyphs}:{}}function Xw(n,o){return{locale:o,timeZone:"UTC",nowMs:n.nowMs??0,...n.logger===void 0?{}:{logger:n.logger}}}function Jw(n,o,i){return Is({platform:n,...o,...i?{fold:{posture:i.posture,hinge:i.band.axis}}:{}})}function Zw(n,o,i,{orientation:a,locale:s,fold:d}){let{frame:l}=i,p=c(n)??{},u=cs(je(l,a),d),h={widthDp:u.width,heightDp:u.height},f=o.skin??l.platform,y=Nc(l.platform,o.textSize),g={style:{mode:"light",palette:eo(n,"light"),parentAxis:M,typography:Us(n),...y?{textScale:y}:{},platform:f,...Mc(p,s)==="rtl"?{rtl:!0}:{}},condition:{state:c(p.state)??{},platform:l.platform,platformState:Jw(l.platform,h,d)},data:p.data,spec:p,format:Xw(o,s),instances:[],inBox:!1,unsupported:[],skin:f,...Yw(o,l),screenWidth:u.width,screenHeight:u.height,safeInsets:o.chromeless?{top:0,bottom:0}:{top:l.safeArea[a].top,bottom:l.safeArea[a].bottom},...Qw(o),stacks:[],layers:[],imageDraws:[]},{mode:b,surface:v}=Tc(n,Ac(p.root,g,"root"),o.mode??"light");return{...g,style:{...g.style,mode:b,palette:eo(n,b,v)}}}function Qw(n){return{...n.screen===void 0?{}:{screen:n.screen},...n.imageSlots===void 0?{}:{imageSlots:n.imageSlots}}}function ev(n){return S("background",n)??S("surface",n)??S("background",{...n,palette:Fg({},n.mode)})}function tv(n,o){let{content:i,background:a,dark:s,screen:d,vars:l}=o,p=c(c(n)?.window)?.statusBar;if(p==="light"||p==="dark")return p;let u=Ia(i,a,d,l);return Pa(u,s?"light":"dark")}function nv(n,o){let i=wt(n);if(o===void 0)return i[0];if(!i.includes(o))throw new le(`Device frame "${n.id}" has no ${o} view. Its orientations: ${i.join(", ")}`);return o}function Lc(n){return n.posture?{posture:n.posture}:{}}function rv(n,o){return{...Lc(n),...o?{fold:o}:{}}}function $c(n,o={}){let i=ds(Re(o.frame??Fe(o.platform??"android")),o.posture),{frame:a}=i,s=Wc(o.locale),d=vie(Ig(n),[s]),l=nv(a,o.orientation),p=ls(i,l),u=Zw(d,o,i,{orientation:l,locale:s,fold:p}),h=Er(Vw(d),u,"root"),f=u.style.mode==="dark",y=S("onSurface",u.style)??(f?"#e6e0e9":"#1d1b20"),g=ev(u.style),b=Kw(d,h,u.layers,s),v=a.input==="dpad"?Ps(b):b,x={dark:f,textColor:y,background:g,...u.style.textScale?{fontSize:pe(14,u.style)}:{}},E=o.chromeless?La(a,l,x,v):$a(a,l,{...x,statusBarContent:tv(d,{content:v,background:g,dark:f,screen:je(a,l),vars:Da(a,l)}),...rv(i,p)},v),W=u.stacks?.[0];return{element:E,frame:a.id,...Lc(i),unsupportedNodes:u.unsupported,...W?{stack:W}:{},imageDraws:u.imageDraws??[]}}var ov=`(${Rs.toString()})({ zoomScale: ${ps.toString()}, fitScale: ${us.toString()}, wheelFactor: ${ms.toString()}, screenView: ${hs.toString()}, viewMatches: ${fs.toString()}, rotation: ${ys.toString()}, animateTurn: ${Ss.toString()}, clockText: ${gs.toString()}, clockDelay: ${bs.toString()}, startClock: ${xs.toString()}, browserClock: ${vs.toString()} });`,iv=`(${ss.toString()})({ pose: ${Xa.toString()}, orbit: ${qa.toString()}, hingeLine: ${Ya.toString()}, postureAt: ${Xr.toString()}, wrap: ${ns.toString()}, unwrap: ${rs.toString()}, bodyHinge: ${is.toString()}, orbitKey: ${as.toString()}, dragOrbit: ${os.toString()}, leaves: ${ts.toString()}, flat: ${JSON.stringify(Va)}, start: ${JSON.stringify(Ka)} });`,Fc=`${ov}
|
|
970
|
-
${iv}`;var Ho=2097152,av=["*{box-sizing:border-box}","html,body{margin:0;height:100%}","body{display:flex;flex-direction:column;font:14px system-ui,-apple-system,Roboto,sans-serif;background:#f3f3f3;color:#1d1b20}","[data-toolbar]{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px;border-bottom:1px solid #ccc;background:#fff}","[data-toolbar] button,[data-toolbar] select{font:inherit;padding:4px 10px}","[aria-pressed=true]{font-weight:700}","[data-main]{flex:1;display:flex;min-height:0}","[data-viewport]{flex:1;overflow:hidden;position:relative;cursor:grab;touch-action:none}","[data-stage]{position:absolute;left:50%;top:50%;transform-origin:center}","[data-view]{position:absolute;transform:translate(-50%,-50%)}","[data-control=revisions]{width:180px;overflow:auto;border-left:1px solid #ccc;background:#fff;margin:0;padding:8px;list-style:none}","[data-control=revisions] button{width:100%;text-align:start;margin-bottom:4px}","[data-note]{color:#5f5b66;font-size:12px}","@media (max-width:720px){[data-main]{flex-direction:column}[data-control=revisions]{width:auto;max-height:30vh;border-left:0;border-top:1px solid #ccc}}","[hidden]{display:none!important}",Ls,es].join("");function sv(n){return["default-src 'none'",`script-src 'sha256-${Gc("sha256").update(n).digest("base64")}'`,"style-src 'unsafe-inline'","img-src data:","font-src data:"].join("; ")}function dv(n){if(!n||n.screens.length<2||!n.screens.includes(n.start))return[];return[n.start,...n.screens.filter((o)=>o!==n.start)]}function Bc(n,o,i,{orientation:a,posture:s}){let d=$c(i.revision.spec,{frame:o,orientation:a,...s===void 0?{}:{posture:s},mode:n.mode,nowMs:n.nowMs,imageSlots:n.slots,...n.locale===void 0?{}:{locale:n.locale},...n.textSize===void 0?{}:{textSize:n.textSize},logger:e,glyphs:zn(),...i.screen===void 0?{}:{screen:i.screen}}),l=m("div",{attrs:{"data-view":"","data-variant":i.variant,"data-revision":String(i.revision.revision),"data-orientation":a,...s===void 0?{}:{"data-posture":s},...i.screen===void 0?{}:{"data-screen":i.screen},hidden:""}},[d.element]);return{variant:i.variant,revision:i.revision.revision,orientation:a,...s===void 0?{}:{posture:s},...i.screen===void 0?{}:{screen:i.screen},html:Ue(l),unsupported:d.unsupportedNodes,draws:d.imageDraws,...d.stack?{stack:d.stack}:{}}}function lv(n){return n.postures.flatMap((o)=>n.orientations.map((i)=>({orientation:i,posture:o})))}function cv(n,o,i,a){let s=Bc(n,o,i,a),d=dv(s.stack);return d.length===0?[s]:d.map((l)=>Bc(n,o,{...i,screen:l},a))}function pv(n,o,i){return[...i.revisions].reverse().map((a)=>{let s={variant:i.id,revision:a},d=lv(o).map((u)=>cv(n,o.id,s,u)),l=Math.max(...d.map((u)=>u.length)),p=Array.from({length:l},(u,h)=>d.flatMap((f)=>f.slice(h,h+1)));return{variant:i.id,revision:a.revision,screens:p}})}var uv={closed:"Closed",half_opened:"Half opened",opened:"Opened",rear_display:"Rear display",flipped:"Flipped",tent:"Tent"};function mv(n){if(n.postures.length<2)return[];return[m("select",{attrs:{"data-control":"layout-posture","aria-label":"Layout posture"}},n.postures.map((o)=>m("option",{attrs:{value:o,...o===n.posture?{selected:""}:{}}},[uv[o]??o])))]}function hv(n){if(n===void 0)return[];let o={"data-control":"screen","aria-label":"Screen"};return[m("select",{attrs:n.length<2?{...o,hidden:""}:o},n.map((i)=>m("option",{attrs:{value:i}},[i])))]}function fv(n,o,i,a){let s=(p,u,h)=>m("button",{attrs:{type:"button","data-control":p,"aria-label":u}},[h]),d=n.variants.filter((p)=>p.revisions.length>0),l=d.length>1?[m("select",{attrs:{"data-control":"variant","aria-label":"Variant"}},d.map((p)=>m("option",{attrs:{value:p.id,"data-latest":String(p.revisions.at(-1)?.revision??""),...p.id===o.id?{selected:""}:{}}},[p.label])))]:[];return m("div",{attrs:{"data-toolbar":"",role:"toolbar","aria-label":"Prototype view"}},[...a.rotates?[s("rotate","Rotate device","Rotate")]:[],...mv(a),s("zoom-out","Zoom out","\u2212"),m("span",{attrs:{"data-control":"zoom-level","aria-live":"polite"}},["100%"]),s("zoom-in","Zoom in","+"),s("zoom-fit","Fit to window","Fit"),...l,...hv(i),...Za(a.fold),m("span",{attrs:{"data-note":""}},["Static preview: taps do nothing; these controls switch pre-rendered views."])])}function zc(n,o){return m("li",{},[m("button",{attrs:{type:"button","data-revision-for":n,"data-revision-value":String(o.revision),"aria-pressed":"false"}},[`r${o.revision} \xB7 ${o.operation}`])])}function yv(n,o,i){let a=n.variants.find((s)=>s.id===o)?.revisions.find((s)=>s.revision===i);return a?Buffer.byteLength(Ue(zc(o,a))):0}function Uc(n,o,i=!1){let a=n.variants.map((d)=>[...d.revisions].reverse().filter((l)=>o(d.id,l.revision)).map((l)=>zc(d.id,l)));if(!i&&!a.some((d)=>d.length>1))return;let s=a.flat();return m("ul",{attrs:{"data-control":"revisions","aria-label":"Revision history"}},s)}var Uo=(n)=>n.reduce((o,i)=>o+Buffer.byteLength(i.html),0),gv=Buffer.byteLength(' hidden=""');function bv(n){return n.flat().reduce((o,i)=>Buffer.byteLength(i.html)>Buffer.byteLength(o.html)?i:o)}function wv(n,o){let i=bv(o.map((a)=>a.screens[0]));throw new t(`The prototype web page would exceed ${n} bytes even with only the latest revision of each variant and the revision shown first. Largest view: variant ${i.variant} revision ${i.revision} (${Buffer.byteLength(i.html)} bytes). Reduce the spec's repeated content or show fewer variants.`)}function vv(n){return[...new Set(n.flatMap((o)=>o.flatMap((i)=>i.draws.map((a)=>a.asset))))]}function xv(n,o,i,{pinned:a,isShown:s,rules:d}){let l=n.maxBytes??Ho,p=l-i+gv,u=(E)=>{let W=E<=p;return p-=W?E:0,W},h=(E)=>a(E.variant,E.revision),f=o.filter(h);if(!u(f.reduce((E,W)=>E+Uo(W.screens[0]),0)))wv(l,f);let y=new Set,g=new Set,b=(E)=>{for(let W of vv(E)){let ee=d.get(W);if(ee!==void 0&&!g.has(W)){if(g.add(W),u(Buffer.byteLength(ee)))y.add(W)}}},v=new Map(f.map((E)=>[E,[E.screens[0]]])),x=(E)=>{for(let W of E.screens.slice(1))if(u(Uo(W)))v.get(E).push(W),b([W])};[...f.filter(s),...f.filter((E)=>!s(E))].forEach((E)=>b([E.screens[0]])),f.forEach(x);for(let E of o.filter((W)=>!h(W))){let W=yv(n,E.variant,E.revision);if(u(Uo(E.screens[0])+W))v.set(E,[E.screens[0]]),b([E.screens[0]]),x(E)}return{revisions:o.filter((E)=>v.has(E)).map((E)=>({...E,screens:v.get(E)})),images:[...d.keys()].filter((E)=>y.has(E))}}function Sv(n,o,i,a){let s=Re(a).screen,d=[...n.filter(o),...n.filter((u)=>i(u)&&!o(u)),...n.filter((u)=>!i(u))],l=new Map;for(let u of d)for(let h of u.screens.flat().flatMap((f)=>f.draws))l.set(h.asset,[...l.get(h.asset)??[],h]);let p=(u,h)=>[...new Map(u.map((f)=>Vl(f,s,h)).map((f)=>[JSON.stringify(f),f])).values()];return[...l].map(([u,h])=>{let f=p(h,"long"),y=p(h,"short");return JSON.stringify(y)===JSON.stringify(f)?{id:u,boxes:f}:{id:u,boxes:f,compactBoxes:y}})}function Hc(n,o){if(!n.some((s)=>s.screens.length>1))return;let a=(n.find((s)=>s.variant===o.variant.id&&s.revision===o.revision)?.screens??[]).flat().flatMap((s)=>s.screen??[]);return[...new Set(a)]}function Rv(n){let o=n.variant===void 0?n.variants[0]:n.variants.find((i)=>i.id===n.variant);if(!o||o.revisions.length===0)throw new t(`Unknown or empty prototype variant "${n.variant??""}". Variants: ${n.variants.map((i)=>i.id).join(", ")}`);return o}function Ev(n){let o=new Map;for(let i of n)if(!o.has(i.id))o.set(i.id,Gl(o.size,i));return o}function jc(n,o,{frame:i,views:a,history:s,screens:d,images:l=""}){let p=`<body data-variant="${Yt(o.variant.id)}" data-revision="${o.revision}" data-platform="${Yt(i.platform)}" data-orientation="${i.orientation}"${i.posture===void 0?"":` data-posture="${Yt(i.posture)}"`}${Qa(i.fold)}>${Ue(fv(n,o.variant,d,i))}<div data-main=""><div data-viewport="" aria-label="Device preview"><div data-stage="">${a}</div></div>${s?Ue(s):""}</div><script>${Fc}</script></body>`;return`<!doctype html><html lang="en">${`<head><meta charset="utf-8"><meta http-equiv="Content-Security-Policy" content="${sv(Fc)}"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" href="data:,"><title>${Ue(n.title)}</title><style>${av}${l}</style></head>`}${p}</html>
|
|
971
|
-
`}function jo(n){return Gn(()=>Tv(n))}function Tv(n){let o=Rv(n),i=Re(n.frame??Fe(n.platform??"android")),a=wt(i),s=Jr(i),d=Vn(i),l={platform:i.platform,orientation:a[0],rotates:a.length>1,fold:Ja(i),postures:d,...s===void 0?{}:{posture:s}},p={id:i.id,orientations:a,postures:s===void 0?[void 0]:[s,...d.filter((I)=>I!==s)]},u={variant:o,revision:n.revision??o.revisions.at(-1).revision},h=(I,ge)=>I===o.id&&ge===u.revision||n.variants.some((ke)=>ke.id===I&&ke.revisions.at(-1)?.revision===ge),f=Ev(n.images??[]),y=new Map([...f.keys()].map((I,ge)=>[I,ge])),g=n.variants.flatMap((I)=>pv({...n,slots:y},p,I)),b=(I)=>I.variant===o.id&&I.revision===u.revision,v=(I)=>h(I.variant,I.revision),x=Buffer.byteLength(jc(n,u,{frame:l,views:"",history:Uc(n,h,!0),screens:Hc(g,u)})),E=xv(n,g,x,{pinned:h,isShown:b,rules:f}),{revisions:W}=E,ee=new Set(E.images),_=W.flatMap((I)=>I.screens.flat()),ye=_.find((I)=>I.variant===o.id&&I.revision===u.revision&&I.orientation===l.orientation&&I.posture===s);if(!ye)throw new t(`Revision ${u.revision} of variant ${o.id} is not in the page. Inlined revisions: ${W.filter((I)=>I.variant===o.id).map((I)=>I.revision).join(", ")}`);let C=_.map((I)=>I===ye?I.html.replace(' hidden=""',""):I.html).join(""),me=new Set(W.map((I)=>`${I.variant}\x00${I.revision}`)),O=jc(n,u,{frame:l,views:C,history:Uc(n,(I,ge)=>me.has(`${I}\x00${ge}`)),screens:Hc(W,u),images:E.images.map((I)=>f.get(I)).join("")}),j=Object.fromEntries(n.variants.map((I)=>[I.id,W.filter((ge)=>ge.variant===I.id).map((ge)=>ge.revision)]));return{html:O,sha256:Gc("sha256").update(O).digest("hex"),frame:i.id,unsupportedNodes:ye.unsupported.filter((I)=>!(I.reason==="assetOverBudget"&&ee.has(I.asset??""))),inlinedRevisions:j,imageRequests:Sv(g,b,v,i.id),inlinedImages:E.images}}var Av=new Set(["image/png","image/jpeg","image/webp"]),kv=(n)=>Math.ceil(n/3)*4,Wv=80;class Go{load;constructor(n=bk){this.load=n}async encode(n,o,{applyExifOrientation:i}){let a=await this.load(),s=await a(n).metadata(),d=i?s.autoOrient:s,l=d.width??1,p=d.height??1,u=Kl({width:l,height:p},o),{data:h,info:f}=await a(n,{autoOrient:i}).resize({width:Math.max(1,Math.round(l*u)),height:Math.max(1,Math.round(p*u)),fit:"fill"}).webp({quality:Wv}).toBuffer({resolveWithObject:!0});return{bytes:new Uint8Array(h),width:f.width,height:f.height}}}async function Vc(n,o,i,{maxBytes:a=Ho,applyExifOrientation:s=!1}={}){let d=[],l=new Set;for(let p of n)try{let u=await o.get(p.id);if(!u||!Av.has(u.mimeType))continue;let h=await i.encode(u.bytes,p.boxes,{applyExifOrientation:s});if(kv(h.bytes.byteLength)<=a)d.push({id:p.id,...h});else l.add(p.id)}catch(u){e.warn(`[PROTOTYPE] Could not read or encode asset ${p.id} for the web page: ${r(u)}`,u)}return{images:d,overBudget:l}}function Ar(n,o){if(o.size===0)return n;return{...n,unsupportedNodes:n.unsupportedNodes.map((i)=>i.asset!==void 0&&o.has(i.asset)?{...i,reason:"assetOverBudget"}:i)}}function Kc(n,o){try{return jo({...n,images:o})}catch(i){if(!(i instanceof t))throw i;e.debug(`[PROTOTYPE] Web page images do not fit: ${r(i)}`);return}}async function Pv(n,o,{large:i,fullPage:a},{source:s,encoder:d,options:l}){let p=new Map(i.images.map((C)=>[C.id,C])),u=o.imageRequests.flatMap((C)=>C.compactBoxes&&(p.has(C.id)||i.overBudget.has(C.id))?[{id:C.id,boxes:C.compactBoxes}]:[]);if(u.length===0)return;let h=await Vc(u,s,d,l),f=new Map(h.images.map((C)=>[C.id,C])),y=o.imageRequests.map((C)=>C.id).filter((C)=>p.has(C)||f.has(C)),g=new Map,b=(C)=>{if(!g.has(C)){let me=y.map((O,j)=>j<C?p.get(O)??f.get(O):f.get(O)??p.get(O));g.set(C,Kc(n,me))}return g.get(C)},v=(C)=>C?.inlinedImages.length??-1,x=v(b(0)),E=a?y.findIndex((C)=>!a.inlinedImages.includes(C)):0,W=0,ee=E===-1?y.length:E;while(W<ee){let C=Math.ceil((W+ee)/2);if(v(b(C))>=x)W=C;else ee=C-1}let _=new Set([...i.overBudget].filter((C)=>!f.has(C)));for(let C of h.overBudget)_.add(C);let ye=b(W);return ye?Ar(ye,_):Ar(o,new Set([..._,...y]))}async function qc(n,o,i){let a=jo(n);if(a.imageRequests.length===0)return a;let s={...n.maxBytes===void 0?{}:{maxBytes:n.maxBytes},applyExifOrientation:Re(a.frame).platform==="ios"},d=await Vc(a.imageRequests,o,i,s),l=d.images.length===0?void 0:Kc(n,d.images);if(l&&l.inlinedImages.length===d.images.length&&d.overBudget.size===0)return l;let p=await Pv(n,a,{large:d,fullPage:l},{source:o,encoder:i,options:s});if(p)return p;if(l)return Ar(l,d.overBudget);return Ar(a,new Set([...d.overBudget,...d.images.map((u)=>u.id)]))}var Iv={assets:()=>({get:async()=>{return}}),encoder:{encode:async()=>{throw Error("No prototype web image encoder")}}};function zo(n){if(n===void 0)return;if(!/^[1-9][0-9]{0,15}$/.test(n))throw new t(`Invalid prototype revision "${n}": use a positive integer, or omit revision for the latest.`);return Number(n)}function $t(n){if(n===void 0)return;if(n.trim().length===0)throw new t("Invalid prototype mcpSessionId: use the mcpSessionId a show or patch returned, or omit it for every session's revisions.");return{mcpSessionId:n}}function _v(n,o){return{id:o,label:n.revision(o).variant?.label??o,revisions:n.history(o).map(({revision:i,operation:a,spec:s})=>({revision:i,operation:a,spec:s}))}}function Vo(n,o,i){let a=o.variant??o.id;if(!i.includes(a))throw new t(`Unknown variant "${a}" for prototype "${o.id}". Variants: ${i.join(", ")}.`);let s=$t(o.mcpSessionId);return{id:a,revision:n.revision(a,zo(o.revision),s)}}async function Yc(n,o,i,a=Iv){return Fa(()=>Cv(n,o,i,a))}async function Cv(n,o,i,a){let s=lE(n,o.id),d=Vo(n,o,s),l=d.revision.platform??"android",p=Re(o.frame??Fe(l)).id,u=n.revision(o.id).variant?.group,h=$t(o.mcpSessionId),f=n.history(d.id,h).map((v)=>v.revision),y=await qc({title:u??o.id,variants:s.map((v)=>_v(n,v)),variant:d.id,revision:d.revision.revision,frame:p,platform:l},a.assets(s),a.encoder),{deviceRevision:g,mcpSessionId:b}=d.revision;return{html:y.html,lastModified:d.revision.time,meta:{revision:d.revision.revision,...g===void 0?{}:{deviceRevision:g},...b===void 0?{}:{mcpSessionId:b},revisions:f,variants:s,frame:y.frame,sha256:y.sha256,rendererVersion:i}}}var Dv={compose:{platform:"android",mimeType:dE.compose,render:En},swiftui:{platform:"ios",mimeType:dE.swiftui,render:Tn}};function Nv(n,o,i){let a=Ht(o);return Dr(i).map(({id:s,kind:d})=>({id:s,kind:d,path:Wn(n,a,kn(s)),uri:`${Sb}?${new URLSearchParams({id:o,assetId:s}).toString()}`}))}function Mv(n){if("gradle"in n)return`Library (Gradle): implementation("${n.gradle}")`;let{url:o,from:i,product:a}=n.swiftPackage;return`Library (SwiftPM): .package(url: "${o}", from: "${i}"), product "${a}"`}function Lv(n,o,i,a){let{spec:s}=a,d=Tp(s),l=i.length===0?["Assets: none"]:["Assets (not inlined; add each file at its path, a saved prototype serves its bytes):",...i.map((p)=>` ${p.kind} ${p.path} <- ${p.uri}`)];return[`Generated by ${n} (revision ${a.revision}, frame ${a.frame.id}).`,Mv(Nr(o,a.version)),`Required capabilities: ${d.length===0?"none":d.join(", ")}`,...l]}function $v(n){let{width:o,height:i}=je(n,wt(n)[0]);return{name:n.label,widthDp:o,heightDp:i}}function Xc(n,o,i,a){return Gn(()=>Fv(n,o,i,a))}function Fv(n,o,i,a){let{platform:s,mimeType:d,render:l}=Dv[o],p=$t(i.mcpSessionId),u=n.revision(i.id,zo(i.revision),p),h=Re(i.frame??Fe(s));Lr(u.spec,s);let f=Nv(s,i.id,u.spec);if(s==="ios")Mr(f);let y=$g(i.id,o),g=l({id:i.id,directory:Ht(i.id),typeName:jt(i.id),assets:f,storage:u.spec.storage!==void 0,inline:{spec:JSON.stringify(u.spec),generatedBy:y,header:Lv(y,s,f,{spec:u.spec,revision:u.revision,frame:h,version:a}),preview:$v(h)}}),{deviceRevision:b,mcpSessionId:v}=u;return{text:g,mimeType:d,meta:{revision:u.revision,...b===void 0?{}:{deviceRevision:b},...v===void 0?{}:{mcpSessionId:v},revisions:n.history(i.id,p).map((x)=>x.revision),frame:h.id,sha256:Ov("sha256").update(g,"utf8").digest("hex"),rendererVersion:a}}}import{createHash as zv}from"crypto";var Zc=V.definitions;function Wr(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)}function Qc(n,o,i){if(o)n.forEach((a)=>Ft(a,o,i))}var Bv={chip:(n)=>typeof n.stateKey==="string"?["filled/check"]:[],segmentedButton:()=>["filled/check"],select:()=>["filled/expand_more"],datePicker:()=>["filled/arrow_drop_down","filled/chevron_left","filled/chevron_right"]},Ko=(n,o,i)=>{if(Wr(n))Qc(Object.values(n),o.item,i)},Uv={ref:(n,o,i)=>Hv(n,o.name,i),array:(n,o,i)=>{if(Array.isArray(n))Qc(n,o.item,i)},map:Ko,record:Ko,screenMap:Ko,object:(n,o,i)=>jv(n,o,i),tagged:(n,o,i)=>{let a=Wr(n)?String(n.type):"",s=o.variants?.[a];if(s){for(let d of Bv[a]?.(n)??[])i.keys.add(d);Ft(n,s,i)}},choice:(n,o,i)=>o.options?.forEach((a)=>Ft(n,a,i))};function Ft(n,o,i){if(n!==void 0&&n!==null)Uv[o.kind]?.(n,o,i)}function Hv(n,o,i){if(o==="iconName"){if(typeof n==="string"&&xg.has(n))i.keys.add(`filled/${n}`);return}let a=Zc[o];if(a)Ft(n,a,i)}var Jc=(n,o)=>n?.kind==="ref"&&n.name===o;function jv(n,o,i){if(!Wr(n))return;let a=Object.entries(o.fields??{}),s=a.find(([,l])=>Jc(l?.rule,"iconVariant"))?.[0],d=s?fn(n[s]):"filled";if(s)i.variants.add(d);for(let[l,p]of a){let u=n[l];if(Jc(p?.rule,"iconName")&&typeof u==="string"){if(xg.has(u))i.keys.add(`${d}/${u}`)}else if(p)Ft(u,p.rule,i)}}function kr(n,o){if(typeof n==="string"){if(xg.has(n))o.add(n)}else if(Array.isArray(n))n.forEach((i)=>kr(i,o));else if(Wr(n))Object.values(n).forEach((i)=>kr(i,o))}function Gv(n){let o={keys:new Set,variants:new Set(["filled"])};Ft(Ig(n),Zc.spec,o);let i=new Set;kr(n.state,i),kr(n.data,i);for(let a of i)for(let s of o.variants)o.keys.add(`${s}/${a}`);return[...o.keys].sort()}function ep(n,o){let i={},a=[];for(let s of Gv(n)){let[d,l]=s.split("/"),p=o.glyph(l,fn(d));if(p)i[s]=p.map((u)=>Ue(u)).join("");else a.push(s)}return{glyphs:i,iconMissing:a}}var Vv="automobile-prototype-embed",Kv=1;function qv(n,o=zn()){let{glyphs:i,iconMissing:a}=ep(n,o);return{format:Vv,version:Kv,requires:Tp(n),spec:n,...Object.keys(i).length>0?{glyphs:i}:{},...a.length>0?{iconMissing:a}:{}}}function tp(n,o,i,a){let s=lE(n,o.id),d=Vo(n,o,s),l=qv(d.revision.spec,a),p=JSON.stringify(l),{deviceRevision:u,mcpSessionId:h}=d.revision,f=$t(o.mcpSessionId);return{text:p,envelope:l,meta:{revision:d.revision.revision,...u===void 0?{}:{deviceRevision:u},...h===void 0?{}:{mcpSessionId:h},revisions:n.history(d.id,f).map((y)=>y.revision),variants:s,sha256:zv("sha256").update(p).digest("hex"),rendererVersion:i}}}function gk(){return new Go}function qo(n,o,i){let a=new URLSearchParams(Object.entries(i).filter((d)=>d[1]!==void 0).sort(([d],[l])=>d.localeCompare(l))).toString(),s=$g(n,o);return a?`${s}?${a}`:s}async function wk(n,o){let i=await Yc(n.revisions,o,n.rendererVersion(),n.images),{frame:a,revision:s,variant:d,mcpSessionId:l}=o;return{uri:qo(o.id,"web",{frame:a,revision:s,variant:d,mcpSessionId:l}),mimeType:"text/html",text:i.html,_meta:{...i.meta}}}function vk(n,o){let i=tp(n.revisions,o,n.rendererVersion()),{revision:a,variant:s,mcpSessionId:d}=o;return{uri:qo(o.id,"embed",{revision:a,variant:s,mcpSessionId:d}),mimeType:"application/json",text:i.text,_meta:{...i.meta}}}function xk(n,o,i){let a=Xc(n.revisions,o,i,n.rendererVersion()),{frame:s,revision:d,mcpSessionId:l}=i;return{uri:qo(i.id,o,{frame:s,revision:d,mcpSessionId:l}),mimeType:a.mimeType,text:a.text,_meta:{...a.meta}}}function Sk(){return{uri:Hx,mimeType:"text/markdown",text:Ri()}}function Rk(n){let{total:o,names:i}=Si(n);return{uri:`${tF}?query=${Qe(n)}`,mimeType:"application/json",text:JSON.stringify({query:n,total:o,truncated:o>i.length,names:i})}}async function Ek(n,o){let i=await Ci(n,o),a=new URLSearchParams(n).toString();return{uri:a?`${Bg}?${a}`:Bg,mimeType:"application/json",text:JSON.stringify(i,null,2)}}async function Tk(n,o){let i=await Zi(n,o),a=new URLSearchParams(n).toString();return{uri:a?`${wb}?${a}`:wb,mimeType:"application/json",text:JSON.stringify(i,null,2)}}async function Ak(n,o){let i=await Oi(n,o);return{uri:`${Sb}?${new URLSearchParams(n).toString()}`,mimeType:i.mimeType,blob:Buffer.from(i.bytes).toString("base64")}}export{gk as createPrototypeWebImageEncoder,Tk as readEject,vk as readEmbed,Sk as readGuide,Rk as readIcons,Ek as readNative,Ak as readNativeAsset,xk as readSource,wk as readWeb};
|
|
972
|
-
|
|
973
|
-
//# debugId=6A96D1D58C19C26B64756E2164756E21
|