@limrun/ui 0.16.0 → 0.17.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +64 -0
  2. package/dist/GLTFLoader-Cami_vza.mjs +1679 -0
  3. package/dist/GLTFLoader-DeCLxW_q.js +1 -0
  4. package/dist/components/duo-button-hinge.d.ts +16 -0
  5. package/dist/components/duo-controls.d.ts +21 -0
  6. package/dist/components/duo-flat-frame.d.ts +7 -0
  7. package/dist/components/duo-flat-geometry.d.ts +52 -0
  8. package/dist/components/duo-fold-motion.d.ts +27 -0
  9. package/dist/components/duo-fold-renderer.d.ts +19 -0
  10. package/dist/components/duo-fold-timing.d.ts +1 -0
  11. package/dist/components/duo-frame.d.ts +16 -0
  12. package/dist/components/duo-hardware.d.ts +20 -0
  13. package/dist/components/duo-loading.d.ts +8 -0
  14. package/dist/components/duo-model.d.ts +19 -0
  15. package/dist/components/duo-screen-handoff.d.ts +4 -0
  16. package/dist/components/duo-view.d.ts +9 -0
  17. package/dist/components/remote-control.d.ts +5 -1
  18. package/dist/core/duo.d.ts +63 -0
  19. package/dist/duo-fold-renderer-BXejNHcY.mjs +257 -0
  20. package/dist/duo-fold-renderer-DdltAnF7.js +53 -0
  21. package/dist/duo-frame-Cmw4p2uN.mjs +26767 -0
  22. package/dist/duo-frame-iMtrvx_a.js +4059 -0
  23. package/dist/duo-view-BAh-w2Kz.js +1 -0
  24. package/dist/duo-view-D9Ae00rj.mjs +512 -0
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.css +1 -1
  27. package/dist/index.js +2 -2
  28. package/dist/lite.cjs +1 -1
  29. package/dist/lite.js +1 -1
  30. package/dist/remote-control-B2jZpf3c.js +1 -0
  31. package/dist/remote-control-DiddxS8l.mjs +2883 -0
  32. package/package.json +8 -2
  33. package/dist/demo.d.ts +0 -1
  34. package/dist/remote-control-BRgbD7yo.mjs +0 -2516
  35. package/dist/remote-control-VISrP1zI.js +0 -1
  36. package/index.html +0 -199
  37. package/src/assets/Apple_logo_white.svg +0 -4
  38. package/src/assets/android_boot.gif +0 -0
  39. package/src/assets/android_boot.webp +0 -0
  40. package/src/assets/iphone16pro_black.webp +0 -0
  41. package/src/assets/iphone16pro_black_bg.webp +0 -0
  42. package/src/assets/iphone16pro_black_landscape.webp +0 -0
  43. package/src/assets/iphone16pro_black_landscape_bg.webp +0 -0
  44. package/src/assets/pixel9_black.webp +0 -0
  45. package/src/assets/pixel9_black_landscape.webp +0 -0
  46. package/src/assets/pixel_tablet_landscape.webp +0 -0
  47. package/src/assets/pixel_tablet_portrait.webp +0 -0
  48. package/src/components/device-install/index.ts +0 -1
  49. package/src/components/inspect-overlay.css +0 -223
  50. package/src/components/inspect-overlay.tsx +0 -437
  51. package/src/components/remote-control-framed.tsx +0 -14
  52. package/src/components/remote-control.css +0 -131
  53. package/src/components/remote-control.test.ts +0 -34
  54. package/src/components/remote-control.tsx +0 -3853
  55. package/src/core/ax-fetcher.test.ts +0 -418
  56. package/src/core/ax-fetcher.ts +0 -387
  57. package/src/core/ax-tree.test.ts +0 -491
  58. package/src/core/ax-tree.ts +0 -416
  59. package/src/core/camera.test.ts +0 -155
  60. package/src/core/camera.ts +0 -133
  61. package/src/core/constants.ts +0 -344
  62. package/src/core/webrtc-messages.ts +0 -148
  63. package/src/demo.tsx +0 -269
  64. package/src/frame-assets.ts +0 -22
  65. package/src/hooks/index.ts +0 -1
  66. package/src/index.ts +0 -29
  67. package/src/lite.test.ts +0 -30
  68. package/src/lite.ts +0 -30
  69. package/src/vite-env.d.ts +0 -1
  70. package/tsconfig.json +0 -26
  71. package/tsconfig.node.json +0 -26
  72. package/vite.config.ts +0 -35
  73. package/vitest.config.ts +0 -24
package/dist/lite.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./remote-control-VISrP1zI.js");exports.AX_UNAVAILABLE_ERROR=e.AX_UNAVAILABLE_ERROR;exports.RemoteControl=e.RemoteControl;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.normalizeAndroidTree=e.normalizeAndroidTree;exports.normalizeIosTree=e.normalizeIosTree;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./remote-control-B2jZpf3c.js");exports.AX_UNAVAILABLE_ERROR=e.AX_UNAVAILABLE_ERROR;exports.RemoteControl=e.RemoteControl;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.normalizeAndroidTree=e.normalizeAndroidTree;exports.normalizeIosTree=e.normalizeIosTree;
package/dist/lite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as s, R as o, a as r, b as n, c as m, d as l, e as t, f as E, n as x, g as A } from "./remote-control-BRgbD7yo.mjs";
1
+ import { A as s, R as o, a as r, b as n, c as m, d as l, e as t, f as E, n as x, g as A } from "./remote-control-DiddxS8l.mjs";
2
2
  export {
3
3
  s as AX_UNAVAILABLE_ERROR,
4
4
  o as RemoteControl,
@@ -0,0 +1 @@
1
+ "use strict";require('./index.css');const g=require("react/jsx-runtime"),f=require("react"),kn=require("react-dom");function Lr(r){var e,i,c="";if(typeof r=="string"||typeof r=="number")c+=r;else if(typeof r=="object")if(Array.isArray(r)){var l=r.length;for(e=0;e<l;e++)r[e]&&(i=Lr(r[e]))&&(c&&(c+=" "),c+=i)}else for(i in r)r[i]&&(c&&(c+=" "),c+=i);return c}function be(){for(var r,e,i=0,c="",l=arguments.length;i<l;i++)(r=arguments[i])&&(e=Lr(r))&&(c&&(c+=" "),c+=e);return c}function zt(r,e,i,c,l,u){return"M"+(r+l)+","+e+"H"+(r+i-u)+"a"+u+","+u+" 0 0 1 "+u+","+u+"V"+(e+c-u)+"a"+u+","+u+" 0 0 1 "+-u+","+u+"H"+(r+l)+"a"+l+","+l+" 0 0 1 "+-l+","+-l+"V"+(e+l)+"a"+l+","+l+" 0 0 1 "+l+","+-l+"Z"}function Fr({inner:r,width:e,height:i}){const c=f.useId().replace(/:/g,""),l=r?8.4:1.25,u=8.4;return g.jsxs("svg",{className:"rc-duo-flat-frame",viewBox:"0 0 "+e+" "+i,"aria-hidden":"true",children:[g.jsxs("defs",{children:[g.jsxs("linearGradient",{id:c+"-silver",x1:"0",y1:"0",x2:"1",y2:"1",children:[g.jsx("stop",{offset:"0",stopColor:"#62676b"}),g.jsx("stop",{offset:"0.035",stopColor:"#f9faf9"}),g.jsx("stop",{offset:"0.11",stopColor:"#b0b4b6"}),g.jsx("stop",{offset:"0.31",stopColor:"#fdfefd"}),g.jsx("stop",{offset:"0.43",stopColor:"#797f84"}),g.jsx("stop",{offset:"0.51",stopColor:"#e8eaea"}),g.jsx("stop",{offset:"0.7",stopColor:"#979da1"}),g.jsx("stop",{offset:"0.87",stopColor:"#fafbf9"}),g.jsx("stop",{offset:"1",stopColor:"#5f676c"})]}),g.jsxs("linearGradient",{id:c+"-spine",children:[g.jsx("stop",{stopColor:"#4a5154"}),g.jsx("stop",{offset:"0.16",stopColor:"#d6d9d9"}),g.jsx("stop",{offset:"0.4",stopColor:"#f8f9f7"}),g.jsx("stop",{offset:"0.62",stopColor:"#a2a8ab"}),g.jsx("stop",{offset:"0.83",stopColor:"#e4e7e5"}),g.jsx("stop",{offset:"1",stopColor:"#666e72"})]})]}),!r&&g.jsxs(g.Fragment,{children:[g.jsx("rect",{x:"-2.3",y:"0.7",width:"3.3",height:i-1.4,rx:"0.85",fill:"url(#"+c+"-spine)",stroke:"#8b9296",strokeWidth:"0.15"}),g.jsx("path",{d:"M-.6 2V"+(i-2),stroke:"#f5f6f4",strokeWidth:"0.22"})]}),g.jsx("path",{d:zt(0,0,e,i,l,u),fill:"url(#"+c+"-silver)",stroke:"#696f72",strokeWidth:"0.24"}),g.jsx("path",{d:zt(.48,.48,e-.96,i-.96,Math.max(.5,l-.48),u-.48),fill:"none",stroke:"#ffffff",strokeOpacity:"0.85",strokeWidth:"0.2"}),g.jsx("path",{d:zt(1.12,1.12,e-2.24,i-2.24,r?7.15:.65,7.15),fill:"#090b0d",stroke:"#34393c",strokeWidth:"0.2"}),[e-16,r?19:16].map(C=>g.jsx(f.Fragment,{children:g.jsx("path",{d:"M"+C+",0.17v0.82M"+C+","+(i-1)+"v0.82",stroke:"#b1b2ac",strokeWidth:"1.1"})},C)),r&&[0,i-.6].map(C=>g.jsx("rect",{x:e/2-2.2,y:C,width:"4.4",height:"0.6",rx:"0.18",fill:"url(#"+c+"-spine)",stroke:"#697074",strokeWidth:"0.14"},C)),g.jsx("path",{d:"M"+(e-.1)+",20h-.9m.9,"+(i-40)+"h-.9",stroke:"#b1b2ac",strokeWidth:"1.05"})]})}const Zt={width:164.6,height:117.8,depth:5.2};function Pn(r,e,i){return r=Math.max(0,Math.min(1,r)),e=Math.max(0,Math.min(1,e)),i===1?{x:e,y:1-r}:i===2?{x:1-r,y:1-e}:i===3?{x:1-e,y:r}:{x:r,y:e}}function Un(r){return Number.isFinite(r)&&r>=0&&r<=180}function Ln(r,e){return{x:Math.max(0,Math.min(1,r)),y:Math.max(0,Math.min(1,1-e))}}function Fn(r,e,i){return e&&(r||!i)?"touch":r?"ignore":"orbit"}function Wn(r,e,i,c){if(!Number.isInteger(r)||r<0||r>3||!Number.isInteger(e)||e<1||e>255||!Number.isFinite(i)||!Number.isFinite(c)||i<0||i>1||c<0||c>1)throw new RangeError("Invalid display touch coordinates");const l=new ArrayBuffer(12),u=new DataView(l);return u.setUint8(0,19),u.setUint8(1,r),u.setUint8(2,e),u.setFloat32(4,i,!0),u.setFloat32(8,c,!0),l}class Hn{constructor(e,i){this.send=e,this.failed=i}send;failed;latest;running=!1;stopped=!1;set(e){this.stopped||!Un(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 jn={side:"Sleep/Wake",volumeUp:"Volume Up",volumeDown:"Volume Down"};class Xn{constructor(e,i){this.send=e,this.failed=i}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,i){this.tail=this.tail.then(()=>this.send(e,i)).catch(this.failed)}}function Wr(r,e,i,c){const l=Zt.width/(r?1:2),u=Zt.height,C=r?157.5:77.1,O=r?110.8:112.2,R=(e+(r?3:0))%4,_=Math.max(0,Math.min((i-120)/(R%2?u:l),(c-120)/(R%2?l:u))),b=(A,F)=>{A=(A-l/2)*_,F=(F-u/2)*_;const ee=R===1?{x:-F,y:A}:R===2?{x:-A,y:-F}:R===3?{x:F,y:-A}:{x:A,y:F};return{x:ee.x+i/2,y:ee.y+c/2}},N=(R%2?u:l)*_,G=(R%2?l:u)*_,Q={min:{x:(i-N)/2,y:(c-G)/2},max:{x:(i+N)/2,y:(c+G)/2}},ue=[{button:"volumeDown",x:l-37,y:-.32,width:9.5,height:.65,edge:"top"},{button:"volumeUp",x:l-25,y:-.32,width:9.5,height:.65,edge:"top"},{button:"side",x:l+.35,y:u/2-21,width:.7,height:13,edge:"right"}],Ce=["top","right","bottom","left"],me=ue.map(A=>{const F=Ce[(Ce.indexOf(A.edge)+R)%4],ee=b(A.x,A.y);return F==="top"&&(ee.y=Q.min.y-28),F==="bottom"&&(ee.y=Q.max.y+28),F==="left"&&(ee.x=Q.min.x-28),F==="right"&&(ee.x=Q.max.x+28),{button:A.button,edge:F,...ee,targetX:ee.x,targetY:ee.y}}),P=me.filter(A=>A.button!=="side"),J=R%2?"y":"x";P.sort((A,F)=>A[J]-F[J]);const Z=R%2?"targetY":"targetX";if(P[1][J]-P[0][J]<44){const A=(P[0][J]+P[1][J])/2;P[0][Z]=A-22,P[1][Z]=A+22}return{bodyWidth:l,bodyHeight:u,screenWidth:C,screenHeight:O,scale:_,turns:R,buttons:ue,guides:me,rect:Q,iconSize:Math.min(Hr(Q),12*_)}}function Hr(r){return Math.max(12,Math.min(24,Math.max(r.max.x-r.min.x,r.max.y-r.min.y)/24))}function $n(r,e,i){return[["top",i.min.y-e,r,i.min.x,i.max.x],["bottom",e-i.max.y,r,i.min.x,i.max.x],["left",i.min.x-r,e,i.min.y,i.max.y],["right",r-i.max.x,e,i.min.y,i.max.y]].filter(([,l,u,C,O])=>l>=-7&&l<=52&&u>=C-12&&u<=O+12).sort((l,u)=>Math.abs(l[1])-Math.abs(u[1]))[0]?.[0]}function jr({logo:r}){return g.jsx("div",{className:"rc-duo-loading-screen",role:"status","aria-label":"Connecting to iPhone Duo",children:r&&g.jsx("img",{src:r,alt:""})})}function Yr({logo:r,showFrame:e}){const i=f.useRef(null),[c,l]=f.useState({width:0,height:0});f.useEffect(()=>{const _=new ResizeObserver(([b])=>{b&&l({width:b.contentRect.width,height:b.contentRect.height})});return i.current&&_.observe(i.current),()=>_.disconnect()},[]);const u=Wr(!1,0,c.width,c.height),C=e?u.scale:Math.min(c.width/u.screenWidth,c.height/u.screenHeight),O=e?u.bodyWidth:u.screenWidth,R=e?u.bodyHeight:u.screenHeight;return g.jsx("div",{className:"rc-duo-view",children:g.jsxs("div",{className:e?"rc-duo":"rc-duo rc-duo-frameless",children:[g.jsx("div",{ref:i,className:"rc-duo-flat-stage",children:g.jsxs("div",{className:"rc-duo-flat-device",style:{width:O*C,height:R*C,transform:"translate(-50%, -50%)"},children:[e&&g.jsx(Fr,{inner:!1,width:O,height:R}),g.jsx("div",{className:"rc-duo-flat-screen",style:{width:u.screenWidth*C,height:u.screenHeight*C,left:(O-u.screenWidth)/2*C,top:(R-u.screenHeight)/2*C,borderRadius:e?[.8,6.6,6.6,.8].map(_=>_*C+"px").join(" "):0},children:g.jsx(jr,{logo:r})})]})}),e&&g.jsx("div",{className:"rc-duo-loading-controls","aria-hidden":"true"})]})})}const Kt={INJECT_KEYCODE:0,INJECT_TOUCH_EVENT:2,INJECT_TWO_FINGER_TOUCH_EVENT:18,SET_CLIPBOARD:9},L={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},a={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_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,DPAD_UP:19,DPAD_DOWN:20,DPAD_LEFT:21,DPAD_RIGHT:22,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,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,MENU:82,KEYCODE_PAGE_UP:92,KEYCODE_PAGE_DOWN:93,KEYCODE_ESCAPE:111,FORWARD_DEL:112,KEYCODE_CTRL_LEFT:113,KEYCODE_CTRL_RIGHT:114,KEYCODE_META_LEFT:117,KEYCODE_META_RIGHT:118,KEYCODE_MOVE_HOME:122,KEYCODE_MOVE_END:123,KEYCODE_INSERT:124,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_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},Xr={KeyA:a.KEYCODE_A,KeyB:a.KEYCODE_B,KeyC:a.KEYCODE_C,KeyD:a.KEYCODE_D,KeyE:a.KEYCODE_E,KeyF:a.KEYCODE_F,KeyG:a.KEYCODE_G,KeyH:a.KEYCODE_H,KeyI:a.KEYCODE_I,KeyJ:a.KEYCODE_J,KeyK:a.KEYCODE_K,KeyL:a.KEYCODE_L,KeyM:a.KEYCODE_M,KeyN:a.KEYCODE_N,KeyO:a.KEYCODE_O,KeyP:a.KEYCODE_P,KeyQ:a.KEYCODE_Q,KeyR:a.KEYCODE_R,KeyS:a.KEYCODE_S,KeyT:a.KEYCODE_T,KeyU:a.KEYCODE_U,KeyV:a.KEYCODE_V,KeyW:a.KEYCODE_W,KeyX:a.KEYCODE_X,KeyY:a.KEYCODE_Y,KeyZ:a.KEYCODE_Z,Digit0:a.KEYCODE_0,Digit1:a.KEYCODE_1,Digit2:a.KEYCODE_2,Digit3:a.KEYCODE_3,Digit4:a.KEYCODE_4,Digit5:a.KEYCODE_5,Digit6:a.KEYCODE_6,Digit7:a.KEYCODE_7,Digit8:a.KEYCODE_8,Digit9:a.KEYCODE_9,Backquote:a.KEYCODE_GRAVE,Minus:a.KEYCODE_MINUS,Equal:a.KEYCODE_EQUALS,BracketLeft:a.KEYCODE_LEFT_BRACKET,BracketRight:a.KEYCODE_RIGHT_BRACKET,Backslash:a.KEYCODE_BACKSLASH,Semicolon:a.KEYCODE_SEMICOLON,Quote:a.KEYCODE_APOSTROPHE,Comma:a.KEYCODE_COMMA,Period:a.KEYCODE_PERIOD,Slash:a.KEYCODE_SLASH,Space:a.KEYCODE_SPACE,Tab:a.KEYCODE_TAB,Escape:a.KEYCODE_ESCAPE,ArrowUp:a.DPAD_UP,ArrowDown:a.DPAD_DOWN,ArrowLeft:a.DPAD_LEFT,ArrowRight:a.DPAD_RIGHT,Enter:a.ENTER,Backspace:a.DEL,Delete:a.FORWARD_DEL,Home:a.KEYCODE_MOVE_HOME,End:a.KEYCODE_MOVE_END,PageUp:a.KEYCODE_PAGE_UP,PageDown:a.KEYCODE_PAGE_DOWN,Insert:a.KEYCODE_INSERT,F1:a.KEYCODE_F1,F2:a.KEYCODE_F2,F3:a.KEYCODE_F3,F4:a.KEYCODE_F4,F5:a.KEYCODE_F5,F6:a.KEYCODE_F6,F7:a.KEYCODE_F7,F8:a.KEYCODE_F8,F9:a.KEYCODE_F9,F10:a.KEYCODE_F10,F11:a.KEYCODE_F11,F12:a.KEYCODE_F12,ShiftLeft:a.KEYCODE_SHIFT_LEFT,ShiftRight:a.KEYCODE_SHIFT_RIGHT,ControlLeft:a.KEYCODE_CTRL_LEFT,ControlRight:a.KEYCODE_CTRL_RIGHT,AltLeft:a.KEYCODE_ALT_LEFT,AltRight:a.KEYCODE_ALT_RIGHT,MetaLeft:a.KEYCODE_META_LEFT,MetaRight:a.KEYCODE_META_RIGHT,ContextMenu:a.MENU,Numpad0:a.KEYCODE_NUMPAD_0,Numpad1:a.KEYCODE_NUMPAD_1,Numpad2:a.KEYCODE_NUMPAD_2,Numpad3:a.KEYCODE_NUMPAD_3,Numpad4:a.KEYCODE_NUMPAD_4,Numpad5:a.KEYCODE_NUMPAD_5,Numpad6:a.KEYCODE_NUMPAD_6,Numpad7:a.KEYCODE_NUMPAD_7,Numpad8:a.KEYCODE_NUMPAD_8,Numpad9:a.KEYCODE_NUMPAD_9,NumpadDivide:a.KEYCODE_NUMPAD_DIVIDE,NumpadMultiply:a.KEYCODE_NUMPAD_MULTIPLY,NumpadSubtract:a.KEYCODE_NUMPAD_SUBTRACT,NumpadAdd:a.KEYCODE_NUMPAD_ADD,NumpadDecimal:a.KEYCODE_NUMPAD_DOT,NumpadComma:a.KEYCODE_NUMPAD_COMMA,NumpadEnter:a.KEYCODE_NUMPAD_ENTER,NumpadEqual:a.KEYCODE_NUMPAD_EQUALS};function bt(r,e,i,c,l,u,C=1,O=0,R=0){const _=new ArrayBuffer(32),b=new DataView(_);let N=0;return b.setUint8(N,Kt.INJECT_TOUCH_EVENT),N+=1,b.setUint8(N,r),N+=1,b.setBigInt64(N,BigInt(e),!0),N+=8,b.setInt32(N,Math.round(l),!0),N+=4,b.setInt32(N,Math.round(u),!0),N+=4,b.setUint16(N,i,!0),N+=2,b.setUint16(N,c,!0),N+=2,b.setInt16(N,Math.round(C*65535),!0),N+=2,b.setInt32(N,O,!0),N+=4,b.setInt32(N,R,!0),_}function Bn(r,e,i,c,l,u,C){const O=new ArrayBuffer(24),R=new DataView(O);let _=0;return R.setUint8(_,Kt.INJECT_TWO_FINGER_TOUCH_EVENT),_+=1,R.setUint8(_,r),_+=1,R.setInt32(_,Math.round(c),!0),_+=4,R.setInt32(_,Math.round(l),!0),_+=4,R.setInt32(_,Math.round(u),!0),_+=4,R.setInt32(_,Math.round(C),!0),_+=4,R.setUint16(_,e,!0),_+=2,R.setUint16(_,i,!0),_+=2,R.setUint16(_,0,!0),O}function qn(r,e=!0){const c=new TextEncoder().encode(r),l=new ArrayBuffer(14+c.length),u=new DataView(l);let C=0;return u.setUint8(C,Kt.SET_CLIPBOARD),C+=1,u.setBigInt64(C,BigInt(0),!1),C+=8,u.setUint8(C,e?1:0),C+=1,u.setUint32(C,c.length,!1),C+=4,new Uint8Array(l,C).set(c),l}function ft(r,e,i=0,c=0){const l=new ArrayBuffer(14),u=new DataView(l);let C=0;return u.setUint8(C,Kt.INJECT_KEYCODE),C+=1,u.setUint8(C,r),C+=1,u.setInt32(C,e,!0),C+=4,u.setInt32(C,i,!0),C+=4,u.setInt32(C,c,!0),l}const It="Accessibility unavailable on this device.",Yt=500,$r=(r,e)=>Math.abs(r.x-e.x)<.5&&Math.abs(r.y-e.y)<.5&&Math.abs(r.width-e.width)<.5&&Math.abs(r.height-e.height)<.5,Vn=r=>Math.max(0,r.width)*Math.max(0,r.height),Gn=r=>{const e=r.find(i=>i.frame&&i.frame.width>0&&i.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}},Jn=r=>{const e={};return typeof r.AXUniqueId=="string"&&r.AXUniqueId.length>0&&(e.AXUniqueId=r.AXUniqueId),typeof r.AXLabel=="string"&&r.AXLabel.length>0&&(e.AXLabel=r.AXLabel),typeof r.type=="string"&&r.type.length>0&&(e.className=r.type),e},zn=r=>{const e={};for(const[i,c]of Object.entries(r))i!=="children"&&(e[i]=c);return e};function Br(r){const e=Array.isArray(r)?r:[r],i=Gn(e),c=[],l=(u,C)=>{if(c.length>=Yt)return;const O=u.frame;if(O&&O.width>0&&O.height>0&&!$r(O,i)){const _=u.role_description||u.role||"",b=(typeof u.AXLabel=="string"?u.AXLabel:"")||(typeof u.title=="string"?u.title:"")||"";c.push({id:typeof u.AXUniqueId=="string"&&u.AXUniqueId.length>0?u.AXUniqueId:C,path:C,label:b,value:typeof u.AXValue=="string"?u.AXValue:"",role:_,type:typeof u.type=="string"?u.type:"",enabled:u.enabled!==!1,focused:u.focused===!0,frame:{x:O.x,y:O.y,width:O.width,height:O.height},selectors:Jn(u),raw:zn(u)})}const R=Array.isArray(u.children)?u.children:[];for(let _=0;_<R.length&&c.length<Yt;_++)l(R[_],`${C}.${_}`)};for(let u=0;u<e.length&&c.length<Yt;u++)l(e[u],String(u));return{platform:"ios",screen:{width:i.width,height:i.height},elements:c,capturedAt:Date.now()}}const Qn=r=>{let e={x:0,y:0,width:1,height:1},i=0;for(const c of r){const l=c.parsedBounds;if(!l)continue;const u=l.right-l.left,C=l.bottom-l.top,O=Math.max(0,u)*Math.max(0,C);O>i&&(i=O,e={x:0,y:0,width:u,height:C})}return e},Zn=r=>{const e={};return typeof r.resourceId=="string"&&r.resourceId.length>0&&(e.resourceId=r.resourceId),typeof r.contentDesc=="string"&&r.contentDesc.length>0&&(e.contentDesc=r.contentDesc),typeof r.text=="string"&&r.text.length>0&&(e.text=r.text),typeof r.className=="string"&&r.className.length>0&&(e.className=r.className),e};function qr(r){const e=Qn(r),i=[];for(let c=0;c<r.length&&i.length<Yt;c++){const l=r[c],u=l.parsedBounds;if(!u)continue;const C=Math.max(0,u.right-u.left),O=Math.max(0,u.bottom-u.top);if(C<=0||O<=0)continue;const R={x:u.left,y:u.top,width:C,height:O};if($r(R,{x:0,y:0,width:e.width,height:e.height}))continue;const _=l.contentDesc||l.text||"",b=l.className||"";i.push({id:l.resourceId&&l.resourceId.length>0?l.resourceId:l.contentDesc&&l.contentDesc.length>0?`cd:${l.contentDesc}`:String(c),path:String(c),label:_,value:typeof l.text=="string"?l.text:"",role:b,type:b,enabled:l.enabled!==!1,focused:l.focused===!0,frame:R,selectors:Zn(l),raw:{...l}})}return{platform:"android",screen:{width:e.width,height:e.height},elements:i,capturedAt:Date.now()}}function Vr(r,e){const i=Math.max(0,r.x),c=Math.max(0,r.y),l=Math.min(e.width,r.x+r.width),u=Math.min(e.height,r.y+r.height),C=Math.max(0,l-i),O=Math.max(0,u-c);return C>0&&O>0?{x:i,y:c,width:C,height:O}:null}function er(r,e){if(r===e)return!0;if(r.id!==e.id||r.path!==e.path||r.label!==e.label||r.value!==e.value||r.role!==e.role||r.type!==e.type||r.enabled!==e.enabled||r.focused!==e.focused)return!1;const i=r.frame,c=e.frame;return i.x===c.x&&i.y===c.y&&i.width===c.width&&i.height===c.height}function tr(r,e){if(r===e)return!0;if(!r||!e||r.platform!==e.platform||r.screen.width!==e.screen.width||r.screen.height!==e.screen.height||r.elements.length!==e.elements.length)return!1;for(let i=0;i<r.elements.length;i++)if(!er(r.elements[i],e.elements[i]))return!1;return!0}function Gr(r,e,i){let c=null,l=1/0;for(const u of r.elements){const C=u.frame;if(e<C.x||i<C.y||e>C.x+C.width||i>C.y+C.height)continue;const O=Vn(C);O<l&&(l=O,c=u)}return c}function Jr(r,e){if(e==="ios"){if(r.selectors.AXUniqueId)return`client.tapElement({ AXUniqueId: ${JSON.stringify(r.selectors.AXUniqueId)} })`;if(r.selectors.AXLabel){const i=r.selectors.className?`, type: ${JSON.stringify(r.selectors.className)}`:"";return`client.tapElement({ AXLabel: ${JSON.stringify(r.selectors.AXLabel)}${i} })`}return null}return r.selectors.resourceId?`client.tap({ selector: { resourceId: ${JSON.stringify(r.selectors.resourceId)} } })`:r.selectors.contentDesc?`client.tap({ selector: { contentDesc: ${JSON.stringify(r.selectors.contentDesc)} } })`:r.selectors.text?`client.tap({ selector: { text: ${JSON.stringify(r.selectors.text)} } })`:null}function zr(r){const e=r.role||r.type||"";if(!e)return"element";let i=e.replace(/^AX/,"");return i.includes(".")&&(i=i.split(".").pop()),i==="GenericElement"?"Element":(i=i.replace(/([a-z])([A-Z])/g,"$1 $2"),i)}const Kr=80;function rr(r){const e=zr(r),i=r.label||r.value||"";if(!i)return e;const c=i.length>Kr?i.slice(0,Kr).trimEnd()+"…":i;return`${e} · ${c}`}const eo=500,to=2e3,xr=5e3,ro=8e3,no=1200,oo=250,io=()=>`ax-rc-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;class so{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??eo,this.maxBackoffMs=e.maxBackoffMs??to,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,i){if(this.status!==e&&(this.status=e,!!this.onStatusChange))try{this.onStatusChange(e,i)}catch(c){console.error("[AxFetcher] onStatusChange threw:",c)}}bumpActivity(){if(!this.running)return;const e=Date.now();this.boostUntilMs=e+no;const i=Math.max(150,Math.floor(this.baseIntervalMs/2));if(e-this.lastBumpAtMs<i){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 i=e.id;if(!this.pending.get(i))return!1;if(this.platform==="ios"){if(e.type!=="elementTreeResult")return!1;const O=typeof e.error=="string"?e.error:null;if(O)return this.settleReject(i,new Error(O)),!0;const R=typeof e.json=="string"?e.json:"";try{const _=JSON.parse(R),b=Br(_);this.settleResolve(i,b)}catch(_){this.settleReject(i,_ instanceof Error?_:new Error(String(_)))}return!0}if(e.type!=="getElementTreeResult")return!1;const l=e.error;if(l&&typeof l=="object"){const O=typeof l.message=="string"?l.message:"getElementTree failed";return this.settleReject(i,new Error(O)),!0}const u=e.payload,C=Array.isArray(u?.nodes)?u.nodes:[];try{const O=qr(C);this.settleResolve(i,O)}catch(O){this.settleReject(i,O instanceof Error?O:new Error(String(O)))}return!0}buildRequest(e){return this.platform==="ios"?{type:"elementTree",id:e}:{type:"getElementTree",id:e,...this.androidElementTreeOptions}}async requestOnce(){const e=io();return new Promise((i,c)=>{const l=window.setTimeout(()=>{this.pending.delete(e),c(new Error("elementTree request timed out"))},ro+(this.androidElementTreeOptions?.waitForIdleTimeoutMs??0));this.pending.set(e,{resolve:i,reject:c,timer:l}),this.send(this.buildRequest(e))||(window.clearTimeout(l),this.pending.delete(e),c(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 i=e instanceof Error?e.message:String(e),c=/unavailable|not (yet )?running|failed|timeout/i.test(i);this.currentInterval=c?xr:Math.min(this.currentInterval*2,this.maxBackoffMs),this.setStatus(c?"unavailable":"error",i)}finally{this.inflight=!1,this.scheduleNext()}}}deliver(e){const i=this.lastSnapshot;if(tr(i,e)){this.currentInterval=Math.min(this.currentInterval*2,this.maxBackoffMs),this.lastSnapshot=e,e.errors?.includes(It)||this.setStatus("ready");return}this.lastSnapshot=e,this.currentInterval=this.baseIntervalMs,e.errors?.includes(It)?(this.currentInterval=xr,this.setStatus("unavailable",It)):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(oo,this.currentInterval):this.currentInterval;this.timer=window.setTimeout(()=>{this.timer=void 0,this.runOnce()},e)}settleResolve(e,i){const c=this.pending.get(e);c&&(window.clearTimeout(c.timer),this.pending.delete(e),c.resolve(i))}settleReject(e,i){const c=this.pending.get(e);c&&(window.clearTimeout(c.timer),this.pending.delete(e),c.reject(i))}failAllPending(e){for(const[i,c]of this.pending.entries())window.clearTimeout(c.timer),c.reject(new Error(e)),this.pending.delete(i)}}class co{generation=0;tail=Promise.resolve();get currentGeneration(){return this.generation}enqueue(e){const i=++this.generation;return this.append(i,e)}enqueueCurrent(e){return this.append(this.generation,e)}append(e,i){const c={generation:e,isCurrent:()=>e===this.generation},l=this.tail.then(()=>i(c));return this.tail=l.catch(()=>{}),l}invalidate(){++this.generation}}function ao(r){if(!r||typeof r!="object")return null;const e=r;if(e.type!=="cameraRequest"||typeof e.active!="boolean")return null;const i={active:e.active};return(e.facingMode==="user"||e.facingMode==="environment")&&(i.facingMode=e.facingMode),i}function uo(r){const e={frameRate:{ideal:30,max:30}};return r?.facingMode&&(e.facingMode={ideal:r.facingMode}),e}function lo(r,e){return!r||r.facingMode!==e.facingMode}function fo(r){const e=r.getSettings();return{width:e.width,height:e.height,frameRate:e.frameRate,deviceId:e.deviceId,label:r.label||void 0,facingMode:e.facingMode}}function ho(r){return{type:"cameraResult",granted:!0,camera:fo(r)}}const mo=async r=>{if(!r)return!1;try{if(typeof navigator<"u"&&navigator.clipboard?.writeText)return await navigator.clipboard.writeText(r),!0}catch{}try{const e=document.createElement("textarea");e.value=r,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();const i=document.execCommand("copy");return document.body.removeChild(e),i}catch{return!1}},po=f.memo(function({element:e,screen:i,highlighted:c,selected:l,selectable:u,onClick:C}){const O=Vr(e.frame,i);if(!O)return null;const R=rr(e);return g.jsx("button",{type:"button",className:be("rc-inspect-box",!e.enabled&&"rc-inspect-box-disabled"),"data-ax-id":e.id,"data-ax-path":e.path,"data-ax-label":e.label||void 0,"data-ax-role":e.role||void 0,"data-highlighted":c?"true":"false","data-selected":l?"true":"false","aria-label":R,onClick:_=>{u&&(_.preventDefault(),_.stopPropagation(),C(e,{x:_.clientX,y:_.clientY}))},style:{left:`${O.x/i.width*100}%`,top:`${O.y/i.height*100}%`,width:`${O.width/i.width*100}%`,height:`${O.height/i.height*100}%`}})},(r,e)=>r.highlighted===e.highlighted&&r.selected===e.selected&&r.selectable===e.selectable&&r.screen.width===e.screen.width&&r.screen.height===e.screen.height&&r.onClick===e.onClick&&er(r.element,e.element)),Eo=260,go=220,Co=6,yo=8,vo=f.memo(function({element:e,platform:i,anchor:c,cursorAnchored:l,showActions:u,onTap:C}){const[O,R]=f.useState(null);f.useEffect(()=>{if(!O)return;const P=window.setTimeout(()=>R(null),1100);return()=>window.clearTimeout(P)},[O]);const _=f.useMemo(()=>{const P=Eo,J=go,Z=Co,A=yo,F=typeof window<"u"?window.innerWidth:1024,ee=typeof window<"u"?window.innerHeight:768,Ne=c.x+Z+P<=F-A,pe=c.y-Z-J>=A;let j=Ne?c.x+Z:c.x-Z,Ie=pe?c.y-Z:c.y+Z;const oe=`translate(${Ne?"0":"-100%"}, ${pe?"-100%":"0"})`;return j=Math.max(A+(Ne?0:P),Math.min(F-A-(Ne?P:0),j)),Ie=Math.max(A+(pe?J:0),Math.min(ee-A-(pe?0:J),Ie)),{left:`${j}px`,top:`${Ie}px`,transform:oe}},[c.x,c.y]),b=f.useMemo(()=>Jr(e,i),[e,i]),N=i==="ios"?e.selectors.AXUniqueId:e.selectors.resourceId,G=i==="ios"?"AXUniqueId":"resourceId",Q=f.useCallback(async(P,J)=>{if(!P)return;await mo(P)&&R(J)},[]),ue=zr(e),Ce=e.label||e.value||ue,me=rr(e);return kn.createPortal(g.jsxs("div",{className:"rc-inspect-card","data-cursor-anchored":l?"true":"false",style:_,onClick:P=>P.stopPropagation(),onMouseDown:P=>P.stopPropagation(),onMouseMove:P=>P.stopPropagation(),children:[g.jsxs("div",{className:"rc-inspect-card-header",children:[g.jsx("span",{className:"rc-inspect-card-role",children:ue}),!e.enabled&&g.jsx("span",{className:"rc-inspect-card-tag",children:"disabled"}),e.focused&&g.jsx("span",{className:"rc-inspect-card-tag rc-inspect-card-tag-blue",children:"focused"})]}),g.jsx("p",{className:"rc-inspect-card-title",title:me,children:Ce}),N&&g.jsxs("div",{className:"rc-inspect-card-row",children:[g.jsxs("span",{className:"rc-inspect-card-row-label",children:[G,":"]}),g.jsx("span",{className:"rc-inspect-card-row-value",children:N})]}),e.value&&e.value!==e.label&&g.jsxs("div",{className:"rc-inspect-card-row",children:[g.jsx("span",{className:"rc-inspect-card-row-label",children:"value:"}),g.jsx("span",{className:"rc-inspect-card-row-value",children:e.value})]}),g.jsxs("div",{className:"rc-inspect-card-row",children:[g.jsx("span",{className:"rc-inspect-card-row-label",children:"frame:"}),g.jsxs("span",{className:"rc-inspect-card-row-value",children:[Math.round(e.frame.width),"×",Math.round(e.frame.height)," @ ",Math.round(e.frame.x),",",Math.round(e.frame.y)]})]}),u&&g.jsxs("div",{className:"rc-inspect-card-actions",children:[g.jsx("button",{type:"button",className:"rc-inspect-card-btn rc-inspect-card-btn-primary",onClick:()=>C(e,c),children:"Tap"}),g.jsx("button",{type:"button",className:be("rc-inspect-card-btn",O==="selector"&&"rc-inspect-card-btn-copied"),disabled:!b,title:b??"No usable selector for this element",onClick:()=>Q(b??void 0,"selector"),children:O==="selector"?"Copied!":"Copy selector"}),g.jsx("button",{type:"button",className:be("rc-inspect-card-btn",O==="id"&&"rc-inspect-card-btn-copied"),disabled:!N,title:N??`No ${G}`,onClick:()=>Q(N,"id"),children:O==="id"?"Copied!":`Copy ${G}`})]})]}),document.body)}),Oo=f.memo(function({snapshot:e,geometry:i,highlightedId:c,selectedId:l,mode:u,cursorPosition:C,frozenCursorPosition:O,onSelectChange:R,onTapElement:_}){const b=u==="select",N=b?c!==null&&c!==l:c!==null,G=b?c??l:c,Q=f.useMemo(()=>{const A=new Map;if(!e)return A;for(const F of e.elements)A.set(F.id,F);return A},[e]),ue=f.useMemo(()=>G?Q.get(G)??null:null,[G,Q]);if(!(!!e&&!!i&&e.screen.width>0&&e.screen.height>0&&e.elements.length>0))return null;const me=N?C:O??C,P=N,J=b&&!N&&l!==null,Z=A=>{b&&A.target===A.currentTarget&&R(null,null)};return g.jsxs(g.Fragment,{children:[g.jsx("div",{className:be("rc-inspect-overlay",b&&"rc-inspect-overlay-select"),style:{left:`${i.left}px`,top:`${i.top}px`,width:`${i.width}px`,height:`${i.height}px`},onClick:Z,children:e.elements.map(A=>g.jsx(po,{element:A,screen:e.screen,highlighted:A.id===c,selected:A.id===l,selectable:b,onClick:R},A.id))}),ue&&me&&g.jsx(vo,{element:ue,platform:e.platform,anchor:me,cursorAnchored:P,showActions:J,onTap:_})]})}),Qr=()=>Promise.resolve().then(()=>require("./duo-view-BAh-w2Kz.js")).then(r=>r.duoView),_o=f.lazy(Qr),H=(...r)=>{window.debugRemoteControl&&console.log(...r)},S=(...r)=>{window.debugRemoteControl&&console.warn(...r)},W=(r,e,...i)=>{if(e)try{e(...i)}catch(c){console.error(`[RemoteControl] customer callback "${r}" threw:`,c)}},Nt=r=>Object.entries(L).find(([i,c])=>i.startsWith("ACTION_")&&c===r)?.[0]??String(r),Do=r=>r.includes("/android_")?"android":"ios",kr=(r,e)=>{const i=new URL(r);return i.searchParams.set("token",e),i.toString()},Pr=1920,Ur=1200,Qt=3,To=1e3,Ro=15e3,wo=3e3,So=4e3,Mo=(r,e)=>r===Pr&&e===Ur||r===Ur&&e===Pr,Ao={ios:{videoBorderRadiusMultiplier:.15,loadingLogoSize:"20%",videoPosition:{portrait:{heightMultiplier:.9678},landscape:{widthMultiplier:.9678}}},android:{videoBorderRadiusMultiplier:.13,loadingLogoSize:"40%",videoPosition:{portrait:{heightMultiplier:.967},landscape:{widthMultiplier:.962}}}};function bo(r){const e=r.code,i=Xr[e];if(!i)return S(`Unknown event.code: ${e}, key: ${r.key}`),null;let c=a.META_NONE;const l=e>="KeyA"&&e<="KeyZ",u=r.getModifierState("CapsLock"),C=r.shiftKey;let O=C;return l&&(O=C!==u),O&&(c|=a.META_SHIFT_ON),r.ctrlKey&&(c|=a.META_CTRL_ON),r.altKey&&(c|=a.META_ALT_ON),r.metaKey&&(c|=a.META_META_ON),{keycode:i,metaState:c}}const No=f.forwardRef(({className:r,url:e,token:i,sessionId:c,openUrl:l,showFrame:u=!0,deviceModel:C,duoModelUrl:O,autoReconnect:R=!1,onTerminated:_,assets:b,onConnectionStateChange:N,inspectMode:G,onAxSnapshotChange:Q,onInspectSelectionChange:ue,onAxStatusChange:Ce,axPollIntervalMs:me,axMaxBackoffMs:P,androidElementTreeOptions:J,onCameraDemandChange:Z,onCameraStats:A,microphoneEnabled:F=!1,onMicrophoneStateChange:ee},Ne)=>{const pe=f.useRef(null),j=f.useRef(null),Ie=f.useRef(null),[nr,or]=f.useState(!1),oe=C==="iphone-duo"||nr;f.useEffect(()=>{oe&&Qr().catch(()=>{})},[oe]);const ze=f.useRef(null),[xt,ir]=f.useState(null),[sr,cr]=f.useState(),Ye=f.useRef(new Map),kt=(t,s)=>new Promise((o,n)=>{const h=w.current;if(!h||h.readyState!==WebSocket.OPEN){n(new Error("Simulator disconnected"));return}const d=crypto.randomUUID(),p=setTimeout(()=>{Ye.current.delete(d),n(new Error("Device control timed out"))},5e3);Ye.current.set(d,{resolve:o,reject:n,timer:p}),h.send(JSON.stringify({type:t,id:d,...s}))}),[Zr,Pt]=f.useState(!1),[en,ht]=f.useState(!1),[tn,ar]=f.useState(!1),Ke=f.useRef(!1),Ut=f.useRef(!1),[ur,rn]=f.useState(!1),[nn,on]=f.useState(!1),[sn,dr]=f.useState({}),w=f.useRef(null),X=f.useRef(null),U=f.useRef(null),xe=f.useRef(void 0),Qe=f.useRef(void 0),Ze=f.useRef(void 0),mt=f.useRef(void 0),ke=f.useRef(void 0),Oe=f.useRef(0),pt=f.useRef(0),Pe=f.useRef(!1),Lt=f.useRef(R);Lt.current=R;const _e=f.useRef(null),ie=f.useRef(null),De=f.useRef(void 0),Ft=f.useMemo(()=>new co,[]),Ee=f.useRef(Z);Ee.current=Z;const Et=f.useRef(A);Et.current=A;const et=f.useRef(null),gt=f.useRef(null),Wt=f.useRef(F);Wt.current=F;const Ht=f.useRef(!1),tt=f.useRef(ee);tt.current=ee;const rt=f.useRef(null),fe=f.useRef(null),Ct=f.useRef(0),lr=f.useRef(Promise.resolve()),Ue=f.useRef(null),nt=f.useRef(!1),ye=f.useRef(new Map),ge=f.useRef(new Map),Te=f.useRef(new Map),Re=f.useRef(new Map),z=f.useRef(new Map),we=f.useRef(!1),[cn,an]=f.useState(!1),B=f.useRef(null),Le=f.useRef(null),ot=f.useRef({handle:()=>{},end:()=>{}}),[Se,yt]=f.useState(null),te=f.useRef(null),[fr,hr]=f.useState(null),[jt,it]=f.useState(null),[Xt,vt]=f.useState(null),[un,mr]=f.useState(null),[dn,pr]=f.useState(null),Ot=f.useRef(null),ae=f.useRef(void 0),Er=t=>{Ot.current=t,ae.current===void 0&&(ae.current=window.requestAnimationFrame(()=>{ae.current=void 0,pr(Ot.current)}))},[ln,Fe]=f.useState(null),We=f.useRef(G);We.current=G;const He=f.useRef(null);He.current=fr;const $t=f.useRef(Q);$t.current=Q;const je=f.useRef(ue);je.current=ue;const gr=f.useRef(Ce);gr.current=Ce;const Cr=f.useRef(_);Cr.current=_;const yr=f.useRef(N);yr.current=N;const Bt=f.useRef(null),Xe=t=>{Bt.current!==t&&(Bt.current=t,W("onConnectionStateChange",yr.current,t))},st=G===!0||G==="hover-only",fn=G==="hover-only"?"hover-only":"select",de=f.useMemo(()=>c||Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15),[c]),he=f.useMemo(()=>Do(e),[e]),$e=Ao[he],ct=b?.[he],vr=he==="android"&&nn?ur?ct?.tabletFrameLandscape:ct?.tabletFrame:ur?ct?.frameLandscape:ct?.frame,at=ct?.loadingLogo,_t=!oe&&u&&!!vr,x=t=>{H(t)},le=t=>{!U.current||U.current.readyState!=="open"||(U.current.send(t),te.current?.bumpActivity())},Or=-10,_r=(t,s)=>{const o=ut();if(!o)return;const n=qe(o,t,s);if(!n)return;const{videoX:h,videoY:d,videoWidth:p,videoHeight:y}=n,v=bt(L.ACTION_DOWN,Or,p,y,h,d,1,L.BUTTON_PRIMARY,L.BUTTON_PRIMARY);v&&le(v),window.setTimeout(()=>{const E=bt(L.ACTION_UP,Or,p,y,h,d,0,L.BUTTON_PRIMARY,L.BUTTON_PRIMARY);E&&le(E)},60)},hn=(t,s)=>{const o=ut();if(!o||s.screen.width<=0||s.screen.height<=0)return;const n=t.frame.x+t.frame.width/2,h=t.frame.y+t.frame.height/2,d=n/s.screen.width*o.actualWidth,p=h/s.screen.height*o.actualHeight,y=o.videoRect.left+o.offsetX+d,v=o.videoRect.top+o.offsetY+p;_r(y,v)},Dt=-1,Tt=-2,Me=-3,Be=(t,s,o,n,h,d)=>{const p=bt(t,s,o,n,h,d,1,L.BUTTON_PRIMARY,L.BUTTON_PRIMARY);p&&(H("[rc-touch] sendSingleTouch",{action:t,actionName:Nt(t),pointerId:s,x:h,y:d,video:{width:o,height:n}}),le(p))},Ae=(t,s,o)=>{if(!o)return;const{videoX:n,videoY:h,videoWidth:d,videoHeight:p}=o;let y=null,v=null,E=1;const I=L.BUTTON_PRIMARY;switch(s){case"down":t!==Me&&ot.current.end(),y=z.current.size===0?L.ACTION_DOWN:L.ACTION_POINTER_DOWN,v={x:n,y:h},z.current.set(t,v),t===-1&&j.current?.focus();break;case"move":z.current.has(t)&&(y=L.ACTION_MOVE,v={x:n,y:h},z.current.set(t,v));break;case"up":case"cancel":z.current.has(t)&&(v=z.current.get(t),z.current.delete(t),s==="cancel"?y=L.ACTION_CANCEL:y=z.current.size===0?L.ACTION_UP:L.ACTION_POINTER_UP);break}if(y!==null&&v!==null){H("[rc-touch][mouse->touch] sending",{pointerId:t,eventType:s,action:y,actionName:Nt(y),positionToSend:v,video:{width:d,height:p},altHeld:we.current,activePointersAfter:Array.from(z.current.entries()).map(([Y,$])=>({id:Y,x:$.x,y:$.y}))});const T=bt(y,t,d,p,v.x,v.y,E,I,I);T&&(H("[rc-touch][mouse->touch] buffer",{pointerId:t,actionName:Nt(y),byteLength:T.byteLength}),le(T))}else(s==="up"||s==="cancel")&&z.current.delete(t)},qt=t=>{if(we.current!==t&&(we.current=t,an(t),t||yt(null),H("[rc-touch][alt] updateAltHeld",{nextHeld:t,activePointerIds:Array.from(z.current.keys())}),he==="ios"&&U.current&&U.current.readyState==="open")){const s=t?a.ACTION_DOWN:a.ACTION_UP,o=ft(s,a.KEYCODE_ALT_LEFT,0,a.META_NONE);H("[rc-touch][alt] sending Indigo modifier keycode",{action:s,keycode:a.KEYCODE_ALT_LEFT}),o&&le(o)}},ut=()=>{const t=j.current,s=pe.current;if(!t||!s)return null;const o=t.videoWidth,n=t.videoHeight;if(!o||!n)return null;const h=t.getBoundingClientRect(),d=s.getBoundingClientRect(),p=h.width,y=h.height,v=o/n,E=p/y;let I=p,T=y;v>E?T=p/v:I=y*v;const Y=(p-I)/2,$=(y-T)/2;return{videoWidth:o,videoHeight:n,videoRect:h,containerRect:d,actualWidth:I,actualHeight:T,offsetX:Y,offsetY:$}},qe=(t,s,o)=>{const n=s-t.videoRect.left-t.offsetX,h=o-t.videoRect.top-t.offsetY,d=Math.max(0,Math.min(t.actualWidth,n)),p=Math.max(0,Math.min(t.actualHeight,h)),y=Math.max(0,Math.min(t.videoWidth,d/t.actualWidth*t.videoWidth)),v=Math.max(0,Math.min(t.videoHeight,p/t.actualHeight*t.videoHeight));return{videoX:y,videoY:v,videoWidth:t.videoWidth,videoHeight:t.videoHeight}},mn=(t,s,o)=>{const n=s-t.videoRect.left-t.offsetX,h=o-t.videoRect.top-t.offsetY,d=Math.max(0,Math.min(t.actualWidth,n)),p=Math.max(0,Math.min(t.actualHeight,h)),y=Math.max(0,Math.min(t.videoWidth,d/t.actualWidth*t.videoWidth)),v=Math.max(0,Math.min(t.videoHeight,p/t.actualHeight*t.videoHeight)),E=t.videoWidth-y,I=t.videoHeight-v,T=t.videoRect.left+t.offsetX,Y=t.videoRect.top+t.offsetY,$=T-t.containerRect.left+d,se=Y-t.containerRect.top+p,V=T-t.containerRect.left+(t.actualWidth-d),D=Y-t.containerRect.top+(t.actualHeight-p);return{containerX:$,containerY:se,mirrorContainerX:V,mirrorContainerY:D,videoX:y,videoY:v,mirrorVideoX:E,mirrorVideoY:I,videoWidth:t.videoWidth,videoHeight:t.videoHeight}},pn=(t,s,o,n,h,d,p)=>{const y=Bn(t,s,o,n,h,d,p);H("[rc-touch2] sendTwoFingerMessage (iOS)",{actionName:Nt(t),video:{width:s,height:o},p0:{x:n,y:h},p1:{x:d,y:p},byteLength:y.byteLength}),le(y)},Ve=(t,s,o,n,h,d,p,y,v)=>{if(H("[rc-touch2] applyTwoFingerEvent",{platform:he,eventType:t,video:{width:s,height:o},p0:{x:n,y:h,id:y},p1:{x:d,y:p,id:v}}),t==="down"&&ot.current.end(),he==="ios"){const E=t==="down"?L.ACTION_DOWN:t==="move"?L.ACTION_MOVE:L.ACTION_UP;pn(E,s,o,n,h,d,p)}else t==="down"?(Be(L.ACTION_DOWN,y,s,o,n,h),Be(L.ACTION_POINTER_DOWN,v,s,o,d,p)):t==="move"?(Be(L.ACTION_MOVE,y,s,o,n,h),Be(L.ACTION_MOVE,v,s,o,d,p)):(Be(L.ACTION_POINTER_UP,v,s,o,d,p),Be(L.ACTION_UP,y,s,o,n,h))},En=(t,s,o)=>{if(!we.current){Se!==null&&yt(null);return}const n=mn(t,s,o);yt(n)},gn=(t,s,o)=>{const n=He.current;if(!n||n.screen.width<=0||n.screen.height<=0)return null;const h=s-t.videoRect.left-t.offsetX,d=o-t.videoRect.top-t.offsetY;if(h<0||d<0||h>t.actualWidth||d>t.actualHeight)return null;const p=h/t.actualWidth*n.screen.width,y=d/t.actualHeight*n.screen.height;return Gr(n,p,y)},ve=t=>{if(oe)return;t.preventDefault(),t.stopPropagation();const s=ut();if((We.current===!0||We.current==="hover-only")&&!("touches"in t))if(t.type==="mousemove"){if(Er({x:t.clientX,y:t.clientY}),s){const n=gn(s,t.clientX,t.clientY);it(n?.id??null)}}else t.type==="mouseleave"&&(Er(null),it(null));if(We.current!==!0&&(!("touches"in t)&&s&&(t.type==="mousemove"?En(s,t.clientX,t.clientY):t.type==="mouseleave"&&yt(null)),!(!U.current||U.current.readyState!=="open"||!j.current||!s)))if("touches"in t){const n=t.touches,h=t.changedTouches;let d;switch(t.type){case"touchstart":d="down";break;case"touchmove":d="move";break;case"touchend":d="up";break;case"touchcancel":d="cancel";break;default:return}if(n.length===2){const p=n[0],y=n[1],v=qe(s,p.clientX,p.clientY),E=qe(s,y.clientX,y.clientY);if(!v||!E)return;B.current?B.current.source==="real-touch"&&(B.current.finger0={x:v.videoX,y:v.videoY},B.current.finger1={x:E.videoX,y:E.videoY},Ve("move",v.videoWidth,v.videoHeight,v.videoX,v.videoY,E.videoX,E.videoY,B.current.pointerId0,B.current.pointerId1)):(B.current={finger0:{x:v.videoX,y:v.videoY},finger1:{x:E.videoX,y:E.videoY},videoSize:{width:v.videoWidth,height:v.videoHeight},source:"real-touch",pointerId0:p.identifier,pointerId1:y.identifier},Ve("down",v.videoWidth,v.videoHeight,v.videoX,v.videoY,E.videoX,E.videoY,p.identifier,y.identifier))}else if(n.length<2&&B.current?.source==="real-touch"){const p=B.current;Ve("up",p.videoSize.width,p.videoSize.height,p.finger0.x,p.finger0.y,p.finger1.x,p.finger1.y,p.pointerId0,p.pointerId1),B.current=null;return}else{if(n.length>2)return;{const p=h[0];if(p){const y=qe(s,p.clientX,p.clientY);Ae(p.identifier,d,y)}}}}else{let h=null;const d=B.current?.source==="alt-mouse";switch(t.type){case"mousedown":t.button===0&&(h="down");break;case"mousemove":(d||z.current.has(-1))&&(h="move");break;case"mouseup":t.button===0&&(h="up");break;case"mouseleave":(d||z.current.has(-1))&&(h="up");break}if(h){const p=qe(s,t.clientX,t.clientY);if(!p)return;H("[rc-touch][mouse] event",{domType:t.type,eventType:h,button:t.button,buttons:t.buttons,client:{x:t.clientX,y:t.clientY},altHeldRef:we.current,inTwoFingerMode:d,geometry:{videoX:p.videoX,videoY:p.videoY,videoWidth:p.videoWidth,videoHeight:p.videoHeight},activePointerIds:Array.from(z.current.keys())}),we.current||d?Cn(h,p):Ae(-1,h,p)}}},Cn=(t,s)=>{const{videoX:o,videoY:n,videoWidth:h,videoHeight:d}=s,p=h-o,y=d-n;if(t==="down"){B.current={finger0:{x:o,y:n},finger1:{x:p,y},videoSize:{width:h,height:d},source:"alt-mouse",pointerId0:Dt,pointerId1:Tt},j.current?.focus(),Ve("down",h,d,o,n,p,y,Dt,Tt);return}if(t==="move"){B.current?.source==="alt-mouse"&&(B.current.finger0={x:o,y:n},B.current.finger1={x:p,y},Ve("move",h,d,o,n,p,y,Dt,Tt));return}if(t==="up"||t==="cancel"){const v=B.current;if(v?.source==="alt-mouse"){const{finger0:E,finger1:I,videoSize:T}=v;Ve("up",T.width,T.height,E.x,E.y,I.x,I.y,Dt,Tt),B.current=null}return}},yn=150,Dr=()=>{const t=Le.current;t&&(window.clearTimeout(t.endTimer),Ae(Me,"up",t.pos),Le.current=null)},vn=t=>{if(t.ctrlKey||we.current||B.current)return;const s=z.current.size;if(s>1||s===1&&!z.current.has(Me))return;const o=ut();if(!o)return;const n=t.clientX-o.videoRect.left-o.offsetX,h=t.clientY-o.videoRect.top-o.offsetY;if(n<0||n>o.actualWidth||h<0||h>o.actualHeight)return;const d=qe(o,t.clientX,t.clientY);if(!d)return;t.preventDefault();const p=(t.deltaMode===1?16:t.deltaMode===2?o.actualWidth:1)*(o.videoWidth/o.actualWidth),y=(t.deltaMode===1?16:t.deltaMode===2?o.actualHeight:1)*(o.videoHeight/o.actualHeight),v=-t.deltaX*p,E=-t.deltaY*y,I=D=>{window.clearTimeout(D.endTimer),D.endTimer=window.setTimeout(Dr,yn)};if(v===0&&E===0){Le.current&&I(Le.current);return}const T=()=>({videoWidth:d.videoWidth,videoHeight:d.videoHeight,videoX:Math.abs(v)>Math.abs(E)?Math.min(Math.max(d.videoX,d.videoWidth*.2),d.videoWidth*.8):d.videoX,videoY:Math.abs(E)>=Math.abs(v)?Math.min(Math.max(d.videoY,d.videoHeight*.2),d.videoHeight*.8):d.videoY}),Y=D=>({...D,videoX:Math.min(Math.max(D.videoX+v,0),D.videoWidth),videoY:Math.min(Math.max(D.videoY+E,0),D.videoHeight)});let $=Le.current;if($)window.clearTimeout($.endTimer);else{const D=T();Ae(Me,"down",D),$={pos:D,endTimer:0},Le.current=$}let se=$.pos,V=Y(se);V.videoX===se.videoX&&V.videoY===se.videoY&&(Ae(Me,"up",se),se=T(),Ae(Me,"down",se),V=Y(se)),Ae(Me,"move",V),$.pos=V,I($)};f.useEffect(()=>{ot.current={handle:vn,end:Dr}}),f.useEffect(()=>{const t=pe.current;if(!t)return;const s=o=>ot.current.handle(o);return t.addEventListener("wheel",s,{passive:!1}),()=>{ot.current.end(),t.removeEventListener("wheel",s)}},[]),f.useEffect(()=>{const t=n=>{n.key==="Alt"&&qt(!0)},s=n=>{n.key==="Alt"&&qt(!1)},o=()=>{qt(!1)};return window.addEventListener("keydown",t,!0),window.addEventListener("keyup",s,!0),window.addEventListener("blur",o),()=>{window.removeEventListener("keydown",t,!0),window.removeEventListener("keyup",s,!0),window.removeEventListener("blur",o)}},[]);const Rt=t=>{t.preventDefault(),t.stopPropagation();const s=document.activeElement===j.current||oe&&document.activeElement===t.currentTarget;if(H("Keyboard event:",{type:t.type,key:t.key,keyCode:t.keyCode,code:t.code,target:t.target.tagName,focused:s}),!s){S("Simulator input not focused, skipping keyboard event");return}if(!U.current||U.current.readyState!=="open"){S("Data channel not ready for keyboard event:",U.current?.readyState);return}if(t.type==="keydown"){if(t.key.toLowerCase()==="v"&&(t.metaKey||t.ctrlKey)){H("Paste shortcut detected"),navigator.clipboard.readText().then(n=>{if(n){H("Pasting text via SET_CLIPBOARD:",n.substring(0,20)+(n.length>20?"...":""));const h=qn(n,!0);le(h)}}).catch(n=>{console.error("Failed to read clipboard contents: ",n)});return}if(t.key.toLowerCase()==="m"&&(t.metaKey||t.ctrlKey)){H("Menu shortcut detected");const n=ft(a.ACTION_DOWN,a.MENU,0,a.META_NONE);le(n);const h=ft(a.ACTION_UP,a.MENU,0,a.META_NONE);le(h);return}}const o=bo(t);if(o){const{keycode:n,metaState:h}=o,d=t.type==="keydown"?a.ACTION_DOWN:a.ACTION_UP;H(`Sending Keycode: key=${t.key}, code=${n}, action=${d}, meta=${h}`);const p=ft(d,n,0,h);le(p)}else H(`Ignoring unhandled key event: type=${t.type}, key=${t.key}`)},On=()=>{w.current&&w.current.readyState===WebSocket.OPEN&&w.current.send(JSON.stringify({type:"keepAlive",sessionId:de}))},Tr=()=>{xe.current&&window.clearInterval(xe.current),xe.current=window.setInterval(On,1e4)},Rr=()=>{xe.current&&(window.clearInterval(xe.current),xe.current=void 0)},wt=()=>{Qe.current&&(window.clearTimeout(Qe.current),Qe.current=void 0)},St=()=>{Ze.current&&(window.clearTimeout(Ze.current),Ze.current=void 0)},dt=()=>{mt.current&&(window.clearInterval(mt.current),mt.current=void 0)},lt=()=>{ke.current!==void 0&&(window.clearTimeout(ke.current),ke.current=void 0)},_n=()=>{nt.current||(nt.current=!0,dt(),Pt(!0),Xe("connected"))},re=t=>{for(const s of t.getTracks())try{s.stop()}catch(o){S("track.stop() failed:",o)}},Dn=()=>{const t=ie.current;t&&(ie.current=null,re(t))},wr=t=>{const s=lr.current.then(t).catch(o=>{S("microphone operation failed:",o)});return lr.current=s,s},Vt=()=>Wt.current||Ht.current,Sr=t=>{const s=`ui-mic-${Date.now()}-${Math.random().toString(36).substring(2,9)}`;Ue.current=s,t.send(JSON.stringify({type:"microphoneStart",id:s}))},Gt=()=>wr(()=>Tn()),Tn=async()=>{const t=Ct.current,s=()=>t===Ct.current&&Vt(),o=y=>{W("onMicrophoneStateChange",tt.current,{active:!1,error:y})};if(!s())return;const n=w.current,h=rt.current;if(!n||n.readyState!==WebSocket.OPEN||!h||fe.current)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)."),o("Microphone capture requires a secure context (https)");return}let d=null;try{d=await navigator.mediaDevices.getUserMedia({audio:!0,video:!1})}catch(y){console.warn("[RemoteControl] microphone getUserMedia denied/failed:",y)}if(!s()){d&&re(d);return}if(!d){o("Microphone permission denied or no device available");return}const p=d.getAudioTracks()[0]??null;if(!p){re(d),o("Captured stream has no audio track");return}try{await h.replaceTrack(p)}catch(y){S("replaceTrack(audioTrack) failed:",y),re(d),o("Failed to attach the microphone track to the connection");return}if(!s()){try{await h.replaceTrack(null)}catch(y){S("replaceTrack(null) on stale mic attach failed:",y)}re(d);return}fe.current=d,p.onended=()=>{fe.current===d&&Mt("microphone capture ended by the browser")},Sr(n),W("onMicrophoneStateChange",tt.current,{active:!0,label:p.label||void 0})},Mt=t=>(++Ct.current,Ue.current=null,wr(async()=>{const s=rt.current,o=fe.current;if(fe.current=null,s&&o)try{await s.replaceTrack(null)}catch(h){S("replaceTrack(null) on mic detach failed:",h)}o&&re(o);const n=w.current;if(o&&n&&n.readyState===WebSocket.OPEN){const h=`ui-mic-${Date.now()}-${Math.random().toString(36).substring(2,9)}`;n.send(JSON.stringify({type:"microphoneStop",id:h}))}(o||t)&&W("onMicrophoneStateChange",tt.current,{active:!1,...t!==void 0&&{error:t}})})),Mr=(t,s)=>{let o;try{o=ho(s),console.info(`[RemoteControl] camera capture: ${o.camera?.width}x${o.camera?.height} @ ${o.camera?.frameRate??"?"}fps`+(o.camera?.label?` — ${o.camera.label}`:""))}catch(n){S("getSettings() on outbound camera track failed:",n),o={type:"cameraResult",granted:!0,camera:{label:s.label||void 0}}}t.send(JSON.stringify(o)),W("onCameraDemandChange",Ee.current,!0,!0,o.camera)},Rn=t=>{if(!t)return;const s=t.indexOf("/"),n=(s>=0?t.slice(s+1):t).toUpperCase();return n==="HEVC"?"H265":n},wn=async()=>{const t=_e.current,s=Et.current;if(!t||!s)return;let o;try{o=await t.getStats()}catch{return}let n,h,d;if(o.forEach(Y=>{Y.type==="outbound-rtp"&&Y.kind==="video"?n=Y:Y.type==="remote-inbound-rtp"&&Y.kind==="video"&&(d=Y)}),n?.codecId){const Y=o.get(n.codecId);Y&&(h=Y.mimeType)}if(!n)return;const p=n.timestamp??Date.now(),y=gt.current;let v,E,I;if(y&&p>y.timestamp){const Y=(p-y.timestamp)/1e3;if(typeof n.framesEncoded=="number"&&typeof y.framesEncoded=="number"&&(v=Math.max(0,(n.framesEncoded-y.framesEncoded)/Y)),typeof n.bytesSent=="number"&&typeof y.bytesSent=="number"&&(E=Math.max(0,(n.bytesSent-y.bytesSent)*8/Y)),typeof n.packetsSent=="number"&&typeof y.packetsSent=="number"&&d&&typeof d.packetsLost=="number"&&typeof y.packetsLost=="number"){const $=n.packetsSent-y.packetsSent,se=d.packetsLost-y.packetsLost;$>0&&(I=Math.max(0,Math.min(100,se/$*100)))}}gt.current={timestamp:p,framesEncoded:n.framesEncoded,bytesSent:n.bytesSent,packetsSent:n.packetsSent,packetsLost:d?.packetsLost};const T={codec:Rn(h),encoderImplementation:n.encoderImplementation,hardwareAccelerated:typeof n.powerEfficientEncoder=="boolean"?n.powerEfficientEncoder:void 0,framesPerSecond:v,framesEncoded:n.framesEncoded,bitrateBps:E,width:n.frameWidth,height:n.frameHeight,qualityLimitationReason:n.qualityLimitationReason,rttMs:typeof d?.roundTripTime=="number"?d.roundTripTime*1e3:void 0,packetsLostPct:I};W("onCameraStats",Et.current,T)},Ar=()=>{et.current===null&&(gt.current=null,et.current=setInterval(()=>{wn()},1e3))},At=()=>{et.current!==null&&(clearInterval(et.current),et.current=null),gt.current=null,W("onCameraStats",Et.current,null)},Sn=(t,s,o,n)=>Ft.enqueue(async({isCurrent:h})=>{const d=()=>h()&&n()&&w.current===s&&_e.current===o;if(!d())return;if(!t.active){const T=ie.current;try{await o.replaceTrack(null)}catch(Y){S("replaceTrack(null) on camera detach failed:",Y)}if(ie.current===T&&(ie.current=null,De.current=void 0,T&&re(T)),At(),!d())return;W("onCameraDemandChange",Ee.current,!1);return}W("onCameraDemandChange",Ee.current,!0);const p=ie.current,y=p?.getVideoTracks()[0],v=De.current;if(y?.readyState==="live"&&v&&!lo(v,t)){De.current=t,Mr(s,y),Ar();return}if(p){try{await o.replaceTrack(null)}catch(T){S("replaceTrack(null) before camera switch failed:",T)}if(ie.current===p&&(ie.current=null,De.current=void 0,re(p)),At(),!d())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."),!d())return;s.send(JSON.stringify({type:"cameraResult",granted:!1})),W("onCameraDemandChange",Ee.current,!0,!1);return}let E=null;try{E=await navigator.mediaDevices.getUserMedia({video:uo(t),audio:!1})}catch(T){console.warn("[RemoteControl] getUserMedia denied/failed:",T)}if(!d()){E&&re(E);return}if(!E){s.send(JSON.stringify({type:"cameraResult",granted:!1})),W("onCameraDemandChange",Ee.current,!0,!1);return}const I=E.getVideoTracks()[0]??null;if(!I){if(re(E),!d())return;s.send(JSON.stringify({type:"cameraResult",granted:!1})),W("onCameraDemandChange",Ee.current,!0,!1);return}try{I.contentHint="motion"}catch{}try{await o.replaceTrack(I)}catch(T){if(S("replaceTrack(videoTrack) failed:",T),re(E),!d())return;s.send(JSON.stringify({type:"cameraResult",granted:!1})),W("onCameraDemandChange",Ee.current,!0,!1);return}if(!d()){try{await o.replaceTrack(null)}catch(T){S("replaceTrack(null) for stale camera attach failed:",T)}re(E);return}try{const T=o.getParameters();(!T.encodings||T.encodings.length===0)&&(T.encodings=[{}]),T.encodings[0].maxBitrate=8e6,T.encodings[0].maxFramerate=30,T.degradationPreference="maintain-framerate",await o.setParameters(T)}catch(T){S("setParameters on outbound camera failed:",T)}if(!d()){try{await o.replaceTrack(null)}catch(T){S("replaceTrack(null) for stale camera finalize failed:",T)}re(E);return}ie.current=E,De.current=t,I.onended=()=>{ie.current===E&&Ft.enqueueCurrent(async({isCurrent:T})=>{if(!(!T()||ie.current!==E||!n()||w.current!==s||_e.current!==o)){try{await o.replaceTrack(null)}catch(Y){S("replaceTrack(null) after camera ended failed:",Y)}!T()||ie.current!==E||!n()||w.current!==s||_e.current!==o||(ie.current=null,De.current=void 0,re(E),At(),s.send(JSON.stringify({type:"cameraResult",granted:!1})),W("onCameraDemandChange",Ee.current,!0,!1))}}).catch(T=>S("camera ended cleanup failed:",T))},d()&&(Mr(s,I),Ar())}),Ge=()=>{for(const t of Ye.current.values())clearTimeout(t.timer),t.reject(new Error("Simulator disconnected"));Ye.current.clear(),ir(null),ze.current&&(ze.current.srcObject=null),St(),lt(),dt(),te.current&&(te.current.stop(),te.current=null),Ft.invalidate(),At(),Dn(),De.current=void 0,_e.current=null,++Ct.current,Ht.current=!1,Ue.current=null,fe.current&&(re(fe.current),fe.current=null,W("onMicrophoneStateChange",tt.current,{active:!1})),rt.current=null,ae.current!==void 0&&(window.cancelAnimationFrame(ae.current),ae.current=void 0),w.current&&(w.current.onopen=null,w.current.onmessage=null,w.current.onerror=null,w.current.onclose=null,w.current.close(),w.current=null),X.current&&(X.current.onconnectionstatechange=null,X.current.oniceconnectionstatechange=null,X.current.ontrack=null,X.current.onicecandidate=null,X.current.close(),X.current=null),j.current&&(j.current.srcObject=null),U.current&&(U.current.onopen=null,U.current.onclose=null,U.current.onerror=null,U.current.close(),U.current=null)},br=()=>{document.hidden?Rr():Tr()},Mn=async()=>{if(typeof navigator<"u"&&navigator.onLine===!1)return!1;let t;try{const n=new URL(e);n.protocol=n.protocol==="wss:"?"https:":n.protocol==="ws:"?"http:":n.protocol,t=kr(n.toString(),i)}catch{return!1}const s=new AbortController,o=window.setTimeout(()=>s.abort(),So);try{return(await fetch(t,{method:"GET",cache:"no-store",signal:s.signal})).status===404}catch{return!1}finally{window.clearTimeout(o)}},An=()=>{Ke.current||(Ke.current=!0,ar(!0),ht(!1),Oe.current+=1,wt(),St(),lt(),Ge(),x("Instance terminated"),Xe("terminated"),W("onTerminated",Cr.current))},bn=()=>{Ke.current||Ut.current||(Ut.current=!0,Mn().then(t=>{Ut.current=!1,t&&An()}))},Je=(t,s)=>{if(Ke.current||s!==Oe.current)return;if(bn(),Pe.current){if(!Lt.current){x(`Connection failed after it was established: ${t}`),ht(!0),Xe("failed"),Ge();return}x(`Reconnecting after established session dropped: ${t}`),Pe.current=!1,pt.current=-1}wt();const o=pt.current+1;if(o>=Qt){x(`Connection failed after ${Qt} attempts: ${t}`),ht(!0),Xe("failed"),Ge();return}x(`Retrying connection (${o+1}/${Qt})`),Xe("reconnecting"),Ge(),Qe.current=window.setTimeout(()=>{Qe.current=void 0,s===Oe.current&&Nr(o)},To)},Nr=async(t=0)=>{if(Ke.current)return;const s=Oe.current+1;Oe.current=s,pt.current=t,Pe.current=!1,ht(!1),t===0&&Bt.current!=="reconnecting"&&Xe("connecting"),wt(),St(),dt(),nt.current=!1,Pt(!1),Ge();const o=()=>s===Oe.current;Ze.current=window.setTimeout(()=>{Ze.current=void 0,!(!o()||Pe.current)&&Je("Connection did not succeed within 15 seconds",s)},Ro);try{const n=new WebSocket(kr(e,i));if(w.current=n,await new Promise((D,m)=>{let k=!1;const ne=window.setTimeout(()=>m(new Error("WebSocket connection timeout")),3e4),M=K=>{k||(k=!0,window.clearTimeout(ne),K())};n.onopen=()=>{!o()||w.current!==n||M(D)},n.onerror=K=>{!o()||w.current!==n||(x("WebSocket error: "+K),M(()=>m(new Error("WebSocket connection failed"))))},n.onclose=()=>{!o()||w.current!==n||(x("WebSocket closed"),M(()=>m(new Error("WebSocket closed before connection was established"))))}}),!o()||w.current!==n)return;n.onerror=D=>{!o()||w.current!==n||x("WebSocket error: "+D)},n.onclose=()=>{!o()||w.current!==n||x("WebSocket closed")};const h=new Promise((D,m)=>{const k=K=>{window.clearTimeout(ne),n.removeEventListener("message",M),K()},ne=window.setTimeout(()=>k(()=>m(new Error("RTCConfiguration timeout"))),3e4),M=K=>{if(!(!o()||w.current!==n))try{const q=JSON.parse(K.data);if(q.type==="signalingError"&&q.requestType==="requestRtcConfiguration"&&q.sessionId===de){const ce=typeof q.error=="string"?q.error:"Unable to load streaming configuration";k(()=>m(new Error(ce)))}else q.type==="rtcConfiguration"&&k(()=>D({rtcConfiguration:q.rtcConfiguration,cameraSupported:q.cameraSupported===!0,foldSupported:q.foldSupported===!0}))}catch(q){console.error("Error handling RTC configuration:",q),k(()=>m(q))}};n.addEventListener("message",M),n.send(JSON.stringify({type:"requestRtcConfiguration",sessionId:de}))}),{rtcConfiguration:d,cameraSupported:p,foldSupported:y}=await h;if(!o()||w.current!==n)return;const v=C==="iphone-duo"||y;or(v);const E=new RTCPeerConnection(d);X.current=E,E.addTransceiver("audio",{direction:"recvonly"});const I=E.addTransceiver("video",{direction:"recvonly"}),T=v?E.addTransceiver("video",{direction:"recvonly"}):null,Y=he==="ios"||p,$=Y?E.addTransceiver("video",{direction:"sendonly"}):null;_e.current=$?.sender??null;const se=Y?E.addTransceiver("audio",{direction:"sendonly"}):null;if(rt.current=se?.sender??null,RTCRtpReceiver.getCapabilities){const D=RTCRtpReceiver.getCapabilities("video");if(D&&D.codecs){const k=D.codecs.sort((ne,M)=>{const K=q=>{const ce=q.mimeType.toLowerCase();return ce.includes("vp9")?1:ce.includes("h265")||ce.includes("hevc")?2:ce.includes("h264")||ce.includes("avc")?3:4};return K(ne)-K(M)});I.setCodecPreferences(k),T?.setCodecPreferences(k),H("Set codec preferences:",k.map(ne=>ne.mimeType).join(", "))}}if($&&RTCRtpSender.getCapabilities){const D=RTCRtpSender.getCapabilities("video");if(D&&D.codecs){const m=new Set(["42e01f","42e028","640c1f"]),k=M=>{const K=M.mimeType.toLowerCase(),ce=(M.sdpFmtpLine||"").toLowerCase().match(/profile-level-id=([0-9a-f]{6})/),xn=ce?ce[1]:"";return K==="video/h265"||K==="video/hevc"?1:K==="video/h264"&&m.has(xn)?2:K==="video/h264"?3:K==="video/vp9"?4:K==="video/vp8"?5:K==="video/rtx"||K==="video/red"||K==="video/ulpfec"?0:6},ne=[...D.codecs].sort((M,K)=>k(M)-k(K));try{$.setCodecPreferences(ne),H("Outbound camera codec preferences:",ne.map(M=>`${M.mimeType}${M.sdpFmtpLine?`[${M.sdpFmtpLine}]`:""}`).join(", "))}catch(M){S("Failed to set outbound camera codec preferences:",M)}}}const V=E.createDataChannel("control",{ordered:!0,negotiated:!0,id:1});if(U.current=V,V.onopen=()=>{if(!o()||U.current!==V||w.current!==n)return;Pe.current=!0,St(),x("Control channel opened"),te.current||(te.current=new so({platform:he,baseIntervalMs:me,maxBackoffMs:P,androidElementTreeOptions:J,send:m=>{if(!w.current||w.current.readyState!==WebSocket.OPEN)return!1;try{return w.current.send(JSON.stringify(m)),!0}catch{return!1}},onSnapshot:m=>{hr(k=>tr(k,m)?k:m),queueMicrotask(()=>{W("onAxSnapshotChange",$t.current,m)})},onStatusChange:(m,k)=>{W("onAxStatusChange",gr.current,m,k)}}),(We.current===!0||We.current==="hover-only")&&te.current.start());const D=()=>{!o()||nt.current||U.current!==V||w.current!==n||n.readyState!==WebSocket.OPEN||n.send(JSON.stringify({type:"requestFrame",sessionId:de}))};if(D(),dt(),mt.current=window.setInterval(()=>{if(!o()||nt.current||U.current!==V||w.current!==n||n.readyState!==WebSocket.OPEN){dt();return}D()},250),l){try{const m=decodeURIComponent(l);x("Opening URL"),n.send(JSON.stringify({type:"openUrl",url:m,sessionId:de}))}catch(m){console.error({error:m},"Error decoding URL, falling back to the original URL"),n.send(JSON.stringify({type:"openUrl",url:l,sessionId:de}))}te.current?.bumpActivity()}},V.onclose=()=>{!o()||U.current!==V||x("Control channel closed")},V.onerror=D=>{!o()||U.current!==V||(console.error("Control channel error:",D),x("Control channel error: "+D))},E.onconnectionstatechange=()=>{!o()||X.current!==E||(x("Connection state: "+E.connectionState),E.connectionState==="failed"&&Je("WebRTC connection entered failed state",s))},E.oniceconnectionstatechange=()=>{if(!o()||X.current!==E)return;const D=E.iceConnectionState;if(x("ICE state: "+D),D==="connected"||D==="completed"){lt(),Vt()&&!fe.current&&Gt();return}if(D==="failed"){lt(),Je("ICE connection entered failed state",s);return}D==="disconnected"&&Lt.current&&ke.current===void 0&&(ke.current=window.setTimeout(()=>{ke.current=void 0,!(!o()||X.current!==E)&&E.iceConnectionState==="disconnected"&&Je("ICE stayed disconnected past grace period",s)},wo))},E.ontrack=D=>{if(!(!o()||X.current!==E)&&(x("Received remote track: "+D.track.kind),D.track.kind==="video"&&j.current)){H(`[${new Date().toISOString()}] Video track received:`,D.track);const k=D.track.id==="duo-inner"||D.streams.some(ne=>ne.id==="duo-inner")?ze.current:j.current;k&&(k.srcObject=v?new MediaStream([D.track]):D.streams[0]??new MediaStream([D.track]),k.play().catch(()=>{}))}},E.onicecandidate=D=>{if(!(!o()||X.current!==E||w.current!==n))if(D.candidate&&n.readyState===WebSocket.OPEN){const m={type:"candidate",candidate:D.candidate.candidate,sdpMid:D.candidate.sdpMid,sdpMLineIndex:D.candidate.sdpMLineIndex,sessionId:de};n.send(JSON.stringify(m)),x("Sent ICE candidate")}else x("ICE candidate gathering completed")},n.onmessage=async D=>{if(!o()||w.current!==n)return;let m;try{m=JSON.parse(D.data)}catch(k){S("Error parsing message:",k);return}if(!te.current?.handleMessage(m))switch(x("Received: "+m.type),m.type){case"performActionsResult":case"foldStateResult":case"foldStateChanged":{if(!v)break;m.state?(ir(m.state),cr(void 0)):m.id==="duo-capabilities"&&cr(m.error||"This instance does not support native iPhone Duo displays.");const M=Ye.current.get(m.id);M&&(clearTimeout(M.timer),Ye.current.delete(m.id),m.error?M.reject(new Error(m.error)):M.resolve());break}case"signalingError":{if(m.requestType!=="offer"||m.sessionId!==de)break;const M=typeof m.error=="string"?m.error:"Unable to establish the streaming connection";x("Error: "+M),Je(M,s);break}case"answer":if(!X.current||X.current!==E){x("No peer connection, skipping answer");break}if(await E.setRemoteDescription(new RTCSessionDescription({type:"answer",sdp:m.sdp})),!o()||X.current!==E)return;x("Set remote description");break;case"candidate":if(!X.current||X.current!==E){x("No peer connection, skipping candidate");break}if(await E.addIceCandidate(new RTCIceCandidate({candidate:m.candidate,sdpMid:m.sdpMid,sdpMLineIndex:m.sdpMLineIndex})),!o()||X.current!==E)return;x("Added ICE candidate");break;case"screenshot":case"screenshotResult":{if(typeof m.id!="string"){S("Received invalid screenshot success message:",m);break}const M=Io(m);if(M){const ce=ge.current.get(m.id);if(!ce){S(`Received screenshot error for unknown or handled id: ${m.id}`);break}S(`Received screenshot error for id ${m.id}: ${M}`),ce(new Error(M)),ye.current.delete(m.id),ge.current.delete(m.id);break}const K=Yo(m);if(!K){S("Received screenshot message without image data:",m);break}const q=ye.current.get(m.id);if(!q){S(`Received screenshot data for unknown or handled id: ${m.id}`);break}H(`Received screenshot data for id ${m.id}`),q(K),ye.current.delete(m.id),ge.current.delete(m.id);break}case"screenshotError":if(typeof m.id!="string"||typeof m.message!="string"){S("Received invalid screenshot error message:",m);break}const k=ge.current.get(m.id);if(!k){S(`Received screenshot error for unknown or handled id: ${m.id}`);break}S(`Received screenshot error for id ${m.id}: ${m.message}`),k(new Error(m.message)),ye.current.delete(m.id),ge.current.delete(m.id);break;case"cameraRequest":{const M=_e.current;if(!M)break;const K=ao(m);if(!K){S("Received invalid cameraRequest:",m);break}console.info("[RemoteControl] cameraRequest received:",K.active,K.facingMode),await Sn(K,n,M,o);break}case"microphoneRequest":{if(!rt.current)break;const M=m.active===!0;if(Ht.current=M,console.info("[RemoteControl] microphoneRequest received, active=",M),!M){Wt.current||await Mt();break}if(fe.current){Sr(n);break}await Gt();break}case"microphoneStartResult":{if(Ue.current===null||m.id!==Ue.current)break;Ue.current=null,typeof m.error=="string"&&(console.warn("[RemoteControl] microphoneStart rejected by host:",m.error),Mt(m.error));break}case"terminateAppResult":if(typeof m.id!="string"){S("Received invalid terminateApp result message:",m);break}if(typeof m.error=="string"){const M=Re.current.get(m.id);if(!M){S(`Received terminateApp error for unknown or handled id: ${m.id}`);break}S(`Received terminateApp error for id ${m.id}: ${m.error}`),M(new Error(m.error)),Te.current.delete(m.id),Re.current.delete(m.id);break}const ne=Te.current.get(m.id);if(!ne){S(`Received terminateApp result for unknown or handled id: ${m.id}`);break}H(`Received terminateApp success for id ${m.id}`),ne(),Te.current.delete(m.id),Re.current.delete(m.id);break;default:S(`Received unhandled message type: ${m.type}`,m);break}},v&&n.send(JSON.stringify({type:"getFoldState",id:"duo-capabilities"})),X.current===E){const D=await E.createOffer({offerToReceiveVideo:!0,offerToReceiveAudio:!1});if(!o()||X.current!==E||(await E.setLocalDescription(D),!o()||X.current!==E))return;o()&&w.current===n&&n.readyState===WebSocket.OPEN&&n.send(JSON.stringify({type:"offer",...v?{displayStreams:!0}:{},sdp:D.sdp,sessionId:de})),x("Sent offer")}}catch(n){if(!o())return;const h=n instanceof Error?n.message:String(n);x("Error: "+h),Je(h,s)}},Jt=()=>{Ke.current=!1,ar(!1),Nr(0)},Nn=()=>{Oe.current+=1,pt.current=0,Pe.current=!1,wt(),lt(),Ge(),x("Stopped")},In=t=>{t.stopPropagation(),Jt()};f.useEffect(()=>{Vt()?Gt():Mt()},[F]),f.useEffect(()=>(Pt(!1),Jt(),document.hidden||Tr(),document.addEventListener("visibilitychange",br),()=>{Rr(),Nn(),document.removeEventListener("visibilitychange",br)}),[e,i,c,C]);const Ir=()=>{const t=ut();if(!t){mr(null);return}const s={left:t.videoRect.left-t.containerRect.left+t.offsetX,top:t.videoRect.top-t.containerRect.top+t.offsetY,width:t.actualWidth,height:t.actualHeight};mr(o=>o&&o.left===s.left&&o.top===s.top&&o.width===s.width&&o.height===s.height?o:s)};f.useEffect(()=>{const t=j.current,s=Ie.current,o=pe.current;if(!t)return;const n=()=>{if(!_t||!s){dr({}),Ir();return}const p=s.clientWidth,y=s.clientHeight;if(p===0||y===0)return;const v=t.videoWidth>t.videoHeight;rn(v),on(he==="android"&&Mo(t.videoWidth,t.videoHeight));const E=v?$e.videoPosition.landscape:$e.videoPosition.portrait;let I={};E.heightMultiplier?(I.height=`${y*E.heightMultiplier}px`,I.width="auto"):E.widthMultiplier&&(I.width=`${p*E.widthMultiplier}px`,I.height="auto"),I.borderRadius=`${v?y*$e.videoBorderRadiusMultiplier:p*$e.videoBorderRadiusMultiplier}px`,dr(I),Ir()},h=new ResizeObserver(()=>{n()});s&&h.observe(s),h.observe(t),o&&h.observe(o),s&&s.addEventListener("load",n),t.addEventListener("loadedmetadata",n),t.addEventListener("resize",n);const d=()=>te.current?.bumpActivity();return t.addEventListener("resize",d),n(),()=>{h.disconnect(),t.removeEventListener("loadedmetadata",n),t.removeEventListener("resize",n),t.removeEventListener("resize",d),s&&s.removeEventListener("load",n)}},[$e,_t]),f.useEffect(()=>{const t=te.current;st?t?.start():(t?.stop(),hr(null),it(null),vt(null),pr(null),Fe(null),Ot.current=null,ae.current!==void 0&&(window.cancelAnimationFrame(ae.current),ae.current=void 0),W("onAxSnapshotChange",$t.current,null))},[st]),f.useEffect(()=>()=>{ae.current!==void 0&&(window.cancelAnimationFrame(ae.current),ae.current=void 0)},[]),f.useEffect(()=>{if(!st)return;const t=s=>{s.key==="Escape"&&(Xt||jt)&&(vt(null),it(null),Fe(null),W("onInspectSelectionChange",je.current,null))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[st,Xt,jt]);const Yn=()=>{j.current&&j.current.focus()};f.useImperativeHandle(Ne,()=>({openUrl:t=>{if(!w.current||w.current.readyState!==WebSocket.OPEN){S("WebSocket not open, cannot send open_url command via ref.");return}try{const s=decodeURIComponent(t);x("Opening URL"),w.current.send(JSON.stringify({type:"openUrl",url:s,sessionId:de}))}catch(s){S("Error decoding or sending URL via ref:",{error:s,url:t}),w.current.send(JSON.stringify({type:"openUrl",url:t,sessionId:de}))}te.current?.bumpActivity()},sendKeyEvent:t=>{if(!U.current||U.current.readyState!=="open"){S("Data channel not ready for imperative key command:",U.current?.readyState);return}const s=Xr[t.code];if(!s){S(`Unknown event.code for imperative command: ${t.code}`);return}let o=a.META_NONE;t.shiftKey&&(o|=a.META_SHIFT_ON),t.altKey&&(o|=a.META_ALT_ON),t.ctrlKey&&(o|=a.META_CTRL_ON),t.metaKey&&(o|=a.META_META_ON);const n=t.type==="keydown"?a.ACTION_DOWN:a.ACTION_UP;H(`Sending Imperative Key Command: code=${t.code}, keycode=${s}, action=${n}, meta=${o}`);const h=ft(n,s,0,o);h&&le(h)},screenshot:t=>new Promise((s,o)=>{if(!w.current||w.current.readyState!==WebSocket.OPEN)return S("WebSocket not open, cannot send screenshot command."),o(new Error("WebSocket is not connected or connection is not open."));const n=`ui-ss-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,h={type:t?"screenshotDisplay":"screenshot",...t?{display:t}:{},id:n};ye.current.set(n,s),ge.current.set(n,o),H("Sending screenshot request:",h);try{w.current.send(JSON.stringify(h))}catch(d){S("Failed to send screenshot request immediately:",d),ye.current.delete(n),ge.current.delete(n),o(d);return}setTimeout(()=>{ye.current.has(n)&&(S(`Screenshot request timed out for id ${n}`),ge.current.get(n)?.(new Error("Screenshot request timed out")),ye.current.delete(n),ge.current.delete(n))},3e4)}),terminateApp:t=>new Promise((s,o)=>{if(!w.current||w.current.readyState!==WebSocket.OPEN)return S("WebSocket not open, cannot send terminateApp command."),o(new Error("WebSocket is not connected or connection is not open."));const n=`ui-term-${Date.now()}-${Math.random().toString(36).substring(2,9)}`,h={type:"terminateApp",id:n,bundleId:t};Te.current.set(n,s),Re.current.set(n,o),H("Sending terminateApp request:",h);try{w.current.send(JSON.stringify(h))}catch(d){S("Failed to send terminateApp request immediately:",d),Te.current.delete(n),Re.current.delete(n),o(d);return}te.current?.bumpActivity(),setTimeout(()=>{Te.current.has(n)&&(S(`terminateApp request timed out for id ${n}`),Re.current.get(n)?.(new Error("terminateApp request timed out")),Te.current.delete(n),Re.current.delete(n))},3e4)}),reconnect:()=>Jt(),refreshAxTree:async()=>{const t=te.current;if(!t)throw new Error("Inspect mode is not active");return t.refresh()},getAxSnapshot:()=>He.current,setInspectHighlight:t=>{it(t?.id??null)},setInspectSelection:t=>{vt(t?.id??null),Fe(t?Ot.current:null);const s=He.current;t&&s?W("onInspectSelectionChange",je.current,{element:t,snapshot:s}):W("onInspectSelectionChange",je.current,null)},getAxStatus:()=>te.current?.getStatus()??"idle"}));const Kn=cn&&Se!==null;return g.jsxs("div",{ref:pe,className:be("rc-container",r),style:{touchAction:"none"},onMouseDown:ve,onMouseMove:ve,onMouseUp:ve,onMouseLeave:ve,onTouchStart:ve,onTouchMove:ve,onTouchEnd:ve,onTouchCancel:ve,children:[Kn&&Se&&g.jsxs(g.Fragment,{children:[g.jsx("div",{className:"rc-touch-indicator",style:{left:`${Se.containerX}px`,top:`${Se.containerY}px`}}),g.jsx("div",{className:"rc-touch-indicator",style:{left:`${Se.mirrorContainerX}px`,top:`${Se.mirrorContainerY}px`}})]}),_t&&g.jsx("img",{ref:Ie,src:vr,alt:"",className:he==="ios"?be("rc-phone-frame","rc-phone-frame-ios"):"rc-phone-frame",draggable:!1}),g.jsx("video",{ref:j,className:be("rc-video",!_t&&"rc-video-frameless",!Zr&&"rc-video-loading"),style:{...sn,...oe?{opacity:0,width:1,height:1,pointerEvents:"none"}:{},...at?{backgroundImage:`url("${at}")`,backgroundRepeat:"no-repeat",backgroundPosition:"center",backgroundSize:$e.loadingLogoSize}:{}},autoPlay:!0,playsInline:!0,muted:!0,tabIndex:oe?-1:0,onKeyDown:Rt,onKeyUp:Rt,onClick:Yn,onLoadedData:_n,onFocus:()=>{j.current&&(j.current.style.outline="none")},onBlur:()=>{j.current&&(j.current.style.outline="none")}}),oe&&g.jsx("video",{ref:ze,autoPlay:!0,playsInline:!0,muted:!0,style:{position:"absolute",width:1,height:1,opacity:0,pointerEvents:"none"}}),oe&&!xt&&g.jsx(Yr,{logo:at,showFrame:u}),oe&&xt&&g.jsx(f.Suspense,{fallback:g.jsx(Yr,{logo:at,showFrame:u}),children:g.jsx(_o,{loadingLogo:at,showFrame:u,modelUrl:O,outer:j.current,inner:ze.current,state:xt,setAngle:t=>kt("setHingeAngle",{angleDegrees:t}),setOrientation:t=>kt("setDuoOrientation",{orientation:t}),button:(t,s)=>kt("performActions",{actions:[{type:s?"buttonDown":"buttonUp",button:t}]}),touch:(t,s,o,n)=>{const h=U.current;h?.readyState==="open"&&h.send(Wn(t,s,o,n))},onKeyDown:Rt,onKeyUp:Rt})}),oe&&sr&&g.jsx("div",{role:"alert",className:"rc-duo-error",children:sr}),!oe&&st&&g.jsx(Oo,{snapshot:fr,geometry:un,highlightedId:jt,selectedId:Xt,mode:fn,cursorPosition:dn,frozenCursorPosition:ln,onSelectChange:(t,s)=>{vt(t?.id??null),t&&s?Fe(s):t||Fe(null);const o=He.current;t&&o?W("onInspectSelectionChange",je.current,{element:t,snapshot:o}):W("onInspectSelectionChange",je.current,null)},onTapElement:(t,s)=>{if(s){_r(s.x,s.y);return}const o=He.current;o&&hn(t,o)}}),tn?g.jsxs("div",{className:"rc-terminated",role:"status",children:[g.jsx("div",{className:"rc-terminated-title",children:"Instance terminated"}),g.jsx("div",{className:"rc-terminated-message",children:"This instance no longer exists and can't be reconnected."})]}):en&&g.jsx("button",{type:"button",className:"rc-retry-button",onClick:In,children:"Retry"})]})}),Io=r=>typeof r.message=="string"?r.message:typeof r.error=="string"?r.error:null,Yo=r=>typeof r.dataUri=="string"?{dataUri:r.dataUri}:typeof r.base64=="string"?r.base64.startsWith("data:")?{dataUri:r.base64}:{dataUri:`data:${r.base64.startsWith("/9j/")?"image/jpeg":"image/png"};base64,${r.base64}`}:null;exports.AX_UNAVAILABLE_ERROR=It;exports.DUO_BUTTONS=jn;exports.DUO_DIMENSIONS=Zt;exports.DuoButtonSender=Xn;exports.DuoFlatFrame=Fr;exports.DuoLoadingScreen=jr;exports.HingeSender=Hn;exports.RemoteControl=No;exports.axElementAtPoint=Gr;exports.axElementSelectorExpression=Jr;exports.axElementSummary=rr;exports.axElementsEqual=er;exports.axSnapshotsEqual=tr;exports.clampAxFrameForScreen=Vr;exports.duoPointerMode=Fn;exports.flatDisplayTouch=Pn;exports.flatFrameGeometry=Wr;exports.flatHoverEdge=$n;exports.hardwareIconSize=Hr;exports.normalizeAndroidTree=qr;exports.normalizeIosTree=Br;exports.panelTouch=Ln;