@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.
Files changed (257) hide show
  1. package/dist/build-info.json +12 -12
  2. package/dist/schemas/test-plan.schema.json +370 -52
  3. package/dist/src/ble-peripheral.py +153 -0
  4. package/dist/src/{chunk-r14wwk37.js → chunk-026y62r9.js} +12 -12
  5. package/dist/src/chunk-0jyfg947.js +4 -0
  6. package/dist/src/{chunk-950qcq1e.js → chunk-0zfpp1wh.js} +4 -4
  7. package/dist/src/chunk-13qxf7ym.js +7 -0
  8. package/dist/src/chunk-1scenrk7.js +4 -0
  9. package/dist/src/chunk-1vb5ph1k.js +4 -0
  10. package/dist/src/chunk-20g565q7.js +5 -0
  11. package/dist/src/chunk-21h6dhdm.js +5 -0
  12. package/dist/src/{chunk-2e6s75qv.js → chunk-25mfpthk.js} +8 -8
  13. package/dist/src/{chunk-9rkfyt6q.js → chunk-2b39zyxc.js} +3 -3
  14. package/dist/src/chunk-2gzd6wbd.js +4 -0
  15. package/dist/src/{chunk-eka89q3k.js → chunk-3dntffy9.js} +1 -1
  16. package/dist/src/chunk-3gfczcsn.js +4 -0
  17. package/dist/src/chunk-3h5jz1vb.js +9 -0
  18. package/dist/src/chunk-41zcy6b3.js +5 -0
  19. package/dist/src/chunk-47n9m2de.js +4 -0
  20. package/dist/src/chunk-4vxeq0vd.js +58 -0
  21. package/dist/src/chunk-59dx6qaf.js +4 -0
  22. package/dist/src/chunk-5sdf9y92.js +4 -0
  23. package/dist/src/chunk-5wk1t46v.js +5 -0
  24. package/dist/src/chunk-661c50hh.js +17 -0
  25. package/dist/src/chunk-68n6bjjd.js +21 -0
  26. package/dist/src/{chunk-zg67wjkh.js → chunk-69pmjdf2.js} +3 -3
  27. package/dist/src/chunk-6hrj3jt6.js +145 -0
  28. package/dist/src/{chunk-b4cxdzwy.js → chunk-6myr26wx.js} +8 -8
  29. package/dist/src/chunk-6n96k09n.js +4 -0
  30. package/dist/src/chunk-6vwrbkre.js +4 -0
  31. package/dist/src/chunk-6wk0yrab.js +4 -0
  32. package/dist/src/chunk-6yhm9een.js +4 -0
  33. package/dist/src/chunk-7k7gjg2t.js +7 -0
  34. package/dist/src/chunk-7n5fz68h.js +4 -0
  35. package/dist/src/chunk-8cvnpnbp.js +4 -0
  36. package/dist/src/chunk-8kzv7rk7.js +4 -0
  37. package/dist/src/chunk-8nj68t1v.js +167 -0
  38. package/dist/src/{chunk-r20pe1nv.js → chunk-96r3bpg7.js} +3 -3
  39. package/dist/src/chunk-97x887te.js +4 -0
  40. package/dist/src/{chunk-sz1a7p43.js → chunk-99a6tbvd.js} +1 -1
  41. package/dist/src/chunk-9p5d2994.js +5 -0
  42. package/dist/src/{chunk-w7zsh13a.js → chunk-9q265er0.js} +4 -4
  43. package/dist/src/chunk-9xgnrv5w.js +5 -0
  44. package/dist/src/chunk-9xgsmshb.js +5 -0
  45. package/dist/src/chunk-a02d1wgv.js +4 -0
  46. package/dist/src/{chunk-km0dy5vc.js → chunk-a9ps00a1.js} +10 -10
  47. package/dist/src/chunk-aewdveet.js +5 -0
  48. package/dist/src/chunk-b3tdtq7r.js +9 -0
  49. package/dist/src/chunk-bn7jx7a2.js +4 -0
  50. package/dist/src/chunk-bnyw27ja.js +4 -0
  51. package/dist/src/{chunk-s1zq65ny.js → chunk-bpwsg76p.js} +2 -2
  52. package/dist/src/chunk-bvranw3g.js +4 -0
  53. package/dist/src/chunk-c25a84zb.js +4 -0
  54. package/dist/src/chunk-c27yv1dx.js +5 -0
  55. package/dist/src/chunk-c3ewxm4x.js +5 -0
  56. package/dist/src/chunk-cb1ga9rd.js +7 -0
  57. package/dist/src/chunk-cn7fwy7k.js +4 -0
  58. package/dist/src/chunk-cnvy4a64.js +4 -0
  59. package/dist/src/chunk-cqhw4yr6.js +5 -0
  60. package/dist/src/{chunk-v90es00d.js → chunk-ctmfshjc.js} +2 -2
  61. package/dist/src/chunk-ctwmhz13.js +4 -0
  62. package/dist/src/{chunk-qv2918jt.js → chunk-d3jx9bz5.js} +2 -2
  63. package/dist/src/{chunk-wry6skrm.js → chunk-d6rb08ga.js} +1 -1
  64. package/dist/src/chunk-ddqhj4eg.js +5 -0
  65. package/dist/src/{chunk-d57432wq.js → chunk-ddrhs1c3.js} +2 -2
  66. package/dist/src/chunk-dnjnh9p6.js +4 -0
  67. package/dist/src/{chunk-ajsrz473.js → chunk-dw5rwgya.js} +3 -3
  68. package/dist/src/chunk-e0870khr.js +5 -0
  69. package/dist/src/chunk-ea3k10kj.js +4 -0
  70. package/dist/src/chunk-emv82m1w.js +7 -0
  71. package/dist/src/chunk-f3m6pdnx.js +4 -0
  72. package/dist/src/chunk-f84z32cb.js +4 -0
  73. package/dist/src/chunk-fpczgf0z.js +4 -0
  74. package/dist/src/chunk-g2js4c2v.js +971 -0
  75. package/dist/src/chunk-g3af2qbk.js +5 -0
  76. package/dist/src/chunk-gadtna7s.js +11 -0
  77. package/dist/src/{chunk-c9nk1r78.js → chunk-gcyx407v.js} +3 -3
  78. package/dist/src/{chunk-jdqvcq0a.js → chunk-gfpntwc1.js} +3 -3
  79. package/dist/src/chunk-gmnm5e3e.js +4 -0
  80. package/dist/src/chunk-gp6vb5gf.js +4 -0
  81. package/dist/src/chunk-gppgy7pa.js +4 -0
  82. package/dist/src/chunk-hegfz0ae.js +5 -0
  83. package/dist/src/chunk-hpzxdp1k.js +17 -0
  84. package/dist/src/{chunk-2v7tw1nj.js → chunk-j69g8b50.js} +3 -3
  85. package/dist/src/chunk-jvstjnqm.js +19 -0
  86. package/dist/src/chunk-jzqrv78s.js +4 -0
  87. package/dist/src/chunk-k2948b8d.js +4 -0
  88. package/dist/src/chunk-k4ftd40d.js +4 -0
  89. package/dist/src/chunk-kd9vfaxh.js +5 -0
  90. package/dist/src/{chunk-34zxqcmq.js → chunk-kdczmgwk.js} +3 -3
  91. package/dist/src/chunk-ke3wn14v.js +4 -0
  92. package/dist/src/chunk-kh5n7m6w.js +4 -0
  93. package/dist/src/{chunk-0dfnyfkh.js → chunk-khejfph4.js} +3 -3
  94. package/dist/src/chunk-kny2xemh.js +4 -0
  95. package/dist/src/chunk-knyzw9md.js +4 -0
  96. package/dist/src/chunk-mbzpt2hp.js +4 -0
  97. package/dist/src/chunk-mm8rcxad.js +4 -0
  98. package/dist/src/chunk-nc4516tx.js +4 -0
  99. package/dist/src/{chunk-stfzjr9y.js → chunk-ntfrqrqn.js} +5 -5
  100. package/dist/src/chunk-nz5h2j52.js +4 -0
  101. package/dist/src/chunk-p22s97qy.js +4 -0
  102. package/dist/src/chunk-p9kt1sgr.js +6 -0
  103. package/dist/src/{chunk-9y5bcy28.js → chunk-pf282r5g.js} +4 -4
  104. package/dist/src/chunk-pnd4mrxy.js +4 -0
  105. package/dist/src/chunk-pqqteyj6.js +4 -0
  106. package/dist/src/chunk-qj1tbnv2.js +8 -0
  107. package/dist/src/chunk-qnh9egwr.js +4 -0
  108. package/dist/src/chunk-qy3khhf8.js +8 -0
  109. package/dist/src/chunk-r0vp315h.js +11 -0
  110. package/dist/src/chunk-r4j43b9s.js +237 -0
  111. package/dist/src/{chunk-4pfftt07.js → chunk-r54cxxze.js} +3 -3
  112. package/dist/src/chunk-r6pvhj33.js +325 -0
  113. package/dist/src/chunk-rb7aa5gr.js +54 -0
  114. package/dist/src/chunk-rdj50kb4.js +4 -0
  115. package/dist/src/chunk-rnd4vcas.js +4 -0
  116. package/dist/src/chunk-s3y3zfcx.js +14 -0
  117. package/dist/src/chunk-s4g43k75.js +5 -0
  118. package/dist/src/chunk-sfqe223f.js +311 -0
  119. package/dist/src/chunk-sqdrxjw5.js +7 -0
  120. package/dist/src/{chunk-0w1spptt.js → chunk-t54k47em.js} +4 -4
  121. package/dist/src/chunk-tek4pnvv.js +26 -0
  122. package/dist/src/chunk-tn74y7af.js +4 -0
  123. package/dist/src/chunk-tvq0nzam.js +5 -0
  124. package/dist/src/chunk-tx4f0h9c.js +6 -0
  125. package/dist/src/chunk-vdqag3fj.js +5 -0
  126. package/dist/src/chunk-vz5zzs57.js +4 -0
  127. package/dist/src/chunk-w4s2vfpj.js +4 -0
  128. package/dist/src/chunk-w5yypt53.js +42 -0
  129. package/dist/src/{chunk-r0f1q783.js → chunk-w68v64vh.js} +3 -3
  130. package/dist/src/chunk-whwj0pdk.js +5 -0
  131. package/dist/src/chunk-wnmqt1dc.js +4 -0
  132. package/dist/src/{chunk-8en08r7q.js → chunk-wpe46vsa.js} +3 -3
  133. package/dist/src/chunk-wxdjeb4k.js +27 -0
  134. package/dist/src/chunk-xcqzwf9j.js +247 -0
  135. package/dist/src/chunk-xezekwwn.js +5 -0
  136. package/dist/src/chunk-xf19m15s.js +4 -0
  137. package/dist/src/chunk-xghbxha4.js +4 -0
  138. package/dist/src/{chunk-jhnbfj19.js → chunk-xn9m3xc2.js} +5 -5
  139. package/dist/src/{chunk-a4k9rt7z.js → chunk-yqfz4vts.js} +3 -3
  140. package/dist/src/chunk-z8tvs8nk.js +5 -0
  141. package/dist/src/chunk-zm2rehqb.js +5 -0
  142. package/dist/src/chunk-zs6dqm35.js +4 -0
  143. package/dist/src/daemon/processEntry.js +2 -2
  144. package/dist/src/index.js +4 -4
  145. package/dist/src/runtime/bunRuntimeGuard.js +2 -2
  146. package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -2
  147. package/ios/CameraPosterInjection/Injection/CameraPosterInjection.m +466 -0
  148. package/package.json +4 -3
  149. package/schemas/test-plan.schema.json +370 -52
  150. package/dist/src/chunk-09442h7v.js +0 -4
  151. package/dist/src/chunk-0e4gm1kj.js +0 -5
  152. package/dist/src/chunk-0eb8576f.js +0 -4
  153. package/dist/src/chunk-0rjm4nx7.js +0 -5
  154. package/dist/src/chunk-1zmh2eak.js +0 -4
  155. package/dist/src/chunk-28k63ha3.js +0 -5
  156. package/dist/src/chunk-2d4wmp8b.js +0 -4
  157. package/dist/src/chunk-32jpxz2y.js +0 -323
  158. package/dist/src/chunk-3jmvqygr.js +0 -238
  159. package/dist/src/chunk-3swvfhqt.js +0 -5
  160. package/dist/src/chunk-44bt78m9.js +0 -5
  161. package/dist/src/chunk-488vt2bp.js +0 -4
  162. package/dist/src/chunk-4fgdhcwx.js +0 -5
  163. package/dist/src/chunk-4jp2se4w.js +0 -4
  164. package/dist/src/chunk-4vhr9e4t.js +0 -4
  165. package/dist/src/chunk-4xd6zs3y.js +0 -15
  166. package/dist/src/chunk-51567pg8.js +0 -4
  167. package/dist/src/chunk-5agqsfev.js +0 -4
  168. package/dist/src/chunk-5d706gmr.js +0 -4
  169. package/dist/src/chunk-5kd4rqk7.js +0 -5
  170. package/dist/src/chunk-61t538bm.js +0 -4
  171. package/dist/src/chunk-6d3mmqxt.js +0 -54
  172. package/dist/src/chunk-6hyt398x.js +0 -5
  173. package/dist/src/chunk-6mnr8kpm.js +0 -4
  174. package/dist/src/chunk-79q5xsdc.js +0 -42
  175. package/dist/src/chunk-7bdgand3.js +0 -4
  176. package/dist/src/chunk-84cp9dw5.js +0 -4
  177. package/dist/src/chunk-86f2h5ww.js +0 -5
  178. package/dist/src/chunk-8cghfzb2.js +0 -19
  179. package/dist/src/chunk-9tf2p9y9.js +0 -5
  180. package/dist/src/chunk-a2sc4jm0.js +0 -5
  181. package/dist/src/chunk-aa5ng3d1.js +0 -4
  182. package/dist/src/chunk-b3h0a6ca.js +0 -4
  183. package/dist/src/chunk-b6a737qt.js +0 -4
  184. package/dist/src/chunk-bn64x5z5.js +0 -5
  185. package/dist/src/chunk-bvh649za.js +0 -12
  186. package/dist/src/chunk-c9tyfg4j.js +0 -26
  187. package/dist/src/chunk-cfsdfqnm.js +0 -4
  188. package/dist/src/chunk-cxyf04jc.js +0 -7
  189. package/dist/src/chunk-da08tx5v.js +0 -4
  190. package/dist/src/chunk-f2tc08m2.js +0 -4
  191. package/dist/src/chunk-f8tnk179.js +0 -5
  192. package/dist/src/chunk-f9s1kkhx.js +0 -5
  193. package/dist/src/chunk-fbp8a4rx.js +0 -4
  194. package/dist/src/chunk-fd2z0sze.js +0 -4
  195. package/dist/src/chunk-fk927f4q.js +0 -54
  196. package/dist/src/chunk-fxmr3a0f.js +0 -4
  197. package/dist/src/chunk-gaqwhd44.js +0 -4
  198. package/dist/src/chunk-ggtd5x5a.js +0 -5
  199. package/dist/src/chunk-gndcfrm7.js +0 -4
  200. package/dist/src/chunk-h3n4adc6.js +0 -310
  201. package/dist/src/chunk-h5pjbb83.js +0 -4
  202. package/dist/src/chunk-hgnnh302.js +0 -4
  203. package/dist/src/chunk-hmke8nhx.js +0 -5
  204. package/dist/src/chunk-j2bx12hn.js +0 -4
  205. package/dist/src/chunk-j70y1a2g.js +0 -4
  206. package/dist/src/chunk-js1jpyxp.js +0 -6
  207. package/dist/src/chunk-kbjq0qvb.js +0 -4
  208. package/dist/src/chunk-kfwx57xd.js +0 -4
  209. package/dist/src/chunk-kzwctna2.js +0 -4
  210. package/dist/src/chunk-m9ehyehy.js +0 -4
  211. package/dist/src/chunk-mct91p1f.js +0 -4
  212. package/dist/src/chunk-mf9spd4g.js +0 -5
  213. package/dist/src/chunk-mgrcansb.js +0 -4
  214. package/dist/src/chunk-mqc1d0eb.js +0 -6
  215. package/dist/src/chunk-n1zmpk0z.js +0 -4
  216. package/dist/src/chunk-ncyjf63g.js +0 -4
  217. package/dist/src/chunk-nr64d21q.js +0 -973
  218. package/dist/src/chunk-nwm2pq5v.js +0 -168
  219. package/dist/src/chunk-pm06b05d.js +0 -9
  220. package/dist/src/chunk-q50s00ry.js +0 -4
  221. package/dist/src/chunk-qwye1958.js +0 -14
  222. package/dist/src/chunk-r8z9pfve.js +0 -5
  223. package/dist/src/chunk-rdpgkjf6.js +0 -4
  224. package/dist/src/chunk-rkr0dks9.js +0 -5
  225. package/dist/src/chunk-rn84t3sf.js +0 -11
  226. package/dist/src/chunk-s123kn7n.js +0 -4
  227. package/dist/src/chunk-s73qn3fx.js +0 -4
  228. package/dist/src/chunk-sjn0nj4p.js +0 -5
  229. package/dist/src/chunk-sns0c35v.js +0 -7
  230. package/dist/src/chunk-t4dr5c8v.js +0 -8
  231. package/dist/src/chunk-tc8k9c1j.js +0 -4
  232. package/dist/src/chunk-teznhase.js +0 -4
  233. package/dist/src/chunk-ty9xgmz4.js +0 -4
  234. package/dist/src/chunk-tyazf3sk.js +0 -145
  235. package/dist/src/chunk-v6npjrjm.js +0 -5
  236. package/dist/src/chunk-vbvtzkwz.js +0 -5
  237. package/dist/src/chunk-vefd8qee.js +0 -8
  238. package/dist/src/chunk-vs9r72ta.js +0 -17
  239. package/dist/src/chunk-w2mwa0jk.js +0 -4
  240. package/dist/src/chunk-w88k0bgr.js +0 -4
  241. package/dist/src/chunk-wzdt0enk.js +0 -4
  242. package/dist/src/chunk-xhhv854c.js +0 -4
  243. package/dist/src/chunk-y58270hd.js +0 -4
  244. package/dist/src/chunk-yk0hmbex.js +0 -4
  245. package/dist/src/chunk-ympy4fdz.js +0 -28
  246. package/dist/src/chunk-yw436axy.js +0 -4
  247. package/dist/src/chunk-z04jrpjy.js +0 -5
  248. package/dist/src/chunk-z2xznczw.js +0 -4
  249. package/dist/src/chunk-z4xnrgps.js +0 -4
  250. package/dist/src/chunk-z7csyszv.js +0 -4
  251. package/dist/src/chunk-z8t0v07j.js +0 -11
  252. package/dist/src/chunk-z916af47.js +0 -228
  253. package/dist/src/chunk-zcr8he8q.js +0 -5
  254. package/dist/src/chunk-zd9vmkzn.js +0 -9
  255. package/dist/src/chunk-zj939v0h.js +0 -5
  256. package/dist/src/chunk-zkdjwtc1.js +0 -4
  257. package/dist/src/chunk-zkv5kzt6.js +0 -4
@@ -1,4 +0,0 @@
1
- // @bun
2
- import{ht,Zi,pe,B,Y,je,ti,ce,o,R,st,sp,BL,tg,M,Vt,Qt,_t,to,mt,G,Ui,er,we,Kw,Qc,gi,Lv,GT,dl,mr,sR,_e,Lm,ir,Na,qm,SD,LB,La,Rn,tr,PD,D3,Wm,Sk,wk,AD,Ere,Rk,kD,RR,Mt,da,od,ar,qB,VB,_,k,Bs}from"./chunk-h3n4adc6.js";import{Nr,i,te,gt,Q,Ft,e}from"./chunk-z8t0v07j.js";import{sr,Fi,pn,om,sm,mn,vo,SV,Qy,oC,UF,eT}from"./chunk-6d3mmqxt.js";import{ac,Jy,eV,Qx,De,Ht,wt}from"./chunk-4fgdhcwx.js";import{Mc,Wl,S7,fA,G6,XI,v0,Kp,Gp,Ou,zl}from"./chunk-4xd6zs3y.js";import{es,ba,gr,Ni,ts}from"./chunk-bn64x5z5.js";import{Lo,dc,Ra,Ih,rs,Zs,_h,CQ,Bo}from"./chunk-sns0c35v.js";import{r,t,yt}from"./chunk-9rkfyt6q.js";function me(n,s,a){if(!s)return[];let c=[...n.extractRootNodes(s),...n.extractWindowRootNodes(s,"topmost-first")],l=[];for(let u of c)n.traverseNode(u,(d)=>{if(!a(n.extractNodeProperties(d)))return;let p=n.parseNodeBounds(d);if(p)l.push(p)});return l}var dt=(n)=>n.scrollable==="true"||n.scrollable===!0;class WI{parser;constructor(n=new G){this.parser=n}findScrollableElements(n){return me(this.parser,n,dt)}}class V6{parser;constructor(n=new G){this.parser=n}findClickableElements(n){return me(this.parser,n,sp)}}var zI=Object.freeze({partialMatch:!0,caseSensitive:!1}),m7=Object.freeze({partialMatch:!1}),Ny=Object.freeze({intentAction:"inspect"}),f7=Object.freeze({intentAction:"focus-input",allowHintFallback:!0}),h7=Object.freeze({intentAction:"focus-input"}),g7=Object.freeze({intentAction:"inspect",selectionIntent:"toggle"}),y7=Object.freeze({intentAction:"inspect",selectionIntent:"focus-input"}),Ie=Object.freeze({intentAction:"drag"});function uA(n){return{partialMatch:n,caseSensitive:!1}}var j=(n)=>mn(n)??"",jI=async(n,s)=>{let{observe:a,timer:c,maxWaitMs:l,pollIntervalMs:u,logPrefix:d,signal:p}=s;if(!n.viewHierarchy)return n;let m=c.now(),h=j(n.viewHierarchy),f=n;while(c.now()-m<l){p?.throwIfAborted();let S=await a();if(!S.viewHierarchy)break;let y=j(S.viewHierarchy);if(y===h)return e.info(`${d} Scroll settled after ${c.now()-m}ms idle check`),S;e.info(`${d} Scroll still settling (elapsed=${c.now()-m}ms), retrying in ${u}ms`),h=y,f=S,p?.throwIfAborted(),await c.sleep(u)}return e.info(`${d} Scroll idle check reached ${l}ms limit, proceeding`),f};var pt="[REDACTED]";function Ae(n){return Mt(n).trim().toLowerCase()}function ft(n,s){let a=Ae(s),c=new Map;for(let{id:u}of n)c.set(u,(c.get(u)??0)+1);let l=n.filter((u)=>u.id!==""&&c.get(u.id)===1&&u.enabled&&u.visible&&[u.label,u.value===pt?void 0:u.value].some((d)=>d!==void 0&&Ae(d)===a));return l.length===1?l[0]:null}function St(n){let s=n.enabled??(()=>M.isIosSdkObservationBridgeEnabled());return{async scroll(a,c,l){if(!s()||a.text===void 0)return null;if(UF(c.viewHierarchy).length!==1)return null;let u=await n.reader.snapshots(l),d=u.length===1?u[0]:void 0,p=d?.snapshot,m=p?ft(p.elements,a.text):null;if(!d||!p||!m)return null;let h={snapshotId:p.snapshotId,elementId:m.id};return fA(n.client(),{webViewId:d.webViewId,...h},{scrollIntoView:h},{verb:"scroll into view",signal:l})}}}function bt(n){return St({reader:eT(n),client:()=>_.getExistingInstance(n.deviceId)})}function Ce(n,s){return n.platform==="ios"?s??bt(n):void 0}class he{device;selector;constructor(n,s){this.device=n;this.selector=s}buildScrollableCandidates(n){let s=[],a=new Set;for(let c of n){let l={elementId:c["resource-id"],text:c.text,contentDesc:c["content-desc"],className:c.class};if(!l.elementId&&!l.text&&!l.contentDesc&&!l.className)continue;let u=`${l.elementId??""}|${l.text??""}|${l.contentDesc??""}|${l.className??""}`;if(a.has(u))continue;a.add(u),s.push(l)}return s}resolveAutoTargetDecision({scrollables:n,candidates:s,observeResult:a,direction:c,includeSystemInsets:l}){if(n.length===0)return e.info("[SwipeOn] Mode: screen swipe (no scrollables found)"),{};let u=a?this.selector().getScreenBounds(a,{platform:Q(this.device.platform,"swipeOn"),includeSystemInsets:l}):null,d=this.selector().selectAutoTargetScrollable(n,u,c);if(!d)return e.info(`[SwipeOn] Mode: screen swipe (scrollables found but none matched direction=${c})`),{warning:"Scrollable containers found but none matched the swipe direction; swiping the screen. Set autoTarget: false to force screen swipes.",scrollableCandidates:s};let p=BL(d);if(!p&&this.device.platform==="android")return e.info("[SwipeOn] Mode: element swipe (auto-target element has no usable identifier)"),{element:d,warning:"Auto-targeted scrollable container lacks a usable identifier; swiping within its bounds without container metadata.",scrollableCandidates:s};if(!p)return e.info("[SwipeOn] Mode: screen swipe (auto-target element has no usable identifier)"),{scrollFrame:l?void 0:d.bounds,warning:"Auto-targeted scrollable container lacks a usable identifier; swiping the screen. Provide container.elementId or container.text to target it explicitly.",scrollableCandidates:s};return e.info(`[SwipeOn] Mode: auto-target element swipe (container=${JSON.stringify(p)})`),{container:p,warning:`Auto-targeted scrollable container (${this.selector().describeContainer(p)}). Set autoTarget: false to force full-screen swipes.`,scrollableCandidates:s}}withAutoTargetDecision({result:n,decision:s}){if(!s.warning)return n;return{...n,warning:this.selector().mergeWarnings(n.warning,s.warning),scrollableCandidates:s.scrollableCandidates}}}import{AsyncLocalStorage as vt}from"async_hooks";var Te=new vt;function J(n){return Te.getStore()?n():Te.run(!0,()=>om(n))}function fe(n){let s=Zi()?.getDeadlineMs?.();return Math.max(0,Math.min(Fi,s===void 0?Fi:s-n.now()))}async function T(n,s,a,c){if(o(c),!n.viewHierarchy||n.viewHierarchy.hierarchy.error||sm(n.viewHierarchy))return n;let l=fe(a);if(l>0)try{let u=await s(l);return o(c),tg(u)?{...u,viewHierarchy:void 0}:u}catch(u){if(o(c),u instanceof _e||u instanceof Error&&u.name==="AbortError")throw u;e.warn(`[SwipeOn] Fresh hierarchy unavailable: ${r(u)}`,u)}return{...n,viewHierarchy:void 0}}var KI=600,m0=3000,GI=300,f0=2000,vS=100,pA=3000,Ot=100,Et=Na,xt=0.5;function ke(n,s,a){let c=n+s+a;return Math.max(Ui,c+Et+c*xt)}function Z(n){return{success:!1,error:`Drag outcome is indeterminate: the request was dispatched but no result was confirmed (${n}). The gesture may have run. Do not retry automatically. Verify state first with observe.`}}function Pe(n){if(n===void 0||n.trim()!==n)return!0;return!(["Gesture display routing requires Android 11 (API 30)","Stale frame context for input/drag; observe a fresh frame before retrying","Stale frame context; observe a fresh frame before retrying","Failed to dispatch gesture"].includes(n)||/^displayId must be non-negative: -[1-9]\d*$/.test(n)||/^Non-finite gesture coordinate: (x1|y1|x2|y2)=(NaN|-?Infinity)\. Coordinates must be finite \(not NaN or Infinity\)\.$/.test(n))}var Dt=5000,Rt=15000;class W6 extends De{lastRenderedObservation;selector;hierarchyCapture;geometry;accessibilityService;visionConfig;screenshotCapturer;visionAnalyzer;constructor(n,s=null,a=i,c={}){super(n,{adb:s,timer:a,displayFence:c});this.lastRenderedObservation=c.lastRenderedObservation,this.selector=c.selector??new gr(void 0,void 0,{platform:Q(n.platform,"dragAndDrop"),iosMultiPanel:n.platform==="ios"&&(n.displays?.panels.length??0)>1}),this.hierarchyCapture=c.hierarchyCapture??pn(n,{timer:a,adbFactory:this.adbFactory}),this.geometry=new tr,this.accessibilityService=Bs(n,this.adbFactory),this.visionConfig=c.visionConfig??Kp,this.screenshotCapturer=c.screenshotCapturer??new Ou(n,this.adbFactory),this.visionAnalyzer=c.visionAnalyzer}async executeOnAndroidDisplay(n,s,a){let c=s.observation.viewHierarchy;if(!c)throw new t("Selected display has no view hierarchy");let{sourcePoint:l,targetPoint:u}=this.resolveTargetPoints(c,{...n,observation:s.observation}),d=this.getDragDurationMs(n),p=await Ra(this.accessibilityService,s.displayId);if(s.assertCurrent(),o(a),p){let m=this.getPressDurationMs(n),h=this.getHoldDurationMs(n),f=!1,S;try{S=await R(Promise.resolve().then(()=>(o(a),this.accessibilityService.requestDrag({x1:l.x,y1:l.y,x2:u.x,y2:u.y,pressDurationMs:m,dragDurationMs:d,holdDurationMs:h,timeoutMs:ke(m,d,h),signal:a,displayId:s.displayId===0?void 0:s.displayId,beforeSend:s.assertCurrent,onDispatch:()=>{f=!0}}))),a),o(a)}catch(y){if(o(a),!f)throw y;throw e.warn(`Drag outcome indeterminate: ${r(y)}`,y),new t(Z(r(y)).error)}if(!S.success)throw new t(f&&Pe(S.error)?Z(S.error??"unknown error").error:S.error??"Android drag failed")}else{if(n.pressDurationMs!==void 0||n.holdDurationMs!==void 0)throw new t(`pressDurationMs and holdDurationMs require the CtrlProxy gesture route on display ${s.displayId} (capability gesture_display_id_v1); adb draganddrop cannot express press or hold durations`);await dc(this.adb,`draganddrop ${l.x} ${l.y} ${u.x} ${u.y} ${Lo(d)}`,s.displayId,{signal:a,assertCurrent:s.assertCurrent})}return{success:!0,duration:d,distance:Math.hypot(u.x-l.x,u.y-l.y)}}async executeExplicitDisplay(n,s){if(n.display!==void 0)try{let a=await Ni(this.device,n.display,this.observeScreen,{adb:this.adb,lastRenderedObservation:this.lastRenderedObservation,signal:s,transitions:this.displayTransitionReader});if(this.device.platform==="android")return await this.observedInteraction(()=>this.executeOnAndroidDisplay(n,a,s),{...Ht.rawCoordinateGesture,display:a.observation.display.key,previousObservation:a.observation,signal:s})}catch(a){if(o(s),a instanceof Error&&a.name==="AbortError")throw a;return e.warn(`dragAndDrop display routing failed: ${r(a)}`,a),ir(this.failureResult(a,r(a)),a)}return}async execute(n,s,a){let{progress:c,signal:l}=Bo(s,a),u=this.device.platform==="ios"?pe(l):l,d=await this.executeExplicitDisplay(n,u);if(d)return d;let p=Y();if(p.serial("dragAndDrop"),this.device.platform!=="android"&&this.device.platform!=="ios")return p.end(),{success:!1,duration:0,distance:0,error:`dragAndDrop is not supported on ${this.device.platform}`};if(this.device.platform==="android"){let h=ce.getInstance(this.device,{create:()=>this.adb});if(!await p.track("a11yAvailable",()=>h.isAvailable()))return p.end(),{success:!1,duration:0,distance:0,error:"dragAndDrop requires the Android accessibility service to be installed and enabled."}}let m=this.validateOptions(n);if(m)return p.end(),{success:!1,duration:0,distance:0,error:m};return this.executeObservedDrag(n,p,c,u)}async executeObservedDrag(n,s,a,c){try{let l=this.getPressDurationMs(n),u=this.getDragDurationMs(n),d=this.getHoldDurationMs(n),p,m=await this.observedInteraction(async(h,f)=>{o(c);let S=await this.resolveViewHierarchy(c);if(!S)return{success:!1,error:"Unable to get view hierarchy, cannot drag and drop"};let{sourcePoint:y,targetPoint:b}=this.resolveTargetPoints(S,{...n,observation:h});f?.assertCurrent();let w=await this.dispatchDrag({startX:y.x,startY:y.y,endX:b.x,endY:b.y,pressDurationMs:l,dragDurationMs:u,holdDurationMs:d,signal:c});if(this.device.platform==="ios"&&w.success)p=this.timer.now(),_.getExistingInstance(this.device.deviceId)?.invalidateCache();await this.timer.sleep(Ot);let v=Math.hypot(b.x-y.x,b.y-y.y);return{success:w.success,duration:u,distance:v,a11yTotalTimeMs:w.a11yTotalTimeMs,a11yGestureTimeMs:w.a11yGestureTimeMs,error:w.error}},{...Ht.selectorResolvedGesture,display:n.display,progress:a,perf:s,signal:c,observationTimestampProvider:()=>p,predictionContext:{toolName:"dragAndDrop",toolArgs:{source:n.source,target:n.target,pressDurationMs:l,dragDurationMs:u,holdDurationMs:d,platform:this.device.platform}}});return s.end(),o(c),{...m,duration:m.duration??this.getDragDurationMs(n),distance:m.distance??0}}catch(l){if(s.end(),e.warn(`Drag and drop failed: ${r(l)}`,l),o(c),l instanceof _e||l instanceof mr)return ir({success:!1,duration:0,distance:0},l);let u=r(l),d=`Failed to perform drag and drop: ${u}`;if(this.visionConfig.enabled){let p=this.isSourceResolutionError(u),m=p?n.source:n.target;if(m){let h={text:m.text,resourceId:m.elementId,description:p?"Source element for drag":"Target element for drop"},S=(await this.observeScreen.getMostRecentCachedObserveResult())?.viewHierarchy??null;d=await Gp(this.screenshotCapturer,S,h,{visionConfig:this.visionConfig,baseError:d,signal:c,visionAnalyzer:this.visionAnalyzer})}}return o(c),this.failureResult(l,d)}}failureResult(n,s){return{success:!1,duration:0,distance:0,error:s,...n instanceof t&&n.containerFailure?{containerFailure:n.containerFailure}:{}}}isSourceResolutionError(n){return n.startsWith("dragAndDrop source")||!n.startsWith("dragAndDrop target")&&n.toLowerCase().includes("source")}validateOptions(n){if(!n?.source||!n?.target)return"dragAndDrop requires source and target";if([n.source.text,n.source.elementId].filter(Boolean).length!==1)return"dragAndDrop source must specify exactly one of text or elementId";if([n.target.text,n.target.elementId].filter(Boolean).length!==1)return"dragAndDrop target must specify exactly one of text or elementId";if(!this.isDurationInRange(n.pressDurationMs,KI,m0))return`dragAndDrop pressDurationMs must be between ${KI}ms and ${m0}ms`;if(!this.isDurationInRange(n.dragDurationMs,GI,f0))return`dragAndDrop dragDurationMs must be between ${GI}ms and ${f0}ms`;if(!this.isDurationInRange(n.holdDurationMs,vS,pA))return`dragAndDrop holdDurationMs must be between ${vS}ms and ${pA}ms`;return null}resolveTargetPoints(n,s){let a={observationScreenSize:s.observation.screenSize,display:s.observation.viewHierarchy},c=gi(n,s.layer),l=this.resolveTarget(c,{...s.source,screenSizeOptions:a},"source"),u=this.resolveTarget(c,{...s.target,screenSizeOptions:a},"target"),d=this.prototypeSafePoint(n,s.layer,l,"source"),p=this.prototypeSafePoint(n,s.layer,u,"target");return Lv(n,s.layer,d,"drag from"),Lv(n,s.layer,p,"drop"),{sourcePoint:d,targetPoint:p}}prototypeSafePoint(n,s,a,c){let l=this.geometry.getElementCenter(a);if(s!==void 0||this.device.platform==="ios")return l;let u=LB(n,a,a.bounds,l);if(!u)throw new t(`dragAndDrop ${c} is covered by an AutoMobile prototype window; hide or move the prototype, then retry.`);return u}get testHooks(){return{resolveTarget:this.resolveTarget.bind(this)}}resolveTarget(n,s,a){if([s.elementId,s.text].filter(Boolean).length!==1)throw new t(`dragAndDrop ${a} must specify exactly one of text or elementId`);let l;try{if(l=this.selectTargetElement(n,s),!l&&s.container)throw new t("Target not found within container")}catch(u){let d=es(s,"any-container")?`dragAndDrop ${a}: `:"";throw new t(`${d}${r(u)}`,{cause:u})}if(!l){let u=s.elementId?"elementId":"text";throw new t(`dragAndDrop ${a} not found with ${u} '${s.elementId??s.text}'`)}return l}selectTargetElement(n,s){let a={...Ie,screenSizeOptions:s.screenSizeOptions,container:s.container,strategy:s.selectionStrategy};if(s.container&&!es(s)&&this.selector.resolveContainer&&!this.selector.resolveContainer(n,s.container,s.selectionStrategy))throw new t(`Container level 1 not found: ${s.container.elementId??s.container.text}`,{containerFailure:{level:1,reason:"not-found",selector:s.container}});if(s.elementId)return this.selector.select(n,{elementId:s.elementId},a).element;let c=this.selector.select(n,{text:s.text??""},a);return c.matchedElement??c.element}async resolveViewHierarchy(n){let s=await this.hierarchyCapture.capture({freshness:"fresh",searchRaw:this.device.platform==="android"&&M.isRawElementSearchEnabled(),signal:n,timeoutMs:this.device.platform==="ios"?Rt:Dt});if(this.device.platform==="ios")o(n);return s.hierarchy}getPressDurationMs(n){if(typeof n.pressDurationMs==="number")return n.pressDurationMs;return KI}getDragDurationMs(n){if(typeof n.dragDurationMs==="number")return n.dragDurationMs;return GI}getHoldDurationMs(n){if(typeof n.holdDurationMs==="number")return n.holdDurationMs;return vS}isDurationInRange(n,s,a){if(typeof n!=="number")return!0;return n>=s&&n<=a}dispatchDrag=(n)=>this.executeDrag(n);setDragDispatchForTesting(n){this.dispatchDrag=n}async executeDrag({startX:n,startY:s,endX:a,endY:c,pressDurationMs:l,dragDurationMs:u,holdDurationMs:d,signal:p}){o(p);let m=ke(l,u,d),h=!1,f=()=>{h=!0},S;try{let y=Promise.resolve().then(()=>(o(p),this.device.platform==="ios"?_.getInstance(this.device).requestDrag({x1:n,y1:s,x2:a,y2:c,pressDurationMs:l,dragDurationMs:u,holdDurationMs:d,timeoutMs:m,signal:p,onDispatch:f}):this.accessibilityService.requestDrag({x1:n,y1:s,x2:a,y2:c,pressDurationMs:l,dragDurationMs:u,holdDurationMs:d,timeoutMs:m,signal:p,onDispatch:f})));if(S=await R(y,p),o(p),!S.success&&h&&(this.device.platform==="ios"||Pe(S.error)))return Z(S.error??"unknown error")}catch(y){if(o(p),!h)throw y;return e.warn(`Drag outcome indeterminate: ${r(y)}`,y),Z(r(y))}if(S.success)return{success:!0,a11yTotalTimeMs:S.totalTimeMs,a11yGestureTimeMs:S.gestureTimeMs};return{success:!1,error:S.error??"Drag failed via CtrlProxy"}}}var ee=vS,Me=3,Fe=4,It=new we;function re(n,s){let a=n.endX-n.startX,c=n.endY-n.startY,u=Math.abs(a)>Math.abs(c)?s.right-s.left:s.bottom-s.top,d=Math.hypot(a,c),p=d>0?Math.min(1,Math.floor(u*0.75)/d):1;return{...n,endX:Math.round(n.startX+a*p),endY:Math.round(n.startY+c*p)}}function YI(n){return{up:"down",down:"up",left:"right",right:"left"}[n]}function ie(n,s){if(!n.viewHierarchy)return new Map;let a=It.project(n.viewHierarchy),c=a.find((d)=>d.element&&d.element["resource-id"]===s["resource-id"]&&Vt(d.element.bounds,s.bounds)),l=new Set,u=new Map;for(let d of a){if(d===c){l.add(d.index);continue}if(!c||d.parentIndex===void 0||!l.has(d.parentIndex))continue;l.add(d.index);let p=At(d,s.bounds);if(!p)continue;u.set(p,(u.get(p)??0)+1)}return u}function At(n,s){if(!n.bounds||n.categories.scrollable||!Qt(n.bounds,s))return;if([n.properties.visible,n.properties["visible-to-user"]].some((u)=>u===!1||u==="false"))return;let{text:a,"content-desc":c,"ios-accessibility-label":l}=n.textSources;if(!a&&!c&&!l&&!n.nativeId)return;return JSON.stringify([n.nativeId,a,c,l])}function Ne(n,s){let a=(c,l)=>[...c].filter(([u,d])=>d===1&&(l.get(u)??0)<=1).length;return a(n,s)>=Fe&&a(s,n)>=Fe}async function Ve(n){let s=n.observation,a=await n.keys(s);if(!Ne(n.previousKeys,a))return s;for(let c=0;;c++){if(o(n.signal),c>0&&await n.hasTarget?.(s))return s;let l=c===0?a:await n.keys(s);if([...l.keys()].some((u)=>n.previousKeys.has(u)))return s;if(!Ne(n.previousKeys,l))return e.debug("[SwipeOn] Recovery overlap evidence is sparse; continuing forward"),s;if(c>=Me||n.timer.now()>=n.deadline)return e.debug(`[SwipeOn] Overlap not restored after ${c} back-scrolls; continuing forward`),s;e.debug(`[SwipeOn] Zero visible child overlap; back-scroll ${c+1}/${Me}`),s=await n.backScroll(s)}}function Ct(n,s){let a=s?.deviceInfo??n.requestDeviceInfo();if(s)s.deviceInfo=a;return a}function Tt(n,s){return n instanceof mr||n instanceof _e&&!s}async function ne(n){let{client:s,x1:a,y1:c,x2:l,y2:u,duration:d,signal:p,displayId:m,beforeSend:h}=n,f=()=>(o(p),h?.(),n.onFallback?.(),n.fallback()),S=(b)=>{n.onIndeterminate?.(b);let w=new mr(b);return ir({success:!1,outcomeIndeterminate:!0,x1:a,y1:c,x2:l,y2:u,duration:d,error:w.message},w)},y=!1;try{o(p);let b=await Ct(s,n.searchDragState);if(o(p),h?.(),!b.success||b.sdkInt===void 0||b.sdkInt<26)return f();let w=await s.requestDrag({x1:a,y1:c,x2:l,y2:u,pressDurationMs:0,dragDurationMs:d,holdDurationMs:ee,timeoutMs:5000,signal:p,displayId:m,beforeSend:h,onDispatch:()=>{y=!0,n.onDispatched?.()}});if(o(p),!w.success){if(!y)return f();return e.warn(`[SwipeOn] Search drag outcome indeterminate: ${w.error}`),S(w.error??"unknown error")}return{...w,x1:a,y1:c,x2:l,y2:u,duration:d}}catch(b){if(Tt(b,y))throw b;if(o(p),y)return e.warn(`[SwipeOn] Search drag outcome indeterminate: ${r(b)}`,b),S(b);return e.debug(`[SwipeOn] Precise search drag unavailable: ${r(b)}`,b),f()}}function Se(n,s){if(!n)return s;return{...n,container:Se(n.container,s)}}function Be(n){if(!A(n.container)&&!W(n.lookFor))return"";let s=[];for(let a=Se(n.lookFor?.container,n.container);a;a=a.container)s.unshift(JSON.stringify(a.elementId??a.text));return s.length?` within container scope ${s.join(" > ")}`:""}function kt(n){if(n.selectionStrategy==="unique")return!0;for(let s=n.container;s;s=s.container)if(s.selectionStrategy==="unique")return!0;return!1}function Pt(n,s){let a=s?n.find((l)=>l.element===s):void 0;if(!a)return{nodes:n,container:void 0};let c="swipe-resolved-scope";while(n.some((l)=>l.nativeId===c||l.nodeKey===c))c+="_";return{nodes:n.map((l)=>l===a?{...l,nodeKey:c}:l),container:{elementId:c}}}function A(n){return es(n,"swipe-container-options")}function W(n){return es(n,"swipe-look-for-options")}function Ge({lookFor:n,container:s,containerElement:a,resolver:c,nodes:l,id:u}){if(!n.text&&!n.elementId)return null;let d=Pt(l,s&&!kt(n)?a:void 0),p={...n,container:Se(n.container,d.container??s)},m=c.resolve({id:u,nodes:d.nodes},p,{action:"inspect"});if(od(m.error)||m.error?.startsWith("Target not found"))return null;if(m.error)throw new t(m.error);return da(m,p)?.element??null}class V extends Error{swipesDispatched;constructor(n,s){super(`${je} after ${n} swipe(s) were dispatched; the screen has scrolled. Observe before retrying.`,s);this.swipesDispatched=n;this.name="SwipeSearchCancelledError"}}var Nt=(n)=>n instanceof Error&&(n.message===je||n.name==="AbortError");function $e(n,s,a){if(!s?.aborted||a.dispatched===0||ht(n)||!Nt(n))return n;return new V(a.dispatched,{cause:n})}var lq=Ui,JI=Ui-Na,h0=pA,g0=JI/1,uq=0,pq=0,bS=1,SS=JI;function U(n){if(n.durationMs!==void 0)return n.durationMs;if(n.duration!==void 0)return n.duration;return n.geometry.getSwipeDurationFromSpeed(n.speed)}function C(n){return n.boomerang?{apexPauseMs:n.apexPause??100,returnSpeed:n.returnSpeed??1}:void 0}function He(n,s){return Math.max(1,Math.round(n/s))}function Le(n,s){let a=He(n,s);if(!Number.isFinite(n)||n<0||!Number.isFinite(s)||s<=pq||s>g0||!Number.isFinite(a)||a>JI)return`returnSpeed must be finite, > 0 and <= ${g0}, and produce a finite return duration <= ${JI}ms; increase returnSpeed or shorten the forward duration`;return null}function P(n){let s=Le(n.forwardDuration,n.returnSpeed);if(s)throw new t(s);return He(n.forwardDuration,n.returnSpeed)}function Bt(n,s){if(!Number.isFinite(n.apexPauseMs)||n.apexPauseMs<uq||n.apexPauseMs>h0)return`apexPause must be finite and >= 0 and <= ${h0}ms; shorten the apex pause`;let a=Le(s,n.returnSpeed);if(a)return a;let c=P({forwardDuration:s,returnSpeed:n.returnSpeed});if(s+n.apexPauseMs+c>lq)return`boomerang duration must be <= ${lq}ms; shorten duration/apexPause or increase returnSpeed`;return null}function y0(n){let{durationMs:s}=n;if(s===void 0)return null;if(n.speed!==void 0)return"durationMs cannot be combined with speed; give one or the other";if(n.lookFor)return"durationMs cannot be used with lookFor; search swipes choose their own pace";if(!Number.isInteger(s)||s<bS||s>SS)return`durationMs must be an integer from ${bS} to ${SS} ms`;return null}function Zf(n,s=U({...n,geometry:new tr})){let a=y0(n);if(a)return a;if(n.boomerang&&n.lookFor)return"boomerang cannot be used with lookFor";if(!n.boomerang&&(n.apexPause!==void 0||n.returnSpeed!==void 0))return"apexPause/returnSpeed require boomerang=true";let c=C(n);return c?Bt(c,s):null}var z6=4,mq=50,j6=0.5,We=0.7,Gt={left:"right",right:"left",top:"down",bottom:"up"};function $t(n){let{edgeInset:s,at:a}=n;if(s!==void 0&&(!Number.isInteger(s)||s<0||s>mq))return`edgeInset must be an integer from 0 to ${mq}`;if(a!==void 0&&!(Number.isFinite(a)&&a>=0&&a<=1))return"at must be a finite number from 0 to 1";return null}function K6(n){if(n.fromEdge===void 0)return n.edgeInset!==void 0||n.at!==void 0?"edgeInset/at require fromEdge":null;if(n.container||n.lookFor||n.autoTarget===!0)return"fromEdge swipes the screen or panel edge; it cannot be combined with container, lookFor, or autoTarget=true";let s=$t(n);if(s)return s;let a=Gt[n.fromEdge];if(n.direction!==a)return`fromEdge "${n.fromEdge}" swipes inward, so the finger direction must be "${a}"`;return null}function oe(n){return K6({...n,direction:Mc(n).direction??n.direction})}function se(n){let{edge:s,bounds:a}=n,c=n.inset??z6,l=n.at??j6,u=a.right-a.left,d=a.bottom-a.top,p=(w,v,O)=>Math.min(O,Math.max(v,w)),m=p(Math.round(a.left+l*u),a.left,a.right-1),h=p(Math.round(a.top+l*d),a.top,a.bottom-1),f=Math.round(u*We),S=Math.round(d*We),y=(w)=>p(w,a.left,a.right-1),b=(w)=>p(w,a.top,a.bottom-1);switch(s){case"left":return{x1:y(a.left+c),y1:h,x2:y(a.left+c+f),y2:h};case"right":return{x1:y(a.right-1-c),y1:h,x2:y(a.right-1-c-f),y2:h};case"top":return{x1:m,y1:b(a.top+c),x2:m,y2:b(a.top+c+S)};case"bottom":return{x1:m,y1:b(a.bottom-1-c),x2:m,y2:b(a.bottom-1-c-S)}}}function Lt(n,s){if(!Number.isFinite(n)||!Number.isFinite(s))return;if(n<=0||s<=0)return;let a=n/(s/1000),c=Math.min(Math.max(a,100),1e4),l=Math.round(n/c*1000);if(Math.abs(l-s)<=1)return;return{effectiveDurationMs:l,warning:`durationMs ${s} was clamped on the iOS XCUICoordinate swipe route: velocity is limited to 100-10000 pt/s, so this ${Math.round(n)} pt swipe ran for about ${l} ms (effectiveDurationMs). The unpinned synthesized route honours the duration down to 50 ms.`}}function Ue(n,s,a){let{swipeRoute:c,effectiveDurationMs:l}=a;if(c===void 0||l===void 0){let u=Lt(n,s);return u?{effectiveDurationMs:u.effectiveDurationMs,warnings:[u.warning]}:{}}if(Math.abs(l-s)<=1)return{dispatchRoute:c};return{dispatchRoute:c,effectiveDurationMs:l,warnings:[c==="xcuiCoordinate"?`durationMs ${s} was clamped on the iOS XCUICoordinate swipe route: velocity is limited to 100-10000 pt/s, so this swipe ran for about ${l} ms (effectiveDurationMs).`:`durationMs ${s} was adjusted on the iOS ${c} swipe route: the runner dispatched ${l} ms (effectiveDurationMs; the synthesized route floors the stroke at 50 ms).`]}}var Wt="durationMs was ignored: the TalkBack semantic scroll route (ACTION_SCROLL on the container) performs a discrete scroll with no timed stroke, so the reported duration is a nominal value. Use a container without a stable selector, or turn TalkBack off, to get a timed swipe.";function qe(n,s){return{success:!0,...n,duration:s?.duration||300,durationIgnored:!0,...s?.durationExplicit?{warnings:[Wt]}:{}}}function q(n){return n.durationMs===void 0?void 0:!0}function fq(n,s,a,c){if(c<=0)return n;let l=Math.hypot(a.x-s.x,a.y-s.y);return{...n,velocityPxPerSecond:Math.round(l/c*1000)}}function Xe(n,s){if(!n.success||n.durationIgnored||s.boomerang||s.lookFor)return n;if(![n.x1,n.y1,n.x2,n.y2].every(Number.isFinite))return n;return fq(n,{x:n.x1,y:n.y1},{x:n.x2,y:n.y2},n.effectiveDurationMs??n.duration)}var Ut=["lookFor","focusTarget","autoTarget","includeSystemInsets","scrollMode","layer"];function qt(n,s){if(!s||n.warnings?.includes(s))return n;return{...n,warnings:[...n.warnings??[],s]}}function Xt({options:n,platform:s}){return Ut.find((a)=>n[a]!==void 0&&(s!=="android"||a==="focusTarget"||a==="layer"))}function Yt(n,s,a){let c=a??{left:0,top:0,right:s.screenSize.width,bottom:s.screenSize.height};if(n.fromEdge)return se({edge:n.fromEdge,bounds:c,inset:n.edgeInset,at:n.at});let l=Math.round((c.left+c.right)/2),u=Math.round((c.top+c.bottom)/2),d=Math.round((c.right-c.left)*0.6)/2,p=Math.round((c.bottom-c.top)*0.6)/2;switch(n.direction){case"left":return{x1:l+d,y1:u,x2:l-d,y2:u};case"right":return{x1:l-d,y1:u,x2:l+d,y2:u};case"up":return{x1:l,y1:u+p,x2:l,y2:u-p};default:return{x1:l,y1:u-p,x2:l,y2:u+p}}}function be(n){return n instanceof t&&n.containerFailure?{containerFailure:n.containerFailure}:{}}class ye{ctx;constructor(n){this.ctx=n}async executeOnAndroidDisplay({options:n,target:s,signal:a,talkBack:c}){let l=s.observation;if(n.container||n.autoTarget===!0)l=await T(l,(g)=>this.ctx().observeScreen.execute({...ac,display:s.observation.display.key,freshness:"fresh",timeoutMs:g,signal:a}),this.ctx().timer,a);let u=this.validateSelectedDisplayObservation({observation:l,target:s,includeSystemInsets:n.includeSystemInsets}),{options:d,decision:p}=this.selectedDisplayAutoTarget({options:n,observation:u}),{x1:m,y1:h,x2:f,y2:S,targetType:y,warning:b}=this.resolveDisplaySwipeCoordinates({options:d,decision:p,observation:u}),w=U({...d,geometry:this.ctx().geometry}),v=C(d);if(c.enabled){let g=await this.dispatchTalkBackDisplaySwipe({options:d,element:p.element,coordinates:{x1:m,y1:h,x2:f,y2:S},duration:w,boomerang:v,target:s,signal:a});return this.ctx().autoTargeting.withAutoTargetDecision({result:{...g,targetType:y,warning:b},decision:p})}let O=await this.resolveDisplaySwipeRoute({options:d,target:s});await this.dispatchDisplaySwipeLeg({x1:m,y1:h,x2:f,y2:S,duration:w,target:s,useCtrlProxy:O,signal:a});let E=w;if(v){let g=P({forwardDuration:w,returnSpeed:v.returnSpeed});E+=v.apexPauseMs+g;let x=await Qx({timer:this.ctx().timer,apexPauseMs:v.apexPauseMs,signal:a,returnSwipe:()=>this.dispatchDisplayReturnLeg({x1:f,y1:S,x2:m,y2:h,duration:g,target:s,useCtrlProxy:O,signal:a})});if(!x.success)return this.ctx().autoTargeting.withAutoTargetDecision({result:{...x,targetType:y,x1:m,y1:h,x2:f,y2:S,duration:E,warning:b},decision:p})}return this.ctx().autoTargeting.withAutoTargetDecision({result:{success:!0,targetType:y,x1:m,y1:h,x2:f,y2:S,duration:E,warning:b,...c.unknownWarning?{warnings:[c.unknownWarning]}:{}},decision:p})}async resolveDisplayTalkBack(n,s){let a=await this.ctx().accessibilityDetector.resolveTalkBackState(this.ctx().device.deviceId,this.ctx().adb,this.ctx().featureFlags);if(o(s),a!==!0)return{enabled:!1,unknownWarning:a===null?ba:void 0};let c=Ih(n.displayId,"scrolling");if(c)throw c;return{enabled:!0}}async dispatchTalkBackDisplaySwipe({options:n,element:s,coordinates:a,duration:c,boomerang:l,target:u,signal:d}){let p=Mc(n);if(!p.direction)throw new t(p.error??"direction is required");u.assertCurrent();let{x1:m,y1:h,x2:f,y2:S}=a,y=await this.ctx().talkBackExecutor.executeSwipeGesture({x1:m,y1:h,x2:f,y2:S,direction:p.direction,containerElement:s??null,gestureOptions:{displayFence:{assertCurrent:u.assertCurrent},duration:c,durationExplicit:q(n),scrollMode:n.scrollMode},perf:void 0,boomerang:l,signal:d});if(o(d),!y.success)throw new t(y.error??"TalkBack swipe failed");return y}resolveDisplaySwipeCoordinates({options:n,decision:s,observation:a}){if(s.element&&a.viewHierarchy){let l=this.ctx().resolveContainerSwipeCoordinates({...n,direction:n.direction},a.viewHierarchy,s.element,a);return{x1:l.startX,y1:l.startY,x2:l.endX,y2:l.endY,targetType:"element",warning:l.warning}}let c=this.selectedDisplayContainerBounds(n,a);if(n.container&&!c)throw new t("Swipe container not found on selected display");return{...Yt(n,a,this.resolveDisplaySwipeBounds(n,a,c)),targetType:c?"element":"screen"}}resolveDisplaySwipeBounds(n,s,a){return n.includeSystemInsets===!1||n.autoTarget===!0&&!a&&n.includeSystemInsets!==!0?this.insetDisplaySwipeBounds({observation:s,bounds:a}):a}selectedDisplayAutoTarget({options:n,observation:s}){if(n.autoTarget!==!0||n.container)return{options:n,decision:{}};let a=Mc(n);if(!a.direction)throw new t(a.error??"direction is required");let c=s.viewHierarchy?this.ctx().scrollables.findScrollableElements(s.viewHierarchy):[],l=this.ctx().autoTargeting.resolveAutoTargetDecision({scrollables:c,candidates:this.ctx().autoTargeting.buildScrollableCandidates(c),observeResult:s,direction:a.direction,includeSystemInsets:n.includeSystemInsets});return{options:{...n,direction:a.direction,container:l.container},decision:l}}async resolveDisplaySwipeRoute({options:n,target:s}){if(n.scrollMode==="adb")return!1;let a=await Ra(this.ctx().accessibilityService,s.displayId);if(n.scrollMode==="a11y"&&!a)throw new t(`scrollMode "a11y" requires CtrlProxy capability gesture_display_id_v1 for display "${s.observation.display.key}". Update CtrlProxy or use scrollMode "adb".`);return a}insetDisplaySwipeBounds({observation:n,bounds:s}){let a={observation:n,platform:Q(this.ctx().device.platform,"swipeOn")},c=Wm(a)??n.screenSize;return wk({...a,bounds:s??La(c)})}validateSelectedDisplayObservation(n){let{observation:s,target:a,includeSystemInsets:c}=n;if(a.assertCurrent(),s.display.key!==a.observation.display.key)throw Lm(a.observation.display.generation,this.ctx().displayTransitionReader.identityRevision(this.ctx().device.deviceId),this.ctx().displayTransitionReader.currentObservedPanel(this.ctx().device.deviceId)?.key);if(c!==void 0&&s.insets?.available!==!0)throw new t(`includeSystemInsets is not supported with \`display\` for display "${a.observation.display.key}": per-display system insets are unavailable`);return s.insets?.available===!0?s:{...s,systemInsets:{top:0,right:0,bottom:0,left:0}}}async resolveSearchDisplaySwipeRoute({options:n,target:s,signal:a}){if(n.scrollMode==="a11y")return this.resolveDisplaySwipeRoute({options:n,target:s});try{return await this.resolveDisplaySwipeRoute({options:n,target:s})}catch(c){return o(a),e.debug("[SwipeOn] CtrlProxy display gesture capability unavailable",c),!1}}executeDisplayTalkBackSwipe(n){return n.onDispatched?.(),this.ctx().talkBackExecutor.executeSwipeGesture({x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2,direction:n.direction,containerElement:null,gestureOptions:{displayFence:{assertCurrent:n.target.assertCurrent},duration:n.duration,scrollMode:n.options.scrollMode,searchDragState:n.searchDragState},perf:void 0,boomerang:void 0,signal:n.signal})}validatedObserveScreen(n,s){let a=this.ctx().observeScreen;return{execute:async(c)=>(s.assertCurrent(),n(await a.execute(c))),getMostRecentCachedObserveResult:a.getMostRecentCachedObserveResult.bind(a),appendRawViewHierarchy:a.appendRawViewHierarchy.bind(a),captureScreenshot:a.captureScreenshot?.bind(a),runAccessibilityAudit:a.runAccessibilityAudit?.bind(a),processRecomposition:a.processRecomposition?.bind(a),captureCacheGeneration:a.captureCacheGeneration?.bind(a),cacheObserveResult:a.cacheObserveResult?.bind(a)}}async searchOnAndroidDisplay({options:n,target:s,progress:a,signal:c,talkBack:l}){let u=Mc(n);if(u.error)throw new t(u.error);let d=await this.resolveSearchDisplaySwipeRoute({options:n,target:s,signal:c}),p=s.observation.display.key,m=(b)=>this.validateSelectedDisplayObservation({observation:b,target:s,includeSystemInsets:n.includeSystemInsets}),h=this.validatedObserveScreen(m,s),f=!1,S=async(b)=>{try{return s.assertCurrent(),m(await this.ctx().observeScreen.execute({display:p,freshness:b?.freshness??"cached-ok",timeoutMs:b?.timeoutMs,skipScreenshot:!0,skipAccessibilityAudit:!0,signal:c}))}catch(w){throw this.ctx().rethrowObservationAbort(w,c),e.warn(`[SwipeOn] Display search read failed: ${r(w)}`,w),f?new mr(w):w}},y=await this.ctx().scrollUntilVisible.executeWithStrategy({options:{...n,direction:u.direction},progress:a,signal:c,strategy:{observe:S,swipe:async({previousObservation:b,searchDragState:w,onDispatched:v,...O})=>{let E=await this.ctx().visual.observedInteraction(async()=>{let g=async()=>(O.onSearchFallback?.(),await this.dispatchDisplaySwipeLeg({...O,target:s,useCtrlProxy:!1,signal:c,onDispatched:v}),f=!0,{...O,success:!0}),x=await(l.enabled?this.executeDisplayTalkBackSwipe({...O,direction:u.direction,options:n,target:s,searchDragState:w,signal:c,onDispatched:v}):d?ne({...O,searchDragState:w,client:this.ctx().accessibilityService,signal:c,displayId:s.displayId===0?void 0:s.displayId,beforeSend:s.assertCurrent,fallback:g,onDispatched:v,onIndeterminate:(I)=>{throw new mr(I)}}):g());return f||=x.success,x},{changeExpected:!1,timeoutMs:wt.brief,display:p,previousObservation:b,progress:a,signal:c,deferPostActionScreenshot:!0,postActionObserveScreen:h});return this.ctx().checkPostActionDisplay(E,()=>m(E.observation),c),{...O,targetType:"screen",success:E.success,error:E.error,outcomeIndeterminate:E.outcomeIndeterminate,observation:E.observation,staleDisplay:E.staleDisplay}}}});if(f)this.ctx().checkPostActionDisplay({},s.assertCurrent,c);else s.assertCurrent();return qt(y,l.unknownWarning)}async dispatchDisplayReturnLeg(n){let{x1:s,y1:a,x2:c,y2:l,duration:u,signal:d}=n;try{return await this.dispatchDisplaySwipeLeg(n),{success:!0,x1:s,y1:a,x2:c,y2:l,duration:u}}catch(p){if(o(d),ht(p)||p instanceof _e)throw p;if(p instanceof Error&&p.name==="AbortError")throw p;return e.warn(`swipeOn display return leg failed: ${r(p)}`,p),{success:!1,error:r(p),x1:s,y1:a,x2:c,y2:l,duration:u}}}async dispatchDisplaySwipeLeg(n){let{x1:s,y1:a,x2:c,y2:l,duration:u,target:d,useCtrlProxy:p,signal:m,onDispatched:h}=n;if(d.assertCurrent(),o(m),p){let f=await this.ctx().accessibilityService.requestSwipe({x1:s,y1:a,x2:c,y2:l,duration:u,onDispatch:h,signal:m,displayId:d.displayId===0?void 0:d.displayId,beforeSend:d.assertCurrent});if(o(m),!f.success)throw new t(f.error??"Android swipe failed")}else await dc(this.ctx().adb,`swipe ${s} ${a} ${c} ${l} ${Lo(u)}`,d.displayId,{signal:m,assertCurrent:d.assertCurrent,onDispatch:h})}selectedDisplayContainerBounds(n,s){if(!n.container||!s.viewHierarchy)return;if(A(n.container))return this.ctx().scrollUntilVisible.resolveSwipeContainer(s.viewHierarchy,n.container).bounds;let a=this.ctx().scrollUntilVisible.resolveElement(s.viewHierarchy,n.container,"inspect",n.container.text!==void 0);return a&&n.direction?this.ctx().scrollUntilVisible.resolveSwipeTarget(s.viewHierarchy,a,n.direction).bounds:a?.bounds}async executeExplicitDisplay(n,s={}){let{progress:a,signal:c}=s;if(n.display!==void 0)try{let l=Xt({options:n,platform:this.ctx().device.platform});if(l)throw new t(sR(l));let u=Zf(n,this.ctx().getDuration(n))??oe(n);if(u)throw new t(u);let d=await Ni(this.ctx().device,n.display,this.ctx().observeScreen,{adb:this.ctx().adb,lastRenderedObservation:this.ctx().lastRenderedObservation,signal:c,transitions:this.ctx().displayTransitionReader});if(o(c),this.ctx().device.platform==="android"){this.validateSelectedDisplayObservation({observation:d.observation,target:d,includeSystemInsets:n.includeSystemInsets});let p=await this.resolveDisplayTalkBack(d,c);return n.lookFor?await this.searchOnAndroidDisplay({options:n,target:d,progress:a,signal:c,talkBack:p}):await this.ctx().observedSwipeInteraction(()=>this.executeOnAndroidDisplay({options:n,target:d,signal:c,talkBack:p}),{changeExpected:!1,display:d.observation.display.key,previousObservation:d.observation,signal:c},{boomerang:C(n)})}}catch(l){if(l instanceof V)throw l;if(eV(c,l),l instanceof Error&&l.name==="AbortError")throw l;return e.warn(`swipeOn display routing failed: ${r(l)}`,l),ir({...this.ctx().createErrorResult(r(l)),...be(l)},l)}return}}function ve(n){return n.perf??new B}function zt(n,s){return(n.dispatched??s)&&n.acknowledged!==!0||dl(n)}class mA extends De{constructor(n,s=null,a=i){super(n,{adb:s,timer:a});this.device=n}async swipe(n,s={},a={}){switch(o(a.signal),this.device.platform){case"android":return await this.executeAndroidSwipe(n,s,a);case"ios":return await this.executeiOSSwipe(n,s,a);default:throw yt(this.device.platform,"execute gesture")}}async executeAndroidSwipe(n,s={},a={}){let{x1:c,y1:l,x2:u,y2:d}=n,{signal:p}=a,m=ve(a),h=s.duration??300,f=s.scrollMode||"adb";if(s.searchScroll){let S=s.searchScrollBounds?re({startX:c,startY:l,endX:u,endY:d},s.searchScrollBounds):{startX:c,startY:l,endX:u,endY:d},y=new tr().getSwipeDurationFromSpeed("slow"),b=()=>this.executeAndroidSwipe({x1:S.startX,y1:S.startY,x2:S.endX,y2:S.endY},{duration:y,scrollMode:"adb",displayFence:s.displayFence},a);if(s.scrollMode==="adb")return b();return ne({client:k.getInstance(this.device,this.adbFactory),x1:S.startX,y1:S.startY,x2:S.endX,y2:S.endY,duration:y,signal:p,searchDragState:s.searchDragState,onFallback:s.onSearchFallback,fallback:b,beforeSend:()=>s.displayFence?.assertCurrent()})}if(f==="a11y")return await this.executeA11ySwipe(n,h,{perf:m,signal:p,displayFence:s.displayFence});try{await m.track("adbInputSwipe",async()=>{o(p),s.displayFence?.assertCurrent(),await this.adb.executeCommand(`shell input swipe ${c} ${l} ${u} ${d} ${Lo(h)}`,{signal:p})}),o(p)}catch(S){if(S instanceof _e)throw S;return o(p),e.warn(`[SWIPE] ADB swipe failed: ${r(S)}`),{success:!1,x1:c,y1:l,x2:u,y2:d,duration:h,error:r(S)}}return{success:!0,x1:c,y1:l,x2:u,y2:d,duration:h}}async executeA11ySwipe(n,s,a={}){let{x1:c,y1:l,x2:u,y2:d}=n,{signal:p}=a,m=ve(a),h=Jy(a),f=!1,S=(w)=>({success:!1,outcomeIndeterminate:!0,x1:c,y1:l,x2:u,y2:d,duration:s,error:`Swipe outcome is indeterminate: the request was dispatched but no result was confirmed (${w}). Do not retry automatically.`}),y,b="failure";try{o(p);let w=k.getInstance(this.device,this.adbFactory),v=await m.track("a11ySwipe",async()=>(o(p),h.assertCurrent(),await w.requestSwipe({x1:c,y1:l,x2:u,y2:d,duration:s,timeoutMs:5000,perf:m,onDispatch:()=>{f=!0}})));if(o(p),v.success)return e.info(`[SWIPE] A11y swipe successful: deviceTotal=${v.totalTimeMs}ms, gesture=${v.gestureTimeMs}ms`),{success:!0,x1:c,y1:l,x2:u,y2:d,duration:s,a11yTotalTimeMs:v.totalTimeMs,a11yGestureTimeMs:v.gestureTimeMs};if(f)return e.warn(`[SWIPE] A11y swipe outcome indeterminate: ${v.error}`),S(v.error??"unknown error");e.warn(`[SWIPE] A11y swipe failed: ${v.error}, falling back to ADB`),y=v.error}catch(w){if(w instanceof _e)throw w;if(o(p),f)return e.warn(`[SWIPE] A11y swipe outcome indeterminate: ${w}`),S(`${w}`);e.warn(`[SWIPE] A11y swipe exception: ${w}, falling back to ADB`),y=r(w),b="exception"}try{await m.track("adbInputSwipeFallback",async()=>{o(p),h.assertCurrent(),await this.adb.executeCommand(`shell input swipe ${c} ${l} ${u} ${d} ${Lo(s)}`,{signal:p})}),o(p)}catch(w){if(w instanceof _e)throw w;return o(p),e.warn(`[SWIPE] ADB fallback failed after a11y ${b}: ${r(w)}`),{success:!1,x1:c,y1:l,x2:u,y2:d,duration:s,fallbackReason:y,error:`Accessibility swipe failed: ${y??"unknown error"}; ADB fallback failed: ${r(w)}`}}return{success:!0,x1:c,y1:l,x2:u,y2:d,duration:s,fallbackReason:y}}async executeiOSSwipe(n,s={},a={}){return await this.executeXCTestSwipe(n,s,a)}async executeXCTestSwipe(n,s={},a={}){let{x1:c,y1:l,x2:u,y2:d}=n,p=s.duration||300,{signal:m}=a,h=ve(a),f=s.displayFence;o(m);let S=_.getInstance(this.device),y=!1,b=(v)=>({success:!1,outcomeIndeterminate:!0,x1:c,y1:l,x2:u,y2:d,duration:p,error:`Swipe outcome is indeterminate: the request was dispatched but no result was confirmed (${v}). The swipe may have been applied. Do not retry automatically.`}),w;try{w=await h.track("xctestSwipe",async()=>(o(m),f?.assertCurrent(),await S.requestSwipe({x1:c,y1:l,x2:u,y2:d,duration:p,timeoutMs:Math.min(5000,s.timeoutMs??5000),perf:h,contextOptions:s.lockScreen===!0?{lockScreen:!0}:void 0,signal:m,onDispatch:()=>{y=!0}})))}catch(v){if(!y||v instanceof t)throw v;return e.warn(`[SWIPE] CtrlProxy iOS swipe outcome indeterminate: ${r(v)}`),b(r(v))}if(!w.success&&zt(w,y))return e.warn(`[SWIPE] CtrlProxy iOS swipe outcome indeterminate: ${w.error}`),b(w.error??"unknown error");if(o(m),w.success){e.info(`[SWIPE] CtrlProxy iOS swipe successful: deviceTotal=${w.totalTimeMs}ms, gesture=${w.gestureTimeMs}ms`);let v=Ue(Math.hypot(u-c,d-l),p,w);return{success:!0,x1:c,y1:l,x2:u,y2:d,duration:p,a11yTotalTimeMs:w.totalTimeMs,a11yGestureTimeMs:w.gestureTimeMs,...v}}else return e.error(`[SWIPE] CtrlProxy iOS swipe failed: ${w.error}`),{success:!1,x1:c,y1:l,x2:u,y2:d,duration:p,error:w.error}}async execute(n,s,a,c={}){let{durationMs:l=300,signal:u,displayFence:d}=typeof s==="object"?s:{durationMs:s,signal:a,displayFence:c.displayFence};switch(o(u),this.device.platform){case"android":return await this.executeAndroidGesture(n,l,u,{displayFence:d});case"ios":return await this.executeiOSGesture(n,l,u,{displayFence:d});default:throw yt(this.device.platform,"execute gesture")}}async executeAndroidGesture(n,s,a,c={}){let l=c.displayFence;if(Array.isArray(n)&&n.length>0)if("finger"in n[0])throw Error("Multi-finger gestures not supported - use simple swipe instead");else{let u=n;if(u.length>=2){let d=u[0],p=u[u.length-1];o(a),l?.assertCurrent(),await this.adb.executeCommand(`shell input swipe ${d.x} ${d.y} ${p.x} ${p.y} ${Lo(s)}`,{signal:a}),o(a)}}return{pathLength:n.length,duration:s,platform:"android"}}async executeiOSGesture(n,s,a,c={}){let l=c.displayFence;if(Array.isArray(n)&&n.length>0)if("finger"in n[0]){let u=n,d=this.resolveIOSMultiFingerSwipe(u);if(d)await this.executeIOSMultiFingerSwipe(d,s,a,l)}else{let u=n;if(u.length>=2)await this.executeIOSSingleFingerSwipe(u[0],u[u.length-1],s,{signal:a,fence:l})}return{pathLength:n.length,duration:s,platform:"ios"}}async executeIOSSingleFingerSwipe(n,s,a,{signal:c,fence:l}={}){o(c);let u=_.getInstance(this.device);l?.assertCurrent();let d=await u.requestSwipe({x1:n.x,y1:n.y,x2:s.x,y2:s.y,duration:a,signal:c});if(this.throwIfIosGestureUnconfirmed(d),o(c),!d.success)throw new t(`iOS gesture failed: ${d.error??"unknown error"}`)}async executeIOSMultiFingerSwipe(n,s,a,c){o(a);let l=_.getInstance(this.device);c?.assertCurrent();let u=await l.requestMultiFingerSwipe({x1:n.start.x,y1:n.start.y,x2:n.end.x,y2:n.end.y,fingerCount:n.fingerCount,duration:s,fingerSpacing:n.fingerSpacing,signal:a,beforeSend:()=>c?.assertCurrent()});if(this.throwIfIosGestureUnconfirmed(u),o(a),!u.success)throw new t(`iOS multi-finger gesture failed: ${u.error??"unknown error"}`)}throwIfIosGestureUnconfirmed(n){if(!n.success&&n.dispatched&&(n.acknowledged===!1||dl(n)))throw new t(`Gesture outcome is indeterminate: the request was dispatched but no result was confirmed (${n.error??"unknown error"}). The gesture may have been applied. Do not retry automatically. Observe before retrying.`)}resolveIOSMultiFingerSwipe(n){if(n.length===0)return null;for(let u=0;u<n.length;u++){let d=n[u].points;if(d.length<2)throw Error("iOS multi-finger gestures require at least two points per finger");if(d.length!==2)throw Error("iOS multi-finger gestures only support two-point swipes")}let s=n[0].points,a=s[0],c=s[1],l=n.length>1?n[1].points[0].x-a.x:0;for(let u=0;u<n.length;u++){let d=n[u].points,p=d[0],m=d[1],h=u*l;if(!this.sameCoordinate(p.y,a.y)||!this.sameCoordinate(m.y,c.y)||!this.sameCoordinate(p.x-a.x,h)||!this.sameCoordinate(m.x-c.x,h))throw Error("iOS multi-finger gestures only support horizontally spaced parallel swipes")}return{start:a,end:c,fingerCount:n.length,fingerSpacing:l}}sameCoordinate(n,s){return Math.abs(n-s)<0.001}}class H{geometry;elementParser;static OVERLAY_PADDING=8;static CANDIDATE_FRACTIONS=[0.5,0.25,0.75,0.15,0.85];constructor(n,s){this.geometry=n;this.elementParser=s}collectOverlayCandidates(n,s){let a=this.elementParser,c=a.extractWindowRootGroups(n,"topmost-first"),l=c.length>0?c:[a.extractRootNodes(n)],u=Math.max(1,l.length),d=[],p=new Set,m=s.bounds,h=this.resolveSelectedContainerNode(n,a,s,m),f=h?.node??null,S=this.collectContainerAncestors(h?.roots??null,a,f),y=this.findContainerWindowIndex(l,a,f);return l.forEach((b,w)=>{if(y!==null&&w>y)return;let v=u-w,O=0;for(let E of b){let g=!1,x=-1;a.traverseNode(E,(I,D)=>{if(p.has(I))return;p.add(I);let ue=O++,L=a.extractNodeProperties(I);if(this.isContainerNode(I,L,f,{containerElement:s,containerBounds:m})){if(!g)g=!0,x=D;return}if(g&&D<=x)g=!1,x=-1;if(g||S.has(I))return;if(!this.isClickableNode(L))return;let F=a.parseNodeBounds(I);if(!F)return;let N=this.intersectBounds(m,F.bounds);if(!N)return;let K=_t(N);if(K<=0)return;d.push({bounds:F.bounds,overlapBounds:N,coverage:K,zOrder:{windowRank:v,nodeOrder:ue}})})}}),d}computeSafeSwipeCoordinates(n,s,a){let c=n==="up"||n==="down",l=c?s.top:s.left,u=c?s.bottom:s.right,d=c?s.left:s.top,p=c?s.right:s.bottom,m=this.buildCandidateCoordinates(d,p),h=this.findBestSwipeCandidate(c,s,a,{candidates:m,primary:{start:l,end:u}});if(!h)return null;let f=c?{left:s.left,right:s.right,top:h.interval.start,bottom:h.interval.end}:{left:h.interval.start,right:h.interval.end,top:s.top,bottom:s.bottom},S=this.geometry.getSwipeWithinBounds(n,f),{startX:y,startY:b,endX:w,endY:v}=S;if(c)y=h.coordinate,w=h.coordinate;else b=h.coordinate,v=h.coordinate;y=to(y,f.left,f.right),w=to(w,f.left,f.right),b=to(b,f.top,f.bottom),v=to(v,f.top,f.bottom);let O=Math.max(1,u-l),E=Math.max(50,O*0.1),g=h.interval.length<E?`Swipe area reduced by overlaying elements; safe ${c?"height":"width"} is ${Math.round(h.interval.length)}px.`:void 0;return{startX:y,startY:b,endX:w,endY:v,warning:g}}findBestSwipeCandidate(n,s,a,{candidates:c,primary:l}){let u=null;for(let d of c){let p=n?this.getBlockedIntervalsForX(a,s,d):this.getBlockedIntervalsForY(a,s,d),m=this.findLargestGap(l.start,l.end,p);if(!m)continue;if(!u||m.length>u.interval.length)u={coordinate:d,interval:m}}return u}getBlockedIntervalsForX(n,s,a){let c=[];for(let l of n){let u=this.expandBounds(l,H.OVERLAY_PADDING);if(a<u.left||a>u.right)continue;let d=Math.max(s.top,u.top),p=Math.min(s.bottom,u.bottom);if(p>d)c.push({start:d,end:p,length:p-d})}return c}getBlockedIntervalsForY(n,s,a){let c=[];for(let l of n){let u=this.expandBounds(l,H.OVERLAY_PADDING);if(a<u.top||a>u.bottom)continue;let d=Math.max(s.left,u.left),p=Math.min(s.right,u.right);if(p>d)c.push({start:d,end:p,length:p-d})}return c}findLargestGap(n,s,a){let c=this.mergeIntervals(a),l=n,u=null;for(let d of c){if(d.start>l){let p={start:l,end:d.start,length:d.start-l};if(!u||p.length>u.length)u=p}l=Math.max(l,d.end)}if(l<s){let d={start:l,end:s,length:s-l};if(!u||d.length>u.length)u=d}return u}mergeIntervals(n){let s=n.filter((c)=>c.end>c.start).sort((c,l)=>c.start-l.start),a=[];for(let c of s){let l=a[a.length-1];if(!l||c.start>l.end){a.push({...c});continue}l.end=Math.max(l.end,c.end),l.length=l.end-l.start}return a}buildCandidateCoordinates(n,s){let a=s-n;if(a<=0)return[];let c=H.CANDIDATE_FRACTIONS.map((l)=>Math.floor(n+a*l));return Array.from(new Set(c.filter((l)=>l>=n&&l<=s)))}expandBounds(n,s){return{left:n.left-s,top:n.top-s,right:n.right+s,bottom:n.bottom+s}}intersectBounds(n,s){let a=Math.max(n.left,s.left),c=Math.min(n.right,s.right),l=Math.max(n.top,s.top),u=Math.min(n.bottom,s.bottom);if(c<=a||u<=l)return null;return{left:a,top:l,right:c,bottom:u}}collectContainerAncestors(n,s,a){let c=new Set;if(!a||!n)return c;let l=[],u=!1;for(let d of n)if(s.traverseNode(d,(p,m)=>{if(u)return;if(l.length=m,l[m]=p,p===a){for(let h of l.slice(0,m))c.add(h);u=!0}}),u)return c;return c}findContainerWindowIndex(n,s,a){if(!a||n.length<2)return null;let c=n.findIndex((l)=>l.some((u)=>this.treeContains(u,s,a)));return c===-1?null:c}treeContains(n,s,a){let c=!1;return s.traverseNode(n,(l)=>{if(l===a)c=!0}),c}isClickableNode(n){return st(n.clickable)||st(n.focusable)}resolveSelectedContainerNode(n,s,a,c){let l=s.extractRootNodes(n),u=this.findSelectorBoundsMatch(l,s,a,c);if(u.matchCount>0)return u.matchCount===1&&u.match?{node:u.match,roots:l}:null;let d=s.extractWindowRootGroups(n,"topmost-first");for(let p of d){let m=this.findSelectorBoundsMatch(p,s,a,c);if(m.matchCount>0)return m.matchCount===1&&m.match?{node:m.match,roots:p}:null}return null}findSelectorBoundsMatch(n,s,a,c){let l=null,u=0;for(let d of n)s.traverseNode(d,(p)=>{let m=s.extractNodeProperties(p);if(!this.matchesContainerSelector(p,m,a,c))return;let h=this.elementParser.parseBounds(Ft(p));if(h===null||!Vt(h,c))return;u++,l=p});return{match:l,matchCount:u}}isContainerNode(n,s,a,{containerElement:c,containerBounds:l}){if(a&&n===a)return!0;return this.matchesContainerSelector(n,s,c,l)}matchesContainerSelector(n,s,a,c){let l=er(s),u=Boolean(a["resource-id"]),d=Boolean(a.text),p=Boolean(a["content-desc"]);if(u||d||p){if(u&&l.nativeId!==a["resource-id"])return!1;if(d&&l.textSources.text!==a.text)return!1;if(p&&l.textSources["content-desc"]!==a["content-desc"])return!1;return!0}let m=this.elementParser.parseBounds(Ft(n));return m!==null&&Vt(m,c)}}class X{geometry;constructor(n=new tr){this.geometry=n}selectAutoTargetScrollable(n,s,a){let c=n.filter((d)=>this.matchesDirection(d,a));if(c.length===0)return null;let l=s?c.filter((d)=>!Vt(d.bounds,s)):c,u=l.length>0?l:c;if(s){let d=(s.left+s.right)/2,p=(s.top+s.bottom)/2,m=u.filter((h)=>this.geometry.isPointInElement(h,d,p));if(m.length>0)return m.reduce((h,f)=>_t(f.bounds)<_t(h.bounds)?f:h)}if(u.length>1){let d=a==="up"||a==="down",p=u.filter((m)=>{if(this.knownScrollAxis(m))return!0;let h=Math.abs(m.bounds.right-m.bounds.left),f=Math.abs(m.bounds.bottom-m.bounds.top);return d?f>=h:h>=f});if(p.length>0)return this.pickLargestScrollable(p)}return this.pickLargestScrollable(u)}pickLargestScrollable(n){if(n.length===0)return null;return n.reduce((s,a)=>{let c=_t(s.bounds);return _t(a.bounds)>c?a:s})}matchesDirection(n,s){let a=this.knownScrollAxis(n);return a===void 0||(s==="up"||s==="down")===(a==="vertical")}scrollsInDirection(n,s){return(gt(n.scrollable)||this.knownScrollAxis(n)!==void 0)&&this.matchesDirection(n,s)}knownScrollAxis(n){let s=typeof n.orientation==="string"?n.orientation.toLowerCase():void 0;if(s==="horizontal"||s==="vertical")return s;let a=n.class??n.className,c=typeof a==="string"?a.split(".").at(-1)??"":"";if(["HorizontalScrollView","ViewPager","ViewPager2","LazyRow"].includes(c))return"horizontal";if(["ScrollView","NestedScrollView","ListView","ExpandableListView","LazyColumn"].includes(c))return"vertical";return}getScreenBounds(n,s={}){let a=s.platform??Rn(n.viewHierarchy)?.platform,c={observation:n,platform:a,includeSystemInsets:a==="ios"?s.includeSystemInsets:void 0},l=Wm(c);if(!l)return null;return La(l,Sk(c))}describeContainer(n){if(!n)return"unknown";if(n.elementId)return`elementId="${n.elementId}"`;if(n.text)return`text="${n.text}"`;return"unknown"}mergeWarnings(...n){let s=n.filter((a)=>Boolean(a));if(s.length===0)return;return Array.from(new Set(s)).join(" ")}}function Kt(n){return n==="up"||n==="left"?"scroll_forward":"scroll_backward"}class ge{device;executeGesture;accessibilityService;accessibilityDetector;adb;timer;featureFlags;constructor({device:n,executeGesture:s,accessibilityService:a,accessibilityDetector:c,adb:l,timer:u,featureFlags:d}){this.device=n,this.executeGesture=s,this.accessibilityService=a,this.accessibilityDetector=c,this.adb=l,this.timer=u,this.featureFlags=d}async executeSwipeGesture({x1:n,y1:s,x2:a,y2:c,direction:l,containerElement:u,gestureOptions:d,perf:p,boomerang:m,signal:h}){o(h);let f=Boolean(m);if(e.info(`[SwipeOn] executeSwipeGesture: direction=${l}, (${n},${s})\u2192(${a},${c}), duration=${d?.duration}ms, boomerang=${f}, container=${u?.["resource-id"]??"none"}`),this.device.platform!=="android"){if(f)return this.executeBoomerangGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:d,boomerang:m,perf:p,signal:h});return this.executeGesture.swipe({x1:n,y1:s,x2:a,y2:c},d,{perf:p,signal:h})}let S=await this.accessibilityDetector.resolveTalkBackState(this.device.deviceId,this.adb,this.featureFlags),y=S===!0,b=S===null?ba:void 0;if(o(h),y){if(d?.searchDragState)d.searchDragState.pagingStep=!0;if(f)return e.info("[SwipeOn] TalkBack enabled, boomerang requested; announcing swipeable element"),this.announceSwipeable({x1:n,y1:s,x2:a,y2:c,containerElement:u,gestureOptions:d,perf:p,signal:h});return e.info("[SwipeOn] TalkBack enabled, using accessibility-aware swipe"),this.executeAndroidSwipeWithAccessibility({x1:n,y1:s,x2:a,y2:c,direction:l,containerElement:u,gestureOptions:d,perf:p,signal:h})}else{if(f){e.debug("[SwipeOn] TalkBack disabled, using boomerang swipe");let v=await this.executeBoomerangGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:d,boomerang:m,perf:p,signal:h});return zl(v,b)}e.debug("[SwipeOn] TalkBack disabled, using standard swipe");let w=await this.executeGesture.swipe({x1:n,y1:s,x2:a,y2:c},d,{perf:p,signal:h});return zl(w,b)}}async executeBoomerangGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:l,boomerang:u,perf:d=new B,signal:p}){let m=l?.duration??300,h=Zf({boomerang:!0,apexPause:u.apexPauseMs,returnSpeed:u.returnSpeed},m);if(h)throw new t(h);let f=this.getReturnDuration(m,u.returnSpeed),S=m+u.apexPauseMs+f,y=this.buildGestureOptions(l,m),b=this.buildGestureOptions(l,f),w=await this.executeGesture.swipe({x1:n,y1:s,x2:a,y2:c},y,{perf:d,signal:p});if(!w.success)return o(p),w;let v=await Qx({timer:this.timer,apexPauseMs:u.apexPauseMs,signal:p,returnSwipe:()=>this.executeGesture.swipe({x1:a,y1:c,x2:n,y2:s},b,{perf:d,signal:p})});if(!v.success)return{...v,x1:n,y1:s,x2:a,y2:c,duration:S};return{...w,x1:n,y1:s,x2:a,y2:c,duration:S,a11yTotalTimeMs:this.sumOptional(w.a11yTotalTimeMs,v.a11yTotalTimeMs),a11yGestureTimeMs:this.sumOptional(w.a11yGestureTimeMs,v.a11yGestureTimeMs),fallbackReason:w.fallbackReason??v.fallbackReason}}async announceSwipeable({x1:n,y1:s,x2:a,y2:c,containerElement:l,gestureOptions:u,perf:d=new B,signal:p}){let m=u?.duration??0,h=l?.["resource-id"];if(!h)return e.warn("[SwipeOn] Boomerang swipe in TalkBack mode requires a container element with a resource-id."),{success:!1,error:"Boomerang swipe in TalkBack mode requires a container element with a resource-id.",x1:n,y1:s,x2:a,y2:c,duration:m};o(p);let f=await this.accessibilityService.requestAction("focus",h,5000,{perf:d});if(o(p),!f.success){let S=f.error??"Failed to set accessibility focus for boomerang swipe.";return e.warn(`[SwipeOn] ${S}`),{success:!1,error:S,x1:n,y1:s,x2:a,y2:c,duration:m}}return{success:!0,x1:n,y1:s,x2:a,y2:c,duration:m}}async executeAndroidSwipeWithAccessibility({x1:n,y1:s,x2:a,y2:c,direction:l,containerElement:u,gestureOptions:d,perf:p,signal:m}){let h=u&&rs(u);if(h){let b=await this.attemptAccessibilityScroll({x1:n,y1:s,x2:a,y2:c,direction:l,selector:h,gestureOptions:d,perf:p,signal:m});if(b)return b}else e.debug("[SwipeOn] No container with resource-id, skipping ACTION_SCROLL");e.info("[SwipeOn] Using two-finger swipe gesture for TalkBack");let f=d?.duration||300,S=100;o(m),d?.displayFence?.assertCurrent();let y=await this.accessibilityService.requestTwoFingerSwipe({x1:n,y1:s,x2:a,y2:c,duration:f,offset:S,timeoutMs:5000,perf:p||new B});if(o(m),y.success)return{success:!0,x1:n,y1:s,x2:a,y2:c,duration:f};else throw new t(`Two-finger swipe failed: ${y.error||"Unknown error"}`)}async attemptAccessibilityScroll({x1:n,y1:s,x2:a,y2:c,direction:l,selector:u,gestureOptions:d,perf:p,signal:m}){let h=(b)=>({success:!1,x1:n,y1:s,x2:a,y2:c,duration:d?.duration||300,error:`Swipe outcome is indeterminate: the request was dispatched but no result was confirmed (${b}). Do not retry automatically.`}),f=Kt(l),S=Zs(u),y=await _h(u,{supportsNodeActionSelectors:()=>this.accessibilityService.supportsNodeActionSelectors(),getAccessibilityHierarchy:()=>this.accessibilityService.getAccessibilityHierarchy(void 0,{perf:p,skipWaitForFresh:!1,disableAllFiltering:!0})});if(y){e.info(`[SwipeOn] ${y}`);return}e.info(`[SwipeOn] Attempting ACTION_SCROLL (${f}) on container: ${JSON.stringify(u)}`);try{o(m);let b=S?await this.accessibilityService.requestNodeAction(f,u,{timeoutMs:5000,perf:p}):await this.accessibilityService.requestAction(f,u.resourceId,5000,{perf:p||new B});if(b.success)return e.info("[SwipeOn] ACTION_SCROLL succeeded"),qe({x1:n,y1:s,x2:a,y2:c},d);if(b.dispatched&&b.acknowledged!==!0)return e.warn(`[SwipeOn] ACTION_SCROLL outcome indeterminate: ${b.error}`),h(b.error??"unknown error");e.warn(`[SwipeOn] ACTION_SCROLL failed: ${b.error}, falling back to two-finger swipe`)}catch(b){if(b instanceof _e)throw b;return o(m),e.warn(`[SwipeOn] ACTION_SCROLL outcome indeterminate: ${b}`),h(String(b))}return}buildGestureOptions(n,s){return{...n??{},duration:s}}getReturnDuration(n,s){return P({forwardDuration:n,returnSpeed:s})}sumOptional(n,s){if(n===void 0&&s===void 0)return;return(n??0)+(s??0)}resolveBoomerangConfig(n){return C(n)}}class z extends t{constructor(n){super(n);this.name="SwipeOutcomeIndeterminateError"}}var jt=3000,Jt=G6;function Zt(n){return Math.min(Math.max(Jt,n+jt),Nr)}function rr(n,s,a){let c=s.viewHierarchy;if(n.containerElement){let d=Qy(n.containerElement),p=d&&oC(c,d.elementId);if(!p)return null;if(n.boomerang)return"unsupported";let m={x:n.x1-n.x2,y:n.y1-n.y2};return{action:{scroll:{...p,delta:m}},verb:"scroll"}}let l=oC(c);if(!l)return null;if(n.boomerang)return"unsupported";return{action:{swipe:{observationIdentity:l.observationIdentity,start:{x:n.x1,y:n.y1},end:{x:n.x2,y:n.y2},durationMs:a}},verb:"swipe"}}var nr="durationMs was ignored: the app's SDK observation bridge scrolls the container by an offset with no timed stroke, so the reported duration is a nominal value.";function or(n,s){return{...n,durationIgnored:!0,...s.gestureOptions?.durationExplicit?{warnings:[nr]}:{}}}class Ye{xctest;options;enabled;constructor(n,s){this.xctest=n;this.options=s;this.enabled=s.enabled??(()=>M.isIosSdkObservationBridgeEnabled())}async executeSwipeGesture(n){let s=Math.max(0,Math.round(n.gestureOptions?.duration??300)),a=this.enabled()&&n.sdkObservation?rr(n,n.sdkObservation,s):null;if(!a)return this.xctest.executeSwipeGesture(n);let c=a==="unsupported"?{backend:"xctest",fallbackReason:"unsupported"}:await this.dispatch(a,s,n);if(c.backend==="sdk"){let{x1:u,y1:d,x2:p,y2:m}=n,h={success:!0,x1:u,y1:d,x2:p,y2:m,duration:s,backend:"sdk"};return a!=="unsupported"&&a.verb==="scroll"?or(h,n):h}return{...await this.xctest.executeSwipeGesture(n),backend:"xctest",fallbackReason:c.fallbackReason}}async dispatch(n,s,a){a.gestureOptions?.displayFence?.assertCurrent();let c=a.signal,l=this.options.client();if(!l)return{backend:"xctest",fallbackReason:"unavailable"};let u=await l.requestSdkActionForIos(n.action,{timeoutMs:Zt(s),signal:c});return XI(u,n.verb)}}function ze(n,s){return new Ye(s,{client:()=>_.getExistingInstance(n.deviceId)})}var Ke="AutoMobile could not determine the current VoiceOver state; used the default gesture. VoiceOver may be enabled.";class Qe{device;executeGesture;iosClient;iosVoiceOverDetector;timer;featureFlags;constructor({device:n,executeGesture:s,iosClient:a,iosVoiceOverDetector:c,timer:l,featureFlags:u}){this.device=n,this.executeGesture=s,this.iosClient=a,this.iosVoiceOverDetector=c,this.timer=l,this.featureFlags=u}async executeSwipeGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:l,perf:u=new B,boomerang:d,signal:p}){if(o(p),this.device.platform!=="ios"){if(d)return this.executeBoomerangGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:l,boomerang:d,perf:u,signal:p});return this.executeGesture.swipe({x1:n,y1:s,x2:a,y2:c},l,{perf:u,signal:p})}let m=await this.iosVoiceOverDetector.resolveState(this.device.deviceId,this.iosClient,{featureFlags:this.featureFlags});if(o(p),m!==!0){let h=m===null?Ke:void 0,f=d?await this.executeBoomerangGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:l,boomerang:d,perf:u,signal:p}):await this.executeGesture.swipe({x1:n,y1:s,x2:a,y2:c},l,{perf:u,signal:p});return zl(f,h)}if(d)return this.voiceOverScrollFailure({x1:n,y1:s,x2:a,y2:c},l?.duration??300,"VoiceOver boomerang gestures are not supported because they require XCTest-synthesized touches, which do not reach VoiceOver");return this.voiceOverScrollFailure({x1:n,y1:s,x2:a,y2:c},l?.duration??300,"VoiceOver scrolling is not supported: CtrlProxy only provides XCTest-synthesized touches, which do not reach VoiceOver")}async executeBoomerangGesture({x1:n,y1:s,x2:a,y2:c,gestureOptions:l,boomerang:u,perf:d=new B,signal:p}){let m=l?.duration??300,h=Zf({boomerang:!0,apexPause:u.apexPauseMs,returnSpeed:u.returnSpeed},m);if(h)throw new t(h);let f=P({forwardDuration:m,returnSpeed:u.returnSpeed}),S=m+u.apexPauseMs+f,y=this.buildGestureOptions(l,m),b=this.buildGestureOptions(l,f),w=await this.executeGesture.swipe({x1:n,y1:s,x2:a,y2:c},y,{perf:d,signal:p});if(!w.success)return o(p),w;let v=await Qx({timer:this.timer,apexPauseMs:u.apexPauseMs,signal:p,returnSwipe:()=>this.executeGesture.swipe({x1:a,y1:c,x2:n,y2:s},b,{perf:d,signal:p})});if(!v.success)return{...v,x1:n,y1:s,x2:a,y2:c,duration:S};return{...w,x1:n,y1:s,x2:a,y2:c,duration:S}}voiceOverScrollFailure(n,s,a){let{x1:c,y1:l,x2:u,y2:d}=n;return{success:!1,error:a,x1:c,y1:l,x2:u,y2:d,duration:s,fallbackReason:"XCTest-synthesized touches do not reach VoiceOver; no gesture fallback is available"}}buildGestureOptions(n,s){return{...n??{},duration:s}}}function Je(n){if(n.device.platform==="watchos")return{executeSwipeGesture:async()=>Wl("VoiceOver swipe")};return ze(n.device,new Qe({...n,iosClient:_.getInstance(n.device)}))}function Ze(n){let s=n.error??"iOS lock-screen swipe failed";return n.outcomeIndeterminate===!0?new z(s):new t(s)}function Oe(n){return n.success||n.outcomeIndeterminate===!0}var cr=150,lr=250;class Ee{request;deps;host;perf;observe;observationFence;lastObservation;containerElement;lookForOptions;maxTime=0;maxSwipes=0;startTime=0;foundElement=null;scrollIteration=0;lastFingerprint="";unchangedScrollCount=0;maxUnchangedScrolls=1;scopeDescription="";target="";accessibilityWarnings=new Set;isTalkBackEnabled=!1;searchDragState={};overlapRecoveryUsed=!1;interruptedDisplay;swipeWarning;lastAndroidSwipeError;reverseMode=!1;reverseDirection;reverseOptions;fallbackLogged=!1;webScroll;onSearchFallback=()=>{if(!this.fallbackLogged)e.debug("[SwipeOn] lookFor using slow ADB swipe fallback (600ms, at most 75% viewport)"),this.fallbackLogged=!0};constructor(n,s,a,c){this.request=n;this.deps=s;this.host=a;this.perf=c;this.observe=n.strategy?.observe??((l)=>s.observeScreen.execute({freshness:l?.freshness??"cached-ok",timeoutMs:l?.timeoutMs,skipScreenshot:!0,skipAccessibilityAudit:!0,signal:n.signal}))}async execute(){if(await this.initialize(),await this.initialSearch(),this.foundElement)return this.initialSuccess();if(await this.scrollWebElementIntoView(),this.foundElement)return this.initialSuccess();this.initializeLoop();while(this.deps.timer.now()-this.startTime<this.maxTime&&this.scrollIteration<this.maxSwipes){let n=this.createStep(),s=await this.dispatchStep(n);if(s.kind==="interrupted")break;if(s.kind==="failed")return s.result;if(await this.settleAndSearch(),this.foundElement)break;let a=await this.recoverAndSearch(n,s.failedAndroidSwipe);if(this.foundElement)break;let c=await this.recheckStaleObservation(a);if(this.foundElement)break;await this.finishIteration({recoveryAttempted:a,currentFingerprint:c,failedAndroidSwipe:s.failedAndroidSwipe,chromeStartWarning:n.chromeStartWarning})}return this.finish()}async initialize(){if(o(this.request.signal),e.info(`[SwipeOn] Starting scroll-until-visible: direction=${this.request.options.direction}, lookFor=${JSON.stringify(this.request.options.lookFor)}`),this.observationFence=this.request.strategy?void 0:this.deps.captureDisplayFence?.(),this.lastObservation=await this.perf.track("initialObserve",async()=>T(await this.observe(),(n)=>this.observe({freshness:"fresh",timeoutMs:n}),this.deps.timer,this.request.signal)),o(this.request.signal),!this.lastObservation.viewHierarchy||!this.lastObservation.screenSize)throw Error("Failed to get initial observation for scrolling until visible.");this.containerElement=await this.perf.track("findContainer",()=>this.host.findScrollableContainer(this.request.options,this.lastObservation,this.request.strategy?this.host.screenBoundsContainer({observation:this.lastObservation,includeSystemInsets:this.request.options.includeSystemInsets}):void 0)),e.info(`[SwipeOn] Using container: bounds=${JSON.stringify(this.containerElement.bounds)}, scrollable=${this.containerElement.scrollable}`),this.lookForOptions=this.host.resolveLookForOptions(this.request.options,this.containerElement,this.lastObservation),this.maxTime=this.request.options.lookFor.maxTime??15000,this.maxSwipes=this.request.options.lookFor.maxSwipes??Number.POSITIVE_INFINITY,this.startTime=this.deps.timer.now(),this.foundElement=null,this.scrollIteration=0,this.lastFingerprint=this.host.computeHierarchyFingerprint(this.lastObservation.viewHierarchy),this.unchangedScrollCount=0,this.maxUnchangedScrolls=1,this.scopeDescription=Be(this.request.options),this.target=this.request.options.lookFor.text?`text "${this.request.options.lookFor.text}"`:`element with id "${this.request.options.lookFor.elementId}"`,e.info(`[SwipeOn] Looking for ${this.target} with maxTime=${this.maxTime}ms`),this.accessibilityWarnings=new Set,this.isTalkBackEnabled=await this.perf.track("checkTalkBack",async()=>{if(o(this.request.signal),this.request.strategy||this.deps.device.platform!=="android")return!1;let n=await this.deps.accessibilityDetector.resolveTalkBackState(this.deps.device.deviceId,this.deps.adb,this.deps.featureFlags);if(n===null)this.accessibilityWarnings.add(ba);return n===!0})}async initialSearch(){if(this.foundElement=await this.perf.track("initialSearch",()=>this.host.findElementInHierarchy(this.request.options.lookFor,this.lastObservation.viewHierarchy,{container:this.request.options.container,containerElement:this.containerElement,layer:this.request.options.layer})),this.foundElement&&!this.host.isElementWithinContainer(this.foundElement,this.containerElement.bounds,this.lastObservation))e.info(`[SwipeOn] Found ${this.target} initially but it is outside container bounds (element center y=${Math.floor((this.foundElement.bounds.top+this.foundElement.bounds.bottom)/2)}, container=${JSON.stringify(this.containerElement.bounds)}), will scroll`),this.foundElement=null}async scrollWebElementIntoView(){let n=this.deps.webScrollIntoView;if(!n||!this.webScrollApplies())return;let s=await n.scroll(this.request.options.lookFor,this.lastObservation,this.request.signal);if(!s)return;if(s.backend==="xctest"){this.webScroll=s;return}await this.deps.timer.sleep(lr),o(this.request.signal);let a=fe(this.deps.timer);if(a<=0)return;try{this.lastObservation=await this.observe({freshness:"fresh",timeoutMs:a})}catch(c){if(o(this.request.signal),c instanceof Error&&c.name==="AbortError")throw c;e.warn(`[SwipeOn] Read after the page scrolled failed: ${r(c)}`,c);return}if(o(this.request.signal),await this.initialSearch(),this.foundElement)this.webScroll=s}webScrollApplies(){let{container:n,layer:s,lookFor:a}=this.request.options;return!this.request.strategy&&this.deps.device.platform==="ios"&&n===void 0&&s===void 0&&!W(a)}webScrollFields(){if(!this.webScroll)return{};return this.webScroll.backend==="xctest"?{backend:"xctest",fallbackReason:this.webScroll.fallbackReason}:{backend:"sdk"}}async initialSuccess(){if(!this.foundElement)throw Error("Initial search did not find an element");if(e.info(`[SwipeOn] Element already visible at bounds=${JSON.stringify(this.foundElement.bounds)}, no scrolling needed`),this.isTalkBackEnabled&&this.request.options.focusTarget)o(this.request.signal),await this.host.setAccessibilityFocusOnElement(this.foundElement,this.perf);return this.perf.end(),o(this.request.signal),await this.deps.captureTerminalObservationScreenshot?.(this.lastObservation,this.perf),{success:!0,targetType:"element",element:this.foundElement,found:!0,...this.accessibilityWarnings.size?{warnings:[...this.accessibilityWarnings]}:{},scrollIterations:0,elapsedMs:this.deps.timer.now()-this.startTime,...this.webScrollFields(),x1:0,y1:0,x2:0,y2:0,duration:0,observation:this.lastObservation}}initializeLoop(){this.searchDragState={},this.overlapRecoveryUsed=!1,this.reverseMode=!1,this.reverseDirection=YI(this.request.options.direction),this.reverseOptions={...this.lookForOptions,speed:"slow"}}createStep(){o(this.request.signal),this.scrollIteration++,e.info(`[SwipeOn] Iteration ${this.scrollIteration}: elapsed=${this.deps.timer.now()-this.startTime}ms, reverseMode=${this.reverseMode}, unchangedScrollCount=${this.unchangedScrollCount}/${this.maxUnchangedScrolls}`);let n=this.host.resolveContainerSwipeCoordinates(this.request.options,this.lastObservation.viewHierarchy,this.containerElement,this.lastObservation);this.swipeWarning=n.warning??this.swipeWarning;let s=this.host.resolveReverseBounds(this.request.options,this.containerElement,this.lastObservation),a=this.host.computeHalfScreenReverseCoords(this.reverseDirection,s),c=ie(this.lastObservation,this.containerElement),l=this.deps.device.platform==="android"&&this.request.strategy&&!this.reverseMode?re(n,s):this.reverseMode?a:n,u=this.reverseMode?this.reverseDirection:this.request.options.direction,d=this.deps.getDuration(this.request.strategy&&this.deps.device.platform==="android"?{...this.lookForOptions,duration:void 0,speed:"slow"}:this.reverseMode?this.reverseOptions:this.lookForOptions),{startX:p,startY:m,endX:h,endY:f}=l,S=AD({observation:this.lastObservation,platform:Q(this.deps.device.platform,"swipeOn"),startX:Math.floor(p),startY:Math.floor(m)});return e.info(`[SwipeOn] Swipe: direction=${u}, coords=(${Math.floor(p)},${Math.floor(m)})\u2192(${Math.floor(h)},${Math.floor(f)}), duration=${d}ms`),{previousKeys:c,chromeStartWarning:S,dispatch:{coordinates:l,direction:u,duration:d,options:this.request.options,containerElement:this.containerElement,observation:this.lastObservation,observationFence:this.observationFence,strategy:this.request.strategy,scrollIteration:this.scrollIteration,perf:this.perf,progress:this.request.progress,signal:this.request.signal,onSearchFallback:this.onSearchFallback,searchDragState:this.searchDragState,swipes:this.request.swipes}}}async dispatchStep(n){this.searchDragState.pagingStep=!1;let s=await this.host.dispatchSearchSwipe(n.dispatch);o(this.request.signal);for(let l of s.warnings??[])this.accessibilityWarnings.add(l);if(s.observation?.viewHierarchy)this.lastObservation=s.observation;if(s.staleDisplay&&!s.outcomeIndeterminate)return this.interruptedDisplay=s.staleDisplay,this.foundElement=await this.host.matchInterruptedDisplaySearch(this.request.options,this.lastObservation,this.containerElement,this.interruptedDisplay),{kind:"interrupted"};let a=await this.validateIosSwipe(s);if(a)return{kind:"failed",result:a};let c=this.validateAndroidSwipe(s);if(!s.observation?.viewHierarchy)throw Error("Lost observation after swipe during scroll until visible.");return{kind:"continue",failedAndroidSwipe:c}}async validateIosSwipe(n){if(!n.success&&n.outcomeIndeterminate&&this.deps.device.platform==="ios")throw this.perf.end(),new t(`${n.error??"iOS scroll swipe outcome is indeterminate."} The scroll may have happened. Observe before retrying.`);if(!n.success&&this.deps.device.platform==="ios")return this.perf.end(),o(this.request.signal),await this.deps.captureTerminalObservationScreenshot?.(this.lastObservation,this.perf),{...n,targetType:"screen",found:!1,scrollIterations:this.scrollIteration,elapsedMs:this.deps.timer.now()-this.startTime};return}validateAndroidSwipe(n){let s=this.deps.device.platform==="android"&&!n.success;if(s){let a=n.error??"Android scroll swipe failed";if(n.outcomeIndeterminate)throw this.perf.end(),new t(`${a} The scroll may have happened. Observe before retrying.`);if(this.lastAndroidSwipeError!==void 0||!n.observation?.viewHierarchy)throw this.perf.end(),new t(`Scroll swipe failed: ${a}`);this.lastAndroidSwipeError=a,e.warn(`[SwipeOn] Scroll swipe failed; tolerating one rejection: ${a}`)}else this.lastAndroidSwipeError=void 0;return s}async settleAndSearch(){if(this.host.computeHierarchyFingerprint(this.lastObservation.viewHierarchy)===this.lastFingerprint)e.warn(`[SwipeOn] iter=${this.scrollIteration} post-swipe fingerprint matches pre-swipe \u2014 `+"observation may be stale (cache hit) or swipe had no visible effect");let s=this.deps.timer.now()-this.startTime,a=Math.min(1500,Math.max(0,this.maxTime-s-300));if(a>100)this.lastObservation=await jI(this.lastObservation,{observe:this.observe,timer:this.deps.timer,maxWaitMs:a,pollIntervalMs:cr,logPrefix:"[SwipeOn]",signal:this.request.signal});this.foundElement=await this.host.findVisibleSearchTarget(this.request.options,this.lastObservation,this.containerElement)}async recoverAndSearch(n,s){let a=!1;if(this.host.shouldGuardSearchStep({failedAndroidSwipe:s,reverseMode:this.reverseMode,overlapRecoveryUsed:this.overlapRecoveryUsed,searchDragState:this.searchDragState})){let c=await this.host.recoverSearchObservation({previousKeys:n.previousKeys,observe:this.observe,deadline:this.startTime+this.maxTime,dispatch:{...n.dispatch,observation:this.lastObservation},onRecovery:()=>{a=!0,this.overlapRecoveryUsed=!0}});this.lastObservation=c.observation,this.interruptedDisplay=c.staleDisplay}if(a)this.foundElement=await this.host.findVisibleSearchTarget(this.request.options,this.lastObservation,this.containerElement);return a}async recheckStaleObservation(n){let s=this.host.computeHierarchyFingerprint(this.lastObservation.viewHierarchy);if(!n&&s===this.lastFingerprint&&this.lastObservation.freshness?.isFresh===!1)e.info(`[SwipeOn] Iteration ${this.scrollIteration}: stale unchanged observation; re-observing once before scroll-end decision`),this.lastObservation=await this.observe(),s=this.host.computeHierarchyFingerprint(this.lastObservation.viewHierarchy),this.foundElement=await this.host.findVisibleSearchTarget(this.request.options,this.lastObservation,this.containerElement);return s}async finishIteration({recoveryAttempted:n,currentFingerprint:s,failedAndroidSwipe:a,chromeStartWarning:c}){let l=n||s!==this.lastFingerprint;if(e.info(`[SwipeOn] Iteration ${this.scrollIteration}: hierarchy ${l?"changed":"UNCHANGED"} (fingerprint[0:40]="${s.slice(0,40)}")`),this.containerElement=await this.host.findScrollableContainer(this.request.options,this.lastObservation,this.containerElement),!l&&c)throw this.perf.end(),new t(`${c} Cannot determine end of container from this swipe. Retry without includeSystemInsets.`);if(!a&&!l&&this.lastObservation.freshness?.isFresh!==!1){if(this.unchangedScrollCount++,e.info(`[SwipeOn] Iteration ${this.scrollIteration}: unchanged count now ${this.unchangedScrollCount}/${this.maxUnchangedScrolls}`),this.unchangedScrollCount>=this.maxUnchangedScrolls)this.host.checkReverseExhausted(this.reverseMode,{perf:this.perf,startTime:this.startTime,maxUnchangedScrolls:this.maxUnchangedScrolls,target:this.target,scopeDescription:this.scopeDescription,scrollIteration:this.scrollIteration}),this.reverseMode=!0,this.unchangedScrollCount=0,e.info(`[SwipeOn] Reached end in forward direction without finding ${this.target}, switching to reverse half-screen recovery`)}else if(l)this.unchangedScrollCount=0,this.lastFingerprint=s;e.info(`[SwipeOn] Iteration ${this.scrollIteration}: ${this.target} not yet found`)}async finish(){if(!this.foundElement){o(this.request.signal),this.perf.end();let n=this.deps.timer.now()-this.startTime;if(this.lastAndroidSwipeError!==void 0)throw new t(`Scroll swipe failed: ${this.lastAndroidSwipeError}`);throw new t(`${this.target} not found${this.scopeDescription} after scrolling for ${n}ms (${this.scrollIteration} iterations, timeout=${this.maxTime}ms).`)}if(this.isTalkBackEnabled&&this.request.options.focusTarget)o(this.request.signal),await this.host.setAccessibilityFocusOnElement(this.foundElement,this.perf);return this.perf.end(),o(this.request.signal),await this.deps.captureTerminalObservationScreenshot?.(this.lastObservation,this.perf),{success:!0,targetType:"element",element:this.foundElement,found:!0,scrollIterations:this.scrollIteration,elapsedMs:this.deps.timer.now()-this.startTime,...this.webScrollFields(),observation:this.lastObservation,x1:0,y1:0,x2:0,y2:0,duration:0,warning:this.swipeWarning,...this.accessibilityWarnings.size?{warnings:[...this.accessibilityWarnings]}:{},...this.interruptedDisplay?{staleDisplay:this.interruptedDisplay}:{}}}}function et(n,s){if(n===s)return[n];let a=Array.isArray(n.node)?n.node:n.node?[n.node]:[];for(let c of a){let l=et(c,s);if(l)return[n,...l]}return}function tt({hierarchy:n,element:s,direction:a,parser:c,scrollsInDirection:l}){let u=mt(s);if(!u||l(s,a))return s;let d=[...c.extractRootNodes(n),...c.extractWindowRootNodes(n,"topmost-first")];for(let p of d){let m=et(p,u);if(!m)continue;for(let h of m.slice(0,-1).reverse()){let f=c.parseNodeBounds(h);if(f&&l(f,a))return f}return s}return s}function ae({geometry:n,overlayDetector:s,options:a,viewHierarchy:c,containerElement:l,observeResult:u,platform:d}){let p={observation:u,platform:d,includeSystemInsets:a.includeSystemInsets},m=wk({...p,bounds:l.bounds}),h=(w)=>{let v=AD({...p,...w});return v?{...w,warning:[w.warning,v].filter(Boolean).join(" ")}:w},f=n.getSwipeWithinBounds(a.direction,m),S=s.collectOverlayCandidates(c,l);if(S.length===0)return h(f);let y=S.map((w)=>w.overlapBounds),b=s.computeSafeSwipeCoordinates(a.direction,m,y);if(!b)return h({...f,warning:"No unobstructed swipe area found; using container bounds."});return h(b)}var ur=150,dr=10,pr=1000;class le{deps;static MAX_ATTEMPTS=5;searchable=new we;parser=new G;autoTarget=new X;resolver;constructor(n){this.deps=n;this.resolver=n.resolver??new ar}swipePlatform(){return Q(this.deps.device.platform,"swipeOn")}resolveSwipeTarget(n,s,a){return tt({hierarchy:n,element:s,direction:a,parser:this.parser,scrollsInDirection:(c,l)=>this.autoTarget.scrollsInDirection(c,l)})}resolveNamedSwipeContainer(n,s){let a=this.resolveElement(n,s.container);return a&&this.resolveSwipeTarget(n,a,s.direction)}resolveElement(n,s,a="inspect",c=!1){let l=this.resolver.resolve({id:String(n.updatedAt??"swipe"),nodes:this.searchable.project(n)},s,{action:a});if(od(l.error))return null;if(l.error)throw new t(l.error,{containerFailure:l.containerFailure});return c?da(l,s)?.element??null:l.chosen?.element??null}resolveSwipeContainer(n,s){let a=this.resolver.resolve({id:String(n.updatedAt??"swipe"),nodes:this.searchable.project(n)},{container:s},{action:"inspect"});if(a.error)throw new t(a.error,{containerFailure:a.containerFailure});let c=a.scope?.element;if(!c)throw new t(`Container level 1 not found: ${s.elementId??s.text}`,{containerFailure:{level:1,reason:"not-found",selector:s}});return c}async execute(n,s,a,c){let{progress:l,perf:u=new B,signal:d}=CQ(s,a,c);return this.executeWithStrategy({options:n,progress:l,perf:u,signal:d})}async executeWithStrategy(n){let s={dispatched:0};try{return await J(()=>new Ee({...n,swipes:s},this.deps,{findScrollableContainer:(...a)=>this.findScrollableContainer(...a),screenBoundsContainer:(...a)=>this.screenBoundsContainer(...a),resolveLookForOptions:(...a)=>this.resolveLookForOptions(...a),computeHierarchyFingerprint:(...a)=>this.computeHierarchyFingerprint(...a),findElementInHierarchy:(...a)=>this.findElementInHierarchy(...a),isElementWithinContainer:(...a)=>this.isElementWithinContainer(...a),setAccessibilityFocusOnElement:(...a)=>this.setAccessibilityFocusOnElement(...a),resolveContainerSwipeCoordinates:(...a)=>this.resolveContainerSwipeCoordinates(...a),resolveReverseBounds:(...a)=>this.resolveReverseBounds(...a),computeHalfScreenReverseCoords:(...a)=>this.computeHalfScreenReverseCoords(...a),dispatchSearchSwipe:(...a)=>this.dispatchSearchSwipe(...a),matchInterruptedDisplaySearch:(...a)=>this.matchInterruptedDisplaySearch(...a),findVisibleSearchTarget:(...a)=>this.findVisibleSearchTarget(...a),shouldGuardSearchStep:(...a)=>this.shouldGuardSearchStep(...a),recoverSearchObservation:(...a)=>this.recoverSearchObservation(...a),checkReverseExhausted:(...a)=>this.checkReverseExhausted(...a)},n.perf??new B).execute())}catch(a){throw $e(a,n.signal,s)}}checkReverseExhausted(n,s){let{perf:a,startTime:c,maxUnchangedScrolls:l,target:u,scopeDescription:d,scrollIteration:p}=s;if(n){a.end();let m=this.deps.timer.now()-c;throw new t(`Scroll reached end of container (no change after ${l} scrolls). ${u} not found${d} after ${p} iterations (${m}ms).`)}}resolveLookForOptions(n,s,a){let c=s.bounds.bottom-s.bounds.top,l=a.screenSize.height,u=c/l*100,d=n.speed;if(u>=80){if(!d||d==="fast")d="normal",e.info(`[SwipeOn] Container is ${u.toFixed(1)}% of screen height, limiting lookFor speed to "normal"`)}else if(!d||d==="normal"||d==="fast")d="slow",e.info(`[SwipeOn] Container is ${u.toFixed(1)}% of screen height, limiting lookFor speed to "slow"`);return{...n,speed:d}}shouldGuardSearchStep(n){return this.deps.device.platform==="android"&&!n.failedAndroidSwipe&&!n.reverseMode&&!n.overlapRecoveryUsed&&!n.searchDragState.pagingStep}async findVisibleSearchTarget(n,s,a){let c=await this.findScrollableContainer(n,s,a),l=await this.findElementInHierarchy(n.lookFor,s.viewHierarchy,{container:n.container,containerElement:c,layer:n.layer});return l&&this.isElementWithinContainer(l,c.bounds,s)?l:null}async recoverSearchObservation({previousKeys:n,dispatch:s,observe:a,deadline:c,onRecovery:l}){let{options:u,containerElement:d}=s,p;return{observation:await Ve({previousKeys:n,observation:s.observation,timer:this.deps.timer,deadline:c,signal:s.signal,hasTarget:async(h)=>Boolean(await this.findVisibleSearchTarget(u,h,d)),keys:async(h)=>ie(h,await this.findScrollableContainer(u,h,d)),backScroll:async(h)=>{l();let f=await this.performOverlapBackScroll({...s,observation:h},a,c);return p=f.staleDisplay,f.observation}}),staleDisplay:p}}async performOverlapBackScroll(n,s,a){let{options:c,observation:l,signal:u}=n,d=await this.findScrollableContainer(c,l,n.containerElement),p=YI(n.direction),m=await this.dispatchSearchSwipe({...n,coordinates:this.computeHalfScreenReverseCoords(p,this.resolveReverseBounds(c,d,l)),direction:p,duration:this.deps.getDuration({...c,speed:"slow"}),containerElement:d});if(o(u),m.outcomeIndeterminate)throw new t(m.error??"Recovery scroll outcome is indeterminate");if(m.staleDisplay)return await this.matchInterruptedDisplaySearch(c,m.observation,d,m.staleDisplay),{observation:m.observation,staleDisplay:m.staleDisplay};if(!m.success||!m.observation?.viewHierarchy)return e.debug("[SwipeOn] Overlap recovery unavailable; continuing forward",m.error),{observation:l};if(await this.findVisibleSearchTarget(c,m.observation,d))return{observation:m.observation};return{observation:await jI(m.observation,{observe:s,timer:this.deps.timer,maxWaitMs:Math.min(1500,Math.max(0,a-this.deps.timer.now())),pollIntervalMs:ur,logPrefix:"[SwipeOn] overshoot",signal:u})}}async dispatchSearchSwipe({coordinates:n,direction:s,duration:a,options:c,containerElement:l,observation:u,observationFence:d,strategy:p,scrollIteration:m,perf:h,progress:f,signal:S,onSearchFallback:y,searchDragState:b,swipes:w}){let{startX:v,startY:O,endX:E,endY:g}=n;GT(u.viewHierarchy,c.layer,[{x:Math.floor(v),y:Math.floor(O)}],"swipe");let x=a,I=s,D=u,ue=this.deps.resolveBoomerangConfig(c),L={duration:x,scrollMode:c.scrollMode,searchScroll:this.deps.device.platform==="android",searchScrollBounds:this.resolveReverseBounds(c,l,u),onSearchFallback:y,searchDragState:b},F;if(p)o(S);let N=!1,K=()=>{if(!N)N=!0,w.dispatched++};return p?await p.swipe({x1:Math.floor(v),y1:Math.floor(O),x2:Math.floor(E),y2:Math.floor(g),duration:x,holdDurationMs:this.deps.device.platform==="android"?ee:void 0,onSearchFallback:y,searchDragState:b,previousObservation:D,onDispatched:K}):await this.deps.observedInteraction(async(vr,ut)=>{L.displayFence={assertCurrent:()=>{d?.assertCurrent(),ut?.assertCurrent()}},o(S),w.dispatched++;let Re=this.deps.device.platform==="ios"?this.deps.voiceOverExecutor:this.deps.talkBackExecutor;if(!Re)throw Error("VoiceOver swipe runner is not configured for iOS scroll-until-visible");let de=await Re.executeSwipeGesture({x1:Math.floor(v),y1:Math.floor(O),x2:Math.floor(E),y2:Math.floor(g),direction:I,containerElement:l,gestureOptions:L,perf:h,boomerang:ue,signal:S});if(this.deps.device.platform==="ios"&&(de.success||de.outcomeIndeterminate))F=this.deps.timer.now(),_.getExistingInstance(this.deps.device.deviceId)?.invalidateCache();return de},{...Ht.selectorResolvedGesture,timeoutMs:wt.brief,progress:f,perf:h,signal:S,previousObservation:D,deferPostActionScreenshot:!0,observationTimestampProvider:()=>F,predictionContext:{toolName:"swipeOn",toolArgs:this.deps.buildPredictionArgs(c)}})}async matchInterruptedDisplaySearch(n,s,a,c){let l=await this.findElementInHierarchy(n.lookFor,s.viewHierarchy,{container:n.container,containerElement:a,layer:n.layer});if(l&&this.isElementWithinContainer(l,a.bounds,s))return l;throw new mr(new _e(c))}async findTargetElement(n,s,a=0,c){o(c);let l=null;if(!n.container)throw new t("Container must be specified for element swipe");if(s=gi(s,n.layer),!n.container.text&&!n.container.elementId)throw new t("Container must specify either text or elementId");if(A(n.container))return this.resolveSwipeContainer(s,n.container);if(l=this.resolveElement(s,n.container,"inspect",n.container.text!==void 0),!l&&a<le.MAX_ATTEMPTS){let u=te({initialDelayMs:dr,maxDelayMs:pr}).delayForAttempt(a+1);await this.deps.timer.sleep(u),o(c);let d=await this.refreshContainerHierarchy(n.container,c);if(d)return e.info(`Retrying to find element after ${u}ms delay`),await this.findTargetElement(n,d,a+1,c)}if(!l)if(n.container.text)throw new t(`Element not found with provided text '${n.container.text}'`);else throw new t(`Element not found with provided elementId '${n.container.elementId}'`);return this.resolveSwipeTarget(s,l,n.direction)}async refreshContainerHierarchy(n,s){switch(this.deps.device.platform){case"android":let a={query:n.text||n.elementId||"",containerElementId:void 0};return await this.deps.accessibilityService.getAccessibilityHierarchy(a,{disableAllFiltering:M.isRawElementSearchEnabled()});case"ios":return(await this.deps.observeScreen.execute({freshness:"cached-ok",skipScreenshot:!0,skipAccessibilityAudit:!0,signal:s})).viewHierarchy;default:throw yt(this.deps.device.platform,"scroll until visible")}}async findScrollableContainer(n,s,a=this.screenBoundsContainer({observation:s})){let c=null,l=gi(s.viewHierarchy,n.layer);if(n.container){if(A(n.container))return this.resolveSwipeContainer(l,n.container);if(n.container.elementId||n.container.text)c=this.resolveNamedSwipeContainer(l,n)}if(!c){if(c=[...this.resolver.resolve({id:String(l.updatedAt??"swipe"),nodes:this.searchable.project(l)},{},{action:"scroll"}).candidates].sort((p,m)=>Number(p.rootGroup!==0)-Number(m.rootGroup!==0)).find((p)=>p.element)?.element??null,c)e.info("[SwipeOn] Found scrollable container automatically")}if(!c)e.info("[SwipeOn] No scrollable container found, using fallback bounds"),c=a;return c}screenBoundsContainer({observation:n,includeSystemInsets:s}){let a={observation:n,platform:this.swipePlatform(),includeSystemInsets:s},c=Wm(a)||{width:1080,height:1920};return{bounds:La(c,Sk(a)),scrollable:!0}}async findElementInHierarchy(n,s,{container:a,containerElement:c,layer:l}={}){if(!n.text&&!n.elementId)return null;if(s=gi(s,l),!A(a)&&!W(n))return this.resolveElement(s,{...n,container:a},"inspect",!0);let u=A(a)?c:a?this.resolveElement(s,a):void 0;return Ge({lookFor:n,container:A(a)||u?a:void 0,containerElement:u??void 0,resolver:this.resolver,nodes:this.searchable.project(s),id:String(s.updatedAt??"swipe")})}computeHierarchyFingerprint(n){return j(n)}async setAccessibilityFocusOnElement(n,s){try{await s.track("setAccessibilityFocus",async()=>{let a=n["resource-id"];if(!a){e.warn("[SwipeOn] Cannot set accessibility focus: element has no resource-id");return}await this.deps.accessibilityService.requestAction("focus",a,5000,{perf:s}),e.info(`[SwipeOn] Set accessibility focus on element: ${a}`)})}catch(a){e.warn(`[SwipeOn] Failed to set accessibility focus: ${a}`)}}isElementWithinContainer(n,s,a){let c=(n.bounds.top+n.bounds.bottom)/2,l=(n.bounds.left+n.bounds.right)/2,u=c>=s.top&&c<=s.bottom&&l>=s.left&&l<=s.right;return this.deps.device.platform==="ios"?this.isIosElementWithinContainer(n,s,a,u):u}isIosElementWithinContainer(n,s,a,c){let l=a.viewHierarchy,u=Wm({observation:a,platform:"ios"});if(!l||!u)return c;let d=new Qc().collect(l,"ios"),p=d&&kD(d,n),m=D3(l,{observationScreenSize:a.screenSize});if(!p&&!Object.values(m).some((D)=>D>0))return c;let h=La(u,a.systemInsets??l.systemInsets),f={left:Math.max(s.left,h.left),top:Math.max(s.top,h.top),right:Math.min(s.right,h.right),bottom:Math.min(s.bottom,h.bottom)},S=PD({bounds:n.bounds,hierarchy:l,screen:u,elements:[n],forTapTarget:!0}).bounds;if(!S)return!1;let y=PD({bounds:f,hierarchy:l,screen:u,elements:[n]}).bounds;if(!y)return!1;let b={left:Math.max(S.left,y.left),top:Math.max(S.top,y.top),right:Math.min(S.right,y.right),bottom:Math.min(S.bottom,y.bottom)},{left:w,top:v,right:O,bottom:E}=b,g=p&&Rk(p,u).bounds,x=this.deps.geometry.getElementCenter({bounds:b});return(g?[RR([w,v,O,E],g),x]:[x]).some((D)=>D!==null&&Number.isInteger(D.x)&&Number.isInteger(D.y)&&this.deps.geometry.isPointInElement({bounds:b},D.x,D.y)&&D.x<O&&D.y<E&&!(g&&D.x>=g[0]&&D.x<g[2]&&D.y>=g[1]&&D.y<g[3]))}computeHalfScreenReverseCoords(n,s){let a=(s.left+s.right)/2,c=(s.top+s.bottom)/2,l=s.bottom-s.top,u=s.right-s.left;switch(n){case"down":return{startX:a,startY:s.top+l*0.25,endX:a,endY:s.top+l*0.75};case"up":return{startX:a,startY:s.bottom-l*0.25,endX:a,endY:s.top+l*0.25};case"right":return{startX:s.left+u*0.25,startY:c,endX:s.left+u*0.75,endY:c};case"left":return{startX:s.right-u*0.25,startY:c,endX:s.left+u*0.25,endY:c}}}resolveReverseBounds(n,s,a){return wk({observation:a,platform:this.swipePlatform(),includeSystemInsets:n.includeSystemInsets,bounds:s.bounds})}resolveContainerSwipeCoordinates(n,s,a,c){return ae({geometry:this.deps.geometry,overlayDetector:this.deps.overlayDetector,options:n,viewHierarchy:s,containerElement:a,observeResult:c,platform:this.swipePlatform()})}}function xe(n,s){if(!n)return;let{bundleId:a,navigationRoute:c,navigationTitle:l,presentation:u,modalClass:d}=n.components;if(!c&&!l&&!u&&!d)return;return{kind:`${s}:${n.platform}:${n.source}`,key:JSON.stringify([a,c,l,u,d]),name:l??c??d??u??"",title:l}}function rt(n){let s=n.activeWindow;if(!s?.appId||!s.activityName)return;return{kind:"window",key:JSON.stringify([s.appId,s.activityName]),name:s.activityName}}function hr(n){return xe(Kw(n.viewHierarchy,n.screenSize),"hierarchy")}function fr(n){return xe(SV(n.viewHierarchy),"hierarchy")}function it(n){return xe(n.screenIdentity,"reported")}function Sr(n,s,a){let c=a==="ios"?[hr,it,rt]:[it,fr,rt];for(let l of c){let u=l(n),d=l(s);if(u&&d&&u.kind===d.kind)return[u,d]}return}function nt(n){return n.trim().replace(/\s+/g," ").toLowerCase()}function wr(n,s){let a=nt(n),c=nt(s);if(!c)return!1;return a===c||a.startsWith(c)&&!/[\p{L}\p{N}]/u.test(a.charAt(c.length))}function br(n,s,a){if(!n.viewHierarchy)return;let c=qm(new we().project(n.viewHierarchy));for(let l of SD(c,s)){let u=[l.displayedLabel,l.label,...l.textFields].find((d)=>typeof d==="string"&&wr(d,a));if(u)return u}return}function ot(n,s,a,c){if(!n||!s)return;let l=Sr(n,s,c);if(!l)return;let[u,d]=l;if(u.key===d.key)return u.kind==="window"?void 0:{navigated:!1};let p=`"${u.name}" to "${d.name}"`,m=d.title?br(n,a,d.title):void 0;return{navigated:!0,warning:m?`Swipe navigated from ${p} instead of scrolling; the new screen is titled like the element under the start point ("${m}"), so the gesture likely registered as a tap. Observe and go back before retrying.`:`Swipe navigated from ${p} instead of scrolling. If you expected a scroll, observe before retrying.`}}function at(n){let s=n?.screenIdentity;return s?.platform==="android"&&s.source==="sdk"?s.components.bundleId:void 0}async function ct(n,s,a,c){let{swipeEndedAtMs:l,source:u,reassess:d}=c,p=at(a);if(n?.navigated!==!1||!u||!p||!s||at(s)!==p||l===void 0)return n;let m=u.receivedAtMs(p);if(m!==void 0&&m>l)return n;let h=await u.awaitRouteAfter(p,l,300);if(!h)return;if(a)a.screenIdentity=h;return d()}function lt(n,s,a,c){GT(n,s,[{x:Math.floor(a),y:Math.floor(c)}],"swipe")}function yr(n,s,a){let{x1:c,y1:l,x2:u,y2:d}=se({edge:s,bounds:a,inset:n.edgeInset,at:n.at});return{startX:c,startY:l,endX:u,endY:d}}class Vl extends De{skipCallerDisplayFence;stopAfterIosGestureFailure;iosLockScreenSwipe;iosGestureTimeoutMs;lastRenderedObservation;executeGesture;scrollables;geometry;accessibilityService;accessibilityDetector;featureFlags;overlayDetector;autoTargetSelector;autoTargeting;androidDisplay;talkBackExecutor;voiceOverExecutor;scrollUntilVisible;visionConfig;screenshotCapturer;visionAnalyzer;sdkRouteSourceOverride;constructor(n,s=null,a={}){super(n,{adb:s,timer:a.timer,displayFence:a});ts(n.platform,"swipeOn"),this.skipCallerDisplayFence=a.skipCallerDisplayFence??!1,this.stopAfterIosGestureFailure=a.stopAfterIosGestureFailure??!1,this.iosLockScreenSwipe=a.iosLockScreenSwipe,this.iosGestureTimeoutMs=a.iosGestureTimeoutMs,this.lastRenderedObservation=a.lastRenderedObservation;let c=this.initializeGestureDependencies(n,s,a),l=a.featureFlags??sr.getInstance();if(this.featureFlags=l,this.visionConfig=a.visionConfig??Kp,this.screenshotCapturer=a.screenshotCapturer??new Ou(n,this.adbFactory),this.visionAnalyzer=a.visionAnalyzer,this.sdkRouteSourceOverride=a.sdkRouteSource,a.observeScreen)this.observeScreen=a.observeScreen;this.overlayDetector=new H(this.geometry,c),this.autoTargetSelector=a.autoTargetSelector??new X,this.autoTargeting=new he(n,()=>this.autoTargetSelector),this.androidDisplay=new ye(()=>({device:this.device,adb:this.adb,timer:this.timer,observeScreen:this.observeScreen,displayTransitionReader:this.displayTransitionReader,accessibilityService:this.accessibilityService,accessibilityDetector:this.accessibilityDetector,featureFlags:this.featureFlags,talkBackExecutor:this.talkBackExecutor,scrollUntilVisible:this.scrollUntilVisible,scrollables:this.scrollables,geometry:this.geometry,lastRenderedObservation:this.lastRenderedObservation,autoTargeting:this.autoTargeting,visual:this,getDuration:(u)=>this.getDuration(u),createErrorResult:(u)=>this.createErrorResult(u),observedSwipeInteraction:(u,d,p)=>this.observedSwipeInteraction(u,d,p),checkPostActionDisplay:(u,d,p)=>this.checkPostActionDisplay(u,d,p),rethrowObservationAbort:(u,d,p)=>this.rethrowObservationAbort(u,d,p),resolveContainerSwipeCoordinates:(u,d,p,m)=>this.resolveContainerSwipeCoordinates(u,d,p,m)})),this.talkBackExecutor=new ge({device:n,executeGesture:this.executeGesture,accessibilityService:this.accessibilityService,accessibilityDetector:this.accessibilityDetector,adb:this.adb,timer:this.timer,featureFlags:l}),this.voiceOverExecutor=a.voiceOverExecutor??Je({device:n,executeGesture:this.executeGesture,iosVoiceOverDetector:a.iosVoiceOverDetector??vo,timer:this.timer,featureFlags:l}),this.scrollUntilVisible=new le({device:n,resolver:a.resolver,geometry:this.geometry,observeScreen:this.observeScreen,accessibilityService:this.accessibilityService,accessibilityDetector:this.accessibilityDetector,adb:this.adb,featureFlags:l,overlayDetector:this.overlayDetector,talkBackExecutor:this.talkBackExecutor,voiceOverExecutor:this.voiceOverExecutor,webScrollIntoView:Ce(n,a.webScrollIntoView),timer:this.timer,getDuration:this.getDuration.bind(this),resolveBoomerangConfig:this.resolveBoomerangConfig.bind(this),buildPredictionArgs:this.buildPredictionArgs.bind(this),observedInteraction:this.observedInteraction.bind(this),captureDisplayFence:()=>this.captureDisplayFence(),captureTerminalObservationScreenshot:this.captureTerminalObservationScreenshot.bind(this)})}initializeGestureDependencies(n,s,a){this.executeGesture=a.executeGesture??new mA(n,s);let c=a.parser??new G;return this.scrollables=a.scrollables??new WI,this.geometry=a.geometry??new tr,this.accessibilityService=a.accessibilityService??Bs(n,this.adbFactory),this.accessibilityDetector=a.accessibilityDetector||ti,c}createErrorResult(n,s={}){return{success:!1,error:n,warning:s.warning,scrollableCandidates:s.scrollableCandidates,targetType:"screen",x1:0,y1:0,x2:0,y2:0,duration:0}}async getScrollableContext(n,s){o(n);let a=await this.observeScreen.getMostRecentCachedObserveResult(),c=qB(this.device.deviceId),l=c!==void 0||De.shouldRefetchCachedObservation(a);if(l||!a.viewHierarchy||a.viewHierarchy.hierarchy?.error)o(n),a=await this.observeScreen.execute({...ac,freshness:l?"fresh":"cached-ok",timeoutMs:Fi,skipStaleWindowRecovery:!0,signal:n});if(a=await T(a,(p)=>this.observeScreen.execute({...ac,freshness:"fresh",timeoutMs:p,skipStaleWindowRecovery:!0,signal:n}),this.timer,n),!a.viewHierarchy||a.viewHierarchy.hierarchy?.error)return{scrollables:[],candidates:[],observeResult:a};if(tg(a))return{scrollables:[],candidates:[],observeResult:a};if(c!==void 0)VB(this.device.deviceId,c);let u=this.scrollables.findScrollableElements(gi(a.viewHierarchy,s)),d=this.autoTargeting.buildScrollableCandidates(u);return{scrollables:u,candidates:d,observeResult:a}}async execute(n,s,a){let{progress:c,signal:l}=Bo(s,a);if(ts(this.device.platform,"swipeOn"),this.device.platform==="watchos")return S7(this.device.deviceId,n,l);let u=await J(()=>this.executeWithReadScope(n,c,l));return Xe(u,n)}executeExplicitDisplay(n,s={}){return this.androidDisplay.executeExplicitDisplay(n,s)}async executeWithReadScope(n,s,a){o(a);let c=await this.executeExplicitDisplay(n,{progress:s,signal:a});if(c)return c;return this.executeLegacy(n,s,a)}async executeAutoTargetSwipe({options:n,progress:s,perf:a,signal:c}){let l=await this.getScrollableContext(c,n.layer),u=this.autoTargeting.resolveAutoTargetDecision({...l,direction:n.direction,includeSystemInsets:n.includeSystemInsets}),d=u.element&&l.observeResult?await this.executeElementSwipe(n,{progress:s,perf:a,signal:c,selected:{element:u.element,observation:l.observeResult}}):u.container?await this.executeElementSwipe({...n,container:u.container},{progress:s,perf:a,signal:c,selected:l.observeResult?{observation:l.observeResult}:void 0}):await this.executeScreenSwipe(n,s,a,{signal:c,within:u.scrollFrame});return this.autoTargeting.withAutoTargetDecision({result:d,decision:u})}async executeLegacy(n,s,a){let c=Y();c.serial("swipeOn");let l=this.validateOptions(n);if(l)return c.end(),this.createErrorResult(l);let u=Mc(n);if(u.error)return c.end(),this.createErrorResult(u.error);let d={...n,direction:u.direction};e.info(`[SwipeOn] execute: direction=${d.direction}, lookFor=${JSON.stringify(d.lookFor)}, container=${JSON.stringify(d.container)}, speed=${d.speed}, autoTarget=${d.autoTarget}`);try{return await Vl.dispatchLegacySwipe(this,d,s,{perf:c,signal:a})}catch(p){if(c.end(),p instanceof V)throw p;if(eV(a,p),e.warn(`Swipe failed: ${r(p)}`,p),p instanceof _e||p instanceof mr)return ir(this.createErrorResult(p.message),p);let m=d.lookFor||d.container?await v0(this.device,Vl.legacyDebugSearchCriteria(d)):void 0;o(a);let f=`Failed to perform swipeOn: ${r(p)}`,S=Vl.legacyVisionSearchCriteria(this,d);if(S){o(a);let y=await this.observeScreen.getMostRecentCachedObserveResult(),b={visionConfig:this.visionConfig,visionAnalyzer:this.visionAnalyzer};f=await Gp(this.screenshotCapturer,y?.viewHierarchy??null,S,{...b,baseError:f})}return Vl.legacyFailureResult({action:this,normalizedOptions:d,perf:c,errorMsg:f,debugContext:m,cause:p})}}static legacyDebugSearchCriteria(n){return{text:n.lookFor?.text,resourceId:n.lookFor?.elementId||n.container?.elementId,container:n.container}}static legacyVisionSearchCriteria(n,s){if(n.visionConfig.enabled&&(s.lookFor||s.container)){let a=null;if(s.lookFor)a={text:s.lookFor.text,resourceId:s.lookFor.elementId,description:"Target element to scroll to"};else if(s.container)a={text:s.container.text,resourceId:s.container.elementId,description:"Container element for swiping"};return a}return null}static legacyFailureResult({action:n,normalizedOptions:s,perf:a,errorMsg:c,debugContext:l,cause:u}){let d=n.device.platform==="ios"?a.getTimings():null;return{success:!1,error:c,...u instanceof z?{outcomeIndeterminate:!0}:{},...be(u),...d?{timing:d}:{},targetType:s.container?"element":"screen",x1:0,y1:0,x2:0,y2:0,duration:0,...l?{debug:{elementSearch:l}}:{}}}static dispatchLegacySwipe(n,s,a,{perf:c,signal:l}){if(s.lookFor)return e.info("[SwipeOn] Mode: scroll-until-visible"),n.scrollUntilVisible.execute(s,{progress:a,perf:c,signal:l});else if(!s.container){if(s.autoTarget===!1)return e.info("[SwipeOn] Mode: screen swipe (autoTarget disabled)"),n.executeScreenSwipe(s,a,c,{signal:l});return n.executeAutoTargetSwipe({options:s,progress:a,perf:c,signal:l})}else return e.info(`[SwipeOn] Mode: element swipe (explicit container=${JSON.stringify(s.container)})`),n.executeElementSwipe(s,{progress:a,perf:c,signal:l})}validateOptions(n){if(n.container){let s=[n.container.elementId,n.container.text].filter(Boolean).length;if(s===0)return"container must specify exactly one of elementId or text";if(s>1)return"container must specify exactly one of elementId or text"}if(n.lookFor){if([n.lookFor.elementId,n.lookFor.text].filter(Boolean).length!==1)return"lookFor must specify exactly one of elementId or text"}return Zf(n,this.getDuration(n))??oe(n)}buildPredictionArgs(n){return{includeSystemInsets:n.includeSystemInsets,container:n.container,autoTarget:n.autoTarget,direction:n.direction,lookFor:n.lookFor,speed:n.speed,boomerang:n.boomerang,apexPause:n.apexPause,returnSpeed:n.returnSpeed,platform:this.device.platform}}async observedSwipeInteraction(n,s,a){let c=null,l,u=this.sdkRouteSource(),d=await this.observedInteraction(async(p,m)=>{c=p;let h=await n(p,m);return l=u?this.timer.now():void 0,h},{...s,observePartialApplication:!0});if(await this.annotateSwipeNavigation(d,c,l,u),this.device.platform!=="android")return d;if(d.effect=this.deriveInteractionEffect(c,d.observation),a.boomerang)return d;if(d.success&&d.effect?.screenChanged===!1&&d.effect.basis!=="insufficient observation data")d.warning=this.autoTargetSelector.mergeWarnings(d.warning,this.unchangedSwipeWarning(d,c));return d}sdkRouteSource(){if(this.device.platform!=="android")return;return this.sdkRouteSourceOverride??{receivedAtMs:(n)=>this.accessibilityService.getSdkScreenIdentityReceivedAtMs(n),awaitRouteAfter:(n,s,a)=>this.accessibilityService.awaitSdkScreenIdentityAfter(n,s,a)}}async annotateSwipeNavigation(n,s,a,c){if(!n.success)return;let l=()=>ot(s,n.observation,{x:n.x1,y:n.y1},Q(this.device.platform,"swipeOn")),u=await ct(l(),s,n.observation,{swipeEndedAtMs:a,source:c,reassess:l});if(!u)return;if(n.navigated=u.navigated,u.warning)e.warn(`[SwipeOn] ${u.warning}`),n.warning=this.autoTargetSelector.mergeWarnings(n.warning,u.warning)}unchangedSwipeWarning(n,s){let a=s?.viewHierarchy?this.scrollables.findScrollableElements(s.viewHierarchy):[],c=n.element&&st(n.element.scrollable)?[n.element,...a]:a;if(c.some((l)=>this.geometry.isPointInElement(l,n.x1,n.y1)))return"Swipe did not change the screen; the start point was inside the scrollable, which may already be at the end of the scrollable content.";return c.length>0?"Swipe did not change the screen; the start point was outside every scrollable region, so the gesture geometry may have prevented scrolling.":"Swipe did not change the screen; no scrollable region was found in the hierarchy."}async executeScreenSwipe(n,s,a=new B,{signal:c,within:l}={}){e.info(`[SwipeOn] Starting screen swipe: direction=${n.direction}`);let u,d=this.resolveBoomerangConfig(n);return this.observedSwipeInteraction(async(p,m)=>{o(c);let h={observation:p,platform:Q(this.device.platform,"swipeOn"),includeSystemInsets:n.includeSystemInsets,includeFloatingBars:!n.fromEdge},f=Wm(h);if(!f)throw new t("Could not determine screen size");let S=La(f,Sk(h)),y=Ere(S,l,n.fromEdge),{startX:b,startY:w,endX:v,endY:O}=n.fromEdge?yr(n,n.fromEdge,y):this.geometry.getSwipeWithinBounds(n.direction,y);lt(p.viewHierarchy,n.layer,b,w);let E=this.getDuration(n),g={displayFence:m,duration:E,scrollMode:n.scrollMode,durationExplicit:q(n),timeoutMs:this.iosGestureTimeoutMs?.(),lockScreen:this.iosLockScreenSwipe};if(g.timeoutMs!==void 0&&g.timeoutMs<=0)throw new t("iOS swipe budget exhausted before gesture dispatch");o(c);let x=await a.track("executeScreenSwipe",()=>this.device.platform==="ios"?this.voiceOverExecutor.executeSwipeGesture({x1:Math.floor(b),y1:Math.floor(w),x2:Math.floor(v),y2:Math.floor(O),direction:n.direction,containerElement:null,gestureOptions:g,perf:a,boomerang:d,signal:c,sdkObservation:n.fromEdge?void 0:p}):this.talkBackExecutor.executeSwipeGesture({x1:Math.floor(b),y1:Math.floor(w),x2:Math.floor(v),y2:Math.floor(O),direction:n.direction,containerElement:null,gestureOptions:g,perf:a,boomerang:d,signal:c}));if(this.stopAfterIosGestureFailure&&this.device.platform==="ios"&&!x.success)throw Ze(x);if(o(c),this.device.platform==="ios"&&Oe(x))u=this.timer.now(),_.getExistingInstance(this.device.deviceId)?.invalidateCache();return a.end(),{...x,targetType:"screen",warning:AD({...h,startX:Math.floor(b),startY:Math.floor(w)})}},{usesObservationForResolution:!1,changeExpected:!1,display:n.display,timeoutMs:wt.brief,progress:s,perf:a,signal:c,skipCallerDisplayFence:this.skipCallerDisplayFence,observationTimestampProvider:()=>u,predictionContext:{toolName:"swipeOn",toolArgs:this.buildPredictionArgs(n)}},{boomerang:d})}async executeElementSwipe(n,{progress:s,perf:a=new B,signal:c,selected:l}={}){e.info(`[SwipeOn] Starting element swipe: direction=${n.direction}, container=${JSON.stringify(n.container)}`);let u,d=this.resolveBoomerangConfig(n);return this.observedSwipeInteraction(async(p,m)=>{o(c),p=await T(p,(x)=>this.observeScreen.execute({...ac,freshness:"fresh",timeoutMs:x,skipStaleWindowRecovery:!0,display:n.display,signal:c}),this.timer,c);let h=p.viewHierarchy;if(!h||h.hierarchy.error)throw new t("Unable to get view hierarchy, cannot swipe on element");let f=(l?.observation.viewHierarchy===h?l.element:void 0)??await a.track("findElement",()=>this.scrollUntilVisible.findTargetElement(n,h,0,c));o(c);let{startX:S,startY:y,endX:b,endY:w,warning:v}=this.resolveContainerSwipeCoordinates(n,h,f,p);lt(h,n.layer,S,y);let O=this.getDuration(n),E={displayFence:m,duration:O,scrollMode:n.scrollMode,durationExplicit:q(n)};o(c);let g=await a.track("executeElementSwipe",()=>this.device.platform==="ios"?this.voiceOverExecutor.executeSwipeGesture({x1:Math.floor(S),y1:Math.floor(y),x2:Math.floor(b),y2:Math.floor(w),direction:n.direction,containerElement:f??null,gestureOptions:E,perf:a,boomerang:d,signal:c,sdkObservation:p}):this.talkBackExecutor.executeSwipeGesture({x1:Math.floor(S),y1:Math.floor(y),x2:Math.floor(b),y2:Math.floor(w),direction:n.direction,containerElement:f,gestureOptions:E,perf:a,boomerang:d,signal:c}));if(o(c),this.device.platform==="ios"&&Oe(g))u=this.timer.now(),_.getExistingInstance(this.device.deviceId)?.invalidateCache();return a.end(),{...g,targetType:"element",element:f,warning:v}},{previousObservation:l?.observation,resolvesTargetFromRead:!0,queryOptions:l||A(n.container)?void 0:{text:n.container?.text,elementId:n.container?.elementId,containerElementId:void 0},changeExpected:!1,display:n.display,timeoutMs:wt.brief,progress:s,perf:a,signal:c,observationTimestampProvider:()=>u,predictionContext:{toolName:"swipeOn",toolArgs:this.buildPredictionArgs(n)}},{boomerang:d})}resolveContainerSwipeCoordinates(n,s,a,c){return ae({geometry:this.geometry,overlayDetector:this.overlayDetector,options:n,viewHierarchy:s,containerElement:a,observeResult:c,platform:Q(this.device.platform,"swipeOn")})}getDuration(n){return U({...n,geometry:this.geometry})}resolveBoomerangConfig(n){return C(n)}}export{WI,V6,zI,m7,Ny,f7,h7,g7,y7,uA,jI,KI,m0,GI,f0,vS,pA,W6,YI,lq,JI,h0,g0,uq,pq,bS,SS,y0,Zf,z6,mq,j6,K6,fq,mA,Vl};
3
-
4
- //# debugId=2392CBC5A9C0C6C364756E2164756E21
@@ -1,4 +0,0 @@
1
- // @bun
2
- import{Toe,Ry,s6}from"./chunk-nwm2pq5v.js";import"./chunk-ggtd5x5a.js";import"./chunk-z8t0v07j.js";import"./chunk-mf9spd4g.js";export{Toe as createTemplateMaintenance,Ry as getDefaultSimulatorCreationService,s6 as stopTemplateBuilds};
3
-
4
- //# debugId=20DC26A9E6DFB19D64756E2164756E21
@@ -1,4 +0,0 @@
1
- // @bun
2
- import{i2}from"./chunk-zcr8he8q.js";import"./chunk-6hyt398x.js";import"./chunk-ympy4fdz.js";import"./chunk-r20pe1nv.js";import"./chunk-f9s1kkhx.js";import"./chunk-6d3mmqxt.js";import"./chunk-zg67wjkh.js";import"./chunk-h3n4adc6.js";import"./chunk-32jpxz2y.js";import"./chunk-79q5xsdc.js";import"./chunk-ggtd5x5a.js";import"./chunk-z8t0v07j.js";import"./chunk-mf9spd4g.js";export{i2 as cleanupDaemonChildProcesses};
3
-
4
- //# debugId=F2789EB0C6C5FFCF64756E2164756E21
@@ -1,4 +0,0 @@
1
- // @bun
2
- import{cq}from"./chunk-34zxqcmq.js";import"./chunk-vefd8qee.js";import"./chunk-sjn0nj4p.js";import"./chunk-4xd6zs3y.js";import"./chunk-0rjm4nx7.js";import"./chunk-pm06b05d.js";import"./chunk-bn64x5z5.js";import"./chunk-0e4gm1kj.js";import"./chunk-4fgdhcwx.js";import"./chunk-6d3mmqxt.js";import"./chunk-0w1spptt.js";import"./chunk-sns0c35v.js";import"./chunk-h3n4adc6.js";import"./chunk-32jpxz2y.js";import"./chunk-79q5xsdc.js";import"./chunk-ggtd5x5a.js";import"./chunk-z8t0v07j.js";import"./chunk-mf9spd4g.js";export{cq as InputText};
3
-
4
- //# debugId=FF6F23225AD40E1D64756E2164756E21
@@ -1,4 +0,0 @@
1
- // @bun
2
- import{doe,E2,_$}from"./chunk-js1jpyxp.js";import"./chunk-zj939v0h.js";import"./chunk-z916af47.js";import"./chunk-6hyt398x.js";import"./chunk-ympy4fdz.js";import"./chunk-t4dr5c8v.js";import"./chunk-r20pe1nv.js";import"./chunk-cxyf04jc.js";import"./chunk-3jmvqygr.js";import"./chunk-qwye1958.js";import"./chunk-rn84t3sf.js";import"./chunk-c9nk1r78.js";import"./chunk-f9s1kkhx.js";import"./chunk-zd9vmkzn.js";import"./chunk-vs9r72ta.js";import"./chunk-mqc1d0eb.js";import"./chunk-nwm2pq5v.js";import"./chunk-a4k9rt7z.js";import"./chunk-8cghfzb2.js";import"./chunk-44bt78m9.js";import"./chunk-a2sc4jm0.js";import"./chunk-jhnbfj19.js";import"./chunk-9y5bcy28.js";import"./chunk-hmke8nhx.js";import"./chunk-vefd8qee.js";import"./chunk-sjn0nj4p.js";import"./chunk-kbjq0qvb.js";import"./chunk-4xd6zs3y.js";import"./chunk-tyazf3sk.js";import"./chunk-0rjm4nx7.js";import"./chunk-w7zsh13a.js";import"./chunk-z04jrpjy.js";import"./chunk-jdqvcq0a.js";import"./chunk-pm06b05d.js";import"./chunk-bn64x5z5.js";import"./chunk-0e4gm1kj.js";import"./chunk-4fgdhcwx.js";import"./chunk-6d3mmqxt.js";import"./chunk-0w1spptt.js";import"./chunk-sns0c35v.js";import"./chunk-zg67wjkh.js";import"./chunk-h3n4adc6.js";import"./chunk-32jpxz2y.js";import"./chunk-79q5xsdc.js";import"./chunk-ggtd5x5a.js";import"./chunk-z8t0v07j.js";import"./chunk-mf9spd4g.js";export{E2 as createMcpServer,_$ as refreshMcpResourceList,doe as registerMcpTools};
3
-
4
- //# debugId=60EF61BA6E8426D064756E2164756E21
@@ -1,5 +0,0 @@
1
- // @bun
2
- var i={DATA_DIR:{name:"AUTOMOBILE_DATA_DIR",legacyName:"AUTO_MOBILE_DATA_DIR",kind:"path",default:"~/.auto-mobile",doc:"Base directory for AutoMobile state; relative to the daemon launch directory."},COORDINATION_DIR:{name:"AUTOMOBILE_COORDINATION_DIR",legacyName:"AUTO_MOBILE_COORDINATION_DIR",kind:"path",default:"~/.auto-mobile",doc:"Absolute root of cross-process coordination state shared by cooperating agents."},SESSION_BROKER_CONFIG:{name:"AUTOMOBILE_SESSION_BROKER_CONFIG",kind:"path",default:"unset (broker disabled)",doc:"Operator session-broker host configuration file; never a session requester input."},SESSION_CONFIG:{name:"AUTOMOBILE_SESSION_CONFIG",kind:"path",default:"unset",doc:"Session configuration file read by the CLI, equivalent to --session-config."},ADB_SERVER_COORDINATION_DIR:{name:"AUTOMOBILE_ADB_SERVER_COORDINATION_DIR",legacyName:"AUTO_MOBILE_ADB_SERVER_COORDINATION_DIR",kind:"path",default:"~/.auto-mobile/adb-servers",doc:"Absolute root of per-ADB-server claims shared by every daemon on one ADB server."},PRIVATE_DAEMON_ORPHAN_IDLE_MS:{name:"AUTOMOBILE_PRIVATE_DAEMON_ORPHAN_IDLE_MS",kind:"number",default:"900000",min:0,doc:"Idle timeout in ms for an orphaned private daemon; 0 disables the watchdog."},PORT_RANGE_START:{name:"AUTOMOBILE_PORT_RANGE_START",legacyName:"AUTO_MOBILE_PORT_RANGE_START",kind:"int",default:"see docs",min:1,doc:"First CtrlProxy host port."},PORT_RANGE_END:{name:"AUTOMOBILE_PORT_RANGE_END",legacyName:"AUTO_MOBILE_PORT_RANGE_END",kind:"string",default:"unset",doc:"Inclusive last CtrlProxy host port."},PORT_RANGE_SIZE:{name:"AUTOMOBILE_PORT_RANGE_SIZE",legacyName:"AUTO_MOBILE_PORT_RANGE_SIZE",kind:"string",default:"unset",doc:"Number of CtrlProxy host ports."},PORT_REVERSE_ALLOWED_PORTS:{name:"AUTOMOBILE_PORT_REVERSE_ALLOWED_PORTS",kind:"string",default:"unset",doc:"Ports portReverse may map: comma-separated ports or inclusive ranges."},PORT_REVERSE_RECONCILE_INTERVAL_MS:{name:"AUTOMOBILE_PORT_REVERSE_RECONCILE_INTERVAL_MS",kind:"int",default:"30000",fallback:30000,min:1000,doc:"Milliseconds between periodic re-checks of owned portReverse mappings."},DOCTOR_TIMEOUT_MS:{name:"AUTOMOBILE_DOCTOR_TIMEOUT_MS",kind:"int",default:"5000",fallback:5000,min:1,doc:"Timeout in ms for each external doctor probe."},WORK_PROFILE_POLL_INTERVAL_MS:{name:"AUTOMOBILE_WORK_PROFILE_POLL_INTERVAL_MS",kind:"int",default:"5000",min:1,doc:"Work-profile polling interval in ms."},DB_PATH:{name:"AUTOMOBILE_DB_PATH",legacyName:"AUTO_MOBILE_DB_PATH",kind:"path",default:"~/.auto-mobile/auto-mobile.db",doc:"Exact SQLite database file; takes precedence over the DB directory. `:memory:` is test-only."},DB_DIR:{name:"AUTOMOBILE_DB_DIR",legacyName:"AUTO_MOBILE_DB_DIR",kind:"path",default:"~/.auto-mobile",doc:"Directory containing auto-mobile.db."},MIGRATIONS_DIR:{name:"AUTOMOBILE_MIGRATIONS_DIR",legacyName:"AUTO_MOBILE_MIGRATIONS_DIR",kind:"path",default:"bundled static migrations",doc:"Directory of migration modules loaded instead of the bundled static migrations."},MIGRATION_RECOVERY:{name:"AUTOMOBILE_MIGRATION_RECOVERY",legacyName:"AUTO_MOBILE_MIGRATION_RECOVERY",kind:"string",default:"safe recovery on; destructive reset off",doc:"Safe recovery is on unless 0/false/no/off; only exact 1 permits the destructive reset."},MIGRATION_LOCK_TIMEOUT_MS:{name:"AUTOMOBILE_MIGRATION_LOCK_TIMEOUT_MS",legacyName:"AUTO_MOBILE_MIGRATION_LOCK_TIMEOUT_MS",kind:"int",default:"60000",min:1,doc:"File-scoped migration lock wait; positive base-10 integer milliseconds."},ALLOW_IN_MEMORY_DB:{name:"AUTOMOBILE_ALLOW_IN_MEMORY_DB",kind:"bool",default:"unset",doc:"Test-only opt-in (1/true/yes) permitting the `:memory:` database path."},NAV_RETENTION_STRUCTURE_TTL_MS:{name:"AUTOMOBILE_NAV_RETENTION_STRUCTURE_TTL_MS",kind:"int",default:"7776000000",min:1,doc:"Structure retention TTL; positive safe integer milliseconds."},NAV_RETENTION_EVICTION_CHUNK_SIZE:{name:"AUTOMOBILE_NAV_RETENTION_EVICTION_CHUNK_SIZE",kind:"int",default:"5000",min:1,doc:"Rows per eviction batch; positive safe integer clamped to 10000."},NAV_RETENTION_INTERVAL_MS:{name:"AUTOMOBILE_NAV_RETENTION_INTERVAL_MS",kind:"int",default:"21600000",min:1,doc:"Retention sweep cadence; positive safe integer milliseconds at most 2147483647."},VERSION:{name:"AUTOMOBILE_VERSION",kind:"string",default:"latest",doc:"Pins the daemon, APK and IPA to one coherent release version."},UNIT_TEST_ISOLATED_DATA_DIR:{name:"AUTOMOBILE_UNIT_TEST_ISOLATED_DATA_DIR",kind:"path",default:"unset",doc:"Test-only: the data directory the unit-test preload isolated, exempt from the real-data-dir guard."},ACCEPTANCE_LIVE:{name:"AUTOMOBILE_ACCEPTANCE_LIVE",kind:"string",default:"off",internal:!0,doc:"Live acceptance harness activation; exact 1 enables."},ACCEPTANCE_DISCOVERY_ORDER:{name:"AUTOMOBILE_ACCEPTANCE_DISCOVERY_ORDER",kind:"string",default:"unset",internal:!0,doc:"Acceptance harness discovery ordering."},MCP_MODERN_ERA:{name:"AUTOMOBILE_MCP_MODERN_ERA",kind:"bool",default:"off",doc:"Serve MCP 2026-07-28 envelope requests on the daemon HTTP endpoint (1/true/yes/on)."},ELICITATION:{name:"AUTOMOBILE_ELICITATION",kind:"enum",values:["on","off"],default:"on",doc:"`off` never asks the client which device to use for an ambiguous call; the call returns the ambiguous_device_target refusal (CI and benchmarks)."},SERVER_INSTRUCTIONS:{name:"AUTOMOBILE_SERVER_INSTRUCTIONS",kind:"bool",default:"off",doc:"Return a short usage instructions block in the MCP initialize result (agent benchmark A/B)."},TOOL_RESULTS_NO_STRUCTURED_CONTENT:{name:"AUTOMOBILE_TOOL_RESULTS_NO_STRUCTURED_CONTENT",kind:"bool",default:"off",doc:"Omit structuredContent from tool results (output-reduction flag)."},DAEMON_LAUNCH_CWD:{name:"AUTOMOBILE_DAEMON_LAUNCH_CWD",kind:"path",default:"unset",internal:!0,doc:"Manager-injected caller working directory for child path resolution."},RUNNER_READINESS_TIMEOUT_MS:{name:"AUTOMOBILE_RUNNER_READINESS_TIMEOUT_MS",legacyName:"AUTO_MOBILE_RUNNER_READINESS_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"iOS runner readiness timeout in ms."},STARTUP_BENCHMARK:{name:"AUTOMOBILE_STARTUP_BENCHMARK",legacyName:"AUTO_MOBILE_STARTUP_BENCHMARK",kind:"bool",default:"off",internal:!0,doc:"Startup benchmark harness activation (1/true/yes)."},STARTUP_BENCHMARK_OUTPUT:{name:"AUTOMOBILE_STARTUP_BENCHMARK_OUTPUT",legacyName:"AUTO_MOBILE_STARTUP_BENCHMARK_OUTPUT",kind:"path",default:"unset",internal:!0,doc:"Startup benchmark harness output file."},STARTUP_BENCHMARK_LABEL:{name:"AUTOMOBILE_STARTUP_BENCHMARK_LABEL",legacyName:"AUTO_MOBILE_STARTUP_BENCHMARK_LABEL",kind:"string",default:"unset",internal:!0,doc:"Startup benchmark harness sample label."},TEST_MODE:{name:"AUTOMOBILE_TEST_MODE",kind:"string",default:"unset",internal:!0,doc:"ADB test fake activation, not a device configuration option."},ACCEPTANCE_DISCOVERY_CAPABILITY:{name:"AUTOMOBILE_ACCEPTANCE_DISCOVERY_CAPABILITY",kind:"string",default:"unset",internal:!0,doc:"Private acceptance discovery capability between processes."},DAEMON_LIVE_ACCEPTANCE_STARTUP_SECRET:{name:"AUTOMOBILE_DAEMON_LIVE_ACCEPTANCE_STARTUP_SECRET",kind:"string",default:"unset",internal:!0,doc:"Private live acceptance startup secret."},AUX_SOCKET_DIR:{name:"AUTOMOBILE_AUX_SOCKET_DIR",kind:"path",default:"see docs",doc:"Directory for auxiliary stream and push sockets; a non-blank value also isolates the daemon state files."},DAEMON_SOCKET_PATH:{name:"AUTOMOBILE_DAEMON_SOCKET_PATH",legacyName:"AUTO_MOBILE_DAEMON_SOCKET_PATH",kind:"path",default:"/tmp state file",doc:"Daemon control socket path override."},DAEMON_PID_FILE_PATH:{name:"AUTOMOBILE_DAEMON_PID_FILE_PATH",legacyName:"AUTO_MOBILE_DAEMON_PID_FILE_PATH",kind:"path",default:"/tmp state file",doc:"Daemon PID file path override."},DAEMON_LOCK_FILE_PATH:{name:"AUTOMOBILE_DAEMON_LOCK_FILE_PATH",legacyName:"AUTO_MOBILE_DAEMON_LOCK_FILE_PATH",kind:"path",default:"/tmp state file",doc:"Daemon lock file path override."},DAEMON_TOKEN_FILE_PATH:{name:"AUTOMOBILE_DAEMON_TOKEN_FILE_PATH",kind:"path",default:"POSIX: /tmp state file; Windows: per-user auto-mobile directory",doc:"Daemon HTTP bearer token file path override."},DAEMON_HTTP_TOKEN:{name:"AUTOMOBILE_DAEMON_HTTP_TOKEN",kind:"string",default:"unset",internal:!0,doc:"Client override for the daemon HTTP bearer token."},DAEMON_TIMEOUT_MS:{name:"AUTOMOBILE_DAEMON_TIMEOUT_MS",legacyName:"AUTO_MOBILE_DAEMON_TIMEOUT_MS",kind:"int",default:"120000",min:1,doc:"Daemon request connection timeout in ms."},DAEMON_STARTUP_TIMEOUT_MS:{name:"AUTOMOBILE_DAEMON_STARTUP_TIMEOUT_MS",legacyName:"AUTO_MOBILE_DAEMON_STARTUP_TIMEOUT_MS",kind:"int",default:"30000",min:1,doc:"Daemon startup timeout in ms."},DAEMON_EXISTING_REACHABILITY_TIMEOUT_MS:{name:"AUTOMOBILE_DAEMON_EXISTING_REACHABILITY_TIMEOUT_MS",legacyName:"AUTO_MOBILE_DAEMON_EXISTING_REACHABILITY_TIMEOUT_MS",kind:"int",default:"10000",min:1,doc:"Reachability timeout in ms for an existing daemon."},CLI_SESSION_IDLE_TIMEOUT_MS:{name:"AUTOMOBILE_CLI_SESSION_IDLE_TIMEOUT_MS",legacyName:"AUTO_MOBILE_CLI_SESSION_IDLE_TIMEOUT_MS",kind:"int",default:"120000",min:1,doc:"CLI session idle leash in ms."},DAEMON_DISABLE_HANDSHAKE:{name:"AUTOMOBILE_DAEMON_DISABLE_HANDSHAKE",legacyName:"AUTO_MOBILE_DAEMON_DISABLE_HANDSHAKE",kind:"bool",default:"off",doc:"Disable the client handshake check (1/true)."},SESSION_HEARTBEAT_TIMEOUT_MS:{name:"AUTOMOBILE_SESSION_HEARTBEAT_TIMEOUT_MS",legacyName:"AUTO_MOBILE_SESSION_HEARTBEAT_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"Session heartbeat timeout in ms."},SESSION_HEARTBEAT_INITIAL_GRACE_MS:{name:"AUTOMOBILE_SESSION_HEARTBEAT_INITIAL_GRACE_MS",legacyName:"AUTO_MOBILE_SESSION_HEARTBEAT_INITIAL_GRACE_MS",kind:"int",default:"see docs",min:1,doc:"Initial grace in ms before the first session heartbeat is required."},SESSION_HEARTBEAT_CHECK_INTERVAL_MS:{name:"AUTOMOBILE_SESSION_HEARTBEAT_CHECK_INTERVAL_MS",legacyName:"AUTO_MOBILE_SESSION_HEARTBEAT_CHECK_INTERVAL_MS",kind:"int",default:"see docs",min:1,doc:"Interval in ms between session heartbeat checks."},SESSION_IDLE_TIMEOUT_MS:{name:"AUTOMOBILE_SESSION_IDLE_TIMEOUT_MS",legacyName:"AUTO_MOBILE_SESSION_IDLE_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"Idle window in ms after the last tool call ends."},SESSION_PRE_FIRST_HEARTBEAT_GRACE_MS:{name:"AUTOMOBILE_SESSION_PRE_FIRST_HEARTBEAT_GRACE_MS",legacyName:"AUTO_MOBILE_SESSION_PRE_FIRST_HEARTBEAT_GRACE_MS",kind:"int",default:"see docs",min:1,doc:"Grace in ms for a session before its first heartbeat."},OPEN_LINK_MCP_TIMEOUT_MS:{name:"AUTOMOBILE_OPEN_LINK_MCP_TIMEOUT_MS",legacyName:"AUTO_MOBILE_OPEN_LINK_MCP_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"openLink MCP budget in ms: daemon decides; explicit client or daemon value applies; daemon wins if both set. The client connection timeout (default 120 s) is bypassed only when an explicit value is set in the client or daemon process; with neither set it still floors the budget."},DEVICE_RECOVERY_ON_LOSS:{name:"AUTOMOBILE_DEVICE_RECOVERY_ON_LOSS",legacyName:"AUTO_MOBILE_DEVICE_RECOVERY_ON_LOSS",kind:"string",default:"0",doc:"Device-loss session continuity: exact 0 disables, exact 1 opts in."},DEVICE_RECOVERY_MAX_ATTEMPTS:{name:"AUTOMOBILE_DEVICE_RECOVERY_MAX_ATTEMPTS",legacyName:"AUTO_MOBILE_DEVICE_RECOVERY_MAX_ATTEMPTS",kind:"int",default:"see docs",min:1,doc:"Rolling active restart budget; integer 1..10."},DEVICE_RECOVERY_WINDOW_MS:{name:"AUTOMOBILE_DEVICE_RECOVERY_WINDOW_MS",legacyName:"AUTO_MOBILE_DEVICE_RECOVERY_WINDOW_MS",kind:"int",default:"see docs",min:1,doc:"Rolling recovery budget window in ms."},DEVICE_POOL_MATCHING:{name:"AUTOMOBILE_DEVICE_POOL_MATCHING",legacyName:"AUTO_MOBILE_DEVICE_POOL_MATCHING",kind:"enum",default:"see docs",doc:"Device selection: LATEST, RANDOM or MINIMUM."},DEVICE_POOL_AUTOLOCK:{name:"AUTOMOBILE_DEVICE_POOL_AUTOLOCK",legacyName:"AUTO_MOBILE_DEVICE_POOL_AUTOLOCK",kind:"string",default:"see docs",doc:"Require an acquired device session UUID and auto-release on idle."},DEVICE_POOL_TIMEOUT:{name:"AUTOMOBILE_DEVICE_POOL_TIMEOUT",legacyName:"AUTO_MOBILE_DEVICE_POOL_TIMEOUT",kind:"int",default:"see docs",min:1,doc:"Autolock idle timeout in seconds."},DAEMON_LAUNCHER_PID:{name:"AUTOMOBILE_DAEMON_LAUNCHER_PID",kind:"int",default:"unset",doc:"Manager-injected launcher PID for the orphan watchdog."},DAEMON_LAUNCH_NONCE:{name:"AUTOMOBILE_DAEMON_LAUNCH_NONCE",kind:"string",default:"unset",internal:!0,doc:"Manager-injected per-launch nonce that readiness matches against the answering daemon."},HARNESS_PRIVATE_DAEMON:{name:"AUTOMOBILE_HARNESS_PRIVATE_DAEMON",kind:"string",default:"unset",doc:"Marks a harness private daemon (1) or a shared one (0)."},APPEARANCE_SYNC:{name:"AUTOMOBILE_APPEARANCE_SYNC",kind:"string",default:"on",doc:"Enable appearance sync; 0, false, off and no disable it."},ENABLED_TOOLS:{name:"AUTOMOBILE_ENABLED_TOOLS",kind:"list",default:"unset",doc:"Comma-separated exact tool names to enable."},DISABLED_TOOLS:{name:"AUTOMOBILE_DISABLED_TOOLS",kind:"list",default:"unset",doc:"Comma-separated exact tool names to disable."},ALWAYS_LOAD_TOOLS:{name:"AUTOMOBILE_ALWAYS_LOAD_TOOLS",kind:"bool",default:"off",doc:"Register optional tool definitions eagerly (1/true)."},DAEMON_STREAM_AUTH:{name:"AUTOMOBILE_DAEMON_STREAM_AUTH",kind:"string",default:"see docs",doc:"Require session authentication on video and WebRTC stream sockets."},ALLOW_SHARED_DAEMON_NAMESPACE:{name:"AUTOMOBILE_ALLOW_SHARED_DAEMON_NAMESPACE",kind:"bool",default:"off",doc:"Permit lifecycle commands against the shared daemon namespace."},DEBUG:{name:"AUTOMOBILE_DEBUG",kind:"bool",default:"off",doc:"Enable CLI debug logging (1/true)."}};var O={CTRL_PROXY_REBIND_WRITE_TIMEOUT_MS:{name:"AUTOMOBILE_CTRL_PROXY_REBIND_WRITE_TIMEOUT_MS",kind:"int",min:1,default:"5000",fallback:5000,doc:"Base timeout for each Android accessibility rebind command."},CTRL_PROXY_REBIND_WRITE_TIMEOUT_MAX_MS:{name:"AUTOMOBILE_CTRL_PROXY_REBIND_WRITE_TIMEOUT_MAX_MS",kind:"int",min:1,default:"30000",fallback:30000,doc:"Ceiling for Android accessibility rebind command timeouts."},IOS_RESET_STEP_BUDGET_MS:{name:"AUTOMOBILE_IOS_RESET_STEP_BUDGET_MS",kind:"int",min:1,default:"30000",fallback:30000,doc:"Base budget for each iOS keep-booted reset step and health probe."},IOS_RESET_STEP_BUDGET_MAX_MS:{name:"AUTOMOBILE_IOS_RESET_STEP_BUDGET_MAX_MS",kind:"int",min:1,default:"120000",fallback:120000,doc:"Ceiling for iOS keep-booted reset step and health probe budgets."},ANDROID_MAX_BOOTED:{name:"AUTOMOBILE_ANDROID_MAX_BOOTED",kind:"int",default:"see docs",min:1,doc:"Positive integer cap on concurrently booted Android emulators."},ANDROID_BOOT_BUDGET_VCPUS:{name:"AUTOMOBILE_ANDROID_BOOT_BUDGET_VCPUS",kind:"string",default:"fixed (2 cores per emulator)",doc:"`configured` budgets each emulator at the vCPU count its AVD resolved to (hardware-qemu.ini) when sizing the boot limit; any other value keeps two cores per emulator."},IOS_SIM_BOOT_CONCURRENCY:{name:"AUTOMOBILE_IOS_SIM_BOOT_CONCURRENCY",kind:"int",default:"see docs",min:1,doc:"Concurrent iOS simulator boot bursts; positive integer, otherwise derived from host cores."},IOS_SIM_MAX_BOOTED:{name:"AUTOMOBILE_IOS_SIM_MAX_BOOTED",kind:"int",default:"see docs",min:1,doc:"Positive integer cap on concurrently booted iOS simulators."},LMK_PRESSURE_DIR:{name:"AUTOMOBILE_LMK_PRESSURE_DIR",kind:"path",default:"build/lmk-pressure under the package root, then the release download",doc:"Directory containing per-ABI Android memory-pressure binaries. When set, the release binary is never downloaded."},NETWORK_FILTER_APP_PATH:{name:"AUTOMOBILE_NETWORK_FILTER_APP_PATH",kind:"path",default:"unset",doc:"Path to a locally built signed network-filter .app used instead of the release download."},NETWORK_FILTER_TEAM_ID:{name:"AUTOMOBILE_NETWORK_FILTER_TEAM_ID",kind:"string",default:"unset",doc:"Apple team id used to sign the network-filter app."},IOS_TAP_STRATEGY:{name:"AUTOMOBILE_IOS_TAP_STRATEGY",kind:"string",default:"unset",doc:"iOS tap coordinate strategy recorded in debug tap diagnostics."},CTRL_PROXY_LEASE_IDLE_MS:{name:"AUTOMOBILE_CTRL_PROXY_LEASE_IDLE_MS",kind:"int",default:"60000",min:1,doc:"Idle window in ms after which a daemon gives up a CtrlProxy forwarding lease."},IOS_PROTOTYPE_AGENT:{name:"AUTOMOBILE_IOS_PROTOTYPE_AGENT",kind:"path",default:"unset",doc:"Absolute path to a locally built iOS prototype-agent dylib."},SKIP_IOS_PROTOTYPE_AGENT_DOWNLOAD:{name:"AUTOMOBILE_SKIP_IOS_PROTOTYPE_AGENT_DOWNLOAD",kind:"bool",default:"off",doc:"Forbid the prototype-agent release download (1/true)."},ANDROID_PROTOTYPE_APP_TEMPLATE:{name:"AUTOMOBILE_ANDROID_PROTOTYPE_APP_TEMPLATE",kind:"path",default:"unset",doc:"Packaged Android disposable app template directory or parent of flavor directories."},IOS_PROTOTYPE_VIEWER:{name:"AUTOMOBILE_IOS_PROTOTYPE_VIEWER",kind:"path",default:"unset",doc:"Path to a locally built iOS prototype-viewer template."},SKIP_IOS_PROTOTYPE_VIEWER_DOWNLOAD:{name:"AUTOMOBILE_SKIP_IOS_PROTOTYPE_VIEWER_DOWNLOAD",kind:"bool",default:"off",doc:"Forbid the prototype-viewer release download (1/true)."},BUNDLETOOL_JAR:{name:"AUTOMOBILE_BUNDLETOOL_JAR",kind:"path",default:"unset",doc:"Path to a bundletool-all jar run with java for .aab/.apks installs; else bundletool on PATH."},MANAGED_ADB_SERVER:{name:"AUTOMOBILE_MANAGED_ADB_SERVER",legacyName:"AUTO_MOBILE_MANAGED_ADB_SERVER",kind:"string",default:"see docs",doc:"Whether AutoMobile manages (starts and stops) its own ADB server."},EMULATOR_HEADLESS:{name:"AUTOMOBILE_EMULATOR_HEADLESS",kind:"string",default:"host dependent",doc:"Exact true forces headless emulator launches; exact false forces a windowed launch."},EMULATOR_ARGS:{name:"AUTOMOBILE_EMULATOR_ARGS",kind:"string",default:"unset",doc:"Extra whitespace-separated arguments appended to emulator launches."},EMULATOR_EXCLUDED_CONSOLE_PORTS:{name:"AUTOMOBILE_EMULATOR_EXCLUDED_CONSOLE_PORTS",kind:"string",default:"5554 on broker hosts; otherwise empty",doc:"Excluded even emulator console ports (5554\u20135682) or emulator serials, comma/whitespace-separated; explicit blank disables exclusions."},SKIP_CTRL_PROXY_DOWNLOAD:{name:"AUTOMOBILE_SKIP_CTRL_PROXY_DOWNLOAD",kind:"bool",default:"off",doc:"Skip CtrlProxy APK and IPA downloads (1/true)."},EAGER_PREFETCH:{name:"AUTOMOBILE_EAGER_PREFETCH",kind:"bool",default:"off",doc:"Run the full startup CtrlProxy APK cache check (zip parse + SHA-256) even when the cache is already warm (1/true)."},ALLOW_DEVICE_CREATE:{name:"AUTOMOBILE_ALLOW_DEVICE_CREATE",kind:"bool",default:"off",doc:"Enable device creation when no explicit flag is supplied (1/true)."},ALLOW_REAL_CTRL_PROXY_WEBSOCKET:{name:"AUTOMOBILE_ALLOW_REAL_CTRL_PROXY_WEBSOCKET",kind:"bool",default:"off",internal:!0,doc:"Test-only opt-in to a real CtrlProxy WebSocket."},BOOT_CAPACITY_GATE:{name:"AUTOMOBILE_BOOT_CAPACITY_GATE",kind:"string",default:"on",doc:"Boot admission gate for every platform; exact 0 disables."},IOS_TEMPLATE_CLONE:{name:"AUTOMOBILE_IOS_TEMPLATE_CLONE",kind:"string",default:"false",doc:"Provision iOS simulators from settled templates; off by default (clones share Safari and system-app data, #15327): 1/true opts in."},IOS_PREBOOT_LEAN_PROFILE:{name:"AUTOMOBILE_IOS_PREBOOT_LEAN_PROFILE",kind:"string",default:"minimal",doc:"Pre-boot iOS simulator lean profile: minimal by default, none opts out, or catalog-cpu; unknown values use the default."},IOS_SIM_CAPACITY_GATE:{name:"AUTOMOBILE_IOS_SIM_CAPACITY_GATE",kind:"string",default:"follows boot gate",doc:"iOS-only override of the boot admission gate; exact 0 disables, exact 1 enables."},IOS_CODE_SIGN_ENTITLEMENTS_PATH:{name:"AUTOMOBILE_IOS_CODE_SIGN_ENTITLEMENTS_PATH",kind:"path",default:"generated",doc:"Entitlements plist used when signing iOS builds."},IOS_CODE_SIGN_IDENTITY:{name:"AUTOMOBILE_IOS_CODE_SIGN_IDENTITY",kind:"string",default:"unset",doc:"Preferred code-signing identity for iOS builds."},IOS_PROFILE_UUID:{name:"AUTOMOBILE_IOS_PROFILE_UUID",kind:"string",default:"unset",doc:"Preferred provisioning profile UUID for iOS builds."},IOS_PROFILE_NAME:{name:"AUTOMOBILE_IOS_PROFILE_NAME",kind:"string",default:"unset",doc:"Preferred provisioning profile name for iOS builds."},IOS_PROFILE_SPECIFIER:{name:"AUTOMOBILE_IOS_PROFILE_SPECIFIER",kind:"string",default:"unset",doc:"Preferred provisioning profile specifier for iOS builds."},IOS_TEAM_IDS:{name:"AUTOMOBILE_IOS_TEAM_IDS",kind:"list",default:"unset",doc:"Comma-separated preferred Apple team ids for iOS signing."},IOS_TEAM_ID:{name:"AUTOMOBILE_IOS_TEAM_ID",kind:"string",default:"unset",doc:"Preferred Apple team id for iOS signing; consulted when AUTOMOBILE_IOS_TEAM_IDS is unset."},IOS_CTRLPROXY_RECORD_DIR:{name:"AUTOMOBILE_IOS_CTRLPROXY_RECORD_DIR",kind:"path",default:"unset",doc:"Directory where the iOS client records CtrlProxy exchanges."},IOS_HEADLESS:{name:"AUTOMOBILE_IOS_HEADLESS",kind:"string",default:"detected",doc:"Force headless (true/1) or windowed iOS simulator launches on macOS."},IOS_SIMULATOR_WINDOW_TIMEOUT_MS:{name:"AUTOMOBILE_IOS_SIMULATOR_WINDOW_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"Timeout in ms for the iOS simulator window to appear."},CTRL_PROXY_IOS_IPA_PATH:{name:"AUTOMOBILE_CTRL_PROXY_IOS_IPA_PATH",kind:"path",default:"unset",doc:"Vendored iOS CtrlProxy IPA; takes precedence over the bundle path."},CTRL_PROXY_IOS_BUNDLE_PATH:{name:"AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH",kind:"path",default:"unset",doc:"Vendored iOS CtrlProxy bundle directory."},ANDROID_REBOOT_ON_DEATH:{name:"AUTOMOBILE_ANDROID_REBOOT_ON_DEATH",legacyName:"AUTO_MOBILE_ANDROID_REBOOT_ON_DEATH",kind:"bool",default:"off",doc:"Reboot an Android device whose CtrlProxy died."},IOS_WARMUP_DEVICES:{name:"AUTOMOBILE_IOS_WARMUP_DEVICES",kind:"list",default:"unset",doc:"Simulator UDIDs allowed passive startup warm-up."},ANDROID_OBSERVATION_STREAM_DEVICES:{name:"AUTOMOBILE_ANDROID_OBSERVATION_STREAM_DEVICES",kind:"list",default:"unset",doc:"Android serials allowed passive observation streams."},ANDROID_APPEARANCE_SYNC_DEVICES:{name:"AUTOMOBILE_ANDROID_APPEARANCE_SYNC_DEVICES",kind:"list",default:"unset",doc:"Android serials allowed appearance sync."},CTRL_PROXY_APK_PATH:{name:"AUTOMOBILE_CTRL_PROXY_APK_PATH",kind:"path",default:"unset",doc:"Local CtrlProxy APK used instead of the release download."},SKIP_ACCESSIBILITY_CHECKSUM:{name:"AUTOMOBILE_SKIP_ACCESSIBILITY_CHECKSUM",legacyName:"AUTO_MOBILE_ACCESSIBILITY_SERVICE_SHA_SKIP_CHECK",kind:"bool",default:"off",doc:"Skip Android APK checksum enforcement (1/true)."},SKIP_ACCESSIBILITY_DOWNLOAD_IF_INSTALLED:{name:"AUTOMOBILE_SKIP_ACCESSIBILITY_DOWNLOAD_IF_INSTALLED",kind:"bool",default:"off",doc:"Accept an installed APK unchecked outside readiness (1/true)."},IOS_SKIP_CTRL_PROXY_APP_HASH:{name:"AUTOMOBILE_IOS_SKIP_CTRL_PROXY_APP_HASH",kind:"bool",default:"off",doc:"Skip iOS CtrlProxy app hash verification (true/1)."},CTRLPROXY_VERBOSE:{name:"AUTOMOBILE_CTRLPROXY_VERBOSE",kind:"bool",default:"off",doc:"Promote all iOS CtrlProxy output to info logs (1/true)."},IOS_RUNNER_LAUNCH_CONCURRENCY:{name:"AUTOMOBILE_IOS_RUNNER_LAUNCH_CONCURRENCY",kind:"int",default:"2",min:1,doc:"Maximum concurrent iOS runner launches per daemon; positive integer."},CTRL_PROXY_HEALTH_MAX_ATTEMPTS:{name:"AUTOMOBILE_CTRL_PROXY_HEALTH_MAX_ATTEMPTS",legacyName:"AUTO_MOBILE_CTRL_PROXY_HEALTH_MAX_ATTEMPTS",kind:"int",default:"see docs",min:1,doc:"iOS CtrlProxy health poll attempt budget."},IOS_HELPER_REQUIRE_CODESIGN:{name:"AUTOMOBILE_IOS_HELPER_REQUIRE_CODESIGN",kind:"bool",default:"off",doc:"Refuse to launch an iOS helper that fails codesign inspection."},IOS_HELPER_TEAM_ID:{name:"AUTOMOBILE_IOS_HELPER_TEAM_ID",kind:"string",default:"unset",doc:"Pinned Apple Team ID the iOS helper must match."},CTRL_PROXY_IOS_RUNNER_SHA256:{name:"AUTOMOBILE_CTRL_PROXY_IOS_RUNNER_SHA256",kind:"string",default:"unset",doc:"Expected SHA256 of an explicit or source-built iOS runner."},CTRL_PROXY_IOS_RUNNER_SHA256_TARGET:{name:"AUTOMOBILE_CTRL_PROXY_IOS_RUNNER_SHA256_TARGET",kind:"string",default:"unset",doc:"Executable the runner SHA256 applies to."},CTRL_PROXY_IOS_USE_LOCAL_BUILD:{name:"AUTOMOBILE_CTRL_PROXY_IOS_USE_LOCAL_BUILD",kind:"bool",default:"off",doc:"Serve a locally built iOS runner and derive its integrity pin."},PROJECT_ROOT:{name:"AUTOMOBILE_PROJECT_ROOT",kind:"path",default:"repository root",doc:"Project root used to build the iOS CtrlProxy."},CTRL_PROXY_IOS_DERIVED_DATA:{name:"AUTOMOBILE_CTRL_PROXY_IOS_DERIVED_DATA",kind:"path",default:"temp dir",doc:"Derived-data directory for iOS CtrlProxy builds."},TVOS_RUNNER_XCTESTRUN:{name:"AUTOMOBILE_TVOS_RUNNER_XCTESTRUN",kind:"path",default:"discover, download a verified release runner, or build from source",doc:"Prebuilt tvOS simulator runner xctestrun used by startDevice."},VISIONOS_RUNNER_XCTESTRUN:{name:"AUTOMOBILE_VISIONOS_RUNNER_XCTESTRUN",kind:"path",default:"discover or build the AutoMobileVisionTest scheme",doc:"Prebuilt visionOS window-app runner xctestrun used on first observe, tapOn or sendKeys."},WATCH_RUNNER_XCTESTRUN:{name:"AUTOMOBILE_WATCH_RUNNER_XCTESTRUN",kind:"path",default:"discover or build the CtrlProxyWatch scheme",doc:"Prebuilt watchOS simulator runner xctestrun used by startDevice."},CTRL_PROXY_IOS_CACHE_DIR:{name:"AUTOMOBILE_CTRL_PROXY_IOS_CACHE_DIR",kind:"path",default:"coordination dir",doc:"iOS CtrlProxy bundle cache directory."},CTRL_PROXY_IOS_BUNDLE_URL:{name:"AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_URL",kind:"string",default:"release asset",doc:"iOS CtrlProxy bundle URL override; https unless the insecure opt-out is set."},IOS_CTRL_PROXY_APP_HASH:{name:"AUTOMOBILE_IOS_CTRL_PROXY_APP_HASH",kind:"string",default:"release constant",doc:"Expected iOS device CtrlProxy app hash."},IPROXY_START_TIMEOUT_MS:{name:"AUTOMOBILE_IPROXY_START_TIMEOUT_MS",legacyName:"AUTO_MOBILE_IPROXY_START_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"iOS USB iproxy tunnel startup timeout in ms."}};var d={PROTOTYPE_CUSTOM_SHADERS:{name:"AUTOMOBILE_PROTOTYPE_CUSTOM_SHADERS",kind:"string",default:"off",doc:"Enable Android prototype AGSL assets and style.shader only with the exact value 1."},PROTOTYPE_FULL_SCHEMA:{name:"AUTOMOBILE_PROTOTYPE_FULL_SCHEMA",kind:"bool",default:"off",doc:"Inline the full prototype spec JSON Schema in the prototype tool definition (1/true)."},SCREENSHOT_CACHE_MB:{name:"AUTOMOBILE_SCREENSHOT_CACHE_MB",kind:"number",default:"128",min:0,minExclusive:!0,doc:"Base screenshot cache capacity in MiB; positive number."},SCREENSHOT_CACHE_PER_DEVICE_MB:{name:"AUTOMOBILE_SCREENSHOT_CACHE_PER_DEVICE_MB",kind:"number",default:"64",min:0,minExclusive:!0,doc:"Screenshot cache capacity per active device in MiB; positive number."},SCREENSHOT_CACHE_CEILING_MB:{name:"AUTOMOBILE_SCREENSHOT_CACHE_CEILING_MB",kind:"number",default:"2048",min:0,minExclusive:!0,doc:"Host screenshot cache ceiling in MiB; frames inside their 10-minute guarantee grow the cache up to it. Never lowers the base capacity."},SCREENSHOT_KEEP_PER_DEVICE:{name:"AUTOMOBILE_SCREENSHOT_KEEP_PER_DEVICE",kind:"int",default:"3",min:0,doc:"Newest screenshots per device evicted only as a last resort; 0 disables fairness."},LOG_DIR:{name:"AUTOMOBILE_LOG_DIR",legacyName:"AUTO_MOBILE_LOG_DIR",kind:"path",default:"$AUTOMOBILE_DATA_DIR/logs",doc:"Daemon and client log directory; relative to the daemon launch directory."},OBSERVE_PERF_SNAPSHOT:{name:"AUTOMOBILE_OBSERVE_PERF_SNAPSHOT",legacyName:"AUTO_MOBILE_OBSERVE_PERF_SNAPSHOT",kind:"bool",default:"off",doc:"Attach a windowed performance snapshot to observe results."},OBSERVE_PERF_WINDOW_MS:{name:"AUTOMOBILE_OBSERVE_PERF_WINDOW_MS",legacyName:"AUTO_MOBILE_OBSERVE_PERF_WINDOW_MS",kind:"number",default:"5000",min:0,minExclusive:!0,doc:"Rolling window for the performance snapshot; fractions are rounded."},VIDEO_RETENTION_DAYS:{name:"AUTOMOBILE_VIDEO_RETENTION_DAYS",legacyName:"AUTO_MOBILE_VIDEO_RETENTION_DAYS",kind:"number",default:"see docs",min:0,doc:"Age in days after which recordings are deleted; 0 disables the sweep."},VIDEO_RETENTION_SWEEP_MINUTES:{name:"AUTOMOBILE_VIDEO_RETENTION_SWEEP_MINUTES",legacyName:"AUTO_MOBILE_VIDEO_RETENTION_SWEEP_MINUTES",kind:"number",default:"see docs",min:0,minExclusive:!0,doc:"How often the recording retention sweep runs, in minutes."},VIDEO_INPROGRESS_CHECK_SECONDS:{name:"AUTOMOBILE_VIDEO_INPROGRESS_CHECK_SECONDS",legacyName:"AUTO_MOBILE_VIDEO_INPROGRESS_CHECK_SECONDS",kind:"number",default:"see docs",min:0,minExclusive:!0,doc:"How often an in-progress recording's size is checked, in seconds."},DISABLE_PERF_AUDIT:{name:"AUTOMOBILE_DISABLE_PERF_AUDIT",kind:"bool",default:"off",doc:"Disable the UI performance audit."},TOUCH_LATENCY_SAMPLING:{name:"AUTOMOBILE_TOUCH_LATENCY_SAMPLING",kind:"bool",default:"off",doc:"Opt into synthetic tap latency sampling."},MAX_OBSERVATION_AGE_MS:{name:"AUTOMOBILE_MAX_OBSERVATION_AGE_MS",kind:"int",default:"see docs",min:1,doc:"Hierarchy freshness budget in ms."},IOS_SCREEN_CAPTURE_HELPER:{name:"AUTOMOBILE_IOS_SCREEN_CAPTURE_HELPER",legacyName:"AUTO_MOBILE_IOS_SCREEN_CAPTURE_HELPER",kind:"path",default:"unset",doc:"Absolute path to a locally built screen-capture-helper."},IOS_AUDIO_LOOPBACK_HELPER:{name:"AUTOMOBILE_IOS_AUDIO_LOOPBACK_HELPER",kind:"path",default:"unset",doc:"Absolute path to an audio-loopback-helper executable, for iOS Simulator audio tools."},ACTION_OBSERVATION_SKIP_SCREENSHOT:{name:"AUTOMOBILE_ACTION_OBSERVATION_SKIP_SCREENSHOT",kind:"string",default:"skip",doc:"Skip automatic screenshots after actions unless set to false or 0."},OBSERVE_WAIT_FOR_SKIP_SCREENSHOT:{name:"AUTOMOBILE_OBSERVE_WAIT_FOR_SKIP_SCREENSHOT",kind:"string",default:"skip",doc:"Skip automatic screenshots for waitFor observations unless set to false or 0."},OBSERVE_SETTLED_SCREENSHOT:{name:"AUTOMOBILE_OBSERVE_SETTLED_SCREENSHOT",kind:"string",default:"unset",doc:"Select settled screenshot mode with true or 1."},EMULATOR_NETSIM_ISOLATION:{name:"AUTOMOBILE_EMULATOR_NETSIM_ISOLATION",kind:"string",default:"off",doc:"Exact true gives each newly launched Android emulator a private netsimd so BLE peripherals are invisible to other sessions; explicit packet-streamer endpoints take precedence."},EMULATOR_AUDIO:{name:"AUTOMOBILE_EMULATOR_AUDIO",kind:"string",default:"audio on",doc:"Exact false adds -no-audio to emulator launches, disabling emulator audio; other values keep audio."},NAV_RETENTION_SCREENSHOT_TTL_MS:{name:"AUTOMOBILE_NAV_RETENTION_SCREENSHOT_TTL_MS",kind:"int",default:"604800000",min:1,doc:"Screenshot retention TTL; positive safe integer milliseconds."},NAV_RETENTION_PER_APP_MAX_OBSERVATIONS:{name:"AUTOMOBILE_NAV_RETENTION_PER_APP_MAX_OBSERVATIONS",kind:"int",default:"50000",min:1,doc:"Per-app observation cap; positive safe integer."},NAV_RETENTION_GLOBAL_MAX_OBSERVATIONS:{name:"AUTOMOBILE_NAV_RETENTION_GLOBAL_MAX_OBSERVATIONS",kind:"int",default:"500000",min:1,doc:"Global observation cap; positive safe integer."},ASSET_BASE_URL:{name:"AUTOMOBILE_ASSET_BASE_URL",kind:"string",default:"GitHub Releases",doc:"Mirror for APK/IPA and other release asset downloads; absolute https URL."},ALLOW_INSECURE_ASSET_URL:{name:"AUTOMOBILE_ALLOW_INSECURE_ASSET_URL",kind:"bool",default:"off",doc:"Permit a plaintext http asset base/bundle URL for a trusted loopback or dev mirror (1/true)."},ANDROID_VIDEO_USE_FFMPEG_PIPE:{name:"AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE",kind:"bool",default:"off",doc:"Capture Android video through an exec-out screenrecord to ffmpeg pipe (1/true)."},OBSERVE_RESULT_INCLUDE_ELEMENTS:{name:"AUTOMOBILE_OBSERVE_RESULT_INCLUDE_ELEMENTS",kind:"bool",default:"off",doc:"Include the element list in observe results (output-reduction flag)."},ACTIONS_DIFF_OBSERVE:{name:"AUTOMOBILE_ACTIONS_DIFF_OBSERVE",kind:"bool",default:"off",doc:"Return a diff observation from actions (output-reduction flag)."},ACTIONS_NO_OBSERVE:{name:"AUTOMOBILE_ACTIONS_NO_OBSERVE",kind:"bool",default:"off",doc:"Skip the post-action observation (output-reduction flag)."},ACTIONS_COMPACT_METADATA:{name:"AUTOMOBILE_ACTIONS_COMPACT_METADATA",kind:"bool",default:"on",doc:"Compact action result metadata (output-reduction flag)."},CWEBP_PATH:{name:"AUTOMOBILE_CWEBP_PATH",kind:"path",default:"unset",doc:"Trusted cwebp binary used instead of PATH or the bundled copy."},TRACE_PROCESSOR:{name:"AUTOMOBILE_TRACE_PROCESSOR",kind:"path",default:"unset",doc:"Perfetto trace_processor_shell used to summarise Android performanceTrace traces instead of PATH."},DWEBP_PATH:{name:"AUTOMOBILE_DWEBP_PATH",kind:"path",default:"unset",doc:"Trusted dwebp binary used instead of PATH or the bundled copy."},EVENT_ALL_MARKERS:{name:"AUTOMOBILE_EVENT_ALL_MARKERS",kind:"list",default:"unset",doc:"Marker names recorded for every event."},FFMPEG:{name:"AUTOMOBILE_FFMPEG",kind:"path",default:"ffmpeg",doc:"ffmpeg binary used for video processing."},LOG_FORMAT:{name:"AUTOMOBILE_LOG_FORMAT",legacyName:"AUTO_MOBILE_LOG_FORMAT",kind:"enum",default:"text",values:["text","json"],doc:"Log serialization: text or json."},LOG_SINK:{name:"AUTOMOBILE_LOG_SINK",legacyName:"AUTO_MOBILE_LOG_SINK",kind:"enum",default:"file",values:["file","stderr","both"],doc:"Log destination: file, stderr or both."},LOG_LEVEL:{name:"AUTOMOBILE_LOG_LEVEL",legacyName:"AUTO_MOBILE_LOG_LEVEL",kind:"string",default:"info",doc:"Initial logging threshold: debug, info, warn, error or none."},PLAN_HEALTH_DIR:{name:"AUTOMOBILE_PLAN_HEALTH_DIR",kind:"path",default:"unset",doc:"Directory where executePlan writes a JSON health summary."},REQUIRE_VIDEO_SERVER:{name:"AUTOMOBILE_REQUIRE_VIDEO_SERVER",kind:"bool",default:"off",doc:"Fail instead of degrading when no verifiable video-server jar is available (1/true)."},SKIP_VIDEO_SERVER_DOWNLOAD:{name:"AUTOMOBILE_SKIP_VIDEO_SERVER_DOWNLOAD",kind:"bool",default:"off",doc:"Resolve video-server jar from local sources only (1/true)."},VIDEO_SERVER_JAR:{name:"AUTOMOBILE_VIDEO_SERVER_JAR",kind:"path",default:"unset",doc:"Explicit local video-server jar override."},TOOL_OUTPUTS_DIR:{name:"AUTOMOBILE_TOOL_OUTPUTS_DIR",legacyName:"AUTO_MOBILE_TOOL_OUTPUTS_DIR",kind:"path",default:"data directory tool_outputs",doc:"Directory for large CLI tool-output artifacts."},WEBRTC_WHIP_ENDPOINT:{name:"AUTOMOBILE_WEBRTC_WHIP_ENDPOINT",kind:"string",default:"unset",doc:"Default WHIP endpoint for WebRTC streaming."},WEBRTC_WHIP_TOKEN:{name:"AUTOMOBILE_WEBRTC_WHIP_TOKEN",kind:"string",default:"unset",doc:"Default WHIP bearer token."},WEBRTC_ICE_SERVERS:{name:"AUTOMOBILE_WEBRTC_ICE_SERVERS",kind:"string",default:"Google STUN",doc:"ICE servers as a JSON array or comma-separated URL list."},WEBRTC_BITRATE_KBPS:{name:"AUTOMOBILE_WEBRTC_BITRATE_KBPS",kind:"string",default:"see docs",doc:"Default WebRTC video bitrate in kbps."},WEBRTC_MAX_SIZE:{name:"AUTOMOBILE_WEBRTC_MAX_SIZE",kind:"string",default:"see docs",doc:"Default WebRTC maximum frame size."},WEBRTC_IOS_SIMULATOR_FPS:{name:"AUTOMOBILE_WEBRTC_IOS_SIMULATOR_FPS",kind:"string",default:"see docs",doc:"iOS Simulator capture fps for WebRTC."},WEBRTC_ANDROID_FPS:{name:"AUTOMOBILE_WEBRTC_ANDROID_FPS",kind:"string",default:"see docs",doc:"Android capture fps for WebRTC."},WEBRTC_TRICKLE_ICE:{name:"AUTOMOBILE_WEBRTC_TRICKLE_ICE",kind:"bool",default:"off",doc:"Enable trickle ICE for WebRTC streaming."},WEBRTC_AUDIO:{name:"AUTOMOBILE_WEBRTC_AUDIO",kind:"bool",default:"off",doc:"Enable audio for WebRTC streaming."},WEBRTC_ALLOW_INSECURE_WHIP:{name:"AUTOMOBILE_WEBRTC_ALLOW_INSECURE_WHIP",kind:"bool",default:"off",doc:"Re-permit plaintext http WHIP endpoints on non-loopback hosts."},WEBRTC_WHIP_ALLOWED_ORIGINS:{name:"AUTOMOBILE_WEBRTC_WHIP_ALLOWED_ORIGINS",kind:"list",default:"unset",doc:"Allow-list of origins a wire-supplied WHIP endpoint may target."},DAEMON_LAUNCH_LOG_PATH:{name:"AUTOMOBILE_DAEMON_LAUNCH_LOG_PATH",kind:"path",default:"unset",internal:!0,doc:"Manager-injected child launch log ownership marker."},OBSERVE_MCP_TIMEOUT_MS:{name:"AUTOMOBILE_OBSERVE_MCP_TIMEOUT_MS",legacyName:"AUTO_MOBILE_OBSERVE_MCP_TIMEOUT_MS",kind:"int",default:"see docs",min:1,doc:"observe MCP budget in ms: daemon decides; explicit client or daemon value applies; daemon wins if both set. The client connection timeout (default 120 s) is bypassed only when an explicit value is set in the client or daemon process; with neither set it still floors the budget."},WEBRTC_STREAM_SOCKET_PATH:{name:"AUTOMOBILE_WEBRTC_STREAM_SOCKET_PATH",legacyName:"AUTO_MOBILE_WEBRTC_STREAM_SOCKET_PATH",kind:"path",default:"aux socket dir",doc:"WebRTC stream socket path override."},DEBUG_PERF:{name:"AUTOMOBILE_DEBUG_PERF",kind:"bool",default:"off",doc:"Enable UI performance debug tracking (1/true)."},VIDEO_QUALITY_PRESET:{name:"AUTOMOBILE_VIDEO_QUALITY_PRESET",legacyName:"AUTO_MOBILE_VIDEO_QUALITY_PRESET",kind:"string",default:"see docs",doc:"Default video quality preset."},VIDEO_TARGET_BITRATE_KBPS:{name:"AUTOMOBILE_VIDEO_TARGET_BITRATE_KBPS",legacyName:"AUTO_MOBILE_VIDEO_TARGET_BITRATE_KBPS",kind:"string",default:"see docs",doc:"Default video target bitrate in kbps."},VIDEO_MAX_THROUGHPUT_MBPS:{name:"AUTOMOBILE_VIDEO_MAX_THROUGHPUT_MBPS",legacyName:"AUTO_MOBILE_VIDEO_MAX_THROUGHPUT_MBPS",kind:"string",default:"see docs",doc:"Default video max throughput in Mbps."},VIDEO_FPS:{name:"AUTOMOBILE_VIDEO_FPS",legacyName:"AUTO_MOBILE_VIDEO_FPS",kind:"string",default:"see docs",doc:"Default video frame rate."},VIDEO_MAX_ARCHIVE_MB:{name:"AUTOMOBILE_VIDEO_MAX_ARCHIVE_MB",legacyName:"AUTO_MOBILE_VIDEO_MAX_ARCHIVE_MB",kind:"string",default:"see docs",doc:"Default video archive size cap in MB."},VIDEO_FORMAT:{name:"AUTOMOBILE_VIDEO_FORMAT",legacyName:"AUTO_MOBILE_VIDEO_FORMAT",kind:"string",default:"see docs",doc:"Default video container format."}};var g={...i,...d,...O},K={DEVELOPER_DIR:{name:"DEVELOPER_DIR",kind:"path",default:"unset",doc:"Active Xcode developer directory; overrides xcode-select for simulator profile caching."},ANDROID_HOME:{name:"ANDROID_HOME",kind:"path",default:"unset",doc:"Android SDK root; ambient Android toolchain variable, read for emulator resolution."},ANDROID_SDK_ROOT:{name:"ANDROID_SDK_ROOT",kind:"path",default:"unset",doc:"Android SDK root (deprecated by Google); ambient, read for emulator resolution."},ANDROID_SDK_HOME:{name:"ANDROID_SDK_HOME",kind:"path",default:"unset",doc:"Android user-data home; ambient, reported in emulator-not-found diagnostics."},HOME:{name:"HOME",kind:"path",default:"unset",doc:"POSIX home directory; ambient, used to probe the default Android SDK locations."},USERPROFILE:{name:"USERPROFILE",kind:"path",default:"unset",doc:"Windows home directory; ambient, fallback when HOME is unset or empty."},PATH:{name:"PATH",kind:"string",default:"unset",doc:"Executable search path; ambient, reported in emulator-not-found diagnostics."},JAVA_HOME:{name:"JAVA_HOME",kind:"path",default:"unset",doc:"Java installation root; ambient, checked by doctor and used to run a bundletool jar."},ANTHROPIC_API_KEY:{name:"ANTHROPIC_API_KEY",kind:"string",default:"unset",doc:"Anthropic API key for vision features; ambient, used when no key is configured explicitly."},DISPLAY:{name:"DISPLAY",kind:"string",default:"unset",doc:"X11 display; ambient, a usable value keeps Linux emulator launches windowed."},WAYLAND_DISPLAY:{name:"WAYLAND_DISPLAY",kind:"string",default:"unset",doc:"Wayland display; ambient, a usable value keeps Linux emulator launches windowed."},USER:{name:"USER",kind:"string",default:"unset",doc:"POSIX account name; ambient, locates the emulator advertisement directory."},LOGNAME:{name:"LOGNAME",kind:"string",default:"unset",doc:"POSIX login name; ambient, fallback when USER is unset."},XDG_RUNTIME_DIR:{name:"XDG_RUNTIME_DIR",kind:"path",default:"unset",doc:"Linux per-user runtime directory; ambient, locates emulator advertisements."},TMPDIR:{name:"TMPDIR",kind:"path",default:"unset",doc:"POSIX temporary directory; ambient, takes precedence for the Linux netsimd discovery directory."},NETSIM_ARGS:{name:"NETSIM_ARGS",kind:"string",default:"unset",doc:"Extra netsimd arguments; ambient, --no-shutdown is stripped for private netsimd instances."},ANDROID_AVD_HOME:{name:"ANDROID_AVD_HOME",kind:"path",default:"unset",doc:"Android AVD home override; ambient, used to locate AVD definitions."},ANDROID_EMULATOR_HOME:{name:"ANDROID_EMULATOR_HOME",kind:"path",default:"unset",doc:"Android emulator home override; ambient, used to locate AVD definitions."},ANDROID_USER_HOME:{name:"ANDROID_USER_HOME",kind:"path",default:"unset",doc:"Android user home override; ambient, used to locate AVD definitions."},CI:{name:"CI",kind:"string",default:"unset",doc:"Set to true on CI hosts; ambient."},GITHUB_ACTIONS:{name:"GITHUB_ACTIONS",kind:"string",default:"unset",doc:"Set to true inside GitHub Actions; ambient."},GITHUB_WORKSPACE:{name:"GITHUB_WORKSPACE",kind:"path",default:"unset",doc:"GitHub Actions checkout directory; ambient."},COMSPEC:{name:"ComSpec",legacyName:"COMSPEC",kind:"path",default:"cmd.exe",doc:"Windows command interpreter; ambient."},DEBUG_ADB_EXEC:{name:"DEBUG_ADB_EXEC",kind:"string",default:"unset",doc:"Any value logs real adb execution with stack traces; ambient debug aid."},EMULATOR_POLLING_INTERVAL_MS:{name:"EMULATOR_POLLING_INTERVAL_MS",kind:"string",default:"500",doc:"Emulator readiness polling interval in ms (minimum 100)."},LOCALAPPDATA:{name:"LOCALAPPDATA",kind:"path",default:"unset",doc:"Windows local app data directory; ambient."},MCP_SERVER_VERSION:{name:"MCP_SERVER_VERSION",kind:"string",default:"unset",doc:"Exact override of the reported MCP server version (CI/test pin)."},NPM_PACKAGE_VERSION:{name:"npm_package_version",kind:"string",default:"unset",doc:"Package version exported by npm; ambient fallback for the MCP server version."},NODE_ENV:{name:"NODE_ENV",kind:"string",default:"unset",doc:"Runtime mode; ambient, exact test arms the test-only guards and defaults."},WINDOWS_PATH:{name:"Path",kind:"string",default:"unset",doc:"Windows spelling of PATH; ambient, consulted when PATH is unset."},USERNAME:{name:"USERNAME",kind:"string",default:"unset",doc:"Windows account name; ambient, daemon state file suffix fallback."},PATHEXT:{name:"PATHEXT",kind:"string",default:"unset",doc:"Windows executable extensions; ambient, used to locate bunx."},ADB_SERVER_SOCKET:{name:"ADB_SERVER_SOCKET",kind:"string",default:"unset",doc:"adb server socket spec; ambient, identifies the ADB server scope."},ANDROID_ADB_SERVER_ADDRESS:{name:"ANDROID_ADB_SERVER_ADDRESS",kind:"string",default:"localhost",doc:"adb server host; ambient, identifies the ADB server scope."},ANDROID_ADB_SERVER_PORT:{name:"ANDROID_ADB_SERVER_PORT",kind:"string",default:"5037",doc:"adb server port; ambient, identifies the ADB server scope."},GIT_DIR:{name:"GIT_DIR",kind:"path",default:"unset",doc:"Git repository directory; ambient, honoured when stamping a source build's commit."},GIT_WORK_TREE:{name:"GIT_WORK_TREE",kind:"path",default:"unset",doc:"Git work tree; ambient, locates the source checkout when stamping its commit."},GIT_COMMON_DIR:{name:"GIT_COMMON_DIR",kind:"path",default:"unset",doc:"Git common directory; ambient, resolves shared refs when stamping a commit."},CTRL_PROXY_IOS_BUNDLE_ID:{name:"CTRL_PROXY_IOS_BUNDLE_ID",kind:"string",default:"unset",doc:"Target app bundle id passed to the iOS CtrlProxy runner."},CTRL_PROXY_IOS_TIMEOUT:{name:"CTRL_PROXY_IOS_TIMEOUT",kind:"string",default:"86400",doc:"Runner lifetime in seconds passed to the iOS CtrlProxy runner."}},u=Object.values(g),R=Object.values(K);function E(e,t=process.env){return t[e.name]??(e.legacyName===void 0?void 0:t[e.legacyName])}function ft(e,t=process.env){let n=E(e,t)?.trim();return n?n:void 0}var r=new Set(["1","true","yes","on"]);function $Y(e){return e!==void 0&&r.has(e.trim().toLowerCase())}function $e(e,t=process.env){return $Y(E(e,t))}function wu(e,t=process.env,n){let _=ft(e,t);if(_===void 0)return;let a=Number(_),o=e.min??Number.NEGATIVE_INFINITY;if(Number.isFinite(a)&&(e.minExclusive?a>o:a>=o))return a;n?.(_);return}function soe(e,t=process.env){let n=ft(e,t)?.toLowerCase();return n!==void 0&&e.values?.includes(n)?n:void 0}function b$(e){return e.startsWith("AUTOMOBILE_TOOLSET_")}
3
- export{g,K,E,ft,$Y,$e,wu,soe,b$};
4
-
5
- //# debugId=879E239D281DCB4664756E2164756E21
@@ -1,4 +0,0 @@
1
- // @bun
2
- import{P$,Roe,Poe}from"./chunk-rkr0dks9.js";import"./chunk-6d3mmqxt.js";import"./chunk-ggtd5x5a.js";import"./chunk-z8t0v07j.js";import"./chunk-mf9spd4g.js";export{Poe as guardDatabaseStartup,P$ as handleFatalDatabaseStartupFailure,Roe as resolveDaemonStartupExitCode};
3
-
4
- //# debugId=061AD5A8E85E940964756E2164756E21