@limrun/ui 0.18.2 → 0.20.0
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 +173 -0
- package/dist/{GLTFLoader-C62L6gT7.mjs → GLTFLoader-BjfxfJc4.mjs} +1 -1
- package/dist/{GLTFLoader--3fP8K2r.js → GLTFLoader-Ccp1cQVL.js} +1 -1
- package/dist/components/remote-control.d.ts +22 -68
- package/dist/core/device-stream.d.ts +30 -0
- package/dist/core/jitter-buffer.d.ts +2 -0
- package/dist/core/playback-stats.d.ts +48 -0
- package/dist/core/playback-subscription.d.ts +7 -0
- package/dist/core/stream-options.d.ts +62 -0
- package/dist/core/stream-types.d.ts +66 -0
- package/dist/core/stream-utils.d.ts +6 -0
- package/dist/core/use-playback-stats.d.ts +4 -0
- package/dist/core-BhHpU_lr.mjs +2113 -0
- package/dist/core-DkhLItUD.js +2 -0
- package/dist/core.cjs +1 -0
- package/dist/core.d.ts +12 -0
- package/dist/core.js +21 -0
- package/dist/{duo-frame-B6jf62Rq.mjs → duo-frame-CMiDITQA.mjs} +3 -3
- package/dist/{duo-frame-DAmRgZuT.js → duo-frame-D9832t6H.js} +2 -2
- package/dist/duo-view-Bhr7zyWr.js +1 -0
- package/dist/{duo-view-DSZO0-zg.mjs → duo-view-tndcvbIi.mjs} +64 -64
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -2
- package/dist/lite.cjs +1 -1
- package/dist/lite.d.ts +1 -0
- package/dist/lite.js +7 -6
- package/dist/remote-control-BBgt4TkM.mjs +1145 -0
- package/dist/remote-control-GLVdY8Xa.js +1 -0
- package/package.json +15 -5
- package/dist/duo-view-hTVLMDcc.js +0 -1
- package/dist/remote-control-B3_Hzmx8.js +0 -2
- package/dist/remote-control-BFxEfAdr.mjs +0 -2774
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const Ie={INJECT_KEYCODE:0,INJECT_TEXT:1,INJECT_TOUCH_EVENT:2,INJECT_TWO_FINGER_TOUCH_EVENT:18,INJECT_SCROLL_EVENT:3,BACK_OR_SCREEN_ON:4,EXPAND_NOTIFICATION_PANEL:5,EXPAND_SETTINGS_PANEL:6,COLLAPSE_PANELS:7,GET_CLIPBOARD:8,SET_CLIPBOARD:9,SET_DISPLAY_POWER:10,ROTATE_DEVICE:11},Ne={ACTION_DOWN:0,ACTION_UP:1,ACTION_MOVE:2,ACTION_CANCEL:3,ACTION_POINTER_DOWN:5,ACTION_POINTER_UP:6,BUTTON_PRIMARY:1,BUTTON_SECONDARY:2,BUTTON_TERTIARY:4},i={ACTION_DOWN:0,ACTION_UP:1,META_NONE:0,META_SHIFT_ON:1,META_ALT_ON:2,META_CTRL_ON:4096,META_META_ON:65536,KEYCODE_UNKNOWN:0,KEYCODE_SOFT_LEFT:1,KEYCODE_SOFT_RIGHT:2,KEYCODE_HOME:3,KEYCODE_BACK:4,KEYCODE_CALL:5,KEYCODE_ENDCALL:6,KEYCODE_0:7,KEYCODE_1:8,KEYCODE_2:9,KEYCODE_3:10,KEYCODE_4:11,KEYCODE_5:12,KEYCODE_6:13,KEYCODE_7:14,KEYCODE_8:15,KEYCODE_9:16,KEYCODE_STAR:17,KEYCODE_POUND:18,DPAD_UP:19,DPAD_DOWN:20,DPAD_LEFT:21,DPAD_RIGHT:22,KEYCODE_DPAD_CENTER:23,KEYCODE_VOLUME_UP:24,KEYCODE_VOLUME_DOWN:25,KEYCODE_POWER:26,KEYCODE_CAMERA:27,KEYCODE_CLEAR:28,KEYCODE_A:29,KEYCODE_B:30,KEYCODE_C:31,KEYCODE_D:32,KEYCODE_E:33,KEYCODE_F:34,KEYCODE_G:35,KEYCODE_H:36,KEYCODE_I:37,KEYCODE_J:38,KEYCODE_K:39,KEYCODE_L:40,KEYCODE_M:41,KEYCODE_N:42,KEYCODE_O:43,KEYCODE_P:44,KEYCODE_Q:45,KEYCODE_R:46,KEYCODE_S:47,KEYCODE_T:48,KEYCODE_U:49,KEYCODE_V:50,KEYCODE_W:51,KEYCODE_X:52,KEYCODE_Y:53,KEYCODE_Z:54,KEYCODE_COMMA:55,KEYCODE_PERIOD:56,KEYCODE_ALT_LEFT:57,KEYCODE_ALT_RIGHT:58,KEYCODE_SHIFT_LEFT:59,KEYCODE_SHIFT_RIGHT:60,KEYCODE_TAB:61,KEYCODE_SPACE:62,KEYCODE_SYM:63,KEYCODE_EXPLORER:64,KEYCODE_ENVELOPE:65,ENTER:66,DEL:67,KEYCODE_GRAVE:68,KEYCODE_MINUS:69,KEYCODE_EQUALS:70,KEYCODE_LEFT_BRACKET:71,KEYCODE_RIGHT_BRACKET:72,KEYCODE_BACKSLASH:73,KEYCODE_SEMICOLON:74,KEYCODE_APOSTROPHE:75,KEYCODE_SLASH:76,KEYCODE_AT:77,KEYCODE_NUM:78,KEYCODE_HEADSETHOOK:79,KEYCODE_FOCUS:80,KEYCODE_PLUS:81,MENU:82,KEYCODE_NOTIFICATION:83,KEYCODE_SEARCH:84,KEYCODE_MEDIA_PLAY_PAUSE:85,KEYCODE_MEDIA_STOP:86,KEYCODE_MEDIA_NEXT:87,KEYCODE_MEDIA_PREVIOUS:88,KEYCODE_MEDIA_REWIND:89,KEYCODE_MEDIA_FAST_FORWARD:90,KEYCODE_MUTE:91,KEYCODE_PAGE_UP:92,KEYCODE_PAGE_DOWN:93,KEYCODE_PICTSYMBOLS:94,KEYCODE_SWITCH_CHARSET:95,KEYCODE_BUTTON_A:96,KEYCODE_BUTTON_B:97,KEYCODE_BUTTON_C:98,KEYCODE_BUTTON_X:99,KEYCODE_BUTTON_Y:100,KEYCODE_BUTTON_Z:101,KEYCODE_BUTTON_L1:102,KEYCODE_BUTTON_R1:103,KEYCODE_BUTTON_L2:104,KEYCODE_BUTTON_R2:105,KEYCODE_BUTTON_THUMBL:106,KEYCODE_BUTTON_THUMBR:107,KEYCODE_BUTTON_START:108,KEYCODE_BUTTON_SELECT:109,KEYCODE_BUTTON_MODE:110,KEYCODE_ESCAPE:111,FORWARD_DEL:112,KEYCODE_CTRL_LEFT:113,KEYCODE_CTRL_RIGHT:114,KEYCODE_CAPS_LOCK:115,KEYCODE_SCROLL_LOCK:116,KEYCODE_META_LEFT:117,KEYCODE_META_RIGHT:118,KEYCODE_FUNCTION:119,KEYCODE_SYSRQ:120,KEYCODE_BREAK:121,KEYCODE_MOVE_HOME:122,KEYCODE_MOVE_END:123,KEYCODE_INSERT:124,KEYCODE_FORWARD:125,KEYCODE_MEDIA_PLAY:126,KEYCODE_MEDIA_PAUSE:127,KEYCODE_MEDIA_CLOSE:128,KEYCODE_MEDIA_EJECT:129,KEYCODE_MEDIA_RECORD:130,KEYCODE_F1:131,KEYCODE_F2:132,KEYCODE_F3:133,KEYCODE_F4:134,KEYCODE_F5:135,KEYCODE_F6:136,KEYCODE_F7:137,KEYCODE_F8:138,KEYCODE_F9:139,KEYCODE_F10:140,KEYCODE_F11:141,KEYCODE_F12:142,KEYCODE_NUM_LOCK:143,KEYCODE_NUMPAD_0:144,KEYCODE_NUMPAD_1:145,KEYCODE_NUMPAD_2:146,KEYCODE_NUMPAD_3:147,KEYCODE_NUMPAD_4:148,KEYCODE_NUMPAD_5:149,KEYCODE_NUMPAD_6:150,KEYCODE_NUMPAD_7:151,KEYCODE_NUMPAD_8:152,KEYCODE_NUMPAD_9:153,KEYCODE_NUMPAD_DIVIDE:154,KEYCODE_NUMPAD_MULTIPLY:155,KEYCODE_NUMPAD_SUBTRACT:156,KEYCODE_NUMPAD_ADD:157,KEYCODE_NUMPAD_DOT:158,KEYCODE_NUMPAD_COMMA:159,KEYCODE_NUMPAD_ENTER:160,KEYCODE_NUMPAD_EQUALS:161,KEYCODE_NUMPAD_LEFT_PAREN:162,KEYCODE_NUMPAD_RIGHT_PAREN:163,KEYCODE_VOLUME_MUTE:164,KEYCODE_INFO:165,KEYCODE_CHANNEL_UP:166,KEYCODE_CHANNEL_DOWN:167,KEYCODE_ZOOM_IN:168,KEYCODE_ZOOM_OUT:169,KEYCODE_TV:170,KEYCODE_WINDOW:171,KEYCODE_GUIDE:172,KEYCODE_DVR:173,KEYCODE_BOOKMARK:174,KEYCODE_CAPTIONS:175,KEYCODE_SETTINGS:176,KEYCODE_TV_POWER:177,KEYCODE_TV_INPUT:178,KEYCODE_STB_POWER:179,KEYCODE_STB_INPUT:180,KEYCODE_AVR_POWER:181,KEYCODE_AVR_INPUT:182,KEYCODE_PROG_RED:183,KEYCODE_PROG_GREEN:184,KEYCODE_PROG_YELLOW:185,KEYCODE_PROG_BLUE:186,KEYCODE_APP_SWITCH:187,KEYCODE_LANGUAGE_SWITCH:204,KEYCODE_ASSIST:219,KEYCODE_BRIGHTNESS_DOWN:220,KEYCODE_BRIGHTNESS_UP:221,KEYCODE_SLEEP:223,KEYCODE_WAKEUP:224,KEYCODE_SOFT_SLEEP:276},vt={KeyA:i.KEYCODE_A,KeyB:i.KEYCODE_B,KeyC:i.KEYCODE_C,KeyD:i.KEYCODE_D,KeyE:i.KEYCODE_E,KeyF:i.KEYCODE_F,KeyG:i.KEYCODE_G,KeyH:i.KEYCODE_H,KeyI:i.KEYCODE_I,KeyJ:i.KEYCODE_J,KeyK:i.KEYCODE_K,KeyL:i.KEYCODE_L,KeyM:i.KEYCODE_M,KeyN:i.KEYCODE_N,KeyO:i.KEYCODE_O,KeyP:i.KEYCODE_P,KeyQ:i.KEYCODE_Q,KeyR:i.KEYCODE_R,KeyS:i.KEYCODE_S,KeyT:i.KEYCODE_T,KeyU:i.KEYCODE_U,KeyV:i.KEYCODE_V,KeyW:i.KEYCODE_W,KeyX:i.KEYCODE_X,KeyY:i.KEYCODE_Y,KeyZ:i.KEYCODE_Z,Digit0:i.KEYCODE_0,Digit1:i.KEYCODE_1,Digit2:i.KEYCODE_2,Digit3:i.KEYCODE_3,Digit4:i.KEYCODE_4,Digit5:i.KEYCODE_5,Digit6:i.KEYCODE_6,Digit7:i.KEYCODE_7,Digit8:i.KEYCODE_8,Digit9:i.KEYCODE_9,Backquote:i.KEYCODE_GRAVE,Minus:i.KEYCODE_MINUS,Equal:i.KEYCODE_EQUALS,BracketLeft:i.KEYCODE_LEFT_BRACKET,BracketRight:i.KEYCODE_RIGHT_BRACKET,Backslash:i.KEYCODE_BACKSLASH,Semicolon:i.KEYCODE_SEMICOLON,Quote:i.KEYCODE_APOSTROPHE,Comma:i.KEYCODE_COMMA,Period:i.KEYCODE_PERIOD,Slash:i.KEYCODE_SLASH,Space:i.KEYCODE_SPACE,Tab:i.KEYCODE_TAB,Escape:i.KEYCODE_ESCAPE,ArrowUp:i.DPAD_UP,ArrowDown:i.DPAD_DOWN,ArrowLeft:i.DPAD_LEFT,ArrowRight:i.DPAD_RIGHT,Enter:i.ENTER,Backspace:i.DEL,Delete:i.FORWARD_DEL,Home:i.KEYCODE_MOVE_HOME,End:i.KEYCODE_MOVE_END,PageUp:i.KEYCODE_PAGE_UP,PageDown:i.KEYCODE_PAGE_DOWN,Insert:i.KEYCODE_INSERT,F1:i.KEYCODE_F1,F2:i.KEYCODE_F2,F3:i.KEYCODE_F3,F4:i.KEYCODE_F4,F5:i.KEYCODE_F5,F6:i.KEYCODE_F6,F7:i.KEYCODE_F7,F8:i.KEYCODE_F8,F9:i.KEYCODE_F9,F10:i.KEYCODE_F10,F11:i.KEYCODE_F11,F12:i.KEYCODE_F12,ShiftLeft:i.KEYCODE_SHIFT_LEFT,ShiftRight:i.KEYCODE_SHIFT_RIGHT,ControlLeft:i.KEYCODE_CTRL_LEFT,ControlRight:i.KEYCODE_CTRL_RIGHT,AltLeft:i.KEYCODE_ALT_LEFT,AltRight:i.KEYCODE_ALT_RIGHT,MetaLeft:i.KEYCODE_META_LEFT,MetaRight:i.KEYCODE_META_RIGHT,ContextMenu:i.MENU,Numpad0:i.KEYCODE_NUMPAD_0,Numpad1:i.KEYCODE_NUMPAD_1,Numpad2:i.KEYCODE_NUMPAD_2,Numpad3:i.KEYCODE_NUMPAD_3,Numpad4:i.KEYCODE_NUMPAD_4,Numpad5:i.KEYCODE_NUMPAD_5,Numpad6:i.KEYCODE_NUMPAD_6,Numpad7:i.KEYCODE_NUMPAD_7,Numpad8:i.KEYCODE_NUMPAD_8,Numpad9:i.KEYCODE_NUMPAD_9,NumpadDivide:i.KEYCODE_NUMPAD_DIVIDE,NumpadMultiply:i.KEYCODE_NUMPAD_MULTIPLY,NumpadSubtract:i.KEYCODE_NUMPAD_SUBTRACT,NumpadAdd:i.KEYCODE_NUMPAD_ADD,NumpadDecimal:i.KEYCODE_NUMPAD_DOT,NumpadComma:i.KEYCODE_NUMPAD_COMMA,NumpadEnter:i.KEYCODE_NUMPAD_ENTER,NumpadEqual:i.KEYCODE_NUMPAD_EQUALS};function Kt(t,e,n,s,E,d,c=1,m=0,C=0){const p=new ArrayBuffer(32),v=new DataView(p);let w=0;v.setUint8(w,Ie.INJECT_TOUCH_EVENT),w+=1;const k=t===Ne.ACTION_POINTER_DOWN?Ne.ACTION_DOWN:t===Ne.ACTION_POINTER_UP?Ne.ACTION_UP:t;return v.setUint8(w,k),w+=1,v.setBigInt64(w,BigInt(e),!0),w+=8,v.setInt32(w,Math.round(E),!0),w+=4,v.setInt32(w,Math.round(d),!0),w+=4,v.setUint16(w,n,!0),w+=2,v.setUint16(w,s,!0),w+=2,v.setInt16(w,Math.round(c*65535),!0),w+=2,v.setInt32(w,m,!0),w+=4,v.setInt32(w,C,!0),p}function Zt(t,e,n,s,E,d,c){const m=new ArrayBuffer(24),C=new DataView(m);let p=0;return C.setUint8(p,Ie.INJECT_TWO_FINGER_TOUCH_EVENT),p+=1,C.setUint8(p,t),p+=1,C.setInt32(p,Math.round(s),!0),p+=4,C.setInt32(p,Math.round(E),!0),p+=4,C.setInt32(p,Math.round(d),!0),p+=4,C.setInt32(p,Math.round(c),!0),p+=4,C.setUint16(p,e,!0),p+=2,C.setUint16(p,n,!0),p+=2,C.setUint16(p,0,!0),m}function Mt(t,e=!0){const s=new TextEncoder().encode(t),E=new ArrayBuffer(14+s.length),d=new DataView(E);let c=0;return d.setUint8(c,Ie.SET_CLIPBOARD),c+=1,d.setBigInt64(c,BigInt(0),!1),c+=8,d.setUint8(c,e?1:0),c+=1,d.setUint32(c,s.length,!1),c+=4,new Uint8Array(E,c).set(s),E}function Je(t,e,n=0,s=0){const E=new ArrayBuffer(14),d=new DataView(E);let c=0;return d.setUint8(c,Ie.INJECT_KEYCODE),c+=1,d.setUint8(c,t),c+=1,d.setInt32(c,e,!0),c+=4,d.setInt32(c,n,!0),c+=4,d.setInt32(c,s,!0),E}const en={width:164.6,height:117.8,depth:5.2};function tn(t,e,n){return t=Math.max(0,Math.min(1,t)),e=Math.max(0,Math.min(1,e)),n===1?{x:e,y:1-t}:n===2?{x:1-t,y:1-e}:n===3?{x:1-e,y:t}:{x:t,y:e}}function nn(t){return Number.isFinite(t)&&t>=0&&t<=180}function rn(t,e){return{x:Math.max(0,Math.min(1,t)),y:Math.max(0,Math.min(1,1-e))}}function on(t,e,n){return e&&(t||!n)?"touch":t?"ignore":"orbit"}function wt(t,e,n,s){if(!Number.isInteger(t)||t<0||t>3||!Number.isInteger(e)||e<1||e>255||!Number.isFinite(n)||!Number.isFinite(s)||n<0||n>1||s<0||s>1)throw new RangeError("Invalid display touch coordinates");const E=new ArrayBuffer(12),d=new DataView(E);return d.setUint8(0,19),d.setUint8(1,t),d.setUint8(2,e),d.setFloat32(4,n,!0),d.setFloat32(8,s,!0),E}class an{constructor(e,n){this.send=e,this.failed=n}send;failed;latest;running=!1;stopped=!1;set(e){this.stopped||!nn(e)||(this.latest=e,this.flush())}stop(){this.stopped=!0,this.latest=void 0}async flush(){if(!(this.running||this.stopped)){this.running=!0;try{for(;this.latest!==void 0&&!this.stopped;){const e=this.latest;this.latest=void 0,await this.send(e)}}catch(e){this.latest=void 0,this.stopped||this.failed(e)}finally{this.running=!1}}}}const sn={side:"Sleep/Wake",volumeUp:"Volume Up",volumeDown:"Volume Down"};class cn{constructor(e,n){this.send=e,this.failed=n}send;failed;held;tail=Promise.resolve();timeout;press(e){this.held||(this.held=e,this.enqueue(e,!0),this.timeout=setTimeout(()=>this.release(),1e4))}release(){if(!this.held)return;clearTimeout(this.timeout);const e=this.held;this.held=void 0,this.enqueue(e,!1)}enqueue(e,n){this.tail=this.tail.then(()=>this.send(e,n)).catch(this.failed)}}const je="Accessibility unavailable on this device.",Xe=500,Yt=(t,e)=>Math.abs(t.x-e.x)<.5&&Math.abs(t.y-e.y)<.5&&Math.abs(t.width-e.width)<.5&&Math.abs(t.height-e.height)<.5,ln=t=>Math.max(0,t.width)*Math.max(0,t.height),dn=t=>{const e=t.find(n=>n.frame&&n.frame.width>0&&n.frame.height>0);return e?.frame?((Math.abs(e.frame.x)>.5||Math.abs(e.frame.y)>.5)&&console.warn(`[ax-tree] iOS root frame is not anchored at (0,0): (${e.frame.x},${e.frame.y}). Element positions may be slightly off from the rendered video.`),{x:0,y:0,width:e.frame.width,height:e.frame.height}):{x:0,y:0,width:1,height:1}},un=t=>{const e={};return typeof t.AXUniqueId=="string"&&t.AXUniqueId.length>0&&(e.AXUniqueId=t.AXUniqueId),typeof t.AXLabel=="string"&&t.AXLabel.length>0&&(e.AXLabel=t.AXLabel),typeof t.type=="string"&&t.type.length>0&&(e.className=t.type),e},En=t=>{const e={};for(const[n,s]of Object.entries(t))n!=="children"&&(e[n]=s);return e};function bt(t){const e=Array.isArray(t)?t:[t],n=dn(e),s=[],E=(d,c)=>{if(s.length>=Xe)return;const m=d.frame;if(m&&m.width>0&&m.height>0&&!Yt(m,n)){const p=d.role_description||d.role||"",v=(typeof d.AXLabel=="string"?d.AXLabel:"")||(typeof d.title=="string"?d.title:"")||"";s.push({id:typeof d.AXUniqueId=="string"&&d.AXUniqueId.length>0?d.AXUniqueId:c,path:c,label:v,value:typeof d.AXValue=="string"?d.AXValue:"",role:p,type:typeof d.type=="string"?d.type:"",enabled:d.enabled!==!1,focused:d.focused===!0,frame:{x:m.x,y:m.y,width:m.width,height:m.height},selectors:un(d),raw:En(d)})}const C=Array.isArray(d.children)?d.children:[];for(let p=0;p<C.length&&s.length<Xe;p++)E(C[p],`${c}.${p}`)};for(let d=0;d<e.length&&s.length<Xe;d++)E(e[d],String(d));return{platform:"ios",screen:{width:n.width,height:n.height},elements:s,capturedAt:Date.now()}}const fn=t=>{let e={x:0,y:0,width:1,height:1},n=0;for(const s of t){const E=s.parsedBounds;if(!E)continue;const d=E.right-E.left,c=E.bottom-E.top,m=Math.max(0,d)*Math.max(0,c);m>n&&(n=m,e={x:0,y:0,width:d,height:c})}return e},mn=t=>{const e={};return typeof t.resourceId=="string"&&t.resourceId.length>0&&(e.resourceId=t.resourceId),typeof t.contentDesc=="string"&&t.contentDesc.length>0&&(e.contentDesc=t.contentDesc),typeof t.text=="string"&&t.text.length>0&&(e.text=t.text),typeof t.className=="string"&&t.className.length>0&&(e.className=t.className),e};function Nt(t){const e=fn(t),n=[];for(let s=0;s<t.length&&n.length<Xe;s++){const E=t[s],d=E.parsedBounds;if(!d)continue;const c=Math.max(0,d.right-d.left),m=Math.max(0,d.bottom-d.top);if(c<=0||m<=0)continue;const C={x:d.left,y:d.top,width:c,height:m};if(Yt(C,{x:0,y:0,width:e.width,height:e.height}))continue;const p=E.contentDesc||E.text||"",v=E.className||"";n.push({id:E.resourceId&&E.resourceId.length>0?E.resourceId:E.contentDesc&&E.contentDesc.length>0?`cd:${E.contentDesc}`:String(s),path:String(s),label:p,value:typeof E.text=="string"?E.text:"",role:v,type:v,enabled:E.enabled!==!1,focused:E.focused===!0,frame:C,selectors:mn(E),raw:{...E}})}return{platform:"android",screen:{width:e.width,height:e.height},elements:n,capturedAt:Date.now()}}function hn(t,e){const n=Math.max(0,t.x),s=Math.max(0,t.y),E=Math.min(e.width,t.x+t.width),d=Math.min(e.height,t.y+t.height),c=Math.max(0,E-n),m=Math.max(0,d-s);return c>0&&m>0?{x:n,y:s,width:c,height:m}:null}function Rt(t,e){if(t===e)return!0;if(t.id!==e.id||t.path!==e.path||t.label!==e.label||t.value!==e.value||t.role!==e.role||t.type!==e.type||t.enabled!==e.enabled||t.focused!==e.focused)return!1;const n=t.frame,s=e.frame;return n.x===s.x&&n.y===s.y&&n.width===s.width&&n.height===s.height}function It(t,e){if(t===e)return!0;if(!t||!e||t.platform!==e.platform||t.screen.width!==e.screen.width||t.screen.height!==e.screen.height||t.elements.length!==e.elements.length)return!1;for(let n=0;n<t.elements.length;n++)if(!Rt(t.elements[n],e.elements[n]))return!1;return!0}function pn(t,e,n){let s=null,E=1/0;for(const d of t.elements){const c=d.frame;if(e<c.x||n<c.y||e>c.x+c.width||n>c.y+c.height)continue;const m=ln(c);m<E&&(E=m,s=d)}return s}function Cn(t,e){if(e==="ios"){if(t.selectors.AXUniqueId)return`client.tapElement({ AXUniqueId: ${JSON.stringify(t.selectors.AXUniqueId)} })`;if(t.selectors.AXLabel){const n=t.selectors.className?`, type: ${JSON.stringify(t.selectors.className)}`:"";return`client.tapElement({ AXLabel: ${JSON.stringify(t.selectors.AXLabel)}${n} })`}return null}return t.selectors.resourceId?`client.tap({ selector: { resourceId: ${JSON.stringify(t.selectors.resourceId)} } })`:t.selectors.contentDesc?`client.tap({ selector: { contentDesc: ${JSON.stringify(t.selectors.contentDesc)} } })`:t.selectors.text?`client.tap({ selector: { text: ${JSON.stringify(t.selectors.text)} } })`:null}function Ut(t){const e=t.role||t.type||"";if(!e)return"element";let n=e.replace(/^AX/,"");return n.includes(".")&&(n=n.split(".").pop()),n==="GenericElement"?"Element":(n=n.replace(/([a-z])([A-Z])/g,"$1 $2"),n)}const Dt=80;function On(t){const e=Ut(t),n=t.label||t.value||"";if(!n)return e;const s=n.length>Dt?n.slice(0,Dt).trimEnd()+"…":n;return`${e} · ${s}`}const _n=500,Dn=2e3,gt=5e3,gn=8e3,Tn=1200,Sn=250,yn=()=>`ax-rc-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;class An{platform;send;onSnapshot;onStatusChange;baseIntervalMs;maxBackoffMs;androidElementTreeOptions;pending=new Map;running=!1;timer;currentInterval;lastSnapshot=null;inflight=!1;lastBumpAtMs=0;boostUntilMs=0;status="idle";constructor(e){this.platform=e.platform,this.send=e.send,this.onSnapshot=e.onSnapshot,this.onStatusChange=e.onStatusChange,this.baseIntervalMs=e.baseIntervalMs??_n,this.maxBackoffMs=e.maxBackoffMs??Dn,this.androidElementTreeOptions=e.androidElementTreeOptions,this.currentInterval=this.baseIntervalMs}start(){this.running||(this.running=!0,this.currentInterval=this.baseIntervalMs,this.boostUntilMs=0,this.setStatus("starting"),this.runOnce())}stop(){this.running&&(this.running=!1,this.timer!==void 0&&(window.clearTimeout(this.timer),this.timer=void 0),this.failAllPending("Inspector stopped"),this.lastSnapshot=null,this.setStatus("idle"),this.onSnapshot(null))}getStatus(){return this.status}setStatus(e,n){if(this.status!==e&&(this.status=e,!!this.onStatusChange))try{this.onStatusChange(e,n)}catch(s){console.error("[AxFetcher] onStatusChange threw:",s)}}bumpActivity(){if(!this.running)return;const e=Date.now();this.boostUntilMs=e+Tn;const n=Math.max(150,Math.floor(this.baseIntervalMs/2));if(e-this.lastBumpAtMs<n){this.currentInterval=this.baseIntervalMs;return}this.lastBumpAtMs=e,this.currentInterval=this.baseIntervalMs,this.timer!==void 0&&(window.clearTimeout(this.timer),this.timer=void 0),this.inflight||this.runOnce()}async refresh(){const e=await this.requestOnce();return this.running&&this.deliver(e),e}getLatest(){return this.lastSnapshot}handleMessage(e){if(!e||typeof e.id!="string")return!1;const n=e.id;if(!this.pending.get(n))return!1;if(this.platform==="ios"){if(e.type!=="elementTreeResult")return!1;const m=typeof e.error=="string"?e.error:null;if(m)return this.settleReject(n,new Error(m)),!0;const C=typeof e.json=="string"?e.json:"";try{const p=JSON.parse(C),v=bt(p);this.settleResolve(n,v)}catch(p){this.settleReject(n,p instanceof Error?p:new Error(String(p)))}return!0}if(e.type!=="getElementTreeResult")return!1;const E=e.error;if(E&&typeof E=="object"){const m=typeof E.message=="string"?E.message:"getElementTree failed";return this.settleReject(n,new Error(m)),!0}const d=e.payload,c=Array.isArray(d?.nodes)?d.nodes:[];try{const m=Nt(c);this.settleResolve(n,m)}catch(m){this.settleReject(n,m instanceof Error?m:new Error(String(m)))}return!0}buildRequest(e){return this.platform==="ios"?{type:"elementTree",id:e}:{type:"getElementTree",id:e,...this.androidElementTreeOptions}}async requestOnce(){const e=yn();return new Promise((n,s)=>{const E=window.setTimeout(()=>{this.pending.delete(e),s(new Error("elementTree request timed out"))},gn+(this.androidElementTreeOptions?.waitForIdleTimeoutMs??0));this.pending.set(e,{resolve:n,reject:s,timer:E}),this.send(this.buildRequest(e))||(window.clearTimeout(E),this.pending.delete(e),s(new Error("elementTree send failed (WebSocket not open)")))})}async runOnce(){if(this.running&&!this.inflight){this.inflight=!0;try{const e=await this.requestOnce();if(!this.running)return;this.deliver(e)}catch(e){if(!this.running)return;const n=e instanceof Error?e.message:String(e),s=/unavailable|not (yet )?running|failed|timeout/i.test(n);this.currentInterval=s?gt:Math.min(this.currentInterval*2,this.maxBackoffMs),this.setStatus(s?"unavailable":"error",n)}finally{this.inflight=!1,this.scheduleNext()}}}deliver(e){const n=this.lastSnapshot;if(It(n,e)){this.currentInterval=Math.min(this.currentInterval*2,this.maxBackoffMs),this.lastSnapshot=e,e.errors?.includes(je)||this.setStatus("ready");return}this.lastSnapshot=e,this.currentInterval=this.baseIntervalMs,e.errors?.includes(je)?(this.currentInterval=gt,this.setStatus("unavailable",je)):this.setStatus("ready"),this.onSnapshot(e)}scheduleNext(){if(!this.running)return;this.timer!==void 0&&window.clearTimeout(this.timer);const e=Date.now()<this.boostUntilMs?Math.min(Sn,this.currentInterval):this.currentInterval;this.timer=window.setTimeout(()=>{this.timer=void 0,this.runOnce()},e)}settleResolve(e,n){const s=this.pending.get(e);s&&(window.clearTimeout(s.timer),this.pending.delete(e),s.resolve(n))}settleReject(e,n){const s=this.pending.get(e);s&&(window.clearTimeout(s.timer),this.pending.delete(e),s.reject(n))}failAllPending(e){for(const[n,s]of this.pending.entries())window.clearTimeout(s.timer),s.reject(new Error(e)),this.pending.delete(n)}}function Tt(t,e){if(e!=null&&(!Number.isFinite(e)||e<0||e>4e3)){console.warn("RemoteControl: jitterBufferTargetMs must be a finite number between 0 and 4000.");return}if(!("jitterBufferTarget"in t))return;const n=e??null;try{t.jitterBufferTarget!==n&&(t.jitterBufferTarget=n)}catch(s){console.warn("RemoteControl: could not set the jitter buffer target.",s)}}const kt=`(function(){"use strict";let e,t;self.onmessage=async({data:s})=>{s.type==="start"?(e=new AbortController,t=s.readable.pipeTo(s.writable,{signal:e.signal}).catch(o=>{e?.signal.aborted||self.postMessage({type:"error",message:String(o)})})):s.type==="stop"&&(e?.abort(),await t,self.postMessage({type:"stopped"}),self.close())}})();
|
|
2
|
+
`,St=typeof self<"u"&&self.Blob&&new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);",kt],{type:"text/javascript;charset=utf-8"});function vn(t){let e;try{if(e=St&&(self.URL||self.webkitURL).createObjectURL(St),!e)throw"";const n=new Worker(e,{name:t?.name});return n.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(e)}),n}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(kt),{name:t?.name})}}function Kn(t,e,n){const{MediaStreamTrackProcessor:s,MediaStreamTrackGenerator:E}=globalThis,d=e.getVideoTracks()[0];let c,m,C,p,v=!1;const w=()=>{v||(v=!0,c?.stop(),m?.stop(),C&&(C.postMessage({type:"stop"}),p=setTimeout(()=>C?.terminate(),1e3)))},k=b=>{t.srcObject=b,t.play().catch(()=>{})},T=b=>{v||(w(),n(b),k(e))};try{if(d&&s&&E){c=d.clone();const b=new s({track:c,maxBufferSize:1}),V=new E({kind:"video"});m=V,C=new vn,C.onmessage=({data:F})=>{F.type==="error"?T(new Error(F.message)):F.type==="stopped"&&(clearTimeout(p),C?.terminate())},C.onerror=F=>T(new Error(F.message)),C.postMessage({type:"start",readable:b.readable,writable:V.writable},[b.readable,V.writable]),k(new MediaStream(e.getTracks().map(F=>F===d?V:F)))}else k(e)}catch(b){T(b)}return w}function Re(t){return typeof t=="number"&&Number.isFinite(t)}function ge(t,e){if(!(!Re(t)||!Re(e)||t<e||e<0))return t-e}class Mn{previous=new Map;reset(){this.previous.clear()}read(e,n,s){const E={timestamp:0,video:[],audio:[]};s==null?E.requestedTargetMs=null:Re(s)&&s>=0&&s<=4e3&&(E.requestedTargetMs=s);const d=new Map;return e.forEach(c=>{if(c.type!=="inbound-rtp"||!Re(c.timestamp))return;const m=c.kind??c.mediaType;if(m!=="video"&&m!=="audio")return;const C=n.filter(Y=>Y.kind===m),p=c.trackIdentifier?C.find(Y=>Y.trackId===c.trackIdentifier):c.mid!=null?C.find(Y=>Y.mid===c.mid):C.length===1?C[0]:void 0;if(!p)return;const v=this.previous.get(c.id),k=v?.trackId===p.trackId&&v.stats.ssrc===c.ssrc?v.stats:void 0,T=k?c.timestamp-k.timestamp:void 0,b={id:c.id,trackId:p.trackId,timestamp:c.timestamp};if(T!==void 0&&T>0){b.intervalMs=T;const Y=ge(c.jitterBufferEmittedCount,k?.jitterBufferEmittedCount),L=ge(c.jitterBufferDelay,k?.jitterBufferDelay);Y!==void 0&&Y>0&&L!==void 0&&(b.bufferDelayMs=L/Y*1e3);const $=ge(c.bytesReceived,k?.bytesReceived);$!==void 0&&(b.bitrateBps=$*8e3/T)}if(m==="video"){const Y={...b,display:p.display??"primary"};if(b.intervalMs!==void 0){const L=ge(c.framesDecoded,k?.framesDecoded);L!==void 0&&(Y.fps=L*1e3/b.intervalMs),Y.droppedFrames=ge(c.framesDropped,k?.framesDropped),Y.freezes=ge(c.freezeCount,k?.freezeCount)}E.video.push(Y)}else E.audio.push(b);E.timestamp=Math.max(E.timestamp,c.timestamp),d.set(c.id,k&&c.timestamp<=k.timestamp?v:{stats:c,trackId:p.trackId});const V=c.transportId?e.get(c.transportId):void 0,F=V?.selectedCandidatePairId?e.get(V.selectedCandidatePairId):void 0;F?.state==="succeeded"&&Re(F.currentRoundTripTime)&&F.currentRoundTripTime>=0&&(E.rttMs=F.currentRoundTripTime*1e3)}),this.previous=d,E.video.length||E.audio.length?E:null}}const it=new WeakSet;function wn(t,e,n){const{peer:s,displays:E}=t,d=new Mn;let c,m=!1,C=!1,p=!1,v=0,w=!1,k=!1;const T=()=>!m&&!document.hidden&&s.connectionState==="connected",b=L=>{if(!(!L&&!w)){w=L!==null;try{e()?.(L)}catch($){console.error('[RemoteControl] customer callback "onPlaybackStats" threw:',$)}}},V=()=>{C=!1,v++,clearTimeout(c),d.reset(),b(null)},F=async()=>{if(p||!T())return;if(it.has(s)){c=setTimeout(()=>{F()},2e3);return}p=!0,it.add(s);const L=v;try{const $=await s.getStats();if(L!==v||!T())return;const B=s.getTransceivers().filter(J=>(J.currentDirection==="recvonly"||J.currentDirection==="sendrecv")&&J.receiver.track.readyState!=="ended").map(J=>({trackId:J.receiver.track.id,kind:J.receiver.track.kind,mid:J.mid,display:E.get(J.receiver)}));b(d.read($,B,n())),k=!1}catch($){if(L!==v||!T())return;k||console.warn("[RemoteControl] could not read playback stats:",$),k=!0,d.reset(),b(null)}finally{p=!1,it.delete(s),C&&T()&&(c=setTimeout(()=>{F()},L===v?2e3:0))}},Y=()=>{if(!T()){V();return}C||(C=!0,F())};return document.addEventListener("visibilitychange",Y),s.addEventListener("connectionstatechange",Y),Y(),()=>{m=!0,document.removeEventListener("visibilitychange",Y),s.removeEventListener("connectionstatechange",Y),V()}}function Yn(t,e){const n=t.createDataChannel("latency-trace-v1",{ordered:!0,negotiated:!0,id:2});let s=!1,E=!1,d=0;return n.onmessage=c=>{if(E)return;let m;try{m=JSON.parse(c.data)}catch(C){console.warn("Invalid latency trace message",C);return}m&&typeof m=="object"&&!Array.isArray(m)&&e(m)},n.onclose=()=>{E=!0,s=!1},{accept(c){s=!E&&c===1},wrap(c){if(!s||c.byteLength!==32)return c;const m=new DataView(c);if(m.getUint8(0)!==2||m.getUint8(1)>2)return c;const C=new ArrayBuffer(38),p=new DataView(C);return p.setUint8(0,240),p.setUint8(1,1),p.setUint32(2,++d,!0),new Uint8Array(C,6).set(new Uint8Array(c)),C},close(){E=!0,s=!1,n.onmessage=null,n.onclose=null,n.close()}}}class bn{generation=0;tail=Promise.resolve();get currentGeneration(){return this.generation}enqueue(e){const n=++this.generation;return this.append(n,e)}enqueueCurrent(e){return this.append(this.generation,e)}append(e,n){const s={generation:e,isCurrent:()=>e===this.generation},E=this.tail.then(()=>n(s));return this.tail=E.catch(()=>{}),E}invalidate(){++this.generation}}function Nn(t){if(!t||typeof t!="object")return null;const e=t;if(e.type!=="cameraRequest"||typeof e.active!="boolean")return null;const n={active:e.active};return(e.facingMode==="user"||e.facingMode==="environment")&&(n.facingMode=e.facingMode),n}function Rn(t){const e={frameRate:{ideal:30,max:30}};return t?.facingMode&&(e.facingMode={ideal:t.facingMode}),e}function In(t,e){return!t||t.facingMode!==e.facingMode}function Un(t){const e=t.getSettings();return{width:e.width,height:e.height,frameRate:e.frameRate,deviceId:e.deviceId,label:t.label||void 0,facingMode:e.facingMode}}function kn(t){return{type:"cameraResult",granted:!0,camera:Un(t)}}const ae=(...t)=>{window.debugRemoteControl&&console.log(...t)},S=(...t)=>{window.debugRemoteControl&&console.warn(...t)},P=(t,e,...n)=>{if(e)try{e(...n)}catch(s){console.error(`[RemoteControl] customer callback "${t}" threw:`,s)}},Pt=t=>t.includes("/android_")?"android":"ios",yt=(t,e)=>{const n=new URL(t);return n.searchParams.set("token",e),n.toString()},ot=3,Pn=1e3,Ln=15e3,Fn=3e3,Bn=4e3;function At(){const t=crypto.getRandomValues(new Uint8Array(16));t[6]=t[6]&15|64,t[8]=t[8]&63|128;const e=Array.from(t,n=>n.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`}function xn(t){let e={...t};const{url:n,token:s,deviceModel:E}=e,d=e.sessionId??At(),c=e.platform??Pt(n??"");let m={connection:"idle",videoReady:!1,controlReady:!1,duo:!1,duoState:null};const C=r=>{m={...m,...r},P("onStateChange",e.onStateChange,m)},p=r=>C({videoReady:r}),v=r=>C({duoState:r}),w=r=>C({duoError:r}),k=r=>C({duo:r}),T=r=>ae(r);let b=null,V;const F=()=>{V?.(),V=b&&e.onPlaybackStats?wn(b,()=>e.onPlaybackStats,()=>e.jitterBufferTargetMs):void 0},Y=new Map,L=new Set,$=new Set,B=new Map;let J=!1;const Ue=new Map,at=(r,u,a)=>{u.stop?.(),u.stop=Kn(r,a,l=>S("Video playback fallback:",l))},Lt=()=>{Ue.clear();for(const[r,u]of Y)u.clear?.(),u.stop?.(),u.stop=void 0,r.srcObject=null};let Ee=!1,Te=!1,ke=0,D=null,N=null,x=null,Pe=null,fe,Se,ye,Le,me,le=0,Fe=0,ne=!1,de=null,z=null,ue;const Qe=new bn;let Ae=null,Be=null,ze=e.microphoneEnabled??!1,Ze=!1,ve=null,te=null,xe=0,st=Promise.resolve(),he=null,Ke=!1,re=new Map,ee=new Map,se=new Map,ie=new Map,q=null,Me=null,ct=0;const We=r=>{if(r===null&&Me===null)return;Me=r;const u=++ct;queueMicrotask(()=>{u===ct&&P("onAxSnapshotChange",e.onAxSnapshotChange,r)})};let pe=null,Ce=new Map;const Ft=(r,u)=>new Promise((a,l)=>{const y=D;if(!y||y.readyState!==WebSocket.OPEN){l(new Error("Simulator disconnected"));return}const h=At(),O=setTimeout(()=>{Ce.delete(h),l(new Error("Device control timed out"))},5e3);Ce.set(h,{resolve:a,reject:l,timer:O}),y.send(JSON.stringify({type:r,id:h,...u}))}),Oe=r=>{pe!==r&&(pe=r,C({connection:r}),P("onConnectionStateChange",e.onConnectionStateChange,r))},ce=r=>{!x||x.readyState!=="open"||(x.send(Pe?.wrap(r)??r),q?.bumpActivity())},Bt=()=>{D&&D.readyState===WebSocket.OPEN&&D.send(JSON.stringify({type:"keepAlive",sessionId:d}))},lt=()=>{fe&&window.clearInterval(fe),fe=window.setInterval(Bt,1e4)},we=()=>{fe&&(window.clearInterval(fe),fe=void 0)},qe=()=>{Se&&(window.clearTimeout(Se),Se=void 0)},Ve=()=>{ye&&(window.clearTimeout(ye),ye=void 0)},Ye=()=>{Le&&(window.clearInterval(Le),Le=void 0)},be=()=>{me!==void 0&&(window.clearTimeout(me),me=void 0)},xt=()=>{Ke||(Ke=!0,Ye(),p(!0),Oe("connected"))},H=r=>{for(const u of r.getTracks())try{u.stop()}catch(a){S("track.stop() failed:",a)}},Wt=()=>{const r=z;r&&(z=null,H(r))},dt=r=>{const u=st.then(r).catch(a=>{S("microphone operation failed:",a)});return st=u,u},et=()=>ze||Ze,ut=r=>{const u=`ui-mic-${Date.now()}-${Math.random().toString(36).substring(2,9)}`;he=u,r.send(JSON.stringify({type:"microphoneStart",id:u}))},tt=()=>dt(()=>qt()),qt=async()=>{const r=xe,u=()=>r===xe&&et(),a=f=>{P("onMicrophoneStateChange",e.onMicrophoneStateChange,{active:!1,error:f})};if(!u())return;const l=D,y=ve;if(!l||l.readyState!==WebSocket.OPEN||!y||te)return;if(!navigator.mediaDevices||typeof navigator.mediaDevices.getUserMedia!="function"){console.warn("[RemoteControl] navigator.mediaDevices.getUserMedia unavailable. getUserMedia requires a secure context (https or http://localhost)."),a("Microphone capture requires a secure context (https)");return}let h=null;try{h=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1})}catch(f){console.warn("[RemoteControl] microphone getUserMedia denied/failed:",f)}if(!u()){h&&H(h);return}if(!h){a("Microphone permission denied or no device available");return}const O=h.getAudioTracks()[0]??null;if(!O){H(h),a("Captured stream has no audio track");return}try{await y.replaceTrack(O)}catch(f){S("replaceTrack(audioTrack) failed:",f),H(h),a("Failed to attach the microphone track to the connection");return}if(!u()){try{await y.replaceTrack(null)}catch(f){S("replaceTrack(null) on stale mic attach failed:",f)}H(h);return}te=h,O.onended=()=>{te===h&&$e("microphone capture ended by the browser")},ut(l),P("onMicrophoneStateChange",e.onMicrophoneStateChange,{active:!0,label:O.label||void 0})},$e=r=>(++xe,he=null,dt(async()=>{const u=ve,a=te;if(te=null,u&&a)try{await u.replaceTrack(null)}catch(y){S("replaceTrack(null) on mic detach failed:",y)}a&&H(a);const l=D;if(a&&l&&l.readyState===WebSocket.OPEN){const y=`ui-mic-${Date.now()}-${Math.random().toString(36).substring(2,9)}`;l.send(JSON.stringify({type:"microphoneStop",id:y}))}(a||r)&&P("onMicrophoneStateChange",e.onMicrophoneStateChange,{active:!1,...r!==void 0&&{error:r}})})),Et=(r,u)=>{let a;try{a=kn(u),console.info(`[RemoteControl] camera capture: ${a.camera?.width}x${a.camera?.height} @ ${a.camera?.frameRate??"?"}fps`+(a.camera?.label?` — ${a.camera.label}`:""))}catch(l){S("getSettings() on outbound camera track failed:",l),a={type:"cameraResult",granted:!0,camera:{label:u.label||void 0}}}r.send(JSON.stringify(a)),P("onCameraDemandChange",e.onCameraDemandChange,!0,!0,a.camera)},Vt=r=>{if(!r)return;const u=r.indexOf("/"),l=(u>=0?r.slice(u+1):r).toUpperCase();return l==="HEVC"?"H265":l},$t=async()=>{const r=de,u=e.onCameraStats;if(!r||!u)return;let a;try{a=await r.getStats()}catch{return}let l,y,h;if(a.forEach(R=>{R.type==="outbound-rtp"&&R.kind==="video"?l=R:R.type==="remote-inbound-rtp"&&R.kind==="video"&&(h=R)}),l?.codecId){const R=a.get(l.codecId);R&&(y=R.mimeType)}if(!l)return;const O=l.timestamp??Date.now(),f=Be;let j,U,X;if(f&&O>f.timestamp){const R=(O-f.timestamp)/1e3;if(typeof l.framesEncoded=="number"&&typeof f.framesEncoded=="number"&&(j=Math.max(0,(l.framesEncoded-f.framesEncoded)/R)),typeof l.bytesSent=="number"&&typeof f.bytesSent=="number"&&(U=Math.max(0,(l.bytesSent-f.bytesSent)*8/R)),typeof l.packetsSent=="number"&&typeof f.packetsSent=="number"&&h&&typeof h.packetsLost=="number"&&typeof f.packetsLost=="number"){const A=l.packetsSent-f.packetsSent,Ge=h.packetsLost-f.packetsLost;A>0&&(X=Math.max(0,Math.min(100,Ge/A*100)))}}Be={timestamp:O,framesEncoded:l.framesEncoded,bytesSent:l.bytesSent,packetsSent:l.packetsSent,packetsLost:h?.packetsLost};const M={codec:Vt(y),encoderImplementation:l.encoderImplementation,hardwareAccelerated:typeof l.powerEfficientEncoder=="boolean"?l.powerEfficientEncoder:void 0,framesPerSecond:j,framesEncoded:l.framesEncoded,bitrateBps:U,width:l.frameWidth,height:l.frameHeight,qualityLimitationReason:l.qualityLimitationReason,rttMs:typeof h?.roundTripTime=="number"?h.roundTripTime*1e3:void 0,packetsLostPct:X};P("onCameraStats",e.onCameraStats,M)},ft=()=>{Ae===null&&(Be=null,Ae=setInterval(()=>{$t()},1e3))},He=()=>{Ae!==null&&(clearInterval(Ae),Ae=null),Be=null,P("onCameraStats",e.onCameraStats,null)},Ht=(r,u,a,l)=>Qe.enqueue(async({isCurrent:y})=>{const h=()=>y()&&l()&&D===u&&de===a;if(!h())return;if(!r.active){const M=z;try{await a.replaceTrack(null)}catch(R){S("replaceTrack(null) on camera detach failed:",R)}if(z===M&&(z=null,ue=void 0,M&&H(M)),He(),!h())return;P("onCameraDemandChange",e.onCameraDemandChange,!1);return}P("onCameraDemandChange",e.onCameraDemandChange,!0);const O=z,f=O?.getVideoTracks()[0],j=ue;if(f?.readyState==="live"&&j&&!In(j,r)){ue=r,Et(u,f),ft();return}if(O){try{await a.replaceTrack(null)}catch(M){S("replaceTrack(null) before camera switch failed:",M)}if(z===O&&(z=null,ue=void 0,H(O)),He(),!h())return}if(!navigator.mediaDevices||typeof navigator.mediaDevices.getUserMedia!="function"){if(console.warn("[RemoteControl] navigator.mediaDevices.getUserMedia unavailable. getUserMedia requires a secure context (https or http://localhost). Replying cameraResult granted=false so limulator falls back to black frames."),!h())return;u.send(JSON.stringify({type:"cameraResult",granted:!1})),P("onCameraDemandChange",e.onCameraDemandChange,!0,!1);return}let U=null;try{U=await navigator.mediaDevices.getUserMedia({video:Rn(r),audio:!1})}catch(M){console.warn("[RemoteControl] getUserMedia denied/failed:",M)}if(!h()){U&&H(U);return}if(!U){u.send(JSON.stringify({type:"cameraResult",granted:!1})),P("onCameraDemandChange",e.onCameraDemandChange,!0,!1);return}const X=U.getVideoTracks()[0]??null;if(!X){if(H(U),!h())return;u.send(JSON.stringify({type:"cameraResult",granted:!1})),P("onCameraDemandChange",e.onCameraDemandChange,!0,!1);return}try{X.contentHint="motion"}catch{}try{await a.replaceTrack(X)}catch(M){if(S("replaceTrack(videoTrack) failed:",M),H(U),!h())return;u.send(JSON.stringify({type:"cameraResult",granted:!1})),P("onCameraDemandChange",e.onCameraDemandChange,!0,!1);return}if(!h()){try{await a.replaceTrack(null)}catch(M){S("replaceTrack(null) for stale camera attach failed:",M)}H(U);return}try{const M=a.getParameters();(!M.encodings||M.encodings.length===0)&&(M.encodings=[{}]),M.encodings[0].maxBitrate=8e6,M.encodings[0].maxFramerate=30,M.degradationPreference="maintain-framerate",await a.setParameters(M)}catch(M){S("setParameters on outbound camera failed:",M)}if(!h()){try{await a.replaceTrack(null)}catch(M){S("replaceTrack(null) for stale camera finalize failed:",M)}H(U);return}z=U,ue=r,X.onended=()=>{z===U&&Qe.enqueueCurrent(async({isCurrent:M})=>{if(!(!M()||z!==U||!l()||D!==u||de!==a)){try{await a.replaceTrack(null)}catch(R){S("replaceTrack(null) after camera ended failed:",R)}!M()||z!==U||!l()||D!==u||de!==a||(z=null,ue=void 0,H(U),He(),u.send(JSON.stringify({type:"cameraResult",granted:!1})),P("onCameraDemandChange",e.onCameraDemandChange,!0,!1))}}).catch(M=>S("camera ended cleanup failed:",M))},h()&&(Et(u,X),ft())}),_e=()=>{for(const r of $)r();$.clear();for(const r of B.values())clearTimeout(r);B.clear();for(const r of ee.values())r(new Error("Simulator disconnected"));for(const r of ie.values())r(new Error("Simulator disconnected"));ee.clear(),re.clear(),ie.clear(),se.clear(),V?.(),V=void 0,Lt(),b=null;for(const r of Ce.values())clearTimeout(r.timer),r.reject(new Error("Simulator disconnected"));Ce.clear(),v(null),C({controlReady:!1,videoReady:!1}),Ve(),be(),Ye(),q&&(q.stop(),q=null),Me!==null&&We(null),Qe.invalidate(),He(),Wt(),ue=void 0,de=null,++xe,Ze=!1,he=null,te&&(H(te),te=null,P("onMicrophoneStateChange",e.onMicrophoneStateChange,{active:!1})),ve=null,D&&(D.onopen=null,D.onmessage=null,D.onerror=null,D.onclose=null,D.close(),D=null),Pe?.close(),Pe=null,N&&(N.onconnectionstatechange=null,N.oniceconnectionstatechange=null,N.ontrack=null,N.onicecandidate=null,N.close(),N=null),x&&(x.onopen=null,x.onclose=null,x.onerror=null,x.close(),x=null)},mt=()=>{document.hidden?we():lt()},Gt=async()=>{if(e.transport)return e.transport.isTerminated?.()??!1;if(typeof navigator<"u"&&navigator.onLine===!1)return!1;let r;try{const l=new URL(n);l.protocol=l.protocol==="wss:"?"https:":l.protocol==="ws:"?"http:":l.protocol,r=yt(l.toString(),s)}catch{return!1}const u=new AbortController,a=window.setTimeout(()=>u.abort(),Bn);try{return(await fetch(r,{method:"GET",cache:"no-store",signal:u.signal})).status===404}catch{return!1}finally{window.clearTimeout(a)}},Jt=()=>{Ee||(Ee=!0,le+=1,qe(),Ve(),be(),_e(),T("Instance terminated"),we(),Oe("terminated"),P("onTerminated",e.onTerminated))},jt=()=>{if(Ee||Te)return;Te=!0;const r=ke;Gt().catch(()=>!1).then(u=>{r===ke&&(Te=!1,u&&Jt())})},De=(r,u)=>{if(Ee||u!==le)return;if(jt(),ne){if(!e.autoReconnect){T(`Connection failed after it was established: ${r}`),we(),Oe("failed"),_e();return}T(`Reconnecting after established session dropped: ${r}`),ne=!1,Fe=-1}qe();const a=Fe+1;if(a>=ot){T(`Connection failed after ${ot} attempts: ${r}`),we(),Oe("failed"),_e();return}T(`Retrying connection (${a+1}/${ot})`),Oe("reconnecting"),_e(),Se=window.setTimeout(()=>{Se=void 0,u===le&&ht(a)},Pn)},ht=async(r=0)=>{const{openUrl:u,axPollIntervalMs:a,axMaxBackoffMs:l,androidElementTreeOptions:y}=e;if(Ee)return;const h=le+1;le=h,Fe=r,ne=!1,r===0&&pe!=="reconnecting"&&Oe("connecting"),qe(),Ve(),Ye(),Ke=!1,p(!1),_e();const O=()=>h===le;ye=window.setTimeout(()=>{ye=void 0,!(!O()||ne)&&De("Connection did not succeed within 15 seconds",h)},Ln);try{const f=e.transport?await e.transport.connect():new WebSocket(yt(n,s));if(!O()){f.close();return}if(D=f,await new Promise((_,o)=>{let I=!1;const W=()=>K(()=>o(new Error("Connection stopped")));$.add(W);const g=window.setTimeout(()=>K(()=>o(new Error("WebSocket connection timeout"))),3e4),K=Z=>{I||(I=!0,$.delete(W),window.clearTimeout(g),Z())};f.onopen=()=>{!O()||D!==f||K(_)},f.onerror=Z=>{!O()||D!==f||(T("WebSocket error: "+Z),K(()=>o(new Error("WebSocket connection failed"))))},f.onclose=()=>{!O()||D!==f||(T("WebSocket closed"),K(()=>o(new Error("WebSocket closed before connection was established"))))},f.readyState===WebSocket.OPEN?K(_):f.readyState!==WebSocket.CONNECTING&&K(()=>o(new Error("WebSocket is closed")))}),!O()||D!==f)return;f.onerror=_=>{!O()||D!==f||T("WebSocket error: "+_)},f.onclose=()=>{!O()||D!==f||T("WebSocket closed")};const j=new Promise((_,o)=>{let I=!1;const W=()=>g(()=>o(new Error("Connection stopped")));$.add(W);const g=G=>{I||(I=!0,$.delete(W),window.clearTimeout(K),f.removeEventListener("message",Z),G())},K=window.setTimeout(()=>g(()=>o(new Error("RTCConfiguration timeout"))),3e4),Z=G=>{if(!(!O()||D!==f))try{const Q=JSON.parse(G.data);if(Q.type==="signalingError"&&Q.requestType==="requestRtcConfiguration"&&Q.sessionId===d){const zt=typeof Q.error=="string"?Q.error:"Unable to load streaming configuration";g(()=>o(new Error(zt)))}else Q.type==="rtcConfiguration"&&g(()=>_({rtcConfiguration:Q.rtcConfiguration,cameraSupported:Q.cameraSupported===!0,foldSupported:Q.foldSupported===!0}))}catch(Q){console.error("Error handling RTC configuration:",Q),g(()=>o(Q))}};f.addEventListener("message",Z),f.send(JSON.stringify({type:"requestRtcConfiguration",sessionId:d}))}),{rtcConfiguration:U,cameraSupported:X,foldSupported:M}=await j;if(!O()||D!==f)return;const R=E==="iphone-duo"||M;k(R);const A=new RTCPeerConnection({...U,iceTransportPolicy:"relay"});N=A;const Ge={peer:A,displays:new Map};b=Ge,F(),A.addTransceiver("audio",{direction:"recvonly"});const Xt=A.addTransceiver("video",{direction:"recvonly"}),Qt=R?A.addTransceiver("video",{direction:"recvonly"}):null,_t=c==="ios"||X,nt=_t?A.addTransceiver("video",{direction:"sendonly"}):null;if(de=nt?.sender??null,ve=(_t?A.addTransceiver("audio",{direction:"sendonly"}):null)?.sender??null,RTCRtpReceiver.getCapabilities){const _=RTCRtpReceiver.getCapabilities("video");if(_&&_.codecs){const I=_.codecs.sort((W,g)=>{const K=Z=>{const G=Z.mimeType.toLowerCase();return G.includes("vp9")?1:G.includes("h265")||G.includes("hevc")?2:G.includes("h264")||G.includes("avc")?3:4};return K(W)-K(g)});Xt.setCodecPreferences(I),Qt?.setCodecPreferences(I),ae("Set codec preferences:",I.map(W=>W.mimeType).join(", "))}}if(nt&&RTCRtpSender.getCapabilities){const _=RTCRtpSender.getCapabilities("video");if(_&&_.codecs){const o=new Set(["42e01f","42e028","640c1f"]),I=g=>{const K=g.mimeType.toLowerCase(),G=(g.sdpFmtpLine||"").toLowerCase().match(/profile-level-id=([0-9a-f]{6})/),Q=G?G[1]:"";return K==="video/h265"||K==="video/hevc"?1:K==="video/h264"&&o.has(Q)?2:K==="video/h264"?3:K==="video/vp9"?4:K==="video/vp8"?5:K==="video/rtx"||K==="video/red"||K==="video/ulpfec"?0:6},W=[..._.codecs].sort((g,K)=>I(g)-I(K));try{nt.setCodecPreferences(W),ae("Outbound camera codec preferences:",W.map(g=>`${g.mimeType}${g.sdpFmtpLine?`[${g.sdpFmtpLine}]`:""}`).join(", "))}catch(g){S("Failed to set outbound camera codec preferences:",g)}}}const oe=A.createDataChannel("control",{ordered:!0,negotiated:!0,id:1});x=oe;const rt=!R&&e.onTrace?Yn(A,_=>{O()&&N===A&&P("onTrace",e.onTrace,_)}):null;if(Pe=rt,oe.onopen=()=>{if(!O()||x!==oe||D!==f)return;ne=!0,C({controlReady:!0}),Ve(),T("Control channel opened"),R&&f.send(JSON.stringify({type:"getFoldState",id:"duo-capabilities"})),q||(q=new An({platform:c,baseIntervalMs:a,maxBackoffMs:l,androidElementTreeOptions:y,send:o=>{if(!D||D.readyState!==WebSocket.OPEN)return!1;try{return D.send(JSON.stringify(o)),!0}catch{return!1}},onSnapshot:We,onStatusChange:(o,I)=>{P("onAxStatusChange",e.onAxStatusChange,o,I)}}),(e.inspectMode===!0||e.inspectMode==="hover-only")&&q.start());const _=()=>{!O()||Ke||x!==oe||D!==f||f.readyState!==WebSocket.OPEN||f.send(JSON.stringify({type:"requestFrame",sessionId:d}))};if(_(),Ye(),Le=window.setInterval(()=>{if(!O()||Ke||x!==oe||D!==f||f.readyState!==WebSocket.OPEN){Ye();return}_()},250),u){try{const o=decodeURIComponent(u);T("Opening URL"),f.send(JSON.stringify({type:"openUrl",url:o,sessionId:d}))}catch(o){console.error({error:o},"Error decoding URL, falling back to the original URL"),f.send(JSON.stringify({type:"openUrl",url:u,sessionId:d}))}q?.bumpActivity()}},oe.onclose=()=>{!O()||x!==oe||(C({controlReady:!1}),T("Control channel closed"))},oe.onerror=_=>{!O()||x!==oe||(console.error("Control channel error:",_),T("Control channel error: "+_))},A.onconnectionstatechange=()=>{!O()||N!==A||(T("Connection state: "+A.connectionState),A.connectionState==="failed"&&ne&&De("WebRTC connection entered failed state",h))},A.oniceconnectionstatechange=()=>{if(!O()||N!==A)return;const _=A.iceConnectionState;if(T("ICE state: "+_),_==="connected"||_==="completed"){be(),et()&&!te&&tt();return}if(_==="failed"){be(),ne&&De("ICE connection entered failed state",h);return}_==="disconnected"&&ne&&e.autoReconnect&&me===void 0&&(me=window.setTimeout(()=>{me=void 0,!(!O()||N!==A)&&A.iceConnectionState==="disconnected"&&De("ICE stayed disconnected past grace period",h)},Fn))},A.ontrack=_=>{if(!O()||N!==A)return;Tt(_.receiver,e.jitterBufferTargetMs);const o=_.track.id==="duo-inner"||_.streams.some(I=>I.id==="duo-inner");if(_.track.kind==="video"&&Ge.displays.set(_.receiver,o?"inner":"primary"),T("Received remote track: "+_.track.kind),_.track.kind==="video"){const I=o?"inner":"primary",W=R?new MediaStream([_.track]):_.streams[0]??new MediaStream([_.track]);Ue.set(I,W);for(const[g,K]of Y)K.display===I&&at(g,K,W)}},A.onicecandidate=_=>{if(!(!O()||N!==A||D!==f))if(_.candidate&&f.readyState===WebSocket.OPEN){const o={type:"candidate",candidate:_.candidate.candidate,sdpMid:_.candidate.sdpMid,sdpMLineIndex:_.candidate.sdpMLineIndex,sessionId:d};f.send(JSON.stringify(o)),T("Sent ICE candidate")}else T("ICE candidate gathering completed")},f.onmessage=async _=>{if(!O()||D!==f)return;let o;try{o=JSON.parse(_.data)}catch(I){S("Error parsing message:",I);return}if(!q?.handleMessage(o))switch(T("Received: "+o.type),o.type){case"performActionsResult":case"foldStateResult":case"foldStateChanged":{if(!R)break;o.state?(v(o.state),w(void 0)):o.id==="duo-capabilities"&&w(o.error||"This instance does not support native iPhone Duo displays.");const g=Ce.get(o.id);g&&(clearTimeout(g.timer),Ce.delete(o.id),o.error?g.reject(new Error(o.error)):g.resolve());break}case"signalingError":{if(o.requestType!=="offer"||o.sessionId!==d)break;const g=typeof o.error=="string"?o.error:"Unable to establish the streaming connection";T("Error: "+g),De(g,h);break}case"answer":if(!N||N!==A){T("No peer connection, skipping answer");break}if(rt?.accept(o.latencyTraceVersion),await A.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:o.sdp})),!O()||N!==A)return;T("Set remote description");break;case"candidate":if(!N||N!==A){T("No peer connection, skipping candidate");break}if(await A.addIceCandidate(new RTCIceCandidate({candidate:o.candidate,sdpMid:o.sdpMid,sdpMLineIndex:o.sdpMLineIndex})),!O()||N!==A)return;T("Added ICE candidate");break;case"screenshot":case"screenshotResult":{if(typeof o.id!="string"){S("Received invalid screenshot success message:",o);break}const g=Wn(o);if(g){const G=ee.get(o.id);if(typeof G!="function"){S(`Received screenshot error for unknown or handled id: ${o.id}`);break}S(`Received screenshot error for id ${o.id}: ${g}`),G(new Error(g)),re.delete(o.id),ee.delete(o.id),clearTimeout(B.get(o.id)),B.delete(o.id);break}const K=qn(o);if(!K){S("Received screenshot message without image data:",o);break}const Z=re.get(o.id);if(typeof Z!="function"){S(`Received screenshot data for unknown or handled id: ${o.id}`);break}ae(`Received screenshot data for id ${o.id}`),Z(K),re.delete(o.id),ee.delete(o.id),clearTimeout(B.get(o.id)),B.delete(o.id);break}case"screenshotError":if(typeof o.id!="string"||typeof o.message!="string"){S("Received invalid screenshot error message:",o);break}const I=ee.get(o.id);if(typeof I!="function"){S(`Received screenshot error for unknown or handled id: ${o.id}`);break}S(`Received screenshot error for id ${o.id}: ${o.message}`),I(new Error(o.message)),re.delete(o.id),ee.delete(o.id),clearTimeout(B.get(o.id)),B.delete(o.id);break;case"cameraRequest":{const g=de;if(!g)break;const K=Nn(o);if(!K){S("Received invalid cameraRequest:",o);break}console.info("[RemoteControl] cameraRequest received:",K.active,K.facingMode),await Ht(K,f,g,O);break}case"microphoneRequest":{if(!ve)break;const g=o.active===!0;if(Ze=g,console.info("[RemoteControl] microphoneRequest received, active=",g),!g){ze||await $e();break}if(te){ut(f);break}await tt();break}case"microphoneStartResult":{if(he===null||o.id!==he)break;he=null,typeof o.error=="string"&&(console.warn("[RemoteControl] microphoneStart rejected by host:",o.error),$e(o.error));break}case"terminateAppResult":if(typeof o.id!="string"){S("Received invalid terminateApp result message:",o);break}if(typeof o.error=="string"){const g=ie.get(o.id);if(typeof g!="function"){S(`Received terminateApp error for unknown or handled id: ${o.id}`);break}S(`Received terminateApp error for id ${o.id}: ${o.error}`),g(new Error(o.error)),se.delete(o.id),ie.delete(o.id),clearTimeout(B.get(o.id)),B.delete(o.id);break}const W=se.get(o.id);if(typeof W!="function"){S(`Received terminateApp result for unknown or handled id: ${o.id}`);break}ae(`Received terminateApp success for id ${o.id}`),W(),se.delete(o.id),ie.delete(o.id),clearTimeout(B.get(o.id)),B.delete(o.id);break;default:S(`Received unhandled message type: ${o.type}`,o);break}},N===A){const _=await A.createOffer({offerToReceiveVideo:!0,offerToReceiveAudio:!1});if(!O()||N!==A||(await A.setLocalDescription(_),!O()||N!==A))return;O()&&D===f&&f.readyState===WebSocket.OPEN&&f.send(JSON.stringify({type:"offer",...R?{displayStreams:!0}:{},...rt?{latencyTraceVersion:1}:{},sdp:_.sdp,sessionId:d})),T("Sent offer")}}catch(f){if(!O()||f instanceof Error&&f.message==="Connection stopped")return;const j=f instanceof Error?f.message:String(f);T("Error: "+j),De(j,h)}},pt=()=>{if(J)throw new Error("Device stream is disposed");ke++,Te=!1,We(null),pe!=="reconnecting"&&(pe=null),document.addEventListener("visibilitychange",mt),document.hidden||lt(),Ee=!1,ht(0)},Ct=()=>{ke++,Te=!1,we(),document.removeEventListener("visibilitychange",mt),le+=1,Fe=0,ne=!1,qe(),be(),_e(),pe=null,C({connection:"idle",videoReady:!1,controlReady:!1}),T("Stopped")},Ot=(r,u="primary")=>{if(J)throw new Error("Device stream is disposed");if(Y.has(r))throw new Error("Video element is already attached");const a={display:u};Y.set(r,a);const l=()=>{u==="primary"&&Ue.has(u)&&xt()};r.addEventListener("loadeddata",l);const y=Ue.get(u);y&&at(r,a,y);let h=!1;const O=()=>{h||(h=!0,L.delete(O),r.removeEventListener("loadeddata",l),a.stop?.(),Y.delete(r),r.srcObject=null)};return L.add(O),O};return{start:pt,stop:Ct,attachVideo:Ot,attachFrameSink:(r,u="primary")=>{const a=document.createElement("video");a.muted=!0,a.playsInline=!0,a.autoplay=!0;const l=Ot(a,u);let y=!1,h=0,O=0;const f=()=>{a.cancelVideoFrameCallback?.(h),cancelAnimationFrame(O)},j=()=>{y||!a.srcObject||(a.readyState>=2&&a.videoWidth>0&&P("present",(...M)=>r.present(...M),a,a.videoWidth,a.videoHeight,u),!(y||!a.srcObject)&&(a.requestVideoFrameCallback?h=a.requestVideoFrameCallback(j):O=requestAnimationFrame(j)))},U=()=>{f(),j()};Y.get(a).clear=f,a.addEventListener("loadeddata",U);const X=()=>{y||(y=!0,L.delete(X),f(),a.removeEventListener("loadeddata",U),l(),a.remove())};return L.delete(l),L.add(X),a.readyState>=2&&U(),X},dispose:()=>{if(!J){J=!0,Ct();for(const r of L)r();L.clear()}},getState:()=>m,updateOptions:r=>{if(J)throw new Error("Device stream is disposed");const u=e;if(e={...e,...r},u.jitterBufferTargetMs!==e.jitterBufferTargetMs)for(const a of N?.getTransceivers()??[])(a.currentDirection==="recvonly"||a.currentDirection==="sendrecv")&&Tt(a.receiver,e.jitterBufferTargetMs);!!u.onPlaybackStats!=!!e.onPlaybackStats&&F(),!!u.microphoneEnabled!=!!e.microphoneEnabled&&(ze=e.microphoneEnabled??!1,et()?tt():$e()),!!u.inspectMode!=!!e.inspectMode&&(e.inspectMode?q?.start():(q?.stop(),Me!==null&&We(null)))},sendControl:ce,sendTouch:(r,u,a,l,y,h=0)=>ce(Kt(r==="begin"?0:r==="end"?1:2,h,l,y,u,a,r==="end"?0:1)),sendText:r=>ce(Mt(r)),sendDisplayTouch:(r,u,a,l)=>ce(wt(r,u,a,l)),sendDuoControl:Ft,pressButton:r=>{const u={home:3,back:4,recents:187,power:26}[r];ce(Je(0,u,0,0)),ce(Je(1,u,0,0))},rotate:()=>ce(new Uint8Array([11]).buffer),bumpActivity:()=>q?.bumpActivity(),getAxStatus:()=>q?.getStatus()??"idle",openUrl:r=>{if(!D||D.readyState!==WebSocket.OPEN){S("WebSocket not open, cannot send open_url command.");return}try{const u=decodeURIComponent(r);T("Opening URL"),D.send(JSON.stringify({type:"openUrl",url:u,sessionId:d}))}catch(u){S("Error decoding or sending URL :",{error:u,url:r}),D.send(JSON.stringify({type:"openUrl",url:r,sessionId:d}))}q?.bumpActivity()},sendKeyEvent:r=>{if(!x||x.readyState!=="open"){S("Data channel not ready for imperative key command:",x?.readyState);return}const u=vt[r.code];if(!u){S(`Unknown event.code for imperative command: ${r.code}`);return}let a=i.META_NONE;r.shiftKey&&(a|=i.META_SHIFT_ON),r.altKey&&(a|=i.META_ALT_ON),r.ctrlKey&&(a|=i.META_CTRL_ON),r.metaKey&&(a|=i.META_META_ON);const l=r.type==="keydown"?i.ACTION_DOWN:i.ACTION_UP;ae(`Sending Imperative Key Command: code=${r.code}, keycode=${u}, action=${l}, meta=${a}`);const y=Je(l,u,0,a);y&&ce(y)},screenshot:r=>new Promise((u,a)=>{if(!D||D.readyState!==WebSocket.OPEN)return S("WebSocket not open, cannot send screenshot command."),a(new Error("WebSocket is not connected or connection is not open."));const l=`ui-ss-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,y={type:r?"screenshotDisplay":"screenshot",...r?{display:r}:{},id:l};re.set(l,u),ee.set(l,a),ae("Sending screenshot request:",y);try{D.send(JSON.stringify(y))}catch(h){S("Failed to send screenshot request immediately:",h),re.delete(l),ee.delete(l),a(h);return}B.set(l,setTimeout(()=>{B.delete(l),re.has(l)&&(S(`Screenshot request timed out for id ${l}`),ee.get(l)?.(new Error("Screenshot request timed out")),re.delete(l),ee.delete(l))},3e4))}),terminateApp:r=>new Promise((u,a)=>{if(!D||D.readyState!==WebSocket.OPEN)return S("WebSocket not open, cannot send terminateApp command."),a(new Error("WebSocket is not connected or connection is not open."));const l=`ui-term-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,y={type:"terminateApp",id:l,bundleId:r};se.set(l,u),ie.set(l,a),ae("Sending terminateApp request:",y);try{D.send(JSON.stringify(y))}catch(h){S("Failed to send terminateApp request immediately:",h),se.delete(l),ie.delete(l),a(h);return}q?.bumpActivity(),B.set(l,setTimeout(()=>{B.delete(l),se.has(l)&&(S(`terminateApp request timed out for id ${l}`),ie.get(l)?.(new Error("terminateApp request timed out")),se.delete(l),ie.delete(l))},3e4))}),reconnect:()=>pt(),refreshAxTree:async()=>{const r=q;if(!r)throw new Error("Inspect mode is not active");return r.refresh()},getAxSnapshot:()=>Me}}const Wn=t=>typeof t.message=="string"?t.message:typeof t.error=="string"?t.error:null,qn=t=>typeof t.dataUri=="string"?{dataUri:t.dataUri}:typeof t.base64=="string"?t.base64.startsWith("data:")?{dataUri:t.base64}:{dataUri:`data:${t.base64.startsWith("/9j/")?"image/jpeg":"image/png"};base64,${t.base64}`}:null;exports.AMOTION_EVENT=Ne;exports.ANDROID_KEYS=i;exports.AX_UNAVAILABLE_ERROR=je;exports.CONTROL_MSG_TYPE=Ie;exports.DUO_BUTTONS=sn;exports.DUO_DIMENSIONS=en;exports.DuoButtonSender=cn;exports.HingeSender=an;exports.axElementAtPoint=pn;exports.axElementRoleLabel=Ut;exports.axElementSelectorExpression=Cn;exports.axElementSummary=On;exports.axElementsEqual=Rt;exports.axSnapshotsEqual=It;exports.clampAxFrameForScreen=hn;exports.codeMap=vt;exports.createDeviceStream=xn;exports.createDisplayTouchMessage=wt;exports.createInjectKeycodeMessage=Je;exports.createSetClipboardMessage=Mt;exports.createTouchControlMessage=Kt;exports.createTwoFingerTouchControlMessage=Zt;exports.debugLog=ae;exports.debugWarn=S;exports.detectPlatform=Pt;exports.duoPointerMode=on;exports.flatDisplayTouch=tn;exports.normalizeAndroidTree=Nt;exports.normalizeIosTree=bt;exports.panelTouch=rn;exports.safeInvoke=P;
|
package/dist/core.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core-DkhLItUD.js");exports.AMOTION_EVENT=e.AMOTION_EVENT;exports.ANDROID_KEYS=e.ANDROID_KEYS;exports.AX_UNAVAILABLE_ERROR=e.AX_UNAVAILABLE_ERROR;exports.CONTROL_MSG_TYPE=e.CONTROL_MSG_TYPE;exports.axElementAtPoint=e.axElementAtPoint;exports.axElementSelectorExpression=e.axElementSelectorExpression;exports.axElementSummary=e.axElementSummary;exports.axElementsEqual=e.axElementsEqual;exports.axSnapshotsEqual=e.axSnapshotsEqual;exports.clampAxFrameForScreen=e.clampAxFrameForScreen;exports.createDeviceStream=e.createDeviceStream;exports.createDisplayTouchMessage=e.createDisplayTouchMessage;exports.createInjectKeycodeMessage=e.createInjectKeycodeMessage;exports.createSetClipboardMessage=e.createSetClipboardMessage;exports.createTouchControlMessage=e.createTouchControlMessage;exports.createTwoFingerTouchControlMessage=e.createTwoFingerTouchControlMessage;exports.normalizeAndroidTree=e.normalizeAndroidTree;exports.normalizeIosTree=e.normalizeIosTree;
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { createDeviceStream, type DeviceStream } from './core/device-stream';
|
|
2
|
+
export type { DeviceStreamOptions, DeviceStreamLiveOptions, DeviceStreamState, DeviceStreamTransport, DeviceFrameSink, StreamDisplay, } from './core/stream-options';
|
|
3
|
+
export type { RemoteControlConnectionState, ImperativeKeyboardEvent, ScreenshotData, MicrophoneState, CameraStreamStats, } from './core/stream-types';
|
|
4
|
+
export type { PlaybackStats, PlaybackVideoStats, PlaybackAudioStats, PlaybackTrackStats, } from './core/playback-stats';
|
|
5
|
+
export type { CameraCaptureInfo, CameraFacingMode, CameraRequest, CameraResult } from './core/camera';
|
|
6
|
+
export type { AxSnapshot, AxElement, AxRect, AxSelectors, AxPlatform } from './core/ax-tree';
|
|
7
|
+
export { axElementAtPoint, axElementSelectorExpression, axElementSummary, axElementsEqual, axSnapshotsEqual, clampAxFrameForScreen, normalizeAndroidTree, normalizeIosTree, AX_UNAVAILABLE_ERROR, } from './core/ax-tree';
|
|
8
|
+
export type { AndroidElementTreeOptions, AxStatus } from './core/ax-fetcher';
|
|
9
|
+
export type { DuoState, DuoOrientation } from './core/duo';
|
|
10
|
+
export { createTouchControlMessage, createTwoFingerTouchControlMessage, createInjectKeycodeMessage, createSetClipboardMessage, } from './core/webrtc-messages';
|
|
11
|
+
export { createDisplayTouchMessage } from './core/duo';
|
|
12
|
+
export { ANDROID_KEYS, AMOTION_EVENT, CONTROL_MSG_TYPE } from './core/constants';
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { t as s, p as r, A as o, C as t, a as c, b as n, c as l, d as m, e as E, f as A, j as T, B as i, o as x, m as S, q as g, u as p, n as u, g as M } from "./core-BhHpU_lr.mjs";
|
|
2
|
+
export {
|
|
3
|
+
s as AMOTION_EVENT,
|
|
4
|
+
r as ANDROID_KEYS,
|
|
5
|
+
o as AX_UNAVAILABLE_ERROR,
|
|
6
|
+
t as CONTROL_MSG_TYPE,
|
|
7
|
+
c as axElementAtPoint,
|
|
8
|
+
n as axElementSelectorExpression,
|
|
9
|
+
l as axElementSummary,
|
|
10
|
+
m as axElementsEqual,
|
|
11
|
+
E as axSnapshotsEqual,
|
|
12
|
+
A as clampAxFrameForScreen,
|
|
13
|
+
T as createDeviceStream,
|
|
14
|
+
i as createDisplayTouchMessage,
|
|
15
|
+
x as createInjectKeycodeMessage,
|
|
16
|
+
S as createSetClipboardMessage,
|
|
17
|
+
g as createTouchControlMessage,
|
|
18
|
+
p as createTwoFingerTouchControlMessage,
|
|
19
|
+
u as normalizeAndroidTree,
|
|
20
|
+
M as normalizeIosTree
|
|
21
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs as wr, jsx as Jn } from "react/jsx-runtime";
|
|
2
2
|
import { useRef as en, useState as cs, useEffect as Ea } from "react";
|
|
3
|
-
import { D as Tu,
|
|
4
|
-
import { h as Ru, u as Pu, D as Iu, a as Du, f as Lu } from "./duo-view-
|
|
3
|
+
import { D as Tu, v as Au, w as Cr, y as wu, z as Cu } from "./core-BhHpU_lr.mjs";
|
|
4
|
+
import { h as Ru, u as Pu, D as Iu, a as Du, f as Lu } from "./duo-view-tndcvbIi.mjs";
|
|
5
5
|
const To = "183", Nu = 0, ec = 1, Uu = 2, ls = 1, Fu = 2, ir = 3, Xn = 0, Oe = 1, hn = 2, Pn = 0, Li = 1, nc = 2, ic = 3, rc = 4, Ou = 5, ri = 100, Bu = 101, zu = 102, Vu = 103, ku = 104, Gu = 200, Hu = 201, Wu = 202, Xu = 203, Ta = 204, Aa = 205, qu = 206, Yu = 207, Zu = 208, Ju = 209, $u = 210, Ku = 211, ju = 212, Qu = 213, th = 214, wa = 0, Ca = 1, Ra = 2, Ui = 3, Pa = 4, Ia = 5, Da = 6, La = 7, Pl = 0, eh = 1, nh = 2, dn = 0, Il = 1, Dl = 2, Ll = 3, Ao = 4, Nl = 5, Ul = 6, Fl = 7, sc = "attached", ih = "detached", Ol = 300, li = 301, Fi = 302, us = 303, Us = 304, As = 306, Na = 1e3, An = 1001, Ua = 1002, Ce = 1003, rh = 1004, Rr = 1005, ve = 1006, Fs = 1007, oi = 1008, He = 1009, Bl = 1010, zl = 1011, fr = 1012, wo = 1013, mn = 1014, We = 1015, Dn = 1016, Co = 1017, Ro = 1018, dr = 1020, Vl = 35902, kl = 35899, Gl = 1021, Hl = 1022, Xe = 1023, Ln = 1026, ci = 1027, Po = 1028, Io = 1029, Oi = 1030, Do = 1031, Lo = 1033, hs = 33776, fs = 33777, ds = 33778, ps = 33779, Fa = 35840, Oa = 35841, Ba = 35842, za = 35843, Va = 36196, ka = 37492, Ga = 37496, Ha = 37488, Wa = 37489, Xa = 37490, qa = 37491, Ya = 37808, Za = 37809, Ja = 37810, $a = 37811, Ka = 37812, ja = 37813, Qa = 37814, to = 37815, eo = 37816, no = 37817, io = 37818, ro = 37819, so = 37820, ao = 37821, oo = 36492, co = 36494, lo = 36495, uo = 36283, ho = 36284, fo = 36285, po = 36286, gs = 2300, mo = 2301, Os = 2302, ac = 2303, oc = 2400, cc = 2401, lc = 2402, sh = 2500, ah = 0, oh = 1, uc = 2, ch = 3200, Wl = 0, lh = 1, Hn = "", Fe = "srgb", Bi = "srgb-linear", _s = "linear", re = "srgb", mi = 7680, hc = 519, uh = 512, hh = 513, fh = 514, No = 515, dh = 516, ph = 517, Uo = 518, mh = 519, go = 35044, fc = 35048, dc = "300 es", fn = 2e3, pr = 2001;
|
|
6
6
|
function gh(i) {
|
|
7
7
|
for (let t = i.length - 1; t >= 0; --t)
|
|
@@ -26256,7 +26256,7 @@ function T0(i, t, e) {
|
|
|
26256
26256
|
},
|
|
26257
26257
|
// Imported appearances replace the rigid body while live screens and the hinge remain under our control.
|
|
26258
26258
|
loadAppearance: async (mt) => {
|
|
26259
|
-
const { GLTFLoader: st } = await import("./GLTFLoader-
|
|
26259
|
+
const { GLTFLoader: st } = await import("./GLTFLoader-BjfxfJc4.mjs"), { scene: F } = await new st().loadAsync(mt), $ = /* @__PURE__ */ new Set();
|
|
26260
26260
|
if (F.traverse((J) => {
|
|
26261
26261
|
if (J instanceof Ee) {
|
|
26262
26262
|
$.add(J.geometry);
|