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