@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,5 +0,0 @@
1
- // @bun
2
- import{Vc,tw,cv,Pe}from"./chunk-h3n4adc6.js";var r=new Set([Vc,Pe.DEVICE_PORT,...Array.from({length:cv-tw+1},(o,t)=>tw+t)]),ZI=r;function P7(o){r.add(o)}
3
- export{ZI,P7};
4
-
5
- //# debugId=83CF690DD4D638D364756E2164756E21
@@ -1,5 +0,0 @@
1
- // @bun
2
- import{i,te,xo,l,e}from"./chunk-z8t0v07j.js";import{g}from"./chunk-mf9spd4g.js";import{ne,tW,v,S,W}from"./chunk-h3n4adc6.js";import{L,zn}from"./chunk-32jpxz2y.js";import{IN,_N,_I,mZ,HH,xN,Ty,_c,FN,WH,y6,Ld}from"./chunk-nwm2pq5v.js";import{CP,Ub,Hb}from"./chunk-f9s1kkhx.js";import{Ai}from"./chunk-6d3mmqxt.js";import{r,t,u}from"./chunk-9rkfyt6q.js";var vd=7,bd=8;function Rs(o){return o.length>0?o[0]&31:0}function F(o){let s=Rs(o);return s>=1&&s<=5}function mt(o){return o.length>1&&(o[1]&128)!==0}class nf{current=[];hasVcl=!1;push(o){let s=[],n=Rs(o),a=n===7||n===8||n===6;if(F(o)&&this.hasVcl&&mt(o)||n===9&&this.current.length>0||a&&this.hasVcl)s.push(this.current),this.current=[],this.hasVcl=!1;if(this.current.push(o),F(o))this.hasVcl=!0;return s}flushPicture(){return this.hasVcl?this.flush():[]}flush(){if(this.current.length===0)return[];let o=this.current;return this.current=[],this.hasVcl=!1,[o]}}var Og=5,ht=28,Ee=2,Vk=1200,oO=4194304;function T2(o){return Rs(o)===Og}class za{maxBufferedBytes;buffered=Buffer.alloc(0);constructor(o=oO){this.maxBufferedBytes=o;if(!Number.isSafeInteger(o)||o<1)throw Error("H.264 Annex-B parser buffer limit must be a positive integer.")}push(o){if(this.buffered=this.buffered.length===0?o:Buffer.concat([this.buffered,o]),this.buffered.length>this.maxBufferedBytes)throw this.buffered=Buffer.alloc(0),Error(`H.264 Annex-B parser buffer exceeded ${this.maxBufferedBytes} bytes without a complete NAL.`);return this.drain(!1)}flush(){return this.drain(!0)}hasBufferedNalType(o){let n=this.findStartCodes(this.buffered).at(-1);if(!n)return!1;let a=n.offset+n.length;return a<this.buffered.length&&Rs(this.buffered.subarray(a))===o}drain(o){let s=[],n=this.findStartCodes(this.buffered);if(n.length===0){if(o)this.buffered=Buffer.alloc(0);return s}for(let c=0;c<n.length-1;c++){let d=n[c].offset+n[c].length,p=n[c+1].offset,m=this.buffered.subarray(d,p);if(m.length>0)s.push(Buffer.from(m))}let a=n[n.length-1];if(o){let c=this.buffered.subarray(a.offset+a.length);if(c.length>0)s.push(Buffer.from(c));this.buffered=Buffer.alloc(0)}else this.buffered=Buffer.from(this.buffered.subarray(a.offset));return s}findStartCodes(o){let s=[];for(let n=0;n+2<o.length;n++)if(o[n]===0&&o[n+1]===0&&o[n+2]===1){let a=n>0&&o[n-1]===0;s.push({offset:a?n-1:n,length:a?4:3})}return s}}function ft(o,s=Vk){if(o.length===0)return[];if(o.length<=s)return[Buffer.from(o)];if(!Number.isFinite(s)||s<=Ee)throw new t(`RTP MTU ${s} is too small to fragment a ${o.length}-byte NAL unit; it must exceed the ${Ee}-byte FU-A header.`);let n=o[0],a=n&224,c=n&31,d=a|ht,p=o.subarray(1),m=s-2,f=[],y=0;while(y<p.length){let w=Math.min(m,p.length-y),h=y===0,E=y+w>=p.length,b=c;if(h)b|=128;if(E)b|=64;f.push(Buffer.concat([Buffer.from([d,b]),p.subarray(y,y+w)])),y+=w}return f}function HY(o,s=Vk){let n=[];for(let a of o)for(let c of ft(a,s))n.push(c);return n.map((a,c)=>({payload:a,marker:c===n.length-1}))}class I{entry;options;active=!0;hasConsumers;joined=!1;pendingAlignment=!1;released=!1;startWaiter=null;constructor(o,s,n){this.entry=o;this.options=s;this.hasConsumers=n}start(){if(!this.active||this.entry.retired)return this.released?Promise.resolve():this.entry.startPromise??Promise.resolve();if(!this.joined){if(this.joined=!0,this.pendingAlignment=this.entry.emittedData,this.entry.replayMetrics(this),this.pendingAlignment)this.entry.source?.requestKeyFrame?.("viewer")}if(this.entry.running)return this.entry.start();if(!this.startWaiter)this.startWaiter=Promise.withResolvers(),this.entry.start().then(this.startWaiter.resolve,this.startWaiter.reject);return this.startWaiter.promise}releaseStart(){this.released=!0,this.startWaiter?.resolve()}stop(){return this.entry.release(this)}get stopStale(){return this.entry.source?.stopStale?(o)=>this.entry.release(this,{producerStale:o}):void 0}get setHasConsumers(){let o=this.entry.source??this.entry.lastSource;if(!o||!("setHasConsumers"in o)||typeof o.setHasConsumers!=="function")return;return(s)=>{if(!this.active)return;this.hasConsumers=s,this.entry.updateConsumers()}}get requestKeyFrame(){let o=this.entry.source;return o?.requestKeyFrame?o.requestKeyFrame.bind(o):void 0}get getTelemetry(){let o=this.entry.source;return o?.getTelemetry?o.getTelemetry.bind(o):void 0}}import{isDeepStrictEqual as vt}from"util";var St=["bitrateBps","size","quality","fps"];function be(o,s,n=[]){let a=St.filter((c)=>!n.includes(c)&&s[c]!==void 0&&!vt(o[c],s[c]));if(s.audioEnabled&&!o.audioEnabled)a.push("audioEnabled");return a}class Y{request;onRetire;handles=new Set;parser=new za;source=null;creation=null;startPromise=null;startCompletion=null;retryOwner=null;retryAvailable=!1;finalStop=!1;stopSettled=!1;stopPromise=null;retired=!1;running=!1;sps=null;pps=null;emittedData=!1;frameMetrics=null;loggedConflicts=new Set;lastSource=null;fps;sourceFps;generation=0;restarting=null;constructor(o,s){this.request=o;this.onRetire=s;this.fps=o.options.fps}sharesFrameRate(){return this.request.device.platform==="ios"&&this.fps!==void 0}conflicts(o,s=[],n){let a=be({...this.request.options,fps:this.fps},o,s),c=o.fps;return this.sharesFrameRate()&&c!==void 0&&(n||c<=this.fps)?a.filter((p)=>p!=="fps"):a}canShare(o){let s=this.conflicts(o.options,o.flexibleHints,!0);if(o.options.audioEnabled&&o.options.onAudioData&&!this.request.options.onAudioData)s.push("onAudioData");if(s.length===0)return!0;let n=s.join(", ");if(!this.loggedConflicts.has(n))this.loggedConflicts.add(n),e.info(`[DeviceCapture] ${o.device.deviceId}: private capture required by incompatible settings (${n})`);return!1}add(o){let s=new I(this,o.options,o.hasConsumers??!0);this.handles.add(s),s.pendingAlignment=this.emittedData,this.updateConsumers();let n=o.options.fps;if(!o.flexibleHints?.includes("fps")&&n!==void 0&&this.sharesFrameRate()&&n>this.fps)this.raiseFrameRate(n);return s}initialize(){let o=this.request.create(this.sourceOptions());if(!(o instanceof Promise))this.adopt(o),this.creation=Promise.resolve(o);else this.creation=o.then((s)=>(this.adopt(s),s)),this.creation.then(void 0,()=>this.creationFailed())}adopt(o){this.source=o,this.lastSource=o,this.updateConsumers()}raiseFrameRate(o){e.info(`[DeviceCapture] ${this.request.device.deviceId}: restarting shared capture at ${o} fps (was ${this.fps})`),this.fps=o,this.restarting??=this.restartAtTargetRate()}async restartAtTargetRate(){if(this.running=!1,this.startPromise)this.startCompletion=Promise.withResolvers(),this.startPromise=this.startCompletion.promise,this.startPromise.catch((o)=>{e.debug(`[DeviceCapture] restart start rejected: ${r(o)}`)});try{while(!this.retired&&this.sourceFps!==this.fps)if(await this.replaceSource(),!this.retired&&this.startPromise&&this.source&&this.sourceFps===this.fps)await this.source.start();this.running=!this.retired&&this.startPromise!==null,this.startCompletion?.resolve()}catch(o){this.restartFailed(o)}finally{this.restarting=null}}restartFailed(o){let s=this.startCompletion;if(this.retired){s?.resolve();return}e.warn(`[DeviceCapture] ${this.request.device.deviceId}: frame-rate restart failed`,o),this.fail(o instanceof Error?o:Error(String(o)));let n=()=>s?.reject(o);this.stopPromise?.then(n,n)}async replaceSource(){if(!this.source)await this.creation?.catch(()=>null);let o=this.source;if(this.retired||!o||this.sourceFps===this.fps)return;this.generation++,this.source=null,this.parser=new za,this.sps=null,this.pps=null;let s=Promise.withResolvers();this.creation=s.promise,s.promise.catch((a)=>{e.debug(`[DeviceCapture] restart replacement not adopted: ${r(a)}`)});try{await o.stop()}catch(a){e.warn(`[DeviceCapture] ${this.request.device.deviceId}: stopping capture for restart failed`,a)}if(this.retired){s.reject(Error("Capture released during frame-rate restart"));return}let n;try{n=await this.request.create(this.sourceOptions())}catch(a){throw s.reject(a),a}this.adopt(n),s.resolve(n)}start(){if(this.startPromise)return this.startPromise;if(this.startCompletion=Promise.withResolvers(),this.startPromise=this.startCompletion.promise,this.restarting)return this.startPromise;if(this.source)this.startSource(this.source);else{if(!this.creation)this.initialize();this.creation.then((o)=>this.startSource(o),(o)=>this.startFailed(o))}return this.startPromise}startSource(o){if(this.retired){this.startCompletion?.resolve();return}if(this.restarting)return;let s=this.generation,n=()=>s!==this.generation||this.restarting!==null;try{o.start().then(()=>{if(n())return;this.running=!this.retired,this.startCompletion?.resolve()},(a)=>{if(n()){e.debug(`[DeviceCapture] ${this.request.device.deviceId}: replaced source start aborted: ${r(a)}`);return}this.startFailed(a)})}catch(a){e.warn(`[DeviceCapture] ${this.request.device.deviceId}: source start failed`,a),this.startFailed(a)}}creationFailed(){if(!this.startPromise)this.retire(void 0,!0)}startFailed(o){if(this.retired){this.startCompletion?.resolve();return}this.retire(void 0,!0).then(()=>this.startCompletion?.reject(o))}release(o,s){if(!o.active){if(o.releaseStart(),o===this.retryOwner&&this.retryAvailable)return this.retryAvailable=!1,this.retryOwner=null,this.finalStop=!0,this.beginStop(s,!1);return this.finalStop&&this.stopSettled?Promise.resolve():this.stopPromise??Promise.resolve()}if(o.active=!1,o.releaseStart(),this.handles.delete(o),s&&this.handles.size>0){this.retryOwner=o;let n=[...this.handles],a=Error(`Shared capture for ${this.request.device.deviceId} retired: producer declared stale`);return this.retire(s,!1,()=>{for(let c of n)this.deliver(c,(d)=>d.onError?.(a))})}if(this.handles.size===0)return this.retryOwner=o,this.retire(s);return this.updateConsumers(),Promise.resolve()}retire(o,s=!1,n){if(this.stopPromise)return this.stopPromise;this.retired=!0,this.running=!1;for(let a of this.handles)if(a.active=!1,o)a.releaseStart();return this.handles.clear(),this.beginStop(o,s,n)}beginStop(o,s,n){let a=Promise.withResolvers();this.stopSettled=!1,this.stopPromise=a.promise,this.onRetire(this),n?.();let c=()=>this.stopSource(o,s,a);if(!this.source&&this.creation)this.creation.then(c,c);else c();return a.promise}stopSource(o,s,n){try{((o&&this.source?.stopStale?this.source.stopStale(o.producerStale):this.source?.stop())??Promise.resolve()).then(()=>{this.stopSettled=!0,n.resolve()},(c)=>this.stopFailed(c,s,n))}catch(a){this.stopFailed(a,s,n)}}stopFailed(o,s,n){if(this.stopSettled=!0,e.warn(`[DeviceCapture] ${this.request.device.deviceId}: source stop failed`,o),s)n.resolve();else this.retryAvailable=this.retryOwner!==null,n.reject(o)}updateConsumers(){let o=this.source;if(o&&"setHasConsumers"in o&&typeof o.setHasConsumers==="function")o.setHasConsumers([...this.handles].some((s)=>s.hasConsumers))}deliver(o,s){try{s(o.options)}catch(n){e.warn(`[DeviceCapture] ${this.request.device.deviceId}: capture sink failed`,n)}}fanout(o){for(let s of[...this.handles])if(s.active)this.deliver(s,o)}cache(o){for(let s of o){let n=Rs(s);if(n===vd)this.sps=Buffer.concat([Buffer.from([0,0,0,1]),s]);else if(n===bd)this.pps=Buffer.concat([Buffer.from([0,0,0,1]),s])}}replay(o){for(let s of[this.sps,this.pps])if(s&&o.active)this.deliver(o,(n)=>(n.onReplayData??n.onData)(s))}replayMetrics(o){if(this.frameMetrics)this.deliver(o,(s)=>s.onFrameMetrics?.(this.frameMetrics))}deliverData(o){for(let s of[...this.handles]){if(!s.active)continue;let n=o;if(s.pendingAlignment){let a=o.indexOf(Buffer.from([0,0,1]));if(a<0)continue;let c=a>0&&o[a-1]===0?a-1:a;s.pendingAlignment=!1,this.replay(s),n=o.subarray(c)}if(s.active)this.deliver(s,(a)=>a.onData(n))}}fail(o){if(this.retired)return;let s=[...this.handles];this.retire(void 0,!0,()=>{for(let n of s)this.deliver(n,(a)=>a.onError?.(o))})}sourceOptions(){let o=this.generation;this.sourceFps=this.fps;let s=()=>this.retired||o!==this.generation,n=(a)=>(...c)=>{if(!s())a(...c)};return{...this.request.options,fps:this.fps,onData:(a)=>{if(s())return;try{this.cache(this.parser.push(a))}catch(c){e.warn(`[DeviceCapture] ${this.request.device.deviceId}: invalid H.264 stream`,c)}this.emittedData||=a.length>0,this.deliverData(a)},onEncodedAccessUnit:n(()=>{this.cache(this.parser.flush());for(let a of[...this.handles])if(a.active&&!a.pendingAlignment)this.deliver(a,(c)=>c.onEncodedAccessUnit?.())}),onSourceFrame:n(()=>this.fanout((a)=>a.onSourceFrame?.())),onSourceIdle:n(()=>this.fanout((a)=>a.onSourceIdle?.())),onIdleAttestationSupport:n((a)=>this.fanout((c)=>c.onIdleAttestationSupport?.(a))),onRotation:n((a)=>this.fanout((c)=>c.onRotation?.(a))),onDroppedFrames:n((a)=>this.fanout((c)=>c.onDroppedFrames?.(a))),onFrameMetrics:n((a)=>{this.frameMetrics=a,this.fanout((c)=>c.onFrameMetrics?.(a))}),onAudioData:this.request.options.onAudioData?n((a)=>this.fanout((c)=>c.onAudioData?.(a))):void 0,onError:n((a)=>this.fail(a))}}}function qY(o,s,n=[]){return o instanceof I&&o.entry.handles.size>1&&o.entry.conflicts(s,n,!1).length===0}function VY(o,s){return o instanceof I?o.entry.release(o,{producerStale:s}):o.stopStale?o.stopStale(s):o.stop()}class Ce{entries=new Map;stopping=new Map;acquire(o){let s=o.device.deviceId,n=this.entries.get(s),a=n?!n.canShare(o):!1;if(n&&!a)return n.add(o);let c=new Y(o,(m)=>{if(this.entries.get(s)===m)this.entries.delete(s);let f=m.stopPromise,y=this.stopping.get(s)??new Set;y.add(m),this.stopping.set(s,y);let w=()=>{if(m.stopPromise===f){if(y.delete(m),y.size===0)this.stopping.delete(s)}};f.then(w,w)}),d=c.add(o);if(!a)this.entries.set(s,c);let p=this.stopping.get(s);if(p?.size){let m=()=>{if(c.retired)throw Error("Capture released before creation");return c.initialize(),c.creation},f=(y)=>{let w=y.stopPromise,h=()=>y.stopPromise!==w?f(y):void 0;return w.then(h,h)};c.creation=Promise.all([...p].map(f)).then(m),c.creation.then(void 0,()=>c.creationFailed())}else try{c.initialize()}catch(m){if(e.warn(`[DeviceCapture] ${s}: source creation failed`,m),this.entries.get(s)===c)this.entries.delete(s);throw c.retired=!0,d.active=!1,c.handles.clear(),m}return d}}function k2(){return new Ce}var gt;function cO(){return gt??=k2()}var yt={low:2000000,medium:4000000,high:8000000},j={low:540,medium:720,high:1080};function D(o,s){if(!s)return o;if(!Number.isFinite(o.width)||!Number.isFinite(o.height)||o.width<=0||o.height<=0)return o;let n=j[s],a=Math.max(o.width,o.height);if(a<=n)return{width:Math.max(2,o.width&-2),height:Math.max(2,o.height&-2)};let c=n/a;if(o.height>=o.width)return{width:Math.max(2,Math.trunc(o.width*c)&-2),height:n};return{width:n,height:Math.max(2,Math.trunc(o.height*c)&-2)}}function N(o){return o?yt[o]:void 0}var wt=(Ai-5)*1000,Et={width:1280,height:720},bt=3000,Ct=2000,Pt=30000,Tt=2,Rt=te({initialDelayMs:500,multiplier:2,maxDelayMs:2000});class X{options;adbFactory;timer;segmentTimeLimitSeconds;segmentRotateMs;healthySegmentAgeMs;runningRetryMaxAttempts;runningRetryBackoff;current=null;segmentStartedAtMs=null;rotateHandle=null;cancelRetryDelay=null;running=!1;runId=0;runningRetryAttempts=0;segmentCount=0;resolvedSize=null;lastForcedKeyFrameMs=Number.NEGATIVE_INFINITY;constructor(o){this.options=o,this.adbFactory=o.adbFactory??v,this.timer=o.timer??i,this.segmentTimeLimitSeconds=Math.min(o.segmentTimeLimitSeconds??Ai,Ai),this.segmentRotateMs=o.segmentRotateMs??wt,this.healthySegmentAgeMs=Math.min(Pt,this.segmentRotateMs/2),this.runningRetryMaxAttempts=o.runningRetryMaxAttempts??Tt,this.runningRetryBackoff=xo(o.runningRetryBackoff??Rt)}get segmentsStarted(){return this.segmentCount}get isRunning(){return this.running}async start(){if(this.running)throw new t("Android H.264 source already started.");this.runId++,this.runningRetryAttempts=0,this.running=!0,await this.startSegment()}async stop(){if(this.runId++,this.cancelRetryDelay?.(),!this.running)return;this.running=!1,this.clearRotateTimer(),this.segmentStartedAtMs=null;let o=this.current;if(this.current=null,!o)return;o.kill("SIGINT")}requestKeyFrame(){let o=this.current;if(!this.running||!o)return!1;let s=this.timer.now();if(s-this.lastForcedKeyFrameMs<bt)return!1;return this.lastForcedKeyFrameMs=s,e.info(`[AndroidH264Source] keyframe requested; rotating segment ${this.segmentCount} to emit a fresh IDR`),o.kill("SIGINT"),!0}async startSegment(){let o=this.runId,s=this.adbFactory.create(this.options.device);if(!this.running||o!==this.runId)return;let n=await this.captureSize(s);if(!this.running||o!==this.runId)return;let a=["exec-out","screenrecord","--output-format=h264","--time-limit",String(this.segmentTimeLimitSeconds)],c=this.options.bitrateBps&&this.options.bitrateBps>0?this.options.bitrateBps:N(this.options.quality);if(c!==void 0)a.push("--bit-rate",String(Math.round(c)));a.push("--size",`${n.width}x${n.height}`),a.push("-"),e.info(`[AndroidH264Source] starting screenrecord segment ${this.segmentCount+1}: ${a.join(" ")}`);let d=await s.spawn(a);if(!this.running||o!==this.runId){d.kill("SIGINT");return}this.current=d,this.segmentStartedAtMs=this.timer.now(),this.segmentCount++;let p=new za;d.stdout.on("data",(m)=>{if(this.current===d){if(m.length>0){let f=!1;try{f=p.push(m).some(F)}catch(y){this.options.onError?.(y instanceof Error?y:Error(String(y)));return}if(f)this.options.onSourceFrame?.()}this.options.onData(m)}}),d.stderr.on("data",(m)=>{let f=m.toString().trim();if(f)e.debug(`[AndroidH264Source] screenrecord stderr: ${f}`)}),d.once("error",(m)=>{if(e.warn(`[AndroidH264Source] screenrecord process error: ${m.message}`),this.current===d&&this.running)this.resetRetryAfterHealthySegment(),this.current=null,this.segmentStartedAtMs=null,this.clearRotateTimer(),d.kill("SIGINT"),this.retryAfterFailure(m)}),d.once("exit",(m,f)=>{this.handleSegmentExit(d,m,f)}),this.armRotateTimer()}handleSegmentExit(o,s,n){if(this.current!==o)return;let a=this.segmentStartedAtMs,c=a===null?0:this.timer.now()-a;if(this.resetRetryAfterHealthySegment(),this.current=null,this.segmentStartedAtMs=null,this.clearRotateTimer(),!this.running)return;if(!(n==="SIGINT"||s===0&&c>=Ct)){e.warn(`[AndroidH264Source] screenrecord failed (code=${s}, signal=${n}, age=${c}ms); retrying`),this.retryAfterFailure(Error(`screenrecord exited with code ${s}`));return}e.info(`[AndroidH264Source] segment ${this.segmentCount} ended (code=${s}, signal=${n}); rotating`);let p=this.runId;this.startSegment().catch((m)=>{e.warn(`[AndroidH264Source] failed to start next segment: ${m}`),this.retryAfterFailure(m instanceof Error?m:Error(String(m)),p)})}resetRetryAfterHealthySegment(){if(this.segmentStartedAtMs!==null&&this.timer.now()-this.segmentStartedAtMs>=this.healthySegmentAgeMs)this.runningRetryAttempts=0}async retryAfterFailure(o,s=this.runId){if(!this.running||s!==this.runId)return;if(this.runningRetryAttempts>=this.runningRetryMaxAttempts){this.running=!1,this.clearRotateTimer(),this.options.onError?.(o);return}let n=++this.runningRetryAttempts;if(await this.waitRetryBackoff(this.runningRetryBackoff.delayForAttempt(n))||!this.running||s!==this.runId)return;this.startSegment().catch((c)=>{e.warn(`[AndroidH264Source] failed to start retry segment: ${c}`),this.retryAfterFailure(c instanceof Error?c:Error(String(c)),s)})}waitRetryBackoff(o){return new Promise((s)=>{let n=this.timer.setTimeout(()=>{this.cancelRetryDelay=null,s(!1)},o);this.cancelRetryDelay=()=>{this.timer.clearTimeout(n),this.cancelRetryDelay=null,s(!0)}})}armRotateTimer(){this.clearRotateTimer(),this.rotateHandle=this.timer.setTimeout(()=>{let o=this.current;if(!this.running||!o)return;e.info(`[AndroidH264Source] rotating segment ${this.segmentCount} before time limit`),o.kill("SIGINT")},this.segmentRotateMs)}clearRotateTimer(){if(this.rotateHandle)this.timer.clearTimeout(this.rotateHandle),this.rotateHandle=null}async captureSize(o){if(this.options.size)return this.options.size;if(this.resolvedSize)return this.resolvedSize;try{let{stdout:s}=await o.executeCommand("shell wm size"),n=/Physical size:\s*(\d+)x(\d+)/.exec(s);if(n)return this.resolvedSize=At(D({width:Number(n[1]),height:Number(n[2])},this.options.quality)),this.resolvedSize}catch(s){e.debug(`[AndroidH264Source] could not query display size: ${s}`)}return this.resolvedSize=D(Et,this.options.quality),this.resolvedSize}}function At(o){let s=Math.min(1,Math.sqrt(FN*256/(o.width*o.height))),n=Math.max(2,Math.floor(o.width*s/2)*2),a=Math.max(2,Math.floor(o.height*s/2)*2);while(WH(n,a)>FN)if(n>=a)n-=2;else a-=2;return{width:n,height:a}}import{connect as $t}from"net";var It=new Set;class V{byDevice=new Map;add(o,s){let n=this.byDevice.get(o);if(n){n.add(s);return}this.byDevice.set(o,new Set([s]))}remove(o,s){let n=this.byDevice.get(o);if(!n)return;if(n.delete(s),n.size===0)this.byDevice.delete(o)}active(o){return this.byDevice.get(o)??It}}import{createHash as Ht}from"crypto";var B="automobile_video",ee="dev.jasonpearson.automobile.video.VideoServer",T="/data/local/tmp/automobile-video-sessions",_t=30000,Ft=300000,Mt=300000;function kt(o){return Ht("sha256").update(o,"ascii").digest("hex")}function xt(o){let s=o.trim().split(/\s+/),n=s.find((d)=>d.startsWith(`localabstract:${B}_`)),a=s.find((d)=>d.startsWith("tcp:"));if(n===void 0||a===void 0)return null;let c=Number.parseInt(a.slice(4),10);if(!Number.isInteger(c)||c<=0)return null;return{port:c,socketName:n.slice(14)}}function Ot(o){return typeof o==="string"&&/^[a-f0-9]{64}$/.test(o)}var re=/^[A-Za-z0-9_.-]{1,100}$/;function Q(o){return typeof o==="number"&&Number.isInteger(o)&&o>0}function Z(o){return typeof o==="number"&&Number.isFinite(o)}function Dt(o){return o===void 0||Z(o)&&o>=0}function Nt(o){if(typeof o!=="object"||o===null)return!1;if(!Bt(o))return!1;let s=o;return[Ot(s.sessionTokenHash),typeof s.socketName==="string",typeof s.socketName==="string"&&re.test(s.socketName),typeof s.deviceSerial==="string",Q(s.ownerPid),Q(s.pid),Q(s.forwardPort),Z(s.startedAtMs),Z(s.heartbeatAtMs),Dt("heartbeatElapsedRealtimeMs"in s?s.heartbeatElapsedRealtimeMs:void 0)].every(Boolean)}function Pe(o){return o.split(/\r?\n/).flatMap((s)=>{try{let n=JSON.parse(s);if(!Nt(n))return[];return[n]}catch(n){return e.debug(`[PersistentEncoderH264Source] ignoring malformed video session lease: ${n}`),[]}})}var Lt=/^[A-Za-z0-9_.-]+\.json(?:\.tmp)?$/;function Vt(o){let s=null,n=[];for(let a of o.split(/\r?\n/)){let c=a.trim();if(c.length===0)continue;if(c.startsWith("NOW ")){let y=Number.parseInt(c.slice(4).trim(),10);if(Number.isFinite(y)&&y>=0)s=y*1000;continue}let d=c.indexOf(" ");if(d<=0)continue;let p=Number.parseInt(c.slice(0,d),10),m=c.slice(d+1).trim(),f=m.slice(m.lastIndexOf("/")+1);if(!Number.isFinite(p)||p<0||!Lt.test(f))continue;n.push({name:f,mtimeMs:p*1000})}return{nowEpochMs:s,files:n}}class ie{options;adbFactory;timer;teardownTimeoutMs;withTimeout;activeVideoSessionRegistry;constructor(o,s,n,{activeVideoSessionRegistry:a,teardown:c}){this.options=o;this.adbFactory=s;this.timer=n;this.activeVideoSessionRegistry=a,this.teardownTimeoutMs=c.timeoutMs,this.withTimeout=c.withTimeout}async reconcileExpiredLeases(o){let s;try{let a=`for f in ${T}/*.json; do [ -f "$f" ] || continue; cat "$f"; printf "\\n"; done`,c=await this.withTimeout(o.executeCommand(`shell sh -c ${S(a)}`),this.teardownTimeoutMs,"adb read video session leases");s=Pe(c.stdout)}catch(a){e.debug(`[PersistentEncoderH264Source] unable to read video session leases: ${a}`);return}if(await this.sweepOrphanLeaseFiles(o,new Set(s.map((a)=>`${a.socketName}.json`))),await this.sweepOrphanForwards(o,new Set(s.map((a)=>a.socketName))),s.length===0)return;let n=await this.readDeviceElapsedRealtimeMs(o);if(n===null){e.warn("[PersistentEncoderH264Source] unable to read device uptime; skipping stale-session cleanup");return}for(let a of s){let c=this.classifyLeaseForReclaim(a,n);if(c===null)continue;e.info(`[PersistentEncoderH264Source] stale-session-cleanup socket=${a.socketName} reason=${c}`),await this.removeForwardIfMatching(o,a.forwardPort,a.socketName),await this.terminateProcessIfMatching(o,a),await this.removeLeaseIfMatching(o,a)}}classifyLeaseForReclaim(o,s){let n=o.heartbeatElapsedRealtimeMs;if(n!==void 0&&s-n<0)return"previous-boot";if(o.deviceSerial!==this.options.device.deviceId)return null;if(n===void 0)return this.timer.now()-o.heartbeatAtMs>=Ft?"wall-clock-stale":null;return s-n>=_t?"elapsed-stale":null}async sweepOrphanLeaseFiles(o,s){let n;try{let a=`printf 'NOW %s\\n' "$(date +%s)"; for f in ${T}/*.json ${T}/*.json.tmp; do [ -f "$f" ] || continue; stat -c '%Y %n' "$f"; done`,c=await this.withTimeout(o.executeCommand(`shell sh -c ${S(a)}`),this.teardownTimeoutMs,"adb list stale video session lease files");n=Vt(c.stdout)}catch(a){e.debug(`[PersistentEncoderH264Source] unable to list video session lease files: ${a}`);return}if(n.nowEpochMs===null){e.debug("[PersistentEncoderH264Source] lease-file sweep skipped: no device clock in listing");return}for(let a of n.files){if(!a.name.endsWith(".json.tmp")&&s.has(a.name))continue;let d=n.nowEpochMs-a.mtimeMs;if(d<Mt)continue;e.info(`[PersistentEncoderH264Source] stale-lease-file-sweep name=${a.name} ageMs=${d}`);try{await this.withTimeout(o.executeCommand(`shell rm -f ${T}/${a.name}`),this.teardownTimeoutMs,"adb remove stale video session lease file")}catch(p){e.debug(`[PersistentEncoderH264Source] stale-lease-file sweep failed name=${a.name}: ${p}`)}}}async sweepOrphanForwards(o,s){let n;try{n=(await this.withTimeout(o.executeCommand("forward --list"),this.teardownTimeoutMs,"adb forward --list for orphan sweep")).stdout}catch(d){e.debug(`[PersistentEncoderH264Source] unable to list forwards for orphan sweep: ${d}`);return}let a=this.activeVideoSessionRegistry.active(this.options.device.deviceId),c=[];for(let d of n.split(/\r?\n/)){let p=xt(d);if(p===null)continue;if(s.has(p.socketName)||a.has(p.socketName))continue;c.push(p)}for(let d of c)e.info(`[PersistentEncoderH264Source] orphan-forward-sweep port=${d.port} socket=${d.socketName}`),await this.removeForwardIfMatching(o,d.port,d.socketName)}async cleanupOwnedSession(o,s,n){let a=this.adbFactory.create(this.options.device),c=await this.readLease(a,o.socketName);if(c&&this.isOwnedSessionLease(c,o,n)){await this.removeForwardIfMatching(a,c.forwardPort,c.socketName),await this.removeOwnedForward(a,s,o.socketName,c.forwardPort),await this.terminateProcessIfMatching(a,c),await this.removeLeaseIfMatching(a,c);return}if(c){e.warn(`[PersistentEncoderH264Source] refusing owned-session process cleanup socket=${o.socketName}: lease identity or PID mismatch`),await this.removeOwnedForward(a,s,o.socketName);return}await this.removeOwnedForward(a,s,o.socketName)}isOwnedSessionLease(o,s,n){return o.sessionTokenHash===kt(s.token)&&o.socketName===s.socketName&&o.ownerPid===s.ownerPid&&o.deviceSerial===s.deviceSerial&&(n===null||o.pid===n)}async removeOwnedForward(o,s,n,a){if(s!==null&&s!==a)await this.removeForwardIfMatching(o,s,n)}async readLease(o,s){try{let n=await this.withTimeout(o.executeCommand(`shell cat ${T}/${s}.json`),this.teardownTimeoutMs,"adb read owned video session lease");return Pe(n.stdout).find((a)=>a.socketName===s)??null}catch(n){return e.debug(`[PersistentEncoderH264Source] unable to read owned video session lease: ${n}`),null}}async terminateProcessIfMatching(o,s){try{let n=await this.withTimeout(o.executeCommand(`shell cat /proc/${s.pid}/cmdline`),this.teardownTimeoutMs,"adb read video-server process cmdline"),a=n.stdout.split("\x00");if(n.stdout.length===0||a.every((d)=>d.length===0)){e.debug(`[PersistentEncoderH264Source] stale-session process cleanup skipped socket=${s.socketName}: process already exited`);return}let c=a.some((d,p)=>d==="--socket-name"&&a[p+1]===s.socketName);if(!a.includes(ee)||!c){e.warn(`[PersistentEncoderH264Source] refusing stale-session process cleanup socket=${s.socketName}: PID/socket mismatch`);return}await this.withTimeout(o.executeCommand(`shell kill -2 ${s.pid}`),this.teardownTimeoutMs,"adb terminate video-server process")}catch(n){e.debug(`[PersistentEncoderH264Source] stale-session process cleanup skipped socket=${s.socketName}: ${n}`)}}async removeForwardIfMatching(o,s,n){try{let a=await this.withTimeout(o.executeCommand("forward --list"),this.teardownTimeoutMs,"adb forward --list"),c=`tcp:${s}`,d=`localabstract:${n}`;if(!a.stdout.split(/\r?\n/).some((m)=>{let f=m.trim().split(/\s+/);return f.includes(c)&&f.includes(d)})){e.warn(`[PersistentEncoderH264Source] refusing stale-session forward cleanup port=${s}: destination mismatch`);return}await this.withTimeout(o.executeCommand(`forward --remove tcp:${s}`),this.teardownTimeoutMs,"adb forward --remove")}catch(a){e.debug(`[PersistentEncoderH264Source] forward --remove failed: ${a}`)}}async removeLeaseIfMatching(o,s){let n=await this.readLease(o,s.socketName);if(n?.socketName!==s.socketName||n.sessionTokenHash!==s.sessionTokenHash||n.pid!==s.pid)return;try{await this.withTimeout(o.executeCommand(`shell rm -f ${T}/${s.socketName}.json`),this.teardownTimeoutMs,"adb remove video session lease")}catch(a){e.debug(`[PersistentEncoderH264Source] stale-session lease cleanup failed: ${a}`)}}async readDeviceElapsedRealtimeMs(o){try{let s=await this.withTimeout(o.executeCommand("shell cat /proc/uptime"),this.teardownTimeoutMs,"adb read device uptime"),n=Number.parseFloat(s.stdout.trim().split(/\s+/,1)[0]??"");if(Number.isFinite(n)&&n>=0)return Math.floor(n*1000)}catch(s){e.debug(`[PersistentEncoderH264Source] unable to read device uptime: ${s}`)}return null}}function Bt(o){if(!(("sessionTokenHash"in o)&&("socketName"in o)&&("deviceSerial"in o)&&("ownerPid"in o)&&("pid"in o)&&("forwardPort"in o)&&("startedAtMs"in o)&&("heartbeatAtMs"in o)))return!1;return!0}var Re=1,oe=1,Te=Buffer.from([65,86,77,72]),Ae=5000,Ie=100,He=20000,_e=5000,Fe=3,Me=te({initialDelayMs:1000,multiplier:2,maxDelayMs:8000}),ke=60000,xe=new V,Oe=(o,s)=>new Promise((n,a)=>{let c=$t(o,"127.0.0.1"),d=!1,p=(w)=>{if(d)return;d=!0,c.off("connect",m),c.off("error",f),s?.removeEventListener("abort",y),w()},m=()=>p(()=>n(c)),f=(w)=>p(()=>a(w)),y=()=>p(()=>{c.destroy(),a(Error("video-server socket connection aborted"))});if(c.once("connect",m),c.once("error",f),s?.aborted){y();return}s?.addEventListener("abort",y,{once:!0})}),De=1e4;function Ne(o){return`${B}_${o.next().replaceAll("-","")}`}function Le(o,s){let n=Buffer.from(o,"ascii"),a=Buffer.alloc(Te.length+2+n.length),c=Te.copy(a,0);return c=a.writeUInt8(s,c),c=a.writeUInt8(n.length,c),n.copy(a,c),a}function Ve(o){return/^[A-Za-z0-9-]{8,80}$/.test(o)}var R="/data/local/tmp/automobile-video.jar";function Ut(o){let s=null,n=null;for(let a of o.split(/\r?\n/)){let c=a.trim();if(c.length===0)continue;if(/^[0-9]+$/.test(c)){n=Number.parseInt(c,10);continue}let d=/^([a-f0-9]{64})(?:\s|$)/.exec(c);if(d)s=d[1]}if(s===null||n===null||!Number.isInteger(n)||n<0)return null;return{sha256:s,size:n}}class se{options;commandTimeoutMs;withTimeout;expectedJarIntegrity=null;remoteJarVerified=!1;jarIntegrityProvider;constructor(o,s,n){this.options=o;this.commandTimeoutMs=s;this.withTimeout=n;this.jarIntegrityProvider=o.jarIntegrityProvider}async ensureRemoteJar(o){let s=await this.resolveExpectedJarIntegrity(),n=await this.statAndHashRemoteJar(o);if(n!==null&&n.size===s.size&&n.sha256===s.sha256){this.remoteJarVerified=!0,e.info(`[PersistentEncoderH264Source] on-device video-server jar already matches (sha256=${s.sha256}, size=${s.size}); skipping push`);return}if(n!==null)e.info(`[PersistentEncoderH264Source] on-device video-server jar differs (expected sha256=${s.sha256} size=${s.size}, remote sha256=${n.sha256} size=${n.size}); pushing`);await this.withTimeout(o.executeCommand(`push "${this.options.jarPath}" ${R}`,{timeoutMs:this.commandTimeoutMs}),this.commandTimeoutMs,"adb push video-server jar")}async verifyRemoteJarBeforeLaunch(o){if(this.remoteJarVerified)return;let s=await this.resolveExpectedJarIntegrity(),n=await this.statAndHashRemoteJar(o);if(n===null){e.warn(`[PersistentEncoderH264Source] could not hash the on-device jar at ${R} before launch; proceeding on the just-pushed trusted bytes (integrity verification degraded)`);return}if(n.size!==s.size||n.sha256!==s.sha256)throw new t(`Refusing to launch video-server: the on-device jar at ${R} failed integrity verification (expected sha256=${s.sha256} size=${s.size}, got sha256=${n.sha256} size=${n.size}). The bytes on the device do not match the verified host copy; app_process will not be launched.`);this.remoteJarVerified=!0}async resolveExpectedJarIntegrity(){if(this.expectedJarIntegrity===null){let s=await(this.jarIntegrityProvider??Ld.getInstance()).computeLocalJarIntegrity(this.options.jarPath);this.expectedJarIntegrity={sha256:s.sha256.toLowerCase(),size:s.size}}return this.expectedJarIntegrity}async statAndHashRemoteJar(o){let s=`sha256sum ${R} 2>/dev/null; wc -c < ${R} 2>/dev/null`;try{let n=await this.withTimeout(o.executeCommand(`shell sh -c ${S(s)}`,{timeoutMs:this.commandTimeoutMs}),this.commandTimeoutMs,"adb hash video-server jar");return Ut(n.stdout)}catch(n){return e.debug(`[PersistentEncoderH264Source] unable to hash on-device video-server jar: ${n}`),null}}}function Be(o){let s=o.session;if(!s||o.forwardedPort===null)throw Error("Video server session was not initialized.");let n=["shell",`CLASSPATH=${R}`,"app_process","/",ee,"--quality",o.options.quality??"medium","--socket-name",s.socketName,"--session-token",s.token,"--owner-pid",String(s.ownerPid),"--device-serial",s.deviceSerial,"--forward-port",String(o.forwardedPort)];if(o.options.bitrateBps&&o.options.bitrateBps>0)n.push("--bit-rate",String(Math.round(o.options.bitrateBps)));if(Number.isInteger(o.options.fps)&&o.options.fps>0)n.push("--fps",String(o.options.fps));if(o.options.size)n.push("--size",`${o.options.size.width}x${o.options.size.height}`);if(o.options.audioEnabled)n.push("--audio");return n}function $e(o){let s=o.sessionTokenFactory();if(!Ve(s))throw Error("Video server session token factory returned an unsafe token.");let n=o.socketNameFactory();if(!re.test(n))throw Error("Video server socket-name factory returned an unsafe socket name.");return{token:s,socketName:n,ownerPid:process.pid,deviceSerial:o.options.device.deviceId}}function Ue(o){if(o===null)return e.warn("[PersistentEncoderH264Source] device advertised no handshake protocol; streaming without a token handshake (defense-in-depth degraded, UID gating still applies)"),null;return Math.min(o,oe)}function We(o,s){let{session:n,negotiatedHandshakeVersion:a}=o;if(!n||a===null)return;try{s.write(Le(n.token,a))}catch(c){e.debug(`[PersistentEncoderH264Source] handshake write failed: ${c}`)}}function qe(o,s,n,a){return new Promise((c,d)=>{let p=!1,m=o.timer.setTimeout(()=>{if(p)return;p=!0,e.warn(`[PersistentEncoderH264Source] ${a} timed out after ${n}ms`),d(new t(`${a} did not complete within ${n}ms`))},n);s.then((f)=>{if(p)return;p=!0,o.timer.clearTimeout(m),c(f)},(f)=>{if(p)return;p=!0,o.timer.clearTimeout(m),d(f instanceof Error?f:Error(String(f)))})})}var K=1748121140,Wt=1634563448,x=1932605036,qt=1,Kt=2,M=12,U=12,Ke=16,q=16,ze=16777216,zt=16,ae=1n<<63n,Je=1n<<62n,Ge=1n<<61n,ue=59n,Jt=0b11n<<ue,Ye=(1n<<ue)-1n;class k{callbacks;buffered=new IN;header=null;muxTracks=null;constructor(o){this.callbacks=o}static rotationFromFlags(o){if((o&ae)===0n)return;return Number((o&Jt)>>ue)}assertWithinCap(o,s,n){if(o>s)throw new t(`video-server stream declared ${n}=${o}, exceeding the ${s} cap; the stream is likely corrupt or out of sync.`)}push(o){if(this.buffered.append(o),!this.header&&!this.muxTracks&&!this.readStreamHeader())return;if(this.muxTracks){this.drainMuxPackets();return}while(this.buffered.length>=U){let s=this.buffered.peek(U),n=s.readBigUInt64BE(0),a=s.readUInt32BE(8);if(this.assertWithinCap(a,ze,"packet size"),this.buffered.length<U+a)break;this.buffered.discard(U);let c=this.buffered.takeDetached(a);this.callbacks.onPacket({trackId:qt,codecId:this.header?.codecId??K,data:c,config:(n&ae)!==0n,keyFrame:(n&Je)!==0n,replayed:(n&Ge)!==0n,rotation:k.rotationFromFlags(n),ptsUs:Number(n&Ye)})}}readStreamHeader(){if(this.buffered.length<M)return!1;let o=this.buffered.peek(M),s=o.readUInt32BE(0);if(s===Wt){let n=o.readUInt32BE(8);this.assertWithinCap(n,zt,"trackCount");let a=M+n*Ke;if(this.buffered.length<a)return!1;let c=this.buffered.peek(a);this.muxTracks=new Map;let d=null,p=!1;for(let m=0;m<n;m++){let f=M+m*Ke,y=c.readUInt32BE(f),w=c.readUInt32BE(f+4),h=c.readUInt32BE(f+8),E=c.readUInt32BE(f+12);if(this.muxTracks.set(y,{codecId:w,param1:h,param2:E}),w===K)d={codecId:w,width:h,height:E};else if(y===Kt&&w===x)p=!0}if(d)this.header={...d,muxed:!0,audio:p,muxVersion:c.readUInt32BE(4)},this.callbacks.onHeader?.(this.header);this.buffered.discard(a)}else this.header={codecId:s,width:o.readUInt32BE(4),height:o.readUInt32BE(8)},this.buffered.discard(M),this.callbacks.onHeader?.(this.header);return!0}drainMuxPackets(){while(this.buffered.length>=q){let o=this.buffered.peek(q),s=o.readUInt32BE(0),n=o.readBigUInt64BE(4),a=o.readUInt32BE(12);if(this.assertWithinCap(a,ze,"packet size"),this.buffered.length<q+a)break;this.buffered.discard(q);let c=this.buffered.takeDetached(a),d=this.muxTracks?.get(s);if(!d)continue;this.callbacks.onPacket({trackId:s,codecId:d.codecId,data:c,config:(n&ae)!==0n,keyFrame:(n&Je)!==0n,replayed:(n&Ge)!==0n,rotation:k.rotationFromFlags(n),ptsUs:Number(n&Ye)})}}}var Gt=/^VIDEO_SESSION_READY token=([^ ]+) pid=(\d+) socket=([^ ]+?)(?: proto=(\d+))?$/,je="Streaming started",Yt=/(?:^|\s)dropped=(\d+)(?:\s|$)/;class ce{options;timer;readyTimeoutMs;session;resolveStartupAudioHeader;resolveStartupAudioPacket;serverOutputObserver=null;serverOutputBuffer="";sawStreamingStarted=!1;constructor(o,s,n,a){this.options=o;this.timer=s;this.readyTimeoutMs=n;this.session=a}waitForReady(o){let s=this.session()?.token;if(!s)throw Error("Video server session token was unavailable.");return new Promise((n,a)=>{let c=!1,d="",p=(h)=>{if(c)return;c=!0,this.timer.clearTimeout(m),o.stdout.off("data",f),o.removeListener("exit",y),o.removeListener("error",w),h()},m=this.timer.setTimeout(()=>{p(()=>a(new t(`video-server did not become session-ready within ${this.readyTimeoutMs}ms. Set AUTOMOBILE_VIDEO_SERVER_JAR to a current automobile-video.jar.`)))},this.readyTimeoutMs),f=(h)=>{if(c)return;d+=h.toString();let E=d.split(/\r?\n/);d=E.pop()??"";for(let b of E){let C=Gt.exec(b);if(!C)continue;if(C[1]!==s||C[3]!==this.session()?.socketName){p(()=>a(new t(`video-server session readiness token mismatch (expected=${s}, got=${C[1]})`)));return}let _=Number.parseInt(C[2],10);if(!Number.isInteger(_)||_<=0){p(()=>a(new t("video-server returned an invalid session PID")));return}let P=C[4]!==void 0?Number.parseInt(C[4],10):null;p(()=>n({pid:_,protocolVersion:P}));return}},y=(h,E)=>{p(()=>a(Error(`video-server exited before ready (code=${h}, signal=${E})`)))},w=(h)=>p(()=>a(h));o.stdout.on("data",f),o.once("exit",y),o.once("error",w)})}waitForStreamingStarted(o){if(this.sawStreamingStarted)return Promise.resolve();return this.waitForServerLine(o,je,`video-server did not start streaming within ${this.readyTimeoutMs}ms`,"video-server exited before streaming started")}waitForStartupAudioReady(){return new Promise((o,s)=>{let n=!1,a=!1,c=this.timer.setTimeout(()=>{d(()=>s(new t(`video-server did not produce PCM audio within ${this.readyTimeoutMs}ms`)))},this.readyTimeoutMs),d=(p)=>{if(n)return;n=!0,this.timer.clearTimeout(c),this.resolveStartupAudioHeader=void 0,this.resolveStartupAudioPacket=void 0,p()};this.resolveStartupAudioHeader=(p)=>{if(p.muxed===!0&&p.audio===!0){a=!0;return}d(()=>{s(new t("Audio was requested, but video-server did not advertise muxed PCM audio. Rebuild or provide a current automobile-video.jar."))})},this.resolveStartupAudioPacket=(p)=>{if(a&&p.codecId===x&&p.data.length>0)d(o)}})}waitForServerLine(o,s,n,a){return new Promise((c,d)=>{let p=!1,m="",f=(b)=>{if(p)return;p=!0,this.timer.clearTimeout(y),o.stdout.off("data",w),o.removeListener("exit",h),o.removeListener("error",E),b()},y=this.timer.setTimeout(()=>{f(()=>d(new t(n)))},this.readyTimeoutMs),w=(b)=>{if(p)return;if(m+=b.toString(),m.includes(s))f(c)},h=(b,C)=>{f(()=>d(Error(`${a} (code=${b}, signal=${C})`)))},E=(b)=>f(()=>d(b));o.stdout.on("data",w),o.once("exit",h),o.once("error",E)})}attachServerOutputObserver(o){this.serverOutputBuffer="",this.sawStreamingStarted=!1;let s=(n)=>{this.serverOutputBuffer+=n.toString();let a=this.serverOutputBuffer.split(/\r?\n/);if(this.serverOutputBuffer=a.pop()??"",a.includes(je))this.sawStreamingStarted=!0;for(let c of a){if(!c.startsWith("VIDEO_STATS "))continue;let d=Yt.exec(c),p=d?Number(d[1]):NaN;if(Number.isSafeInteger(p)&&p>=0)this.options.onDroppedFrames?.(p)}};this.serverOutputObserver=s,o.stdout.on("data",s)}detachServerOutputObserver(o){if(this.serverOutputObserver)o.stdout.off("data",this.serverOutputObserver);this.serverOutputObserver=null,this.serverOutputBuffer="",this.sawStreamingStarted=!1}}class z{leases;jar;startup;options;adbFactory;connector;timer;readyTimeoutMs;commandTimeoutMs;teardownTimeoutMs;localSocketReconnectWindowMs;localSocketReconnectRetryMs;sessionTokenFactory;socketNameFactory;activeVideoSessionRegistry;maxServerRelaunchAttempts;serverRelaunchBackoff;serverRelaunchHealthyWindowMs;server=null;socket=null;forwardedPort=null;session=null;deviceProcessId=null;negotiatedHandshakeVersion=null;running=!1;teardownPromise=null;socketReconnectPromise=null;socketReconnectAbortController=null;telemetryInitialized=!1;lastEncodedFrameTimestampUs=null;lastIdrTimestampUs=null;idrRequestCount=0;idrCompletionCount=0;pendingIdrRequests=0;encodedAccessUnitCount=0;serverStartupInProgress=null;serverStartupFailure=null;serverRelaunchAttempts=0;serverHealthySinceMs=null;relaunching=!1;relaunchAbortController=null;constructor(o){this.options=o,this.adbFactory=o.adbFactory??v,this.connector=o.connector??Oe,this.timer=o.timer??i,this.readyTimeoutMs=o.readyTimeoutMs??De,this.commandTimeoutMs=o.commandTimeoutMs??He,this.teardownTimeoutMs=o.teardownTimeoutMs??_e,this.localSocketReconnectWindowMs=o.localSocketReconnectWindowMs??Ae,this.localSocketReconnectRetryMs=o.localSocketReconnectRetryMs??Ie,this.sessionTokenFactory=o.sessionTokenFactory??(()=>L.next()),this.socketNameFactory=o.socketNameFactory??(()=>Ne(L)),this.activeVideoSessionRegistry=o.activeVideoSessionRegistry??xe,this.jar=new se(o,this.commandTimeoutMs,(n,a,c)=>this.withTimeout(n,a,c));let s=z.resolveRelaunchPolicy(o);this.maxServerRelaunchAttempts=s.maxAttempts,this.serverRelaunchBackoff=s.backoff,this.serverRelaunchHealthyWindowMs=s.healthyWindowMs,this.leases=new ie(o,this.adbFactory,this.timer,{activeVideoSessionRegistry:this.activeVideoSessionRegistry,teardown:{timeoutMs:this.teardownTimeoutMs,withTimeout:(n,a,c)=>this.withTimeout(n,a,c)}}),this.startup=new ce(o,this.timer,this.readyTimeoutMs,()=>this.session),this.validateTimings()}static resolveRelaunchPolicy(o){return{maxAttempts:o.maxServerRelaunchAttempts??Fe,backoff:xo(o.serverRelaunchBackoff??Me),healthyWindowMs:o.serverRelaunchHealthyWindowMs??ke}}validateTimings(){if(this.commandTimeoutMs<=0||this.teardownTimeoutMs<=0)throw new t("Video server command timeouts must be positive milliseconds.");if(this.localSocketReconnectWindowMs<=0||this.localSocketReconnectRetryMs<=0)throw new t("Local socket reconnect timings must be positive milliseconds.");if(!Number.isInteger(this.maxServerRelaunchAttempts)||this.maxServerRelaunchAttempts<0)throw new t("Server relaunch attempts must be a non-negative integer.");if(this.serverRelaunchHealthyWindowMs<=0)throw new t("Server relaunch healthy window must be positive milliseconds.")}get isRunning(){return this.running}getTelemetry(){if(!this.telemetryInitialized)return{lastEncodedFrameTimestampUs:null,lastIdrTimestampUs:null,idrRequestCount:null,idrCompletionCount:null,encodedAccessUnitCount:null};return{lastEncodedFrameTimestampUs:this.lastEncodedFrameTimestampUs,lastIdrTimestampUs:this.lastIdrTimestampUs,idrRequestCount:this.idrRequestCount,idrCompletionCount:this.idrCompletionCount,encodedAccessUnitCount:this.encodedAccessUnitCount}}async start(){if(this.running)throw new t("Persistent encoder H.264 source already started.");this.running=!0,this.serverStartupInProgress=null,this.serverStartupFailure=null;try{await this.launch(),this.serverHealthySinceMs=this.timer.now()}catch(o){throw this.running=!1,await this.beginTeardown(),o}}async stop(){if(!this.running){await this.teardownPromise;return}this.running=!1,this.relaunchAbortController?.abort(),await this.beginTeardown()}requestKeyFrame(){let o=this.socket;if(!this.running||!o)return!1;this.telemetryInitialized=!0,this.idrRequestCount++,this.pendingIdrRequests++;try{return o.write(Buffer.from([Re])),!0}catch(s){return this.pendingIdrRequests--,e.debug(`[PersistentEncoderH264Source] keyframe request write failed: ${s}`),!1}}withTimeout(o,s,n){return qe({timer:this.timer},o,s,n)}async launch(){let o=this.adbFactory.create(this.options.device),s=await this.prepareSession(o);if(s===null)return;let n=await this.spawnAndWaitForServer(o);if(!n)return;await this.connectToServer(n,s)}async prepareSession(o){if(!this.running)return null;let s=this.createSession();if(this.session=s,this.deviceProcessId=null,this.jar.remoteJarVerified=!1,this.activeVideoSessionRegistry.add(this.options.device.deviceId,s.socketName),await this.leases.reconcileExpiredLeases(o),!this.running)return null;if(await this.jar.ensureRemoteJar(o),!this.running)return null;let n=await this.withTimeout(o.executeCommand(`forward tcp:0 localabstract:${s.socketName}`,{timeoutMs:this.commandTimeoutMs}),this.commandTimeoutMs,"adb forward video-server socket"),a=Number.parseInt(n.stdout.trim(),10);if(!Number.isInteger(a)||a<=0)throw new t(`adb forward returned an invalid port: "${n.stdout.trim()}"`);if(!this.running)return await this.leases.removeForwardIfMatching(o,a,s.socketName),null;return this.forwardedPort=a,a}async spawnAndWaitForServer(o){if(await this.jar.verifyRemoteJarBeforeLaunch(o),!this.running)return null;let s=await this.withTimeout(o.spawn(this.buildServerArgs()),this.commandTimeoutMs,"adb spawn video-server");if(!this.running)return s.kill("SIGINT"),null;this.server=s,this.startup.attachServerOutputObserver(s),s.stderr.on("data",(a)=>{let c=a.toString().trim();if(c)e.debug(`[PersistentEncoderH264Source] server stderr: ${c}`)});let n=await this.startup.waitForReady(s);return this.deviceProcessId=n.pid,this.negotiatedHandshakeVersion=Ue(n.protocolVersion),this.serverStartupInProgress=s,this.watchServer(s),this.running?s:null}async connectToServer(o,s){this.throwIfServerStartupFailed(o);let n=this.options.audioEnabled?this.startup.waitForStreamingStarted(o):null;n?.catch((h)=>{e.debug(`[PersistentEncoderH264Source] Audio startup waiter rejected: ${r(h)}`)});let a=new AbortController,c=this.timer.now()+this.commandTimeoutMs,d=this.connectBeforeDeadline(s,c,a.signal),p=!1,m,f=new Promise((h,E)=>{m=E}),y=(h,E)=>{m(Error(`video-server exited (code=${h}, signal=${E})`))},w=(h)=>{m(h)};o.once("exit",y),o.once("error",w);try{let h=await l([d,f],{timer:this.timer,label:"video-server connection"});if(p=!0,!this.running){h.destroy();return}this.socket=h,this.sendHandshake(h);let E=this.options.audioEnabled?this.startup.waitForStartupAudioReady():null,b=this.options.audioEnabled?"startup":"post-start",C,_=this.options.audioEnabled?new Promise((P,pt)=>{C=pt}):null;if(this.wireSocket(h,(P)=>{if(b==="startup"){C?.(P);return}this.reconnectSocket(h,P)},(P)=>this.startup.resolveStartupAudioHeader?.(P)),this.options.audioEnabled){if(await l([Promise.all([n,E]),Promise.resolve(_)],{timer:this.timer,label:"video-server audio startup"}),!this.running)return}b="post-start"}finally{if(o.removeListener("exit",y),o.removeListener("error",w),!p)a.abort(),d.catch((h)=>{e.debug(`[PersistentEncoderH264Source] Losing connection rejected: ${r(h)}`)});if(this.serverStartupInProgress===o)this.serverStartupInProgress=null}}throwIfServerStartupFailed(o){let s=this.serverStartupFailure;if(s?.server===o)throw s.error}watchServer(o){o.once("exit",(s,n)=>{if(this.server!==o)return;if(this.startup.detachServerOutputObserver(o),this.server=null,this.serverStartupInProgress===o){this.serverStartupFailure={server:o,error:Error(`video-server exited (code=${s}, signal=${n})`)};return}this.handlePostStartServerLoss(Error(`video-server exited (code=${s}, signal=${n})`))}),o.once("error",(s)=>{if(this.serverStartupInProgress===o){this.serverStartupFailure={server:o,error:s};return}this.handlePostStartServerLoss(s)})}buildServerArgs(){return Be({session:this.session,forwardedPort:this.forwardedPort,options:this.options})}createSession(){return $e({options:this.options,sessionTokenFactory:this.sessionTokenFactory.bind(this),socketNameFactory:this.socketNameFactory.bind(this)})}sendHandshake(o){return We({session:this.session,negotiatedHandshakeVersion:this.negotiatedHandshakeVersion},o)}wireSocket(o,s,n){let a=new k({onHeader:(p)=>{n?.(p),this.requestKeyFrame(),e.info(`[PersistentEncoderH264Source] stream ${p.width}x${p.height} codec=0x${p.codecId.toString(16)}`)},onPacket:(p)=>{if(this.socket===o){if(p.codecId===K)this.deliverVideoPacket(p);else if(p.codecId===x)this.options.onAudioData?.(p.data),this.startup.resolveStartupAudioPacket?.(p)}}}),c=!1,d=(p)=>{if(c||this.socket!==o)return;c=!0,s(p)};o.on("data",(p)=>{try{a.push(p)}catch(m){d(m instanceof Error?m:Error(String(m)))}}),o.on("error",d),o.on("close",()=>d(Error("video-server socket closed")))}deliverVideoPacket(o){if(this.observeVideoPacket(o),o.config&&o.rotation!==void 0)this.options.onRotation?.(o.rotation);if(!o.config&&!o.replayed)this.options.onSourceFrame?.();this.options.onData(o.data),this.options.onEncodedAccessUnit?.()}observeVideoPacket(o){if(o.config)return;if(this.telemetryInitialized=!0,o.replayed){if(this.lastEncodedFrameTimestampUs??=o.ptsUs,o.keyFrame)this.lastIdrTimestampUs??=o.ptsUs;return}if(this.lastEncodedFrameTimestampUs=o.ptsUs,this.encodedAccessUnitCount++,!o.keyFrame)return;if(this.lastIdrTimestampUs=o.ptsUs,this.pendingIdrRequests>0)this.pendingIdrRequests--,this.idrCompletionCount++}reconnectSocket(o,s){if(!this.running||this.socket!==o||this.socketReconnectPromise!==null)return;this.socket=null,o.destroy();let n=new AbortController;this.socketReconnectAbortController=n,this.socketReconnectPromise=this.tryReconnectSocket(s,n.signal).finally(()=>{if(this.socketReconnectAbortController===n)this.socketReconnectAbortController=null;this.socketReconnectPromise=null})}async tryReconnectSocket(o,s){let n=this.forwardedPort;if(n===null){this.failIfRunning(o);return}let a=this.timer.now()+this.localSocketReconnectWindowMs,c=o;while(this.running&&this.server!==null&&!s.aborted){try{let p=await this.connectBeforeDeadline(n,a,s);if(!this.running||this.server===null||s.aborted){p.destroy();return}this.socket=p,this.sendHandshake(p),this.wireSocket(p,(m)=>this.reconnectSocket(p,m)),e.info("[PersistentEncoderH264Source] reconnected to retained video-server socket");return}catch(p){c=p instanceof Error?p:Error(String(p))}let d=a-this.timer.now();if(d<=0)break;await this.waitForReconnectRetry(Math.min(this.localSocketReconnectRetryMs,d),s)}this.failReconnectIfServerRetained(s,c)}failReconnectIfServerRetained(o,s){if(o.aborted||this.server===null)return;this.failIfRunning(Error(`video-server socket did not reconnect within ${this.localSocketReconnectWindowMs}ms: ${s.message}`))}waitForReconnectRetry(o,s){if(s.aborted)return Promise.resolve();return new Promise((n)=>{let a=!1,c=()=>{if(a)return;a=!0,this.timer.clearTimeout(d),s.removeEventListener("abort",c),n()},d=this.timer.setTimeout(c,o);s.addEventListener("abort",c,{once:!0})})}async connectBeforeDeadline(o,s,n){let a=s-this.timer.now();if(a<=0)throw Error("video-server socket reconnect deadline elapsed");let c=new AbortController,d=new AbortController,p=!1,m=()=>c.abort();if(n.aborted)m();else n.addEventListener("abort",m,{once:!0});let f=this.connector(o,c.signal),y=this.timer.setTimeout(()=>{p=!0,c.abort()},a),w=()=>d.abort(Error(p?"video-server socket reconnect attempt timed out":"video-server socket reconnect attempt aborted"));if(c.signal.aborted)w();else c.signal.addEventListener("abort",w,{once:!0});try{return await l(f,{timer:this.timer,signal:d.signal,label:"video-server socket reconnect attempt"})}finally{if(this.timer.clearTimeout(y),n.removeEventListener("abort",m),c.signal.removeEventListener("abort",w),c.signal.aborted)f.then((h)=>h.destroy(),()=>{})}}handlePostStartServerLoss(o){if(!this.running||this.relaunching)return;this.resetRelaunchBudgetAfterHealthyRun(),this.relaunching=!0,this.relaunchAbortController=new AbortController,this.recoverFromServerLoss(o).finally(()=>{this.relaunching=!1})}async recoverFromServerLoss(o){let s=this.relaunchAbortController?.signal??new AbortController().signal,n=o;while(this.canAttemptRelaunch(s)){this.serverRelaunchAttempts++;let a=await this.attemptRelaunch(this.serverRelaunchAttempts,n,s);if(a.status!=="retry")return;n=a.error}if(this.running&&!s.aborted)await this.fallBackAfterRelaunchExhausted(n)}resetRelaunchBudgetAfterHealthyRun(){if(this.serverHealthySinceMs!==null&&this.timer.now()-this.serverHealthySinceMs>=this.serverRelaunchHealthyWindowMs)this.serverRelaunchAttempts=0}canAttemptRelaunch(o){return this.running&&!o.aborted&&this.serverRelaunchAttempts<this.maxServerRelaunchAttempts}async attemptRelaunch(o,s,n){let a=this.serverRelaunchBackoff.delayForAttempt(o);if(e.warn(`[PersistentEncoderH264Source] on-device server lost post-start (${s.message}); relaunch attempt ${o}/${this.maxServerRelaunchAttempts} after ${a}ms`),await this.delayBeforeRelaunch(a,n),!this.running||n.aborted)return{status:"aborted",error:s};if(await this.beginTeardown(),!this.running||n.aborted)return{status:"aborted",error:s};try{if(await this.launch(),!this.running)return{status:"aborted",error:s};return this.serverHealthySinceMs=this.timer.now(),e.info(`[PersistentEncoderH264Source] on-device server relaunched after ${o} attempt(s)`),{status:"recovered",error:s}}catch(c){let d=c instanceof Error?c:Error(String(c));return e.warn(`[PersistentEncoderH264Source] relaunch attempt ${o} failed: ${d.message}`,c),{status:"retry",error:d}}}delayBeforeRelaunch(o,s){if(o<=0||s.aborted)return Promise.resolve();return new Promise((n)=>{let a=()=>{this.timer.clearTimeout(c),s.removeEventListener("abort",a),n()},c=this.timer.setTimeout(a,o);s.addEventListener("abort",a,{once:!0})})}async fallBackAfterRelaunchExhausted(o){if(!this.running)return;let s=this.options.onScreenrecordFallback;if(!s){this.failIfRunning(o);return}e.warn(`[PersistentEncoderH264Source] relaunch budget of ${this.maxServerRelaunchAttempts} spent; falling back to screenrecord: ${o.message}`),this.running=!1,await this.beginTeardown();try{await s(o)}catch(n){this.options.onError?.(n instanceof Error?n:Error(String(n)))}}failIfRunning(o){if(!this.running)return;this.running=!1,this.beginTeardown(),this.options.onError?.(o)}beginTeardown(){return this.teardownPromise??=this.teardown().finally(()=>{this.teardownPromise=null}),this.teardownPromise}async teardown(){let o=this.socketReconnectAbortController;this.socketReconnectAbortController=null,o?.abort();let s=this.socket;this.socket=null,s?.destroy();let n=this.server;if(this.server=null,n)this.startup.detachServerOutputObserver(n);n?.kill("SIGINT");let a=this.session,c=this.forwardedPort,d=this.deviceProcessId;if(this.forwardedPort=null,this.deviceProcessId=null,this.session=null,a)await this.leases.cleanupOwnedSession(a,c,d),this.activeVideoSessionRegistry.remove(this.options.device.deviceId,a.socketName);else if(c!==null)e.warn(`[PersistentEncoderH264Source] refusing forward cleanup port=${c}: session identity is unavailable`)}}var jt={createPersistent:(o)=>new z(o),createScreenrecord:(o)=>new X(o)};class Xe{buildScreenrecord;active=null;stopped=!1;persistent;constructor(o,s){this.buildScreenrecord=s;this.persistent=o((n)=>this.switchToScreenrecord(n))}async start(){this.stopped=!1,this.active=this.persistent;try{await this.persistent.start()}catch(o){await this.switchToScreenrecord(o instanceof Error?o:Error(String(o)))}}async switchToScreenrecord(o){if(this.stopped||this.active!==this.persistent)return;e.warn(`[webrtc] persistent encoder unavailable, falling back to screenrecord: ${o.message}`);let s=this.buildScreenrecord();this.active=s,await s.start()}async stop(){this.stopped=!0;let o=this.active;this.active=null,await o?.stop()}requestKeyFrame(){return this.active?.requestKeyFrame?.()??!1}get getTelemetry(){let o=this.active;return o?.getTelemetry?.bind(o)}}function Qe(o,s,n=jt){if(!s){if(o.audioEnabled)throw Error("WebRTC audio requires the persistent Android video-server jar.");return n.createScreenrecord(o)}let a=(c)=>({device:o.device,onData:o.onData,onSourceFrame:o.onSourceFrame,onEncodedAccessUnit:o.onEncodedAccessUnit,onAudioData:o.onAudioData,onRotation:o.onRotation,onDroppedFrames:o.onDroppedFrames,onError:o.onError,bitrateBps:o.bitrateBps,size:o.size,quality:o.quality,fps:o.fps,audioEnabled:o.audioEnabled,adbFactory:o.adbFactory,timer:o.timer,jarPath:s,onScreenrecordFallback:c});if(o.audioEnabled)return n.createPersistent(a());return new Xe((c)=>n.createPersistent(a(c)),()=>n.createScreenrecord(o))}class A extends t{finalStartupError(o){return this}}class Rp extends t{approvalTarget;constructor(o="AutoMobile"){super("Screen Recording permission is required to discover and observe iOS Simulator windows.");this.approvalTarget=o}}class le extends A{finalStartupError(o){return new Rp(o??"AutoMobile")}}var Xt="warn: no frames received";function Ze(o,s){let n=s===null?"":` (last stage: ${s})`,a=Zt(o,s);return new A(`iOS screen capture did not produce a first frame${n}.${a}`)}function Qt(o,s){return new le(Ze(o,s).message)}function Zt(o,s){switch(s){case null:case"helper-executable-found":case"helper-process-spawned":return o.kind==="simulator"?" Screen Recording permission may be required to observe the iOS Simulator window.":"";case"permission-ready":return" The Simulator window could not be resolved; ensure the Simulator is booted and visible.";case"target-resolved":return" Capture never started after the window resolved (hung start); retry or restart the Simulator.";case"capture-started":return o.kind==="simulator"?" Screen Recording permission may be required to observe the iOS Simulator window.":"";case"first-frame":return""}}function er(o){return o.toLowerCase().includes(Xt)}function de(o){return o.trimStart().toLowerCase().startsWith("error:")}class pe{timer;firstFrameTimeoutMs;context;cancelFirstFrameWait=null;cancelFirstAudioWait=null;rejectFirstAudioWait=null;constructor(o,s,n){this.timer=o;this.firstFrameTimeoutMs=s;this.context=n}waitForFirstAudio(o){let s=this.context.generation();return new Promise((n,a)=>{let c=!1,d=(y)=>{if(c)return;if(c=!0,this.timer.clearTimeout(f),this.cancelFirstAudioWait===p)this.cancelFirstAudioWait=null;if(this.rejectFirstAudioWait===m)this.rejectFirstAudioWait=null;y()},p=()=>d(n),m=(y)=>d(()=>a(y)),f=this.timer.setTimeout(()=>{d(()=>a(new t("iOS Simulator audio capture did not produce PCM audio before startup timed out.")))},this.firstFrameTimeoutMs);this.cancelFirstAudioWait=p,this.rejectFirstAudioWait=m,o.on("audio",()=>{if(this.context.isCurrentHelper(o,s)&&this.context.isActive())d(n)}),o.on("error",(y)=>{if(this.context.isCurrentHelper(o,s)&&this.context.isActive())d(()=>a(y))}),o.on("exit",(y)=>{if(this.context.isCurrentHelper(o,s)&&this.context.isActive())d(()=>a(Error(this.context.describeHelperExit(y,"exited before audio"))))})})}waitForFirstEncodedRecord(o,s){let n=this.context.generation();return new Promise((a,c)=>{let d=!1,p=!1,m=(h)=>{if(d)return;if(d=!0,this.timer.clearTimeout(w),this.cancelFirstFrameWait===f)this.cancelFirstFrameWait=null;h()},f=()=>{m(a)},y=(h)=>{m(()=>c(this.context.encodedStartupError(h)))},w=this.timer.setTimeout(()=>{y(Ze(s,this.context.lastReadinessPhase()))},this.firstFrameTimeoutMs);this.cancelFirstFrameWait=f,o.on("encodedVideo",()=>{if(!this.context.isCurrentHelper(o,n)||!this.context.isActive())return;p=!0,this.context.markRunning(),m(a)}),o.on("stderr",(h)=>{if(!this.context.isCurrentHelper(o,n)||!this.context.isActive())return;if(er(h))m(()=>c(Qt(s,this.context.lastReadinessPhase())));else if(de(h))y(this.context.helperFailureFor(h))}),o.on("error",(h)=>{if(!this.context.isCurrentHelper(o,n)||!this.context.isActive())return;if(p){this.context.failIfCurrentHelper(o,n,h);return}y(h)}),o.on("exit",(h)=>{if(!this.context.isCurrentHelper(o,n)||!this.context.isActive())return;let E=Error(this.context.describeHelperExit(h,"exited"));if(p){this.context.failIfCurrentHelper(o,n,E);return}y(E)})})}}var tr=5;function et(o,s){o.on("capability",(n)=>{if(s.isCurrentHelper()&&n===mZ)s.confirmIdleSupport(),s.options.onIdleAttestationSupport?.(!0)}),o.on("idle",()=>{if(s.isCurrentHelper()&&s.isActive()&&s.nativeIdleCapabilityConfirmed())s.options.onSourceIdle?.()}),o.on("captureMetrics",(n)=>{if(s.isCurrentHelper()&&s.isActive())s.options.onDroppedFrames?.(n.droppedFrames),s.setNativeFrameMetrics(n)}),o.on("audio",(n)=>{if(s.isCurrentHelper()&&s.isActive()&&s.options.audioEnabled)s.options.onAudioData?.(n.pcm16le)}),o.on("permission",(n)=>{if(s.isCurrentHelper())s.setRequiredPermission(n)}),o.on("permissionTarget",(n)=>{if(s.isCurrentHelper())s.setRequiredPermissionTarget(n)}),o.on("stderr",(n)=>{if(!s.isCurrentHelper())return;if(n.length>0)if(n.startsWith(_N))rr(n);else{if(s.helperStderrTail().push(n.slice(-2048)),s.helperStderrTail().length>tr)s.helperStderrTail().shift();e.warn(`[IosH264Source] screen-capture-helper stderr: ${n}`)}if(de(n))s.failForHelperLine(n)}),o.on("readiness",(n)=>{if(s.isCurrentHelper()&&s.isActive())s.setLastReadinessPhase(n.phase);e.debug(`[IosH264Source] capture readiness phase=${n.phase} atMs=${n.atMs}${n.detail?` detail=${n.detail}`:""}`)})}function rr(o){try{let s=JSON.parse(o.slice(_N.length));if(s===null||typeof s!=="object"||Array.isArray(s)){e.warn(`[IosH264Source] unrecognised frame-metrics line: ${o}`);return}let n=s;if(typeof n.droppedFrames==="number"&&n.droppedFrames>0||typeof n.frameQueueDepth==="number"&&n.frameQueueDepth!==0){e.warn(`[IosH264Source] screen-capture-helper frame metrics: ${o}`);return}e.debug(`[IosH264Source] screen-capture-helper frame metrics: ${o}`)}catch(s){e.warn(`[IosH264Source] unrecognised frame-metrics line: ${o}; ${r(s)}`)}}import{EventEmitter as ir}from"events";class me extends ir{pool;options;started=!1;attachment=null;attachmentGeneration=0;entryKey=null;constructor(o,s){super();this.pool=o;this.options=s}async start(){if(this.started)throw Error("IOSSimulatorCaptureHelperLease already started");this.started=!0;let o=this.pool.attach(this),s=++this.attachmentGeneration;this.attachment=o;try{await o}catch(n){throw this.started=!1,n}finally{if(this.attachmentGeneration===s)this.attachment=null}}async stop(){if(!this.started)return null;return this.started=!1,this.removeAllListeners(),await this.attachment?.catch(()=>{return}),await this.pool.detach(this),null}async invalidate(){if(!this.started)return;this.started=!1,this.removeAllListeners(),await this.attachment?.catch(()=>{return}),await this.pool.invalidate(this)}requestKeyFrame(){return this.started&&this.pool.requestKeyFrame(this)}get isStarted(){return this.started}forward(o,s){if(this.started)this.emit(o,s)}}var or=45000,tt=5000;class rt{idleTtlMs;timer;createHelper;entries=new Map;transitions=new Map;shutdownTransition=Promise.resolve();constructor(o={}){this.idleTtlMs=o.idleTtlMs??or,this.timer=o.timer??i,this.createHelper=o.createHelper??((s)=>new Ty(s))}acquire(o){if(o.target.kind!=="simulator")throw Error("IOSSimulatorCaptureHelperPool only accepts simulator targets.");if(!o.target.encode)throw Error("IOSSimulatorCaptureHelperPool requires H.264 encode settings.");return new me(this,o)}async shutdown(){let o=[...this.transitions.values()],s=this.shutdownTransition.then(async()=>{await Promise.all(o);let n=[...this.entries.values()];this.entries.clear();for(let a of n)this.clearEntryIdleTimer(a),await this.stopHelperWithinDeadline(a).catch((c)=>{e.debug(`[IOSSimulatorCaptureHelperPool] helper shutdown failed: ${c}`)})});this.shutdownTransition=s.catch(()=>{return}),await s}async attach(o){await this.enqueue(J(o.options.target),async()=>{if(!o.isStarted)return;let s=sr(o.options.target,o.options.binaryPath),n=await this.resolveOrCreateEntry(s,o);if(n!==null)this.finalizeAttach(n,o,s)})}async resolveOrCreateEntry(o,s){let n=this.entries.get(o);if(n?.failedStopFailed)this.clearEntryIdleTimer(n),this.entries.delete(o),n=void 0;if(n)return n;let a=J(s.options.target);for(let d of this.entries.values())if(d.key!==o&&d.leases.size===0)if(d.windowID===a)await this.stopIdleEntry(d);else this.enqueueBestEffort(d.windowID,()=>this.stopIdleEntry(d),"idle helper eviction failed");if(!s.isStarted)return null;let c={key:o,windowID:J(s.options.target),helper:this.createHelper(s.options),capabilities:new Set,leases:new Set,idleTimer:null,failed:!1,failedStopFailed:!1,failedStopError:void 0};return this.entries.set(o,c),this.wireHelper(c),c}finalizeAttach(o,s,n){this.clearEntryIdleTimer(o),o.leases.add(s),s.entryKey=n;for(let a of o.capabilities)s.forward("capability",a);if(!o.helper.isRunning)try{o.helper.start()}catch(a){throw o.leases.delete(s),s.entryKey=null,this.entries.delete(n),a}o.helper.requestKeyFrame()}requestKeyFrame(o){let s=o.entryKey;if(!s)return!1;let n=this.entries.get(s);if(!n||!n.leases.has(o))return!1;return n.helper.requestKeyFrame()}async detach(o){let s=o.entryKey;if(o.entryKey=null,!s)return;let n=this.entries.get(s);if(!n)return;if(n.leases.delete(o),n.leases.size!==0)return;this.clearEntryIdleTimer(n),n.idleTimer=this.timer.setTimeout(()=>{n.idleTimer=null,this.enqueueBestEffort(n.windowID,()=>this.stopIdleEntry(n),"idle helper stop failed")},this.idleTtlMs)}async invalidate(o){let s=o.entryKey;if(o.entryKey=null,!s)return;await this.enqueue(J(o.options.target),async()=>{let n=this.entries.get(s);if(!n||!n.leases.has(o))return;if(n.failed){await this.stopFailedEntry(n);return}await this.stopEntry(n)})}wireHelper(o){o.helper.on("idle",(s)=>this.broadcast(o,"idle",s)),o.helper.on("encodedVideo",(s)=>this.broadcast(o,"encodedVideo",s)),o.helper.on("capability",(s)=>{o.capabilities.add(s),this.broadcast(o,"capability",s)}),o.helper.on("permission",(s)=>this.broadcast(o,"permission",s)),o.helper.on("permissionTarget",(s)=>this.broadcast(o,"permissionTarget",s)),o.helper.on("captureMetrics",(s)=>this.broadcast(o,"captureMetrics",s)),o.helper.on("audio",(s)=>this.broadcast(o,"audio",s)),o.helper.on("malformed",(s)=>this.broadcast(o,"malformed",s)),o.helper.on("stderr",(s)=>{if(nr(s)&&this.entries.get(o.key)===o)o.failed=!0,this.enqueueBestEffort(o.windowID,()=>this.stopFailedEntry(o),"failed helper stop failed");this.broadcast(o,"stderr",s)}),o.helper.on("readiness",(s)=>this.broadcast(o,"readiness",s)),o.helper.on("error",(s)=>{if(this.entries.get(o.key)===o)o.failed=!0,this.enqueueBestEffort(o.windowID,()=>this.stopFailedEntry(o),"failed helper stop failed");this.broadcast(o,"error",s)}),o.helper.on("exit",(s)=>{if(this.broadcast(o,"exit",s),this.entries.get(o.key)===o)this.clearEntryIdleTimer(o),this.entries.delete(o.key)})}broadcast(o,s,n){for(let a of o.leases)a.forward(s,n)}async stopIdleEntry(o){if(o.leases.size!==0||this.entries.get(o.key)!==o)return;await this.stopEntry(o)}async stopFailedEntry(o){if(this.entries.get(o.key)!==o)return;if(o.failedStopFailed)throw o.failedStopError;this.clearEntryIdleTimer(o);try{await this.stopHelperWithinDeadline(o)}catch(s){throw o.failedStopFailed=!0,o.failedStopError=s,s}if(this.entries.get(o.key)===o)this.entries.delete(o.key)}async stopEntry(o){if(this.entries.get(o.key)!==o)return;this.clearEntryIdleTimer(o),this.entries.delete(o.key),await this.stopHelperWithinDeadline(o)}async stopHelperWithinDeadline(o){let s=o.helper.stop(),n=!1;s.catch((c)=>{if(n)e.debug(`[IOSSimulatorCaptureHelperPool] helper stop failed after timeout: ${c}`)});let a=Error("Helper stop deadline expired");try{await l(s,{timer:this.timer,timeoutMs:tt,label:"Helper stop",timeoutError:()=>a,onTimeout:()=>{n=!0,e.warn(`[IOSSimulatorCaptureHelperPool] helper stop exceeded ${tt}ms`)}})}catch(c){if(c!==a)throw c}}enqueue(o,s){let n=this.transitions.get(o)??Promise.resolve(),a=Promise.all([n,this.shutdownTransition]).then(s),c=a.catch(()=>{return});return this.transitions.set(o,c),c.then(()=>{if(this.transitions.get(o)===c)this.transitions.delete(o)}),a}enqueueBestEffort(o,s,n){this.enqueue(o,s).catch((a)=>{e.warn(`[IOSSimulatorCaptureHelperPool] ${n}: ${a}`)})}clearEntryIdleTimer(o){if(o.idleTimer)this.timer.clearTimeout(o.idleTimer),o.idleTimer=null}}function sr(o,s){if(o.kind!=="simulator")throw Error("Simulator helper pool received a non-simulator target.");return JSON.stringify({binaryPath:s,windowID:o.windowID,fps:o.fps,audio:o.audio===!0,encode:o.encode})}function J(o){if(o.kind!=="simulator")throw Error("Simulator helper pool received a non-simulator target.");return o.windowID}function nr(o){let s=o.trimStart().toLowerCase();return s.startsWith("error:")||s.includes("warn: no frames received")}var sO=new rt;class H extends t{}import{basename as mr}from"path";var ar=new ne,ur=(o=ar)=>(s,n)=>tW(o.spawn(s,n,{stdio:["ignore","pipe","pipe"]}),s),it=ur();var ot=0.1,G=y6,st=15000,cr=g.IOS_SIMULATOR_WINDOW_TIMEOUT_MS.name;function lr(o=process.env){return zn(cr,void 0,{fallback:2000,env:o})}var O=lr(),he=500,nt=500,dr=2,fe=6000,at=35000,pr=te({initialDelayMs:500,multiplier:2,maxDelayMs:2000});function ut(o){return{maxAttempts:o.runningReconnectMaxAttempts??dr,backoff:xo(o.runningReconnectBackoff??pr)}}var ct=(o,s,n)=>new Promise((a,c)=>{if(n?.aborted){c(Error(`Command aborted: ${o}`));return}let d=it(o,s),p="",m="",f=!1,y=(h)=>{if(f)return;f=!0,n?.removeEventListener("abort",w),h()},w=()=>{d.kill("SIGTERM"),y(()=>c(Error(`Command aborted: ${o}`)))};d.stdout.on("data",(h)=>{p+=Buffer.isBuffer(h)?h.toString("utf8"):String(h)}),d.stderr.on("data",(h)=>{m+=Buffer.isBuffer(h)?h.toString("utf8"):String(h)}),d.once("error",(h)=>y(()=>c(h))),d.once("exit",(h,E)=>y(()=>a({stdout:p,stderr:m,exitCode:h,signal:E}))),n?.addEventListener("abort",w,{once:!0})});class ve{dependencies;constructor(o){this.dependencies=o}async resolveCaptureTarget(o){if(W({deviceId:this.dependencies.options.device.deviceId})==="simulator")return{kind:"simulator",windowID:await this.resolveSimulatorWindowIdWithDeadline(o),fps:this.dependencies.fps,...this.dependencies.options.audioEnabled===!0?{audio:!0}:{}};return{kind:"device",deviceId:this.dependencies.options.device.deviceId}}async resolveHelperPath(){let o=this.dependencies.helperPath??Ub(process.env);if(o)return Hb(o,{exists:this.dependencies.helperPathExists,env:{}});let s=await this.dependencies.withPreCaptureDeadline(this.dependencies.screenCaptureHelperProvider.ensure(),at,"Resolving iOS screen-capture-helper");if(s)return s;throw new t(`iOS WebRTC streaming requires a verified screen-capture-helper from the matching GitHub Release. For local development, run swift build in ios/screen-capture and set ${CP} to the resulting absolute path.`)}async resolveSimulatorWindowIdWithDeadline(o){return new Promise((s,n)=>{let a=new AbortController,c=!1,d=(m)=>{if(c)return;c=!0,this.dependencies.timer.clearTimeout(p),m()},p=this.dependencies.timer.setTimeout(()=>{a.abort(),d(()=>n(new t(`Timed out resolving iOS Simulator window for ${this.dependencies.options.device.name} after ${O}ms. Open the Simulator window and verify Screen Recording permission.`)))},O);this.dependencies.simulatorWindowResolver(o,this.dependencies.options.device,this.dependencies.options.audioEnabled===!0,a.signal).then((m)=>d(()=>s(m)),(m)=>d(()=>n(m)))})}async reresolveSimulatorTarget(o,s){if(s.kind!=="simulator")return s;let n;try{n=await this.resolveSimulatorWindowIdWithDeadline(o)}catch(a){throw u(a,"Failed to re-resolve iOS Simulator window for capture retry")}if(n===s.windowID)return s;return e.debug(`[IosH264Source] Simulator windowID changed from ${s.windowID} to ${n} before retry; targeting the freshly-resolved window`),{...s,windowID:n}}}function Se(o){return o.kind==="simulator"?`iOS Simulator window ${o.windowID} at ${o.fps??G} fps`:`iOS device ${o.deviceId??"default"}`}async function lt(o,s,n,{audioEnabled:a,poll:c}){let{signal:d}=c,p=c.timer.now(),m=0;for(;;){m+=1;let f=await hr(o,s,n,{audioEnabled:a,signal:d});if(f.kind==="found")return f.windowID;if(d.aborted||c.timer.now()-p+he>=c.pollBudgetMs)throw new t(`No visible iOS Simulator window matched ${s.name} after ${m} lookup(s) over ${c.timer.now()-p}ms; windows seen: ${f.seen}. Open the simulator window and grant Screen Recording permission if prompted.`);await c.timer.sleep(he)}}async function hr(o,s,n,{audioEnabled:a,signal:c}){let d=await n(o,["--list-simulators"],c);if(d.exitCode!==0){if(ge(d.stderr))throw new Rp(fr(d.stderr)??ye(o));throw new t(`Unable to list iOS Simulator windows: ${d.stderr.trim()||`exited with code ${d.exitCode}`}`)}let p;try{p=JSON.parse(d.stdout).windows??[]}catch(h){throw u(h,"Unable to parse iOS Simulator window list")}if(a&&p.length>1)throw new t("iOS Simulator audio capture requires exactly one visible Simulator window because ScreenCaptureKit cannot isolate audio to a selected Simulator window. Close other Simulator windows and try again.");let m=s.name.trim().toLowerCase(),f=p.filter((h)=>typeof h.title==="string"&&h.title.trim().length>0),y=f.filter((h)=>vr(h.title,m)),w=y.length>0?y:f.filter((h)=>h.title.toLowerCase().includes(m));if(w.length===1)return{kind:"found",windowID:w[0].windowID};if(w.length===0)return{kind:"missing",seen:`[${p.map((E)=>JSON.stringify(E.title??null)).join(", ")}]`};throw new t(`Multiple iOS Simulator windows matched ${s.name}; close extras or use a more specific device.`)}function ge(o){return o.split(/\r?\n/).some((s)=>{let n=s.trim().toLowerCase();return n===`${HH} screen-recording`||n.startsWith("error: screen recording permission is required.")||n.includes("the user declined tccs for application, window, display capture")})}function fr(o){for(let s of o.split(/\r?\n/)){let n=s.trim();if(!n.startsWith(xN))continue;let a=n.slice(xN.length).trim();if(a.length>0)return a}return null}function ye(o){let s=mr(o).trim();return s==="screen-capture-helper"||s.length===0?"AutoMobile":s}function vr(o,s){let n=o.trim().toLowerCase();if(n===s)return!0;let[a]=n.split(/\s+[\u2014\u2013-]\s+/,1);return a.trim()===s}function dt(o,s){let n=o.bitrateBps&&o.bitrateBps>0?o.bitrateBps:N(o.quality),a=n!==void 0?{kind:"explicitBps",bps:n}:s==="simulator"?{kind:"bitsPerPixel",bpp:ot}:{kind:"videoToolboxDefault"},c=o.quality?j[o.quality]:void 0;return{codec:"h264",bitrate:a,...c===void 0?{}:{maxLongSide:c}}}class we{options;resolver;nativeFrameMetrics=null;captureKind=null;lastForcedKeyFrameMs=Number.NEGATIVE_INFINITY;startup;getFrameMetrics(){return{native:this.nativeFrameMetrics}}helperPath;fps;createHelper;simulatorWindowResolver;commandRunner;helperPathExists;screenCaptureHelperProvider;timer;firstFrameTimeoutMs;simulatorHelperPool;runningReconnectMaxAttempts;runningReconnectBackoff;helper=null;helperGeneration=0;cancelPreCaptureDeadline=null;encodedCapabilityConfirmed=!1;nativeIdleCapabilityConfirmed=!1;idleSupportReported=!1;teardownPromise=null;helperStderrTail=[];lastReadinessPhase=null;phase="idle";requiredPermission=null;requiredPermissionTarget=null;startupComplete=!1;hasConsumers=!0;deferredHelperFailure=null;invalidateHelperOnStop=!1;reconnectPromise=null;cancelReconnectDelay=null;constructor(o){this.options=o;this.helperPath=o.helperPath,this.fps=o.fps??G,this.createHelper=o.createHelper??((n)=>new Ty(n)),this.commandRunner=o.commandRunner??ct,this.helperPathExists=o.helperPathExists,this.screenCaptureHelperProvider=o.screenCaptureHelperProvider??_c.getInstance(),this.timer=o.timer??i,this.firstFrameTimeoutMs=o.firstFrameTimeoutMs??st,this.simulatorHelperPool=o.simulatorHelperPool??sO;let s=ut(o);this.runningReconnectMaxAttempts=s.maxAttempts,this.runningReconnectBackoff=s.backoff,this.simulatorWindowResolver=o.simulatorWindowResolver??((n,a,c,d)=>lt(n,a,this.commandRunner,{audioEnabled:c,poll:{signal:d,timer:this.timer,pollBudgetMs:Math.max(0,O)}})),this.startup=new pe(this.timer,this.firstFrameTimeoutMs,{generation:()=>this.helperGeneration,lastReadinessPhase:()=>this.lastReadinessPhase,markRunning:()=>{this.phase="running"},isCurrentHelper:(n,a)=>this.isCurrentHelper(n,a),isActive:()=>this.isActive(),helperFailureFor:(n)=>this.helperFailureFor(n),failIfCurrentHelper:(n,a,c)=>this.failIfCurrentHelper(n,a,c),describeHelperExit:(n,a)=>this.describeHelperExit(n,a),encodedStartupError:(n)=>this.encodedStartupError(n)}),this.resolver=new ve({options:this.options,helperPath:this.helperPath,helperPathExists:this.helperPathExists,screenCaptureHelperProvider:this.screenCaptureHelperProvider,fps:this.fps,timer:this.timer,simulatorWindowResolver:this.simulatorWindowResolver,withPreCaptureDeadline:(n,a,c)=>this.withPreCaptureDeadline(n,a,c)})}async start(){if(this.isActive())throw new t("iOS H.264 source already started.");await this.teardownPromise;let o=++this.helperGeneration;if(this.phase="starting",this.startupComplete=!1,this.deferredHelperFailure=null,this.helperStderrTail=[],this.lastReadinessPhase=null,this.nativeFrameMetrics=null,this.lastForcedKeyFrameMs=Number.NEGATIVE_INFINITY,this.encodedCapabilityConfirmed=!1,this.options.size!==void 0)e.warn("[IosH264Source] iOS ignores explicit encoder size; capture encodes at native size capped by the quality preset.");try{if(await this.establishCapture(o),o===this.helperGeneration)this.startupComplete=this.phaseNow()==="running"}catch(s){if(o!==this.helperGeneration)return;throw this.phase="stopping",await this.beginTeardown(),s}}async establishCapture(o){let s=await this.resolver.resolveHelperPath();if(o!==this.helperGeneration)return;let n=await this.resolver.resolveCaptureTarget(s);if(this.captureKind=n.kind,!this.isActive()||o!==this.helperGeneration)return;await this.startCaptureWithSimulatorRetry(s,{...n,encode:dt(this.options,n.kind)})}async stop(){if(this.deferredHelperFailure=null,!this.isActive()){await this.teardownPromise;return}this.phase="stopping",this.helperGeneration++,this.startupComplete=!1,this.cancelPreCaptureDeadline?.(),this.cancelReconnectDelay?.(),this.startup.cancelFirstFrameWait?.(),this.startup.cancelFirstAudioWait?.(),await this.beginTeardown()}async stopStale(o=!0){this.invalidateHelperOnStop=o,await this.stop()}setHasConsumers(o){if(this.hasConsumers=o,o){if(this.deferredHelperFailure)this.queueReconnect(this.deferredHelperFailure)}else this.cancelReconnectDelay?.()}requestKeyFrame(){if(this.phase!=="running"||!this.helper)return!1;let o=this.timer.now();if(o-this.lastForcedKeyFrameMs<nt)return!1;let s=this.helper.requestKeyFrame?.()??!1;if(s)this.lastForcedKeyFrameMs=o,e.debug("[IosH264Source] forced keyframe requested on helper control channel");return s}async withPreCaptureDeadline(o,s,n){let a=new AbortController,c=()=>a.abort(new t(`${n} cancelled by stop.`));this.cancelPreCaptureDeadline=c;let d=this.timer.setTimeout(()=>a.abort(new t(`${n} timed out after ${s}ms.`)),s);try{return await l(o,{timer:this.timer,signal:a.signal,label:n})}finally{if(this.cancelPreCaptureDeadline===c)this.cancelPreCaptureDeadline=null;if(d)this.timer.clearTimeout(d)}}createCaptureHelper(o){if(o.target.kind==="simulator"&&!this.options.createHelper)return this.simulatorHelperPool.acquire(o);return this.createHelper(o)}async startCaptureWithSimulatorRetry(o,s){let n=s.kind==="simulator"&&!this.options.createHelper,a=s;for(let c=0;;c++)try{await this.startCaptureAttempt(o,a);return}catch(d){if(d instanceof H)throw d;if(!n||!(d instanceof A))throw u(d,"Failed to start iOS screen capture");try{await this.helper?.invalidate?.()}catch(p){throw u(p,"Failed to invalidate silent iOS Simulator capture")}if(await this.stopCurrentHelper(),!this.isActive())return;if(c!==0)throw d.finalStartupError(this.requiredPermissionTarget);e.debug(`[IosH264Source] no first frame from pooled Simulator helper for ${Se(a)}; retrying once`),a=await this.reresolveSimulatorTarget(o,a)}}reresolveSimulatorTarget(o,s){return this.resolver.reresolveSimulatorTarget(o,s)}async startCaptureAttempt(o,s){e.info(`[IosH264Source] starting screen-capture-helper for ${Se(s)}`),this.lastReadinessPhase=null,this.requiredPermission=null,this.requiredPermissionTarget=ye(o),this.nativeIdleCapabilityConfirmed=!1,this.idleSupportReported=!1;let n=this.createCaptureHelper({binaryPath:o,target:s});this.helper=n,this.encodedCapabilityConfirmed=!1,this.wireEncodedHelper(n);let a=this.options.audioEnabled?this.startup.waitForFirstAudio(n):null,c=this.startup.waitForFirstEncodedRecord(n,s);try{await Promise.all([c,a,Promise.resolve().then(()=>n.start())])}catch(d){throw this.encodedStartupError(d instanceof Error?d:Error(r(d)))}}encodedStartupError(o){if(this.encodedCapabilityConfirmed||o instanceof Rp||o instanceof H)return o;return new H(`The screen-capture-helper did not advertise the '${_I}' capability before failing to start encoded capture (${o.message}). Update to the screen-capture-helper from the matching AutoMobile release, or rebuild the local helper and update AUTOMOBILE_IOS_SCREEN_CAPTURE_HELPER.`)}wireEncodedHelper(o){let s=this.helperGeneration;o.on("encodedVideo",(n)=>{if(this.isCurrentHelper(o,s))this.handleEncodedVideo(n)}),o.on("capability",(n)=>{if(this.isCurrentHelper(o,s)&&n===_I)this.encodedCapabilityConfirmed=!0}),o.on("malformed",(n)=>{if(!this.isCurrentHelper(o,s))return;e.warn(`[IosH264Source] malformed encoded record from helper: ${n.reason}; requesting keyframe to recover`),this.requestKeyFrame()}),this.wireHelperDiagnostics(o)}wireHelperDiagnostics(o){let s=this.helperGeneration;et(o,{isCurrentHelper:()=>this.isCurrentHelper(o,s),isActive:()=>this.isActive(),confirmIdleSupport:()=>{this.nativeIdleCapabilityConfirmed=!0,this.idleSupportReported=!0},nativeIdleCapabilityConfirmed:()=>this.nativeIdleCapabilityConfirmed,setRequiredPermission:(n)=>{this.requiredPermission=n},setRequiredPermissionTarget:(n)=>{this.requiredPermissionTarget=n},setLastReadinessPhase:(n)=>{this.lastReadinessPhase=n},helperStderrTail:()=>this.helperStderrTail,failForHelperLine:(n)=>this.failIfCurrentHelper(o,s,this.helperFailureFor(n)),setNativeFrameMetrics:(n)=>{this.nativeFrameMetrics=n,this.options.onFrameMetrics?.(this.getFrameMetrics())},options:this.options})}helperFailureFor(o){return this.requiredPermission==="screen-recording"||ge(o)?new Rp(this.requiredPermissionTarget??"AutoMobile"):Error(`screen-capture-helper reported an error: ${o}`)}handleEncodedVideo(o){if(!this.isActive())return;this.encodedCapabilityConfirmed=!0,this.reportLegacyIdleSupport(),this.options.onSourceFrame?.(),this.options.onData(o.payload),this.options.onEncodedAccessUnit?.()}reportLegacyIdleSupport(){if(this.captureKind==="simulator"&&!this.idleSupportReported)this.idleSupportReported=!0,this.options.onIdleAttestationSupport?.(!1)}failIfRunning(o){if(this.phase!=="running")return;if(!this.startupComplete||this.runningReconnectMaxAttempts<=0){this.failNow(o);return}if(!this.hasConsumers){this.phase="reconnecting",this.startupComplete=!1,this.beginTeardown(),this.queueReconnect(o);return}this.phase="reconnecting",this.startupComplete=!1,this.queueReconnect(o)}failNow(o){this.startup.rejectFirstAudioWait?.(o),this.phase="stopping",this.startupComplete=!1,this.beginTeardown(),this.options.onError?.(o)}async runReconnect(o){if(e.warn(`[IosH264Source] running-phase capture failure; attempting bounded reconnect (up to ${this.runningReconnectMaxAttempts}): ${o.message}`),await this.beginTeardown(),!this.hasConsumers){this.deferredHelperFailure=o;return}for(let s=1;this.phase==="reconnecting"&&s<=this.runningReconnectMaxAttempts;s++){let n=this.runningReconnectBackoff.delayForAttempt(s);if(!await this.waitForActiveReconnect(n,o))return;this.phase="starting";let a=++this.helperGeneration;try{if(await this.establishCapture(a),a!==this.helperGeneration)return;if(this.phaseNow()==="running"){this.startupComplete=!0,e.info(`[IosH264Source] running-phase reconnect succeeded on attempt ${s}`);return}return}catch(c){if(a!==this.helperGeneration)return;e.warn(`[IosH264Source] reconnect attempt ${s}/${this.runningReconnectMaxAttempts} failed: ${r(c)}`),await this.beginTeardown();let d=this.phaseNow();if(d==="stopping"||d==="idle")return;if(c instanceof H){this.failNow(c);return}this.phase="reconnecting"}}this.finishReconnectExhausted(o)}finishReconnectExhausted(o){if(this.phase!=="reconnecting")return;if(!this.hasConsumers){this.deferredHelperFailure=o;return}this.failNow(o)}async waitForActiveReconnect(o,s){let n=await this.waitReconnectBackoff(o);if(this.phase==="reconnecting"&&(!this.hasConsumers||n))this.deferredHelperFailure=s;return!n&&this.hasConsumers&&this.phase==="reconnecting"}queueReconnect(o){if(this.deferredHelperFailure=o,!this.hasConsumers||this.phase!=="reconnecting"||this.reconnectPromise)return;this.deferredHelperFailure=null,this.reconnectPromise=this.runReconnect(o).finally(()=>{if(this.reconnectPromise=null,this.deferredHelperFailure&&this.hasConsumers)this.queueReconnect(this.deferredHelperFailure)})}waitReconnectBackoff(o){return new Promise((s)=>{let n=this.timer.setTimeout(()=>{this.cancelReconnectDelay=null,s(!1)},o);this.cancelReconnectDelay=()=>{this.timer.clearTimeout(n),this.cancelReconnectDelay=null,s(!0)}})}describeHelperExit(o,s){let n=this.helperStderrTail.length===0?"":`; last stderr: ${this.helperStderrTail.join(" | ")}`;return`screen-capture-helper ${s} (code=${o.code}, signal=${o.signal})${n}`}failIfCurrentHelper(o,s,n){if(!this.isCurrentHelper(o,s))return;this.failIfRunning(n)}isCurrentHelper(o,s){return this.helper===o&&this.helperGeneration===s}isActive(){return this.phase==="starting"||this.phase==="running"||this.phase==="reconnecting"}phaseNow(){return this.phase}beginTeardown(){return this.teardownPromise??=this.teardown().finally(()=>{if(this.teardownPromise=null,this.phase==="stopping")this.phase="idle"}),this.teardownPromise}async teardown(){await this.stopCurrentHelper()}async stopCurrentHelper(){this.startup.cancelFirstFrameWait?.(),this.startup.cancelFirstFrameWait=null,this.startup.cancelFirstAudioWait?.(),this.startup.cancelFirstAudioWait=null,this.startup.rejectFirstAudioWait=null;let o=this.helper;if(this.helper=null,!o)return;let s=(this.invalidateHelperOnStop&&o.invalidate?o.invalidate():o.stop()).then(()=>!0,(a)=>(e.debug(`[IosH264Source] helper stop failed: ${a}`),!0)),n=Symbol("helper stop timeout");try{await l(s,{timer:this.timer,timeoutMs:fe,label:"iOS capture helper stop",timeoutError:()=>n})}catch(a){if(a!==n)throw a;e.warn(`[IosH264Source] helper stop exceeded ${fe}ms; continuing teardown`)}}}var aO=(o,s)=>{if(o.device.platform==="android")return Qe(o,s);if(o.device.platform==="ios"){if(o.audioEnabled&&W({deviceId:o.device.deviceId})!=="simulator")throw new t("WebRTC playback audio capture is available only for iOS Simulator targets; public iOS APIs cannot capture playback audio from a physical device.");return new we(o)}throw new t(`WebRTC streaming does not support ${o.device.platform} devices.`)};
3
- export{vd,bd,Rs,nf,Og,Vk,oO,T2,za,HY,Rp,sO,aO,qY,VY,k2,cO};
4
-
5
- //# debugId=3071BA593E5DC7CE64756E2164756E21
@@ -1,8 +0,0 @@
1
- // @bun
2
- import{i,Bt,jR,dr,Q,Ft,e}from"./chunk-z8t0v07j.js";import{sr,jA,jS,KA,im,Ln,yo,Fi,pn,om,sm,Kd,mn,vo,ZA,wa}from"./chunk-6d3mmqxt.js";import{qc,Y,hn,F,ti,o,W,eo,Xc,Wo,$w,ur,st,Uw,Io,$L,M,Zc,Zt,Gt,Vt,Qt,Ms,VL,_t,Da,mt,G,zW,Dte,Fv,jW,KL,du,we,Qc,xm,ra,ed,gi,Lv,ni,mr,sR,_e,ir,fr,DB,qm,SD,x3,On,Rn,gg,Vm,ys,qi,tr,kre,PD,Ez,Iz,Ire,$B,_re,Rk,kD,RR,zm,ED,Pn,ar,$3,Bz,$z,DD,Uz,Km,_,xe,k,Bs,Vi}from"./chunk-h3n4adc6.js";import{fp}from"./chunk-79q5xsdc.js";import{De,Ht,wt}from"./chunk-4fgdhcwx.js";import{Yx,mF,fF,hF,gF,yF,qA,Vq,oQ,yh}from"./chunk-0e4gm1kj.js";import{hq,R7,v0,Kp,Gp,Ou,Y6}from"./chunk-4xd6zs3y.js";import{Lc}from"./chunk-pm06b05d.js";import{Oc,s0,q6,My,a0,VI,c0,d0,l0,u0,p0}from"./chunk-sjn0nj4p.js";import{$q,es,ba,gh,gr,Ni,pF,eQ}from"./chunk-bn64x5z5.js";import{nT,dc,Eh,Ih,xQ,fn,YS,JS,XS,zF,rs,Zs,_h,kV,rv,jF,Ta}from"./chunk-sns0c35v.js";import{r,t,u,yt}from"./chunk-9rkfyt6q.js";import{AsyncLocalStorage as kt}from"async_hooks";var Fe=new kt;function dA(n,a){return n?Fe.run(n,a):a()}function qI(){Fe.getStore()?.()}function ae(n){let{left:a,top:s,right:c,bottom:l}=n.bounds;return JSON.stringify([n["resource-id"],a,s,c,l])}function xt(n,a){return n.bounds.left===a.bounds.left&&n.bounds.top===a.bounds.top&&n.bounds.right===a.bounds.right&&n.bounds.bottom===a.bounds.bottom}function Ct(n,a){let s=n.bounds,c=a.bounds,l=(c.left+c.right-s.left-s.right)/2,d=(c.top+c.bottom-s.top-s.bottom)/2,p=l===0?[]:[l>0?"right":"left"],h=d===0?[]:[d>0?"down":"up"],m=s.left<c.right&&c.left<s.right;return(s.top<c.bottom&&c.top<s.bottom?!0:m?!1:Math.abs(l)>=Math.abs(d))?[...p,...h]:[...h,...p]}function Dt({maxMoves:n=30,maxSearchMoves:a=60}){if(!Number.isInteger(n)||n<0)throw new t("tvOS maxMoves must be a non-negative integer.");if(!Number.isInteger(a)||a<0)throw new t("tvOS maxSearchMoves must be a non-negative integer.");return{maxMoves:n,maxSearchMoves:a}}function It(n,a){let s=Object.entries(n).filter(([c,l])=>l!==void 0&&(l!==!1||c==="ensureChecked")&&!["action","elementId","text","index"].includes(c));if(n.action!=="tap"||s.length)throw new t(`tvOS tapOn supports only action tap and elementId, text, index; unsupported: ${n.action!=="tap"?n.action:s.map(([c])=>c).join(", ")}.`);if(n.index!==void 0&&(!Number.isInteger(n.index)||n.index<0))throw new t("tvOS tap index must be a non-negative integer.");return Dt(a)}function Nt(n,a){return(a.elementId!==void 0||a.text!==void 0)&&(a.elementId===void 0||n["resource-id"]===a.elementId||n["view-id"]===a.elementId)&&(a.text===void 0||n.text===a.text)}function ie(n){return JSON.stringify([n["resource-id"],n["view-id"],n.text,n.className])}function Ie(n){return JSON.stringify([n["resource-id"],n["view-id"],n.className])}function Lt(n,a){if(!a)return"[]";let s=Ie(a);return JSON.stringify([ae(a),n.filter((c)=>Ie(c)===s).map((c)=>[ae(c),c.text])])}function Mt(n,a,s){let{left:c,top:l,right:d,bottom:p}=n.bounds;return c>=0&&l>=0&&d<=a&&p<=s}async function Ve(n,a,s,c){let l=im(await n.hierarchy(s));s?.throwIfAborted();let d=new G().flattenViewHierarchy(l).map(({element:v})=>v),p=d.find((v)=>v.focused==="true"),h=Lt(d,p),m=c?d.filter((v)=>ie(v)===c.key):[];if(c&&m.length!==c.count)throw new t("The tvOS tapOn target disappeared or became ambiguous; observe and retry with its current identifier or exact text.");let f=c?m[c.ordinal]:d.filter((v)=>v.bounds.right>v.bounds.left&&v.bounds.bottom>v.bounds.top&&Nt(v,a)).map((v,b)=>({element:v,windowRank:Mt(v,l.screenWidth,l.screenHeight)?0:1,area:_t(v.bounds),order:b,interactive:!1})).sort(zm)[a.index??0]?.element;if(!f||c)return{focus:p,target:f,identity:c,signature:h};let T=ie(f),y=d.filter((v)=>ie(v)===T);return{focus:p,target:f,identity:{key:T,ordinal:y.indexOf(f),count:y.length},signature:h}}function He(n){if(!n.focus)throw new t("Nothing is focused on tvOS; use pressButton to establish focus and observe before retrying tapOn.");return n.focus}async function zt({client:n,options:a,signal:s},c,l){let d=c,p=0,h=async(f)=>{if(p>=l)throw new t(`No tvOS element matched after searching ${l} focus moves; observe and check the identifier, exact text or index, or move closer with pressButton before retrying.`);p++,await n.request({type:"request_press_button",action:f},s),s?.throwIfAborted();let T=await Ve(n,a,s),y=T.signature!==d.signature;return d=T,y},m=async(f)=>{while(!d.target&&await h(f));return Boolean(d.target)};for(let f of["down","up"]){do if(await m("right")||await m("left"))return d;while(await h(f));if(d.target)return d}throw new t("No tvOS element matched after searching the screen with focus moves; observe and check the identifier, exact text or index.")}function ne(n){return n["resource-id"]||n.text||ae(n)}async function Wt(n,a,s){let{client:c,options:l,signal:d}=n,p=await Ve(c,l,d,a);if(!p.target&&!a){if(l.elementId===void 0&&l.text===void 0)throw new t("No tvOS element matched; observe and check the identifier, exact text or index.");He(p),p=await zt(n,p,s)}return{focus:He(p),target:p.target,identity:p.identity,signature:p.signature}}async function Be(n,a,s,c={}){let{maxMoves:l,maxSearchMoves:d}=It(a,c);s?.throwIfAborted();let p={client:Ln.require(n),options:a,signal:s},{client:h}=p,m=new Map,f,T;for(let y=0;;y++){s?.throwIfAborted();let v=await Wt(p,T,d),{focus:b,target:g}=v;if(T=v.identity,xt(b,g))return await h.request({type:"request_press_button",action:"select"},s),{success:!0,action:"tap",element:g};let E=m.get(v.signature)??new Set;if(f?.signature===v.signature)E.add(f.direction),m.set(v.signature,E);let S=Ct(b,g).find((R)=>!E.has(R));if(!S)throw new t(`tvOS focus stopped making progress from ${ne(b)} toward ${ne(g)}; the target may be unreachable or in a focus trap. Observe and navigate with pressButton before retrying.`);if(y>=l)throw new t(`tvOS tapOn exceeded maxMoves (${l}) before reaching ${ne(g)}; observe and move closer with pressButton before retrying.`);await h.request({type:"request_press_button",action:S},s),f={signature:v.signature,direction:S}}}var Ut=new Set(["\b","\x7F","\uF728"]);function qt(n,a,s){if(s.container!==void 0||s.selectionStrategy!==void 0||s.layer!==void 0||s.display!==void 0||n.length===0)throw new t("watchOS sendKeys supports only type commands into the focused field; focus it with tapOn first.");if(a!==void 0&&(a.testTag!==void 0||a.textAny!==void 0||a.elementId===void 0&&a.text===void 0))throw new t("watchOS sendKeys selector supports only exact elementId or text; focus the field with tapOn first.");return n.map((c)=>{if(c.action!=="type"||!c.text||c.operation==="replace"||c.mode!==void 0&&c.mode!=="auto"||c.keyboardProfile!==void 0)throw new t("watchOS sendKeys supports only non-empty append type commands; focus the field with tapOn first.");if([...c.text].some((l)=>Ut.has(l)))throw new t("watchOS sendKeys appends text only; text containing a delete key would erase existing content.");return c})}var Ne=[50,100,200,250,250,250,250];function Le(n){return n instanceof wa&&n.errorCode==="command_failed"&&n.message.startsWith("No focused text field")}async function $t(n,a,s,c){await new hn(s).executeOrThrow(()=>n.request({type:"type",text:a},c).then(()=>{return}),{maxAttempts:Ne.length+1,delays:Ne,signal:c,shouldRetry:Le,expectedFailure:{reason:"sendKeys reports the focus refusal as a failed command",matches:Le}})}async function Me(n,a,s,c={}){let l=qt(a,s,c),{signal:d,timer:p}=c;d?.throwIfAborted();let h=yo.require(n);if(s!==void 0)await hq(n,{action:"tap",...s},d,!0);let m=[];for(let[f,T]of l.entries()){d?.throwIfAborted();try{if(f===0&&s!==void 0)await $t(h,T.text,p,d);else await h.request({type:"type",text:T.text},d)}catch(y){d?.throwIfAborted();let v=u(y,"watchOS text entry failed; focus a text field with tapOn first");return e.warn(v.message,y),m.push({index:f,action:"type",success:!1,resolvedMode:"xcuiTypeText",error:v.message}),{success:!1,completedCommands:f,failedIndex:f,commands:m,error:v.message}}m.push({index:f,action:"type",success:!0,textLength:[...T.text].length,resolvedMode:"xcuiTypeText"})}return{success:!0,completedCommands:m.length,commands:m}}var Kt=new Set(["\b","\x7F","\uF728"]);function jt(n){let a=Object.entries(n).filter(([s,c])=>c!==void 0&&(c!==!1||s==="ensureChecked")&&!["action","elementId","text","index"].includes(s));if(n.action!=="tap"||a.length||n.elementId===void 0&&n.text===void 0)throw new t("visionOS tapOn supports only action tap with elementId, exact text and optional index in a window or ornament.");if(n.index!==void 0&&(!Number.isInteger(n.index)||n.index<0))throw new t("visionOS tap index must be a non-negative integer.")}function ze(n){if(n.enabled!=="false"&&n["resource-id"])return n.clickable==="true"?0:1;return 2}async function We(n,a,s){return jt(a),KA(n,s,()=>Yt(n,a,s))}async function Yt(n,a,s){let c=await jS(n,s),l=jA(await c.hierarchy(s)),d=new G().flattenViewHierarchy(l).map(({element:y})=>y),h=d.filter((y)=>(a.elementId===void 0||y["resource-id"]===a.elementId||y["view-id"]===a.elementId)&&(a.text===void 0||y.text===a.text)).sort((y,v)=>ze(y)-ze(v))[a.index??0];if(!h)throw new t("No visionOS element matched the selector and index; observe and use its identifier or exact text.");let m=h["resource-id"];if(!m)throw new t("The matched visionOS element has no accessibility identifier; use an identified control's text or elementId.");if(h.enabled==="false")throw new t("The matched visionOS element is disabled; observe and select an enabled control.");let f=d.filter((y)=>y["resource-id"]===m),T=f.filter((y)=>y.enabled!=="false"&&y.class===h.class&&(y.text??"")===(h.text??""));if(f.length>1&&T.length!==1){let y=T.map((v)=>`className=${v.class}, text=${JSON.stringify(v.text??"")}, bounds=${JSON.stringify(v.bounds)}`);throw new t(`The visionOS match was ambiguous for identifier '${m}'; candidates: ${y.join("; ")}. Pass index or a distinct text/elementId to select a distinguishable target.`)}return s?.throwIfAborted(),await c.request({type:"request_tap_element",identifier:m,...f.length>1?{label:h.text??"",elementType:Number(h.class)}:{}},s),{success:!0,action:"tap",element:h}}async function Ue(n,a,s,c={}){if(s!==void 0||c.container!==void 0||c.selectionStrategy!==void 0||c.layer!==void 0||c.display!==void 0||a.length===0)throw new t("visionOS sendKeys supports only type commands into the focused field; focus it with tapOn first.");let l=a.map((m)=>{if(m.action!=="type"||!m.text||m.operation==="replace")throw new t("visionOS sendKeys supports only non-empty append type commands; focus the field with tapOn first.");if([...m.text].some((f)=>Kt.has(f)))throw new t("visionOS sendKeys appends text only; text containing a delete key would erase existing content.");return m}),{signal:d}=c,p=await jS(n,d),h=[];for(let[m,f]of l.entries()){d?.throwIfAborted();try{await p.request({type:"request_append_text",text:f.text},d)}catch(T){d?.throwIfAborted();let y=u(T,"visionOS text entry failed; focus a text field with tapOn first");return e.warn(y.message,T),h.push({index:m,action:"type",success:!1,error:y.message}),{success:!1,completedCommands:m,failedIndex:m,commands:h,error:y.message}}h.push({index:m,action:"type",success:!0,textLength:[...f.text].length})}return{success:!0,completedCommands:h.length,commands:h}}function se(n){return n==="watchos"||n==="tvos"||n==="visionos"}function qe(n,a,s){switch(n.platform){case"visionos":return We(n.deviceId,a,s);case"tvos":return Be(n.deviceId,a,s);case"watchos":return hq(n.deviceId,a,s);default:return}}function l7(n,a,s,c={}){return(n.platform==="watchos"?Me:n.platform==="visionos"?Ue:eQ)(n.deviceId,a,s,c)}var A=3;function L(n,a,s,c){let l=mt(a);if(c&&l===c.source)return!0;if(!c&&Ge(n,a))return!0;if(!s||!l)return!1;let d=c?[c]:s.filter((p)=>p.element&&Ge(n,p.element));return s.some((p)=>{if(p.source!==l||!p.element)return!1;return d.some((h)=>{for(let[m,f]of[[p,h],[h,p]]){let T=m.parentIndex;while(T!==void 0){let y=s[T];if(y===f)return!0;if(Pn(y.properties))break;T=y.parentIndex}}return!1})})}function Ge(n,a){for(let s of["resource-id","view-id","test-tag"]){let c=n[s],l=a[s];if(s==="view-id"&&c!==l&&[c,l].some((d)=>String(d).startsWith("s2-")))continue;if(typeof c==="string"&&c.length>0&&typeof l==="string"&&l.length>0)return c===l}return Ms(n.bounds,a.bounds,A)&&oe(n,a)}function D(n,a){let s=n.text??n["content-desc"]??n["ios-accessibility-label"]??a.text??a.textAny?.[0];return typeof s==="string"&&s.length>0?JSON.stringify(s):"the matched element"}function oe(n,a,s){if(n.class!==a.class)return!1;let c=["resource-id","test-tag"].filter((h)=>{let m=n[h];return typeof m==="string"&&m.length>0});if(c.length>0)return c.every((h)=>n[h]===a[h]);let l=n.text??n["content-desc"]??n["ios-accessibility-label"],d=a.text??a["content-desc"]??a["ios-accessibility-label"],p=typeof l==="string"&&l.length>0?l:s;return typeof p==="string"&&p.length>0&&p===d}function C(n){let a=[];for(let s of n){let c=a.find((l)=>l.every((d)=>d.rootGroup!==s.rootGroup&&Jt(d,s)));if(c)c.push(s);else a.push([s])}return a.map((s)=>s[0])}function Jt(n,a){return Boolean(n.element&&a.element&&n.className===a.className&&Ms(n.element.bounds,a.element.bounds,A)&&Ta(n.element)===Ta(a.element)&&["resource-id","test-tag","view-id","text","content-desc","ios-accessibility-label"].every((s)=>n.element[s]===a.element[s]))}function ce(n,a){let s=A;return VL(n.bounds,a.bounds,s)&&Math.abs(n.bounds.right-n.bounds.left-(a.bounds.right-a.bounds.left))<=s&&Math.abs(n.bounds.bottom-n.bounds.top-(a.bounds.bottom-a.bounds.top))<=s}function $e(n,a){if(!n.length||n.length!==a.length)return;let s=a[0].element.bounds.top-n[0].element.bounds.top;return n.every((l,d)=>{let p=l.element,h=a[d].element;return p.class===h.class&&ce(p,h)&&Ms({...p.bounds,top:p.bounds.top+s,bottom:p.bounds.bottom+s},h.bounds,A)})?s:void 0}function Ke(n,a){let s;for(let c of["resource-id","test-tag","view-id"]){let l=n[c];if(typeof l!=="string"||l.length===0)continue;let d=C(a.filter((p)=>p.element&&Pn(p.properties)&&p.element[c]===l));if(d.length===1)return{key:c,value:l,shared:!1};if(d.length>1)s??={key:c,value:l,shared:!0}}return s}function je(n){if(!n.testTag)throw new t("tapOn requires non-blank text, textAny, elementId, or testTag to interact with");return n.testTag}function P(n,a){return n.x>=a.left&&n.x<a.right&&n.y>=a.top&&n.y<a.bottom}function Ye(n){return!!n&&n.left<n.right&&n.top<n.bottom}function x(n,a){let s=mt(a);return(s&&n.find((c)=>c.source===s))??n.find((c)=>c.element&&c.bounds&&Vt(c.bounds,a.bounds)&&c.nativeId===a["resource-id"]&&c.nodeKey===a["view-id"])}function j(n,a,s){let c=s==="ios"?Rn(a):void 0,l=mt(n);return c&&(!l||c.nodes.some((d)=>d.source===l))?c.hierarchy:a}function Je(n){return n===void 0?"touch":"none"}class w extends t{reason;constructor(n,a){super(n);this.reason=a}}var yS=Symbol("tapFocusFailure"),n0=Symbol("tapResolvedLayer");function z(n,a,s){if(!ra(n))return;n=j(a,n,s);let c=mt(a);if(!c)return;let l=new G;for(let d of["prototype","app"])if(l.flattenViewHierarchy(ed(n,d),{includeWindows:!0}).some((h)=>mt(h.element)===c))return d;return}function H(n,a){if(a!==void 0)Object.defineProperty(n,n0,{value:a,enumerable:!1,configurable:!0,writable:!0});return n}function V(n,a,s){if(n==="focus"&&s instanceof w)Object.defineProperty(a,yS,{value:s.reason});return a}class jp extends t{}function J(n){return n.length?{warnings:n}:{}}function Xe(n,a){return a?[...n,a]:n}class le{host;constructor(n){this.host=n}createErrorResult(n,a,s){return V(n,yF(n,a),s)}validateOptions(n){if(n.ensureChecked!==void 0&&n.action!=="tap")return'tapOn ensureChecked requires action "tap"';if(n.ensureChecked!==void 0&&n.selectionStrategy==="random")return"tapOn ensureChecked cannot use random selection; use a unique selector or index";if([n.text,n.elementId,n.testTag,n.textAny,n.accessibilityLink].filter(Boolean).length!==1)return"tapOn requires exactly one of text, textAny, elementId, testTag, or accessibilityLink";if(n.textAny&&n.textAny.length===0)return"tapOn textAny selector must be non-empty";let s=hF(n.container,"tapOn");if(s)return s;return this.validateSemanticLinkOptions(n)}validateSemanticLinkOptions(n){if(n.layer!==void 0&&this.hasSemanticLinkTarget(n))return"tapOn layer cannot be used with accessibilityLink or subtext";if(n.selectionStrategy==="unique"&&(n.sibling||n.accessibilityLink))return"tapOn unique selection cannot use sibling or direct accessibilityLink; select a unique owner with subtext instead";if(n.relativePosition!==void 0)return"tapOn relativePosition is no longer supported; use accessibilityLink or subtext";if(!this.hasSemanticLinkTarget(n))return null;return this.semanticLinkValidationErrors(n).find(({invalid:a})=>a)?.error??null}hasSemanticLinkTarget(n){return[n.accessibilityLink,n.subtext].some((a)=>a!==void 0)}semanticLinkValidationErrors(n){return[{invalid:[n.accessibilityLink,n.subtext].every((a)=>a!==void 0),error:"tapOn accessibilityLink and subtext cannot be used together"},{invalid:n.action!=="tap",error:"tapOn semantic link activation supports only the tap action"},{invalid:n.sibling,error:"tapOn semantic link activation cannot use sibling"},{invalid:Boolean(n.retryIfNoChange??n.ensureTap),error:"tapOn semantic link activation cannot retry an acknowledged link activation"},{invalid:n.ensureChecked!==void 0,error:"tapOn semantic link activation cannot ensure checked state"},{invalid:n.searchUntil,error:"tapOn semantic link activation cannot use searchUntil"},{invalid:this.semanticLinkTextIsBlank(n),error:"tapOn semantic link text must be non-empty"},{invalid:this.semanticLinkOccurrenceIsInvalid(n),error:"tapOn semantic link occurrence must be a non-negative integer"},{invalid:n.subtext?n.index!==void 0:!1,error:"tapOn owner-scoped semantic link activation cannot use index; use a unique owner selector"},{invalid:n.subtext?n.selectionStrategy==="random":!1,error:"tapOn owner-scoped semantic link activation cannot use random selection; use a unique owner selector"}]}semanticLinkTextIsBlank(n){return(n.subtext?.text??n.accessibilityLink)?.trim().length===0}semanticLinkOccurrenceIsInvalid(n){let a=n.subtext?.occurrence??n.index??0;return![Number.isInteger(a),a>=0].every(Boolean)}async activateSemanticLink(n,a,{owner:s,viewHierarchy:c,signal:l}){let d=(p,h)=>{if(p.dispatched&&p.acknowledged!==!0)throw h(),fn(p.error)};if(s&&!this.host.hasUniqueSemanticLinkOwner(s,c))return{success:!1,error:"Container-scoped semantic link activation requires a unique resource-id owner identity"};if(this.host.usesAndroidLinkActivation()){let p=s?rs(s):void 0;if(s&&!p)return{success:!1,error:"Container-scoped semantic link activation requires a stable native owner identity"};let h=await this.host.accessibilityService().requestActivateAccessibilityLink({text:n,occurrence:a,selector:p,signal:l});return d(h,()=>{k.getExistingInstance(this.host.device().deviceId)?.invalidateCache()}),{success:h.success,error:h.error}}if(this.host.usesIosLinkActivation()){let p=s?.["resource-id"];if(s&&(typeof p!=="string"||p.length===0))return{success:!1,error:"Container-scoped semantic link activation requires a stable native owner identity"};let h=await _.getInstance(this.host.device()).requestActivateAccessibilityLink({text:n,occurrence:a,ownerResourceId:p,signal:l});return d(h,()=>Vq(this.host.device(),{success:!0})),Vq(this.host.device(),h),{success:h.success,error:h.error,warning:h.warning}}return{success:!1,error:yt(this.host.device().platform,"tap on elements").message}}hasUniqueSemanticLinkOwner(n,a){if(!a)return!1;let s=this.host.elementParser().flattenViewHierarchy(a,{includeWindows:!0}).map(({element:l})=>l);if(this.host.usesCapturedOwnerIdentity()){let l=n["resource-id"];return typeof l==="string"&&l.length>0&&Xt(s.filter((d)=>d["resource-id"]===l)).length===1}let c=rs(n);return c!==void 0&&s.filter((l)=>KL(l,c)).length===1}async activateAccessibilityLinkPhase(n,a,{observeResult:s,viewHierarchy:c,activationWarnings:l,signal:d}){let p=n.index??0,h=this.host.resolveContainerElement(c,this.host.withObservationScreenSize(n,s));if(n.container&&!h)return{success:!1,error:"Semantic link container is no longer present"};let m=await this.host.activateSemanticLink(a,p,{owner:h,viewHierarchy:c,signal:d});if(!m.success)return{success:!1,error:m.error};return{success:!0,action:n.action,element:{text:a,bounds:{left:0,top:0,right:0,bottom:0}},activatedSubtext:{text:a,occurrence:p},...J(Xe(l,m.warning))}}async activateSubtextPhase({options:n,subtext:a,element:s,viewHierarchy:c,selectedElement:l,searchUntil:d,activationWarnings:p,signal:h}){let m=a.occurrence??0,f=await this.host.activateSemanticLink(a.text,m,{owner:s,viewHierarchy:c,signal:h});if(!f.success)return{success:!1,error:f.error};return{success:!0,action:n.action,element:s,selectedElement:l,searchUntil:d,activatedSubtext:{text:a.text,occurrence:m},...J(Xe(p,f.warning))}}}function Xt(n){let a=n.filter((s)=>{let c=mt(s);return!c||!$L(c)});return a.length>0?a:n}class de{host;constructor(n){this.host=n}async prepareAndroidDisplaySelection(n,a){let{target:s,signal:c}=a,l=a.selection,d=s.observation.viewHierarchy;if(!d)throw new t("Selected display has no view hierarchy");let p=await this.host.refreshEnsureCheckedSelection(n,s.observation,l,c);l=p.selection,d=p.viewHierarchy;let h={durationMs:0,requestCount:0,changeCount:0},m=l.element&&this.host.ensureCheckedBeforeTap(n,l.element,this.host.buildSelectedElementMetadata(l),h);if(m)return{result:m};if(this.host.strategy().shouldRunPreTapStability(n)){let f=await this.host.resolveAndroidStableTapTargetAfterRefreshes(n,s.observation,n.action,{requireResourceId:!1,signal:c});if(!f.ok)return{result:{success:!1,error:f.error}};this.host.replaceObservationHierarchy(s.observation,f.viewHierarchy,!0),d=f.viewHierarchy,l={...f.selection,element:f.tapElement};let T=this.host.ensureCheckedBeforeTap(n,f.selection.element??f.tapElement,this.host.buildSelectedElementMetadata(l),h);if(T)return{result:T}}return{selection:l,hierarchy:d}}async executeOnAndroidDisplay(n,a){let{target:s,signal:c}=a,l=await this.prepareAndroidDisplaySelection(n,a);if("result"in l)return l.result;let{selection:d,hierarchy:p}=l,h=d.element;if(!h?.bounds)throw new w("Element not found on selected display","not-found");let m=this.host.buildSelectedElementMetadata(d),f=z(p,h,Q(this.host.device().platform,"tapOn"));if(n.action==="focus"){if(!Pn(h))return{success:!1,action:n.action,element:h,selectedElement:m,error:`Cannot focus ${D(h,n)} because it is not an editable input`};if(Ta(h))return H({success:!0,action:n.action,element:h,selectedElement:m,wasAlreadyFocused:!0,focusChanged:!1,focusVerified:!0,...this.host.geometry().getElementCenter(h)},f)}let T=this.host.visibleTapBounds(d,p,{screenSize:s.observation.screenSize,options:n}),y=T&&this.host.resolveVisibleTapPoint(h,p,T,{options:n,screenSize:s.observation.screenSize});if(!y)throw new w("Matched element has no visible tap area on selected display",this.host.tapPoints().visibilityFailureReason(d,p,s.observation.screenSize));let v=n.retryIfNoChange?this.host.hashViewHierarchy(p):null,b=[...a.talkBack.warnings],g=await this.androidDisplayDispatch(n,{...a,onWarning:(E)=>b.push(E)});if(qI(),await g(y),v&&this.host.strategy().retryTapIfNoChange)await this.host.retryTapIfNoChange(v,y,n.action,{longPressDuration:this.host.strategy().longPressDurationMs,tapElement:h,options:{...this.host.withObservationScreenSize(n,s.observation),verification:{refresh:n.verification.refresh,dispatch:g}},isTalkBackEnabled:!1,screenSize:s.observation.screenSize,signal:c,selection:d});return H({success:!0,action:n.action,element:h,selectedElement:m,...J(b)},f)}async resolveAndroidDisplayTalkBack(n){let a=[],s=await this.host.strategy().isAccessibilityServiceEnabled((l)=>a.push(l)),c=s?Ih(n.displayId):void 0;if(c)throw c;return{enabled:s,warnings:a}}async androidDisplayDispatch(n,a){return zF(this.host.accessibilityService(),this.host.adb(),{action:n.action==="focus"?"tap":n.action,duration:n.duration},{target:a.target,signal:a.signal,onDispatched:a.onDispatched,timer:this.host.timer(),onWarning:a.onWarning,talkBack:a.talkBack.enabled?{strategy:this.host.talkBackStrategy(),driver:this.host.talkBackDriverFactory().createDriver(this.host.device())}:void 0})}selectElementOnDisplay(n,a){if(n.action==="focus"){let s=this.host.findElementInHierarchy(n,a).selection;if(s.element)return s;let c=this.host.findElementInHierarchy({...n,action:"tap"},a).selection;return c.element&&!Pn(c.element)?c:s}return this.host.findElementInHierarchy(n,a).selection}async resolveAndroidDisplaySelection(n,a,s){if(!a.viewHierarchy)throw new t("Selected display has no view hierarchy");if(n.action==="focus"){let l=this.selectElementOnDisplay(this.host.withObservationScreenSize(n,a),a.viewHierarchy);if(l.element)return{selection:l,stats:{durationMs:0,requestCount:0,changeCount:0}}}let c=await this.host.searchForElement(n,a,s);if(this.host.replaceObservationHierarchy(a,c.viewHierarchy,c.refreshedFromDevice),!c.selection.element)try{if(c.visibilityError)throw c.visibilityError;await this.host.handleElementNotFound(n,{containerFound:c.containerFound,signal:s,selection:c.selection})}catch(l){return e.warn(`tapOn display resolution failed: ${r(l)}`,l),{result:V(n.action,{...this.host.createErrorResult(n.action,r(l)),searchUntil:c.stats},l)}}return c}async observedAndroidDisplayInteraction(n,a){let{target:s,signal:c}=a,l=await this.resolveAndroidDisplayTalkBack(s),p={...n,verification:{refresh:(v)=>pF(s,this.host.hierarchyCapture(),v,{stale:()=>this.host.staleDisplay(s.observation.display.generation??this.host.displayTransitionReader().identityRevision(this.host.device().deviceId)),signal:c})}},h=await this.resolveAndroidDisplaySelection(p,s.observation,c);if("result"in h)return h.result;let{selection:m,stats:f}=h,T,y=await this.host.observedInteraction(async()=>{let v=await this.executeOnAndroidDisplay(p,{target:s,selection:m,signal:c,talkBack:l,onDispatched:()=>{T=this.host.timer().now()}});if(T!==void 0)a.onDispatchCompleted();return v},{...Ht.rawCoordinateGesture,display:s.observation.display.key,previousObservation:s.observation,signal:c,...n.ensureChecked!==void 0?{observationHostTimestampProvider:()=>T}:{}});if(y.searchUntil=f,T===void 0)s.assertCurrent();else if(this.host.checkPostActionDisplay(y,s.assertCurrent,c),y.staleDisplay)return this.host.unverifiableDisplayPostState(y,n);if(y.success&&y.skipped!=="already-checked")await this.host.applyEnsureCheckedResult(y,p,c);return this.finalizeDisplayFocusResult(y,n,m,s.observation)}unverifiableDisplayPostState(n,a){if(!n.staleDisplay||a.action!=="focus"&&a.ensureChecked===void 0)return n;return ir({...n,success:!1,error:void 0},new mr(new _e(n.staleDisplay)))}finalizeDisplayFocusResult(n,a,s,c){if(a.action!=="focus"||!n.success||n.wasAlreadyFocused)return n;let l=s.matchedElement!==n.element?s.matchedElement?.text:void 0;if(n.focusVerified=this.host.verifyFocusedInputTarget(a,n.element,n.observation,{labelText:l,selectedIndex:n.selectedElement?.indexInMatches,preTapHierarchy:c.viewHierarchy}),!n.focusVerified)n.success=!1,n.error=`Failed to confirm focus on editable input ${D(n.element,a)}: the focused field could not be matched to the target`;return n}async executeOnDisplay(n,a,s){let c=n.display,l=!1;if(c!==void 0)try{let d=["subtext","accessibilityLink","focusFirst","screenReaderNavigation"].find((f)=>n[f]!==void 0);if(d)throw new t(sR(d));if(n.ensureTap)n={...n,preTapStability:!0,retryIfNoChange:!0};let h=n.ensureChecked!==void 0||n.sibling!==void 0||n.textAny!==void 0||n.searchUntil!==void 0?this.host.validateOptions(n):null;if(h)return this.host.createErrorResult(n.action,h);if(n.searchUntil!==void 0)this.host.getSearchUntilDuration(n);let m=await Ni(this.host.device(),c,this.host.observeScreen(),{adb:this.host.adb(),lastRenderedObservation:this.host.lastRenderedObservation(),signal:a,transitions:this.host.displayTransitionReader()});if(this.host.routesAndroidDisplay())return await this.observedAndroidDisplayInteraction(n,{target:m,signal:a,onDispatchCompleted:()=>{l=!0}})}catch(d){this.host.rethrowObservationAbort(d,a,l),this.host.rethrowKeyboardOcclusion(d,n.action,s),e.warn(`tapOn display routing failed: ${r(d)}`,d);let p=this.host.completedDisplayFailure(d,l);return ir(this.host.createErrorResult(n.action,r(p),p),p)}return}didCompleteDisplayGesture(n,a){return a!==void 0&&n.success&&!n.skipped&&!n.wasAlreadyFocused}completedDisplayFailure(n,a){return a&&n instanceof _e?new mr(n):n}rethrowKeyboardOcclusion(n,a,s){if(s?.throwOnKeyboardOcclusion&&this.host.strategy().rethrowsKeyboardOcclusion&&a==="focus"&&n instanceof jp)throw e.debug(`Tap on element awaits IME recovery: ${r(n)}`,n),n}}function er(n,a){return n.left<=a.left&&n.top<=a.top&&n.right>=a.right&&n.bottom>=a.bottom}function pe(n){return`[${n.left},${n.top}][${n.right},${n.bottom}]`}function rr(n){return{x:Math.round((n.left+n.right)/2),y:Math.round((n.top+n.bottom)/2)}}function U(n){let a=n["resource-id"]??n["content-desc"]??n.text,s=[a===void 0?void 0:`"${a}"`,n.bounds?pe(n.bounds):void 0].filter((c)=>c!==void 0);return s.length?s.join(" "):"(unlabelled)"}function Qe(n){if(!n.bounds)return"Observe the screen before retrying.";let{x:a,y:s}=rr(n.bounds);return`Observe the screen; if the intended control was not activated, use tapAt {x: ${a}, y: ${s}} (the matched element's center).`}function nr(n,a){if(!n?.bounds||!a.bounds||er(a.bounds,n.bounds))return;return`The activated element ${U(a)} does not contain the matched element ${U(n)}, so a different control may have been activated. ${Qe(n)}`}function or(n,a){let s=n??a;return`TalkBack activation is unconfirmed: the screen did not change after activating ${!!n?.bounds&&!!a.bounds&&pe(n.bounds)!==pe(a.bounds)&&n?`${U(a)} for the matched element ${U(n)}`:`the matched element ${U(s)}`}. `+Qe(s)}function Ze(n,a,s){if(n==="focus")return[];let c=nr(a.matchedElement??a.element??void 0,s);return c?[c]:[]}function et(n,a){if(a&&n.effect?.screenChanged===!1)n.warnings=[...n.warnings??[],or(a.matched,n.element)]}function cr(n,a,s){if(n.warnsOnDisabledElement&&jR(a.enabled))s.push("The matched element is disabled; the tap may have no effect.")}class ue{host;constructor(n){this.host=n}platform(){return Q(this.host.device().platform,"tapOn")}async executeWithReadScope(n,a={}){let{progress:s,signal:c,recovery:l,settlePostTapEffect:d}=a,p=jF(a.deadlineMs);if(this.host.assertLongPressWithinRequestBudget(n,p),n.display!==void 0){let y=await this.host.executeOnDisplay(n,c,l);if(y)return y}if(!n.action)return this.host.createErrorResult(n.action,"tap on action is required");let h=n.action;if(n.ensureTap)n={...n,preTapStability:!0,retryIfNoChange:!0};let m=this.host.validateOptions(n);if(m)return this.host.createErrorResult(n.action,m);let f=Y();f.serial("tapOnElement");let T={options:n,requestedAction:h,effectiveAction:h,signal:c,recovery:l,request:p,perf:f,previousObserveResult:null,selectionCapture:null,completedDisplayGesture:!1,settlePostTapEffect:d};try{o(c);let y=await this.host.observedInteraction((v,b)=>this.executeObservedTap(T,v,b),{queryOptions:{text:n.text??n.textAny?.[0],elementId:n.elementId,containerElementId:n.container?.elementId},...Ht.selectorResolvedGesture,display:n.display,timeoutMs:wt.gesture,progress:s,perf:f,signal:c,deferPredictionOutcome:!0,deferPostActionScreenshot:!0,...n.ensureChecked!==void 0?{observationHostTimestampProvider:()=>T.ensureCheckedTapTimestamp}:{},predictionContext:{toolName:"tapOn",toolArgs:this.host.predictionToolArgs(n)}});return await this.finalizeResult(T,y)}catch(y){return this.failureResult(T,y)}}async finalizeResult(n,a){let{options:s,requestedAction:c,signal:l,perf:d}=n;if(n.completedDisplayGesture=this.host.didCompleteDisplayGesture(a,s.display),s.display!==void 0&&a.staleDisplay)return this.host.unverifiableDisplayPostState(a,s);let p=!1;if(a.success&&a.observation&&a.element){p=!0;let h=await this.host.deriveTapEffectAfterPostTapObservation(n.previousObserveResult,a.observation,l,{settlePostTapEffect:n.settlePostTapEffect});a.effect=h.effect,a.observation=h.observation,await this.host.applyEnsureCheckedResult(a,s,l),await this.host.captureTerminalObservationScreenshot(a.observation,d,l),await this.host.recordDeferredPredictionOutcome(a,a.observation);let m=await this.host.selectionStateTracker().finalize({action:n.effectiveAction,selectionState:n.selectionCapture,currentObservation:a.observation,previousObservation:n.previousObserveResult,element:a.element,effect:h.effect,signal:l});if(m.length>0)a.observation.selectedElements=m;this.host.enforceFreshnessConsistencyWithEffect(n.previousObserveResult,a)}if(await this.host.confirmFocusAfterTap({result:a,options:s,requestedAction:c,focusTarget:n.focusTarget,focusLabelText:n.focusLabelText,preTapHierarchy:n.preTapHierarchy,signal:l}),p&&(c!=="focus"||a.focusVerified!==!0))et(a,n.screenReaderActivation);if(n.effectiveAction==="longPress"){let h=this.host.detectLongPressMetadata(n.previousObserveResult,a.observation);return{...a,...h,...this.longClickAdvertisement(a.element)}}return a}async failureResult(n,a){let{options:s,requestedAction:c,recovery:l,perf:d}=n;d.end(),this.host.rethrowKeyboardOcclusion(a,c,l),e.warn(`Tap on element failed: ${r(a)}`,a);let p=this.host.completedDisplayFailure(a,n.completedDisplayGesture);if(p instanceof _e||p instanceof mr)return ir(this.host.createErrorResult(n.effectiveAction,p.message),p);let h=xQ(a)?await v0(this.host.device(),{text:s.text,resourceId:s.elementId,container:s.container}):void 0;return this.host.readScopeFailureResult(c,n.effectiveAction,a,{searchUntilStats:n.searchUntilStats,debugContext:h})}async executeObservedTap(n,a,s){let{options:c,signal:l,perf:d}=n;if(n.previousObserveResult=a,n.preTapHierarchy=a.viewHierarchy,o(l),!a.viewHierarchy)return d.end(),{success:!1,error:"Unable to get view hierarchy, cannot tap on element"};let p={observeResult:a,viewHierarchy:a.viewHierarchy,activationWarnings:[],isAccessibilityServiceEnabled:void 0};if(await this.prepareHierarchy(n,p),c.accessibilityLink)return this.host.activateAccessibilityLinkPhase(c,c.accessibilityLink,{observeResult:a,viewHierarchy:p.viewHierarchy,activationWarnings:p.activationWarnings,signal:l});let h=await this.searchCurrentTarget(n,p),m=await this.prepareSelection(n,p,h);if("result"in m)return m.result;let f=m.target,T=await this.stabilizeTarget(n,f);if(T)return T;return this.dispatchTarget(n,f,s)}async prepareHierarchy(n,a){let{signal:s}=n,{observeResult:c}=a;if(a.isAccessibilityServiceEnabled=this.host.detectsAccessibilityBeforeSearch()?await this.host.strategy().isAccessibilityServiceEnabled((l)=>a.activationWarnings.push(l)):void 0,this.host.refreshesAccessibilityHierarchyBeforeSearch()&&a.isAccessibilityServiceEnabled){let l=await My(this.host.tapVerificationRefresh({screenSize:c.screenSize,signal:s}),this.host.timer(),s);n.preTapHierarchy=l,this.host.replaceObservationHierarchy(c,l,!0),a.viewHierarchy=l}}async shouldRevalidateCachedTarget(n,a,s){let{options:c}=n;return Boolean(this.host.revalidatesCachedTargets()&&!a.isAccessibilityServiceEnabled&&s.selection.element&&!sm(a.viewHierarchy)&&s.stats.requestCount===0&&c.ensureChecked===void 0&&!this.host.strategy().shouldRunPreTapStability(c)&&(this.host.canReuseAccessibilityState()||!(a.isAccessibilityServiceEnabled??=await this.host.strategy().isAccessibilityServiceEnabled())))}async searchCurrentTarget(n,a){let{options:s,signal:c,perf:l,request:d}=n,{observeResult:p}=a,h=await l.track("findElement",()=>this.host.searchForElement(s,p,c));if(await this.shouldRevalidateCachedTarget(n,a,h)){let m=await My(this.host.requiresFreshExtractionForCachedTarget()?(f)=>this.host.refreshViewHierarchy(f,p.screenSize,c,!0):this.host.tapVerificationRefresh({screenSize:p.screenSize,signal:c}),this.host.timer(),c,{timeoutMs:Math.min(Fi,d?.requestDeadlineMs===void 0?Fi:d.requestDeadlineMs-this.host.timer().now()),context:"while revalidating a cached observation",platform:this.platform()});this.host.replaceObservationHierarchy(p,m,!0),h=await this.host.searchForElement(s,p,c)}if(n.searchUntilStats=h.stats,this.host.replaceObservationHierarchy(p,h.viewHierarchy,h.refreshedFromDevice),a.viewHierarchy=h.viewHierarchy,!h.selection.element){if(h.visibilityError)throw h.visibilityError;await this.host.handleElementNotFound(s,{observeResult:p,containerFound:h.containerFound,signal:c,selection:h.selection})}return h}async prepareSelection(n,a,s){let{options:c,signal:l,perf:d}=n,{observeResult:p,activationWarnings:h}=a,m=await this.host.refreshEnsureCheckedSelection(c,p,s.selection,l);a.viewHierarchy=m.viewHierarchy,n.preTapHierarchy=a.viewHierarchy;let f=m.selection,T=f.element,y=this.host.buildSelectedElementMetadata(f),v=this.host.ensureCheckedBeforeTap(c,T,y,s.stats);if(v)return d.end(),{result:v};if(c.subtext)return{result:await this.host.activateSubtextPhase({options:c,subtext:c.subtext,element:T,viewHierarchy:a.viewHierarchy,selectedElement:y,searchUntil:s.stats,activationWarnings:h,signal:l})};let b=c.action,g=this.host.geometry().getElementCenter(T),E=this.host.getLongPressDuration(c),S={...a,searchOutcome:s,element:T,finalSelection:f,selectedElementMetadata:y,action:b,initialTapPoint:g,longPressDuration:E,tapOptions:{...c,action:b},tapElement:T,usedParent:!1},R=this.prepareFocusTarget(n,S);if(R)return{result:R};return S.tapOptions={...c,action:S.action},{target:S}}prepareFocusTarget(n,a){let{options:s,perf:c}=n,{searchOutcome:l}=a,{initialTapPoint:d}=a;if(a.action==="focus"){if(!Pn(a.element))return c.end(),{success:!1,action:a.action,element:a.element,selectedElement:a.selectedElementMetadata,searchUntil:l.stats,error:`Cannot focus ${D(a.element,s)} because it is not an editable input`};n.focusTarget=a.element;let p=l.selection.matchedElement;if(p&&p!==a.element)n.focusLabelText=p.text;if(Ta(a.element))return e.info("Element is already focused, no action needed"),c.end(),H({success:!0,action:a.action,element:a.element,selectedElement:a.selectedElementMetadata,searchUntil:l.stats,wasAlreadyFocused:!0,focusChanged:!1,focusVerified:!0,x:d.x,y:d.y},z(a.viewHierarchy,a.element,this.platform()));a.action="tap",n.effectiveAction="tap"}return}async stabilizeTarget(n,a){let{options:s,signal:c,perf:l,requestedAction:d}=n,{observeResult:p,activationWarnings:h,searchOutcome:m}=a;a.isAccessibilityServiceEnabled??=await this.host.strategy().isAccessibilityServiceEnabled((y)=>h.push(y));let f=a.isAccessibilityServiceEnabled,T=this.host.resolveTapTargetElement(a.element,a.viewHierarchy,a.action,{requireResourceId:f,scoped:s.container!==void 0});if(a.tapElement=T.element,a.usedParent=T.usedParent,this.host.strategy().shouldRunPreTapStability(s)){let y=await this.host.resolveAndroidStableTapTargetAfterRefreshes(s,p,a.action,{requireResourceId:f,signal:c});if(!y.ok)return l.end(),{success:!1,error:y.error};if(this.host.replaceObservationHierarchy(p,y.viewHierarchy,!0),y.selection.captureId)p.observationId=y.selection.captureId;a.viewHierarchy=y.viewHierarchy,n.preTapHierarchy=a.viewHierarchy,a.tapElement=y.tapElement,a.finalSelection=y.selection,a.usedParent=y.usedParent,a.selectedElementMetadata=this.host.rebuildSelectedElementMetadataAfterStability(a.selectedElementMetadata,y.selection);let v=y.selection.element;if(!v)return l.end(),{success:!1,error:"Android tap aborted: refreshed stable target selection was empty"};if(d==="focus")n.focusTarget=v,n.focusLabelText=y.selection.matchedElement!==v?y.selection.matchedElement?.text:void 0;let b=this.host.ensureCheckedBeforeTap(s,v,a.selectedElementMetadata,m.stats);if(b)return l.end(),b}return}async dispatchTarget(n,a,s){let{options:c,requestedAction:l,signal:d,perf:p}=n,{observeResult:h}=a;cr(this.host.strategy(),a.tapElement,a.activationWarnings),this.host.logClickableParentSelection(a.usedParent),a.activationWarnings.push(...Ze(l,a.finalSelection,a.tapElement));let m=await this.host.tapPoints().prototypeTapHierarchy(a.viewHierarchy,a.tapElement,l),{tapPoint:f,warning:T}=this.host.tapPoints().planVisibleTapPoint({options:a.tapOptions,requestedAction:l,observeResult:h,viewHierarchy:m,finalSelection:a.finalSelection,tapElement:a.tapElement});if(T)a.activationWarnings.push(T);let y=a.tapElement.bounds;e.info(`[TapOnElement] Tapping (${f.x}, ${f.y}) on element: text=${JSON.stringify(a.tapElement.text??c.text)}, bounds=${JSON.stringify(y)}, clickable=${a.tapElement.clickable}, usedParent=${a.usedParent}`),n.selectionCapture=await this.host.prepareSelectionCapture(a.action,h,a.tapElement,d);let v=c.retryIfNoChange?this.host.hashViewHierarchy(a.viewHierarchy):null;if(await p.track("executeTap",()=>this.dispatchPlatform(n,a,f,s)),c.ensureChecked!==void 0)n.ensureCheckedTapTimestamp=this.host.timer().now();if(v&&this.host.strategy().retryTapIfNoChange&&a.iosBackend?.backend!=="sdk")await this.host.retryTapIfNoChange(v,f,a.action,{longPressDuration:a.longPressDuration,tapElement:a.tapElement,options:{...this.host.withObservationScreenSize(a.tapOptions,h),displayFence:s},isTalkBackEnabled:a.isAccessibilityServiceEnabled,screenSize:h.screenSize,signal:d,selection:a.finalSelection});return p.end(),H({success:!0,action:a.action,element:a.tapElement,selectedElement:a.selectedElementMetadata,...lr(a.iosBackend),searchUntil:a.searchOutcome.stats,...a.screenReaderNavigation?{screenReaderNavigation:a.screenReaderNavigation}:{},...a.activationWarnings.length?{warnings:a.activationWarnings}:{}},z(a.viewHierarchy,n.focusTarget??a.tapElement,this.platform()))}async dispatchPlatform(n,a,s,c){let{signal:l}=n,{observeResult:d}=a;qI(),await this.host.runPlatformTap({android:async()=>{a.screenReaderNavigation=await this.host.executeAndroidTap(a.action,s,a.longPressDuration,{element:a.tapElement,signal:l,options:{...a.tapOptions,displayFence:c,resolvedHierarchy:a.viewHierarchy,onResolvedElement:(p,h,m)=>{if(a.tapElement=p,a.finalSelection=h??{...a.finalSelection,element:p,matchedElement:p},m)a.viewHierarchy=m,n.preTapHierarchy=m,this.host.replaceObservationHierarchy(d,m,!0);a.selectedElementMetadata=this.host.buildSelectedElementMetadata(a.finalSelection),Object.assign(s,this.host.geometry().getElementCenter(p))},onActivationWarning:(p)=>a.activationWarnings.push(p),onTalkBackActivation:()=>{n.screenReaderActivation={matched:a.finalSelection.matchedElement}}},isTalkBackEnabled:a.isAccessibilityServiceEnabled})},ios:async()=>{let p=this.host.iosSdkBridgeTapper?.()??R7(this.host.device());if(a.iosBackend=await p.tap({action:n.requestedAction==="focus"?"focus":a.action,element:a.tapElement,longPressDurationMs:a.longPressDuration,signal:l})??void 0,a.iosBackend?.backend==="sdk")return;await this.host.executeiOSTap(a.action,s,a.longPressDuration,{element:a.tapElement,isVoiceOverEnabled:a.isAccessibilityServiceEnabled,displayFence:c,signal:l})}})}async confirmFocusAfterTap({result:n,options:a,requestedAction:s,focusTarget:c,focusLabelText:l,preTapHierarchy:d,signal:p}){if(s!=="focus"||!n.success||n.wasAlreadyFocused)return;let h=c??n.element;if(n.focusVerified=await this.host.verifyFocusAfterTap(n,(m)=>this.host.verifyFocusedInputTarget(a,h,m,{labelText:l,selectedIndex:n.selectedElement?.indexInMatches,preTapHierarchy:d}),p),!n.focusVerified)n.success=!1,n.error=`Failed to confirm focus on editable input ${D(h,a)}: the focused field could not be matched to the target`}assertLongPressWithinRequestBudget(n,a){if(n.action==="longPress")DB(this.host.getLongPressDuration(n),a?.requestDeadlineMs===void 0?void 0:a.requestDeadlineMs-this.host.timer().now())}predictionToolArgs(n){return{text:n.text,textAny:n.textAny,id:n.elementId,action:n.action,duration:n.duration,container:n.container,searchUntil:n.searchUntil,selectionStrategy:n.selectionStrategy,accessibilityLink:n.accessibilityLink,subtext:n.subtext,platform:this.host.device().platform}}readScopeFailureResult(n,a,s,{searchUntilStats:c,debugContext:l}){let d=r(s);return V(n,{success:!1,action:a,error:`Failed to perform tap on element: ${d}`,element:{bounds:{left:0,top:0,right:0,bottom:0}},...c?{searchUntil:c}:{},...s instanceof t&&s.containerFailure?{containerFailure:s.containerFailure}:{},...l?{debug:{elementSearch:l}}:{}},s)}longClickAdvertisement(n){if(this.host.device().platform!=="android"||!Array.isArray(n?.actions))return{};return{longClickAdvertised:Io(n.actions,"long_click")}}detectLongPressMetadata(n,a){return this.host.longPressMetadataDetector().detect(n,a)}}function lr(n){if(!n)return{};return n.backend==="sdk"?{backend:"sdk"}:{backend:"xctest",fallbackReason:n.fallbackReason}}function q(n){return n["resource-id"]==="com.android.documentsui:id/item_root"||n["resource-id"]==="com.google.android.documentsui:id/item_root"}function X(n,a,s){if(n.success&&s!=="longPress")a?.onTalkBackActivation?.()}class he{host;constructor(n){this.host=n}async executeAndroidTap(n,a,s,{element:c,signal:l,options:d,isTalkBackEnabled:p}){let{x:h,y:m}=a,{displayFence:f,resolvedHierarchy:T,onActivationWarning:y}=d??{},v=typeof p==="boolean"?p:await this.host.strategy().isAccessibilityServiceEnabled(d?.onActivationWarning);if(c["hierarchy-source"]==="uiautomator"){await this.host.executeAndroidTapWithCoordinates(n,h,m,s,c,l,!0,{displayFence:f,onActivationWarning:y});return}if(es(d)){await this.host.executeScopedAndroidTap({action:n,x:h,y:m,durationMs:s,element:c,signal:l,talkBackEnabled:v,fence:f,onActivationWarning:d?.onActivationWarning,onTalkBackActivation:d?.onTalkBackActivation});return}if(v)return this.host.executeAndroidTapWithAccessibility(n,h,m,c,s,d,l);await this.host.executeAndroidTapWithCoordinates(n,h,m,s,c,l,!1,{displayFence:f,resolvedHierarchy:T,onActivationWarning:y});return}async executeScopedAndroidTap(n){let{action:a,x:s,y:c,durationMs:l,element:d,signal:p,talkBackEnabled:h,fence:m}=n;if(h){let f=this.host.talkBackDriverFactory().createDriver(this.host.device()),T=a==="tap"?await this.host.talkBackStrategy().executePreciseTap(s,c,f,m):await this.host.talkBackStrategy().executeCoordinateFallback({x:s,y:c},a,l,{driver:f,fenceOptions:{displayFence:m}});if(T.success){X(T,n,a),this.host.reportTalkBackActivationWarning(T,n,a);return}await this.host.executeAndroidTapWithCoordinates(a,s,c,l,d,p,!0,{displayFence:m,onActivationWarning:n.onActivationWarning}),this.host.reportTalkBackActivationWarning(T,n,a);return}await this.host.executeAndroidTapWithCoordinates(a,s,c,l,d,p,!0,{displayFence:m,onActivationWarning:n.onActivationWarning})}async executeAndroidTapWithCoordinates(...[n,a,s,c,l,d,p=!1,h={}]){let m=h.displayFence;if(n==="tap"){if(!p&&q(l)&&await this.host.tryDocumentsUiRowActivation(l,d))return;await this.host.dispatchCoordinateTapOrAdbFallback(a,s,l,{signal:d,fenceOptions:{displayFence:m}})}else if(n==="longPress")await this.host.executeAndroidLongPress(a,s,c,{element:l,signal:d,skipSemanticAction:p,...h});else if(n==="doubleTap")await Eh({client:q(l)?void 0:this.host.accessibilityService(),point:{x:a,y:s},timer:this.host.timer(),signal:d,assertCurrent:()=>m?.assertCurrent(),onWarning:h.onActivationWarning,tap:()=>this.host.dispatchCoordinateTapOrAdbFallback(a,s,l,{signal:d,fenceOptions:{displayFence:m}})})}async tryDocumentsUiRowActivation(n,a){o(a);let s=rs(n);if(!Io(n.actions,"click")||!s||s.uniqueId===void 0&&(s.collectionRow===void 0||s.collectionColumn===void 0))return!1;try{if(!await this.host.accessibilityService().supportsNodeActionSelectors(void 0,a))return!1;o(a);let c=await this.host.accessibilityService().requestNodeAction("click",s,{signal:a});return o(a),c.success}catch(c){if(c instanceof _e)throw c;return o(a),e.warn(`[TapOnElement] DocumentsUI row activation failed: ${c}`),!1}}async dispatchCoordinateTapOrAdbFallback(n,a,s,{signal:c,fenceOptions:l={}}={}){let d=l.displayFence;if(o(c),!q(s)){d?.assertCurrent(),await YS(this.host.accessibilityService(),this.host.adb(),{x:n,y:a},{durationMs:10,options:{signal:c}});return}e.info(`[TapOnElement] Using ADB input recovery for DocumentsUI row at (${n}, ${a})`),d?.assertCurrent(),await dc(this.host.adb(),`tap ${n} ${a}`,void 0,{signal:c})}resolveEnsureCheckedRetryTarget(n,a,s,c){let l=this.host.findElementInHierarchy(n,a).selection.element;if(!l||!st(l.checkable))return e.warn("[TapOnElement][retryIfNoChange] Toggle not found in fresh hierarchy; skipping retry"),null;if(st(l.checked)===n.ensureChecked)return e.info("[TapOnElement][retryIfNoChange] Toggle reached requested checked state"),null;return this.host.resolveTapTargetElement(l,a,s,{requireResourceId:c,scoped:n.container!==void 0}).element}withRetryScreenSize(n,a){return{...n,screenSizeOptions:n.screenSizeOptions??{observationScreenSize:a}}}refreshedRetrySelection(n,a,s,c){if(n.text||n.textAny?.length||n.elementId||n.testTag)return this.host.findElementInHierarchy(n,a).selection;return c??{element:s,indexInMatches:-1,totalMatches:1,strategy:"first"}}resolveRefreshedRetryTarget(n,a,s,c){let{isTalkBackEnabled:l,selection:d,previousTarget:p}=c;if(n.ensureChecked!==void 0)return this.host.resolveEnsureCheckedRetryTarget(n,a,s,l);if(d.element)return this.host.resolveTapTargetElement(d.element,a,s,{requireResourceId:l,scoped:n.container!==void 0}).element;if(n.text||n.textAny?.length||n.elementId||n.testTag)return e.warn("[TapOnElement][retryIfNoChange] Target not found in refreshed hierarchy; skipping retry"),null;return p}async retryTapIfNoChange(n,a,s,{longPressDuration:c,tapElement:l,options:d,isTalkBackEnabled:p,screenSize:h,signal:m,selection:f}){let T=await d0(this.host.timer(),this.host.tapVerificationRefresh({refresh:d.verification?.refresh,screenSize:h,signal:m}),(R)=>this.host.hashViewHierarchy(R),{preTapHash:n,signal:m});if(T.status==="unavailable"){e.warn(`[TapOnElement][retryIfNoChange] Tap hierarchy unreadable or could not be fingerprinted (post-tap refresh budget ${VI}ms) \u2014 skipping retry`);return}if(T.status==="changed"){e.info("[TapOnElement][retryIfNoChange] Hierarchy changed after tap \u2014 tap registered");return}let y=this.host.withRetryScreenSize(d,h),v=this.host.refreshedRetrySelection(y,T.hierarchy,l,f),b=this.host.resolveRefreshedRetryTarget(y,T.hierarchy,s,{isTalkBackEnabled:p,selection:v,previousTarget:l});if(!b)return;let g=this.host.getScreenSizeFromHierarchy(T.hierarchy,y.screenSizeOptions),E=this.host.visibleTapBounds(v.element?v:f??{...v,element:b},T.hierarchy,{screenSize:g,options:y,tapTarget:b});if(!E){e.warn("[TapOnElement][retryIfNoChange] Refreshed target has no visible tap area; skipping retry");return}let S=P(a,E)?a:this.host.resolveVisibleTapPoint(b,T.hierarchy,E,{options:d,screenSize:g});if(!S){e.warn("[TapOnElement][retryIfNoChange] Refreshed target has no unobstructed tap point; skipping retry");return}if(e.warn(`[TapOnElement][retryIfNoChange] Hierarchy unchanged after tap at (${S.x}, ${S.y}) \u2014 ghost tap detected, retrying`),await this.host.timer().sleep(c0),d.verification?.dispatch){await d.verification.dispatch(S);return}await this.host.executeAndroidTap(s,S,c,{element:b,signal:m,options:{...d,resolvedHierarchy:T.hierarchy},isTalkBackEnabled:p})}isScreenReaderNavigationEnabled(n){return Boolean(n?.screenReaderNavigation)||this.host.featureFlags().isEnabled("screen-reader-navigation")}reportTalkBackActivationWarning(n,a,s="tap"){if(s==="longPress"||n.method==="accessibility-action")return;let c=n.success?n.warnings??[kV]:[n.unsupportedCapability==="tap_double_v1"?"TalkBack activation is unconfirmed: the connected device service does not support the single-gesture double tap (tap_double_v1). Update CtrlProxy. The plain coordinate tap path was used instead. Observe the result before retrying.":"TalkBack activation is unconfirmed: the TalkBack gesture failed, so the plain coordinate tap path was used instead. Observe the result before retrying."];for(let l of c)a?.onActivationWarning?.(l)}talkBackTargetContext(n,a,s){let c,l,d=n&&[n.text,n.textAny,n.elementId,n.testTag].some(Boolean);return{hierarchy:Zt(n?.resolvedHierarchy),reResolve:d?(p)=>{let h=this.host.finder().selectElementInHierarchy(n,gi(p,n.layer)).selection;return c=h,l=p,h.element?this.host.resolveTapTargetElement(h.element,p,a,{requireResourceId:!0,scoped:n.container!==void 0}).element:null}:void 0,onResolvedElement:(p)=>s(p,c,l)}}async executeAndroidTapWithAccessibility(...[n,a,s,c,l,d,p]){let h=this.host.readOptionalDisplayFence(d),m=this.host.talkBackDriverFactory().createDriver(this.host.device()),f,T=this.host.talkBackTargetContext(d,n,(b,g,E)=>{c=b;let S=this.host.geometry().getElementCenter(b);a=S.x,s=S.y,d?.onResolvedElement?.(b,g,E)});if(n==="longPress"){let b=await this.host.talkBackStrategy().executeLongPress({x:a,y:s},l,c,{driver:m,fenceOptions:{displayFence:h,...T}});if(!b.success){if(b.semanticActionFailure)throw new t(`Semantic long press failed for the selected element: ${b.error??"unknown error"}`);e.warn(`[TapOnElement] Long press accessibility methods failed (${b.error}), falling back to ADB tap at (${a}, ${s})`),await this.host.executeAndroidTapWithCoordinates(n,a,s,l,c,p,!0,{displayFence:h})}return}if(this.host.isScreenReaderNavigationEnabled(d)){let b=await this.host.talkBackStrategy().executeTap(this.host.device().deviceId,c,m,{fence:h,signal:p});if(b.success)return X(b,d,n),this.host.reportTalkBackActivationWarning(b,d,n),b.screenReaderNavigation;e.warn(`[TapOnElement] Focus navigation unavailable (${b.error}); nothing was dispatched, falling back to coordinate-based tap at (${a}, ${s})`),f=b.screenReaderNavigation}else if(n==="tap"){let b=await this.host.talkBackStrategy().executeDirectActivation(c,m,T);if(b.success){X(b,d,n);return}e.warn(`[TapOnElement] Direct accessibility activation failed (${b.error}), falling back to coordinate-based tap at (${a}, ${s})`)}if(q(c))return await this.host.executeAndroidTapWithCoordinates(n,a,s,l,c,p,!1,{displayFence:h}),f;let y=n,v=y==="tap"?await this.host.talkBackStrategy().executePreciseTap(a,s,m,h):await this.host.talkBackStrategy().executeCoordinateFallback({x:a,y:s},y,l,{driver:m,fenceOptions:{displayFence:h}});if(!v.success)e.warn(`[TapOnElement] Accessibility coordinate tap failed (${v.error}), falling back to ADB tap at (${a}, ${s})`),await this.host.executeAndroidTapWithCoordinates(n,a,s,l,c,p,!1,{displayFence:h});return X(v,d,n),this.host.reportTalkBackActivationWarning(v,d,n),f}async executeiOSTap(n,a,s,{element:c,isVoiceOverEnabled:l,...d}={}){let{x:p,y:h}=a;if(l&&c){await this.host.executeIOSTapWithVoiceOver(n,c,{x:p,y:h},{durationMs:s,fenceOptions:d});return}let m=()=>this.host.executeiOSTapWithCoordinates(n,p,h,{durationMs:s,fenceOptions:d});if(l)await qA(m);else await m()}async executeiOSTapWithCoordinates(n,a,s,{durationMs:c,fenceOptions:l={}}){let{displayFence:d,signal:p}=l,h=n==="longPress"?c:50,m=_.getInstance(this.host.device());if(n==="doubleTap")d?.assertCurrent(),await XS(m,{x:a,y:s},{durationMs:h,options:{signal:p}}),_.getExistingInstance(this.host.device().deviceId)?.invalidateCache();else d?.assertCurrent(),await JS(m,{x:a,y:s},{durationMs:h,options:{signal:p}}),_.getExistingInstance(this.host.device().deviceId)?.invalidateCache()}executeIOSTapWithVoiceOver(n,a,s,{durationMs:c,fenceOptions:l}){let{x:d,y:p}=s;return oQ({device:this.host.device(),action:n,element:a,point:{x:d,y:p},durationMs:c,fenceOptions:l??{},coordinateTap:(h)=>this.host.executeiOSTapWithCoordinates(n,d,p,{durationMs:c,fenceOptions:h})})}readOptionalDisplayFence(n){return n?.displayFence}getLongPressDuration(n){if(gF(n.duration),typeof n.duration==="number"&&n.duration>0)return n.duration;return this.host.strategy().longPressDurationMs}async executeAndroidLongPress(n,a,s,{element:c,signal:l,skipSemanticAction:d=!1,...p}){let h=p.displayFence;if(o(l),!d){let m=rs(c);if(m&&await this.host.trySemanticAndroidLongPress(c,m,l,p))return}await a0({adb:this.host.adb(),x:n,y:a,durationMs:s,signal:l,assertCurrent:h?()=>h.assertCurrent():void 0,logTag:"TapOnElement"})}throwIfLongPressInterrupted(n,a,s){Yx(n,a,s)}semanticAndroidLongPressTargetError(n,a,s={}){let c=Zt(s.resolvedHierarchy);return _h(n,{supportsNodeActionSelectors:()=>this.host.accessibilityService().supportsNodeActionSelectors(),getAccessibilityHierarchy:()=>c?Promise.resolve(c):this.host.accessibilityService().getAccessibilityHierarchy(void 0,{skipWaitForFresh:!0,disableAllFiltering:!0,signal:a})})}async trySemanticAndroidLongPress(n,a,s,c={}){let l=Zs(a),d=await this.host.semanticAndroidLongPressTargetError(a,s,c);if(o(s),d)return e.info(`[TapOnElement] ${d}; using coordinate long press`),!1;try{let p=l?await this.host.accessibilityService().requestNodeAction("long_click",a):await this.host.accessibilityService().requestAction("long_click",a.resourceId);if(p.success)return!0;let h=await nT({advertised:Io(n.actions,"long_click"),error:p.error,needsNodeSelector:l,selected:n,readHierarchy:()=>this.host.accessibilityService().getAccessibilityHierarchy(void 0,{skipWaitForFresh:!0,disableAllFiltering:!0,signal:s})});if(o(s),h)throw new t(`Semantic long press failed for the selected element: ${p.error??"unknown error"}`);e.warn(`[TapOnElement] Accessibility long click failed: ${p.error}`)}catch(p){if(p instanceof t)throw p;e.warn(`[TapOnElement] Accessibility long click error: ${p}`)}return!1}}var pr=3,hr=new we;function tt(n){return typeof n==="string"&&n.trim()!==""?n.trim():void 0}function yr(n,a){let s=n.bounds;if(!s||s.right<=s.left||s.bottom<=s.top)return!1;if(!a||a.width<=0||a.height<=0)return!0;return s.right>0&&s.bottom>0&&s.left<a.width&&s.top<a.height}function Tr(n){let a=tt(n.properties["hint-text"]),s=tt(n.displayedLabel),c=s??a,l=s!==void 0&&a!==void 0&&a!==s?a:void 0;return{...n.elementId!==void 0?{elementId:n.elementId}:{},...c!==void 0?{label:c}:{},...l!==void 0?{sublabel:l}:{}}}function rt(n,a){if(!n)return[];let s=new Set;return hr.project(n).filter((c)=>{if(s.has(c.source))return!1;return s.add(c.source),c.affordances.includes("input")&&!du(c)&&yr(c,a)}).toSorted((c,l)=>c.windowRank-l.windowRank||(c.bounds?.top??0)-(l.bounds?.top??0)||(c.bounds?.left??0)-(l.bounds?.left??0)).slice(0,pr).map(Tr)}function me(n,a){return a===void 0?void 0:`${n} ${JSON.stringify(a)}`}function it(n){return`On-screen inputs: ${n.map((s)=>`{${[me("elementId",s.elementId),me("label",s.label),me("sublabel",s.sublabel)].filter((c)=>c!==void 0).join(", ")}}`).join("; ")}. Select one by its elementId or label.`}function nt(n){return 2}var vr=/progress_bar|loading_indicator|progress_indicator|shimmer|content_loading/i,br=/ProgressBar$|ProgressIndicator|ShimmerFrameLayout|ContentLoadingProgressBar/i;function at(n,a){let s=[...a.extractRootNodes(n),...a.extractWindowRootNodes(n,"topmost-first")],c=!1;for(let l of s)if(a.traverseNode(l,(d)=>{if(c)return;let p=a.extractNodeProperties(d),h=String(p["resource-id"]??p.resourceId??""),m=String(p.class??p.className??"");if(h.length>0&&vr.test(h)){c=!0;return}if(m.length>0&&br.test(m))c=!0}),c)break;return c}var ct=2500,lt=8,fe=1e4,Sr=32,Er=1000,ot=12,Or=150;function Rr(n,a,s){let c=s.viewHierarchy?n.findElementInHierarchy(a,s.viewHierarchy).selection:null;return c?.matchedElement??c?.element??null}function wr(n,a,s){if(++n.iterations>Er)return!1;let c=a.now()-n.startTime-n.noHierarchyTimeMs,l=n.refindAttempt>=n.minProductivePolls&&c>=n.budgetMs,d=n.best!==null&&n.consecutiveStable>0&&n.consecutiveStable<s;if(!n.firstIteration&&n.consecutiveNoHierarchy===0&&l)if(d&&n.deadlineGracePolls>0)n.deadlineGracePolls--;else return!1;return!0}function Ar(n,a,s){if(n.noHierarchyTimeMs+=a.now()-s,n.consecutiveNoHierarchy++,e.warn(`[TapOnElement] Android pre-tap refresh returned no hierarchy (consecutive: ${n.consecutiveNoHierarchy}/${ot}, refind attempt: ${n.refindAttempt})`),n.consecutiveNoHierarchy>=ot)return{ok:!1,error:`Android tap aborted: accessibility service was unreachable for ${n.consecutiveNoHierarchy} consecutive attempts (ctrl-proxy WebSocket unresponsive). The device may be under heavy load or the accessibility service may need reconnection.`};n.consecutiveStable=0,n.prevBounds=null;return}function Pr(n,a,s){if(at(s,n.elementParser)&&a.budgetMs<fe)a.budgetMs=fe,a.minProductivePolls=Sr,e.info(`[TapOnElement] Android pre-tap: loading/progress indicators present; extending refind budget to ${a.budgetMs}ms / ${a.minProductivePolls} polls`)}function kr(n,a,s,{selection:c,element:l}){let{original:d,options:p,observeResult:h}=a;if(d?.["resource-id"]&&d["resource-id"]!==(c.matchedElement??l)["resource-id"])return"Stale tap target: the fresh capture matched a different native ID. Observe again before acting.";return p.elementId!==void 0&&p.elementId===d?.["view-id"]?n.staleSyntheticTarget(d,h.viewHierarchy,s):void 0}function xr({state:n,freshHierarchy:a,selection:s,refreshed:c,stableMatchesRequired:l}){let d=c.element.bounds;if(d===void 0||d===null){n.consecutiveStable=0,n.prevBounds=null;return}if(n.prevBounds!==null&&Ms(n.prevBounds,d,A))n.consecutiveStable++;else n.consecutiveStable=1;n.prevBounds=d;let p=Rn(a)?.captureId;if(n.best={viewHierarchy:a,tapElement:c.element,usedParent:c.usedParent,selection:p?{...s,captureId:p}:s},n.consecutiveStable>=l)return e.info(`[TapOnElement] Android tap target stable after ${n.refindAttempt} refresh(es) (bounds matched on last ${l} consecutive re-find(s), \u03B5=${A}px)`),{ok:!0,...n.best};return}function Cr(n,a,s,c){s.consecutiveNoHierarchy=0,s.refindAttempt++,Pr(n,s,c);let l=n.findElementInHierarchy(a.options,c);if(!l.selection.element){e.warn(`[TapOnElement] Android pre-tap refresh attempt ${s.refindAttempt} did not re-find tap target`),s.consecutiveStable=0,s.prevBounds=null;return}let d=kr(n,a,c,{selection:l.selection,element:l.selection.element});if(d)return{ok:!1,error:d};let p=n.resolveTapTargetElement(l.selection.element,c,a.action,{requireResourceId:a.requireResourceId,scoped:a.options.container!==void 0});return xr({state:s,freshHierarchy:c,selection:l.selection,refreshed:p,stableMatchesRequired:a.stableMatchesRequired})}async function dt(n,a){let{observeResult:s,action:c,requireResourceId:l,signal:d}=a,p=n.withObservationScreenSize(a.options,s),h=nt(p),m=Rr(n,p,s),f={options:p,observeResult:s,action:c,requireResourceId:l,original:m,stableMatchesRequired:h},T={prevBounds:null,consecutiveStable:0,best:null,startTime:n.timer.now(),noHierarchyTimeMs:0,budgetMs:ct,minProductivePolls:lt,consecutiveNoHierarchy:0,refindAttempt:0,firstIteration:!0,iterations:0,deadlineGracePolls:h};while(!0){if(o(d),!wr(T,n.timer,h))break;if(!T.firstIteration){let g=T.consecutiveNoHierarchy>0,E=g?q6:Or;if(await n.timer.sleep(E),g)T.noHierarchyTimeMs+=E}T.firstIteration=!1;let y=n.timer.now(),v=await n.tapVerificationRefresh({refresh:p.verification?.refresh,screenSize:s.screenSize,signal:d})(s0);if(!v){let g=Ar(T,n.timer,y);if(g)return g;continue}let b=Cr(n,f,T,v);if(b)return b}return{ok:!1,error:"Android tap aborted: could not re-find the target in the accessibility hierarchy with stable bounds after repeated refreshes (refusing tap using pre-observe coordinates). The UI may still be updating (list, keyboard, loading overlay, or animation)."}}var Z=2500,ee=150,pt=1000;class ye{deps;constructor(n){this.deps=n}async waitForPostTapChange(n,a,s){let c=this.deps.timer.now(),l=null,d=0,p={},h=(b)=>{let g=this.deps.deriveTapEffect(n,b);if(g?.screenChanged===!0&&g.basis!=="viewHierarchy changed")return{matched:!0};let E=this.deps.timer.now();if(g?.screenChanged===!0&&p.seenAt===void 0)p.observation=b,p.seenAt=E;if(p.seenAt===void 0)return{matched:!1};let S=this.deps.hashViewHierarchy(b.viewHierarchy??null);if(S===null||S!==l)return l=S,d=E,{matched:!1};return{matched:E-d>=pt}},m={readBackStackEachPoll:!0,timeoutMs:Z,pollMs:ee,signal:s,initialMinTimestampMs:On(a.viewHierarchy),skipWaitForFresh:!0,requireFreshExtraction:!0},f=await this.deps.waitForCondition().execute(h,m),T=p.observation??a;if(f.timedOut&&!f.screenOff&&p.seenAt!==void 0){let g=Math.min(c+2*Z,p.seenAt+Z)-this.deps.timer.now();if(g>0)o(s),f=await this.deps.waitForCondition().execute(h,{...m,timeoutMs:g,initialMinTimestampMs:On(this.resolveSettleTimeoutObservation(n,T,f).viewHierarchy)})}let y=this.resolveSettleTimeoutObservation(n,T,f),v=this.deps.deriveTapEffect(n,f.screenOff?T:y);if(!f.matched&&v?.screenChanged!==!0)return{effect:v,observation:a};return{effect:v,observation:{...y,gfxMetrics:y.gfxMetrics??a.gfxMetrics,perfTiming:y.perfTiming??a.perfTiming}}}async settleHierarchyOnlyChange(n,a,s){let c=null,l=0,d=await this.deps.waitForCondition().execute((f)=>{let T=this.deps.deriveTapEffect(n,f);if(this.deps.compareActiveWindow(n,f)?.screenChanged===!0||T?.basis==="screenIdentity changed")return{matched:!0};let y=this.deps.hashViewHierarchy(f.viewHierarchy??null),v=this.deps.timer.now();if(y===null)return c=null,{matched:!1};if(y!==c)return c=y,l=v,{matched:!1};return{matched:v-l>=pt}},{readBackStackEachPoll:!0,timeoutMs:Z,pollMs:ee,signal:s,initialMinTimestampMs:On(a.viewHierarchy),skipWaitForFresh:!0,requireFreshExtraction:!0}),p=this.resolveSettleTimeoutObservation(n,a,d);return{effect:d.screenOff===!0?{screenChanged:!0,basis:"viewHierarchy changed"}:this.deps.deriveTapEffect(n,p),observation:{...p,gfxMetrics:p.gfxMetrics??a.gfxMetrics,perfTiming:p.perfTiming??a.perfTiming}}}resolveSettleTimeoutObservation(n,a,s){let c=s.observation,l=s.screenOff===!0;if(!s.timedOut||l)return c;let d=a.freshness?.isFresh!==!1&&this.deps.deriveTapEffect(n,a)?.screenChanged===!0,p=c.freshness?.isFresh===!1||this.deps.hashViewHierarchy(c.viewHierarchy??null)===null;return d&&p?a:c}}var Fr=1500,ut=50,Dr=1500,Ir=100,Hr=12000;function Vr(n,a,s){let c=n.action==="focus"&&a?rt(a.viewHierarchy,a.screenSize):[];return c.length>0?{baseError:`${s}. ${it(c)}`,reason:"not-found-inputs-listed"}:{baseError:s,reason:"not-found"}}class Te{host;constructor(n){this.host=n}getSearchUntilDuration(n){return mF(n.searchUntil?.duration,{defaultMs:Dr,minMs:Ir,maxMs:Hr})}hashViewHierarchy(n){return mn(n)}deriveTapEffect(n,a){return this.host.deriveInteractionEffect(n,a)}async deriveTapEffectAfterPostTapObservation(n,a,s,c){return this.host.postTapEffect().deriveEffectAfterPostTapObservation(n,a,s,c)}enforceFreshnessConsistencyWithEffect(n,a){this.host.postTapEffect().enforceFreshnessConsistency(n,a)}replaceObservationHierarchy(n,a,s){this.host.postTapEffect().replaceObservationHierarchy(n,a,s)}logClickableParentSelection(n){if(n)e.info("[TapOnElement] Using clickable parent for non-clickable element")}async prepareSelectionCapture(n,a,s,c){return this.host.selectionStateTracker().prepare({action:n,observation:a,element:s,signal:c})}withObservationScreenSize(n,a){return{...n,screenSizeOptions:{observationScreenSize:a.screenSize,display:a.viewHierarchy}}}findElementInHierarchy(n,a){a=gi(a,n.layer);try{return this.host.finder().selectElementInHierarchy(n,a)}catch(s){if(n.action!=="focus"||!(s instanceof t)||s instanceof w||!es(n)&&n.index===void 0||!this.host.finder().isContainerAvailable(a,n.container))throw s;return this.host.finder().classifyFocusSelectionFailure(n,a,s)}}verifyFocusedInputTarget(n,a,s,c={}){return this.host.focusVerifier().verify(n,a,s,c)}invisibleMatchFailure(...n){return this.host.tapPoints().invisibleMatchFailure(...n)}resolveTapPoint(...n){return this.host.tapPoints().resolveTapPoint(...n)}resolveContainerElement(...n){return this.host.finder().resolveContainerElement(...n)}visibleTapBounds(...n){return this.host.tapPoints().visibleTapBounds(...n)}resolveVisibleTapPoint(...n){return this.host.tapPoints().resolveVisibleTapPoint(...n)}async verifyFocusAfterTap(n,a,s){if(a(n.observation))return!0;let c=n.observation;if(!this.host.strategy().settlesFocusChangeAfterTap||!c)return!1;let l=this.host.timer().now()+Fr;while(this.host.timer().now()<l){await this.host.timer().sleep(ee),o(s);let d=await this.host.refreshViewHierarchy(l-this.host.timer().now(),c.screenSize,s,!0);if(!d)continue;let p={...c};if(this.host.replaceObservationHierarchy(p,d,!0),a(p))return n.observation=p,!0}return!1}prepareViewHierarchyForResponse(n,a){if(l0(M.isRawElementSearchEnabled(),n))return n;return this.host.strategy().prepareViewHierarchyForResponse(n,this.host.viewHierarchy(),a)??n}async refreshViewHierarchy(n,a,s,c=!1){if(o(s),n<=0)return null;let l=this.host.renderedDisplayGeneration()(this.host.device().deviceId)??this.host.displayTransitionReader().identityRevision(this.host.device().deviceId),d;try{d=(await this.host.hierarchyCapture().capture({freshness:"fresh",...c?{requireFreshExtraction:!0}:{},searchRaw:M.isRawElementSearchEnabled(),timeoutMs:n,signal:s})).hierarchy}catch(p){if(p instanceof _e)throw p;return o(s),e.warn(`[TapOnElement] Fresh capture failed: ${r(p)}`),null}if(ys(a)&&this.host.strategy().verifiesRefreshedDisplay)await this.checkRefreshedDisplay(d,a,l,s);return d}tapVerificationRefresh(n){return n.refresh??((a)=>this.host.refreshViewHierarchy(a,n.screenSize,n.signal))}async checkRefreshedDisplay(n,a,s,c){let l=this.host.getScreenSizeFromHierarchy(n);if(!l||l.width===a.width&&l.height===a.height&&(this.host.device().displays?.panels.length??0)<2)return;let d=await this.refreshedDisplay(n,c),p=this.host.refreshedDisplayTransitions().checkIdentity(this.host.device().deviceId,d),h=this.host.refreshedDisplayTransitions().record(this.host.device().deviceId,{display:d,screenSize:l});if(p||h)throw this.host.staleDisplay(s)}async refreshedDisplay(n,a){let s=new fr(this.host.timer()),c=await s.panelForLogicalId(this.host.device(),this.host.adb(),n.displayId,{signal:a,identity:{panelUniqueId:n.panelUniqueId,panelFingerprint:n.panelFingerprint},allowProbe:!1}),l=await s.resolve(this.host.device(),this.host.adb(),a),d=c??this.host.device().displays?.panels.find((p)=>p.key===l.display.key);return{...l.display,key:d?.key??l.display.key,role:d?.role??l.display.role,posture:await s.posture(this.host.device(),this.host.adb(),a)}}async readFreshHierarchy(n,a,s,c=!1){o(s);let l=Math.max(0,n);if(l===0)return null;return u0({device:this.host.device(),adb:this.host.adb(),timer:this.host.timer(),androidService:this.host.accessibilityService(),viewHierarchy:this.host.viewHierarchy(),prepareForResponse:(d,p)=>this.prepareViewHierarchyForResponse(d,p),actionLabel:"tap on elements"},{timeoutMs:l,screenSize:a,signal:s,forceCapture:c})}resolveAndroidStableTapTargetAfterRefreshes(n,a,s,{requireResourceId:c,signal:l}){return dt({timer:this.host.timer(),elementParser:this.host.elementParser(),findElementInHierarchy:(d,p)=>this.host.findElementInHierarchy(d,p),resolveTapTargetElement:(d,p,h,m)=>this.host.resolveTapTargetElement(d,p,h,m),staleSyntheticTarget:(d,p,h)=>this.host.staleSyntheticTarget(d,p,h),tapVerificationRefresh:(d)=>this.host.tapVerificationRefresh(d),withObservationScreenSize:(d,p)=>this.host.withObservationScreenSize(d,p)},{options:n,observeResult:a,action:s,requireResourceId:c,signal:l})}staleSyntheticTarget(n,a,s){if(!n||n["resource-id"]||!n["view-id"]||!a)return;let c=new we,l=n["view-id"],d=c.project(a).find((f)=>f.nodeKey===l);if(!d)return"Stale tap target: the observed reference is no longer identifiable.";let p=Rn(a)?.captureId??"before-refresh",h=Rn(s)?.captureId??(a===s?p:"after-refresh");return new ar().resolve({id:h,nodes:c.project(s)},{elementId:l},{action:"inspect",ref:{snapshotId:p,nodeKey:l,bounds:d.bounds,label:d.label,nativeId:d.nativeId}}).error}isPrototypeWindowPending(n,a){return n.layer==="prototype"&&a.prototypeSuspended!==!0&&!ra(a)}findElementForSearch(n,a){if(this.isPrototypeWindowPending(n,a))return{selection:{element:null,indexInMatches:-1,totalMatches:0,strategy:"first"},containerFound:!1};return this.host.findElementInHierarchy(n,a)}async searchForElement(n,a,s){let c=a.viewHierarchy;if(!c)throw new t("Unable to get view hierarchy, cannot tap on element");let l=this.host.getSearchUntilDuration(n),d=this.host.timer().now(),p=0,h=0,m=0,f,T=this.host.hashViewHierarchy(c),y=c,v=this.host.getScreenSizeFromHierarchy(y,{observationScreenSize:a.screenSize,display:a.viewHierarchy}),b=this.findElementForSearch(this.host.withObservationScreenSize(n,a),y),g=b.selection,E=()=>this.host.invisibleMatchFailure(g,n,y,{screenSize:v}),S=g.element,R=b.containerFound;if(!S&&g.matchedElement)f=E();if(!S||this.host.isElementTapTargetOffScreen(g,y,v,n)){if(S)f=E(),e.warn(`[TapOnElement] Element found but tap target is off-screen, will retry. bounds=${JSON.stringify(S.bounds)}, screen=${v?.width}x${v?.height}`),g={...g,element:null},S=null,m+=1;p=(await p0({timer:this.host.timer(),startTime:d,durationMs:l,intervalMs:ut,pacing:"cadence",maxRequests:Math.ceil(l/ut),discardLateResult:!1,signal:s,fetch:(I)=>this.host.tapVerificationRefresh({refresh:n.verification?.refresh,screenSize:v,signal:s})(I),accept:(I)=>{v=this.host.getScreenSizeFromHierarchy(I,{observationScreenSize:v,display:y}),y=I;let N=this.host.hashViewHierarchy(I);if(N&&N!==T)h+=1,T=N;else if(N&&!T)h+=1,T=N;let Ce=this.findElementForSearch({...n,screenSizeOptions:{observationScreenSize:v,display:y}},I);if(g=Ce.selection,S=g.element,R=R||Ce.containerFound,!S&&g.matchedElement)f=E();if(S&&this.host.isElementTapTargetOffScreen(g,I,v,n))return f=E(),e.warn(`[TapOnElement] Element found but tap target is off-screen, retrying. bounds=${JSON.stringify(S.bounds)}`),g={...g,element:null},S=null,m+=1,!1;return S!==null}})).requestCount}if(this.isPrototypeWindowPending(n,y))gi(y,n.layer);this.reportOffScreenRejections(m,S);let O={durationMs:Math.max(0,Math.round(this.host.timer().now()-d)),requestCount:p,changeCount:h};return{selection:g,viewHierarchy:y,containerFound:R,stats:O,refreshedFromDevice:y!==c,...f&&!S?{visibilityError:f}:{}}}reportOffScreenRejections(n,a){if(n>0&&!a)e.warn(`[TapOnElement] Element was found ${n} time(s) but had no visible tap area. Scroll it into view before retrying.`)}buildSelectedElementMetadata(n){if(!n.element)return;let a=n.element.bounds,s=this.host.geometry().getElementCenter(n.element),c=Uw(n.element)??(typeof n.element.text==="string"&&n.element.text.length>0?n.element.text:typeof n.element["content-desc"]==="string"?n.element["content-desc"]:typeof n.element["ios-accessibility-label"]==="string"?n.element["ios-accessibility-label"]:""),l=typeof n.element["resource-id"]==="string"?n.element["resource-id"]:"",d=typeof n.element["test-tag"]==="string"?n.element["test-tag"]:void 0;return{...n.matchedElement?{matchedElement:n.matchedElement}:{},...n.captureId?{captureId:n.captureId}:{},text:c,resourceId:l,...d?{testTag:d}:{},bounds:{left:a.left,top:a.top,right:a.right,bottom:a.bottom,centerX:s.x,centerY:s.y},indexInMatches:n.indexInMatches,totalMatches:n.totalMatches,selectionStrategy:n.strategy}}rebuildSelectedElementMetadataAfterStability(n,a){return this.host.buildSelectedElementMetadata(a)??n}async handleElementNotFound(n,{observeResult:a,containerFound:s=!0,signal:c,selection:l}={}){this.assertContainerFound(n,s);let d=this.containerHint(n),p=this.elementNotFoundMessage(n,d),{baseError:h,reason:m}=Vr(n,a,p);if(l?.onlyKeyboardKeyMatch)throw new w(`${p}. The only match is a soft-keyboard key, which observe does not list; use sendKeys or pressButton to drive the keyboard, or dismiss the keyboard first.`,"not-found");if(this.host.visionConfig().enabled&&a){e.info("\uD83D\uDD0D Element not found after polling, trying vision fallback...");let f=await Gp(this.host.screenshotCapturer(),a.viewHierarchy,{text:n.text??n.textAny?.join(" | "),resourceId:n.elementId,description:`Interactive element for tapping (action: ${n.action})`},{visionConfig:this.host.visionConfig(),baseError:h,signal:c,visionAnalyzer:this.host.visionAnalyzer()});throw new w(f,m)}throw new w(h,m)}assertContainerFound(n,a){if(n.container&&!a){let s=n.container.elementId?`elementId '${n.container.elementId}'`:`text '${n.container.text}'`;throw new t(n.container.elementId?.startsWith("s2-")?`Container element id '${n.container.elementId}' is stale; re-observe and use the id from the new observation.`:`Container element not found with provided ${s}`)}}containerHint(n){return n.container?` within container ${n.container.elementId?`elementId '${n.container.elementId}'`:`text '${n.container.text}'`}`:""}siblingNotFoundMessage(n,a){if(n.sibling&&n.text)return`No clickable sibling found next to element with text '${n.text}'${a}`;else if(n.sibling&&n.elementId)return`No clickable sibling found next to element with elementId '${n.elementId}'${a}`;return}elementNotFoundMessage(n,a){let s=this.siblingNotFoundMessage(n,a);if(s!==void 0)return s;if(n.text)return`Element not found with provided text '${n.text}'${a}`;else if(n.textAny)return`Element not found with any provided text '${n.textAny.join("', '")}'${a}`;else if(n.testTag)return`Element not found with provided testTag '${n.testTag}'${a}`;else if(n.accessibilityLink)return`Element not found with provided accessibilityLink '${n.accessibilityLink}'${a}`;else return n.elementId?.startsWith("s2-")?`Element id '${n.elementId}' is stale; re-observe and use the id from the new observation.${a}`:`Element not found with provided elementId '${n.elementId}'${a}`}isClickableElement(n){return st(n.clickable)||Io(n.actions,"click")}isLongClickableElement(n){return st(n["long-clickable"])||st(n.longClickable)||Io(n.actions,"long_click")}elementAffordances(n){let a=[];if(this.host.isClickableElement(n))a.push("tap");if(this.host.isLongClickableElement(n))a.push("long-press");let s=typeof n.class==="string"?n.class:"";if(st(n.focusable)&&(s.includes("EditText")||typeof n["input-type"]==="string"&&n["input-type"].trim()!==""))a.push("input");if(st(n.scrollable))a.push("scroll");if(st(n.checkable))a.push("toggle");return a}elementIdentity(n){return n.text??n["resource-id"]??n.testTag??n["test-tag"]??n["content-desc"]??"unidentified element"}ensureCheckedBeforeTap(n,a,s,c){return this.host.ensureChecked().beforeTap(n,a,s,c)}refreshEnsureCheckedSelection(n,a,s,c){return this.host.ensureChecked().refreshSelection(n,a,s,c)}applyEnsureCheckedResult(n,a,s){return this.host.ensureChecked().applyResult(n,a,s)}resolveTapTargetElement(n,a,s,c){if(typeof c!=="boolean"&&c.scoped)return{element:n,usedParent:!1};if(!a||!this.host.strategy().promotesClickableAncestor)return{element:n,usedParent:!1};let l=new we().project(a),d=x(l,n),p=d?ED(d,l,{action:s==="longPress"?"long-press":"tap"}):null;if(p?.element)return{element:p.element,usedParent:!Vt(p.element.bounds,n.bounds)};return{element:n,usedParent:!1}}}var Br={tap:"tap",doubleTap:"tap",longPress:"tap",focus:"focus-input"};class ve{deps;constructor(n){this.deps=n}selectVariantOrSiblingOrMiss(n,a){try{return a()}catch(s){if(!(s instanceof t))throw s;if(!(n.verification!==void 0&&s.message==="Sibling row not found"||n.textAny!==void 0&&n.selectionStrategy==="unique"&&s.message.startsWith("Target not found")))throw s;return e.debug("[TapOnElement] Text variant or display sibling not found yet",s),{element:null,totalMatches:0,indexInMatches:-1,strategy:n.selectionStrategy??"first"}}}classifyFocusSelectionFailure(n,a,s){let c=this.selectElementInHierarchy({...n,selectionStrategy:"first",index:void 0},a).selection;if(c.totalMatches===0&&!c.matchedElement)throw new w(s.message,"not-found");let l=c.element??c.matchedElement;if(c.totalMatches===1&&l&&Pn(l)&&this.deps.tapPoints.isElementTapTargetOffScreen(c,a,this.deps.tapPoints.getScreenSizeFromHierarchy(a,n.screenSizeOptions),n))throw new w(s.message,this.deps.tapPoints.isCoveredByNavigationBar(c,a,this.deps.tapPoints.getScreenSizeFromHierarchy(a,n.screenSizeOptions))?"navigation-bar":"no-visible-tap-area");throw s}selectElementInHierarchy(n,a){let s=this.isContainerAvailable(a,n.container),c=this.selectionContext(n),{text:l,elementId:d}=n,p=(h)=>({selection:h,containerFound:s});if(l)return p(n.sibling?this.selectVariantOrSiblingOrMiss(n,()=>this.selectSiblingText(n,a,l,c)):this.selectPartialText(n,a,l,c));if(n.textAny){let h=this.selectTextAny(n,a,c);if(h)return p(h)}if(d)return p(n.sibling?this.selectVariantOrSiblingOrMiss(n,()=>this.selectSiblingElementId(n,a,d,c)):this.selectElementId(n,a,d,c));return p(this.deps.elementSelector().select(a,{testTag:je(n)},{container:n.container,screenSizeOptions:n.screenSizeOptions,strategy:n.selectionStrategy,intentAction:c.lookupAction,selectionIntent:c.selectionIntent,index:n.index}))}selectionContext(n){let a=n.action==="longPress"?"long-press":n.action==="focus"?"focus-input":"tap",s=n.subtext?"inspect":es(n)?a:n.action==="focus"?"focus-input":"inspect";return{intentAction:a,lookupAction:s,selectionIntent:this.selectionIntentFor(n)}}selectSiblingText(n,a,s,c){return this.deps.elementSelector().select(a,{sibling:{text:s}},{container:n.container,screenSizeOptions:n.screenSizeOptions,fuzzyMatch:!0,caseSensitive:!1,strategy:n.selectionStrategy,intentAction:c.intentAction,selectionIntent:c.selectionIntent,index:n.index})}selectPartialText(n,a,s,c){return this.deps.elementSelector().select(a,{text:s},{container:n.container,screenSizeOptions:n.screenSizeOptions,partialMatch:!0,caseSensitive:!1,strategy:n.selectionStrategy,intentAction:c.lookupAction,allowHintFallback:n.action==="tap"||n.action==="focus",index:n.index,selectionIntent:c.selectionIntent})}selectSiblingElementId(n,a,s,c){return this.deps.elementSelector().select(a,{sibling:{elementId:s}},{container:n.container,screenSizeOptions:n.screenSizeOptions,partialMatch:!1,strategy:n.selectionStrategy,intentAction:c.intentAction,index:n.index})}selectElementId(n,a,s,c){return this.deps.elementSelector().select(a,{elementId:s},{container:n.container,screenSizeOptions:n.screenSizeOptions,partialMatch:!1,strategy:n.selectionStrategy,intentAction:c.lookupAction,index:n.index})}selectTextAny(n,a,s){let c=null,l=null,d=this.deps.tapPoints.getScreenSizeFromHierarchy(a,n.screenSizeOptions);for(let p of n.textAny??[]){let h=this.selectVariantOrSiblingOrMiss(n,()=>n.sibling?this.selectSiblingText(n,a,p,s):this.selectPartialText(n,a,p,s));if(c=h,!h.element)continue;if(this.deps.tapPoints.isElementTapTargetOffScreen(h,a,d,n)){l=h;continue}return h}if(l)return{...l,element:null};if(c&&n.selectionStrategy==="unique")throw new w(`Target not found${n.container?" within container":""}: no textAny variant matched`,"not-found");return c}selectionIntentFor(n){return n.ensureChecked!==void 0&&n.index===void 0&&!n.elementId?"toggle":Br[n.action]}isContainerAvailable(n,a){return fF(this.deps.elementSelector(),n,a)}resolveContainerElement(n,a){let s=a.container;if(!s)return;let c=this.deps.elementSelector();if(c.resolveContainer)return c.resolveContainer(n,s,a.selectionStrategy);let l={container:s.container,index:s.index,strategy:$q(s,a.selectionStrategy).selectionStrategy};if(s.elementId)return this.deps.elementSelector().select(n,{elementId:s.elementId},{...l,intentAction:"inspect",screenSizeOptions:a.screenSizeOptions}).element;if(s.text)return this.deps.elementSelector().select(n,{text:s.text},{...l,intentAction:"inspect",screenSizeOptions:a.screenSizeOptions,caseSensitive:!1}).element;return}}function te(n,a,s){return s?.sibling||s?.action==="focus"?a:n.matchedElement??a}var Nr=25;function Lr(n){return{elementId:n.elementId??null,label:n.displayedLabel??n.label??null,className:n.className??null,bounds:n.bounds,clickable:n.categories.clickable,actionable:n.actionable,depth:n.depth,windowRank:n.windowRank}}function u7(n,a,s){let c=Lc(n,a,s,"hitTest");if("error"in c)throw new t(c.error);let l=a.viewHierarchy?qm(new we().project(a.viewHierarchy)):[],d=SD(l,c).slice(0,Nr).map(Lr),p=a.screenSize,h=s==="ios"?"points":"pixels";return{method:"hierarchy-bounds",dispatchGuaranteed:!1,point:c,screenSize:{width:p.width,height:p.height,unit:h},reference:{kind:"screen",bounds:{left:0,top:0,right:p.width,bottom:p.height},unit:h,display:a.display},firstCandidate:d[0]??null,candidates:d}}function B(n,a){if(!n||!a)return!1;let s=new Da,c=xm(n).filter((p)=>p.hierarchy).flatMap((p)=>s.extractWindowRootGroups({hierarchy:{},windows:[p]})[0]),l=n.hierarchy.node&&jW(Fv,n.hierarchy.node);for(let[p,h]of l??[])if(h)c.push(p);let d=!1;for(let p of c)s.traverseNode(p,(h)=>{d||=h===a});return d}function Mr(n){if(n?.source==="ios-sdk-safe-area"&&n.safeArea){let a=n.systemChrome?.statusBar;return{top:a==="hidden"?0:n.safeArea.top,bottom:0,visibilityKnown:a==="visible"||a==="hidden"}}return}function ht(n,a=!1){let s=n.insets?.available===!1?void 0:n.insets;if(s?.systemBars){let{systemBars:d,tappableElement:p}=s;return{top:d.visible.top,bottom:d.visible.bottom,visibilityKnown:!0,...p?{bottomConsumesTouches:p.bottom>0}:{}}}let c=Mr(s);if(c)return c;let l=n.systemInsets;if(a&&l?.top===0)return;return l?{top:l.top,bottom:l.bottom,visibilityKnown:!1}:void 0}function be(n,a,s){let c=ht(n,!0);if(!a||!c?.visibilityKnown||!n.screenHeight||n.screenHeight<=0||c.top<=s.top)return s;return Qt(s,{...s,top:Math.max(0,c.top)})}var _r="The tap point is inside the gesture navigation bar area. The thin gesture bar does not consume touches, so the tap is sent, but the system's own swipe gestures can claim it: confirm the prototype control reacted (awaitEvent for its page_changed / selected event) before relying on it.",ft="The tap point is inside the system bar area and the capture does not say whether the bars are showing, so the AutoMobile prototype control there may not receive the touch.";function zr(n,a){if(a.y<n.top)return{kind:"refuse",bar:"status bar"};if(n.bottomConsumesTouches===void 0)return{kind:"proceed",point:a,warning:ft};return n.bottomConsumesTouches?{kind:"refuse",bar:"navigation bar"}:{kind:"proceed",point:a,warning:_r}}function Tt(n){let{hierarchy:a,ownedByPrototype:s,bounds:c,point:l}=n,d=a?.screenHeight,p=a&&ht(a,n.warnIfUnknown);if(!s)return{kind:"proceed",point:l};if(!p||!d||d<=0)return{kind:"proceed",point:l,...n.warnIfUnknown?{warning:"The capture does not say whether the bars are showing or where the status bar ends, so the AutoMobile prototype control may not receive the touch."}:{}};let h=d-Math.max(0,p.bottom);if(l.y>=Math.max(0,p.top)&&l.y<h)return{kind:"proceed",point:l};if(!p.visibilityKnown)return{kind:"proceed",point:l,warning:ft};let m=Math.max(c.top,p.top),f=Math.min(c.bottom,h);if(f<=m)return zr(p,l);return{kind:"proceed",point:{x:l.x,y:Math.floor((m+f)/2)}}}function Wr({coveredBy:n,coveredByKind:a}){return a==="view"?`Target is covered by ${JSON.stringify(n)} drawn over it at its only visible tap area; scroll the target clear of it with swipeOn, then retry tapOn.`:`Target is covered by ${n}; dismiss the covering window, then retry tapOn.`}class ge{deps;prototypeAgents;constructor(n){this.deps=n;this.prototypeAgents=n.prototypeAgents??{get:()=>{return}}}async prototypeTapHierarchy(n,a,s){if(s!=="tap"||this.deps.device.platform!=="ios"||!n.packageName)return n;let c=x(new we().project(n),a)?.source;if(!B(n,c))return n;let l=this.prototypeAgents.get(this.deps.device.deviceId,n.packageName);if(!l)return n;try{let d=await l.request("get_prototype_status",void 0,{timeoutMs:Uz}),p=d.success?Bz(d.status)?.safeAreaTop:void 0;if(p===void 0)return n;return{...n,insets:{available:!0,source:"ios-sdk-safe-area",units:"points",safeArea:{top:p,left:0,right:0,bottom:0},systemChrome:{visibility:"visible",statusBar:p>0?"visible":"hidden",source:"ios-status-bar-manager"}}}}catch(d){return e.debug("Prototype tap safe-area status unavailable",d),n}}resolveTapPoint(n){return this.deps.geometry().getElementCenter(n)}getImeOccluderForTap(n,a,s){let c=this.deps.device.platform;if(c!=="android"&&c!=="ios")return;let l=new Qc().collect(j(n,a,c),c),d=l&&kD(l,n);return d&&c==="ios"?Rk(d,s):d}prototypeBarTapDecision(n,a,s,c=a.bounds){if(this.deps.device.platform!=="android"&&this.deps.device.platform!=="ios")return{kind:"proceed",point:s};let l=x(new we().project(n),a)?.source;return Tt({hierarchy:n,ownedByPrototype:B(n,l),bounds:c,point:s,warnIfUnknown:this.deps.device.platform==="ios"})}resolveImeSafeTapPoint(n,a,{options:s,screenSize:c},l=n.bounds){let d=this.getImeOccluderForTap(n,a,c);if(!d)return this.resolveTapPoint(n);let{left:p,top:h,right:m,bottom:f}=l,T=RR([p,h,m,f],d.bounds),y={left:d.bounds[0],top:d.bounds[1],right:d.bounds[2],bottom:d.bounds[3]};if(T&&!P(T,y))return T;let v=n.text??n["content-desc"]??n["resource-id"],b=D(n,s),g=b!=="the matched element"?b:JSON.stringify(s.elementId??s.testTag??s.accessibilityLink??"element"),E=JSON.stringify(v)??g;throw new jp(`Target ${E} is covered by the soft keyboard; dismiss the keyboard first.`)}isElementTapTargetOffScreen(n,a,s,c){if(!ys(s))return!1;return!this.visibleTapBounds(n,a,{screenSize:s,options:c})}invisibleMatchError(n,a,s,c){let l=n.matchedElement??n.element;if(this.isCoveredByNavigationBar(n,s,c))return`Target ${JSON.stringify(l?.text??a.text??a.elementId??"target")} is covered by the navigation bar; scroll it into view with swipeOn, then retry tapOn.`;return`Matched element ${JSON.stringify(l?.text??a.text??a.elementId??"target")} has no visible tap area (bounds ${JSON.stringify(l?.bounds)}). Scroll it into view with swipeOn, then retry tapOn.`}visibilityFailureReason(n,a,s){return this.isCoveredByNavigationBar(n,a,s)?"navigation-bar":"no-visible-tap-area"}invisibleMatchFailure(n,a,s,{screenSize:c,fallback:l}={}){let d=this.visibilityFailureReason(n,s,c);return new w(d==="navigation-bar"||!l?this.invisibleMatchError(n,a,s,c):l,d)}navigationTapBounds(n,a,s,c){return this.deps.strategy().clipNavigationTapBounds(n,a,s,c)}isCoveredByNavigationBar(n,a,s){let c=n.element??n.matchedElement;if(!c)return!1;let l=n.matchedElement??c,d=Qt(c.bounds,l.bounds);return!!d&&!!this.navigationTapBounds(d,a,s,[l,c]).coveredBy}visibleTapBounds(n,a,{screenSize:s,options:c,tapTarget:l}={}){let d=l??n.element;if(!d?.bounds)return null;let p=te(n,d,c),h=p.bounds,m=Ye(h)?p:d,f=Vm(d.bounds,s,m.bounds);if(!f||!ys(s)||this.deps.device.platform!=="ios")return f;let T=new we().project(a),y=Ez(T,s,a);if(y&&this.prototypeBarGuardHandlesLegacyInsets(a,x(T,d)?.source))y.statusBarTop=0;return Iz({bounds:f,matched:m,target:d,nodes:T,context:y})}prototypeBarGuardHandlesLegacyInsets(n,a){return!!n.systemInsets&&(n.screenHeight??0)>0&&B(n,a)}resolveVisibleTapPoint(n,a,s,c){let l=this.resolveImeSafeTapPoint(n,a,c),d=this.getImeOccluderForTap(n,a,c.screenSize);if(this.deps.device.platform!=="ios"){let R=P(l,s)?l:d?this.resolveImeSafeTapPoint(n,a,c,s):this.deps.geometry().getElementCenter({bounds:s}),O=x3(a,n,s,{point:R,imeBounds:d&&{left:d.bounds[0],top:d.bounds[1],right:d.bounds[2],bottom:d.bounds[3]},ownWindows:Je(c.options.layer),views:!0});if(!O.point)throw new w(Wr(O),"no-visible-tap-area");return O.point}let p=new we().project(a),h=x(p,n),m=this.barSafeIosVisibleBounds(a,h,s,l),f=m!==s,T=d?RR([m.left,m.top,m.right,m.bottom],d.bounds):null,y=this.deps.geometry().getElementCenter({bounds:m}),v=c.chromeElements??[n],b=this.navigationTapBounds(n.bounds,a,c.screenSize,v).bounds;if(!b)return null;let g=Ire(p,h,n.bounds,b)?[T,y,l]:[l,T,y],E=d&&{left:d.bounds[0],top:d.bounds[1],right:d.bounds[2],bottom:d.bounds[3]},S=$B({nodes:p,target:h,matched:v.flatMap((R)=>{let O=x(p,R);return O?[O]:[]}),screen:c.screenSize,visibleBounds:m,candidates:g,imeBounds:E,isValid:(R)=>R!==null&&Number.isInteger(R.x)&&Number.isInteger(R.y)&&P(R,m)&&P(R,n.bounds)&&(!E||!P(R,E))&&(!ys(c.screenSize)||!kre({point:R,hierarchy:a,screen:c.screenSize,elements:v}))});if(this.assertBarClippedIosTapPoint(f,S.point,l),S.coveredBy)throw new w(_re(n,S.coveredBy,S.ownerInsideScrollContainer),"no-visible-tap-area");return S.point}getScreenSizeFromHierarchy(n,a={}){return qi(n,{...a,platform:Q(this.deps.device.platform,"tapOn"),iosMultiPanel:this.deps.device.platform==="ios"&&(this.deps.device.displays?.panels.length??0)>1})}hostControls(n){return new we().project(n).flatMap((a)=>zW(a.nativeId)&&a.bounds?[{id:a.nativeId,bounds:a.bounds}]:[])}pointClearOfHostControls(n,a,s,c){let l=this.hostControls(n);if(l.length===0)return c;let d=Dte({controls:l,targetId:a["resource-id"],visibleBounds:s,point:c});if(d.kind==="refuse")throw new t(`Cannot tap (${c.x}, ${c.y}): the AutoMobile prototype control ${d.control} covers the whole visible target and a touch there would dismiss the prototype. Move the target away from the top-end corner (or the top-centre escape pill), then retry.`);return d.point}barSafeIosVisibleBounds(n,a,s,c){let l=be(n,B(n,a?.source),s);if(!l)throw this.prototypeBarRefusal(c,"status bar");return l}assertBarClippedIosTapPoint(n,a,s){if(n&&!a)throw this.prototypeBarRefusal(s,"status bar")}revalidateBarAdjustedIosTapPoint({viewHierarchy:n,tapElement:a,visibleBounds:s,finalSelection:c,options:l,screenSize:d,tapPoint:p}){if(this.deps.device.platform==="ios"){let h=new we().project(n),m=x(h,a),f=be(n,B(n,m?.source),s);if(f!==s){let T=f&&$B({nodes:h,target:m,matched:[x(h,te(c,a,l))].flatMap((y)=>y?[y]:[]),screen:d,visibleBounds:f,candidates:[p],isValid:(y)=>y!==null&&P(y,f)&&P(y,a.bounds)});if(!T?.point||T.point.x!==p.x||T.point.y!==p.y)throw this.prototypeBarRefusal(p,"status bar")}}}prototypeBarRefusal(n,a){return new t(`Cannot tap (${n.x}, ${n.y}): the AutoMobile prototype control is under the ${a} and the touch would not reach it. Move the control inside the safe area (safeAreaPadding on the node, or an offset in the floating placement), then retry.`)}planVisibleTapPoint({options:n,requestedAction:a,observeResult:s,viewHierarchy:c,finalSelection:l,tapElement:d}){let p=this.getScreenSizeFromHierarchy(c,{observationScreenSize:s.screenSize,display:s.viewHierarchy}),h=this.visibleTapBounds(l,c,{screenSize:p,options:a==="focus"?{...n,action:"focus"}:n,tapTarget:d});if(!h)throw this.invisibleMatchFailure(l,n,c,{screenSize:p,fallback:"Matched element has no visible tap area on this screen. Scroll it into view with swipeOn, then retry tapOn."});let m=this.resolveVisibleTapPoint(d,c,h,{options:n,screenSize:p,chromeElements:[te(l,d,a==="focus"?{...n,action:"focus"}:n),d]});if(!m)throw this.invisibleMatchFailure(l,n,c,{screenSize:p,fallback:"Matched element has no unobstructed visible tap area. Dismiss the keyboard or scroll it into view, then retry tapOn."});let f=this.pointClearOfHostControls(c,d,h,m),T=this.getImeOccluderForTap(d,c,p);if(T&&f!==m&&P(f,{left:T.bounds[0],top:T.bounds[1],right:T.bounds[2],bottom:T.bounds[3]}))throw new jp("Target is covered by the soft keyboard and a host dismiss control; dismiss the keyboard first.");let y=this.prototypeBarTapDecision(c,d,f,h);if(y.kind==="refuse")throw this.prototypeBarRefusal(f,y.bar);let v=y.point;this.revalidateBarAdjustedIosTapPoint({viewHierarchy:c,tapElement:d,visibleBounds:h,finalSelection:l,options:n,screenSize:p,tapPoint:v});let b=this.hostControls(c).find((g)=>!zW(d["resource-id"])&&P(v,g.bounds));if(b)throw new t(`Cannot tap (${v.x}, ${v.y}): the AutoMobile prototype control ${b.id} covers the visible target once the system bars are avoided and a touch there would dismiss the prototype. Move the target away from the top-end corner (or the top-centre escape pill), then retry.`);return Lv(c,n.layer,v,"tap"),{tapPoint:v,...y.warning?{warning:y.warning}:{}}}}import{posix as qr}from"path";var vt="Library/AutoMobile/prototype-endpoint.json";function Ur(n){return typeof n==="object"&&n!==null&&!Array.isArray(n)&&Object.getPrototypeOf(n)===Object.prototype}function bt(n){let a;try{a=JSON.parse(n)}catch{throw new t("The viewer wrote an invalid endpoint file: expected JSON.")}if(!Ur(a))throw new t("The viewer wrote an invalid endpoint file: expected a plain object.");if(typeof a.port!=="number"||!Number.isInteger(a.port)||a.port<1||a.port>65535)throw new t("The viewer wrote an invalid endpoint file: port must be an integer in 1..65535.");if(typeof a.token!=="string"||a.token.length<16||a.token.length>256||/[\s\p{Cc}]/u.test(a.token))throw new t("The viewer wrote an invalid endpoint file: token must contain 16..256 characters without whitespace or control characters.");return{port:a.port,token:a.token}}class re{records=new Map;get(n,a){let s=this.records.get(n);return a===void 0||s?.bundleId===a?s?.client:void 0}release(n,a){let s=this.get(n,a);if(s!==void 0)this.records.delete(n),s.close()}releaseDevice(n){this.release(n)}record(n,a){let s=this.records.get(n);if(this.records.set(n,a),a.client.onClosed(()=>{if(this.records.get(n)===a)this.records.delete(n)}),s!==void 0&&s.client!==a.client)s.client.close()}}var gt=256;class K{client;events=[];listeners=new Set;buffering=!0;replayDelivered=!1;closedError;closedListeners=new Set;constructor(n){this.client=n;let a=n.onEvent((s)=>{if(this.buffering){if(this.events.length===256)this.events.shift();this.events.push(s)}else this.listeners.forEach((c)=>c(s))});n.onClosed((s)=>{this.closedError=s,a(),this.events.length=0,this.listeners.clear(),this.closedListeners.forEach((c)=>c(s)),this.closedListeners.clear()})}get handshake(){return this.client.handshake}request(n,a,s){return this.client.request(n,a,s)}onEvent(n){if(this.listeners.add(n),!this.replayDelivered){this.replayDelivered=!0;while(this.events.length>0)n(this.events.shift());this.buffering=!1}return()=>this.listeners.delete(n)}onClosed(n){if(this.closedError!==void 0)n(this.closedError);else this.closedListeners.add(n);return()=>this.closedListeners.delete(n)}attachRequestHost(n){this.client.attachRequestHost?.(n)}attachChannelHost(n){this.client.attachChannelHost?.(n)}close(){this.client.close()}}class Se{socket;lines=[];firstFrame=!0;released=!1;dataListener;closeListener;failure;framer=new qc($3,{onLine:(n)=>{if(this.failure!==void 0||!n.trim())return;if(this.firstFrame||this.released)this.firstFrame=!1,this.dataListener?.(`${n}
3
- `);else{if(this.lines.length===gt)this.lines.shift();this.lines.push(n)}},onOverflow:()=>{this.failure=new t("Prototype viewer response frame exceeded the client limit; reconnect to the viewer."),this.lines.length=0,this.socket.end(),this.closeListener?.(this.failure)}});constructor(n){this.socket=n}write(n){this.socket.write(n)}end(){this.lines.length=0,this.socket.end()}onData(n){this.dataListener=n,this.socket.onData((a)=>this.framer.push(a))}onClose(n){this.closeListener=n,this.socket.onClose((a)=>{this.failure=a??new t("Prototype viewer closed the connection."),this.lines.length=0,n(this.failure)})}release(){if(this.failure!==void 0)throw this.failure;while(this.lines.length>0)this.dataListener?.(`${this.lines.shift()}
4
- `);this.released=!0}}class dq{viewer;injected;constructor(n,a){this.viewer=n;this.injected=a}get(n){return this.viewer.get(n)??this.injected.get(n)}}var{join:Gr}=qr,lA=new re;class St{deps;inFlight=new Map;constructor(n){this.deps=n}attach(n,a){let s=JSON.stringify([n.deviceId,a]),c=this.inFlight.get(s);if(c!==void 0)return c;let l=this.attachViewer(n,a).finally(()=>this.inFlight.delete(s));return this.inFlight.set(s,l),l}async attachViewer(n,a){if(n.platform!=="ios"||W(n)!=="simulator")throw new t("Prototype viewers run on simulators only; choose a booted iOS simulator.");let s=this.deps.connections.get(n.deviceId,a);if(s!==void 0)return s;let c=(await this.deps.containers.dataContainer(n.deviceId,a)).trim();if(!c)throw new t("No data container for the prototype viewer; install it on this simulator and retry.");let l=await this.deps.files.readText(Gr(c,vt));if(l===void 0)throw new t("no endpoint file: the viewer is not running or has exited cleanly; open it from the home screen (launchApp) and retry");let{port:d,token:p}=bt(l);this.deps.connections.releaseDevice(n.deviceId);let h;try{h=await this.deps.connect(d,p)}catch(f){throw new t("Could not attach to the prototype viewer: the token may be stale (viewer relaunched) or another host is already attached (the viewer accepts one host at a time). Open the viewer and retry.",{cause:f})}if(!h.handshake.capabilities.includes(fp))throw h.close(),new t("The endpoint is not a prototype viewer: missing prototype_persistence_replay_v1; open the viewer and retry.");let m=h instanceof K?h:new K(h);return this.deps.connections.record(n.deviceId,{bundleId:a,client:m}),m}}function p7(n={}){let a=n.simctl??new F,s=n.files??new ni,c=n.connector??new DD;return new St({containers:{dataContainer:async(l,d)=>{try{return await Wo({...n.containerOwnership,deviceId:l,bundleId:d,run:(p)=>a.executeCommandArgs(p)})}catch(p){if(p instanceof eo)return e.debug("Simulator returned an empty prototype viewer data container path"),"";if(p instanceof Xc)throw p;throw new t("Could not resolve the prototype viewer data container; check that it is installed on this simulator.",{cause:p})}}},files:{readText:async(l)=>{if(!s.existsSync(l))return;try{return await s.readFile(l,"utf8")}catch(d){if(d instanceof Error&&"code"in d&&d.code==="ENOENT"){e.debug("Prototype viewer endpoint disappeared before it could be read.");return}throw new t("Could not read the prototype viewer endpoint file; check its permissions and retry.",{cause:d})}}},connect:async(l,d)=>{let p=new Se(await c.connect(l));try{let h=await $z({port:l,token:d,connector:{connect:async()=>p},timer:n.timer??i}),m=new K(h);return p.release(),m}catch(h){throw p.end(),new t("Prototype viewer authentication failed; reopen the viewer and retry.",{cause:h})}},connections:n.connections??lA})}function Et(n,a){let s=[];for(let c=n.parentIndex;c!==void 0;c=a[c].parentIndex){let l=a[c].properties,d=l["resource-id"]||l["test-tag"];if(d&&s[0]!==d)s.unshift(d)}return s}function $r(n,a){return n.length===a.length&&n.every((s,c)=>s===a[c])}function Kr(n,a){for(let s=n.parentIndex;s!==void 0;s=a[s].parentIndex)if(a[s].className==="WKWebView")return!0;return!1}function jr(n,a){let s=A,c=n.bounds,l=a.bounds;return l.left<=c.left+s&&l.top<=c.top+s&&l.right>=c.right-s&&l.bottom>=c.bottom-s&&(l.right-l.left>c.right-c.left+s||l.bottom-l.top>c.bottom-c.top+s)}function Yr(n,a,s,c){let l=A,d=c!==void 0&&s.some((h)=>h.className==="UIKeyboard"&&h.bounds!==void 0&&h.bounds.top<c&&a.bounds.bottom<=h.bounds.top+l),p=["resource-id","view-id"].some((h)=>{let m=n[h];return m&&!(h==="view-id"&&m.startsWith("s2-"))&&m===a[h]});return d&&(a.bounds.right-a.bounds.left>n.bounds.right-n.bounds.left+l||p&&Ms(n.bounds,a.bounds,l))}function Jr(n,a,s,c){let l=C(a.filter((m)=>m.element&&Pn(m.properties)&&!Kr(m,a))),d=l.filter((m)=>m.className===n.class);if(d.length!==1)return;let p=d[0].element;if(!jr(n,p)&&!Yr(n,p,a,s)||l.some((m)=>m.element!==p&&Ta(m.element)))return;let h=c??n.text;return typeof h==="string"&&h.length>0&&typeof p.text==="string"&&p.text.length>0&&h!==p.text?void 0:p}class Ee{deps;constructor(n){this.deps=n}preTapProjections=new WeakMap;findSoleFocusedFieldByStableIdentity(n,a,s,c){let l=a.filter((h)=>h.element&&Pn(h.properties)&&Ta(h.element)),d=C(l);if(d.length!==1)return;let p=d[0].element;return p&&(this.deps.device.platform==="android"&&!p.text?this.hasEmptyTextFocusIdentity(n,p,a,{labelText:s,preTapHierarchy:c}):oe(n,p,s))&&VL(n.bounds,p.bounds,A)?p:void 0}findSoleFocusedFieldAtTargetBounds(n,a,s){if(this.deps.device.platform!=="ios")return;let c=C(a.filter((d)=>d.element&&Pn(d.properties)&&Ta(d.element))),l=c.length===1?c[0].element:void 0;return l&&Ms(n.bounds,l.bounds,A)&&!this.focusIdentitySignals(n,l,s).conflict?l:void 0}focusProjection=new we;attachedFocusLabels=new WeakMap;attachedFocusLabel(n){let a=mt(n);if(!a)return;if(this.attachedFocusLabels.has(a))return this.attachedFocusLabels.get(a);let s=this.focusProjection.project({hierarchy:{node:a}}).filter((l)=>l.parentIndex===0&&!Pn(l.properties)).map((l)=>l.textSources.text).filter((l)=>typeof l==="string"&&l.trim().length>0),c=s.length?s.join(`
5
- `):void 0;return this.attachedFocusLabels.set(a,c),c}focusIdentitySignals(n,a,s){if(!Pn(n)||n.class!==a.class||!ce(n,a)||["resource-id","test-tag","view-id"].some((l)=>[n[l],a[l]].some((d)=>d&&!(l==="view-id"&&d.startsWith("s2-")))&&n[l]!==a[l]))return{conflict:!0,matched:!1};let c=[...["hint-text","hint","placeholder","content-desc","test-tag"].map((l)=>[n[l],a[l]]),[this.attachedFocusLabel(n)??s??n.text,this.attachedFocusLabel(a)]].filter((l)=>l.every((d)=>typeof d==="string"&&d.trim().length>0));return{conflict:c.some(([l,d])=>l!==d),matched:c.some(([l,d])=>l===d)}}hasEmptyTextFocusIdentity(n,a,s,{labelText:c,preTapHierarchy:l}){let d=this.focusIdentitySignals(n,a,c);if(d.conflict)return!1;let p=C(s.filter((O)=>O.element&&Pn(O.properties)));if(p.filter((O)=>Ms(O.element.bounds,a.bounds,A)).length!==1)return!1;let m=l?this.focusProjection.project(Zt(l)):[],f=C(m.filter((O)=>O.element&&Pn(O.properties))),T=f.filter((O)=>O.source===mt(n)||O.className===n.class&&Ms(O.element.bounds,n.bounds,A)),y=T.length===1?f.indexOf(T[0]):-1,v=p.findIndex((O)=>O.element===a);if(y>=0&&y!==v)return!1;let b=$e(f,p),g=b??0,E={...n.bounds,top:n.bounds.top+g,bottom:n.bounds.bottom+g},S=Ms(E,a.bounds,A),R=p.filter((O)=>O.className===n.class&&!O.element.text);return d.matched||S&&(R.length===1||y>=0&&b!==void 0)}verifyIndexedFocusTarget(n,a,s,{identifier:c,selectedIndex:l}){let d=this.focusProjection.project(s),p=this.findIndexedFocusSelection(n,s,d,{identifier:c,selectedIndex:l}),h=p&&mt(p),m=d.find((f)=>f.source===h);return Boolean(p&&Pn(p)&&m&&d.some((f)=>f.element&&Pn(f.properties)&&Ta(f.element)&&L(p,f.element,d,m))&&p[c.key]===c.value&&a.class===p.class&&VL(a.bounds,p.bounds,A))}findIndexedFocusSelection(n,a,s,{identifier:c,selectedIndex:l}){let d=c.key==="view-id"&&n.elementId===c.value&&s.filter((h)=>h.nodeKey===c.value&&!h.nativeId).length>1,p=(h)=>({windowRank:h.windowRank,area:h.bounds?_t(h.bounds):1/0,order:h.index,interactive:!0});if(d)return s.filter((h)=>h.nodeKey===c.value&&!h.nativeId&&h.element&&Pn(h.properties)).sort((h,m)=>zm(p(h),p(m)))[n.index??l??0]?.element??null;return this.deps.findElementInHierarchy({...n,index:n.index??(n.selectionStrategy==="unique"?void 0:l)},a).selection.element}isFocusedMatchingNode(n,a,s){return Boolean(a.element&&Pn(a.properties)&&Ta(a.element)&&L(n,a.element,s))}isRefoundFocusTarget(n,a,s){let c=this.deps.findElementInHierarchy(n,s).selection.element;return Boolean(c&&Pn(c)&&Ta(c)&&L(a,c,this.focusProjection.project(s)))}verify(n,a,s,c={}){let{labelText:l,selectedIndex:d,preTapHierarchy:p}=c;if(!s?.viewHierarchy)return!1;let h=Zt(s.viewHierarchy)??s.viewHierarchy,m=this.focusProjection.project(h);if(this.isFocusedInPreTapScope(a,m,l,p))return!0;try{return this.matchFocusedInputTarget(n,this.deps.withObservationScreenSize(n,s),a,{viewHierarchy:s.viewHierarchy,nodes:m,labelText:l,selectedIndex:d,preTapHierarchy:p,screenHeight:s.screenSize?.height??s.viewHierarchy.screenHeight})}catch(f){return e.debug(`[TapOnElement] focus check could not resolve the target: ${r(f)}`),!1}}isFocusedInPreTapScope(n,a,s,c){let l=mt(n);if(!c||!l)return!1;let d=this.projectPreTapHierarchy(c),p=d.find((y)=>y.source===l),h=p?Et(p,d):[];if(h.length===0)return!1;let m=(y,v)=>Boolean(y.element&&Pn(y.properties)&&!this.focusIdentitySignals(n,y.element,s).conflict&&$r(Et(y,v),h));if(C(d.filter((y)=>m(y,d))).length!==1)return!1;let f=a.filter((y)=>m(y,a)),T=a.filter((y)=>y.element&&Pn(y.properties)&&Ta(y.element));return C(f).length===1&&f.every((y)=>Ta(y.element))&&T.every((y)=>f.includes(y))}projectPreTapHierarchy(n){let a=this.preTapProjections.get(n);if(a)return a;let s=this.focusProjection.project(Zt(n)??n);return this.preTapProjections.set(n,s),s}matchFocusedInputTarget(n,a,s,{viewHierarchy:c,nodes:l,labelText:d,selectedIndex:p,preTapHierarchy:h,screenHeight:m}){let f=Ke(s,l);if(f?.shared)return this.verifyIndexedFocusTarget(a,s,c,{identifier:f,selectedIndex:p});let T=()=>this.deps.device.platform==="ios"&&Boolean(Jr(s,l,m,d));if(f)return l.some((v)=>v.element&&Pn(v.properties)&&Ta(v.element)&&v.element[f.key]===f.value&&L(s,v.element,l))||T();if(l.find((v)=>this.isFocusedMatchingNode(s,v,l)))return!0;if(this.findSoleFocusedFieldByStableIdentity(s,l,d,h))return!0;if(this.findSoleFocusedFieldAtTargetBounds(s,l,d))return!0;if(T())return!0;if(!n.testTag&&!(n.elementId&&s["resource-id"]))return!1;return this.isRefoundFocusTarget(a,s,c)}}var Ot=[50,100,200,400],Xr=Bt(Ot),Qr=Ot.reduce((n,a)=>n+a,0);class Oe{host;constructor(n){this.host=n}beforeTap(n,a,s,c){if(n.ensureChecked===void 0)return;if(!st(a.checkable)){let l=this.host.elementAffordances(a);throw new t(`tapOn ensureChecked requires a toggle element; ${this.host.elementIdentity(a)} has affordances: ${l.join(", ")||"none"}`)}if(st(a.checked)!==n.ensureChecked)return;return{success:!0,action:n.action,element:a,selectedElement:s,searchUntil:c,skipped:"already-checked"}}async refreshSelection(n,a,s,c){if(n.ensureChecked===void 0)return{selection:s,viewHierarchy:a.viewHierarchy};let l=await this.host.tapVerificationRefresh({refresh:n.verification?.refresh,screenSize:a.screenSize,signal:c})(VI);if(!l)throw new t("tapOn ensureChecked: unable to refresh toggle before tapping");let d=this.host.findElementInHierarchy(this.host.withObservationScreenSize(n,a),l).selection;if(!d.element)throw new t("tapOn ensureChecked: toggle not found in fresh hierarchy");return this.host.replaceObservationHierarchy(a,l,!0),{selection:d,viewHierarchy:l}}async afterTap(n,a,s){if(n.ensureChecked===void 0)return;let c=()=>{let d=a.viewHierarchy?this.host.findElementInHierarchy(this.host.withObservationScreenSize(n,a),a.viewHierarchy).selection.element:void 0;return d?st(d.checked):"not found"},l=c();if(l!==n.ensureChecked)l=await this.pollAfterTap(c,n.ensureChecked,a,{signal:s,refresh:n.verification?.refresh});return l===n.ensureChecked?void 0:`tapOn ensureChecked: tapped element but checked is now ${l} (expected ${n.ensureChecked})`}async applyResult(n,a,s){if(a.ensureChecked===void 0)return;let c=n.observation;if(c===void 0)return;let l=await this.afterTap(a,c,s);if(l!==void 0)n.success=!1,n.error=l}async pollAfterTap(n,a,s,c={}){let{signal:l}=c,d=this.host.timer.now()+Qr,p=n();for(let h=1;this.host.timer.now()<d;h++){o(l);let m=Math.min(Xr.delayForAttempt(h),d-this.host.timer.now());await this.host.timer.sleep(m);let f=d-this.host.timer.now();if(f<=0)break;let T=await this.host.tapVerificationRefresh({refresh:c.refresh,screenSize:s.screenSize,signal:l})(Math.min(VI,f));if(!T)continue;if(this.host.replaceObservationHierarchy(s,T,!0),p=n(),p===a)return p}return p}}function Zr(n){let{freshness:a,viewHierarchy:s}=n,c=On(s);if(s!==void 0&&typeof s.hierarchy==="object"&&s.hierarchy!==null&&!("error"in s.hierarchy)&&s.ctrlProxyIncomplete!==!0&&s.fresh!==!1&&c!==void 0&&a?.isFresh===!1&&a.category==="cache_age")n.freshness={...a,isFresh:!0,verified:!0,actualTimestamp:c,ageMs:0,staleDurationMs:void 0,warning:void 0,category:void 0}}class Re{host;constructor(n){this.host=n}async deriveEffectAfterPostTapObservation(n,a,s,c){let l=this.host.deriveTapEffect(n,a);if(c?.settlePostTapEffect===!1||!this.host.settlesPostTapChange()||!n)return{effect:l,observation:a};if(l?.screenChanged!==!0)return this.host.settler().waitForPostTapChange(n,a,s);if(l.basis!=="viewHierarchy changed")return{effect:l,observation:a};return this.host.settler().settleHierarchyOnlyChange(n,a,s)}enforceFreshnessConsistency(n,a){if(!n||!a.observation||a.effect?.screenChanged!==!0)return;if(a.observation.wakefulness==="Asleep")return;if(this.host.deriveTapEffect(n,a.observation)?.screenChanged===!0)return;let c=a.observation.freshness;a.observation.freshness={...c??{isFresh:!0},verified:!1,isFresh:!1,category:"effect_inconsistent",warning:"effect.screenChanged is true, but this observation's own capture still matches the "+"pre-action screen \u2014 it predates the detected transition. Call observe again for the "+"current, post-action state."}}replaceObservationHierarchy(n,a,s){let c=this.host.getScreenSizeFromHierarchy(a,{observationScreenSize:n.screenSize,display:n.viewHierarchy});n.viewHierarchy=a;let l=On(a);if(l!==void 0)n.updatedAt=l;if(c)n.screenSize=c;else if(n.screenSize)n.screenSize={width:0,height:0};if(this.host.applyRefreshedObservationRotation(n,a.rotation),s)Zr(n)}}var ei=Oc,ri=150;class i0{observeScreen;timer;constructor(n,a=i){this.observeScreen=n;this.timer=a}async execute(n,a={}){let s=a.timeoutMs??ei,c=a.pollMs??ri,l={matched:!1,candidates:[]},d=await ZA(this.observeScreen,this.timer,{timeoutMs:s,pollMs:c,signal:a.signal,initialMinTimestampMs:a.initialMinTimestampMs,skipWaitForFresh:a.skipWaitForFresh,requireFreshExtraction:a.requireFreshExtraction,readBackStackEachPoll:a.readBackStackEachPoll},(p)=>(l=n(p),l.matched));if(d.stopped)return{matched:!0,matchedElement:l.matchedElement,candidates:[],observation:d.observation,polls:d.polls,waitMs:d.waitMs,timedOut:!1};return{matched:!1,matchedElement:void 0,candidates:l.candidates??[],...l.diagnostic?{diagnostic:l.diagnostic}:{},observation:d.observation,polls:d.polls,waitMs:d.waitMs,timedOut:!0,screenOff:d.terminalReason==="screen_off"?!0:void 0}}}class Ae{elementParser;constructor(n){this.elementParser=n}detect(n,a){let s=n?.viewHierarchy,c=a?.viewHierarchy,l=this.detectContextMenuOpened(s,c),d=this.detectSelectionStarted(c),p=this.detectNewWindow(s,c);return{pressRecognized:l||d||p,contextMenuOpened:l,selectionStarted:d}}detectContextMenuOpened(n,a){if(!a)return!1;let s=this.getRootSignatures(n),c=this.elementParser.extractRootNodes(a);for(let l of c){let d=this.getRootSignature(l);if(s.has(d))continue;if(this.containsMenuIndicators(l))return!0}return!1}detectNewWindow(n,a){if(!a)return!1;let s=this.getRootSignatures(n),c=this.elementParser.extractRootNodes(a);if(c.length===0)return!1;return c.some((l)=>!s.has(this.getRootSignature(l)))}detectSelectionStarted(n){if(!n)return!1;let a=this.elementParser.extractRootNodes(n),s=!1,c=[["textSelectionStart","textSelectionEnd"],["selectionStart","selectionEnd"]];for(let l of a)if(this.elementParser.traverseNode(l,(d)=>{if(s)return;let p=this.elementParser.extractNodeProperties(d);for(let[h,m]of c){let f=p?.[h]??p?.[h.toLowerCase()],T=p?.[m]??p?.[m.toLowerCase()];if(!this.isActiveSelectionRange(f,T))continue;s=!0;return}}),s)break;return s}isActiveSelectionRange(n,a){if(n===void 0||a===void 0)return!1;let s=typeof n==="string"?parseInt(n,10):Number(n),c=typeof a==="string"?parseInt(a,10):Number(a);return!Number.isNaN(s)&&!Number.isNaN(c)&&c>s}getRootSignatures(n){if(!n)return new Set;let a=this.elementParser.extractRootNodes(n);return new Set(a.map((s)=>this.getRootSignature(s)))}getRootSignature(n){let a=this.elementParser.extractNodeProperties(n),s=ur(a),c=a.class??a.className??"",l=Gt(Ft(n)),d=l?`${l.left},${l.top},${l.right},${l.bottom}`:"",p=$w(a,["text","content-desc"]);return`${s}|${c}|${d}|${p}`}containsMenuIndicators(n){let a=!1;return this.elementParser.traverseNode(n,(s)=>{if(a)return;let c=this.elementParser.extractNodeProperties(s),l=ur(c).toLowerCase(),d=(c.class??c.className??"").toLowerCase(),p=$w(c,["text","content-desc"]).toLowerCase();if(this.hasMenuIndicator(l,d,p))a=!0}),a}hasMenuIndicator(n,a,s){return n.includes("menu")||n.includes("popup")||a.includes("menu")||a.includes("popup")||s.includes("menu")||s.includes("popup")}}class Pe{device;adb;accessibilityDetector;featureFlags;longPressDurationMs=500;retryTapIfNoChange=!0;warnsOnDisabledElement=!0;settlesPostTapChange=!0;verifiesRefreshedDisplay=!0;promotesClickableAncestor=!0;settlesFocusChangeAfterTap=!1;rethrowsKeyboardOcclusion=!0;applyRefreshedObservationRotation(){}constructor(n,a,s=ti,c){this.device=n;this.adb=a;this.accessibilityDetector=s;this.featureFlags=c}prepareViewHierarchyForResponse(n,a,s){let c=a.filterViewHierarchy(n);return Zc(c,n),c}clipNavigationTapBounds(n,a,s,c){return{bounds:n}}async isAccessibilityServiceEnabled(n){let{talkBack:a,unconfirmed:s}=await gh(this.accessibilityDetector,this.device.deviceId,this.adb,this.featureFlags);if(s)n?.(ba);return a===!0}shouldRunPreTapStability(n){return Boolean(n.preTapStability)}}class ke{device;iosVoiceOverDetector;featureFlags;longPressDurationMs=1000;retryTapIfNoChange=!1;warnsOnDisabledElement=!1;settlesPostTapChange=!1;verifiesRefreshedDisplay=!1;promotesClickableAncestor=!1;settlesFocusChangeAfterTap=!0;rethrowsKeyboardOcclusion=!1;applyRefreshedObservationRotation(n,a){n.rotation=Kd(a,n.screenSize)}constructor(n,a=vo,s){this.device=n;this.iosVoiceOverDetector=a;this.featureFlags=s}prepareViewHierarchyForResponse(n,a,s){if(!s?.width||!s?.height)return null;let c=a.filterOffscreenNodes(n,s.width,s.height);return Zc(c,n),c}clipNavigationTapBounds(n,a,s,c){if(!ys(s))return{bounds:n};return PD({bounds:n,hierarchy:a,screen:s,elements:c,regions:["navigation bar"],forTapTarget:!0})}async isAccessibilityServiceEnabled(){let n=_.getInstance(this.device);return this.iosVoiceOverDetector.isVoiceOverActiveOrUnknown(this.device.deviceId,n,{featureFlags:this.featureFlags})}shouldRunPreTapStability(n){return!1}}function Rt(n,a,s,{iosVoiceOverDetector:c,featureFlags:l}){if(n.platform==="ios")return new ke(n,c,l);return new Pe(n,a,s,l)}function At(n,a){let{device:s,adbFactory:c,adb:l,timer:d,accessibilityDetector:p}=a,h=n.talkBackDriverFactory??new yh(c),m=n.talkBackStrategy??new rv({timer:d,driverFactory:h}),f=n.iosVoiceOverDetector??vo,T=n.featureFlags??sr.getInstance(),y=n.tapStrategy??Rt(s,l,p,{iosVoiceOverDetector:f,featureFlags:T});return{talkBackDriverFactory:h,talkBackStrategy:m,iosVoiceOverDetector:f,featureFlags:T,strategy:y}}var ii={android:{tapDispatch:"android",androidLinkActivation:!0,iosLinkActivation:!1,capturedOwnerIdentity:!1,routesAndroidDisplay:!0,detectsAccessibilityBeforeSearch:!0,refreshesAccessibilityHierarchyBeforeSearch:!0,revalidatesCachedTargets:!0,canReuseAccessibilityState:!0,requiresFreshExtractionForCachedTarget:!1,panelAwareSelection:!1},ios:{tapDispatch:"ios",androidLinkActivation:!1,iosLinkActivation:!0,capturedOwnerIdentity:!0,routesAndroidDisplay:!1,detectsAccessibilityBeforeSearch:!1,refreshesAccessibilityHierarchyBeforeSearch:!1,revalidatesCachedTargets:!0,canReuseAccessibilityState:!1,requiresFreshExtractionForCachedTarget:!0,panelAwareSelection:!0}},ai={tapDispatch:void 0,androidLinkActivation:!1,iosLinkActivation:!1,capturedOwnerIdentity:!1,routesAndroidDisplay:!1,detectsAccessibilityBeforeSearch:!1,refreshesAccessibilityHierarchyBeforeSearch:!1,revalidatesCachedTargets:!1,canReuseAccessibilityState:!0,requiresFreshExtractionForCachedTarget:!1,panelAwareSelection:!1};function Pt(n){return dr(n)?ii[n]:ai}class nc extends De{semanticLinks=new le({usesAndroidLinkActivation:()=>this.platformTraits.androidLinkActivation,usesIosLinkActivation:()=>this.platformTraits.iosLinkActivation,usesCapturedOwnerIdentity:()=>this.platformTraits.capturedOwnerIdentity,accessibilityService:()=>this.accessibilityService,activateSemanticLink:(...n)=>this.activateSemanticLink(...n),device:()=>this.device,elementParser:()=>this.elementParser,hasUniqueSemanticLinkOwner:(...n)=>this.hasUniqueSemanticLinkOwner(...n),resolveContainerElement:(...n)=>this.resolveContainerElement(...n),withObservationScreenSize:(...n)=>this.withObservationScreenSize(...n)});targets=new Te({accessibilityService:()=>this.accessibilityService,adb:()=>this.adb,buildSelectedElementMetadata:(...n)=>this.buildSelectedElementMetadata(...n),deriveInteractionEffect:(...n)=>this.deriveInteractionEffect(...n),device:()=>this.device,displayTransitionReader:()=>this.displayTransitionReader,elementParser:()=>this.elementParser,ensureChecked:()=>this.ensureChecked,findElementInHierarchy:(...n)=>this.findElementInHierarchy(...n),finder:()=>this.finder,focusVerifier:()=>this.focusVerifier,geometry:()=>this.geometry,getScreenSizeFromHierarchy:(...n)=>this.getScreenSizeFromHierarchy(...n),getSearchUntilDuration:(...n)=>this.getSearchUntilDuration(...n),hashViewHierarchy:(...n)=>this.hashViewHierarchy(...n),hierarchyCapture:()=>this.hierarchyCapture,invisibleMatchFailure:(...n)=>this.invisibleMatchFailure(...n),isClickableElement:(...n)=>this.isClickableElement(...n),isElementTapTargetOffScreen:(...n)=>this.isElementTapTargetOffScreen(...n),isLongClickableElement:(...n)=>this.isLongClickableElement(...n),postTapEffect:()=>this.postTapEffect,refreshViewHierarchy:(...n)=>this.refreshViewHierarchy(...n),refreshedDisplayTransitions:()=>this.refreshedDisplayTransitions,renderedDisplayGeneration:()=>this.renderedDisplayGeneration,replaceObservationHierarchy:(...n)=>this.replaceObservationHierarchy(...n),resolveTapTargetElement:(...n)=>this.resolveTapTargetElement(...n),screenshotCapturer:()=>this.screenshotCapturer,selectionStateTracker:()=>this.selectionStateTracker,staleDisplay:(...n)=>this.staleDisplay(...n),staleSyntheticTarget:(...n)=>this.staleSyntheticTarget(...n),strategy:()=>this.strategy,tapPoints:()=>this.tapPoints,tapVerificationRefresh:(...n)=>this.tapVerificationRefresh(...n),timer:()=>this.timer,viewHierarchy:()=>this.viewHierarchy,visionAnalyzer:()=>this.visionAnalyzer,visionConfig:()=>this.visionConfig,withObservationScreenSize:(...n)=>this.withObservationScreenSize(...n)});displayRouter=new de({routesAndroidDisplay:()=>this.platformTraits.routesAndroidDisplay,accessibilityService:()=>this.accessibilityService,adb:()=>this.adb,applyEnsureCheckedResult:(...n)=>this.applyEnsureCheckedResult(...n),buildSelectedElementMetadata:(...n)=>this.buildSelectedElementMetadata(...n),checkPostActionDisplay:(...n)=>this.checkPostActionDisplay(...n),completedDisplayFailure:(...n)=>this.completedDisplayFailure(...n),createErrorResult:(...n)=>this.createErrorResult(...n),device:()=>this.device,displayTransitionReader:()=>this.displayTransitionReader,ensureCheckedBeforeTap:(...n)=>this.ensureCheckedBeforeTap(...n),findElementInHierarchy:(...n)=>this.findElementInHierarchy(...n),geometry:()=>this.geometry,getSearchUntilDuration:(...n)=>this.getSearchUntilDuration(...n),handleElementNotFound:(...n)=>this.handleElementNotFound(...n),hashViewHierarchy:(...n)=>this.hashViewHierarchy(...n),hierarchyCapture:()=>this.hierarchyCapture,lastRenderedObservation:()=>this.lastRenderedObservation,observeScreen:()=>this.observeScreen,observedInteraction:(...n)=>this.observedInteraction(...n),refreshEnsureCheckedSelection:(...n)=>this.refreshEnsureCheckedSelection(...n),replaceObservationHierarchy:(...n)=>this.replaceObservationHierarchy(...n),resolveAndroidStableTapTargetAfterRefreshes:(...n)=>this.resolveAndroidStableTapTargetAfterRefreshes(...n),resolveVisibleTapPoint:(...n)=>this.resolveVisibleTapPoint(...n),rethrowKeyboardOcclusion:(...n)=>this.rethrowKeyboardOcclusion(...n),rethrowObservationAbort:(...n)=>this.rethrowObservationAbort(...n),retryTapIfNoChange:(...n)=>this.retryTapIfNoChange(...n),searchForElement:(...n)=>this.searchForElement(...n),staleDisplay:(...n)=>this.staleDisplay(...n),strategy:()=>this.strategy,talkBackDriverFactory:()=>this.talkBackDriverFactory,talkBackStrategy:()=>this.talkBackStrategy,tapPoints:()=>this.tapPoints,timer:()=>this.timer,unverifiableDisplayPostState:(...n)=>this.unverifiableDisplayPostState(...n),validateOptions:(...n)=>this.validateOptions(...n),verifyFocusedInputTarget:(...n)=>this.verifyFocusedInputTarget(...n),visibleTapBounds:(...n)=>this.visibleTapBounds(...n),withObservationScreenSize:(...n)=>this.withObservationScreenSize(...n)});execution=new ue({runPlatformTap:async(n)=>{let a=this.platformTraits.tapDispatch;if(a===void 0)throw yt(this.device.platform,"tap on elements");return n[a]()},detectsAccessibilityBeforeSearch:()=>this.platformTraits.detectsAccessibilityBeforeSearch,refreshesAccessibilityHierarchyBeforeSearch:()=>this.platformTraits.refreshesAccessibilityHierarchyBeforeSearch,revalidatesCachedTargets:()=>this.platformTraits.revalidatesCachedTargets,canReuseAccessibilityState:()=>this.platformTraits.canReuseAccessibilityState,requiresFreshExtractionForCachedTarget:()=>this.platformTraits.requiresFreshExtractionForCachedTarget,activateAccessibilityLinkPhase:(...n)=>this.activateAccessibilityLinkPhase(...n),activateSubtextPhase:(...n)=>this.activateSubtextPhase(...n),applyEnsureCheckedResult:(...n)=>this.applyEnsureCheckedResult(...n),assertLongPressWithinRequestBudget:(...n)=>this.assertLongPressWithinRequestBudget(...n),buildSelectedElementMetadata:(...n)=>this.buildSelectedElementMetadata(...n),captureTerminalObservationScreenshot:(...n)=>this.captureTerminalObservationScreenshot(...n),completedDisplayFailure:(...n)=>this.completedDisplayFailure(...n),confirmFocusAfterTap:(...n)=>this.confirmFocusAfterTap(...n),createErrorResult:(...n)=>this.createErrorResult(...n),deriveTapEffectAfterPostTapObservation:(...n)=>this.deriveTapEffectAfterPostTapObservation(...n),detectLongPressMetadata:(...n)=>this.detectLongPressMetadata(...n),device:()=>this.device,didCompleteDisplayGesture:(...n)=>this.didCompleteDisplayGesture(...n),enforceFreshnessConsistencyWithEffect:(...n)=>this.enforceFreshnessConsistencyWithEffect(...n),ensureCheckedBeforeTap:(...n)=>this.ensureCheckedBeforeTap(...n),executeAndroidTap:(...n)=>this.executeAndroidTap(...n),executeOnDisplay:(...n)=>this.executeOnDisplay(...n),executeiOSTap:(...n)=>this.executeiOSTap(...n),geometry:()=>this.geometry,getLongPressDuration:(...n)=>this.getLongPressDuration(...n),handleElementNotFound:(...n)=>this.handleElementNotFound(...n),hashViewHierarchy:(...n)=>this.hashViewHierarchy(...n),logClickableParentSelection:(...n)=>this.logClickableParentSelection(...n),longPressMetadataDetector:()=>this.longPressMetadataDetector,observedInteraction:(...n)=>this.observedInteraction(...n),predictionToolArgs:(...n)=>this.predictionToolArgs(...n),prepareSelectionCapture:(...n)=>this.prepareSelectionCapture(...n),readScopeFailureResult:(...n)=>this.readScopeFailureResult(...n),rebuildSelectedElementMetadataAfterStability:(...n)=>this.rebuildSelectedElementMetadataAfterStability(...n),recordDeferredPredictionOutcome:(...n)=>this.recordDeferredPredictionOutcome(...n),refreshEnsureCheckedSelection:(...n)=>this.refreshEnsureCheckedSelection(...n),refreshViewHierarchy:(...n)=>this.refreshViewHierarchy(...n),replaceObservationHierarchy:(...n)=>this.replaceObservationHierarchy(...n),resolveAndroidStableTapTargetAfterRefreshes:(...n)=>this.resolveAndroidStableTapTargetAfterRefreshes(...n),resolveTapTargetElement:(...n)=>this.resolveTapTargetElement(...n),rethrowKeyboardOcclusion:(...n)=>this.rethrowKeyboardOcclusion(...n),retryTapIfNoChange:(...n)=>this.retryTapIfNoChange(...n),searchForElement:(...n)=>this.searchForElement(...n),selectionStateTracker:()=>this.selectionStateTracker,strategy:()=>this.strategy,tapPoints:()=>this.tapPoints,tapVerificationRefresh:(...n)=>this.tapVerificationRefresh(...n),timer:()=>this.timer,unverifiableDisplayPostState:(...n)=>this.unverifiableDisplayPostState(...n),validateOptions:(...n)=>this.validateOptions(...n),verifyFocusAfterTap:(...n)=>this.verifyFocusAfterTap(...n),verifyFocusedInputTarget:(...n)=>this.verifyFocusedInputTarget(...n),withObservationScreenSize:(...n)=>this.withObservationScreenSize(...n)});gestureDispatcher=new he({accessibilityService:()=>this.accessibilityService,adb:()=>this.adb,device:()=>this.device,dispatchCoordinateTapOrAdbFallback:(...n)=>this.dispatchCoordinateTapOrAdbFallback(...n),executeAndroidLongPress:(...n)=>this.executeAndroidLongPress(...n),executeAndroidTap:(...n)=>this.executeAndroidTap(...n),executeAndroidTapWithAccessibility:(...n)=>this.executeAndroidTapWithAccessibility(...n),executeAndroidTapWithCoordinates:(...n)=>this.executeAndroidTapWithCoordinates(...n),executeIOSTapWithVoiceOver:(...n)=>this.executeIOSTapWithVoiceOver(...n),executeScopedAndroidTap:(...n)=>this.executeScopedAndroidTap(...n),executeiOSTapWithCoordinates:(...n)=>this.executeiOSTapWithCoordinates(...n),featureFlags:()=>this.featureFlags,findElementInHierarchy:(...n)=>this.findElementInHierarchy(...n),finder:()=>this.finder,geometry:()=>this.geometry,getScreenSizeFromHierarchy:(...n)=>this.getScreenSizeFromHierarchy(...n),hashViewHierarchy:(...n)=>this.hashViewHierarchy(...n),isScreenReaderNavigationEnabled:(...n)=>this.isScreenReaderNavigationEnabled(...n),readOptionalDisplayFence:(...n)=>this.readOptionalDisplayFence(...n),refreshedRetrySelection:(...n)=>this.refreshedRetrySelection(...n),reportTalkBackActivationWarning:(...n)=>this.reportTalkBackActivationWarning(...n),resolveEnsureCheckedRetryTarget:(...n)=>this.resolveEnsureCheckedRetryTarget(...n),resolveRefreshedRetryTarget:(...n)=>this.resolveRefreshedRetryTarget(...n),resolveTapTargetElement:(...n)=>this.resolveTapTargetElement(...n),resolveVisibleTapPoint:(...n)=>this.resolveVisibleTapPoint(...n),semanticAndroidLongPressTargetError:(...n)=>this.semanticAndroidLongPressTargetError(...n),strategy:()=>this.strategy,talkBackDriverFactory:()=>this.talkBackDriverFactory,talkBackStrategy:()=>this.talkBackStrategy,talkBackTargetContext:(...n)=>this.talkBackTargetContext(...n),tapVerificationRefresh:(...n)=>this.tapVerificationRefresh(...n),timer:()=>this.timer,tryDocumentsUiRowActivation:(...n)=>this.tryDocumentsUiRowActivation(...n),trySemanticAndroidLongPress:(...n)=>this.trySemanticAndroidLongPress(...n),visibleTapBounds:(...n)=>this.visibleTapBounds(...n),withRetryScreenSize:(...n)=>this.withRetryScreenSize(...n)});refreshedDisplayTransitions;lastRenderedObservation;focusVerifier=new Ee({device:this.device,findElementInHierarchy:(n,a)=>this.findElementInHierarchy(n,a),withObservationScreenSize:(n,a)=>this.withObservationScreenSize(n,a)});tapPoints=new ge({device:this.device,geometry:()=>this.geometry,strategy:()=>this.strategy,prototypeAgents:{get:(n,a)=>this.prototypeAgents.get(n,a)}});prototypeAgents;finder=new ve({device:this.device,elementSelector:()=>this.elementSelector,tapPoints:this.tapPoints});settler=new ye({timer:this.timer,waitForCondition:()=>this.waitForCondition,hashViewHierarchy:(n)=>this.hashViewHierarchy(n),deriveTapEffect:(n,a)=>this.deriveTapEffect(n,a),compareActiveWindow:(n,a)=>this.compareActiveWindow(n,a)});postTapEffect=new Re({applyRefreshedObservationRotation:(n,a)=>this.strategy.applyRefreshedObservationRotation(n,a),settlesPostTapChange:()=>this.strategy.settlesPostTapChange,settler:()=>this.settler,deriveTapEffect:(n,a)=>this.deriveTapEffect(n,a),getScreenSizeFromHierarchy:(n,a)=>this.getScreenSizeFromHierarchy(n,a)});ensureChecked=new Oe({timer:this.timer,tapVerificationRefresh:(n)=>this.tapVerificationRefresh(n),findElementInHierarchy:(n,a)=>this.findElementInHierarchy(n,a),withObservationScreenSize:(n,a)=>this.withObservationScreenSize(n,a),replaceObservationHierarchy:(n,a,s)=>this.replaceObservationHierarchy(n,a,s),elementAffordances:(n)=>this.elementAffordances(n),elementIdentity:(n)=>this.elementIdentity(n)});geometry;elementParser;accessibilityService;visionConfig;screenshotCapturer;visionAnalyzer;selectionStateTracker;accessibilityDetector;elementSelector;viewHierarchy;hierarchyCapture;talkBackStrategy;featureFlags;talkBackDriverFactory;iosVoiceOverDetector;strategy;longPressMetadataDetector;waitForCondition;constructor(n,a=null,s={}){super(n,{adb:a,timer:s.timer,displayFence:s});this.refreshedDisplayTransitions=s.displayTransitions??xe,this.lastRenderedObservation=s.lastRenderedObservation,this.prototypeAgents=s.prototypeAgents??{get:(l,d)=>lA.get(l,d)??Km.getRecord(l,d)?.client},this.waitForCondition=s.waitForCondition??new i0(this.observeScreen,this.timer),this.geometry=new tr,this.elementParser=new G,this.accessibilityService=Bs(n,this.adbFactory),this.visionConfig=s.visionConfig||Kp,this.screenshotCapturer=s.screenshotCapturer??new Ou(n,this.adbFactory),this.visionAnalyzer=s.visionAnalyzer,this.viewHierarchy=new Vi(n,this.adbFactory),this.hierarchyCapture=s.hierarchyCapture??new gg(n.platform,{readCached:(l)=>this.viewHierarchy.getViewHierarchy({},{skipWaitForFresh:!0,minTimestamp:l.minTimestamp,signal:l.signal,timeoutMs:l.timeoutMs}),readFresh:async(l)=>{if(l.displayId!==void 0)return(await pn(n,{adbFactory:this.adbFactory,timer:this.timer}).capture(l)).hierarchy;let d=await this.readFreshHierarchy(l.timeoutMs??s0,void 0,l.signal,l.requireFreshExtraction);if(!d)throw new t("Unable to retrieve a fresh tap hierarchy");return d},projectVisible:(l)=>this.viewHierarchy.projectActionableHierarchy(l)},this.timer),this.selectionStateTracker=s.selectionStateTracker??new Y6({screenshotCapturer:this.screenshotCapturer}),this.accessibilityDetector=s.accessibilityDetector||ti,this.elementSelector=this.createElementSelector(s);let c=At(s,{device:n,adbFactory:this.adbFactory,adb:this.adb,timer:this.timer,accessibilityDetector:this.accessibilityDetector});this.talkBackDriverFactory=c.talkBackDriverFactory,this.talkBackStrategy=c.talkBackStrategy,this.iosVoiceOverDetector=c.iosVoiceOverDetector,this.featureFlags=c.featureFlags,this.strategy=c.strategy,this.longPressMetadataDetector=new Ae(this.elementParser)}get platformTraits(){return Pt(this.device.platform)}createElementSelector(n){return n.elementSelector??new gr(void 0,void 0,{platform:se(this.device.platform)?"ios":Q(this.device.platform,"tapOn"),iosMultiPanel:!se(this.device.platform)&&this.platformTraits.panelAwareSelection&&(this.device.displays?.panels.length??0)>1})}get testHooks(){return{validateOptions:this.validateOptions.bind(this),hasUniqueSemanticLinkOwner:this.hasUniqueSemanticLinkOwner.bind(this),hashViewHierarchy:this.hashViewHierarchy.bind(this),replaceObservationHierarchy:this.replaceObservationHierarchy.bind(this),verifyFocusedInputTarget:this.verifyFocusedInputTarget.bind(this),handleElementNotFound:this.handleElementNotFound.bind(this),executeAndroidLongPress:this.executeAndroidLongPress.bind(this),executeiOSTap:this.executeiOSTap.bind(this),executeiOSTapWithCoordinates:this.executeiOSTapWithCoordinates.bind(this),executeIOSTapWithVoiceOver:this.executeIOSTapWithVoiceOver.bind(this),setValidateOptions:(n)=>{this.validateOptions=n},setIosCoordinateTap:(n)=>{this.executeiOSTapWithCoordinates=n},setTerminalScreenshotCapture:(n)=>{this.captureTerminalObservationScreenshot=n},setDeferredPredictionRecorder:(n)=>{this.recordDeferredPredictionOutcome=n}}}createErrorResult(...n){return this.semanticLinks.createErrorResult(...n)}validateOptions(...n){return this.semanticLinks.validateOptions(...n)}activateSemanticLink(...n){return this.semanticLinks.activateSemanticLink(...n)}hasUniqueSemanticLinkOwner(...n){return this.semanticLinks.hasUniqueSemanticLinkOwner(...n)}getSearchUntilDuration(...n){return this.targets.getSearchUntilDuration(...n)}hashViewHierarchy(...n){return this.targets.hashViewHierarchy(...n)}deriveTapEffect(...n){return this.targets.deriveTapEffect(...n)}deriveTapEffectAfterPostTapObservation(...n){return this.targets.deriveTapEffectAfterPostTapObservation(...n)}enforceFreshnessConsistencyWithEffect(...n){return this.targets.enforceFreshnessConsistencyWithEffect(...n)}replaceObservationHierarchy(...n){return this.targets.replaceObservationHierarchy(...n)}logClickableParentSelection(...n){return this.targets.logClickableParentSelection(...n)}prepareSelectionCapture(...n){return this.targets.prepareSelectionCapture(...n)}withObservationScreenSize(...n){return this.targets.withObservationScreenSize(...n)}findElementInHierarchy(...n){return this.targets.findElementInHierarchy(...n)}verifyFocusedInputTarget(...n){return this.targets.verifyFocusedInputTarget(...n)}invisibleMatchFailure(...n){return this.targets.invisibleMatchFailure(...n)}resolveTapPoint(...n){return this.targets.resolveTapPoint(...n)}resolveContainerElement(...n){return this.targets.resolveContainerElement(...n)}isElementTapTargetOffScreen=(...n)=>this.tapPoints.isElementTapTargetOffScreen(...n);visibleTapBounds(...n){return this.targets.visibleTapBounds(...n)}resolveVisibleTapPoint(...n){return this.targets.resolveVisibleTapPoint(...n)}getScreenSizeFromHierarchy=(...n)=>this.tapPoints.getScreenSizeFromHierarchy(...n);verifyFocusAfterTap(...n){return this.targets.verifyFocusAfterTap(...n)}refreshViewHierarchy(...n){return this.targets.refreshViewHierarchy(...n)}tapVerificationRefresh(...n){return this.targets.tapVerificationRefresh(...n)}readFreshHierarchy(...n){return this.targets.readFreshHierarchy(...n)}resolveAndroidStableTapTargetAfterRefreshes(...n){return this.targets.resolveAndroidStableTapTargetAfterRefreshes(...n)}staleSyntheticTarget(...n){return this.targets.staleSyntheticTarget(...n)}searchForElement(...n){return this.targets.searchForElement(...n)}buildSelectedElementMetadata(...n){return this.targets.buildSelectedElementMetadata(...n)}rebuildSelectedElementMetadataAfterStability(...n){return this.targets.rebuildSelectedElementMetadataAfterStability(...n)}handleElementNotFound(...n){return this.targets.handleElementNotFound(...n)}isClickableElement(...n){return this.targets.isClickableElement(...n)}isLongClickableElement(...n){return this.targets.isLongClickableElement(...n)}elementAffordances(...n){return this.targets.elementAffordances(...n)}elementIdentity(...n){return this.targets.elementIdentity(...n)}ensureCheckedBeforeTap(...n){return this.targets.ensureCheckedBeforeTap(...n)}refreshEnsureCheckedSelection(...n){return this.targets.refreshEnsureCheckedSelection(...n)}applyEnsureCheckedResult(...n){return this.targets.applyEnsureCheckedResult(...n)}resolveTapTargetElement(...n){return this.targets.resolveTapTargetElement(...n)}unverifiableDisplayPostState(...n){return this.displayRouter.unverifiableDisplayPostState(...n)}executeOnDisplay(...n){return this.displayRouter.executeOnDisplay(...n)}didCompleteDisplayGesture(...n){return this.displayRouter.didCompleteDisplayGesture(...n)}completedDisplayFailure(...n){return this.displayRouter.completedDisplayFailure(...n)}rethrowKeyboardOcclusion(...n){return this.displayRouter.rethrowKeyboardOcclusion(...n)}async execute(n,a={}){let s=qe(this.device,n,a.signal);if(s)return s;return om(()=>this.executeWithReadScope(n,a))}executeWithReadScope(...n){return this.execution.executeWithReadScope(...n)}activateAccessibilityLinkPhase(...n){return this.semanticLinks.activateAccessibilityLinkPhase(...n)}activateSubtextPhase(...n){return this.semanticLinks.activateSubtextPhase(...n)}confirmFocusAfterTap(...n){return this.execution.confirmFocusAfterTap(...n)}assertLongPressWithinRequestBudget(...n){return this.execution.assertLongPressWithinRequestBudget(...n)}predictionToolArgs(...n){return this.execution.predictionToolArgs(...n)}readScopeFailureResult(...n){return this.execution.readScopeFailureResult(...n)}executeAndroidTap(...n){return this.gestureDispatcher.executeAndroidTap(...n)}executeScopedAndroidTap(...n){return this.gestureDispatcher.executeScopedAndroidTap(...n)}executeAndroidTapWithCoordinates(...n){return this.gestureDispatcher.executeAndroidTapWithCoordinates(...n)}tryDocumentsUiRowActivation(...n){return this.gestureDispatcher.tryDocumentsUiRowActivation(...n)}dispatchCoordinateTapOrAdbFallback(...n){return this.gestureDispatcher.dispatchCoordinateTapOrAdbFallback(...n)}resolveEnsureCheckedRetryTarget(...n){return this.gestureDispatcher.resolveEnsureCheckedRetryTarget(...n)}withRetryScreenSize(...n){return this.gestureDispatcher.withRetryScreenSize(...n)}refreshedRetrySelection(...n){return this.gestureDispatcher.refreshedRetrySelection(...n)}resolveRefreshedRetryTarget(...n){return this.gestureDispatcher.resolveRefreshedRetryTarget(...n)}retryTapIfNoChange(...n){return this.gestureDispatcher.retryTapIfNoChange(...n)}isScreenReaderNavigationEnabled(...n){return this.gestureDispatcher.isScreenReaderNavigationEnabled(...n)}reportTalkBackActivationWarning(...n){return this.gestureDispatcher.reportTalkBackActivationWarning(...n)}talkBackTargetContext(...n){return this.gestureDispatcher.talkBackTargetContext(...n)}executeAndroidTapWithAccessibility(...n){return this.gestureDispatcher.executeAndroidTapWithAccessibility(...n)}executeiOSTap(...n){return this.gestureDispatcher.executeiOSTap(...n)}executeiOSTapWithCoordinates(...n){return this.gestureDispatcher.executeiOSTapWithCoordinates(...n)}executeIOSTapWithVoiceOver(...n){return this.gestureDispatcher.executeIOSTapWithVoiceOver(...n)}readOptionalDisplayFence(...n){return this.gestureDispatcher.readOptionalDisplayFence(...n)}getLongPressDuration(...n){return this.gestureDispatcher.getLongPressDuration(...n)}executeAndroidLongPress(...n){return this.gestureDispatcher.executeAndroidLongPress(...n)}throwIfLongPressInterrupted(...n){return this.gestureDispatcher.throwIfLongPressInterrupted(...n)}semanticAndroidLongPressTargetError(...n){return this.gestureDispatcher.semanticAndroidLongPressTargetError(...n)}trySemanticAndroidLongPress(...n){return this.gestureDispatcher.trySemanticAndroidLongPress(...n)}detectLongPressMetadata(...n){return this.execution.detectLongPressMetadata(...n)}}
6
- export{dA,qI,l7,yS,n0,jp,u7,dq,lA,p7,i0,nc};
7
-
8
- //# debugId=295520B882C839BD64756E2164756E21