@buoy-gg/highlight-updates 7.0.84 → 7.0.86

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.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.describeScreen=describeScreen;exports.hitTest=hitTest;exports.readMaps=readMaps;exports.resolveTouchTarget=resolveTouchTarget;exports.tapElement=tapElement;exports.waitFor=waitFor;var _utils=require("@buoy-gg/shared-ui/utils");var _reactNative=require("react-native");var _tapMatch=require("./tapMatch");var _domScreenElements=require("./domScreenElements");const HostComponent=5;const OffscreenComponent=22;const INTERNAL_NAMES=new Set(["View","RCTView","ScrollView","RCTScrollView","RCTScrollContentView","SafeAreaView","RCTSafeAreaView","AndroidHorizontalScrollContentView","KeyboardAvoidingView","Pressable","PlatformPressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","AnimatedComponent","Wrapper"]);function getReactDevToolsHook(){if(typeof global==="undefined")return null;return global.__REACT_DEVTOOLS_GLOBAL_HOOK__??null}let commitCount=0;let commitCounterInstalled=false;function ensureCommitCounter(){if(commitCounterInstalled)return;const e=getReactDevToolsHook();if(!e)return;const t=e.onCommitFiberRoot;e.onCommitFiberRoot=function(...n){commitCount++;return typeof t==="function"?t.apply(e,n):void 0};commitCounterInstalled=true}const TAP_SETTLE_MS=250;function makeChromeCheck(){const e=new Map;return t=>{const n=[];let r=t;let i=0;let s=false;while(r&&i<400){const a=e.get(r);if(a!==void 0){s=a;break}if(getProps(r)?.__buoyDevToolsRoot){s=true;e.set(r,true);break}n.push(r);r=r.return;i++}for(const a of n)e.set(a,s);return s}}function getAllFiberRoots(){const e=getReactDevToolsHook();if(!e)return[];const t=[];try{if(e.renderers&&typeof e.renderers.forEach==="function"){e.renderers.forEach((n,r)=>{try{const i=e.getFiberRoots?.(r);if(i)i.forEach(s=>t.push(s))}catch{}})}if(t.length===0&&e.getFiberRoots){const n=e.getFiberRoots(1);if(n)n.forEach(r=>t.push(r))}}catch{}return t}function isHiddenOffscreen(e){return e.tag===OffscreenComponent&&e.memoizedState!==null}let includeHiddenScreens=false;let prunedHiddenScreens=0;let fullVisibleText=false;function withHiddenScreens(e,t){const n=includeHiddenScreens;includeHiddenScreens=e;try{return t()}finally{includeHiddenScreens=n}}function isNotShowingScreen(e){const t=e.memoizedProps;if(!t)return false;if(t["aria-hidden"]===true&&(t.activityState!==void 0||"shouldFreeze"in t))return true;if(t.isFocused===false&&(t.routeKey!==void 0||"freezeContents"in t))return true;return false}function isInactiveScreen(e){const t=e.memoizedProps?.activityState;if(t===0||t===1)return true;if(e.memoizedProps?.isPageFocused===false)return true;if(!includeHiddenScreens&&isNotShowingScreen(e)){prunedHiddenScreens++;return true}return false}function traverseFiberTree(e,t,n=0,r=new Set){if(!e||r.has(e)||n>500)return;r.add(e);if(isHiddenOffscreen(e)||isInactiveScreen(e)){if(e.sibling)traverseFiberTree(e.sibling,t,n,r);return}t(e);if(e.child)traverseFiberTree(e.child,t,n+1,r);if(e.sibling)traverseFiberTree(e.sibling,t,n,r)}function getPublicInstance(e){const t=(0,_utils.getDOMPublicInstance)(e);if(t)return t;if(!e)return null;const n=e;if(n.canonical?.publicInstance)return n.canonical.publicInstance;if(n.canonical&&typeof n.canonical.measure==="function"){return n.canonical}if(typeof n.measure==="function"||typeof n.measureInWindow==="function"){return n}return null}function getNativeTag(e){const t=(0,_utils.getDOMNodeHandle)(e);if(t!==null)return t;if(e==null)return null;const n=e;if(typeof n.__nativeTag==="number")return n.__nativeTag;if(typeof n._nativeTag==="number")return n._nativeTag;if(typeof n.nativeTag==="number")return n.nativeTag;if(n.canonical){if(typeof n.canonical.__nativeTag==="number")return n.canonical.__nativeTag;if(typeof n.canonical._nativeTag==="number")return n.canonical._nativeTag;if(typeof n.canonical.nativeTag==="number")return n.canonical.nativeTag}return null}function findHostInstance(e){const t=getPublicInstance(e.stateNode);if(t){return{instance:t,nativeTag:getNativeTag(e.stateNode),stateNode:e.stateNode}}const n=[];if(e.child)n.push(e.child);let r=0;while(n.length>0&&r<4e3){r++;const i=n.pop();if(!i)continue;const s=getPublicInstance(i.stateNode);if(s)return{instance:s,nativeTag:getNativeTag(i.stateNode),stateNode:i.stateNode};if(i.child)n.push(i.child);if(i.sibling)n.push(i.sibling)}return null}function findScrollAncestor(e){let t=e;let n=0;while(t&&n++<200){const r=t.stateNode;if(r&&typeof r.scrollTo==="function"){const i=typeof r.getNativeScrollRef==="function"&&r.getNativeScrollRef()||null;const s=typeof r.getInnerViewNode==="function"&&r.getInnerViewNode()||typeof r.getScrollableNode==="function"&&r.getScrollableNode()||r;return{instance:r,nativeRef:i,innerNode:s}}t=t.return}return null}async function scrollIntoView(e,t,n,r){try{if((0,_utils.isDOMElement)(n)){n.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});await new Promise(u=>setTimeout(u,16));return true}const i=findScrollAncestor(e);if(!i)return false;const s=t;let a=null;const o=u=>new Promise(l=>{let c=false;const d=m=>{if(c)return;c=true;l(m)};const g=setTimeout(()=>d(null),600);try{u(m=>{clearTimeout(g);d(m)})}catch{clearTimeout(g);d(null)}});if(i.nativeRef&&typeof s.measureLayout==="function"){a=await o(u=>s.measureLayout(i.nativeRef,(l,c)=>u(c),()=>u(null)))}if(a==null){const u=(0,_reactNative.findNodeHandle)(t);const l=typeof i.innerNode==="number"?i.innerNode:(0,_reactNative.findNodeHandle)(i.innerNode);if(u!=null&&l!=null){a=await o(c=>_reactNative.UIManager.measureLayout(u,l,()=>c(null),(d,g)=>c(g)))}}if(a==null)return false;i.instance.scrollTo({y:Math.max(0,a-r),animated:false});await new Promise(u=>setTimeout(u,120));return true}catch{return false}}function getComponentName(e){const t=e?.type;if(!t)return null;if(typeof t==="string")return t;return t.displayName||t.name||null}function getOwningComponentName(e){let t=e?._debugOwner||e?.return;let n=0;while(t&&n<30){n++;const r=getComponentName(t);if(r&&!INTERNAL_NAMES.has(r)&&typeof t.type!=="string"){return r}t=t.return}return null}function getProps(e){return(0,_utils.getDOMControlProps)(e?.stateNode,e?.memoizedProps??e?.pendingProps??null)}function flattenText(e,t=0){if(typeof e==="string")return e;if(typeof e==="number"&&Number.isFinite(e))return String(e);if(Array.isArray(e)&&t<4){const n=[];for(const r of e){const i=flattenText(r,t+1);if(i)n.push(i)}return n.length>0?n.join(""):void 0}return void 0}function normalizeVisibleText(e){return e.replace(/\s+/g," ").trim()}function getVisibleText(e){if(!e)return void 0;const t=n=>{const r=flattenText(n);if(r===void 0)return void 0;const i=normalizeVisibleText(r);return i?fullVisibleText?i:i.slice(0,80):void 0};return t(e.children)??t(e.title)??t(e.label)??t(e.placeholder)??void 0}function collectDescendantText(e,t){const n=[];const r=(s,a)=>{if(!s||a>t||n.length>=4)return;if(s!==e){const u=getProps(s);if(u&&(typeof u.onPress==="function"||typeof u.onLongPress==="function"))return}const o=getVisibleText(getProps(s));if(o&&!n.includes(o))n.push(o);if(s.child)r(s.child,a+1);if(s!==e&&s.sibling)r(s.sibling,a)};if(e.child)r(e.child,1);const i=n.join(" ").trim();return i?i.slice(0,80):void 0}function findPressHandler(e){let t=e;let n=0;let r=null;let i=null;while(t&&n<25&&!(r&&i)){const s=getProps(t);if(s){if(!r&&typeof s.onPress==="function")r=s.onPress;if(!i&&typeof s.onLongPress==="function")i=s.onLongPress}t=t.return;n++}if(r)return{handler:r,kind:"onPress",longPress:i??void 0};return i?{handler:i,kind:"onLongPress"}:null}function measureInstance(e){return new Promise(t=>{let n=false;const r=i=>{if(n)return;n=true;t(i)};setTimeout(()=>r(null),1e3);try{if(typeof e.measureInWindow==="function"){e.measureInWindow((i,s,a,o)=>{if(a>0&&o>0)r({x:i,y:s,width:a,height:o});else r(null)})}else if(typeof e.measure==="function"){e.measure((i,s,a,o,u,l)=>{if(a>0&&o>0&&u!=null&&l!=null){r({x:u,y:l,width:a,height:o})}else{r(null)}})}else{r(null)}}catch{r(null)}})}const SPINNER_HOSTS=new Set(["RCTActivityIndicatorView","AndroidProgressBar"]);function collectCandidates(){const e=getAllFiberRoots();const t=[];const n=new Map;const r=new Map;const i=makeChromeCheck();for(const s of e){traverseFiberTree(s.current,a=>{const o=getProps(a);if(!o)return;const u=typeof o.onPress==="function"||typeof o.onLongPress==="function";const l=typeof o.onValueChange==="function";const c=typeof o.onChangeText==="function";const d=o.testID||void 0;const g=o.accessibilityLabel||void 0;const m=o.accessibilityRole||o.role||void 0;let w=getVisibleText(o);const y=m==="button"||m==="link"||m==="menuitem"||m==="tab"||m==="switch"||m==="checkbox";const b=typeof a.type==="string"&&SPINNER_HOSTS.has(a.type)&&o.animating!==false;if(!u&&!l&&!c&&!d&&!g&&!w&&!y&&!b){return}let x=null;let N=null;let I=null;if(l){const D=o.value;const S=typeof D==="number"||typeof o.minimumValue==="number";N={handler:o.onValueChange,kind:S?"slider":"toggle",current:D,min:typeof o.minimumValue==="number"?o.minimumValue:void 0,max:typeof o.maximumValue==="number"?o.maximumValue:void 0}}else if(c){I={handler:o.onChangeText,current:typeof o.value==="string"?o.value:void 0}}else{x=findPressHandler(a)}const C=getComponentName(a);let f=C??"Unknown";if(!C||INTERNAL_NAMES.has(C)||typeof a.type==="string"){f=getOwningComponentName(a)??C??"Unknown"}const h=findHostInstance(a);if(!h&&!d)return;if(!w&&!g&&u){w=collectDescendantText(a,6)}const p=h?.instance??null;const T=h?.nativeTag??null;const v=(p?n.get(p):void 0)??(T!=null?r.get(T):void 0);if(v){if(x)v.press=x;if(!v.valueControl&&N)v.valueControl=N;if(!v.textControl&&I)v.textControl=I;if(!v.testID&&d)v.testID=d;if(!v.label&&g)v.label=g;if(!v.text&&w)v.text=w;if(p&&!n.has(p))n.set(p,v);if(T!=null&&!r.has(T))r.set(T,v);return}const P={nativeTag:T,name:f,role:m??(b?"progressbar":void 0),testID:d,label:g,text:w,instance:p,stateNode:h?.stateNode??null,fiber:a,press:x,valueControl:N,textControl:I,rect:null,buoy:i(a)};t.push(P);if(p)n.set(p,P);if(T!=null)r.set(T,P)})}t.push(...collectDOMCandidates());return t}function collectDOMCandidates(){return(0,_domScreenElements.collectDOMElements)({fullText:fullVisibleText}).map(({element:e,props:t,text:n,buoy:r})=>{const i=typeof t.onValueChange==="function"?{handler:t.onValueChange,kind:typeof t.value==="number"?"slider":"toggle",current:t.value,min:t.minimumValue,max:t.maximumValue}:null;const s=!i&&typeof t.onChangeText==="function"?{handler:t.onChangeText,current:t.value}:null;const a=!i&&!s&&typeof t.onPress==="function"?{handler:t.onPress,kind:"onPress"}:null;return{nativeTag:(0,_utils.getDOMNodeHandle)(e),name:(0,_domScreenElements.domElementName)(e),role:t.accessibilityRole,testID:t.testID,label:t.accessibilityLabel,text:n,instance:(0,_utils.getDOMPublicInstance)(e),stateNode:e,fiber:null,buoy:r,press:a,valueControl:i,textControl:s,rect:null}})}function explicitlyTargets(e,t){if(t.nativeTag!=null)return e.nativeTag===t.nativeTag;if(t.testID&&e.testID)return e.testID.toLowerCase()===t.testID.toLowerCase();return false}function appCandidates(e){const t=collectCandidates();if(e.includeBuoy)return t;return t.filter(n=>!n.buoy||explicitlyTargets(n,e))}async function measureCandidates(e){await Promise.all(e.map(async t=>{if(t.instance)t.rect=await measureInstance(t.instance)}))}const LIST_WRAPPERS=/^(FlatList|SectionList|VirtualizedSectionList|VirtualizedList|Animated\(.*\)|AnimatedComponent.*)$/;async function collectLists(e,t){const n=[];const r=makeChromeCheck();for(const s of getAllFiberRoots()){traverseFiberTree(s.current,a=>{if(getComponentName(a)!=="VirtualizedList")return;const o=a.memoizedProps;if(!o||typeof o.getItemCount!=="function")return;if(!e&&r(a))return;let u;try{u=Number(o.getItemCount(o.data))}catch{return}if(!Number.isFinite(u)||u<=0)return;const l=[];const c=(m,w)=>{for(let y=m?.child;y;y=y.sibling){const b=getComponentName(y);if(b==="VirtualizedList")continue;if(b==="CellRenderer"){l.push(y);continue}if(w<40)c(y,w+1)}};c(a,0);let d=a;let g=getOwningComponentName(d);for(let m=0;m<6&&g&&LIST_WRAPPERS.test(g);m++){d=d._debugOwner||d.return;g=getOwningComponentName(d)}n.push({owner:g,items:u,cells:l})})}const i=[];for(const s of n){const a=await Promise.all(s.cells.map(async u=>{const l=findHostInstance(u);return l?measureInstance(l.instance):null}));const o=a.filter(t).length;if(o>0&&s.items>o)i.push({owner:s.owner,items:s.items,listed:o})}return i}async function describeScreen(e={}){const t=includeHiddenScreens;const n=fullVisibleText;includeHiddenScreens=!!e.includeHidden;fullVisibleText=!!e.fullText;try{return await describeScreenInner(e)}finally{includeHiddenScreens=t;fullVisibleText=n}}async function describeScreenInner(e){prunedHiddenScreens=0;const t=collectCandidates();const n=prunedHiddenScreens;const r=e.includeBuoy?t:t.filter(c=>!c.buoy);const i=t.length-r.length;await measureCandidates(r);const s=_reactNative.Dimensions.get("window");const a=Math.round(s.width)||1;const o=Math.round(s.height)||1;const u=[];for(const c of r){const d=c.rect;if(!d&&!c.testID)continue;let g;let m;if(d){const b=d.x+d.width/2;const x=d.y+d.height/2;if(x<-o*.1||x>o*1.1||b<-a*.1||b>a*1.1){continue}g={x:round2(b/a),y:round2(x/o)};m={x:round2(d.x/a),y:round2(d.y/o),width:round2(d.width/a),height:round2(d.height/o)}}const w=c.valueControl?c.valueControl.kind:c.textControl?"text":void 0;const y=c.valueControl?c.valueControl.current:c.textControl?.current;u.push({nativeTag:c.nativeTag,name:c.name,role:c.role,testID:c.testID,label:c.label,text:c.text,interactive:!!(c.press||c.valueControl||c.textControl),longPressable:c.press&&(c.press.kind==="onLongPress"||c.press.longPress)?true:void 0,control:w,value:y,tap:g,frame:m,...c.buoy?{buoy:true}:{}})}u.sort((c,d)=>{const g=c.tap?.y??2;const m=d.tap?.y??2;if(Math.abs(g-m)>.02)return g-m;return(c.tap?.x??2)-(d.tap?.x??2)});const l=await collectLists(!!e.includeBuoy,c=>{if(!c)return false;const d=c.x+c.width/2;return c.y<=o*1.1&&c.y+c.height>=-o*.1&&d>=-a*.1&&d<=a*1.1});return{screen:{width:a,height:o},count:u.length,elements:u,...i>0?{hiddenBuoy:i}:{},...n>0?{hiddenScreens:n}:{},...l.length?{lists:l}:{}}}function round2(e){return Math.round(e*100)/100}function fieldsOf(e){return{nativeTag:e.nativeTag,testID:e.testID,label:e.label,text:e.text,name:e.name}}function matchScore(e,t){return(0,_tapMatch.scoreTapMatch)(fieldsOf(e),t)}function tapPoint(e,t,n){if(!e||!t||!n)return void 0;return{x:(e.x+e.width/2)/t,y:(e.y+e.height/2)/n}}function makeSyntheticPressEvent(e){const t=e?e.x+e.width/2:0;const n=e?e.y+e.height/2:0;const r={locationX:e?e.width/2:0,locationY:e?e.height/2:0,pageX:t,pageY:n,timestamp:0,target:null,identifier:1,touches:[],changedTouches:[]};return{nativeEvent:r,persist:()=>{},preventDefault:()=>{},stopPropagation:()=>{},isDefaultPrevented:()=>false,isPropagationStopped:()=>false,target:null,currentTarget:null,type:"press",timeStamp:0}}async function tapElement(e){const t=withHiddenScreens(!!e.includeHidden,()=>appCandidates(e));if(t.length===0){return{tapped:false,reason:"Nothing on screen to tap: no React elements and no page elements were found."}}const n=t.map(f=>({c:f,score:matchScore(f,e)})).filter(f=>f.score>0).sort((f,h)=>h.score-f.score);const r=f=>!!(f.press||f.valueControl||f.textControl);if(n.length===0&&!e.includeHidden){const f=withHiddenScreens(true,()=>appCandidates(e)).map(h=>({c:h,score:matchScore(h,e)})).filter(h=>h.score>0);if(f.length>0){return{tapped:false,reason:"That element is only on a screen that isn't showing (another tab, or a screen under the current one). Navigate to it first, or pass includeHidden:true if you really mean the hidden one."}}}if(n.length===0){return{tapped:false,reason:"No element matched. Call describe_screen to see available elements (match by testID, text, or name).",candidates:t.filter(r).slice(0,12).map(f=>({nativeTag:f.nativeTag,name:f.name,testID:f.testID,text:f.text}))}}const i=_reactNative.Dimensions.get("window");const s=i.width||1;const a=i.height||1;const o=n.slice(0,15);await Promise.all(o.map(async f=>{if(f.c.instance&&!f.c.rect)f.c.rect=await measureInstance(f.c.instance)}));for(const f of o){f.score=(0,_tapMatch.scoreTapMatch)({...fieldsOf(f.c),tap:tapPoint(f.c.rect,s,a)},e)}o.sort((f,h)=>h.score-f.score);if(e.text!==void 0){for(const f of o){const h=!r(f.c)&&(0,_utils.isDOMElement)(f.c.stateNode)?(0,_domScreenElements.labeledField)(f.c.stateNode):null;const p=h?t.find(T=>T.stateNode===h&&T.textControl):void 0;if(p)f.c=p}}const u=o.find(f=>r(f.c))??n.find(f=>r(f.c))??o[0];const l=u.c;const c=(f,h)=>f.press&&f.press.handler===h.press?.handler||f.valueControl&&f.valueControl.handler===h.valueControl?.handler||f.textControl&&f.textControl.handler===h.textControl?.handler;const d=o.filter(f=>f!==u&&r(f.c)&&f.score===u.score).filter(f=>!c(f.c,l)).filter((f,h,p)=>p.findIndex(T=>c(T.c,f.c))===h).slice(0,3).map(f=>({nativeTag:f.c.nativeTag,name:f.c.name,testID:f.c.testID,text:f.c.text,tap:tapPoint(f.c.rect,s,a)}));const g=e.nativeTag==null&&!(e.testID&&!e.query);if(g&&d.length>0){const f=[l,...d.map(h=>o.find(p=>p.c.nativeTag===h.nativeTag)?.c).filter(Boolean)];return{tapped:false,reason:`"${e.query}" matches ${f.length} different controls equally well, so nothing was tapped. Tap one by its nativeTag.`,candidates:f.map(h=>({nativeTag:h.nativeTag,name:h.name,testID:h.testID,text:h.text}))}}const m=o[0];if(g&&m&&m!==u&&!r(m.c)&&m.score>=90&&u.score<m.score-40){return{tapped:false,reason:`The best match for "${e.query}" is "${m.c.text??m.c.label??m.c.name}", which has no JS press handler (it may be native, like a tab bar button). The closest pressable match, "${l.text??l.label??l.name}", is a much weaker match, so nothing was tapped. Use navigate, or tap a specific element by nativeTag.`,candidates:[{nativeTag:l.nativeTag,name:l.name,testID:l.testID,text:l.text}]}}if(!r(l)){return{tapped:false,reason:(0,_utils.isDOMElement)(l.stateNode)?`Matched "${l.name}"${l.text?` ("${l.text}")`:""}, but it is not a button or a field. This element can't be driven in JS.`:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onPress / onValueChange / onChangeText handler (e.g. a react-native-gesture-handler GestureDetector). This element can't be driven in JS.`,matched:{nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text,via:"onPress"}}}if(l.instance&&!l.rect)l.rect=await measureInstance(l.instance);let w=false;const y=l.rect==null||!(0,_tapMatch.isRectCenterOnScreen)(l.rect,s,a);if(y&&e.scrollIntoView!==false&&l.instance){w=await scrollIntoView(l.fiber,l.instance,l.stateNode,80);if(w)l.rect=await measureInstance(l.instance)}const b={nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text};ensureCommitCounter();const x=commitCount;const N=l.fiber===null&&(0,_utils.isDOMElement)(l.stateNode)?(0,_domScreenElements.watchDOMChanges)():null;const I=Date.now();const C=async f=>{await new Promise(h=>setTimeout(h,TAP_SETTLE_MS));return{tapped:true,scrolled:w,matched:f,effect:{commits:N?N():commitCount-x,observedMs:Date.now()-I},...d.length?{alsoMatched:d}:{}}};try{if(l.press){if(e.longPress){const h=l.press.kind==="onLongPress"?l.press.handler:l.press.longPress;if(!h){return{tapped:false,scrolled:w,reason:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onLongPress handler \u2014 call tap_element without longPress to tap it normally.`,matched:{...b,via:"onPress"}}}h(makeSyntheticPressEvent(l.rect));return await C({...b,via:"onLongPress"})}l.press.handler(makeSyntheticPressEvent(l.rect));return await C({...b,via:l.press.kind})}if(l.valueControl){const h=l.valueControl;let p;if(h.kind==="toggle"){p=typeof e.value==="boolean"?e.value:!h.current}else{const T=h.min??0;const v=h.max??1;if(typeof e.value==="number"){p=Math.min(v,Math.max(T,e.value))}else{p=h.current===v?T:v}}h.handler(p);return await C({...b,via:"onValueChange",value:p})}const f=e.text??(typeof e.value==="string"?e.value:"");l.textControl.handler(f);return await C({...b,via:"onChangeText",value:f})}catch(f){N?.();return{tapped:false,scrolled:w,reason:`handler threw: ${f instanceof Error?f.message:String(f)}`,matched:{...b,via:l.press?l.press.kind:l.valueControl?"onValueChange":"onChangeText"}}}}const WAIT_DEFAULT_MS=5e3;const WAIT_MAX_MS=3e4;const WAIT_MIN_POLL_MS=50;const WAIT_DEFAULT_POLL_MS=150;async function waitFor(e){const t=e.nativeTag!=null||!!String(e.testID??"").trim()||!!String(e.query??"").trim();if(!t){return{ok:false,waitedMs:0,polls:0,reason:"Nothing to wait for \u2014 pass nativeTag, testID or query."}}const n=Math.min(Math.max(e.timeoutMs??WAIT_DEFAULT_MS,0),WAIT_MAX_MS);const r=Math.max(e.pollMs??WAIT_DEFAULT_POLL_MS,WAIT_MIN_POLL_MS);const i=e.gone===true;const s=Date.now();let a=0;for(;;){a+=1;const{hit:o,closest:u}=await findOnScreen(e);if(i?!o:!!o){return{ok:true,waitedMs:Date.now()-s,polls:a,matched:o??void 0}}if(Date.now()-s>=n){const l=u?.length?u:void 0;const c=i?`Still on screen after ${n}ms.`:l?`Not on screen after ${n}ms \u2014 ${l.length===1?"one element":`${l.length} elements`} matched but ${l.some(d=>d.onScreen)?"not well enough":"none is visible"}. See \`closest\`; do not retry with different words, call describeScreen.`:`Not on screen after ${n}ms, and nothing matched those words at all. Call describeScreen to see what is there.`;return{ok:false,waitedMs:Date.now()-s,polls:a,reason:c,matched:o??void 0,closest:l}}await new Promise(l=>setTimeout(l,r))}}async function findOnScreen(e){const t=appCandidates(e).map(o=>({c:o,score:matchScore(o,e)})).filter(o=>o.score>0).sort((o,u)=>u.score-o.score).slice(0,8);if(t.length===0)return{hit:null,closest:void 0};await measureCandidates(t.map(o=>o.c));const n=_reactNative.Dimensions.get("window");const r=Math.round(n.width)||1;const i=Math.round(n.height)||1;let s=null;for(const{c:o}of t){if(!(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i))continue;s={nativeTag:o.nativeTag,name:o.name,testID:o.testID,label:o.label,text:o.text,interactive:!!(o.press||o.valueControl||o.textControl)};break}const a=t.slice(0,3).map(({c:o})=>({name:o.name,testID:o.testID,text:o.text,onScreen:(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i)}));return{hit:s,closest:a}}function isBuoyChrome(e){let t=e;let n=0;while(t&&n<400){if(getProps(t)?.__buoyDevToolsRoot)return true;t=t.return;n++}return false}function preferHandlerOwner(e,t){const n=getProps(e.fiber);if(typeof n?.onPress==="function"||typeof n?.onValueChange==="function"||typeof n?.onChangeText==="function"){return e}let r=null;let i=e.fiber?.return;let s=0;while(i&&s<25){if(typeof getProps(i)?.onPress==="function"){r=i;break}i=i.return;s++}if(!r)return e;let a=r;for(let o=0;o<6&&a;o++){const u=t.get(a);if(u)return u;a=a.return}return e}function resolveTouchTarget(e){const t=collectCandidates();if(t.length===0)return null;const n=new Map;for(const a of t)n.set(a.fiber,a);const r=t.find(a=>a.nativeTag===e);let i=null;if(!r){for(const a of getAllFiberRoots()){traverseFiberTree(a.current,o=>{if(i)return;if(o.stateNode&&getNativeTag(o.stateNode)===e){i=o}});if(i)break}}let s=r??null;if(!s&&i){let a=i;let o=0;let u=null;while(a&&o<25){const l=n.get(a);if(l){if(l.press||l.valueControl||l.textControl){s=l;break}if(!u)u=l}a=a.return;o++}if(!s)s=u}if(!s?.fiber&&!i){const a=s?.stateNode;const o=(0,_utils.isDOMElement)(a)?a:domElementForTag(e);if(o){for(let u=o;u;u=u.parentElement){const l=t.find(c=>c.stateNode===u&&(c.press||c.valueControl||c.textControl));if(l)return l.buoy?null:touchTargetOf(l)}return null}}if(!s)return null;s=preferHandlerOwner(s,n);if(!s.press&&!s.valueControl&&!s.textControl)return null;if(isBuoyChrome(s.fiber))return null;return touchTargetOf(s)}function domElementForTag(e){const t=global.document;if(!t?.querySelectorAll)return null;return Array.from(t.querySelectorAll("*")).find(n=>(0,_utils.getDOMNodeHandle)(n)===e)??null}function touchTargetOf(e){return{nativeTag:e.nativeTag,name:e.name,role:e.role,testID:e.testID,label:e.label,text:e.text,control:e.valueControl?e.valueControl.kind:e.textControl?"text":"press",value:e.valueControl?e.valueControl.current:e.textControl?.current}}function fiberForTag(e){let t=null;for(const n of getAllFiberRoots()){traverseFiberTree(n.current,r=>{if(!t&&r.stateNode&&getNativeTag(r.stateNode)===e)t=r});if(t)break}return t}function rootHostFibers(){const e=[];for(const t of getAllFiberRoots()){let n=t.current?.child;let r=0;while(n&&r++<200){if(n.tag===HostComponent&&n.stateNode){e.push(n);break}n=n.child}}return e}function fabricFiberAt(e,t){const n=global.nativeFabricUIManager;if(!n||typeof n.findNodeAtPoint!=="function")return null;const r=rootHostFibers().filter(i=>i.stateNode?.node);if(!r.length)return null;return new Promise(i=>{const s=setTimeout(()=>i(null),1e3);let a=r.length;let o=null;r.forEach((u,l)=>{try{n.findNodeAtPoint(u.stateNode.node,e,t,c=>{if(c&&(!o||l>=o.i))o={i:l,fiber:c};if(--a===0){clearTimeout(s);i(o?.fiber??null)}})}catch{if(--a===0){clearTimeout(s);i(o?.fiber??null)}}})})}function paperFiberAt(e,t){const n=_reactNative.UIManager?.findSubviewIn;if(typeof n!=="function")return null;const r=rootHostFibers()[0];const i=r?getNativeTag(r.stateNode)??(0,_reactNative.findNodeHandle)(r.stateNode):null;if(i==null)return null;return new Promise(s=>{const a=setTimeout(()=>s(null),1e3);try{n.call(_reactNative.UIManager,i,[e,t],o=>{clearTimeout(a);s(typeof o==="number"?fiberForTag(o):null)})}catch{clearTimeout(a);s(null)}})}function visibleHostFibers(){const e=[];const t=new Set;const n=i=>{const s=[];const a=(o,u)=>{for(let l=o;l&&s.length<5e3;l=l.sibling){if(t.has(l)||u>500)continue;if(isHiddenOffscreen(l)||isInactiveScreen(l))continue;if(l.tag===HostComponent&&l.stateNode)s.push(l);else if(l.child)a(l.child,u+1)}};if(i.child)a(i.child,0);return s};const r=(i,s)=>{if(t.has(i)||s>500)return;t.add(i);e.push(i);sortByZ(n(i)).forEach(a=>r(a,s+1))};for(const i of getAllFiberRoots())sortByZ(n(i.current)).forEach(s=>r(s,0));return e}function sortByZ(e){const t=e.map(n=>{const r=Number(flatStyle(getProps(n)?.style).zIndex);return Number.isFinite(r)?r:0});return e.map((n,r)=>({h:n,i:r})).sort((n,r)=>t[n.i]-t[r.i]||n.i-r.i).map(({h:n})=>n)}function flatStyle(e,t=0){if(!e||typeof e!=="object"||t>10)return{};if(Array.isArray(e))return Object.assign({},...e.map(n=>flatStyle(n,t+1)));return e}const SCROLL_HOSTS=new Set(["RCTScrollView","AndroidHorizontalScrollView","RCTScrollContentView"]);function clipsChildren(e){if(typeof e.type==="string"&&SCROLL_HOSTS.has(e.type)&&e.type!=="RCTScrollContentView")return true;const t=flatStyle(getProps(e)?.style).overflow;return t==="hidden"||t==="scroll"}function passesTouchesThrough(e){let t=getProps(e)?.pointerEvents??getProps(e)?.style?.pointerEvents;if(t==="none")return"all";let n=e.return;let r=0;while(n&&r++<200){const i=getProps(n)?.pointerEvents??getProps(n)?.style?.pointerEvents;if(i==="none")return"all";if(i==="box-only"&&n.tag===HostComponent)return"all";n=n.return}return t==="box-none"?"self":null}async function measuredFiberAt(e,t,n){const r=await Promise.all(n.map(o=>{const u=getPublicInstance(o.stateNode);return u?measureInstance(u):Promise.resolve(null)}));const i=new Map;n.forEach((o,u)=>i.set(o,r[u]));const s=o=>!!o&&e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height;const a=o=>{for(let u=o.return,l=0;u&&l<300;u=u.return,l++){if(u.tag===HostComponent&&i.has(u)&&clipsChildren(u)&&!s(i.get(u)))return true}return false};for(let o=n.length-1;o>=0;o--){if(!s(r[o])||passesTouchesThrough(n[o])||a(n[o]))continue;return n[o]}return null}function domFiberAt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;let i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);while(i){const s=Object.keys(i).find(a=>a.startsWith("__reactFiber$"));if(s)return i[s];i=i.parentElement}return null}function domPageHit(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;const i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);if(!i)return null;for(let c=i;c;c=c.parentElement){if(Object.keys(c).some(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactContainer$")))return null}const s=!!i.closest("[data-buoy-root], [data-buoy-portal-host]");const a=collectDOMCandidates();const o=a.find(c=>c.stateNode===i);let u;for(let c=i;c&&!u;c=c.parentElement){u=a.find(d=>d.stateNode===c&&(d.press||d.valueControl||d.textControl))}const l=[];for(let c=i;c&&l.length<6;c=c.parentElement){const d=(0,_domScreenElements.domElementName)(c);if(d!==c.tagName.toLowerCase()&&l[l.length-1]!==d)l.push(d)}return{found:true,method:"dom",buoy:s,view:{name:(0,_domScreenElements.domElementName)(i),nativeTag:(0,_utils.getDOMNodeHandle)(i),testID:o?.testID,label:o?.label,text:o?.text},path:l,target:u&&!s?touchTargetOf(u):null}}async function hitTest(e){const t=Math.min(1,Math.max(0,Number(e?.x)));const n=Math.min(1,Math.max(0,Number(e?.y)));if(!Number.isFinite(t)||!Number.isFinite(n))return{found:false,method:"none",reason:"x and y must be numbers from 0 to 1."};const r=_reactNative.Dimensions.get("window");const i=t*r.width;const s=n*r.height;let a="none";let o=null;const u=domFiberAt(t,n);const l=u?null:domPageHit(t,n);if(l)return l;if(u){a="dom";o=u}else{const y=fabricFiberAt(i,s);if(y){a="fabric";o=await y}else{const x=paperFiberAt(i,s);if(x){a="paper";o=await x}}const b=visibleHostFibers();if(!o||!new Set(b).has(o)){o=await measuredFiberAt(i,s,b);a="measured"}}if(!o)return{found:false,method:a};const c=getProps(o)??{};const d=getNativeTag(o.stateNode);const g=[];let m=o;let w=0;while(m&&w++<80&&g.length<6){const y=getComponentName(m);if(y&&typeof m.type!=="string"&&!INTERNAL_NAMES.has(y)&&g[g.length-1]!==y)g.push(y);m=m.return}return{found:true,method:a,buoy:isBuoyChrome(o),view:{name:getComponentName(o)??"Unknown",nativeTag:d,testID:c.testID||void 0,label:c.accessibilityLabel||c["aria-label"]||void 0,text:getVisibleText(c)},path:g,target:d!=null?resolveTouchTarget(d):null}}async function readMaps(){const e=[];for(const i of getAllFiberRoots()){traverseFiberTree(i.current,s=>{const a=s.stateNode;if(s.tag===1&&a&&typeof a.getCamera==="function"&&!isBuoyChrome(s))e.push(s)})}const t=_reactNative.Dimensions.get("window");const n=i=>Promise.race([i,new Promise(s=>setTimeout(()=>s(null),1e3))]);const r=await Promise.all(e.slice(0,5).map(async i=>{try{const s=await n(Promise.resolve(i.stateNode.getCamera()));if(!s)return null;const a=findHostInstance(i);const o=a?await measureInstance(a.instance):null;const u=getProps(i)??{};return{name:getComponentName(i)??"Map",testID:typeof u.testID==="string"?u.testID:void 0,frame:o&&t.width&&t.height?{x:round2(o.x/t.width),y:round2(o.y/t.height),width:round2(o.width/t.width),height:round2(o.height/t.height)}:void 0,camera:{heading:typeof s.heading==="number"?s.heading:void 0,pitch:typeof s.pitch==="number"?s.pitch:void 0,altitude:typeof s.altitude==="number"?s.altitude:void 0,zoom:typeof s.zoom==="number"?s.zoom:void 0,center:s.center}}}catch{return null}}));return{maps:r.filter(i=>!!i)}}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.describeScreen=describeScreen;exports.hitTest=hitTest;exports.readMaps=readMaps;exports.resolveTouchTarget=resolveTouchTarget;exports.tapElement=tapElement;exports.waitFor=waitFor;var _utils=require("@buoy-gg/shared-ui/utils");var _reactNative=require("react-native");var _tapMatch=require("./tapMatch");var _domScreenElements=require("./domScreenElements");const HostComponent=5;const OffscreenComponent=22;const INTERNAL_NAMES=new Set(["View","RCTView","ScrollView","RCTScrollView","RCTScrollContentView","SafeAreaView","RCTSafeAreaView","AndroidHorizontalScrollContentView","KeyboardAvoidingView","Pressable","PlatformPressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","AnimatedComponent","Wrapper"]);function getReactDevToolsHook(){if(typeof global==="undefined")return null;return global.__REACT_DEVTOOLS_GLOBAL_HOOK__??null}let commitCount=0;let commitCounterInstalled=false;function ensureCommitCounter(){if(commitCounterInstalled)return;const e=getReactDevToolsHook();if(!e)return;const t=e.onCommitFiberRoot;e.onCommitFiberRoot=function(...n){commitCount++;return typeof t==="function"?t.apply(e,n):void 0};commitCounterInstalled=true}const TAP_SETTLE_MS=250;function makeChromeCheck(){const e=new Map;return t=>{const n=[];let r=t;let i=0;let s=false;while(r&&i<400){const a=e.get(r);if(a!==void 0){s=a;break}if(getProps(r)?.__buoyDevToolsRoot){s=true;e.set(r,true);break}n.push(r);r=r.return;i++}for(const a of n)e.set(a,s);return s}}function getAllFiberRoots(){const e=getReactDevToolsHook();if(!e)return(0,_utils.getAnchoredFiberRoots)();const t=[];try{if(e.renderers&&typeof e.renderers.forEach==="function"){e.renderers.forEach((n,r)=>{try{const i=e.getFiberRoots?.(r);if(i)i.forEach(s=>t.push(s))}catch{}})}if(t.length===0&&e.getFiberRoots){const n=e.getFiberRoots(1);if(n)n.forEach(r=>t.push(r))}}catch{}return t.length?t:(0,_utils.getAnchoredFiberRoots)()}function isHiddenOffscreen(e){return e.tag===OffscreenComponent&&e.memoizedState!==null}let includeHiddenScreens=false;let prunedHiddenScreens=0;let fullVisibleText=false;function withHiddenScreens(e,t){const n=includeHiddenScreens;includeHiddenScreens=e;try{return t()}finally{includeHiddenScreens=n}}function isNotShowingScreen(e){const t=e.memoizedProps;if(!t)return false;if(t["aria-hidden"]===true&&(t.activityState!==void 0||"shouldFreeze"in t))return true;if(t.isFocused===false&&(t.routeKey!==void 0||"freezeContents"in t))return true;return false}function isInactiveScreen(e){const t=e.memoizedProps?.activityState;if(t===0||t===1)return true;if(e.memoizedProps?.isPageFocused===false)return true;if(!includeHiddenScreens&&isNotShowingScreen(e)){prunedHiddenScreens++;return true}return false}function traverseFiberTree(e,t,n=0,r=new Set){if(!e||r.has(e)||n>500)return;r.add(e);if(isHiddenOffscreen(e)||isInactiveScreen(e)){if(e.sibling)traverseFiberTree(e.sibling,t,n,r);return}t(e);if(e.child)traverseFiberTree(e.child,t,n+1,r);if(e.sibling)traverseFiberTree(e.sibling,t,n,r)}function getPublicInstance(e){const t=(0,_utils.getDOMPublicInstance)(e);if(t)return t;if(!e)return null;const n=e;if(n.canonical?.publicInstance)return n.canonical.publicInstance;if(n.canonical&&typeof n.canonical.measure==="function"){return n.canonical}if(typeof n.measure==="function"||typeof n.measureInWindow==="function"){return n}return null}function getNativeTag(e){const t=(0,_utils.getDOMNodeHandle)(e);if(t!==null)return t;if(e==null)return null;const n=e;if(typeof n.__nativeTag==="number")return n.__nativeTag;if(typeof n._nativeTag==="number")return n._nativeTag;if(typeof n.nativeTag==="number")return n.nativeTag;if(n.canonical){if(typeof n.canonical.__nativeTag==="number")return n.canonical.__nativeTag;if(typeof n.canonical._nativeTag==="number")return n.canonical._nativeTag;if(typeof n.canonical.nativeTag==="number")return n.canonical.nativeTag}return null}function findHostInstance(e){const t=getPublicInstance(e.stateNode);if(t){return{instance:t,nativeTag:getNativeTag(e.stateNode),stateNode:e.stateNode}}const n=[];if(e.child)n.push(e.child);let r=0;while(n.length>0&&r<4e3){r++;const i=n.pop();if(!i)continue;const s=getPublicInstance(i.stateNode);if(s)return{instance:s,nativeTag:getNativeTag(i.stateNode),stateNode:i.stateNode};if(i.child)n.push(i.child);if(i.sibling)n.push(i.sibling)}return null}function findScrollAncestor(e){let t=e;let n=0;while(t&&n++<200){const r=t.stateNode;if(r&&typeof r.scrollTo==="function"){const i=typeof r.getNativeScrollRef==="function"&&r.getNativeScrollRef()||null;const s=typeof r.getInnerViewNode==="function"&&r.getInnerViewNode()||typeof r.getScrollableNode==="function"&&r.getScrollableNode()||r;return{instance:r,nativeRef:i,innerNode:s}}t=t.return}return null}async function scrollIntoView(e,t,n,r){try{if((0,_utils.isDOMElement)(n)){n.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});await new Promise(u=>setTimeout(u,16));return true}const i=findScrollAncestor(e);if(!i)return false;const s=t;let a=null;const o=u=>new Promise(l=>{let c=false;const d=m=>{if(c)return;c=true;l(m)};const g=setTimeout(()=>d(null),600);try{u(m=>{clearTimeout(g);d(m)})}catch{clearTimeout(g);d(null)}});if(i.nativeRef&&typeof s.measureLayout==="function"){a=await o(u=>s.measureLayout(i.nativeRef,(l,c)=>u(c),()=>u(null)))}if(a==null){const u=(0,_reactNative.findNodeHandle)(t);const l=typeof i.innerNode==="number"?i.innerNode:(0,_reactNative.findNodeHandle)(i.innerNode);if(u!=null&&l!=null){a=await o(c=>_reactNative.UIManager.measureLayout(u,l,()=>c(null),(d,g)=>c(g)))}}if(a==null)return false;i.instance.scrollTo({y:Math.max(0,a-r),animated:false});await new Promise(u=>setTimeout(u,120));return true}catch{return false}}function getComponentName(e){const t=e?.type;if(!t)return null;if(typeof t==="string")return t;return t.displayName||t.name||null}function getOwningComponentName(e){let t=e?._debugOwner||e?.return;let n=0;while(t&&n<30){n++;const r=getComponentName(t);if(r&&!INTERNAL_NAMES.has(r)&&typeof t.type!=="string"){return r}t=t.return}return null}function getProps(e){return(0,_utils.getDOMControlProps)(e?.stateNode,e?.memoizedProps??e?.pendingProps??null)}function flattenText(e,t=0){if(typeof e==="string")return e;if(typeof e==="number"&&Number.isFinite(e))return String(e);if(Array.isArray(e)&&t<4){const n=[];for(const r of e){const i=flattenText(r,t+1);if(i)n.push(i)}return n.length>0?n.join(""):void 0}return void 0}function normalizeVisibleText(e){return e.replace(/\s+/g," ").trim()}function getVisibleText(e){if(!e)return void 0;const t=n=>{const r=flattenText(n);if(r===void 0)return void 0;const i=normalizeVisibleText(r);return i?fullVisibleText?i:i.slice(0,80):void 0};return t(e.children)??t(e.title)??t(e.label)??t(e.placeholder)??void 0}function collectDescendantText(e,t){const n=[];const r=(s,a)=>{if(!s||a>t||n.length>=4)return;if(s!==e){const u=getProps(s);if(u&&(typeof u.onPress==="function"||typeof u.onLongPress==="function"))return}const o=getVisibleText(getProps(s));if(o&&!n.includes(o))n.push(o);if(s.child)r(s.child,a+1);if(s!==e&&s.sibling)r(s.sibling,a)};if(e.child)r(e.child,1);const i=n.join(" ").trim();return i?i.slice(0,80):void 0}function findPressHandler(e){let t=e;let n=0;let r=null;let i=null;while(t&&n<25&&!(r&&i)){const s=getProps(t);if(s){if(!r&&typeof s.onPress==="function")r=s.onPress;if(!i&&typeof s.onLongPress==="function")i=s.onLongPress}t=t.return;n++}if(r)return{handler:r,kind:"onPress",longPress:i??void 0};return i?{handler:i,kind:"onLongPress"}:null}function measureInstance(e){return new Promise(t=>{let n=false;const r=i=>{if(n)return;n=true;t(i)};setTimeout(()=>r(null),1e3);try{if(typeof e.measureInWindow==="function"){e.measureInWindow((i,s,a,o)=>{if(a>0&&o>0)r({x:i,y:s,width:a,height:o});else r(null)})}else if(typeof e.measure==="function"){e.measure((i,s,a,o,u,l)=>{if(a>0&&o>0&&u!=null&&l!=null){r({x:u,y:l,width:a,height:o})}else{r(null)}})}else{r(null)}}catch{r(null)}})}const SPINNER_HOSTS=new Set(["RCTActivityIndicatorView","AndroidProgressBar"]);function collectCandidates(){const e=getAllFiberRoots();const t=[];const n=new Map;const r=new Map;const i=makeChromeCheck();for(const s of e){traverseFiberTree(s.current,a=>{const o=getProps(a);if(!o)return;const u=typeof o.onPress==="function"||typeof o.onLongPress==="function";const l=typeof o.onValueChange==="function";const c=typeof o.onChangeText==="function";const d=o.testID||void 0;const g=o.accessibilityLabel||void 0;const m=o.accessibilityRole||o.role||void 0;let w=getVisibleText(o);const y=m==="button"||m==="link"||m==="menuitem"||m==="tab"||m==="switch"||m==="checkbox";const b=typeof a.type==="string"&&SPINNER_HOSTS.has(a.type)&&o.animating!==false;if(!u&&!l&&!c&&!d&&!g&&!w&&!y&&!b){return}let x=null;let N=null;let I=null;if(l){const D=o.value;const S=typeof D==="number"||typeof o.minimumValue==="number";N={handler:o.onValueChange,kind:S?"slider":"toggle",current:D,min:typeof o.minimumValue==="number"?o.minimumValue:void 0,max:typeof o.maximumValue==="number"?o.maximumValue:void 0}}else if(c){I={handler:o.onChangeText,current:typeof o.value==="string"?o.value:void 0}}else{x=findPressHandler(a)}const C=getComponentName(a);let f=C??"Unknown";if(!C||INTERNAL_NAMES.has(C)||typeof a.type==="string"){f=getOwningComponentName(a)??C??"Unknown"}const h=findHostInstance(a);if(!h&&!d)return;if(!w&&!g&&u){w=collectDescendantText(a,6)}const p=h?.instance??null;const T=h?.nativeTag??null;const v=(p?n.get(p):void 0)??(T!=null?r.get(T):void 0);if(v){if(x)v.press=x;if(!v.valueControl&&N)v.valueControl=N;if(!v.textControl&&I)v.textControl=I;if(!v.testID&&d)v.testID=d;if(!v.label&&g)v.label=g;if(!v.text&&w)v.text=w;if(p&&!n.has(p))n.set(p,v);if(T!=null&&!r.has(T))r.set(T,v);return}const P={nativeTag:T,name:f,role:m??(b?"progressbar":void 0),testID:d,label:g,text:w,instance:p,stateNode:h?.stateNode??null,fiber:a,press:x,valueControl:N,textControl:I,rect:null,buoy:i(a)};t.push(P);if(p)n.set(p,P);if(T!=null)r.set(T,P)})}t.push(...collectDOMCandidates());return t}function collectDOMCandidates(){return(0,_domScreenElements.collectDOMElements)({fullText:fullVisibleText}).map(({element:e,props:t,text:n,buoy:r})=>{const i=typeof t.onValueChange==="function"?{handler:t.onValueChange,kind:typeof t.value==="number"?"slider":"toggle",current:t.value,min:t.minimumValue,max:t.maximumValue}:null;const s=!i&&typeof t.onChangeText==="function"?{handler:t.onChangeText,current:t.value}:null;const a=!i&&!s&&typeof t.onPress==="function"?{handler:t.onPress,kind:"onPress"}:null;return{nativeTag:(0,_utils.getDOMNodeHandle)(e),name:(0,_domScreenElements.domElementName)(e),role:t.accessibilityRole,testID:t.testID,label:t.accessibilityLabel,text:n,instance:(0,_utils.getDOMPublicInstance)(e),stateNode:e,fiber:null,buoy:r,press:a,valueControl:i,textControl:s,rect:null}})}function explicitlyTargets(e,t){if(t.nativeTag!=null)return e.nativeTag===t.nativeTag;if(t.testID&&e.testID)return e.testID.toLowerCase()===t.testID.toLowerCase();return false}function appCandidates(e){const t=collectCandidates();if(e.includeBuoy)return t;return t.filter(n=>!n.buoy||explicitlyTargets(n,e))}async function measureCandidates(e){await Promise.all(e.map(async t=>{if(t.instance)t.rect=await measureInstance(t.instance)}))}const LIST_WRAPPERS=/^(FlatList|SectionList|VirtualizedSectionList|VirtualizedList|Animated\(.*\)|AnimatedComponent.*)$/;async function collectLists(e,t){const n=[];const r=makeChromeCheck();for(const s of getAllFiberRoots()){traverseFiberTree(s.current,a=>{if(getComponentName(a)!=="VirtualizedList")return;const o=a.memoizedProps;if(!o||typeof o.getItemCount!=="function")return;if(!e&&r(a))return;let u;try{u=Number(o.getItemCount(o.data))}catch{return}if(!Number.isFinite(u)||u<=0)return;const l=[];const c=(m,w)=>{for(let y=m?.child;y;y=y.sibling){const b=getComponentName(y);if(b==="VirtualizedList")continue;if(b==="CellRenderer"){l.push(y);continue}if(w<40)c(y,w+1)}};c(a,0);let d=a;let g=getOwningComponentName(d);for(let m=0;m<6&&g&&LIST_WRAPPERS.test(g);m++){d=d._debugOwner||d.return;g=getOwningComponentName(d)}n.push({owner:g,items:u,cells:l})})}const i=[];for(const s of n){const a=await Promise.all(s.cells.map(async u=>{const l=findHostInstance(u);return l?measureInstance(l.instance):null}));const o=a.filter(t).length;if(o>0&&s.items>o)i.push({owner:s.owner,items:s.items,listed:o})}return i}async function describeScreen(e={}){const t=includeHiddenScreens;const n=fullVisibleText;includeHiddenScreens=!!e.includeHidden;fullVisibleText=!!e.fullText;try{return await describeScreenInner(e)}finally{includeHiddenScreens=t;fullVisibleText=n}}async function describeScreenInner(e){prunedHiddenScreens=0;const t=collectCandidates();const n=prunedHiddenScreens;const r=e.includeBuoy?t:t.filter(c=>!c.buoy);const i=t.length-r.length;await measureCandidates(r);const s=_reactNative.Dimensions.get("window");const a=Math.round(s.width)||1;const o=Math.round(s.height)||1;const u=[];for(const c of r){const d=c.rect;if(!d&&!c.testID)continue;let g;let m;if(d){const b=d.x+d.width/2;const x=d.y+d.height/2;if(x<-o*.1||x>o*1.1||b<-a*.1||b>a*1.1){continue}g={x:round2(b/a),y:round2(x/o)};m={x:round2(d.x/a),y:round2(d.y/o),width:round2(d.width/a),height:round2(d.height/o)}}const w=c.valueControl?c.valueControl.kind:c.textControl?"text":void 0;const y=c.valueControl?c.valueControl.current:c.textControl?.current;u.push({nativeTag:c.nativeTag,name:c.name,role:c.role,testID:c.testID,label:c.label,text:c.text,interactive:!!(c.press||c.valueControl||c.textControl),longPressable:c.press&&(c.press.kind==="onLongPress"||c.press.longPress)?true:void 0,control:w,value:y,tap:g,frame:m,...c.buoy?{buoy:true}:{}})}u.sort((c,d)=>{const g=c.tap?.y??2;const m=d.tap?.y??2;if(Math.abs(g-m)>.02)return g-m;return(c.tap?.x??2)-(d.tap?.x??2)});const l=await collectLists(!!e.includeBuoy,c=>{if(!c)return false;const d=c.x+c.width/2;return c.y<=o*1.1&&c.y+c.height>=-o*.1&&d>=-a*.1&&d<=a*1.1});return{screen:{width:a,height:o},count:u.length,elements:u,...i>0?{hiddenBuoy:i}:{},...n>0?{hiddenScreens:n}:{},...l.length?{lists:l}:{}}}function round2(e){return Math.round(e*100)/100}function fieldsOf(e){return{nativeTag:e.nativeTag,testID:e.testID,label:e.label,text:e.text,name:e.name}}function matchScore(e,t){return(0,_tapMatch.scoreTapMatch)(fieldsOf(e),t)}function tapPoint(e,t,n){if(!e||!t||!n)return void 0;return{x:(e.x+e.width/2)/t,y:(e.y+e.height/2)/n}}function makeSyntheticPressEvent(e){const t=e?e.x+e.width/2:0;const n=e?e.y+e.height/2:0;const r={locationX:e?e.width/2:0,locationY:e?e.height/2:0,pageX:t,pageY:n,timestamp:0,target:null,identifier:1,touches:[],changedTouches:[]};return{nativeEvent:r,persist:()=>{},preventDefault:()=>{},stopPropagation:()=>{},isDefaultPrevented:()=>false,isPropagationStopped:()=>false,target:null,currentTarget:null,type:"press",timeStamp:0}}async function tapElement(e){const t=withHiddenScreens(!!e.includeHidden,()=>appCandidates(e));if(t.length===0){return{tapped:false,reason:"Nothing on screen to tap: no React elements and no page elements were found."}}const n=t.map(f=>({c:f,score:matchScore(f,e)})).filter(f=>f.score>0).sort((f,h)=>h.score-f.score);const r=f=>!!(f.press||f.valueControl||f.textControl);if(n.length===0&&!e.includeHidden){const f=withHiddenScreens(true,()=>appCandidates(e)).map(h=>({c:h,score:matchScore(h,e)})).filter(h=>h.score>0);if(f.length>0){return{tapped:false,reason:"That element is only on a screen that isn't showing (another tab, or a screen under the current one). Navigate to it first, or pass includeHidden:true if you really mean the hidden one."}}}if(n.length===0){return{tapped:false,reason:"No element matched. Call describe_screen to see available elements (match by testID, text, or name).",candidates:t.filter(r).slice(0,12).map(f=>({nativeTag:f.nativeTag,name:f.name,testID:f.testID,text:f.text}))}}const i=_reactNative.Dimensions.get("window");const s=i.width||1;const a=i.height||1;const o=n.slice(0,15);await Promise.all(o.map(async f=>{if(f.c.instance&&!f.c.rect)f.c.rect=await measureInstance(f.c.instance)}));for(const f of o){f.score=(0,_tapMatch.scoreTapMatch)({...fieldsOf(f.c),tap:tapPoint(f.c.rect,s,a)},e)}o.sort((f,h)=>h.score-f.score);if(e.text!==void 0){for(const f of o){const h=!r(f.c)&&(0,_utils.isDOMElement)(f.c.stateNode)?(0,_domScreenElements.labeledField)(f.c.stateNode):null;const p=h?t.find(T=>T.stateNode===h&&T.textControl):void 0;if(p)f.c=p}}const u=o.find(f=>r(f.c))??n.find(f=>r(f.c))??o[0];const l=u.c;const c=(f,h)=>f.press&&f.press.handler===h.press?.handler||f.valueControl&&f.valueControl.handler===h.valueControl?.handler||f.textControl&&f.textControl.handler===h.textControl?.handler;const d=o.filter(f=>f!==u&&r(f.c)&&f.score===u.score).filter(f=>!c(f.c,l)).filter((f,h,p)=>p.findIndex(T=>c(T.c,f.c))===h).slice(0,3).map(f=>({nativeTag:f.c.nativeTag,name:f.c.name,testID:f.c.testID,text:f.c.text,tap:tapPoint(f.c.rect,s,a)}));const g=e.nativeTag==null&&!(e.testID&&!e.query);if(g&&d.length>0){const f=[l,...d.map(h=>o.find(p=>p.c.nativeTag===h.nativeTag)?.c).filter(Boolean)];return{tapped:false,reason:`"${e.query}" matches ${f.length} different controls equally well, so nothing was tapped. Tap one by its nativeTag.`,candidates:f.map(h=>({nativeTag:h.nativeTag,name:h.name,testID:h.testID,text:h.text}))}}const m=o[0];if(g&&m&&m!==u&&!r(m.c)&&m.score>=90&&u.score<m.score-40){return{tapped:false,reason:`The best match for "${e.query}" is "${m.c.text??m.c.label??m.c.name}", which has no JS press handler (it may be native, like a tab bar button). The closest pressable match, "${l.text??l.label??l.name}", is a much weaker match, so nothing was tapped. Use navigate, or tap a specific element by nativeTag.`,candidates:[{nativeTag:l.nativeTag,name:l.name,testID:l.testID,text:l.text}]}}if(!r(l)){return{tapped:false,reason:(0,_utils.isDOMElement)(l.stateNode)?`Matched "${l.name}"${l.text?` ("${l.text}")`:""}, but it is not a button or a field. This element can't be driven in JS.`:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onPress / onValueChange / onChangeText handler (e.g. a react-native-gesture-handler GestureDetector). This element can't be driven in JS.`,matched:{nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text,via:"onPress"}}}if(l.instance&&!l.rect)l.rect=await measureInstance(l.instance);let w=false;const y=l.rect==null||!(0,_tapMatch.isRectCenterOnScreen)(l.rect,s,a);if(y&&e.scrollIntoView!==false&&l.instance){w=await scrollIntoView(l.fiber,l.instance,l.stateNode,80);if(w)l.rect=await measureInstance(l.instance)}const b={nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text};ensureCommitCounter();const x=commitCount;const N=l.fiber===null&&(0,_utils.isDOMElement)(l.stateNode)?(0,_domScreenElements.watchDOMChanges)():null;const I=Date.now();const C=async f=>{await new Promise(h=>setTimeout(h,TAP_SETTLE_MS));return{tapped:true,scrolled:w,matched:f,effect:{commits:N?N():commitCount-x,observedMs:Date.now()-I},...d.length?{alsoMatched:d}:{}}};try{if(l.press){if(e.longPress){const h=l.press.kind==="onLongPress"?l.press.handler:l.press.longPress;if(!h){return{tapped:false,scrolled:w,reason:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onLongPress handler \u2014 call tap_element without longPress to tap it normally.`,matched:{...b,via:"onPress"}}}h(makeSyntheticPressEvent(l.rect));return await C({...b,via:"onLongPress"})}l.press.handler(makeSyntheticPressEvent(l.rect));return await C({...b,via:l.press.kind})}if(l.valueControl){const h=l.valueControl;let p;if(h.kind==="toggle"){p=typeof e.value==="boolean"?e.value:!h.current}else{const T=h.min??0;const v=h.max??1;if(typeof e.value==="number"){p=Math.min(v,Math.max(T,e.value))}else{p=h.current===v?T:v}}h.handler(p);return await C({...b,via:"onValueChange",value:p})}const f=e.text??(typeof e.value==="string"?e.value:"");l.textControl.handler(f);return await C({...b,via:"onChangeText",value:f})}catch(f){N?.();return{tapped:false,scrolled:w,reason:`handler threw: ${f instanceof Error?f.message:String(f)}`,matched:{...b,via:l.press?l.press.kind:l.valueControl?"onValueChange":"onChangeText"}}}}const WAIT_DEFAULT_MS=5e3;const WAIT_MAX_MS=3e4;const WAIT_MIN_POLL_MS=50;const WAIT_DEFAULT_POLL_MS=150;async function waitFor(e){const t=e.nativeTag!=null||!!String(e.testID??"").trim()||!!String(e.query??"").trim();if(!t){return{ok:false,waitedMs:0,polls:0,reason:"Nothing to wait for \u2014 pass nativeTag, testID or query."}}const n=Math.min(Math.max(e.timeoutMs??WAIT_DEFAULT_MS,0),WAIT_MAX_MS);const r=Math.max(e.pollMs??WAIT_DEFAULT_POLL_MS,WAIT_MIN_POLL_MS);const i=e.gone===true;const s=Date.now();let a=0;for(;;){a+=1;const{hit:o,closest:u}=await findOnScreen(e);if(i?!o:!!o){return{ok:true,waitedMs:Date.now()-s,polls:a,matched:o??void 0}}if(Date.now()-s>=n){const l=u?.length?u:void 0;const c=i?`Still on screen after ${n}ms.`:l?`Not on screen after ${n}ms \u2014 ${l.length===1?"one element":`${l.length} elements`} matched but ${l.some(d=>d.onScreen)?"not well enough":"none is visible"}. See \`closest\`; do not retry with different words, call describeScreen.`:`Not on screen after ${n}ms, and nothing matched those words at all. Call describeScreen to see what is there.`;return{ok:false,waitedMs:Date.now()-s,polls:a,reason:c,matched:o??void 0,closest:l}}await new Promise(l=>setTimeout(l,r))}}async function findOnScreen(e){const t=appCandidates(e).map(o=>({c:o,score:matchScore(o,e)})).filter(o=>o.score>0).sort((o,u)=>u.score-o.score).slice(0,8);if(t.length===0)return{hit:null,closest:void 0};await measureCandidates(t.map(o=>o.c));const n=_reactNative.Dimensions.get("window");const r=Math.round(n.width)||1;const i=Math.round(n.height)||1;let s=null;for(const{c:o}of t){if(!(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i))continue;s={nativeTag:o.nativeTag,name:o.name,testID:o.testID,label:o.label,text:o.text,interactive:!!(o.press||o.valueControl||o.textControl)};break}const a=t.slice(0,3).map(({c:o})=>({name:o.name,testID:o.testID,text:o.text,onScreen:(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i)}));return{hit:s,closest:a}}function isBuoyChrome(e){let t=e;let n=0;while(t&&n<400){if(getProps(t)?.__buoyDevToolsRoot)return true;t=t.return;n++}return false}function preferHandlerOwner(e,t){const n=getProps(e.fiber);if(typeof n?.onPress==="function"||typeof n?.onValueChange==="function"||typeof n?.onChangeText==="function"){return e}let r=null;let i=e.fiber?.return;let s=0;while(i&&s<25){if(typeof getProps(i)?.onPress==="function"){r=i;break}i=i.return;s++}if(!r)return e;let a=r;for(let o=0;o<6&&a;o++){const u=t.get(a);if(u)return u;a=a.return}return e}function resolveTouchTarget(e){const t=collectCandidates();if(t.length===0)return null;const n=new Map;for(const a of t)n.set(a.fiber,a);const r=t.find(a=>a.nativeTag===e);let i=null;if(!r){for(const a of getAllFiberRoots()){traverseFiberTree(a.current,o=>{if(i)return;if(o.stateNode&&getNativeTag(o.stateNode)===e){i=o}});if(i)break}}let s=r??null;if(!s&&i){let a=i;let o=0;let u=null;while(a&&o<25){const l=n.get(a);if(l){if(l.press||l.valueControl||l.textControl){s=l;break}if(!u)u=l}a=a.return;o++}if(!s)s=u}if(!s?.fiber&&!i){const a=s?.stateNode;const o=(0,_utils.isDOMElement)(a)?a:domElementForTag(e);if(o){for(let u=o;u;u=u.parentElement){const l=t.find(c=>c.stateNode===u&&(c.press||c.valueControl||c.textControl));if(l)return l.buoy?null:touchTargetOf(l)}return null}}if(!s)return null;s=preferHandlerOwner(s,n);if(!s.press&&!s.valueControl&&!s.textControl)return null;if(isBuoyChrome(s.fiber))return null;return touchTargetOf(s)}function domElementForTag(e){const t=global.document;if(!t?.querySelectorAll)return null;return Array.from(t.querySelectorAll("*")).find(n=>(0,_utils.getDOMNodeHandle)(n)===e)??null}function touchTargetOf(e){return{nativeTag:e.nativeTag,name:e.name,role:e.role,testID:e.testID,label:e.label,text:e.text,control:e.valueControl?e.valueControl.kind:e.textControl?"text":"press",value:e.valueControl?e.valueControl.current:e.textControl?.current}}function fiberForTag(e){let t=null;for(const n of getAllFiberRoots()){traverseFiberTree(n.current,r=>{if(!t&&r.stateNode&&getNativeTag(r.stateNode)===e)t=r});if(t)break}return t}function rootHostFibers(){const e=[];for(const t of getAllFiberRoots()){let n=t.current?.child;let r=0;while(n&&r++<200){if(n.tag===HostComponent&&n.stateNode){e.push(n);break}n=n.child}}return e}function fabricFiberAt(e,t){const n=global.nativeFabricUIManager;if(!n||typeof n.findNodeAtPoint!=="function")return null;const r=rootHostFibers().filter(i=>i.stateNode?.node);if(!r.length)return null;return new Promise(i=>{const s=setTimeout(()=>i(null),1e3);let a=r.length;let o=null;r.forEach((u,l)=>{try{n.findNodeAtPoint(u.stateNode.node,e,t,c=>{if(c&&(!o||l>=o.i))o={i:l,fiber:c};if(--a===0){clearTimeout(s);i(o?.fiber??null)}})}catch{if(--a===0){clearTimeout(s);i(o?.fiber??null)}}})})}function paperFiberAt(e,t){const n=_reactNative.UIManager?.findSubviewIn;if(typeof n!=="function")return null;const r=rootHostFibers()[0];const i=r?getNativeTag(r.stateNode)??(0,_reactNative.findNodeHandle)(r.stateNode):null;if(i==null)return null;return new Promise(s=>{const a=setTimeout(()=>s(null),1e3);try{n.call(_reactNative.UIManager,i,[e,t],o=>{clearTimeout(a);s(typeof o==="number"?fiberForTag(o):null)})}catch{clearTimeout(a);s(null)}})}function visibleHostFibers(){const e=[];const t=new Set;const n=i=>{const s=[];const a=(o,u)=>{for(let l=o;l&&s.length<5e3;l=l.sibling){if(t.has(l)||u>500)continue;if(isHiddenOffscreen(l)||isInactiveScreen(l))continue;if(l.tag===HostComponent&&l.stateNode)s.push(l);else if(l.child)a(l.child,u+1)}};if(i.child)a(i.child,0);return s};const r=(i,s)=>{if(t.has(i)||s>500)return;t.add(i);e.push(i);sortByZ(n(i)).forEach(a=>r(a,s+1))};for(const i of getAllFiberRoots())sortByZ(n(i.current)).forEach(s=>r(s,0));return e}function sortByZ(e){const t=e.map(n=>{const r=Number(flatStyle(getProps(n)?.style).zIndex);return Number.isFinite(r)?r:0});return e.map((n,r)=>({h:n,i:r})).sort((n,r)=>t[n.i]-t[r.i]||n.i-r.i).map(({h:n})=>n)}function flatStyle(e,t=0){if(!e||typeof e!=="object"||t>10)return{};if(Array.isArray(e))return Object.assign({},...e.map(n=>flatStyle(n,t+1)));return e}const SCROLL_HOSTS=new Set(["RCTScrollView","AndroidHorizontalScrollView","RCTScrollContentView"]);function clipsChildren(e){if(typeof e.type==="string"&&SCROLL_HOSTS.has(e.type)&&e.type!=="RCTScrollContentView")return true;const t=flatStyle(getProps(e)?.style).overflow;return t==="hidden"||t==="scroll"}function passesTouchesThrough(e){let t=getProps(e)?.pointerEvents??getProps(e)?.style?.pointerEvents;if(t==="none")return"all";let n=e.return;let r=0;while(n&&r++<200){const i=getProps(n)?.pointerEvents??getProps(n)?.style?.pointerEvents;if(i==="none")return"all";if(i==="box-only"&&n.tag===HostComponent)return"all";n=n.return}return t==="box-none"?"self":null}async function measuredFiberAt(e,t,n){const r=await Promise.all(n.map(o=>{const u=getPublicInstance(o.stateNode);return u?measureInstance(u):Promise.resolve(null)}));const i=new Map;n.forEach((o,u)=>i.set(o,r[u]));const s=o=>!!o&&e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height;const a=o=>{for(let u=o.return,l=0;u&&l<300;u=u.return,l++){if(u.tag===HostComponent&&i.has(u)&&clipsChildren(u)&&!s(i.get(u)))return true}return false};for(let o=n.length-1;o>=0;o--){if(!s(r[o])||passesTouchesThrough(n[o])||a(n[o]))continue;return n[o]}return null}function domFiberAt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;let i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);while(i){const s=Object.keys(i).find(a=>a.startsWith("__reactFiber$"));if(s)return i[s];i=i.parentElement}return null}function domPageHit(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;const i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);if(!i)return null;for(let c=i;c;c=c.parentElement){if(Object.keys(c).some(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactContainer$")))return null}const s=!!i.closest("[data-buoy-root], [data-buoy-portal-host]");const a=collectDOMCandidates();const o=a.find(c=>c.stateNode===i);let u;for(let c=i;c&&!u;c=c.parentElement){u=a.find(d=>d.stateNode===c&&(d.press||d.valueControl||d.textControl))}const l=[];for(let c=i;c&&l.length<6;c=c.parentElement){const d=(0,_domScreenElements.domElementName)(c);if(d!==c.tagName.toLowerCase()&&l[l.length-1]!==d)l.push(d)}return{found:true,method:"dom",buoy:s,view:{name:(0,_domScreenElements.domElementName)(i),nativeTag:(0,_utils.getDOMNodeHandle)(i),testID:o?.testID,label:o?.label,text:o?.text},path:l,target:u&&!s?touchTargetOf(u):null}}async function hitTest(e){const t=Math.min(1,Math.max(0,Number(e?.x)));const n=Math.min(1,Math.max(0,Number(e?.y)));if(!Number.isFinite(t)||!Number.isFinite(n))return{found:false,method:"none",reason:"x and y must be numbers from 0 to 1."};const r=_reactNative.Dimensions.get("window");const i=t*r.width;const s=n*r.height;let a="none";let o=null;const u=domFiberAt(t,n);const l=u?null:domPageHit(t,n);if(l)return l;if(u){a="dom";o=u}else{const y=fabricFiberAt(i,s);if(y){a="fabric";o=await y}else{const x=paperFiberAt(i,s);if(x){a="paper";o=await x}}const b=visibleHostFibers();if(!o||!new Set(b).has(o)){o=await measuredFiberAt(i,s,b);a="measured"}}if(!o)return{found:false,method:a};const c=getProps(o)??{};const d=getNativeTag(o.stateNode);const g=[];let m=o;let w=0;while(m&&w++<80&&g.length<6){const y=getComponentName(m);if(y&&typeof m.type!=="string"&&!INTERNAL_NAMES.has(y)&&g[g.length-1]!==y)g.push(y);m=m.return}return{found:true,method:a,buoy:isBuoyChrome(o),view:{name:getComponentName(o)??"Unknown",nativeTag:d,testID:c.testID||void 0,label:c.accessibilityLabel||c["aria-label"]||void 0,text:getVisibleText(c)},path:g,target:d!=null?resolveTouchTarget(d):null}}async function readMaps(){const e=[];for(const i of getAllFiberRoots()){traverseFiberTree(i.current,s=>{const a=s.stateNode;if(s.tag===1&&a&&typeof a.getCamera==="function"&&!isBuoyChrome(s))e.push(s)})}const t=_reactNative.Dimensions.get("window");const n=i=>Promise.race([i,new Promise(s=>setTimeout(()=>s(null),1e3))]);const r=await Promise.all(e.slice(0,5).map(async i=>{try{const s=await n(Promise.resolve(i.stateNode.getCamera()));if(!s)return null;const a=findHostInstance(i);const o=a?await measureInstance(a.instance):null;const u=getProps(i)??{};return{name:getComponentName(i)??"Map",testID:typeof u.testID==="string"?u.testID:void 0,frame:o&&t.width&&t.height?{x:round2(o.x/t.width),y:round2(o.y/t.height),width:round2(o.width/t.width),height:round2(o.height/t.height)}:void 0,camera:{heading:typeof s.heading==="number"?s.heading:void 0,pitch:typeof s.pitch==="number"?s.pitch:void 0,altitude:typeof s.altitude==="number"?s.altitude:void 0,zoom:typeof s.zoom==="number"?s.zoom:void 0,center:s.center}}}catch{return null}}));return{maps:r.filter(i=>!!i)}}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.clearTouchCapture=clearTouchCapture;exports.getTouchCaptureStatus=getTouchCaptureStatus;exports.readTouchCapture=readTouchCapture;exports.startTouchCapture=startTouchCapture;exports.stopTouchCapture=stopTouchCapture;var _screenElements=require("./screenElements");var _rawEventEmitter=require("./rawEventEmitter");const TAP_SLOP_PT=14;const LONG_PRESS_MS=550;const MAX_TAP_MS=4e3;const TEXT_COALESCE_MS=8e3;const MAX_RECORDS=600;let emitter=null;let emitterResolved=false;let unavailableReason=null;let subscriptions=[];let status="idle";let records=[];let seq=0;let pending=null;function getEmitter(){if(emitterResolved)return emitter;emitterResolved=true;const e=(0,_rawEventEmitter.resolveRawEventEmitter)();emitter=e.emitter;unavailableReason=e.reason;return emitter}function num(e){return typeof e==="number"&&Number.isFinite(e)?e:null}function tagOf(e){const t=e?.nativeEvent;if(!t)return null;return num(t.target)??num(t.tag)}function pointOf(e){const t=e?.nativeEvent;if(!t)return null;const n={x:num(t.pageX),y:num(t.pageY)};if(n.x!==null&&n.y!==null)return{x:n.x,y:n.y};for(const r of["changedTouches","touches"]){const o=t[r];if(Array.isArray(o)&&o.length){const u=o[0];const a=num(u?.pageX);const i=num(u?.pageY);if(a!==null&&i!==null)return{x:a,y:i}}}return null}function push(e){records.push({...e,seq:++seq});if(records.length>MAX_RECORDS)records=records.slice(-MAX_RECORDS)}function onTouchStart(e){const t=tagOf(e);if(t===null)return;const n=pointOf(e);let r=null;try{r=(0,_screenElements.resolveTouchTarget)(t)}catch{}pending={tag:t,x:n?.x??0,y:n?.y??0,t:Date.now(),drift:0,target:r}}function onTouchMove(e){if(!pending)return;const t=pointOf(e);if(!t)return;const n=t.x-pending.x;const r=t.y-pending.y;pending.drift=Math.max(pending.drift,Math.sqrt(n*n+r*r))}function onTouchEnd(e){const t=pending;pending=null;if(!t||!t.target)return;const n=pointOf(e);if(n){const o=n.x-t.x;const u=n.y-t.y;t.drift=Math.max(t.drift,Math.sqrt(o*o+u*u))}if(t.drift>TAP_SLOP_PT)return;const r=Date.now()-t.t;if(r>MAX_TAP_MS)return;if(t.target.control==="text")return;if(t.target.control==="toggle"||t.target.control==="slider")return;push({t:Date.now(),kind:r>=LONG_PRESS_MS?"longPress":"press",target:t.target})}function onTouchCancel(){pending=null}function onChange(e){const t=tagOf(e);if(t===null)return;const n=e.nativeEvent;let r;let o;if(typeof n.text==="string"){r="text";o=n.text}else if(typeof n.value==="boolean"){r="toggle";o=n.value}else if(typeof n.value==="number"){r="slider";o=n.value}else{return}const u=records[records.length-1];if(u&&u.kind===r&&u.target.nativeTag===t&&Date.now()-u.t<TEXT_COALESCE_MS){u.value=o;u.t=Date.now();return}let a=null;try{a=(0,_screenElements.resolveTouchTarget)(t)}catch{}if(!a)return;push({t:Date.now(),kind:r,target:a,value:o})}function startTouchCapture(){if(status==="capturing")return getTouchCaptureStatus();const e=getEmitter();if(!e){status="unavailable";return getTouchCaptureStatus()}try{subscriptions=[e.addListener("topTouchStart",onTouchStart),e.addListener("topTouchMove",onTouchMove),e.addListener("topTouchEnd",onTouchEnd),e.addListener("topTouchCancel",onTouchCancel),e.addListener("topChange",onChange),e.addListener("topValueChange",onChange),e.addListener("topSlidingComplete",onChange)];pending=null;status="capturing"}catch(t){subscriptions=[];status="unavailable";unavailableReason=t?.message??"addListener failed"}return getTouchCaptureStatus()}function stopTouchCapture(){subscriptions.forEach(e=>{try{e.remove()}catch{}});subscriptions=[];pending=null;if(status==="capturing")status="idle"}function clearTouchCapture(){records=[];seq=0}function getTouchCaptureStatus(){return{status,reason:status==="unavailable"?unavailableReason:null}}function readTouchCapture(e=0){return{...getTouchCaptureStatus(),records:records.filter(t=>t.seq>e),seq}}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.clearTouchCapture=clearTouchCapture;exports.getTouchCaptureStatus=getTouchCaptureStatus;exports.readTouchCapture=readTouchCapture;exports.startTouchCapture=startTouchCapture;exports.stopTouchCapture=stopTouchCapture;var _sharedUi=require("@buoy-gg/shared-ui");var _screenElements=require("./screenElements");var _rawEventEmitter=require("./rawEventEmitter");const TAP_SLOP_PT=14;const LONG_PRESS_MS=550;const MAX_TAP_MS=4e3;const TEXT_COALESCE_MS=8e3;const MAX_RECORDS=600;let emitter=null;let emitterResolved=false;let unavailableReason=null;let subscriptions=[];let status="idle";let records=[];let seq=0;let pending=null;function getEmitter(){if(emitterResolved)return emitter;emitterResolved=true;const e=(0,_rawEventEmitter.resolveRawEventEmitter)();emitter=e.emitter;unavailableReason=e.reason;return emitter}function num(e){return typeof e==="number"&&Number.isFinite(e)?e:null}function tagOf(e){const t=e?.nativeEvent;if(!t)return null;return num(t.target)??num(t.tag)}function pointOf(e){const t=e?.nativeEvent;if(!t)return null;const n={x:num(t.pageX),y:num(t.pageY)};if(n.x!==null&&n.y!==null)return{x:n.x,y:n.y};for(const r of["changedTouches","touches"]){const u=t[r];if(Array.isArray(u)&&u.length){const o=u[0];const a=num(o?.pageX);const l=num(o?.pageY);if(a!==null&&l!==null)return{x:a,y:l}}}return null}function push(e){records.push({...e,seq:++seq,wall:(0,_sharedUi.realNow)()});if(records.length>MAX_RECORDS)records=records.slice(-MAX_RECORDS)}function onTouchStart(e){const t=tagOf(e);if(t===null)return;const n=pointOf(e);let r=null;try{r=(0,_screenElements.resolveTouchTarget)(t)}catch{}pending={tag:t,x:n?.x??0,y:n?.y??0,t:Date.now(),drift:0,target:r}}function onTouchMove(e){if(!pending)return;const t=pointOf(e);if(!t)return;const n=t.x-pending.x;const r=t.y-pending.y;pending.drift=Math.max(pending.drift,Math.sqrt(n*n+r*r))}function onTouchEnd(e){const t=pending;pending=null;if(!t||!t.target)return;const n=pointOf(e);if(n){const u=n.x-t.x;const o=n.y-t.y;t.drift=Math.max(t.drift,Math.sqrt(u*u+o*o))}if(t.drift>TAP_SLOP_PT)return;const r=Date.now()-t.t;if(r>MAX_TAP_MS)return;if(t.target.control==="text")return;if(t.target.control==="toggle"||t.target.control==="slider")return;push({t:Date.now(),kind:r>=LONG_PRESS_MS?"longPress":"press",target:t.target})}function onTouchCancel(){pending=null}function onChange(e){const t=tagOf(e);if(t===null)return;const n=e.nativeEvent;let r;let u;if(typeof n.text==="string"){r="text";u=n.text}else if(typeof n.value==="boolean"){r="toggle";u=n.value}else if(typeof n.value==="number"){r="slider";u=n.value}else{return}const o=records[records.length-1];if(o&&o.kind===r&&o.target.nativeTag===t&&(0,_sharedUi.realNow)()-(o.wall??o.t)<TEXT_COALESCE_MS){o.value=u;o.t=Date.now();o.wall=(0,_sharedUi.realNow)();return}let a=null;try{a=(0,_screenElements.resolveTouchTarget)(t)}catch{}if(!a)return;push({t:Date.now(),kind:r,target:a,value:u})}function startTouchCapture(){if(status==="capturing")return getTouchCaptureStatus();const e=getEmitter();if(!e){status="unavailable";return getTouchCaptureStatus()}try{subscriptions=[e.addListener("topTouchStart",onTouchStart),e.addListener("topTouchMove",onTouchMove),e.addListener("topTouchEnd",onTouchEnd),e.addListener("topTouchCancel",onTouchCancel),e.addListener("topChange",onChange),e.addListener("topValueChange",onChange),e.addListener("topSlidingComplete",onChange)];pending=null;status="capturing"}catch(t){subscriptions=[];status="unavailable";unavailableReason=t?.message??"addListener failed"}return getTouchCaptureStatus()}function stopTouchCapture(){subscriptions.forEach(e=>{try{e.remove()}catch{}});subscriptions=[];pending=null;if(status==="capturing")status="idle"}function clearTouchCapture(){records=[];seq=0}function getTouchCaptureStatus(){return{status,reason:status==="unavailable"?unavailableReason:null}}function readTouchCapture(e=0){return{...getTouchCaptureStatus(),records:records.filter(t=>t.seq>e),seq}}
@@ -1 +1 @@
1
- "use strict";import{getDOMControlProps as Te,getDOMNodeHandle as R,getDOMPublicInstance as re,isDOMElement as F}from"@buoy-gg/shared-ui/utils";import{Dimensions as L,UIManager as $,findNodeHandle as z}from"react-native";import{isRectCenterOnScreen as W,scoreTapMatch as ie}from"./tapMatch";import{collectDOMElements as xe,domElementName as B,labeledField as Ce,watchDOMChanges as Pe}from"./domScreenElements";const O=5;const Ie=22;const q=new Set(["View","RCTView","ScrollView","RCTScrollView","RCTScrollContentView","SafeAreaView","RCTSafeAreaView","AndroidHorizontalScrollContentView","KeyboardAvoidingView","Pressable","PlatformPressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","AnimatedComponent","Wrapper"]);function le(){if(typeof global==="undefined")return null;return global.__REACT_DEVTOOLS_GLOBAL_HOOK__??null}let U=0;let se=false;function Ne(){if(se)return;const e=le();if(!e)return;const t=e.onCommitFiberRoot;e.onCommitFiberRoot=function(...n){U++;return typeof t==="function"?t.apply(e,n):void 0};se=true}const Se=250;function ae(){const e=new Map;return t=>{const n=[];let r=t;let i=0;let s=false;while(r&&i<400){const a=e.get(r);if(a!==void 0){s=a;break}if(x(r)?.__buoyDevToolsRoot){s=true;e.set(r,true);break}n.push(r);r=r.return;i++}for(const a of n)e.set(a,s);return s}}function D(){const e=le();if(!e)return[];const t=[];try{if(e.renderers&&typeof e.renderers.forEach==="function"){e.renderers.forEach((n,r)=>{try{const i=e.getFiberRoots?.(r);if(i)i.forEach(s=>t.push(s))}catch{}})}if(t.length===0&&e.getFiberRoots){const n=e.getFiberRoots(1);if(n)n.forEach(r=>t.push(r))}}catch{}return t}function ue(e){return e.tag===Ie&&e.memoizedState!==null}let _=false;let j=0;let E=false;function ce(e,t){const n=_;_=e;try{return t()}finally{_=n}}function De(e){const t=e.memoizedProps;if(!t)return false;if(t["aria-hidden"]===true&&(t.activityState!==void 0||"shouldFreeze"in t))return true;if(t.isFocused===false&&(t.routeKey!==void 0||"freezeContents"in t))return true;return false}function fe(e){const t=e.memoizedProps?.activityState;if(t===0||t===1)return true;if(e.memoizedProps?.isPageFocused===false)return true;if(!_&&De(e)){j++;return true}return false}function S(e,t,n=0,r=new Set){if(!e||r.has(e)||n>500)return;r.add(e);if(ue(e)||fe(e)){if(e.sibling)S(e.sibling,t,n,r);return}t(e);if(e.child)S(e.child,t,n+1,r);if(e.sibling)S(e.sibling,t,n,r)}function G(e){const t=re(e);if(t)return t;if(!e)return null;const n=e;if(n.canonical?.publicInstance)return n.canonical.publicInstance;if(n.canonical&&typeof n.canonical.measure==="function"){return n.canonical}if(typeof n.measure==="function"||typeof n.measureInWindow==="function"){return n}return null}function A(e){const t=R(e);if(t!==null)return t;if(e==null)return null;const n=e;if(typeof n.__nativeTag==="number")return n.__nativeTag;if(typeof n._nativeTag==="number")return n._nativeTag;if(typeof n.nativeTag==="number")return n.nativeTag;if(n.canonical){if(typeof n.canonical.__nativeTag==="number")return n.canonical.__nativeTag;if(typeof n.canonical._nativeTag==="number")return n.canonical._nativeTag;if(typeof n.canonical.nativeTag==="number")return n.canonical.nativeTag}return null}function J(e){const t=G(e.stateNode);if(t){return{instance:t,nativeTag:A(e.stateNode),stateNode:e.stateNode}}const n=[];if(e.child)n.push(e.child);let r=0;while(n.length>0&&r<4e3){r++;const i=n.pop();if(!i)continue;const s=G(i.stateNode);if(s)return{instance:s,nativeTag:A(i.stateNode),stateNode:i.stateNode};if(i.child)n.push(i.child);if(i.sibling)n.push(i.sibling)}return null}function _e(e){let t=e;let n=0;while(t&&n++<200){const r=t.stateNode;if(r&&typeof r.scrollTo==="function"){const i=typeof r.getNativeScrollRef==="function"&&r.getNativeScrollRef()||null;const s=typeof r.getInnerViewNode==="function"&&r.getInnerViewNode()||typeof r.getScrollableNode==="function"&&r.getScrollableNode()||r;return{instance:r,nativeRef:i,innerNode:s}}t=t.return}return null}async function Me(e,t,n,r){try{if(F(n)){n.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});await new Promise(u=>setTimeout(u,16));return true}const i=_e(e);if(!i)return false;const s=t;let a=null;const o=u=>new Promise(l=>{let c=false;const d=m=>{if(c)return;c=true;l(m)};const g=setTimeout(()=>d(null),600);try{u(m=>{clearTimeout(g);d(m)})}catch{clearTimeout(g);d(null)}});if(i.nativeRef&&typeof s.measureLayout==="function"){a=await o(u=>s.measureLayout(i.nativeRef,(l,c)=>u(c),()=>u(null)))}if(a==null){const u=z(t);const l=typeof i.innerNode==="number"?i.innerNode:z(i.innerNode);if(u!=null&&l!=null){a=await o(c=>$.measureLayout(u,l,()=>c(null),(d,g)=>c(g)))}}if(a==null)return false;i.instance.scrollTo({y:Math.max(0,a-r),animated:false});await new Promise(u=>setTimeout(u,120));return true}catch{return false}}function M(e){const t=e?.type;if(!t)return null;if(typeof t==="string")return t;return t.displayName||t.name||null}function K(e){let t=e?._debugOwner||e?.return;let n=0;while(t&&n<30){n++;const r=M(t);if(r&&!q.has(r)&&typeof t.type!=="string"){return r}t=t.return}return null}function x(e){return Te(e?.stateNode,e?.memoizedProps??e?.pendingProps??null)}function de(e,t=0){if(typeof e==="string")return e;if(typeof e==="number"&&Number.isFinite(e))return String(e);if(Array.isArray(e)&&t<4){const n=[];for(const r of e){const i=de(r,t+1);if(i)n.push(i)}return n.length>0?n.join(""):void 0}return void 0}function ke(e){return e.replace(/\s+/g," ").trim()}function X(e){if(!e)return void 0;const t=n=>{const r=de(n);if(r===void 0)return void 0;const i=ke(r);return i?E?i:i.slice(0,80):void 0};return t(e.children)??t(e.title)??t(e.label)??t(e.placeholder)??void 0}function Ve(e,t){const n=[];const r=(s,a)=>{if(!s||a>t||n.length>=4)return;if(s!==e){const u=x(s);if(u&&(typeof u.onPress==="function"||typeof u.onLongPress==="function"))return}const o=X(x(s));if(o&&!n.includes(o))n.push(o);if(s.child)r(s.child,a+1);if(s!==e&&s.sibling)r(s.sibling,a)};if(e.child)r(e.child,1);const i=n.join(" ").trim();return i?i.slice(0,80):void 0}function Ae(e){let t=e;let n=0;let r=null;let i=null;while(t&&n<25&&!(r&&i)){const s=x(t);if(s){if(!r&&typeof s.onPress==="function")r=s.onPress;if(!i&&typeof s.onLongPress==="function")i=s.onLongPress}t=t.return;n++}if(r)return{handler:r,kind:"onPress",longPress:i??void 0};return i?{handler:i,kind:"onLongPress"}:null}function k(e){return new Promise(t=>{let n=false;const r=i=>{if(n)return;n=true;t(i)};setTimeout(()=>r(null),1e3);try{if(typeof e.measureInWindow==="function"){e.measureInWindow((i,s,a,o)=>{if(a>0&&o>0)r({x:i,y:s,width:a,height:o});else r(null)})}else if(typeof e.measure==="function"){e.measure((i,s,a,o,u,l)=>{if(a>0&&o>0&&u!=null&&l!=null){r({x:u,y:l,width:a,height:o})}else{r(null)}})}else{r(null)}}catch{r(null)}})}const Fe=new Set(["RCTActivityIndicatorView","AndroidProgressBar"]);function Y(){const e=D();const t=[];const n=new Map;const r=new Map;const i=ae();for(const s of e){S(s.current,a=>{const o=x(a);if(!o)return;const u=typeof o.onPress==="function"||typeof o.onLongPress==="function";const l=typeof o.onValueChange==="function";const c=typeof o.onChangeText==="function";const d=o.testID||void 0;const g=o.accessibilityLabel||void 0;const m=o.accessibilityRole||o.role||void 0;let w=X(o);const y=m==="button"||m==="link"||m==="menuitem"||m==="tab"||m==="switch"||m==="checkbox";const b=typeof a.type==="string"&&Fe.has(a.type)&&o.animating!==false;if(!u&&!l&&!c&&!d&&!g&&!w&&!y&&!b){return}let C=null;let N=null;let V=null;if(l){const oe=o.value;const ve=typeof oe==="number"||typeof o.minimumValue==="number";N={handler:o.onValueChange,kind:ve?"slider":"toggle",current:oe,min:typeof o.minimumValue==="number"?o.minimumValue:void 0,max:typeof o.maximumValue==="number"?o.maximumValue:void 0}}else if(c){V={handler:o.onChangeText,current:typeof o.value==="string"?o.value:void 0}}else{C=Ae(a)}const I=M(a);let f=I??"Unknown";if(!I||q.has(I)||typeof a.type==="string"){f=K(a)??I??"Unknown"}const h=J(a);if(!h&&!d)return;if(!w&&!g&&u){w=Ve(a,6)}const p=h?.instance??null;const T=h?.nativeTag??null;const v=(p?n.get(p):void 0)??(T!=null?r.get(T):void 0);if(v){if(C)v.press=C;if(!v.valueControl&&N)v.valueControl=N;if(!v.textControl&&V)v.textControl=V;if(!v.testID&&d)v.testID=d;if(!v.label&&g)v.label=g;if(!v.text&&w)v.text=w;if(p&&!n.has(p))n.set(p,v);if(T!=null&&!r.has(T))r.set(T,v);return}const H={nativeTag:T,name:f,role:m??(b?"progressbar":void 0),testID:d,label:g,text:w,instance:p,stateNode:h?.stateNode??null,fiber:a,press:C,valueControl:N,textControl:V,rect:null,buoy:i(a)};t.push(H);if(p)n.set(p,H);if(T!=null)r.set(T,H)})}t.push(...he());return t}function he(){return xe({fullText:E}).map(({element:e,props:t,text:n,buoy:r})=>{const i=typeof t.onValueChange==="function"?{handler:t.onValueChange,kind:typeof t.value==="number"?"slider":"toggle",current:t.value,min:t.minimumValue,max:t.maximumValue}:null;const s=!i&&typeof t.onChangeText==="function"?{handler:t.onChangeText,current:t.value}:null;const a=!i&&!s&&typeof t.onPress==="function"?{handler:t.onPress,kind:"onPress"}:null;return{nativeTag:R(e),name:B(e),role:t.accessibilityRole,testID:t.testID,label:t.accessibilityLabel,text:n,instance:re(e),stateNode:e,fiber:null,buoy:r,press:a,valueControl:i,textControl:s,rect:null}})}function Le(e,t){if(t.nativeTag!=null)return e.nativeTag===t.nativeTag;if(t.testID&&e.testID)return e.testID.toLowerCase()===t.testID.toLowerCase();return false}function Z(e){const t=Y();if(e.includeBuoy)return t;return t.filter(n=>!n.buoy||Le(n,e))}async function me(e){await Promise.all(e.map(async t=>{if(t.instance)t.rect=await k(t.instance)}))}const Ee=/^(FlatList|SectionList|VirtualizedSectionList|VirtualizedList|Animated\(.*\)|AnimatedComponent.*)$/;async function Re(e,t){const n=[];const r=ae();for(const s of D()){S(s.current,a=>{if(M(a)!=="VirtualizedList")return;const o=a.memoizedProps;if(!o||typeof o.getItemCount!=="function")return;if(!e&&r(a))return;let u;try{u=Number(o.getItemCount(o.data))}catch{return}if(!Number.isFinite(u)||u<=0)return;const l=[];const c=(m,w)=>{for(let y=m?.child;y;y=y.sibling){const b=M(y);if(b==="VirtualizedList")continue;if(b==="CellRenderer"){l.push(y);continue}if(w<40)c(y,w+1)}};c(a,0);let d=a;let g=K(d);for(let m=0;m<6&&g&&Ee.test(g);m++){d=d._debugOwner||d.return;g=K(d)}n.push({owner:g,items:u,cells:l})})}const i=[];for(const s of n){const a=await Promise.all(s.cells.map(async u=>{const l=J(u);return l?k(l.instance):null}));const o=a.filter(t).length;if(o>0&&s.items>o)i.push({owner:s.owner,items:s.items,listed:o})}return i}export async function describeScreen(e={}){const t=_;const n=E;_=!!e.includeHidden;E=!!e.fullText;try{return await Oe(e)}finally{_=t;E=n}}async function Oe(e){j=0;const t=Y();const n=j;const r=e.includeBuoy?t:t.filter(c=>!c.buoy);const i=t.length-r.length;await me(r);const s=L.get("window");const a=Math.round(s.width)||1;const o=Math.round(s.height)||1;const u=[];for(const c of r){const d=c.rect;if(!d&&!c.testID)continue;let g;let m;if(d){const b=d.x+d.width/2;const C=d.y+d.height/2;if(C<-o*.1||C>o*1.1||b<-a*.1||b>a*1.1){continue}g={x:P(b/a),y:P(C/o)};m={x:P(d.x/a),y:P(d.y/o),width:P(d.width/a),height:P(d.height/o)}}const w=c.valueControl?c.valueControl.kind:c.textControl?"text":void 0;const y=c.valueControl?c.valueControl.current:c.textControl?.current;u.push({nativeTag:c.nativeTag,name:c.name,role:c.role,testID:c.testID,label:c.label,text:c.text,interactive:!!(c.press||c.valueControl||c.textControl),longPressable:c.press&&(c.press.kind==="onLongPress"||c.press.longPress)?true:void 0,control:w,value:y,tap:g,frame:m,...c.buoy?{buoy:true}:{}})}u.sort((c,d)=>{const g=c.tap?.y??2;const m=d.tap?.y??2;if(Math.abs(g-m)>.02)return g-m;return(c.tap?.x??2)-(d.tap?.x??2)});const l=await Re(!!e.includeBuoy,c=>{if(!c)return false;const d=c.x+c.width/2;return c.y<=o*1.1&&c.y+c.height>=-o*.1&&d>=-a*.1&&d<=a*1.1});return{screen:{width:a,height:o},count:u.length,elements:u,...i>0?{hiddenBuoy:i}:{},...n>0?{hiddenScreens:n}:{},...l.length?{lists:l}:{}}}function P(e){return Math.round(e*100)/100}function ge(e){return{nativeTag:e.nativeTag,testID:e.testID,label:e.label,text:e.text,name:e.name}}function Q(e,t){return ie(ge(e),t)}function pe(e,t,n){if(!e||!t||!n)return void 0;return{x:(e.x+e.width/2)/t,y:(e.y+e.height/2)/n}}function ye(e){const t=e?e.x+e.width/2:0;const n=e?e.y+e.height/2:0;const r={locationX:e?e.width/2:0,locationY:e?e.height/2:0,pageX:t,pageY:n,timestamp:0,target:null,identifier:1,touches:[],changedTouches:[]};return{nativeEvent:r,persist:()=>{},preventDefault:()=>{},stopPropagation:()=>{},isDefaultPrevented:()=>false,isPropagationStopped:()=>false,target:null,currentTarget:null,type:"press",timeStamp:0}}export async function tapElement(e){const t=ce(!!e.includeHidden,()=>Z(e));if(t.length===0){return{tapped:false,reason:"Nothing on screen to tap: no React elements and no page elements were found."}}const n=t.map(f=>({c:f,score:Q(f,e)})).filter(f=>f.score>0).sort((f,h)=>h.score-f.score);const r=f=>!!(f.press||f.valueControl||f.textControl);if(n.length===0&&!e.includeHidden){const f=ce(true,()=>Z(e)).map(h=>({c:h,score:Q(h,e)})).filter(h=>h.score>0);if(f.length>0){return{tapped:false,reason:"That element is only on a screen that isn't showing (another tab, or a screen under the current one). Navigate to it first, or pass includeHidden:true if you really mean the hidden one."}}}if(n.length===0){return{tapped:false,reason:"No element matched. Call describe_screen to see available elements (match by testID, text, or name).",candidates:t.filter(r).slice(0,12).map(f=>({nativeTag:f.nativeTag,name:f.name,testID:f.testID,text:f.text}))}}const i=L.get("window");const s=i.width||1;const a=i.height||1;const o=n.slice(0,15);await Promise.all(o.map(async f=>{if(f.c.instance&&!f.c.rect)f.c.rect=await k(f.c.instance)}));for(const f of o){f.score=ie({...ge(f.c),tap:pe(f.c.rect,s,a)},e)}o.sort((f,h)=>h.score-f.score);if(e.text!==void 0){for(const f of o){const h=!r(f.c)&&F(f.c.stateNode)?Ce(f.c.stateNode):null;const p=h?t.find(T=>T.stateNode===h&&T.textControl):void 0;if(p)f.c=p}}const u=o.find(f=>r(f.c))??n.find(f=>r(f.c))??o[0];const l=u.c;const c=(f,h)=>f.press&&f.press.handler===h.press?.handler||f.valueControl&&f.valueControl.handler===h.valueControl?.handler||f.textControl&&f.textControl.handler===h.textControl?.handler;const d=o.filter(f=>f!==u&&r(f.c)&&f.score===u.score).filter(f=>!c(f.c,l)).filter((f,h,p)=>p.findIndex(T=>c(T.c,f.c))===h).slice(0,3).map(f=>({nativeTag:f.c.nativeTag,name:f.c.name,testID:f.c.testID,text:f.c.text,tap:pe(f.c.rect,s,a)}));const g=e.nativeTag==null&&!(e.testID&&!e.query);if(g&&d.length>0){const f=[l,...d.map(h=>o.find(p=>p.c.nativeTag===h.nativeTag)?.c).filter(Boolean)];return{tapped:false,reason:`"${e.query}" matches ${f.length} different controls equally well, so nothing was tapped. Tap one by its nativeTag.`,candidates:f.map(h=>({nativeTag:h.nativeTag,name:h.name,testID:h.testID,text:h.text}))}}const m=o[0];if(g&&m&&m!==u&&!r(m.c)&&m.score>=90&&u.score<m.score-40){return{tapped:false,reason:`The best match for "${e.query}" is "${m.c.text??m.c.label??m.c.name}", which has no JS press handler (it may be native, like a tab bar button). The closest pressable match, "${l.text??l.label??l.name}", is a much weaker match, so nothing was tapped. Use navigate, or tap a specific element by nativeTag.`,candidates:[{nativeTag:l.nativeTag,name:l.name,testID:l.testID,text:l.text}]}}if(!r(l)){return{tapped:false,reason:F(l.stateNode)?`Matched "${l.name}"${l.text?` ("${l.text}")`:""}, but it is not a button or a field. This element can't be driven in JS.`:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onPress / onValueChange / onChangeText handler (e.g. a react-native-gesture-handler GestureDetector). This element can't be driven in JS.`,matched:{nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text,via:"onPress"}}}if(l.instance&&!l.rect)l.rect=await k(l.instance);let w=false;const y=l.rect==null||!W(l.rect,s,a);if(y&&e.scrollIntoView!==false&&l.instance){w=await Me(l.fiber,l.instance,l.stateNode,80);if(w)l.rect=await k(l.instance)}const b={nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text};Ne();const C=U;const N=l.fiber===null&&F(l.stateNode)?Pe():null;const V=Date.now();const I=async f=>{await new Promise(h=>setTimeout(h,Se));return{tapped:true,scrolled:w,matched:f,effect:{commits:N?N():U-C,observedMs:Date.now()-V},...d.length?{alsoMatched:d}:{}}};try{if(l.press){if(e.longPress){const h=l.press.kind==="onLongPress"?l.press.handler:l.press.longPress;if(!h){return{tapped:false,scrolled:w,reason:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onLongPress handler \u2014 call tap_element without longPress to tap it normally.`,matched:{...b,via:"onPress"}}}h(ye(l.rect));return await I({...b,via:"onLongPress"})}l.press.handler(ye(l.rect));return await I({...b,via:l.press.kind})}if(l.valueControl){const h=l.valueControl;let p;if(h.kind==="toggle"){p=typeof e.value==="boolean"?e.value:!h.current}else{const T=h.min??0;const v=h.max??1;if(typeof e.value==="number"){p=Math.min(v,Math.max(T,e.value))}else{p=h.current===v?T:v}}h.handler(p);return await I({...b,via:"onValueChange",value:p})}const f=e.text??(typeof e.value==="string"?e.value:"");l.textControl.handler(f);return await I({...b,via:"onChangeText",value:f})}catch(f){N?.();return{tapped:false,scrolled:w,reason:`handler threw: ${f instanceof Error?f.message:String(f)}`,matched:{...b,via:l.press?l.press.kind:l.valueControl?"onValueChange":"onChangeText"}}}}const He=5e3;const $e=3e4;const ze=50;const We=150;export async function waitFor(e){const t=e.nativeTag!=null||!!String(e.testID??"").trim()||!!String(e.query??"").trim();if(!t){return{ok:false,waitedMs:0,polls:0,reason:"Nothing to wait for \u2014 pass nativeTag, testID or query."}}const n=Math.min(Math.max(e.timeoutMs??He,0),$e);const r=Math.max(e.pollMs??We,ze);const i=e.gone===true;const s=Date.now();let a=0;for(;;){a+=1;const{hit:o,closest:u}=await Be(e);if(i?!o:!!o){return{ok:true,waitedMs:Date.now()-s,polls:a,matched:o??void 0}}if(Date.now()-s>=n){const l=u?.length?u:void 0;const c=i?`Still on screen after ${n}ms.`:l?`Not on screen after ${n}ms \u2014 ${l.length===1?"one element":`${l.length} elements`} matched but ${l.some(d=>d.onScreen)?"not well enough":"none is visible"}. See \`closest\`; do not retry with different words, call describeScreen.`:`Not on screen after ${n}ms, and nothing matched those words at all. Call describeScreen to see what is there.`;return{ok:false,waitedMs:Date.now()-s,polls:a,reason:c,matched:o??void 0,closest:l}}await new Promise(l=>setTimeout(l,r))}}async function Be(e){const t=Z(e).map(o=>({c:o,score:Q(o,e)})).filter(o=>o.score>0).sort((o,u)=>u.score-o.score).slice(0,8);if(t.length===0)return{hit:null,closest:void 0};await me(t.map(o=>o.c));const n=L.get("window");const r=Math.round(n.width)||1;const i=Math.round(n.height)||1;let s=null;for(const{c:o}of t){if(!W(o.rect,r,i))continue;s={nativeTag:o.nativeTag,name:o.name,testID:o.testID,label:o.label,text:o.text,interactive:!!(o.press||o.valueControl||o.textControl)};break}const a=t.slice(0,3).map(({c:o})=>({name:o.name,testID:o.testID,text:o.text,onScreen:W(o.rect,r,i)}));return{hit:s,closest:a}}function ee(e){let t=e;let n=0;while(t&&n<400){if(x(t)?.__buoyDevToolsRoot)return true;t=t.return;n++}return false}function qe(e,t){const n=x(e.fiber);if(typeof n?.onPress==="function"||typeof n?.onValueChange==="function"||typeof n?.onChangeText==="function"){return e}let r=null;let i=e.fiber?.return;let s=0;while(i&&s<25){if(typeof x(i)?.onPress==="function"){r=i;break}i=i.return;s++}if(!r)return e;let a=r;for(let o=0;o<6&&a;o++){const u=t.get(a);if(u)return u;a=a.return}return e}export function resolveTouchTarget(e){const t=Y();if(t.length===0)return null;const n=new Map;for(const a of t)n.set(a.fiber,a);const r=t.find(a=>a.nativeTag===e);let i=null;if(!r){for(const a of D()){S(a.current,o=>{if(i)return;if(o.stateNode&&A(o.stateNode)===e){i=o}});if(i)break}}let s=r??null;if(!s&&i){let a=i;let o=0;let u=null;while(a&&o<25){const l=n.get(a);if(l){if(l.press||l.valueControl||l.textControl){s=l;break}if(!u)u=l}a=a.return;o++}if(!s)s=u}if(!s?.fiber&&!i){const a=s?.stateNode;const o=F(a)?a:Ue(e);if(o){for(let u=o;u;u=u.parentElement){const l=t.find(c=>c.stateNode===u&&(c.press||c.valueControl||c.textControl));if(l)return l.buoy?null:te(l)}return null}}if(!s)return null;s=qe(s,n);if(!s.press&&!s.valueControl&&!s.textControl)return null;if(ee(s.fiber))return null;return te(s)}function Ue(e){const t=global.document;if(!t?.querySelectorAll)return null;return Array.from(t.querySelectorAll("*")).find(n=>R(n)===e)??null}function te(e){return{nativeTag:e.nativeTag,name:e.name,role:e.role,testID:e.testID,label:e.label,text:e.text,control:e.valueControl?e.valueControl.kind:e.textControl?"text":"press",value:e.valueControl?e.valueControl.current:e.textControl?.current}}function je(e){let t=null;for(const n of D()){S(n.current,r=>{if(!t&&r.stateNode&&A(r.stateNode)===e)t=r});if(t)break}return t}function we(){const e=[];for(const t of D()){let n=t.current?.child;let r=0;while(n&&r++<200){if(n.tag===O&&n.stateNode){e.push(n);break}n=n.child}}return e}function Ge(e,t){const n=global.nativeFabricUIManager;if(!n||typeof n.findNodeAtPoint!=="function")return null;const r=we().filter(i=>i.stateNode?.node);if(!r.length)return null;return new Promise(i=>{const s=setTimeout(()=>i(null),1e3);let a=r.length;let o=null;r.forEach((u,l)=>{try{n.findNodeAtPoint(u.stateNode.node,e,t,c=>{if(c&&(!o||l>=o.i))o={i:l,fiber:c};if(--a===0){clearTimeout(s);i(o?.fiber??null)}})}catch{if(--a===0){clearTimeout(s);i(o?.fiber??null)}}})})}function Je(e,t){const n=$?.findSubviewIn;if(typeof n!=="function")return null;const r=we()[0];const i=r?A(r.stateNode)??z(r.stateNode):null;if(i==null)return null;return new Promise(s=>{const a=setTimeout(()=>s(null),1e3);try{n.call($,i,[e,t],o=>{clearTimeout(a);s(typeof o==="number"?je(o):null)})}catch{clearTimeout(a);s(null)}})}function Ke(){const e=[];const t=new Set;const n=i=>{const s=[];const a=(o,u)=>{for(let l=o;l&&s.length<5e3;l=l.sibling){if(t.has(l)||u>500)continue;if(ue(l)||fe(l))continue;if(l.tag===O&&l.stateNode)s.push(l);else if(l.child)a(l.child,u+1)}};if(i.child)a(i.child,0);return s};const r=(i,s)=>{if(t.has(i)||s>500)return;t.add(i);e.push(i);be(n(i)).forEach(a=>r(a,s+1))};for(const i of D())be(n(i.current)).forEach(s=>r(s,0));return e}function be(e){const t=e.map(n=>{const r=Number(ne(x(n)?.style).zIndex);return Number.isFinite(r)?r:0});return e.map((n,r)=>({h:n,i:r})).sort((n,r)=>t[n.i]-t[r.i]||n.i-r.i).map(({h:n})=>n)}function ne(e,t=0){if(!e||typeof e!=="object"||t>10)return{};if(Array.isArray(e))return Object.assign({},...e.map(n=>ne(n,t+1)));return e}const Xe=new Set(["RCTScrollView","AndroidHorizontalScrollView","RCTScrollContentView"]);function Ye(e){if(typeof e.type==="string"&&Xe.has(e.type)&&e.type!=="RCTScrollContentView")return true;const t=ne(x(e)?.style).overflow;return t==="hidden"||t==="scroll"}function Ze(e){let t=x(e)?.pointerEvents??x(e)?.style?.pointerEvents;if(t==="none")return"all";let n=e.return;let r=0;while(n&&r++<200){const i=x(n)?.pointerEvents??x(n)?.style?.pointerEvents;if(i==="none")return"all";if(i==="box-only"&&n.tag===O)return"all";n=n.return}return t==="box-none"?"self":null}async function Qe(e,t,n){const r=await Promise.all(n.map(o=>{const u=G(o.stateNode);return u?k(u):Promise.resolve(null)}));const i=new Map;n.forEach((o,u)=>i.set(o,r[u]));const s=o=>!!o&&e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height;const a=o=>{for(let u=o.return,l=0;u&&l<300;u=u.return,l++){if(u.tag===O&&i.has(u)&&Ye(u)&&!s(i.get(u)))return true}return false};for(let o=n.length-1;o>=0;o--){if(!s(r[o])||Ze(n[o])||a(n[o]))continue;return n[o]}return null}function et(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;let i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);while(i){const s=Object.keys(i).find(a=>a.startsWith("__reactFiber$"));if(s)return i[s];i=i.parentElement}return null}function tt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;const i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);if(!i)return null;for(let c=i;c;c=c.parentElement){if(Object.keys(c).some(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactContainer$")))return null}const s=!!i.closest("[data-buoy-root], [data-buoy-portal-host]");const a=he();const o=a.find(c=>c.stateNode===i);let u;for(let c=i;c&&!u;c=c.parentElement){u=a.find(d=>d.stateNode===c&&(d.press||d.valueControl||d.textControl))}const l=[];for(let c=i;c&&l.length<6;c=c.parentElement){const d=B(c);if(d!==c.tagName.toLowerCase()&&l[l.length-1]!==d)l.push(d)}return{found:true,method:"dom",buoy:s,view:{name:B(i),nativeTag:R(i),testID:o?.testID,label:o?.label,text:o?.text},path:l,target:u&&!s?te(u):null}}export async function hitTest(e){const t=Math.min(1,Math.max(0,Number(e?.x)));const n=Math.min(1,Math.max(0,Number(e?.y)));if(!Number.isFinite(t)||!Number.isFinite(n))return{found:false,method:"none",reason:"x and y must be numbers from 0 to 1."};const r=L.get("window");const i=t*r.width;const s=n*r.height;let a="none";let o=null;const u=et(t,n);const l=u?null:tt(t,n);if(l)return l;if(u){a="dom";o=u}else{const y=Ge(i,s);if(y){a="fabric";o=await y}else{const C=Je(i,s);if(C){a="paper";o=await C}}const b=Ke();if(!o||!new Set(b).has(o)){o=await Qe(i,s,b);a="measured"}}if(!o)return{found:false,method:a};const c=x(o)??{};const d=A(o.stateNode);const g=[];let m=o;let w=0;while(m&&w++<80&&g.length<6){const y=M(m);if(y&&typeof m.type!=="string"&&!q.has(y)&&g[g.length-1]!==y)g.push(y);m=m.return}return{found:true,method:a,buoy:ee(o),view:{name:M(o)??"Unknown",nativeTag:d,testID:c.testID||void 0,label:c.accessibilityLabel||c["aria-label"]||void 0,text:X(c)},path:g,target:d!=null?resolveTouchTarget(d):null}}export async function readMaps(){const e=[];for(const i of D()){S(i.current,s=>{const a=s.stateNode;if(s.tag===1&&a&&typeof a.getCamera==="function"&&!ee(s))e.push(s)})}const t=L.get("window");const n=i=>Promise.race([i,new Promise(s=>setTimeout(()=>s(null),1e3))]);const r=await Promise.all(e.slice(0,5).map(async i=>{try{const s=await n(Promise.resolve(i.stateNode.getCamera()));if(!s)return null;const a=J(i);const o=a?await k(a.instance):null;const u=x(i)??{};return{name:M(i)??"Map",testID:typeof u.testID==="string"?u.testID:void 0,frame:o&&t.width&&t.height?{x:P(o.x/t.width),y:P(o.y/t.height),width:P(o.width/t.width),height:P(o.height/t.height)}:void 0,camera:{heading:typeof s.heading==="number"?s.heading:void 0,pitch:typeof s.pitch==="number"?s.pitch:void 0,altitude:typeof s.altitude==="number"?s.altitude:void 0,zoom:typeof s.zoom==="number"?s.zoom:void 0,center:s.center}}}catch{return null}}));return{maps:r.filter(i=>!!i)}}
1
+ "use strict";import{getAnchoredFiberRoots as re,getDOMControlProps as xe,getDOMNodeHandle as R,getDOMPublicInstance as ie,isDOMElement as F}from"@buoy-gg/shared-ui/utils";import{Dimensions as L,UIManager as $,findNodeHandle as z}from"react-native";import{isRectCenterOnScreen as W,scoreTapMatch as le}from"./tapMatch";import{collectDOMElements as Ce,domElementName as B,labeledField as Pe,watchDOMChanges as Ie}from"./domScreenElements";const O=5;const Ne=22;const q=new Set(["View","RCTView","ScrollView","RCTScrollView","RCTScrollContentView","SafeAreaView","RCTSafeAreaView","AndroidHorizontalScrollContentView","KeyboardAvoidingView","Pressable","PlatformPressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","AnimatedComponent","Wrapper"]);function se(){if(typeof global==="undefined")return null;return global.__REACT_DEVTOOLS_GLOBAL_HOOK__??null}let U=0;let ae=false;function Se(){if(ae)return;const e=se();if(!e)return;const t=e.onCommitFiberRoot;e.onCommitFiberRoot=function(...n){U++;return typeof t==="function"?t.apply(e,n):void 0};ae=true}const De=250;function ue(){const e=new Map;return t=>{const n=[];let r=t;let i=0;let s=false;while(r&&i<400){const a=e.get(r);if(a!==void 0){s=a;break}if(x(r)?.__buoyDevToolsRoot){s=true;e.set(r,true);break}n.push(r);r=r.return;i++}for(const a of n)e.set(a,s);return s}}function D(){const e=se();if(!e)return re();const t=[];try{if(e.renderers&&typeof e.renderers.forEach==="function"){e.renderers.forEach((n,r)=>{try{const i=e.getFiberRoots?.(r);if(i)i.forEach(s=>t.push(s))}catch{}})}if(t.length===0&&e.getFiberRoots){const n=e.getFiberRoots(1);if(n)n.forEach(r=>t.push(r))}}catch{}return t.length?t:re()}function ce(e){return e.tag===Ne&&e.memoizedState!==null}let _=false;let j=0;let E=false;function fe(e,t){const n=_;_=e;try{return t()}finally{_=n}}function _e(e){const t=e.memoizedProps;if(!t)return false;if(t["aria-hidden"]===true&&(t.activityState!==void 0||"shouldFreeze"in t))return true;if(t.isFocused===false&&(t.routeKey!==void 0||"freezeContents"in t))return true;return false}function de(e){const t=e.memoizedProps?.activityState;if(t===0||t===1)return true;if(e.memoizedProps?.isPageFocused===false)return true;if(!_&&_e(e)){j++;return true}return false}function S(e,t,n=0,r=new Set){if(!e||r.has(e)||n>500)return;r.add(e);if(ce(e)||de(e)){if(e.sibling)S(e.sibling,t,n,r);return}t(e);if(e.child)S(e.child,t,n+1,r);if(e.sibling)S(e.sibling,t,n,r)}function G(e){const t=ie(e);if(t)return t;if(!e)return null;const n=e;if(n.canonical?.publicInstance)return n.canonical.publicInstance;if(n.canonical&&typeof n.canonical.measure==="function"){return n.canonical}if(typeof n.measure==="function"||typeof n.measureInWindow==="function"){return n}return null}function A(e){const t=R(e);if(t!==null)return t;if(e==null)return null;const n=e;if(typeof n.__nativeTag==="number")return n.__nativeTag;if(typeof n._nativeTag==="number")return n._nativeTag;if(typeof n.nativeTag==="number")return n.nativeTag;if(n.canonical){if(typeof n.canonical.__nativeTag==="number")return n.canonical.__nativeTag;if(typeof n.canonical._nativeTag==="number")return n.canonical._nativeTag;if(typeof n.canonical.nativeTag==="number")return n.canonical.nativeTag}return null}function J(e){const t=G(e.stateNode);if(t){return{instance:t,nativeTag:A(e.stateNode),stateNode:e.stateNode}}const n=[];if(e.child)n.push(e.child);let r=0;while(n.length>0&&r<4e3){r++;const i=n.pop();if(!i)continue;const s=G(i.stateNode);if(s)return{instance:s,nativeTag:A(i.stateNode),stateNode:i.stateNode};if(i.child)n.push(i.child);if(i.sibling)n.push(i.sibling)}return null}function Me(e){let t=e;let n=0;while(t&&n++<200){const r=t.stateNode;if(r&&typeof r.scrollTo==="function"){const i=typeof r.getNativeScrollRef==="function"&&r.getNativeScrollRef()||null;const s=typeof r.getInnerViewNode==="function"&&r.getInnerViewNode()||typeof r.getScrollableNode==="function"&&r.getScrollableNode()||r;return{instance:r,nativeRef:i,innerNode:s}}t=t.return}return null}async function ke(e,t,n,r){try{if(F(n)){n.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});await new Promise(u=>setTimeout(u,16));return true}const i=Me(e);if(!i)return false;const s=t;let a=null;const o=u=>new Promise(l=>{let c=false;const d=m=>{if(c)return;c=true;l(m)};const g=setTimeout(()=>d(null),600);try{u(m=>{clearTimeout(g);d(m)})}catch{clearTimeout(g);d(null)}});if(i.nativeRef&&typeof s.measureLayout==="function"){a=await o(u=>s.measureLayout(i.nativeRef,(l,c)=>u(c),()=>u(null)))}if(a==null){const u=z(t);const l=typeof i.innerNode==="number"?i.innerNode:z(i.innerNode);if(u!=null&&l!=null){a=await o(c=>$.measureLayout(u,l,()=>c(null),(d,g)=>c(g)))}}if(a==null)return false;i.instance.scrollTo({y:Math.max(0,a-r),animated:false});await new Promise(u=>setTimeout(u,120));return true}catch{return false}}function M(e){const t=e?.type;if(!t)return null;if(typeof t==="string")return t;return t.displayName||t.name||null}function K(e){let t=e?._debugOwner||e?.return;let n=0;while(t&&n<30){n++;const r=M(t);if(r&&!q.has(r)&&typeof t.type!=="string"){return r}t=t.return}return null}function x(e){return xe(e?.stateNode,e?.memoizedProps??e?.pendingProps??null)}function he(e,t=0){if(typeof e==="string")return e;if(typeof e==="number"&&Number.isFinite(e))return String(e);if(Array.isArray(e)&&t<4){const n=[];for(const r of e){const i=he(r,t+1);if(i)n.push(i)}return n.length>0?n.join(""):void 0}return void 0}function Ve(e){return e.replace(/\s+/g," ").trim()}function X(e){if(!e)return void 0;const t=n=>{const r=he(n);if(r===void 0)return void 0;const i=Ve(r);return i?E?i:i.slice(0,80):void 0};return t(e.children)??t(e.title)??t(e.label)??t(e.placeholder)??void 0}function Ae(e,t){const n=[];const r=(s,a)=>{if(!s||a>t||n.length>=4)return;if(s!==e){const u=x(s);if(u&&(typeof u.onPress==="function"||typeof u.onLongPress==="function"))return}const o=X(x(s));if(o&&!n.includes(o))n.push(o);if(s.child)r(s.child,a+1);if(s!==e&&s.sibling)r(s.sibling,a)};if(e.child)r(e.child,1);const i=n.join(" ").trim();return i?i.slice(0,80):void 0}function Fe(e){let t=e;let n=0;let r=null;let i=null;while(t&&n<25&&!(r&&i)){const s=x(t);if(s){if(!r&&typeof s.onPress==="function")r=s.onPress;if(!i&&typeof s.onLongPress==="function")i=s.onLongPress}t=t.return;n++}if(r)return{handler:r,kind:"onPress",longPress:i??void 0};return i?{handler:i,kind:"onLongPress"}:null}function k(e){return new Promise(t=>{let n=false;const r=i=>{if(n)return;n=true;t(i)};setTimeout(()=>r(null),1e3);try{if(typeof e.measureInWindow==="function"){e.measureInWindow((i,s,a,o)=>{if(a>0&&o>0)r({x:i,y:s,width:a,height:o});else r(null)})}else if(typeof e.measure==="function"){e.measure((i,s,a,o,u,l)=>{if(a>0&&o>0&&u!=null&&l!=null){r({x:u,y:l,width:a,height:o})}else{r(null)}})}else{r(null)}}catch{r(null)}})}const Le=new Set(["RCTActivityIndicatorView","AndroidProgressBar"]);function Y(){const e=D();const t=[];const n=new Map;const r=new Map;const i=ue();for(const s of e){S(s.current,a=>{const o=x(a);if(!o)return;const u=typeof o.onPress==="function"||typeof o.onLongPress==="function";const l=typeof o.onValueChange==="function";const c=typeof o.onChangeText==="function";const d=o.testID||void 0;const g=o.accessibilityLabel||void 0;const m=o.accessibilityRole||o.role||void 0;let w=X(o);const y=m==="button"||m==="link"||m==="menuitem"||m==="tab"||m==="switch"||m==="checkbox";const b=typeof a.type==="string"&&Le.has(a.type)&&o.animating!==false;if(!u&&!l&&!c&&!d&&!g&&!w&&!y&&!b){return}let C=null;let N=null;let V=null;if(l){const oe=o.value;const Te=typeof oe==="number"||typeof o.minimumValue==="number";N={handler:o.onValueChange,kind:Te?"slider":"toggle",current:oe,min:typeof o.minimumValue==="number"?o.minimumValue:void 0,max:typeof o.maximumValue==="number"?o.maximumValue:void 0}}else if(c){V={handler:o.onChangeText,current:typeof o.value==="string"?o.value:void 0}}else{C=Fe(a)}const I=M(a);let f=I??"Unknown";if(!I||q.has(I)||typeof a.type==="string"){f=K(a)??I??"Unknown"}const h=J(a);if(!h&&!d)return;if(!w&&!g&&u){w=Ae(a,6)}const p=h?.instance??null;const T=h?.nativeTag??null;const v=(p?n.get(p):void 0)??(T!=null?r.get(T):void 0);if(v){if(C)v.press=C;if(!v.valueControl&&N)v.valueControl=N;if(!v.textControl&&V)v.textControl=V;if(!v.testID&&d)v.testID=d;if(!v.label&&g)v.label=g;if(!v.text&&w)v.text=w;if(p&&!n.has(p))n.set(p,v);if(T!=null&&!r.has(T))r.set(T,v);return}const H={nativeTag:T,name:f,role:m??(b?"progressbar":void 0),testID:d,label:g,text:w,instance:p,stateNode:h?.stateNode??null,fiber:a,press:C,valueControl:N,textControl:V,rect:null,buoy:i(a)};t.push(H);if(p)n.set(p,H);if(T!=null)r.set(T,H)})}t.push(...me());return t}function me(){return Ce({fullText:E}).map(({element:e,props:t,text:n,buoy:r})=>{const i=typeof t.onValueChange==="function"?{handler:t.onValueChange,kind:typeof t.value==="number"?"slider":"toggle",current:t.value,min:t.minimumValue,max:t.maximumValue}:null;const s=!i&&typeof t.onChangeText==="function"?{handler:t.onChangeText,current:t.value}:null;const a=!i&&!s&&typeof t.onPress==="function"?{handler:t.onPress,kind:"onPress"}:null;return{nativeTag:R(e),name:B(e),role:t.accessibilityRole,testID:t.testID,label:t.accessibilityLabel,text:n,instance:ie(e),stateNode:e,fiber:null,buoy:r,press:a,valueControl:i,textControl:s,rect:null}})}function Ee(e,t){if(t.nativeTag!=null)return e.nativeTag===t.nativeTag;if(t.testID&&e.testID)return e.testID.toLowerCase()===t.testID.toLowerCase();return false}function Z(e){const t=Y();if(e.includeBuoy)return t;return t.filter(n=>!n.buoy||Ee(n,e))}async function ge(e){await Promise.all(e.map(async t=>{if(t.instance)t.rect=await k(t.instance)}))}const Re=/^(FlatList|SectionList|VirtualizedSectionList|VirtualizedList|Animated\(.*\)|AnimatedComponent.*)$/;async function Oe(e,t){const n=[];const r=ue();for(const s of D()){S(s.current,a=>{if(M(a)!=="VirtualizedList")return;const o=a.memoizedProps;if(!o||typeof o.getItemCount!=="function")return;if(!e&&r(a))return;let u;try{u=Number(o.getItemCount(o.data))}catch{return}if(!Number.isFinite(u)||u<=0)return;const l=[];const c=(m,w)=>{for(let y=m?.child;y;y=y.sibling){const b=M(y);if(b==="VirtualizedList")continue;if(b==="CellRenderer"){l.push(y);continue}if(w<40)c(y,w+1)}};c(a,0);let d=a;let g=K(d);for(let m=0;m<6&&g&&Re.test(g);m++){d=d._debugOwner||d.return;g=K(d)}n.push({owner:g,items:u,cells:l})})}const i=[];for(const s of n){const a=await Promise.all(s.cells.map(async u=>{const l=J(u);return l?k(l.instance):null}));const o=a.filter(t).length;if(o>0&&s.items>o)i.push({owner:s.owner,items:s.items,listed:o})}return i}export async function describeScreen(e={}){const t=_;const n=E;_=!!e.includeHidden;E=!!e.fullText;try{return await He(e)}finally{_=t;E=n}}async function He(e){j=0;const t=Y();const n=j;const r=e.includeBuoy?t:t.filter(c=>!c.buoy);const i=t.length-r.length;await ge(r);const s=L.get("window");const a=Math.round(s.width)||1;const o=Math.round(s.height)||1;const u=[];for(const c of r){const d=c.rect;if(!d&&!c.testID)continue;let g;let m;if(d){const b=d.x+d.width/2;const C=d.y+d.height/2;if(C<-o*.1||C>o*1.1||b<-a*.1||b>a*1.1){continue}g={x:P(b/a),y:P(C/o)};m={x:P(d.x/a),y:P(d.y/o),width:P(d.width/a),height:P(d.height/o)}}const w=c.valueControl?c.valueControl.kind:c.textControl?"text":void 0;const y=c.valueControl?c.valueControl.current:c.textControl?.current;u.push({nativeTag:c.nativeTag,name:c.name,role:c.role,testID:c.testID,label:c.label,text:c.text,interactive:!!(c.press||c.valueControl||c.textControl),longPressable:c.press&&(c.press.kind==="onLongPress"||c.press.longPress)?true:void 0,control:w,value:y,tap:g,frame:m,...c.buoy?{buoy:true}:{}})}u.sort((c,d)=>{const g=c.tap?.y??2;const m=d.tap?.y??2;if(Math.abs(g-m)>.02)return g-m;return(c.tap?.x??2)-(d.tap?.x??2)});const l=await Oe(!!e.includeBuoy,c=>{if(!c)return false;const d=c.x+c.width/2;return c.y<=o*1.1&&c.y+c.height>=-o*.1&&d>=-a*.1&&d<=a*1.1});return{screen:{width:a,height:o},count:u.length,elements:u,...i>0?{hiddenBuoy:i}:{},...n>0?{hiddenScreens:n}:{},...l.length?{lists:l}:{}}}function P(e){return Math.round(e*100)/100}function pe(e){return{nativeTag:e.nativeTag,testID:e.testID,label:e.label,text:e.text,name:e.name}}function Q(e,t){return le(pe(e),t)}function ye(e,t,n){if(!e||!t||!n)return void 0;return{x:(e.x+e.width/2)/t,y:(e.y+e.height/2)/n}}function we(e){const t=e?e.x+e.width/2:0;const n=e?e.y+e.height/2:0;const r={locationX:e?e.width/2:0,locationY:e?e.height/2:0,pageX:t,pageY:n,timestamp:0,target:null,identifier:1,touches:[],changedTouches:[]};return{nativeEvent:r,persist:()=>{},preventDefault:()=>{},stopPropagation:()=>{},isDefaultPrevented:()=>false,isPropagationStopped:()=>false,target:null,currentTarget:null,type:"press",timeStamp:0}}export async function tapElement(e){const t=fe(!!e.includeHidden,()=>Z(e));if(t.length===0){return{tapped:false,reason:"Nothing on screen to tap: no React elements and no page elements were found."}}const n=t.map(f=>({c:f,score:Q(f,e)})).filter(f=>f.score>0).sort((f,h)=>h.score-f.score);const r=f=>!!(f.press||f.valueControl||f.textControl);if(n.length===0&&!e.includeHidden){const f=fe(true,()=>Z(e)).map(h=>({c:h,score:Q(h,e)})).filter(h=>h.score>0);if(f.length>0){return{tapped:false,reason:"That element is only on a screen that isn't showing (another tab, or a screen under the current one). Navigate to it first, or pass includeHidden:true if you really mean the hidden one."}}}if(n.length===0){return{tapped:false,reason:"No element matched. Call describe_screen to see available elements (match by testID, text, or name).",candidates:t.filter(r).slice(0,12).map(f=>({nativeTag:f.nativeTag,name:f.name,testID:f.testID,text:f.text}))}}const i=L.get("window");const s=i.width||1;const a=i.height||1;const o=n.slice(0,15);await Promise.all(o.map(async f=>{if(f.c.instance&&!f.c.rect)f.c.rect=await k(f.c.instance)}));for(const f of o){f.score=le({...pe(f.c),tap:ye(f.c.rect,s,a)},e)}o.sort((f,h)=>h.score-f.score);if(e.text!==void 0){for(const f of o){const h=!r(f.c)&&F(f.c.stateNode)?Pe(f.c.stateNode):null;const p=h?t.find(T=>T.stateNode===h&&T.textControl):void 0;if(p)f.c=p}}const u=o.find(f=>r(f.c))??n.find(f=>r(f.c))??o[0];const l=u.c;const c=(f,h)=>f.press&&f.press.handler===h.press?.handler||f.valueControl&&f.valueControl.handler===h.valueControl?.handler||f.textControl&&f.textControl.handler===h.textControl?.handler;const d=o.filter(f=>f!==u&&r(f.c)&&f.score===u.score).filter(f=>!c(f.c,l)).filter((f,h,p)=>p.findIndex(T=>c(T.c,f.c))===h).slice(0,3).map(f=>({nativeTag:f.c.nativeTag,name:f.c.name,testID:f.c.testID,text:f.c.text,tap:ye(f.c.rect,s,a)}));const g=e.nativeTag==null&&!(e.testID&&!e.query);if(g&&d.length>0){const f=[l,...d.map(h=>o.find(p=>p.c.nativeTag===h.nativeTag)?.c).filter(Boolean)];return{tapped:false,reason:`"${e.query}" matches ${f.length} different controls equally well, so nothing was tapped. Tap one by its nativeTag.`,candidates:f.map(h=>({nativeTag:h.nativeTag,name:h.name,testID:h.testID,text:h.text}))}}const m=o[0];if(g&&m&&m!==u&&!r(m.c)&&m.score>=90&&u.score<m.score-40){return{tapped:false,reason:`The best match for "${e.query}" is "${m.c.text??m.c.label??m.c.name}", which has no JS press handler (it may be native, like a tab bar button). The closest pressable match, "${l.text??l.label??l.name}", is a much weaker match, so nothing was tapped. Use navigate, or tap a specific element by nativeTag.`,candidates:[{nativeTag:l.nativeTag,name:l.name,testID:l.testID,text:l.text}]}}if(!r(l)){return{tapped:false,reason:F(l.stateNode)?`Matched "${l.name}"${l.text?` ("${l.text}")`:""}, but it is not a button or a field. This element can't be driven in JS.`:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onPress / onValueChange / onChangeText handler (e.g. a react-native-gesture-handler GestureDetector). This element can't be driven in JS.`,matched:{nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text,via:"onPress"}}}if(l.instance&&!l.rect)l.rect=await k(l.instance);let w=false;const y=l.rect==null||!W(l.rect,s,a);if(y&&e.scrollIntoView!==false&&l.instance){w=await ke(l.fiber,l.instance,l.stateNode,80);if(w)l.rect=await k(l.instance)}const b={nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text};Se();const C=U;const N=l.fiber===null&&F(l.stateNode)?Ie():null;const V=Date.now();const I=async f=>{await new Promise(h=>setTimeout(h,De));return{tapped:true,scrolled:w,matched:f,effect:{commits:N?N():U-C,observedMs:Date.now()-V},...d.length?{alsoMatched:d}:{}}};try{if(l.press){if(e.longPress){const h=l.press.kind==="onLongPress"?l.press.handler:l.press.longPress;if(!h){return{tapped:false,scrolled:w,reason:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onLongPress handler \u2014 call tap_element without longPress to tap it normally.`,matched:{...b,via:"onPress"}}}h(we(l.rect));return await I({...b,via:"onLongPress"})}l.press.handler(we(l.rect));return await I({...b,via:l.press.kind})}if(l.valueControl){const h=l.valueControl;let p;if(h.kind==="toggle"){p=typeof e.value==="boolean"?e.value:!h.current}else{const T=h.min??0;const v=h.max??1;if(typeof e.value==="number"){p=Math.min(v,Math.max(T,e.value))}else{p=h.current===v?T:v}}h.handler(p);return await I({...b,via:"onValueChange",value:p})}const f=e.text??(typeof e.value==="string"?e.value:"");l.textControl.handler(f);return await I({...b,via:"onChangeText",value:f})}catch(f){N?.();return{tapped:false,scrolled:w,reason:`handler threw: ${f instanceof Error?f.message:String(f)}`,matched:{...b,via:l.press?l.press.kind:l.valueControl?"onValueChange":"onChangeText"}}}}const $e=5e3;const ze=3e4;const We=50;const Be=150;export async function waitFor(e){const t=e.nativeTag!=null||!!String(e.testID??"").trim()||!!String(e.query??"").trim();if(!t){return{ok:false,waitedMs:0,polls:0,reason:"Nothing to wait for \u2014 pass nativeTag, testID or query."}}const n=Math.min(Math.max(e.timeoutMs??$e,0),ze);const r=Math.max(e.pollMs??Be,We);const i=e.gone===true;const s=Date.now();let a=0;for(;;){a+=1;const{hit:o,closest:u}=await qe(e);if(i?!o:!!o){return{ok:true,waitedMs:Date.now()-s,polls:a,matched:o??void 0}}if(Date.now()-s>=n){const l=u?.length?u:void 0;const c=i?`Still on screen after ${n}ms.`:l?`Not on screen after ${n}ms \u2014 ${l.length===1?"one element":`${l.length} elements`} matched but ${l.some(d=>d.onScreen)?"not well enough":"none is visible"}. See \`closest\`; do not retry with different words, call describeScreen.`:`Not on screen after ${n}ms, and nothing matched those words at all. Call describeScreen to see what is there.`;return{ok:false,waitedMs:Date.now()-s,polls:a,reason:c,matched:o??void 0,closest:l}}await new Promise(l=>setTimeout(l,r))}}async function qe(e){const t=Z(e).map(o=>({c:o,score:Q(o,e)})).filter(o=>o.score>0).sort((o,u)=>u.score-o.score).slice(0,8);if(t.length===0)return{hit:null,closest:void 0};await ge(t.map(o=>o.c));const n=L.get("window");const r=Math.round(n.width)||1;const i=Math.round(n.height)||1;let s=null;for(const{c:o}of t){if(!W(o.rect,r,i))continue;s={nativeTag:o.nativeTag,name:o.name,testID:o.testID,label:o.label,text:o.text,interactive:!!(o.press||o.valueControl||o.textControl)};break}const a=t.slice(0,3).map(({c:o})=>({name:o.name,testID:o.testID,text:o.text,onScreen:W(o.rect,r,i)}));return{hit:s,closest:a}}function ee(e){let t=e;let n=0;while(t&&n<400){if(x(t)?.__buoyDevToolsRoot)return true;t=t.return;n++}return false}function Ue(e,t){const n=x(e.fiber);if(typeof n?.onPress==="function"||typeof n?.onValueChange==="function"||typeof n?.onChangeText==="function"){return e}let r=null;let i=e.fiber?.return;let s=0;while(i&&s<25){if(typeof x(i)?.onPress==="function"){r=i;break}i=i.return;s++}if(!r)return e;let a=r;for(let o=0;o<6&&a;o++){const u=t.get(a);if(u)return u;a=a.return}return e}export function resolveTouchTarget(e){const t=Y();if(t.length===0)return null;const n=new Map;for(const a of t)n.set(a.fiber,a);const r=t.find(a=>a.nativeTag===e);let i=null;if(!r){for(const a of D()){S(a.current,o=>{if(i)return;if(o.stateNode&&A(o.stateNode)===e){i=o}});if(i)break}}let s=r??null;if(!s&&i){let a=i;let o=0;let u=null;while(a&&o<25){const l=n.get(a);if(l){if(l.press||l.valueControl||l.textControl){s=l;break}if(!u)u=l}a=a.return;o++}if(!s)s=u}if(!s?.fiber&&!i){const a=s?.stateNode;const o=F(a)?a:je(e);if(o){for(let u=o;u;u=u.parentElement){const l=t.find(c=>c.stateNode===u&&(c.press||c.valueControl||c.textControl));if(l)return l.buoy?null:te(l)}return null}}if(!s)return null;s=Ue(s,n);if(!s.press&&!s.valueControl&&!s.textControl)return null;if(ee(s.fiber))return null;return te(s)}function je(e){const t=global.document;if(!t?.querySelectorAll)return null;return Array.from(t.querySelectorAll("*")).find(n=>R(n)===e)??null}function te(e){return{nativeTag:e.nativeTag,name:e.name,role:e.role,testID:e.testID,label:e.label,text:e.text,control:e.valueControl?e.valueControl.kind:e.textControl?"text":"press",value:e.valueControl?e.valueControl.current:e.textControl?.current}}function Ge(e){let t=null;for(const n of D()){S(n.current,r=>{if(!t&&r.stateNode&&A(r.stateNode)===e)t=r});if(t)break}return t}function be(){const e=[];for(const t of D()){let n=t.current?.child;let r=0;while(n&&r++<200){if(n.tag===O&&n.stateNode){e.push(n);break}n=n.child}}return e}function Je(e,t){const n=global.nativeFabricUIManager;if(!n||typeof n.findNodeAtPoint!=="function")return null;const r=be().filter(i=>i.stateNode?.node);if(!r.length)return null;return new Promise(i=>{const s=setTimeout(()=>i(null),1e3);let a=r.length;let o=null;r.forEach((u,l)=>{try{n.findNodeAtPoint(u.stateNode.node,e,t,c=>{if(c&&(!o||l>=o.i))o={i:l,fiber:c};if(--a===0){clearTimeout(s);i(o?.fiber??null)}})}catch{if(--a===0){clearTimeout(s);i(o?.fiber??null)}}})})}function Ke(e,t){const n=$?.findSubviewIn;if(typeof n!=="function")return null;const r=be()[0];const i=r?A(r.stateNode)??z(r.stateNode):null;if(i==null)return null;return new Promise(s=>{const a=setTimeout(()=>s(null),1e3);try{n.call($,i,[e,t],o=>{clearTimeout(a);s(typeof o==="number"?Ge(o):null)})}catch{clearTimeout(a);s(null)}})}function Xe(){const e=[];const t=new Set;const n=i=>{const s=[];const a=(o,u)=>{for(let l=o;l&&s.length<5e3;l=l.sibling){if(t.has(l)||u>500)continue;if(ce(l)||de(l))continue;if(l.tag===O&&l.stateNode)s.push(l);else if(l.child)a(l.child,u+1)}};if(i.child)a(i.child,0);return s};const r=(i,s)=>{if(t.has(i)||s>500)return;t.add(i);e.push(i);ve(n(i)).forEach(a=>r(a,s+1))};for(const i of D())ve(n(i.current)).forEach(s=>r(s,0));return e}function ve(e){const t=e.map(n=>{const r=Number(ne(x(n)?.style).zIndex);return Number.isFinite(r)?r:0});return e.map((n,r)=>({h:n,i:r})).sort((n,r)=>t[n.i]-t[r.i]||n.i-r.i).map(({h:n})=>n)}function ne(e,t=0){if(!e||typeof e!=="object"||t>10)return{};if(Array.isArray(e))return Object.assign({},...e.map(n=>ne(n,t+1)));return e}const Ye=new Set(["RCTScrollView","AndroidHorizontalScrollView","RCTScrollContentView"]);function Ze(e){if(typeof e.type==="string"&&Ye.has(e.type)&&e.type!=="RCTScrollContentView")return true;const t=ne(x(e)?.style).overflow;return t==="hidden"||t==="scroll"}function Qe(e){let t=x(e)?.pointerEvents??x(e)?.style?.pointerEvents;if(t==="none")return"all";let n=e.return;let r=0;while(n&&r++<200){const i=x(n)?.pointerEvents??x(n)?.style?.pointerEvents;if(i==="none")return"all";if(i==="box-only"&&n.tag===O)return"all";n=n.return}return t==="box-none"?"self":null}async function et(e,t,n){const r=await Promise.all(n.map(o=>{const u=G(o.stateNode);return u?k(u):Promise.resolve(null)}));const i=new Map;n.forEach((o,u)=>i.set(o,r[u]));const s=o=>!!o&&e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height;const a=o=>{for(let u=o.return,l=0;u&&l<300;u=u.return,l++){if(u.tag===O&&i.has(u)&&Ze(u)&&!s(i.get(u)))return true}return false};for(let o=n.length-1;o>=0;o--){if(!s(r[o])||Qe(n[o])||a(n[o]))continue;return n[o]}return null}function tt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;let i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);while(i){const s=Object.keys(i).find(a=>a.startsWith("__reactFiber$"));if(s)return i[s];i=i.parentElement}return null}function nt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;const i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);if(!i)return null;for(let c=i;c;c=c.parentElement){if(Object.keys(c).some(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactContainer$")))return null}const s=!!i.closest("[data-buoy-root], [data-buoy-portal-host]");const a=me();const o=a.find(c=>c.stateNode===i);let u;for(let c=i;c&&!u;c=c.parentElement){u=a.find(d=>d.stateNode===c&&(d.press||d.valueControl||d.textControl))}const l=[];for(let c=i;c&&l.length<6;c=c.parentElement){const d=B(c);if(d!==c.tagName.toLowerCase()&&l[l.length-1]!==d)l.push(d)}return{found:true,method:"dom",buoy:s,view:{name:B(i),nativeTag:R(i),testID:o?.testID,label:o?.label,text:o?.text},path:l,target:u&&!s?te(u):null}}export async function hitTest(e){const t=Math.min(1,Math.max(0,Number(e?.x)));const n=Math.min(1,Math.max(0,Number(e?.y)));if(!Number.isFinite(t)||!Number.isFinite(n))return{found:false,method:"none",reason:"x and y must be numbers from 0 to 1."};const r=L.get("window");const i=t*r.width;const s=n*r.height;let a="none";let o=null;const u=tt(t,n);const l=u?null:nt(t,n);if(l)return l;if(u){a="dom";o=u}else{const y=Je(i,s);if(y){a="fabric";o=await y}else{const C=Ke(i,s);if(C){a="paper";o=await C}}const b=Xe();if(!o||!new Set(b).has(o)){o=await et(i,s,b);a="measured"}}if(!o)return{found:false,method:a};const c=x(o)??{};const d=A(o.stateNode);const g=[];let m=o;let w=0;while(m&&w++<80&&g.length<6){const y=M(m);if(y&&typeof m.type!=="string"&&!q.has(y)&&g[g.length-1]!==y)g.push(y);m=m.return}return{found:true,method:a,buoy:ee(o),view:{name:M(o)??"Unknown",nativeTag:d,testID:c.testID||void 0,label:c.accessibilityLabel||c["aria-label"]||void 0,text:X(c)},path:g,target:d!=null?resolveTouchTarget(d):null}}export async function readMaps(){const e=[];for(const i of D()){S(i.current,s=>{const a=s.stateNode;if(s.tag===1&&a&&typeof a.getCamera==="function"&&!ee(s))e.push(s)})}const t=L.get("window");const n=i=>Promise.race([i,new Promise(s=>setTimeout(()=>s(null),1e3))]);const r=await Promise.all(e.slice(0,5).map(async i=>{try{const s=await n(Promise.resolve(i.stateNode.getCamera()));if(!s)return null;const a=J(i);const o=a?await k(a.instance):null;const u=x(i)??{};return{name:M(i)??"Map",testID:typeof u.testID==="string"?u.testID:void 0,frame:o&&t.width&&t.height?{x:P(o.x/t.width),y:P(o.y/t.height),width:P(o.width/t.width),height:P(o.height/t.height)}:void 0,camera:{heading:typeof s.heading==="number"?s.heading:void 0,pitch:typeof s.pitch==="number"?s.pitch:void 0,altitude:typeof s.altitude==="number"?s.altitude:void 0,zoom:typeof s.zoom==="number"?s.zoom:void 0,center:s.center}}}catch{return null}}));return{maps:r.filter(i=>!!i)}}
@@ -1 +1 @@
1
- "use strict";import{resolveTouchTarget as v}from"./screenElements";import{resolveRawEventEmitter as S}from"./rawEventEmitter";const L=14;const M=550;const _=4e3;const b=8e3;const T=600;let d=null;let m=false;let p=null;let f=[];let i="idle";let l=[];let g=0;let a=null;function w(){if(m)return d;m=true;const e=S();d=e.emitter;p=e.reason;return d}function s(e){return typeof e==="number"&&Number.isFinite(e)?e:null}function C(e){const t=e?.nativeEvent;if(!t)return null;return s(t.target)??s(t.tag)}function h(e){const t=e?.nativeEvent;if(!t)return null;const n={x:s(t.pageX),y:s(t.pageY)};if(n.x!==null&&n.y!==null)return{x:n.x,y:n.y};for(const r of["changedTouches","touches"]){const o=t[r];if(Array.isArray(o)&&o.length){const u=o[0];const c=s(u?.pageX);const y=s(u?.pageY);if(c!==null&&y!==null)return{x:c,y}}}return null}function E(e){l.push({...e,seq:++g});if(l.length>T)l=l.slice(-T)}function A(e){const t=C(e);if(t===null)return;const n=h(e);let r=null;try{r=v(t)}catch{}a={tag:t,x:n?.x??0,y:n?.y??0,t:Date.now(),drift:0,target:r}}function D(e){if(!a)return;const t=h(e);if(!t)return;const n=t.x-a.x;const r=t.y-a.y;a.drift=Math.max(a.drift,Math.sqrt(n*n+r*r))}function O(e){const t=a;a=null;if(!t||!t.target)return;const n=h(e);if(n){const o=n.x-t.x;const u=n.y-t.y;t.drift=Math.max(t.drift,Math.sqrt(o*o+u*u))}if(t.drift>L)return;const r=Date.now()-t.t;if(r>_)return;if(t.target.control==="text")return;if(t.target.control==="toggle"||t.target.control==="slider")return;E({t:Date.now(),kind:r>=M?"longPress":"press",target:t.target})}function P(){a=null}function x(e){const t=C(e);if(t===null)return;const n=e.nativeEvent;let r;let o;if(typeof n.text==="string"){r="text";o=n.text}else if(typeof n.value==="boolean"){r="toggle";o=n.value}else if(typeof n.value==="number"){r="slider";o=n.value}else{return}const u=l[l.length-1];if(u&&u.kind===r&&u.target.nativeTag===t&&Date.now()-u.t<b){u.value=o;u.t=Date.now();return}let c=null;try{c=v(t)}catch{}if(!c)return;E({t:Date.now(),kind:r,target:c,value:o})}export function startTouchCapture(){if(i==="capturing")return getTouchCaptureStatus();const e=w();if(!e){i="unavailable";return getTouchCaptureStatus()}try{f=[e.addListener("topTouchStart",A),e.addListener("topTouchMove",D),e.addListener("topTouchEnd",O),e.addListener("topTouchCancel",P),e.addListener("topChange",x),e.addListener("topValueChange",x),e.addListener("topSlidingComplete",x)];a=null;i="capturing"}catch(t){f=[];i="unavailable";p=t?.message??"addListener failed"}return getTouchCaptureStatus()}export function stopTouchCapture(){f.forEach(e=>{try{e.remove()}catch{}});f=[];a=null;if(i==="capturing")i="idle"}export function clearTouchCapture(){l=[];g=0}export function getTouchCaptureStatus(){return{status:i,reason:i==="unavailable"?p:null}}export function readTouchCapture(e=0){return{...getTouchCaptureStatus(),records:l.filter(t=>t.seq>e),seq:g}}
1
+ "use strict";import{realNow as d}from"@buoy-gg/shared-ui";import{resolveTouchTarget as T}from"./screenElements";import{resolveRawEventEmitter as w}from"./rawEventEmitter";const L=14;const M=550;const _=4e3;const b=8e3;const m=600;let p=null;let C=false;let g=null;let f=[];let l="idle";let i=[];let h=0;let a=null;function A(){if(C)return p;C=true;const e=w();p=e.emitter;g=e.reason;return p}function s(e){return typeof e==="number"&&Number.isFinite(e)?e:null}function E(e){const t=e?.nativeEvent;if(!t)return null;return s(t.target)??s(t.tag)}function x(e){const t=e?.nativeEvent;if(!t)return null;const n={x:s(t.pageX),y:s(t.pageY)};if(n.x!==null&&n.y!==null)return{x:n.x,y:n.y};for(const r of["changedTouches","touches"]){const u=t[r];if(Array.isArray(u)&&u.length){const o=u[0];const c=s(o?.pageX);const v=s(o?.pageY);if(c!==null&&v!==null)return{x:c,y:v}}}return null}function S(e){i.push({...e,seq:++h,wall:d()});if(i.length>m)i=i.slice(-m)}function D(e){const t=E(e);if(t===null)return;const n=x(e);let r=null;try{r=T(t)}catch{}a={tag:t,x:n?.x??0,y:n?.y??0,t:Date.now(),drift:0,target:r}}function O(e){if(!a)return;const t=x(e);if(!t)return;const n=t.x-a.x;const r=t.y-a.y;a.drift=Math.max(a.drift,Math.sqrt(n*n+r*r))}function P(e){const t=a;a=null;if(!t||!t.target)return;const n=x(e);if(n){const u=n.x-t.x;const o=n.y-t.y;t.drift=Math.max(t.drift,Math.sqrt(u*u+o*o))}if(t.drift>L)return;const r=Date.now()-t.t;if(r>_)return;if(t.target.control==="text")return;if(t.target.control==="toggle"||t.target.control==="slider")return;S({t:Date.now(),kind:r>=M?"longPress":"press",target:t.target})}function R(){a=null}function y(e){const t=E(e);if(t===null)return;const n=e.nativeEvent;let r;let u;if(typeof n.text==="string"){r="text";u=n.text}else if(typeof n.value==="boolean"){r="toggle";u=n.value}else if(typeof n.value==="number"){r="slider";u=n.value}else{return}const o=i[i.length-1];if(o&&o.kind===r&&o.target.nativeTag===t&&d()-(o.wall??o.t)<b){o.value=u;o.t=Date.now();o.wall=d();return}let c=null;try{c=T(t)}catch{}if(!c)return;S({t:Date.now(),kind:r,target:c,value:u})}export function startTouchCapture(){if(l==="capturing")return getTouchCaptureStatus();const e=A();if(!e){l="unavailable";return getTouchCaptureStatus()}try{f=[e.addListener("topTouchStart",D),e.addListener("topTouchMove",O),e.addListener("topTouchEnd",P),e.addListener("topTouchCancel",R),e.addListener("topChange",y),e.addListener("topValueChange",y),e.addListener("topSlidingComplete",y)];a=null;l="capturing"}catch(t){f=[];l="unavailable";g=t?.message??"addListener failed"}return getTouchCaptureStatus()}export function stopTouchCapture(){f.forEach(e=>{try{e.remove()}catch{}});f=[];a=null;if(l==="capturing")l="idle"}export function clearTouchCapture(){i=[];h=0}export function getTouchCaptureStatus(){return{status:l,reason:l==="unavailable"?g:null}}export function readTouchCapture(e=0){return{...getTouchCaptureStatus(),records:i.filter(t=>t.seq>e),seq:h}}
@@ -44,6 +44,11 @@ export interface TouchRecord {
44
44
  target: TouchTarget;
45
45
  /** For text/toggle/slider: the value the user ended up with. */
46
46
  value?: string | number | boolean;
47
+ /**
48
+ * The real time, which Buoy's clock tool never moves (`t` follows the app's
49
+ * clock). A bug's tap pictures are matched to their taps by it.
50
+ */
51
+ wall?: number;
47
52
  }
48
53
  export type CaptureStatus = "idle" | "capturing" | "unavailable";
49
54
  export declare function startTouchCapture(): {