@ycodium-ai/plugin-devices 0.2.3851 → 0.2.3908
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/README.md +3 -1
- package/assets/ui.js +4 -4
- package/dist/helper.mjs +6 -5
- package/dist/index.js +174 -92
- package/locales/en.json +3 -1
- package/locales/zh-CN.json +3 -1
- package/package.json +4 -4
- package/skills/mobile-devices/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -46,7 +46,9 @@ stopping or restarting it.
|
|
|
46
46
|
If a private environment is needed, accept the Android SDK license and choose
|
|
47
47
|
**Download and prepare**. The plugin downloads fixed official Google archives for
|
|
48
48
|
Platform-Tools, Emulator and an Android 15 AOSP system image, checks their recorded
|
|
49
|
-
sizes and official checksums, and creates a private virtual device.
|
|
49
|
+
sizes and official checksums, and creates a private virtual device. Choose Android 11
|
|
50
|
+
to add its image and a second virtual device next to Android 15; each version is
|
|
51
|
+
downloaded only when chosen, and both can run at the same time. The panel shows
|
|
50
52
|
the current component, amount, speed and time left; cancelling keeps components that
|
|
51
53
|
finished downloading. **Download proxy** in the Devices settings chooses the proxy
|
|
52
54
|
for these downloads when the machine default is slow. SDK files,
|
package/assets/ui.js
CHANGED
|
@@ -557,7 +557,7 @@ var la=`/*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
|
|
|
557
557
|
}
|
|
558
558
|
}
|
|
559
559
|
}
|
|
560
|
-
`;var
|
|
561
|
-
`&&
|
|
562
|
-
`&&
|
|
563
|
-
`),id:this.lastId}:void 0;return this.data=[],this.eventName="",d}if(a.startsWith(":"))return;let t=a.indexOf(":"),o=t===-1?a:a.slice(0,t),l=t===-1?"":a.slice(t+1);l.startsWith(" ")&&(l=l.slice(1)),o==="data"?this.data.push(l):o==="event"?this.eventName=l:o==="id"&&!l.includes("\0")&&(this.lastId=l)}};async function je(e,a,t){let o=e.body;if(!o)throw new Error("The response has no body to stream.");let l=o.getReader(),d=()=>{l.cancel().catch(()=>{})};if(t?.aborted)return d();t?.addEventListener("abort",d,{once:!0});try{for(;;){let{done:s,value:u}=await l.read();if(s||t?.aborted)return;a(u)}}catch(s){if(t?.aborted)return;throw s}finally{t?.removeEventListener("abort",d)}}async function Ja(e,a,t){if(!e.ok)throw await e.body?.cancel().catch(()=>{}),new Error(`Event stream failed (${e.status}).`);let o=new $e;await je(e,l=>{for(let d of o.push(l))a(d)},t)}var pe=e=>e==="ios"?"/vendor/serve-sim":"/vendor/serve-emu";var Lo=1e3,ho=500,Ze=(e,a,t)=>`${pe(e.platform)}${a}${t?`?${new URLSearchParams(t).toString()}`:""}`,Qa=async(e,a,t)=>{let o=await e.transport.fetch(a,t?{signal:t}:void 0);if(!o.ok)throw new Error(`${o.status} ${o.statusText}`);return await o.json()},Q=e=>typeof e=="object"&&e!==null,$=(e,a)=>typeof e=="number"&&Number.isFinite(e)?e:a,xo=e=>{let a=e[0],t=Q(a)&&Q(a.frame)?a.frame:null,o=Math.max(1,$(t?.width,1)),l=Math.max(1,$(t?.height,1)),d=[],s=(u,n)=>{if(d.length>=ho||!Q(u)||!Q(u.frame))return;let i=u.frame,p=$(i.width,0),g=$(i.height,0);!(Math.abs(p-o)<.5&&Math.abs(g-l)<.5)&&p>0&&g>0&&d.push({id:typeof u.AXUniqueId=="string"?u.AXUniqueId:n,label:typeof u.AXLabel=="string"?u.AXLabel:"",role:typeof u.type=="string"?u.type:"",x:$(i.x,0)/o,y:$(i.y,0)/l,width:p/o,height:g/l}),(Array.isArray(u.children)?u.children:[]).forEach((h,b)=>s(h,`${n}.${b}`))};return e.forEach((u,n)=>s(u,String(n))),d},Ya=e=>Q(e)&&typeof e.error=="string"?e.error:"Unexpected accessibility payload.";async function at(e,a){if(e.platform==="ios"){let n=await Qa(e,Ze(e,`/helper/${encodeURIComponent(e.deviceId)}/ax`),a);return Array.isArray(n)?{elements:xo(n),errors:[]}:{elements:[],errors:[Ya(n)]}}let t=await Qa(e,Ze(e,"/api/accessibility",{device:e.deviceId}),a);if(!Q(t)||!Array.isArray(t.nodes))return{elements:[],errors:[Ya(t)]};let o=t.nodes.filter(n=>Q(n)&&Q(n.bounds)),l=o[0]?.bounds,d=Math.max(1,$(l?.right,1)),s=Math.max(1,$(l?.bottom,1));return{elements:o.slice(1).flatMap(n=>{let i=n.bounds,p=$(i.left,0),g=$(i.top,0),v=($(i.right,p)-p)/d,c=($(i.bottom,g)-g)/s,h=typeof n.text=="string"?n.text:"",b=typeof n.contentDescription=="string"?n.contentDescription:"",R=h||b;if(v>=.95&&c>=.9)return[];if(!R&&n.clickable!==!0)return[];let m=typeof n.className=="string"?n.className:"";return[{id:String(n.id??""),label:R,role:m.split(".").at(-1)??"",x:p/d,y:g/s,width:v,height:c}]}),errors:[]}}var tt=(e,a,t)=>{let o=new AbortController,l=null,d=()=>{e.transport.fetch(a,{signal:o.signal}).then(s=>Ja(s,u=>{try{t(JSON.parse(u.data))}catch{}},o.signal)).catch(()=>{}).finally(()=>{o.signal.aborted||(l=setTimeout(d,Lo))})};return d(),()=>{o.abort(),l!==null&&clearTimeout(l)}};function ot(e,a){return e.platform!=="ios"?()=>{}:tt(e,Ze(e,"/appstate",{device:e.deviceId}),t=>{if(Q(t)){if(t.bundleId===null||t.bundleId===""){a(null);return}typeof t.bundleId=="string"&&a({id:t.bundleId,...typeof t.pid=="number"?{pid:t.pid}:{},...typeof t.isReactNative=="boolean"?{isReactNative:t.isReactNative}:{}})}})}var et=e=>!Q(e)||typeof e.id!="number"?null:{id:e.id,timestamp:typeof e.timestamp=="string"?e.timestamp:"",kind:typeof e.kind=="string"?e.kind:"",summary:typeof e.summary=="string"?e.summary:typeof e.msg=="string"?e.msg:""};function rt(e,a){return e.platform!=="ios"?()=>{}:tt(e,Ze(e,"/api/event-log/events",{device:e.deviceId,limit:"100"}),t=>{if(!Q(t))return;if(Array.isArray(t.events)){a(t.events.flatMap(l=>et(l)??[]),!0);return}let o=et(t.event);o&&a([o],!1)})}function B(){return{t:q().i18n.usePluginTranslation()}}function Qe(e){if(e.length<4)return"avc1.42E01E";let a=t=>t.toString(16).padStart(2,"0");return`avc1.${a(e[1])}${a(e[2])}${a(e[3])}`}function lt(e){let a=new Uint8Array(e);if(a.byteLength>16){let t=new DataView(e,0,16);if(t.getUint32(0,!1)===1397050709&&t.getUint8(4)===1){let o=t.getBigUint64(8,!1);return{data:a.subarray(16),isKey:(t.getUint8(5)&1)!==0,timestamp:o<=BigInt(Number.MAX_SAFE_INTEGER)?Number(o):null}}}return{data:a,isKey:null,timestamp:null}}var st=e=>{try{return JSON.parse(e)?.type==="video-session"}catch{return!1}};function dt(e){let a=!1,t=null,o=e.length,l=0;for(;l+2<o;){if(e[l]===0&&e[l+1]===0){let d=0;if(e[l+2]===1?d=3:l+3<o&&e[l+2]===0&&e[l+3]===1&&(d=4),d){let s=e[l+d]&31;s===7&&!t&&(t=e.subarray(l+d)),s===5&&(a=!0),l+=d+1;continue}}l++}return{isKey:a,sps:t}}var Io={1:"description",2:"keyframe",3:"delta",4:"seed"},Je=class{buffer=new Uint8Array(64*1024);length=0;push(a){if(this.length+a.length>this.buffer.length){let l=this.buffer.length;for(;l<this.length+a.length;)l*=2;let d=new Uint8Array(l);d.set(this.buffer.subarray(0,this.length)),this.buffer=d}this.buffer.set(a,this.length),this.length+=a.length;let t=[],o=0;for(;this.length-o>=4;){let d=new DataView(this.buffer.buffer,this.buffer.byteOffset+o,4).getUint32(0,!1);if(this.length-o-4<d)break;if(d>=1){let s=Io[this.buffer[o+4]];s&&t.push({type:s,payload:this.buffer.slice(o+5,o+4+d)})}o+=4+d}return o>0&&(this.buffer.copyWithin(0,o,this.length),this.length-=o),t}reset(){this.length=0}};var Co={Enter:40,Escape:41,Backspace:42,Tab:43,Space:44,Minus:45,Equal:46,BracketLeft:47,BracketRight:48,Backslash:49,Semicolon:51,Quote:52,Backquote:53,Comma:54,Period:55,Slash:56,Delete:76,ArrowRight:79,ArrowLeft:80,ArrowDown:81,ArrowUp:82,ControlLeft:224,ShiftLeft:225,AltLeft:226,MetaLeft:227,ControlRight:228,ShiftRight:229,AltRight:230,MetaRight:231};function ut(e){return/^Key[A-Z]$/.test(e)?4+(e.charCodeAt(3)-65):/^Digit[1-9]$/.test(e)?30+(e.charCodeAt(5)-49):e==="Digit0"?39:Co[e]??null}var nt={ArrowUp:19,ArrowDown:20,ArrowLeft:21,ArrowRight:22,Tab:61,Enter:66,Backspace:67,Delete:112,Home:122,End:123,PageUp:92,PageDown:93};function ga(e){if(e.stopped)return;let a=d=>{e.configuring=!1,e.connecting(d),e.scheduleRetry("input",()=>ga(e))},t;try{t=e.transport.connect(`${e.vendor}/ws?device=${e.device}&frame-meta=1`)}catch(d){e.events.onInputConnected(!1,d.message),a(d.message);return}e.socket=t;let o=[],l=!1;t.onopen=()=>{e.stopped||e.socket!==t||(e.connecting(),e.events.onInputConnected(!0))},t.onmessage=d=>{if(e.stopped||e.socket!==t)return;if(typeof d.data=="string"){st(d.data)&&(e.closeDecoder(),e.configuring=!1,o=[],l=!1,e.connecting());return}let s=lt(d.data),u=!e.videoDecoder||e.videoDecoder.state!=="configured",i=s.isKey===null||s.isKey&&u?dt(s.data):null,p=s.isKey??i?.isKey??!1,g={isKey:p,data:s.data,timestamp:s.timestamp};if(e.configuring){o.push(g);return}if(i?.sps&&u){e.configuring=!0,o=[g];let v=e.decoderEpoch,c=()=>!e.stopped&&e.socket===t;e.configureDecoder({codec:Qe(i.sps)},c).then(h=>{if(!c()||v!==e.decoderEpoch)return;e.configuring=!1,e.awaitingKeyframe=!0;let b=o;if(o=[],!!h){for(let R of b)e.decode(R.isKey,R.data,R.timestamp);e.awaitingKeyframe&&e.requestKeyframe()}});return}if(u){!p&&!l&&(l=!0,e.requestKeyframe());return}e.decode(p,s.data,s.timestamp)},t.onclose=d=>{e.socket===t&&(e.socket=null,e.closeDecoder(),!e.stopped&&(e.events.onInputConnected(!1,d.reason||`closed ${d.code}`),a(d.reason||void 0)))},t.onerror=()=>t.close()}function it(e){return{sendTouch(a,t,o){let l=a==="begin"?"down":a==="move"?"move":"up";e.send(JSON.stringify({type:"touch",action:l,x:t,y:o}))},sendKey(a,t){if(t!=="down")return;if(a.key==="Escape")return e.send(JSON.stringify({type:"back"}));let o=nt[a.key];if(o!==void 0)return e.send(JSON.stringify({type:"key",keycode:o}));a.key.length===1&&!a.metaKey&&!a.ctrlKey&&e.send(JSON.stringify({type:"text",text:a.key}))},pressButton(a){let t=a==="appSwitcher"?"recents":a;(t==="home"||t==="back"||t==="recents"||t==="power")&&e.send(JSON.stringify({type:t}))},rotate(){},setOrientation(){}}}function ft(e){return{present(a,t,o){let l=e.getContext("2d");return l?((e.width!==t||e.height!==o)&&(e.width=t,e.height=o),l.drawImage(a,0,0,t,o),!0):!1}}}var ct=new TextEncoder,pt=new TextDecoder;function gt(e){if(!e)return null;let a=/boundary=(?:"([^"]+)"|([^;\s]+))/i.exec(e),t=a?.[1]??a?.[2];return t?t.startsWith("--")?t:`--${t}`:null}function mt(e,a,t,o){let l=o-a.length;for(let d=t;d<=l;d++){if(e[d]!==a[0])continue;let s=1;for(;s<a.length&&e[d+s]===a[s];)s++;if(s===a.length)return d}return-1}var Ye=class{delimiter;buffer=new Uint8Array(64*1024);length=0;pos=0;state="boundary";contentLength=null;scanFrom=0;constructor(a){this.delimiter=a?ct.encode(a):null}push(a){this.append(a);let t=[];for(;;){if(this.state==="done"){this.pos=this.length=0;break}if(this.state==="boundary"){if(!this.readBoundary())break}else if(this.state==="headers"){if(!this.readHeaders())break}else{let o=this.readBody();if(!o)break;o.length>0&&t.push(o)}}if(this.length-this.pos>16777216)throw new Error("MJPEG part is too large.");return this.pos>0&&(this.buffer.copyWithin(0,this.pos,this.length),this.length-=this.pos,this.scanFrom=Math.max(0,this.scanFrom-this.pos),this.pos=0),t}append(a){if(this.length+a.length>this.buffer.length){let t=this.buffer.length;for(;t<this.length+a.length;)t*=2;let o=new Uint8Array(t);o.set(this.buffer.subarray(0,this.length)),this.buffer=o}this.buffer.set(a,this.length),this.length+=a.length}lineEnd(a){return this.buffer.subarray(0,this.length).indexOf(10,a)}readBoundary(){let a=this.buffer;if(!this.delimiter)for(;;){let s=this.lineEnd(this.pos);if(s===-1)return!1;let u=pt.decode(a.subarray(this.pos,s)).trim();if(this.pos=s+1,u.startsWith("--"))return this.delimiter=ct.encode(u),this.state="headers",!0}let t=this.delimiter,o=mt(a,t,this.pos,this.length);if(o===-1)return this.pos=Math.max(this.pos,this.length-t.length+1),!1;let l=o+t.length;if(l+2>this.length)return this.pos=o,!1;if(a[l]===45&&a[l+1]===45)return this.state="done",!0;let d=this.lineEnd(l);return d===-1?(this.pos=o,!1):(this.pos=d+1,this.state="headers",!0)}readHeaders(){let a=this.pos,t=null;for(;;){let o=this.lineEnd(a);if(o===-1)return!1;let l=pt.decode(this.buffer.subarray(a,o)).replace(/\r$/,"");if(a=o+1,l==="")break;let d=l.indexOf(":");if(d>0&&l.slice(0,d).trim().toLowerCase()==="content-length"){let s=Number.parseInt(l.slice(d+1).trim(),10);Number.isFinite(s)&&s>=0&&(t=s)}}return this.pos=a,this.contentLength=t,this.scanFrom=a,this.state="body",!0}readBody(){if(this.contentLength!==null){if(this.length-this.pos<this.contentLength)return null;let o=this.buffer.slice(this.pos,this.pos+this.contentLength);return this.pos+=this.contentLength,this.state="boundary",o}let a=this.delimiter,t=Math.max(this.scanFrom,this.pos+1);for(;;){let o=mt(this.buffer,a,t,this.length);if(o===-1)return this.scanFrom=Math.max(this.pos,this.length-a.length),null;if(this.buffer[o-1]!==10){t=o+1;continue}let l=o-1;l>this.pos&&this.buffer[l-1]===13&&l--;let d=this.buffer.slice(this.pos,Math.max(l,this.pos));return this.pos=o,this.state="boundary",d}}};async function So(e,a,t){let o=new Ye(gt(e.headers.get("content-type")));await je(e,l=>{for(let d of o.push(l))a(d)},t)}function Se(e){e.stopped||e.mjpeg||(e.mjpeg=!0,e.controller?.abort(),e.controller=null,e.closeDecoder(),e.connecting(),e.events.onMjpegFallback?.(),Lt(e))}var La=e=>`${e.vendor}/helper/${e.device}/stream.mjpeg`;async function Lt(e){let a=e.generation,t=++e.videoGeneration,o=new AbortController;e.controller=o;let l=()=>!e.stopped&&e.generation===a&&e.videoGeneration===t&&e.controller===o,d=null,s=!1,u=async()=>{s=!0;try{for(;d;){let i=d;d=null;try{let p=await e.createBitmap(new Blob([i],{type:"image/jpeg"}));try{l()&&e.paint(p,p.width,p.height)}finally{p.close()}}catch{}}}finally{s=!1}},n;try{let i=await e.transport.fetch(La(e),{signal:o.signal});if(!l()){await i.body?.cancel();return}if(!i.ok||!i.body)throw new Error(`stream ${i.status}`);if(await So(i,p=>{l()&&(d=p,s||u())},o.signal),!l())return;n="Device stream ended."}catch(i){if(!l())return;n=i.message}l()&&(e.controller=null,o.abort(),e.connecting(n),e.scheduleRetry("video",()=>{Lt(e)}))}var vo=1e3,ha=15e3,yo=16667,wo=8,bo=e=>typeof e=="object"&&e!==null&&"present"in e;function xt(e){let{transport:a,platform:t,events:o}=e,l=bo(e.output)?e.output:ft(e.output),d=u=>e.globals?.[u]??globalThis[u],s={platform:t,transport:a,events:o,preferMjpeg:e.preferMjpeg===!0,vendor:pe(t),device:encodeURIComponent(e.deviceId),stopped:!0,generation:0,videoGeneration:0,decoderEpoch:0,socket:null,controller:null,primeController:null,videoDecoder:null,timestamp:0,awaitingKeyframe:!0,screen:null,firstFrame:!1,configuring:!1,mjpeg:!1,frameTimer:null,videoReadTimer:null,retryTimers:new Map,webCodecs(){let u=d("VideoDecoder"),n=d("EncodedVideoChunk");return u&&n?{VideoDecoder:u,EncodedVideoChunk:n}:null},createBitmap(u){let n=d("createImageBitmap");return n?n(u):Promise.reject(new Error("createImageBitmap is unavailable."))},setStatus(u,n){s.stopped||o.onStatus(u,n)},fail(u){s.stopped||(s.stop(),o.onInputConnected(!1,u),o.onStatus("error",u))},connecting(u){s.firstFrame=!1,s.frameTimer===null&&(s.frameTimer=setTimeout(()=>s.fail("No video received from the device. Reconnect to try again."),ha)),s.setStatus("connecting",u)},paint(u,n,i){if(!s.stopped){if(t==="android"&&(s.screen?.width!==n||s.screen.height!==i)&&(s.screen={width:n,height:i,orientation:n>i?"landscape_left":"portrait"},o.onScreen(s.screen)),!l.present(u,n,i)){s.fail("Could not display the device stream. Reconnect to try again.");return}s.firstFrame||(s.firstFrame=!0,s.frameTimer!==null&&clearTimeout(s.frameTimer),s.frameTimer=null,s.setStatus("streaming"))}},closeDecoder(){s.decoderEpoch++,s.configuring=!1;try{s.videoDecoder?.close()}catch{}s.videoDecoder=null,s.awaitingKeyframe=!0},recoverDecoder(){t==="ios"?Se(s):(s.closeDecoder(),s.connecting("Video decoder restarted."),s.requestKeyframe())},async configureDecoder(u,n=()=>!s.stopped){let i=s.webCodecs();if(!i)return!1;let p=s.decoderEpoch,g={...u,optimizeForLatency:!0},v=await i.VideoDecoder.isConfigSupported(g).catch(()=>({supported:!1}));if(!n()||p!==s.decoderEpoch)return!1;if(!v.supported)return t==="android"&&s.fail(`This browser cannot decode ${u.codec}.`),!1;try{return(!s.videoDecoder||s.videoDecoder.state==="closed")&&(s.videoDecoder=ko(s,i)),s.videoDecoder.configure(g),!0}catch(c){return t==="android"&&s.fail(`Video decoder: ${c.message}`),!1}},decode(u,n,i){let p=s.videoDecoder,g=s.webCodecs();if(!(!p||p.state!=="configured"||!g)){if(s.awaitingKeyframe){if(!u)return;s.awaitingKeyframe=!1}if(p.decodeQueueSize>wo){s.recoverDecoder();return}try{p.decode(new g.EncodedVideoChunk({type:u?"key":"delta",timestamp:i??s.timestamp,data:n})),s.timestamp+=yo}catch{s.recoverDecoder()}}},requestKeyframe(){t==="android"&&s.socket?.readyState===1&&s.socket.send(JSON.stringify({type:"reset-video",ack:!1}))},scheduleRetry(u,n){s.stopped||s.retryTimers.has(u)||s.retryTimers.set(u,setTimeout(()=>{s.retryTimers.delete(u),n()},vo))},send(u){!s.stopped&&s.socket?.readyState===1&&s.socket.send(u)},stop(){if(s.stopped)return;s.stopped=!0,s.generation++,s.videoGeneration++,s.mjpeg=!1,s.frameTimer!==null&&clearTimeout(s.frameTimer),s.frameTimer=null,s.videoReadTimer!==null&&clearTimeout(s.videoReadTimer),s.videoReadTimer=null;for(let n of s.retryTimers.values())clearTimeout(n);s.retryTimers.clear(),s.primeController?.abort(),s.primeController=null,s.controller?.abort(),s.controller=null;let u=s.socket;s.socket=null,u?.close(),s.closeDecoder()}};return s}function ko(e,a){let t=e.videoGeneration,o=()=>e.platform!=="ios"||t===e.videoGeneration,l=new a.VideoDecoder({output:d=>{try{e.videoDecoder===l&&o()&&e.paint(d,d.displayWidth,d.displayHeight)}finally{d.close()}},error:()=>{e.stopped||e.videoDecoder!==l||!o()||e.recoverDecoder()}});return l}var Do=3,Po=4,Ao=6,It=7,To=13,Bo=130,Mo=2e3,Ro=new TextEncoder,Fo=new TextDecoder,ea=["portrait","landscape_left","portrait_upside_down","landscape_right"],Eo=new Set(ea);function me(e,a){let t=Ro.encode(JSON.stringify(a)),o=new Uint8Array(1+t.length);return o[0]=e,o.set(t,1),o}function Oo(e){if(typeof e!="object"||e===null)return null;let{width:a,height:t,orientation:o,screenId:l}=e;if(typeof a!="number"||!Number.isFinite(a)||a<=0||typeof t!="number"||!Number.isFinite(t)||t<=0||typeof o!="string"||!Eo.has(o))return null;let d={width:a,height:t,orientation:o};return typeof l=="number"?{...d,screenId:l}:d}function Ct(e,a){vt(e),a?St(e):Se(e)}async function St(e){let a=e.generation,t=++e.videoGeneration,o=new Je,l=new AbortController;e.controller=l;let d=()=>!e.stopped&&e.generation===a&&e.videoGeneration===t&&e.controller===l,s;try{let u=await e.transport.fetch(`${e.vendor}/helper/${e.device}/stream.avcc`,{signal:l.signal});if(!d()){await u.body?.cancel();return}if(!u.ok||!u.body)throw new Error(`stream ${u.status}`);let n=u.body.getReader();for(;;){let i=setTimeout(()=>{d()&&e.fail("Device stream stopped receiving video. Reconnect to try again.")},ha);e.videoReadTimer=i;let p;try{p=await n.read()}finally{clearTimeout(i),e.videoReadTimer===i&&(e.videoReadTimer=null)}let{done:g,value:v}=p;if(!d())return;if(g)break;for(let c of o.push(v))switch(c.type){case"seed":e.createBitmap(new Blob([c.payload],{type:"image/jpeg"})).then(h=>{try{d()&&e.paint(h,h.width,h.height)}finally{h.close()}}).catch(()=>{});break;case"description":{e.awaitingKeyframe=!0;let h=await e.configureDecoder({codec:Qe(c.payload),description:c.payload},d);if(!d())return;if(!h){if(await n.cancel().catch(()=>{}),!d())return;Se(e);return}break}case"keyframe":case"delta":e.decode(c.type==="keyframe",c.payload);break}}}catch(u){if(!d())return;s=u.message}d()&&(e.controller=null,l.abort(),e.closeDecoder(),e.connecting(s),e.scheduleRetry("video",()=>{St(e)}))}async function Uo(e,a){let t=new AbortController;e.primeController=t;let o=setTimeout(()=>t.abort(),Mo);try{let l=await e.transport.fetch(La(e),{signal:t.signal});if(e.stopped||e.generation!==a)return;await l.body?.getReader().read()}catch{}finally{clearTimeout(o),t.abort(),e.primeController===t&&(e.primeController=null)}}async function vt(e){if(e.stopped)return;let a=e.generation;if(await Uo(e,a),e.stopped||e.generation!==a)return;let t=()=>e.scheduleRetry("input",()=>{vt(e)}),o;try{o=e.transport.connect(`${e.vendor}/helper/ws?device=${e.device}`)}catch(l){e.events.onInputConnected(!1,l.message),t();return}e.socket=o,o.onopen=()=>{e.stopped||e.socket!==o||(o.send(me(To,{enabled:!1})),e.events.onInputConnected(!0))},o.onmessage=l=>{if(e.stopped||e.socket!==o||typeof l.data=="string")return;let d=new Uint8Array(l.data);if(!(d.length<1||d[0]!==Bo))try{let s=Oo(JSON.parse(Fo.decode(d.subarray(1))));s&&(e.screen=s,e.events.onScreen(s))}catch{}},o.onclose=l=>{e.socket===o&&(e.socket=null,!e.stopped&&(e.events.onInputConnected(!1,l.reason||(l.code===1006?"input socket refused":`closed ${l.code}`)),t()))},o.onerror=()=>o.close()}function qo(e,a,t){let o=e.screen;if(!o||o.width>o.height)return{x:a,y:t};switch(o.orientation){case"landscape_left":return{x:t,y:1-a};case"landscape_right":return{x:1-t,y:a};case"portrait_upside_down":return{x:1-a,y:1-t};default:return{x:a,y:t}}}function yt(e){return{sendTouch(a,t,o){e.send(me(Do,{type:a,...qo(e,t,o)}))},sendKey(a,t){let o=ut(a.code);o!==null&&e.send(me(Ao,{type:t,usage:o}))},pressButton(a){let t=a==="home"?"home":a==="appSwitcher"?"app_switcher":a==="power"?"lock":null;t&&e.send(me(Po,{button:t}))},rotate(){let a=e.screen?.orientation??"portrait",t=ea[(ea.indexOf(a)+1)%ea.length];e.send(me(It,{orientation:t}))},setOrientation(a){e.send(me(It,{orientation:a}))}}}function wt(e){let a=xt(e),t=e.platform==="ios"?yt(a):it(a);return{start:()=>{if(!a.stopped)return;a.stopped=!1,a.generation++,a.configuring=!1,a.connecting();let l=a.webCodecs()!==null&&!(e.platform==="ios"&&a.preferMjpeg);e.platform==="ios"?Ct(a,l):l?ga(a):a.fail("This browser cannot decode the Android stream (WebCodecs unavailable).")},stop:a.stop,isMjpeg:()=>a.mjpeg,...t}}var Ho=56,No=2e3;function Go(e,a,t,o=0){let l=Math.max(0,a-o);if(l===0||t===0)return{width:0,height:0};let d={width:t*e,height:t};return d.width<=l?d:{width:l,height:l/e}}function Vo(e,a){if(!a)return e==="ios"?9/19.5:9/20;let t=a.orientation==="landscape_left"||a.orientation==="landscape_right",o=Math.max(a.width,a.height),l=Math.min(a.width,a.height);return t?o/l:l/o}function zo(e,a){if(e!=="ios"||!a||a.width>a.height)return 0;switch(a.orientation){case"landscape_left":return 90;case"landscape_right":return-90;case"portrait_upside_down":return 180;default:return 0}}var _o=()=>typeof navigator<"u"&&/iPhone|iPad|iPod/.test(navigator.userAgent);function aa(e){let{t:a}=B(),t=z(null),o=z(null),[l,d]=L("connecting"),[s,u]=L(),[n,i]=L(!1),[p,g]=L(null),[v,c]=L({connected:!1}),{onHandle:h,onStreaming:b,onScreen:R,transport:m,platform:w,deviceId:C}=e;T(()=>R?.(p),[R,p]),T(()=>{let x=t.current;if(!x)return;let D=wt({transport:m,platform:w,deviceId:C,output:x,preferMjpeg:_o(),events:{onStatus:(A,V)=>{d(A),u(V),A==="streaming"&&i(!0),b(A==="streaming")},onScreen:g,onInputConnected:(A,V)=>{c({connected:A,...V?{detail:V}:{}}),h({pressButton:D.pressButton,rotate:D.rotate,inputConnected:A})}}});return o.current=D,c({connected:!1}),D.start(),h({pressButton:D.pressButton,rotate:D.rotate,inputConnected:!1}),()=>{D.stop(),o.current=null,h(null),b(!1),i(!1),g(null)}},[C,h,b,w,m]);let k=z(null),[F,_]=L({width:0,height:0});T(()=>{let x=k.current;if(!x)return;let D=()=>{let V=x.getBoundingClientRect();_(M=>M.width===V.width&&M.height===V.height?M:{width:V.width,height:V.height})};D();let A=new ResizeObserver(D);return A.observe(x),()=>A.disconnect()},[]);let N=e.withControls?Ho:0,E=ne(()=>Go(Vo(w,p),F.width,F.height,N),[F,N,w,p]),W=zo(w,p),j=W===90||W===-90?{width:E.height,height:E.width,left:(E.width-E.height)/2,top:(E.height-E.width)/2,transform:`rotate(${W}deg)`}:{width:E.width,height:E.height,...W?{transform:`rotate(${W}deg)`}:{}},[K,G]=L([]);T(()=>{if(!e.axOverlay)return;let x=null,D=null,A=!1,V=async()=>{x=new AbortController;try{let M=await at({transport:m,platform:w,deviceId:C},x.signal);A||G(M.elements)}catch{}A||(D=setTimeout(()=>{V()},No))};return V(),()=>{A=!0,x?.abort(),D&&clearTimeout(D),G([])}},[C,w,e.axOverlay,m]);let U=z(!1),I=x=>{let D=x.currentTarget.getBoundingClientRect(),A=(x.clientX-D.left)/D.width,V=(x.clientY-D.top)/D.height;return{x:Math.min(1,Math.max(0,A)),y:Math.min(1,Math.max(0,V))}},X=x=>{if(!U.current)return;U.current=!1;let{x:D,y:A}=I(x);o.current?.sendTouch("end",D,A)};return f("div",{ref:k,className:"relative flex size-full min-h-0 min-w-0 items-center justify-center overflow-hidden",style:N?{paddingRight:N}:void 0,tabIndex:0,role:"application","aria-label":a(w==="ios"?"stream.iosScreen":"stream.androidScreen"),onKeyDown:x=>{x.target===x.currentTarget&&(x.metaKey&&!["r","R"].includes(x.key)||(x.preventDefault(),o.current?.sendKey(x.nativeEvent,"down")))},onKeyUp:x=>{x.target===x.currentTarget&&o.current?.sendKey(x.nativeEvent,"up")},children:[f("div",{className:"relative touch-none select-none",style:{width:E.width,height:E.height},onPointerDown:x=>{x.currentTarget.setPointerCapture(x.pointerId),x.currentTarget.parentElement?.focus(),U.current=!0;let{x:D,y:A}=I(x);o.current?.sendTouch("begin",D,A)},onPointerMove:x=>{if(!U.current)return;let{x:D,y:A}=I(x);o.current?.sendTouch("move",D,A)},onPointerUp:X,onPointerCancel:X,children:[r("canvas",{ref:t,className:"absolute top-0 left-0",style:j}),K.length>0?r("div",{className:"pointer-events-none absolute inset-0","aria-hidden":!0,children:K.map(x=>r("div",{className:"absolute border border-info/80 bg-info/10",style:{left:`${x.x*100}%`,top:`${x.y*100}%`,width:`${x.width*100}%`,height:`${x.height*100}%`},children:x.label?r("span",{className:"absolute -top-3.5 left-0 max-w-full truncate rounded-sm bg-info px-1 text-ui-2xs leading-3.5 text-white",children:x.label}):null},x.id))}):null]}),l==="streaming"&&!v.connected?r("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 flex justify-center p-2",children:r("span",{className:"rounded-md bg-background/85 px-2 py-1 text-xs text-muted-foreground",children:v.detail?a("stream.inputLostDetail",{detail:v.detail}):a("stream.inputLost")})}):null,l==="connecting"&&n?r("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 flex justify-center p-2",children:r("span",{className:"rounded-md bg-background/85 px-2 py-1 text-xs text-muted-foreground",children:a("stream.connecting")})}):null,l==="error"||l!=="streaming"&&!n?r("div",{className:"absolute inset-0 bg-background",children:r(ae,{name:e.deviceName,description:e.deviceDescription,stage:l==="error"?"error":"connecting",message:l==="error"?s??a("stream.failed"):a("stream.connecting"),children:l==="error"?r(S,{size:"sm",variant:"outline",onClick:()=>{o.current?.stop(),o.current?.start()},children:a("stream.reconnect")}):null})}):null]})}var Wo={hosts:[],hostStatuses:{},devices:[],sessions:[],bootingDevices:[],revision:0};function ge(e){let t=q().commands.useSubscription("state",{},{environmentId:e});return{state:t.data??Wo,loaded:t.data!==null,error:t.error,unavailable:t.isUnavailable}}function oe(){let e=q();return ee((a,t,o={})=>e.commands.invoke(a,o,{environmentId:t}),[e])}var Le="local",ta=class extends Error{code;constructor(a,t,o){super(t,o),this.name="DeviceError",this.code=a}};var bt="hub";function oa(e){let a=q(),[t,o]=L({status:"connecting"});return T(()=>{let l=a.network;if(!fe(a,"network")||l===void 0){o({status:"failed",message:null});return}let d=!1;return o({status:"connecting"}),l.client(e).then(s=>{d||o({status:"ready",transport:{fetch:(u,n)=>s.fetch(bt,u,{...n,instance:Le}),connect:u=>s.connect(bt,u,{instance:Le})}})},s=>{d||o({status:"failed",message:s instanceof Error?s.message:String(s)})}),()=>{d=!0}},[a,e]),t}var kt=()=>{};function Dt(e){let{environmentId:a,threadId:t,hostId:o,deviceId:l,platform:d}=e,s=e[Ea],u=q(),{t:n}=B(),{state:i,loaded:p}=ge(a),g=oa(a),v=ne(()=>({environmentId:a,threadId:t}),[a,t]),c=i.devices.find(w=>w.hostId===o&&w.id===l),h=i.sessions.some(w=>w.threadId===t&&w.hostId===o&&w.deviceId===l);T(()=>{p&&!h&&u.floating?.close(v,s.key)},[u,s.key,p,h,v]),T(()=>(s.setOpenInPanel(()=>{Ne(a,t,s.key),u.floating?.openPanel(v,qe),u.floating?.close(v,s.key)}),()=>s.setOpenInPanel(null)),[u,a,s,v,t]);let b=ee(w=>s.reportSourceSize(w===null?null:Oa(w)),[s]),R=c?.name??l,m=c?.version??d;return g.status!=="ready"?r(ae,{name:R,description:m,stage:g.status==="failed"?"error":"connecting",message:g.status==="failed"?g.message??n("workspace.needsNewerApp"):n("stream.connecting")}):r(aa,{transport:g.transport,platform:d,deviceId:l,deviceName:R,deviceDescription:m,axOverlay:!1,withControls:!1,onHandle:kt,onStreaming:kt,onScreen:b})}var ra=(...e)=>e.filter((a,t,o)=>!!a&&a.trim()!==""&&o.indexOf(a)===t).join(" ").trim();var Pt=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var At=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,t,o)=>o?o.toUpperCase():t.toLowerCase());var xa=e=>{let a=At(e);return a.charAt(0).toUpperCase()+a.slice(1)};var Tt={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var Bt=e=>{for(let a in e)if(a.startsWith("aria-")||a==="role"||a==="title")return!0;return!1};var Mt=Oe(({color:e="currentColor",size:a=24,strokeWidth:t=2,absoluteStrokeWidth:o,className:l="",children:d,iconNode:s,...u},n)=>ue("svg",{ref:n,...Tt,width:a,height:a,stroke:e,strokeWidth:o?Number(t)*24/Number(a):t,className:ra("lucide",l),...!d&&!Bt(u)&&{"aria-hidden":"true"},...u},[...s.map(([i,p])=>ue(i,p)),...Array.isArray(d)?d:[d]]));var y=(e,a)=>{let t=Oe(({className:o,...l},d)=>ue(Mt,{ref:d,iconNode:a,className:ra(`lucide-${Pt(xa(e))}`,`lucide-${e}`,o),...l}));return t.displayName=xa(e),t};var Ko=[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",key:"18u6gg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]],ve=y("camera",Ko);var Xo=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],ye=y("chevron-down",Xo);var $o=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],we=y("chevron-left",$o);var jo=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]],re=y("ellipsis",jo);var Zo=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"r6nss1"}]],le=y("house",Zo);var Jo=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],be=y("info",Jo);var Qo=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],ke=y("moon",Qo);var Yo=[["path",{d:"M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4",key:"daa4of"}],["rect",{width:"10",height:"7",x:"12",y:"13",rx:"2",key:"1nb8gs"}]],De=y("picture-in-picture-2",Yo);var er=[["path",{d:"M12 2v10",key:"mnfbl"}],["path",{d:"M18.4 6.6a9 9 0 1 1-12.77.04",key:"obofu9"}]],Pe=y("power",er);var ar=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],he=y("rotate-ccw",ar);var tr=[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]],Ae=y("rotate-cw",tr);var or=[["path",{d:"M10 5H3",key:"1qgfaw"}],["path",{d:"M12 19H3",key:"yhmn1j"}],["path",{d:"M14 3v4",key:"1sua03"}],["path",{d:"M16 17v4",key:"1q0r14"}],["path",{d:"M21 12h-9",key:"1o4lsq"}],["path",{d:"M21 19h-5",key:"1rlt1p"}],["path",{d:"M21 5h-7",key:"1oszz2"}],["path",{d:"M8 10v4",key:"tgpxqk"}],["path",{d:"M8 12H3",key:"a7s4jb"}]],Te=y("sliders-horizontal",or);var rr=[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]],xe=y("smartphone",rr);var lr=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]],Be=y("square",lr);var sr=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],Me=y("sun",sr);var dr=[["path",{d:"M12 4v16",key:"1654pz"}],["path",{d:"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2",key:"e0r10z"}],["path",{d:"M9 20h6",key:"s66wpe"}]],Re=y("type",dr);var ur=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Y=y("x",ur);function nr(e,a){let t=o=>a(o==="hub"?"versions.hubName":"versions.agentName");return e.status==="starting"?a("panel.startingHost"):e.status!=="installing"?e.message??"":e.tool&&e.toVersion?e.fromVersion?a("panel.updatingTool",{tool:t(e.tool),from:e.fromVersion,to:e.toVersion}):a("panel.installingTool",{tool:t(e.tool),to:e.toVersion}):a("panel.installing")}function Ia(){let{t:e}=B();return a=>nr(a,e)}function Rt(e){let{t:a}=B(),t=Ia(),[o,l]=L(!1),d=e.detail;return!d||d.status==="ready"||d.status==="idle"?null:d.status==="failed"?f("div",{role:"alert",className:"flex items-start gap-2 border-b bg-destructive/5 px-3 py-2 text-xs",children:[f("div",{className:"min-w-0 flex-1 space-y-0.5",children:[r("p",{className:"font-medium text-destructive-foreground",children:a("panel.hostFailed")}),d.message?r("p",{className:"whitespace-pre-wrap break-words text-muted-foreground",children:d.message}):null]}),f(S,{size:"xs",variant:"outline",disabled:o,onClick:()=>{l(!0),e.onRetry().finally(()=>l(!1))},children:[o?r(H,{size:"xs"}):r(Ae,{}),a(o?"panel.retrying":"panel.retry")]})]}):f("div",{role:"status",className:"flex items-center gap-2 border-b px-3 py-2 text-xs text-muted-foreground",children:[r(H,{size:"xs"}),r("span",{className:"min-w-0 flex-1",children:t(d)})]})}var Ca=["hub","agent"],Sa=e=>e!==void 0&&!e.installedVersions.includes(e.requiredVersion);function Ft(e){let{t:a}=B(),t=oe(),[o,l]=L(null),[d,s]=L(null),[u,n]=L(!1),i=e.host?.tools,p=e.busy||o!==null,g=c=>{l(c),s(null),n(!1),(c==="check"?t("inspect",e.environmentId):t("updateTool",e.environmentId,{tool:c})).then(()=>n(c==="check")).catch(()=>s(a(c==="check"?"versions.checkFailed":"versions.updateFailed"))).finally(()=>l(null))},v=c=>c??a("versions.none");return f($a,{children:[f(ja,{render:r(S,{size:"xs",variant:"ghost","aria-label":a("versions.title")}),children:[r(be,{}),a("versions.title"),Ca.some(c=>Sa(i?.[c]))?r("span",{className:"size-1.5 rounded-full bg-warning","aria-hidden":!0}):null]}),r(Za,{side:"bottom",align:"start",className:"w-80",children:f("div",{className:"space-y-3 text-xs",children:[Ca.map(c=>{let h=i?.[c];return f("section",{className:"space-y-1",children:[r("h4",{className:"font-medium text-foreground",children:a(c==="hub"?"versions.hubName":"versions.agentName")}),f("dl",{className:"grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-muted-foreground",children:[r("dt",{children:a("versions.required")}),r("dd",{className:"font-mono",children:v(h?.requiredVersion)}),r("dt",{children:a("versions.installed")}),r("dd",{className:"font-mono",children:h&&h.installedVersions.length>0?h.installedVersions.join(", "):a("versions.none")}),r("dt",{children:a("versions.running")}),r("dd",{className:"font-mono",children:v(h?.runningVersion)})]}),Sa(h)?f(S,{size:"xs",variant:"outline",disabled:p,onClick:()=>g(c),children:[o===c?r(H,{size:"xs"}):null,a("versions.updateTo",{version:h?.requiredVersion??""})]}):null]},c)}),i===void 0?r("p",{className:"text-muted-foreground",children:a("versions.unknown")}):null,Ca.some(c=>Sa(i?.[c]))?r("p",{className:"text-muted-foreground",children:a("versions.pendingPolicy")}):null,d?r("p",{role:"alert",className:"text-destructive-foreground",children:d}):null,f("div",{className:"flex items-center justify-between gap-2 border-t pt-2",children:[r("p",{role:"status",className:"text-muted-foreground",children:a(u?"versions.checked":"versions.checkHint")}),f(S,{size:"xs",variant:"ghost",disabled:p,onClick:()=>g("check"),children:[o==="check"?r(H,{size:"xs"}):null,a("versions.check")]})]})]})})]})}var Fe=e=>e>=1073741824?`${(e/1073741824).toFixed(2)} GB`:`${(e/1048576).toFixed(1)} MB`;function Et(e){let{phase:a,receivedBytes:t,totalBytes:o,bytesPerSecond:l}=e,d=a==="download"&&t!==void 0&&o?{received:t,total:o}:null,s=d&&l?(d.total-d.received)/l:null;return{titleKey:`environment.stages.${a??"starting"}`,component:e.component??"",percent:d?Math.floor(d.received/d.total*100):null,transferred:d?{done:Fe(d.received),total:Fe(d.total)}:null,speed:d&&l?Fe(l):null,minutesLeft:s===null?null:Math.ceil(s/60),slow:s!==null&&s>1200}}var Ot=e=>e.source==="private"&&e.ready;function Ut(e){return e.supported?e.freeBytes!==null&&e.freeBytes<e.requiredFreeBytes?"environment.notEnoughSpace":null:e.reasonCode?`environment.reasons.${e.reasonCode}`:"environment.unsupported"}function qt(e,a){return e.cacheBytes>0||a==="android"&&e.deviceDataBytes>0}function Ht(e){let{t:a}=B(),t=Et(e.progress),o=[t.transferred?a("environment.transferred",t.transferred):null,t.speed?a("environment.speed",{speed:t.speed}):null,t.minutesLeft===null?null:a("environment.timeLeft",{minutes:String(t.minutesLeft)})].filter(l=>l!==null);return f("div",{role:"status",className:"space-y-2",children:[f("p",{className:"flex items-center gap-2 font-medium text-foreground",children:[r(H,{size:"xs"}),a(t.titleKey,{component:t.component})]}),t.percent===null?null:r("div",{role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":t.percent,className:"h-1.5 overflow-hidden rounded-full bg-muted",children:r("div",{className:"h-full rounded-full bg-primary",style:{width:`${t.percent}%`}})}),o.length>0?r("p",{children:o.join(" \xB7 ")}):null,t.slow?r("p",{className:"text-warning-foreground",children:a("environment.slowDownload")}):null,r("p",{children:a("environment.continues")}),r(S,{size:"sm",variant:"outline",disabled:e.cancelling,onClick:e.onCancel,children:a("environment.cancel")})]})}function Nt(e){let{t:a}=B(),t=oe(),l=q().commands.useSubscription("environmentProgress",{},{environmentId:e.environmentId}).data,[d,s]=L(!1),[u,n]=L("android"),[i,p]=L(""),[g,v]=L(""),[c,h]=L(null),[b,R]=L(!1),[m,w]=L(!1),[C,k]=L(!1),[F,_]=L(null),[N,E]=L(!1),[W,O]=L(!1),[j,K]=L(void 0),G=l?.status==="working",U=F!==null||G,I=l&&l.id!==j?l:null;T(()=>{(G||I?.status==="failed")&&s(!0),I?.status==="done"&&I.plan?.platform===u&&h(I.plan)},[I,u,G]);let X=()=>{h(null),R(!1),w(!1),k(!1),O(!1),K(l?.id)},x=async(M,fo={})=>{_(M),E(!1),O(!1),K(l?.id);try{let co=await t(M,e.environmentId,{platform:u,directory:i,version:g,...fo});M==="cleanupEnvironment"?h(await t("environmentPlan",e.environmentId,{platform:u,directory:i,version:g})):M!=="prepareEnvironment"&&h(co),O(M==="cleanupEnvironment")}catch{E(!0)}finally{_(null)}},D=c?Ut(c):null,A=M=>M===null?a("environment.unknownSize"):Fe(M),V=c!==null&&Ot(c);return f(We,{open:d,onOpenChange:s,className:"w-full text-left",children:[r(Ke,{render:r(S,{variant:"outline",size:"sm",className:"w-full"}),children:a("environment.title")}),r(Xe,{children:f("div",{className:"space-y-3 rounded-md border p-3 text-xs",children:[G?r(Ht,{progress:l,cancelling:F==="cancelEnvironment",onCancel:()=>{_("cancelEnvironment"),t("cancelEnvironment",e.environmentId,{}).catch(()=>E(!0)).finally(()=>_(null))}}):f(J,{children:[r("p",{children:a("environment.description")}),e.iosSupported?r("div",{className:"flex gap-2",children:["android","ios"].map(M=>r(S,{size:"sm",variant:u===M?"default":"outline",disabled:U,onClick:()=>{n(M),X()},children:a(M==="ios"?"panel.platformIos":"panel.platformAndroid")},M))}):null,f("label",{className:"block space-y-1",children:[r("span",{children:a("environment.directory")}),r(te,{value:i,disabled:U,onChange:M=>{p(M.target.value),X()},placeholder:a("environment.defaultDirectory")})]}),r("p",{children:a("environment.directoryHint")}),u==="ios"?f("label",{className:"block space-y-1",children:[r("span",{children:a("environment.iosVersion")}),r(te,{value:g,disabled:U,onChange:M=>{v(M.target.value),X()},placeholder:a("environment.iosVersionPlaceholder")})]}):null,r(S,{size:"sm",variant:"outline",disabled:U,onClick:()=>{x("environmentPlan")},children:a("environment.inspect")}),c?f("div",{className:"space-y-2",children:[f("dl",{className:"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 break-all",children:[r("dt",{children:a("environment.source")}),r("dd",{children:a(`environment.sources.${c.source}`)}),r("dt",{children:a("environment.version")}),r("dd",{children:c.version||a("environment.versionRequired")}),r("dt",{children:a("environment.location")}),r("dd",{children:c.root}),c.existingSdkRoot?f(J,{children:[r("dt",{children:a("environment.existingSdk")}),r("dd",{children:c.existingSdkRoot})]}):null,r("dt",{children:a("environment.download")}),r("dd",{children:c.downloadBytes===0?a("environment.nothingToDownload"):A(c.downloadBytes)}),r("dt",{children:a("environment.free")}),r("dd",{children:A(c.freeBytes)}),r("dt",{children:a("environment.required")}),r("dd",{children:A(c.requiredFreeBytes)})]}),c.source==="external"?r("p",{children:a("environment.external")}):null,c.reasonCode&&c.supported?r("p",{role:"status",children:a(`environment.reasons.${c.reasonCode}`)}):null,r("a",{className:"underline",href:c.guidanceUrl,target:"_blank",rel:"noreferrer",children:a("environment.guide")}),u==="ios"?r("p",{children:a("environment.appleOwnership")}):r("p",{children:a("environment.privateOwnership")}),V?r("p",{role:"status",className:"font-medium text-foreground",children:a("environment.ready")}):f(J,{children:[r("ul",{children:c.licenses.map(M=>r("li",{children:r("a",{className:"underline",href:M.url,target:"_blank",rel:"noreferrer",children:a(u==="ios"?"environment.appleLicense":"environment.androidLicense")})},M.url))}),f("label",{className:"flex items-center gap-2",children:[r(ce,{checked:b,disabled:U,onCheckedChange:R}),r("span",{children:a("environment.acceptLicense")})]}),u==="ios"?f("label",{className:"flex items-center gap-2",children:[r(ce,{checked:m,disabled:U,onCheckedChange:w}),r("span",{children:a("environment.confirmApple")})]}):null,D?r("p",{role:"alert",className:"font-medium text-warning-foreground",children:a(D)}):null,r(S,{size:"sm",disabled:U||!c.supported||!b||u==="ios"&&(!m||!g)||c.freeBytes===null||c.freeBytes<c.requiredFreeBytes,onClick:()=>{x("prepareEnvironment",{acceptLicenses:b,confirmAppleInstall:m})},children:a("environment.prepare")})]}),qt(c,u)?f("div",{className:"space-y-2 border-t pt-2",children:[r("p",{children:a("environment.retention")}),r(S,{size:"sm",variant:"outline",disabled:U||c.cacheBytes===0,onClick:()=>{x("cleanupEnvironment",{category:"cache",confirm:!0})},children:a("environment.cleanCache",{size:A(c.cacheBytes)})}),u==="android"?f(J,{children:[r("p",{children:a("environment.deviceData",{size:A(c.deviceDataBytes)})}),f("label",{className:"flex items-center gap-2",children:[r(ce,{checked:C,disabled:U,onCheckedChange:k}),r("span",{children:a("environment.confirmData")})]}),r(S,{size:"sm",variant:"destructive",disabled:U||!C||c.deviceDataBytes===0,onClick:()=>{x("cleanupEnvironment",{category:"devices",confirm:C})},children:a("environment.cleanDevices")})]}):null]}):null]}):null]}),F!==null&&!G?f("p",{role:"status",className:"flex items-center gap-2",children:[r(H,{size:"xs"}),a("environment.working")]}):null,N?r("p",{role:"alert",className:"text-destructive-foreground",children:a("environment.failed")}):null,I?.status==="failed"?f("div",{role:"alert",className:"space-y-1 text-destructive-foreground",children:[r("p",{children:a("environment.prepareFailed")}),I.message?r("p",{className:"whitespace-pre-wrap break-words text-muted-foreground",children:I.message}):null]}):null,I?.status==="cancelled"?r("p",{role:"status",children:a("environment.cancelled")}):null,W?r("p",{role:"status",children:a("environment.cleaned")}):null]})})]})}var Gt=["small","default","large","extra-large"],ir=e=>Gt.includes(e);function Vt(e){let{t:a}=B(),{handle:t,controls:o}=e,l=o.detail?.settings,d=!t?.inputConnected,s=l?.appearance==="dark"?"light":"dark",u=n=>a(n==="small"?"rail.textSmall":n==="default"?"rail.textDefault":n==="large"?"rail.textLarge":"rail.textExtraLarge");return r("aside",{"aria-label":a("rail.label"),className:"pointer-events-none absolute inset-y-0 right-0 z-10 flex w-14 flex-col items-center justify-center gap-2 overflow-y-auto py-3 pr-2",children:f("div",{className:"pointer-events-auto flex shrink-0 flex-col items-center gap-1 rounded-full border border-border/50 bg-background/80 p-2 shadow-sm",children:[r(se,{label:a("rail.home"),disabled:d,onClick:()=>t?.pressButton("home"),children:r(le,{})}),e.platform==="android"?f(J,{children:[r(se,{label:a("rail.back"),disabled:d,onClick:()=>t?.pressButton("back"),children:r(we,{})}),r(se,{label:a("rail.recents"),disabled:d,onClick:()=>t?.pressButton("recents"),children:r(Be,{})}),f(Ve,{children:[r(_e,{render:r(S,{size:"icon-sm",variant:"ghost","aria-label":a("rail.rotate"),disabled:o.disabled}),children:r(he,{})}),f(ze,{side:"left",children:[r(Ce,{onClick:()=>{o.act({type:"setOrientation",value:"portrait"})},children:a("rail.portrait")}),r(Ce,{onClick:()=>{o.act({type:"setOrientation",value:"landscape_left"})},children:a("rail.landscape")})]})]})]}):r(se,{label:a("rail.rotate"),disabled:d,onClick:()=>t?.rotate(),children:r(he,{})}),r(fr,{}),r(se,{label:a(s==="dark"?"rail.toDark":"rail.toLight"),disabled:o.disabled||!l?.appearance,onClick:()=>{o.act({type:"setAppearance",value:s})},children:l?.appearance==="dark"?r(Me,{}):r(ke,{})}),f(Ve,{children:[r(_e,{render:r(S,{size:"icon-sm",variant:"ghost","aria-label":a("rail.textSize"),title:a("rail.textSize"),disabled:o.disabled||!l?.textSize}),children:r(Re,{})}),r(ze,{side:"left",children:r(za,{value:l?.textSize??"",onValueChange:n=>{ir(n)&&o.act({type:"setTextSize",value:n})},children:Gt.map(n=>r(_a,{value:n,children:u(n)},n))})})]}),r(se,{label:a("rail.tools"),pressed:e.toolsOpen,onClick:e.onTools,children:r(Te,{})}),r(se,{label:e.screenshotPending?a("rail.capturing"):a("rail.screenshot"),disabled:!e.streaming||e.screenshotPending,onClick:e.onScreenshot,children:r(ve,{})}),e.onFloat?r(se,{label:a("rail.float"),onClick:e.onFloat,children:r(De,{})}):null,f(Ve,{children:[r(_e,{render:r(S,{size:"icon-sm",variant:"ghost","aria-label":a("rail.more"),title:a("rail.more")}),children:r(re,{})}),f(ze,{side:"left",align:"end",children:[f(Ce,{onClick:e.onClose,children:[r(Y,{}),a("rail.closePanel")]}),r(Va,{}),f(Ce,{variant:"destructive",onClick:e.onPowerOff,children:[r(Pe,{}),a("rail.powerOff")]})]})]})]})})}function fr(){return r("div",{"aria-hidden":!0,className:"my-1 h-px w-5 shrink-0 bg-border/70"})}function se(e){return f(Ha,{children:[r(Ga,{render:r(S,{size:"icon-sm",variant:e.pressed?"secondary":"ghost","aria-label":e.label,"aria-pressed":e.pressed,disabled:e.disabled,onClick:e.onClick}),children:e.children}),r(Na,{side:"left",children:e.label})]})}var va=(e,a)=>new ta("invalid-input",`Invalid ${e}: ${a}.`);var zt=4096,_t=["light","dark"],Wt=["small","default","large","extra-large"];var Kt=["clear","tinted"],Xt=["none","grayscale","red-green","green-red","blue-yellow"],$t=["portrait","landscape_left","portrait_upside_down","landscape_right"],jt=["camera","microphone","photos","contacts","calendar","reminders","location","notifications","motion","media-library","faceid"];var cr=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);var Zt=e=>{let a=typeof e=="string"?{aps:{alert:e}}:e;if(!cr(a))throw va("push payload","expected a string or an object");let t;try{t=JSON.stringify(a)}catch{t=void 0}if(t===void 0)throw va("push payload","could not be encoded as JSON");if(new TextEncoder().encode(t).length>zt)throw va("push payload",`larger than ${String(zt)} bytes`);return t};var pr=new Set(["setAppearance","setTextSize","setToggle","setLiquidGlass","setColorFilter","setLocation","clearLocation","setPermission","openUrl","launchApp","relaunchApp","terminateApp","sendPush"]),mr=new Set(["setAppearance","setTextSize","setToggle","setOrientation","setLocation","setPermission","openUrl","launchApp","relaunchApp","terminateApp"]),gr=new Set(["reduceMotion","increaseContrast","reduceTransparency","showBorders","voiceOver"]),Lr=new Set(["reduceMotion","networkEnabled"]),ya=(e,a)=>(e==="ios"?pr:mr).has(a.type)?a.type==="setToggle"?(e==="ios"?gr:Lr).has(a.setting):!0:!1;function ie(e){return f("section",{className:"flex flex-col gap-2 border-b px-3 py-2.5",children:[r("h3",{className:"text-xs font-medium text-muted-foreground",children:e.title}),e.children]})}function de(e){return f("div",{className:"flex min-h-7 items-center justify-between gap-3",children:[r("span",{className:"shrink-0 text-xs text-muted-foreground",children:e.label}),r("div",{className:"flex min-w-0 items-center justify-end",children:e.children})]})}function wa(e){return r(de,{label:e.label,children:r(ce,{"aria-label":e.label,checked:e.checked??!1,disabled:e.disabled||e.checked===void 0,onCheckedChange:a=>{e.onChange(a)}})})}function ba(e){return r(Ka,{"aria-label":e.label,variant:"outline",value:e.value===void 0?[]:[e.value],disabled:e.disabled||e.value===void 0,onValueChange:a=>{let t=e.options.find(o=>o.value===a[0]);t&&e.onChange(t.value)},children:e.options.map(a=>r(Xa,{size:"xs",value:a.value,children:a.label},a.value))})}function Ee(e){let a=e.options.find(t=>t.value===e.value);return f(ia,{value:e.value,disabled:e.disabled,onValueChange:t=>{let o=e.options.find(l=>l.value===t);o&&o.value!==e.value&&e.onChange(o.value)},children:[r(fa,{size:"xs",className:e.width??"w-40","aria-label":e.ariaLabel,children:r(ca,{children:a?a.label:r("span",{className:"text-muted-foreground",children:e.placeholder})})}),r(pa,{align:"end",alignItemWithTrigger:!1,children:e.options.map(t=>r(ma,{value:t.value,children:t.label},t.value))})]})}function ka(e){let[a,t]=L(""),o=a.trim()||e.fallback||"",l=()=>{o&&e.onSubmit(o).then(()=>t(""))};return f("form",{className:"flex gap-1.5",onSubmit:d=>{d.preventDefault(),l()},children:[r(te,{size:"compact",className:"min-w-0 flex-1 font-mono",placeholder:e.placeholder,"aria-label":e.placeholder,value:a,disabled:e.disabled,onChange:d=>t(d.target.value)}),r(S,{type:"submit",size:"xs",variant:"outline",disabled:e.disabled||!o,children:e.action})]})}var Jt=[{key:"tools.location.sanFrancisco",latitude:37.7749,longitude:-122.4194},{key:"tools.location.newYork",latitude:40.7128,longitude:-74.006},{key:"tools.location.london",latitude:51.5074,longitude:-.1278},{key:"tools.location.stockholm",latitude:59.3293,longitude:18.0686},{key:"tools.location.tokyo",latitude:35.6762,longitude:139.6503}];function Yt(e){let{t:a}=B(),[t,o]=L(e.current?String(e.current.latitude):""),[l,d]=L(e.current?String(e.current.longitude):""),s={latitude:Number(t),longitude:Number(l)},u=t.trim()!==""&&l.trim()!==""&&Math.abs(s.latitude)<=90&&Math.abs(s.longitude)<=180,n=(i,p)=>e.act({type:"setLocation",latitude:i,longitude:p});return f(ie,{title:a("tools.location.title"),children:[f("div",{className:"flex gap-1.5",children:[r(te,{size:"compact",className:"min-w-0 flex-1 font-mono",placeholder:a("tools.location.latitude"),"aria-label":a("tools.location.latitude"),inputMode:"decimal",value:t,disabled:e.disabled,onChange:i=>o(i.target.value)}),r(te,{size:"compact",className:"min-w-0 flex-1 font-mono",placeholder:a("tools.location.longitude"),"aria-label":a("tools.location.longitude"),inputMode:"decimal",value:l,disabled:e.disabled,onChange:i=>d(i.target.value)})]}),f("div",{className:"flex flex-wrap items-center gap-1.5",children:[f(ia,{value:null,disabled:e.disabled,onValueChange:i=>{let p=Jt.find(g=>g.key===i);p&&(o(String(p.latitude)),d(String(p.longitude)),n(p.latitude,p.longitude))},children:[r(fa,{size:"xs",className:"w-32","aria-label":a("tools.location.preset"),children:r(ca,{children:r("span",{className:"text-muted-foreground",children:a("tools.location.presetPlaceholder")})})}),r(pa,{align:"start",alignItemWithTrigger:!1,children:Jt.map(i=>r(ma,{value:i.key,children:a(i.key)},i.key))})]}),r(S,{size:"xs",variant:"outline",disabled:e.disabled||!u,onClick:()=>{n(s.latitude,s.longitude)},children:a("tools.location.set")}),e.canClear?r(S,{size:"xs",variant:"ghost",disabled:e.disabled,onClick:()=>{o(""),d(""),e.act({type:"clearLocation"})},children:a("tools.location.clear")}):null]}),e.current?r("p",{role:"status",className:"text-xs text-muted-foreground",children:a("tools.location.current",{latitude:e.current.latitude,longitude:e.current.longitude})}):null]})}var hr={camera:"tools.permissions.camera",microphone:"tools.permissions.microphone",photos:"tools.permissions.photos",contacts:"tools.permissions.contacts",calendar:"tools.permissions.calendar",reminders:"tools.permissions.reminders",location:"tools.permissions.location",notifications:"tools.permissions.notifications",motion:"tools.permissions.motion","media-library":"tools.permissions.mediaLibrary",faceid:"tools.permissions.faceId"},xr=new Set(["camera","microphone","photos","contacts","calendar","location","notifications","motion"]);function eo(e){let{t:a}=B(),t=e.platform==="ios",[o,l]=L(""),[d,s]=L("camera"),u=o.trim()||e.defaultAppId,n=jt.filter(p=>t||xr.has(p)).map(p=>({value:p,label:a(!t&&p==="motion"?"tools.permissions.activity":hr[p])})),i=p=>{e.act({type:"setPermission",appId:u,permission:d,decision:p})};return f(ie,{title:a("tools.permissions.title"),children:[r(te,{size:"compact",className:"font-mono",placeholder:e.defaultAppId||a("tools.permissions.appId"),"aria-label":a("tools.permissions.appId"),value:o,disabled:e.disabled,onChange:p=>l(p.target.value)}),f("div",{className:"flex flex-wrap items-center gap-1.5",children:[r(Ee,{ariaLabel:a("tools.permissions.permission"),value:d,options:n,placeholder:a("tools.unknown"),disabled:e.disabled,onChange:p=>(s(p),Promise.resolve())}),r(S,{size:"xs",variant:"outline",disabled:e.disabled||!u,onClick:()=>i("grant"),children:a("tools.permissions.grant")}),r(S,{size:"xs",variant:"outline",disabled:e.disabled||!u,onClick:()=>i("revoke"),children:a("tools.permissions.revoke")}),t?r(S,{size:"xs",variant:"ghost",disabled:e.disabled||!u,onClick:()=>i("reset"),children:a("tools.permissions.reset")}):null]})]})}var Ir=e=>{let a=e;try{let t=JSON.parse(e);typeof t=="object"&&t!==null&&!Array.isArray(t)&&(a=t)}catch{}try{return Zt(a),a}catch{return null}};function ao(e){let{t:a}=B(),[t,o]=L(""),l=t.trim(),d=l?Ir(l):null,s=e.appId;return f(ie,{title:a("tools.push.title"),children:[r(Wa,{size:"sm",rows:4,className:"font-mono",placeholder:a("tools.push.placeholder"),"aria-label":a("tools.push.placeholder"),value:t,disabled:e.disabled||!s,onChange:u=>o(u.target.value)}),f("div",{className:"flex items-center gap-2",children:[r(S,{size:"xs",variant:"outline",disabled:e.disabled||!s||d===null,onClick:()=>{s&&d!==null&&e.act({type:"sendPush",appId:s,payload:d})},children:a("tools.push.send")}),s?l&&d===null?r("p",{className:"text-xs text-destructive-foreground",children:a("tools.push.invalid")}):null:r("p",{className:"text-xs text-muted-foreground",children:a("tools.push.needsApp")})]})]})}var Qt=100;function to(e){let{t:a}=B(),[t,o]=L(!1),[l,d]=L([]),{transport:s,platform:u,deviceId:n}=e;return T(()=>{if(!t)return;let i=rt({transport:s,platform:u,deviceId:n},(p,g)=>{d(v=>{let c=g?[...p]:[...v,...p];return c.length>Qt?c.slice(-Qt):c})});return()=>{i(),d([])}},[t,s,u,n]),f(We,{open:t,onOpenChange:o,children:[f(Ke,{className:"flex w-full items-center gap-1.5 border-b px-3 py-2.5 text-left text-xs font-medium text-muted-foreground",children:[a("tools.eventLog.title"),r(ye,{className:`ml-auto size-3.5 transition-transform ${t?"rotate-180":""}`})]}),r(Xe,{children:r("ol",{className:"max-h-64 overflow-y-auto px-3 py-2 font-mono text-ui-2xs leading-relaxed",children:l.length===0?r("li",{className:"text-muted-foreground",children:a("tools.eventLog.empty")}):l.map(i=>f("li",{className:"flex gap-2",children:[r("span",{className:"shrink-0 text-muted-foreground",children:i.timestamp.slice(11,19)}),r("span",{className:"truncate",children:i.summary})]},i.id))})})]})}var Cr=640,Sr={light:"tools.settings.light",dark:"tools.settings.dark"},vr={small:"tools.settings.textSmall",default:"tools.settings.textDefault",large:"tools.settings.textLarge","extra-large":"tools.settings.textExtraLarge"},yr={clear:"tools.settings.glassClear",tinted:"tools.settings.glassTinted"},wr={none:"tools.settings.filterNone",grayscale:"tools.settings.filterGrayscale","red-green":"tools.settings.filterRedGreen","green-red":"tools.settings.filterGreenRed","blue-yellow":"tools.settings.filterBlueYellow"},br={portrait:"tools.settings.orientationPortrait",landscape_left:"tools.settings.orientationLandscapeLeft",portrait_upside_down:"tools.settings.orientationUpsideDown",landscape_right:"tools.settings.orientationLandscapeRight"},kr=[{setting:"reduceMotion",labelKey:"tools.settings.reduceMotion"},{setting:"increaseContrast",labelKey:"tools.settings.increaseContrast"},{setting:"reduceTransparency",labelKey:"tools.settings.reduceTransparency"},{setting:"showBorders",labelKey:"tools.settings.showBorders"},{setting:"voiceOver",labelKey:"tools.settings.voiceOver"},{setting:"networkEnabled",labelKey:"tools.settings.network"}];function oo(e){let{t:a}=B(),{device:t,controls:o}=e,{detail:l,pending:d,error:s,foregroundApp:u,disabled:n,act:i}=o,p=l?.settings,g=t.platform==="ios",v=z(null),[c,h]=L(!0);Ba(()=>{let m=v.current?.parentElement;if(!m)return;let w=()=>h(m.clientWidth<Cr);w();let C=new ResizeObserver(w);return C.observe(m),()=>C.disconnect()},[]),T(()=>o.followDevice(),[o.followDevice]);let b=Wt.map(m=>({value:m,label:a(vr[m])})),R=kr.filter(m=>ya(t.platform,{type:"setToggle",setting:m.setting,value:!0}));return f("aside",{ref:v,"aria-label":a("tools.title"),className:`flex min-h-0 flex-col border-l bg-background text-sm ${c?"absolute inset-y-0 right-0 z-10 w-full max-w-72 shadow-lg":"w-72 shrink-0"}`,children:[f("div",{className:"flex h-9 shrink-0 items-center gap-2 border-b px-3",children:[r("span",{className:"font-medium",children:a("tools.title")}),d?r(H,{size:"sm"}):null,r(S,{size:"icon-xs",variant:"ghost-muted","aria-label":a("tools.close"),className:"ml-auto",onClick:e.onClose,children:r(Y,{})})]}),f("div",{className:"min-h-0 flex-1 overflow-y-auto",children:[s?r("p",{role:"alert",className:"border-b bg-destructive/10 px-3 py-2 text-xs text-destructive-foreground",children:s}):null,l===null&&!s?f("div",{className:"flex items-center gap-2 px-3 py-3 text-xs text-muted-foreground",children:[r(H,{size:"sm"}),a("tools.reading")]}):null,f(ie,{title:a("tools.app.title"),children:[r(de,{label:a("tools.app.foreground"),children:r("span",{className:"truncate font-mono text-xs",children:u?.id??a("tools.app.none")})}),u?f("div",{className:"flex gap-1.5",children:[r(S,{size:"xs",variant:"outline",disabled:n,onClick:()=>{i({type:"terminateApp",appId:u.id})},children:a("tools.app.terminate")}),r(S,{size:"xs",variant:"outline",disabled:n,onClick:()=>{i({type:"relaunchApp",appId:u.id})},children:a("tools.app.relaunch")})]}):null,r(ka,{placeholder:a("tools.app.urlPlaceholder"),action:a("tools.app.open"),disabled:n,onSubmit:m=>i({type:"openUrl",url:m})}),r(ka,{placeholder:a(g?"tools.app.bundleIdPlaceholder":"tools.app.packagePlaceholder"),action:a("tools.app.launch"),disabled:n,fallback:u?.id,onSubmit:m=>i({type:"launchApp",appId:m})})]}),f(ie,{title:a(g?"tools.settings.titleIos":"tools.settings.titleAndroid"),children:[r(de,{label:a("tools.settings.appearance"),children:r(ba,{label:a("tools.settings.appearance"),value:p?.appearance,options:_t.map(m=>({value:m,label:a(Sr[m])})),disabled:n,onChange:m=>i({type:"setAppearance",value:m})})}),r(de,{label:a("tools.settings.textSize"),children:r(Ee,{ariaLabel:a("tools.settings.textSize"),value:p?.textSize??null,options:b,placeholder:a("tools.unknown"),disabled:n,onChange:m=>i({type:"setTextSize",value:m})})}),g?f(J,{children:[r(de,{label:a("tools.settings.liquidGlass"),children:r(ba,{label:a("tools.settings.liquidGlass"),value:p?.liquidGlass,options:Kt.map(m=>({value:m,label:a(yr[m])})),disabled:n,onChange:m=>i({type:"setLiquidGlass",value:m})})}),r(de,{label:a("tools.settings.colorFilter"),children:r(Ee,{ariaLabel:a("tools.settings.colorFilter"),value:p?.colorFilter??null,options:Xt.map(m=>({value:m,label:a(wr[m])})),placeholder:a("tools.unknown"),disabled:n,onChange:m=>i({type:"setColorFilter",value:m})})})]}):r(de,{label:a("tools.settings.orientation"),children:r(Ee,{ariaLabel:a("tools.settings.orientation"),value:null,options:$t.map(m=>({value:m,label:a(br[m])})),placeholder:a("tools.settings.rotateTo"),disabled:n,onChange:m=>i({type:"setOrientation",value:m})})}),R.map(m=>r(wa,{label:a(m.labelKey),checked:p?.[m.setting],disabled:n,onChange:w=>i({type:"setToggle",setting:m.setting,value:w})},m.setting))]}),r(ie,{title:a("tools.accessibility.title"),children:r(wa,{label:a("tools.accessibility.overlay"),checked:e.axOverlay,disabled:!1,onChange:m=>(e.onAxOverlayChange(m),Promise.resolve())})}),r(Yt,{current:o.location,canClear:ya(t.platform,{type:"clearLocation"}),disabled:n,act:i}),r(eo,{platform:t.platform,defaultAppId:u?.id??"",disabled:n,act:i}),g?r(ao,{appId:u?.id,disabled:n,act:i}):null,g?r(to,{transport:e.transport,platform:t.platform,deviceId:t.id}):null]})]})}var Dr=2e4,Da=class extends Error{status;constructor(a){super(`Screenshot capture failed (${a}). Try again.`),this.status=a}};async function ro(e,a,t,o){let l=AbortSignal.timeout(Dr),d=await e.fetch(`${pe(a)}/api/screenshot?device=${encodeURIComponent(t)}`,{method:"POST",signal:o?AbortSignal.any([o,l]):l});if(!d.ok)throw new Da(d.status);let s=await d.blob();if(!s.size)throw new Error("The device returned an empty screenshot. Try again.");return s.type?s:new Blob([s],{type:"image/png"})}var Pr=3e3,lo=e=>e instanceof Error?e.message:String(e);function so(e){let{environmentId:a,device:t}=e,o=oe(),[l,d]=L(null),[s,u]=L(null),[n,i]=L(!1),[p,g]=L(null),v=z(!1),c=z(0),h={hostId:t.hostId,deviceId:t.id},b=C=>o("detail",a,h).then(k=>{c.current===C&&(d(k),g(null))},k=>{c.current===C&&(d(null),g(lo(k)))});T(()=>{let C=++c.current;return b(C),()=>{c.current++}},[a,t.hostId,t.id]);let R=async C=>{if(v.current||l===null)return!1;v.current=!0;let k=++c.current;i(!0),g(null);try{let F=await o("action",a,{...h,...C});return c.current===k?d(F):await b(++c.current),C.type==="setLocation"?u({latitude:C.latitude,longitude:C.longitude}):C.type==="clearLocation"&&u(null),!0}catch(F){return c.current===k&&g(lo(F)),!1}finally{v.current=!1,i(!1)}},m=z(()=>{});m.current=()=>{if(v.current)return;let C=++c.current;o("detail",a,h).then(k=>{c.current===C&&d(k)},()=>{})};let w=ee(()=>{m.current();let C=setInterval(()=>m.current(),Pr);return()=>clearInterval(C)},[]);return{detail:l,location:s,pending:n,error:p,act:R,followDevice:w,disabled:n||l===null,foregroundApp:e.foreground===void 0?l?.foregroundApp??null:e.foreground}}var Ar=()=>typeof window<"u"&&"ReactNativeWebView"in window;function uo(e){let{t:a}=B(),t=oa(e.environmentId),[o,l]=L(null),[d,s]=L(!1),[u,n]=L(!1),[i,p]=L(!1),[g,v]=L(),[c,h]=L(!1),[b,R]=L(null),[m,w]=L(null),C=z(null),k=z(null),F=t.status==="ready"?t.transport:null,_=so({environmentId:e.environmentId,device:e.device,foreground:g}),N=ee(O=>l(O),[]),E=ee(O=>s(O),[]);T(()=>{if(!F)return;let O=ot({transport:F,platform:e.device.platform,deviceId:e.device.id},v);return()=>{O(),v(void 0)}},[e.device.id,e.device.platform,F]),T(()=>()=>{C.current?.abort(),k.current&&URL.revokeObjectURL(k.current)},[]);let W=()=>{if(!F||C.current)return;let O=new AbortController;C.current=O,h(!0),R(null),ro(F,e.device.platform,e.device.id,O.signal).then(j=>{if(O.signal.aborted)return;k.current&&URL.revokeObjectURL(k.current);let K=URL.createObjectURL(j);if(k.current=K,Ar()){w(K);return}let G=document.createElement("a");G.href=K,G.download=`${e.device.name.replace(/[^a-z0-9-]/gi,"-")}-${Date.now()}.png`,document.body.append(G),G.click(),G.remove()}).catch(j=>{O.signal.aborted||R(j instanceof Error?j.message:a("workspace.screenshotFailed"))}).finally(()=>{C.current===O&&(C.current=null,h(!1))})};return t.status!=="ready"?r(ae,{name:e.device.name,description:e.device.version,stage:t.status==="failed"?"error":"connecting",message:t.status==="failed"?t.message??a("workspace.needsNewerApp"):a("stream.connecting"),children:r(S,{size:"sm",variant:"outline",onClick:e.onBack,children:a("workspace.allDevices")})}):f("div",{className:"relative flex min-h-0 min-w-0 flex-1",children:[f("div",{className:"relative flex min-h-0 min-w-0 flex-1 flex-col",children:[b||_.error&&!u?r("p",{role:"alert",className:"px-3 py-2 text-xs text-destructive-foreground",children:b??_.error}):null,f("div",{className:"relative min-h-0 flex-1",children:[r(aa,{transport:t.transport,platform:e.device.platform,deviceId:e.device.id,deviceName:e.device.name,deviceDescription:e.device.version,axOverlay:i,withControls:!0,onHandle:N,onStreaming:E}),r(Vt,{platform:e.device.platform,handle:o,streaming:d,controls:_,screenshotPending:c,onScreenshot:W,toolsOpen:u,onTools:()=>n(!u),onClose:e.onClose,onPowerOff:e.onPowerOff,onFloat:e.onFloat})]})]}),u?r(oo,{device:e.device,controls:_,transport:t.transport,axOverlay:i,onAxOverlayChange:p,onClose:()=>n(!1)}):null,m?f("div",{className:"absolute inset-0 z-20 flex flex-col items-center justify-center gap-3 bg-background/95 p-4",children:[r("img",{src:m,alt:a("workspace.screenshotAlt"),className:"max-h-[80%] max-w-full object-contain"}),r("p",{className:"text-xs text-muted-foreground",children:a("workspace.screenshotSaveHint")}),f(S,{size:"sm",variant:"outline",onClick:()=>w(null),children:[r(Y,{}),a("workspace.closeBrowser")]})]}):null]})}var Pa=e=>e instanceof Error?e.message:String(e);function no(e){let{environmentId:a,threadId:t}=e,{t:o}=B(),{state:l,loaded:d,error:s,unavailable:u}=ge(a),n=oe(),[i,p]=L(null),[g,v]=L(null),c=Ua(a,t),h=I=>Ne(a,t,I),b=q(),R=fe(b,"floating"),m=()=>{p(null),n("refresh",a).catch(I=>p(Pa(I)))};T(()=>{!d||u||n("refresh",a).catch(()=>{})},[a,d,n,u]);let w=ne(()=>l.sessions.filter(I=>I.threadId===t),[l.sessions,t]),C=Br(w,c),k=C?l.devices.find(I=>I.hostId===C.hostId&&I.id===C.deviceId):void 0,F=k&&C?Ie(k):null;T(()=>{b.floating?.present({environmentId:a,threadId:t},F)}),T(()=>()=>b.floating?.present({environmentId:a,threadId:t},null),[b,a,t]);let _=ne(()=>Mr(l),[l]),N=l.hostStatuses[Le],E=N?.status==="ready",W=N?.status==="installing"||N?.status==="starting",O=Ia(),j=l.bootingDevices.filter(I=>I.threadId===t),K=l.hosts.flatMap(I=>I.platforms.filter(X=>!X.available)),G=async I=>{p(null),v(I),na(a,t,Z(I));try{await n("open",a,{threadId:t,hostId:I.hostId,deviceId:I.id,platform:I.platform}),h(Z(I))}catch(X){na(a,t,Z(I),!1),p(Pa(X))}finally{v(null)}},U=I=>{C&&(p(null),n("close",a,{threadId:t,hostId:C.hostId,deviceId:C.deviceId,shutdown:I}).then(()=>h(null)).catch(X=>p(Pa(X))))};return u?r(ae,{name:o("panel.title"),stage:"error",message:o("panel.unavailable")}):f("div",{className:"flex size-full min-h-0 flex-col",children:[j.length>0?r("div",{role:"status",className:"border-b px-3 py-2 text-xs text-muted-foreground",children:o("panel.booting",{names:j.map(I=>I.name).join(", ")})}):null,W&&!k?null:r(Rt,{detail:N,onRetry:()=>n("refresh",a).catch(()=>{})}),i||s?f("div",{role:"alert",className:"flex items-start gap-2 border-b bg-destructive/5 px-3 py-2 text-xs text-destructive-foreground",children:[r("p",{className:"min-w-0 flex-1 whitespace-pre-wrap break-words",children:i??s}),i?r(S,{size:"icon-xs",variant:"ghost","aria-label":o("panel.dismissError"),onClick:()=>p(null),children:r(Y,{className:"size-3"})}):null]}):null,r("div",{className:"relative flex min-h-0 flex-1",children:k&&C?r(uo,{environmentId:a,device:k,onBack:()=>h(""),onFloat:R?()=>b.floating?.open({environmentId:a,threadId:t},{...Ie(k),reason:"user"}):void 0,onPowerOff:()=>U(!0),onClose:()=>U(!1)},`${a}\0${Z(k)}`):g||W||!d?r(ae,{name:g?.name??o("panel.title"),...g?{description:g.version}:{},stage:"opening",message:g?g.booted?o("panel.opening"):o("panel.starting"):W&&N?O(N):o("panel.finding")}):r(Tr,{environmentId:a,host:l.hosts.find(I=>I.id===Le),grouped:_,hostReady:E,hostFailed:N?.status==="failed",unavailableReasons:K,showNoAvdHint:E&&!l.devices.some(I=>I.platform==="android")&&!K.some(I=>I.platform==="android"),pendingKey:g?Z(g):null,onOpen:I=>{G(I)},onRefresh:m})})]})}function Tr(e){let{t:a}=B(),t=e.grouped.length===0;return r("div",{className:"flex size-full flex-col overflow-y-auto px-4 py-6 text-sm text-muted-foreground",children:f("div",{className:`mx-auto flex w-full max-w-xl flex-col gap-5 ${t?"items-center text-center":""}`,children:[r(Nt,{environmentId:e.environmentId,iosSupported:!e.unavailableReasons.some(o=>o.reasonCode==="ios-needs-macos")},e.environmentId),t?f(J,{children:[r(xe,{className:"size-6 opacity-60"}),r("p",{className:"max-w-sm",children:e.hostFailed?a("panel.hubFailed"):a("panel.empty")})]}):null,e.hostReady?e.grouped.map(o=>f("section",{className:"w-full space-y-2 text-left",children:[f("h3",{className:"flex items-center gap-2 font-medium",children:[r(xe,{className:"size-4 shrink-0"}),o.platform==="ios"?a("panel.platformIos"):a("panel.platformAndroid")]}),r("ul",{className:"divide-y rounded-md border",children:o.devices.map(l=>r("li",{children:f(S,{variant:"ghost",className:"h-auto min-h-11 w-full justify-between gap-3 rounded-none px-3 py-2 text-left font-normal",disabled:e.pendingKey!==null,onClick:()=>e.onOpen(l),children:[f("span",{className:"min-w-0 flex-1",children:[r("span",{className:"block truncate text-foreground",children:l.name}),f("span",{className:"block text-xs",children:[l.version,","," ",l.booted?a("panel.running"):a("panel.stopped")]})]}),e.pendingKey===Z(l)?r(H,{size:"xs"}):r("span",{className:"text-xs",children:l.booted?a("panel.open"):a("panel.start")})]})},Z(l)))})]},o.platform)):null,e.unavailableReasons.map(o=>r("p",{className:"max-w-sm text-xs",children:o.reasonCode?a(`unavailable.${o.reasonCode}`,{root:o.sdkRoot??""}):o.reason},`${o.platform}:${o.reasonCode}`)),e.showNoAvdHint?r("p",{className:"max-w-sm text-xs",children:a("panel.noAvd")}):null,f("div",{className:`flex flex-wrap items-center gap-2 ${t?"self-center":"self-start"}`,children:[r(S,{variant:t?"outline":"ghost",size:"sm",onClick:e.onRefresh,children:a("panel.refresh")}),r(Ft,{environmentId:e.environmentId,host:e.host,busy:!1})]})]})})}function Br(e,a){if(a!==""){if(a!==null){let t=e.find(o=>Z({hostId:o.hostId,id:o.deviceId})===a);if(t)return t}return e.toSorted((t,o)=>o.openedAt.localeCompare(t.openedAt))[0]}}function Mr(e){let a=[];for(let t of["ios","android"]){let o=e.devices.filter(l=>l.platform===t).toSorted((l,d)=>Number(d.booted)-Number(l.booted)||l.name.localeCompare(d.name));o.length>0&&a.push({platform:t,devices:o})}return a}function io({environmentId:e,threadId:a}){let t=q(),{state:o,loaded:l}=ge(e),d=z(null);return T(()=>{if(!l||!fe(t,"floating"))return;let s=`${e}\0${a}`,u=d.current?.key===s?d.current.seen:null,{seen:n,opened:i}=qa({environmentId:e,threadId:a,previous:u,sessions:o.sessions,devices:o.devices});d.current={key:s,seen:n};for(let p of i)t.floating?.open({environmentId:e,threadId:a},{...Ie(p),reason:"agent",panelId:qe})},[t,e,l,o.devices,o.sessions,a]),null}function Rr(e){return{panels:{device:function(t){return f(Ue,{value:e,children:[r("style",{children:la}),r("div",{className:`${Ge} flex h-full min-h-0 flex-1 flex-col`,children:r(no,{environmentId:t.environmentId,threadId:t.threadId})})]})}},views:{deviceFloat:function(t){return f(Ue,{value:e,children:[r("style",{children:la}),r("div",{className:`${Ge} relative size-full`,children:r(Dt,{...t})})]})},deviceSessions:function(t){return r(Ue,{value:e,children:r(io,{environmentId:t.environmentId,threadId:t.threadId})})}}}}export{Rr as default};
|
|
560
|
+
`;var Lo=window.__ycodiumPluginHost.react;var{Activity:Ur,Children:qr,Component:Hr,Fragment:Nr,Profiler:Vr,PureComponent:Gr,StrictMode:zr,Suspense:_r,__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE:Wr,__COMPILER_RUNTIME:Kr,act:Xr,cache:$r,cacheSignal:jr,captureOwnerStack:Zr,cloneElement:Jr,createContext:Ta,createElement:ne,createRef:Qr,forwardRef:Oe,isValidElement:Yr,lazy:el,memo:al,startTransition:tl,unstable_useCacheRefresh:ol,use:rl,useActionState:ll,useCallback:ee,useContext:Ba,useDebugValue:sl,useDeferredValue:dl,useEffect:B,useEffectEvent:nl,useId:ul,useImperativeHandle:il,useInsertionEffect:fl,useLayoutEffect:Ma,useMemo:ue,useOptimistic:cl,useReducer:pl,useRef:H,useState:L,useSyncExternalStore:Ra,useTransition:ml,version:gl}=Lo;var Fa=Ta(null),Ue=Fa.Provider;function N(){let e=Ba(Fa);if(e===null)throw new Error("The devices panel has not been registered.");return e}var Ea=window.__ycodiumPluginHost.modules?.["@ycodium-ai/plugin-api/ui"];if(!Ea)throw new Error("This plugin needs a newer Ycodium app. Update the app.");var{HOST_TEAM_VIEW_PREFIX:Il,PLUGIN_UI_BRIDGE_VERSION:Cl,PLUGIN_UI_FLOATING_VIEW_PROP:Oa,PLUGIN_UI_GLOBAL_KEY:Sl,PLUGIN_UI_HOST_CAPABILITIES:vl,PLUGIN_UI_HOST_COMMAND_PALETTE_UNAVAILABLE_MESSAGE:yl,PLUGIN_UI_HOST_UPGRADE_MESSAGE:wl,TEAM_VIEW_KEY_PATTERN:bl,communicationRecordStage:kl,defineTeamView:Dl,isTeamViewKey:Pl,pluginUiHostHasCapability:fe}=Ea;var ho="deviceFloat",qe="device",Z=e=>`${e.hostId}\0${e.id}`;function Ie(e){let a={hostId:e.hostId,deviceId:e.id,platform:e.platform};return{viewId:ho,key:Z(e),title:e.name,props:{...a},sourceSize:e.platform==="ios"?{width:9,height:19.5}:{width:9,height:20},...e.platform==="android"?{cornerRatio:.14}:{}}}function Ua(e){let a=e.orientation==="landscape_left"||e.orientation==="landscape_right",t=Math.max(e.width,e.height),o=Math.min(e.width,e.height);return a?{width:t,height:o}:{width:o,height:t}}var sa=new Map,da=new Set,He=(e,a)=>`${e}\0${a}`;function qa(e,a){return Ra(t=>(da.add(t),()=>{da.delete(t)}),()=>sa.get(He(e,a))??null)}function Ne(e,a,t){let o=He(e,a);if((sa.get(o)??null)!==t){sa.set(o,t);for(let l of da)l()}}var na=new Set;function ua(e,a,t,o=!0){let l=`${He(e,a)}\0${t}`;o?na.add(l):na.delete(l)}function Ha(e){let a=new Set,t=[];for(let o of e.sessions){if(o.threadId!==e.threadId)continue;let l=e.devices.find(n=>n.hostId===o.hostId&&n.id===o.deviceId);if(l===void 0)continue;let d=Z(l);if(a.add(d),e.previous===null||e.previous.has(d))continue;let s=`${He(e.environmentId,e.threadId)}\0${d}`;na.delete(s)||t.push(l)}return{seen:a,opened:t}}var Ve="ycodium-devices-ui";function A(e){return(a=>ne(N().ui[e],{...a,className:`${Ve} ${typeof a.className=="string"?a.className:""}`}))}var S=A("Button"),V=A("Spinner"),ce=A("Switch"),Na=A("Tooltip"),Va=A("TooltipPopup"),Ga=A("TooltipTrigger"),Ge=A("Menu"),ze=A("MenuPopup"),Ce=A("MenuItem"),za=A("MenuSeparator"),_e=A("MenuTrigger"),_a=A("MenuRadioGroup"),Wa=A("MenuRadioItem"),te=A("Input"),Ka=A("Textarea"),ia=A("Select"),fa=A("SelectTrigger"),ca=A("SelectValue"),pa=A("SelectPopup"),ma=A("SelectItem"),We=A("Collapsible"),Ke=A("CollapsibleTrigger"),Xe=A("CollapsiblePanel"),Xa=A("ToggleGroup"),$a=A("Toggle"),ja=A("Popover"),Za=A("PopoverTrigger"),Ja=A("PopoverPopup");var{jsx:r,jsxs:f,Fragment:J}=window.__ycodiumPluginHost.jsxRuntime;function ae(e){return f("div",{className:"flex size-full flex-col items-center justify-center gap-3 p-6 text-center",children:[e.stage==="error"?null:r(V,{size:"sm"}),f("div",{className:"space-y-1",children:[r("p",{className:"text-sm font-medium text-foreground",children:e.name}),e.description?r("p",{className:"text-xs text-muted-foreground",children:e.description}):null]}),r("p",{role:e.stage==="error"?"alert":"status",className:e.stage==="error"?"max-w-sm whitespace-pre-wrap break-words text-xs text-destructive-foreground":"max-w-sm text-xs text-muted-foreground",children:e.message}),e.children]})}var $e=class{decoder=new TextDecoder;rawDecoder=new TextDecoder("utf-8",{ignoreBOM:!0});pending="";raw="";data=[];eventName="";lastId=null;push(a){let t=[];return this.scan(a,!1,(o,l)=>{l!==void 0&&t.push(l)}),t}pushBlocks(a){let t=[];return this.scan(a,!0,(o,l)=>t.push({raw:o,event:l})),t}scan(a,t,o){let l=this.decoder.decode(a,{stream:!0}),d=this.pending+l;if(this.rawDecoder!==void 0){let n=this.rawDecoder.decode(a,{stream:!0});t&&(this.raw+=n.slice(0,n.length-l.length)),d.length>0&&(this.rawDecoder=void 0,d.charCodeAt(0)===65279&&(t&&(this.raw+=d[0]),d=d.slice(1)))}let s=0;for(let n=0;n<d.length;n++){let u=d[n];if(u!==`
|
|
561
|
+
`&&u!=="\r")continue;if(u==="\r"&&n===d.length-1)break;let i=d.slice(s,n);u==="\r"&&d[n+1]===`
|
|
562
|
+
`&&n++,t&&(this.raw+=d.slice(s,n+1));let p=this.line(i);i===""&&(o(this.raw,p),this.raw=""),s=n+1}this.pending=d.slice(s)}flush(){let a=this.raw+this.pending+this.decoder.decode();return this.raw="",this.pending="",this.data=[],this.eventName="",a}line(a){if(a===""){let d=this.data.length>0?{event:this.eventName||"message",data:this.data.join(`
|
|
563
|
+
`),id:this.lastId}:void 0;return this.data=[],this.eventName="",d}if(a.startsWith(":"))return;let t=a.indexOf(":"),o=t===-1?a:a.slice(0,t),l=t===-1?"":a.slice(t+1);l.startsWith(" ")&&(l=l.slice(1)),o==="data"?this.data.push(l):o==="event"?this.eventName=l:o==="id"&&!l.includes("\0")&&(this.lastId=l)}};async function je(e,a,t){let o=e.body;if(!o)throw new Error("The response has no body to stream.");let l=o.getReader(),d=()=>{l.cancel().catch(()=>{})};if(t?.aborted)return d();t?.addEventListener("abort",d,{once:!0});try{for(;;){let{done:s,value:n}=await l.read();if(s||t?.aborted)return;a(n)}}catch(s){if(t?.aborted)return;throw s}finally{t?.removeEventListener("abort",d)}}async function Qa(e,a,t){if(!e.ok)throw await e.body?.cancel().catch(()=>{}),new Error(`Event stream failed (${e.status}).`);let o=new $e;await je(e,l=>{for(let d of o.push(l))a(d)},t)}var pe=e=>e==="ios"?"/vendor/serve-sim":"/vendor/serve-emu";var xo=1e3,Io=500,Ze=(e,a,t)=>`${pe(e.platform)}${a}${t?`?${new URLSearchParams(t).toString()}`:""}`,Ya=async(e,a,t)=>{let o=await e.transport.fetch(a,t?{signal:t}:void 0);if(!o.ok)throw new Error(`${o.status} ${o.statusText}`);return await o.json()},Q=e=>typeof e=="object"&&e!==null,$=(e,a)=>typeof e=="number"&&Number.isFinite(e)?e:a,Co=e=>{let a=e[0],t=Q(a)&&Q(a.frame)?a.frame:null,o=Math.max(1,$(t?.width,1)),l=Math.max(1,$(t?.height,1)),d=[],s=(n,u)=>{if(d.length>=Io||!Q(n)||!Q(n.frame))return;let i=n.frame,p=$(i.width,0),m=$(i.height,0);!(Math.abs(p-o)<.5&&Math.abs(m-l)<.5)&&p>0&&m>0&&d.push({id:typeof n.AXUniqueId=="string"?n.AXUniqueId:u,label:typeof n.AXLabel=="string"?n.AXLabel:"",role:typeof n.type=="string"?n.type:"",x:$(i.x,0)/o,y:$(i.y,0)/l,width:p/o,height:m/l}),(Array.isArray(n.children)?n.children:[]).forEach((h,k)=>s(h,`${u}.${k}`))};return e.forEach((n,u)=>s(n,String(u))),d},et=e=>Q(e)&&typeof e.error=="string"?e.error:"Unexpected accessibility payload.";async function tt(e,a){if(e.platform==="ios"){let u=await Ya(e,Ze(e,`/helper/${encodeURIComponent(e.deviceId)}/ax`),a);return Array.isArray(u)?{elements:Co(u),errors:[]}:{elements:[],errors:[et(u)]}}let t=await Ya(e,Ze(e,"/api/accessibility",{device:e.deviceId}),a);if(!Q(t)||!Array.isArray(t.nodes))return{elements:[],errors:[et(t)]};let o=t.nodes.filter(u=>Q(u)&&Q(u.bounds)),l=o[0]?.bounds,d=Math.max(1,$(l?.right,1)),s=Math.max(1,$(l?.bottom,1));return{elements:o.slice(1).flatMap(u=>{let i=u.bounds,p=$(i.left,0),m=$(i.top,0),C=($(i.right,p)-p)/d,c=($(i.bottom,m)-m)/s,h=typeof u.text=="string"?u.text:"",k=typeof u.contentDescription=="string"?u.contentDescription:"",R=h||k;if(C>=.95&&c>=.9)return[];if(!R&&u.clickable!==!0)return[];let g=typeof u.className=="string"?u.className:"";return[{id:String(u.id??""),label:R,role:g.split(".").at(-1)??"",x:p/d,y:m/s,width:C,height:c}]}),errors:[]}}var ot=(e,a,t)=>{let o=new AbortController,l=null,d=()=>{e.transport.fetch(a,{signal:o.signal}).then(s=>Qa(s,n=>{try{t(JSON.parse(n.data))}catch{}},o.signal)).catch(()=>{}).finally(()=>{o.signal.aborted||(l=setTimeout(d,xo))})};return d(),()=>{o.abort(),l!==null&&clearTimeout(l)}};function rt(e,a){return e.platform!=="ios"?()=>{}:ot(e,Ze(e,"/appstate",{device:e.deviceId}),t=>{if(Q(t)){if(t.bundleId===null||t.bundleId===""){a(null);return}typeof t.bundleId=="string"&&a({id:t.bundleId,...typeof t.pid=="number"?{pid:t.pid}:{},...typeof t.isReactNative=="boolean"?{isReactNative:t.isReactNative}:{}})}})}var at=e=>!Q(e)||typeof e.id!="number"?null:{id:e.id,timestamp:typeof e.timestamp=="string"?e.timestamp:"",kind:typeof e.kind=="string"?e.kind:"",summary:typeof e.summary=="string"?e.summary:typeof e.msg=="string"?e.msg:""};function lt(e,a){return e.platform!=="ios"?()=>{}:ot(e,Ze(e,"/api/event-log/events",{device:e.deviceId,limit:"100"}),t=>{if(!Q(t))return;if(Array.isArray(t.events)){a(t.events.flatMap(l=>at(l)??[]),!0);return}let o=at(t.event);o&&a([o],!1)})}function M(){return{t:N().i18n.usePluginTranslation()}}function Qe(e){if(e.length<4)return"avc1.42E01E";let a=t=>t.toString(16).padStart(2,"0");return`avc1.${a(e[1])}${a(e[2])}${a(e[3])}`}function st(e){let a=new Uint8Array(e);if(a.byteLength>16){let t=new DataView(e,0,16);if(t.getUint32(0,!1)===1397050709&&t.getUint8(4)===1){let o=t.getBigUint64(8,!1);return{data:a.subarray(16),isKey:(t.getUint8(5)&1)!==0,timestamp:o<=BigInt(Number.MAX_SAFE_INTEGER)?Number(o):null}}}return{data:a,isKey:null,timestamp:null}}var dt=e=>{try{return JSON.parse(e)?.type==="video-session"}catch{return!1}};function nt(e){let a=!1,t=null,o=e.length,l=0;for(;l+2<o;){if(e[l]===0&&e[l+1]===0){let d=0;if(e[l+2]===1?d=3:l+3<o&&e[l+2]===0&&e[l+3]===1&&(d=4),d){let s=e[l+d]&31;s===7&&!t&&(t=e.subarray(l+d)),s===5&&(a=!0),l+=d+1;continue}}l++}return{isKey:a,sps:t}}var So={1:"description",2:"keyframe",3:"delta",4:"seed"},Je=class{buffer=new Uint8Array(64*1024);length=0;push(a){if(this.length+a.length>this.buffer.length){let l=this.buffer.length;for(;l<this.length+a.length;)l*=2;let d=new Uint8Array(l);d.set(this.buffer.subarray(0,this.length)),this.buffer=d}this.buffer.set(a,this.length),this.length+=a.length;let t=[],o=0;for(;this.length-o>=4;){let d=new DataView(this.buffer.buffer,this.buffer.byteOffset+o,4).getUint32(0,!1);if(this.length-o-4<d)break;if(d>=1){let s=So[this.buffer[o+4]];s&&t.push({type:s,payload:this.buffer.slice(o+5,o+4+d)})}o+=4+d}return o>0&&(this.buffer.copyWithin(0,o,this.length),this.length-=o),t}reset(){this.length=0}};var vo={Enter:40,Escape:41,Backspace:42,Tab:43,Space:44,Minus:45,Equal:46,BracketLeft:47,BracketRight:48,Backslash:49,Semicolon:51,Quote:52,Backquote:53,Comma:54,Period:55,Slash:56,Delete:76,ArrowRight:79,ArrowLeft:80,ArrowDown:81,ArrowUp:82,ControlLeft:224,ShiftLeft:225,AltLeft:226,MetaLeft:227,ControlRight:228,ShiftRight:229,AltRight:230,MetaRight:231};function ut(e){return/^Key[A-Z]$/.test(e)?4+(e.charCodeAt(3)-65):/^Digit[1-9]$/.test(e)?30+(e.charCodeAt(5)-49):e==="Digit0"?39:vo[e]??null}var it={ArrowUp:19,ArrowDown:20,ArrowLeft:21,ArrowRight:22,Tab:61,Enter:66,Backspace:67,Delete:112,Home:122,End:123,PageUp:92,PageDown:93};function ga(e){if(e.stopped)return;let a=d=>{e.configuring=!1,e.connecting(d),e.scheduleRetry("input",()=>ga(e))},t;try{t=e.transport.connect(`${e.vendor}/ws?device=${e.device}&frame-meta=1`)}catch(d){e.events.onInputConnected(!1,d.message),a(d.message);return}e.socket=t;let o=[],l=!1;t.onopen=()=>{e.stopped||e.socket!==t||(e.connecting(),e.events.onInputConnected(!0))},t.onmessage=d=>{if(e.stopped||e.socket!==t)return;if(typeof d.data=="string"){dt(d.data)&&(e.closeDecoder(),e.configuring=!1,o=[],l=!1,e.connecting());return}let s=st(d.data),n=!e.videoDecoder||e.videoDecoder.state!=="configured",i=s.isKey===null||s.isKey&&n?nt(s.data):null,p=s.isKey??i?.isKey??!1,m={isKey:p,data:s.data,timestamp:s.timestamp};if(e.configuring){o.push(m);return}if(i?.sps&&n){e.configuring=!0,o=[m];let C=e.decoderEpoch,c=()=>!e.stopped&&e.socket===t;e.configureDecoder({codec:Qe(i.sps)},c).then(h=>{if(!c()||C!==e.decoderEpoch)return;e.configuring=!1,e.awaitingKeyframe=!0;let k=o;if(o=[],!!h){for(let R of k)e.decode(R.isKey,R.data,R.timestamp);e.awaitingKeyframe&&e.requestKeyframe()}});return}if(n){!p&&!l&&(l=!0,e.requestKeyframe());return}e.decode(p,s.data,s.timestamp)},t.onclose=d=>{e.socket===t&&(e.socket=null,e.closeDecoder(),!e.stopped&&(e.events.onInputConnected(!1,d.reason||`closed ${d.code}`),a(d.reason||void 0)))},t.onerror=()=>t.close()}function ft(e){return{sendTouch(a,t,o){let l=a==="begin"?"down":a==="move"?"move":"up";e.send(JSON.stringify({type:"touch",action:l,x:t,y:o}))},sendKey(a,t){if(t!=="down")return;if(a.key==="Escape")return e.send(JSON.stringify({type:"back"}));let o=it[a.key];if(o!==void 0)return e.send(JSON.stringify({type:"key",keycode:o}));a.key.length===1&&!a.metaKey&&!a.ctrlKey&&e.send(JSON.stringify({type:"text",text:a.key}))},pressButton(a){let t=a==="appSwitcher"?"recents":a;(t==="home"||t==="back"||t==="recents"||t==="power")&&e.send(JSON.stringify({type:t}))},rotate(){},setOrientation(){}}}function ct(e){return{present(a,t,o){let l=e.getContext("2d");return l?((e.width!==t||e.height!==o)&&(e.width=t,e.height=o),l.drawImage(a,0,0,t,o),!0):!1}}}var pt=new TextEncoder,mt=new TextDecoder;function Lt(e){if(!e)return null;let a=/boundary=(?:"([^"]+)"|([^;\s]+))/i.exec(e),t=a?.[1]??a?.[2];return t?t.startsWith("--")?t:`--${t}`:null}function gt(e,a,t,o){let l=o-a.length;for(let d=t;d<=l;d++){if(e[d]!==a[0])continue;let s=1;for(;s<a.length&&e[d+s]===a[s];)s++;if(s===a.length)return d}return-1}var Ye=class{delimiter;buffer=new Uint8Array(64*1024);length=0;pos=0;state="boundary";contentLength=null;scanFrom=0;constructor(a){this.delimiter=a?pt.encode(a):null}push(a){this.append(a);let t=[];for(;;){if(this.state==="done"){this.pos=this.length=0;break}if(this.state==="boundary"){if(!this.readBoundary())break}else if(this.state==="headers"){if(!this.readHeaders())break}else{let o=this.readBody();if(!o)break;o.length>0&&t.push(o)}}if(this.length-this.pos>16777216)throw new Error("MJPEG part is too large.");return this.pos>0&&(this.buffer.copyWithin(0,this.pos,this.length),this.length-=this.pos,this.scanFrom=Math.max(0,this.scanFrom-this.pos),this.pos=0),t}append(a){if(this.length+a.length>this.buffer.length){let t=this.buffer.length;for(;t<this.length+a.length;)t*=2;let o=new Uint8Array(t);o.set(this.buffer.subarray(0,this.length)),this.buffer=o}this.buffer.set(a,this.length),this.length+=a.length}lineEnd(a){return this.buffer.subarray(0,this.length).indexOf(10,a)}readBoundary(){let a=this.buffer;if(!this.delimiter)for(;;){let s=this.lineEnd(this.pos);if(s===-1)return!1;let n=mt.decode(a.subarray(this.pos,s)).trim();if(this.pos=s+1,n.startsWith("--"))return this.delimiter=pt.encode(n),this.state="headers",!0}let t=this.delimiter,o=gt(a,t,this.pos,this.length);if(o===-1)return this.pos=Math.max(this.pos,this.length-t.length+1),!1;let l=o+t.length;if(l+2>this.length)return this.pos=o,!1;if(a[l]===45&&a[l+1]===45)return this.state="done",!0;let d=this.lineEnd(l);return d===-1?(this.pos=o,!1):(this.pos=d+1,this.state="headers",!0)}readHeaders(){let a=this.pos,t=null;for(;;){let o=this.lineEnd(a);if(o===-1)return!1;let l=mt.decode(this.buffer.subarray(a,o)).replace(/\r$/,"");if(a=o+1,l==="")break;let d=l.indexOf(":");if(d>0&&l.slice(0,d).trim().toLowerCase()==="content-length"){let s=Number.parseInt(l.slice(d+1).trim(),10);Number.isFinite(s)&&s>=0&&(t=s)}}return this.pos=a,this.contentLength=t,this.scanFrom=a,this.state="body",!0}readBody(){if(this.contentLength!==null){if(this.length-this.pos<this.contentLength)return null;let o=this.buffer.slice(this.pos,this.pos+this.contentLength);return this.pos+=this.contentLength,this.state="boundary",o}let a=this.delimiter,t=Math.max(this.scanFrom,this.pos+1);for(;;){let o=gt(this.buffer,a,t,this.length);if(o===-1)return this.scanFrom=Math.max(this.pos,this.length-a.length),null;if(this.buffer[o-1]!==10){t=o+1;continue}let l=o-1;l>this.pos&&this.buffer[l-1]===13&&l--;let d=this.buffer.slice(this.pos,Math.max(l,this.pos));return this.pos=o,this.state="boundary",d}}};async function yo(e,a,t){let o=new Ye(Lt(e.headers.get("content-type")));await je(e,l=>{for(let d of o.push(l))a(d)},t)}function Se(e){e.stopped||e.mjpeg||(e.mjpeg=!0,e.controller?.abort(),e.controller=null,e.closeDecoder(),e.connecting(),e.events.onMjpegFallback?.(),ht(e))}var La=e=>`${e.vendor}/helper/${e.device}/stream.mjpeg`;async function ht(e){let a=e.generation,t=++e.videoGeneration,o=new AbortController;e.controller=o;let l=()=>!e.stopped&&e.generation===a&&e.videoGeneration===t&&e.controller===o,d=null,s=!1,n=async()=>{s=!0;try{for(;d;){let i=d;d=null;try{let p=await e.createBitmap(new Blob([i],{type:"image/jpeg"}));try{l()&&e.paint(p,p.width,p.height)}finally{p.close()}}catch{}}}finally{s=!1}},u;try{let i=await e.transport.fetch(La(e),{signal:o.signal});if(!l()){await i.body?.cancel();return}if(!i.ok||!i.body)throw new Error(`stream ${i.status}`);if(await yo(i,p=>{l()&&(d=p,s||n())},o.signal),!l())return;u="Device stream ended."}catch(i){if(!l())return;u=i.message}l()&&(e.controller=null,o.abort(),e.connecting(u),e.scheduleRetry("video",()=>{ht(e)}))}var wo=1e3,ha=15e3,bo=16667,ko=8,Do=e=>typeof e=="object"&&e!==null&&"present"in e;function It(e){let{transport:a,platform:t,events:o}=e,l=Do(e.output)?e.output:ct(e.output),d=n=>e.globals?.[n]??globalThis[n],s={platform:t,transport:a,events:o,preferMjpeg:e.preferMjpeg===!0,vendor:pe(t),device:encodeURIComponent(e.deviceId),stopped:!0,generation:0,videoGeneration:0,decoderEpoch:0,socket:null,controller:null,primeController:null,videoDecoder:null,timestamp:0,awaitingKeyframe:!0,screen:null,firstFrame:!1,configuring:!1,mjpeg:!1,frameTimer:null,videoReadTimer:null,retryTimers:new Map,webCodecs(){let n=d("VideoDecoder"),u=d("EncodedVideoChunk");return n&&u?{VideoDecoder:n,EncodedVideoChunk:u}:null},createBitmap(n){let u=d("createImageBitmap");return u?u(n):Promise.reject(new Error("createImageBitmap is unavailable."))},setStatus(n,u){s.stopped||o.onStatus(n,u)},fail(n){s.stopped||(s.stop(),o.onInputConnected(!1,n),o.onStatus("error",n))},connecting(n){s.firstFrame=!1,s.frameTimer===null&&(s.frameTimer=setTimeout(()=>s.fail("No video received from the device. Reconnect to try again."),ha)),s.setStatus("connecting",n)},paint(n,u,i){if(!s.stopped){if(t==="android"&&(s.screen?.width!==u||s.screen.height!==i)&&(s.screen={width:u,height:i,orientation:u>i?"landscape_left":"portrait"},o.onScreen(s.screen)),!l.present(n,u,i)){s.fail("Could not display the device stream. Reconnect to try again.");return}s.firstFrame||(s.firstFrame=!0,s.frameTimer!==null&&clearTimeout(s.frameTimer),s.frameTimer=null,s.setStatus("streaming"))}},closeDecoder(){s.decoderEpoch++,s.configuring=!1;try{s.videoDecoder?.close()}catch{}s.videoDecoder=null,s.awaitingKeyframe=!0},recoverDecoder(){t==="ios"?Se(s):(s.closeDecoder(),s.connecting("Video decoder restarted."),s.requestKeyframe())},async configureDecoder(n,u=()=>!s.stopped){let i=s.webCodecs();if(!i)return!1;let p=s.decoderEpoch,m={...n,optimizeForLatency:!0},C=await i.VideoDecoder.isConfigSupported(m).catch(()=>({supported:!1}));if(!u()||p!==s.decoderEpoch)return!1;if(!C.supported)return t==="android"&&s.fail(`This browser cannot decode ${n.codec}.`),!1;try{return(!s.videoDecoder||s.videoDecoder.state==="closed")&&(s.videoDecoder=Po(s,i)),s.videoDecoder.configure(m),!0}catch(c){return t==="android"&&s.fail(`Video decoder: ${c.message}`),!1}},decode(n,u,i){let p=s.videoDecoder,m=s.webCodecs();if(!(!p||p.state!=="configured"||!m)){if(s.awaitingKeyframe){if(!n)return;s.awaitingKeyframe=!1}if(p.decodeQueueSize>ko){s.recoverDecoder();return}try{p.decode(new m.EncodedVideoChunk({type:n?"key":"delta",timestamp:i??s.timestamp,data:u})),s.timestamp+=bo}catch{s.recoverDecoder()}}},requestKeyframe(){t==="android"&&s.socket?.readyState===1&&s.socket.send(JSON.stringify({type:"reset-video",ack:!1}))},scheduleRetry(n,u){s.stopped||s.retryTimers.has(n)||s.retryTimers.set(n,setTimeout(()=>{s.retryTimers.delete(n),u()},wo))},send(n){!s.stopped&&s.socket?.readyState===1&&s.socket.send(n)},stop(){if(s.stopped)return;s.stopped=!0,s.generation++,s.videoGeneration++,s.mjpeg=!1,s.frameTimer!==null&&clearTimeout(s.frameTimer),s.frameTimer=null,s.videoReadTimer!==null&&clearTimeout(s.videoReadTimer),s.videoReadTimer=null;for(let u of s.retryTimers.values())clearTimeout(u);s.retryTimers.clear(),s.primeController?.abort(),s.primeController=null,s.controller?.abort(),s.controller=null;let n=s.socket;s.socket=null,n?.close(),s.closeDecoder()}};return s}function Po(e,a){let t=e.videoGeneration,o=()=>e.platform!=="ios"||t===e.videoGeneration,l=new a.VideoDecoder({output:d=>{try{e.videoDecoder===l&&o()&&e.paint(d,d.displayWidth,d.displayHeight)}finally{d.close()}},error:()=>{e.stopped||e.videoDecoder!==l||!o()||e.recoverDecoder()}});return l}var Ao=3,To=4,Bo=6,Ct=7,Mo=13,Ro=130,Fo=2e3,Eo=new TextEncoder,Oo=new TextDecoder,ea=["portrait","landscape_left","portrait_upside_down","landscape_right"],Uo=new Set(ea);function me(e,a){let t=Eo.encode(JSON.stringify(a)),o=new Uint8Array(1+t.length);return o[0]=e,o.set(t,1),o}function qo(e){if(typeof e!="object"||e===null)return null;let{width:a,height:t,orientation:o,screenId:l}=e;if(typeof a!="number"||!Number.isFinite(a)||a<=0||typeof t!="number"||!Number.isFinite(t)||t<=0||typeof o!="string"||!Uo.has(o))return null;let d={width:a,height:t,orientation:o};return typeof l=="number"?{...d,screenId:l}:d}function St(e,a){yt(e),a?vt(e):Se(e)}async function vt(e){let a=e.generation,t=++e.videoGeneration,o=new Je,l=new AbortController;e.controller=l;let d=()=>!e.stopped&&e.generation===a&&e.videoGeneration===t&&e.controller===l,s;try{let n=await e.transport.fetch(`${e.vendor}/helper/${e.device}/stream.avcc`,{signal:l.signal});if(!d()){await n.body?.cancel();return}if(!n.ok||!n.body)throw new Error(`stream ${n.status}`);let u=n.body.getReader();for(;;){let i=setTimeout(()=>{d()&&e.fail("Device stream stopped receiving video. Reconnect to try again.")},ha);e.videoReadTimer=i;let p;try{p=await u.read()}finally{clearTimeout(i),e.videoReadTimer===i&&(e.videoReadTimer=null)}let{done:m,value:C}=p;if(!d())return;if(m)break;for(let c of o.push(C))switch(c.type){case"seed":e.createBitmap(new Blob([c.payload],{type:"image/jpeg"})).then(h=>{try{d()&&e.paint(h,h.width,h.height)}finally{h.close()}}).catch(()=>{});break;case"description":{e.awaitingKeyframe=!0;let h=await e.configureDecoder({codec:Qe(c.payload),description:c.payload},d);if(!d())return;if(!h){if(await u.cancel().catch(()=>{}),!d())return;Se(e);return}break}case"keyframe":case"delta":e.decode(c.type==="keyframe",c.payload);break}}}catch(n){if(!d())return;s=n.message}d()&&(e.controller=null,l.abort(),e.closeDecoder(),e.connecting(s),e.scheduleRetry("video",()=>{vt(e)}))}async function Ho(e,a){let t=new AbortController;e.primeController=t;let o=setTimeout(()=>t.abort(),Fo);try{let l=await e.transport.fetch(La(e),{signal:t.signal});if(e.stopped||e.generation!==a)return;await l.body?.getReader().read()}catch{}finally{clearTimeout(o),t.abort(),e.primeController===t&&(e.primeController=null)}}async function yt(e){if(e.stopped)return;let a=e.generation;if(await Ho(e,a),e.stopped||e.generation!==a)return;let t=()=>e.scheduleRetry("input",()=>{yt(e)}),o;try{o=e.transport.connect(`${e.vendor}/helper/ws?device=${e.device}`)}catch(l){e.events.onInputConnected(!1,l.message),t();return}e.socket=o,o.onopen=()=>{e.stopped||e.socket!==o||(o.send(me(Mo,{enabled:!1})),e.events.onInputConnected(!0))},o.onmessage=l=>{if(e.stopped||e.socket!==o||typeof l.data=="string")return;let d=new Uint8Array(l.data);if(!(d.length<1||d[0]!==Ro))try{let s=qo(JSON.parse(Oo.decode(d.subarray(1))));s&&(e.screen=s,e.events.onScreen(s))}catch{}},o.onclose=l=>{e.socket===o&&(e.socket=null,!e.stopped&&(e.events.onInputConnected(!1,l.reason||(l.code===1006?"input socket refused":`closed ${l.code}`)),t()))},o.onerror=()=>o.close()}function No(e,a,t){let o=e.screen;if(!o||o.width>o.height)return{x:a,y:t};switch(o.orientation){case"landscape_left":return{x:t,y:1-a};case"landscape_right":return{x:1-t,y:a};case"portrait_upside_down":return{x:1-a,y:1-t};default:return{x:a,y:t}}}function wt(e){return{sendTouch(a,t,o){e.send(me(Ao,{type:a,...No(e,t,o)}))},sendKey(a,t){let o=ut(a.code);o!==null&&e.send(me(Bo,{type:t,usage:o}))},pressButton(a){let t=a==="home"?"home":a==="appSwitcher"?"app_switcher":a==="power"?"lock":null;t&&e.send(me(To,{button:t}))},rotate(){let a=e.screen?.orientation??"portrait",t=ea[(ea.indexOf(a)+1)%ea.length];e.send(me(Ct,{orientation:t}))},setOrientation(a){e.send(me(Ct,{orientation:a}))}}}function bt(e){let a=It(e),t=e.platform==="ios"?wt(a):ft(a);return{start:()=>{if(!a.stopped)return;a.stopped=!1,a.generation++,a.configuring=!1,a.connecting();let l=a.webCodecs()!==null&&!(e.platform==="ios"&&a.preferMjpeg);e.platform==="ios"?St(a,l):l?ga(a):a.fail("This browser cannot decode the Android stream (WebCodecs unavailable).")},stop:a.stop,isMjpeg:()=>a.mjpeg,...t}}var Vo=56,Go=2e3;function zo(e,a,t,o=0){let l=Math.max(0,a-o);if(l===0||t===0)return{width:0,height:0};let d={width:t*e,height:t};return d.width<=l?d:{width:l,height:l/e}}function _o(e,a){if(!a)return e==="ios"?9/19.5:9/20;let t=a.orientation==="landscape_left"||a.orientation==="landscape_right",o=Math.max(a.width,a.height),l=Math.min(a.width,a.height);return t?o/l:l/o}function Wo(e,a){if(e!=="ios"||!a||a.width>a.height)return 0;switch(a.orientation){case"landscape_left":return 90;case"landscape_right":return-90;case"portrait_upside_down":return 180;default:return 0}}var Ko=()=>typeof navigator<"u"&&/iPhone|iPad|iPod/.test(navigator.userAgent);function aa(e){let{t:a}=M(),t=H(null),o=H(null),[l,d]=L("connecting"),[s,n]=L(),[u,i]=L(!1),[p,m]=L(null),[C,c]=L({connected:!1}),{onHandle:h,onStreaming:k,onScreen:R,transport:g,platform:v,deviceId:D}=e;B(()=>R?.(p),[R,p]),B(()=>{let x=t.current;if(!x)return;let P=bt({transport:g,platform:v,deviceId:D,output:x,preferMjpeg:Ko(),events:{onStatus:(T,_)=>{d(T),n(_),T==="streaming"&&i(!0),k(T==="streaming")},onScreen:m,onInputConnected:(T,_)=>{c({connected:T,..._?{detail:_}:{}}),h({pressButton:P.pressButton,rotate:P.rotate,inputConnected:T})}}});return o.current=P,c({connected:!1}),P.start(),h({pressButton:P.pressButton,rotate:P.rotate,inputConnected:!1}),()=>{P.stop(),o.current=null,h(null),k(!1),i(!1),m(null)}},[D,h,k,v,g]);let y=H(null),[F,q]=L({width:0,height:0});B(()=>{let x=y.current;if(!x)return;let P=()=>{let _=x.getBoundingClientRect();q(b=>b.width===_.width&&b.height===_.height?b:{width:_.width,height:_.height})};P();let T=new ResizeObserver(P);return T.observe(x),()=>T.disconnect()},[]);let G=e.withControls?Vo:0,E=ue(()=>zo(_o(v,p),F.width,F.height,G),[F,G,v,p]),W=Wo(v,p),j=W===90||W===-90?{width:E.height,height:E.width,left:(E.width-E.height)/2,top:(E.height-E.width)/2,transform:`rotate(${W}deg)`}:{width:E.width,height:E.height,...W?{transform:`rotate(${W}deg)`}:{}},[X,z]=L([]);B(()=>{if(!e.axOverlay)return;let x=null,P=null,T=!1,_=async()=>{x=new AbortController;try{let b=await tt({transport:g,platform:v,deviceId:D},x.signal);T||z(b.elements)}catch{}T||(P=setTimeout(()=>{_()},Go))};return _(),()=>{T=!0,x?.abort(),P&&clearTimeout(P),z([])}},[D,v,e.axOverlay,g]);let O=H(!1),I=x=>{let P=x.currentTarget.getBoundingClientRect(),T=(x.clientX-P.left)/P.width,_=(x.clientY-P.top)/P.height;return{x:Math.min(1,Math.max(0,T)),y:Math.min(1,Math.max(0,_))}},K=x=>{if(!O.current)return;O.current=!1;let{x:P,y:T}=I(x);o.current?.sendTouch("end",P,T)};return f("div",{ref:y,className:"relative flex size-full min-h-0 min-w-0 items-center justify-center overflow-hidden",style:G?{paddingRight:G}:void 0,tabIndex:0,role:"application","aria-label":a(v==="ios"?"stream.iosScreen":"stream.androidScreen"),onKeyDown:x=>{x.target===x.currentTarget&&(x.metaKey&&!["r","R"].includes(x.key)||(x.preventDefault(),o.current?.sendKey(x.nativeEvent,"down")))},onKeyUp:x=>{x.target===x.currentTarget&&o.current?.sendKey(x.nativeEvent,"up")},children:[f("div",{className:"relative touch-none select-none",style:{width:E.width,height:E.height},onPointerDown:x=>{x.currentTarget.setPointerCapture(x.pointerId),x.currentTarget.parentElement?.focus(),O.current=!0;let{x:P,y:T}=I(x);o.current?.sendTouch("begin",P,T)},onPointerMove:x=>{if(!O.current)return;let{x:P,y:T}=I(x);o.current?.sendTouch("move",P,T)},onPointerUp:K,onPointerCancel:K,children:[r("canvas",{ref:t,className:"absolute top-0 left-0",style:j}),X.length>0?r("div",{className:"pointer-events-none absolute inset-0","aria-hidden":!0,children:X.map(x=>r("div",{className:"absolute border border-info/80 bg-info/10",style:{left:`${x.x*100}%`,top:`${x.y*100}%`,width:`${x.width*100}%`,height:`${x.height*100}%`},children:x.label?r("span",{className:"absolute -top-3.5 left-0 max-w-full truncate rounded-sm bg-info px-1 text-ui-2xs leading-3.5 text-white",children:x.label}):null},x.id))}):null]}),l==="streaming"&&!C.connected?r("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 flex justify-center p-2",children:r("span",{className:"rounded-md bg-background/85 px-2 py-1 text-xs text-muted-foreground",children:C.detail?a("stream.inputLostDetail",{detail:C.detail}):a("stream.inputLost")})}):null,l==="connecting"&&u?r("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 flex justify-center p-2",children:r("span",{className:"rounded-md bg-background/85 px-2 py-1 text-xs text-muted-foreground",children:a("stream.connecting")})}):null,l==="error"||l!=="streaming"&&!u?r("div",{className:"absolute inset-0 bg-background",children:r(ae,{name:e.deviceName,description:e.deviceDescription,stage:l==="error"?"error":"connecting",message:l==="error"?s??a("stream.failed"):a("stream.connecting"),children:l==="error"?r(S,{size:"sm",variant:"outline",onClick:()=>{o.current?.stop(),o.current?.start()},children:a("stream.reconnect")}):null})}):null]})}var Xo={hosts:[],hostStatuses:{},devices:[],sessions:[],bootingDevices:[],revision:0};function ge(e){let t=N().commands.useSubscription("state",{},{environmentId:e});return{state:t.data??Xo,loaded:t.data!==null,error:t.error,unavailable:t.isUnavailable}}function oe(){let e=N();return ee((a,t,o={})=>e.commands.invoke(a,o,{environmentId:t}),[e])}var Le="local",ta=class extends Error{code;constructor(a,t,o){super(t,o),this.name="DeviceError",this.code=a}};var kt="hub";function oa(e){let a=N(),[t,o]=L({status:"connecting"});return B(()=>{let l=a.network;if(!fe(a,"network")||l===void 0){o({status:"failed",message:null});return}let d=!1;return o({status:"connecting"}),l.client(e).then(s=>{d||o({status:"ready",transport:{fetch:(n,u)=>s.fetch(kt,n,{...u,instance:Le}),connect:n=>s.connect(kt,n,{instance:Le})}})},s=>{d||o({status:"failed",message:s instanceof Error?s.message:String(s)})}),()=>{d=!0}},[a,e]),t}var Dt=()=>{};function Pt(e){let{environmentId:a,threadId:t,hostId:o,deviceId:l,platform:d}=e,s=e[Oa],n=N(),{t:u}=M(),{state:i,loaded:p}=ge(a),m=oa(a),C=ue(()=>({environmentId:a,threadId:t}),[a,t]),c=i.devices.find(v=>v.hostId===o&&v.id===l),h=i.sessions.some(v=>v.threadId===t&&v.hostId===o&&v.deviceId===l);B(()=>{p&&!h&&n.floating?.close(C,s.key)},[n,s.key,p,h,C]),B(()=>(s.setOpenInPanel(()=>{Ne(a,t,s.key),n.floating?.openPanel(C,qe),n.floating?.close(C,s.key)}),()=>s.setOpenInPanel(null)),[n,a,s,C,t]);let k=ee(v=>s.reportSourceSize(v===null?null:Ua(v)),[s]),R=c?.name??l,g=c?.version??d;return m.status!=="ready"?r(ae,{name:R,description:g,stage:m.status==="failed"?"error":"connecting",message:m.status==="failed"?m.message??u("workspace.needsNewerApp"):u("stream.connecting")}):r(aa,{transport:m.transport,platform:d,deviceId:l,deviceName:R,deviceDescription:g,axOverlay:!1,withControls:!1,onHandle:Dt,onStreaming:Dt,onScreen:k})}var ra=(...e)=>e.filter((a,t,o)=>!!a&&a.trim()!==""&&o.indexOf(a)===t).join(" ").trim();var At=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();var Tt=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,t,o)=>o?o.toUpperCase():t.toLowerCase());var xa=e=>{let a=Tt(e);return a.charAt(0).toUpperCase()+a.slice(1)};var Bt={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};var Mt=e=>{for(let a in e)if(a.startsWith("aria-")||a==="role"||a==="title")return!0;return!1};var Rt=Oe(({color:e="currentColor",size:a=24,strokeWidth:t=2,absoluteStrokeWidth:o,className:l="",children:d,iconNode:s,...n},u)=>ne("svg",{ref:u,...Bt,width:a,height:a,stroke:e,strokeWidth:o?Number(t)*24/Number(a):t,className:ra("lucide",l),...!d&&!Mt(n)&&{"aria-hidden":"true"},...n},[...s.map(([i,p])=>ne(i,p)),...Array.isArray(d)?d:[d]]));var w=(e,a)=>{let t=Oe(({className:o,...l},d)=>ne(Rt,{ref:d,iconNode:a,className:ra(`lucide-${At(xa(e))}`,`lucide-${e}`,o),...l}));return t.displayName=xa(e),t};var $o=[["path",{d:"M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",key:"18u6gg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]],ve=w("camera",$o);var jo=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],ye=w("chevron-down",jo);var Zo=[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]],we=w("chevron-left",Zo);var Jo=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]],re=w("ellipsis",Jo);var Qo=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"r6nss1"}]],le=w("house",Qo);var Yo=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]],be=w("info",Yo);var er=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],ke=w("moon",er);var ar=[["path",{d:"M21 9V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v10c0 1.1.9 2 2 2h4",key:"daa4of"}],["rect",{width:"10",height:"7",x:"12",y:"13",rx:"2",key:"1nb8gs"}]],De=w("picture-in-picture-2",ar);var tr=[["path",{d:"M12 2v10",key:"mnfbl"}],["path",{d:"M18.4 6.6a9 9 0 1 1-12.77.04",key:"obofu9"}]],Pe=w("power",tr);var or=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],he=w("rotate-ccw",or);var rr=[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]],Ae=w("rotate-cw",rr);var lr=[["path",{d:"M10 5H3",key:"1qgfaw"}],["path",{d:"M12 19H3",key:"yhmn1j"}],["path",{d:"M14 3v4",key:"1sua03"}],["path",{d:"M16 17v4",key:"1q0r14"}],["path",{d:"M21 12h-9",key:"1o4lsq"}],["path",{d:"M21 19h-5",key:"1rlt1p"}],["path",{d:"M21 5h-7",key:"1oszz2"}],["path",{d:"M8 10v4",key:"tgpxqk"}],["path",{d:"M8 12H3",key:"a7s4jb"}]],Te=w("sliders-horizontal",lr);var sr=[["rect",{width:"14",height:"20",x:"5",y:"2",rx:"2",ry:"2",key:"1yt0o3"}],["path",{d:"M12 18h.01",key:"mhygvu"}]],xe=w("smartphone",sr);var dr=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]],Be=w("square",dr);var nr=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],Me=w("sun",nr);var ur=[["path",{d:"M12 4v16",key:"1654pz"}],["path",{d:"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2",key:"e0r10z"}],["path",{d:"M9 20h6",key:"s66wpe"}]],Re=w("type",ur);var ir=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],Y=w("x",ir);function fr(e,a){let t=o=>a(o==="hub"?"versions.hubName":"versions.agentName");return e.status==="starting"?a("panel.startingHost"):e.status!=="installing"?e.message??"":e.tool&&e.toVersion?e.fromVersion?a("panel.updatingTool",{tool:t(e.tool),from:e.fromVersion,to:e.toVersion}):a("panel.installingTool",{tool:t(e.tool),to:e.toVersion}):a("panel.installing")}function Ia(){let{t:e}=M();return a=>fr(a,e)}function Ft(e){let{t:a}=M(),t=Ia(),[o,l]=L(!1),d=e.detail;return!d||d.status==="ready"||d.status==="idle"?null:d.status==="failed"?f("div",{role:"alert",className:"flex items-start gap-2 border-b bg-destructive/5 px-3 py-2 text-xs",children:[f("div",{className:"min-w-0 flex-1 space-y-0.5",children:[r("p",{className:"font-medium text-destructive-foreground",children:a("panel.hostFailed")}),d.message?r("p",{className:"whitespace-pre-wrap break-words text-muted-foreground",children:d.message}):null]}),f(S,{size:"xs",variant:"outline",disabled:o,onClick:()=>{l(!0),e.onRetry().finally(()=>l(!1))},children:[o?r(V,{size:"xs"}):r(Ae,{}),a(o?"panel.retrying":"panel.retry")]})]}):f("div",{role:"status",className:"flex items-center gap-2 border-b px-3 py-2 text-xs text-muted-foreground",children:[r(V,{size:"xs"}),r("span",{className:"min-w-0 flex-1",children:t(d)})]})}var Ca=["hub","agent"],Sa=e=>e!==void 0&&!e.installedVersions.includes(e.requiredVersion);function Et(e){let{t:a}=M(),t=oe(),[o,l]=L(null),[d,s]=L(null),[n,u]=L(!1),i=e.host?.tools,p=e.busy||o!==null,m=c=>{l(c),s(null),u(!1),(c==="check"?t("inspect",e.environmentId):t("updateTool",e.environmentId,{tool:c})).then(()=>u(c==="check")).catch(()=>s(a(c==="check"?"versions.checkFailed":"versions.updateFailed"))).finally(()=>l(null))},C=c=>c??a("versions.none");return f(ja,{children:[f(Za,{render:r(S,{size:"xs",variant:"ghost","aria-label":a("versions.title")}),children:[r(be,{}),a("versions.title"),Ca.some(c=>Sa(i?.[c]))?r("span",{className:"size-1.5 rounded-full bg-warning","aria-hidden":!0}):null]}),r(Ja,{side:"bottom",align:"start",className:"w-80",children:f("div",{className:"space-y-3 text-xs",children:[Ca.map(c=>{let h=i?.[c];return f("section",{className:"space-y-1",children:[r("h4",{className:"font-medium text-foreground",children:a(c==="hub"?"versions.hubName":"versions.agentName")}),f("dl",{className:"grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-muted-foreground",children:[r("dt",{children:a("versions.required")}),r("dd",{className:"font-mono",children:C(h?.requiredVersion)}),r("dt",{children:a("versions.installed")}),r("dd",{className:"font-mono",children:h&&h.installedVersions.length>0?h.installedVersions.join(", "):a("versions.none")}),r("dt",{children:a("versions.running")}),r("dd",{className:"font-mono",children:C(h?.runningVersion)})]}),Sa(h)?f(S,{size:"xs",variant:"outline",disabled:p,onClick:()=>m(c),children:[o===c?r(V,{size:"xs"}):null,a("versions.updateTo",{version:h?.requiredVersion??""})]}):null]},c)}),i===void 0?r("p",{className:"text-muted-foreground",children:a("versions.unknown")}):null,Ca.some(c=>Sa(i?.[c]))?r("p",{className:"text-muted-foreground",children:a("versions.pendingPolicy")}):null,d?r("p",{role:"alert",className:"text-destructive-foreground",children:d}):null,f("div",{className:"flex items-center justify-between gap-2 border-t pt-2",children:[r("p",{role:"status",className:"text-muted-foreground",children:a(n?"versions.checked":"versions.checkHint")}),f(S,{size:"xs",variant:"ghost",disabled:p,onClick:()=>m("check"),children:[o==="check"?r(V,{size:"xs"}):null,a("versions.check")]})]})]})})]})}var va=[{api:"35",name:"Android 15"},{api:"30",name:"Android 11"}],Ot=va[0].api;var Fe=e=>e>=1073741824?`${(e/1073741824).toFixed(2)} GB`:`${(e/1048576).toFixed(1)} MB`;function Ut(e){let{phase:a,receivedBytes:t,totalBytes:o,bytesPerSecond:l}=e,d=a==="download"&&t!==void 0&&o?{received:t,total:o}:null,s=d&&l?(d.total-d.received)/l:null;return{titleKey:`environment.stages.${a??"starting"}`,component:e.component??"",percent:d?Math.floor(d.received/d.total*100):null,transferred:d?{done:Fe(d.received),total:Fe(d.total)}:null,speed:d&&l?Fe(l):null,minutesLeft:s===null?null:Math.ceil(s/60),slow:s!==null&&s>1200}}var qt=e=>e.source==="private"&&e.ready;function Ht(e){return e.supported?e.freeBytes!==null&&e.freeBytes<e.requiredFreeBytes?"environment.notEnoughSpace":null:e.reasonCode?`environment.reasons.${e.reasonCode}`:"environment.unsupported"}function Nt(e,a){return e.cacheBytes>0||a==="android"&&e.deviceDataBytes>0}function Vt(e){let{t:a}=M(),t=Ut(e.progress),o=[t.transferred?a("environment.transferred",t.transferred):null,t.speed?a("environment.speed",{speed:t.speed}):null,t.minutesLeft===null?null:a("environment.timeLeft",{minutes:String(t.minutesLeft)})].filter(l=>l!==null);return f("div",{role:"status",className:"space-y-2",children:[f("p",{className:"flex items-center gap-2 font-medium text-foreground",children:[r(V,{size:"xs"}),a(t.titleKey,{component:t.component})]}),t.percent===null?null:r("div",{role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":t.percent,className:"h-1.5 overflow-hidden rounded-full bg-muted",children:r("div",{className:"h-full rounded-full bg-primary",style:{width:`${t.percent}%`}})}),o.length>0?r("p",{children:o.join(" \xB7 ")}):null,t.slow?r("p",{className:"text-warning-foreground",children:a("environment.slowDownload")}):null,r("p",{children:a("environment.continues")}),r(S,{size:"sm",variant:"outline",disabled:e.cancelling,onClick:e.onCancel,children:a("environment.cancel")})]})}function Gt(e){let{t:a}=M(),t=oe(),l=N().commands.useSubscription("environmentProgress",{},{environmentId:e.environmentId}).data,[d,s]=L(!1),[n,u]=L("android"),[i,p]=L(""),[m,C]=L(""),[c,h]=L(null),[k,R]=L(!1),[g,v]=L(!1),[D,y]=L(!1),[F,q]=L(null),[G,E]=L(!1),[W,U]=L(!1),[j,X]=L(void 0),z=l?.status==="working",O=F!==null||z,I=l&&l.id!==j?l:null;B(()=>{(z||I?.status==="failed")&&s(!0),I?.status==="done"&&I.plan?.platform===n&&h(I.plan)},[I,n,z]);let K=()=>{h(null),R(!1),v(!1),y(!1),U(!1),X(l?.id)},x=async(b,po={})=>{q(b),E(!1),U(!1),X(l?.id);try{let mo=await t(b,e.environmentId,{platform:n,directory:i,version:m,...po});b==="cleanupEnvironment"?h(await t("environmentPlan",e.environmentId,{platform:n,directory:i,version:m})):b!=="prepareEnvironment"&&h(mo),U(b==="cleanupEnvironment")}catch{E(!0)}finally{q(null)}},P=c?Ht(c):null,T=b=>b===null?a("environment.unknownSize"):Fe(b),_=c!==null&&qt(c);return f(We,{open:d,onOpenChange:s,className:"w-full text-left",children:[r(Ke,{render:r(S,{variant:"outline",size:"sm",className:"w-full"}),children:a("environment.title")}),r(Xe,{children:f("div",{className:"space-y-3 rounded-md border p-3 text-xs",children:[z?r(Vt,{progress:l,cancelling:F==="cancelEnvironment",onCancel:()=>{q("cancelEnvironment"),t("cancelEnvironment",e.environmentId,{}).catch(()=>E(!0)).finally(()=>q(null))}}):f(J,{children:[r("p",{children:a("environment.description")}),e.iosSupported?r("div",{className:"flex gap-2",children:["android","ios"].map(b=>r(S,{size:"sm",variant:n===b?"default":"outline",disabled:O,onClick:()=>{u(b),C(""),K()},children:a(b==="ios"?"panel.platformIos":"panel.platformAndroid")},b))}):null,f("label",{className:"block space-y-1",children:[r("span",{children:a("environment.directory")}),r(te,{value:i,disabled:O,onChange:b=>{p(b.target.value),K()},placeholder:a("environment.defaultDirectory")})]}),r("p",{children:a("environment.directoryHint")}),n==="android"?f("div",{className:"space-y-1",children:[r("span",{children:a("environment.androidVersion")}),r("div",{className:"flex flex-wrap gap-2",children:va.map(b=>r(S,{size:"sm",variant:(m||Ot)===b.api?"default":"outline",disabled:O,onClick:()=>{C(b.api),K()},children:a("environment.androidVersionOption",{name:b.name,api:b.api})},b.api))})]}):f("label",{className:"block space-y-1",children:[r("span",{children:a("environment.iosVersion")}),r(te,{value:m,disabled:O,onChange:b=>{C(b.target.value),K()},placeholder:a("environment.iosVersionPlaceholder")})]}),r(S,{size:"sm",variant:"outline",disabled:O,onClick:()=>{x("environmentPlan")},children:a("environment.inspect")}),c?f("div",{className:"space-y-2",children:[f("dl",{className:"grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 break-all",children:[r("dt",{children:a("environment.source")}),r("dd",{children:a(`environment.sources.${c.source}`)}),r("dt",{children:a("environment.version")}),r("dd",{children:c.version||a("environment.versionRequired")}),r("dt",{children:a("environment.location")}),r("dd",{children:c.root}),c.existingSdkRoot?f(J,{children:[r("dt",{children:a("environment.existingSdk")}),r("dd",{children:c.existingSdkRoot})]}):null,r("dt",{children:a("environment.download")}),r("dd",{children:c.downloadBytes===0?a("environment.nothingToDownload"):T(c.downloadBytes)}),r("dt",{children:a("environment.free")}),r("dd",{children:T(c.freeBytes)}),r("dt",{children:a("environment.required")}),r("dd",{children:T(c.requiredFreeBytes)})]}),c.source==="external"?r("p",{children:a("environment.external")}):null,c.reasonCode&&c.supported?r("p",{role:"status",children:a(`environment.reasons.${c.reasonCode}`)}):null,r("a",{className:"underline",href:c.guidanceUrl,target:"_blank",rel:"noreferrer",children:a("environment.guide")}),n==="ios"?r("p",{children:a("environment.appleOwnership")}):r("p",{children:a("environment.privateOwnership")}),_?r("p",{role:"status",className:"font-medium text-foreground",children:a("environment.ready")}):f(J,{children:[r("ul",{children:c.licenses.map(b=>r("li",{children:r("a",{className:"underline",href:b.url,target:"_blank",rel:"noreferrer",children:a(n==="ios"?"environment.appleLicense":"environment.androidLicense")})},b.url))}),f("label",{className:"flex items-center gap-2",children:[r(ce,{checked:k,disabled:O,onCheckedChange:R}),r("span",{children:a("environment.acceptLicense")})]}),n==="ios"?f("label",{className:"flex items-center gap-2",children:[r(ce,{checked:g,disabled:O,onCheckedChange:v}),r("span",{children:a("environment.confirmApple")})]}):null,P?r("p",{role:"alert",className:"font-medium text-warning-foreground",children:a(P)}):null,r(S,{size:"sm",disabled:O||!c.supported||!k||n==="ios"&&(!g||!m)||c.freeBytes===null||c.freeBytes<c.requiredFreeBytes,onClick:()=>{x("prepareEnvironment",{acceptLicenses:k,confirmAppleInstall:g})},children:a("environment.prepare")})]}),Nt(c,n)?f("div",{className:"space-y-2 border-t pt-2",children:[r("p",{children:a("environment.retention")}),r(S,{size:"sm",variant:"outline",disabled:O||c.cacheBytes===0,onClick:()=>{x("cleanupEnvironment",{category:"cache",confirm:!0})},children:a("environment.cleanCache",{size:T(c.cacheBytes)})}),n==="android"?f(J,{children:[r("p",{children:a("environment.deviceData",{size:T(c.deviceDataBytes)})}),f("label",{className:"flex items-center gap-2",children:[r(ce,{checked:D,disabled:O,onCheckedChange:y}),r("span",{children:a("environment.confirmData")})]}),r(S,{size:"sm",variant:"destructive",disabled:O||!D||c.deviceDataBytes===0,onClick:()=>{x("cleanupEnvironment",{category:"devices",confirm:D})},children:a("environment.cleanDevices")})]}):null]}):null]}):null]}),F!==null&&!z?f("p",{role:"status",className:"flex items-center gap-2",children:[r(V,{size:"xs"}),a("environment.working")]}):null,G?r("p",{role:"alert",className:"text-destructive-foreground",children:a("environment.failed")}):null,I?.status==="failed"?f("div",{role:"alert",className:"space-y-1 text-destructive-foreground",children:[r("p",{children:a("environment.prepareFailed")}),I.message?r("p",{className:"whitespace-pre-wrap break-words text-muted-foreground",children:I.message}):null]}):null,I?.status==="cancelled"?r("p",{role:"status",children:a("environment.cancelled")}):null,W?r("p",{role:"status",children:a("environment.cleaned")}):null]})})]})}var zt=["small","default","large","extra-large"],cr=e=>zt.includes(e);function _t(e){let{t:a}=M(),{handle:t,controls:o}=e,l=o.detail?.settings,d=!t?.inputConnected,s=l?.appearance==="dark"?"light":"dark",n=u=>a(u==="small"?"rail.textSmall":u==="default"?"rail.textDefault":u==="large"?"rail.textLarge":"rail.textExtraLarge");return r("aside",{"aria-label":a("rail.label"),className:"pointer-events-none absolute inset-y-0 right-0 z-10 flex w-14 flex-col items-center justify-center gap-2 overflow-y-auto py-3 pr-2",children:f("div",{className:"pointer-events-auto flex shrink-0 flex-col items-center gap-1 rounded-full border border-border/50 bg-background/80 p-2 shadow-sm",children:[r(se,{label:a("rail.home"),disabled:d,onClick:()=>t?.pressButton("home"),children:r(le,{})}),e.platform==="android"?f(J,{children:[r(se,{label:a("rail.back"),disabled:d,onClick:()=>t?.pressButton("back"),children:r(we,{})}),r(se,{label:a("rail.recents"),disabled:d,onClick:()=>t?.pressButton("recents"),children:r(Be,{})}),f(Ge,{children:[r(_e,{render:r(S,{size:"icon-sm",variant:"ghost","aria-label":a("rail.rotate"),disabled:o.disabled}),children:r(he,{})}),f(ze,{side:"left",children:[r(Ce,{onClick:()=>{o.act({type:"setOrientation",value:"portrait"})},children:a("rail.portrait")}),r(Ce,{onClick:()=>{o.act({type:"setOrientation",value:"landscape_left"})},children:a("rail.landscape")})]})]})]}):r(se,{label:a("rail.rotate"),disabled:d,onClick:()=>t?.rotate(),children:r(he,{})}),r(pr,{}),r(se,{label:a(s==="dark"?"rail.toDark":"rail.toLight"),disabled:o.disabled||!l?.appearance,onClick:()=>{o.act({type:"setAppearance",value:s})},children:l?.appearance==="dark"?r(Me,{}):r(ke,{})}),f(Ge,{children:[r(_e,{render:r(S,{size:"icon-sm",variant:"ghost","aria-label":a("rail.textSize"),title:a("rail.textSize"),disabled:o.disabled||!l?.textSize}),children:r(Re,{})}),r(ze,{side:"left",children:r(_a,{value:l?.textSize??"",onValueChange:u=>{cr(u)&&o.act({type:"setTextSize",value:u})},children:zt.map(u=>r(Wa,{value:u,children:n(u)},u))})})]}),r(se,{label:a("rail.tools"),pressed:e.toolsOpen,onClick:e.onTools,children:r(Te,{})}),r(se,{label:e.screenshotPending?a("rail.capturing"):a("rail.screenshot"),disabled:!e.streaming||e.screenshotPending,onClick:e.onScreenshot,children:r(ve,{})}),e.onFloat?r(se,{label:a("rail.float"),onClick:e.onFloat,children:r(De,{})}):null,f(Ge,{children:[r(_e,{render:r(S,{size:"icon-sm",variant:"ghost","aria-label":a("rail.more"),title:a("rail.more")}),children:r(re,{})}),f(ze,{side:"left",align:"end",children:[f(Ce,{onClick:e.onClose,children:[r(Y,{}),a("rail.closePanel")]}),r(za,{}),f(Ce,{variant:"destructive",onClick:e.onPowerOff,children:[r(Pe,{}),a("rail.powerOff")]})]})]})]})})}function pr(){return r("div",{"aria-hidden":!0,className:"my-1 h-px w-5 shrink-0 bg-border/70"})}function se(e){return f(Na,{children:[r(Ga,{render:r(S,{size:"icon-sm",variant:e.pressed?"secondary":"ghost","aria-label":e.label,"aria-pressed":e.pressed,disabled:e.disabled,onClick:e.onClick}),children:e.children}),r(Va,{side:"left",children:e.label})]})}var ya=(e,a)=>new ta("invalid-input",`Invalid ${e}: ${a}.`);var Wt=4096,Kt=["light","dark"],Xt=["small","default","large","extra-large"];var $t=["clear","tinted"],jt=["none","grayscale","red-green","green-red","blue-yellow"],Zt=["portrait","landscape_left","portrait_upside_down","landscape_right"],Jt=["camera","microphone","photos","contacts","calendar","reminders","location","notifications","motion","media-library","faceid"];var mr=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);var Qt=e=>{let a=typeof e=="string"?{aps:{alert:e}}:e;if(!mr(a))throw ya("push payload","expected a string or an object");let t;try{t=JSON.stringify(a)}catch{t=void 0}if(t===void 0)throw ya("push payload","could not be encoded as JSON");if(new TextEncoder().encode(t).length>Wt)throw ya("push payload",`larger than ${String(Wt)} bytes`);return t};var gr=new Set(["setAppearance","setTextSize","setToggle","setLiquidGlass","setColorFilter","setLocation","clearLocation","setPermission","openUrl","launchApp","relaunchApp","terminateApp","sendPush"]),Lr=new Set(["setAppearance","setTextSize","setToggle","setOrientation","setLocation","setPermission","openUrl","launchApp","relaunchApp","terminateApp"]),hr=new Set(["reduceMotion","increaseContrast","reduceTransparency","showBorders","voiceOver"]),xr=new Set(["reduceMotion","networkEnabled"]),wa=(e,a)=>(e==="ios"?gr:Lr).has(a.type)?a.type==="setToggle"?(e==="ios"?hr:xr).has(a.setting):!0:!1;function ie(e){return f("section",{className:"flex flex-col gap-2 border-b px-3 py-2.5",children:[r("h3",{className:"text-xs font-medium text-muted-foreground",children:e.title}),e.children]})}function de(e){return f("div",{className:"flex min-h-7 items-center justify-between gap-3",children:[r("span",{className:"shrink-0 text-xs text-muted-foreground",children:e.label}),r("div",{className:"flex min-w-0 items-center justify-end",children:e.children})]})}function ba(e){return r(de,{label:e.label,children:r(ce,{"aria-label":e.label,checked:e.checked??!1,disabled:e.disabled||e.checked===void 0,onCheckedChange:a=>{e.onChange(a)}})})}function ka(e){return r(Xa,{"aria-label":e.label,variant:"outline",value:e.value===void 0?[]:[e.value],disabled:e.disabled||e.value===void 0,onValueChange:a=>{let t=e.options.find(o=>o.value===a[0]);t&&e.onChange(t.value)},children:e.options.map(a=>r($a,{size:"xs",value:a.value,children:a.label},a.value))})}function Ee(e){let a=e.options.find(t=>t.value===e.value);return f(ia,{value:e.value,disabled:e.disabled,onValueChange:t=>{let o=e.options.find(l=>l.value===t);o&&o.value!==e.value&&e.onChange(o.value)},children:[r(fa,{size:"xs",className:e.width??"w-40","aria-label":e.ariaLabel,children:r(ca,{children:a?a.label:r("span",{className:"text-muted-foreground",children:e.placeholder})})}),r(pa,{align:"end",alignItemWithTrigger:!1,children:e.options.map(t=>r(ma,{value:t.value,children:t.label},t.value))})]})}function Da(e){let[a,t]=L(""),o=a.trim()||e.fallback||"",l=()=>{o&&e.onSubmit(o).then(()=>t(""))};return f("form",{className:"flex gap-1.5",onSubmit:d=>{d.preventDefault(),l()},children:[r(te,{size:"compact",className:"min-w-0 flex-1 font-mono",placeholder:e.placeholder,"aria-label":e.placeholder,value:a,disabled:e.disabled,onChange:d=>t(d.target.value)}),r(S,{type:"submit",size:"xs",variant:"outline",disabled:e.disabled||!o,children:e.action})]})}var Yt=[{key:"tools.location.sanFrancisco",latitude:37.7749,longitude:-122.4194},{key:"tools.location.newYork",latitude:40.7128,longitude:-74.006},{key:"tools.location.london",latitude:51.5074,longitude:-.1278},{key:"tools.location.stockholm",latitude:59.3293,longitude:18.0686},{key:"tools.location.tokyo",latitude:35.6762,longitude:139.6503}];function ao(e){let{t:a}=M(),[t,o]=L(e.current?String(e.current.latitude):""),[l,d]=L(e.current?String(e.current.longitude):""),s={latitude:Number(t),longitude:Number(l)},n=t.trim()!==""&&l.trim()!==""&&Math.abs(s.latitude)<=90&&Math.abs(s.longitude)<=180,u=(i,p)=>e.act({type:"setLocation",latitude:i,longitude:p});return f(ie,{title:a("tools.location.title"),children:[f("div",{className:"flex gap-1.5",children:[r(te,{size:"compact",className:"min-w-0 flex-1 font-mono",placeholder:a("tools.location.latitude"),"aria-label":a("tools.location.latitude"),inputMode:"decimal",value:t,disabled:e.disabled,onChange:i=>o(i.target.value)}),r(te,{size:"compact",className:"min-w-0 flex-1 font-mono",placeholder:a("tools.location.longitude"),"aria-label":a("tools.location.longitude"),inputMode:"decimal",value:l,disabled:e.disabled,onChange:i=>d(i.target.value)})]}),f("div",{className:"flex flex-wrap items-center gap-1.5",children:[f(ia,{value:null,disabled:e.disabled,onValueChange:i=>{let p=Yt.find(m=>m.key===i);p&&(o(String(p.latitude)),d(String(p.longitude)),u(p.latitude,p.longitude))},children:[r(fa,{size:"xs",className:"w-32","aria-label":a("tools.location.preset"),children:r(ca,{children:r("span",{className:"text-muted-foreground",children:a("tools.location.presetPlaceholder")})})}),r(pa,{align:"start",alignItemWithTrigger:!1,children:Yt.map(i=>r(ma,{value:i.key,children:a(i.key)},i.key))})]}),r(S,{size:"xs",variant:"outline",disabled:e.disabled||!n,onClick:()=>{u(s.latitude,s.longitude)},children:a("tools.location.set")}),e.canClear?r(S,{size:"xs",variant:"ghost",disabled:e.disabled,onClick:()=>{o(""),d(""),e.act({type:"clearLocation"})},children:a("tools.location.clear")}):null]}),e.current?r("p",{role:"status",className:"text-xs text-muted-foreground",children:a("tools.location.current",{latitude:e.current.latitude,longitude:e.current.longitude})}):null]})}var Ir={camera:"tools.permissions.camera",microphone:"tools.permissions.microphone",photos:"tools.permissions.photos",contacts:"tools.permissions.contacts",calendar:"tools.permissions.calendar",reminders:"tools.permissions.reminders",location:"tools.permissions.location",notifications:"tools.permissions.notifications",motion:"tools.permissions.motion","media-library":"tools.permissions.mediaLibrary",faceid:"tools.permissions.faceId"},Cr=new Set(["camera","microphone","photos","contacts","calendar","location","notifications","motion"]);function to(e){let{t:a}=M(),t=e.platform==="ios",[o,l]=L(""),[d,s]=L("camera"),n=o.trim()||e.defaultAppId,u=Jt.filter(p=>t||Cr.has(p)).map(p=>({value:p,label:a(!t&&p==="motion"?"tools.permissions.activity":Ir[p])})),i=p=>{e.act({type:"setPermission",appId:n,permission:d,decision:p})};return f(ie,{title:a("tools.permissions.title"),children:[r(te,{size:"compact",className:"font-mono",placeholder:e.defaultAppId||a("tools.permissions.appId"),"aria-label":a("tools.permissions.appId"),value:o,disabled:e.disabled,onChange:p=>l(p.target.value)}),f("div",{className:"flex flex-wrap items-center gap-1.5",children:[r(Ee,{ariaLabel:a("tools.permissions.permission"),value:d,options:u,placeholder:a("tools.unknown"),disabled:e.disabled,onChange:p=>(s(p),Promise.resolve())}),r(S,{size:"xs",variant:"outline",disabled:e.disabled||!n,onClick:()=>i("grant"),children:a("tools.permissions.grant")}),r(S,{size:"xs",variant:"outline",disabled:e.disabled||!n,onClick:()=>i("revoke"),children:a("tools.permissions.revoke")}),t?r(S,{size:"xs",variant:"ghost",disabled:e.disabled||!n,onClick:()=>i("reset"),children:a("tools.permissions.reset")}):null]})]})}var Sr=e=>{let a=e;try{let t=JSON.parse(e);typeof t=="object"&&t!==null&&!Array.isArray(t)&&(a=t)}catch{}try{return Qt(a),a}catch{return null}};function oo(e){let{t:a}=M(),[t,o]=L(""),l=t.trim(),d=l?Sr(l):null,s=e.appId;return f(ie,{title:a("tools.push.title"),children:[r(Ka,{size:"sm",rows:4,className:"font-mono",placeholder:a("tools.push.placeholder"),"aria-label":a("tools.push.placeholder"),value:t,disabled:e.disabled||!s,onChange:n=>o(n.target.value)}),f("div",{className:"flex items-center gap-2",children:[r(S,{size:"xs",variant:"outline",disabled:e.disabled||!s||d===null,onClick:()=>{s&&d!==null&&e.act({type:"sendPush",appId:s,payload:d})},children:a("tools.push.send")}),s?l&&d===null?r("p",{className:"text-xs text-destructive-foreground",children:a("tools.push.invalid")}):null:r("p",{className:"text-xs text-muted-foreground",children:a("tools.push.needsApp")})]})]})}var eo=100;function ro(e){let{t:a}=M(),[t,o]=L(!1),[l,d]=L([]),{transport:s,platform:n,deviceId:u}=e;return B(()=>{if(!t)return;let i=lt({transport:s,platform:n,deviceId:u},(p,m)=>{d(C=>{let c=m?[...p]:[...C,...p];return c.length>eo?c.slice(-eo):c})});return()=>{i(),d([])}},[t,s,n,u]),f(We,{open:t,onOpenChange:o,children:[f(Ke,{className:"flex w-full items-center gap-1.5 border-b px-3 py-2.5 text-left text-xs font-medium text-muted-foreground",children:[a("tools.eventLog.title"),r(ye,{className:`ml-auto size-3.5 transition-transform ${t?"rotate-180":""}`})]}),r(Xe,{children:r("ol",{className:"max-h-64 overflow-y-auto px-3 py-2 font-mono text-ui-2xs leading-relaxed",children:l.length===0?r("li",{className:"text-muted-foreground",children:a("tools.eventLog.empty")}):l.map(i=>f("li",{className:"flex gap-2",children:[r("span",{className:"shrink-0 text-muted-foreground",children:i.timestamp.slice(11,19)}),r("span",{className:"truncate",children:i.summary})]},i.id))})})]})}var vr=640,yr={light:"tools.settings.light",dark:"tools.settings.dark"},wr={small:"tools.settings.textSmall",default:"tools.settings.textDefault",large:"tools.settings.textLarge","extra-large":"tools.settings.textExtraLarge"},br={clear:"tools.settings.glassClear",tinted:"tools.settings.glassTinted"},kr={none:"tools.settings.filterNone",grayscale:"tools.settings.filterGrayscale","red-green":"tools.settings.filterRedGreen","green-red":"tools.settings.filterGreenRed","blue-yellow":"tools.settings.filterBlueYellow"},Dr={portrait:"tools.settings.orientationPortrait",landscape_left:"tools.settings.orientationLandscapeLeft",portrait_upside_down:"tools.settings.orientationUpsideDown",landscape_right:"tools.settings.orientationLandscapeRight"},Pr=[{setting:"reduceMotion",labelKey:"tools.settings.reduceMotion"},{setting:"increaseContrast",labelKey:"tools.settings.increaseContrast"},{setting:"reduceTransparency",labelKey:"tools.settings.reduceTransparency"},{setting:"showBorders",labelKey:"tools.settings.showBorders"},{setting:"voiceOver",labelKey:"tools.settings.voiceOver"},{setting:"networkEnabled",labelKey:"tools.settings.network"}];function lo(e){let{t:a}=M(),{device:t,controls:o}=e,{detail:l,pending:d,error:s,foregroundApp:n,disabled:u,act:i}=o,p=l?.settings,m=t.platform==="ios",C=H(null),[c,h]=L(!0);Ma(()=>{let g=C.current?.parentElement;if(!g)return;let v=()=>h(g.clientWidth<vr);v();let D=new ResizeObserver(v);return D.observe(g),()=>D.disconnect()},[]),B(()=>o.followDevice(),[o.followDevice]);let k=Xt.map(g=>({value:g,label:a(wr[g])})),R=Pr.filter(g=>wa(t.platform,{type:"setToggle",setting:g.setting,value:!0}));return f("aside",{ref:C,"aria-label":a("tools.title"),className:`flex min-h-0 flex-col border-l bg-background text-sm ${c?"absolute inset-y-0 right-0 z-10 w-full max-w-72 shadow-lg":"w-72 shrink-0"}`,children:[f("div",{className:"flex h-9 shrink-0 items-center gap-2 border-b px-3",children:[r("span",{className:"font-medium",children:a("tools.title")}),d?r(V,{size:"sm"}):null,r(S,{size:"icon-xs",variant:"ghost-muted","aria-label":a("tools.close"),className:"ml-auto",onClick:e.onClose,children:r(Y,{})})]}),f("div",{className:"min-h-0 flex-1 overflow-y-auto",children:[s?r("p",{role:"alert",className:"border-b bg-destructive/10 px-3 py-2 text-xs text-destructive-foreground",children:s}):null,l===null&&!s?f("div",{className:"flex items-center gap-2 px-3 py-3 text-xs text-muted-foreground",children:[r(V,{size:"sm"}),a("tools.reading")]}):null,f(ie,{title:a("tools.app.title"),children:[r(de,{label:a("tools.app.foreground"),children:r("span",{className:"truncate font-mono text-xs",children:n?.id??a("tools.app.none")})}),n?f("div",{className:"flex gap-1.5",children:[r(S,{size:"xs",variant:"outline",disabled:u,onClick:()=>{i({type:"terminateApp",appId:n.id})},children:a("tools.app.terminate")}),r(S,{size:"xs",variant:"outline",disabled:u,onClick:()=>{i({type:"relaunchApp",appId:n.id})},children:a("tools.app.relaunch")})]}):null,r(Da,{placeholder:a("tools.app.urlPlaceholder"),action:a("tools.app.open"),disabled:u,onSubmit:g=>i({type:"openUrl",url:g})}),r(Da,{placeholder:a(m?"tools.app.bundleIdPlaceholder":"tools.app.packagePlaceholder"),action:a("tools.app.launch"),disabled:u,fallback:n?.id,onSubmit:g=>i({type:"launchApp",appId:g})})]}),f(ie,{title:a(m?"tools.settings.titleIos":"tools.settings.titleAndroid"),children:[r(de,{label:a("tools.settings.appearance"),children:r(ka,{label:a("tools.settings.appearance"),value:p?.appearance,options:Kt.map(g=>({value:g,label:a(yr[g])})),disabled:u,onChange:g=>i({type:"setAppearance",value:g})})}),r(de,{label:a("tools.settings.textSize"),children:r(Ee,{ariaLabel:a("tools.settings.textSize"),value:p?.textSize??null,options:k,placeholder:a("tools.unknown"),disabled:u,onChange:g=>i({type:"setTextSize",value:g})})}),m?f(J,{children:[r(de,{label:a("tools.settings.liquidGlass"),children:r(ka,{label:a("tools.settings.liquidGlass"),value:p?.liquidGlass,options:$t.map(g=>({value:g,label:a(br[g])})),disabled:u,onChange:g=>i({type:"setLiquidGlass",value:g})})}),r(de,{label:a("tools.settings.colorFilter"),children:r(Ee,{ariaLabel:a("tools.settings.colorFilter"),value:p?.colorFilter??null,options:jt.map(g=>({value:g,label:a(kr[g])})),placeholder:a("tools.unknown"),disabled:u,onChange:g=>i({type:"setColorFilter",value:g})})})]}):r(de,{label:a("tools.settings.orientation"),children:r(Ee,{ariaLabel:a("tools.settings.orientation"),value:null,options:Zt.map(g=>({value:g,label:a(Dr[g])})),placeholder:a("tools.settings.rotateTo"),disabled:u,onChange:g=>i({type:"setOrientation",value:g})})}),R.map(g=>r(ba,{label:a(g.labelKey),checked:p?.[g.setting],disabled:u,onChange:v=>i({type:"setToggle",setting:g.setting,value:v})},g.setting))]}),r(ie,{title:a("tools.accessibility.title"),children:r(ba,{label:a("tools.accessibility.overlay"),checked:e.axOverlay,disabled:!1,onChange:g=>(e.onAxOverlayChange(g),Promise.resolve())})}),r(ao,{current:o.location,canClear:wa(t.platform,{type:"clearLocation"}),disabled:u,act:i}),r(to,{platform:t.platform,defaultAppId:n?.id??"",disabled:u,act:i}),m?r(oo,{appId:n?.id,disabled:u,act:i}):null,m?r(ro,{transport:e.transport,platform:t.platform,deviceId:t.id}):null]})]})}var Ar=2e4,Pa=class extends Error{status;constructor(a){super(`Screenshot capture failed (${a}). Try again.`),this.status=a}};async function so(e,a,t,o){let l=AbortSignal.timeout(Ar),d=await e.fetch(`${pe(a)}/api/screenshot?device=${encodeURIComponent(t)}`,{method:"POST",signal:o?AbortSignal.any([o,l]):l});if(!d.ok)throw new Pa(d.status);let s=await d.blob();if(!s.size)throw new Error("The device returned an empty screenshot. Try again.");return s.type?s:new Blob([s],{type:"image/png"})}var Tr=3e3,no=e=>e instanceof Error?e.message:String(e);function uo(e){let{environmentId:a,device:t}=e,o=oe(),[l,d]=L(null),[s,n]=L(null),[u,i]=L(!1),[p,m]=L(null),C=H(!1),c=H(0),h=H(!1),k={hostId:t.hostId,deviceId:t.id},R=y=>o("detail",a,k).then(F=>{c.current===y&&(d(F),m(null))},F=>{c.current===y&&(d(null),m(no(F)))});B(()=>{let y=++c.current;return R(y),()=>{c.current++}},[a,t.hostId,t.id]);let g=async y=>{if(C.current||l===null)return!1;C.current=!0;let F=++c.current;i(!0),m(null);try{let q=await o("action",a,{...k,...y});return c.current===F?d(q):await R(++c.current),y.type==="setLocation"?n({latitude:y.latitude,longitude:y.longitude}):y.type==="clearLocation"&&n(null),!0}catch(q){return c.current===F&&m(no(q)),!1}finally{C.current=!1,i(!1)}},v=H(()=>{});v.current=()=>{if(C.current||h.current)return;h.current=!0;let y=++c.current;o("detail",a,k).then(F=>{c.current===y&&d(F)},()=>{}).finally(()=>{h.current=!1})};let D=ee(()=>{v.current();let y=setInterval(()=>v.current(),Tr);return()=>clearInterval(y)},[]);return{detail:l,location:s,pending:u,error:p,act:g,followDevice:D,disabled:u||l===null,foregroundApp:e.foreground===void 0?l?.foregroundApp??null:e.foreground}}var Br=()=>typeof window<"u"&&"ReactNativeWebView"in window;function io(e){let{t:a}=M(),t=oa(e.environmentId),[o,l]=L(null),[d,s]=L(!1),[n,u]=L(!1),[i,p]=L(!1),[m,C]=L(),[c,h]=L(!1),[k,R]=L(null),[g,v]=L(null),D=H(null),y=H(null),F=t.status==="ready"?t.transport:null,q=uo({environmentId:e.environmentId,device:e.device,foreground:m}),G=ee(U=>l(U),[]),E=ee(U=>s(U),[]);B(()=>{if(!F)return;let U=rt({transport:F,platform:e.device.platform,deviceId:e.device.id},C);return()=>{U(),C(void 0)}},[e.device.id,e.device.platform,F]),B(()=>()=>{D.current?.abort(),y.current&&URL.revokeObjectURL(y.current)},[]);let W=()=>{if(!F||D.current)return;let U=new AbortController;D.current=U,h(!0),R(null),so(F,e.device.platform,e.device.id,U.signal).then(j=>{if(U.signal.aborted)return;y.current&&URL.revokeObjectURL(y.current);let X=URL.createObjectURL(j);if(y.current=X,Br()){v(X);return}let z=document.createElement("a");z.href=X,z.download=`${e.device.name.replace(/[^a-z0-9-]/gi,"-")}-${Date.now()}.png`,document.body.append(z),z.click(),z.remove()}).catch(j=>{U.signal.aborted||R(j instanceof Error?j.message:a("workspace.screenshotFailed"))}).finally(()=>{D.current===U&&(D.current=null,h(!1))})};return t.status!=="ready"?r(ae,{name:e.device.name,description:e.device.version,stage:t.status==="failed"?"error":"connecting",message:t.status==="failed"?t.message??a("workspace.needsNewerApp"):a("stream.connecting"),children:r(S,{size:"sm",variant:"outline",onClick:e.onBack,children:a("workspace.allDevices")})}):f("div",{className:"relative flex min-h-0 min-w-0 flex-1",children:[f("div",{className:"relative flex min-h-0 min-w-0 flex-1 flex-col",children:[k||q.error&&!n?r("p",{role:"alert",className:"px-3 py-2 text-xs text-destructive-foreground",children:k??q.error}):null,f("div",{className:"relative min-h-0 flex-1",children:[r(aa,{transport:t.transport,platform:e.device.platform,deviceId:e.device.id,deviceName:e.device.name,deviceDescription:e.device.version,axOverlay:i,withControls:!0,onHandle:G,onStreaming:E}),r(_t,{platform:e.device.platform,handle:o,streaming:d,controls:q,screenshotPending:c,onScreenshot:W,toolsOpen:n,onTools:()=>u(!n),onClose:e.onClose,onPowerOff:e.onPowerOff,onFloat:e.onFloat})]})]}),n?r(lo,{device:e.device,controls:q,transport:t.transport,axOverlay:i,onAxOverlayChange:p,onClose:()=>u(!1)}):null,g?f("div",{className:"absolute inset-0 z-20 flex flex-col items-center justify-center gap-3 bg-background/95 p-4",children:[r("img",{src:g,alt:a("workspace.screenshotAlt"),className:"max-h-[80%] max-w-full object-contain"}),r("p",{className:"text-xs text-muted-foreground",children:a("workspace.screenshotSaveHint")}),f(S,{size:"sm",variant:"outline",onClick:()=>v(null),children:[r(Y,{}),a("workspace.closeBrowser")]})]}):null]})}var Aa=e=>e instanceof Error?e.message:String(e);function fo(e){let{environmentId:a,threadId:t}=e,{t:o}=M(),{state:l,loaded:d,error:s,unavailable:n}=ge(a),u=oe(),[i,p]=L(null),[m,C]=L(null),c=qa(a,t),h=I=>Ne(a,t,I),k=N(),R=fe(k,"floating"),g=()=>{p(null),u("refresh",a).catch(I=>p(Aa(I)))};B(()=>{!d||n||u("refresh",a).catch(()=>{})},[a,d,u,n]);let v=ue(()=>l.sessions.filter(I=>I.threadId===t),[l.sessions,t]),D=Rr(v,c),y=D?l.devices.find(I=>I.hostId===D.hostId&&I.id===D.deviceId):void 0,F=y&&D?Ie(y):null;B(()=>{k.floating?.present({environmentId:a,threadId:t},F)}),B(()=>()=>k.floating?.present({environmentId:a,threadId:t},null),[k,a,t]);let q=ue(()=>Fr(l),[l]),G=l.hostStatuses[Le],E=G?.status==="ready",W=G?.status==="installing"||G?.status==="starting",U=Ia(),j=l.bootingDevices.filter(I=>I.threadId===t),X=l.hosts.flatMap(I=>I.platforms.filter(K=>!K.available)),z=async I=>{p(null),C(I),ua(a,t,Z(I));try{await u("open",a,{threadId:t,hostId:I.hostId,deviceId:I.id,platform:I.platform}),h(Z(I))}catch(K){ua(a,t,Z(I),!1),p(Aa(K))}finally{C(null)}},O=I=>{D&&(p(null),u("close",a,{threadId:t,hostId:D.hostId,deviceId:D.deviceId,shutdown:I}).then(()=>h(null)).catch(K=>p(Aa(K))))};return n?r(ae,{name:o("panel.title"),stage:"error",message:o("panel.unavailable")}):f("div",{className:"flex size-full min-h-0 flex-col",children:[j.length>0?r("div",{role:"status",className:"border-b px-3 py-2 text-xs text-muted-foreground",children:o("panel.booting",{names:j.map(I=>I.name).join(", ")})}):null,W&&!y?null:r(Ft,{detail:G,onRetry:()=>u("refresh",a).catch(()=>{})}),i||s?f("div",{role:"alert",className:"flex items-start gap-2 border-b bg-destructive/5 px-3 py-2 text-xs text-destructive-foreground",children:[r("p",{className:"min-w-0 flex-1 whitespace-pre-wrap break-words",children:i??s}),i?r(S,{size:"icon-xs",variant:"ghost","aria-label":o("panel.dismissError"),onClick:()=>p(null),children:r(Y,{className:"size-3"})}):null]}):null,r("div",{className:"relative flex min-h-0 flex-1",children:y&&D?r(io,{environmentId:a,device:y,onBack:()=>h(""),onFloat:R?()=>k.floating?.open({environmentId:a,threadId:t},{...Ie(y),reason:"user"}):void 0,onPowerOff:()=>O(!0),onClose:()=>O(!1)},`${a}\0${Z(y)}`):m||W||!d?r(ae,{name:m?.name??o("panel.title"),...m?{description:m.version}:{},stage:"opening",message:m?m.booted?o("panel.opening"):o("panel.starting"):W&&G?U(G):o("panel.finding")}):r(Mr,{environmentId:a,host:l.hosts.find(I=>I.id===Le),grouped:q,hostReady:E,hostFailed:G?.status==="failed",unavailableReasons:X,showNoAvdHint:E&&!l.devices.some(I=>I.platform==="android")&&!X.some(I=>I.platform==="android"),pendingKey:m?Z(m):null,onOpen:I=>{z(I)},onRefresh:g})})]})}function Mr(e){let{t:a}=M(),t=e.grouped.length===0;return r("div",{className:"flex size-full flex-col overflow-y-auto px-4 py-6 text-sm text-muted-foreground",children:f("div",{className:`mx-auto flex w-full max-w-xl flex-col gap-5 ${t?"items-center text-center":""}`,children:[r(Gt,{environmentId:e.environmentId,iosSupported:!e.unavailableReasons.some(o=>o.reasonCode==="ios-needs-macos")},e.environmentId),t?f(J,{children:[r(xe,{className:"size-6 opacity-60"}),r("p",{className:"max-w-sm",children:e.hostFailed?a("panel.hubFailed"):a("panel.empty")})]}):null,e.hostReady?e.grouped.map(o=>f("section",{className:"w-full space-y-2 text-left",children:[f("h3",{className:"flex items-center gap-2 font-medium",children:[r(xe,{className:"size-4 shrink-0"}),o.platform==="ios"?a("panel.platformIos"):a("panel.platformAndroid")]}),r("ul",{className:"divide-y rounded-md border",children:o.devices.map(l=>r("li",{children:f(S,{variant:"ghost",className:"h-auto min-h-11 w-full justify-between gap-3 rounded-none px-3 py-2 text-left font-normal",disabled:e.pendingKey!==null,onClick:()=>e.onOpen(l),children:[f("span",{className:"min-w-0 flex-1",children:[r("span",{className:"block truncate text-foreground",children:l.name}),f("span",{className:"block text-xs",children:[l.version,","," ",l.booted?a("panel.running"):a("panel.stopped")]})]}),e.pendingKey===Z(l)?r(V,{size:"xs"}):r("span",{className:"text-xs",children:l.booted?a("panel.open"):a("panel.start")})]})},Z(l)))})]},o.platform)):null,e.unavailableReasons.map(o=>r("p",{className:"max-w-sm text-xs",children:o.reasonCode?a(`unavailable.${o.reasonCode}`,{root:o.sdkRoot??""}):o.reason},`${o.platform}:${o.reasonCode}`)),e.showNoAvdHint?r("p",{className:"max-w-sm text-xs",children:a("panel.noAvd")}):null,f("div",{className:`flex flex-wrap items-center gap-2 ${t?"self-center":"self-start"}`,children:[r(S,{variant:t?"outline":"ghost",size:"sm",onClick:e.onRefresh,children:a("panel.refresh")}),r(Et,{environmentId:e.environmentId,host:e.host,busy:!1})]})]})})}function Rr(e,a){if(a!==""){if(a!==null){let t=e.find(o=>Z({hostId:o.hostId,id:o.deviceId})===a);if(t)return t}return e.toSorted((t,o)=>o.openedAt.localeCompare(t.openedAt))[0]}}function Fr(e){let a=[];for(let t of["ios","android"]){let o=e.devices.filter(l=>l.platform===t).toSorted((l,d)=>Number(d.booted)-Number(l.booted)||l.name.localeCompare(d.name));o.length>0&&a.push({platform:t,devices:o})}return a}function co({environmentId:e,threadId:a}){let t=N(),{state:o,loaded:l}=ge(e),d=H(null);return B(()=>{if(!l||!fe(t,"floating"))return;let s=`${e}\0${a}`,n=d.current?.key===s?d.current.seen:null,{seen:u,opened:i}=Ha({environmentId:e,threadId:a,previous:n,sessions:o.sessions,devices:o.devices});d.current={key:s,seen:u};for(let p of i)t.floating?.open({environmentId:e,threadId:a},{...Ie(p),reason:"agent",panelId:qe})},[t,e,l,o.devices,o.sessions,a]),null}function Er(e){return{panels:{device:function(t){return f(Ue,{value:e,children:[r("style",{children:la}),r("div",{className:`${Ve} flex h-full min-h-0 flex-1 flex-col`,children:r(fo,{environmentId:t.environmentId,threadId:t.threadId})})]})}},views:{deviceFloat:function(t){return f(Ue,{value:e,children:[r("style",{children:la}),r("div",{className:`${Ve} relative size-full`,children:r(Pt,{...t})})]})},deviceSessions:function(t){return r(Ue,{value:e,children:r(co,{environmentId:t.environmentId,threadId:t.threadId})})}}}}export{Er as default};
|
package/dist/helper.mjs
CHANGED
|
@@ -238,16 +238,17 @@ function applySdkEnvironment(sdk) {
|
|
|
238
238
|
|
|
239
239
|
/**
|
|
240
240
|
* hub 开机、等上线都要先跑 `avdmanager list avd`,失败就当列不出设备。avdmanager 要 JDK,私有 SDK
|
|
241
|
-
*
|
|
242
|
-
*
|
|
241
|
+
* 不带它,外部 SDK 也可能没有。这里直接读 AVD 目录作答,其它命令照常执行。hub 在 Windows 上把
|
|
242
|
+
* `.bat` 和参数拼成一条命令串、args 留空,所以按拼好的整条命令认。hub 改成不经 promisify(execFile)
|
|
243
|
+
* 调它时,这层失效,开机会回到报错。
|
|
243
244
|
*/
|
|
244
245
|
export function answerAvdList(childProcess, listing) {
|
|
245
246
|
const execFile = childProcess.execFile;
|
|
246
247
|
const promisified = NodeUtil.promisify(execFile);
|
|
247
248
|
const isAvdList = (file, args) =>
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
/(?:^|[\\/"\s])avdmanager(?:\.bat)?"? list avd(?: |$)/iu.test(
|
|
250
|
+
[file, ...(args ?? [])].join(" "),
|
|
251
|
+
);
|
|
251
252
|
const patched = (...call) => execFile(...call);
|
|
252
253
|
patched[NodeUtil.promisify.custom] = async (file, args, ...rest) =>
|
|
253
254
|
isAvdList(file, args) ? { stdout: listing(), stderr: "" } : promisified(file, args, ...rest);
|
package/dist/index.js
CHANGED
|
@@ -563,9 +563,16 @@ var registerCommands = (ctx, service) => {
|
|
|
563
563
|
import * as NodeFSP3 from "node:fs/promises";
|
|
564
564
|
import * as NodePath3 from "node:path";
|
|
565
565
|
|
|
566
|
+
// src/environmentTypes.ts
|
|
567
|
+
var ANDROID_VERSIONS = [
|
|
568
|
+
{ api: "35", name: "Android 15" },
|
|
569
|
+
{ api: "30", name: "Android 11" }
|
|
570
|
+
];
|
|
571
|
+
var BASE_ANDROID_API = ANDROID_VERSIONS[0].api;
|
|
572
|
+
|
|
566
573
|
// src/androidPackages.ts
|
|
567
574
|
var repo = "https://dl.google.com/android/repository/";
|
|
568
|
-
var archive = (name, file, sha1, bytes, destination = "
|
|
575
|
+
var archive = (name, file, sha1, bytes, destination = "") => ({ name, url: `${repo}${file}`, sha1, bytes, destination });
|
|
569
576
|
var platformTools = {
|
|
570
577
|
linux: archive(
|
|
571
578
|
"Platform-Tools 37.0.1",
|
|
@@ -612,19 +619,38 @@ var emulators = {
|
|
|
612
619
|
455342868
|
|
613
620
|
)
|
|
614
621
|
};
|
|
615
|
-
var
|
|
622
|
+
var images = {
|
|
623
|
+
"35": {
|
|
624
|
+
name: "Android 15 (API 35), AOSP",
|
|
625
|
+
x64: ["x86_64-35_r02.zip", "2d857d170c0d1b827149565da34b3383e5306f7f", 782404023],
|
|
626
|
+
arm64: ["arm64-v8a-35_r02.zip", "2026a06409db630b56711afdbffb457c1dbaed49", 769099654]
|
|
627
|
+
},
|
|
628
|
+
"30": {
|
|
629
|
+
name: "Android 11 (API 30), AOSP",
|
|
630
|
+
x64: ["x86_64-30_r11.zip", "5e4de3946d46f88856c35efcc4d797b381456347", 676379777],
|
|
631
|
+
arm64: ["arm64-v8a-30_r02.zip", "e96298145a5e0bfd6da4816f51b06c520d8dba72", 548363615]
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
var image = (api, arch2) => {
|
|
635
|
+
const [file, sha1, bytes] = images[api][arch2];
|
|
636
|
+
return archive(
|
|
637
|
+
images[api].name,
|
|
638
|
+
`sys-img/android/${file}`,
|
|
639
|
+
sha1,
|
|
640
|
+
bytes,
|
|
641
|
+
`system-images/android-${api}/default`
|
|
642
|
+
);
|
|
643
|
+
};
|
|
644
|
+
var androidArchives = (platform2, arch2, api = BASE_ANDROID_API) => {
|
|
616
645
|
const emulator = emulators[`${platform2}-${arch2}`];
|
|
617
646
|
const tools = platformTools[platform2];
|
|
618
647
|
if (!emulator || !tools) return null;
|
|
619
|
-
const
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
"image"
|
|
626
|
-
);
|
|
627
|
-
return [tools, emulator, image];
|
|
648
|
+
const imageArch = arch2 === "arm64" ? "arm64" : "x64";
|
|
649
|
+
return [
|
|
650
|
+
tools,
|
|
651
|
+
emulator,
|
|
652
|
+
...[.../* @__PURE__ */ new Set([BASE_ANDROID_API, api])].map((item) => image(item, imageArch))
|
|
653
|
+
];
|
|
628
654
|
};
|
|
629
655
|
|
|
630
656
|
// src/environmentArchive.ts
|
|
@@ -830,7 +856,9 @@ var throttledEnvironmentProgress = (publish, now = Date.now) => {
|
|
|
830
856
|
import * as NodeFSP2 from "node:fs/promises";
|
|
831
857
|
import * as NodePath2 from "node:path";
|
|
832
858
|
var ENVIRONMENT_MARKER = ".ycodium-devices-environment.json";
|
|
833
|
-
var
|
|
859
|
+
var androidVersionLabel = (api) => `${ANDROID_VERSIONS.find((item) => item.api === api)?.name} / API ${api} \xB7 Emulator 37.2.12`;
|
|
860
|
+
var ANDROID_ENVIRONMENT_VERSION = androidVersionLabel(BASE_ANDROID_API);
|
|
861
|
+
var androidAvdName = (api) => `Ycodium_API_${api}`;
|
|
834
862
|
var environmentPaths = (root) => ({
|
|
835
863
|
root,
|
|
836
864
|
sdk: NodePath2.join(root, "sdk"),
|
|
@@ -943,27 +971,28 @@ var selectedPrivateSdk = async (dataDir) => {
|
|
|
943
971
|
if (!root) return null;
|
|
944
972
|
return await privateEnvironmentReady(root) ? NodePath2.join(root, "sdk") : null;
|
|
945
973
|
};
|
|
946
|
-
var privateEnvironmentReady = async (root) => {
|
|
974
|
+
var privateEnvironmentReady = async (root, api = BASE_ANDROID_API) => {
|
|
947
975
|
try {
|
|
948
976
|
await assertPrivateEnvironmentPaths(root);
|
|
949
977
|
const paths = environmentPaths(root);
|
|
950
978
|
if (await NodeFSP2.readFile(NodePath2.join(root, ".prepared"), "utf8") !== ANDROID_ENVIRONMENT_VERSION || await NodeFSP2.readFile(NodePath2.join(paths.sdk, ".ycodium-components"), "utf8") !== ANDROID_ENVIRONMENT_VERSION)
|
|
951
979
|
return false;
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
config
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
980
|
+
for (const item of /* @__PURE__ */ new Set([BASE_ANDROID_API, api])) {
|
|
981
|
+
const avd = NodePath2.join(paths.avd, `${androidAvdName(item)}.avd`);
|
|
982
|
+
const ini = NodePath2.join(paths.avd, `${androidAvdName(item)}.ini`);
|
|
983
|
+
await assertPrivatePath(root, NodePath2.join(avd, "config.ini"));
|
|
984
|
+
await assertPrivatePath(root, ini);
|
|
985
|
+
const config = await NodeFSP2.readFile(NodePath2.join(avd, "config.ini"), "utf8");
|
|
986
|
+
const image2 = new RegExp(
|
|
987
|
+
`^image\\.sysdir\\.1\\s*=\\s*(system-images/android-${item}/default/(?:x86_64|arm64-v8a)/)\\s*$`,
|
|
988
|
+
"m"
|
|
989
|
+
).exec(config)?.[1];
|
|
990
|
+
if (!image2) return false;
|
|
991
|
+
await assertPrivatePath(root, NodePath2.join(paths.sdk, image2, "system.img"));
|
|
992
|
+
await NodeFSP2.access(NodePath2.join(paths.sdk, image2, "system.img"));
|
|
993
|
+
if (!(await NodeFSP2.readFile(ini, "utf8")).includes(`path=${avd}
|
|
994
|
+
`)) return false;
|
|
995
|
+
}
|
|
967
996
|
for (const suffix of ["", ".exe"]) {
|
|
968
997
|
try {
|
|
969
998
|
await NodeFSP2.access(NodePath2.join(paths.sdk, "platform-tools", `adb${suffix}`));
|
|
@@ -1007,6 +1036,18 @@ var cleanEnvironment = async (root, category) => {
|
|
|
1007
1036
|
var GIB = 1024 ** 3;
|
|
1008
1037
|
var androidGuide = "https://developer.android.com/studio/run/emulator-acceleration";
|
|
1009
1038
|
var appleGuide = "https://developer.apple.com/documentation/xcode/downloading-and-installing-additional-xcode-components";
|
|
1039
|
+
var androidApi = (version) => {
|
|
1040
|
+
const requested = version?.trim() || BASE_ANDROID_API;
|
|
1041
|
+
const selected = ANDROID_VERSIONS.find((item) => item.api === requested);
|
|
1042
|
+
if (!selected) throw new DeviceError("invalid-input", `Unsupported Android API: ${requested}`);
|
|
1043
|
+
return selected.api;
|
|
1044
|
+
};
|
|
1045
|
+
var pendingArchives = async (archives, sdk) => {
|
|
1046
|
+
const present = await Promise.all(
|
|
1047
|
+
archives.map((item) => NodeFSP3.lstat(NodePath3.join(sdk, item.destination)).catch(() => null))
|
|
1048
|
+
);
|
|
1049
|
+
return archives.filter((_item, index) => present[index] === null);
|
|
1050
|
+
};
|
|
1010
1051
|
var DeviceEnvironments = class {
|
|
1011
1052
|
busy = false;
|
|
1012
1053
|
abort = new AbortController();
|
|
@@ -1119,12 +1160,12 @@ var DeviceEnvironments = class {
|
|
|
1119
1160
|
deviceDataBytes
|
|
1120
1161
|
};
|
|
1121
1162
|
}
|
|
1122
|
-
const
|
|
1163
|
+
const api = androidApi(input.version);
|
|
1164
|
+
const archives = androidArchives(probe.platform, probe.arch, api);
|
|
1123
1165
|
const sdk = await this.options.externalSdk();
|
|
1124
|
-
const prepared = await privateEnvironmentReady(root);
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
(archives ?? []).map(async (item) => {
|
|
1166
|
+
const prepared = await privateEnvironmentReady(root, api);
|
|
1167
|
+
const missing = await Promise.all(
|
|
1168
|
+
(await pendingArchives(archives ?? [], paths.sdk)).map(async (item) => {
|
|
1128
1169
|
const cached = await NodeFSP3.lstat(archivePath(item, paths.cache)).catch(() => null);
|
|
1129
1170
|
return cached?.size === item.bytes ? 0 : item.bytes;
|
|
1130
1171
|
})
|
|
@@ -1135,7 +1176,7 @@ var DeviceEnvironments = class {
|
|
|
1135
1176
|
source: sdk.available && sdk.root !== paths.sdk ? "external" : "private",
|
|
1136
1177
|
...sdk.available && sdk.root ? { existingSdkRoot: sdk.root } : {},
|
|
1137
1178
|
root,
|
|
1138
|
-
version:
|
|
1179
|
+
version: androidVersionLabel(api),
|
|
1139
1180
|
downloadBytes: archives ? missing.reduce((sum, bytes) => sum + bytes, 0) : null,
|
|
1140
1181
|
requiredFreeBytes: 12 * GIB,
|
|
1141
1182
|
freeBytes: free,
|
|
@@ -1203,7 +1244,7 @@ var DeviceEnvironments = class {
|
|
|
1203
1244
|
])
|
|
1204
1245
|
await NodeFSP3.mkdir(directory, { recursive: true });
|
|
1205
1246
|
if (input.platform === "ios") await this.prepareIos(plan, progress, signal);
|
|
1206
|
-
else await this.prepareAndroid(plan, progress, signal);
|
|
1247
|
+
else await this.prepareAndroid(plan, androidApi(input.version), progress, signal);
|
|
1207
1248
|
} finally {
|
|
1208
1249
|
await release?.();
|
|
1209
1250
|
}
|
|
@@ -1211,57 +1252,68 @@ var DeviceEnvironments = class {
|
|
|
1211
1252
|
return this.plan(input);
|
|
1212
1253
|
});
|
|
1213
1254
|
}
|
|
1214
|
-
async prepareAndroid(plan, progress, signal) {
|
|
1255
|
+
async prepareAndroid(plan, api, progress, signal) {
|
|
1215
1256
|
const probe = await this.probe();
|
|
1216
|
-
const archives = androidArchives(probe.platform, probe.arch);
|
|
1257
|
+
const archives = androidArchives(probe.platform, probe.arch, api);
|
|
1217
1258
|
if (!archives) throw new Error("Android host target is unsupported");
|
|
1218
1259
|
const paths = environmentPaths(plan.root);
|
|
1219
1260
|
const staging = await NodeFSP3.mkdtemp(NodePath3.join(paths.temp, "prepare-"));
|
|
1220
1261
|
try {
|
|
1221
1262
|
const existing2 = await NodeFSP3.lstat(paths.sdk).catch(() => null);
|
|
1263
|
+
if (existing2 && (existing2.isSymbolicLink() || !existing2.isDirectory() || await NodeFSP3.readFile(NodePath3.join(paths.sdk, ".ycodium-components"), "utf8").catch(
|
|
1264
|
+
() => ""
|
|
1265
|
+
) !== ANDROID_ENVIRONMENT_VERSION))
|
|
1266
|
+
throw new Error(
|
|
1267
|
+
"An unrecognized private SDK already exists; its installation will not be overwritten"
|
|
1268
|
+
);
|
|
1269
|
+
const pending = await pendingArchives(archives, paths.sdk);
|
|
1270
|
+
const totalBytes = pending.reduce((sum, item) => sum + item.bytes, 0);
|
|
1271
|
+
let finished = 0;
|
|
1272
|
+
for (const item of pending) {
|
|
1273
|
+
const received = (bytes) => progress({
|
|
1274
|
+
phase: "download",
|
|
1275
|
+
component: item.name,
|
|
1276
|
+
receivedBytes: finished + bytes,
|
|
1277
|
+
totalBytes
|
|
1278
|
+
});
|
|
1279
|
+
received(0);
|
|
1280
|
+
signal.throwIfAborted();
|
|
1281
|
+
const file = await downloadArchive(
|
|
1282
|
+
item,
|
|
1283
|
+
paths.cache,
|
|
1284
|
+
(url2, init) => this.options.fetch(url2, { ...init, signal }),
|
|
1285
|
+
received
|
|
1286
|
+
);
|
|
1287
|
+
finished += item.bytes;
|
|
1288
|
+
progress({
|
|
1289
|
+
phase: "extract",
|
|
1290
|
+
component: item.name,
|
|
1291
|
+
receivedBytes: finished,
|
|
1292
|
+
totalBytes
|
|
1293
|
+
});
|
|
1294
|
+
await extractEnvironmentZip(file, NodePath3.join(staging, item.destination), signal);
|
|
1295
|
+
}
|
|
1222
1296
|
if (existing2) {
|
|
1223
|
-
|
|
1224
|
-
()
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
);
|
|
1229
|
-
} else {
|
|
1230
|
-
const totalBytes = archives.reduce((sum, item) => sum + item.bytes, 0);
|
|
1231
|
-
let finished = 0;
|
|
1232
|
-
for (const item of archives) {
|
|
1233
|
-
const received = (bytes) => progress({
|
|
1234
|
-
phase: "download",
|
|
1235
|
-
component: item.name,
|
|
1236
|
-
receivedBytes: finished + bytes,
|
|
1237
|
-
totalBytes
|
|
1238
|
-
});
|
|
1239
|
-
received(0);
|
|
1240
|
-
signal.throwIfAborted();
|
|
1241
|
-
const file = await downloadArchive(
|
|
1242
|
-
item,
|
|
1243
|
-
paths.cache,
|
|
1244
|
-
(url2, init) => this.options.fetch(url2, { ...init, signal }),
|
|
1245
|
-
received
|
|
1246
|
-
);
|
|
1247
|
-
finished += item.bytes;
|
|
1248
|
-
progress({
|
|
1249
|
-
phase: "extract",
|
|
1250
|
-
component: item.name,
|
|
1251
|
-
receivedBytes: finished,
|
|
1252
|
-
totalBytes
|
|
1253
|
-
});
|
|
1254
|
-
await extractEnvironmentZip(
|
|
1255
|
-
file,
|
|
1256
|
-
item.destination === "sdk" ? staging : NodePath3.join(staging, "system-images", "android-35", "default"),
|
|
1257
|
-
signal
|
|
1258
|
-
);
|
|
1297
|
+
for (const item of pending) {
|
|
1298
|
+
const target2 = NodePath3.join(paths.sdk, item.destination);
|
|
1299
|
+
await assertPrivatePath(paths.root, target2);
|
|
1300
|
+
await NodeFSP3.mkdir(NodePath3.dirname(target2), { recursive: true });
|
|
1301
|
+
await NodeFSP3.rename(NodePath3.join(staging, item.destination), target2);
|
|
1259
1302
|
}
|
|
1260
|
-
|
|
1303
|
+
} else {
|
|
1304
|
+
await NodeFSP3.writeFile(
|
|
1305
|
+
NodePath3.join(staging, ".ycodium-components"),
|
|
1306
|
+
ANDROID_ENVIRONMENT_VERSION
|
|
1307
|
+
);
|
|
1261
1308
|
await NodeFSP3.rename(staging, paths.sdk);
|
|
1262
1309
|
}
|
|
1263
1310
|
progress({ phase: "device" });
|
|
1264
|
-
|
|
1311
|
+
for (const item of /* @__PURE__ */ new Set([BASE_ANDROID_API, api]))
|
|
1312
|
+
await this.createPrivateAvd(
|
|
1313
|
+
paths.root,
|
|
1314
|
+
probe.arch === "arm64" ? "arm64-v8a" : "x86_64",
|
|
1315
|
+
item
|
|
1316
|
+
);
|
|
1265
1317
|
signal.throwIfAborted();
|
|
1266
1318
|
progress({ phase: "validate" });
|
|
1267
1319
|
const validated = await this.options.process.run({
|
|
@@ -1272,7 +1324,7 @@ var DeviceEnvironments = class {
|
|
|
1272
1324
|
});
|
|
1273
1325
|
if (validated.exitCode !== 0)
|
|
1274
1326
|
throw new Error(`The private SDK could not be validated. ${validated.stderr.trim()}`);
|
|
1275
|
-
await NodeFSP3.writeFile(NodePath3.join(plan.root, ".prepared"),
|
|
1327
|
+
await NodeFSP3.writeFile(NodePath3.join(plan.root, ".prepared"), ANDROID_ENVIRONMENT_VERSION);
|
|
1276
1328
|
await NodeFSP3.writeFile(
|
|
1277
1329
|
NodePath3.join(this.options.dataDir, "android-environment.json"),
|
|
1278
1330
|
JSON.stringify({ root: plan.root })
|
|
@@ -1281,9 +1333,9 @@ var DeviceEnvironments = class {
|
|
|
1281
1333
|
await NodeFSP3.rm(staging, { recursive: true, force: true });
|
|
1282
1334
|
}
|
|
1283
1335
|
}
|
|
1284
|
-
async createPrivateAvd(root, abi) {
|
|
1336
|
+
async createPrivateAvd(root, abi, api) {
|
|
1285
1337
|
const paths = environmentPaths(root);
|
|
1286
|
-
const name =
|
|
1338
|
+
const name = androidAvdName(api);
|
|
1287
1339
|
const avd = NodePath3.join(paths.avd, `${name}.avd`);
|
|
1288
1340
|
await assertPrivatePath(root, avd);
|
|
1289
1341
|
await assertPrivatePath(root, NodePath3.join(paths.avd, `${name}.ini`));
|
|
@@ -1298,7 +1350,7 @@ var DeviceEnvironments = class {
|
|
|
1298
1350
|
await NodeFSP3.mkdir(avd, { recursive: true });
|
|
1299
1351
|
const config = {
|
|
1300
1352
|
AvdId: name,
|
|
1301
|
-
"avd.ini.displayname":
|
|
1353
|
+
"avd.ini.displayname": `Ycodium ${ANDROID_VERSIONS.find((item) => item.api === api)?.name}`,
|
|
1302
1354
|
"abi.type": abi,
|
|
1303
1355
|
"hw.cpu.arch": abi === "arm64-v8a" ? "arm64" : "x86_64",
|
|
1304
1356
|
"hw.cpu.ncore": "2",
|
|
@@ -1309,8 +1361,10 @@ var DeviceEnvironments = class {
|
|
|
1309
1361
|
"hw.gpu.enabled": "yes",
|
|
1310
1362
|
"hw.gpu.mode": "auto",
|
|
1311
1363
|
"hw.keyboard": "yes",
|
|
1364
|
+
// 不写时 API 30 按实体按键处理,屏幕上没有导航栏。
|
|
1365
|
+
"hw.mainKeys": "no",
|
|
1312
1366
|
"disk.dataPartition.size": "4G",
|
|
1313
|
-
"image.sysdir.1": `system-images/android
|
|
1367
|
+
"image.sysdir.1": `system-images/android-${api}/default/${abi}/`,
|
|
1314
1368
|
"tag.id": "default",
|
|
1315
1369
|
"tag.display": "Default Android System Image",
|
|
1316
1370
|
"PlayStore.enabled": "false"
|
|
@@ -1324,7 +1378,7 @@ var DeviceEnvironments = class {
|
|
|
1324
1378
|
NodePath3.join(paths.avd, `${name}.ini`),
|
|
1325
1379
|
`avd.ini.encoding=UTF-8
|
|
1326
1380
|
path=${avd}
|
|
1327
|
-
target=android
|
|
1381
|
+
target=android-${api}
|
|
1328
1382
|
`,
|
|
1329
1383
|
{ flag: "wx" }
|
|
1330
1384
|
);
|
|
@@ -2193,7 +2247,7 @@ import * as NodePath7 from "node:path";
|
|
|
2193
2247
|
import * as NodeFSP6 from "node:fs/promises";
|
|
2194
2248
|
import * as NodePath6 from "node:path";
|
|
2195
2249
|
import * as NodeOS from "node:os";
|
|
2196
|
-
var DEVICE_HUB_VERSION = "0.
|
|
2250
|
+
var DEVICE_HUB_VERSION = "0.19.1";
|
|
2197
2251
|
var AGENT_DEVICE_VERSION = "0.21.12";
|
|
2198
2252
|
var runtimeTarget = `${NodeOS.platform()}-${NodeOS.arch()}`;
|
|
2199
2253
|
var HUB_SPEC = {
|
|
@@ -2878,16 +2932,25 @@ var readIos = async (tools, udid) => {
|
|
|
2878
2932
|
};
|
|
2879
2933
|
return { settings, foregroundApp: null };
|
|
2880
2934
|
};
|
|
2935
|
+
var ANDROID_DETAIL_SEPARATOR = "--ycodium-detail--";
|
|
2936
|
+
var ANDROID_DETAIL_READS = [
|
|
2937
|
+
"cmd uimode night",
|
|
2938
|
+
"settings get system font_scale",
|
|
2939
|
+
"settings get global animator_duration_scale",
|
|
2940
|
+
"settings get global wifi_on",
|
|
2941
|
+
// `dumpsys window windows` 在 API 36 起不再打印焦点;不带过滤的整份 dump 还打。
|
|
2942
|
+
"dumpsys window"
|
|
2943
|
+
];
|
|
2881
2944
|
var readAndroid = async (tools, serial) => {
|
|
2882
|
-
const
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
]);
|
|
2945
|
+
const output = await quiet(
|
|
2946
|
+
() => adb(
|
|
2947
|
+
tools,
|
|
2948
|
+
serial,
|
|
2949
|
+
["shell", ANDROID_DETAIL_READS.join(` ; echo ${ANDROID_DETAIL_SEPARATOR} ; `)],
|
|
2950
|
+
"detail"
|
|
2951
|
+
)
|
|
2952
|
+
);
|
|
2953
|
+
const [night, fontScale, animator, wifi, focus] = (output ?? "").split(ANDROID_DETAIL_SEPARATOR).map((part) => part.trim() || void 0);
|
|
2891
2954
|
const scale = fontScale && fontScale !== "null" ? Number(fontScale) : Number.NaN;
|
|
2892
2955
|
const focused = focus?.match(/m(?:CurrentFocus|FocusedApp)=\w+\{[^ ]+ u\d+ ([^/ ]+)\//);
|
|
2893
2956
|
const settings = {
|
|
@@ -3068,6 +3131,8 @@ var classifyBootFailure = (error) => {
|
|
|
3068
3131
|
};
|
|
3069
3132
|
|
|
3070
3133
|
// src/service.ts
|
|
3134
|
+
var ANDROID_BOOT_POLL_MS = 2e3;
|
|
3135
|
+
var ANDROID_BOOT_POLLS = 60;
|
|
3071
3136
|
var sameDevice = (a, hostId, deviceId) => a.hostId === hostId && a.id === deviceId;
|
|
3072
3137
|
var DeviceService = class {
|
|
3073
3138
|
environmentMutating = false;
|
|
@@ -3235,6 +3300,22 @@ var DeviceService = class {
|
|
|
3235
3300
|
this.pendingOpens--;
|
|
3236
3301
|
}
|
|
3237
3302
|
}
|
|
3303
|
+
/** hub 在模拟器连上 adb 时就返回,这时系统还没开机完,画面出不来;等不到也照常打开。 */
|
|
3304
|
+
async waitForAndroidBoot(serial) {
|
|
3305
|
+
for (let poll = 0; poll < ANDROID_BOOT_POLLS; poll += 1) {
|
|
3306
|
+
const result = await this.host.runSdkCommand("adb", [
|
|
3307
|
+
"-s",
|
|
3308
|
+
serial,
|
|
3309
|
+
"shell",
|
|
3310
|
+
"getprop",
|
|
3311
|
+
"sys.boot_completed"
|
|
3312
|
+
]);
|
|
3313
|
+
if (result.code === 0 && result.stdout.trim() === "1") return;
|
|
3314
|
+
await new Promise(
|
|
3315
|
+
(resolve3) => setTimeout(resolve3, this.options.androidBootPollMs ?? ANDROID_BOOT_POLL_MS)
|
|
3316
|
+
);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3238
3319
|
async openDevice(input) {
|
|
3239
3320
|
this.resolveHost(input.hostId);
|
|
3240
3321
|
const availability = await this.host.platformAvailability(input.platform);
|
|
@@ -3276,6 +3357,7 @@ var DeviceService = class {
|
|
|
3276
3357
|
}
|
|
3277
3358
|
if (device.platform === "ios") await hub.attachIosStream(device.id);
|
|
3278
3359
|
bootedId = result.serial ?? result.id ?? device.id;
|
|
3360
|
+
if (device.platform === "android") await this.waitForAndroidBoot(bootedId);
|
|
3279
3361
|
} finally {
|
|
3280
3362
|
this.publish((state) => ({
|
|
3281
3363
|
...state,
|
|
@@ -3674,7 +3756,7 @@ var deviceToolkit = (service) => ({
|
|
|
3674
3756
|
var HUB_SERVICE = "hub";
|
|
3675
3757
|
var index_default = definePlugin({
|
|
3676
3758
|
id: "devices",
|
|
3677
|
-
apiVersion:
|
|
3759
|
+
apiVersion: 67,
|
|
3678
3760
|
activate: async (ctx) => {
|
|
3679
3761
|
const direct = (input, init) => ctx.proxies.fetch(PLUGIN_PROXY_DIRECT).then((fetchDirect) => fetchDirect(input, init));
|
|
3680
3762
|
const host = new LocalDeviceHost({
|
package/locales/en.json
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"directory": "Storage directory on this machine",
|
|
10
10
|
"defaultDirectory": "Ycodium private data directory",
|
|
11
11
|
"directoryHint": "Choose an absolute folder on the desired disk. A dedicated ycodium-devices folder is created inside it. This path belongs to the connected machine.",
|
|
12
|
+
"androidVersion": "Android version",
|
|
13
|
+
"androidVersionOption": "{{name}} (API {{api}})",
|
|
12
14
|
"iosVersion": "iOS runtime version",
|
|
13
15
|
"iosVersionPlaceholder": "For example, 18.0",
|
|
14
16
|
"inspect": "Check prerequisites and storage",
|
|
@@ -29,7 +31,7 @@
|
|
|
29
31
|
"external": "Existing SDKs are reused by default. Preparing a private environment selects it unless an SDK location is explicitly set in Settings. Normal use of existing virtual devices writes to their data. Private preparation does not modify the external SDK.",
|
|
30
32
|
"guide": "Official setup guidance",
|
|
31
33
|
"appleOwnership": "Apple installs this runtime in its shared simulator environment. Only its download archive is stored privately. No existing runtime is upgraded or removed. Xcode may require you to complete permissions or initialization yourself.",
|
|
32
|
-
"privateOwnership": "Android
|
|
34
|
+
"privateOwnership": "The chosen Android AOSP image, Platform-Tools and Emulator are downloaded from Google at pinned revisions. SDK files, virtual device data, configuration and temporary files stay in private storage. Applications installed in a virtual device are user data.",
|
|
33
35
|
"appleLicense": "Apple software license agreements",
|
|
34
36
|
"androidLicense": "Android SDK License Agreement",
|
|
35
37
|
"acceptLicense": "I accept the applicable component licenses",
|
package/locales/zh-CN.json
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"directory": "这台机器上的存储目录",
|
|
10
10
|
"defaultDirectory": "Ycodium 私有数据目录",
|
|
11
11
|
"directoryHint": "填写目标磁盘上的绝对路径,组件将放进其中专用的 ycodium-devices 文件夹。路径属于当前连接的机器。",
|
|
12
|
+
"androidVersion": "Android 版本",
|
|
13
|
+
"androidVersionOption": "{{name}}(API {{api}})",
|
|
12
14
|
"iosVersion": "iOS 运行时版本",
|
|
13
15
|
"iosVersionPlaceholder": "例如 18.0",
|
|
14
16
|
"inspect": "检查条件与存储空间",
|
|
@@ -29,7 +31,7 @@
|
|
|
29
31
|
"external": "默认复用已有 SDK。准备私有环境后会接入它,但设置中明确指定的 SDK 位置优先。正常使用已有虚拟设备会写入其数据;私有准备不会修改外部 SDK。",
|
|
30
32
|
"guide": "官方设置指引",
|
|
31
33
|
"appleOwnership": "Apple 会将运行时安装到共享模拟器环境,只有下载归档存放在私有目录。不会升级或删除已有运行时。Xcode 如需权限或首次初始化,须由你自行完成。",
|
|
32
|
-
"privateOwnership": "从 Google
|
|
34
|
+
"privateOwnership": "从 Google 下载固定版本的所选 Android AOSP 镜像、Platform-Tools 和 Emulator。SDK、虚拟设备数据、配置和临时文件保存在私有目录。虚拟设备中安装的应用属于用户数据。",
|
|
33
35
|
"appleLicense": "Apple 软件许可协议",
|
|
34
36
|
"androidLicense": "Android SDK 许可协议",
|
|
35
37
|
"acceptLicense": "我接受适用的组件许可协议",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/plugin-devices",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3908",
|
|
4
4
|
"description": "Lets agents drive iOS Simulators and Android Emulators on this machine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"android",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"tailwindcss": "^4.0.0",
|
|
35
35
|
"typescript": "~6.0.3",
|
|
36
36
|
"vite-plus": "0.2.2",
|
|
37
|
-
"ycodium-
|
|
38
|
-
"@ycodium-ai/plugin-api": "0.2.
|
|
39
|
-
"ycodium-
|
|
37
|
+
"ycodium-fetch-ports": "0.0.0",
|
|
38
|
+
"@ycodium-ai/plugin-api": "0.2.3908",
|
|
39
|
+
"ycodium-sse-stream": "0.0.0"
|
|
40
40
|
},
|
|
41
41
|
"ycodium": {
|
|
42
42
|
"plugin": "./dist/index.js",
|
|
@@ -21,7 +21,7 @@ Everything else goes through the `agent-device` command that `devices_device_ope
|
|
|
21
21
|
|
|
22
22
|
iOS Simulators need macOS with Xcode. On Windows and Linux, test Android and say that iOS was not run.
|
|
23
23
|
|
|
24
|
-
If no Android device exists, ask the user to choose **Prepare simulator environment** in the Devices panel. It downloads a private SDK and one API 35 emulator; it needs no system-wide install and takes several minutes.
|
|
24
|
+
If no Android device exists, ask the user to choose **Prepare simulator environment** in the Devices panel. It downloads a private SDK and one API 35 emulator; it needs no system-wide install and takes several minutes. The same panel adds an API 30 emulator when a task needs an older Android.
|
|
25
25
|
|
|
26
26
|
## Drive and inspect
|
|
27
27
|
|