@kaeawc/auto-mobile 0.0.92 → 0.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-info.json +12 -12
- package/dist/schemas/test-plan.schema.json +370 -52
- package/dist/src/{chunk-jhnbfj19.js → chunk-00167wan.js} +5 -5
- package/dist/src/chunk-0jrrsnc9.js +6 -0
- package/dist/src/chunk-0n6swkwg.js +5 -0
- package/dist/src/chunk-0qsy1qsx.js +57 -0
- package/dist/src/chunk-11m8wj8j.js +237 -0
- package/dist/src/{chunk-4pfftt07.js → chunk-1p7xf5kb.js} +3 -3
- package/dist/src/chunk-23p5f095.js +4 -0
- package/dist/src/{chunk-a4k9rt7z.js → chunk-26k317v5.js} +3 -3
- package/dist/src/chunk-284ptqa4.js +7 -0
- package/dist/src/chunk-28re4xrg.js +4 -0
- package/dist/src/chunk-2f9rkmhx.js +5 -0
- package/dist/src/chunk-2fxdh48t.js +4 -0
- package/dist/src/chunk-2tbdrbt6.js +4 -0
- package/dist/src/chunk-2tqzq5qh.js +971 -0
- package/dist/src/chunk-32gvv9b4.js +21 -0
- package/dist/src/chunk-3f3t1x97.js +8 -0
- package/dist/src/chunk-3fspkbc7.js +4 -0
- package/dist/src/chunk-3qwrzxh0.js +11 -0
- package/dist/src/chunk-3sy6ahhz.js +26 -0
- package/dist/src/chunk-3vg455e6.js +4 -0
- package/dist/src/chunk-3xkpk44w.js +5 -0
- package/dist/src/chunk-3y6eykz9.js +4 -0
- package/dist/src/chunk-49bsqdx3.js +4 -0
- package/dist/src/chunk-4hw3665t.js +42 -0
- package/dist/src/chunk-58wzr3mt.js +5 -0
- package/dist/src/chunk-5d2hft6c.js +5 -0
- package/dist/src/chunk-5snsn9cf.js +4 -0
- package/dist/src/chunk-5tm9mn47.js +54 -0
- package/dist/src/chunk-5zc77a5t.js +4 -0
- package/dist/src/chunk-64j0majr.js +19 -0
- package/dist/src/chunk-65y8v4td.js +17 -0
- package/dist/src/chunk-6awz7vhq.js +5 -0
- package/dist/src/{chunk-stfzjr9y.js → chunk-6bznss4t.js} +5 -5
- package/dist/src/chunk-6ep7f5ge.js +4 -0
- package/dist/src/{chunk-0dfnyfkh.js → chunk-6wt9rgjf.js} +3 -3
- package/dist/src/chunk-6xmss8er.js +8 -0
- package/dist/src/chunk-710rxz9y.js +5 -0
- package/dist/src/chunk-7cs2da62.js +5 -0
- package/dist/src/chunk-7g103b54.js +4 -0
- package/dist/src/chunk-7j5vj4pa.js +4 -0
- package/dist/src/chunk-7rz9898k.js +5 -0
- package/dist/src/chunk-7tw8x05v.js +4 -0
- package/dist/src/chunk-7zy586cb.js +4 -0
- package/dist/src/{chunk-r0f1q783.js → chunk-8037tzzj.js} +3 -3
- package/dist/src/chunk-84nanf8s.js +5 -0
- package/dist/src/{chunk-950qcq1e.js → chunk-8g1922rp.js} +4 -4
- package/dist/src/chunk-8gvwcv2p.js +4 -0
- package/dist/src/{chunk-sz1a7p43.js → chunk-8ph29g99.js} +1 -1
- package/dist/src/chunk-8thrmfat.js +4 -0
- package/dist/src/chunk-8zgzzs7k.js +78 -0
- package/dist/src/chunk-97b1zmaq.js +4 -0
- package/dist/src/chunk-9fth9ayh.js +4 -0
- package/dist/src/chunk-9j6anhjr.js +4 -0
- package/dist/src/{chunk-w7zsh13a.js → chunk-aabchzxk.js} +4 -4
- package/dist/src/{chunk-wry6skrm.js → chunk-ayp07wbb.js} +1 -1
- package/dist/src/chunk-bfjwqk8q.js +4 -0
- package/dist/src/{chunk-jdqvcq0a.js → chunk-bfw6125s.js} +3 -3
- package/dist/src/chunk-bnhscm2n.js +4 -0
- package/dist/src/chunk-bxmsax22.js +5 -0
- package/dist/src/chunk-c1vs4g1n.js +4 -0
- package/dist/src/chunk-ct3e7yng.js +4 -0
- package/dist/src/{chunk-8en08r7q.js → chunk-cyy71ggq.js} +3 -3
- package/dist/src/chunk-ddzkz92z.js +4 -0
- package/dist/src/chunk-dgrbdpb7.js +9 -0
- package/dist/src/chunk-drdz8hee.js +5 -0
- package/dist/src/chunk-e98dqnc9.js +145 -0
- package/dist/src/chunk-eersndy7.js +5 -0
- package/dist/src/chunk-eggq53ks.js +4 -0
- package/dist/src/chunk-f2dya7cs.js +4 -0
- package/dist/src/chunk-fbakd6cw.js +4 -0
- package/dist/src/chunk-fgb98zjj.js +5 -0
- package/dist/src/chunk-fmpad823.js +5 -0
- package/dist/src/{chunk-v90es00d.js → chunk-g04bwyj3.js} +2 -2
- package/dist/src/chunk-g0xr8zw0.js +4 -0
- package/dist/src/chunk-g3rjs80x.js +4 -0
- package/dist/src/chunk-g78rtrfv.js +4 -0
- package/dist/src/{chunk-r20pe1nv.js → chunk-g7tmjbkt.js} +3 -3
- package/dist/src/chunk-gabgv3y5.js +4 -0
- package/dist/src/chunk-gmr45m8f.js +4 -0
- package/dist/src/chunk-gsyfebqj.js +4 -0
- package/dist/src/chunk-h5rpn9wr.js +247 -0
- package/dist/src/chunk-hb1x7v55.js +4 -0
- package/dist/src/chunk-hrfytkxh.js +168 -0
- package/dist/src/chunk-j4yjzbak.js +4 -0
- package/dist/src/chunk-jd6a5v6p.js +5 -0
- package/dist/src/chunk-jh6vhqzx.js +5 -0
- package/dist/src/chunk-kn5spq15.js +4 -0
- package/dist/src/{chunk-w2mwa0jk.js → chunk-m94qs0f0.js} +2 -2
- package/dist/src/chunk-mjrps0ac.js +7 -0
- package/dist/src/chunk-n03dmn5q.js +5 -0
- package/dist/src/chunk-n72qhwd9.js +4 -0
- package/dist/src/{chunk-km0dy5vc.js → chunk-ndt1ccxm.js} +9 -9
- package/dist/src/chunk-nr6y0n4y.js +5 -0
- package/dist/src/chunk-pcsen2vs.js +4 -0
- package/dist/src/chunk-ppfr0b8h.js +4 -0
- package/dist/src/chunk-q10bdnat.js +4 -0
- package/dist/src/chunk-q9xmq595.js +4 -0
- package/dist/src/{chunk-2v7tw1nj.js → chunk-qcxzr2my.js} +3 -3
- package/dist/src/chunk-qf6nynk6.js +7 -0
- package/dist/src/chunk-qyqypn28.js +5 -0
- package/dist/src/chunk-r2epb56s.js +4 -0
- package/dist/src/chunk-r5bxavdx.js +311 -0
- package/dist/src/{chunk-r14wwk37.js → chunk-r6z1eztj.js} +12 -12
- package/dist/src/{chunk-d57432wq.js → chunk-r7bpkgff.js} +2 -2
- package/dist/src/chunk-r8jf3d92.js +4 -0
- package/dist/src/{chunk-9rkfyt6q.js → chunk-rbpdk7m0.js} +3 -3
- package/dist/src/chunk-rc0dbypm.js +4 -0
- package/dist/src/chunk-rhcty4ms.js +4 -0
- package/dist/src/chunk-rpvckv3p.js +4 -0
- package/dist/src/{chunk-s1zq65ny.js → chunk-rqc9ap3x.js} +2 -2
- package/dist/src/chunk-rvvy1bte.js +7 -0
- package/dist/src/chunk-ry0mz41y.js +4 -0
- package/dist/src/{chunk-34zxqcmq.js → chunk-s3jc6cwp.js} +3 -3
- package/dist/src/chunk-sfv61xjb.js +6 -0
- package/dist/src/chunk-t6bfvfkg.js +4 -0
- package/dist/src/chunk-t6c8akcm.js +5 -0
- package/dist/src/chunk-t7w8rctc.js +4 -0
- package/dist/src/chunk-thbh3jew.js +5 -0
- package/dist/src/chunk-v2wd4n3e.js +5 -0
- package/dist/src/{chunk-zg67wjkh.js → chunk-v6pya0dm.js} +3 -3
- package/dist/src/chunk-vy3bwm1d.js +17 -0
- package/dist/src/chunk-w3vs79ex.js +27 -0
- package/dist/src/chunk-w4zga19f.js +4 -0
- package/dist/src/chunk-w5b2jwk3.js +14 -0
- package/dist/src/chunk-w7hkv422.js +5 -0
- package/dist/src/{chunk-qv2918jt.js → chunk-waqwcjyn.js} +2 -2
- package/dist/src/{chunk-b4cxdzwy.js → chunk-wbh8spm5.js} +7 -7
- package/dist/src/{chunk-ajsrz473.js → chunk-wyrkw6hw.js} +3 -3
- package/dist/src/chunk-xa73x2cx.js +5 -0
- package/dist/src/{chunk-eka89q3k.js → chunk-xgan0qqp.js} +1 -1
- package/dist/src/chunk-y2vs6jwg.js +4 -0
- package/dist/src/chunk-yattm52s.js +4 -0
- package/dist/src/{chunk-9y5bcy28.js → chunk-yb97j25b.js} +4 -4
- package/dist/src/{chunk-c9nk1r78.js → chunk-ybbtagbt.js} +3 -3
- package/dist/src/chunk-ycaj2sgf.js +9 -0
- package/dist/src/chunk-yf7ympyz.js +325 -0
- package/dist/src/chunk-yjawdzk8.js +4 -0
- package/dist/src/chunk-z637nqg8.js +11 -0
- package/dist/src/{chunk-0w1spptt.js → chunk-zgja5f3p.js} +4 -4
- package/dist/src/chunk-zs1sghs9.js +4 -0
- package/dist/src/daemon/processEntry.js +2 -2
- package/dist/src/index.js +4 -4
- package/dist/src/runtime/bunRuntimeGuard.js +2 -2
- package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -2
- package/ios/CameraPosterInjection/Injection/CameraPosterInjection.m +466 -0
- package/package.json +3 -2
- package/schemas/test-plan.schema.json +370 -52
- package/dist/src/chunk-09442h7v.js +0 -4
- package/dist/src/chunk-0e4gm1kj.js +0 -5
- package/dist/src/chunk-0eb8576f.js +0 -4
- package/dist/src/chunk-0rjm4nx7.js +0 -5
- package/dist/src/chunk-1zmh2eak.js +0 -4
- package/dist/src/chunk-28k63ha3.js +0 -5
- package/dist/src/chunk-2d4wmp8b.js +0 -4
- package/dist/src/chunk-2e6s75qv.js +0 -78
- package/dist/src/chunk-32jpxz2y.js +0 -323
- package/dist/src/chunk-3jmvqygr.js +0 -238
- package/dist/src/chunk-3swvfhqt.js +0 -5
- package/dist/src/chunk-44bt78m9.js +0 -5
- package/dist/src/chunk-488vt2bp.js +0 -4
- package/dist/src/chunk-4fgdhcwx.js +0 -5
- package/dist/src/chunk-4jp2se4w.js +0 -4
- package/dist/src/chunk-4vhr9e4t.js +0 -4
- package/dist/src/chunk-4xd6zs3y.js +0 -15
- package/dist/src/chunk-51567pg8.js +0 -4
- package/dist/src/chunk-5agqsfev.js +0 -4
- package/dist/src/chunk-5d706gmr.js +0 -4
- package/dist/src/chunk-5kd4rqk7.js +0 -5
- package/dist/src/chunk-61t538bm.js +0 -4
- package/dist/src/chunk-6d3mmqxt.js +0 -54
- package/dist/src/chunk-6hyt398x.js +0 -5
- package/dist/src/chunk-6mnr8kpm.js +0 -4
- package/dist/src/chunk-79q5xsdc.js +0 -42
- package/dist/src/chunk-7bdgand3.js +0 -4
- package/dist/src/chunk-84cp9dw5.js +0 -4
- package/dist/src/chunk-86f2h5ww.js +0 -5
- package/dist/src/chunk-8cghfzb2.js +0 -19
- package/dist/src/chunk-9tf2p9y9.js +0 -5
- package/dist/src/chunk-a2sc4jm0.js +0 -5
- package/dist/src/chunk-aa5ng3d1.js +0 -4
- package/dist/src/chunk-b3h0a6ca.js +0 -4
- package/dist/src/chunk-b6a737qt.js +0 -4
- package/dist/src/chunk-bn64x5z5.js +0 -5
- package/dist/src/chunk-bvh649za.js +0 -12
- package/dist/src/chunk-c9tyfg4j.js +0 -26
- package/dist/src/chunk-cfsdfqnm.js +0 -4
- package/dist/src/chunk-cxyf04jc.js +0 -7
- package/dist/src/chunk-da08tx5v.js +0 -4
- package/dist/src/chunk-f2tc08m2.js +0 -4
- package/dist/src/chunk-f8tnk179.js +0 -5
- package/dist/src/chunk-f9s1kkhx.js +0 -5
- package/dist/src/chunk-fbp8a4rx.js +0 -4
- package/dist/src/chunk-fd2z0sze.js +0 -4
- package/dist/src/chunk-fk927f4q.js +0 -54
- package/dist/src/chunk-fxmr3a0f.js +0 -4
- package/dist/src/chunk-gaqwhd44.js +0 -4
- package/dist/src/chunk-ggtd5x5a.js +0 -5
- package/dist/src/chunk-gndcfrm7.js +0 -4
- package/dist/src/chunk-h3n4adc6.js +0 -310
- package/dist/src/chunk-h5pjbb83.js +0 -4
- package/dist/src/chunk-hgnnh302.js +0 -4
- package/dist/src/chunk-hmke8nhx.js +0 -5
- package/dist/src/chunk-j2bx12hn.js +0 -4
- package/dist/src/chunk-j70y1a2g.js +0 -4
- package/dist/src/chunk-js1jpyxp.js +0 -6
- package/dist/src/chunk-kbjq0qvb.js +0 -4
- package/dist/src/chunk-kfwx57xd.js +0 -4
- package/dist/src/chunk-kzwctna2.js +0 -4
- package/dist/src/chunk-m9ehyehy.js +0 -4
- package/dist/src/chunk-mct91p1f.js +0 -4
- package/dist/src/chunk-mf9spd4g.js +0 -5
- package/dist/src/chunk-mgrcansb.js +0 -4
- package/dist/src/chunk-mqc1d0eb.js +0 -6
- package/dist/src/chunk-n1zmpk0z.js +0 -4
- package/dist/src/chunk-ncyjf63g.js +0 -4
- package/dist/src/chunk-nr64d21q.js +0 -973
- package/dist/src/chunk-nwm2pq5v.js +0 -168
- package/dist/src/chunk-pm06b05d.js +0 -9
- package/dist/src/chunk-q50s00ry.js +0 -4
- package/dist/src/chunk-qwye1958.js +0 -14
- package/dist/src/chunk-r8z9pfve.js +0 -5
- package/dist/src/chunk-rdpgkjf6.js +0 -4
- package/dist/src/chunk-rkr0dks9.js +0 -5
- package/dist/src/chunk-rn84t3sf.js +0 -11
- package/dist/src/chunk-s123kn7n.js +0 -4
- package/dist/src/chunk-s73qn3fx.js +0 -4
- package/dist/src/chunk-sjn0nj4p.js +0 -5
- package/dist/src/chunk-sns0c35v.js +0 -7
- package/dist/src/chunk-t4dr5c8v.js +0 -8
- package/dist/src/chunk-tc8k9c1j.js +0 -4
- package/dist/src/chunk-teznhase.js +0 -4
- package/dist/src/chunk-ty9xgmz4.js +0 -4
- package/dist/src/chunk-tyazf3sk.js +0 -145
- package/dist/src/chunk-v6npjrjm.js +0 -5
- package/dist/src/chunk-vbvtzkwz.js +0 -5
- package/dist/src/chunk-vefd8qee.js +0 -8
- package/dist/src/chunk-vs9r72ta.js +0 -17
- package/dist/src/chunk-w88k0bgr.js +0 -4
- package/dist/src/chunk-wzdt0enk.js +0 -4
- package/dist/src/chunk-xhhv854c.js +0 -4
- package/dist/src/chunk-y58270hd.js +0 -4
- package/dist/src/chunk-yk0hmbex.js +0 -4
- package/dist/src/chunk-ympy4fdz.js +0 -28
- package/dist/src/chunk-yw436axy.js +0 -4
- package/dist/src/chunk-z04jrpjy.js +0 -5
- package/dist/src/chunk-z2xznczw.js +0 -4
- package/dist/src/chunk-z4xnrgps.js +0 -4
- package/dist/src/chunk-z7csyszv.js +0 -4
- package/dist/src/chunk-z8t0v07j.js +0 -11
- package/dist/src/chunk-z916af47.js +0 -228
- package/dist/src/chunk-zcr8he8q.js +0 -5
- package/dist/src/chunk-zd9vmkzn.js +0 -9
- package/dist/src/chunk-zj939v0h.js +0 -5
- package/dist/src/chunk-zkdjwtc1.js +0 -4
- package/dist/src/chunk-zkv5kzt6.js +0 -4
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{i,Q,No,l,e}from"./chunk-z637nqg8.js";import{f}from"./chunk-58wzr3mt.js";import{re,fz,v,z,b}from"./chunk-r5bxavdx.js";import{B,Yn}from"./chunk-yf7ympyz.js";import{b0,S0,s_,oQ,qq,w0,Yy,qc,I0,jq,B4,Jd}from"./chunk-hrfytkxh.js";import{dA,gS,yS}from"./chunk-v2wd4n3e.js";import{Ci}from"./chunk-284ptqa4.js";import{r,t,u}from"./chunk-rbpdk7m0.js";var Md=7,Nd=8;function Is(o){return o.length>0?o[0]&31:0}function F(o){let s=Is(o);return s>=1&&s<=5}function mt(o){return o.length>1&&(o[1]&128)!==0}class _f{current=[];hasVcl=!1;push(o){let s=[],n=Is(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 iy=5,ht=28,Ee=2,bE=1200,JO=4194304;function VK(o){return Is(o)===iy}class tc{maxBufferedBytes;buffered=Buffer.alloc(0);constructor(o=JO){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&&Is(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=bE){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,S=[],g=0;while(g<p.length){let y=Math.min(m,p.length-g),h=g===0,w=g+y>=p.length,E=c;if(h)E|=128;if(w)E|=64;S.push(Buffer.concat([Buffer.from([d,E]),p.subarray(g,g+y)])),g+=y}return S}function AJ(o,s=bE){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 tc;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 tc,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=Is(s);if(n===Md)this.sps=Buffer.concat([Buffer.from([0,0,0,1]),s]);else if(n===Nd)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 TJ(o,s,n=[]){return o instanceof I&&o.entry.handles.size>1&&o.entry.conflicts(s,n,!1).length===0}function kJ(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 S=m.stopPromise,g=this.stopping.get(s)??new Set;g.add(m),this.stopping.set(s,g);let y=()=>{if(m.stopPromise===S){if(g.delete(m),g.size===0)this.stopping.delete(s)}};S.then(y,y)}),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},S=(g)=>{let y=g.stopPromise,h=()=>g.stopPromise!==y?S(g):void 0;return y.then(h,h)};c.creation=Promise.all([...p].map(S)).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 WK(){return new Ce}var gt;function QO(){return gt??=WK()}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=(Ci-5)*1000,Et={width:1280,height:720},bt=3000,Ct=2000,Pt=30000,Tt=2,Rt=Q({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??Ci,Ci),this.segmentRotateMs=o.segmentRotateMs??wt,this.healthySegmentAgeMs=Math.min(Pt,this.segmentRotateMs/2),this.runningRetryMaxAttempts=o.runningRetryMaxAttempts??Tt,this.runningRetryBackoff=No(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 tc;d.stdout.on("data",(m)=>{if(this.current===d){if(m.length>0){let S=!1;try{S=p.push(m).some(F)}catch(g){this.options.onError?.(g instanceof Error?g:Error(String(g)));return}if(S)this.options.onSourceFrame?.()}this.options.onData(m)}}),d.stderr.on("data",(m)=>{let S=m.toString().trim();if(S)e.debug(`[AndroidH264Source] screenrecord stderr: ${S}`)}),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,S)=>{this.handleSegmentExit(d,m,S)}),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(I0*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(jq(n,a)>I0)if(n>=a)n-=2;else a-=2;return{width:n,height:a}}import{connect as $t}from"net";var It=new Set;class L{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 V="automobile_video",te="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:${V}_`)),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 ie=/^[A-Za-z0-9_.-]{1,100}$/;function Z(o){return typeof o==="number"&&Number.isInteger(o)&&o>0}function ee(o){return typeof o==="number"&&Number.isFinite(o)}function Dt(o){return o===void 0||ee(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"&&ie.test(s.socketName),typeof s.deviceSerial==="string",Z(s.ownerPid),Z(s.pid),Z(s.forwardPort),ee(s.startedAtMs),ee(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 g=Number.parseInt(c.slice(4).trim(),10);if(Number.isFinite(g)&&g>=0)s=g*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(),S=m.slice(m.lastIndexOf("/")+1);if(!Number.isFinite(p)||p<0||!Lt.test(S))continue;n.push({name:S,mtimeMs:p*1000})}return{nowEpochMs:s,files:n}}class oe{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 ${b(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 ${b(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(te)||!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 S=m.trim().split(/\s+/);return S.includes(c)&&S.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,se=1,Te=Buffer.from([65,86,77,72]),Ae=5000,Ie=100,He=20000,_e=5000,Fe=3,Me=Q({initialDelayMs:1000,multiplier:2,maxDelayMs:8000}),ke=60000,xe=new L,Oe=(o,s)=>new Promise((n,a)=>{let c=$t(o,"127.0.0.1"),d=!1,p=(y)=>{if(d)return;d=!0,c.off("connect",m),c.off("error",S),s?.removeEventListener("abort",g),y()},m=()=>p(()=>n(c)),S=(y)=>p(()=>a(y)),g=()=>p(()=>{c.destroy(),a(Error("video-server socket connection aborted"))});if(c.once("connect",m),c.once("error",S),s?.aborted){g();return}s?.addEventListener("abort",g,{once:!0})}),De=1e4;function Ne(o){return`${V}_${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 ne{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??Jd.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 ${b(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","/",te,"--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(!ie.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,se)}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((S)=>{if(p)return;p=!0,o.timer.clearTimeout(m),c(S)},(S)=>{if(p)return;p=!0,o.timer.clearTimeout(m),d(S instanceof Error?S:Error(String(S)))})})}var q=1748121140,Wt=1634563448,x=1932605036,qt=1,Kt=2,M=12,U=12,Ke=16,W=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 b0;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??q,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 S=M+m*Ke,g=c.readUInt32BE(S),y=c.readUInt32BE(S+4),h=c.readUInt32BE(S+8),w=c.readUInt32BE(S+12);if(this.muxTracks.set(g,{codecId:y,param1:h,param2:w}),y===q)d={codecId:y,width:h,height:w};else if(g===Kt&&y===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>=W){let o=this.buffered.peek(W),s=o.readUInt32BE(0),n=o.readBigUInt64BE(4),a=o.readUInt32BE(12);if(this.assertWithinCap(a,ze,"packet size"),this.buffered.length<W+a)break;this.buffered.discard(W);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",S),o.removeListener("exit",g),o.removeListener("error",y),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),S=(h)=>{if(c)return;d+=h.toString();let w=d.split(/\r?\n/);d=w.pop()??"";for(let E of w){let C=Gt.exec(E);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}},g=(h,w)=>{p(()=>a(Error(`video-server exited before ready (code=${h}, signal=${w})`)))},y=(h)=>p(()=>a(h));o.stdout.on("data",S),o.once("exit",g),o.once("error",y)})}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="",S=(E)=>{if(p)return;p=!0,this.timer.clearTimeout(g),o.stdout.off("data",y),o.removeListener("exit",h),o.removeListener("error",w),E()},g=this.timer.setTimeout(()=>{S(()=>d(new t(n)))},this.readyTimeoutMs),y=(E)=>{if(p)return;if(m+=E.toString(),m.includes(s))S(c)},h=(E,C)=>{S(()=>d(Error(`${a} (code=${E}, signal=${C})`)))},w=(E)=>S(()=>d(E));o.stdout.on("data",y),o.once("exit",h),o.once("error",w)})}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 K{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??(()=>B.next()),this.socketNameFactory=o.socketNameFactory??(()=>Ne(B)),this.activeVideoSessionRegistry=o.activeVideoSessionRegistry??xe,this.jar=new ne(o,this.commandTimeoutMs,(n,a,c)=>this.withTimeout(n,a,c));let s=K.resolveRelaunchPolicy(o);this.maxServerRelaunchAttempts=s.maxAttempts,this.serverRelaunchBackoff=s.backoff,this.serverRelaunchHealthyWindowMs=s.healthyWindowMs,this.leases=new oe(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:No(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,S=new Promise((h,w)=>{m=w}),g=(h,w)=>{m(Error(`video-server exited (code=${h}, signal=${w})`))},y=(h)=>{m(h)};o.once("exit",g),o.once("error",y);try{let h=await l([d,S],{timer:this.timer,label:"video-server connection"});if(p=!0,!this.running){h.destroy();return}this.socket=h,this.sendHandshake(h);let w=this.options.audioEnabled?this.startup.waitForStartupAudioReady():null,E=this.options.audioEnabled?"startup":"post-start",C,_=this.options.audioEnabled?new Promise((P,pt)=>{C=pt}):null;if(this.wireSocket(h,(P)=>{if(E==="startup"){C?.(P);return}this.reconnectSocket(h,P)},(P)=>this.startup.resolveStartupAudioHeader?.(P)),this.options.audioEnabled){if(await l([Promise.all([n,w]),Promise.resolve(_)],{timer:this.timer,label:"video-server audio startup"}),!this.running)return}E="post-start"}finally{if(o.removeListener("exit",g),o.removeListener("error",y),!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===q)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 S=this.connector(o,c.signal),g=this.timer.setTimeout(()=>{p=!0,c.abort()},a),y=()=>d.abort(Error(p?"video-server socket reconnect attempt timed out":"video-server socket reconnect attempt aborted"));if(c.signal.aborted)y();else c.signal.addEventListener("abort",y,{once:!0});try{return await l(S,{timer:this.timer,signal:d.signal,label:"video-server socket reconnect attempt"})}finally{if(this.timer.clearTimeout(g),n.removeEventListener("abort",m),c.signal.removeEventListener("abort",y),c.signal.aborted)S.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 K(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 Wp 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 Wp(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=(g)=>{if(c)return;if(c=!0,this.timer.clearTimeout(S),this.cancelFirstAudioWait===p)this.cancelFirstAudioWait=null;if(this.rejectFirstAudioWait===m)this.rejectFirstAudioWait=null;g()},p=()=>d(n),m=(g)=>d(()=>a(g)),S=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",(g)=>{if(this.context.isCurrentHelper(o,s)&&this.context.isActive())d(()=>a(g))}),o.on("exit",(g)=>{if(this.context.isCurrentHelper(o,s)&&this.context.isActive())d(()=>a(Error(this.context.describeHelperExit(g,"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(y),this.cancelFirstFrameWait===S)this.cancelFirstFrameWait=null;h()},S=()=>{m(a)},g=(h)=>{m(()=>c(this.context.encodedStartupError(h)))},y=this.timer.setTimeout(()=>{g(Ze(s,this.context.lastReadinessPhase()))},this.firstFrameTimeoutMs);this.cancelFirstFrameWait=S,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))g(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}g(h)}),o.on("exit",(h)=>{if(!this.context.isCurrentHelper(o,n)||!this.context.isActive())return;let w=Error(this.context.describeHelperExit(h,"exited"));if(p){this.context.failIfCurrentHelper(o,n,w);return}g(w)})})}}var tr=5;function et(o,s){o.on("capability",(n)=>{if(s.isCurrentHelper()&&n===oQ)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(S0))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(S0.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 Yy(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 XO=new rt;class H extends t{}import{basename as mr}from"path";var ar=new re,ur=(o=ar)=>(s,n)=>fz(o.spawn(s,n,{stdio:["ignore","pipe","pipe"]}),s),it=ur();var ot=0.1,G=B4,st=15000,cr=f.IOS_SIMULATOR_WINDOW_TIMEOUT_MS.name;function lr(o=process.env){return Yn(cr,void 0,{fallback:2000,env:o})}var O=lr(),he=500,nt=500,dr=2,fe=6000,at=35000,pr=Q({initialDelayMs:500,multiplier:2,maxDelayMs:2000});function ut(o){return{maxAttempts:o.runningReconnectMaxAttempts??dr,backoff:No(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="",S=!1,g=(h)=>{if(S)return;S=!0,n?.removeEventListener("abort",y),h()},y=()=>{d.kill("SIGTERM"),g(()=>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)=>g(()=>c(h))),d.once("exit",(h,w)=>g(()=>a({stdout:p,stderr:m,exitCode:h,signal:w}))),n?.addEventListener("abort",y,{once:!0})});class ve{dependencies;constructor(o){this.dependencies=o}async resolveCaptureTarget(o){if(z({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??gS(process.env);if(o)return yS(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 ${dA} 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 S=await hr(o,s,n,{audioEnabled:a,signal:d});if(S.kind==="found")return S.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: ${S.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 Wp(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(),S=p.filter((h)=>typeof h.title==="string"&&h.title.trim().length>0),g=S.filter((h)=>vr(h.title,m)),y=g.length>0?g:S.filter((h)=>h.title.toLowerCase().includes(m));if(y.length===1)return{kind:"found",windowID:y[0].windowID};if(y.length===0)return{kind:"missing",seen:`[${p.map((w)=>JSON.stringify(w.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===`${qq} 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(w0))continue;let a=n.slice(w0.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 Yy(n)),this.commandRunner=o.commandRunner??ct,this.helperPathExists=o.helperPathExists,this.screenCaptureHelperProvider=o.screenCaptureHelperProvider??qc.getInstance(),this.timer=o.timer??i,this.firstFrameTimeoutMs=o.firstFrameTimeoutMs??st,this.simulatorHelperPool=o.simulatorHelperPool??XO;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 Wp||o instanceof H)return o;return new H(`The screen-capture-helper did not advertise the '${s_}' 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===s_)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 Wp(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 ZO=(o,s)=>{if(o.device.platform==="android")return Qe(o,s);if(o.device.platform==="ios"){if(o.audioEnabled&&z({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{Md,Nd,Is,_f,iy,bE,JO,VK,tc,AJ,Wp,XO,ZO,TJ,kJ,WK,QO};
|
|
4
|
+
|
|
5
|
+
//# debugId=606B6BD478E3D1A164756E2164756E21
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Bae,OK,MK,NK}from"./chunk-bxmsax22.js";import"./chunk-1p7xf5kb.js";import"./chunk-3qwrzxh0.js";import"./chunk-64j0majr.js";import"./chunk-2f9rkmhx.js";import"./chunk-0n6swkwg.js";import"./chunk-00167wan.js";import"./chunk-e98dqnc9.js";import"./chunk-w7hkv422.js";import"./chunk-7rz9898k.js";import"./chunk-fgb98zjj.js";import"./chunk-3xkpk44w.js";import"./chunk-0qsy1qsx.js";import"./chunk-rvvy1bte.js";import"./chunk-r5bxavdx.js";import"./chunk-yf7ympyz.js";import"./chunk-4hw3665t.js";import"./chunk-5d2hft6c.js";import"./chunk-z637nqg8.js";import"./chunk-58wzr3mt.js";export{Bae as createDirectModeAppearanceDeviceSource,OK as getAppearanceSocketPath,MK as startAppearanceSocketServer,NK as stopAppearanceSocketServer};
|
|
3
|
+
|
|
4
|
+
//# debugId=E5F6C674191279F664756E2164756E21
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{je,me,J,o,P,dt,_g,Tt,K,WB,Vt,KB,Ut,gd,es,x,E}from"./chunk-r5bxavdx.js";import{i,Wt,we,qt,l,e}from"./chunk-z637nqg8.js";import{Oe,Kt,At}from"./chunk-3xkpk44w.js";import{r,u,St}from"./chunk-rbpdk7m0.js";function LF(n,t,s){return["android.","androidx."].some((a)=>n?.startsWith(a))&&typeof t==="string"&&t!==""&&s===t}function F(n){return n?.tokens??[]}function S(n){return n.tokens===void 0?n.value??"":n.trailingText}function I(...n){return n.some((t)=>F(t).length>0)}function v(n){let t=F(n);return t.length===0?"no tokens":`tokens ${JSON.stringify(t)}`}function V(n,t){let s=Array.from(t),a=0;for(let d of n)if(d===s[a])a++;return a===s.length}function _(n,t,s){if(!I(t,s))return;if(F(s).length>F(t).length)return{success:!0};let a=S(t),d=S(s);if(a===void 0||d===void 0)return{success:!0,warning:"iOS typed text result was not verified: the recipient field's value does not follow its tokens."};if(a===d)return{success:!1,error:`iOS nothing was typed: no new recipient token was committed and the text after the tokens is unchanged (${v(s)}).`};return V(d,n)?{success:!0}:{success:!0,warning:`iOS typed text changed in the recipient field; text after the tokens: ${JSON.stringify(d)} (${v(s)}).`}}function D(n,t,s){if(!I(t,s))return;let a=F(t);if(F(s).length>a.length)return`a new recipient token was committed (${v(s)}).`;let c=t===void 0?"":S(t),f=S(s);if(c===void 0||f===void 0)return`the recipient field's value does not follow its tokens, so the typed text is unknown (${v(s)}).`;if(c===f)return`no new recipient token was committed and the text after the tokens is unchanged (${v(s)}).`;return V(f,n)?`the text after the recipient tokens now contains the typed characters (${v(s)}).`:`the text after the recipient tokens changed to ${JSON.stringify(f)} (partial or altered input; ${v(s)}).`}class N extends K{extractNodeProperties(n){let t=we(n),s=t.class??t.className;if(t.password===!0||t.password==="true"||typeof s==="string"&&s.includes("SecureTextField"))return{focused:t.focused,class:s,password:!0,editable:t.editable,actions:t.actions,"resource-id":t["resource-id"],bounds:t.bounds};return super.extractNodeProperties(n)}}var k=512,M=`iOS typed text result was not verified: the focused field value fills the ${k}-character read window, so a change past it cannot be seen.`;function B(n,t,s,a){let d=t.length+n.length-s.length;if(d<0||!a&&d!==0)return!1;for(let c=s.indexOf(n);c!==-1;c=s.indexOf(n,c+1)){if(s.slice(0,c)!==t.slice(0,c))return!1;if(s.slice(c+n.length)===t.slice(c+d))return!0}return!1}function Z(n,t,s,a){if(s.length===k)return{success:!0,warning:M};if(t===s)return{success:!1,error:"iOS nothing was typed: the focused field value is unchanged."};return B(n,t,s,a)?{success:!0}:{success:!1,error:"iOS typed text chunk was not fully appended to the focused field."}}function C(n,t={secure:!1},s={secure:!1},a=!1){if(t.secure||s.secure)return{success:!0,warning:"iOS typed text check skipped for a secure field."};let d=typeof a==="boolean"?a:a.verifyAppend,c=Q(t);return(d?ee(n,c,s,typeof a!=="boolean"&&a.firstChunk===!0):void 0)??te(n,c,s)}function Q(n){return n.iosNativeValueOmitted===!0&&n.value===void 0?{...n,value:""}:n}function ee(n,t,s,a){if(t.identity!==void 0&&s.identity!==void 0&&t.identity!==s.identity)return{success:!0,warning:"iOS typed text result was not verified: focus moved to another field."};let d=t.nativeEditableValues??{},c=s.nativeEditableValues??{};if(Object.keys(d).some((f)=>Object.hasOwn(c,f)&&d[f]!==c[f]&&B(n,d[f],c[f],a)))return{success:!0};if(t.value!==void 0&&s.value!==void 0&&!I(t,s))return Z(n,t.value,s.value,a);return}function te(n,t,s){if(H(t.nativeEditableValues,s.nativeEditableValues)==="changed")return{success:!0};let d=_(n,t,s);if(d!==void 0)return d;if(t.value===void 0||s.value===void 0)return{success:!0,warning:"iOS typed text result was not verified: the focused field could not be read."};if(s.value.length>=k)return{success:!0,warning:M};if(t.value===s.value)return{success:!1,error:"iOS nothing was typed: the focused field value is unchanged."};return L(s.value,n)?{success:!0}:{success:!0,warning:`iOS typed text changed in the focused field; observed value: ${JSON.stringify(s.value)}.`}}function ne(n,t,s){if(s===void 0)return"the focused field could not be read, so what was committed is unknown.";if(t?.secure||s.secure)return"the focused field is secure; its content was not inspected.";let a=D(n,t,s);if(a!==void 0)return a;if(H(t?.nativeEditableValues,s.nativeEditableValues)==="changed")return"another editable on screen changed (a recipient or token entry may hold the text), so the focused field's value does not show what was committed.";return re(n,t?.value,s.value)}function re(n,t,s){if(s!==void 0&&s.length>=k)return`the focused field's value fills the ${k}-character read window, so what was committed is unknown.`;if(t===void 0||s===void 0)return"the focused field's value could not be read, so what was committed is unknown.";if(t===s)return"the focused field's value is unchanged from before typing; entries held as separate tokens would not show in it.";return L(s,n)?"the focused field now contains the typed characters.":`the focused field's value changed to ${JSON.stringify(s)} (partial or altered input).`}function H(n={},t={}){let s=Object.keys(n).filter((a)=>Object.hasOwn(t,a));if(s.some((a)=>n[a]!==t[a]))return"changed";return s.length>0?"unchanged":"unavailable"}function L(n,t){let s=Array.from(t),a=0;for(let d of n)if(d===s[a])a++;return a===s.length}function ie(n,t){let s=es(),a=s===void 0?void 0:s-n.now();return t===void 0?a:Math.min(t,a??t)}async function Bh(n,t={},s){let a=await w5(n,t,s);return a.kind==="read"?a.field:void 0}async function w5(n,t={},s){let{observer:a,timer:d,signal:c,display:f}=n,h=me(c),m=ie(d,s);if(h?.aborted||m!==void 0&&m<=0)return{kind:"unavailable"};let p=new AbortController,b=je(h,p.signal);try{let T=await l(()=>a.execute({freshness:"fresh",skipScreenshot:!0,skipAccessibilityAudit:!0,signal:b,timeoutMs:m,...f===void 0?{}:{display:f}}),{timer:d,timeoutMs:m,signal:b,label:"iOS typed text verification",onTimeout:()=>p.abort()}),y=T.viewHierarchy;if(T.freshness?.isFresh===!1||!y||y.hierarchy.error)return{kind:"unavailable"};return{kind:"read",field:nl(y,new N,{...t,includeIosNativeEditableValues:!0}),hasFocusedTextInput:xa(y,new N),keyboardVisible:KB(T.viewHierarchy,T.screenSize)}}catch{return e.warn("[iOS typed text] Focused field read unavailable; result cannot be verified"),{kind:"unavailable"}}}var oe=1000,se=250;async function BF(n,t,s,a=!1){let{timer:d,signal:c}=s,f=typeof a==="boolean"?a:a.verifyAppend;if(t?.secure&&!f)return{...C(n,t,void 0),after:t};let h=await Bh(s,{includeIdentity:f}),m=C(n,t,h,a),p=d.now()+oe;while(!m.success&&I(t,h)&&d.now()<p)c?.throwIfAborted(),await d.sleep(se),h=await Bh(s,{includeIdentity:f},Math.max(0,p-d.now())),m=C(n,t,h,a);return{...m,after:h}}var ae=2000;async function $F(n,t,s,a){if(!WB(n))return n;let d=s?.secure?s:await Bh(a,{},ae);return`${n} Observed afterwards: ${ne(t,s,d)}`}var de=3,ue=Wt([100,200]);function ce(n,t){return Object.entries(n?.nativeEditableValues??{}).some(([s,a])=>a!==""&&t?.nativeEditableValues?.[s]==="")}function le(n){return n?.keyboardNativeEditableValue===""}function W(n,t,s=1,a){if(ce(a,n)||le(n))return{success:!0};if(n?.secure)return{success:!0,warning:"iOS clear check skipped for a secure field."};if(n?.value===void 0){if(t!==void 0)return{success:!1,partialApplication:!0,error:`iOS clear could not be verified after ${s} attempt(s); the focused field last held ${JSON.stringify(t)} and could not be read again.`};return{success:!0,warning:"iOS clear was not verified: the focused field could not be read."}}if(n.value===t)return fe(n.value,s,a?.value);return n.value===""?{success:!0}:n.value}function fe(n,t,s){if(n!==""&&n===s)return{success:!1,error:`iOS clear removed nothing after ${t} attempt(s): the runner acknowledged each clear, but the focused field still holds its pre-clear value; remaining value: ${JSON.stringify(n)}.`};return{success:!0,warning:`The field still holds ${JSON.stringify(n)} after the clear was acknowledged and retried; it may be a mask or permanent prefix at its cleared content, or the app may have refused the clear.`}}function U(n){if(n===void 0)return"unreadable";let t=Object.entries(n.nativeEditableValues??{}).map(([s,a])=>`${s}:${a.length}`);return`focusedLength=${n.value?.length??"none"} native={${t.join(",")}} keyboardEditableLength=${n.keyboardNativeEditableValue?.length??"none"}`}async function he(n,t,s){s?.throwIfAborted();let a=ue.delayForAttempt(t),d=es();if(d!==void 0&&d-n.now()<=a)return!1;await l(()=>n.sleep(a),{timer:n,signal:s,label:"iOS clear retry"}),s?.throwIfAborted();let c=es();return c===void 0||c>n.now()}async function RV({clear:n,observer:t,timer:s,signal:a,display:d}){let c=me(a),f=async(w=!1)=>{c?.throwIfAborted();let g=await Bh({observer:t,timer:s,signal:c,display:d},{iosPlaceholderAsBlank:!0});if(c?.throwIfAborted(),w&&!g?.secure&&g?.value===void 0)e.warn("[iOS clear] Pre-clear field read unavailable; using post-clear verification only");return g},h=await f(!0),m=await n();if(!m.success)return m;if(c?.throwIfAborted(),h?.secure)return{success:!0,warning:"iOS clear check skipped for a secure field."};let p=await f(),b=W(p,void 0,1,h),T=1;while(typeof b==="string"&&T<de){if(!await he(s,T,c))break;let w=await n();if(T++,!w.success)return{...w,partialApplication:!0};p=await f(),b=W(p,b,T,h)}let y=typeof b==="string"?{success:!1,partialApplication:!0,error:`iOS clear left text in the focused field after ${T} attempt(s); remaining value: ${JSON.stringify(b)}.`}:b;if(!y.success)e.warn(`[iOS clear] Verification failed; before ${U(h)}; after ${U(p)}`);return y}class R{editables=[];keyboardTop;recordKeyboard(n){if(n)this.keyboardTop=Math.min(this.keyboardTop??n.top,n.top)}recordEditable(n,t){if(t)this.editables.push({value:n,bounds:t})}soleValueAboveKeyboard(){let n=this.keyboardTop;if(n===void 0)return;let t=this.editables.filter((s)=>s.bounds.bottom<=n);return t.length===1?t[0].value:void 0}}function pe(n,t){return n!==null&&t!==null&&n.left>=t.left&&n.right<=t.right&&n.top>=t.top&&n.bottom<=t.bottom}function xe(n,t,s){let a=s.extractNodeProperties(n),d=Vt(a),c=d.textSources.text;if(!(d.className==="UIButton"||a.role==="button")||!dt(a.clickable)||d.nativeId!==void 0||c===void 0||c===""||!pe(Tt(qt(n)),t))return;return c}function ye(n,t){let s=n;for(let a of t){if(!s.startsWith(a))return;s=s.slice(a.length),s=s.startsWith(" ")?s.slice(1):s}return s}function G(n,t,s){let a=Tt(qt(n)),d=(n.node??[]).flatMap((f)=>xe(f,a,s)??[]);if(d.length===0)return;let c=t===void 0?void 0:ye(t,d);return c===void 0?{tokens:d}:{tokens:d,trailingText:c}}var UF=1000,q=50;function A(n,t){let s=t.extractWindowRootGroups(n,"topmost-first"),a=t.extractRootNodes(n),d=new Set,c=(f)=>f.filter((h)=>{if(d.has(h))return!1;return d.add(h),!0});return[...s,a].map(c).filter((f)=>f.length>0)}function be(n,t){let s=Vt(n),a=s.textSources.value??s.textSources.text,d=["android.","androidx."].some((f)=>s.className?.startsWith(f));if(!t&&LF(s.className,n["hint-text"],a))return 0;let c=typeof a==="string"?a.length:s.capturedTextLength;if(c===void 0&&d&&O(n)&&!dt(n.password))return 0;return c}function su(n,t=new K,s=!1){for(let a of A(n,t)){let d;for(let c of a)t.traverseNode(c,(f)=>{let h=t.extractNodeProperties(f),m=be(h,s);if((h.focused==="true"||h.focused===!0)&&m!==void 0)d=Math.max(d??0,m)});if(d!==void 0)return d}return}function xa(n,t=new K){for(let s of A(n,t))for(let a of s){let d=!1;if(t.traverseNode(a,(c)=>{if(d)return;let f=t.extractNodeProperties(c);if(O(f))d=!0}),d)return!0}return!1}function HF(n,t=new K){for(let s of A(n,t)){let a;for(let d of s)t.traverseNode(d,(c)=>{let f=t.extractNodeProperties(c);if(a!==void 0||!O(f))return;a=Y(f,!0)});if(a!==void 0)return a}return}function Y(n,t=!1){let s=Vt(n);if(!t&&s.nativeId===void 0&&s.bounds===void 0)return;return JSON.stringify([s.nativeId??null,s.className??null,s.bounds?.left??null,s.bounds?.top??null])}function nl(n,t=new K,s={}){for(let a of A(n,t)){let d,c=s.includeIosNativeEditableValues?{}:void 0,f=s.includeIosNativeEditableValues?new R:void 0;for(let h of a){let m,p;if(t.traverseNode(h,(b,T)=>{if(p!==void 0&&T<=p)p=void 0;let y=t.extractNodeProperties(b),w=y.class??y.className;if(p===void 0&&w==="WKWebView")p=T;if(p===void 0)ge(y,c),Fe(b,y,f);if(!O(y))return;let g=ke(b,y,s,t);if(g===void 0)return;d??=g,m??=p===void 0?Te(g,s):void 0}),m!==void 0)return m}if(c&&Object.keys(c).length>0)return ve(d,c,f);if(d!==void 0)return d}return}function Te(n,t){return t.includeIosNativeEditableValues&&!n.secure&&n.value===void 0?{...n,iosNativeValueOmitted:!0}:n}function ge(n,t){if(!t||dt(n.focused)||!z(n))return;let s=Vt(n),a=n["view-id"]??s.nativeId;if(typeof a==="string"&&a!==""){let d=typeof n.value==="string"?n.value:"";t[a]=d===n["hint-text"]?"":d}}function ve(n,t,s){let a=s?.soleValueAboveKeyboard();return{...n??{secure:!1},nativeEditableValues:t,...a===void 0?{}:{keyboardNativeEditableValue:a}}}function Fe(n,t,s){if(!s)return;if((t.class??t.className)==="UIKeyboard"){s.recordKeyboard(Tt(qt(n)));return}if(z(t)){let d=typeof t.value==="string"?t.value:"";s.recordEditable(d===t["hint-text"]?"":d,Tt(qt(n)))}}function X(n){let t=n.class??n.className;return dt(n.password)||typeof t==="string"&&t.includes("SecureTextField")}function z(n){let t=n.class??n.className;if(X(n))return!1;return n.role==="textfield"||Array.isArray(n.actions)&&n.actions.includes("set_text")||typeof t==="string"&&/UITextField|UISearchBar|UITextView/.test(t)}function Ie(n,t){let s=Vt(n),a=X(n),d=s.textSources.value??s.textSources.text??(s.capturedTextLength===0?"":void 0);if(a)return{value:d,secure:a};let c=t.iosEmptyAsBlank?j(s.textSources):t.iosPlaceholderAsBlank?s.textSources.value===void 0?void 0:j(s.textSources):d;return c!==void 0||t.includeIosNativeEditableValues?{value:c,secure:a}:void 0}function ke(n,t,s,a){let d=Ie(t,s),c=d&&s.includeIdentity?{...d,identity:Y({...t,bounds:qt(n)})}:d;if(c===void 0||c.secure)return c;let f=G(n,c.value,a);return f===void 0?c:{...c,...f}}function j(n){let t=n.value;return t===void 0||t===n["hint-text"]?"":t}function O(n){if(n.focused!=="true"&&n.focused!==!0)return!1;let t=n.class??n.className,s=typeof t==="string"&&(t.includes("SecureTextField")||_g.some((f)=>t.includes(f))),a=n.actions,d=Array.isArray(a)&&a.includes("set_text"),c=n.editable==="true"||n.editable===!0;return s||d||c}async function PV(n,t,{signal:s,onDelete:a,supportsKeyCombination:d}={}){if(s?.throwIfAborted(),await n.executeCommand(d?"shell input keycombination KEYCODE_CTRL_LEFT KEYCODE_A":"shell input keyevent KEYCODE_MOVE_END"),s?.throwIfAborted(),d){await n.executeCommand("shell input keyevent KEYCODE_DEL"),a?.(),s?.throwIfAborted();return}for(let c=0;c<t;c+=q){s?.throwIfAborted();let f=Math.min(q,t-c),h=Array(f).fill("KEYCODE_DEL").join(" ");await n.executeCommand(`shell input keyevent ${h}`),a?.(),s?.throwIfAborted()}}async function AV(n,t,s=new K){o(t);try{let a=await n();o(t);let d=a.viewHierarchy;if(a.freshness?.isFresh===!1||!d||d.hierarchy.error||!xa(d,s))return{success:!1,error:"Cannot verify key-event clear: no fresh focused editable field available"};let c=su(d,s);if(c===void 0)return{success:!1,error:"Cannot verify key-event clear: focused field text length is unreadable"};return c===0?{success:!0}:{success:!1,error:`Field was not fully cleared: ${c} UTF-16 units remain`}}catch(a){return o(t),e.warn("[ClearText] Key-event clear verification unavailable",a),{success:!1,error:`Cannot verify key-event clear: ${r(a)}`}}}class _ae extends Oe{parser;androidKeyCombinationSupported;constructor(n,t=null,s=new K,a=i){super(n,{adb:t,timer:a});this.parser=s}async execute(n,t){t?.throwIfAborted();let s=J();return s.serial("clearText"),this.observedInteraction(async(a)=>{try{switch(this.device.platform){case"android":return await s.track("androidClearText",()=>this.executeAndroidClearText(a,t));case"ios":return await s.track("iOSClearText",()=>this.executeiOSClearText(a,t));default:throw s.end(),St(this.device.platform,"clear text")}}catch(d){s.end(),t?.throwIfAborted();let c=u(d,"Failed to clear text");return e.warn(`[ClearText] ${c.message}`),{success:!1,error:c.message}}},{...Kt.textEdit,tolerancePercent:0,timeoutMs:At.immediate,progress:n,signal:t,perf:s})}get testHooks(){return{executeAndroidClearText:this.executeAndroidClearText.bind(this),executeiOSClearText:this.executeiOSClearText.bind(this)}}async executeAndroidClearText(n,t){let s=n.viewHierarchy,a=n;if(s&&!s.hierarchy.error&&!xa(s,this.parser)){let f=await this.refreshFocusedTextInputObservation(s,t).catch((h)=>{t?.throwIfAborted(),e.warn("[ClearText] Focus refresh unavailable; trying live clearing",h);return});if(f?.viewHierarchy&&!xa(f.viewHierarchy,this.parser))return{success:!1,error:"No focused editable node found"};a=f??{...n,viewHierarchy:void 0}}let d=E.getInstance(this.device,this.adbFactory);t?.throwIfAborted();let c=await d.requestClearText();if(t?.throwIfAborted(),c.success)return e.info(`[ClearText] Cleared text via accessibility service: ${c.totalTimeMs}ms`),{success:!0};return e.warn(`[ClearText] Accessibility service clear failed: ${c.error}, falling back to ADB`),this.executeAdbClearText(a,t)}async refreshFocusedTextInputObservation(n,t){let s;if(typeof n.updatedAt==="number")s=n.updatedAt+1;else{t?.throwIfAborted();let c=await this.adb.getDeviceTimestampMsWithSource();if(t?.throwIfAborted(),c.source==="host")return;s=c.source==="device-seconds"?c.timestampMs+UF:c.timestampMs}t?.throwIfAborted();let a=await this.observeScreen.execute({freshness:"fresh",minTimestamp:s,signal:t,skipScreenshot:!0});t?.throwIfAborted();let d=a.viewHierarchy;return a.freshness?.isFresh!==!1&&d&&!d.hierarchy.error?a:void 0}async executeAdbClearText(n,t){let s=n.viewHierarchy,d=(s&&!s.hierarchy.error?su(s,this.parser):void 0)??200;if(d===0)return{success:!0};return await this.clearWithDeletes(d,t),AV(()=>this.observeScreen.execute({freshness:"fresh",minTimestamp:0,signal:t,skipScreenshot:!0}),t,this.parser)}async executeiOSClearText(n,t){let s=Date.now();e.debug("[ClearText] iOS begin");try{let a=x.getInstance(this.device);t?.throwIfAborted();let c=await RV({clear:()=>{let f=es();return a.requestClearText(void 0,5000,void 0,{abortSignal:t,...f===void 0?{}:{deadlineMs:f}})},observer:this.observeScreen,timer:this.timer,signal:t});if(c.retryable!==!1)t?.throwIfAborted();if(c.success)return e.info(`[ClearText] Cleared text via CtrlProxy iOS totalMs=${Date.now()-s}`),{success:!0,..."warning"in c&&c.warning?{warnings:[c.warning]}:{}};return e.warn(`[ClearText] CtrlProxy iOS clear failed: ${c.error} totalMs=${Date.now()-s}`),{success:!1,error:c.error,...c.retryable===!1?{retryable:!1}:{}}}catch(a){return t?.throwIfAborted(),e.warn(`[ClearText] CtrlProxy iOS exception: ${r(a)} totalMs=${Date.now()-s}`,a),{success:!1,error:String(a)}}}findAnyTextInputLength(n){let t=0;for(let s of A(n,this.parser))for(let a of s)this.parser.traverseNode(a,(d)=>{let c=this.parser.extractNodeProperties(d),f=Vt(c).textSources.text;if(c.class&&_g.some((h)=>c.class.includes(h))&&f&&typeof f==="string")t=Math.max(t,f.length)});return t}async clearWithDeletes(n,t){this.androidKeyCombinationSupported??=Ut(this.adb,1000,this.timer).then((a)=>a!==null&&a>=gd).catch((a)=>{throw this.androidKeyCombinationSupported=void 0,u(a,"Failed to read Android key-combination capability")});let s=await P(this.androidKeyCombinationSupported,t);await PV(this.adb,n,{signal:t,supportsKeyCombination:s})}}
|
|
3
|
+
export{LF,Bh,w5,BF,$F,RV,UF,su,xa,HF,nl,PV,AV,_ae};
|
|
4
|
+
|
|
5
|
+
//# debugId=24BFED71E3BDBBC864756E2164756E21
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{f,I}from"./chunk-58wzr3mt.js";import{t}from"./chunk-rbpdk7m0.js";import{existsSync as E}from"fs";var dA=f.IOS_SCREEN_CAPTURE_HELPER.name,d=f.IOS_SCREEN_CAPTURE_HELPER.legacyName;function gS(r=process.env){return I(f.IOS_SCREEN_CAPTURE_HELPER,r)}function yS(r,n={}){let o=n.env??process.env,s=n.exists??E,a=[r,gS(o)].filter((e)=>Boolean(e));for(let e of a)if(s(e))return e;throw new t(`No executable screen-capture-helper was found at the configured path. Set ${dA} to the absolute path of a local development build.`)}
|
|
3
|
+
export{dA,gS,yS};
|
|
4
|
+
|
|
5
|
+
//# debugId=4893595AD89A891D64756E2164756E21
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
3
|
-
export{
|
|
2
|
+
import{Y,I}from"./chunk-58wzr3mt.js";import{Bl}from"./chunk-qcxzr2my.js";import*as c from"fs";import*as l from"os";import*as n from"path";function D3(o={}){let t={env:o.env??process.env,platform:o.platform??process.platform,homedir:o.homedir??l.homedir,directoryExists:o.directoryExists??b};f(t),m(t)}function f(o){let{env:t,directoryExists:e}=o,r=n.delimiter,i=t.PATH??"",s=new Set(i.split(r).filter(Boolean)),u=h(o),a=[];for(let d of u)if(!s.has(d)&&e(d))a.push(d),s.add(d);if(a.length===0)return;t.PATH=i.length>0?`${i}${r}${a.join(r)}`:a.join(r)}function m(o){let{env:t,directoryExists:e}=o;if(t.ANDROID_HOME||t.ANDROID_SDK_ROOT)return;for(let r of A(o))if(e(r)){t.ANDROID_HOME=r;return}}function h({env:o,platform:t,homedir:e}){let r=e();if(t==="darwin")return["/usr/bin","/bin","/usr/sbin","/sbin","/usr/local/bin","/usr/local/sbin","/opt/homebrew/bin","/opt/homebrew/sbin",n.join(r,"Library/Android/sdk/platform-tools"),n.join(r,"Library/Android/sdk/emulator"),n.join(r,"Library/Android/sdk/cmdline-tools/latest/bin")];if(t==="linux")return["/usr/bin","/bin","/usr/sbin","/sbin","/usr/local/bin","/usr/local/sbin",n.join(r,"Android/Sdk/platform-tools"),n.join(r,"Android/Sdk/emulator"),n.join(r,"Android/Sdk/cmdline-tools/latest/bin")];if(t==="win32"){let i=I(Y.LOCALAPPDATA,o),s=i?n.join(i,"Android","Sdk"):"";return[...s?[n.join(s,"platform-tools"),n.join(s,"emulator"),n.join(s,"cmdline-tools","latest","bin")]:[]]}return[]}function A({env:o,platform:t,homedir:e}){let r=e();if(t==="darwin")return[n.join(r,"Library/Android/sdk")];if(t==="linux")return[n.join(r,"Android/Sdk")];if(t==="win32"){let i=I(Y.LOCALAPPDATA,o);return i?[n.join(i,"Android","Sdk")]:[]}return[]}function b(o){return Bl(()=>c.statSync(o).isDirectory(),()=>!1)}var p=async()=>{};function Jte(o){let t=p;return p=o,()=>{p=t}}function jL(o){return p(o)}
|
|
3
|
+
export{D3,Jte,jL};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=C5674C7F5ACEBD7A64756E2164756E21
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Dr,v,an,N,ft,$t,pt,K,ve,TR,_k,Qo,Hr,Ps,c9,kb,lr,Jie,Mo,x}from"./chunk-r5bxavdx.js";import{i,Tf,Qt,e}from"./chunk-z637nqg8.js";import{fu,Pv,Po,vn,Tv,FW,Oa,td}from"./chunk-0qsy1qsx.js";import{r,t}from"./chunk-rbpdk7m0.js";import{Nt,M,wt}from"./chunk-qcxzr2my.js";var me=M(function(ps,Ze){var Ke=wt("util"),pe=wt("stream"),B=Ze.exports=function(){pe.call(this),this._buffers=[],this._buffered=0,this._reads=[],this._paused=!1,this._encoding="utf8",this.writable=!0};Ke.inherits(B,pe);B.prototype.read=function(n,s){this._reads.push({length:Math.abs(n),allowLess:n<0,func:s}),process.nextTick(function(){if(this._process(),this._paused&&this._reads&&this._reads.length>0)this._paused=!1,this.emit("drain")}.bind(this))};B.prototype.write=function(n,s){if(!this.writable)return this.emit("error",Error("Stream not writable")),!1;let o;if(Buffer.isBuffer(n))o=n;else o=Buffer.from(n,s||this._encoding);if(this._buffers.push(o),this._buffered+=o.length,this._process(),this._reads&&this._reads.length===0)this._paused=!0;return this.writable&&!this._paused};B.prototype.end=function(n,s){if(n)this.write(n,s);if(this.writable=!1,!this._buffers)return;if(this._buffers.length===0)this._end();else this._buffers.push(null),this._process()};B.prototype.destroySoon=B.prototype.end;B.prototype._end=function(){if(this._reads.length>0)this.emit("error",Error("Unexpected end of input"));this.destroy()};B.prototype.destroy=function(){if(!this._buffers)return;this.writable=!1,this._reads=null,this._buffers=null,this.emit("close")};B.prototype._processReadAllowingLess=function(n){this._reads.shift();let s=this._buffers[0];if(s.length>n.length)this._buffered-=n.length,this._buffers[0]=s.slice(n.length),n.func.call(this,s.slice(0,n.length));else this._buffered-=s.length,this._buffers.shift(),n.func.call(this,s)};B.prototype._processRead=function(n){this._reads.shift();let s=0,o=0,a=Buffer.alloc(n.length);while(s<n.length){let l=this._buffers[o++],c=Math.min(l.length,n.length-s);if(l.copy(a,s,0,c),s+=c,c!==l.length)this._buffers[--o]=l.slice(c)}if(o>0)this._buffers.splice(0,o);this._buffered-=n.length,n.func.call(this,a)};B.prototype._process=function(){try{while(this._buffered>0&&this._reads&&this._reads.length>0){let n=this._reads[0];if(n.allowLess)this._processReadAllowingLess(n);else if(this._buffered>=n.length)this._processRead(n);else break}if(this._buffers&&!this.writable)this._end()}catch(n){this.emit("error",n)}}});var ge=M(function(Zr){var F=[{x:[0],y:[0]},{x:[4],y:[0]},{x:[0,4],y:[4]},{x:[2,6],y:[0,4]},{x:[0,2,4,6],y:[2,6]},{x:[1,3,5,7],y:[0,2,4,6]},{x:[0,1,2,3,4,5,6,7],y:[1,3,5,7]}];Zr.getImagePasses=function(n,s){let o=[],a=n%8,l=s%8,c=(n-a)/8,u=(s-l)/8;for(let h=0;h<F.length;h++){let d=F[h],f=c*d.x.length,p=u*d.y.length;for(let g=0;g<d.x.length;g++)if(d.x[g]<a)f++;else break;for(let g=0;g<d.y.length;g++)if(d.y[g]<l)p++;else break;if(f>0&&p>0)o.push({width:f,height:p,index:h})}return o};Zr.getInterlaceIterator=function(n){return function(s,o,a){let l=s%F[a].x.length,c=(s-l)/F[a].x.length*8+F[a].x[l],u=o%F[a].y.length,h=(o-u)/F[a].y.length*8+F[a].y[u];return c*4+h*n*4}}});var be=M(function(gs,Qe){Qe.exports=function(s,o,a){let l=s+o-a,c=Math.abs(l-s),u=Math.abs(l-o),h=Math.abs(l-a);if(c<=u&&c<=h)return s;if(u<=h)return o;return a}});var ye=M(function(bs,tt){var et=ge(),ei=be();function Je(n,s,o){let a=n*s;if(o!==8)a=Math.ceil(a/(8/o));return a}var Y=tt.exports=function(n,s){let{width:o,height:a,interlace:l,bpp:c,depth:u}=n;if(this.read=s.read,this.write=s.write,this.complete=s.complete,this._imageIndex=0,this._images=[],l){let h=et.getImagePasses(o,a);for(let d=0;d<h.length;d++)this._images.push({byteWidth:Je(h[d].width,c,u),height:h[d].height,lineIndex:0})}else this._images.push({byteWidth:Je(o,c,u),height:a,lineIndex:0});if(u===8)this._xComparison=c;else if(u===16)this._xComparison=c*2;else this._xComparison=1};Y.prototype.start=function(){this.read(this._images[this._imageIndex].byteWidth+1,this._reverseFilterLine.bind(this))};Y.prototype._unFilterType1=function(n,s,o){let a=this._xComparison,l=a-1;for(let c=0;c<o;c++){let u=n[1+c],h=c>l?s[c-a]:0;s[c]=u+h}};Y.prototype._unFilterType2=function(n,s,o){let a=this._lastLine;for(let l=0;l<o;l++){let c=n[1+l],u=a?a[l]:0;s[l]=c+u}};Y.prototype._unFilterType3=function(n,s,o){let a=this._xComparison,l=a-1,c=this._lastLine;for(let u=0;u<o;u++){let h=n[1+u],d=c?c[u]:0,f=u>l?s[u-a]:0,p=Math.floor((f+d)/2);s[u]=h+p}};Y.prototype._unFilterType4=function(n,s,o){let a=this._xComparison,l=a-1,c=this._lastLine;for(let u=0;u<o;u++){let h=n[1+u],d=c?c[u]:0,f=u>l?s[u-a]:0,p=u>l&&c?c[u-a]:0,g=ei(f,d,p);s[u]=h+g}};Y.prototype._reverseFilterLine=function(n){let s=n[0],o,a=this._images[this._imageIndex],l=a.byteWidth;if(s===0)o=n.slice(1,l+1);else switch(o=Buffer.alloc(l),s){case 1:this._unFilterType1(n,o,l);break;case 2:this._unFilterType2(n,o,l);break;case 3:this._unFilterType3(n,o,l);break;case 4:this._unFilterType4(n,o,l);break;default:throw Error("Unrecognised filter type - "+s)}if(this.write(o),a.lineIndex++,a.lineIndex>=a.height)this._lastLine=null,this._imageIndex++,a=this._images[this._imageIndex];else this._lastLine=o;if(a)this.read(a.byteWidth+1,this._reverseFilterLine.bind(this));else this._lastLine=null,this.complete()}});var nt=M(function(ys,it){var rt=wt("util"),Se=me(),ti=ye(),ri=it.exports=function(n){Se.call(this);let s=[],o=this;this._filter=new ti(n,{read:this.read.bind(this),write:function(a){s.push(a)},complete:function(){o.emit("complete",Buffer.concat(s))}}),this._filter.start()};rt.inherits(ri,Se)});var G=M(function(Ss,st){st.exports={PNG_SIGNATURE:[137,80,78,71,13,10,26,10],TYPE_IHDR:1229472850,TYPE_IEND:1229278788,TYPE_IDAT:1229209940,TYPE_PLTE:1347179589,TYPE_tRNS:1951551059,TYPE_gAMA:1732332865,COLORTYPE_GRAYSCALE:0,COLORTYPE_PALETTE:1,COLORTYPE_COLOR:2,COLORTYPE_ALPHA:4,COLORTYPE_PALETTE_COLOR:3,COLORTYPE_COLOR_ALPHA:6,COLORTYPE_TO_BPP_MAP:{0:1,2:3,3:1,4:2,6:4},GAMMA_DIVISION:1e5}});var Ee=M(function(ws,ot){var we=[];(function(){for(let n=0;n<256;n++){let s=n;for(let o=0;o<8;o++)if(s&1)s=3988292384^s>>>1;else s=s>>>1;we[n]=s}})();var _e=ot.exports=function(){this._crc=-1};_e.prototype.write=function(n){for(let s=0;s<n.length;s++)this._crc=we[(this._crc^n[s])&255]^this._crc>>>8;return!0};_e.prototype.crc32=function(){return this._crc^-1};_e.crc32=function(n){let s=-1;for(let o=0;o<n.length;o++)s=we[(s^n[o])&255]^s>>>8;return s^-1}});var Ce=M(function(_s,at){var w=G(),ii=Ee(),T=at.exports=function(n,s){this._options=n,n.checkCRC=n.checkCRC!==!1,this._hasIHDR=!1,this._hasIEND=!1,this._emittedHeadersFinished=!1,this._palette=[],this._colorType=0,this._chunks={},this._chunks[w.TYPE_IHDR]=this._handleIHDR.bind(this),this._chunks[w.TYPE_IEND]=this._handleIEND.bind(this),this._chunks[w.TYPE_IDAT]=this._handleIDAT.bind(this),this._chunks[w.TYPE_PLTE]=this._handlePLTE.bind(this),this._chunks[w.TYPE_tRNS]=this._handleTRNS.bind(this),this._chunks[w.TYPE_gAMA]=this._handleGAMA.bind(this),this.read=s.read,this.error=s.error,this.metadata=s.metadata,this.gamma=s.gamma,this.transColor=s.transColor,this.palette=s.palette,this.parsed=s.parsed,this.inflateData=s.inflateData,this.finished=s.finished,this.simpleTransparency=s.simpleTransparency,this.headersFinished=s.headersFinished||function(){}};T.prototype.start=function(){this.read(w.PNG_SIGNATURE.length,this._parseSignature.bind(this))};T.prototype._parseSignature=function(n){let s=w.PNG_SIGNATURE;for(let o=0;o<s.length;o++)if(n[o]!==s[o]){this.error(Error("Invalid file signature"));return}this.read(8,this._parseChunkBegin.bind(this))};T.prototype._parseChunkBegin=function(n){let s=n.readUInt32BE(0),o=n.readUInt32BE(4),a="";for(let c=4;c<8;c++)a+=String.fromCharCode(n[c]);let l=Boolean(n[4]&32);if(!this._hasIHDR&&o!==w.TYPE_IHDR){this.error(Error("Expected IHDR on beggining"));return}if(this._crc=new ii,this._crc.write(Buffer.from(a)),this._chunks[o])return this._chunks[o](s);if(!l){this.error(Error("Unsupported critical chunk type "+a));return}this.read(s+4,this._skipChunk.bind(this))};T.prototype._skipChunk=function(){this.read(8,this._parseChunkBegin.bind(this))};T.prototype._handleChunkEnd=function(){this.read(4,this._parseChunkEnd.bind(this))};T.prototype._parseChunkEnd=function(n){let s=n.readInt32BE(0),o=this._crc.crc32();if(this._options.checkCRC&&o!==s){this.error(Error("Crc error - "+s+" - "+o));return}if(!this._hasIEND)this.read(8,this._parseChunkBegin.bind(this))};T.prototype._handleIHDR=function(n){this.read(n,this._parseIHDR.bind(this))};T.prototype._parseIHDR=function(n){this._crc.write(n);let s=n.readUInt32BE(0),o=n.readUInt32BE(4),a=n[8],l=n[9],c=n[10],u=n[11],h=n[12];if(a!==8&&a!==4&&a!==2&&a!==1&&a!==16){this.error(Error("Unsupported bit depth "+a));return}if(!(l in w.COLORTYPE_TO_BPP_MAP)){this.error(Error("Unsupported color type"));return}if(c!==0){this.error(Error("Unsupported compression method"));return}if(u!==0){this.error(Error("Unsupported filter method"));return}if(h!==0&&h!==1){this.error(Error("Unsupported interlace method"));return}this._colorType=l;let d=w.COLORTYPE_TO_BPP_MAP[this._colorType];this._hasIHDR=!0,this.metadata({width:s,height:o,depth:a,interlace:Boolean(h),palette:Boolean(l&w.COLORTYPE_PALETTE),color:Boolean(l&w.COLORTYPE_COLOR),alpha:Boolean(l&w.COLORTYPE_ALPHA),bpp:d,colorType:l}),this._handleChunkEnd()};T.prototype._handlePLTE=function(n){this.read(n,this._parsePLTE.bind(this))};T.prototype._parsePLTE=function(n){this._crc.write(n);let s=Math.floor(n.length/3);for(let o=0;o<s;o++)this._palette.push([n[o*3],n[o*3+1],n[o*3+2],255]);this.palette(this._palette),this._handleChunkEnd()};T.prototype._handleTRNS=function(n){this.simpleTransparency(),this.read(n,this._parseTRNS.bind(this))};T.prototype._parseTRNS=function(n){if(this._crc.write(n),this._colorType===w.COLORTYPE_PALETTE_COLOR){if(this._palette.length===0){this.error(Error("Transparency chunk must be after palette"));return}if(n.length>this._palette.length){this.error(Error("More transparent colors than palette size"));return}for(let s=0;s<n.length;s++)this._palette[s][3]=n[s];this.palette(this._palette)}if(this._colorType===w.COLORTYPE_GRAYSCALE)this.transColor([n.readUInt16BE(0)]);if(this._colorType===w.COLORTYPE_COLOR)this.transColor([n.readUInt16BE(0),n.readUInt16BE(2),n.readUInt16BE(4)]);this._handleChunkEnd()};T.prototype._handleGAMA=function(n){this.read(n,this._parseGAMA.bind(this))};T.prototype._parseGAMA=function(n){this._crc.write(n),this.gamma(n.readUInt32BE(0)/w.GAMMA_DIVISION),this._handleChunkEnd()};T.prototype._handleIDAT=function(n){if(!this._emittedHeadersFinished)this._emittedHeadersFinished=!0,this.headersFinished();this.read(-n,this._parseIDAT.bind(this,n))};T.prototype._parseIDAT=function(n,s){if(this._crc.write(s),this._colorType===w.COLORTYPE_PALETTE_COLOR&&this._palette.length===0)throw Error("Expected palette not found");this.inflateData(s);let o=n-s.length;if(o>0)this._handleIDAT(o);else this._handleChunkEnd()};T.prototype._handleIEND=function(n){this.read(n,this._parseIEND.bind(this))};T.prototype._parseIEND=function(n){if(this._crc.write(n),this._hasIEND=!0,this._handleChunkEnd(),this.finished)this.finished()}});var ke=M(function(ci){var re=ge(),ni=[function(){},function(n,s,o,a){if(a===s.length)throw Error("Ran out of data");let l=s[a];n[o]=l,n[o+1]=l,n[o+2]=l,n[o+3]=255},function(n,s,o,a){if(a+1>=s.length)throw Error("Ran out of data");let l=s[a];n[o]=l,n[o+1]=l,n[o+2]=l,n[o+3]=s[a+1]},function(n,s,o,a){if(a+2>=s.length)throw Error("Ran out of data");n[o]=s[a],n[o+1]=s[a+1],n[o+2]=s[a+2],n[o+3]=255},function(n,s,o,a){if(a+3>=s.length)throw Error("Ran out of data");n[o]=s[a],n[o+1]=s[a+1],n[o+2]=s[a+2],n[o+3]=s[a+3]}],si=[function(){},function(n,s,o,a){let l=s[0];n[o]=l,n[o+1]=l,n[o+2]=l,n[o+3]=a},function(n,s,o){let a=s[0];n[o]=a,n[o+1]=a,n[o+2]=a,n[o+3]=s[1]},function(n,s,o,a){n[o]=s[0],n[o+1]=s[1],n[o+2]=s[2],n[o+3]=a},function(n,s,o){n[o]=s[0],n[o+1]=s[1],n[o+2]=s[2],n[o+3]=s[3]}];function oi(n,s){let o=[],a=0;function l(){if(a===n.length)throw Error("Ran out of data");let c=n[a];a++;let u,h,d,f,p,g,m,b;switch(s){default:throw Error("unrecognised depth");case 16:m=n[a],a++,o.push((c<<8)+m);break;case 4:m=c&15,b=c>>4,o.push(b,m);break;case 2:p=c&3,g=c>>2&3,m=c>>4&3,b=c>>6&3,o.push(b,m,g,p);break;case 1:u=c&1,h=c>>1&1,d=c>>2&1,f=c>>3&1,p=c>>4&1,g=c>>5&1,m=c>>6&1,b=c>>7&1,o.push(b,m,g,p,f,d,h,u);break}}return{get:function(c){while(o.length<c)l();let u=o.slice(0,c);return o=o.slice(c),u},resetAfterLine:function(){o.length=0},end:function(){if(a!==n.length)throw Error("extra data found")}}}function ai(n,s,o,a,l,c){let{width:u,height:h,index:d}=n;for(let f=0;f<h;f++)for(let p=0;p<u;p++){let g=o(p,f,d);ni[a](s,l,g,c),c+=a}return c}function li(n,s,o,a,l,c){let{width:u,height:h,index:d}=n;for(let f=0;f<h;f++){for(let p=0;p<u;p++){let g=l.get(a),m=o(p,f,d);si[a](s,g,m,c)}l.resetAfterLine()}}ci.dataToBitMap=function(n,s){let{width:o,height:a,depth:l,bpp:c,interlace:u}=s,h;if(l!==8)h=oi(n,l);let d;if(l<=8)d=Buffer.alloc(o*a*4);else d=new Uint16Array(o*a*4);let f=Math.pow(2,l)-1,p=0,g,m;if(u)g=re.getImagePasses(o,a),m=re.getInterlaceIterator(o,a);else{let b=0;m=function(){let _=b;return b+=4,_},g=[{width:o,height:a}]}for(let b=0;b<g.length;b++)if(l===8)p=ai(g[b],d,m,c,n,p);else li(g[b],d,m,c,h,f);if(l===8){if(p!==n.length)throw Error("extra data found")}else h.end();return d}});var Te=M(function(Cs,lt){function hi(n,s,o,a,l){let c=0;for(let u=0;u<a;u++)for(let h=0;h<o;h++){let d=l[n[c]];if(!d)throw Error("index "+n[c]+" not in palette");for(let f=0;f<4;f++)s[c+f]=d[f];c+=4}}function di(n,s,o,a,l){let c=0;for(let u=0;u<a;u++)for(let h=0;h<o;h++){let d=!1;if(l.length===1){if(l[0]===n[c])d=!0}else if(l[0]===n[c]&&l[1]===n[c+1]&&l[2]===n[c+2])d=!0;if(d)for(let f=0;f<4;f++)s[c+f]=0;c+=4}}function fi(n,s,o,a,l){let c=255,u=Math.pow(2,l)-1,h=0;for(let d=0;d<a;d++)for(let f=0;f<o;f++){for(let p=0;p<4;p++)s[h+p]=Math.floor(n[h+p]*c/u+0.5);h+=4}}lt.exports=function(n,s,o=!1){let{depth:a,width:l,height:c,colorType:u,transColor:h,palette:d}=s,f=n;if(u===3)hi(n,f,l,c,d);else{if(h)di(n,f,l,c,h);if(a!==8&&!o){if(a===16)f=Buffer.alloc(l*c*4);fi(n,f,l,c,a)}}return f}});var dt=M(function(ks,ht){var ct=wt("util"),X=wt("zlib"),Ie=me(),pi=nt(),mi=Ce(),ut=ke(),gi=Te(),D=ht.exports=function(n){Ie.call(this),this._parser=new mi(n,{read:this.read.bind(this),error:this._handleError.bind(this),metadata:this._handleMetaData.bind(this),gamma:this.emit.bind(this,"gamma"),palette:this._handlePalette.bind(this),transColor:this._handleTransColor.bind(this),finished:this._finished.bind(this),inflateData:this._inflateData.bind(this),simpleTransparency:this._simpleTransparency.bind(this),headersFinished:this._headersFinished.bind(this)}),this._options=n,this.writable=!0,this._parser.start()};ct.inherits(D,Ie);D.prototype._handleError=function(n){if(this.emit("error",n),this.writable=!1,this.destroy(),this._inflate&&this._inflate.destroy)this._inflate.destroy();if(this._filter)this._filter.destroy(),this._filter.on("error",function(){});this.errord=!0};D.prototype._inflateData=function(n){if(!this._inflate)if(this._bitmapInfo.interlace)this._inflate=X.createInflate(),this._inflate.on("error",this.emit.bind(this,"error")),this._filter.on("complete",this._complete.bind(this)),this._inflate.pipe(this._filter);else{let o=((this._bitmapInfo.width*this._bitmapInfo.bpp*this._bitmapInfo.depth+7>>3)+1)*this._bitmapInfo.height,a=Math.max(o,X.Z_MIN_CHUNK);this._inflate=X.createInflate({chunkSize:a});let l=o,c=this.emit.bind(this,"error");this._inflate.on("error",function(h){if(!l)return;c(h)}),this._filter.on("complete",this._complete.bind(this));let u=this._filter.write.bind(this._filter);this._inflate.on("data",function(h){if(!l)return;if(h.length>l)h=h.slice(0,l);l-=h.length,u(h)}),this._inflate.on("end",this._filter.end.bind(this._filter))}this._inflate.write(n)};D.prototype._handleMetaData=function(n){this._metaData=n,this._bitmapInfo=Object.create(n),this._filter=new pi(this._bitmapInfo)};D.prototype._handleTransColor=function(n){this._bitmapInfo.transColor=n};D.prototype._handlePalette=function(n){this._bitmapInfo.palette=n};D.prototype._simpleTransparency=function(){this._metaData.alpha=!0};D.prototype._headersFinished=function(){this.emit("metadata",this._metaData)};D.prototype._finished=function(){if(this.errord)return;if(!this._inflate)this.emit("error","No Inflate block");else this._inflate.end()};D.prototype._complete=function(n){if(this.errord)return;let s;try{let o=ut.dataToBitMap(n,this._bitmapInfo);s=gi(o,this._bitmapInfo,this._options.skipRescale),o=null}catch(o){this._handleError(o);return}this.emit("parsed",s)}});var gt=M(function(Ts,mt){var k=G();mt.exports=function(n,s,o,a){let l=[k.COLORTYPE_COLOR_ALPHA,k.COLORTYPE_ALPHA].indexOf(a.colorType)!==-1;if(a.colorType===a.inputColorType){let _=function(){let C=new ArrayBuffer(2);return new DataView(C).setInt16(0,256,!0),new Int16Array(C)[0]!==256}();if(a.bitDepth===8||a.bitDepth===16&&_)return n}let c=a.bitDepth!==16?n:new Uint16Array(n.buffer),u=255,h=k.COLORTYPE_TO_BPP_MAP[a.inputColorType];if(h===4&&!a.inputHasAlpha)h=3;let d=k.COLORTYPE_TO_BPP_MAP[a.colorType];if(a.bitDepth===16)u=65535,d*=2;let f=Buffer.alloc(s*o*d),p=0,g=0,m=a.bgColor||{};if(m.red===void 0)m.red=u;if(m.green===void 0)m.green=u;if(m.blue===void 0)m.blue=u;function b(){let _,C,S,y=u;switch(a.inputColorType){case k.COLORTYPE_COLOR_ALPHA:y=c[p+3],_=c[p],C=c[p+1],S=c[p+2];break;case k.COLORTYPE_COLOR:_=c[p],C=c[p+1],S=c[p+2];break;case k.COLORTYPE_ALPHA:y=c[p+1],_=c[p],C=_,S=_;break;case k.COLORTYPE_GRAYSCALE:_=c[p],C=_,S=_;break;default:throw Error("input color type:"+a.inputColorType+" is not supported at present")}if(a.inputHasAlpha){if(!l)y/=u,_=Math.min(Math.max(Math.round((1-y)*m.red+y*_),0),u),C=Math.min(Math.max(Math.round((1-y)*m.green+y*C),0),u),S=Math.min(Math.max(Math.round((1-y)*m.blue+y*S),0),u)}return{red:_,green:C,blue:S,alpha:y}}for(let _=0;_<o;_++)for(let C=0;C<s;C++){let S=b(c,p);switch(a.colorType){case k.COLORTYPE_COLOR_ALPHA:case k.COLORTYPE_COLOR:if(a.bitDepth===8){if(f[g]=S.red,f[g+1]=S.green,f[g+2]=S.blue,l)f[g+3]=S.alpha}else if(f.writeUInt16BE(S.red,g),f.writeUInt16BE(S.green,g+2),f.writeUInt16BE(S.blue,g+4),l)f.writeUInt16BE(S.alpha,g+6);break;case k.COLORTYPE_ALPHA:case k.COLORTYPE_GRAYSCALE:{let y=(S.red+S.green+S.blue)/3;if(a.bitDepth===8){if(f[g]=y,l)f[g+1]=S.alpha}else if(f.writeUInt16BE(y,g),l)f.writeUInt16BE(S.alpha,g+2);break}default:throw Error("unrecognised color Type "+a.colorType)}p+=h,g+=d}return f}});var St=M(function(Is,yt){var bt=be();function bi(n,s,o,a,l){for(let c=0;c<o;c++)a[l+c]=n[s+c]}function yi(n,s,o){let a=0,l=s+o;for(let c=s;c<l;c++)a+=Math.abs(n[c]);return a}function Si(n,s,o,a,l,c){for(let u=0;u<o;u++){let h=u>=c?n[s+u-c]:0,d=n[s+u]-h;a[l+u]=d}}function wi(n,s,o,a){let l=0;for(let c=0;c<o;c++){let u=c>=a?n[s+c-a]:0,h=n[s+c]-u;l+=Math.abs(h)}return l}function _i(n,s,o,a,l){for(let c=0;c<o;c++){let u=s>0?n[s+c-o]:0,h=n[s+c]-u;a[l+c]=h}}function Ei(n,s,o){let a=0,l=s+o;for(let c=s;c<l;c++){let u=s>0?n[c-o]:0,h=n[c]-u;a+=Math.abs(h)}return a}function Ci(n,s,o,a,l,c){for(let u=0;u<o;u++){let h=u>=c?n[s+u-c]:0,d=s>0?n[s+u-o]:0,f=n[s+u]-(h+d>>1);a[l+u]=f}}function ki(n,s,o,a){let l=0;for(let c=0;c<o;c++){let u=c>=a?n[s+c-a]:0,h=s>0?n[s+c-o]:0,d=n[s+c]-(u+h>>1);l+=Math.abs(d)}return l}function Ti(n,s,o,a,l,c){for(let u=0;u<o;u++){let h=u>=c?n[s+u-c]:0,d=s>0?n[s+u-o]:0,f=s>0&&u>=c?n[s+u-(o+c)]:0,p=n[s+u]-bt(h,d,f);a[l+u]=p}}function Ii(n,s,o,a){let l=0;for(let c=0;c<o;c++){let u=c>=a?n[s+c-a]:0,h=s>0?n[s+c-o]:0,d=s>0&&c>=a?n[s+c-(o+a)]:0,f=n[s+c]-bt(u,h,d);l+=Math.abs(f)}return l}var xi={0:bi,1:Si,2:_i,3:Ci,4:Ti},Oi={0:yi,1:wi,2:Ei,3:ki,4:Ii};yt.exports=function(n,s,o,a,l){let c;if(!("filterType"in a)||a.filterType===-1)c=[0,1,2,3,4];else if(typeof a.filterType==="number")c=[a.filterType];else throw Error("unrecognised filter types");if(a.bitDepth===16)l*=2;let u=s*l,h=0,d=0,f=Buffer.alloc((u+1)*o),p=c[0];for(let g=0;g<o;g++){if(c.length>1){let m=1/0;for(let b=0;b<c.length;b++){let _=Oi[c[b]](n,d,u,l);if(_<m)p=c[b],m=_}}f[h]=p,h++,xi[p](n,d,u,f,h,l),h+=u,d+=u}return f}});var xe=M(function(xs,Ct){var E=G(),_t=Ee(),Ai=gt(),Ri=St(),Et=wt("zlib"),U=Ct.exports=function(n){if(this._options=n,n.deflateChunkSize=n.deflateChunkSize||32768,n.deflateLevel=n.deflateLevel!=null?n.deflateLevel:9,n.deflateStrategy=n.deflateStrategy!=null?n.deflateStrategy:3,n.inputHasAlpha=n.inputHasAlpha!=null?n.inputHasAlpha:!0,n.deflateFactory=n.deflateFactory||Et.createDeflate,n.bitDepth=n.bitDepth||8,n.colorType=typeof n.colorType==="number"?n.colorType:E.COLORTYPE_COLOR_ALPHA,n.inputColorType=typeof n.inputColorType==="number"?n.inputColorType:E.COLORTYPE_COLOR_ALPHA,[E.COLORTYPE_GRAYSCALE,E.COLORTYPE_COLOR,E.COLORTYPE_COLOR_ALPHA,E.COLORTYPE_ALPHA].indexOf(n.colorType)===-1)throw Error("option color type:"+n.colorType+" is not supported at present");if([E.COLORTYPE_GRAYSCALE,E.COLORTYPE_COLOR,E.COLORTYPE_COLOR_ALPHA,E.COLORTYPE_ALPHA].indexOf(n.inputColorType)===-1)throw Error("option input color type:"+n.inputColorType+" is not supported at present");if(n.bitDepth!==8&&n.bitDepth!==16)throw Error("option bit depth:"+n.bitDepth+" is not supported at present")};U.prototype.getDeflateOptions=function(){return{chunkSize:this._options.deflateChunkSize,level:this._options.deflateLevel,strategy:this._options.deflateStrategy}};U.prototype.createDeflate=function(){return this._options.deflateFactory(this.getDeflateOptions())};U.prototype.filterData=function(n,s,o){let a=Ai(n,s,o,this._options),l=E.COLORTYPE_TO_BPP_MAP[this._options.colorType];return Ri(a,s,o,this._options,l)};U.prototype._packChunk=function(n,s){let o=s?s.length:0,a=Buffer.alloc(o+12);if(a.writeUInt32BE(o,0),a.writeUInt32BE(n,4),s)s.copy(a,8);return a.writeInt32BE(_t.crc32(a.slice(4,a.length-4)),a.length-4),a};U.prototype.packGAMA=function(n){let s=Buffer.alloc(4);return s.writeUInt32BE(Math.floor(n*E.GAMMA_DIVISION),0),this._packChunk(E.TYPE_gAMA,s)};U.prototype.packIHDR=function(n,s){let o=Buffer.alloc(13);return o.writeUInt32BE(n,0),o.writeUInt32BE(s,4),o[8]=this._options.bitDepth,o[9]=this._options.colorType,o[10]=0,o[11]=0,o[12]=0,this._packChunk(E.TYPE_IHDR,o)};U.prototype.packIDAT=function(n){return this._packChunk(E.TYPE_IDAT,n)};U.prototype.packIEND=function(){return this._packChunk(E.TYPE_IEND,null)}});var Ot=M(function(Os,xt){var kt=wt("util"),Oe=wt("stream"),Tt=G(),vi=xe(),It=xt.exports=function(n){Oe.call(this);let s=n||{};this._packer=new vi(s),this._deflate=this._packer.createDeflate(),this.readable=!0};kt.inherits(It,Oe);It.prototype.pack=function(n,s,o,a){if(this.emit("data",Buffer.from(Tt.PNG_SIGNATURE)),this.emit("data",this._packer.packIHDR(s,o)),a)this.emit("data",this._packer.packGAMA(a));let l=this._packer.filterData(n,s,o);this._deflate.on("error",this.emit.bind(this,"error")),this._deflate.on("data",function(c){this.emit("data",this._packer.packIDAT(c))}.bind(this)),this._deflate.on("end",function(){this.emit("data",this._packer.packIEND()),this.emit("end")}.bind(this)),this._deflate.end(l)}});var Bt=M(function(Z,Mt){var At=wt("assert").ok,P=wt("zlib"),Pt=wt("util"),Rt=wt("buffer").kMaxLength;function H(n){if(!(this instanceof H))return new H(n);if(n&&n.chunkSize<P.Z_MIN_CHUNK)n.chunkSize=P.Z_MIN_CHUNK;if(P.Inflate.call(this,n),this._offset=this._offset===void 0?this._outOffset:this._offset,this._buffer=this._buffer||this._outBuffer,n&&n.maxLength!=null)this._maxLength=n.maxLength}function Pi(n){return new H(n)}function vt(n,s){if(s)process.nextTick(s);if(!n._handle)return;n._handle.close(),n._handle=null}H.prototype._processChunk=function(n,s,o){if(typeof o==="function")return P.Inflate._processChunk.call(this,n,s,o);let a=this,l=n&&n.length,c=this._chunkSize-this._offset,u=this._maxLength,h=0,d=[],f=0,p;this.on("error",function(_){p=_});function g(_,C){if(a._hadError)return;let S=c-C;if(At(S>=0,"have should not go down"),S>0){let y=a._buffer.slice(a._offset,a._offset+S);if(a._offset+=S,y.length>u)y=y.slice(0,u);if(d.push(y),f+=y.length,u-=y.length,u===0)return!1}if(C===0||a._offset>=a._chunkSize)c=a._chunkSize,a._offset=0,a._buffer=Buffer.allocUnsafe(a._chunkSize);if(C===0)return h+=l-_,l=_,!0;return!1}At(this._handle,"zlib binding closed");let m;do m=this._handle.writeSync(s,n,h,l,this._buffer,this._offset,c),m=m||this._writeState;while(!this._hadError&&g(m[0],m[1]));if(this._hadError)throw p;if(f>=Rt)throw vt(this),RangeError("Cannot create final Buffer. It would be larger than 0x"+Rt.toString(16)+" bytes");let b=Buffer.concat(d,f);return vt(this),b};Pt.inherits(H,P.Inflate);function Li(n,s){if(typeof s==="string")s=Buffer.from(s);if(!(s instanceof Buffer))throw TypeError("Not a string or buffer");let o=n._finishFlushFlag;if(o==null)o=P.Z_FINISH;return n._processChunk(s,o)}function Lt(n,s){return Li(new H(s),n)}Mt.exports=Z=Lt;Z.Inflate=H;Z.createInflate=Pi;Z.inflateSync=Lt});var Ae=M(function(As,Ft){var Dt=Ft.exports=function(n){this._buffer=n,this._reads=[]};Dt.prototype.read=function(n,s){this._reads.push({length:Math.abs(n),allowLess:n<0,func:s})};Dt.prototype.process=function(){while(this._reads.length>0&&this._buffer.length){let n=this._reads[0];if(this._buffer.length&&(this._buffer.length>=n.length||n.allowLess)){this._reads.shift();let s=this._buffer;this._buffer=s.slice(n.length),n.func.call(this,s.slice(0,n.length))}else break}if(this._reads.length>0)throw Error("There are some read requests waitng on finished stream");if(this._buffer.length>0)throw Error("unrecognised content at end of stream")}});var Ut=M(function(Di){var Mi=Ae(),Bi=ye();Di.process=function(n,s){let o=[],a=new Mi(n);return new Bi(s,{read:a.read.bind(a),write:function(c){o.push(c)},complete:function(){}}).start(),a.process(),Buffer.concat(o)}});var qt=M(function(vs,zt){var Wt=!0,ie=wt("zlib"),Ni=Bt();if(!ie.deflateSync)Wt=!1;var Ui=Ae(),Ht=Ut(),Wi=Ce(),Vt=ke(),Hi=Te();zt.exports=function(n,s){if(!Wt)throw Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let o;function a(O){o=O}let l;function c(O){l=O}function u(O){l.transColor=O}function h(O){l.palette=O}function d(){l.alpha=!0}let f;function p(O){f=O}let g=[];function m(O){g.push(O)}let b=new Ui(n);if(new Wi(s,{read:b.read.bind(b),error:a,metadata:c,gamma:p,palette:h,transColor:u,inflateData:m,simpleTransparency:d}).start(),b.process(),o)throw o;let C=Buffer.concat(g);g.length=0;let S;if(l.interlace)S=ie.inflateSync(C);else{let z=((l.width*l.bpp*l.depth+7>>3)+1)*l.height;S=Ni(C,{chunkSize:z,maxLength:z})}if(C=null,!S||!S.length)throw Error("bad png - invalid inflate data response");let y=Ht.process(S,l);C=null;let R=Vt.dataToBitMap(y,l);y=null;let W=Hi(R,l,s.skipRescale);return l.data=W,l.gamma=f||0,l}});var jt=M(function(Ls,Xt){var Yt=!0,ne=wt("zlib");if(!ne.deflateSync)Yt=!1;var Gt=G(),Vi=xe();Xt.exports=function(n,s){if(!Yt)throw Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");let a=new Vi(s||{}),l=[];if(l.push(Buffer.from(Gt.PNG_SIGNATURE)),l.push(a.packIHDR(n.width,n.height)),n.gamma)l.push(a.packGAMA(n.gamma));let c=a.filterData(n.data,n.width,n.height),u=ne.deflateSync(c,a.getDeflateOptions());if(c=null,!u||!u.length)throw Error("bad png - invalid compressed data response");return l.push(a.packIDAT(u)),l.push(a.packIEND()),Buffer.concat(l)}});var Kt=M(function(qi){var $i=qt(),zi=jt();qi.read=function(n,s){return $i(n,s||{})};qi.write=function(n,s){return zi(n,s)}});var GF=M(function(Zi){var Zt=wt("util"),Re=wt("stream"),Xi=dt(),ji=Ot(),Ki=Kt(),A=Zi.PNG=function(n){if(Re.call(this),n=n||{},this.width=n.width|0,this.height=n.height|0,this.data=this.width>0&&this.height>0?Buffer.alloc(4*this.width*this.height):null,n.fill&&this.data)this.data.fill(0);this.gamma=0,this.readable=this.writable=!0,this._parser=new Xi(n),this._parser.on("error",this.emit.bind(this,"error")),this._parser.on("close",this._handleClose.bind(this)),this._parser.on("metadata",this._metadata.bind(this)),this._parser.on("gamma",this._gamma.bind(this)),this._parser.on("parsed",function(s){this.data=s,this.emit("parsed",s)}.bind(this)),this._packer=new ji(n),this._packer.on("data",this.emit.bind(this,"data")),this._packer.on("end",this.emit.bind(this,"end")),this._parser.on("close",this._handleClose.bind(this)),this._packer.on("error",this.emit.bind(this,"error"))};Zt.inherits(A,Re);A.sync=Ki;A.prototype.pack=function(){if(!this.data||!this.data.length)return this.emit("error","No data provided"),this;return process.nextTick(function(){this._packer.pack(this.data,this.width,this.height,this.gamma)}.bind(this)),this};A.prototype.parse=function(n,s){if(s){let o,a;o=function(l){this.removeListener("error",a),this.data=l,s(null,this)}.bind(this),a=function(l){this.removeListener("parsed",o),s(l,null)}.bind(this),this.once("parsed",o),this.once("error",a)}return this.end(n),this};A.prototype.write=function(n){return this._parser.write(n),!0};A.prototype.end=function(n){this._parser.end(n)};A.prototype._metadata=function(n){this.width=n.width,this.height=n.height,this.emit("metadata",n)};A.prototype._gamma=function(n){this.gamma=n};A.prototype._handleClose=function(){if(!this._parser.writable&&!this._packer.readable)this.emit("close")};A.bitblt=function(n,s,o,a,l,c,u,h){if(o|=0,a|=0,l|=0,c|=0,u|=0,h|=0,o>n.width||a>n.height||o+l>n.width||a+c>n.height)throw Error("bitblt reading outside image");if(u>s.width||h>s.height||u+l>s.width||h+c>s.height)throw Error("bitblt writing outside image");for(let d=0;d<c;d++)n.data.copy(s.data,(h+d)*s.width+u<<2,(a+d)*n.width+o<<2,(a+d)*n.width+o+l<<2)};A.prototype.bitblt=function(n,s,o,a,l,c,u){return A.bitblt(this,n,s,o,a,l,c,u),this};A.adjustGamma=function(n){if(n.gamma){for(let s=0;s<n.height;s++)for(let o=0;o<n.width;o++){let a=n.width*s+o<<2;for(let l=0;l<3;l++){let c=n.data[a+l]/255;c=Math.pow(c,0.45454545454545453/n.gamma),n.data[a+l]=Math.round(c*255)}}n.gamma=0}};A.prototype.adjustGamma=function(){A.adjustGamma(this)}});function E5(n,s,o,a){TR(n,s,[{x:Math.floor(o),y:Math.floor(a)}],"swipe")}function I5(n,s){let o=(s.left+s.right)/2,a=(s.top+s.bottom)/2,l=s.bottom-s.top,c=s.right-s.left;switch(n){case"down":return{startX:o,startY:s.top+l*0.25,endX:o,endY:s.top+l*0.75};case"up":return{startX:o,startY:s.bottom-l*0.25,endX:o,endY:s.top+l*0.25};case"right":return{startX:s.left+c*0.25,startY:a,endX:s.left+c*0.75,endY:a};case"left":return{startX:s.right-c*0.25,startY:a,endX:s.left+c*0.25,endY:a}}}var rr={up:"down",down:"up",left:"right",right:"left"},ir=(n)=>{let{direction:s,gestureType:o}=n;if(!s)return{error:"direction is required"};if(!o||o==="swipeFingerTowardsDirection")return{direction:s,message:`Swiping ${s} (finger gesture)`};return{direction:rr[s],message:`Scrolling ${s} to reveal content ${s==="up"?"above":s==="down"?"below":s==="left"?"from left":"from right"}`}},Yc=(n)=>ir(n);class Jc{parser;constructor(n=new K){this.parser=n}extract(n){if(!n?.hierarchy)return;let s=[],o,a=[],l=n.windows?.filter((u)=>u.hierarchy)??[];if(this.parser.traverseNode(n.hierarchy,(u,h)=>{let d=this.parser.extractNodeProperties(u),f=this.getAttribute(d,["resource-id","resourceId"]);if(f&&f.startsWith("navigation.")&&f.endsWith("Destination"))o=f.replace("navigation.","");if(this.getAttribute(d,["selected"])==="true"){let p=this.extractSelectedElement(u,d,f);if(p)s.push(p)}if(l.length===0)this.collectModalStack(a,d,h)}),l.length>0)this.collectWindowModals(a,l);let c=this.normalizeModalStack(a);if(s.length===0&&!o&&c.length===0)return;return{selectedElements:s,destinationId:o,modalStack:c.length>0?c:void 0}}extractSelectedElement(n,s,o){let a={},l=this.getAttribute(s,["text"]),c=this.getAttribute(s,["content-desc","contentDesc"]);if(l)a.text=l;if(o)a.resourceId=o;if(c)a.contentDesc=c;if(!a.text&&n.node){let u=this.findTextInChildren(n.node);if(u)a.text=u}return a.text||a.resourceId||a.contentDesc?a:void 0}collectWindowModals(n,s){for(let[o,a]of s.entries()){let l=a.id??void 0,c=a.type!==void 0?String(a.type):void 0,u=a.windowLayer??o;this.parser.traverseNode(a.hierarchy,(h,d)=>{let f=this.parser.extractNodeProperties(h);this.collectModalStack(n,f,u+d,{windowId:l,windowType:c})})}}extractFromObservation(n){if(!n?.viewHierarchy)return;let s=this.extract(n.viewHierarchy),o=s?.selectedElements??[];if(o.length>0){let l=this.applySelectedState(o,{method:"accessibility",confidence:1,reason:"selected attribute present in view hierarchy"});return{...s,selectedElements:l}}let a=n.selectedElements??[];if(a.length>0){if(s)return{...s,selectedElements:a};return{selectedElements:a}}return s}applySelectedState(n,s){return n.map((o)=>({...o,selectedState:o.selectedState??s}))}findTextInChildren(n){if(Array.isArray(n))for(let s of n){let o=this.parser.extractNodeProperties(s),a=this.getAttribute(o,["text"]);if(a)return a;if(!s.node)continue;let l=this.findTextInChildren(s.node);if(l)return l}else if(n&&typeof n==="object"){let s=this.parser.extractNodeProperties(n),o=this.getAttribute(s,["text"]);if(o)return o;if(n.node)return this.findTextInChildren(n.node)}return}getAttribute(n,s){for(let o of s){let a=n[o];if(typeof a==="string"&&a!=="")return a}return}collectModalStack(n,s,o,a){let l=this.getAttribute(s,["class","className"]);if(!l)return;let c=this.classifyModalType(l);if(!c)return;let u=this.getModalIdentifier(s,l),h=this.getWindowId(s,a?.windowId,c,{modalId:u,className:l}),d=this.getWindowType(s,a?.windowType);n.push({type:c,identifier:u,layer:o,windowId:h,windowType:d})}getWindowId(n,s,o,{modalId:a,className:l}){let c=this.getAttribute(n,["window-id","windowId","window_id"]),u=c?Number(c):NaN;if(Number.isFinite(u))return u;if(s!==void 0)return s;let h=`${o}:${a??l}`;return this.hashToId(h)}getWindowType(n,s){return this.getAttribute(n,["window-type","windowType","window_type"])??s}classifyModalType(n){let s=n.toLowerCase();if(s.includes("alert")||s.includes("dialog"))return"dialog";if(s.includes("actionsheet")||s.includes("sheet"))return"bottomsheet";if(s.includes("popover"))return"popup";if(s.includes("menu"))return"menu";if(s.includes("modal")||s.includes("presentation"))return"overlay";return null}getModalIdentifier(n,s){return this.getAttribute(n,["resource-id","resourceId","content-desc","contentDesc","text"])??s}hashToId(n){let s=0;for(let o=0;o<n.length;o+=1)s=s*31+n.charCodeAt(o)>>>0;return s}normalizeModalStack(n){if(n.length===0)return[];let s=new Map;for(let o of n){let a=o.identifier??`${o.type}-${o.layer}`;if(!s.has(a))s.set(a,o)}return Array.from(s.values()).sort((o,a)=>o.layer-a.layer).map((o,a)=>({...o,layer:a}))}static createScrollPosition(n){if(!n.lookFor)return;let s=Yc(n);if(!s.direction)return;let o={targetElement:{text:n.lookFor.text,resourceId:n.lookFor.elementId},direction:s.direction};if(n.container)o.container={text:n.container.text,resourceId:n.container.elementId};if(n.speed)o.speed=n.speed;return o}}var nr="Element subtree:",sr=/\{\{(-?[\d.]+), (-?[\d.]+)\}, \{(-?[\d.]+), (-?[\d.]+)\}\}/,or="(?=$|, (?:(?:identifier|label|value|placeholderValue): |(?:Selected|Disabled|Focused)(?:,|$)))",ar=["identifier","label","value"],cr=ar.map((n)=>[n,new RegExp(`, ${n}: '(.*?)'${or}`)]),ur=new Set(["Button","Cell","Link","Switch","Key"]);function hr(n){let s=sr.exec(n);if(!s)return;let[o,a,l,c]=s.slice(1).map(Number);return{left:o,top:a,right:o+l,bottom:a+c}}function dr(n){let s=/^(\s*)(?:\u2192)?([A-Za-z]+)((?:,.*)?)$/.exec(n);if(!s)return;let[,o,a,l]=s,c={depth:o.length,type:a,frame:hr(l)};for(let[u,h]of cr){let d=h.exec(l)?.[1];if(d!==void 0)c[u]=d}return c}function fr(n){let s=n.replace(/\r\n/g,`
|
|
3
|
+
`).split(`
|
|
4
|
+
`),o=s.findIndex((l)=>l.trim()===nr);if(o<0)return[];let a=s.findIndex((l,c)=>c>o&&/^\S/.test(l));return s.slice(o+1,a<0?void 0:a).map(dr).filter((l)=>l!==void 0)}function De(n,s){return{className:n.type,bounds:n.frame??s,accessibilityIdentifier:n.identifier,accessibilityLabel:n.label??n.value,hasTapTarget:ur.has(n.type),children:[]}}function pr(n,s){let o=De(n[0],s),a=[{depth:n[0].depth,node:o}];for(let l of n.slice(1)){while(a.length>1&&a[a.length-1].depth>=l.depth)a.pop();let c=a[a.length-1].node,u=De(l,c.bounds);c.children.push(u),a.push({depth:l.depth,node:u})}return o}function Fe(n,s){let o=fr(n),a=o.find((l)=>l.type==="Window"&&l.frame)?.frame;if(o.length===0||!a)throw new t("The watch XCUI dump has no element subtree with a window frame; capture it again.");return{timestamp:s.timestamp,screenWidth:a.right-a.left,screenHeight:a.bottom-a.top,screenScale:1,bundleId:s.bundleId,root:pr(o,a)}}var mr="com.apple.clockface",gr="widget";var br="Smart Stack Header",Ne="StackCollectionView",Ue="StackCollectionViewComplicationCell",q=" -- ";function yr(n,s){let o=/^(.*)-(\d+)$/.exec(n);if(!o)return;let[,a,l]=o,c=`${s}-`,u=a.startsWith(c)?a.slice(c.length):"",h=u.startsWith(`${s}.`)?u.indexOf("-"):-1;return{index:Number(l),...h>0&&h<u.length-1?{extensionBundleId:u.slice(0,h),widgetKind:u.slice(h+1)}:{}}}function Sr(n,s){if(n.length>2&&s){let o=s.split(q).length;if(n.slice(0,o).join(q)===s&&o<n.length)return[s,n.slice(o).join(q)]}return[n[0],n.slice(1).join(q)]}function J(n,s){let o=n.split(q);if(o[0]!==Ue||o.length<6)return;let[a,...l]=o.slice(1),c=l[l.length-1],u=l[l.length-2],h=yr(c,u);if(!h)return;let[d,f]=Sr(l.slice(0,-2),s);return{cellId:a,appName:d,widgetName:f,hostBundleId:u,descriptor:c,...h}}function j(n){return(n.children??[]).flatMap((s)=>[s,...j(s)])}function ae(n){return[...new Set(n.map((s)=>s.accessibilityLabel).filter((s)=>!!s))]}function wr(n){let s=j(n),o=s.find((c)=>c.accessibilityLabel)?.accessibilityLabel??void 0,a=J(n.accessibilityIdentifier??"",o);if(!a)return;let l=ae(s.filter((c)=>c.className==="StaticText"));return{type:"widget",...a,bounds:n.bounds,texts:l}}function _r(n){let s=n.accessibilityIdentifier??"";if(s.startsWith(`${Ue}${q}`))return wr(n);if(!s.startsWith(Ne)||s.includes(" "))return;return{type:"system",cellKind:s.slice(Ne.length),bounds:n.bounds,texts:ae(j(n))}}function Er(n){return[n,...j(n)].filter((s)=>s.className==="Cell").map((s)=>({cell:s,card:_r(s)}))}function Cr(n){let s=[n,...j(n)].find((a)=>a.accessibilityIdentifier===br);if(!s)return;let o=(s.children??[]).filter((a)=>a.className==="Button");return{bounds:s.bounds,labels:ae(o)}}function kr(n,s){let o=Cr(n);return{...o?{header:o}:{},cards:s.flatMap(({card:a})=>a?[a]:[])}}function We(n,s){let o=Fe(n,{bundleId:mr,timestamp:s.timestamp}),a=Er(o.root);for(let{cell:l,card:c}of a)if(c?.type==="widget")l.role=gr;return{hierarchy:Pv(o),smartStack:kr(o.root,a)}}async function le(n,s,o){try{let a=await n.request({type:"face",op:"dump"},o,{timeoutMs:2000});if(typeof a!=="string")throw Error("Clockface dump was not text");let{hierarchy:l,smartStack:c}=We(a,{timestamp:s()});return c.header||c.cards.length>0?{hierarchy:l,smartStack:c}:void 0}catch(a){e.debug(`Smart Stack tap preflight unavailable: ${r(a)}`);return}}function ee(n,s){let{left:o,top:a,right:l,bottom:c}=n;return l>o&&c>a&&o>=0&&a>=0&&l<=s.screenWidth&&c<=s.screenHeight}function Ve(n){let s=new K().flattenViewHierarchy(n).map((a)=>a.element),o=s.filter((a)=>ee(a.bounds,n));return{all:s,available:o}}function ce(n,s){return(s.elementId!==void 0||s.text!==void 0)&&(s.elementId===void 0||n["resource-id"]===s.elementId||n["view-id"]===s.elementId)&&(s.text===void 0||n.text===s.text)}function Tr(n){let s=new Set;return n.filter((o)=>{let{left:a,top:l,right:c,bottom:u}=o.bounds,h=`${o["resource-id"]??o["view-id"]}|${o.class}|${a},${l},${c},${u}`;if(s.has(h))return!1;return s.add(h),!0})}function ue(n,s){let o=n.filter((a)=>ce(a,s));return s.elementId!==void 0?Tr(o):o}async function he(n,s,o,a){let{screenWidth:l,screenHeight:c}=s;if(!l||!c||!Number.isFinite(o.x)||!Number.isFinite(o.y)||o.x<0||o.y<0||o.x>l||o.y>c)throw new t("Smart Stack tap is outside the screen; use coordinates in points within the watch screen.");await n.request({type:"face",op:"tap",x:o.x/l,y:o.y/c},a)}function Ir(n){let s=[],o;for(let{element:a,depth:l}of n){if(o!==void 0&&l<=o)o=void 0;let c=a["resource-id"];if(o===void 0&&c!==void 0&&J(c)!==void 0)o=l;if(o===void 0)s.push(a)}return s}function He(n,s,o){return o.text!==void 0&&n.texts.includes(o.text)||o.elementId!==void 0&&s?.["resource-id"]===o.elementId}async function $e(n,{hierarchy:s,smartStack:o},a,l){let c=new K().flattenViewHierarchy(s),u=c.map((y)=>y.element),h=o.cards.map((y)=>{let R=u.find((W)=>{let O=W["resource-id"];return O!==void 0&&(y.type==="widget"?J(O)?.cellId===y.cellId:O===`StackCollectionView${y.cellKind}`)});return{card:y,cell:R}}),d=h.filter(({card:y,cell:R})=>ee(y.bounds,s)&&He(y,R,a)),f=Ir(c).filter((y)=>ee(y.bounds,s)),p=ue(f,a)[a.index??0],g=d[a.index??0],m=d.length>0?g?.cell??(g?p:void 0):p;if(!m){let y=h.some(({card:R,cell:W})=>!ee(R.bounds,s)&&He(R,W,a));throw new t(`The Smart Stack is open, but no element matched.${y?" A matching card is off-screen; scroll the Smart Stack (for example with rotateCrown) until it is wholly on screen, then tap again.":""} To observe it, call the face dump, use tapAt with coordinates in points, or call launchApp to bring the host app forward.`)}let{left:b,top:_,right:C,bottom:S}=g?.card.bounds??m.bounds;return await he(n,s,{x:(b+C)/2,y:(_+S)/2},l),{success:!0,action:"tap",element:m}}function cu(n){throw new t(`${n} is not supported by the watchOS runner; use tap, directional swipe, rotateCrown or home.`)}var xr=0.4,Or=30000,Ar="rotateCrown changed nothing",Rr="The focused control's value stayed";function vr(n,s){if(!(n instanceof Oa)||!n.message.startsWith(Ar)||n.message.includes(Rr)||Math.abs(s)>=1)return n;return new Oa(`${n.message} A delta of ${s} is ${Math.abs(s)} of one crown revolution and may be smaller than one step of the focused control; if it is not at its limit, try a larger delta.`,n.errorCode)}async function Uee(n,s,o){if(n.platform!=="watchos")throw new t("rotateCrown requires a watchOS device; target an Apple Watch session.");let{delta:a,velocity:l=1}=s;if(typeof a!=="number"||!Number.isFinite(a)||a===0)throw new t("rotateCrown delta must be a finite non-zero number.");if(typeof l!=="number"||!Number.isFinite(l)||l<=0)throw new t("rotateCrown velocity must be a finite number greater than zero.");o?.throwIfAborted();try{await Po.require(n.deviceId).request({type:"crown",delta:a,velocity:l},o,{timeoutMs:Or})}catch(c){throw vr(c,a)}return{success:!0,delta:a,velocity:l}}function mv(n,s){if(n==="watchos")cu(s)}function te(n,s){let o=Object.entries(n).filter(([a,l])=>l!==void 0&&(l!==!1||a==="ensureChecked")&&!s.includes(a));if(o.length)cu(`watchOS options ${o.map(([a])=>a).join(", ")}`)}async function ze(n,s){let o=Pv(await n.hierarchy(s));return Ve(o)}function Pr(n,s){let o=(a)=>["XCUIElementType(45)","XCUIElementType(49)","XCUIElementType(50)"].includes(a.class??"");return s?n.toSorted((a,l)=>Number(o(l))-Number(o(a))):[...n]}function Lr(n){if(n.action!=="tap")cu(n.action);if(te(n,["action","elementId","text","index"]),n.index!==void 0&&(!Number.isInteger(n.index)||n.index<0))throw new t("watchOS tap index must be a non-negative integer.")}async function xV(n,s,o,a=!1){Lr(s),o?.throwIfAborted();let l=Po.require(n),c=await le(l,()=>i.now(),o);if(c)return $e(l,c,s,o);let{all:u,available:h}=await ze(l,o),f=Pr(ue(h,s),s.text!==void 0&&a)[s.index??0];if(!f)throw new t("No watch element matched; observe and check the identifier or exact text.");let{left:p,top:g,right:m,bottom:b}=f.bounds,_=(p+m)/2,C=(g+b)/2;return await l.request(f["resource-id"]&&u.filter((S)=>S["resource-id"]===f["resource-id"]).length===1?{type:"tap",identifier:f["resource-id"]}:{type:"tap",x:_,y:C},o),{success:!0,action:"tap",element:f}}function Mr(n){if(n.action!==void 0&&n.action!=="tap")cu(n.action);if(te(n,["action","x","y","coordinateSpace"]),n.coordinateSpace!==void 0&&n.coordinateSpace!=="absolute")cu("non-absolute coordinates");if(typeof n.x!=="number"||typeof n.y!=="number"||!Number.isFinite(n.x)||!Number.isFinite(n.y)||n.x<0||n.y<0)throw new t("watchOS tap requires finite non-negative x/y in XCTest points.")}async function Hee(n,s,o){Mr(s),o?.throwIfAborted();let a=Po.require(n),l=await le(a,()=>i.now(),o);if(l)await he(a,l.hierarchy,s,o);else await a.request({type:"tap",x:s.x,y:s.y},o);return{success:!0,x:s.x,y:s.y,action:"tap"}}function Br(n){if(te(n,["direction","gestureType","lookFor","autoTarget"]),n.lookFor)te(n.lookFor,["text","elementId","maxSwipes"]);let s=n.lookFor?n.lookFor.maxSwipes??10:1;if(!Number.isInteger(s)||s<0||s>100)throw new t("watchOS maxSwipes must be an integer from 0 to 100.");return s}function Fr(n,s){return s?{type:"swipe",direction:n,distance:xr}:{type:"swipe",direction:n}}async function qee(n,s,o){let a=Br(s),l={up:"down",down:"up",left:"right",right:"left"},c=s.gestureType==="scrollTowardsDirection"?l[s.direction]:s.direction;if(!Object.hasOwn(l,c))throw new t("Invalid watch swipe direction.");o?.throwIfAborted();let u=Po.require(n),h=0,d;for(;;){if(s.lookFor)d=(await ze(u,o)).available.find((f)=>ce(f,s.lookFor));if(d||h>=a)break;await u.request(Fr(c,!!s.lookFor),o),h++}return{success:s.lookFor===void 0||!!d,...s.lookFor&&!d?{error:"No watch element matched within the swipe limit; observe before trying again."}:{},targetType:"screen",x1:0,y1:0,x2:0,y2:0,duration:0,durationIgnored:!0,warning:"watchOS performs a directional swipe; stroke coordinates and duration are unavailable.",...s.lookFor?{found:!!d,element:d,scrollIterations:h}:{}}}async function Vee(n,s,o){if(s.toLowerCase()!=="home")cu(`press ${s}`);return o?.throwIfAborted(),await Po.require(n).request({type:"home"},o),{success:!0,button:s,keyCode:0}}var Nr=5000;function qe(n,s){throw new t(`The app's SDK web-view bridge rejected the ${s} (${n}). Re-observe and retry; XCTest does not stand in for this result, because the page may have changed.`)}function Ur(n,s){if(_k(n),n.result?.status==="accepted")return{backend:"sdk"};if(n.result)return qe(n.result.reason??n.result.status,s);if(n.failure==="bridge_unavailable"||n.unsupported)return{backend:"xctest",fallbackReason:"unavailable"};return qe(n.failure??n.error??"no reply",s)}function Ye(n,s){return n==="tap"?{click:{snapshotId:s.snapshotId,elementId:s.elementId}}:null}async function fT(n,s,o,{verb:a,signal:l}){if(!n)return{backend:"xctest",fallbackReason:"unavailable"};let c=await n.requestSdkWebActionForIos(s.webViewId,o,{timeoutMs:Nr,signal:l});return Ur(c,a)}var _5=5000,Wr=new Set(["unsupported_action"]);function Vr(n,s,o){switch(n.action){case"tap":return{tap:{observationIdentity:o,elementId:s}};case"longPress":return{longPress:{observationIdentity:o,elementId:s,durationMs:Math.max(0,Math.round(n.longPressDurationMs??500))}};default:return null}}function $r(n){return"longPress"in n?Hr(n.longPress.durationMs):_5}function Ge(n,s){throw new t(`The app's SDK observation bridge rejected the ${s} (${n}). Re-observe and retry; XCTest does not stand in for this result, because the element may have changed.`)}function gC(n,s){if(_k(n),n.result?.status==="accepted")return{backend:"sdk",nextObservationIdentity:n.result.nextObservationIdentity};if(n.result){let o=n.result.reason??n.result.status;return Wr.has(o)?{backend:"xctest",fallbackReason:"unsupported"}:Ge(o,s)}if(n.failure==="bridge_unavailable"||n.unsupported)return{backend:"xctest",fallbackReason:"unavailable"};return Ge(n.failure??n.error??"no reply",s)}function zr(n){let s=n.enabled??(()=>N.isIosSdkObservationBridgeEnabled());return{async tap(o){let a=FW(o.element);if(a&&s()&&o.action!=="focus"){let d=Ye(o.action,a);return d?fT(n.webClient?.()??null,a,d,{verb:"click",signal:o.signal}):{backend:"xctest",fallbackReason:"unsupported"}}let l=Tv(o.element);if(!l||!s()||o.action==="focus")return null;let c=Vr(o,l.elementId,l.observationIdentity);if(!c)return{backend:"xctest",fallbackReason:"unsupported"};let u=n.client();if(!u)return{backend:"xctest",fallbackReason:"unavailable"};let h=await u.requestSdkActionForIos(c,{timeoutMs:$r(c),signal:o.signal});return gC(h,"tap")}}}function Wee(n){return zr({client:()=>x.getExistingInstance(n.deviceId),webClient:()=>x.getExistingInstance(n.deviceId)})}async function KF(n,s,o){if(!fu())return;if(!n)return{searchCriteria:s,nearMisses:[],totalElementsChecked:0};try{let a=await(o??vn(n)).capture({freshness:"fresh",searchRaw:n.platform==="android"&&N.isRawElementSearchEnabled()}),l=new lr,c=s.container?.text?{...s.container,match:"contains"}:s.container,u=l.resolve({id:String(a.receivedAt),nodes:a.nodes},{elementId:s.resourceId,text:s.text,container:c,match:"contains"},{action:"tap"}),h=c?l.resolve({id:String(a.receivedAt),nodes:a.nodes},{container:c},{action:"inspect"}).candidates:a.nodes,d=new Set([...u.candidates,...u.matches.flatMap(({node:m,sourceNodes:b})=>[m,...b??[]])]),f=s.resourceId??s.text??"",p=new kb,g=h.filter((m)=>m.element&&!d.has(m)).flatMap((m)=>Object.entries(s.resourceId?{"resource-id":m.nativeId}:m.textSources).filter(([,b])=>b&&p.partialTextMatch(b,f)).map(([b,_])=>({element:m.element,property:b,value:_,reason:"Similar but did not match the selected mode"}))).slice(0,10);return{searchCriteria:s,nearMisses:g.length?g:void 0,totalElementsChecked:h.length}}catch(a){return e.warn("Could not build element search debug context",a),{searchCriteria:s,nearMisses:[],totalElementsChecked:0}}}var qr=td("vision",()=>import("./chunk-3sy6ahhz.js"));class de{module;client;constructor(n=qr){this.module=n}async analyzeUIElement(n,s,o){if(this.client===void 0){let{ClaudeVisionClient:a}=await this.module.load();this.client??=new a}return await this.client.analyzeUIElement(n,s,o)}}var Yr=64;class fe{config;claudeClient=null;resultCache;timer;checksums;constructor(n,s=i,o,a=new an){if(this.config=n,this.timer=s,this.checksums=a,this.resultCache=new Map,o)this.claudeClient=o;else if(n.provider==="claude")this.claudeClient=new de}async analyzeAndSuggest(n,s,o){if(!this.config.enabled)throw Error("Vision fallback is not enabled");let a=this.config.cacheResults?await this.generateCacheKey(n,o):null;if(a){let c=this.getCachedResult(a);if(c)return e.debug("Vision fallback: using cached result"),c}if(Gr(this.config.provider),!this.claudeClient)throw Error("Claude client not initialized");e.debug("Vision fallback: analyzing with Claude");let l=await this.claudeClient.analyzeUIElement(n,o,s);if(l.costUsd>this.config.maxCostUsd)e.warn(`Vision fallback cost ($${l.costUsd.toFixed(4)}) exceeds max ($${this.config.maxCostUsd})`);if(e.debug(`Vision fallback complete: confidence=${l.confidence}, cost=$${l.costUsd.toFixed(4)}, time=${l.durationMs}ms`),a)this.cacheResult(a,l);return l}getCachedResult(n){let s=this.resultCache.get(n);if(!s)return null;if((this.timer.now()-s.timestamp)/60000>this.config.cacheTtlMinutes)return this.resultCache.delete(n),null;return s.result}cacheResult(n,s){this.evictExpired(),this.resultCache.set(n,{result:s,timestamp:this.timer.now()}),this.evictOverflow()}evictExpired(){let n=this.timer.now();for(let[s,o]of this.resultCache)if((n-o.timestamp)/60000>this.config.cacheTtlMinutes)this.resultCache.delete(s)}evictOverflow(){while(this.resultCache.size>Yr){let n=this.resultCache.keys().next();if(n.done)return;this.resultCache.delete(n.value)}}async generateCacheKey(n,s){let o=Dr(s);return`${await this.fingerprintScreenshot(n)}:${o}`}async fingerprintScreenshot(n){try{let{checksum:s}=await this.checksums.computeFileSha256(n);return s}catch(s){return e.debug(`Vision fallback: could not fingerprint ${n}, using path as key: ${s}`),n}}clearCache(){this.resultCache.clear()}getCacheStats(){return{size:this.resultCache.size,keys:Array.from(this.resultCache.keys())}}}function Gr(n){if(n==="claude")return n;throw Error(`Unsupported vision provider: ${String(n)}`)}var Am={enabled:!1,provider:"claude",confidenceThreshold:"high",maxCostUsd:1,cacheResults:!0,cacheTtlMinutes:60};var Xr=(n)=>new fe(n),jr=8;class Xe{instances=new Map;createFallback;constructor(n=Xr){this.createFallback=n}get(n){let s=Dr(n),o=this.instances.get(s);if(o)return o;let a=this.createFallback(n);this.instances.set(s,a);while(this.instances.size>jr){let l=this.instances.keys().next();if(l.done)break;this.instances.delete(l.value)}return a}clear(){this.instances.clear()}get size(){return this.instances.size}}var Kr=new Xe;function je(n){return Kr.get(n)}async function Tm(n,s,o,a){let{visionConfig:l,baseError:c,signal:u,visionAnalyzer:h}=a;if(!l.enabled)return c;try{let d=await n.capture(u);if(!d)return e.error("Failed to capture screenshot for vision fallback"),c;let p=await(h??je(l)).analyzeAndSuggest(d,s,o);if(p.confidence==="high"&&p.navigationSteps&&p.navigationSteps.length>0)return`Element not found, but AI suggests these steps:
|
|
5
|
+
${p.navigationSteps.map((m,b)=>`${b+1}. ${m.description}`).join(`
|
|
6
|
+
`)}
|
|
7
|
+
|
|
8
|
+
(Cost: $${p.costUsd.toFixed(4)}, Confidence: ${p.confidence})`;if(p.alternativeSelectors&&p.alternativeSelectors.length>0)return`Element not found. AI suggests trying:
|
|
9
|
+
${p.alternativeSelectors.map((m)=>`- ${m.type}: "${m.value}" (${m.reasoning})`).join(`
|
|
10
|
+
`)}
|
|
11
|
+
|
|
12
|
+
(Cost: $${p.costUsd.toFixed(4)}, Confidence: ${p.confidence})`;return`${c}. ${p.reason||"No clear path found."}
|
|
13
|
+
|
|
14
|
+
(Cost: $${p.costUsd.toFixed(4)}, Confidence: ${p.confidence})`}catch(d){return e.error("Vision fallback failed:",d),c}}var Pe=Nt(GF());async function Qi(){let{default:n}=await import("./chunk-5snsn9cf.js");return n}function Ji(n){return{timer:n.timer??i,backend:n.backend??Ps()}}class I{static PNG_HEADER=Buffer.from([137,80,78,71,13,10,26,10]);static isPngBuffer(n){if(n.length<8)return!1;return n.subarray(0,8).equals(I.PNG_HEADER)}static async convertToPng(n,s=Ps()){try{return await s.execute(n,{operations:[],encoding:{mime:"image/png"}})}catch(o){throw Error(`Failed to convert image to PNG: ${o.message}`)}}static async getImageDimensions(n,s=Ps()){if(I.isPngBuffer(n)&&n.length>=24)return{width:n.readUInt32BE(16),height:n.readUInt32BE(20)};try{let{width:o,height:a}=await s.metadata(n);return{width:o,height:a}}catch(o){throw Error(`Failed to get image dimensions: ${o.message}`)}}static async resizeImageIfNeeded(n,s,o,a=Ps()){let{width:l,height:c}=await I.getImageDimensions(n,a);if(l===s&&c===o)return n;e.debug(`Resizing image from ${l}x${c} to ${s}x${o}`);try{return await a.execute(n,{operations:[{type:"resize",width:s,height:o,maintainAspectRatio:!1,mode:"nearest"}],encoding:{mime:"image/png"}})}catch(u){throw Error(`Failed to resize image: ${u.message}`)}}static getComparisonDimensions(n,s,o){let a=o?Math.min(n.width,s.width,400):Math.min(n.width,s.width),l=o?Math.min(n.height,s.height,600):Math.min(n.height,s.height);return{width:a,height:l}}static dimensionsMatch(n,s,o){return n.width===s&&n.height===o}static async compareImages(n,s,{threshold:o=0.1,fastMode:a=!1,deps:l={}}={}){let{timer:c,backend:u}=Ji(l),h=c.now();e.debug(`Starting image comparison with threshold ${o}${a?" (fast mode)":""}`);try{let d=I.isPngBuffer(n)?n:await I.convertToPng(n,u),f=I.isPngBuffer(s)?s:await I.convertToPng(s,u),p=await I.getImageDimensions(d,u),g=await I.getImageDimensions(f,u);e.debug(`Image 1 dimensions: ${p.width}x${p.height}`),e.debug(`Image 2 dimensions: ${g.width}x${g.height}`);let{width:m,height:b}=I.getComparisonDimensions(p,g,a);if(!I.dimensionsMatch(p,m,b))d=await I.resizeImageIfNeeded(d,m,b,u);if(!I.dimensionsMatch(g,m,b))f=await I.resizeImageIfNeeded(f,m,b,u);let _=Pe.PNG.sync.read(d),C=Pe.PNG.sync.read(f),{width:S,height:y}=_,R=S*y;e.debug(`Comparing images: ${S}x${y} (${R} pixels)`);let W=a?Math.min(o*1.5,0.2):o,z=(await Qi())(_.data,C.data,void 0,S,y,{threshold:W,includeAA:!1}),Be=(R-z)/R*100,tr=c.now()-h;return e.debug(`Image comparison completed in ${tr}ms: ${z}/${R} different pixels (${Be.toFixed(2)}% similar)`),{compared:!0,similarity:Be,pixelDifference:z,totalPixels:R}}catch(d){let f=c.now()-h,p=r(d);return e.warn(`Image comparison failed after ${f}ms: ${p}`,d),{compared:!1,error:p}}}}import oe from"path";var V=8;class se{static async generatePerceptualHash(n,s=Ps()){try{let o=await s.rawPixels(n),a=V*V,l=Array(a),c=0;for(let d=0;d<V;d++){let f=Math.floor(d*o.height/V);for(let p=0;p<V;p++){let g=Math.floor(p*o.width/V),m=(f*o.width+g)*4,b=Math.trunc(0.2126*o.data[m]+0.7152*o.data[m+1]+0.0722*o.data[m+2]);l[d*V+p]=b,c+=b}}let u=c/a,h="";for(let d=0;d<a;d++)h+=l[d]>u?"1":"0";return h}catch(o){return e.warn(`Failed to generate perceptual hash: ${o.message}`),""}}static calculateHammingDistance(n,s){if(n.length!==s.length)return Math.max(n.length,s.length);let o=0;for(let a=0;a<n.length;a++)if(n[a]!==s[a])o++;return o}static getPerceptualSimilarity(n,s){let o=se.calculateHammingDistance(n,s),a=Math.max(n.length,s.length);if(a===0)return 100;return(a-o)/a*100}}class L{static screenshotCache=new Map;static MAX_CACHE_ENTRIES=50;static CACHE_TTL_MS=600000;static async getCachedScreenshot(n,s=i){let o=oe.normalize(n),a=s.now(),l=L.screenshotCache.get(o);if(l&&a-l.lastAccess<L.CACHE_TTL_MS)return l.lastAccess=a,e.debug(`Screenshot cache hit: ${oe.basename(n)}`),{buffer:l.buffer,hash:l.hash};e.debug(`Screenshot cache miss: ${oe.basename(n)}`);let c=await Tf(n),u=await se.generatePerceptualHash(c);return L.addToCache(o,c,u,a),{buffer:c,hash:u}}static addToCache(n,s,o,a){if(L.screenshotCache.size>=L.MAX_CACHE_ENTRIES){let l=Array.from(L.screenshotCache.entries());l.sort((c,u)=>c[1].lastAccess-u[1].lastAccess);for(let c=0;c<10&&c<l.length;c++)L.screenshotCache.delete(l[c][0]);e.debug(`Evicted ${Math.min(10,l.length)} old screenshot cache entries`)}L.screenshotCache.set(n,{buffer:s,hash:o,lastAccess:a})}static clearCache(){L.screenshotCache.clear()}static async getScreenshotFiles(n){try{if(!await Qo(n))return e.debug(`Cache directory does not exist: ${n}`),[];let o=(await Qt(n)).filter((a)=>Jie(a)).map((a)=>oe.join(n,a));return e.debug(`Found ${o.length} screenshot files in ${n}`),o}catch(s){return e.warn(`Failed to get screenshot files from ${n}: ${s.message}`),[]}}}class Q{static async getImageDimensions(n){return I.getImageDimensions(n)}static async compareImages(n,s,o=0.1,a=!1){return I.compareImages(n,s,{threshold:o,fastMode:a})}static async getCachedScreenshot(n){return L.getCachedScreenshot(n)}}class Jt{async getCachedScreenshot(n){return Q.getCachedScreenshot(n)}async getImageDimensions(n){return Q.getImageDimensions(n)}async compareImages(n,s,o,a){return Q.compareImages(n,s,o,a)}}var er=new Jt;var en={minDifferencePercent:1,minElementSizePx:4,pixelmatchThreshold:0.1,confidenceScale:5},tn=0.75;function rn(n){return n?.screenChanged===!0&&(n.basis==="screenIdentity changed"||n.basis==="activeWindow changed")}function Le(n,s){return!n||n===s}function nn(n,s){let o=pt(n);if(!s||o<=0)return!1;let a=$t(n,s);return a!==null&&pt(a)/o>=tn}class Me{screenshotUtils;imageUtils;config;constructor(n={}){this.screenshotUtils=n.screenshotUtils??er,this.imageUtils=n.imageUtils??new c9,this.config={...en,...n.config}}async detectSelectedElements(n){let s=n.currentObservation;if(!s?.viewHierarchy)return[];let o=new Jc().extract(s.viewHierarchy);if(o?.selectedElements?.length){let a=this.applySelectedState(o.selectedElements,{method:"accessibility",confidence:1,reason:"selected attribute present in view hierarchy"});return e.info(`[SELECTION_STATE] Using accessibility selected state (${a.length} element(s))`),a}return this.detectVisualFallback(n,s)}async detectVisualFallback(n,s){let{tappedElement:o,beforeScreenshotPath:a,afterScreenshotPath:l}=n;if(!o)return e.debug("[SELECTION_STATE] Visual fallback skipped: no tapped element provided"),[];if(!a||!l)return e.debug("[SELECTION_STATE] Visual fallback skipped: missing before/after screenshots"),[];let c=this.buildSelectedElement(o);if(!c)return e.debug("[SELECTION_STATE] Visual fallback skipped: tapped element lacks identifiers"),[];let u=this.visualFallbackSkipReason(c,o.bounds,n.tapEffect,s.viewHierarchy);if(u)return e.debug(`[SELECTION_STATE] Visual fallback skipped: ${u}`),[];let h=await this.detectVisualSelection(o.bounds,a,l,{beforeScreenSize:n.previousObservation?.screenSize,afterScreenSize:s.screenSize});if(!h)return[];let d={method:"visual",confidence:h.confidence,reason:h.reason};return e.info(`[SELECTION_STATE] Using visual fallback for ${this.describeElement(c)} (diff=${h.differencePercent.toFixed(2)}%, confidence=${h.confidence})`),[{...c,selectedState:d}]}visualFallbackSkipReason(n,s,o,a){if(rn(o))return`tap navigated (${o?.basis})`;if(!this.isStillPresent(n,s,a))return`${this.describeElement(n)} is not in the post-tap hierarchy`;return null}applySelectedState(n,s){return n.map((o)=>({...o,selectedState:o.selectedState??s}))}buildSelectedElement(n){let s={text:n.text,resourceId:n["resource-id"],contentDesc:n["content-desc"]};if(!s.text&&!s.resourceId&&!s.contentDesc)return null;return s}isStillPresent(n,s,o){if(!o)return!1;return new ve().project(ft(o)??o).some(({properties:l,bounds:c})=>Le(n.text,l.text)&&Le(n.resourceId,l["resource-id"])&&Le(n.contentDesc,l["content-desc"])&&nn(s,c))}describeElement(n){return n.text||n.resourceId||n.contentDesc||"unknown element"}async detectVisualSelection(n,s,o,{beforeScreenSize:a,afterScreenSize:l}={}){try{let c=await this.screenshotUtils.getCachedScreenshot(s),u=await this.screenshotUtils.getCachedScreenshot(o),h=await this.screenshotUtils.getImageDimensions(c.buffer),d=await this.screenshotUtils.getImageDimensions(u.buffer);if(h.width!==d.width||h.height!==d.height)return e.debug(`[SELECTION_STATE] Visual fallback skipped: screenshot size changed ${h.width}x${h.height} -> ${d.width}x${d.height}`),null;let f=await this.cropElementRegion(c.buffer,n,a,h),p=await this.cropElementRegion(u.buffer,n,l,d);if(!f||!p)return e.debug("[SELECTION_STATE] Visual fallback skipped: invalid element bounds for cropping"),null;let g=await this.screenshotUtils.compareImages(f,p,this.config.pixelmatchThreshold,!1);if(!g.compared)return e.warn(`[SELECTION_STATE] Visual fallback skipped: ${g.error}`),null;let m=Math.max(0,100-g.similarity);if(m<this.config.minDifferencePercent)return e.debug(`[SELECTION_STATE] Visual fallback skipped: diff ${m.toFixed(2)}% < threshold ${this.config.minDifferencePercent}%`),null;let b=this.computeConfidence(m);return{differencePercent:m,confidence:b,reason:`visual diff ${m.toFixed(2)}% >= ${this.config.minDifferencePercent}%`}}catch(c){return e.warn(`[SELECTION_STATE] Visual fallback failed: ${r(c)}`,c),null}}async cropElementRegion(n,s,o,a){let l=this.normalizeBounds(s,o,a);if(!l)return null;return this.imageUtils.crop(n,l.width,l.height,{x:l.left,y:l.top})}normalizeBounds(n,s,o){if(o.width<=0||o.height<=0)return null;let a=s?.width?o.width/s.width:1,l=s?.height?o.height/s.height:1,c=Math.max(0,Math.floor(n.left*a)),u=Math.max(0,Math.floor(n.top*l)),h=Math.min(o.width,Math.ceil(n.right*a)),d=Math.min(o.height,Math.ceil(n.bottom*l)),f=h-c,p=d-u;if(f<this.config.minElementSizePx||p<this.config.minElementSizePx)return null;return{left:c,top:u,width:f,height:p}}computeConfidence(n){let s=Math.min(1,Math.max(0,n/this.config.confidenceScale));return Number(s.toFixed(2))}}class rp{device;adbFactory;constructor(n,s=v){this.device=n,this.adbFactory=s}async capture(n){let o=await new Mo(this.device,{adbFactory:this.adbFactory}).execute({format:"png"},n);if(!o.success||!o.path)return null;return o.path}}class x5{detector;screenshotCapturer;isUiPerfModeEnabled;constructor(n){this.detector=n.detector??new Me,this.screenshotCapturer=n.screenshotCapturer,this.isUiPerfModeEnabled=n.isUiPerfModeEnabled??(()=>N.isUiPerfModeEnabled())}async prepare(n){let{observation:s,element:o,action:a,signal:l}=n;if(!s?.viewHierarchy||!o)return null;if(!this.isUiPerfModeEnabled())return e.debug(`[SELECTION_STATE] Skip selection capture (${a}): ui-perf-mode disabled`),null;if(!this.hasIdentifier(o))return e.debug(`[SELECTION_STATE] Skip selection capture (${a}): element lacks identifier`),null;if(!this.isSelectionCandidate(o))return e.debug(`[SELECTION_STATE] Skip selection capture (${a}): element not selectable`),null;if(new Jc().extract(s.viewHierarchy)?.selectedElements?.length)return e.info(`[SELECTION_STATE] Skip visual capture (${a}): accessibility selected state available`),null;let u=await this.screenshotCapturer.capture(l);if(!u)return e.warn(`[SELECTION_STATE] Failed to capture pre-action screenshot (${a})`),null;return{beforeScreenshotPath:u,action:a}}async finalize(n){let{selectionState:s,currentObservation:o,previousObservation:a,element:l,effect:c,action:u,signal:h}=n;if(!s||!o||!l)return[];let d=await this.screenshotCapturer.capture(h);if(!d)return e.warn(`[SELECTION_STATE] Failed to capture post-action screenshot (${u})`),[];let f={currentObservation:o,previousObservation:a,tappedElement:l,tapEffect:c,beforeScreenshotPath:s.beforeScreenshotPath,afterScreenshotPath:d};return this.detector.detectSelectedElements(f)}hasIdentifier(n){return Boolean(n.text||n["resource-id"]||n["content-desc"])}isSelectionCandidate(n){let s=n.clickable===!0||n.clickable==="true",o=n.checkable===!0||n.checkable==="true";return s||o}}function du(n,s){if(!s)return n;return{...n,warnings:[...n.warnings??[],s]}}
|
|
15
|
+
export{E5,I5,Yc,Jc,cu,Uee,mv,xV,Hee,qee,Vee,fT,_5,gC,Wee,KF,Am,Tm,GF,rp,x5,du};
|
|
16
|
+
|
|
17
|
+
//# debugId=F0A2FD2F9C02F92F64756E2164756E21
|