rnxsim 0.1.365 → 0.1.367

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +14 -0
  2. package/cli/bin.ts +18 -0
  3. package/cli/bridge-flow-runner.ts +16 -153
  4. package/cli/commands/assert.ts +1 -1
  5. package/cli/commands/box/checkout-plane.ts +126 -0
  6. package/cli/commands/box/rnx-command.ts +68 -0
  7. package/cli/commands/box.ts +200 -0
  8. package/cli/commands/control.ts +15 -76
  9. package/cli/commands/detox.ts +18 -1
  10. package/cli/commands/do-chain.ts +412 -0
  11. package/cli/commands/flow.ts +2 -11
  12. package/cli/commands/inspect/core.ts +302 -725
  13. package/cli/commands/inspect/describe.ts +3 -76
  14. package/cli/commands/inspect/find.ts +3 -6
  15. package/cli/commands/inspect/get-layout.ts +14 -1
  16. package/cli/commands/inspect/resolve-target.ts +41 -47
  17. package/cli/commands/inspect/shared.ts +28 -123
  18. package/cli/commands/inspect/tree.ts +6 -15
  19. package/cli/commands/inspect/wait-ready.ts +2 -2
  20. package/cli/commands/inspect/wait-selector.ts +4 -8
  21. package/cli/commands/inspect.ts +23 -17
  22. package/cli/commands/install-desktop.ts +44 -7
  23. package/cli/commands/maestro-generate.ts +0 -2
  24. package/cli/commands/platform.ts +68 -0
  25. package/cli/commands/state.ts +5 -2
  26. package/cli/outbound-endpoints.ts +6 -1
  27. package/cli/parse-args.ts +13 -2
  28. package/cli/ws-bridge.ts +30 -2
  29. package/detox/index.ts +37 -18
  30. package/dist-cli/bin.js +5 -5
  31. package/dist-cli/chunks/{agent-BVMNQFKF.js → agent-EKKIAKP5.js} +2 -2
  32. package/dist-cli/chunks/{agent-wrapper-B6YFXGC3.js → agent-wrapper-MHLQUGA6.js} +2 -2
  33. package/dist-cli/chunks/{app-fonts-MEI6R6XR.js → app-fonts-HN6ADRTQ.js} +2 -2
  34. package/dist-cli/chunks/{assert-JGHI53HV.js → assert-IMR6QCN6.js} +3 -3
  35. package/dist-cli/chunks/{auth-STEOXUS7.js → auth-27LPMQNH.js} +2 -2
  36. package/dist-cli/chunks/{beta-HT3FLS5T.js → beta-6RXBB5AI.js} +2 -2
  37. package/dist-cli/chunks/box-DORLF3GP.js +1709 -0
  38. package/dist-cli/chunks/{camera-ZCLFSLON.js → camera-2G7JZ5DL.js} +2 -2
  39. package/dist-cli/chunks/{chunk-RI3NS77J.js → chunk-3QZJLNYY.js} +1 -1
  40. package/dist-cli/chunks/{chunk-FHWZPUGC.js → chunk-3VBVEDDA.js} +1 -1
  41. package/dist-cli/chunks/{chunk-EAFKG5R3.js → chunk-4BWGLTKU.js} +2 -2
  42. package/dist-cli/chunks/chunk-4XSNO374.js +423 -0
  43. package/dist-cli/chunks/{chunk-GZEUDDAW.js → chunk-5DGMFUZG.js} +2 -2
  44. package/dist-cli/chunks/{chunk-TKCGP3DD.js → chunk-6DBS5EGX.js} +2 -2
  45. package/dist-cli/chunks/{chunk-HIDS3PYC.js → chunk-6SO6I3D5.js} +2 -2
  46. package/dist-cli/chunks/chunk-75EFOPXE.js +32 -0
  47. package/dist-cli/chunks/{chunk-FIXRGPUT.js → chunk-A5AJFVOF.js} +1 -1
  48. package/dist-cli/chunks/{chunk-2SFMW5K6.js → chunk-AM2ODYAN.js} +1 -1
  49. package/dist-cli/chunks/{chunk-BGRGP3QR.js → chunk-AVOROGA3.js} +1 -1
  50. package/dist-cli/chunks/chunk-AXMMLO7D.js +130 -0
  51. package/dist-cli/chunks/{chunk-XXNPISER.js → chunk-BSEXEYNX.js} +2 -2
  52. package/dist-cli/chunks/{chunk-67ATAITF.js → chunk-CM6ZKZW7.js} +2 -2
  53. package/dist-cli/chunks/{chunk-MR3YPNUI.js → chunk-DNVABCEC.js} +2 -2
  54. package/dist-cli/chunks/{chunk-5AS7S6HY.js → chunk-E33A4AIR.js} +2 -2
  55. package/dist-cli/chunks/{chunk-DBJZUCFP.js → chunk-EFMOXYDD.js} +2 -2
  56. package/dist-cli/chunks/{chunk-ZTWUNK45.js → chunk-EV4P5UBP.js} +2 -2
  57. package/dist-cli/chunks/{chunk-EVBQDQVY.js → chunk-G5IUIGGC.js} +1 -1
  58. package/dist-cli/chunks/chunk-GMLOCV3E.js +312 -0
  59. package/dist-cli/chunks/{chunk-DQFOHIRF.js → chunk-GRN2FHVW.js} +1 -1
  60. package/dist-cli/chunks/{chunk-CYIE65QN.js → chunk-HFFXPUEP.js} +1 -1
  61. package/dist-cli/chunks/chunk-HG6T4OOR.js +4 -0
  62. package/dist-cli/chunks/{chunk-GK7PGYFH.js → chunk-HNT2OXPZ.js} +1 -1
  63. package/dist-cli/chunks/chunk-IPEURNLI.js +24 -0
  64. package/dist-cli/chunks/chunk-IR44SFBA.js +5 -0
  65. package/dist-cli/chunks/chunk-JMSLXZFW.js +4 -0
  66. package/dist-cli/chunks/{chunk-WGNDJARS.js → chunk-JPXQKLNH.js} +1 -1
  67. package/dist-cli/chunks/chunk-K3EC6JDE.js +4 -0
  68. package/dist-cli/chunks/chunk-KHX65HAU.js +4 -0
  69. package/dist-cli/chunks/{chunk-MACI34ST.js → chunk-LWOVKHRC.js} +2 -2
  70. package/dist-cli/chunks/{chunk-QIQL7Y5V.js → chunk-MQN5DWTI.js} +2 -2
  71. package/dist-cli/chunks/{chunk-5VHWQGGF.js → chunk-N3BXQEUF.js} +1 -1
  72. package/dist-cli/chunks/{chunk-O2ORLK6W.js → chunk-N5OSV26B.js} +2 -2
  73. package/dist-cli/chunks/chunk-PHNURIH3.js +4 -0
  74. package/dist-cli/chunks/{chunk-JRPU5TFI.js → chunk-PP2KNVXP.js} +3 -3
  75. package/dist-cli/chunks/{chunk-UR345KM3.js → chunk-PROKNJVY.js} +2 -2
  76. package/dist-cli/chunks/chunk-QXLLY4IM.js +7 -0
  77. package/dist-cli/chunks/{chunk-2CXHDTQ5.js → chunk-RNQTOGM7.js} +1 -1
  78. package/dist-cli/chunks/{chunk-M5KJCLUW.js → chunk-RPNKKVBN.js} +27 -27
  79. package/dist-cli/chunks/{chunk-EFXNSJ55.js → chunk-RSNLI2NH.js} +2 -2
  80. package/dist-cli/chunks/{chunk-25BTVHK2.js → chunk-RZGHV2WI.js} +2 -2
  81. package/dist-cli/chunks/chunk-SGGL3AFV.js +497 -0
  82. package/dist-cli/chunks/chunk-SH5ETJKG.js +4 -0
  83. package/dist-cli/chunks/{chunk-MRNW4GVL.js → chunk-T6J4YP56.js} +2 -2
  84. package/dist-cli/chunks/{chunk-R4FQZXJC.js → chunk-TWUE7WF5.js} +2 -2
  85. package/dist-cli/chunks/{chunk-X5ZOZVHC.js → chunk-U44VEQRN.js} +1 -1
  86. package/dist-cli/chunks/{chunk-XRO5WQXP.js → chunk-URLVQHC3.js} +1 -1
  87. package/dist-cli/chunks/{chunk-JAFF4RAU.js → chunk-VANZFTUE.js} +1 -1
  88. package/dist-cli/chunks/{chunk-6BAF6GFS.js → chunk-VB2YBH46.js} +1 -1
  89. package/dist-cli/chunks/{chunk-O6P4N2JD.js → chunk-VFU2SJ7M.js} +2 -2
  90. package/dist-cli/chunks/{chunk-XPOTXF5Q.js → chunk-VUBJ6FXU.js} +15 -15
  91. package/dist-cli/chunks/{chunk-XR4KID25.js → chunk-W5PATILQ.js} +2 -2
  92. package/dist-cli/chunks/chunk-WI5V4TYG.js +38 -0
  93. package/dist-cli/chunks/{chunk-NEH4T67X.js → chunk-XTRHQAOV.js} +2 -2
  94. package/dist-cli/chunks/chunk-XWUTJLBM.js +27 -0
  95. package/dist-cli/chunks/{chunk-TULWPOAY.js → chunk-XYRUQQUR.js} +2 -2
  96. package/dist-cli/chunks/chunk-YBFB3RM7.js +4 -0
  97. package/dist-cli/chunks/chunk-YGQVQ2VG.js +4 -0
  98. package/dist-cli/chunks/{chunk-J66US2OZ.js → chunk-YINACV32.js} +1 -1
  99. package/dist-cli/chunks/chunk-YV7ERO2V.js +5 -0
  100. package/dist-cli/chunks/{cleanup-G4TEYVKY.js → cleanup-GVFHQ3KH.js} +2 -2
  101. package/dist-cli/chunks/cli-version-DPX5MA2M.js +4 -0
  102. package/dist-cli/chunks/{compat-EZ5NP32J.js → compat-AYRTXYAM.js} +2 -2
  103. package/dist-cli/chunks/{config-27M2DGCS.js → config-K7LOOV62.js} +2 -2
  104. package/dist-cli/chunks/connect-H3CNY4IO.js +4 -0
  105. package/dist-cli/chunks/control-SMHZ2CF5.js +4 -0
  106. package/dist-cli/chunks/daemon-TEZUNI73.js +4 -0
  107. package/dist-cli/chunks/{debug-EXU3D7PC.js → debug-ELGHG57T.js} +3 -3
  108. package/dist-cli/chunks/{desktop-SHHPZAWQ.js → desktop-4G7FK3MP.js} +3 -3
  109. package/dist-cli/chunks/detox-JKXGEJIZ.js +52 -0
  110. package/dist-cli/chunks/{device-4NI26HG6.js → device-IV3AR6KG.js} +2 -2
  111. package/dist-cli/chunks/{diagnose-P4SFXH6J.js → diagnose-3ERGF7EW.js} +2 -2
  112. package/dist-cli/chunks/{disk-cleanup-BUAKWYMY.js → disk-cleanup-ALFEVZ4B.js} +2 -2
  113. package/dist-cli/chunks/do-chain-K2B4OHM7.js +5 -0
  114. package/dist-cli/chunks/drivers-KJYXA3M3.js +4 -0
  115. package/dist-cli/chunks/env-2KF6IYZE.js +4 -0
  116. package/dist-cli/chunks/{film-Y2BAQINB.js → film-UQXJFAD5.js} +3 -3
  117. package/dist-cli/chunks/flow-ASTUH56E.js +4 -0
  118. package/dist-cli/chunks/help-SNNYFELA.js +4 -0
  119. package/dist-cli/chunks/{hidden-runtime-alias-U2MAY2XV.js → hidden-runtime-alias-VJCWCFVO.js} +2 -2
  120. package/dist-cli/chunks/{home-paths-PAJMZCOS.js → home-paths-EGUZZ6J6.js} +2 -2
  121. package/dist-cli/chunks/inspect-XANAADQT.js +4 -0
  122. package/dist-cli/chunks/install-desktop-JKQA7UY6.js +4 -0
  123. package/dist-cli/chunks/{login-D53XKBEO.js → login-6KQGD7HK.js} +2 -2
  124. package/dist-cli/chunks/{logout-HZQKLNUJ.js → logout-2FCOVLBC.js} +2 -2
  125. package/dist-cli/chunks/{maestro-XSS2KX6L.js → maestro-HPSSEVJD.js} +3 -3
  126. package/dist-cli/chunks/{maestro-generate-DNDQX3JQ.js → maestro-generate-KQQ6JHMR.js} +5 -5
  127. package/dist-cli/chunks/{mode-LEVGOKI3.js → mode-SH7KRZET.js} +2 -2
  128. package/dist-cli/chunks/{optional-demo-registry-2XZIJNDG.js → optional-demo-registry-NAMCAVFX.js} +2 -2
  129. package/dist-cli/chunks/{perf-OKMAXDLB.js → perf-LWKAHXUL.js} +2 -2
  130. package/dist-cli/chunks/{permissions-VG5TBUTN.js → permissions-EZTKWTXV.js} +2 -2
  131. package/dist-cli/chunks/platform-KSOJIVN5.js +6 -0
  132. package/dist-cli/chunks/privacy-EJULWP7L.js +4 -0
  133. package/dist-cli/chunks/{record-BQYGZOMV.js → record-2IC7BAQN.js} +3 -3
  134. package/dist-cli/chunks/{report-issue-HCPZESWE.js → report-issue-MMX6HOQO.js} +2 -2
  135. package/dist-cli/chunks/reset-PKFZA4NC.js +4 -0
  136. package/dist-cli/chunks/resolve-target-AFKU3BRE.js +4 -0
  137. package/dist-cli/chunks/runtime-XHWWPOIN.js +4 -0
  138. package/dist-cli/chunks/{screenshot-command-DWEYPJE7.js → screenshot-command-JYUXDVSA.js} +3 -3
  139. package/dist-cli/chunks/{screenshot-layers-5GMBXLO7.js → screenshot-layers-OGRY6AA3.js} +2 -2
  140. package/dist-cli/chunks/{screenshots-capture-5KCI7IZD.js → screenshots-capture-QHDN65XS.js} +2 -2
  141. package/dist-cli/chunks/{serve-QNKTA2HR.js → serve-W4BKAG4J.js} +3 -3
  142. package/dist-cli/chunks/setup-WJPMPSAC.js +4 -0
  143. package/dist-cli/chunks/sim-client-UOQGFBPO.js +4 -0
  144. package/dist-cli/chunks/{skills-DOEALD3X.js → skills-OPPXOD63.js} +2 -2
  145. package/dist-cli/chunks/state-TDAN7BOM.js +14 -0
  146. package/dist-cli/chunks/{storage-E7WUWN3E.js → storage-CFB2YGLY.js} +2 -2
  147. package/dist-cli/chunks/store-4TEED4ZU.js +4 -0
  148. package/dist-cli/chunks/telemetry-S6N7CV6G.js +4 -0
  149. package/dist-cli/chunks/{timeline-IKNUGQ2A.js → timeline-ASOOVP4C.js} +2 -2
  150. package/dist-cli/chunks/{upgrade-VS3OKXE2.js → upgrade-6MVJISHG.js} +2 -2
  151. package/dist-cli/chunks/upload-CBNIRFEW.js +4 -0
  152. package/dist-cli/chunks/{version-F4XHNTBZ.js → version-5GS7CWRL.js} +2 -2
  153. package/dist-cli/chunks/{web-F72724QL.js → web-QRRMYMV4.js} +2 -2
  154. package/dist-cli/chunks/welcome-33FXMAMB.js +5 -0
  155. package/dist-cli/chunks/{what-happened-APK7YKOV.js → what-happened-GAZJGKXX.js} +2 -2
  156. package/dist-cli/chunks/ws-bridge-DIXUAPLQ.js +4 -0
  157. package/dist-lib/agent-daemon-client.cjs +1 -1
  158. package/dist-lib/agent-events.cjs +1 -1
  159. package/dist-lib/agent-identity.cjs +1 -1
  160. package/dist-lib/agent-sessions.cjs +1 -1
  161. package/dist-lib/attached-projects.cjs +1 -1
  162. package/dist-lib/auth/shared-session.cjs +1 -1
  163. package/dist-lib/backend-origin.cjs +1 -1
  164. package/dist-lib/beta.cjs +1 -1
  165. package/dist-lib/beta.mjs +1 -1
  166. package/dist-lib/bridge-constants.cjs +1 -1
  167. package/dist-lib/bridge-contract-input.cjs +336 -0
  168. package/dist-lib/bridge-contract-input.mjs +303 -0
  169. package/dist-lib/bridge-contract.cjs +29 -1
  170. package/dist-lib/bridge-contract.mjs +19 -0
  171. package/dist-lib/cli-constants.cjs +1 -1
  172. package/dist-lib/config.cjs +1 -1
  173. package/dist-lib/detox/index.cjs +35 -19
  174. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  175. package/dist-lib/home-paths.cjs +1 -1
  176. package/dist-lib/host/bridge-host.cjs +5 -1
  177. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  178. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  179. package/dist-lib/host/fetch-proxy-overrides.mjs +1 -1
  180. package/dist-lib/host/replacement-module-handler.cjs +1 -1
  181. package/dist-lib/host/websocket-proxy.cjs +1 -1
  182. package/dist-lib/index.cjs +244 -594
  183. package/dist-lib/jump-to-source-babel.cjs +1 -1
  184. package/dist-lib/menu.cjs +1 -1
  185. package/dist-lib/menu.mjs +1 -1
  186. package/dist-lib/metro-production-bundle.cjs +1 -1
  187. package/dist-lib/metro-production-bundle.mjs +1 -1
  188. package/dist-lib/metro.cjs +1 -1
  189. package/dist-lib/profiles.cjs +1 -1
  190. package/dist-lib/public-brand.cjs +1 -1
  191. package/dist-lib/react-native-host-modules.cjs +1 -1
  192. package/dist-lib/react-native-host-modules.mjs +1 -1
  193. package/dist-lib/render-mode.cjs +1 -1
  194. package/dist-lib/scripts/dev-server-scanner.cjs +1 -1
  195. package/dist-lib/sdk.cjs +303 -657
  196. package/dist-lib/sdk.mjs +301 -652
  197. package/dist-lib/skills.cjs +256 -339
  198. package/dist-lib/vite.cjs +1 -1
  199. package/package.json +10 -1
  200. package/skills/contrast/SKILL.md +3 -0
  201. package/skills/rnx-debug/SKILL.md +8 -0
  202. package/skills/rnx-test/SKILL.md +21 -0
  203. package/src/app-url.ts +40 -0
  204. package/src/bridge-contract-input.ts +359 -0
  205. package/src/bridge-contract.ts +121 -1
  206. package/src/host/bridge-host.ts +7 -12
  207. package/src/index.ts +7 -0
  208. package/src/sim-client.ts +24 -9
  209. package/dist-cli/chunks/chunk-2JFZ5Z7Q.js +0 -4
  210. package/dist-cli/chunks/chunk-4WFN4DFR.js +0 -5
  211. package/dist-cli/chunks/chunk-52ES4API.js +0 -38
  212. package/dist-cli/chunks/chunk-622E4JET.js +0 -767
  213. package/dist-cli/chunks/chunk-EFL2ASZO.js +0 -124
  214. package/dist-cli/chunks/chunk-IWPS3EKJ.js +0 -15
  215. package/dist-cli/chunks/chunk-MCHKBFUL.js +0 -4
  216. package/dist-cli/chunks/chunk-OSZ5HZSI.js +0 -24
  217. package/dist-cli/chunks/chunk-W3UIDI3W.js +0 -5
  218. package/dist-cli/chunks/chunk-XKRUNS7A.js +0 -32
  219. package/dist-cli/chunks/chunk-YE3M3YD4.js +0 -944
  220. package/dist-cli/chunks/chunk-ZCP4CRP6.js +0 -4
  221. package/dist-cli/chunks/chunk-ZGD7GZRI.js +0 -4
  222. package/dist-cli/chunks/chunk-ZGH5U4AJ.js +0 -27
  223. package/dist-cli/chunks/cli-version-ZM3PVKQ5.js +0 -4
  224. package/dist-cli/chunks/control-4QR43FXV.js +0 -4
  225. package/dist-cli/chunks/daemon-2U4CJ6AT.js +0 -4
  226. package/dist-cli/chunks/detox-RQ6FFSBS.js +0 -52
  227. package/dist-cli/chunks/drivers-OVCUPQTM.js +0 -4
  228. package/dist-cli/chunks/flow-ELTLKKZ3.js +0 -4
  229. package/dist-cli/chunks/help-CDEZAG2L.js +0 -4
  230. package/dist-cli/chunks/inspect-VVQRPJLS.js +0 -4
  231. package/dist-cli/chunks/install-desktop-YXSRKR35.js +0 -4
  232. package/dist-cli/chunks/privacy-MNRHREME.js +0 -4
  233. package/dist-cli/chunks/reset-R4E4W4YI.js +0 -4
  234. package/dist-cli/chunks/runtime-XRQZ7W34.js +0 -4
  235. package/dist-cli/chunks/setup-RNMM5GO5.js +0 -4
  236. package/dist-cli/chunks/state-3HH2IHIF.js +0 -14
  237. package/dist-cli/chunks/store-HUPZUCFG.js +0 -4
  238. package/dist-cli/chunks/telemetry-IJ53XR2Y.js +0 -4
  239. package/dist-cli/chunks/upload-A57NAAHF.js +0 -4
  240. package/dist-cli/chunks/welcome-B72RRMBW.js +0 -5
@@ -1,767 +0,0 @@
1
- /*! rnx v0.1.365 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
- import { createRequire as __sootsimCreateRequire } from 'node:module'
3
- var require = __sootsimCreateRequire(import.meta.url)
4
- function Q(t,e){let r=["--max-ms","--maxMs","--maxms","--max_ms"];for(let n of r){let o=t.indexOf(n);if(o>=0&&t[o+1]){let s=Number(t[o+1]);if(Number.isFinite(s))return Math.max(100,s)}}return e}var P=new Set(["tap","double-tap","tap-text","tap-id","long-press","touch"]);function N(t){return typeof t=="string"&&P.has(t)}async function M(t){return await t.send({type:"evaluate",code:"window.__sootsimEngineState?.inspectActive === true"})===!0}async function X(t,e){if(!N(e))return!1;try{return await M(t)}catch{return!1}}async function Z(t){let e=await t.send({type:"evaluate",code:"(async () => await window.__sootsimTest.getNodeCount())()"});return{nodes:typeof e=="number"?e:0}}async function ee(t,e=5,r){let n=r?.format?`, ${JSON.stringify(r)}`:"",o=await t.send({type:"evaluate",code:`(async () => await window.__sootsimTest.dumpTree(${e}${n}))()`});if(r?.format==="boxes"&&typeof o=="string")try{return{depth:e,tree:JSON.parse(o)}}catch{return{depth:e,tree:o}}return{depth:e,tree:o}}async function te(t){let e=await t.send({type:"evaluate",code:"window.location.href"});return{url:typeof e=="string"?e:""}}async function ne(t,e){let r=e.maxDepth??12,n=`(async () => {
5
- const t = window.__sootsimTest
6
- const mainShell = window.SootSim?.bridges?.mainShell
7
- const kb = window.__sootsimKeyboard
8
- if (!t) return { error: 'no test bridge' }
9
-
10
- let shell = null
11
- try {
12
- shell = typeof mainShell?.getState === 'function' ? await mainShell.getState() : null
13
- } catch {}
14
-
15
- const opts = ${JSON.stringify(e)}
16
- const needsRecursiveDump =
17
- opts.verbose || opts.subtreeRoot || opts.includeOccluded || opts.maxDepth != null
18
- const globToRegex = (glob) => {
19
- const escaped = String(glob).replace(/[.+^$(){}|[\\]\\\\]/g, '\\\\$&')
20
- const body = escaped.replace(/\\*/g, '.*').replace(/\\?/g, '.')
21
- return new RegExp('^' + body + '$', 'i')
22
- }
23
- // clipping a describe line is a DISPLAY decision. opts.fullText (set by
24
- // \`describe --json\`) keeps the real string, so a bundle-eval stack or a
25
- // red-box message reaches the caller whole instead of ending in an
26
- // ellipsis nothing downstream can undo.
27
- const clipForDisplay = (value, max) => {
28
- const text = typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim() : ''
29
- if (opts.fullText || text.length <= max) return text
30
- return text.slice(0, max - 1).trimEnd() + '\u2026'
31
- }
32
- const formatInspectableTree = async () => {
33
- if (typeof t.listInspectable !== 'function') return null
34
- const list = await t.listInspectable({})
35
- if (!Array.isArray(list)) return null
36
- const filter = typeof opts.filter === 'string' ? opts.filter.toLowerCase() : ''
37
- const testIdRegex = opts.testIdLike ? globToRegex(opts.testIdLike) : null
38
- const onlyRegex = opts.onlyGlob ? globToRegex(opts.onlyGlob) : null
39
- const lines = []
40
- let matched = 0
41
- for (const node of list) {
42
- const testID = node?.testID || node?.testId || ''
43
- const role = node?.role || ''
44
- const label = node?.accessibilityLabel || node?.label || ''
45
- const text = node?.text || ''
46
- if (testIdRegex && !testIdRegex.test(testID)) continue
47
- const joined = [role, label, text, testID].filter(Boolean).join(' ')
48
- if (onlyRegex && !onlyRegex.test(joined)) continue
49
- if (filter && !joined.toLowerCase().includes(filter)) continue
50
- matched++
51
-
52
- const type = String(node?.type || 'node').toLowerCase()
53
- const handlers = Array.isArray(node?.handlers) ? node.handlers : []
54
- const parts = []
55
- if (role) parts.push('[' + role + ']')
56
- else if (handlers.length > 0) parts.push('[tap]')
57
- else parts.push('<' + type + '>')
58
- const visibleText = clipForDisplay(text, 50)
59
- if (visibleText) parts.push(JSON.stringify(visibleText))
60
- if (testID) parts.push('#' + testID)
61
- if (label && label !== text) {
62
- parts.push('label=' + JSON.stringify(clipForDisplay(label, 50)))
63
- }
64
- if (!opts.hideXy) {
65
- const abs = node?.absolute || {}
66
- const layout = node?.layout || {}
67
- const x = Math.round(Number(abs.x) || 0)
68
- const y = Math.round(Number(abs.y) || 0)
69
- const w = Math.round(Number(layout.width) || 0)
70
- const h = Math.round(Number(layout.height) || 0)
71
- parts.push('@(' + x + ',' + y + ') ' + w + 'x' + h)
72
- }
73
- if (handlers.length > 0) parts.push('(tap)')
74
- lines.push(' ' + parts.join(' '))
75
- }
76
- return { tree: lines.join('\\n'), matched }
77
- }
78
-
79
- let tree = ''
80
- const compactResult = needsRecursiveDump ? null : await formatInspectableTree()
81
- if (compactResult) {
82
- tree = compactResult.tree
83
- } else {
84
- tree = await t.dumpTree(${r}, opts)
85
- }
86
- const nodeCount = (await t.getNodeCount?.()) || 0
87
- const keyboard = kb && typeof kb.getLayout === 'function' ? kb.getLayout() : null
88
- return { tree, shell, nodeCount, keyboard }
89
- })()`;return await t.send({type:"evaluate",code:n})??{}}function D(t){let e=t.fontSize>=18||t.fontSize>=14&&(t.fontWeight??400)>=700?3:4.5,{normal:r,background:n}=t;if(r.width<=0||r.height<=0||r.width!==n.width||r.height!==n.height)return{ratio:null,required:e,reason:"capture dimensions do not match"};let o=Math.max(0,Math.floor(t.box.x)),s=Math.max(0,Math.floor(t.box.y)),i=Math.min(r.width,Math.ceil(t.box.x+t.box.w)),d=Math.min(r.height,Math.ceil(t.box.y+t.box.h));if(i<=o||d<=s)return{ratio:null,required:e,reason:"text is outside the captured frame"};let p=l=>{let u=l/255;return u<=.04045?u/12.92:Math.pow((u+.055)/1.055,2.4)},g=(l,u)=>{let c=.2126*p(l[0])+.7152*p(l[1])+.0722*p(l[2]),v=.2126*p(u[0])+.7152*p(u[1])+.0722*p(u[2]);return(Math.max(c,v)+.05)/(Math.min(c,v)+.05)},a=l=>`#${l.slice(0,3).map(u=>Math.round(u).toString(16).padStart(2,"0")).join("")}`,h=(i-o)*(d-s),y=Math.max(1,Math.floor(Math.sqrt(h/12e3))),b=(l,u)=>(u*r.width+l)*4,x=l=>Math.max(Math.abs(r.data[l]-n.data[l]),Math.abs(r.data[l+1]-n.data[l+1]),Math.abs(r.data[l+2]-n.data[l+2])),f=0,m=null,w=null;for(let l=s;l<d;l+=y)for(let u=o;u<i;u+=y){let c=b(u,l);if(n.data[c+3]<250)continue;let v=[n.data[c],n.data[c+1],n.data[c+2]];w??=v;let E=x(c);E<=f||(f=E,m=[r.data[c],r.data[c+1],r.data[c+2]])}let S=1/0,I=null,T=null,k=(l,u)=>{let c=g(l,u);c>=S||(S=c,I=l,T=u)};if(f>=2&&m)for(let l=s;l<d;l+=y)for(let u=o;u<i;u+=y){let c=b(u,l);n.data[c+3]<250||x(c)<2||k(m,[n.data[c],n.data[c+1],n.data[c+2]])}else w&&k(w,w);return!I||!T||!Number.isFinite(S)?{ratio:null,required:e,reason:"could not isolate opaque rendered text pixels"}:{ratio:Math.round(S*100)/100,required:e,foreground:a(I),background:a(T)}}function A(t={}){let e=t.styling===!0,r=t.filter?.trim().toLowerCase()??"";return`(async () => {
90
- const t = window.__sootsimTest
91
- if (!t || typeof t.listInspectable !== 'function') return []
92
- const list = await t.listInspectable({})
93
- if (!Array.isArray(list)) return []
94
- const includeStyle = ${JSON.stringify(e)}
95
- const scoreContrast = ${D.toString()}
96
- // narrows by ELEMENT, not by style field: fewer rows, full detail on each.
97
- const filter = ${JSON.stringify(r)}
98
- const matchesFilter = (n, text) => {
99
- if (!filter) return true
100
- const fields = [text, n.testID || n.testId, n.accessibilityRole || n.role, n.type]
101
- return fields.some((f) => typeof f === 'string' && f.toLowerCase().includes(filter))
102
- }
103
-
104
- const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : 0)
105
- const round = (v) => Math.round(num(v))
106
-
107
- // borderRadius can be authored as a string ("12px") or split per-corner;
108
- // prefer the uniform borderRadius, else the largest corner radius present.
109
- const radiusOf = (style) => {
110
- if (!style) return 0
111
- const keys = ['borderRadius','borderTopLeftRadius','borderTopRightRadius','borderBottomLeftRadius','borderBottomRightRadius']
112
- let max = 0
113
- for (const k of keys) {
114
- const raw = style[k]
115
- const n = typeof raw === 'number' ? raw : (typeof raw === 'string' ? parseFloat(raw) : NaN)
116
- if (Number.isFinite(n)) max = Math.max(max, n)
117
- }
118
- return Math.round(max)
119
- }
120
- const fontSizeOf = (style) => {
121
- if (!style) return 0
122
- const raw = style.fontSize
123
- const n = typeof raw === 'number' ? raw : (typeof raw === 'string' ? parseFloat(raw) : NaN)
124
- return Number.isFinite(n) ? Math.round(n) : 0
125
- }
126
- // styling extractors \u2014 omit boring defaults so the agent only sees notable
127
- // styling (low opacity, struck text, clipping, a real border/color).
128
- const colorStr = (v) => {
129
- if (v == null) return undefined
130
- const s = String(v).split(' ').join('')
131
- return s && s !== 'transparent' && s !== 'rgba(0,0,0,0)' ? s : undefined
132
- }
133
- const opacityOf = (style) => {
134
- const o = style && style.opacity
135
- const n = typeof o === 'number' ? o : (typeof o === 'string' ? parseFloat(o) : NaN)
136
- return Number.isFinite(n) && n < 1 ? Math.round(n * 100) / 100 : undefined
137
- }
138
- const weightOf = (style) => {
139
- const w = style && style.fontWeight
140
- const n = w === 'bold' ? 700 : (typeof w === 'number' ? w : (typeof w === 'string' ? parseInt(w, 10) : NaN))
141
- return Number.isFinite(n) && n >= 600 ? n : undefined
142
- }
143
- const decoOf = (style) => {
144
- const d = style && (style.textDecorationLine || style.textDecoration)
145
- return d && d !== 'none' && d !== 'normal' ? String(d).split(' ')[0] : undefined
146
- }
147
- const overflowOf = (style) => (style && style.overflow === 'hidden' ? 'hidden' : undefined)
148
- const borderWOf = (style) => {
149
- if (!style) return undefined
150
- const keys = ['borderWidth','borderTopWidth','borderBottomWidth','borderLeftWidth','borderRightWidth']
151
- let max = 0
152
- for (const k of keys) {
153
- const r = style[k]
154
- const n = typeof r === 'number' ? r : (typeof r === 'string' ? parseFloat(r) : NaN)
155
- if (Number.isFinite(n)) max = Math.max(max, n)
156
- }
157
- return max > 0 ? Math.round(max) : undefined
158
- }
159
- // only meaningful alongside a real border width, so it is resolved by the
160
- // caller below rather than on its own.
161
- const borderColorOf = (style) => {
162
- if (!style) return undefined
163
- const keys = ['borderColor','borderTopColor','borderBottomColor','borderLeftColor','borderRightColor']
164
- for (const k of keys) {
165
- const c = colorStr(style[k])
166
- if (c) return c
167
- }
168
- return undefined
169
- }
170
-
171
- const isVisible = (n) => {
172
- const layout = n && n.layout
173
- if (!layout || layout.width <= 0 || layout.height <= 0) return false
174
- const abs = (n && (n.absolute || n.absolutePosition)) || null
175
- if (!abs) return true
176
- const device = (n && n.device) || {}
177
- const screenW = Number(device.width) || window.innerWidth || 0
178
- const screenH = Number(device.height) || window.innerHeight || 0
179
- if (!screenW || !screenH) return true
180
- return abs.x + layout.width > 0 && abs.y + layout.height > 0 && abs.x < screenW && abs.y < screenH
181
- }
182
-
183
- const elements = list.filter(isVisible).filter((n) => {
184
- const t = typeof n.text === 'string' && n.text.trim() ? n.text.trim() : undefined
185
- return matchesFilter(n, t)
186
- }).map((n) => {
187
- const layout = n.layout || { x: 0, y: 0, width: 0, height: 0 }
188
- const abs = n.absolute || n.absolutePosition || { x: layout.x, y: layout.y }
189
- const text = typeof n.text === 'string' && n.text.trim() ? n.text.trim() : undefined
190
- const base = {
191
- ...(typeof n.nodeId === 'number'
192
- ? {
193
- nodeId: n.nodeId,
194
- ancestorIds: Array.isArray(n.ancestors)
195
- ? n.ancestors.map((ancestor) => ancestor && ancestor.nodeId).filter((id) => typeof id === 'number')
196
- : [],
197
- }
198
- : {}),
199
- testID: n.testID || n.testId || undefined,
200
- role: n.accessibilityRole || n.role || undefined,
201
- type: typeof n.type === 'string' ? n.type : 'node',
202
- text,
203
- box: { x: round(abs.x), y: round(abs.y), w: round(layout.width), h: round(layout.height) },
204
- borderRadius: 0,
205
- padding: { t: 0, r: 0, b: 0, l: 0 },
206
- fontSize: 0,
207
- }
208
- if (!includeStyle) return base
209
- // computedStyle has the resolved values; style is the curated subset \u2014
210
- // fall back across both so radius/fontSize survive either shape.
211
- const style = Object.assign({}, n.style || {}, n.computedStyle || {})
212
- const pad = (n.boxModel && n.boxModel.padding) || {}
213
- const borderWidth = borderWOf(style)
214
- return {
215
- ...base,
216
- borderRadius: radiusOf(style),
217
- padding: { t: round(pad.top), r: round(pad.right), b: round(pad.bottom), l: round(pad.left) },
218
- fontSize: text ? (fontSizeOf(style) || 14) : 0,
219
- color: text ? colorStr(style.color) : undefined,
220
- bg: colorStr(style.backgroundColor),
221
- opacity: opacityOf(style),
222
- fontWeight: weightOf(style),
223
- textDecoration: decoOf(style),
224
- overflow: overflowOf(style),
225
- borderWidth,
226
- borderColor: borderWidth ? borderColorOf(style) : undefined,
227
- }
228
- })
229
- const textElements = elements.filter((element) => element.text && element.fontSize > 0)
230
- if (!includeStyle || textElements.length === 0) return elements
231
-
232
- const screenshot = window.SootSim && window.SootSim.bridges && window.SootSim.bridges.screenshot
233
- if (typeof screenshot !== 'function') {
234
- throw new Error('styled native layout requires the rnx capture bridge')
235
- }
236
- const device = list.find((node) => node && node.device)?.device || {}
237
- const width = Math.round(Number(device.width) || window.innerWidth || 0)
238
- const height = Math.round(Number(device.height) || window.innerHeight || 0)
239
- if (!width || !height) throw new Error('native layout has no capture dimensions')
240
- const capture = async (suppressText) => {
241
- const dataUrl = await screenshot({
242
- format: 'png',
243
- outputWidth: width,
244
- outputHeight: height,
245
- ...(suppressText ? { suppressText: true } : {}),
246
- })
247
- const image = await new Promise((resolve, reject) => {
248
- const next = new Image()
249
- next.onload = () => resolve(next)
250
- next.onerror = () => reject(new Error('could not decode native layout pixels'))
251
- next.src = dataUrl
252
- })
253
- const canvas = document.createElement('canvas')
254
- canvas.width = image.naturalWidth
255
- canvas.height = image.naturalHeight
256
- const context = canvas.getContext('2d', { willReadFrequently: true })
257
- if (!context) throw new Error('could not read native layout pixels')
258
- context.drawImage(image, 0, 0)
259
- return context.getImageData(0, 0, canvas.width, canvas.height)
260
- }
261
- const normal = await capture(false)
262
- const background = await capture(true)
263
- for (const element of textElements) {
264
- element.contrast = scoreContrast({
265
- normal,
266
- background,
267
- box: element.box,
268
- fontSize: element.fontSize,
269
- fontWeight: element.fontWeight,
270
- })
271
- }
272
- return elements
273
- })()`}var re=A();async function oe(t,e={}){let r=await t.send({type:"evaluate",code:A(e)});return Array.isArray(r)?r:[]}function se(t,e){return t.length===0?" no visible elements found":t.map(n=>{let s=[n.testID?`#${n.testID}`:n.selector?n.selector:n.role?`[${n.role}]`:`<${n.type}>`,`@(${n.box.x},${n.box.y})`,`${n.box.w}x${n.box.h}`];n.borderRadius>0&&s.push(`radius:${n.borderRadius}`);let i=n.padding;if(i.t||i.r||i.b||i.l){let d=i.t===i.r&&i.r===i.b&&i.b===i.l;s.push(d?`pad:${i.t}`:`pad:${i.t},${i.r},${i.b},${i.l}`)}if(n.fontSize>0&&s.push(`font:${n.fontSize}`),e?.styling){if(n.fontWeight&&s.push(`weight:${n.fontWeight}`),n.color&&s.push(`color:${n.color}`),n.bg&&s.push(`bg:${n.bg}`),n.contrast){let d=n.contrast.ratio==null?`?/${n.contrast.required}`:`${n.contrast.ratio}/${n.contrast.required}${n.contrast.ratio<n.contrast.required?" FAIL":""}`;s.push(`contrast:${d}`),n.contrast.background&&s.push(`on:${n.contrast.background}`)}n.opacity!=null&&s.push(`opacity:${n.opacity}`),n.textDecoration&&s.push(`deco:${n.textDecoration}`),n.overflow&&s.push(`overflow:${n.overflow}`),n.borderWidth&&s.push(n.borderColor?`border:${n.borderWidth}/${n.borderColor}`:`border:${n.borderWidth}`)}if(n.text){let d=n.text.length>40?`${n.text.slice(0,39)}\u2026`:n.text;s.push(`"${d}"`)}return` ${s.join(" ")}`}).join(`
274
- `)}var C=`(async () => {
275
- const t = window.__sootsimTest
276
- if (!t) return []
277
-
278
- const readLayout = (n) => n?.layout || null
279
- const readAbs = (n) => n?.absolutePosition || n?.absolute || null
280
- const readRole = (n) => n?.accessibilityRole || n?.role || null
281
- const readLabel = (n) => n?.accessibilityLabel || n?.label || n?.text || null
282
- const readHint = (n) => n?.accessibilityHint || n?.hint || null
283
- const readState = (n) => n?.accessibilityState || n?.state || null
284
- const readTestId = (n) => n?.testID || n?.testId || null
285
- const readType = (n) => typeof n?.type === 'string' ? n.type.toLowerCase() : n?.type
286
- const readPressable = (n) => {
287
- if (n?.pressable) return true
288
- const handlers = Array.isArray(n?.handlers) ? n.handlers : []
289
- const role = readRole(n)
290
- return handlers.length > 0 || role === 'button' || role === 'link' || role === 'tab'
291
- }
292
- const isTextInput = (n) => n?.isTextInput === true
293
- const isTextNode = (n) => readType(n) === 'text'
294
- const isVisibleTarget = (n) => {
295
- const layout = readLayout(n)
296
- if (!layout || layout.width <= 0 || layout.height <= 0) return false
297
- const abs = readAbs(n)
298
- if (!abs) return true
299
- const device = n?.device || {}
300
- const screenW = Number(device.width) || window.innerWidth || 0
301
- const screenH = Number(device.height) || window.innerHeight || 0
302
- return (
303
- abs.x + layout.width > 0 &&
304
- abs.y + layout.height > 0 &&
305
- abs.x < screenW &&
306
- abs.y < screenH
307
- )
308
- }
309
- const hasAccessibleSignal = (n) => {
310
- const role = readRole(n)
311
- const label = readLabel(n)
312
- const hint = readHint(n)
313
- if (role) return true
314
- if (hint) return true
315
- if (isTextInput(n)) return true
316
- if (readPressable(n)) return true
317
- if (isTextNode(n) && n?.text) return true
318
- if (typeof label === 'string' && label.length <= 30 && label !== n?.text) return true
319
- return false
320
- }
321
- const normalize = (n) => {
322
- const layout = readLayout(n)
323
- const abs = readAbs(n)
324
- const role = readRole(n) || (readPressable(n) ? 'button' : isTextInput(n) ? 'textfield' : isTextNode(n) ? 'statictext' : 'none')
325
- return {
326
- role,
327
- label: readLabel(n),
328
- hint: readHint(n),
329
- state: readState(n),
330
- testID: readTestId(n),
331
- position: abs ? { x: Math.round(abs.x), y: Math.round(abs.y) } : null,
332
- size: layout ? { w: Math.round(layout.width), h: Math.round(layout.height) } : null,
333
- }
334
- }
335
-
336
- if (typeof t.listInspectable === 'function') {
337
- const list = await t.listInspectable({})
338
- if (Array.isArray(list)) {
339
- return list.filter(n => isVisibleTarget(n) && hasAccessibleSignal(n)).map(normalize)
340
- }
341
- }
342
-
343
- const all = await t.queryAll({ pruneHidden: true })
344
- return all
345
- .filter(n => isVisibleTarget(n) && hasAccessibleSignal(n))
346
- .map(normalize)
347
- })()`;async function ae(t){let e=await t.send({type:"evaluate",code:C});return Array.isArray(e)?e:[]}var R=`
348
- const fromInspectable = async () => {
349
- if (typeof t.listInspectable !== 'function') return null
350
- const list = await t.listInspectable({})
351
- if (!Array.isArray(list)) return null
352
- return list.map((n) => {
353
- const role = n.accessibilityRole ?? n.role
354
- const label = n.accessibilityLabel ?? n.label
355
- const layout = n.layout
356
- const absolutePosition = n.absolutePosition ?? n.absolute
357
- const screenW = Number(n.device?.width) || window.innerWidth || 0
358
- const screenH = Number(n.device?.height) || window.innerHeight || 0
359
- const visibleFrame = layout && absolutePosition
360
- ? {
361
- x: Math.max(0, absolutePosition.x),
362
- y: Math.max(0, absolutePosition.y),
363
- width: Math.max(
364
- 0,
365
- Math.min(screenW, absolutePosition.x + layout.width) -
366
- Math.max(0, absolutePosition.x),
367
- ),
368
- height: Math.max(
369
- 0,
370
- Math.min(screenH, absolutePosition.y + layout.height) -
371
- Math.max(0, absolutePosition.y),
372
- ),
373
- }
374
- : null
375
- const handlers = Array.isArray(n.handlers) ? n.handlers : []
376
- const pressable =
377
- handlers.length > 0 ||
378
- role === 'button' ||
379
- role === 'link' ||
380
- role === 'tab'
381
- return {
382
- type: typeof n.type === 'string' ? n.type.toLowerCase() : n.type,
383
- id: n.id ?? n.nodeId,
384
- nodeId: n.nodeId,
385
- testID: n.testID ?? n.testId,
386
- text: n.text,
387
- layout,
388
- absolutePosition,
389
- visibleFrame,
390
- style: n.computedStyle ?? n.style ?? {},
391
- childCount: n.childCount ?? 0,
392
- pressed: n.pressed ?? false,
393
- pressable,
394
- isTextInput: n.isTextInput ?? false,
395
- accessible: n.accessible ?? true,
396
- accessibilityLabel: label,
397
- accessibilityRole: role,
398
- accessibilityHint: n.accessibilityHint,
399
- accessibilityState: n.accessibilityState,
400
- accessibilityValue: n.accessibilityValue,
401
- }
402
- })
403
- }
404
- const isVisibleTarget = (n) => {
405
- if (!n?.layout) return false
406
- const frame = n.visibleFrame
407
- if (frame) return frame.width > 0 && frame.height > 0
408
- const abs = n.absolutePosition
409
- if (!abs) return n.layout.width > 0 && n.layout.height > 0
410
- const screenW = window.innerWidth || 0
411
- const screenH = window.innerHeight || 0
412
- return (
413
- abs.x + n.layout.width > 0 &&
414
- abs.y + n.layout.height > 0 &&
415
- abs.x < screenW &&
416
- abs.y < screenH
417
- )
418
- }
419
- `;function O(t){return t.testId?{mode:"testid",code:`(async () => {
420
- const t = window.__sootsimTest
421
- if (!t) return null
422
- return (await t.findByTestId(${JSON.stringify(t.testId)})) || (await t.findById(${JSON.stringify(t.testId)}))
423
- })()`}:t.role?{mode:"role",code:`(async () => {
424
- const t = window.__sootsimTest
425
- if (!t) return []
426
- return await t.queryAll({ hasRole: ${JSON.stringify(t.role)}, pruneHidden: true })
427
- })()`}:t.type?{mode:"type",code:`(async () => {
428
- const t = window.__sootsimTest
429
- if (!t) return []
430
- return await t.queryAll({ type: ${JSON.stringify(t.type)}, pruneHidden: true })
431
- })()`}:t.pressable?{mode:"pressable",code:`(async () => {
432
- const t = window.__sootsimTest
433
- if (!t) return []
434
- ${R}
435
- const inspectable = await fromInspectable()
436
- if (inspectable) return inspectable.filter(n => n.pressable && isVisibleTarget(n))
437
- const all = await t.queryAll({ pruneHidden: true })
438
- return all.filter(n => n.pressable && isVisibleTarget(n))
439
- })()`}:t.interactive?{mode:"interactive-targets",code:`(async () => {
440
- const t = window.__sootsimTest
441
- if (!t) return []
442
- ${R}
443
- const inspectable = await fromInspectable()
444
- if (inspectable) {
445
- return inspectable.filter(n => n.pressable && isVisibleTarget(n))
446
- }
447
- const all = await t.queryAll({ pruneHidden: true })
448
- return all.filter(n => n.pressable && isVisibleTarget(n))
449
- })()`}:t.visible?{mode:"visible",code:`(async () => {
450
- const t = window.__sootsimTest
451
- if (!t) return []
452
- const all = await t.queryAll({ pruneHidden: true })
453
- return all.filter(n => n.layout && n.layout.width > 0 && n.layout.height > 0)
454
- })()`}:t.text?{mode:"text",code:`(async () => {
455
- const t = window.__sootsimTest
456
- if (!t) return null
457
- return await t.findByText(${JSON.stringify(t.text)})
458
- })()`}:null}async function ie(t,e){let r=O(e);if(!r)return null;let n=await t.send({type:"evaluate",code:r.code});return{mode:r.mode,result:n}}function le(t){return[...t].sort((e,r)=>$(r)-$(e))}function $(t){let e=0;t.testID&&(e+=100),typeof t.text=="string"&&t.text.trim().length>0&&(e+=60),typeof t.accessibilityLabel=="string"&&t.accessibilityLabel.trim().length>0&&(e+=30),t.accessibilityRole&&(e+=15);let r=t.layout?.width??0,n=t.layout?.height??0,o=r*n;return o>=400&&o<=6e4?e+=25:o>6e4&&(e-=20),(t.absolutePosition?.y??0)<0&&(e-=30),e}function ue(t){if(t.testID)return`rnx do tap-id ${_(t.testID)}`;let e=typeof t.text=="string"?t.text.trim():"";if(e.length>0&&e.length<=80)return`rnx do tap-text ${_(e)}`;let r=Math.round(((t.absolutePosition?.x??0)+(t.layout?.width??0)/2)*10)/10,n=Math.round(((t.absolutePosition?.y??0)+(t.layout?.height??0)/2)*10)/10;return`rnx do tap ${r} ${n}`}function _(t){return/^[A-Za-z0-9_./@:-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}var F=`(async () => {
459
- const t = window.__sootsimTest
460
- let nodes = 0
461
- try { nodes = (await t?.getNodeCount?.()) || 0 } catch {}
462
- let targets = 0
463
- let liveFrameActive = false
464
- let liveFrameChannels = 0
465
- let liveFramePublishes = 0
466
- let loadingText = ''
467
- const cleanText = (value) =>
468
- typeof value === 'string' ? value.replace(/\\s+/g, ' ').trim() : ''
469
- const loadingSignal = (value) => {
470
- const text = cleanText(value)
471
- if (!text) return ''
472
- return /^(opening app\\b|looking for your app\\b|building bundle\\b|preparing rnx runtime\\b|loading native bundle\\b|loading rnx stubs\\b|loading bundle loader\\b|loading native stubs\\b|loading compat bridge\\b|loading react-native shim\\b|loading react bridge\\b|loading reconciler\\b|loading replacement modules\\b|injecting rnx modules\\b|warming sqlite engine\\b|capturing root component\\b|reloading app\\b|loading(?:[.!\u2026]*)?$|connecting(?:[.!\u2026]*)?$)/i.test(text)
473
- ? text
474
- : ''
475
- }
476
- try {
477
- const loading = window.__sootsimConnectRNLoading
478
- if (loading && loading.active === true) {
479
- loadingText = [loading.title, loading.detail].map(cleanText).filter(Boolean).join(' ')
480
- }
481
- } catch {}
482
- try {
483
- if (typeof t?.listInspectable === 'function') {
484
- const list = await t.listInspectable({})
485
- if (Array.isArray(list)) {
486
- const screenW = window.innerWidth || 0
487
- const screenH = window.innerHeight || 0
488
- const isVisible = (n) => {
489
- const layout = n?.layout
490
- if (!layout || layout.width <= 0 || layout.height <= 0) return false
491
- const abs = n?.absolutePosition || n?.absolute
492
- if (!abs) return true
493
- const device = n?.device || {}
494
- const w = Number(device.width) || screenW
495
- const h = Number(device.height) || screenH
496
- return (
497
- abs.x + layout.width > 0 &&
498
- abs.y + layout.height > 0 &&
499
- abs.x < w &&
500
- abs.y < h
501
- )
502
- }
503
- const hasContentSignal = (n) => {
504
- const role = n?.accessibilityRole || n?.role
505
- const label = cleanText(n?.accessibilityLabel || n?.label)
506
- const handlers = Array.isArray(n?.handlers) ? n.handlers : []
507
- const text = cleanText(n?.text)
508
- const testID = cleanText(n?.testID || n?.testId)
509
- const loading = loadingSignal(text) || loadingSignal(label) || loadingSignal(testID)
510
- if (!loadingText && loading) {
511
- loadingText = loading
512
- }
513
- if (handlers.length > 0) return true
514
- if (role) return true
515
- if (n?.isTextInput) return true
516
- if (text) return true
517
- if (label) return true
518
- if (testID && !/^splash|loading/i.test(testID)) return true
519
- return false
520
- }
521
- targets = list.filter(n => isVisible(n) && hasContentSignal(n)).length
522
- }
523
- }
524
- } catch {}
525
- try {
526
- const stats = await t?.getImageLoaderStats?.()
527
- const presentation = stats?.liveFramePresentation
528
- liveFrameChannels = Number(presentation?.activeChannels) || 0
529
- liveFramePublishes = Number(presentation?.publishes) || 0
530
- const previous = window.__sootsimWaitReadyLiveFramePublishes
531
- liveFrameActive =
532
- liveFrameChannels > 0 &&
533
- typeof previous === 'number' &&
534
- liveFramePublishes > previous
535
- window.__sootsimWaitReadyLiveFramePublishes = liveFramePublishes
536
- } catch {}
537
- let externalReady = null
538
- let externalStatus = ''
539
- let externalError = ''
540
- let suppressedEntryError = ''
541
- try {
542
- const getExternalAppState = t?.getExternalAppState
543
- const external = typeof getExternalAppState === 'function'
544
- ? await Promise.race([
545
- getExternalAppState(),
546
- new Promise((resolve) => setTimeout(
547
- () => resolve({
548
- state: {
549
- ready: false,
550
- loading: true,
551
- status: 'waiting for tenant worker...',
552
- },
553
- }),
554
- 1000,
555
- )),
556
- ])
557
- : null
558
- const state = external?.state
559
- if (state && typeof state === 'object') {
560
- externalReady = state.ready === true
561
- if (typeof state.status === 'string') externalStatus = state.status
562
- if (typeof state.error === 'string') externalError = state.error
563
- }
564
- if (!externalError && Array.isArray(external?.entryErrors)) {
565
- // suppressed-and-continued entry errors (bundle-loader's patched __r
566
- // swallows entry throws and moves on) must NOT gate readiness \u2014 the
567
- // app frequently runs fine after one (e.g. metro's "Unknown named
568
- // module" probing noise). they surface separately as a diagnostic
569
- // for the timeout path.
570
- const isReal = (item) => item && typeof item.message === 'string' && item.message.trim()
571
- const fatal = external.entryErrors.find((item) => isReal(item) && item.suppressed !== true)
572
- if (fatal) externalError = fatal.message
573
- const suppressed = external.entryErrors.find((item) => isReal(item) && item.suppressed === true)
574
- if (suppressed) suppressedEntryError = suppressed.message
575
- }
576
- // once the app has errored its last status ("injecting sootsim
577
- // modules...") is stale \u2014 reporting it makes a dead app read as one that
578
- // is still booting.
579
- if (externalError) loadingText = ''
580
- else if (externalReady === false && externalStatus) loadingText = externalStatus
581
- } catch {}
582
- let errors = 0
583
- try { errors = window.__sootsimConsole?.count?.()?.errors ?? 0 } catch {}
584
- return {
585
- flag: (window).__sootsimExternalAppReady,
586
- at: (window).__sootsimExternalAppReadyAt || 0,
587
- nodes,
588
- targets,
589
- liveFrameActive,
590
- liveFrameChannels,
591
- liveFramePublishes,
592
- errors,
593
- loadingText,
594
- externalReady,
595
- externalStatus,
596
- externalError,
597
- suppressedEntryError,
598
- }
599
- })()`,W=100,H=750,B=2e3,z=150;function j(t){return t.liveFrameActive||t.targets>0||t.nodes>=W}function J(t){return t.liveFrameActive||t.targets>0}function ce(t){if(t.bridgeError)return`sim unreachable: ${t.bridgeError} \u2014 the target tab is closed or no sim is connected (check \`rnx list\`, reopen with \`rnx open\`)`;let e=t.externalError?`guest app errored: ${t.externalError}`:t.loadingText?`still showing "${t.loadingText}"`:t.externalReady===!1?"guest app is still loading":t.flag!==!0&&t.targets>0?"native content is rendered but the ready signal has not settled":t.flag!==!0?"guest app has not emitted sootsim:externalAppReady":t.targets<=0?"ready flag emitted but no visible app content is inspectable yet":"node tree is still changing";return!t.externalError&&t.suppressedEntryError?`${e} (suppressed entry error: ${t.suppressedEntryError})`:e}async function de(t,e=2e4,r={}){let n=Date.now(),o=n+e,s=r.progressIntervalMs??B,i=n+s,d=-1,p=n,g="",a={flag:void 0,at:0,nodes:0,targets:0,liveFrameActive:!1,liveFrameChannels:0,liveFramePublishes:0,errors:0,loadingText:"",externalReady:null,externalStatus:"",externalError:"",suppressedEntryError:""};for(;Date.now()<o;){try{a=await t.send({type:"evaluate",code:F})??a,g=""}catch(m){if(g=m instanceof Error?m.message:String(m),g.startsWith("multiple sims are connected:")||g.startsWith("saved sim "))throw m}let y=Date.now(),b={ready:!1,elapsedMs:y-n,nodes:a.nodes,targets:a.targets,liveFrameActive:a.liveFrameActive,liveFrameChannels:a.liveFrameChannels,liveFramePublishes:a.liveFramePublishes,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:g};a.nodes!==d&&(d=a.nodes,p=y);let x=a.flag===!0&&j(a),f=a.flag!==!0&&J(a);if((x||f)&&a.externalReady!==!1&&!a.externalError&&!a.loadingText&&y-p>=H)return{...b,ready:!0};if(a.externalError)return b;if(r.onProgress&&s>0&&y>=i){r.onProgress(b);do i+=s;while(y>=i)}await new Promise(m=>setTimeout(m,z))}let h={ready:!1,elapsedMs:Date.now()-n,nodes:a.nodes,targets:a.targets,liveFrameActive:a.liveFrameActive,liveFrameChannels:a.liveFrameChannels,liveFramePublishes:a.liveFramePublishes,flag:a.flag,loadingText:a.loadingText,externalReady:a.externalReady,externalStatus:a.externalStatus,externalError:a.externalError,suppressedEntryError:a.suppressedEntryError,errors:a.errors,bridgeError:g};return r.onProgress&&s>0&&Date.now()>=i&&r.onProgress(h),h}async function pe(t,e,r=5e3,n={}){let o=n.gone===!0;return await t.send({type:"evaluate",code:`(async () => {
600
- const start = Date.now()
601
- const deadline = start + ${r}
602
- const gone = ${o}
603
- const ID = ${JSON.stringify(e)}
604
- const present = (node) => !!(node && node.layout && node.layout.width > 0 && node.layout.height > 0)
605
- const find = async () => {
606
- const t = window.__sootsimTest
607
- if (!t) return undefined // bridge not ready \u2014 indeterminate, not "gone"
608
- try {
609
- // gone-mode confirms a gate/screen LEFT \u2014 it only needs structural
610
- // existence + layout, NOT the full-tree occlusion pass (pruneHidden).
611
- // that pass (computeOccludedInspectNodeIds) walks the whole tree and
612
- // does O(n\xB2)-ish rect-occlusion testing EVERY poll; on a large
613
- // post-login app tree it costs seconds per poll, so --gone can never
614
- // get two clean "absent" polls inside budget and falsely reports the
615
- // gate as still blocked \u2014 the root cause of the 3pc PR-preview outage.
616
- // presence-mode keeps pruneHidden so "appeared" still means
617
- // visibly-reachable. a departed gate is unmounted or zero-sized, so the
618
- // cheap structural+layout check is correct here and ~O(n) cheap.
619
- const matches = await t.queryAll?.(gone ? { hasId: ID } : { hasId: ID, pruneHidden: true })
620
- if (!Array.isArray(matches)) return undefined
621
- return matches.find(present) || null
622
- } catch {
623
- return undefined
624
- }
625
- }
626
- let goneStreak = 0
627
- while (Date.now() < deadline) {
628
- const node = await find()
629
- if (gone) {
630
- if (node === null) {
631
- goneStreak += 1
632
- if (goneStreak >= 2) return { found: true, elapsed: Date.now() - start }
633
- } else {
634
- goneStreak = 0
635
- }
636
- } else if (present(node)) {
637
- return { found: true, node, elapsed: Date.now() - start }
638
- }
639
- await new Promise((r) => setTimeout(r, 80))
640
- }
641
- return { found: false, elapsed: Date.now() - start }
642
- })()`},{timeoutMs:r+1e3})??{found:!1,elapsed:r}}function L(t,e){return`(() => {
643
- const out = []
644
- const seen = new Set()
645
- const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
646
- const key = (ts, args) => Math.round((ts || 0) / 250) + '|' + (Array.isArray(args) ? args.map(norm).join(' ') : norm(args))
647
- const push = (e) => {
648
- if (!e) return
649
- const ts = typeof e.timestamp === 'number' ? e.timestamp : (typeof e.ts === 'number' ? e.ts : 0)
650
- const k = key(ts, e.args)
651
- if (seen.has(k)) return
652
- seen.add(k)
653
- out.push({ timestamp: ts, args: Array.isArray(e.args) ? e.args : [e.args], stack: e.stack || undefined, source: e.source || undefined })
654
- }
655
- // page-realm ws-bridge buffer first (richest stacks for page-origin errors)
656
- try { for (const e of (window.__sootsimConsole?.${t==="error"?"getErrors":"getWarnings"}(${e}) || [])) push(e) } catch {}
657
- // engine observability store \u2014 the always-on render-worker / forwarded path
658
- try {
659
- const obs = window.__sootsimObservability
660
- const snap = obs && obs.logs && typeof obs.logs.getSnapshot === 'function' ? obs.logs.getSnapshot() : []
661
- for (const e of snap) if (e && e.level === ${JSON.stringify(t)}) push(e)
662
- } catch {}
663
- return out.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)).slice(-${e})
664
- })()`}async function ye(t,e=20){let r=await t.send({type:"evaluate",code:L("error",e)});return Array.isArray(r)?r:[]}async function me(t,e=20){let r=await t.send({type:"evaluate",code:L("warn",e)});return Array.isArray(r)?r:[]}var ge=`(() => {
665
- const norm = (s) => (typeof s === 'string' ? s : (() => { try { return JSON.stringify(s) } catch { return String(s) } })())
666
- const key = (lvl, ts, args) => lvl + '|' + Math.round((ts || 0) / 250) + '|' + (Array.isArray(args) ? args.map(norm).join(' ') : norm(args))
667
- const seen = new Set()
668
- let errors = 0
669
- let warnings = 0
670
- const add = (lvl, ts, args) => {
671
- if (lvl !== 'error' && lvl !== 'warn') return
672
- const k = key(lvl, ts, args)
673
- if (seen.has(k)) return
674
- seen.add(k)
675
- if (lvl === 'error') errors++
676
- else warnings++
677
- }
678
- try {
679
- const c = window.__sootsimConsole
680
- for (const e of (c?.getErrors?.(200) || [])) add('error', e?.timestamp ?? e?.ts, e?.args)
681
- for (const e of (c?.getWarnings?.(200) || [])) add('warn', e?.timestamp ?? e?.ts, e?.args)
682
- } catch {}
683
- try {
684
- const obs = window.__sootsimObservability
685
- const snap = obs && obs.logs && typeof obs.logs.getSnapshot === 'function' ? obs.logs.getSnapshot() : []
686
- for (const e of snap) if (e) add(e.level, e.ts, e.args)
687
- } catch {}
688
- return { errors, warnings, total: errors + warnings }
689
- })()`;async function be(t){await t.send({type:"evaluate",code:'window.__sootsimConsole?.clear(); window.__sootsimObservability?.logs?.clear?.(); "cleared"'})}async function fe(t,e={}){let r=e.limit??20,n=e.failed===!1?"getRequests":"getFailedRequests",o=await t.send({type:"call",path:`__sootsimTest.${n}`,args:[r]});return Array.isArray(o)?o:[]}async function he(t){await t.send({type:"call",path:"__sootsimTest.clearRequests",args:[]})}async function xe(t){let e=await t.send({type:"evaluate",code:`(() => {
690
- const obs = window.__sootsimObservability;
691
- if (!obs) return { ok: false };
692
- return { ok: true, entries: obs.logs.getSnapshot() };
693
- })()`});return!e||!e.ok?[]:e.entries??[]}async function we(t){await t.send({type:"evaluate",code:'window.__sootsimObservability?.logs.clear(); "cleared"'})}function K(t,e){if(t.source===e.source||t.level!==e.level||Math.abs(t.ts-e.ts)>1e3||t.args.length!==e.args.length)return!1;let r=new Set([t.source,e.source]);return!r.has("sootsim-worker")||!r.has("render-worker")&&!r.has("forwarded-render-worker")?!1:t.args.every((n,o)=>n===e.args[o])}function Se(t,e={}){let r=[];for(let n of t)r.some(o=>K(o,n))||r.push(n);if(e.showInternal||(r=r.filter(n=>{let o=n.args[0];return!(typeof o=="string"&&o.startsWith("[rnx]"))})),e.level&&(r=r.filter(n=>e.level.has(n.level))),e.filter){let n=e.filter.toLowerCase();r=r.filter(o=>o.args.join(" ").toLowerCase().includes(n))}return r}async function ve(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.summary",args:[e]})}async function V(t,e){return await t.send({type:"call",path:"SootSim.bridges.timeline.recent",args:[e]})}async function Ie(t){let e;try{e=(await V(t,{kinds:["alert","actionsheet"],limit:80})).events}catch{return[]}let r=new Map;for(let s of e)r.set(s.kind,s);let n=[],o=(s,i)=>{let d=r.get(s);if(!d||!d.data||typeof d.data!="object")return;let p=d.data;p.phase==="show"&&n.push({label:i,title:typeof p.title=="string"?p.title:null})};return o("alert","Alert"),o("actionsheet","ActionSheet"),n}async function Te(t,e,r){await t.send({type:"call",path:"SootSim.bridges.timeline.cursorAdvance",args:[e,r]})}async function ke(t){return await t.send({type:"evaluate",code:`(() => {
694
- const kb = window.__sootsimKeyboard
695
- if (!kb || typeof kb.getLayout !== 'function') {
696
- return { error: 'keyboard bridge getLayout() not available' }
697
- }
698
- return kb.getLayout()
699
- })()`})??{error:"keyboard bridge returned no result"}}function q(t){let e=t instanceof Error?t.message:String(t);return e.includes("call target not found: SootSim.bridges.mainShell")||e.includes("test bridge unavailable before app-in-worker boot")}async function Y(t,e=0){let r=Date.now()+Math.max(0,e);for(;;)try{return await t.send({type:"call",path:"SootSim.bridges.mainShell.getState",args:[]})}catch(n){if(!q(n)||Date.now()>=r)throw n;await new Promise(o=>setTimeout(o,50))}}async function Ee(t){let e=await t.send({type:"evaluate",code:`(async () => {
700
- const test = window.__sootsimTest
701
- const kb = window.__sootsimKeyboard
702
- const navSnap =
703
- test && typeof test.getNavigationSnapshot === 'function'
704
- ? await test.getNavigationSnapshot()
705
- : null
706
- const route =
707
- test && typeof test.getRouteInfo === 'function'
708
- ? await test.getRouteInfo()
709
- : null
710
- const keyboard =
711
- kb && typeof kb.getLayout === 'function'
712
- ? (() => {
713
- const layout = kb.getLayout()
714
- return layout ? {
715
- visible: layout.visible,
716
- mode: layout.mode,
717
- spec: layout.spec
718
- ? {
719
- keyboardType: layout.spec.keyboardType,
720
- returnKeyType: layout.spec.returnKeyType,
721
- }
722
- : null,
723
- } : null
724
- })()
725
- : null
726
- return { nav: navSnap, route, keyboard }
727
- })()`});return{shell:await Y(t,500).catch(()=>null),nav:e?.nav??null,route:e?.route??null,keyboard:e?.keyboard??null}}async function Re(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.status()"})}async function $e(t){return t.send({type:"evaluate",code:"window.__sootsimDebug.flags()"})}async function _e(t,e){return t.send({type:"evaluate",code:`window.__sootsimTest.debugFind(${JSON.stringify(e)})`})}async function Ae(t,e,r=50){let n=e&&e!=="all"?`window.__sootsimDebug.recent(${JSON.stringify(e)}, ${r})`:`window.__sootsimDebug.recent(undefined, ${r})`;return t.send({type:"evaluate",code:n})}async function Le(t,e,r){let n=r.length>0?r.map(o=>JSON.stringify(o)).join(", "):e==="disable"?"'all'":"";return t.send({type:"evaluate",code:`window.__sootsimDebug.${e}(${n})`})}async function Pe(t){return await t.send({type:"evaluate",code:`(async () => {
728
- const host = window.__sootsimRenderHost
729
- const stats = host?.queryStats ? await host.queryStats() : null
730
- const shellRaw = window.__sootsimShellMemory
731
- ? await window.__sootsimShellMemory()
732
- : null
733
- const shell = shellRaw && !shellRaw.error ? shellRaw : null
734
- // the compositor paints home + app:one + app:two, so every app-surface
735
- // picture and raster image is counted here and nowhere else.
736
- let compositor = null
737
- try {
738
- const cs = await window.__sootsimCompositor?.getStats?.(false, true)
739
- compositor = cs?.memory ?? null
740
- } catch {}
741
- const normalize = (m) =>
742
- m
743
- ? {
744
- nodesRegistered: m.nodesRegistered ?? null,
745
- nodesDetached: m.nodesDetached ?? null,
746
- detachedTypes: m.detachedTypes ?? null,
747
- objects: m.objects ?? null,
748
- activeNativeAnimations: m.activeNativeAnimations ?? null,
749
- imageLoader: m.imageLoader ?? null,
750
- workerHeap: m.workerHeap ?? null,
751
- wasmHeapBytes: m.wasmHeapBytes ?? null,
752
- }
753
- : null
754
- const hostMem = performance.memory
755
- ? {
756
- usedJSHeapSize: performance.memory.usedJSHeapSize,
757
- totalJSHeapSize: performance.memory.totalJSHeapSize,
758
- jsHeapSizeLimit: performance.memory.jsHeapSizeLimit,
759
- }
760
- : null
761
- return {
762
- tenant: normalize(stats?.memory),
763
- shell: normalize(shell),
764
- compositor: normalize(compositor),
765
- hostHeap: hostMem,
766
- }
767
- })()`})??{tenant:null,shell:null,compositor:null,hostHeap:null}}function Ne(t){if(t.total===0)return"nothing recorded";let e=[],r=["error","warning","console","fetch","toast","alert","actionsheet","picker","notification","screen","route","keyboard","app-launch","shell","scroll","gesture","text-input","react-commit","animation","reanimated"],n=new Set;for(let o of r){let s=t.byKind[o];s&&(e.push(`${s} ${o}${s===1?"":"s"}`),n.add(o))}for(let[o,s]of Object.entries(t.byKind))!n.has(o)&&s&&e.push(`${s} ${o}${s===1?"":"s"}`);return e.join(" \xB7 ")}var Me=new Set(["react-commit","layout","scroll"]);function U(t,e){if(e===null)return new Date(t).toLocaleTimeString();let r=(t-e)/1e3;return`${r>=0?"+":""}${r.toFixed(2)}s`}function G(t,e){switch(t){case"app-launch":return e.phase==="launch"?`launch ${e.appName??e.toAppId??""}`:`dismiss ${e.appName??e.fromAppId??""} \u2192 ${e.toAppId??""}`;case"toast":return`"${e.text??""}"${e.durationMs?` (${e.durationMs}ms)`:""}`;case"keyboard":return`${e.phase??"?"}${e.heightPx?` h=${e.heightPx}`:""}${e.mode?` ${e.mode}`:""}`;case"screen":return`${e.phase??"?"} ${e.name??e.activeName??""}`;case"flow-step":return`${e.status??"?"} ${e.stepName??"step"}${e.durationMs?` ${e.durationMs}ms`:""}`;case"route":return`${e.phase??"?"} ${e.path??e.pathname??""}`;case"alert":case"actionsheet":case"picker":return`${e.phase??"?"} ${e.title??e.message??""}`;case"notification":return`${e.title??""}${e.body?` \u2014 ${e.body}`:""}`;case"fetch":return`${e.method??"GET"} ${e.url??""}${e.status?` -> ${e.status}`:""}`;case"console":case"console-log":return`${e.level??"log"}: ${(e.message??"").toString().slice(0,120)}`;case"shell":return`${e.event??e.type??e.phase??""}`;case"scroll":return`${e.phase??"?"} ${e.target??""}`;case"gesture":return`${e.phase??"?"} ${e.type??""}`;case"text-input":return`${e.phase??"?"}${e.value!==void 0?` "${String(e.value).slice(0,40)}"`:""}`;case"layout":return`${e.kind??"?"} ${e.testID??e.type??""}${e.skipped?` skipped:${e.reason??"unknown"}`:""}`;case"react-commit":{let r=e.slowest;return`${e.fiberCount??"?"} fibers ${e.durationMs??"?"}ms${r?.displayName?` \xB7 ${r.displayName} ${r.durationMs??"?"}ms`:""}`}case"frame":return`${e.totalMs??"?"}ms${e.renderMs?` \xB7 render ${e.renderMs}ms`:""}${e.layoutMs?` \xB7 layout ${e.layoutMs}ms`:""}${e.copyMs?` \xB7 copy ${e.copyMs}ms`:""}`;case"reanimated":case"animation":return`${e.kind??""} ${e.target??""}${e.durationMs?` ${e.durationMs}ms`:""}`}return""}function De(t,e){let r=U(t.t,e).padStart(8),n=t.context.padEnd(6),o=`[${t.kind}]`.padEnd(15),s=t.data,i=s&&typeof s=="object"?G(t.kind,s):"";return` ${r} ${n} ${o} ${i}`}export{Q as a,X as b,Z as c,ee as d,te as e,ne as f,oe as g,se as h,ae as i,ie as j,le as k,ue as l,F as m,H as n,z as o,j as p,J as q,ce as r,de as s,pe as t,ye as u,me as v,ge as w,be as x,fe as y,he as z,xe as A,we as B,Se as C,ve as D,V as E,Ie as F,Te as G,ke as H,q as I,Y as J,Ee as K,Re as L,$e as M,_e as N,Ae as O,Le as P,Pe as Q,Ne as R,Me as S,De as T};