agent-device 0.21.22 → 0.21.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.apk → agent-device-android-ime-helper-0.21.24.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.24.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.22.manifest.json → agent-device-android-ime-helper-0.21.24.manifest.json} +4 -4
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.24.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.22.manifest.json → agent-device-android-snapshot-helper-0.21.24.manifest.json} +6 -6
- package/apple/macos-helper/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +12 -6
- package/apple/macos-helper/Tests/AgentDeviceMacOSHelperTests/RectResponseTests.swift +21 -0
- package/apple/snapshot-bridge/README.md +9 -7
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +56 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +14 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +8 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +12 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCaptureTarget.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotExecution.swift +29 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +34 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryFocus.swift +19 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +3 -3
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb.js +1 -1
- package/dist/src/agent-browser-lifecycle.js +1 -1
- package/dist/src/agent-browser-process-record.js +1 -1
- package/dist/src/agent-browser-provider.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/alert.js +1 -1
- package/dist/src/android-adb.d.ts +3 -2
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-backend.js +1 -1
- package/dist/src/app-inventory.d.ts +4 -0
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime2.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/app-state-runtime.d.ts +15 -0
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/aws-device-farm-connection.js +1 -0
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/browserstack-connection.js +1 -0
- package/dist/src/browserstack-device-features.js +1 -0
- package/dist/src/browserstack.js +1 -0
- package/dist/src/cache.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +35 -19
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +3 -4
- package/dist/src/client-companion-tunnel.js +1 -0
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-options.js +3 -3
- package/dist/src/client-types.d.ts +7 -5
- package/dist/src/cloud-artifacts.d.ts +9 -2
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +1 -1
- package/dist/src/command-tools.js +2 -2
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection-verification.js +1 -0
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -1
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -1
- package/dist/src/daemon-http.js +1 -1
- package/dist/src/daemon-policy-file.js +1 -1
- package/dist/src/daemon-registration-owner.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.d.ts +2 -15
- package/dist/src/device-readiness-runtime.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +3 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/device3.js +1 -1
- package/dist/src/dispatch-resolve.js +3 -3
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/durable-capture-resource.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/exec.js +1 -1
- package/dist/src/file.js +1 -1
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/format.js +2 -1
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan-types.d.ts +2 -5
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/human-control.js +1 -1
- package/dist/src/ime-rebind.js +1 -0
- package/dist/src/ime-settings-record.js +1 -0
- package/dist/src/ime-state.js +1 -0
- package/dist/src/index.d.ts +3 -3
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/instance-client.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor.js +5 -5
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/ios-client.js +4 -4
- package/dist/src/ios-snapshot-acquisition.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/launch-confirmation.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +4 -555
- package/dist/src/load.js +1 -1
- package/dist/src/local-interactor-operation-set.js +1 -1
- package/dist/src/log-stream.js +33 -0
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/manifest.js +1 -0
- package/dist/src/mechanics.js +16 -16
- package/dist/src/mobile-snapshot-semantics.js +1 -1
- package/dist/src/node-http.js +1 -0
- package/dist/src/observation.js +1 -2
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-request-scope.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
- package/dist/src/platform-runtime-screen-recording-process-host.js +1 -1
- package/dist/src/platform-runtime-unavailable.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/platform-runtime2.js +1 -1
- package/dist/src/plugin.js +1 -0
- package/dist/src/plugins/webdriver.d.ts +111 -0
- package/dist/src/plugins/webdriver.js +1 -0
- package/dist/src/plugins.d.ts +2 -1
- package/dist/src/plugins2.js +1 -1
- package/dist/src/process-exit.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-credential-fingerprint.js +1 -1
- package/dist/src/provider-device-admission.js +1 -1
- package/dist/src/provider-device-runtime.d.ts +556 -0
- package/dist/src/provider-policy.js +1 -0
- package/dist/src/provider-profile-fields.js +1 -1
- package/dist/src/provider-webdriver.js +1 -2
- package/dist/src/providers.js +1 -1
- package/dist/src/proxy.js +2 -2
- package/dist/src/react-devtools.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/registry.js +24 -24
- package/dist/src/remote-bridge.js +1 -0
- package/dist/src/remote-config-core.js +1 -0
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/remote-connection-state.js +1 -0
- package/dist/src/replay.js +2 -2
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-runtime-binding.js +1 -1
- package/dist/src/result-serialization.js +1 -1
- package/dist/src/retry.js +1 -1
- package/dist/src/retry2.js +1 -0
- package/dist/src/runner-artifact-manifest.js +1 -1
- package/dist/src/runner-cache-metadata.js +2 -3
- package/dist/src/runner-cache-retention.js +1 -0
- package/dist/src/runner-cache-trim.js +1 -0
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-device-set.js +1 -0
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +1 -1
- package/dist/src/runner-exchange.js +1 -1
- package/dist/src/runner-lease.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -1
- package/dist/src/runner-start-budget.js +1 -1
- package/dist/src/runner-toolchain-probe.js +2 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-deployment.js +1 -0
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +1 -2
- package/dist/src/runtime11.js +2 -0
- package/dist/src/runtime2.js +2 -5
- package/dist/src/runtime3.js +5 -1
- package/dist/src/runtime4.js +1 -5
- package/dist/src/runtime5.js +5 -1
- package/dist/src/runtime6.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/runtime8.js +1 -1
- package/dist/src/runtime9.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-overlay-draw.js +1 -1
- package/dist/src/screenshot3.js +2 -2
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +25 -33
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +4 -0
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +1 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-pipeline-policy.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session2.js +5 -5
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator-state.js +1 -1
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-capture-annotations.js +1 -1
- package/dist/src/snapshot-desktop-projection.js +1 -1
- package/dist/src/snapshot-private-evidence.js +1 -0
- package/dist/src/snapshot-runtime-binding.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-state.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src2.js +1 -1
- package/dist/src/src3.js +1 -1
- package/dist/src/src4.js +1 -1
- package/dist/src/src5.js +1 -1
- package/dist/src/src6.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +20 -20
- package/dist/src/store.js +1 -1
- package/dist/src/target-evidence.js +1 -1
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime2.js +1 -1
- package/dist/src/tree.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/video.js +1 -1
- package/package.json +24 -16
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.22.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.22.apk.sha256 +0 -1
- package/dist/src/capabilities.js +0 -1
- package/dist/src/compatibility-policy.js +0 -1
- package/dist/src/daemon-artifacts.js +0 -1
- package/dist/src/device-claim-rule.js +0 -1
- package/dist/src/human-control-contract.js +0 -1
- package/dist/src/prepare-kind.js +0 -1
- package/dist/src/provider-device-runtimes.js +0 -1
- package/dist/src/screen-recording-admission-ledger.js +0 -1
- package/dist/src/screenshot-runtime.js +0 -1
- package/dist/src/session-routing.js +0 -1
- package/dist/src/session-runtime-admission.js +0 -1
- package/dist/src/session-stream.js +0 -27
- package/dist/src/timeouts.js +0 -1
- package/dist/src/touch-reference-frame.js +0 -1
- package/dist/src/vars.js +0 -2
- package/dist/src/viewport.js +0 -1
package/dist/src/mechanics.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{$ as t,B as n,F as r,J as i,P as a,b as o,rt as s,tt as c,v as l,z as u}from"./sdk-contracts.js";import"./capture.js";import{k as d,p as f}from"./sdk-batch-runner.js";import{
|
|
2
|
-
`).map(e=>e.trim()).filter(Boolean)}const
|
|
3
|
-
`):void 0}function Tn(e,t){let n=t[0];if(!n)return;let r=En(e,n.index);for(let n of t.slice(1)){let t=new Set(En(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r.at(-1)}function En(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function Dn(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function On(e){let t=e.bundleId??``;return tn.has(t)||sn.test(e.identifier??``)}function kn(e){let t=e.bundleId??``;return rn.has(t)&&cn.test(O(e))}function An(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||on.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function O(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function jn(e){return e.find(e=>e.bundleId)?.bundleId}function Mn(e,t,n){if(typeof e!=`number`||!Number.isInteger(e))throw new a(`INVALID_ARGS`,`Android ${n} manifest ${t} must be an integer.`);return e}function k(e,t,n,r){if(e!==n)throw new a(`INVALID_ARGS`,`Android ${r} manifest ${t} must be "${n}".`);return n}function Nn(e,t,n){if(typeof e!=`string`||e.length===0)throw new a(`INVALID_ARGS`,`Android ${n} manifest ${t} is required.`);return e}function Pn(e,t){let n=Nn(e,`sha256`,t).trim().toLowerCase();if(n.length!==64||!/^[0-9a-f]+$/.test(n))throw new a(`INVALID_ARGS`,`Android ${t} manifest sha256 must be a 64-character hex string.`);return n}function Fn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))In(n,t);return Ln(t),{status:t.status,results:t.results}}function In(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},Bn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){Rn(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},Bn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&zn(t)}function Ln(e){Rn(e),zn(e)}function Rn(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function zn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function Bn(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function A(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function Vn(e){if(e===`true`)return!0;if(e===`false`)return!1}function Hn(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new a(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const Un=1e4;async function Wn(e,t){try{return await Je(e,t)}catch(e){throw st(e)}}async function Gn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,apkPath:a,sha256:o,cache:s,deviceKey:c,installTimeoutMs:l,helperLabel:u}=e,d=`${c}\0${r}\0${i}\0${o}`;if(s.has(d))return{packageName:r,versionCode:i,installedSha256:o,installed:!1,reason:`current`};await Qn(a,o,u);let f=await Kn({adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:o});if(f.reason===`current`)return s.add(d),{packageName:r,versionCode:i,...f,installed:!1};let p=await Wn(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw T(`Failed to install ${u}`,p,{packageName:r,versionCode:i,reason:f.reason});return s.add(d),{packageName:r,versionCode:i,...f,installed:!0}}async function Kn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await Yn(t,r,o);if(s===void 0)return{reason:`missing`};if(s<i)return{installedVersionCode:s,reason:`outdated`};if(s>i)return{installedVersionCode:s,reason:`current`};try{let e=await Xn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function qn(e){let t=b().files,n=Ie(),r=D.join(Le(),`android`,e.helperDirName,`dist`),o=D.join(r,e.manifestFileName(n));try{let n=e.parseManifest(JSON.parse(await t.readText(o))),i=D.join(r,n.assetName);return await t.access(i),{apkPath:i,manifest:n}}catch(t){throw new a(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:i(t).message},t)}}function Jn(e){return async t=>await Gn({adb:t.adb,adbProvider:t.adbProvider,packageName:t.artifact.manifest.packageName,versionCode:t.artifact.manifest.versionCode,apkPath:t.artifact.apkPath,sha256:t.artifact.manifest.sha256,cache:e.cache,deviceKey:t.deviceKey,installTimeoutMs:e.installTimeoutMs,helperLabel:e.helperLabel})}async function Yn(e,t,n){let r=await y(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${er(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Xn(e,t,n,r){let i=await y(e,[`pm`,`path`,n],{allowFailure:!0,timeoutMs:Un,signal:r}),o=Zn(`${i.stdout}\n${i.stderr}`);if(i.exitCode!==0||!o)throw new a(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=b().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=D.join(c,`base.apk`);try{let e=await We(o,l,{provider:t,allowFailure:!0,timeoutMs:Un,signal:r});if(e.exitCode!==0)throw T(`Could not read installed Android helper APK`,e,{packageName:n,remotePath:o});return await $n(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Zn(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function Qn(e,t,n){let r=await $n(e);if(r!==t)throw new a(`COMMAND_FAILED`,`${n} APK checksum mismatch`,{apkPath:e,expectedSha256:t,actualSha256:r})}async function $n(e){let t=b().files;return t.sha256(await t.readBytes(e))}function er(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const tr=`android-snapshot-helper-v1`,nr=`uiautomator-xml`,rr=5e3,ir=3e4;function ar(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new a(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let t=e;return{name:sr(t.name,`name`,`android-snapshot-helper`),version:j(t.version,`version`),releaseTag:lr(t.releaseTag),assetName:lr(t.assetName),apkUrl:ur(t.apkUrl,`apkUrl`),sha256:cr(t.sha256),checksumName:lr(t.checksumName),packageName:j(t.packageName,`packageName`),versionCode:or(t.versionCode,`versionCode`),instrumentationRunner:j(t.instrumentationRunner,`instrumentationRunner`),minSdk:or(t.minSdk,`minSdk`),targetSdk:t.targetSdk===void 0?void 0:or(t.targetSdk,`targetSdk`),outputFormat:sr(t.outputFormat,`outputFormat`,nr),statusProtocol:sr(t.statusProtocol,`statusProtocol`,tr)}}function or(e,t){return Mn(e,t,`snapshot helper`)}function sr(e,t,n){return k(e,t,n,`snapshot helper`)}function cr(e){let t=j(e,`sha256`).trim().toLowerCase();if(t.length!==64||!dr(t))throw new a(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return t}function j(e,t){if(typeof e!=`string`||e.trim().length===0)throw new a(`INVALID_ARGS`,`Android snapshot helper manifest ${t} is required.`);return e}function lr(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function ur(e,t){return e===null?null:j(e,t)}function dr(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}const M=new Map;function fr(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of M.keys())e.startsWith(t)&&vr(e)}const pr=`android-snapshot-helper-not-current`;function mr(e){return r(e).details?.reason===pr}function hr(){M.clear()}function gr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function _r(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of M.keys())t!==e&&t.startsWith(i)&&M.delete(t);M.set(e,t)}function vr(e){e&&M.delete(e)}async function yr(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,o=n.manifest.versionCode,s=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:o,installed:!1,reason:`skipped`};let c=gr(e.deviceKey,i,o,s),l=c?M.get(c):void 0;if(c&&r!==`always`&&l!==void 0)return{packageName:i,versionCode:o,installedVersionCode:l,installedSha256:s,installed:!1,reason:`current`};await Qn(n.apkPath,s,`Android snapshot helper`);let u=r===`always`?{installedVersionCode:await Sr(t,i,e.timeoutMs,e.signal),reason:`forced`}:await Kn({adb:t,adbProvider:xr(e.adbProvider,t),packageName:i,versionCode:o,sha256:s,signal:e.signal}),{installedVersionCode:d}=u,f=`installedSha256`in u?u.installedSha256:void 0,p=u.reason;if(p===`current`){if(d===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return _r(c,d),{packageName:i,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}if(r===`current-only`)throw new a(`COMMAND_FAILED`,`Android snapshot helper is not installed at the current version`,{reason:pr,packageName:i,versionCode:o,installedVersionCode:d});let m;try{m=await Cr(t,e.adbProvider??t,n.apkPath,{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw vr(c),br(e,{packageName:i,versionCode:o})}if(m.exitCode!==0)throw vr(c),br(T(`Failed to install Android snapshot helper`,m,{packageName:i,versionCode:o}));return _r(c,o),{packageName:i,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function br(e,t){let n=r(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function xr(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function Sr(e,t,n,r){let i=await y(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return wr(`${i.stdout}\n${i.stderr}`,t)}async function Cr(e,t,n,r){let i=async()=>await Wn(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!Tr(a))return a;let o=await e([`uninstall`,r.packageName],{allowFailure:!0,timeoutMs:r.timeoutMs,signal:r.signal}),s=await i();return s.exitCode===0?s:{...s,stderr:[s.stderr,o.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${o.stderr}`:``].filter(Boolean).join(`
|
|
4
|
-
`)}}function wr(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function Tr(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Er(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function Dr(e){return e===137?`accessibility-timeout`:void 0}function Or(e){return e?{androidCaptureFailureReason:e}:{}}function N(e,t,n,r){if(r instanceof a){let i=r.details??{};return new a(r.code,r.message,{...i,action:e,package:n,tool:t,hint:typeof i.hint==`string`?i.hint:jr(t,i)},r)}return new a(`COMMAND_FAILED`,`Failed to ${e} Android ${t} for ${n}`,{action:e,package:n,tool:t,hint:kr(t)},r)}function kr(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function Ar(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function jr(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Mr(n):Pr(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:kr(e)}function Mr(e){return Nr(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:kr(`simpleperf`)}function Nr(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function Pr(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const Fr=`adb-shell-simpleperf`,Ir=`adb-shell-perfetto`,Lr=15e3,P=3e4,Rr=`/data/local/tmp`;async function zr(e,t){try{let n=await y(e,[`pidof`,t],{allowFailure:!0,timeoutMs:Lr}),r=Vr(n.stdout);if(n.exitCode===0&&r)return r}catch{}throw new a(`COMMAND_FAILED`,`No active Android app process found for ${t}`,{package:t,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Br(e,t,n){let r=await y(e,[C(`command -v ${w(t)} || which ${w(t)}`)],{allowFailure:!0,timeoutMs:Lr});if(!(r.exitCode===0&&r.stdout.trim()))throw new a(`UNSUPPORTED_OPERATION`,`Android device does not expose ${t}`,{package:n,tool:t,hint:Ar(t)})}function Vr(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const Hr=2e3,Ur=`android_snapshot_helper_runtime_occupied`,F=new Map;function Wr(e){return`${e.platform}:${e.id}`}async function Gr(e){await ii({adb:e.adb,packageName:e.packageName}),await qr({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function Kr(e){let t=F.get(e.deviceKey);if(!t)return;await ii({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await Xr({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await _(250),n=await Xr({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw Yr({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&F.delete(e.deviceKey)}async function qr(e){let t=e.release??await Xr({adb:e.adb,packageName:e.packageName});if(t===`released`)return F.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return F.set(e.deviceKey,{packageName:e.packageName,cause:n}),g({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function Jr(e){return e instanceof a&&e.details?.reason===Ur}function Yr(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);return new a(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:Ur,deviceKey:e.deviceKey,packageName:e.packageName,cause:t,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function Xr(e){try{let t=await y(e.adb,[`pidof`,e.packageName,C(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:Hr}),n=t.stdout.trim();return Vr(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function Zr(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[ii({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],ai({...e,signal:t})]),{timedOut:t.aborted}}function Qr(e){let t=$r(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>$r(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function $r(e){return e.exitCode!=null||e.signalCode!=null}async function ei(e,t,n){let r,i,a=await Promise.race([e.then(()=>!0),new Promise(e=>{r=setTimeout(()=>e(!1),t)}),...n?[new Promise(e=>{i=()=>e(!1),n.addEventListener(`abort`,i,{once:!0}),n.aborted&&i()})]:[]]);return r&&clearTimeout(r),i&&n?.removeEventListener(`abort`,i),a}async function ti(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await ei(e.processExit.ended,e.timeoutMs)}function ni(e){F.delete(e)}function ri(){F.clear()}async function ii(e){await y(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function ai(e){e.process.stdin?.end(),e.process.stdout?.destroy(),e.process.stderr?.destroy(),await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:e.signal})}async function oi(e){let t=ci(e),n=e.deviceKey??`android:default`;await Kr({deviceKey:n,adb:e.adb,signal:e.signal});let r;try{r=await e.adb(li(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs,signal:e.signal})}catch(r){throw e.signal?.aborted?(await Gr({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:r}),e.signal.throwIfAborted(),r):r}e.signal?.aborted&&(await Gr({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:i,cleanupDone:o}=await ui(e,t,r);if(t.outputPath&&!o&&await _i(e.adb,t.outputPath),r.exitCode!==0)throw new a(`COMMAND_FAILED`,`Android snapshot helper failed`,Pe(r,{helper:i.metadata}));return i}function si(e){return{adb:e.adb,adbProvider:e.adbProvider,deviceKey:e.deviceKey,helperVersion:e.artifact.manifest.version,helperVersionCode:e.artifact.manifest.versionCode,helperSha256:e.artifact.manifest.sha256,packageName:e.artifact.manifest.packageName,instrumentationRunner:e.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:rr,commandTimeoutMs:ir,...e.signal?{signal:e.signal}:{}}}function ci(e){let t=I(e.timeoutMs,8e3),n=I(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:I(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:I(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:I(e.commandTimeoutMs,t+5e3),maxDepth:I(e.maxDepth,128),maxNodes:I(e.maxNodes,5e3),packageName:n,runner:I(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function I(e,t){return e===void 0?t:e}function li(e,t={}){return Ze(`adb`,`shell`,[`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],...t.sessionPort===void 0?[]:[`-e`,`sessionPort`,t.sessionPort],e.runner])}async function ui(e,t,n){try{return{output:vi(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await di(e,t,n,r)}}async function di(e,t,n,r){let i=r instanceof a&&r.details?.helper?r:void 0;if(i&&n.exitCode!==0)throw i;let o=await fi(e,t,n);if(o)return{output:o,cleanupDone:!0};throw i||new a(`COMMAND_FAILED`,n.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,...Or(Dr(n.exitCode))},r)}async function fi(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await mi(e.adb,t.outputPath,gi(`${n.stdout}\n${n.stderr}`)??pi(t))}function pi(e){return{outputFormat:nr,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function mi(e,t,n){let r;try{r=await y(e,hi(t),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(r.exitCode!==0)return;let i=r.stdout.trim();if(!(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`)))return{xml:i,metadata:n}}function hi(e){return[`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function gi(e){try{return Ei(bi(Fn(e).results))}catch{return null}}async function _i(e,t){try{await y(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function vi(e){let t=Fn(e),n=bi(t.results);return{xml:Si(yi(t.status),n),metadata:{...Ei(n),transport:`instrumentation`}}}function yi(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:L(n.chunkIndex),count:L(n.chunkCount),payloadBase64:e})}return t}function bi(e){let t=e.find(e=>e.agentDeviceProtocol===tr);if(!t)throw new a(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(t.ok!==`true`)throw new a(`COMMAND_FAILED`,xi(t),{errorType:t.errorType,helper:t,...Or(Er(t))});return t}function xi(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Si(e,t){if(e.length===0)throw new a(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:t});let n=Ci(e),r=Buffer.concat(Ti(wi(e,n),n)).toString(`utf8`);if(!r.includes(`<hierarchy`)||!r.includes(`</hierarchy>`))throw new a(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:r});return r}function Ci(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new a(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:t,actualChunks:e.length});return t}function wi(e,t){let n=new Map;for(let r of e){if(r.index===void 0||r.index<0||r.index>=t)throw new a(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:r.index,expectedChunks:t});if(n.has(r.index))throw new a(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:r.index});n.set(r.index,r.payloadBase64)}return n}function Ti(e,t){let n=[];for(let r=0;r<t;r+=1){let i=e.get(r);if(i===void 0)throw new a(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:r,expectedChunks:t});n.push(Buffer.from(i,`base64`))}return n}function Ei(e){return{helperApiVersion:e.helperApiVersion,outputFormat:nr,waitForIdleTimeoutMs:L(e.waitForIdleTimeoutMs),waitForIdleQuietMs:L(e.waitForIdleQuietMs),timeoutMs:L(e.timeoutMs),maxDepth:L(e.maxDepth),maxNodes:L(e.maxNodes),rootPresent:Oi(e.rootPresent),captureMode:Di(e.captureMode),windowCount:L(e.windowCount),nodeCount:L(e.nodeCount),truncated:Oi(e.truncated),elapsedMs:L(e.elapsedMs),pixelDensity:L(e.pixelDensity),displayWidth:L(e.displayWidth),displayHeight:L(e.displayHeight)}}function Di(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const L=A,Oi=Vn;function ki(){return new Promise((e,t)=>{let n=Yt.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}function Ai(e,t,n,r){return new Promise((i,o)=>{let s=Yt.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new a(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:t,timeoutMs:n,port:e}))},n),u=()=>{clearTimeout(l),r?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,d,{once:!0}),r?.aborted){d();return}s.on(`connect`,()=>s.write(`${t}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),i(Buffer.concat(c).toString(`utf8`))})})}async function ji(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return Li(await Ai(e.port,`snapshot ${t}`,Mi(e),e.signal),t)}function Mi(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function Ni(e,t,n){return new Promise((r,i)=>{let o=``,s=setTimeout(()=>{n?.removeEventListener(`abort`,l),i(new a(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:t,reason:`android_snapshot_helper_session_ready_timeout`}))},t),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),n?.removeEventListener(`abort`,l),r())},l=()=>{clearTimeout(s),i(n?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(n?.addEventListener(`abort`,l,{once:!0}),n?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,t)=>{clearTimeout(s),n?.removeEventListener(`abort`,l),i(new a(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:t,reason:`android_snapshot_helper_session_exited_before_ready`}))}),e.on(`error`,e=>{clearTimeout(s),n?.removeEventListener(`abort`,l),i(e)})})}function Pi(e){let t=e.indexOf(`
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{$ as t,B as n,F as r,J as i,P as a,b as o,rt as s,tt as c,v as l,z as u}from"./sdk-contracts.js";import"./capture.js";import{k as d,p as f}from"./sdk-batch-runner.js";import{n as p,t as m}from"./snapshot-private-evidence.js";import{c as h,r as g}from"./diagnostics.js";import"./diagnostics2.js";import{Gr as ee,Jr as te,Qr as ne,Ur as re,Wr as ie,Xr as ae,ni as oe,qr as se,ri as ce}from"./sdk-batch.js";import{_ as le,d as ue,p as de}from"./scroll-gesture.js";import{r as fe}from"./success-text.js";import{n as pe}from"./alert-contract.js";import{T as me,_ as he,b as ge,d as _e,v as ve,x as ye,y as be}from"./settings.js";import{n as xe}from"./location-coordinates.js";import{r as Se}from"./mobile-snapshot-semantics.js";import"./device.js";import{n as Ce,s as we}from"./device-rotation.js";import{c as Te,g as Ee,l as De,o as Oe,r as ke}from"./exec.js";import{i as _}from"./retry.js";import{i as Ae}from"./tv-remote.js";import"./command.js";import{a as je,r as Me}from"./version.js";import"./retry2.js";import{r as Ne}from"./install-source2.js";import{_ as Pe,a as v,c as Fe,d as y,f as Ie,g as b,h as x,i as Le,l as Re,n as ze,o as S,p as Be,r as Ve,s as He,t as Ue,u as We,v as Ge}from"./adb-executor.js";import{a as C,n as Ke,o as w}from"./device-shell.js";import{c as qe,h as Je,i as Ye,o as Xe,r as Ze,u as Qe}from"./adb-transport.js";import{c as $e,i as et,l as tt,n as T,o as nt,s as rt}from"./adb-failure.js";import{a as it,i as at,n as ot,o as E}from"./adb.js";import{a as st,i as ct,l as lt,o as ut,r as dt,t as ft}from"./android-input-ownership.js";import{i as pt,n as mt,r as ht}from"./gesture-plan.js";import{_ as gt,a as _t,b as vt,c as yt,d as bt,f as xt,g as St,h as Ct,i as wt,l as Tt,m as Et,n as Dt,o as Ot,p as D,r as kt,s as At,t as O,u as jt,v as Mt,y as Nt}from"./ime-state.js";import{n as Pt}from"./android-snapshot-quality.js";import{a as Ft,c as It,i as Lt,l as Rt,n as zt,o as Bt,r as Vt,s as Ht,u as Ut}from"./app-lifecycle.js";import{a as Wt,i as Gt,n as Kt,o as qt,r as Jt,t as Yt}from"./app-deployment-resolution.js";import{a as Xt,i as Zt,n as Qt,o as $t,t as en}from"./app-parsers.js";import{i as tn,n as nn,r as rn,t as an}from"./window-state.js";import{i as on,r as sn}from"./toolchain-probe.js";import{a as cn,i as k,n as ln,o as un,r as dn,s as fn,t as pn}from"./ime-settings-record.js";import{n as mn,r as hn}from"./android-system-chrome.js";import{t as gn}from"./bounds.js";import{t as _n}from"./entities.js";import{n as vn}from"./startup-recovery-fence.js";import{n as yn}from"./numeric.js";import A from"node:path";import bn from"node:net";import{TextDecoder as xn}from"node:util";const Sn=new Map;async function Cn(e){let t=Sn.get(e.deviceKey);if(t!==void 0)return t;let n;try{let t=await e.adb([`features`],{allowFailure:!0,timeoutMs:2e3,...e.signal?{signal:e.signal}:{}});if(t.exitCode!==0)return!1;n=t.stdout}catch{return!1}let r=Tn(n).includes(`shell_v2`);return Sn.set(e.deviceKey,r),r}function wn(){Sn.clear()}function Tn(e){return e.split(`
|
|
2
|
+
`).map(e=>e.trim()).filter(Boolean)}const En=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Dn(e){return En.has(e)}const On=new Set([`android`,`com.android.systemui`]),kn=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,An=/^android:id\/button[123]$/i,jn=/(?:^|:)id\/permission_/i,Mn=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,Nn=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,Pn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Fn(e){if(e!==null){if(An.test(e))return`button`;if(kn.test(e))return`content`}}function In(e){let t=zn(e.filter(Ln)),n=t.nodes;if(n.length===0)return null;let r=Wn(n),i=n.filter(e=>j(e)&&!er(e)),a=qn(i),o=Jn(i,a);if(!a&&!o&&r.length===0)return null;let s=tr(n);return{alert:{...a?{title:a}:{},...o?{message:o}:{},buttons:r.map(e=>e.label),platform:`android`,source:t.source,...s?{packageName:s}:{}},buttons:r}}function Ln(e){return!lt(e)}function Rn(e,t){let n=t===`accept`?`accept`:`dismiss`;return e.find(e=>e.role===n)||(t===`dismiss`?e.find(e=>e.role===`neutral`)??null:e.length===1?e[0]??null:null)}function zn(e){let t=e.filter(e=>Qn(e));if(t.length)return{nodes:t,source:`permission`};let n=Un(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:Bn(e),source:`native-dialog`}}function Bn(e){let t=e.filter(e=>Vn(e.type??``)),n=e.filter(e=>kn.test(e.identifier??``)),r=t.length?[...t,...n]:Hn(n);if(r.length===0)return[];let i=Yn(e,r);return i===void 0?r:Zn(e,i)}function Vn(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function Hn(e){let t=e.some(e=>An.test(e.identifier??``)),n=e.some(e=>!An.test(e.identifier??``));return t&&n?e:[]}function Un(e){let t=e.filter(e=>$n(e));if(t.length===0)return[];let n=Yn(e,t);return n===void 0?t:Zn(e,n).filter(e=>e.bundleId&&On.has(e.bundleId))}function Wn(e){let t=new Set,n=[];for(let r of e){let e=j(r);if(!e||!r.rect||!er(r))continue;let i=e.trim().toLowerCase();if(!i||t.has(i))continue;t.add(i);let a=o(r.rect);n.push({label:e,x:a.x,y:a.y,role:Gn(r,e)})}return n}function Gn(e,t){return Kn(e.identifier??``)||(Nn.test(t.trim())?`accept`:Pn.test(t.trim())?`dismiss`:`neutral`)}function Kn(e){return/(?:^|:)id\/button1$/i.test(e)?`accept`:/(?:^|:)id\/button2$/i.test(e)?`dismiss`:/(?:^|:)id\/button3$/i.test(e)?`neutral`:/(?:^|:)id\/permission_allow/i.test(e)?`accept`:/(?:^|:)id\/permission_deny/i.test(e)?`dismiss`:null}function qn(e){return j(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||j(e[0])}function Jn(e,t){let n=e.map(e=>j(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
|
|
3
|
+
`):void 0}function Yn(e,t){let n=t[0];if(!n)return;let r=Xn(e,n.index);for(let n of t.slice(1)){let t=new Set(Xn(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r.at(-1)}function Xn(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function Zn(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function Qn(e){let t=e.bundleId??``;return En.has(t)||jn.test(e.identifier??``)}function $n(e){let t=e.bundleId??``;return On.has(t)&&Mn.test(j(e))}function er(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||An.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function j(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function tr(e){return e.find(e=>e.bundleId)?.bundleId}function nr(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))rr(n,t);return ir(t),{status:t.status,results:t.results}}function rr(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},sr(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){ar(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},sr(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&or(t)}function ir(e){ar(e),or(e)}function ar(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function or(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function sr(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function M(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function cr(e){if(e===void 0)return;if(e===``)return[];let t=e.split(`,`);return t.every(e=>/^\d+$/.test(e))?t.map(Number):void 0}function lr(e){if(e===`true`)return!0;if(e===`false`)return!1}function ur(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new a(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const dr=1e4;async function fr(e,t){try{return await Ue(e,t)}catch(e){throw nt(e)}}async function pr(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,apkPath:a,sha256:o,cache:s,deviceKey:c,installTimeoutMs:l,helperLabel:u}=e,d=`${c}\0${r}\0${i}\0${o}`;if(s.has(d))return{packageName:r,versionCode:i,installedSha256:o,installed:!1,reason:`current`};await br(a,o,u);let f=await mr({adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:o});if(f.reason===`current`)return s.add(d),{packageName:r,versionCode:i,...f,installed:!1};let p=await fr(a,{provider:n,replace:!0,allowFailure:!0,timeoutMs:l});if(p.exitCode!==0)throw T(`Failed to install ${u}`,p,{packageName:r,versionCode:i,reason:f.reason});return s.add(d),{packageName:r,versionCode:i,...f,installed:!0}}async function mr(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await _r(t,r,o);if(s===void 0)return{reason:`missing`};if(s<i)return{installedVersionCode:s,reason:`outdated`};if(s>i)return{installedVersionCode:s,reason:`current`};try{let e=await vr(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function hr(e){let t=b().files,n=je(),r=A.join(Me(),`android`,e.helperDirName,`dist`),o=A.join(r,e.manifestFileName(n));try{let n=e.parseManifest(JSON.parse(await t.readText(o))),i=A.join(r,n.assetName);return await t.access(i),{apkPath:i,manifest:n}}catch(t){throw new a(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:i(t).message},t)}}function gr(e){return async t=>await pr({adb:t.adb,adbProvider:t.adbProvider,packageName:t.artifact.manifest.packageName,versionCode:t.artifact.manifest.versionCode,apkPath:t.artifact.apkPath,sha256:t.artifact.manifest.sha256,cache:e.cache,deviceKey:t.deviceKey,installTimeoutMs:e.installTimeoutMs,helperLabel:e.helperLabel})}async function _r(e,t,n){let r=await y(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${Sr(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function vr(e,t,n,r){let i=await y(e,[`pm`,`path`,n],{allowFailure:!0,timeoutMs:dr,signal:r}),o=yr(`${i.stdout}\n${i.stderr}`);if(i.exitCode!==0||!o)throw new a(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=b().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=A.join(c,`base.apk`);try{let e=await ze(o,l,{provider:t,allowFailure:!0,timeoutMs:dr,signal:r});if(e.exitCode!==0)throw T(`Could not read installed Android helper APK`,e,{packageName:n,remotePath:o});return await xr(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function yr(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function br(e,t,n){let r=await xr(e);if(r!==t)throw new a(`COMMAND_FAILED`,`${n} APK checksum mismatch`,{apkPath:e,expectedSha256:t,actualSha256:r})}async function xr(e){let t=b().files;return t.sha256(await t.readBytes(e))}function Sr(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const Cr=`android-snapshot-helper-v1`,wr=`uiautomator-xml`,Tr=5e3,Er=3e4;function Dr(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new a(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let t=e;return{name:kr(t.name,`name`,`android-snapshot-helper`),version:N(t.version,`version`),releaseTag:jr(t.releaseTag),assetName:jr(t.assetName),apkUrl:Mr(t.apkUrl,`apkUrl`),sha256:Ar(t.sha256),checksumName:jr(t.checksumName),packageName:N(t.packageName,`packageName`),versionCode:Or(t.versionCode,`versionCode`),instrumentationRunner:N(t.instrumentationRunner,`instrumentationRunner`),minSdk:Or(t.minSdk,`minSdk`),targetSdk:t.targetSdk===void 0?void 0:Or(t.targetSdk,`targetSdk`),outputFormat:kr(t.outputFormat,`outputFormat`,wr),statusProtocol:kr(t.statusProtocol,`statusProtocol`,Cr)}}function Or(e,t){return Nt(e,t,`snapshot helper`)}function kr(e,t,n){return vt(e,t,n,`snapshot helper`)}function Ar(e){let t=N(e,`sha256`).trim().toLowerCase();if(t.length!==64||!Nr(t))throw new a(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return t}function N(e,t){if(typeof e!=`string`||e.trim().length===0)throw new a(`INVALID_ARGS`,`Android snapshot helper manifest ${t} is required.`);return e}function jr(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Mr(e,t){return e===null?null:N(e,t)}function Nr(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}const P=new Map;function Pr(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of P.keys())e.startsWith(t)&&Br(e)}const Fr=`android-snapshot-helper-not-current`;function Ir(e){return r(e).details?.reason===Fr}function Lr(){P.clear()}function Rr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function zr(e,t){if(!e)return;let[n,r]=e.split(`\0`),i=`${n}\0${r}\0`;for(let t of P.keys())t!==e&&t.startsWith(i)&&P.delete(t);P.set(e,t)}function Br(e){e&&P.delete(e)}async function Vr(e){let{adb:t,artifact:n}=e,r=e.installPolicy??`missing-or-outdated`,i=n.manifest.packageName,o=n.manifest.versionCode,s=n.manifest.sha256;if(r===`never`)return{packageName:i,versionCode:o,installed:!1,reason:`skipped`};let c=Rr(e.deviceKey,i,o,s),l=c?P.get(c):void 0;if(c&&r!==`always`&&l!==void 0)return{packageName:i,versionCode:o,installedVersionCode:l,installedSha256:s,installed:!1,reason:`current`};await br(n.apkPath,s,`Android snapshot helper`);let u=r===`always`?{installedVersionCode:await Wr(t,i,e.timeoutMs,e.signal),reason:`forced`}:await mr({adb:t,adbProvider:Ur(e.adbProvider,t),packageName:i,versionCode:o,sha256:s,signal:e.signal}),{installedVersionCode:d}=u,f=`installedSha256`in u?u.installedSha256:void 0,p=u.reason;if(p===`current`){if(d===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return zr(c,d),{packageName:i,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}if(r===`current-only`)throw new a(`COMMAND_FAILED`,`Android snapshot helper is not installed at the current version`,{reason:Fr,packageName:i,versionCode:o,installedVersionCode:d});let m;try{m=await Gr(t,e.adbProvider??t,n.apkPath,{packageName:i,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw Br(c),Hr(e,{packageName:i,versionCode:o})}if(m.exitCode!==0)throw Br(c),Hr(T(`Failed to install Android snapshot helper`,m,{packageName:i,versionCode:o}));return zr(c,o),{packageName:i,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function Hr(e,t){let n=r(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function Ur(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function Wr(e,t,n,r){let i=await y(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return Kr(`${i.stdout}\n${i.stderr}`,t)}async function Gr(e,t,n,r){let i=async()=>await fr(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!qr(a))return a;let o=await e([`uninstall`,r.packageName],{allowFailure:!0,timeoutMs:r.timeoutMs,signal:r.signal}),s=await i();return s.exitCode===0?s:{...s,stderr:[s.stderr,o.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${o.stderr}`:``].filter(Boolean).join(`
|
|
4
|
+
`)}}function Kr(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function qr(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Jr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function Yr(e){return e===137?`accessibility-timeout`:void 0}function Xr(e){return e?{androidCaptureFailureReason:e}:{}}function F(e,t,n,r){if(r instanceof a){let i=r.details??{};return new a(r.code,r.message,{...i,action:e,package:n,tool:t,hint:typeof i.hint==`string`?i.hint:$r(t,i)},r)}return new a(`COMMAND_FAILED`,`Failed to ${e} Android ${t} for ${n}`,{action:e,package:n,tool:t,hint:Zr(t)},r)}function Zr(e){return e===`simpleperf`?`Verify simpleperf is available, the app process is running, and the app/device permits native CPU profiling.`:`Verify perfetto is available, the app process is running, and the device permits trace capture.`}function Qr(e){return e===`simpleperf`?`Use an emulator/system image with simpleperf available, or install the Android NDK simpleperf binary for this device.`:`Use Android 10+ or a system image that exposes the perfetto command-line binary.`}function $r(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?ei(n):ni(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Zr(e)}function ei(e){return ti(e)?`Use a debuggable/profileable Android app or a device image that permits simpleperf for the target process, then retry perf cpu profile start.`:e.includes(`not supported`)||e.includes(`failed to open perf event`)?`This device image does not expose the requested simpleperf event for the app process. Try a different emulator/system image or a profileable app.`:Zr(`simpleperf`)}function ti(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function ni(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const ri=`adb-shell-simpleperf`,ii=`adb-shell-perfetto`,ai=15e3,I=3e4,oi=`/data/local/tmp`;async function si(e,t){try{let n=await y(e,[`pidof`,t],{allowFailure:!0,timeoutMs:ai}),r=li(n.stdout);if(n.exitCode===0&&r)return r}catch{}throw new a(`COMMAND_FAILED`,`No active Android app process found for ${t}`,{package:t,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function ci(e,t,n){let r=await y(e,[C(`command -v ${w(t)} || which ${w(t)}`)],{allowFailure:!0,timeoutMs:ai});if(!(r.exitCode===0&&r.stdout.trim()))throw new a(`UNSUPPORTED_OPERATION`,`Android device does not expose ${t}`,{package:n,tool:t,hint:Qr(t)})}function li(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const ui=2e3,di=`android_snapshot_helper_runtime_occupied`,L=new Map;function fi(e){return`${e.platform}:${e.id}`}async function pi(e){await Ei({adb:e.adb,packageName:e.packageName}),await hi({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function mi(e){let t=L.get(e.deviceKey);if(!t)return;await Ei({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await vi({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await _(250),n=await vi({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw _i({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&L.delete(e.deviceKey)}async function hi(e){let t=e.release??await vi({adb:e.adb,packageName:e.packageName});if(t===`released`)return L.delete(e.deviceKey),t;let n=e.cause instanceof Error?e.cause.message:String(e.cause);return L.set(e.deviceKey,{packageName:e.packageName,cause:n}),g({level:`warn`,phase:`android_snapshot_helper_retirement_pending`,data:{deviceKey:e.deviceKey,packageName:e.packageName,release:t}}),t}function gi(e){return e instanceof a&&e.details?.reason===di}function _i(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);return new a(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:di,deviceKey:e.deviceKey,packageName:e.packageName,cause:t,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function vi(e){try{let t=await y(e.adb,[`pidof`,e.packageName,C(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:ui}),n=t.stdout.trim();return li(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function yi(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[Ei({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],Di({...e,signal:t})]),{timedOut:t.aborted}}function bi(e){let t=xi(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>xi(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function xi(e){return e.exitCode!=null||e.signalCode!=null}async function Si(e,t,n){let r,i,a=await Promise.race([e.then(()=>!0),new Promise(e=>{r=setTimeout(()=>e(!1),t)}),...n?[new Promise(e=>{i=()=>e(!1),n.addEventListener(`abort`,i,{once:!0}),n.aborted&&i()})]:[]]);return r&&clearTimeout(r),i&&n?.removeEventListener(`abort`,i),a}async function Ci(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await Si(e.processExit.ended,e.timeoutMs)}function wi(e){L.delete(e)}function Ti(){L.clear()}async function Ei(e){await y(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function Di(e){e.process.stdin?.end(),e.process.stdout?.destroy(),e.process.stderr?.destroy(),await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:e.timeoutMs,signal:e.signal})}async function Oi(e){let t=Ai(e),n=e.deviceKey??`android:default`;await mi({deviceKey:n,adb:e.adb,signal:e.signal});let r;try{r=await e.adb(ji(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs,signal:e.signal})}catch(r){throw e.signal?.aborted?(await pi({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:r}),e.signal.throwIfAborted(),r):r}e.signal?.aborted&&(await pi({deviceKey:n,packageName:t.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let i=Mi(r);if(r.exitCode!==0)throw new a(`COMMAND_FAILED`,`Android snapshot helper failed`,ke(r,{helper:i.metadata}));return i}function ki(e){return{adb:e.adb,adbProvider:e.adbProvider,deviceKey:e.deviceKey,helperVersion:e.artifact.manifest.version,helperVersionCode:e.artifact.manifest.versionCode,helperSha256:e.artifact.manifest.sha256,packageName:e.artifact.manifest.packageName,instrumentationRunner:e.artifact.manifest.instrumentationRunner,waitForIdleTimeoutMs:500,timeoutMs:Tr,commandTimeoutMs:Er,...e.signal?{signal:e.signal}:{}}}function Ai(e){let t=R(e.timeoutMs,8e3),n=R(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:R(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:R(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:R(e.commandTimeoutMs,t+5e3),maxDepth:R(e.maxDepth,128),maxNodes:R(e.maxNodes,5e3),packageName:n,runner:R(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function R(e,t){return e===void 0?t:e}function ji(e,t={}){return Ke(`adb`,`shell`,[`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],...t.sessionPort===void 0?[]:[`-e`,`sessionPort`,t.sessionPort],e.runner])}function Mi(e){try{return Ni(`${e.stdout}\n${e.stderr}`)}catch(t){throw(t instanceof a&&t.details?.helper?t:void 0)||new a(`COMMAND_FAILED`,e.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,...Xr(Yr(e.exitCode))},t)}}function Ni(e){let t=nr(e),n=Fi(t.results);return{xml:Li(Pi(t.status),n),metadata:{...Vi(n),transport:`instrumentation`}}}function Pi(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:z(n.chunkIndex),count:z(n.chunkCount),payloadBase64:e})}return t}function Fi(e){let t=e.find(e=>e.agentDeviceProtocol===Cr);if(!t)throw new a(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(t.ok!==`true`)throw new a(`COMMAND_FAILED`,Ii(t),{errorType:t.errorType,helper:t,...Xr(Jr(t))});return t}function Ii(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Li(e,t){if(e.length===0)throw new a(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:t});let n=Ri(e),r=Buffer.concat(Bi(zi(e,n),n)).toString(`utf8`);if(!r.includes(`<hierarchy`)||!r.includes(`</hierarchy>`))throw new a(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:r});return r}function Ri(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new a(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:t,actualChunks:e.length});return t}function zi(e,t){let n=new Map;for(let r of e){if(r.index===void 0||r.index<0||r.index>=t)throw new a(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:r.index,expectedChunks:t});if(n.has(r.index))throw new a(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:r.index});n.set(r.index,r.payloadBase64)}return n}function Bi(e,t){let n=[];for(let r=0;r<t;r+=1){let i=e.get(r);if(i===void 0)throw new a(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:r,expectedChunks:t});n.push(Buffer.from(i,`base64`))}return n}function Vi(e){return{helperApiVersion:e.helperApiVersion,outputFormat:wr,waitForIdleTimeoutMs:z(e.waitForIdleTimeoutMs),waitForIdleQuietMs:z(e.waitForIdleQuietMs),timeoutMs:z(e.timeoutMs),maxDepth:z(e.maxDepth),maxNodes:z(e.maxNodes),rootPresent:Ui(e.rootPresent),captureMode:Hi(e.captureMode),windowCount:z(e.windowCount),missingRootWindowTypes:cr(e.missingRootWindowTypes),nodeCount:z(e.nodeCount),truncated:Ui(e.truncated),elapsedMs:z(e.elapsedMs),pixelDensity:z(e.pixelDensity),displayWidth:z(e.displayWidth),displayHeight:z(e.displayHeight)}}function Hi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const z=M,Ui=lr;function Wi(){return new Promise((e,t)=>{let n=bn.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}function Gi(e,t,n,r){return new Promise((i,o)=>{let s=bn.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new a(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:t,timeoutMs:n,port:e}))},n),u=()=>{clearTimeout(l),r?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,d,{once:!0}),r?.aborted){d();return}s.on(`connect`,()=>s.write(`${t}\n`)),s.on(`data`,e=>c.push(Buffer.from(e))),s.on(`error`,e=>{u(),o(e)}),s.on(`close`,()=>{u(),i(Buffer.concat(c).toString(`utf8`))})})}async function Ki(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return Qi(await Gi(e.port,`snapshot ${t}`,qi(e),e.signal),t)}function qi(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function Ji(e,t,n){return new Promise((r,i)=>{let o=``,s=setTimeout(()=>{n?.removeEventListener(`abort`,l),i(new a(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:o,timeoutMs:t,reason:`android_snapshot_helper_session_ready_timeout`}))},t),c=e=>{o+=e.toString(),o.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&o.includes(`sessionReady=true`)&&(clearTimeout(s),n?.removeEventListener(`abort`,l),r())},l=()=>{clearTimeout(s),i(n?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(n?.addEventListener(`abort`,l,{once:!0}),n?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,t)=>{clearTimeout(s),n?.removeEventListener(`abort`,l),i(new a(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:o,exitCode:e,signal:t,reason:`android_snapshot_helper_session_exited_before_ready`}))}),e.on(`error`,e=>{clearTimeout(s),n?.removeEventListener(`abort`,l),i(e)})})}function Yi(e){let t=e.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);return
|
|
6
|
+
`);return ta(e.slice(0,t<0?e.length:t))}function Xi(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new a(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==t)throw new a(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:t})}function Zi(e,t){let n=Yi(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function Qi(e,t){let n=e.indexOf(`
|
|
7
7
|
|
|
8
|
-
`);if(n<0)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let r=Bi(e.slice(0,n)),i=e.slice(n+2);return Ri(r,t),zi(r,i),{xml:i,metadata:Vi(r)}}function Ri(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==t)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:t});if(e.ok!==`true`)throw new a(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...Or(Er(e))})}function zi(e,t){let n=A(e.byteLength);if(n!==void 0&&Buffer.byteLength(t,`utf8`)!==n)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(t,`utf8`)});if(!t.includes(`<hierarchy`)||!t.includes(`</hierarchy>`))throw new a(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:t})}function Bi(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function Vi(e){return{helperApiVersion:e.helperApiVersion,outputFormat:nr,waitForIdleTimeoutMs:A(e.waitForIdleTimeoutMs),waitForIdleQuietMs:A(e.waitForIdleQuietMs),timeoutMs:A(e.timeoutMs),maxDepth:A(e.maxDepth),maxNodes:A(e.maxNodes),rootPresent:Vn(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:A(e.windowCount),nodeCount:A(e.nodeCount),truncated:Vn(e.truncated),elapsedMs:A(e.elapsedMs),pixelDensity:A(e.pixelDensity),displayWidth:A(e.displayWidth),displayHeight:A(e.displayHeight)}}const Hi=5e3,R=new Map,z=new Map;async function Ui(e){return await Wi(e)!==void 0}async function Wi(e){let t=e.deviceKey??`android:default`;if(await Kr({deviceKey:t,adb:e.adb,signal:e.signal}),!ra()||!e.adbProvider?.spawn)return;let n=ci(e),r=ta(n),i=await Ki({deviceKey:t,identity:ea(t,r,e),options:e,resolved:r,startBudgetMs:na(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function Gi(e){return R.get(e)}async function Ki(e){if(!Yi(e.identity))return await qi(e.deviceKey,e.identity),R.get(e.deviceKey)??await Ji(e)}async function qi(e,t){let n=R.get(e);!n||Qi(n,t)||await B(e,{force:$r(n.process)})}async function Ji(e){let t=Date.now();try{return await $i(e)}catch(n){e.options.signal?.throwIfAborted(),z.set(e.identity,Date.now()+Xi(Date.now()-t)),g({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:n instanceof a?n.details?.reason:void 0,detail:n instanceof Error?n.message:String(n)}});return}}function Yi(e){let t=z.get(e);return t===void 0?!1:t>Date.now()||(z.delete(e),!1)}function Xi(e){return Math.min(Math.max(e,1e4),6e4)}async function Zi(e){await B(e.deviceKey,{force:!0,signal:e.signal,cause:e.cause}),!e.signal?.aborted&&z.set(e.identity,Date.now()+e.fallbackBudgetMs+Xi(e.failedAfterMs))}function Qi(e,t){return e.identity===t&&!$r(e.process)}async function $i(e){let t=await ki();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:Hi,signal:e.options.signal});let n=li({...e.resolved,outputPath:void 0,emitChunks:!1},{sessionPort:t}),r=e.options.adbProvider.spawn(n,{allowFailure:!0,captureOutput:!1}),i={identity:e.identity,deviceKey:e.deviceKey,helper:{packageName:e.resolved.packageName,runner:e.resolved.runner,helperVersion:e.options.helperVersion,helperVersionCode:e.options.helperVersionCode,sha256:e.options.helperSha256},port:t,adb:e.options.adb,process:r,startedAtMs:Date.now(),capturedCount:0};try{return await Ni(r,e.startBudgetMs,e.options.signal),R.set(e.deviceKey,i),z.delete(e.identity),ni(e.deviceKey),g({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),i}catch(t){let n=Qr(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([ei(n.ended,250),Zr({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:Hr,forceStopRuntime:!0})]),await qr({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function ea(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,helperSha256:n.helperSha256,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function ta(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function na(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function ra(){let e=b().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function B(e,t={}){let n=R.get(e);if(!n)return!1;R.delete(e);let r=Qr(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await ia(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await Qt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:Hr:Hi,u=i?250:2e3,[d,f]=await Promise.all([ti({process:n.process,processExit:r,timeoutMs:u}),Zr({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await qr({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return g({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,releaseProvenByQuit:c,release:p,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,externalCleanupTimedOut:f.timedOut}}),!0}async function ia(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=Ii(await Ai(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await ei(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function aa(e){await B(Wr(e))}async function oa(){try{await Promise.allSettled([...R.keys()].map(async e=>{await B(e)}))}finally{R.clear(),z.clear(),ri(),$t()}}async function sa(e){let t=await Wi(e);if(t)return await ca({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function ca(e){let{session:t,deviceKey:n,options:r,resolved:i}=e,a=Date.now();try{let e=t.capturedCount>0,n=await ji({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await Zi({deviceKey:n,identity:t.identity,failedAfterMs:Date.now()-a,fallbackBudgetMs:ci(r).commandTimeoutMs,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:gt(e)===`accessibility-timeout`}});return}}function V(e,t){return e!==`gesture`||!(t instanceof a)?t:u(t,ot(t)?`no`:`unknown`)}async function la(e){let t=Gi(e.deviceKey);if(!t)return;if(!ua(t.helper,e.helper)){g({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:t.helper,requestedHelper:e.helper}}),await B(e.deviceKey);return}let n=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=e.payloadBase64?`${e.action} ${n} ${e.payloadBase64}`:`${e.action} ${n}`,i;try{i=Pi(await Ai(t.port,r,e.timeoutMs)),Fi(i,n)}catch(t){throw await B(e.deviceKey),V(e.action,t)}if(i.ok!==`true`)throw V(e.action,new a(`COMMAND_FAILED`,i.message||i.errorType||`Android automation helper ${e.action} failed`,{errorType:i.errorType,helper:i}));return i}function ua(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&da(e.helperVersion,t.helperVersion)&&da(e.helperVersionCode,t.helperVersionCode)&&da(e.sha256,t.sha256)}function da(e,t){return e===void 0||t===void 0||e===t}const fa=`android-touch-plan-v1`,pa=45e3,ma=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,ha=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function ga(e,t){let n=await ya(e),r=xa(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:fa,...r})).toString(`base64`),o=await h(`android_touch_helper_gesture`,async()=>{let e=await la({deviceKey:n.deviceKey,action:`gesture`,helper:va(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Ta(e),helperTransport:`persistent-session`}:{...await Ca({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`gesture`,extraArgs:[`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Ta}),helperTransport:`instrumentation`}},{packageName:n.artifact.manifest.packageName,version:n.artifact.manifest.version});return{backend:`android-helper`,helperVersion:n.artifact.manifest.version,installReason:n.install.reason,...o}}async function _a(e,t={}){let n=await ya(e);t.helperSessionScope===`daemon-session`&&await Ui(si({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await la({deviceKey:n.deviceKey,action:`viewport`,helper:va(n.artifact),timeoutMs:pa});if(e)return Ea(e)}catch(e){await B(n.deviceKey),g({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Ca({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`viewport`,extraArgs:[],timeoutMs:pa,readResult:Ea})}function va(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function ya(e){let t=S(e),n=t.snapshotHelperArtifact??await ba(),r=Wr(e);await Kr({deviceKey:r,adb:t.exec});let i=await h(`android_touch_helper_install`,async()=>await yr({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return g({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await B(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function ba(){return await qn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=ar(e);return{...t,assetName:t.assetName??`agent-device-android-snapshot-helper-${t.version}.apk`}},unavailableMessage:`Android touch gestures require the bundled Android automation helper artifact, but it was not found or could not be read`})}function xa(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(Sa)}}function Sa(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Ca(e){let t=await y(e.adb,[`am`,`instrument`,`-w`,`-e`,`mode`,e.action,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),n;try{n=wa(`${t.stdout}\n${t.stderr}`)}catch(n){if(n instanceof a){if(n.code===ha)throw V(e.action,new a(`COMMAND_FAILED`,n.message,n.details,n));if(n.code!==ma)throw n}let r=new a(`COMMAND_FAILED`,t.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,Pe(t),n);throw V(e.action,t.exitCode===0?r:at(r))}if(t.exitCode!==0)throw V(e.action,at(new a(`COMMAND_FAILED`,`Android automation helper failed`,Pe(t,{helper:n}))));return e.readResult(n)}function wa(e){let t=Fn(e).results.find(e=>e.agentDeviceProtocol===tr);if(!t)throw new a(ma,`Android automation helper did not return a final result`);if(t.ok!==`true`)throw new a(ha,t.message&&t.message!==`null`?t.message:t.errorType||`Android automation helper returned an error`,{errorType:t.errorType,helper:t});return t}function Ta(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:A(e.injectedEvents),elapsedMs:A(e.elapsedMs)}}function Ea(e){let t=A(e.x),n=A(e.y),r=A(e.width),i=A(e.height);if(t===void 0||n===void 0||r===void 0||i===void 0)throw new a(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=Da(e);return{viewport:Hn({x:t,y:n,width:r,height:i}),...o?{keyboard:o}:{}}}function Da(e){let t=A(e.keyboardX),n=A(e.keyboardY),r=A(e.keyboardWidth),i=A(e.keyboardHeight);if(t!==void 0&&n!==void 0&&r!==void 0&&i!==void 0)return{x:t,y:n,width:r,height:i}}function Oa(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...pt(e.durationMs,`android`),...i.map(({offsetMs:e})=>e)])].sort((e,t)=>e-t),o=0,s=a.map(e=>{for(;o<i.length-2&&e>i[o+1].offsetMs;)o+=1;let n=i[o],r=i[o+1],a=r.offsetMs-n.offsetMs,s=(e-n.offsetMs)/a;return{offsetMs:e,point:e===r.offsetMs||a===0?r.point:ht(n.point,r.point,t===`controlled`?ka(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function ka(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function Aa(e,t){let n=Oa(t),r=Be(e);if(r){let e=n.intent===`longPress`?{...n,viewport:Hn(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await ga(e,n)}async function ja(e,t={}){return(await Ma(e,t)).viewport}async function Ma(e,t={}){let n=Be(e);return n?{viewport:Hn(await n.gestureViewport())}:await _a(e,t)}async function H(e,t,n){try{await E(e,[`input`,`tap`,t,n])}catch(e){throw it(e)}}async function Na(e,t,r){await H(e,t,r);try{await H(e,t,r)}catch(e){throw n(e,1)}}async function Pa(e,t,n){let r=Fe(t);await E(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Fa(e){await E(e,[`input`,`keyevent`,`4`])}async function Ia(e){await E(e,[`input`,`keyevent`,`3`])}async function La(e){await E(e,[`input`,`keyevent`,`ENTER`])}async function Ra(e,t){let n=Xa(t);await E(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await E(e,[`settings`,`put`,`system`,`user_rotation`,n]),await Ba(e,t,n)}const za=15e3;async function Ba(e,t,n){let r=Date.now()+za,i=await Va(e,t,r);for(;i!==void 0&&i!==n&&Date.now()<r;)await _(Math.min(500,Ha(r))),i=await Va(e,t,r);if(i!==void 0&&i!==n)throw new a(`COMMAND_FAILED`,`orientation ${t} did not take effect: the display still reports rotation ${i} after ${za}ms`,{requestedRotation:Number(n),observedRotation:Number(i),hint:"The foreground app may pin its orientation, or the device may ignore user_rotation. Check `adb shell dumpsys display | grep mCurrentOrientation` and the app manifest."})}async function Va(e,t,n){try{return(await Ua(e,{timeoutMs:Ha(n)}))[0]}catch(e){throw new a(`COMMAND_FAILED`,`orientation ${t} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function Ha(e){return Math.max(1,e-Date.now())}async function Ua(e,t){let n=await E(e,[`dumpsys`,`display`],{...t,allowFailure:!0});if(n.exitCode!==0)throw T(`adb shell dumpsys display exited with code ${n.exitCode}`,n);return[...n.stdout.matchAll(/mCurrentOrientation=(\d)/g)].map(e=>e[1])}async function Wa(e,t){try{let n=await Ua(e,t);return n.length===1?ke(Number(n[0])):void 0}catch{return}}async function Ga(e){await E(e,[`input`,`keyevent`,`187`])}async function Ka(e,t,n,r=800){let i={x:t,y:n};return await Aa(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function qa(e,t,n){await H(e,t,n)}async function Ja(e,t,n){let{viewport:r,keyboard:i}=await Ma(e,{helperSessionScope:n?.helperSessionScope}),a=Ya(t,r,i),o=he({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.viewport.width,referenceHeight:a.viewport.height}),s={...o,referenceWidth:a.viewport.x+a.viewport.width,referenceHeight:a.viewport.y+a.viewport.height,x1:a.viewport.x+o.x1,y1:a.viewport.y+o.y1,x2:a.viewport.x+o.x2,y2:a.viewport.y+o.y2},c=Math.max(n?.durationMs??300,16),l=await Aa(e,{...mt({intent:`pan`,origin:{x:s.x1,y:s.y1},delta:{x:s.x2-s.x1,y:s.y2-s.y1},durationMs:c},a.viewport,`android`),releaseBehavior:n?.releaseBehavior??`controlled`});return{...s,...a.evidence,...n?.durationMs===void 0?{}:{durationMs:c},...l}}function Ya(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=ge(t,n);if(r.kind===`occluded`)throw me(e,{keyboardMinY:r.keyboardMinY,visibleHeight:r.visibleHeight,viewportHeight:t.height});return r.kind===`avoided`?{viewport:r.viewport,evidence:{keyboardAvoided:!0,keyboardMinY:r.keyboardMinY}}:{viewport:t,evidence:{}}}function Xa(e){let t=Oe[e];if(t===void 0)throw new a(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(t)}async function Za(e){let t=(await E(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new a(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(t[1]),height:Number(t[2])}}async function Qa(e,t,n){return t===`wait`?await $a(n.captureNodes,n.timeoutMs??1e4):t===`get`?ao((await io(n.captureNodes))?.alert??null):await eo(e,t,n.captureNodes)}async function $a(e,t){let n=Date.now(),r=await ro(e,t);if(!r)throw new a(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:r.alert,waitedMs:Date.now()-n,..._e(`Alert visible`)}}async function eo(e,t,n){let r=await ro(n,ve);if(!r)throw new a(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let i=mn(r.buttons,t);if(i)return await H(e,i.x,i.y),await to(r.alert,t,n),oo(t,r.alert,i.label,{x:i.x,y:i.y});if(t===`dismiss`)return await Fa(e),await to(r.alert,t,n),oo(t,r.alert,`Back`);throw new a(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function to(e,t,n){let r=Date.now();for(;;){let i=await io(n);if(!i||!no(i.alert,e))return;if(Date.now()-r>=2e3)throw new a(`COMMAND_FAILED`,`alert ${t} did not dismiss the visible alert`,{alert:e,hint:`The alert button was pressed but the dialog is still visible. Inspect alert get --json, then press the visible button by label/ref or retry.`});await _(300)}}function no(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function ro(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await io(e);if(t)return t;await _(300)}return null}async function io(e){return fn(await h(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function ao(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,..._e(e?`Alert visible`:`No alert visible`)}}function oo(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},..._e(`Alert ${e}ed`)}}const so=`android.intent.category.LAUNCHER`,co=`android.intent.category.DEFAULT`;async function lo(e,t){await y(e,[`am`,`force-stop`,t])}async function uo(e,t,n=[so]){for(let r of n){let n=await y(e,[`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=St(n.stdout);if(i)return i}return null}async function fo(e,t,n={}){let r=n.category??so;if(n.activity){await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,co,`-c`,r,`-n`,po(t,n.activity)]);return}let i=await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,co,`-c`,r,`-p`,t],{allowFailure:!0});if(i.exitCode===0&&!Ct(i.stdout,i.stderr))return;let o=await uo(e,t,[r]);if(!o)throw new a(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${t}`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,co,`-c`,r,`-n`,o])}function po(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let mo=null;function ho(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function go(e){let t=ho(e);if(mo?.key===t)return mo.invocation;if(await je(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return mo={key:t,invocation:e},e}let n=await Ae(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!n)throw new a(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let r={cmd:`java`,prefixArgs:[`-jar`,n]};return mo={key:t,invocation:r},r}async function _o(e,t,n){let r=await go(n);await Me(r.cmd,[...r.prefixArgs,...e],{signal:t})}function vo(e){return D.extname(e).toLowerCase()===`.aab`}async function yo(e,t,n={}){let r=S(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=b().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=D.join(o,`bundle.apks`);try{await _o([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??b().environment),await _o([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??b().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function bo(e,t,n={}){if(vo(t)){await yo(e,t,n);return}await Je(t,{device:e,replace:!0,signal:n.signal})}async function xo(e,t,n={}){await Dt(e,async()=>{e.booted||await vt(e.id,void 0,n.signal),await bo(e,t,n)})}const So=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Co=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),wo=new Set([32,208]),To=new Set([128,224,144]);async function Eo(e){return await U(v(e))}async function U(e){let t=await y(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw T(`Failed to query Android keyboard state`,t);return ko(t.stdout)}async function Do(e){return await Oo(v(e))}async function Oo(e){let t=await U(e),r=t,i=0;try{for(;r.visible&&i<2;)await y(e,[`input`,`keyevent`,`111`]),i+=1,await _(120),r=await U(e)}catch(e){throw n(e,i)}if(t.visible&&r.visible)throw new a(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:t.visible,dismissed:t.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function ko(e){let t=Po(e)??Ao(e),n=jo(e),r=Mo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=Mo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=ne(e),o=ie(r,i,a);return No(r,i,a),{visible:t??!1,inputType:n,type:n?Ro(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function Ao(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:!!(n&1)}function jo(e){let t=Mo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function Mo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function No(e,t,n){n||!ee(e)&&!p(t)||g({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Po(e){return Io(Fo(e,So))}function Fo(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function Io(e){if(e.size===0)return null;let t=Lo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Lo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Lo(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function Ro(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Co.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return wo.has(i)?`email`:To.has(i)?`password`:`text`}async function zo(e){return await Bo(v(e))}async function Bo(e){return Wo(await Uo(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function Vo(e,t){await Ho(v(e),t)}async function Ho(e,t){await Uo(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function Uo(e,t,n){let{androidClipboardShellCommandUnavailableError:r,classifyAndroidClipboardShellResponse:i}=await import(`./clipboard-shell-response.js`),a=await y(e,t,{allowFailure:!0}),o=i(a);if(o===`no-shell-command`)throw r(n);if(o===`call-failed`)throw T(`Failed to ${n} Android clipboard text`,a);return a.stdout}function Wo(e){let t=e.replaceAll(`\r
|
|
8
|
+
`);if(n<0)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let r=ta(e.slice(0,n)),i=e.slice(n+2);return $i(r,t),ea(r,i),{xml:i,metadata:na(r)}}function $i(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==t)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:t});if(e.ok!==`true`)throw new a(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...Xr(Jr(e))})}function ea(e,t){let n=M(e.byteLength);if(n!==void 0&&Buffer.byteLength(t,`utf8`)!==n)throw new a(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(t,`utf8`)});if(!t.includes(`<hierarchy`)||!t.includes(`</hierarchy>`))throw new a(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:t})}function ta(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function na(e){return{helperApiVersion:e.helperApiVersion,outputFormat:wr,waitForIdleTimeoutMs:M(e.waitForIdleTimeoutMs),waitForIdleQuietMs:M(e.waitForIdleQuietMs),timeoutMs:M(e.timeoutMs),maxDepth:M(e.maxDepth),maxNodes:M(e.maxNodes),rootPresent:lr(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:M(e.windowCount),missingRootWindowTypes:cr(e.missingRootWindowTypes),nodeCount:M(e.nodeCount),truncated:lr(e.truncated),elapsedMs:M(e.elapsedMs),pixelDensity:M(e.pixelDensity),displayWidth:M(e.displayWidth),displayHeight:M(e.displayHeight)}}const ra=5e3,B=new Map,V=new Map;async function ia(e){return await aa(e)!==void 0}async function aa(e){let t=e.deviceKey??`android:default`;if(await mi({deviceKey:t,adb:e.adb,signal:e.signal}),!va()||!e.adbProvider?.spawn)return;let n=Ai(e),r=ga(n),i=await sa({deviceKey:t,identity:ha(t,r,e),options:e,resolved:r,startBudgetMs:_a(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function oa(e){return B.get(e)}async function sa(e){if(!ua(e.identity))return await ca(e.deviceKey,e.identity),B.get(e.deviceKey)??await la(e)}async function ca(e,t){let n=B.get(e);!n||pa(n,t)||await H(e,{force:xi(n.process)})}async function la(e){let t=Date.now();try{return await ma(e)}catch(n){e.options.signal?.throwIfAborted(),V.set(e.identity,Date.now()+da(Date.now()-t)),g({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:n instanceof a?n.details?.reason:void 0,detail:n instanceof Error?n.message:String(n)}});return}}function ua(e){let t=V.get(e);return t===void 0?!1:t>Date.now()||(V.delete(e),!1)}function da(e){return Math.min(Math.max(e,1e4),6e4)}async function fa(e){await H(e.deviceKey,{force:!0,signal:e.signal,cause:e.cause}),!e.signal?.aborted&&V.set(e.identity,Date.now()+e.fallbackBudgetMs+da(e.failedAfterMs))}function pa(e,t){return e.identity===t&&!xi(e.process)}async function ma(e){let t=await Wi();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:ra,signal:e.options.signal});let n=ji({...e.resolved,emitChunks:!1},{sessionPort:t}),r=e.options.adbProvider.spawn(n,{allowFailure:!0,captureOutput:!1}),i={identity:e.identity,deviceKey:e.deviceKey,helper:{packageName:e.resolved.packageName,runner:e.resolved.runner,helperVersion:e.options.helperVersion,helperVersionCode:e.options.helperVersionCode,sha256:e.options.helperSha256},port:t,adb:e.options.adb,process:r,startedAtMs:Date.now(),capturedCount:0};try{return await Ji(r,e.startBudgetMs,e.options.signal),B.set(e.deviceKey,i),V.delete(e.identity),wi(e.deviceKey),g({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:e.deviceKey,port:t,packageName:e.resolved.packageName,runner:e.resolved.runner}}),i}catch(t){let n=bi(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([Si(n.ended,250),yi({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:ui,forceStopRuntime:!0})]),await hi({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function ha(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,helperSha256:n.helperSha256,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function ga(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function _a(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function va(){let e=b().environment.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}async function H(e,t={}){let n=B.get(e);if(!n)return!1;B.delete(e);let r=bi(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await ya(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await Cn({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:ui:ra,u=i?250:2e3,[d,f]=await Promise.all([Ci({process:n.process,processExit:r,timeoutMs:u}),yi({adb:n.adb,process:n.process,port:n.port,packageName:n.helper.packageName,timeoutMs:l,forceStopRuntime:t.resetRuntime===!0||!c})]),p=await hi({deviceKey:e,packageName:n.helper.packageName,adb:n.adb,cause:t.cause,...c?{release:`released`}:{}});return g({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs,quitAcknowledged:a.acknowledged,quitExitObserved:s,releaseProvenByQuit:c,release:p,forceKilled:!o&&d,forced:i||t.signal?.aborted===!0,externalCleanupTimedOut:f.timedOut}}),!0}async function ya(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=Zi(await Gi(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await Si(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function ba(e){await H(fi(e))}async function xa(){try{await Promise.allSettled([...B.keys()].map(async e=>{await H(e)}))}finally{B.clear(),V.clear(),Ti(),wn()}}async function Sa(e){let t=await aa(e);if(t)return await Ca({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function Ca(e){let{session:t,deviceKey:n,options:r,resolved:i}=e,a=Date.now();try{let e=t.capturedCount>0,n=await Ki({port:t.port,timeoutMs:i.timeoutMs,commandTimeoutMs:i.commandTimeoutMs,signal:r.signal});return t.capturedCount+=1,{xml:n.xml,metadata:{...n.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){await fa({deviceKey:n,identity:t.identity,failedAfterMs:Date.now()-a,fallbackBudgetMs:Ai(r).commandTimeoutMs,signal:r.signal,cause:e}),r.signal?.throwIfAborted(),g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{deviceKey:n,reason:e instanceof Error?e.message:String(e),uiAutomationConnectionTimeout:Pt(e)===`accessibility-timeout`}});return}}function U(e,t){return e!==`gesture`||!(t instanceof a)?t:u(t,tt(t)?`no`:`unknown`)}async function wa(e){let t=oa(e.deviceKey);if(!t)return;if(!Ta(t.helper,e.helper)){g({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:t.helper,requestedHelper:e.helper}}),await H(e.deviceKey);return}let n=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=e.payloadBase64?`${e.action} ${n} ${e.payloadBase64}`:`${e.action} ${n}`,i;try{i=Yi(await Gi(t.port,r,e.timeoutMs)),Xi(i,n)}catch(t){throw await H(e.deviceKey),U(e.action,t)}if(i.ok!==`true`)throw U(e.action,new a(`COMMAND_FAILED`,i.message||i.errorType||`Android automation helper ${e.action} failed`,{errorType:i.errorType,helper:i}));return i}function Ta(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&Ea(e.helperVersion,t.helperVersion)&&Ea(e.helperVersionCode,t.helperVersionCode)&&Ea(e.sha256,t.sha256)}function Ea(e,t){return e===void 0||t===void 0||e===t}const Da=`android-touch-plan-v1`,Oa=45e3,ka=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,Aa=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function ja(e,t){let n=await Pa(e),r=Ia(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:Da,...r})).toString(`base64`),o=await h(`android_touch_helper_gesture`,async()=>{let e=await wa({deviceKey:n.deviceKey,action:`gesture`,helper:Na(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...Ba(e),helperTransport:`persistent-session`}:{...await Ra({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`gesture`,extraArgs:[`-e`,`payloadBase64`,a],timeoutMs:i,readResult:Ba}),helperTransport:`instrumentation`}},{packageName:n.artifact.manifest.packageName,version:n.artifact.manifest.version});return{backend:`android-helper`,helperVersion:n.artifact.manifest.version,installReason:n.install.reason,...o}}async function Ma(e,t={}){let n=await Pa(e);t.helperSessionScope===`daemon-session`&&await ia(ki({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await wa({deviceKey:n.deviceKey,action:`viewport`,helper:Na(n.artifact),timeoutMs:Oa});if(e)return Va(e)}catch(e){await H(n.deviceKey),g({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await Ra({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,action:`viewport`,extraArgs:[],timeoutMs:Oa,readResult:Va})}function Na(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function Pa(e){let t=S(e),n=t.snapshotHelperArtifact??await Fa(),r=fi(e);await mi({deviceKey:r,adb:t.exec});let i=await h(`android_touch_helper_install`,async()=>await Vr({adb:t.exec,adbProvider:t,artifact:n,deviceKey:r,timeoutMs:3e4}),{packageName:n.manifest.packageName,versionCode:n.manifest.versionCode});return g({phase:`android_touch_helper_install_decision`,data:i}),i.installed&&await H(r),{adb:t.exec,adbProvider:t,artifact:n,install:i,deviceKey:r}}async function Fa(){return await hr({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=Dr(e);return{...t,assetName:t.assetName??`agent-device-android-snapshot-helper-${t.version}.apk`}},unavailableMessage:`Android touch gestures require the bundled Android automation helper artifact, but it was not found or could not be read`})}function Ia(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(La)}}function La(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function Ra(e){let t=await y(e.adb,[`am`,`instrument`,`-w`,`-e`,`mode`,e.action,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),n;try{n=za(`${t.stdout}\n${t.stderr}`)}catch(n){if(n instanceof a){if(n.code===Aa)throw U(e.action,new a(`COMMAND_FAILED`,n.message,n.details,n));if(n.code!==ka)throw n}let r=new a(`COMMAND_FAILED`,t.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,ke(t),n);throw U(e.action,t.exitCode===0?r:et(r))}if(t.exitCode!==0)throw U(e.action,et(new a(`COMMAND_FAILED`,`Android automation helper failed`,ke(t,{helper:n}))));return e.readResult(n)}function za(e){let t=nr(e).results.find(e=>e.agentDeviceProtocol===Cr);if(!t)throw new a(ka,`Android automation helper did not return a final result`);if(t.ok!==`true`)throw new a(Aa,t.message&&t.message!==`null`?t.message:t.errorType||`Android automation helper returned an error`,{errorType:t.errorType,helper:t});return t}function Ba(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:M(e.injectedEvents),elapsedMs:M(e.elapsedMs)}}function Va(e){let t=M(e.x),n=M(e.y),r=M(e.width),i=M(e.height);if(t===void 0||n===void 0||r===void 0||i===void 0)throw new a(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=Ha(e);return{viewport:ur({x:t,y:n,width:r,height:i}),...o?{keyboard:o}:{}}}function Ha(e){let t=M(e.keyboardX),n=M(e.keyboardY),r=M(e.keyboardWidth),i=M(e.keyboardHeight);if(t!==void 0&&n!==void 0&&r!==void 0&&i!==void 0)return{x:t,y:n,width:r,height:i}}function Ua(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...pt(e.durationMs,`android`),...i.map(({offsetMs:e})=>e)])].sort((e,t)=>e-t),o=0,s=a.map(e=>{for(;o<i.length-2&&e>i[o+1].offsetMs;)o+=1;let n=i[o],r=i[o+1],a=r.offsetMs-n.offsetMs,s=(e-n.offsetMs)/a;return{offsetMs:e,point:e===r.offsetMs||a===0?r.point:ht(n.point,r.point,t===`controlled`?Wa(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function Wa(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function Ga(e,t){let n=Ua(t),r=Fe(e);if(r){let e=n.intent===`longPress`?{...n,viewport:ur(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await ja(e,n)}async function Ka(e,t={}){return(await qa(e,t)).viewport}async function qa(e,t={}){let n=Fe(e);return n?{viewport:ur(await n.gestureViewport())}:await Ma(e,t)}async function W(e,t,n){try{await E(e,[`input`,`tap`,t,n])}catch(e){throw $e(e)}}async function Ja(e,t,r){await W(e,t,r);try{await W(e,t,r)}catch(e){throw n(e,1)}}async function Ya(e,t,n){let r=Ae(t);await E(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Xa(e){await E(e,[`input`,`keyevent`,`4`])}async function Za(e){await E(e,[`input`,`keyevent`,`3`])}async function Qa(e){await E(e,[`input`,`keyevent`,`ENTER`])}async function $a(e,t){let n=fo(t);await E(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await E(e,[`settings`,`put`,`system`,`user_rotation`,n]),await to(e,t,n)}const eo=15e3;async function to(e,t,n){let r=Date.now()+eo,i=await no(e,t,r);for(;i!==void 0&&i!==n&&Date.now()<r;)await _(Math.min(500,ro(r))),i=await no(e,t,r);if(i!==void 0&&i!==n)throw new a(`COMMAND_FAILED`,`orientation ${t} did not take effect: the display still reports rotation ${i} after ${eo}ms`,{requestedRotation:Number(n),observedRotation:Number(i),hint:"The foreground app may pin its orientation, or the device may ignore user_rotation. Check `adb shell dumpsys display | grep mCurrentOrientation` and the app manifest."})}async function no(e,t,n){try{return(await io(e,{timeoutMs:ro(n)}))[0]}catch(e){throw new a(`COMMAND_FAILED`,`orientation ${t} could not confirm the display rotation: ${e instanceof Error?e.message:String(e)}`,{hint:"The device did not answer `dumpsys display` within the orientation budget."})}}function ro(e){return Math.max(1,e-Date.now())}async function io(e,t){let n=await E(e,[`dumpsys`,`display`],{...t,allowFailure:!0});if(n.exitCode!==0)throw T(`adb shell dumpsys display exited with code ${n.exitCode}`,n);return[...n.stdout.matchAll(/mCurrentOrientation=(\d)/g)].map(e=>e[1])}async function ao(e,t){try{let n=await io(e,t);return n.length===1?we(Number(n[0])):void 0}catch{return}}async function oo(e){await E(e,[`input`,`keyevent`,`187`])}async function so(e,t,n,r=800){let i={x:t,y:n};return await Ga(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function co(e,t,n){await W(e,t,n)}async function lo(e,t,n){let{viewport:r,keyboard:i}=await qa(e,{helperSessionScope:n?.helperSessionScope}),a=uo(t,r,i),o=ue({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a.viewport.width,referenceHeight:a.viewport.height}),s={...o,referenceWidth:a.viewport.x+a.viewport.width,referenceHeight:a.viewport.y+a.viewport.height,x1:a.viewport.x+o.x1,y1:a.viewport.y+o.y1,x2:a.viewport.x+o.x2,y2:a.viewport.y+o.y2},c=Math.max(n?.durationMs??300,16),l=await Ga(e,{...mt({intent:`pan`,origin:{x:s.x1,y:s.y1},delta:{x:s.x2-s.x1,y:s.y2-s.y1},durationMs:c},a.viewport,`android`),releaseBehavior:n?.releaseBehavior??`controlled`});return{...s,...a.evidence,...n?.durationMs===void 0?{}:{durationMs:c},...l}}function uo(e,t,n){if(n===void 0)return{viewport:t,evidence:{}};let r=de(t,n);if(r.kind===`occluded`)throw le(e,{keyboardMinY:r.keyboardMinY,visibleHeight:r.visibleHeight,viewportHeight:t.height});return r.kind===`avoided`?{viewport:r.viewport,evidence:{keyboardAvoided:!0,keyboardMinY:r.keyboardMinY}}:{viewport:t,evidence:{}}}function fo(e){let t=Ce[e];if(t===void 0)throw new a(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(t)}async function po(e){let t=(await E(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new a(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(t[1]),height:Number(t[2])}}async function mo(e,t,n){return t===`wait`?await ho(n.captureNodes,n.timeoutMs??1e4):t===`get`?xo((await bo(n.captureNodes))?.alert??null):await go(e,t,n.captureNodes)}async function ho(e,t){let n=Date.now(),r=await yo(e,t);if(!r)throw new a(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:r.alert,waitedMs:Date.now()-n,...fe(`Alert visible`)}}async function go(e,t,n){let r=await yo(n,pe);if(!r)throw new a(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let i=Rn(r.buttons,t);if(i)return await W(e,i.x,i.y),await _o(r.alert,t,n),So(t,r.alert,i.label,{x:i.x,y:i.y});if(t===`dismiss`)return await Xa(e),await _o(r.alert,t,n),So(t,r.alert,`Back`);throw new a(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function _o(e,t,n){let r=Date.now();for(;;){let i=await bo(n);if(!i||!vo(i.alert,e))return;if(Date.now()-r>=2e3)throw new a(`COMMAND_FAILED`,`alert ${t} did not dismiss the visible alert`,{alert:e,hint:`The alert button was pressed but the dialog is still visible. Inspect alert get --json, then press the visible button by label/ref or retry.`});await _(300)}}function vo(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function yo(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await bo(e);if(t)return t;await _(300)}return null}async function bo(e){return In(await h(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function xo(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function So(e,t,n,r){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...r?{coordinates:r}:{},...fe(`Alert ${e}ed`)}}const Co=`android.intent.category.LAUNCHER`,wo=`android.intent.category.DEFAULT`;async function To(e,t){await y(e,[`am`,`force-stop`,t])}async function Eo(e,t,n=[Co]){for(let r of n){let n=await y(e,[`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=Bt(n.stdout);if(i)return i}return null}async function Do(e,t,n={}){let r=n.category??Co;if(n.activity){await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,wo,`-c`,r,`-n`,Oo(t,n.activity)]);return}let i=await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,wo,`-c`,r,`-p`,t],{allowFailure:!0});if(i.exitCode===0&&!Vt(i.stdout,i.stderr))return;let o=await Eo(e,t,[r]);if(!o)throw new a(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${t}`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});await y(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,wo,`-c`,r,`-n`,o])}function Oo(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let ko=null;function Ao(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function jo(e){let t=Ao(e);if(ko?.key===t)return ko.invocation;if(await Ee(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return ko={key:t,invocation:e},e}let n=await Te(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!n)throw new a(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let r={cmd:`java`,prefixArgs:[`-jar`,n]};return ko={key:t,invocation:r},r}async function Mo(e,t,n){let r=await jo(n);await De(r.cmd,[...r.prefixArgs,...e],{signal:t})}function No(e){return A.extname(e).toLowerCase()===`.aab`}async function Po(e,t,n={}){let r=S(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=b().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=A.join(o,`bundle.apks`);try{await Mo([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??b().environment),await Mo([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??b().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function Fo(e,t,n={}){if(No(t)){await Po(e,t,n);return}await Ue(t,{device:e,replace:!0,signal:n.signal})}async function Io(e,t,n={}){await Gt(e,async()=>{e.booted||await It(e.id,void 0,n.signal),await Fo(e,t,n)})}const Lo=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],Ro=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),zo=new Set([32,208]),Bo=new Set([128,224,144]);async function Vo(e){return await G(v(e))}async function G(e){let t=await y(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw T(`Failed to query Android keyboard state`,t);return Wo(t.stdout)}async function Ho(e){return await Uo(v(e))}async function Uo(e){let t=await G(e),r=t,i=0;try{for(;r.visible&&i<2;)await y(e,[`input`,`keyevent`,`111`]),i+=1,await _(120),r=await G(e)}catch(e){throw n(e,i)}if(t.visible&&r.visible)throw new a(`UNSUPPORTED_OPERATION`,`Android keyboard dismiss is unavailable for the current IME without back navigation.`,{attempts:i,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner});return{attempts:i,wasVisible:t.visible,dismissed:t.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}function Wo(e){let t=Yo(e)??Go(e),n=Ko(e),r=qo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=qo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=ut(e),o=ft(r,i,a);return Jo(r,i,a),{visible:t??!1,inputType:n,type:n?$o(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function Go(e){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/)?.[1];if(!t)return null;let n=Number.parseInt(t,16);return Number.isNaN(n)?null:!!(n&1)}function Ko(e){let t=qo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function qo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function Jo(e,t,n){n||!ct(e)&&!st(t)||g({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Yo(e){return Zo(Xo(e,Lo))}function Xo(e,t){let n=new Map,r=RegExp(`\\b(${t.join(`|`)})=([a-zA-Z]+)\\b`,`g`);for(let t of e.matchAll(r)){let e=t[1],r=t[2]?.toLowerCase();!e||r!==`true`&&r!==`false`||n.set(e,r===`true`)}return n}function Zo(e){if(e.size===0)return null;let t=Qo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Qo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Qo(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function $o(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=Ro.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return zo.has(i)?`email`:Bo.has(i)?`password`:`text`}async function es(e){return await ts(v(e))}async function ts(e){return as(await is(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function ns(e,t){await rs(v(e),t)}async function rs(e,t){await is(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function is(e,t,n){let{androidClipboardShellCommandUnavailableError:r,classifyAndroidClipboardShellResponse:i}=await import(`./clipboard-shell-response.js`),a=await y(e,t,{allowFailure:!0}),o=i(a);if(o===`no-shell-command`)throw r(n);if(o===`call-failed`)throw T(`Failed to ${n} Android clipboard text`,a);return a.stdout}function as(e){let t=e.replaceAll(`\r
|
|
9
9
|
`,`
|
|
10
|
-
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}
|
|
11
|
-
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`List of devices`)).map(e=>e.split(/\s+/)).filter(e=>e[1]===`device`).map(e=>e[0])}catch{return[]}}const Ss=2e3;async function Cs(e,t,n=b().files){let r=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,i=await Bs(r,n),a=await Ht(`adb`,[`version`]),o=a===void 0?void 0:Vt(a);if(!a||!o)return zs(r,i);let s=t===`win32`?void 0:Ps(a);return s?Fs({windowsAdb:s,sdkRoot:r,versionLine:o}):Is({license:i,sdkRoot:r,versionLine:o})}async function ws(e,t){if(e.platform!==`android`)return[];let n=v(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await As(n,e.id,t.metroPort)),r.push(await Ts(n,e)),r}async function Ts(e,t){try{let n=await K(e),r=ps(t);return n===await Es()&&!r?await Ds(e,t,n):Os(t,n,r)}catch(e){return ks(e)}}async function Es(){try{return(await Jo()).manifest.serviceComponent}catch{return}}async function Ds(e,t,n){let r=(await y(e,[`settings`,`get`,`secure`,os.previousIme],{allowFailure:!0,timeoutMs:Ss})).stdout.trim(),i=r&&r!==`null`?r:void 0;return{id:`android-test-ime`,status:`fail`,summary:`Android test IME helper is the active input method on ${t.id}, but no active session owns it -- likely left over from a crashed session.`,hint:`A stuck test IME leaves the real keyboard unavailable on this device until restored.`,command:i?`adb -s ${t.id} shell ime set ${i}`:`adb -s ${t.id} shell ime list -s`,evidence:{currentIme:n,previousIme:i}}}function Os(e,t,n){return{id:`android-test-ime`,status:`pass`,summary:n?`Android test IME helper is active for this session on ${e.id}.`:`Android test IME helper is not active on ${e.id}; the device's normal IME is in use.`,evidence:{currentIme:t}}}function ks(e){let t=i(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function As(e,t,n){try{let r=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:Ss}),i=`tcp:${n} tcp:${n}`,a=r.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${n}.`:`Android adb reverse is missing for Metro port ${n}.`,command:a?void 0:`adb -s ${t} reverse tcp:${n} tcp:${n}`,evidence:{stdout:r.stdout.trim()}}}catch(e){let t=i(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function js(e){return/^Installed as (.+)$/m.exec(e)?.[1]?.trim()}function Ms(e){return/^(?:[A-Za-z]:[\\/]|\\\\)/.test(e)}function Ns(e){return/^Running on Windows\b/m.test(e)}function Ps(e){let t=js(e);if(t&&Ms(t))return{detectedVia:`installed-as-path`,adbPath:t};if(Ns(e))return{detectedVia:`running-on-line`,adbPath:void 0}}function Fs(e){let{adbPath:t,detectedVia:n}=e.windowsAdb;return{id:`toolchain`,status:`fail`,summary:`Android toolchain: adb on PATH${t?` (${t})`:``} is a Windows binary, which cannot use this host's file paths.`,hint:`adb must be a native binary for this host: install this host's Android platform-tools, put them first on PATH, and point ANDROID_HOME at an SDK on this host's filesystem. Under WSL that means a Linux SDK, not one under /mnt/<drive>.`,evidence:{reason:`android_adb_windows_binary_on_posix_host`,detectedVia:n,adbPath:t??null,adbVersion:e.versionLine,androidHome:e.sdkRoot??null}}}function Is(e){return{id:`toolchain`,status:Ls(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${Rs(e.sdkRoot)}.`:`Android toolchain: adb is present but version check failed.`,hint:e.license===`missing`?`Accept Android SDK licenses before installing/building apps.`:void 0,command:e.license===`missing`?`sdkmanager --licenses`:void 0,evidence:{adbVersion:e.versionLine??null,androidHome:e.sdkRoot??null,license:e.license}}}function Ls(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function Rs(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function zs(e,t){return{id:`toolchain`,status:`info`,summary:`Android toolchain: adb not found on PATH.`,hint:`Install Android platform-tools or add adb to PATH.`,evidence:{androidHome:e??null,license:t}}}async function Bs(e,t){if(!e)return`unknown`;try{return await t.access(D.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Vs(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=Gs(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Us(t.targetInput),actualInput:Us(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function Y(e){return e?e.password?!0:Hs(e.text):!1}function Hs(e){return e?Array.from(e).every(Ws):!1}function Us(e){if(!e)return null;let t=Y(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Ws(e){return e===`•`||e===`*`||e===`●`}function Gs(e){return e.masked===!0||Y(e.targetInput)||Y(e.actualInput)}const Ks=new WeakMap;function qs(e,t){return t&&Ks.set(e,t),e}function Js(e){return Ks.get(e)}function Ys(e){return e.clickable}function Xs(e){return e.focusable||e.focused===!0}function X(e){return Ys(e)||Xs(e)}function Zs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Qs(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function $s(e,t,n){if(!e)return;let r=nc(e);return t&&(r=tc(r,t)),n&&(r=tc(r,n)),r}function ec(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ue(e.effectiveRect)?!0:void 0}}function tc(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height),o=i>n&&a>r;return{x:o?n:e.x,y:o?r:e.y,width:o?i-n:0,height:o?a-r:0}}function nc(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function rc(e,t){let n=new Set;return ic(e,n,t),oc(e,n,t),n}function ic(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}ic(r,t,n)}}function ac(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function oc(e,t,n){let r=ac(e,t,n).filter(cc);if(r.length<2)return;let i=r.filter(e=>lc(e)&&uc(e));if(i.length===0)return;let a=sc(i);for(let r of ac(e,t,n))n?.check(`work`),lc(r)&&(uc(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function sc(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function cc(e){return e.windowIndex!==void 0||e.windowType!==void 0}function lc(e){return e.windowType===1}function uc(e){return e.windowActive===!0||e.windowFocused===!0}function dc(e,t,n,r,i){let a=new Set(e.sourceNodes),o=pc(t,i),s=fc(o,n,mc(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(pc([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:le(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function fc(e,t,n,r){for(let i of e)if(r.check(`work`),oe(i,t)&&n.has(i))return i;return null}function pc(e,t){let n=[],r=[...e].reverse();for(;r.length>0;){t.check(`work`);let e=r.pop();n.push(e);for(let n=e.children.length-1;n>=0;--n)t.check(`work`),r.push(e.children[n])}return n}function mc(e,t,n){let r=new Set;for(let i=e.length-1;i>=0;--i){n.check(`work`);let a=e[i];if(t.has(a)){r.add(a);continue}for(let e of a.children)if(n.check(`work`),r.has(e)){r.add(a);break}}return r}function hc(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=gc(e);return t.interactiveOnly?_c(e,a,n,r,i):a.isStructural||a.isVisual?bc(e,a,r):!0}function gc(e){let t=Sc(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Zs(e.label??``),hasMeaningfulId:r&&!Zs(e.identifier??``),isStructural:Cc(t),isVisual:t===`imageview`||t===`imagebutton`}}function _c(e,t,n,r,i){return yc(e)?!1:X(e)||se(t.type)&&r?!0:vc(t,n,r,i)}function vc(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function yc(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function bc(e,t,n){return X(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function xc(e){if(!e)return!1;let t=Sc(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function Sc(e){return e?e.toLowerCase():``}function Cc(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function wc(e,t,n,r){return{...Qs(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const Tc=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var Z=class extends Error{code=Tc;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function Ec(e){return e instanceof Z?e.code===Tc:!!(e&&typeof e==`object`&&e.code===Tc)}var Dc=class{workUnits=0;options;defaultMaxWorkUnits;deadlineAtMs;constructor(e,t){this.options=e,this.defaultMaxWorkUnits=t;let n=e.now??Date.now;this.deadlineAtMs=e.deadlineAtMs??n()+Mc()}get workUnitCount(){return this.workUnits}check(e){this.consume(1)}consume(e){this.workUnits+=e;let t=this.options.maxWorkUnits??this.defaultMaxWorkUnits;if(this.workUnits>t)throw new Z(`Android snapshot presentation exceeded its linear work budget`,{phase:`complexity`,workUnits:this.workUnits,maxWorkUnits:t});if((this.options.now??Date.now)()>=this.deadlineAtMs)throw new Z(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function Oc(e,t){return new Dc(e??{},t)}function kc(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=Ac(i,r,t),a=i.effectiveRect;if(!a||!ue(a)){if(ec(i).hittable===!0)throw new Z(`Android regular snapshot node ${i.raw.index} with degenerate effective geometry was marked hittable`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a});r.set(i.raw.index,e);continue}if(e&&!jc(a,e))throw new Z(`Android regular snapshot node ${i.raw.index} escaped its cumulative clip`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a,clip:e});r.set(i.raw.index,i.clipsDescendants?a:e)}}function Ac(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function jc(e,t){let n=1e-4;return e.x>=t.x-n&&e.y>=t.y-n&&e.x+e.width<=t.x+t.width+n&&e.y+e.height<=t.y+t.height+n}function Mc(){return 250}function Nc(e,t,n){let r=n.depth??1/0,i=ce(n.scope),a=Zc(e),o=Oc(n.androidPresentation,Math.max(1024,a.rawNodeCount*128)),s={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:i?1/0:r,options:n,analysis:a,interactiveDescendantMemo:new Map,hidden:new Set,presentationBudget:o,presentationNodes:[],truncated:!1};try{o.check(`work`),s.viewport=Wc(e,o),s.hidden=n.raw?new Set:rc(e,o);for(let t of e.children)if(Fc(s,t,0),s.truncated)break;n.raw||kc(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?dc(s,e.children,i,r,o):s,u={nodes:c,sourceNodes:l,occlusionContext:{nodes:t,sourceIndexByNodeIndex:new Map(l.flatMap((e,t)=>{let n=a.get(e),r=c[t]?.index;return n===void 0||r===void 0?[]:[[r,n]]})),androidSiblingOrderByNodeIndex:Pc(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw Ec(e)&&(e.analysis??=s.analysis),e}}function Pc(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Js(i);if(!e)continue;let a=t.get(e.parent);a===void 0&&(a=t.size,t.set(e.parent,a)),n.set(r,{group:a,order:e.order})}return n}function Fc(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Ic(e,t,n))return;let l=t.windowRect??s??e.viewport,u=Lc(e,t,c,l),d=Rc(e,t,r,i,a,o,u,l),f=i||X(t),p=a||xc(t.type),m=zc(e,t,u,c);Bc(e,t,n,d,f,p,o||Wt(t.identifier),l,m)}function Ic(e,t,n){return e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes?(e.truncated=!0,!0):n>e.maxDepth||e.hidden.has(t)}function Lc(e,t,n,r){return e.options.raw?t.rect:$s(t.rect,r,n)}function Rc(e,t,n,r,i,a,o,s){return!e.options.raw&&!hc(t,e.options,r,qc(e,t),i)?n:Vc(e,t,n,a||Wt(t.identifier),o,s)}function zc(e,t,n,r){return e.options.raw||!Gc(t)?r:n}function Bc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Fc(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Vc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Uc(e,t,Hc(e,t,n,r),i,a),o}function Hc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,...t.passiveFacts,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,focused:t.focused,visibleToUser:t.visibleToUser,hittable:X(t)||void 0,depth:Kc(e.nodes,n),parentIndex:n,...Jc(t,e.hidden),...r?{systemChrome:!0}:{}}}function Uc(e,t,n,r,i){let a=wc(n,r,!e.options.raw&&Gc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:ec(a))}function Wc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ue(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return de(n)??void 0}function Gc(e){return e.scrollable===!0&&se(e.type)}function Kc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function qc(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(!e.hidden.has(n)&&n.visibleToUser!==!1&&(X(n)||qc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Jc(e,t){return Yc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Yc(e,t){if(!e.scrollable||!se(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Xc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Xc(e,t){let n=e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1);if(!e.rect||n.length===0)return null;let r=n.map(e=>e.rect).filter(e=>e!==void 0);if(r.length===0)return null;let i=Math.min(...r.map(e=>e.x)),a=Math.max(...r.map(e=>e.x+e.width)),o=Math.min(...r.map(e=>e.y)),s=Math.max(...r.map(e=>e.y+e.height));return{horizontal:Math.max(0,a-i-e.rect.width),vertical:Math.max(0,s-o-e.rect.height)}}function Zc(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function Qc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||Wt(n);return r||e.push(i),i},close(){e.pop()}}}function*$c(e){let t=/<node\b[^>]*>|<\/node>/g,n=Qc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=el(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function el(e){let t=tl(e),n=Gt(t.bounds);return{...t,...n?{rect:n}:{}}}function tl(e){let t=nl(e),n=e=>ul(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=Gt(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let r=n(t);return r===null||r===``?{}:{[e]:r}},c=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...c(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...c(`hintShowing`,`hint-showing`),...s(`hint`,`hint`),...c(`visibleToUser`,`visible-to-user`),...c(`selected`,`selected`),...c(`heading`,`heading`),...s(`roleDescription`,`role-description`),...c(`checked`,`checked`),...a(`drawingOrder`,`drawing-order`),...c(`scrollable`,`scrollable`),...c(`canScrollForward`,`can-scroll-forward`),...c(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...c(`windowActive`,`window-active`),...c(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function nl(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=rl(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function rl(e,t,n){if(t=al(e,t,n),t>=n||ol(e[t]))return;let r=t;t=il(e,t,n);let i=e.slice(r,t);if(t=al(e,t,n),!i||e[t]!==`=`)return;t=al(e,t+1,n);let a=e[t];if(!sl(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Kt(e.slice(o,s)),nextCursor:s+1}}function il(e,t,n){for(;t<n&&!ll(e[t]??``);)t+=1;return t}function al(e,t,n){for(;t<n&&cl(e[t]??``);)t+=1;return t}function ol(e){return e===`/`||e===`>`}function sl(e){return e===`"`||e===`'`}function cl(e){return e===` `||e===`
|
|
12
|
-
`||e===`\r`||e===` `}function ll(e){return e===`=`||e===`/`||e===`>`||cl(e)}function ul(e,t){return e.get(t)??null}function dl(e){let t={type:null,label:null,value:null,passiveFacts:{},identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=el(t),o=n.at(-1),s=fl(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function fl(e,t,n){let r=e.text||e.desc;return qs({type:e.className,label:r,value:e.text,passiveFacts:{contentDescription:e.desc&&e.desc!==r?e.desc:void 0,enabled:e.enabled,selected:e.selected,heading:e.heading,roleDescription:e.roleDescription,checked:e.checked,editable:e.editable,password:e.password,hintShowing:e.hintShowing,placeholder:e.hint,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd},identifier:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function pl(e){let t=new Map;return e.nodes.forEach((n,r)=>{t.set(n.index,e.sourceNodes[r]?.clickable)}),{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:t}}const ml=new Set([`android`,`com.android.systemui`]);function hl(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=El(e,n.foregroundAppPackage);return vl(r,t)?gl(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):wl(r)?{outcome:`ok`}:_l(r)?{outcome:`system-surface-only`}:yl(r)?{outcome:`ok`}:bl(r)?gl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):xl(r)||Sl(r,t)?gl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):Cl(r)?gl(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function gl(e,t,n,r){return{outcome:`unusable`,decision:Tl(e,t,n,r)}}function _l(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function vl(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function yl(e){return bl(e)&&e.inputMethodMeaningfulNodeCount>=2}function bl(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function xl(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function Sl(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function Cl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function wl(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function Tl(e,t,n,r){return{reason:n,failureReason:r,diagnostics:Bl(e,t)}}function El(e,t){let n=Dl(t);for(let t of $c(e))Ol(n,t);return Fl(n)}function Dl(e){return{nodeCount:0,systemUiNodeCount:0,windowRootCount:0,applicationWindowRootCount:0,activeSystemSurfaceMeaningfulNodeCount:0,meaningfulNodeCount:0,applicationMeaningfulNodeCount:0,nonSystemMeaningfulNodeCount:0,inputMethodMeaningfulNodeCount:0,hasAlertButtonIdentifier:!1,hasAlertContentIdentifier:!1,...e===void 0?{}:{foregroundAppPackage:e,foregroundAppMeaningfulNodeCount:0},windowTypes:new Set}}function Ol(e,t){e.nodeCount+=1,zl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&kl(e,t.resourceId),Al(e,t),jl(e,t)}function kl(e,t){let n=dn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function Al(e,t){t.windowType!==void 0&&(e.currentWindowType=t.windowType,e.currentWindowActiveOrFocused=t.windowActive===!0||t.windowFocused===!0,e.windowRootCount+=1,e.windowTypes.add(t.windowType),t.windowType===1&&(e.applicationWindowRootCount+=1))}function jl(e,t){Il(t)&&(e.meaningfulNodeCount+=1,Ml(e,t),Pl(e,t))}function Ml(e,t){e.currentWindowType===1&&!Rl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),Nl(e)&&!Ut(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function Nl(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Pl(e,t){Rl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),re({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function Fl(e){return{nodeCount:e.nodeCount,systemUiNodeCount:e.systemUiNodeCount,windowRootCount:e.windowRootCount,applicationWindowRootCount:e.applicationWindowRootCount,activeSystemSurfaceMeaningfulNodeCount:e.activeSystemSurfaceMeaningfulNodeCount,meaningfulNodeCount:e.meaningfulNodeCount,applicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,nonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,inputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,hasAlertButtonIdentifier:e.hasAlertButtonIdentifier,hasAlertContentIdentifier:e.hasAlertContentIdentifier,...e.foregroundAppPackage===void 0?{}:{foregroundAppPackage:e.foregroundAppPackage,foregroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount??0},windowTypes:[...e.windowTypes].sort((e,t)=>e-t).slice(0,8)}}function Il(e){return e.visibleToUser===!1?!1:Ll(e.text)||Ll(e.desc)||Ll(e.resourceId)}function Ll(e){return e!==null&&e.trim()!==``}function Rl(e){return e===null||ml.has(e)}function zl(e){return e!==null&&ml.has(e)}function Bl(e,t){return{helperNodeCount:e.nodeCount,helperSystemUiNodeCount:e.systemUiNodeCount,helperWindowRootCount:e.windowRootCount,helperApplicationWindowRootCount:e.applicationWindowRootCount,helperMeaningfulNodeCount:e.meaningfulNodeCount,helperApplicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,helperNonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,helperInputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,...e.foregroundAppPackage===void 0?{}:{helperForegroundAppPackage:e.foregroundAppPackage,helperForegroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount,helperForegroundAppMeaningfulNodeThreshold:2},helperWindowTypes:e.windowTypes,...t.captureMode?{helperCaptureMode:t.captureMode}:{}}}async function Vl(e){let t=await B(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Hl(e.adb,e.packageName)}async function Hl(e,t){await ii({adb:e,packageName:t}),await _(150),g({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const Ul=Symbol(`androidSnapshotCaptureEvidence`);function Wl(e,t){return Object.defineProperty(e,Ul,{value:t}),e}function Gl(e){return pe({x:0,y:0,width:e.displayWidth??NaN,height:e.displayHeight??NaN})}function Kl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Ul];return ae(t,n.clickability),n.occlusionContext&&m(t,n.occlusionContext),t}async function ql(e,t={}){let n=S(e,t.helperAdb).exec;return(await tu(e,t,n)).xml}async function Jl(e,t={}){let n=S(e,t.helperAdb).exec,r=await tu(e,t,n),i=Gl(r.helperMetadata),a=r.xml,o=dl(a),s=Zl(r.metadata,o),c={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=Nc(o,void 0,c),n=Xl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&eu({options:c,tree:o,xml:a,interactiveSnapshot:e});let{sourceNodes:l,occlusionContext:u,...d}=e;return Wl({...d,...$l(n),androidSnapshot:s,quality:{state:`healthy`,backend:`android-helper`},...i?{viewport:i}:{}},{clickability:pl(e),occlusionContext:u})}catch(e){if(!Ec(e))throw e;return Yl({failure:e,androidSnapshot:s,...i?{viewport:i}:{}})}}function Yl(e){return Wl({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode},...e.viewport?{viewport:e.viewport}:{}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Xl(e,t){return e===!0||t.helperTruncated===!0||e}function Zl(e,t){return Ql(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Ql(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Js(e)!==void 0)return!0;t.push(...e.children)}return!1}}function $l(e){return e===!0?{truncated:!0}:{}}function eu(e){if(wu(e.interactiveSnapshot.nodes).size>0||Cu(e.xml))return;let t=Nc(e.tree,void 0,{...e.options,interactiveOnly:!1});Tu(De(l(t.nodes)),t,e.interactiveSnapshot)}async function tu(e,t,n){let r=S(e,t.helperAdb),i=await h(`android_snapshot_helper_artifact_resolution`,async()=>await xu(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await nu(e,t,n,i.artifact);throw g({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),Su(i.errorReason)}async function nu(e,t,n,r){let i=Wr(e),a=au(t,i);try{return await ru({options:t,adb:n,adbProvider:S(e,t.helperAdb),artifact:r,helperDeviceKey:i})}finally{a&&await B(i)}}async function ru(e){let{options:t}=e,n=iu(t),r=async(n,r)=>await fu({contentRecovery:n,attempts:r,helperDeviceKey:e.helperDeviceKey,artifact:e.artifact,adb:e.adb,signal:t.signal,retireHelper:t.transient===void 0}),i;for(let a=0;;a+=1){if(i&&(await du(t.signal),Date.now()>=n))return await r(i,a);let o=await uu({...e,attempt:a,previousContentReason:i?.reason});if(o.outcome===`captured`)return o.capture;if(a+1>=3||Date.now()>=n)return await r(o.decision,a+1);i=o.decision}}function iu(e){return Math.min(Date.now()+1e4,e.transient?.settleBy??1/0)}function au(e,t){return e.transient?Gi(t)===void 0:e.helperSessionScope!==`daemon-session`}function ou(e){return e.transient?`current-only`:e.helperInstallPolicy??`missing-or-outdated`}async function su(e,t,n,r,i){let a=await h(`android_snapshot_helper_install`,async()=>await yr({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:ou(e),timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:ou(e)});return g({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function cu(e){let{signal:t,adb:n,adbProvider:r,artifact:a,helperDeviceKey:o}=e,s=si({adb:n,adbProvider:r,artifact:a,deviceKey:o,signal:t});try{let e=await h(`android_snapshot_helper_session_capture`,async()=>await sa(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:rr});if(e)return e}catch(e){if(t?.throwIfAborted(),Jr(e))throw e;g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:i(e).message}}),await Hl(n,a.manifest.packageName)}return await h(`android_snapshot_helper_capture`,async()=>await oi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:rr,commandTimeoutMs:ir})}function lu(e,t,n){return{xml:e.xml,helperMetadata:e.metadata,metadata:{backend:`android-helper`,pixelDensity:e.metadata.pixelDensity,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function uu(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await su(t,n,r,i,a);e.installed&&await B(a),s=lu(await cu({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){if(t.signal?.throwIfAborted(),mr(e))throw e;return{outcome:`captured`,capture:await mu({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=hl(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});if(c.outcome===`unusable`)return{outcome:`unusable`,decision:c.decision};let l=c.outcome===`system-surface-only`;return!l&&o>0&&g({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,helperMetadata:s.helperMetadata,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function du(e){e?.throwIfAborted(),await _(250),e?.throwIfAborted()}async function fu(e){throw g({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),e.retireHelper&&await Vl({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),pu(e.contentRecovery,e.attempts)}function pu(e,t){return new a(`COMMAND_FAILED`,e.failureReason,{...e.diagnostics,androidSnapshotHelperFailureReason:e.reason,attempts:t,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function mu(e){let t=hu(e.error);throw g({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await B(e.helperDeviceKey),await Hl(e.adb,e.artifact.manifest.packageName),fr({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),gu(e.error,t)}function hu(e){let t=i(e),n=bu(t.details?.helper);if(n&&n!==t.message)return`${t.message}: ${n}`;if(n)return n;let r=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return r?`${t.message}: ${r}`:t.message}function gu(e,t){let n=i(e),r=_u(n);return new a(s(n.code),`Android snapshot helper failed: ${t}`,{...n.details,...yu(n),androidSnapshotHelperFailureReason:t,...r?{androidCaptureFailureReason:r}:{},hint:vu(n,r)},e)}function _u(e){return gt(e)}function vu(e,t){return t===`accessibility-timeout`?`Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists.`:e.details?.androidSnapshotHelperInstallFailure===!0?[e.hint,`This is a device-side install failure (adb rejection or OEM policy) — the helper artifact itself is present, this is not a missing/unbuilt build.`].filter(Boolean).join(` `):e.hint??`Retry once. If the helper still fails, run agent-device doctor and report the diagnostic log; agent-device does not substitute a second snapshot engine.`}function yu(e){let t={};return e.diagnosticId!==void 0&&(t.diagnosticId=e.diagnosticId),e.logPath!==void 0&&(t.logPath=e.logPath),e.retriable!==void 0&&(t.retriable=e.retriable),e.supportedOn!==void 0&&(t.supportedOn=e.supportedOn),t}function bu(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}async function xu(e){if(e)return{artifact:e};let t=Ie(),n=D.join(Le(),`android`,`snapshot-helper`,`dist`),r=D.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await b().files.access(r)}catch{return{}}try{let e=ar(JSON.parse(await b().files.readText(r))),t=D.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await b().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:i(e).message}}}function Su(e){let t=e??`the bundled helper artifact was not found`;return new a(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${t}`,{androidSnapshotHelperFailureReason:t,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function Cu(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function wu(e){let t=new Map;for(let n of e){let e={};n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n.index,e)}return t}function Tu(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}const Eu=Object.freeze({now:()=>Date.now(),sleep:_});async function Du(e,t,n,r,i={},a=Eu){let o=await qu(e),s=a.now()+1500,c=null;for(;;){let l=await Lu(e,t,n,r,o,i);if(l.reason===`ime_capture`)return l;let u=s-a.now();if(l.ok&&c?.ok||u<=0)return l;c=l,await a.sleep(Math.min(150,u))}}async function Ou(e,t,n,r={}){return Pu(await ql(e,r),t,n)}async function ku(e,t,n,r){let i=await qu(e);return Ru(await ql(e,r),t,n,i).targetInput}async function Au(e,t,n,r={}){try{return await ku(e,t,n,r)}catch(e){return g({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function ju(e,t,n){if(n?.ok)return;let r=n?Mu(e,t,n):null;if(r)return r;throw u(new a(`COMMAND_FAILED`,Fu(n),Iu(e,n)),`unknown`)}function Mu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||Y(t)||Y(r)||Y(i)||!$u(t,r)||!$u(t,i)||t.text===n.actual)return null;let a=ed(t);return g({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function Nu(e,t,n,r,i={}){let a=Ru(e,t,n,i);return zu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Bu(a,r)??Vu(a,r)}function Pu(e,t,n){return Ru(e,t,n).targetInput?.text??null}function Fu(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function Iu(e,t){let n=Vs(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function Lu(e,t,n,r,i,a){return Nu(await ql(e,a),t,n,r,i)}function Ru(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of $c(e)){let e=Ku(a,r);e&&Ju(i,e,t,n)}return Xu(i)}function zu(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Bu(e,t){let n=e.actualInput;if(!n||!Qu(n))return null;let r=n.text??null,i=Array.from(Hu(n)).length,a=Array.from(t).length,o=a===0?i===0:i>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function Vu(e,t){let n=e.actualInput;return{ok:n!==null&&Uu(Hu(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Hu(e){return e.hintShowing?``:e.text??``}function Uu(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=Wu(e),r=Wu(t);return!n||!r?!1:!!(n===r||Gu(n,r))}function Wu(e){return e.replaceAll(/\s+/g,` `).trim()}function Gu(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function Ku(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:re({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:Zu(e.className??``),hintShowing:e.hintShowing===!0,placeholder:e.hint??null}}async function qu(e){try{return{activeInputMethodPackage:(await Eo(e)).inputMethodPackage}}catch(e){return g({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Ju(e,t,n,r){let i=fe(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Yu(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Yu(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Yu(e.anyAtPoint,t))}function Yu(e,t){return e&&e.area<t.area?e:t}function Xu(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function Zu(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Qu(e){return Y(e)}function $u(e,t){return e.resourceId||t.resourceId?e.resourceId===t.resourceId&&e.packageName===t.packageName:e.className===t.className&&e.packageName===t.packageName&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}function ed(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function td(e,t){return await qt(t.stateDir),await ms(t.stateDir,e.id,async()=>await rd(e,t))}function nd(e){let t=r(e).details?.hint;return{outcome:`helper-unavailable`,reason:i(e).message,...typeof t==`string`?{hint:t}:{}}}async function rd(e,t){let n=b().imeRecoveryMarkers,r=v(e),i=S(e),a=G(e),o;try{o=await qo(i),await Zo({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return nd(e)}let{manifest:s}=o,c=await K(r);if(c===s.serviceComponent){let i=await n.write(t.stateDir,e.id),o=await q(r);return i&&J.add(a),{outcome:`settled`,activated:!1,alreadyActive:!0,...i?{}:{persistFailed:!0},previousIme:o,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}let l=await q(r);if(!await ss(r,c))return await ls(r,l,e.id),x({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let u=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await ls(r,l,e.id),x({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await y(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let d=await y(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),f=await K(r);return f===s.serviceComponent?(J.add(a),x({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:c}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:c,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}):(J.delete(a),await ls(r,l,e.id),u||await n.clear(t.stateDir,e.id),x({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:f,stderr:d.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName})}function id(e){return D.join(e,`android-test-ime-pending`)}function ad(e,t){return D.join(id(e),encodeURIComponent(t))}async function od(e,t){let n=b().files,r,a=!1;try{let i=id(e);if(r=ad(e,t),await n.ensureDirectory(i),(await ld(r))?.serial===t)return!0;let o={version:1,serial:t};if(await n.writeAtomicText(r,`${JSON.stringify(o)}\n`,384),a=!0,(await ld(r))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&r&&await n.remove(r,{force:!0}).catch(()=>{}),g({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:i(o).message}}),!1}}async function sd(e,t){await b().files.remove(ad(e,t),{force:!0}).catch(()=>{})}async function cd(e){let t=b().files,n;try{n=await t.readDirectory(id(e))}catch{return[]}let r=[];for(let t of n)try{let n=D.join(id(e),t),i=await ld(n);i&&ad(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function ld(e){try{return ud(await b().files.readText(e))}catch{return}}function ud(e){try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return;let n=t;return n.version===1&&typeof n.serial==`string`&&n.serial.length>0?{version:1,serial:n.serial}:void 0}catch{return}}const dd=new Xt(`utf-16le`);let fd;async function pd(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await md(e,n,t);if(!r)continue;let i=hd(r);if(i)return i}return await Md(e,t)}async function md(e,t,n){try{let r=await Me(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function hd(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?gd(e.toString(`utf8`)):_d(e)}function gd(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function _d(e){let t=bd(e);if(!t)return;let n;for(let r=t.treeHeaderSize;r+8<=t.dataEnd;){let i=vd(e,r,t.dataEnd);if(!i)return;if(i.type===1){if(n=Ed(e.subarray(r,r+i.chunkSize)),!n)return}else if(n){let t=yd(e,i,r,n);if(t)return t}r+=i.chunkSize}}function vd(e,t,n){let r=e.readUInt16LE(t),i=e.readUInt16LE(t+2),a=e.readUInt32LE(t+4);if(!(!xd(i,a)||t+a>n))return{type:r,headerSize:i,chunkSize:a}}function yd(e,t,n,r){if(t.type===258)return Sd(e,n,n+t.chunkSize,t.headerSize,r)}function bd(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!(!xd(t,n)||n>e.length))return{treeHeaderSize:t,dataEnd:n}}function xd(e,t){return e>=8&&e%4==0&&t%4==0&&e<=t}function Sd(e,t,n,r,i){if(r<16)return;let a=t+r;if(a+20>n||i[e.readUInt32LE(a+4)]!==`manifest`)return;let o=Cd(e,a,n);return o?wd(e,i,o):void 0}function Cd(e,t,n){let r=e.readUInt16LE(t+8),i=e.readUInt16LE(t+10),a=e.readUInt16LE(t+12);if(!(i<20||r<20)&&!(r+i*a>n-t))return{firstOffset:t+r,stride:i,count:a}}function wd(e,t,n){for(let r=0;r<n.count;r+=1){let i=n.firstOffset+r*n.stride;if(t[e.readUInt32LE(i+4)]===`package`)return Td(e,t,i)}}function Td(e,t,n){let r=e.readUInt32LE(n+8);if(r!==4294967295)return t[r];let i=e.readUInt8(n+15),a=e.readUInt32LE(n+16);return i===3?t[a]:void 0}function Ed(e){let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!xd(t,n)||t<28||n>e.length)return;let r=e.readUInt32LE(8),i=e.readUInt32LE(16),a=e.readUInt32LE(20),o=!!(i&256),s=t;if(s+r*4>n||a<s+r*4||a>=n)return;let c=[];for(let t=0;t<r;t+=1){let n=a+e.readUInt32LE(s+t*4);c.push(o?Dd(e,n):Od(e,n))}return c}function Dd(e,t){let n=Ad(e,t);if(!n)return;let r=Ad(e,t+n.bytes);if(!r)return;let i=t+n.bytes+r.bytes;return kd(e,i,r.value)?e.subarray(i,i+r.value).toString(`utf8`):void 0}function Od(e,t){let n=jd(e,t);if(!n)return;let r=t+n.bytes;return kd(e,r,n.value*2)?dd.decode(e.subarray(r,r+n.value*2)):void 0}function kd(e,t,n){return Number.isSafeInteger(t)&&Number.isSafeInteger(n)&&t+n<=e.length}function Ad(e,t){if(t+1>e.length)return;let n=e.readUInt8(t);if(!(n&128))return{value:n,bytes:1};if(!(t+2>e.length))return{value:(n&127)<<8|e.readUInt8(t+1),bytes:2}}function jd(e,t){if(t+2>e.length)return;let n=e.readUInt16LE(t);if(!(n&32768))return{value:n,bytes:2};if(!(t+4>e.length))return{value:(n&32767)<<16|e.readUInt16LE(t+2),bytes:4}}async function Md(e,t){t?.throwIfAborted();let n=await Nd();if(!n)return;let r=await Me(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function Nd(){if(fd!==void 0)return fd??void 0;try{let e=b().files,{hostPlatform:t}=await import(`./process.js`).then(e=>e.t);for(let n of Tt(void 0,t())){let t=D.join(n,`build-tools`);try{let n=(await e.readDirectory(t)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of n){let n=D.join(t,r,`aapt`);if(D.isAbsolute(n)&&await e.isExecutable(n))return fd=n,n}}catch{}}}catch{}fd=null}async function Pd(e,t){let n=await Re({source:e,isInstallablePath:(e,t)=>t.isFile()&&Fd(e),installableLabel:`Android installable (.apk or .aab)`,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await Id(n.installablePath,t?.signal);return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:e.packageName,cleanup:n.cleanup}}catch(e){throw await n.cleanup(),e}}function Fd(e){let t=D.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function Id(e,t){let n=D.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await pd(e,t)}}async function Ld(e,t,n,r={}){let i=typeof n.action==`string`&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,i,`-p`,t],s=typeof n.receiver==`string`?n.receiver.trim():``;s&&o.push(`-n`,s);let c=n.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new a(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Rd(o,e,t),u+=1);return await E(e,o,{signal:r.signal}),{action:i,extrasCount:u}}function Rd(e,t,n){if(typeof n==`string`){e.push(`--es`,t,n);return}if(typeof n==`boolean`){e.push(`--ez`,t,n?`true`:`false`);return}if(typeof n==`number`&&Number.isFinite(n)){if(Number.isInteger(n)){e.push(`--ei`,t,String(n));return}e.push(`--ef`,t,String(n));return}throw new a(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}function Q(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function zd(e){let t=Wd(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return Gd(n)}function Bd(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Vd(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>Ud({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function Hd(e){return Math.round(e*10)/10}function Ud(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:Hd(Math.max(...t.map(e=>e.durationNs))/1e6)}}function Wd(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function Gd(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}function Kd(e,t,n){qd(e,t);let r=rf(e),i=$d(e),a=Yd(i,r,t),o=Date.parse(n),s=of({frames:i,measuredAtMs:o,summary:r}),c=Bd({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??uf(i),u=Xd(r,i,c),d=Qd({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...Zd(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:`adb-shell-dumpsys-gfxinfo-framestats`,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function qd(e,t){if(/no process found for:/i.test(e))throw new a(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${t}`,{metric:`fps`,package:t,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function Jd(e){throw new a(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function Yd(e,t,n){let r=zd(e);if(!t&&e.length===0&&Jd(n),t||r!==void 0)return r;throw new a(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${n}`,{metric:`fps`,package:n,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Xd(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Jt(i/r*100):0)}}function Zd(e){return{frameDeadlineMs:e===void 0?void 0:Hd(e/1e6),refreshRateHz:e===void 0?void 0:Hd(1e9/e)}}function Qd(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Vd({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function $d(e){let t=[],n=null;for(let r of e.split(`
|
|
13
|
-
`)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(ef(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=tf(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function ef(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function tf(e,t){if(!t||e.length<t.size)return;let n=nf(e,t,`Flags`),r=nf(e,t,`IntendedVsync`),i=nf(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function nf(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function rf(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=df(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=Q(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=df(t,`Uptime`),l=df(t,`Stats since`);return{droppedFramePercent:Jt(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:af({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function af(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function of(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=sf(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=cf(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:lf({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function sf(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function cf(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function lf(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function uf(e){if(e.length===0)return;let t=sf(e);return cf(t.firstFrameNs,t.lastFrameNs)}function df(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:Q(i)??void 0}async function ff(e,t,n={}){let r=v(e,n.adb);try{let i=Kd((await y(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await pf(e,t,n),i}catch(e){throw mf(t,e)}}async function pf(e,t,n={}){let r=v(e,n.adb);try{await y(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function mf(e,t){return t instanceof a?new a(t.code,t.message,{...t.details??{},metric:`fps`,package:e},t):new a(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},t)}async function hf(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await gf(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function gf(e,t,n){try{let r=await ff(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}async function _f(e,t,n){let r=v(e,n.adb);await Cf(r,t),await Ef(r,t),await Tf(r,t,n.files);let i=await Sf(t.outPath,n.files);await bf(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await hf(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?Fr:Ir,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function vf(e,t,n={}){let r=v(e,n.adb);try{t.state===`running`&&(await Cf(r,t),await Ef(r,t).catch(()=>{}))}finally{await bf(r,t.remotePath)}}function yf(e,t,n=Rr){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function bf(e,t){try{await y(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:Lr})}catch{}}async function xf(e,t,n=b().files){await n.ensureDirectory(D.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function Sf(e,t=b().files){try{return(await t.stat(e)).size}catch(t){throw new a(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},t)}}async function Cf(e,t){try{await y(e,[C(wf(t.profilerPid))],{timeoutMs:P})}catch(e){throw N(`stop`,t.kind,t.packageName,e)}}function wf(e){return[`pid=${w(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function Tf(e,t,n){await(n??b().files).ensureDirectory(D.dirname(t.outPath));try{await e([`pull`,t.remotePath,t.outPath],{timeoutMs:P})}catch(e){throw new a(`COMMAND_FAILED`,`Failed to pull Android ${t.kind} artifact for ${t.packageName}`,{package:t.packageName,tool:t.kind,remotePath:t.remotePath,outPath:t.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function Ef(e,t){let n;for(let r=0;r<12;r+=1){let r=await Df(e,t.remotePath);if(r!==void 0&&r>0&&r===n)return;n=r,await _(250)}throw new a(`COMMAND_FAILED`,`Android ${t.kind} artifact is not ready to pull`,{package:t.packageName,tool:t.kind,remotePath:t.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function Df(e,t){let n=w(t),r=await y(e,[C(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:Lr});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function Of(e,t,n,r={}){let i=v(e,r.adb),a=await zr(i,t);await Br(i,`perfetto`,t);let o=yf(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await pf(e,t,{adb:i}),s=await Af(i,o,t)}catch(e){throw await bf(i,o),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:Ir,message:`Started Android Perfetto trace for ${t}`}}async function kf(e,t,n,r={}){return await _f(e,{...t,outPath:n},r)}async function Af(e,t,n){try{let r=Vr((await y(e,[`perfetto`,`--background-wait`,`-o`,t,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:P})).stdout);if(r)return r;throw new a(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:n,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw N(`start`,`perfetto`,n,e)}}function jf(e){let t=[];for(let n of d(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:Jt(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Mf(e,t,n,r={}){let i=v(e,r.adb),a=await zr(i,t);await Br(i,`simpleperf`,t);let o=yf(t,`cpu.perf.data`),s;try{s=await Ff(i,a,o,t)}catch(e){throw await bf(i,o),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:Fr,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Nf(e,t,n,r={}){return await _f(e,{...t,outPath:n},r)}async function Pf(e,t,n,r={}){let i=v(e,r.adb);await Br(i,`simpleperf`,t.packageName);let a=await Rf(i,t),o=new Date().toISOString(),s=jf(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await xf(n,{kind:`simpleperf-report`,generatedAt:o,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:s.length,summary:{topFunctions:c},entries:s},r.files);let l=await Sf(n,r.files);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:l,generatedAt:o,entryCount:s.length,summary:{topFunctions:c},method:Fr,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function Ff(e,t,n,r){try{let i=Vr((await y(e,[C(If(t,n))],{timeoutMs:P})).stdout);if(i)return i;throw new a(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:r,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw N(`start`,`simpleperf`,r,e)}}function If(e,t){return Lf([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function Lf(e,t){let n=e.map(w).join(` `),r=`${Rr}/agent-device-${t}-${Date.now()}.err`;return[`err=${w(r)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function Rf(e,t){try{return await y(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:P})}catch(e){throw N(`report`,`simpleperf`,t.packageName,e)}}const zf=15e3,Bf=12e4;async function Vf(e,t,n={}){let r=v(e,n.adb);try{return Gf((await y(r,[`dumpsys`,`meminfo`,t],{timeoutMs:zf})).stdout,t,new Date().toISOString())}catch(e){throw $f(`memory`,t,e)}}async function Hf(e,t,n,r={}){let i=v(e,r.adb),o=r.files??b().files,s=await Kf(i,t),c=qf(t);await o.ensureDirectory(D.dirname(n));let l=await Uf(o,n);try{Ne(await y(i,[`am`,`dumpheap`,t,c],{allowFailure:!0,timeoutMs:Bf}),`Failed to capture Android heap dump for ${t}`,e=>({kind:`android-hprof`,package:t,pid:s,remotePath:c,hint:Jf(e.stdout,e.stderr)}));let e=await i([`pull`,c,n],{allowFailure:!0,timeoutMs:Bf});if(e.exitCode!==0)throw await Wf(o,n,l),T(`Failed to pull Android heap dump for ${t}`,e,{kind:`android-hprof`,package:t,pid:s,remotePath:c,path:n,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let r=await o.stat(n).catch(()=>null);if(!r?.isFile||r.size<=0)throw await Wf(o,n,l),new a(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:t,pid:s,path:n,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:n,sizeBytes:r.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:t,pid:s,remotePath:c}}finally{await y(i,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:zf}).catch(()=>{})}}async function Uf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Wf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function Gf(e,t,n){if(/no process found for:/i.test(e))throw new a(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${t}`,{metric:`memory`,package:t,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let r=ep(e,`TOTAL PSS`)??tp(e);if(r===void 0)throw new a(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${t}`,{metric:`memory`,package:t,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:r,totalRssKb:ep(e,`TOTAL RSS`),measuredAt:n,method:`adb-shell-dumpsys-meminfo`,topConsumers:Yf(e)}}async function Kf(e,t){let n=await y(e,[`pidof`,t],{allowFailure:!0,timeoutMs:zf}),r=n.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(n.exitCode===0&&r!==void 0)return r;throw new a(`COMMAND_FAILED`,`No running Android process found for ${t}`,{kind:`android-hprof`,package:t,stdout:n.stdout,stderr:n.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function qf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function Jf(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Yf(e){let t=e.split(`
|
|
14
|
-
`).flatMap(e=>
|
|
15
|
-
`)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>
|
|
16
|
-
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function
|
|
17
|
-
`).map(e=>e.trim()).filter(e=>e.length>0),n=t[0]??`unknown device error`;return(n.endsWith(`:`)&&t[1]?`${n} ${t[1]}`:n).slice(0,200)}async function Lp(e,t,n,r,i){if(n.kind===`notifications`)return await Kp(e,t,`grant`,n,i),[n.permission];if(n.kind===`photos`)return[await Gp(e,t,`grant`,i)];if(n.kind===`pm`){let a=[...await Bp(e,t,n.values,r)];for(let n of a)await E(e,[`pm`,`grant`,...i,t,n]);return a}throw n.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(n)}`)}async function Rp(e,t,n,r,i){if(r.kind===`notifications`)return await Kp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await Gp(e,t,`revoke`,i);return n===`reset`&&await qp(e,t,r,i),[r]}throw r.kind===`pm`?Error(`Unhandled Android permission target: pm is resolved by the caller.`):r.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(r)}`)}function zp(e,t){let n=Te(e);if(t?.trim())throw new a(`INVALID_ARGS`,`Android does not support permission modes. Received: ${t}.`);if(n===`all`)return{kind:`all`};if(n===`photos`)return{kind:`photos`};if(n===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let r=n in gp?gp[n]:void 0;if(r)return{kind:`pm`,name:n,values:r};throw new a(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${hp.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function Bp(e,t,n,r){let{requested:i}=await np(e,t,r);return Vp(i,n,t)}function Vp(e,t,n){if(e===void 0)return t;let r=t.filter(t=>e.includes(t));if(r.length===0)throw new a(`COMMAND_FAILED`,`Package ${n} has not requested permission ${t.join(`, `)}, so no permission was changed.`,{appPackage:n,permissions:t});return r}async function Hp(e,t,n,r,i,a){let{requested:o,grants:s}=await np(e,t,i),c=Vp(o,r.values,t);await Up(e,t,c,n,a);let{priorGrantState:l,warnings:u}=Wp(t,c,c.map(e=>s?.get(e)??`unknown`));return bp(r.name,c,{priorGrantState:l,warnings:u})}async function Up(e,t,n,r,i){for(let r of n)await E(e,[`pm`,`revoke`,...i,t,r]);if(r===`reset`)for(let r of n)await qp(e,t,r,i)}function Wp(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=mp(e,t,n[r]);return i?[i]:[]})}}async function Gp(e,t,n,r){let i=await Jp(e),o=i!==null&&i>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let i of o){let a=await E(e,[`pm`,n,...r,t,i],{allowFailure:!0});if(a.exitCode===0)return i;s.push({permission:i,reason:jp(a.stderr),detail:Ip(a.stderr)})}throw new a(`COMMAND_FAILED`,`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:i,attempts:s})}async function Kp(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await E(e,[`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await E(e,[`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await qp(e,t,r.permission,i)),await E(e,[`appops`,`set`,...i,t,r.appOps,a])}async function qp(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await E(e,[`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function Jp(e){let t=await E(e,[`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}const Yp=[`cmd`,`connectivity`,`airplane-mode`];async function Xp(e,t){let n=t?`enabled`:`disabled`;await Zp(e),await E(e,[...Yp,t?`enable`:`disable`]);let r=await Qp(e);if(r!==n)throw new a(`COMMAND_FAILED`,`Android airplane mode reads ${r} after requesting ${n}.`,{deviceId:e.id,requested:n,airplaneMode:r});return{airplaneMode:r}}async function Zp(e){let{state:t,result:n}=await $p(e);if(!t)throw n.exitCode!==0&&ft(n.stdout,n.stderr)?new a(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}):T(`Failed to read Android airplane mode`,n,{deviceId:e.id})}async function Qp(e){let{state:t,result:n}=await $p(e);if(t)return t;throw T(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function $p(e){let t=await E(e,[...Yp],{allowFailure:!0});return{state:t.exitCode===0?em(t.stdout):void 0,result:t}}function em(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const tm=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`],nm={"extra-small":`0.82`,small:`0.88`,medium:`0.94`,large:`1.0`,"extra-large":`1.12`,"extra-extra-large":`1.24`,"extra-extra-extra-large":`1.35`,"accessibility-medium":`1.5`,"accessibility-large":`1.75`,"accessibility-extra-large":`2.0`,"accessibility-extra-extra-large":`2.5`,"accessibility-extra-extra-extra-large":`3.2`},rm=nm.large;async function im(e,n,r,i,o){switch(n.toLowerCase()){case`wifi`:{let t=xe(r);await E(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await Xp(e,xe(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new a(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:t,longitude:n}=Ee(o);return await dt(e,[`emu`,`geo`,`fix`,String(n),String(t)]),{latitude:t,longitude:n}}let t=xe(r)?`3`:`0`;await E(e,[`settings`,`put`,`secure`,`location_mode`,t]);return}case`animations`:{let t=xe(r)?`1`:`0`;for(let n of tm)await E(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...tm]}}case`appearance`:{let t=await mm(e,r);await E(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new a(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new a(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`,t());let n=await At(e,i);if(n.type===`intent`)throw new a(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await E(e,[`am`,`force-stop`,n.value],{allowFailure:!0});let o=await E(e,[`pm`,`clear`,n.value],{allowFailure:!0});if(o.exitCode!==0||!/\bSuccess\b/i.test(o.stdout))throw new a(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await dm(e,um(r));return;case`permission`:if(!i)throw new a(`INVALID_ARGS`,`permission setting requires an active app in session`,t());return await vp(e,i,r,o);case`text-size`:return await sm(e,r);default:throw new a(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}const am={"text-size":cm};async function om(e,t){return await am[t](e)}async function sm(e,t){let n=we(t),r=nm[n];return await E(e,[`settings`,`put`,`system`,`font_scale`,r]),ye(n,r)}async function cm(e){let t=(await E(e,[`settings`,`get`,`system`,`font_scale`])).stdout.trim(),n=t===`null`?rm:t,r=/^(\d+(\.\d+)?)$/.test(n)?Number(n):NaN;if(!Number.isFinite(r)||r<=0)throw new a(`COMMAND_FAILED`,`Android reported an unusable font scale: ${t||`(empty)`}`,{deviceId:e.id,fontScale:t,hint:"Run `adb shell settings get system font_scale` to see what the device holds."});return ye(lm(r),n)}function lm(e){let t=Se[0],n=1/0;for(let r of Se){let i=Math.abs(Number.parseFloat(nm[r])-e);i>=n||(t=r,n=i)}return t}function um(e){let t=e.trim().toLowerCase();if(t===`match`)return`match`;if(t===`nonmatch`)return`nonmatch`;throw new a(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function dm(e,t){let n=fm(e,t),r=[];for(let t of n){let n=await dt(e,t,{allowFailure:!0});if(n.exitCode===0)return;r.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let i=c(r);throw r.length>0&&r.every(e=>pm(e.stdout,e.stderr))?new a(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:t,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:i}):new a(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:t,attempts:i})}function fm(e,t){let n=t===`match`?`1`:`9999`,r=[Ze(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),Ze(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function pm(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function mm(e,t){let n=be(t);if(n!==`toggle`)return n;let r=await E(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(r.exitCode!==0)throw T(`Failed to read current Android appearance`,r);let i=hm(r.stdout,r.stderr);if(!i)throw new a(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:r.stdout,stderr:r.stderr});return i===`auto`?`dark`:i===`dark`?`light`:`dark`}function hm(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}const gm=Buffer.from([137,80,78,71,13,10,26,10]);async function _m(e,t,n={}){if(n.stabilize===!1)return await bm(e,t);await vm(e);try{return await _(1e3),await bm(e,t)}finally{await ym(e).catch(()=>{})}}async function vm(e){let t=t=>E(e,t,{allowFailure:!0});await t([`settings`,`put`,`global`,`sysui_demo_allowed`,`1`]);let n=e=>t([`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,...e]);await n([`clock`,`-e`,`hhmm`,`0941`]),await n([`notifications`,`-e`,`visible`,`false`])}async function ym(e){await E(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function bm(e,t){let n=new AbortController,r=Wa(e,{timeoutMs:2e3,signal:n.signal});try{await Sm(e,t);let n=await xm(r,250);return n?{displayRotation:n}:{}}finally{n.abort()}}async function xm(e,t){let n;try{return await Promise.race([e,new Promise(e=>{n=setTimeout(()=>e(void 0),t)})])}finally{clearTimeout(n)}}async function Sm(e,t){let n=await ut(e,[`screencap`,`-p`],{binaryStdout:!0});if(!n.stdoutBuffer)throw new a(`COMMAND_FAILED`,`Failed to capture screenshot`);let r=n.stdoutBuffer.indexOf(gm);if(r<0)throw new a(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let i=Cm(n.stdoutBuffer,r);if(!i)throw new a(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await b().files.writeBytes(t,n.stdoutBuffer.subarray(r,i))}function Cm(e,t){let n=t+gm.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}async function wm(e,t,n=0){let r=qe(e);if(r){await r({action:`type`,text:t,delayMs:n}),Km(`type`,`provider-native`,t);return}let i=await km(e,`type`,t);if(i.backend===`test-ime`){await Am(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Mm(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Mm(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Tm(e,t,r,i,a=0,o={}){let s=await Au(e,t,r,o),c=qe(e);if(c)return await c({action:`fill`,target:{x:t,y:r},text:i,delayMs:a}),Km(`fill`,`provider-native`,i),ju(i,s,await Du(e,t,r,i,o));let l=null,u=0;try{for(let n of Em(a)){await qa(e,t,r),u+=1;let a=await km(e,`fill`,i);if(a.backend===`test-ime`)return ju(i,s,await jm(e,a.packageName,t,r,i,s,o));let c=await Dm(e,{x:t,y:r,text:i,beforeTarget:s,attempt:n},o);if(l=c,c.ok)return;if(c.reason===`ime_capture`)return ju(i,s,c);let d=Mu(i,s,c);if(d)return d}}catch(e){throw n(e,u)}return ju(i,s,l)}function Em(e){return[{clearPadding:12,minClear:8,maxClear:48,chunkSize:e>0?1:8,inputDelayMs:e},{clearPadding:24,minClear:16,maxClear:96,chunkSize:e>0?1:4,inputDelayMs:e>0?e:15}]}async function Dm(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Lm(e,Om(a,o,s)),await Mm(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),Du(e,r,i,a,n)}function Om(e,t,n){let r=Array.from(e).length;return qm(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function km(e,t,n){if(ps(e))return{backend:`test-ime`,packageName:(await qo(S(e))).manifest.packageName};let r=await Rm(e,t),i=r?.inputMethodPackage;return $o(i)?{backend:`test-ime`,packageName:i}:(Bm(n),zm(r,t),{backend:`adb-shell`})}async function Am(e,t,n,r){let i=v(e);await Pm(e,Nm(n,r>0?1:1/0,r),{delayMs:r,sendChunk:async e=>await es(i,t,e)}),Km(`type`,`test-ime`,n)}async function jm(e,t,r,i,a,o,s){let c=v(e),l=null,u=0;try{for(let n=0;n<2;n+=1){n>0&&(await qa(e,r,i),u+=1),await ts(c,t),u+=1,a&&(await es(c,t,a),u+=1);let d=await Du(e,r,i,a,s);if(l=d,d.ok||Mu(a,o,d))break}}catch(e){throw n(e,u)}return Km(`fill`,`test-ime`,a),l}async function Mm(e,t){await Pm(e,Nm(t.text,t.chunkSize,t.delayMs),{delayMs:t.delayMs,sendChunk:async t=>{try{await Im(e,t)}catch(e){throw it(e)}}}),Km(t.action,`adb-shell`,t.text)}function Nm(e,t,n){let r=e.split(`
|
|
18
|
-
`);return r.flatMap((e,i)=>{let a=
|
|
19
|
-
`&&(e<32||e>126))return!1}return!0}function
|
|
10
|
+
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}function os(e,t){return ls(e)?t!==`aborted`:e===`not-activated-here`&&t===`covered-confirmed`}async function ss(e,t){return await Tt(t.stateDir,e.id,async()=>{let n=await cs(e),r=t.shutdownTarget===!0?await Dt(e.id,t.signal):`idle`;return os(n.reason,r)&&await b().imeRecoveryMarkers.clear(t.stateDir,e.id),n})}async function cs(e){let t=D(e);return O.has(t)?(O.delete(t),await us(v(e),e)):{restored:!1,reason:`not-activated-here`}}function ls(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function us(e,t){let n=t.id;if(O.has(D(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await cn(e);if(r.kind===`unreadable`)return x({level:`warn`,phase:`android_test_ime_restore_record_unreadable`,data:{device:n}}),{restored:!1,reason:`record-unreadable`};if(r.kind===`absent`)return{restored:!1,reason:`no-record`};let{previousIme:i}=r,a=await k(e);if(a!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`&&!r.rebindDisplaced)return x({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:a,previousIme:i}}),{restored:!1,previousIme:i,reason:`helper-not-active`};let o=kt(t.id),s=!1;try{await y(e,[`ime`,`set`,i],{allowFailure:!0,timeoutMs:1e4});let t=await k(e);return t===i?(s=!0,await ln(e).catch(()=>{}),await dn(e).catch(()=>{}),x({phase:`android_test_ime_restored`,data:{device:n,previousIme:i}}),{restored:!0,previousIme:i,reason:`ok`}):(x({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:i,afterIme:t}}),{restored:!1,previousIme:i,reason:`set-failed`})}finally{t.kind===`emulator`&&Ot(t.id,s),o()}}async function ds(e){let t=b().imeRecoveryMarkers,n=await t.read(e.stateDir);if(n.length===0)return;let r;try{r=new Set(await e.listSerials())}catch(e){x({level:`debug`,phase:`android_test_ime_startup_scan_failed`,data:{error:i(e).message}});return}for(let a of n){if(!r.has(a))continue;let n={platform:`android`,id:a,name:a,kind:a.startsWith(`emulator-`)?`emulator`:`device`,booted:!0};try{await Tt(e.stateDir,a,async()=>{let r=await us(v(n),n);r.restored&&x({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:r.previousIme}}),os(r.reason,`idle`)&&await t.clear(e.stateDir,a)})}catch(e){x({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:i(e).message}})}}}async function fs(){b();try{return(await Pe(Qe([`devices`]),{timeoutMs:5e3})).stdout.split(`
|
|
11
|
+
`).map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith(`List of devices`)).map(e=>e.split(/\s+/)).filter(e=>e[1]===`device`).map(e=>e[0])}catch{return[]}}const ps=2e3;async function ms(e,t,n=b().files){let r=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,i=await js(r,n),a=await sn(`adb`,[`version`]),o=a===void 0?void 0:on(a);if(!a||!o)return As(r,i);let s=t===`win32`?void 0:Ts(a);return s?Es({windowsAdb:s,sdkRoot:r,versionLine:o}):Ds({license:i,sdkRoot:r,versionLine:o})}async function hs(e,t){if(e.platform!==`android`)return[];let n=v(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await xs(n,e.id,t.metroPort)),r.push(await gs(n,e)),r}async function gs(e,t){try{let n=await k(e),r=_t(t);return n===await _s()&&!r?await vs(e,t,n):ys(t,n,r)}catch(e){return bs(e)}}async function _s(){try{return(await St()).manifest.serviceComponent}catch{return}}async function vs(e,t,n){let r=(await y(e,[`settings`,`get`,`secure`,pn.previousIme],{allowFailure:!0,timeoutMs:ps})).stdout.trim(),i=r&&r!==`null`?r:void 0;return{id:`android-test-ime`,status:`fail`,summary:`Android test IME helper is the active input method on ${t.id}, but no active session owns it -- likely left over from a crashed session.`,hint:`A stuck test IME leaves the real keyboard unavailable on this device until restored.`,command:i?`adb -s ${t.id} shell ime set ${i}`:`adb -s ${t.id} shell ime list -s`,evidence:{currentIme:n,previousIme:i}}}function ys(e,t,n){return{id:`android-test-ime`,status:`pass`,summary:n?`Android test IME helper is active for this session on ${e.id}.`:`Android test IME helper is not active on ${e.id}; the device's normal IME is in use.`,evidence:{currentIme:t}}}function bs(e){let t=i(e);return{id:`android-test-ime`,status:`warn`,summary:`Could not inspect the Android test IME helper state.`,hint:t.message,evidence:{code:t.code}}}async function xs(e,t,n){try{let r=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:ps}),i=`tcp:${n} tcp:${n}`,a=r.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${n}.`:`Android adb reverse is missing for Metro port ${n}.`,command:a?void 0:`adb -s ${t} reverse tcp:${n} tcp:${n}`,evidence:{stdout:r.stdout.trim()}}}catch(e){let t=i(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function Ss(e){return/^Installed as (.+)$/m.exec(e)?.[1]?.trim()}function Cs(e){return/^(?:[A-Za-z]:[\\/]|\\\\)/.test(e)}function ws(e){return/^Running on Windows\b/m.test(e)}function Ts(e){let t=Ss(e);if(t&&Cs(t))return{detectedVia:`installed-as-path`,adbPath:t};if(ws(e))return{detectedVia:`running-on-line`,adbPath:void 0}}function Es(e){let{adbPath:t,detectedVia:n}=e.windowsAdb;return{id:`toolchain`,status:`fail`,summary:`Android toolchain: adb on PATH${t?` (${t})`:``} is a Windows binary, which cannot use this host's file paths.`,hint:`adb must be a native binary for this host: install this host's Android platform-tools, put them first on PATH, and point ANDROID_HOME at an SDK on this host's filesystem. Under WSL that means a Linux SDK, not one under /mnt/<drive>.`,evidence:{reason:`android_adb_windows_binary_on_posix_host`,detectedVia:n,adbPath:t??null,adbVersion:e.versionLine,androidHome:e.sdkRoot??null}}}function Ds(e){return{id:`toolchain`,status:Os(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${ks(e.sdkRoot)}.`:`Android toolchain: adb is present but version check failed.`,hint:e.license===`missing`?`Accept Android SDK licenses before installing/building apps.`:void 0,command:e.license===`missing`?`sdkmanager --licenses`:void 0,evidence:{adbVersion:e.versionLine??null,androidHome:e.sdkRoot??null,license:e.license}}}function Os(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function ks(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function As(e,t){return{id:`toolchain`,status:`info`,summary:`Android toolchain: adb not found on PATH.`,hint:`Install Android platform-tools or add adb to PATH.`,evidence:{androidHome:e??null,license:t}}}async function js(e,t){if(!e)return`unknown`;try{return await t.access(A.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ms(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=Is(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Ps(t.targetInput),actualInput:Ps(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function K(e){return e?e.password?!0:Ns(e.text):!1}function Ns(e){return e?Array.from(e).every(Fs):!1}function Ps(e){if(!e)return null;let t=K(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Fs(e){return e===`•`||e===`*`||e===`●`}function Is(e){return e.masked===!0||K(e.targetInput)||K(e.actualInput)}const Ls=new WeakMap;function Rs(e,t){return t&&Ls.set(e,t),e}function zs(e){return Ls.get(e)}function Bs(e){return e.clickable}function Vs(e){return e.focusable||e.focused===!0}function q(e){return Bs(e)||Vs(e)}function Hs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Us(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function Ws(e,t,n){if(!e)return;let r=qs(e);return t&&(r=Ks(r,t)),n&&(r=Ks(r,n)),r}function Gs(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ae(e.effectiveRect)?!0:void 0}}function Ks(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height),o=i>n&&a>r;return{x:o?n:e.x,y:o?r:e.y,width:o?i-n:0,height:o?a-r:0}}function qs(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function Js(e,t){let n=new Set;return Ys(e,n,t),Zs(e,n,t),n}function Ys(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Ys(r,t,n)}}function Xs(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function Zs(e,t,n){let r=Xs(e,t,n).filter($s);if(r.length<2)return;let i=r.filter(e=>ec(e)&&tc(e));if(i.length===0)return;let a=Qs(i);for(let r of Xs(e,t,n))n?.check(`work`),ec(r)&&(tc(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function Qs(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function $s(e){return e.windowIndex!==void 0||e.windowType!==void 0}function ec(e){return e.windowType===1}function tc(e){return e.windowActive===!0||e.windowFocused===!0}function nc(e,t,n,r,i){let a=new Set(e.sourceNodes),o=ic(t,i),s=rc(o,n,ac(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(ic([s],i)),l=[];for(let[t,n]of e.sourceNodes.entries())i.check(`work`),c.has(n)&&l.push(t);if(l.length===0)return{nodes:[],sourceNodes:[]};let u=1/0;for(let t of l)i.check(`work`),u=Math.min(u,e.nodes[t]?.depth??0);let d=[];for(let t of l)i.check(`work`),(e.nodes[t]?.depth??0)-u<=r&&d.push(t);return i.consume(d.length),{nodes:ee(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function rc(e,t,n,r){for(let i of e)if(r.check(`work`),re(i,t)&&n.has(i))return i;return null}function ic(e,t){let n=[],r=[...e].reverse();for(;r.length>0;){t.check(`work`);let e=r.pop();n.push(e);for(let n=e.children.length-1;n>=0;--n)t.check(`work`),r.push(e.children[n])}return n}function ac(e,t,n){let r=new Set;for(let i=e.length-1;i>=0;--i){n.check(`work`);let a=e[i];if(t.has(a)){r.add(a);continue}for(let e of a.children)if(n.check(`work`),r.has(e)){r.add(a);break}}return r}function oc(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=sc(e);return t.interactiveOnly?cc(e,a,n,r,i):a.isStructural||a.isVisual?dc(e,a,r):!0}function sc(e){let t=pc(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Hs(e.label??``),hasMeaningfulId:r&&!Hs(e.identifier??``),isStructural:mc(t),isVisual:t===`imageview`||t===`imagebutton`}}function cc(e,t,n,r,i){return uc(e)?!1:q(e)||se(t.type)&&r?!0:lc(t,n,r,i)}function lc(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function uc(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function dc(e,t,n){return q(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function fc(e){if(!e)return!1;let t=pc(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function pc(e){return e?e.toLowerCase():``}function mc(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function hc(e,t,n,r){return{...Us(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const gc=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var J=class extends Error{code=gc;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function _c(e){return e instanceof J?e.code===gc:!!(e&&typeof e==`object`&&e.code===gc)}var vc=class{workUnits=0;options;defaultMaxWorkUnits;deadlineAtMs;constructor(e,t){this.options=e,this.defaultMaxWorkUnits=t;let n=e.now??Date.now;this.deadlineAtMs=e.deadlineAtMs??n()+Cc()}get workUnitCount(){return this.workUnits}check(e){this.consume(1)}consume(e){this.workUnits+=e;let t=this.options.maxWorkUnits??this.defaultMaxWorkUnits;if(this.workUnits>t)throw new J(`Android snapshot presentation exceeded its linear work budget`,{phase:`complexity`,workUnits:this.workUnits,maxWorkUnits:t});if((this.options.now??Date.now)()>=this.deadlineAtMs)throw new J(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function yc(e,t){return new vc(e??{},t)}function bc(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=xc(i,r,t),a=i.effectiveRect;if(!a||!ae(a)){if(Gs(i).hittable===!0)throw new J(`Android regular snapshot node ${i.raw.index} with degenerate effective geometry was marked hittable`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a});r.set(i.raw.index,e);continue}if(e&&!Sc(a,e))throw new J(`Android regular snapshot node ${i.raw.index} escaped its cumulative clip`,{phase:`regular-invariant`,workUnits:n.workUnitCount,nodeIndex:i.raw.index,frame:a,clip:e});r.set(i.raw.index,i.clipsDescendants?a:e)}}function xc(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function Sc(e,t){let n=1e-4;return e.x>=t.x-n&&e.y>=t.y-n&&e.x+e.width<=t.x+t.width+n&&e.y+e.height<=t.y+t.height+n}function Cc(){return 250}function wc(e,t,n){let r=n.depth??1/0,i=ie(n.scope),a=Hc(e),o=yc(n.androidPresentation,Math.max(1024,a.rawNodeCount*128)),s={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:i?1/0:r,options:n,analysis:a,interactiveDescendantMemo:new Map,hidden:new Set,presentationBudget:o,presentationNodes:[],truncated:!1};try{o.check(`work`),s.viewport=Fc(e,o),s.hidden=n.raw?new Set:Js(e,o);for(let t of e.children)if(Ec(s,t,0),s.truncated)break;n.raw||bc(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?nc(s,e.children,i,r,o):s,u={nodes:c,sourceNodes:l,occlusionContext:{nodes:t,sourceIndexByNodeIndex:new Map(l.flatMap((e,t)=>{let n=a.get(e),r=c[t]?.index;return n===void 0||r===void 0?[]:[[r,n]]})),androidSiblingOrderByNodeIndex:Tc(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw _c(e)&&(e.analysis??=s.analysis),e}}function Tc(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=zs(i);if(!e)continue;let a=t.get(e.parent);a===void 0&&(a=t.size,t.set(e.parent,a)),n.set(r,{group:a,order:e.order})}return n}function Ec(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),Dc(e,t,n))return;let l=t.windowRect??s??e.viewport,u=Oc(e,t,c,l),d=kc(e,t,r,i,a,o,u,l),f=i||q(t),p=a||fc(t.type),m=Ac(e,t,u,c);jc(e,t,n,d,f,p,o||hn(t.identifier),l,m)}function Dc(e,t,n){return e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes?(e.truncated=!0,!0):n>e.maxDepth||e.hidden.has(t)}function Oc(e,t,n,r){return e.options.raw?t.rect:Ws(t.rect,r,n)}function kc(e,t,n,r,i,a,o,s){return!e.options.raw&&!oc(t,e.options,r,Rc(e,t),i)?n:Mc(e,t,n,a||hn(t.identifier),o,s)}function Ac(e,t,n,r){return e.options.raw||!Ic(t)?r:n}function jc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(Ec(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Mc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Pc(e,t,Nc(e,t,n,r),i,a),o}function Nc(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,...t.passiveFacts,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,focused:t.focused,visibleToUser:t.visibleToUser,hittable:q(t)||void 0,depth:Lc(e.nodes,n),parentIndex:n,...zc(t,e.hidden),...r?{systemChrome:!0}:{}}}function Pc(e,t,n,r,i){let a=hc(n,r,!e.options.raw&&Ic(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:Gs(a))}function Fc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ae(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ne(n)??void 0}function Ic(e){return e.scrollable===!0&&se(e.type)}function Lc(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function Rc(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(!e.hidden.has(n)&&n.visibleToUser!==!1&&(q(n)||Rc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function zc(e,t){return Bc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Bc(e,t){if(!e.scrollable||!se(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Vc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Vc(e,t){let n=e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1);if(!e.rect||n.length===0)return null;let r=n.map(e=>e.rect).filter(e=>e!==void 0);if(r.length===0)return null;let i=Math.min(...r.map(e=>e.x)),a=Math.max(...r.map(e=>e.x+e.width)),o=Math.min(...r.map(e=>e.y)),s=Math.max(...r.map(e=>e.y+e.height));return{horizontal:Math.max(0,a-i-e.rect.width),vertical:Math.max(0,s-o-e.rect.height)}}function Hc(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function Uc(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||hn(n);return r||e.push(i),i},close(){e.pop()}}}function*Wc(e){let t=/<node\b[^>]*>|<\/node>/g,n=Uc(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=Gc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function Gc(e){let t=Kc(e),n=gn(t.bounds);return{...t,...n?{rect:n}:{}}}function Kc(e){let t=qc(e),n=e=>tl(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=gn(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let r=n(t);return r===null||r===``?{}:{[e]:r}},c=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...c(`editable`,`editable`),...a(`selectionStart`,`selection-start`),...a(`selectionEnd`,`selection-end`),...c(`hintShowing`,`hint-showing`),...s(`hint`,`hint`),...c(`visibleToUser`,`visible-to-user`),...c(`selected`,`selected`),...c(`heading`,`heading`),...s(`roleDescription`,`role-description`),...c(`checked`,`checked`),...a(`drawingOrder`,`drawing-order`),...c(`scrollable`,`scrollable`),...c(`canScrollForward`,`can-scroll-forward`),...c(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...c(`windowActive`,`window-active`),...c(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`),...c(`windowRegionRect`,`window-region-rect`)}}function qc(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=Jc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function Jc(e,t,n){if(t=Xc(e,t,n),t>=n||Zc(e[t]))return;let r=t;t=Yc(e,t,n);let i=e.slice(r,t);if(t=Xc(e,t,n),!i||e[t]!==`=`)return;t=Xc(e,t+1,n);let a=e[t];if(!Qc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:_n(e.slice(o,s)),nextCursor:s+1}}function Yc(e,t,n){for(;t<n&&!el(e[t]??``);)t+=1;return t}function Xc(e,t,n){for(;t<n&&$c(e[t]??``);)t+=1;return t}function Zc(e){return e===`/`||e===`>`}function Qc(e){return e===`"`||e===`'`}function $c(e){return e===` `||e===`
|
|
12
|
+
`||e===`\r`||e===` `}function el(e){return e===`=`||e===`/`||e===`>`||$c(e)}function tl(e,t){return e.get(t)??null}function nl(e){let t={type:null,label:null,value:null,passiveFacts:{},identifier:null,packageName:null,clickable:!1,focusable:!1,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=Gc(t),o=n.at(-1),s=rl(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function rl(e,t,n){let r=e.text||e.desc;return Rs({type:e.className,label:r,value:e.text,passiveFacts:{contentDescription:e.desc&&e.desc!==r?e.desc:void 0,enabled:e.enabled,selected:e.selected,heading:e.heading,roleDescription:e.roleDescription,checked:e.checked,editable:e.editable,password:e.password,hintShowing:e.hintShowing,placeholder:e.hint,selectionStart:e.selectionStart,selectionEnd:e.selectionEnd},identifier:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused,visibleToUser:e.visibleToUser,clickable:e.clickable===!0,focusable:e.focusable===!0,scrollable:e.scrollable,canScrollForward:e.canScrollForward,canScrollBackward:e.canScrollBackward,windowIndex:e.windowIndex,windowType:e.windowType,windowLayer:e.windowLayer,windowActive:e.windowActive,windowFocused:e.windowFocused,windowRect:e.windowRect,windowRegionRect:e.windowRegionRect,depth:t,parentIndex:void 0,children:[]},e.drawingOrder===void 0?void 0:{parent:n,order:e.drawingOrder})}function il(e){let t=new Map;return e.nodes.forEach((n,r)=>{t.set(n.index,e.sourceNodes[r]?.clickable)}),{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:t}}const al=new Set([`android`,`com.android.systemui`]);function ol(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=_l(e,n.foregroundAppPackage);return ll(r,t)?sl(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):hl(r)?{outcome:`ok`}:cl(r)?{outcome:`system-surface-only`}:ul(r)?{outcome:`ok`}:dl(r)?sl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):fl(r)||pl(r,t)?sl(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):ml(r)?sl(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function sl(e,t,n,r){return{outcome:`unusable`,decision:gl(e,t,n,r)}}function cl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function ll(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function ul(e){return dl(e)&&e.inputMethodMeaningfulNodeCount>=2}function dl(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function fl(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function pl(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function ml(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function hl(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function gl(e,t,n,r){return{reason:n,failureReason:r,diagnostics:jl(e,t)}}function _l(e,t){let n=vl(t);for(let t of Wc(e))yl(n,t);return El(n)}function vl(e){return{nodeCount:0,systemUiNodeCount:0,windowRootCount:0,applicationWindowRootCount:0,activeSystemSurfaceMeaningfulNodeCount:0,meaningfulNodeCount:0,applicationMeaningfulNodeCount:0,nonSystemMeaningfulNodeCount:0,inputMethodMeaningfulNodeCount:0,hasAlertButtonIdentifier:!1,hasAlertContentIdentifier:!1,...e===void 0?{}:{foregroundAppPackage:e,foregroundAppMeaningfulNodeCount:0},windowTypes:new Set}}function yl(e,t){e.nodeCount+=1,Al(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&bl(e,t.resourceId),xl(e,t),Sl(e,t)}function bl(e,t){let n=Fn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function xl(e,t){t.windowType!==void 0&&(e.currentWindowType=t.windowType,e.currentWindowActiveOrFocused=t.windowActive===!0||t.windowFocused===!0,e.windowRootCount+=1,e.windowTypes.add(t.windowType),t.windowType===1&&(e.applicationWindowRootCount+=1))}function Sl(e,t){Dl(t)&&(e.meaningfulNodeCount+=1,Cl(e,t),Tl(e,t))}function Cl(e,t){e.currentWindowType===1&&!kl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),wl(e)&&!mn(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function wl(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function Tl(e,t){kl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),dt({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function El(e){return{nodeCount:e.nodeCount,systemUiNodeCount:e.systemUiNodeCount,windowRootCount:e.windowRootCount,applicationWindowRootCount:e.applicationWindowRootCount,activeSystemSurfaceMeaningfulNodeCount:e.activeSystemSurfaceMeaningfulNodeCount,meaningfulNodeCount:e.meaningfulNodeCount,applicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,nonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,inputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,hasAlertButtonIdentifier:e.hasAlertButtonIdentifier,hasAlertContentIdentifier:e.hasAlertContentIdentifier,...e.foregroundAppPackage===void 0?{}:{foregroundAppPackage:e.foregroundAppPackage,foregroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount??0},windowTypes:[...e.windowTypes].sort((e,t)=>e-t).slice(0,8)}}function Dl(e){return e.visibleToUser===!1?!1:Ol(e.text)||Ol(e.desc)||Ol(e.resourceId)}function Ol(e){return e!==null&&e.trim()!==``}function kl(e){return e===null||al.has(e)}function Al(e){return e!==null&&al.has(e)}function jl(e,t){return{helperNodeCount:e.nodeCount,helperSystemUiNodeCount:e.systemUiNodeCount,helperWindowRootCount:e.windowRootCount,helperApplicationWindowRootCount:e.applicationWindowRootCount,helperMeaningfulNodeCount:e.meaningfulNodeCount,helperApplicationMeaningfulNodeCount:e.applicationMeaningfulNodeCount,helperNonSystemMeaningfulNodeCount:e.nonSystemMeaningfulNodeCount,helperInputMethodMeaningfulNodeCount:e.inputMethodMeaningfulNodeCount,...e.foregroundAppPackage===void 0?{}:{helperForegroundAppPackage:e.foregroundAppPackage,helperForegroundAppMeaningfulNodeCount:e.foregroundAppMeaningfulNodeCount,helperForegroundAppMeaningfulNodeThreshold:2},helperWindowTypes:e.windowTypes,...t.captureMode?{helperCaptureMode:t.captureMode}:{}}}async function Ml(e){let t=await H(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await Nl(e.adb,e.packageName)}async function Nl(e,t){await Ei({adb:e,packageName:t}),await _(150),g({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const Pl=Symbol(`androidSnapshotCaptureEvidence`);function Fl(e,t){return Object.defineProperty(e,Pl,{value:t}),e}function Il(e){return oe({x:0,y:0,width:e.displayWidth??NaN,height:e.displayHeight??NaN})}function Ll(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Pl];return m(t,n.clickability),n.occlusionContext&&p(t,n.occlusionContext),t}async function Rl(e,t={}){let n=S(e,t.helperAdb).exec;return(await Kl(e,t,n)).xml}async function zl(e,t={}){let n=S(e,t.helperAdb).exec,r=await Kl(e,t,n),i=Il(r.helperMetadata),a=r.xml,o=nl(a),s=Hl(r.metadata,o),c=_u(o,r.metadata),l={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=wc(o,void 0,l),n=Vl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Gl({options:l,tree:o,xml:a,interactiveSnapshot:e});let{sourceNodes:u,occlusionContext:d,...f}=e;return Fl({...f,...Wl(n),androidSnapshot:s,quality:{state:`healthy`,backend:`android-helper`},keyboard:c,...i?{viewport:i}:{}},{clickability:il(e),occlusionContext:d})}catch(e){if(!_c(e))throw e;return Bl({failure:e,androidSnapshot:s,keyboard:c,...i?{viewport:i}:{}})}}function Bl(e){return Fl({nodes:[],truncated:!0,analysis:e.failure.analysis??{rawNodeCount:0,maxDepth:0},androidSnapshot:{...e.androidSnapshot,presentationFailure:{phase:e.failure.details.phase,workUnits:e.failure.details.workUnits,...e.failure.details.maxWorkUnits===void 0?{}:{maxWorkUnits:e.failure.details.maxWorkUnits}}},quality:{state:`sparse`,backend:`android-helper`,reason:e.failure.message,reasonCode:e.failure.qualityReasonCode},keyboard:e.keyboard,...e.viewport?{viewport:e.viewport}:{}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Vl(e,t){return e===!0||t.helperTruncated===!0||e}function Hl(e,t){return Ul(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Ul(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(zs(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Wl(e){return e===!0?{truncated:!0}:{}}function Gl(e){if(hu(e.interactiveSnapshot.nodes).size>0||mu(e.xml))return;let t=wc(e.tree,void 0,{...e.options,interactiveOnly:!1});gu(Se(l(t.nodes)),t,e.interactiveSnapshot)}async function Kl(e,t,n){let r=S(e,t.helperAdb),i=await h(`android_snapshot_helper_artifact_resolution`,async()=>await fu(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await ql(e,t,n,i.artifact);throw g({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),pu(i.errorReason)}async function ql(e,t,n,r){let i=fi(e),a=Xl(t,i);try{return await Jl({options:t,adb:n,adbProvider:S(e,t.helperAdb),artifact:r,helperDeviceKey:i})}finally{a&&await H(i)}}async function Jl(e){let{options:t}=e,n=Yl(t),r=async(n,r)=>await ru({contentRecovery:n,attempts:r,helperDeviceKey:e.helperDeviceKey,artifact:e.artifact,adb:e.adb,signal:t.signal,retireHelper:t.transient===void 0}),i;for(let a=0;;a+=1){if(i&&(await nu(t.signal),Date.now()>=n))return await r(i,a);let o=await tu({...e,attempt:a,previousContentReason:i?.reason});if(o.outcome===`captured`)return o.capture;if(a+1>=3||Date.now()>=n)return await r(o.decision,a+1);i=o.decision}}function Yl(e){return Math.min(Date.now()+1e4,e.transient?.settleBy??1/0)}function Xl(e,t){return e.transient?oa(t)===void 0:e.helperSessionScope!==`daemon-session`}function Zl(e){return e.transient?`current-only`:e.helperInstallPolicy??`missing-or-outdated`}async function Ql(e,t,n,r,i){let a=await h(`android_snapshot_helper_install`,async()=>await Vr({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:Zl(e),timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:Zl(e)});return g({phase:`android_snapshot_helper_install_decision`,data:{packageName:a.packageName,versionCode:a.versionCode,installedVersionCode:a.installedVersionCode,artifactSha256:r.manifest.sha256,installedSha256:a.installedSha256,installed:a.installed,reason:a.reason}}),a}async function $l(e){let{signal:t,adb:n,adbProvider:r,artifact:a,helperDeviceKey:o}=e,s=ki({adb:n,adbProvider:r,artifact:a,deviceKey:o,signal:t});try{let e=await h(`android_snapshot_helper_session_capture`,async()=>await Sa(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Tr});if(e)return e}catch(e){if(t?.throwIfAborted(),gi(e))throw e;g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:i(e).message}}),await Nl(n,a.manifest.packageName)}return await h(`android_snapshot_helper_capture`,async()=>await Oi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Tr,commandTimeoutMs:Er})}function eu(e,t,n){return{xml:e.xml,helperMetadata:e.metadata,metadata:{backend:`android-helper`,pixelDensity:e.metadata.pixelDensity,helperVersion:t.manifest.version,helperApiVersion:e.metadata.helperApiVersion,helperTransport:e.metadata.transport,helperSessionReused:e.metadata.sessionReused,installReason:n,waitForIdleTimeoutMs:e.metadata.waitForIdleTimeoutMs,waitForIdleQuietMs:e.metadata.waitForIdleQuietMs,timeoutMs:e.metadata.timeoutMs,maxDepth:e.metadata.maxDepth,maxNodes:e.metadata.maxNodes,rootPresent:e.metadata.rootPresent,captureMode:e.metadata.captureMode,windowCount:e.metadata.windowCount,missingRootWindowTypes:e.metadata.missingRootWindowTypes,nodeCount:e.metadata.nodeCount,helperTruncated:e.metadata.truncated,elapsedMs:e.metadata.elapsedMs}}}async function tu(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await Ql(t,n,r,i,a);e.installed&&await H(a),s=eu(await $l({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){if(t.signal?.throwIfAborted(),Ir(e))throw e;return{outcome:`captured`,capture:await au({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=ol(s.xml,s.metadata,{foregroundAppPackage:t.appBundleId});if(c.outcome===`unusable`)return{outcome:`unusable`,decision:c.decision};let l=c.outcome===`system-surface-only`;return!l&&o>0&&g({phase:`android_snapshot_helper_content_recaptured`,data:{attempts:o+1,recoveredFromReason:e.previousContentReason}}),{outcome:`captured`,capture:{xml:s.xml,helperMetadata:s.helperMetadata,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function nu(e){e?.throwIfAborted(),await _(250),e?.throwIfAborted()}async function ru(e){throw g({level:`error`,phase:`android_snapshot_helper_content_invalid`,data:{reason:e.contentRecovery.reason,failureReason:e.contentRecovery.failureReason,attempts:e.attempts,...e.contentRecovery.diagnostics}}),e.retireHelper&&await Ml({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),iu(e.contentRecovery,e.attempts)}function iu(e,t){return new a(`COMMAND_FAILED`,e.failureReason,{...e.diagnostics,androidSnapshotHelperFailureReason:e.reason,attempts:t,retriable:!0,hint:`Retry after the app UI stabilizes. If this persists, capture a screenshot and report the helper diagnostics; agent-device does not substitute a second snapshot engine.`})}async function au(e){let t=ou(e.error);throw g({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await H(e.helperDeviceKey),await Nl(e.adb,e.artifact.manifest.packageName),Pr({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),su(e.error,t)}function ou(e){let t=i(e),n=du(t.details?.helper);if(n&&n!==t.message)return`${t.message}: ${n}`;if(n)return n;let r=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return r?`${t.message}: ${r}`:t.message}function su(e,t){let n=i(e),r=cu(n);return new a(s(n.code),`Android snapshot helper failed: ${t}`,{...n.details,...uu(n),androidSnapshotHelperFailureReason:t,...r?{androidCaptureFailureReason:r}:{},hint:lu(n,r)},e)}function cu(e){return Pt(e)}function lu(e,t){return t===`accessibility-timeout`?`Android accessibility snapshots can be blocked by busy or continuously changing app UI. Use screenshot as visual truth after this timeout and report the busy UI if it persists.`:e.details?.androidSnapshotHelperInstallFailure===!0?[e.hint,`This is a device-side install failure (adb rejection or OEM policy) — the helper artifact itself is present, this is not a missing/unbuilt build.`].filter(Boolean).join(` `):e.hint??`Retry once. If the helper still fails, run agent-device doctor and report the diagnostic log; agent-device does not substitute a second snapshot engine.`}function uu(e){let t={};return e.diagnosticId!==void 0&&(t.diagnosticId=e.diagnosticId),e.logPath!==void 0&&(t.logPath=e.logPath),e.retriable!==void 0&&(t.retriable=e.retriable),e.supportedOn!==void 0&&(t.supportedOn=e.supportedOn),t}function du(e){if(!e||typeof e!=`object`||!(`message`in e))return;let t=String(e.message).trim();return t&&t!==`null`?t:void 0}async function fu(e){if(e)return{artifact:e};let t=je(),n=A.join(Me(),`android`,`snapshot-helper`,`dist`),r=A.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await b().files.access(r)}catch{return{}}try{let e=Dr(JSON.parse(await b().files.readText(r))),t=A.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await b().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:i(e).message}}}function pu(e){let t=e??`the bundled helper artifact was not found`;return new a(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${t}`,{androidSnapshotHelperFailureReason:t,hint:"Run `pnpm build:android` to build the helper dist for a source checkout — the runtime needs android/snapshot-helper/dist/agent-device-android-snapshot-helper-<version>.manifest.json and the .apk it references. Packaged installs ship these via the prepack script; if they are missing from a packaged install, reinstall agent-device."})}function mu(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function hu(e){let t=new Map;for(let n of e){let e={};n.hiddenContentAbove&&(e.hiddenContentAbove=!0),n.hiddenContentBelow&&(e.hiddenContentBelow=!0),(e.hiddenContentAbove||e.hiddenContentBelow)&&t.set(n.index,e)}return t}function gu(e,t,n){if(e.size===0)return;let r=new Map;for(let[e,t]of n.sourceNodes.entries()){let i=n.nodes[e];i&&r.set(t,i)}for(let[n,i]of e){let e=t.sourceNodes[n];if(!e)continue;let a=r.get(e);a&&(i.hiddenContentAbove&&(a.hiddenContentAbove=!0),i.hiddenContentBelow&&(a.hiddenContentBelow=!0))}}function _u(e,t){let n=e.children,r=n.filter(e=>e.windowType===2),i=[];for(let{windowRect:e,windowRegionRect:t}of r){if(t===!1)return{kind:`unmeasurable`,reason:`window-region-not-rectangular`};if(ae(e))i.push(e);else if(!vu(e))return{kind:`unmeasurable`,reason:`window-bounds-unavailable`}}return t.missingRootWindowTypes?.includes(2)?{kind:`unmeasurable`,reason:`window-root-unavailable`}:i.length>0?{kind:`visible`,frame:ce(i)}:t.captureMode!==`interactive-windows`||n.some(e=>e.windowType===void 0)?{kind:`unmeasurable`,reason:`window-list-unavailable`}:t.helperTruncated===!0?{kind:`unmeasurable`,reason:`capture-truncated`}:{kind:`absent`}}function vu(e){return!e||![e.x,e.y,e.width,e.height].every(Number.isFinite)?!1:e.width===0||e.height===0}const yu=Object.freeze({now:()=>Date.now(),sleep:_});async function bu(e,t,n,r,i={},a=yu){let o=await Bu(e),s=a.now()+1500,c=null;for(;;){let l=await Au(e,t,n,r,o,i);if(l.reason===`ime_capture`)return l;let u=s-a.now();if(l.ok&&c?.ok||u<=0)return l;c=l,await a.sleep(Math.min(150,u))}}async function xu(e,t,n,r={}){return Du(await Rl(e,r),t,n)}async function Su(e,t,n,r){let i=await Bu(e);return ju(await Rl(e,r),t,n,i).targetInput}async function Cu(e,t,n,r={}){try{return await Su(e,t,n,r)}catch(e){return g({level:`warn`,phase:`android_fill_pre_action_target_capture_failed`,data:{error:e instanceof Error?e.message:String(e)}}),null}}function Y(e,t,n){if(n?.ok)return;let r=n?Tu(e,t,n):null;if(r)return r;throw u(new a(`COMMAND_FAILED`,Ou(n),ku(e,n)),`unknown`)}function wu(e,t){if(e.ok)return!1;let n=e.actualInput;return n&&(n.hintShowing===!0||n.text===null)?!0:t?.text!=null&&e.actual===t.text}function Tu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||wu(n,t)||!t||!r||!i||K(t)||K(r)||K(i)||!Ku(t,r)||!Ku(t,i))return null;let a=qu(t);return g({level:`warn`,phase:`android_fill_verification_unconfirmed`,data:{target:a}}),{verification:`unconfirmed`,requested:e,before:t.text,after:n.actual,target:a}}function Eu(e,t,n,r,i={}){let a=ju(e,t,n,i);return Mu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Nu(a,r)??Pu(a,r)}function Du(e,t,n){return ju(e,t,n).targetInput?.text??null}function Ou(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function ku(e,t){let n=Ms(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function Au(e,t,n,r,i,a){return Eu(await Rl(e,a),t,n,r,i)}function ju(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of Wc(e)){let e=zu(a,r);e&&Vu(i,e,t,n)}return Uu(i)}function Mu(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Nu(e,t){let n=e.actualInput;if(!n||!Gu(n))return null;let r=n.text??null,i=Array.from(Fu(n)).length,a=Array.from(t).length,o=a===0?i===0:i>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function Pu(e,t){let n=e.actualInput;return{ok:n!==null&&Iu(Fu(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Fu(e){return e.hintShowing?``:e.text??``}function Iu(e,t){if(e===t)return!0;if(t.length===0)return!1;let n=Lu(e),r=Lu(t);return!n||!r?!1:!!(n===r||Ru(n,r))}function Lu(e){return e.replaceAll(/\s+/g,` `).trim()}function Ru(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function zu(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:dt({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:Wu(e.className??``),hintShowing:e.hintShowing===!0,placeholder:e.hint??null}}async function Bu(e){try{return{activeInputMethodPackage:(await Vo(e)).inputMethodPackage}}catch(e){return g({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Vu(e,t,n,r){let i=te(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=Hu(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=Hu(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=Hu(e.anyAtPoint,t))}function Hu(e,t){return e&&e.area<t.area?e:t}function Uu(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function Wu(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Gu(e){return K(e)}function Ku(e,t){return e.resourceId||t.resourceId?e.resourceId===t.resourceId&&e.packageName===t.packageName:e.className===t.className&&e.packageName===t.packageName&&e.rect.x===t.rect.x&&e.rect.y===t.rect.y&&e.rect.width===t.rect.width&&e.rect.height===t.rect.height}function qu(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Ju(e,t){return await vn(t.stateDir),await Tt(t.stateDir,e.id,async()=>await Xu(e,t))}function Yu(e){let t=r(e).details?.hint;return{outcome:`helper-unavailable`,reason:i(e).message,...typeof t==`string`?{hint:t}:{}}}async function Xu(e,t){let n=b().imeRecoveryMarkers,r=v(e),i=S(e),a=D(e),o;try{o=await gt(i),await xt({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return Yu(e)}let{manifest:s}=o,c=await k(r);if(c===s.serviceComponent)return await Zu(e,s,t.stateDir);let l=await cn(r);if(l.kind===`unreadable`)return x({level:`warn`,phase:`android_test_ime_record_unreadable`,data:{device:e.id}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let{previousIme:u,priorPersistedIme:d}=Qu(l,c);if(!await fn(r,u))return await un(r,d,e.id),x({level:`warn`,phase:`android_test_ime_persist_failed`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let f=(await n.read(t.stateDir)).includes(e.id);if(!await n.write(t.stateDir,e.id))return await un(r,d,e.id),x({level:`warn`,phase:`android_test_ime_marker_persist_failed`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!1,alreadyActive:!1,persistFailed:!0,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};await y(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let p=await y(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),m=await k(r);if(m!==s.serviceComponent)return O.delete(a),await un(r,d,e.id),f||await n.clear(t.stateDir,e.id),x({level:`warn`,phase:`android_test_ime_activate_failed`,data:{device:e.id,activeIme:m,stderr:p.stderr.trim()}}),{outcome:`settled`,activated:!1,alreadyActive:!1,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName};let h={stateDir:t.stateDir,rebindUnconfirmed:l.rebindDisplaced};return O.set(a,h),l.rebindDisplaced&&(h.rebindUnconfirmed=!await dn(r)),x({phase:`android_test_ime_activated`,data:{device:e.id,previousIme:u}}),{outcome:`settled`,activated:!0,alreadyActive:!1,previousIme:u,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}async function Zu(e,t,n){let r=v(e),i=D(e),a=await b().imeRecoveryMarkers.write(n,e.id),o=await cn(r);if(a){let e=o.kind===`unreadable`||o.rebindDisplaced;O.set(i,{stateDir:n,rebindUnconfirmed:e})}let s=o.kind===`owned`?o.previousIme:void 0;return{outcome:`settled`,activated:!1,alreadyActive:!0,...a?{}:{persistFailed:!0},previousIme:s,helperServiceComponent:t.serviceComponent,helperPackageName:t.packageName}}function Qu(e,t){return e.kind===`absent`?{previousIme:t,priorPersistedIme:void 0}:{previousIme:e.rebindDisplaced?e.previousIme:t,priorPersistedIme:e.previousIme}}function $u(e){return A.join(e,`android-test-ime-pending`)}function ed(e,t){return A.join($u(e),encodeURIComponent(t))}async function td(e,t){let n=b().files,r,a=!1;try{let i=$u(e);if(r=ed(e,t),await n.ensureDirectory(i),(await id(r))?.serial===t)return!0;let o={version:1,serial:t};if(await n.writeAtomicText(r,`${JSON.stringify(o)}\n`,384),a=!0,(await id(r))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&r&&await n.remove(r,{force:!0}).catch(()=>{}),g({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:i(o).message}}),!1}}async function nd(e,t){await b().files.remove(ed(e,t),{force:!0}).catch(()=>{})}async function rd(e){let t=b().files,n;try{n=await t.readDirectory($u(e))}catch{return[]}let r=[];for(let t of n)try{let n=A.join($u(e),t),i=await id(n);i&&ed(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function id(e){try{return ad(await b().files.readText(e))}catch{return}}function ad(e){try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return;let n=t;return n.version===1&&typeof n.serial==`string`&&n.serial.length>0?{version:1,serial:n.serial}:void 0}catch{return}}const od=new xn(`utf-16le`);let sd;async function cd(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await ld(e,n,t);if(!r)continue;let i=ud(r);if(i)return i}return await Dd(e,t)}async function ld(e,t,n){try{let r=await De(`unzip`,[`-p`,e,t],{allowFailure:!0,binaryStdout:!0,signal:n});return r.exitCode!==0||!r.stdoutBuffer||r.stdoutBuffer.length===0?void 0:r.stdoutBuffer}catch{n?.throwIfAborted();return}}function ud(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?dd(e.toString(`utf8`)):fd(e)}function dd(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function fd(e){let t=hd(e);if(!t)return;let n;for(let r=t.treeHeaderSize;r+8<=t.dataEnd;){let i=pd(e,r,t.dataEnd);if(!i)return;if(i.type===1){if(n=xd(e.subarray(r,r+i.chunkSize)),!n)return}else if(n){let t=md(e,i,r,n);if(t)return t}r+=i.chunkSize}}function pd(e,t,n){let r=e.readUInt16LE(t),i=e.readUInt16LE(t+2),a=e.readUInt32LE(t+4);if(!(!gd(i,a)||t+a>n))return{type:r,headerSize:i,chunkSize:a}}function md(e,t,n,r){if(t.type===258)return _d(e,n,n+t.chunkSize,t.headerSize,r)}function hd(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!(!gd(t,n)||n>e.length))return{treeHeaderSize:t,dataEnd:n}}function gd(e,t){return e>=8&&e%4==0&&t%4==0&&e<=t}function _d(e,t,n,r,i){if(r<16)return;let a=t+r;if(a+20>n||i[e.readUInt32LE(a+4)]!==`manifest`)return;let o=vd(e,a,n);return o?yd(e,i,o):void 0}function vd(e,t,n){let r=e.readUInt16LE(t+8),i=e.readUInt16LE(t+10),a=e.readUInt16LE(t+12);if(!(i<20||r<20)&&!(r+i*a>n-t))return{firstOffset:t+r,stride:i,count:a}}function yd(e,t,n){for(let r=0;r<n.count;r+=1){let i=n.firstOffset+r*n.stride;if(t[e.readUInt32LE(i+4)]===`package`)return bd(e,t,i)}}function bd(e,t,n){let r=e.readUInt32LE(n+8);if(r!==4294967295)return t[r];let i=e.readUInt8(n+15),a=e.readUInt32LE(n+16);return i===3?t[a]:void 0}function xd(e){let t=e.readUInt16LE(2),n=e.readUInt32LE(4);if(!gd(t,n)||t<28||n>e.length)return;let r=e.readUInt32LE(8),i=e.readUInt32LE(16),a=e.readUInt32LE(20),o=!!(i&256),s=t;if(s+r*4>n||a<s+r*4||a>=n)return;let c=[];for(let t=0;t<r;t+=1){let n=a+e.readUInt32LE(s+t*4);c.push(o?Sd(e,n):Cd(e,n))}return c}function Sd(e,t){let n=Td(e,t);if(!n)return;let r=Td(e,t+n.bytes);if(!r)return;let i=t+n.bytes+r.bytes;return wd(e,i,r.value)?e.subarray(i,i+r.value).toString(`utf8`):void 0}function Cd(e,t){let n=Ed(e,t);if(!n)return;let r=t+n.bytes;return wd(e,r,n.value*2)?od.decode(e.subarray(r,r+n.value*2)):void 0}function wd(e,t,n){return Number.isSafeInteger(t)&&Number.isSafeInteger(n)&&t+n<=e.length}function Td(e,t){if(t+1>e.length)return;let n=e.readUInt8(t);if(!(n&128))return{value:n,bytes:1};if(!(t+2>e.length))return{value:(n&127)<<8|e.readUInt8(t+1),bytes:2}}function Ed(e,t){if(t+2>e.length)return;let n=e.readUInt16LE(t);if(!(n&32768))return{value:n,bytes:2};if(!(t+4>e.length))return{value:(n&32767)<<16|e.readUInt16LE(t+2),bytes:4}}async function Dd(e,t){t?.throwIfAborted();let n=await Od();if(!n)return;let r=await De(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function Od(){if(sd!==void 0)return sd??void 0;try{let e=b().files,{hostPlatform:t}=await import(`./process.js`).then(e=>e.t);for(let n of Ut(void 0,t())){let t=A.join(n,`build-tools`);try{let n=(await e.readDirectory(t)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of n){let n=A.join(t,r,`aapt`);if(A.isAbsolute(n)&&await e.isExecutable(n))return sd=n,n}}catch{}}}catch{}sd=null}async function kd(e,t){let n=await Ne({source:e,isInstallablePath:(e,t)=>t.isFile()&&Ad(e),installableLabel:`Android installable (.apk or .aab)`,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await jd(n.installablePath,t?.signal);return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:e.packageName,cleanup:n.cleanup}}catch(e){throw await n.cleanup(),e}}function Ad(e){let t=A.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function jd(e,t){let n=A.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await cd(e,t)}}async function Md(e,t,n,r={}){let i=typeof n.action==`string`&&n.action.trim()?n.action.trim():`${t}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,i,`-p`,t],s=typeof n.receiver==`string`?n.receiver.trim():``;s&&o.push(`-n`,s);let c=n.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new a(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(Nd(o,e,t),u+=1);return await E(e,o,{signal:r.signal}),{action:i,extrasCount:u}}function Nd(e,t,n){if(typeof n==`string`){e.push(`--es`,t,n);return}if(typeof n==`boolean`){e.push(`--ez`,t,n?`true`:`false`);return}if(typeof n==`number`&&Number.isFinite(n)){if(Number.isInteger(n)){e.push(`--ei`,t,String(n));return}e.push(`--ef`,t,String(n));return}throw new a(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}function X(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function Pd(e){let t=zd(e.map(e=>e.intendedVsyncNs)),n=[];for(let e=1;e<t.length;e+=1){let r=t[e]-t[e-1];r>=4e6&&r<=5e7&&n.push(r)}if(n.length!==0)return Bd(n)}function Fd(e){let{frames:t,frameDeadlineNs:n,summaryDroppedFrameCount:r}=e;return r===void 0?n===void 0?[]:t.filter(e=>e.durationNs>n):r<=0?[]:[...t].sort((e,t)=>t.durationNs-e.durationNs).slice(0,r).sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Id(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e;if(t.length===0||n===void 0)return[];let a=[],o=[];for(let e of t){let t=o.at(-1);if(!t||e.intendedVsyncNs-t.frameCompletedNs<=5e8){o.push(e);continue}a.push(o),o=[e]}return o.length>0&&a.push(o),a.map(e=>Rd({frames:e,windowStartNs:n,measuredAtMs:r,uptimeMs:i})).sort((e,t)=>t.missedDeadlineFrameCount-e.missedDeadlineFrameCount||t.worstFrameMs-e.worstFrameMs).slice(0,3).sort((e,t)=>e.startOffsetMs-t.startOffsetMs)}function Ld(e){return Math.round(e*10)/10}function Rd(e){let{frames:t,windowStartNs:n,measuredAtMs:r,uptimeMs:i}=e,a=Math.min(...t.map(e=>e.intendedVsyncNs)),o=Math.max(...t.map(e=>e.frameCompletedNs)),s=Math.max(0,Math.round((a-n)/1e6)),c=Math.max(s,Math.round((o-n)/1e6)),l=i!==void 0&&Number.isFinite(r)?r-i:void 0;return{startOffsetMs:s,endOffsetMs:c,startAt:l===void 0?void 0:new Date(l+a/1e6).toISOString(),endAt:l===void 0?void 0:new Date(l+o/1e6).toISOString(),missedDeadlineFrameCount:t.length,worstFrameMs:Ld(Math.max(...t.map(e=>e.durationNs))/1e6)}}function zd(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function Bd(e){let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2==1?t[n]:(t[n-1]+t[n])/2}function Vd(e,t,n){Hd(e,t);let r=Qd(e),i=Jd(e),a=Wd(i,r,t),o=Date.parse(n),s=ef({frames:i,measuredAtMs:o,summary:r}),c=Fd({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??af(i),u=Gd(r,i,c),d=qd({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...Kd(a),windowStartedAt:s.windowStartedAt,windowEndedAt:s.windowEndedAt,timestampSource:s.timestampSource,measuredAt:n,method:`adb-shell-dumpsys-gfxinfo-framestats`,source:r?`android-gfxinfo-summary`:`framestats-rows`,worstWindows:d&&d.length>0?d:void 0}}function Hd(e,t){if(/no process found for:/i.test(e))throw new a(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${t}`,{metric:`fps`,package:t,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf after the interaction you want to inspect.`})}function Ud(e){throw new a(`COMMAND_FAILED`,`Failed to parse Android framestats output for ${e}`,{metric:`fps`,package:e,hint:`Retry perf after exercising the app screen. If the problem persists, capture adb shell dumpsys gfxinfo <package> framestats output for debugging.`})}function Wd(e,t,n){let r=Pd(e);if(!t&&e.length===0&&Ud(n),t||r!==void 0)return r;throw new a(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${n}`,{metric:`fps`,package:n,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Gd(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?yn(i/r*100):0)}}function Kd(e){return{frameDeadlineMs:e===void 0?void 0:Ld(e/1e6),refreshRateHz:e===void 0?void 0:Ld(1e9/e)}}function qd(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=Id({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Jd(e){let t=[],n=null;for(let r of e.split(`
|
|
13
|
+
`)){let e=r.trim();if(e.length===0||e===`---PROFILEDATA---`)continue;let i=e.split(`,`).map(e=>e.trim());if(Yd(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=Xd(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Yd(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function Xd(e,t){if(!t||e.length<t.size)return;let n=Zd(e,t,`Flags`),r=Zd(e,t,`IntendedVsync`),i=Zd(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Zd(e,t,n){let r=t.get(n);if(r===void 0)return null;let i=Number(e[r]);return Number.isFinite(i)?i:null}function Qd(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=of(t,`Total frames rendered`),r=t.match(/^\s*Janky frames:\s*([0-9][0-9,]*)\s*\(([0-9.]+)%\)/im);if(n===void 0||!r)return;let i=r[1],a=r[2];if(i===void 0||a===void 0)return;let o=X(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=of(t,`Uptime`),l=of(t,`Stats since`);return{droppedFramePercent:yn(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:$d({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function $d(e){let{uptimeMs:t,statsSinceNs:n}=e;if(t===void 0||n===void 0)return;let r=t-Math.round(n/1e6);return r>=0?r:void 0}function ef(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=tf(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=nf(o,i.lastFrameNs),c=r?.sampleWindowMs??s;if(!Number.isFinite(n)||r?.uptimeMs===void 0||o===void 0)return{sampleWindowMs:c,windowStartNs:o};let l=n-r.uptimeMs;return{sampleWindowMs:c,windowStartNs:o,windowStartedAt:new Date(l+o/1e6).toISOString(),windowEndedAt:rf({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function tf(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function nf(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function rf(e){let{deviceBootWallClockMs:t,measuredAtMs:n,summaryStartNs:r,lastFrameNs:i}=e;return r===void 0?i===void 0?void 0:new Date(t+i/1e6).toISOString():new Date(n).toISOString()}function af(e){if(e.length===0)return;let t=tf(e);return nf(t.firstFrameNs,t.lastFrameNs)}function of(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`^\\s*${n}:\\s*([0-9][0-9,]*)`,`im`));if(!r)return;let i=r[1];return i===void 0?void 0:X(i)??void 0}async function sf(e,t,n={}){let r=v(e,n.adb);try{let i=Vd((await y(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await cf(e,t,n),i}catch(e){throw lf(t,e)}}async function cf(e,t,n={}){let r=v(e,n.adb);try{await y(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function lf(e,t){return t instanceof a?new a(t.code,t.message,{...t.details??{},metric:`fps`,package:e},t):new a(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},t)}async function uf(e,t,n,r,i){return{capture:{durationMs:r,packageName:t.packageName,appPid:t.appPid,artifactPath:t.outPath,sizeBytes:n},frameHealth:t.kind===`perfetto`?await df(e,t.packageName,i):void 0,notes:[t.kind===`perfetto`?`Frame health is sampled from Android gfxinfo around the trace window; open the Perfetto artifact for timeline root cause.`:`Open the Simpleperf report artifact for symbol-level CPU attribution.`]}}async function df(e,t,n){try{let r=await sf(e,t,n);return{available:!0,droppedFramePercent:r.droppedFramePercent,droppedFrameCount:r.droppedFrameCount,totalFrameCount:r.totalFrameCount,method:r.method,worstWindows:r.worstWindows?.slice(0,3).map(e=>({startOffsetMs:e.startOffsetMs,endOffsetMs:e.endOffsetMs,missedDeadlineFrameCount:e.missedDeadlineFrameCount,worstFrameMs:e.worstFrameMs}))}}catch(e){return{available:!1,reason:e instanceof Error?e.message:`Android frame health was not available`}}}async function ff(e,t,n){let r=v(e,n.adb);await _f(r,t),await bf(r,t),await yf(r,t,n.files);let i=await gf(t.outPath,n.files);await Z(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await uf(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?ri:ii,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function pf(e,t,n={}){let r=v(e,n.adb);try{t.state===`running`&&(await _f(r,t),await bf(r,t).catch(()=>{}))}finally{await Z(r,t.remotePath)}}function mf(e,t,n=oi){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Z(e,t){try{await y(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:ai})}catch{}}async function hf(e,t,n=b().files){await n.ensureDirectory(A.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function gf(e,t=b().files){try{return(await t.stat(e)).size}catch(t){throw new a(`COMMAND_FAILED`,`Profiler artifact was not written: ${e}`,{outPath:e,hint:`Retry the profiling command and check daemon logs if the artifact path is still missing.`},t)}}async function _f(e,t){try{await y(e,[C(vf(t.profilerPid))],{timeoutMs:I})}catch(e){throw F(`stop`,t.kind,t.packageName,e)}}function vf(e){return[`pid=${w(e)}`,`kill -INT "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`kill -TERM "$pid" 2>/dev/null || true`,`for i in 1 2 3 4 5 6 7 8 9 10; do kill -0 "$pid" 2>/dev/null || exit 0; sleep 0.2; done`,`echo "profiler process did not stop after SIGTERM" >&2`,`exit 1`].join(`; `)}async function yf(e,t,n){await(n??b().files).ensureDirectory(A.dirname(t.outPath));try{await e([`pull`,t.remotePath,t.outPath],{timeoutMs:I})}catch(e){throw new a(`COMMAND_FAILED`,`Failed to pull Android ${t.kind} artifact for ${t.packageName}`,{package:t.packageName,tool:t.kind,remotePath:t.remotePath,outPath:t.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function bf(e,t){let n;for(let r=0;r<12;r+=1){let r=await xf(e,t.remotePath);if(r!==void 0&&r>0&&r===n)return;n=r,await _(250)}throw new a(`COMMAND_FAILED`,`Android ${t.kind} artifact is not ready to pull`,{package:t.packageName,tool:t.kind,remotePath:t.remotePath,hint:`The profiler stopped, but the remote artifact was missing, empty, or still changing. Retry stop with the same session or inspect the device-side artifact.`})}async function xf(e,t){let n=w(t),r=await y(e,[C(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:ai});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function Sf(e,t,n,r={}){let i=v(e,r.adb),a=await si(i,t);await ci(i,`perfetto`,t);let o=mf(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await cf(e,t,{adb:i}),s=await wf(i,o,t)}catch(e){throw await Z(i,o),e}return{type:`trace`,kind:`perfetto`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:ii,message:`Started Android Perfetto trace for ${t}`}}async function Cf(e,t,n,r={}){return await ff(e,{...t,outPath:n},r)}async function wf(e,t,n){try{let r=li((await y(e,[`perfetto`,`--background-wait`,`-o`,t,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:I})).stdout);if(r)return r;throw new a(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:n,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw F(`start`,`perfetto`,n,e)}}function Tf(e){let t=[];for(let n of d(e)){let e=n.match(/^([0-9]+(?:\.[0-9]+)?)%\s+(.+)$/);if(!e)continue;let r=Number(e[1]),i=e[2]?.trim();if(!Number.isFinite(r)||!i)continue;let a=i.split(/\s{2,}/).filter(Boolean);if(t.push({percentage:yn(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function Ef(e,t,n,r={}){let i=v(e,r.adb),a=await si(i,t);await ci(i,`simpleperf`,t);let o=mf(t,`cpu.perf.data`),s;try{s=await kf(i,a,o,t)}catch(e){throw await Z(i,o),e}return{type:`cpu-profile`,kind:`simpleperf`,packageName:t,appPid:a,profilerPid:s,remotePath:o,outPath:n,startedAt:Date.now(),state:`running`,action:`start`,platform:`android`,method:ri,message:`Started Android Simpleperf CPU profile for ${t}`}}async function Df(e,t,n,r={}){return await ff(e,{...t,outPath:n},r)}async function Of(e,t,n,r={}){let i=v(e,r.adb);await ci(i,`simpleperf`,t.packageName);let a=await Mf(i,t),o=new Date().toISOString(),s=Tf(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await hf(n,{kind:`simpleperf-report`,generatedAt:o,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,sourceRemotePath:t.remotePath,entryCount:s.length,summary:{topFunctions:c},entries:s},r.files);let l=await gf(n,r.files);return{action:`report`,platform:`android`,type:`cpu-profile-report`,kind:`simpleperf`,packageName:t.packageName,appPid:t.appPid,sourceProfilePath:t.outPath,outPath:n,sizeBytes:l,generatedAt:o,entryCount:s.length,summary:{topFunctions:c},method:ri,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function kf(e,t,n,r){try{let i=li((await y(e,[C(Af(t,n))],{timeoutMs:I})).stdout);if(i)return i;throw new a(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:r,tool:`simpleperf`,hint:`Retry perf. If simpleperf exits immediately, verify the app is profileable and the device permits native profiling.`})}catch(e){throw F(`start`,`simpleperf`,r,e)}}function Af(e,t){return jf([`simpleperf`,`record`,`-e`,`cpu-clock:u`,`-p`,e,`-o`,t,`--duration`,`3600`],`simpleperf`)}function jf(e,t){let n=e.map(w).join(` `),r=`${oi}/agent-device-${t}-${Date.now()}.err`;return[`err=${w(r)}`,`(${n}) >/dev/null 2>"$err" & pid=$!`,`sleep 1`,`if kill -0 "$pid" 2>/dev/null; then rm -f "$err"; echo "$pid"; exit 0; fi`,`cat "$err" >&2`,`rm -f "$err"`,`exit 1`].join(`; `)}async function Mf(e,t){try{return await y(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:I})}catch(e){throw F(`report`,`simpleperf`,t.packageName,e)}}const Nf=15e3,Pf=12e4;async function Ff(e,t,n={}){let r=v(e,n.adb);try{return zf((await y(r,[`dumpsys`,`meminfo`,t],{timeoutMs:Nf})).stdout,t,new Date().toISOString())}catch(e){throw qf(`memory`,t,e)}}async function If(e,t,n,r={}){let i=v(e,r.adb),o=r.files??b().files,s=await Bf(i,t),c=Vf(t);await o.ensureDirectory(A.dirname(n));let l=await Lf(o,n);try{Oe(await y(i,[`am`,`dumpheap`,t,c],{allowFailure:!0,timeoutMs:Pf}),`Failed to capture Android heap dump for ${t}`,e=>({kind:`android-hprof`,package:t,pid:s,remotePath:c,hint:Hf(e.stdout,e.stderr)}));let e=await i([`pull`,c,n],{allowFailure:!0,timeoutMs:Pf});if(e.exitCode!==0)throw await Rf(o,n,l),T(`Failed to pull Android heap dump for ${t}`,e,{kind:`android-hprof`,package:t,pid:s,remotePath:c,path:n,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let r=await o.stat(n).catch(()=>null);if(!r?.isFile||r.size<=0)throw await Rf(o,n,l),new a(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:t,pid:s,path:n,remotePath:c,hint:`Retry with a writable --out path. If the file is still empty, inspect adb pull output with --debug.`});return{available:!0,kind:`android-hprof`,path:n,sizeBytes:r.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:t,pid:s,remotePath:c}}finally{await y(i,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:Nf}).catch(()=>{})}}async function Lf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function Rf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function zf(e,t,n){if(/no process found for:/i.test(e))throw new a(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${t}`,{metric:`memory`,package:t,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let r=Jf(e,`TOTAL PSS`)??Yf(e);if(r===void 0)throw new a(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${t}`,{metric:`memory`,package:t,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:r,totalRssKb:Jf(e,`TOTAL RSS`),measuredAt:n,method:`adb-shell-dumpsys-meminfo`,topConsumers:Uf(e)}}async function Bf(e,t){let n=await y(e,[`pidof`,t],{allowFailure:!0,timeoutMs:Nf}),r=n.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(n.exitCode===0&&r!==void 0)return r;throw new a(`COMMAND_FAILED`,`No running Android process found for ${t}`,{kind:`android-hprof`,package:t,stdout:n.stdout,stderr:n.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function Vf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function Hf(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`profileable`)||n.includes(`debuggable`)||n.includes(`not allowed`)?`Android heap dumps require a debuggable/profileable app process on many devices. Use a debug/profileable build, reopen the app, then retry.`:n.includes(`permission`)||n.includes(`denied`)?`The device denied heap dump access. Use a debug/profileable build or a device image that permits app heap dumping.`:`Reopen the app to refresh the process, then retry perf memory snapshot. If it still fails, run with --debug and inspect adb am dumpheap output.`}function Uf(e){let t=e.split(`
|
|
14
|
+
`).flatMap(e=>Wf(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Wf(e){let t=e.trim();if(Gf(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return Kf(n[1],n[2])}function Gf(e){if(!e||e.startsWith(`**`)||e.startsWith(`-`)||e.includes(`:`))return!0;let t=/^\S.+\s+\d/.test(e);return/^(pss|total|native|dalvik|unknown|app summary\b)/i.test(e)&&!t}function Kf(e,t){let n=e?.trim(),r=t?X(t):null;if(!(!n||n===`TOTAL`||r===null||r<=0)&&!/^(pss|private|shared|heap|size|alloc|free)$/i.test(n))return{name:n,pssKb:r}}function qf(e,t,n){return n instanceof a?new a(n.code,n.message,{...n.details??{},metric:e,package:t},n):new a(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},n)}function Jf(e,t){let n=t.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`),r=e.match(RegExp(`${n}:\\s*([0-9][0-9,]*)`,`i`));if(!r)return;let i=r[1];return i===void 0?void 0:X(i)??void 0}function Yf(e){for(let t of e.split(`
|
|
15
|
+
`)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>X(e)!==null);return n?X(n)??void 0:void 0}}async function Xf(e,t,n){let r=await E(e,[`dumpsys`,`package`,t],{allowFailure:!0});return r.exitCode===0?op(r.stdout,n):{requested:void 0,grants:void 0}}async function Zf(e){let t=await E(e,[`am`,`get-current-user`],{allowFailure:!0});if(t.exitCode!==0)return;let n=Number.parseInt(t.stdout.trim(),10);return Number.isInteger(n)&&n>=0?n:void 0}const Qf=/^\s*User (\d+):/,$f=/^\s*runtime permissions:\s*$/,ep=/^\s*([\w.]+): granted=(true|false)\b/,tp=/^\s*Package \[.+?\]/,np=/^\s*requested permissions:\s*$/,rp=/^\s*([A-Za-z][\w.]*)/;function ip(e){return e.split(`
|
|
16
|
+
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function ap(e,t){let n=Q(Q(Q(ip(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>Qf.exec(e.text)?.[1]===String(t)),e=>$f.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=ep.exec(e);t&&r.set(t[1],t[2]===`true`?`granted`:`not_granted`)}return r}function Q(e,t){if(!e)return;let n=e.findIndex(e=>t(e));if(n<0)return;let r=e.slice(n+1),i=r.findIndex(t=>t.indent<=e[n].indent);return i<0?r:r.slice(0,i)}function op(e,t){return{requested:sp(e),grants:ap(e,t)}}function sp(e){let t=Q(Q(Q(ip(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>tp.test(e.text)),e=>np.test(e.text));if(!t)return;let n=[];for(let{text:e}of t){let t=rp.exec(e)?.[1];t&&t.includes(`.`)&&!n.includes(t)&&n.push(t)}return n}function cp(e,t,n){if(n!==`not_granted`)return`${n===`granted`?`${t} was granted before this revoke, and Android kills an app when a granted permission is revoked: if ${e} was running it is no longer.`:`Whether ${t} was granted before this revoke could not be read (adb did not report the acting user's runtime permission state), and Android kills an app when a granted permission is revoked: ${e} may no longer be running.`} Relaunch it with open ${e} --relaunch before the next interaction.`}const lp=[`all`,`camera`,`microphone`,`photos`,`contacts`,`notifications`,`calendar`,`location`,`media-library`],up={calendar:[`android.permission.WRITE_CALENDAR`,`android.permission.READ_CALENDAR`],camera:[`android.permission.CAMERA`],contacts:[`android.permission.READ_CONTACTS`,`android.permission.WRITE_CONTACTS`],location:[`android.permission.ACCESS_FINE_LOCATION`,`android.permission.ACCESS_COARSE_LOCATION`],"media-library":[`android.permission.WRITE_EXTERNAL_STORAGE`,`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_AUDIO`,`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_MEDIA_VIDEO`],microphone:[`android.permission.RECORD_AUDIO`]};async function dp(e){let t=await Zf(e);if(t!==void 0)return t;throw new a(`COMMAND_FAILED`,`Could not determine which Android user the session runs as, so no permission was changed.`,{deviceId:e.id,hint:`Check adb -s ${e.id} shell am get-current-user — if the device is still booting, retry once it reports a user. agent-device refuses to change permissions it cannot scope, because pm would silently apply them to user 0.`})}async function fp(e,t,n,r){let i=ve(n),a=Np(r?.permissionTarget,r?.permissionMode),o=await dp(e),s=[`--user`,String(o)];if(a.kind===`all`)return await hp(e,t,i,o,s);if(i===`grant`){let n=await jp(e,t,a,o,s);return mp(pp(a),n)}if(a.kind===`pm`)return await Ip(e,t,i,a,o,s);let{grants:c}=await Xf(e,t,o),l=await Mp(e,t,i,a,s),{priorGrantState:u,warnings:d}=Rp(t,l,l.map(e=>c?.get(e)??`unknown`));return mp(a.kind,l,{priorGrantState:u,warnings:d})}function pp(e){return e.kind===`pm`?e.name:e.kind}function mp(e,t,n){return{permission:e,permissions:[...t],...n?{priorGrantState:n.priorGrantState,...n.warnings.length>0?{warnings:n.warnings}:{}}:{}}}async function hp(e,t,n,r,i){let{requested:o,grants:s}=await Xf(e,t,r);if(o===void 0)throw new a(`COMMAND_FAILED`,`Could not read declared permissions for ${t}, so no permission was changed.`,{appPackage:t});let c=n===`grant`?void 0:s,l=[],u=[];for(let r of Sp(o))await gp({device:e,appPackage:t,action:n,userArgs:i,grants:c,applied:l,warnings:u},r);return{permission:`all`,permissions:l,...u.length>0?{warnings:u}:{}}}async function gp(e,t){return t.kind===`notification`?await _p(e):t.kind===`photos`?await vp(e):await yp(e,t.value)}async function _p(e){let{device:t,appPackage:n,action:r,userArgs:i}=e;await Bp(t,n,r,{appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`},i),bp(e,`android.permission.POST_NOTIFICATIONS`)}async function vp(e){let{device:t,appPackage:n,action:r,userArgs:i,warnings:a}=e,o=await Dp(t,n,r===`grant`?`grant`:`revoke`,i);if(o===void 0){a.push(`Skipped Android photos permission for ${n}: device refused both media candidates.`);return}await xp(e,o)}async function yp(e,t){let{device:n,appPackage:r,action:i,userArgs:a,warnings:o}=e,s=await Ep(n,i===`grant`?`grant`:`revoke`,a,r,t);if(s.kind===`skipped`){o.push(`Skipped ${t} for ${r}: ${s.detail}`);return}await xp(e,t)}function bp(e,t){let{appPackage:n,action:r,grants:i,applied:a,warnings:o}=e;a.push(t),r!==`grant`&&Cp(o,i,n,t)}async function xp(e,t){bp(e,t),e.action===`reset`&&await Vp(e.device,e.appPackage,t,e.userArgs)}function Sp(e){let t=[],n=!1;for(let r of e)r===`android.permission.POST_NOTIFICATIONS`?t.push({kind:`notification`}):r===`android.permission.READ_MEDIA_IMAGES`||r===`android.permission.READ_EXTERNAL_STORAGE`?n||(n=!0,t.push({kind:`photos`})):t.push({kind:`pm`,value:r});return t}function Cp(e,t,n,r){let i=cp(n,r,t?.get(r)??`unknown`);i&&e.push(i)}const wp=[[/not a changeable permission/,`not-changeable`],[/has not requested permission/,`not-requested`],[/is not a runtime permission/,`not-runtime-permission`],[/unknown permission/,`unknown-permission`],[/managed by role/,`role-managed`]];function Tp(e){let t=e.toLowerCase();return wp.find(([e])=>e.test(t))?.[1]}async function Ep(e,t,n,r,i){let a=await E(e,[`pm`,t,...n,r,i],{allowFailure:!0});if(a.exitCode===0)return{kind:`applied`};let o=Tp(a.stderr);if(o)return{kind:`skipped`,reason:o,detail:Ap(a.stderr)};throw T(`Failed to ${t} Android permission ${i} for ${r}`,a,{appPackage:r,permission:i})}async function Dp(e,t,n,r){try{return await zp(e,t,n,r)}catch(e){if(Op(e))return;throw e}}function Op(e){if(!(e instanceof a)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.attempts;return kp(t)&&t.length>0&&t.every(e=>e.reason!==void 0)}function kp(e){return Array.isArray(e)&&e.every(e=>typeof e==`object`&&!!e&&typeof e.permission==`string`&&typeof e.detail==`string`)}function Ap(e){let t=e.split(`
|
|
17
|
+
`).map(e=>e.trim()).filter(e=>e.length>0),n=t[0]??`unknown device error`;return(n.endsWith(`:`)&&t[1]?`${n} ${t[1]}`:n).slice(0,200)}async function jp(e,t,n,r,i){if(n.kind===`notifications`)return await Bp(e,t,`grant`,n,i),[n.permission];if(n.kind===`photos`)return[await zp(e,t,`grant`,i)];if(n.kind===`pm`){let a=[...await Pp(e,t,n.values,r)];for(let n of a)await E(e,[`pm`,`grant`,...i,t,n]);return a}throw n.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(n)}`)}async function Mp(e,t,n,r,i){if(r.kind===`notifications`)return await Bp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await zp(e,t,`revoke`,i);return n===`reset`&&await Vp(e,t,r,i),[r]}throw r.kind===`pm`?Error(`Unhandled Android permission target: pm is resolved by the caller.`):r.kind===`all`?Error(`Unhandled Android permission target: all is resolved by the caller.`):Error(`Unhandled Android permission target: ${JSON.stringify(r)}`)}function Np(e,t){let n=be(e);if(t?.trim())throw new a(`INVALID_ARGS`,`Android does not support permission modes. Received: ${t}.`);if(n===`all`)return{kind:`all`};if(n===`photos`)return{kind:`photos`};if(n===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let r=n in up?up[n]:void 0;if(r)return{kind:`pm`,name:n,values:r};throw new a(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${lp.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function Pp(e,t,n,r){let{requested:i}=await Xf(e,t,r);return Fp(i,n,t)}function Fp(e,t,n){if(e===void 0)return t;let r=t.filter(t=>e.includes(t));if(r.length===0)throw new a(`COMMAND_FAILED`,`Package ${n} has not requested permission ${t.join(`, `)}, so no permission was changed.`,{appPackage:n,permissions:t});return r}async function Ip(e,t,n,r,i,a){let{requested:o,grants:s}=await Xf(e,t,i),c=Fp(o,r.values,t);await Lp(e,t,c,n,a);let{priorGrantState:l,warnings:u}=Rp(t,c,c.map(e=>s?.get(e)??`unknown`));return mp(r.name,c,{priorGrantState:l,warnings:u})}async function Lp(e,t,n,r,i){for(let r of n)await E(e,[`pm`,`revoke`,...i,t,r]);if(r===`reset`)for(let r of n)await Vp(e,t,r,i)}function Rp(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=cp(e,t,n[r]);return i?[i]:[]})}}async function zp(e,t,n,r){let i=await Hp(e),o=i!==null&&i>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let i of o){let a=await E(e,[`pm`,n,...r,t,i],{allowFailure:!0});if(a.exitCode===0)return i;s.push({permission:i,reason:Tp(a.stderr),detail:Ap(a.stderr)})}throw new a(`COMMAND_FAILED`,`Failed to ${n} Android photos permission`,{appPackage:t,sdkInt:i,attempts:s})}async function Bp(e,t,n,r,i){let a=n===`grant`?`allow`:n===`deny`?`deny`:`default`;n===`grant`?await E(e,[`pm`,`grant`,...i,t,r.permission],{allowFailure:!0}):(await E(e,[`pm`,`revoke`,...i,t,r.permission],{allowFailure:!0}),n===`reset`&&await Vp(e,t,r.permission,i)),await E(e,[`appops`,`set`,...i,t,r.appOps,a])}async function Vp(e,t,n,r){for(let i of[`user-set`,`user-fixed`])await E(e,[`pm`,`clear-permission-flags`,...r,t,n,i],{allowFailure:!0})}async function Hp(e){let t=await E(e,[`getprop`,`ro.build.version.sdk`],{allowFailure:!0});if(t.exitCode!==0)return null;let n=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(n)||n<=0?null:n}const Up=[`cmd`,`connectivity`,`airplane-mode`];async function Wp(e,t){let n=t?`enabled`:`disabled`;await Gp(e),await E(e,[...Up,t?`enable`:`disable`]);let r=await Kp(e);if(r!==n)throw new a(`COMMAND_FAILED`,`Android airplane mode reads ${r} after requesting ${n}.`,{deviceId:e.id,requested:n,airplaneMode:r});return{airplaneMode:r}}async function Gp(e){let{state:t,result:n}=await qp(e);if(!t)throw n.exitCode!==0&&ot(n.stdout,n.stderr)?new a(`UNSUPPORTED_OPERATION`,`The connectivity service on this Android build has no airplane-mode command, so nothing was changed.`,{deviceId:e.id,hint:`settings airplane needs cmd connectivity airplane-mode, which requires Android 11 (API 30) or newer. Use a newer device or emulator image.`,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode}):T(`Failed to read Android airplane mode`,n,{deviceId:e.id})}async function Kp(e){let{state:t,result:n}=await qp(e);if(t)return t;throw T(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function qp(e){let t=await E(e,[...Up],{allowFailure:!0});return{state:t.exitCode===0?Jp(t.stdout):void 0,result:t}}function Jp(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Yp=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`],Xp={"extra-small":`0.82`,small:`0.88`,medium:`0.94`,large:`1.0`,"extra-large":`1.12`,"extra-extra-large":`1.24`,"extra-extra-extra-large":`1.35`,"accessibility-medium":`1.5`,"accessibility-large":`1.75`,"accessibility-extra-large":`2.0`,"accessibility-extra-extra-large":`2.5`,"accessibility-extra-extra-extra-large":`3.2`},Zp=Xp.large;async function Qp(e,n,r,i,o){switch(n.toLowerCase()){case`wifi`:{let t=ge(r);await E(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await Wp(e,ge(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new a(`UNSUPPORTED_OPERATION`,`Android precise location coordinates are supported only on emulators.`,{deviceId:e.id,hint:`Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling.`});let{latitude:t,longitude:n}=xe(o);return await at(e,[`emu`,`geo`,`fix`,String(n),String(t)]),{latitude:t,longitude:n}}let t=ge(r)?`3`:`0`;await E(e,[`settings`,`put`,`secure`,`location_mode`,t]);return}case`animations`:{let t=ge(r)?`1`:`0`;for(let n of Yp)await E(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Yp]}}case`appearance`:{let t=await cm(e,r);await E(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new a(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new a(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`,t());let n=await Jt(e,i);if(n.type===`intent`)throw new a(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await E(e,[`am`,`force-stop`,n.value],{allowFailure:!0});let o=await E(e,[`pm`,`clear`,n.value],{allowFailure:!0});if(o.exitCode!==0||!/\bSuccess\b/i.test(o.stdout))throw new a(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await am(e,im(r));return;case`permission`:if(!i)throw new a(`INVALID_ARGS`,`permission setting requires an active app in session`,t());return await fp(e,i,r,o);case`text-size`:return await tm(e,r);default:throw new a(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}const $p={"text-size":nm};async function em(e,t){return await $p[t](e)}async function tm(e,t){let n=ye(t),r=Xp[n];return await E(e,[`settings`,`put`,`system`,`font_scale`,r]),me(n,r)}async function nm(e){let t=(await E(e,[`settings`,`get`,`system`,`font_scale`])).stdout.trim(),n=t===`null`?Zp:t,r=/^(\d+(\.\d+)?)$/.test(n)?Number(n):NaN;if(!Number.isFinite(r)||r<=0)throw new a(`COMMAND_FAILED`,`Android reported an unusable font scale: ${t||`(empty)`}`,{deviceId:e.id,fontScale:t,hint:"Run `adb shell settings get system font_scale` to see what the device holds."});return me(rm(r),n)}function rm(e){let t=_e[0],n=1/0;for(let r of _e){let i=Math.abs(Number.parseFloat(Xp[r])-e);i>=n||(t=r,n=i)}return t}function im(e){let t=e.trim().toLowerCase();if(t===`match`)return`match`;if(t===`nonmatch`)return`nonmatch`;throw new a(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function am(e,t){let n=om(e,t),r=[];for(let t of n){let n=await at(e,t,{allowFailure:!0});if(n.exitCode===0)return;r.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let i=c(r);throw r.length>0&&r.every(e=>sm(e.stdout,e.stderr))?new a(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:t,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:i}):new a(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:t,attempts:i})}function om(e,t){let n=t===`match`?`1`:`9999`,r=[Ke(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),Ke(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function sm(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unknown command`)||n.includes(`can't find service: fingerprint`)||n.includes(`service fingerprint was not found`)||n.includes(`fingerprint cmd unavailable`)||n.includes(`emu command is not supported`)||n.includes(`emulator console is not running`)||n.includes(`fingerprint`)&&n.includes(`not found`)}async function cm(e,t){let n=he(t);if(n!==`toggle`)return n;let r=await E(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(r.exitCode!==0)throw T(`Failed to read current Android appearance`,r);let i=lm(r.stdout,r.stderr);if(!i)throw new a(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:r.stdout,stderr:r.stderr});return i===`auto`?`dark`:i===`dark`?`light`:`dark`}function lm(e,t){let n=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`yes`?`dark`:r===`no`?`light`:r===`auto`?`auto`:null}const um=Buffer.from([137,80,78,71,13,10,26,10]);async function dm(e,t,n={}){if(n.stabilize===!1)return await mm(e,t);await fm(e);try{return await _(1e3),await mm(e,t)}finally{await pm(e).catch(()=>{})}}async function fm(e){let t=t=>E(e,t,{allowFailure:!0});await t([`settings`,`put`,`global`,`sysui_demo_allowed`,`1`]);let n=e=>t([`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,...e]);await n([`clock`,`-e`,`hhmm`,`0941`]),await n([`notifications`,`-e`,`visible`,`false`])}async function pm(e){await E(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function mm(e,t){let n=new AbortController,r=ao(e,{timeoutMs:2e3,signal:n.signal});try{await gm(e,t);let n=await hm(r,250);return n?{displayRotation:n}:{}}finally{n.abort()}}async function hm(e,t){let n;try{return await Promise.race([e,new Promise(e=>{n=setTimeout(()=>e(void 0),t)})])}finally{clearTimeout(n)}}async function gm(e,t){let n=await it(e,[`screencap`,`-p`],{binaryStdout:!0});if(!n.stdoutBuffer)throw new a(`COMMAND_FAILED`,`Failed to capture screenshot`);let r=n.stdoutBuffer.indexOf(um);if(r<0)throw new a(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let i=_m(n.stdoutBuffer,r);if(!i)throw new a(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await b().files.writeBytes(t,n.stdoutBuffer.subarray(r,i))}function _m(e,t){let n=t+um.length;for(;n+8<=e.length;){let t=e.readUInt32BE(n),r=n+4,i=e.toString(`ascii`,r,r+4),a=n+12+t;if(a>e.length)return null;if(i===`IEND`)return a;n=a}return null}async function vm(e,t,n=0){let r=He(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Cm(e,`type`,t);if(i.backend===`test-ime`){await Tm(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Dm(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Dm(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function ym(e,t,r,i,a=0,o={}){let s=await Cu(e,t,r,o),c=He(e);if(c)return await c({action:`fill`,target:{x:t,y:r},text:i,delayMs:a}),$(`fill`,`provider-native`,i),Y(i,s,await bu(e,t,r,i,o));let l=null,u=0;try{for(let n of bm(a)){await co(e,t,r),u+=1;let a=await Cm(e,`fill`,i);if(a.backend===`test-ime`)return Y(i,s,await Em(e,a.packageName,t,r,i,s,o));let c=await xm(e,{x:t,y:r,text:i,beforeTarget:s,attempt:n},o);if(l=c,c.ok)return;if(c.reason===`ime_capture`)return Y(i,s,c);let d=Tu(i,s,c);if(d)return d}}catch(e){throw n(e,u)}return Y(i,s,l)}function bm(e){return[{clearPadding:12,minClear:8,maxClear:48,chunkSize:e>0?1:8,inputDelayMs:e},{clearPadding:24,minClear:16,maxClear:96,chunkSize:e>0?1:4,inputDelayMs:e>0?e:15}]}async function xm(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await Mm(e,Sm(a,o,s)),await Dm(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),bu(e,r,i,a,n)}function Sm(e,t,n){let r=Array.from(e).length;return Vm(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Cm(e,t,n){let r=wt(e);if(r)return r.rebindUnconfirmed&&await wm(e),{backend:`test-ime`,packageName:(await gt(S(e))).manifest.packageName};let i=await Nm(e,t),a=i?.inputMethodPackage;return Et(a)?{backend:`test-ime`,packageName:a}:(Fm(n),Pm(i,t),{backend:`adb-shell`})}async function wm(e){let{rebindAndroidTestIme:t}=await import(`./ime-rebind.js`),n=await t(e);if(n.kind!==`confirmed`)throw new a(`COMMAND_FAILED`,`Could not confirm the Android test IME rebind on ${e.name??e.id}.`,{reason:`android_test_ime_rebind_unconfirmed`,rebindCause:n.kind===`not-owned`?`not-owned`:n.cause,deviceId:e.id,hint:`Close and reopen the session to restore the keyboard and reactivate the test IME.`})}async function Tm(e,t,n,r){let i=v(e);await km(e,Om(n,r>0?1:1/0,r),{delayMs:r,sendChunk:async e=>await Mt(i,t,e)}),$(`type`,`test-ime`,n)}async function Em(e,t,r,i,a,o,s){let c=v(e),l=0,u=async()=>(await bt(c,t),l+=1,a&&(await Mt(c,t,a),l+=1),await bu(e,r,i,a,s)),d=async()=>{let t=await u();return t.ok||Tu(a,o,t)?t:(wu(t,o)&&await wm(e),await co(e,r,i),l+=1,await u())},f;try{f=await d()}catch(e){throw n(e,l)}return $(`fill`,`test-ime`,a),f}async function Dm(e,t){await km(e,Om(t.text,t.chunkSize,t.delayMs),{delayMs:t.delayMs,sendChunk:async t=>{try{await jm(e,t)}catch(e){throw $e(e)}}}),$(t.action,`adb-shell`,t.text)}function Om(e,t,n){let r=e.split(`
|
|
18
|
+
`);return r.flatMap((e,i)=>{let a=Bm(e,t),o=i+1===r.length,s=a.map((e,t)=>({kind:`chunk`,text:e,pauseAfter:n>0&&!(o&&t+1===a.length)}));return o?s:[...s,{kind:`enter`}]})}async function km(e,t,r){let i=0;try{for(let n of t){if(n.kind===`enter`){await Am(e),i+=1;continue}n.text&&(await r.sendChunk(n.text),i+=1),n.pauseAfter&&await _(r.delayMs)}}catch(e){throw n(e,i)}}async function Am(e){try{await E(e,[`input`,`keyevent`,`ENTER`])}catch(e){throw $e(e)}}async function jm(e,t){try{await E(e,[`input`,`text`,Lm(t)])}catch(e){throw Rm(e)?zm(t,e):e}}async function Mm(e,t){let r=Math.max(0,t),i=0;try{await E(e,[`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0}),i+=1;for(let t=0;t<r;t+=24){let n=Math.min(24,r-t);await E(e,[`input`,`keyevent`,...Array(n).fill(`KEYCODE_DEL`)],{allowFailure:!0}),i+=1}}catch(e){throw n(e,i)}}async function Nm(e,t){try{return await Vo(e)}catch(e){return g({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:t,error:e instanceof Error?e.message:String(e)}}),null}}function Pm(e,t){if(!(!e||e.inputOwner!==`ime`))throw new a(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:t,inputOwner:e.inputOwner,inputType:e.inputType,type:e.type,inputMethodPackage:e.inputMethodPackage,focusedPackage:e.focusedPackage,focusedResourceId:e.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}function Fm(e){if(!Im(e))throw zm(e)}function Im(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
|
|
19
|
+
`&&(e<32||e>126))return!1}return!0}function Lm(e){return e.replaceAll(` `,`%s`)}function Rm(e){if(!(e instanceof a)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.stderr,n=(typeof t==`string`?t:``).toLowerCase();return!!(n.includes(`exception occurred while executing 'text'`)||n.includes(`nullpointerexception`)&&n.includes(`inputshellcommand.sendtext`))}function zm(e,t){return new a(`COMMAND_FAILED`,`Android text input requires provider-native text injection or the bundled test IME helper for non-ASCII/control characters; the adb-shell fallback supports ASCII text only.`,{backend:`adb-shell`,reason:f,textLength:Array.from(e).length,textPreview:e.slice(0,32),hint:"On emulators the test IME activates automatically; on real devices pass `open --test-ime` to enable it (see `agent-device doctor` for the current IME state)."},t instanceof Error?t:void 0)}function Bm(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,n){g({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}function Vm(e,t,n){return Math.max(t,Math.min(n,e))}var Hm=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>en,ANDROID_FOCUS_MARKERS:()=>Qt,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>jt,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>pn,ANDROID_TOUCH_PLAN_PROTOCOL:()=>Da,AndroidSnapshotPresentationFailure:()=>J,activateAndroidTestIme:()=>Ju,androidAdbForwardsDeviceExitStatus:()=>Cn,androidAdbHostTarget:()=>Ze,androidAdbInvocation:()=>Ye,androidAdbResultError:()=>T,androidAdbSerialTarget:()=>Xe,androidAppsDiscoveryHint:()=>Yt,androidCaptureFailureReasonDetail:()=>Xr,androidCaptureFailureReasonFromExitCode:()=>Yr,androidCaptureFailureReasonFromHelperResult:()=>Jr,androidClipboardShellSupportForResult:()=>Wm,androidDeviceChecks:()=>hs,androidFillFailureDetails:()=>ku,androidFillFailureMessage:()=>Ou,androidRevokedPermissionWarning:()=>cp,androidSnapshotPublicationInput:()=>Ll,androidToolchainCheck:()=>ms,androidUiNodes:()=>Wc,annotateAndroidNativePerfError:()=>F,appSwitcherAndroid:()=>oo,attachAdbFailureHint:()=>et,backAndroid:()=>Xa,buildAndroidFillUnconfirmedVerification:()=>Tu,buildAndroidNativeToolUnavailableHint:()=>Qr,buildAndroidSnapshotClickabilityEvidence:()=>il,buildAndroidSnapshotHelperArgs:()=>ji,buildAndroidSnapshotHelperCaptureOptions:()=>ki,buildUiHierarchySnapshot:()=>wc,captureAndroidHeapSnapshot:()=>If,captureAndroidLogcatWithAdb:()=>Gm,captureAndroidSnapshotWithHelper:()=>Oi,captureAndroidSnapshotWithHelperSession:()=>Sa,classifyAdbFailure:()=>rt,classifyAndroidAlertIdentifier:()=>Fn,classifyAndroidAppTarget:()=>Wt,classifyAndroidHelperContent:()=>ol,cleanupAndroidNativePerfSession:()=>pf,clearAndroidImeHelperText:()=>bt,clearAndroidTestImeRecoveryMarker:()=>nd,closeAndroidApp:()=>zt,completeAndroidFillVerification:()=>Y,createAndroidPortReverseManager:()=>Be,createAndroidSnapshotCapture:()=>Fl,createAndroidSnapshotPresentationBudget:()=>yc,createAndroidSnapshotPresentationNode:()=>hc,createAndroidWindowDumpReader:()=>an,createDeviceAdbExecutor:()=>Ve,createLocalAndroidAdbProvider:()=>Le,dismissAndroidKeyboard:()=>Ho,dismissAndroidKeyboardWithAdb:()=>Uo,doubleTapAndroid:()=>Ja,ensureAndroidEmulatorBooted:()=>Ht,ensureAndroidImeHelper:()=>xt,ensureAndroidSdkPathConfigured:()=>Rt,ensureAndroidSnapshotHelper:()=>Vr,executeAndroidTouchHelperPlan:()=>ja,executeAndroidTouchPlan:()=>Ga,fillAndroid:()=>ym,findAndroidAlertCandidate:()=>In,focusAndroid:()=>co,forceStopAndroidAppWithAdb:()=>To,forgetAndroidSnapshotHelperInstall:()=>Pr,formatAndroidInstalledPackageRequiredMessage:()=>qt,getAndroidAppState:()=>nn,getAndroidBlockingDialogObservation:()=>rn,getAndroidImeHelperDeviceKey:()=>D,getAndroidKeyboardState:()=>Vo,getAndroidKeyboardStatusWithAdb:()=>G,getAndroidScreenSize:()=>po,handleAndroidAlert:()=>mo,homeAndroid:()=>Za,inferAndroidAppName:()=>Kt,inferAndroidPackageAfterOpen:()=>qm,inspectInstalledAndroidHelper:()=>mr,installAndroidAdbPackage:()=>Ue,installAndroidInstallablePath:()=>Io,isAmStartError:()=>Vt,isAndroidImeHelperPackage:()=>Et,isAndroidPermissionPackage:()=>Dn,isAndroidSnapshotPresentationFailure:()=>_c,isAndroidTestImeActive:()=>_t,listAndroidAdbSerialsQuick:()=>fs,listAndroidAppsWithAdb:()=>Um,longPressAndroid:()=>so,lowerAndroidAdbInvocation:()=>qe,lowerAndroidTouchPlan:()=>Ua,makeEnsureAndroidHelperInstalled:()=>gr,normalizeAndroidTouchHelperGestureRequest:()=>Ia,openAndroidApp:()=>Lt,openAndroidAppWithAdb:()=>Do,openAndroidDevice:()=>Ft,parseAndroidAdbArgv:()=>Qe,parseAndroidHelperManifest:()=>Dr,parseAndroidLaunchComponent:()=>Bt,parseAndroidLaunchablePackages:()=>Zt,parseAndroidSnapshotHelperManifest:()=>Dr,parseAndroidSnapshotHelperOutput:()=>Ni,parseAndroidUserInstalledPackages:()=>Xt,parseInstrumentationRecords:()=>nr,parseUiHierarchyTree:()=>nl,prepareAndroidInstallArtifact:()=>kd,pressAndroid:()=>W,pressAndroidEnter:()=>Qa,pressAndroidTvRemote:()=>Ya,pullAndroidAdbFile:()=>ze,pushAndroidNotification:()=>Md,readAndroidBlockingDialogFocus:()=>$t,readAndroidClipboardText:()=>es,readAndroidClipboardWithAdb:()=>ts,readAndroidDefaultInputMethod:()=>k,readAndroidFillTargetBeforeMutation:()=>Cu,readAndroidGestureViewport:()=>Ka,readAndroidHelperManifestInteger:()=>Nt,readAndroidHelperManifestLiteral:()=>vt,readAndroidSetting:()=>em,readAndroidTestImeRecoveryMarkers:()=>rd,readAndroidTextAtPoint:()=>xu,readAndroidTextAtPointInHierarchy:()=>Du,readAndroidTouchHelperFinalRecord:()=>za,readAndroidTouchHelperViewportReading:()=>Ma,readInstrumentationResultBoolean:()=>lr,readInstrumentationResultNumber:()=>M,resetAndroidAdbShellProtocolProbes:()=>wn,resetAndroidFramePerfStats:()=>cf,resetAndroidImeHelperInstallCache:()=>Ct,resetAndroidSnapshotHelperInstallCache:()=>Lr,resetAndroidSnapshotHelperRuntime:()=>Nl,resetAndroidSnapshotHelperSessions:()=>xa,resetAndroidTestImeActivationCacheForTests:()=>At,resetAndroidWindowDumpFocusMemoForTests:()=>tn,resolveAndroidAdbExecutor:()=>v,resolveAndroidAdbProvider:()=>S,resolveAndroidApp:()=>Jt,resolveAndroidArchivePackageName:()=>cd,resolveAndroidHelperArtifact:()=>hr,resolveAndroidImeHelperArtifact:()=>St,resolveAndroidPackageForOpen:()=>Km,resolveAndroidSnapshotHelperCaptureOptions:()=>Ai,resolveAndroidTextInjector:()=>He,resolveAndroidTouchProvider:()=>Fe,resolveScopedAndroidAdbBackgroundTransport:()=>Re,restoreAndroidTestIme:()=>ss,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>ds,retireAndroidSnapshotHelperAfterContentFailure:()=>Ml,runAdbExecOut:()=>We,runAdbShell:()=>y,runAndroidAdb:()=>at,runAndroidExecOut:()=>it,runAndroidHostAdb:()=>Pe,runAndroidShell:()=>E,runAndroidSnapshotHelperSessionTouchCommand:()=>wa,sampleAndroidFramePerf:()=>sf,sampleAndroidMemoryPerf:()=>Ff,screenshotAndroid:()=>dm,scrollAndroid:()=>lo,selectAndroidImeHelperArtifact:()=>gt,sendAndroidImeHelperText:()=>Mt,serializeAndroidAdbInvocation:()=>Je,setAndroidOrientation:()=>$a,setAndroidPermission:()=>fp,setAndroidSetting:()=>Qp,setAndroidTestImeActiveForTests:()=>yt,sleep:()=>_,snapshotAndroid:()=>zl,startAndroidPerfettoTrace:()=>Sf,startAndroidSimpleperfProfile:()=>Ef,stopAndroidPerfettoTrace:()=>Cf,stopAndroidSimpleperfProfile:()=>Df,stopAndroidSnapshotHelperSession:()=>H,stopAndroidSnapshotHelperSessionForDevice:()=>ba,typeAndroid:()=>vm,validateAndroidGestureViewport:()=>ur,validateAndroidRegularPresentation:()=>bc,verifyAndroidFilledText:()=>bu,verifyAndroidFilledTextInHierarchy:()=>Eu,verifyAndroidHelperApkChecksum:()=>br,waitForAndroidBoot:()=>It,withAndroidAdbProvider:()=>Ie,withAndroidAppResolutionCacheInvalidated:()=>Gt,withAndroidHostAdbTransport:()=>Ge,writeAndroidClipboardText:()=>ns,writeAndroidClipboardWithAdb:()=>rs,writeAndroidSimpleperfReport:()=>Of,writeAndroidTestImeRecoveryMarker:()=>td});async function Um(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function Wm(...e){let{androidClipboardShellSupportForResult:t}=await import(`./clipboard-shell-response.js`);return t(...e)}async function Gm(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function Km(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function qm(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{Ya as A,Xa as C,so as D,Za as E,$a as M,Ga as N,W as O,Ka as P,oo as S,co as T,ns as _,vm as a,Do as b,Qp as c,Ho as d,Uo as f,ts as g,es as h,ym as i,lo as j,Qa as k,zl as l,G as m,Um as n,dm as o,Vo as p,Hm as r,em as s,Gm as t,Ll as u,rs as v,Ja as w,mo as x,To as y};
|