agent-device 0.21.15 → 0.21.17
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/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.15.apk → agent-device-android-ime-helper-0.21.17.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.17.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.15.manifest.json → agent-device-android-ime-helper-0.21.17.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.15.apk → agent-device-android-snapshot-helper-0.21.17.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.17.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.15.manifest.json → agent-device-android-snapshot-helper-0.21.17.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +1 -4
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +9 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +13 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSystemSurfaceHostPolicy.swift +0 -9
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandDispatch.swift +31 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +9 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +40 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +202 -73
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +17 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +109 -128
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +4 -0
- package/dist/src/adapter.js +1 -1
- package/dist/src/adb-executor.js +1 -1
- package/dist/src/adb-failure.js +1 -1
- package/dist/src/adb-transport.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-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/ai-sdk.js +1 -1
- package/dist/src/alert-runtime.js +1 -1
- package/dist/src/android-input-ownership.js +1 -1
- package/dist/src/app-catalog.js +1 -1
- package/dist/src/app-deployment-resolution.js +1 -1
- package/dist/src/app-inventory.js +1 -1
- package/dist/src/app-launch.js +1 -1
- package/dist/src/app-lifecycle.js +1 -1
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-files.js +1 -1
- package/dist/src/app-log-runtime2.js +1 -1
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/apple-runner-platform.js +1 -1
- package/dist/src/application-lifecycle-interaction.js +1 -1
- package/dist/src/archive.js +1 -1
- package/dist/src/artifact-download.js +1 -1
- package/dist/src/auth-session.js +1 -1
- package/dist/src/auth.js +1 -1
- package/dist/src/back-mode.js +1 -1
- package/dist/src/backend-snapshot-options.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/cache.js +1 -0
- package/dist/src/capture.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +9 -7
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/click-button.js +1 -1
- package/dist/src/client-metro-companion.js +1 -1
- package/dist/src/client-metro.js +1 -1
- package/dist/src/client-types.d.ts +6 -6
- package/dist/src/clipboard-shell-response.js +1 -1
- package/dist/src/code-signature-cache.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/command-tools.js +3 -3
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/connection.js +5 -5
- package/dist/src/contracts.js +1 -1
- package/dist/src/daemon-client-lease-beat.js +1 -0
- package/dist/src/daemon-client-lifecycle.js +1 -1
- package/dist/src/daemon-client-transport.js +1 -0
- package/dist/src/daemon-policy-file.js +1 -0
- package/dist/src/daemon-process.js +1 -1
- package/dist/src/daemon-registration.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -1
- package/dist/src/daemon.js +1 -1
- package/dist/src/debug-symbols-facade.js +1 -1
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-claim-rule.js +1 -2
- package/dist/src/device-inventory-context.js +1 -1
- package/dist/src/{stop-sequence.js → device-readiness-runtime.js} +1 -1
- package/dist/src/device-rotation.js +1 -1
- package/dist/src/device-selection-resolver.js +1 -1
- package/dist/src/device-session.js +1 -1
- package/dist/src/device-shell.js +1 -1
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +1 -1
- package/dist/src/devicectl.js +1 -1
- package/dist/src/diagnostics.js +1 -1
- package/dist/src/dispatch-resolve.js +1 -1
- package/dist/src/doctor-facade.js +1 -1
- package/dist/src/doctor2.js +1 -1
- package/dist/src/durable-resource.js +1 -1
- package/dist/src/engine-eval-script.js +1 -1
- package/dist/src/error.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/format.js +1 -2
- package/dist/src/gesture-admission.js +1 -1
- package/dist/src/gesture-plan.js +1 -1
- package/dist/src/gesture-runtime.js +1 -1
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/helper.js +2 -2
- package/dist/src/host.js +1 -1
- package/dist/src/human-control-contract.js +1 -1
- package/dist/src/human-control.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/input-actions.js +1 -1
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact-facade.js +1 -1
- package/dist/src/install-source-network-transport.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-positionals.js +1 -1
- package/dist/src/interaction-ref-policy.js +1 -1
- package/dist/src/interaction2.js +1 -1
- package/dist/src/interactor-operation-binding.js +1 -1
- package/dist/src/interactor.js +5 -4
- package/dist/src/interactor2.js +1 -1
- package/dist/src/interactors.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +2 -2
- package/dist/src/internal/png-worker.js +1 -1
- package/dist/src/internal/run-script-http-child.js +1 -1
- package/dist/src/inventory.js +1 -1
- package/dist/src/inventory2.js +1 -1
- package/dist/src/inventory3.js +1 -1
- package/dist/src/inventory5.js +1 -1
- package/dist/src/ios-snapshot-engine.js +1 -1
- package/dist/src/ios-snapshot-runtime.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease-scope.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/legacy-xctest-device-set.js +1 -0
- package/dist/src/limrun-download-file.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/limrun.d.ts +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/location-coordinates.js +1 -1
- package/dist/src/managed-device-scope.js +1 -1
- package/dist/src/mechanics.js +16 -16
- package/dist/src/multitouch-support.js +1 -1
- package/dist/src/observation.js +1 -1
- package/dist/src/overlay.js +3 -3
- package/dist/src/owner-identity.js +3 -3
- package/dist/src/parameterized-recorded-fill.js +1 -1
- package/dist/src/perf-facade.js +1 -1
- package/dist/src/perf-runtime-operation-builder.js +1 -1
- package/dist/src/perf-runtime-plan.js +1 -1
- package/dist/src/perf-target.js +1 -1
- package/dist/src/perf.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-managed-owner.js +1 -1
- package/dist/src/platform-runtime-open-target.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +2 -2
- package/dist/src/platform-runtime-runtime-hints.js +1 -1
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.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/png-crop-bytes.js +1 -1
- package/dist/src/png-size.js +1 -1
- package/dist/src/png-worker-client.js +1 -1
- package/dist/src/png.js +1 -1
- package/dist/src/prepare-kind.js +1 -1
- package/dist/src/process.js +1 -1
- package/dist/src/provider-session-ownership.js +1 -1
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +2 -2
- package/dist/src/quality-warnings.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -1
- package/dist/src/recording.js +1 -1
- package/dist/src/rect-center.js +1 -1
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +36 -36
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay-divergence.js +1 -1
- package/dist/src/replay.js +1 -1
- package/dist/src/reporting.js +1 -1
- package/dist/src/request-admission.js +1 -1
- package/dist/src/request-cancel.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/runner-artifact-manifest.js +1 -0
- package/dist/src/runner-cache-metadata.js +3 -2
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-command-traits.js +1 -0
- package/dist/src/runner-dev-tools-security.js +1 -1
- package/dist/src/runner-device-readiness.js +1 -1
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-error-classification.js +3 -3
- package/dist/src/runner-exchange.js +1 -0
- package/dist/src/runner-operations-facade.js +1 -1
- package/dist/src/runner-owner-facade.js +1 -1
- package/dist/src/runner-session-types.js +1 -0
- package/dist/src/runner-start-budget.js +1 -0
- package/dist/src/runner-startup-transport.js +1 -0
- package/dist/src/runner-xctestrun.js +1 -0
- package/dist/src/runner.js +1 -1
- package/dist/src/runtime-transport-hints.js +1 -1
- package/dist/src/runtime.js +1 -1
- package/dist/src/runtime10.js +2 -2
- package/dist/src/runtime2.js +3 -3
- package/dist/src/runtime3.js +1 -1
- package/dist/src/runtime4.js +5 -5
- package/dist/src/runtime5.js +1 -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-admission-ledger.js +1 -1
- package/dist/src/screen-recording-completion.js +1 -1
- package/dist/src/screen-recording-options.js +1 -1
- package/dist/src/screen-recording-resource-recovery.js +1 -1
- package/dist/src/screen-recording-transport.js +1 -1
- package/dist/src/screenshot-density.js +1 -1
- package/dist/src/screenshot-image.js +1 -1
- package/dist/src/screenshot-runtime.js +1 -1
- package/dist/src/screenshot.js +1 -1
- package/dist/src/screenshot3.js +1 -1
- package/dist/src/script.js +1 -1
- package/dist/src/scroll-command.d.ts +4 -1
- package/dist/src/scroll-command.js +1 -1
- package/dist/src/scroll-gesture.js +1 -1
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-batch.js +2 -2
- package/dist/src/sdk-contracts.d.ts +10 -0
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-io.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/selection.js +0 -0
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/server.js +1 -1
- package/dist/src/session-allocation.js +1 -1
- package/dist/src/session-routing.js +1 -1
- package/dist/src/session-runtime-admission.js +1 -1
- package/dist/src/session-snapshot.js +1 -1
- package/dist/src/session-store.js +3 -3
- package/dist/src/session2.js +5 -4
- package/dist/src/settings.js +1 -1
- package/dist/src/settings2.js +1 -1
- package/dist/src/simctl.js +1 -1
- package/dist/src/simulator-boot.js +1 -1
- package/dist/src/simulator.js +1 -1
- 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/snapshot2.js +1 -1
- package/dist/src/snapshot3.js +1 -1
- package/dist/src/snapshot4.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src7.js +1 -1
- package/dist/src/src8.js +2 -2
- package/dist/src/string-enum.js +1 -1
- package/dist/src/takeover.js +1 -1
- package/dist/src/target-evidence.js +1 -0
- package/dist/src/text-entry-focus.js +1 -1
- package/dist/src/tool-provider.js +1 -1
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/touch-runtime.js +1 -1
- package/dist/src/transport.js +2 -2
- package/dist/src/tv-remote.js +1 -1
- package/dist/src/type-text-runtime.js +1 -1
- package/dist/src/vars.js +2 -0
- package/dist/src/verified-file.js +1 -1
- package/dist/src/video.js +1 -1
- package/dist/src/viewport.js +1 -1
- package/dist/src/web.js +1 -1
- package/dist/src/web2.js +1 -1
- package/dist/src/webdriver-source.js +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.15.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.15.apk.sha256 +0 -1
- package/dist/src/capture-disclosure.js +0 -1
- package/dist/src/fold-runtime.js +0 -1
- package/dist/src/native-build-cache.js +0 -1
package/dist/src/mechanics.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime.js";import{
|
|
2
|
-
`).map(e=>e.trim()).filter(Boolean)}const qt=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Jt(e){return qt.has(e)}const Yt=new Set([`android`,`com.android.systemui`]),Xt=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,Zt=/^android:id\/button[123]$/i,Qt=/(?:^|:)id\/permission_/i,$t=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,en=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,tn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function nn(e){if(e!==null){if(Zt.test(e))return`button`;if(Xt.test(e))return`content`}}function rn(e){let t=sn(e.filter(an)),n=t.nodes;if(n.length===0)return null;let r=fn(n),i=n.filter(e=>O(e)&&!Sn(e)),a=hn(i),o=gn(i,a);if(!a&&!o&&r.length===0)return null;let s=Cn(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 an(e){return!f(e)}function on(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 sn(e){let t=e.filter(e=>bn(e));if(t.length)return{nodes:t,source:`permission`};let n=dn(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:cn(e),source:`native-dialog`}}function cn(e){let t=e.filter(e=>ln(e.type??``)),n=e.filter(e=>Xt.test(e.identifier??``)),r=t.length?[...t,...n]:un(n);if(r.length===0)return[];let i=_n(e,r);return i===void 0?r:yn(e,i)}function ln(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function un(e){let t=e.some(e=>Zt.test(e.identifier??``)),n=e.some(e=>!Zt.test(e.identifier??``));return t&&n?e:[]}function dn(e){let t=e.filter(e=>xn(e));if(t.length===0)return[];let n=_n(e,t);return n===void 0?t:yn(e,n).filter(e=>e.bundleId&&Yt.has(e.bundleId))}function fn(e){let t=new Set,n=[];for(let r of e){let e=O(r);if(!e||!r.rect||!Sn(r))continue;let
|
|
3
|
-
`):void 0}function _n(e,t){let n=t[0];if(!n)return;let r=vn(e,n.index);for(let n of t.slice(1)){let t=new Set(vn(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 vn(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 yn(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 bn(e){let t=e.bundleId??``;return qt.has(t)||Qt.test(e.identifier??``)}function xn(e){let t=e.bundleId??``;return Yt.has(t)&&$t.test(O(e))}function Sn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Zt.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 Cn(e){return e.find(e=>e.bundleId)?.bundleId}function wn(e,n,r){if(typeof e!=`number`||!Number.isInteger(e))throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return e}function k(e,n,r,i){if(e!==r)throw new t(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}function Tn(e,n,r){if(typeof e!=`string`||e.length===0)throw new t(`INVALID_ARGS`,`Android ${r} manifest ${n} is required.`);return e}function En(e,n){let r=Tn(e,`sha256`,n).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new t(`INVALID_ARGS`,`Android ${n} manifest sha256 must be a 64-character hex string.`);return r}function Dn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))On(n,t);return kn(t),{status:t.status,results:t.results}}function On(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},Mn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){An(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},Mn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&jn(t)}function kn(e){An(e),jn(e)}function An(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function jn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function Mn(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 Nn(e){if(e===`true`)return!0;if(e===`false`)return!1}function Pn(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 t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const Fn=1e4;async function In(e,t){try{return await We(e,t)}catch(e){throw et(e)}}async function Ln(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 Wn(a,o,u);let f=await Rn({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 In(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 Rn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await Vn(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 Hn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function zn(e){let r=S().files,i=je(),a=D.join(Me(),`android`,e.helperDirName,`dist`),o=D.join(a,e.manifestFileName(i));try{let t=e.parseManifest(JSON.parse(await r.readText(o))),n=D.join(a,t.assetName);return await r.access(n),{apkPath:n,manifest:t}}catch(r){throw new t(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:n(r).message},r)}}function Bn(e){return async t=>await Ln({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 Vn(e,t,n){let r=await x(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${Kn(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Hn(e,n,r,i){let a=await x(e,[`pm`,`path`,r],{allowFailure:!0,timeoutMs:Fn,signal:i}),o=Un(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new t(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=S().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=D.join(c,`base.apk`);try{let e=await Be(o,l,{provider:n,allowFailure:!0,timeoutMs:Fn,signal:i});if(e.exitCode!==0)throw T(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await Gn(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Un(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function Wn(e,n,r){let i=await Gn(e);if(i!==n)throw new t(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:n,actualSha256:i})}async function Gn(e){let t=S().files;return t.sha256(await t.readBytes(e))}function Kn(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const qn=`android-snapshot-helper-v1`,Jn=`uiautomator-xml`,Yn=5e3,Xn=3e4;function Zn(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=e;return{name:$n(n.name,`name`,`android-snapshot-helper`),version:j(n.version,`version`),releaseTag:tr(n.releaseTag),assetName:tr(n.assetName),apkUrl:nr(n.apkUrl,`apkUrl`),sha256:er(n.sha256),checksumName:tr(n.checksumName),packageName:j(n.packageName,`packageName`),versionCode:Qn(n.versionCode,`versionCode`),instrumentationRunner:j(n.instrumentationRunner,`instrumentationRunner`),minSdk:Qn(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:Qn(n.targetSdk,`targetSdk`),outputFormat:$n(n.outputFormat,`outputFormat`,Jn),statusProtocol:$n(n.statusProtocol,`statusProtocol`,qn)}}function Qn(e,t){return wn(e,t,`snapshot helper`)}function $n(e,t,n){return k(e,t,n,`snapshot helper`)}function er(e){let n=j(e,`sha256`).trim().toLowerCase();if(n.length!==64||!rr(n))throw new t(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}function j(e,n){if(typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return e}function tr(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function nr(e,t){return e===null?null:j(e,t)}function rr(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 ir(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of M.keys())e.startsWith(t)&&ur(e)}const ar=`android-snapshot-helper-not-current`;function or(e){return o(e).details?.reason===ar}function sr(){M.clear()}function cr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function lr(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 ur(e){e&&M.delete(e)}async function dr(e){let{adb:n,artifact:r}=e,i=e.installPolicy??`missing-or-outdated`,a=r.manifest.packageName,o=r.manifest.versionCode,s=r.manifest.sha256;if(i===`never`)return{packageName:a,versionCode:o,installed:!1,reason:`skipped`};let c=cr(e.deviceKey,a,o,s),l=c?M.get(c):void 0;if(c&&i!==`always`&&l!==void 0)return{packageName:a,versionCode:o,installedVersionCode:l,installedSha256:s,installed:!1,reason:`current`};await Wn(r.apkPath,s,`Android snapshot helper`);let u=i===`always`?{installedVersionCode:await mr(n,a,e.timeoutMs,e.signal),reason:`forced`}:await Rn({adb:n,adbProvider:pr(e.adbProvider,n),packageName:a,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 lr(c,d),{packageName:a,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}if(i===`current-only`)throw new t(`COMMAND_FAILED`,`Android snapshot helper is not installed at the current version`,{reason:ar,packageName:a,versionCode:o,installedVersionCode:d});let m;try{m=await hr(n,e.adbProvider??n,r.apkPath,{packageName:a,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw ur(c),fr(e,{packageName:a,versionCode:o})}if(m.exitCode!==0)throw ur(c),fr(T(`Failed to install Android snapshot helper`,m,{packageName:a,versionCode:o}));return lr(c,o),{packageName:a,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function fr(e,t){let n=o(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function pr(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function mr(e,t,n,r){let i=await x(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return gr(`${i.stdout}\n${i.stderr}`,t)}async function hr(e,t,n,r){let i=async()=>await In(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!_r(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 gr(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 _r(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function vr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function yr(e){return e===137?`accessibility-timeout`:void 0}function br(e){return e?{androidCaptureFailureReason:e}:{}}function xr(){return new Promise((e,t)=>{let n=Vt.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 Sr(e,
|
|
1
|
+
import{r as e}from"./rolldown-runtime.js";import{J as t,N as n,P as r,U as i,X as a,_ as o,y as s}from"./sdk-contracts.js";import"./capture.js";import{O as c}from"./sdk-batch-runner.js";import{a as l,d as u,i as d,l as f,o as p,r as m,t as ee,u as te}from"./android-input-ownership.js";import{Gr as ne,Hr as re,Jr as ie,Kr as ae,Ur as oe,Vr as se,Xr 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{C 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}from"./device-rotation.js";import{c as h,r as g}from"./diagnostics.js";import{a as we,c as Te,h as Ee,n as De,s as Oe}from"./exec.js";import{t as _}from"./timeouts.js";import{i as ke}from"./tv-remote.js";import"./diagnostics2.js";import"./command.js";import{a as v,n as Ae,o as y}from"./device-shell.js";import"./retry.js";import{a as je,r as Me}from"./version.js";import{n as Ne,r as Pe}from"./install-source2.js";import{_ as Fe,a as b,c as Ie,d as x,f as Le,g as S,h as C,i as Re,l as ze,n as Be,o as w,p as Ve,r as He,s as Ue,t as We,u as Ge,v as Ke}from"./adb-executor.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{i as $e,n as T,o as et,s as tt}from"./adb-failure.js";import{a as nt,i as rt,n as it,o as E}from"./adb.js";import{i as at,n as ot,r as st}from"./gesture-plan.js";import{n as ct}from"./android-snapshot-quality.js";import{a as lt,c as ut,i as dt,l as ft,n as pt,o as mt,r as ht,s as gt,u as _t}from"./app-lifecycle.js";import{a as vt,i as yt,n as bt,o as xt,r as St,t as Ct}from"./app-deployment-resolution.js";import{a as wt,i as Tt,n as Et,o as Dt,t as Ot}from"./app-parsers.js";import{i as kt,n as At,r as jt,t as Mt}from"./window-state.js";import{n as Nt}from"./toolchain-probe.js";import{t as Pt}from"./keyed-lock.js";import{n as Ft,r as It}from"./android-system-chrome.js";import{t as Lt}from"./bounds.js";import{t as Rt}from"./entities.js";import{n as zt}from"./startup-recovery-fence.js";import{n as Bt}from"./numeric.js";import D from"node:path";import Vt from"node:net";import{TextDecoder as Ht}from"node:util";const Ut=new Map;async function Wt(e){let t=Ut.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=Kt(n).includes(`shell_v2`);return Ut.set(e.deviceKey,r),r}function Gt(){Ut.clear()}function Kt(e){return e.split(`
|
|
2
|
+
`).map(e=>e.trim()).filter(Boolean)}const qt=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]);function Jt(e){return qt.has(e)}const Yt=new Set([`android`,`com.android.systemui`]),Xt=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,Zt=/^android:id\/button[123]$/i,Qt=/(?:^|:)id\/permission_/i,$t=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,en=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,tn=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function nn(e){if(e!==null){if(Zt.test(e))return`button`;if(Xt.test(e))return`content`}}function rn(e){let t=sn(e.filter(an)),n=t.nodes;if(n.length===0)return null;let r=fn(n),i=n.filter(e=>O(e)&&!Sn(e)),a=hn(i),o=gn(i,a);if(!a&&!o&&r.length===0)return null;let s=Cn(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 an(e){return!f(e)}function on(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 sn(e){let t=e.filter(e=>bn(e));if(t.length)return{nodes:t,source:`permission`};let n=dn(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:cn(e),source:`native-dialog`}}function cn(e){let t=e.filter(e=>ln(e.type??``)),n=e.filter(e=>Xt.test(e.identifier??``)),r=t.length?[...t,...n]:un(n);if(r.length===0)return[];let i=_n(e,r);return i===void 0?r:yn(e,i)}function ln(e){let t=Math.max(e.lastIndexOf(`.`),e.lastIndexOf(`$`));return e.slice(t+1).toLowerCase().endsWith(`dialog`)}function un(e){let t=e.some(e=>Zt.test(e.identifier??``)),n=e.some(e=>!Zt.test(e.identifier??``));return t&&n?e:[]}function dn(e){let t=e.filter(e=>xn(e));if(t.length===0)return[];let n=_n(e,t);return n===void 0?t:yn(e,n).filter(e=>e.bundleId&&Yt.has(e.bundleId))}function fn(e){let t=new Set,n=[];for(let r of e){let e=O(r);if(!e||!r.rect||!Sn(r))continue;let i=e.trim().toLowerCase();if(!i||t.has(i))continue;t.add(i);let a=s(r.rect);n.push({label:e,x:a.x,y:a.y,role:pn(r,e)})}return n}function pn(e,t){return mn(e.identifier??``)||(en.test(t.trim())?`accept`:tn.test(t.trim())?`dismiss`:`neutral`)}function mn(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 hn(e){return O(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||O(e[0])}function gn(e,t){let n=e.map(e=>O(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
|
|
3
|
+
`):void 0}function _n(e,t){let n=t[0];if(!n)return;let r=vn(e,n.index);for(let n of t.slice(1)){let t=new Set(vn(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 vn(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 yn(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 bn(e){let t=e.bundleId??``;return qt.has(t)||Qt.test(e.identifier??``)}function xn(e){let t=e.bundleId??``;return Yt.has(t)&&$t.test(O(e))}function Sn(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||Zt.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 Cn(e){return e.find(e=>e.bundleId)?.bundleId}function wn(e,t,r){if(typeof e!=`number`||!Number.isInteger(e))throw new n(`INVALID_ARGS`,`Android ${r} manifest ${t} must be an integer.`);return e}function k(e,t,r,i){if(e!==r)throw new n(`INVALID_ARGS`,`Android ${i} manifest ${t} must be "${r}".`);return r}function Tn(e,t,r){if(typeof e!=`string`||e.length===0)throw new n(`INVALID_ARGS`,`Android ${r} manifest ${t} is required.`);return e}function En(e,t){let r=Tn(e,`sha256`,t).trim().toLowerCase();if(r.length!==64||!/^[0-9a-f]+$/.test(r))throw new n(`INVALID_ARGS`,`Android ${t} manifest sha256 must be a 64-character hex string.`);return r}function Dn(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))On(n,t);return kn(t),{status:t.status,results:t.results}}function On(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},Mn(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){An(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},Mn(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&jn(t)}function kn(e){An(e),jn(e)}function An(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function jn(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function Mn(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 Nn(e){if(e===`true`)return!0;if(e===`false`)return!1}function Pn(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 n(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const Fn=1e4;async function In(e,t){try{return await We(e,t)}catch(e){throw et(e)}}async function Ln(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 Wn(a,o,u);let f=await Rn({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 In(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 Rn(e){let{adb:t,adbProvider:n,packageName:r,versionCode:i,sha256:a,signal:o}=e,s=await Vn(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 Hn(t,n,r,o);return{installedVersionCode:s,installedSha256:e,reason:e===a?`current`:`mismatched`}}catch{return o?.throwIfAborted(),{installedVersionCode:s,reason:`unverifiable`}}}async function zn(e){let t=S().files,r=je(),a=D.join(Me(),`android`,e.helperDirName,`dist`),o=D.join(a,e.manifestFileName(r));try{let n=e.parseManifest(JSON.parse(await t.readText(o))),r=D.join(a,n.assetName);return await t.access(r),{apkPath:r,manifest:n}}catch(t){throw new n(`UNSUPPORTED_OPERATION`,e.unavailableMessage,{manifestPath:o,error:i(t).message},t)}}function Bn(e){return async t=>await Ln({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 Vn(e,t,n){let r=await x(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:5e3,signal:n});if(r.exitCode!==0)return;let i=RegExp(`package:${Kn(t)}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}\n${r.stderr}`);return i?Number(i[1]):void 0}async function Hn(e,t,r,i){let a=await x(e,[`pm`,`path`,r],{allowFailure:!0,timeoutMs:Fn,signal:i}),o=Un(`${a.stdout}\n${a.stderr}`);if(a.exitCode!==0||!o)throw new n(`COMMAND_FAILED`,`Could not resolve installed Android helper APK`);let s=S().files,c=await s.makeTempDirectory(`agent-device-helper-`),l=D.join(c,`base.apk`);try{let e=await Be(o,l,{provider:t,allowFailure:!0,timeoutMs:Fn,signal:i});if(e.exitCode!==0)throw T(`Could not read installed Android helper APK`,e,{packageName:r,remotePath:o});return await Gn(l)}finally{await s.remove(c,{recursive:!0,force:!0})}}function Un(e){return e.split(/\r?\n/).map(e=>e.startsWith(`package:`)?e.slice(8).trim():``).find(e=>e.endsWith(`/base.apk`))}async function Wn(e,t,r){let i=await Gn(e);if(i!==t)throw new n(`COMMAND_FAILED`,`${r} APK checksum mismatch`,{apkPath:e,expectedSha256:t,actualSha256:i})}async function Gn(e){let t=S().files;return t.sha256(await t.readBytes(e))}function Kn(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}const qn=`android-snapshot-helper-v1`,Jn=`uiautomator-xml`,Yn=5e3,Xn=3e4;function Zn(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new n(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let t=e;return{name:$n(t.name,`name`,`android-snapshot-helper`),version:j(t.version,`version`),releaseTag:tr(t.releaseTag),assetName:tr(t.assetName),apkUrl:nr(t.apkUrl,`apkUrl`),sha256:er(t.sha256),checksumName:tr(t.checksumName),packageName:j(t.packageName,`packageName`),versionCode:Qn(t.versionCode,`versionCode`),instrumentationRunner:j(t.instrumentationRunner,`instrumentationRunner`),minSdk:Qn(t.minSdk,`minSdk`),targetSdk:t.targetSdk===void 0?void 0:Qn(t.targetSdk,`targetSdk`),outputFormat:$n(t.outputFormat,`outputFormat`,Jn),statusProtocol:$n(t.statusProtocol,`statusProtocol`,qn)}}function Qn(e,t){return wn(e,t,`snapshot helper`)}function $n(e,t,n){return k(e,t,n,`snapshot helper`)}function er(e){let t=j(e,`sha256`).trim().toLowerCase();if(t.length!==64||!rr(t))throw new n(`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 n(`INVALID_ARGS`,`Android snapshot helper manifest ${t} is required.`);return e}function tr(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function nr(e,t){return e===null?null:j(e,t)}function rr(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 ir(e){let t=`${e.deviceKey}\0${e.packageName}\0${e.versionCode}\0`;for(let e of M.keys())e.startsWith(t)&&ur(e)}const ar=`android-snapshot-helper-not-current`;function or(e){return r(e).details?.reason===ar}function sr(){M.clear()}function cr(e,t,n,r){return e?`${e}\0${t}\0${n}\0${r}`:void 0}function lr(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 ur(e){e&&M.delete(e)}async function dr(e){let{adb:t,artifact:r}=e,i=e.installPolicy??`missing-or-outdated`,a=r.manifest.packageName,o=r.manifest.versionCode,s=r.manifest.sha256;if(i===`never`)return{packageName:a,versionCode:o,installed:!1,reason:`skipped`};let c=cr(e.deviceKey,a,o,s),l=c?M.get(c):void 0;if(c&&i!==`always`&&l!==void 0)return{packageName:a,versionCode:o,installedVersionCode:l,installedSha256:s,installed:!1,reason:`current`};await Wn(r.apkPath,s,`Android snapshot helper`);let u=i===`always`?{installedVersionCode:await mr(t,a,e.timeoutMs,e.signal),reason:`forced`}:await Rn({adb:t,adbProvider:pr(e.adbProvider,t),packageName:a,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 lr(c,d),{packageName:a,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!1,reason:p}}if(i===`current-only`)throw new n(`COMMAND_FAILED`,`Android snapshot helper is not installed at the current version`,{reason:ar,packageName:a,versionCode:o,installedVersionCode:d});let m;try{m=await hr(t,e.adbProvider??t,r.apkPath,{packageName:a,timeoutMs:e.timeoutMs,signal:e.signal})}catch(e){throw ur(c),fr(e,{packageName:a,versionCode:o})}if(m.exitCode!==0)throw ur(c),fr(T(`Failed to install Android snapshot helper`,m,{packageName:a,versionCode:o}));return lr(c,o),{packageName:a,versionCode:o,installedVersionCode:d,installedSha256:f,installed:!0,reason:p}}function fr(e,t){let n=r(e,`COMMAND_FAILED`);return n.details={...t,...n.details,androidSnapshotHelperInstallFailure:!0},n}function pr(e,t){return e?typeof e==`function`?{exec:e}:e:{exec:t}}async function mr(e,t,n,r){let i=await x(e,[`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n,signal:r});if(i.exitCode===0)return gr(`${i.stdout}\n${i.stderr}`,t)}async function hr(e,t,n,r){let i=async()=>await In(n,{allowFailure:!0,provider:t,replace:!0,timeoutMs:r.timeoutMs,signal:r.signal}),a=await i();if(a.exitCode===0||!_r(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 gr(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 _r(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function vr(e){return e.errorType===`java.util.concurrent.TimeoutException`?`accessibility-timeout`:void 0}function yr(e){return e===137?`accessibility-timeout`:void 0}function br(e){return e?{androidCaptureFailureReason:e}:{}}function xr(){return new Promise((e,t)=>{let n=Vt.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 Sr(e,t,r,i){return new Promise((a,o)=>{let s=Vt.connect({host:`127.0.0.1`,port:e}),c=[],l=setTimeout(()=>{u(),s.destroy(),o(new n(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:t,timeoutMs:r,port:e}))},r),u=()=>{clearTimeout(l),i?.removeEventListener(`abort`,d)},d=()=>{u(),s.destroy(),o(i?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(i?.addEventListener(`abort`,d,{once:!0}),i?.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(),a(Buffer.concat(c).toString(`utf8`))})})}async function Cr(e){let t=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`;return kr(await Sr(e.port,`snapshot ${t}`,wr(e),e.signal),t)}function wr(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+3e3,3e3))}function Tr(e,t,r){return new Promise((i,a)=>{let o=``,s=setTimeout(()=>{r?.removeEventListener(`abort`,l),a(new n(`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),r?.removeEventListener(`abort`,l),i())},l=()=>{clearTimeout(s),a(r?.reason??new DOMException(`The operation was aborted`,`AbortError`))};if(r?.addEventListener(`abort`,l,{once:!0}),r?.aborted){l();return}e.stdout?.on(`data`,c),e.stderr?.on(`data`,c),e.once(`exit`,(e,t)=>{clearTimeout(s),r?.removeEventListener(`abort`,l),a(new n(`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),r?.removeEventListener(`abort`,l),a(e)})})}function Er(e){let t=e.indexOf(`
|
|
5
5
|
|
|
6
|
-
`);return Mr(e.slice(0,t<0?e.length:t))}function Dr(e,
|
|
6
|
+
`);return Mr(e.slice(0,t<0?e.length:t))}function Dr(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new n(`COMMAND_FAILED`,`Android automation helper session returned wrong protocol`,{headers:e});if(e.requestId!==t)throw new n(`COMMAND_FAILED`,`Android automation helper session returned stale output`,{headers:e,requestId:t})}function Or(e,t){let n=Er(e);return n.agentDeviceProtocol===`android-snapshot-helper-v1`&&n.requestId===t&&n.ok===`true`}function kr(e,t){let r=e.indexOf(`
|
|
7
7
|
|
|
8
|
-
`);if(r<0)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=Mr(e.slice(0,r)),a=e.slice(r+2);return Ar(i,n),jr(i,a),{xml:a,metadata:Nr(i)}}function Ar(e,n){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==n)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:n});if(e.ok!==`true`)throw new t(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...br(vr(e))})}function jr(e,n){let r=A(e.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new t(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:e,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:n})}function Mr(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 Nr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Jn,waitForIdleTimeoutMs:A(e.waitForIdleTimeoutMs),waitForIdleQuietMs:A(e.waitForIdleQuietMs),timeoutMs:A(e.timeoutMs),maxDepth:A(e.maxDepth),maxNodes:A(e.maxNodes),rootPresent:Nn(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:A(e.windowCount),nodeCount:A(e.nodeCount),truncated:Nn(e.truncated),elapsedMs:A(e.elapsedMs),pixelDensity:A(e.pixelDensity)}}function N(e,n,r,i){if(i instanceof t){let a=i.details??{};return new t(i.code,i.message,{...a,action:e,package:r,tool:n,hint:typeof a.hint==`string`?a.hint:Ir(n,a)},i)}return new t(`COMMAND_FAILED`,`Failed to ${e} Android ${n} for ${r}`,{action:e,package:r,tool:n,hint:Pr(n)},i)}function Pr(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 Fr(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 Ir(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Lr(n):zr(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Pr(e)}function Lr(e){return Rr(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.`:Pr(`simpleperf`)}function Rr(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function zr(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const Br=`adb-shell-simpleperf`,Vr=`adb-shell-perfetto`,Hr=15e3,P=3e4,Ur=`/data/local/tmp`;async function Wr(e,n){try{let t=await x(e,[`pidof`,n],{allowFailure:!0,timeoutMs:Hr}),r=Kr(t.stdout);if(t.exitCode===0&&r)return r}catch{}throw new t(`COMMAND_FAILED`,`No active Android app process found for ${n}`,{package:n,hint:`Run open <app> for this session again, wait for the app UI to appear, then retry perf.`})}async function Gr(e,n,r){let i=await x(e,[v(`command -v ${y(n)} || which ${y(n)}`)],{allowFailure:!0,timeoutMs:Hr});if(!(i.exitCode===0&&i.stdout.trim()))throw new t(`UNSUPPORTED_OPERATION`,`Android device does not expose ${n}`,{package:r,tool:n,hint:Fr(n)})}function Kr(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const qr=2e3,Jr=`android_snapshot_helper_runtime_occupied`,F=new Map;function Yr(e){return`${e.platform}:${e.id}`}async function Xr(e){await li({adb:e.adb,packageName:e.packageName}),await Qr({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function Zr(e){let t=F.get(e.deviceKey);if(!t)return;await li({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await ti({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await _(250),n=await ti({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw ei({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&F.delete(e.deviceKey)}async function Qr(e){let t=e.release??await ti({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 $r(e){return e instanceof t&&e.details?.reason===Jr}function ei(e){let n=e.cause instanceof Error?e.cause.message:String(e.cause);return new t(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:Jr,deviceKey:e.deviceKey,packageName:e.packageName,cause:n,hint:`Retry after the helper process exits, or restart the device if Android keeps reporting the helper as running.`})}async function ti(e){try{let t=await x(e.adb,[`pidof`,e.packageName,v(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:qr}),n=t.stdout.trim();return Kr(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function ni(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[li({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],ui({...e,signal:t})]),{timedOut:t.aborted}}function ri(e){let t=ii(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>ii(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function ii(e){return e.exitCode!=null||e.signalCode!=null}async function ai(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 oi(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await ai(e.processExit.ended,e.timeoutMs)}function si(e){F.delete(e)}function ci(){F.clear()}async function li(e){await x(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function ui(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 di(e){let n=pi(e),r=e.deviceKey??`android:default`;await Zr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(mi(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs,signal:e.signal})}catch(t){throw e.signal?.aborted?(await Xr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:t}),e.signal.throwIfAborted(),t):t}e.signal?.aborted&&(await Xr({deviceKey:r,packageName:n.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await hi(e,n,i);if(n.outputPath&&!o&&await Si(e.adb,n.outputPath),i.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android snapshot helper failed`,De(i,{helper:a.metadata}));return a}function fi(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:Yn,commandTimeoutMs:Xn,...e.signal?{signal:e.signal}:{}}}function pi(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 mi(e,t={}){return Ae(`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 hi(e,t,n){try{return{output:Ci(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await gi(e,t,n,r)}}async function gi(e,n,r,i){if(i instanceof t&&r.exitCode!==0&&i.details?.helper)throw i;let a=await _i(e,n,r);if(a)return{output:a,cleanupDone:!0};throw new t(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...br(yr(r.exitCode))},i)}async function _i(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await yi(e.adb,t.outputPath,xi(`${n.stdout}\n${n.stderr}`)??vi(t))}function vi(e){return{outputFormat:Jn,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function yi(e,t,n){let r;try{r=await x(e,bi(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 bi(e){return[`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function xi(e){try{return ji(Ti(Dn(e).results))}catch{return null}}async function Si(e,t){try{await x(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Ci(e){let t=Dn(e),n=Ti(t.results);return{xml:Di(wi(t.status),n),metadata:{...ji(n),transport:`instrumentation`}}}function wi(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 Ti(e){let n=e.find(e=>e.agentDeviceProtocol===qn);if(!n)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new t(`COMMAND_FAILED`,Ei(n),{errorType:n.errorType,helper:n,...br(vr(n))});return n}function Ei(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Di(e,n){if(e.length===0)throw new t(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=Oi(e),i=Buffer.concat(Ai(ki(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new t(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function Oi(e){let n=e[0]?.count??e.length;if(n<1||e.length!==n||e.some(e=>e.count!==n))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:e.length});return n}function ki(e,n){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=n)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new t(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function Ai(e,n){let r=[];for(let i=0;i<n;i+=1){let a=e.get(i);if(a===void 0)throw new t(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function ji(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Jn,waitForIdleTimeoutMs:L(e.waitForIdleTimeoutMs),waitForIdleQuietMs:L(e.waitForIdleQuietMs),timeoutMs:L(e.timeoutMs),maxDepth:L(e.maxDepth),maxNodes:L(e.maxNodes),rootPresent:Ni(e.rootPresent),captureMode:Mi(e.captureMode),windowCount:L(e.windowCount),nodeCount:L(e.nodeCount),truncated:Ni(e.truncated),elapsedMs:L(e.elapsedMs),pixelDensity:L(e.pixelDensity)}}function Mi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const L=A,Ni=Nn,Pi=5e3,R=new Map,z=new Map;async function Fi(e){return await Ii(e)!==void 0}async function Ii(e){let t=e.deviceKey??`android:default`;if(await Zr({deviceKey:t,adb:e.adb,signal:e.signal}),!Ji()||!e.adbProvider?.spawn)return;let n=pi(e),r=Ki(n),i=await Ri({deviceKey:t,identity:Gi(t,r,e),options:e,resolved:r,startBudgetMs:qi(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function Li(e){return R.get(e)}async function Ri(e){if(!Vi(e.identity))return await zi(e.deviceKey,e.identity),R.get(e.deviceKey)??await Bi(e)}async function zi(e,t){let n=R.get(e);!n||Ui(n,t)||await B(e,{force:ii(n.process)})}async function Bi(e){let n=Date.now();try{return await Wi(e)}catch(r){e.options.signal?.throwIfAborted(),z.set(e.identity,Date.now()+Hi(Date.now()-n)),g({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:r instanceof t?r.details?.reason:void 0,detail:r instanceof Error?r.message:String(r)}});return}}function Vi(e){let t=z.get(e);return t===void 0?!1:t>Date.now()||(z.delete(e),!1)}function Hi(e){return Math.min(Math.max(e,1e4),6e4)}function Ui(e,t){return e.identity===t&&!ii(e.process)}async function Wi(e){let t=await xr();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:Pi,signal:e.options.signal});let n=mi({...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 Tr(r,e.startBudgetMs,e.options.signal),R.set(e.deviceKey,i),z.delete(e.identity),si(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=ri(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([ai(n.ended,250),ni({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:qr,forceStopRuntime:!0})]),await Qr({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function Gi(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 Ki(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function qi(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function Ji(){let e=S().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=ri(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Yi(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await Wt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:qr:Pi,u=i?250:2e3,[d,f]=await Promise.all([oi({process:n.process,processExit:r,timeoutMs:u}),ni({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 Yi(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=Or(await Sr(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await ai(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function Xi(e){await B(Yr(e))}async function Zi(){try{await Promise.allSettled([...R.keys()].map(async e=>{await B(e)}))}finally{R.clear(),z.clear(),ci(),Gt()}}async function Qi(e){let t=await Ii(e);if(t)return await $i({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function $i(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await Cr({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 B(n,{force:!0,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:ct(e)===`accessibility-timeout`}});return}}async function ea(e){let n=Li(e.deviceKey);if(!n)return;if(!ta(n.helper,e.helper)){g({level:`warn`,phase:`android_snapshot_helper_session_touch_identity_mismatch`,data:{deviceKey:e.deviceKey,sessionHelper:n.helper,requestedHelper:e.helper}}),await B(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=Er(await Sr(n.port,i,e.timeoutMs)),Dr(a,r)}catch(t){throw await B(e.deviceKey),t}if(a.ok!==`true`)throw new t(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function ta(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&na(e.helperVersion,t.helperVersion)&&na(e.helperVersionCode,t.helperVersionCode)&&na(e.sha256,t.sha256)}function na(e,t){return e===void 0||t===void 0||e===t}const ra=`android-touch-plan-v1`,ia=45e3,aa=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,oa=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function sa(e,t){let n=await ua(e),r=fa(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:ra,...r})).toString(`base64`),o=await h(`android_touch_helper_gesture`,async()=>{let e=await ea({deviceKey:n.deviceKey,action:`gesture`,helper:la(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...ga(e),helperTransport:`persistent-session`}:{...await ma({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:ga}),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 ca(e,t={}){let n=await ua(e);t.helperSessionScope===`daemon-session`&&await Fi(fi({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await ea({deviceKey:n.deviceKey,action:`viewport`,helper:la(n.artifact),timeoutMs:ia});if(e)return _a(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 ma({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:ia,readResult:_a})}function la(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function ua(e){let t=w(e),n=t.snapshotHelperArtifact??await da(),r=Yr(e);await Zr({deviceKey:r,adb:t.exec});let i=await h(`android_touch_helper_install`,async()=>await dr({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 da(){return await zn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=Zn(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 fa(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(pa)}}function pa(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function ma(e){let n=await x(e.adb,[`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=ha(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===oa)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==aa)throw e}throw new t(`COMMAND_FAILED`,n.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,De(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,De(n,{helper:r}));return e.readResult(r)}function ha(e){let n=Dn(e).results.find(e=>e.agentDeviceProtocol===qn);if(!n)throw new t(aa,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(oa,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function ga(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:A(e.injectedEvents),elapsedMs:A(e.elapsedMs)}}function _a(e){let n=A(e.x),r=A(e.y),i=A(e.width),a=A(e.height);if(n===void 0||r===void 0||i===void 0||a===void 0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=va(e);return{viewport:Pn({x:n,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function va(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 ya(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...at(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:st(n.point,r.point,t===`controlled`?ba(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function ba(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function xa(e,t){let n=ya(t),r=Ie(e);if(r){let e=n.intent===`longPress`?{...n,viewport:Pn(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await sa(e,n)}async function Sa(e,t={}){return(await Ca(e,t)).viewport}async function Ca(e,t={}){let n=Ie(e);return n?{viewport:Pn(await n.gestureViewport())}:await ca(e,t)}async function wa(e,t,n){await E(e,[`input`,`tap`,t,n])}async function Ta(e,t,n){let r=ke(t);await E(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Ea(e){await E(e,[`input`,`keyevent`,`4`])}async function Da(e){await E(e,[`input`,`keyevent`,`3`])}async function Oa(e){await E(e,[`input`,`keyevent`,`ENTER`])}async function ka(e,t){let n=za(t);await E(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await E(e,[`settings`,`put`,`system`,`user_rotation`,n]),await ja(e,t,n)}const Aa=15e3;async function ja(e,n,r){let i=Date.now()+Aa,a=await Ma(e,n,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await _(Math.min(500,Na(i))),a=await Ma(e,n,i);if(a!==void 0&&a!==r)throw new t(`COMMAND_FAILED`,`orientation ${n} did not take effect: the display still reports rotation ${a} after ${Aa}ms`,{requestedRotation:Number(r),observedRotation:Number(a),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 Ma(e,n,r){try{let t=await E(e,[`dumpsys`,`display`],{timeoutMs:Na(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new t(`COMMAND_FAILED`,`orientation ${n} 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 Na(e){return Math.max(1,e-Date.now())}async function Pa(e){await E(e,[`input`,`keyevent`,`187`])}async function Fa(e,t,n,r=800){let i={x:t,y:n};return await xa(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function Ia(e,t,n){await wa(e,t,n)}async function La(e,t,n){let{viewport:r,keyboard:i}=await Ca(e,{helperSessionScope:n?.helperSessionScope}),a=Ra(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 xa(e,{...ot({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 Ra(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 za(e){let n=Ce[e];if(n===void 0)throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(n)}async function Ba(e){let n=(await E(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}async function Va(e,t,n){return t===`wait`?await Ha(n.captureNodes,n.timeoutMs??1e4):t===`get`?Ja((await qa(n.captureNodes))?.alert??null):await Ua(e,t,n.captureNodes)}async function Ha(e,n){let r=Date.now(),i=await Ka(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...fe(`Alert visible`)}}async function Ua(e,n,r){let i=await Ka(r,pe);if(!i)throw new t(`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 a=on(i.buttons,n);if(a)return await wa(e,a.x,a.y),await Wa(i.alert,n,r),Ya(n,i.alert,a.label,{x:a.x,y:a.y});if(n===`dismiss`)return await Ea(e),await Wa(i.alert,n,r),Ya(n,i.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:i.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function Wa(e,n,r){let i=Date.now();for(;;){let a=await qa(r);if(!a||!Ga(a.alert,e))return;if(Date.now()-i>=2e3)throw new t(`COMMAND_FAILED`,`alert ${n} 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 Ga(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function Ka(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await qa(e);if(t)return t;await _(300)}return null}async function qa(e){return rn(await h(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function Ja(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function Ya(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 Xa=`android.intent.category.LAUNCHER`,Za=`android.intent.category.DEFAULT`;async function Qa(e,t){await x(e,[`am`,`force-stop`,t])}async function $a(e,t,n=[Xa]){for(let r of n){let n=await x(e,[`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=mt(n.stdout);if(i)return i}return null}async function eo(e,n,r={}){let i=r.category??Xa;if(r.activity){await x(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Za,`-c`,i,`-n`,to(n,r.activity)]);return}let a=await x(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Za,`-c`,i,`-p`,n],{allowFailure:!0});if(a.exitCode===0&&!ht(a.stdout,a.stderr))return;let o=await $a(e,n,[i]);if(!o)throw new t(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${n}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await x(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Za,`-c`,i,`-n`,o])}function to(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let no=null;function ro(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function io(e){let n=ro(e);if(no?.key===n)return no.invocation;if(await Ee(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return no={key:n,invocation:e},e}let r=await Oe(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return no={key:n,invocation:i},i}async function ao(e,t,n){let r=await io(n);await Te(r.cmd,[...r.prefixArgs,...e],{signal:t})}function oo(e){return D.extname(e).toLowerCase()===`.aab`}async function so(e,t,n={}){let r=w(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=S().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=D.join(o,`bundle.apks`);try{await ao([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??S().environment),await ao([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??S().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function co(e,t,n={}){if(oo(t)){await so(e,t,n);return}await We(t,{device:e,replace:!0,signal:n.signal})}async function lo(e,t,n={}){await yt(e,async()=>{e.booted||await ut(e.id,void 0,n.signal),await co(e,t,n)})}const uo=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],fo=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),po=new Set([32,208]),mo=new Set([128,224,144]);async function ho(e){return await V(b(e))}async function V(e){let t=await x(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw T(`Failed to query Android keyboard state`,t);return vo(t.stdout)}async function go(e){return await _o(b(e))}async function _o(e){let n=await V(e),r=n,i=0;for(;r.visible&&i<2;)await x(e,[`input`,`keyevent`,`111`]),i+=1,await _(120),r=await V(e);if(n.visible&&r.visible)throw new t(`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:n.visible,dismissed:n.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 vo(e){let t=Co(e)??yo(e),n=bo(e),r=xo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=xo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=p(e),o=ee(r,i,a);return So(r,i,a),{visible:t??!1,inputType:n,type:n?Do(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function yo(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 bo(e){let t=xo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function xo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function So(e,t,n){n||!d(e)&&!l(t)||g({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Co(e){return To(wo(e,uo))}function wo(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 To(e){if(e.size===0)return null;let t=Eo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Eo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Eo(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function Do(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=fo.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return po.has(i)?`email`:mo.has(i)?`password`:`text`}async function Oo(e){return await ko(b(e))}async function ko(e){return No(await Mo(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function Ao(e,t){await jo(b(e),t)}async function jo(e,t){await Mo(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function Mo(e,t,n){let{androidClipboardShellCommandUnavailableError:r,classifyAndroidClipboardShellResponse:i}=await import(`./clipboard-shell-response.js`),a=await x(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 No(e){let t=e.replaceAll(`\r
|
|
8
|
+
`);if(r<0)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:e});let i=Mr(e.slice(0,r)),a=e.slice(r+2);return Ar(i,t),jr(i,a),{xml:a,metadata:Nr(i)}}function Ar(e,t){if(e.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:e});if(e.outputFormat!==`uiautomator-xml`)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:e});if(e.requestId!==t)throw new n(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:e,requestId:t});if(e.ok!==`true`)throw new n(`COMMAND_FAILED`,e.message||e.errorType||`Android snapshot helper session returned an error`,{helper:e,...br(vr(e))})}function jr(e,t){let r=A(e.byteLength);if(r!==void 0&&Buffer.byteLength(t,`utf8`)!==r)throw new n(`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 n(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:e,xml:t})}function Mr(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 Nr(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Jn,waitForIdleTimeoutMs:A(e.waitForIdleTimeoutMs),waitForIdleQuietMs:A(e.waitForIdleQuietMs),timeoutMs:A(e.timeoutMs),maxDepth:A(e.maxDepth),maxNodes:A(e.maxNodes),rootPresent:Nn(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:A(e.windowCount),nodeCount:A(e.nodeCount),truncated:Nn(e.truncated),elapsedMs:A(e.elapsedMs),pixelDensity:A(e.pixelDensity)}}function N(e,t,r,i){if(i instanceof n){let a=i.details??{};return new n(i.code,i.message,{...a,action:e,package:r,tool:t,hint:typeof a.hint==`string`?a.hint:Ir(t,a)},i)}return new n(`COMMAND_FAILED`,`Failed to ${e} Android ${t} for ${r}`,{action:e,package:r,tool:t,hint:Pr(t)},i)}function Pr(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 Fr(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 Ir(e,t){let n=(typeof t.stderr==`string`?t.stderr:``).toLowerCase();return e===`simpleperf`?Lr(n):zr(n)?`Use a device image that permits perfetto trace capture for shell, keep the app running, then retry perf trace start.`:Pr(e)}function Lr(e){return Rr(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.`:Pr(`simpleperf`)}function Rr(e){return e.includes(`permission denied`)||e.includes(`not profileable`)||e.includes(`profileable`)}function zr(e){return e.includes(`permission denied`)||e.includes(`not allowed`)}const Br=`adb-shell-simpleperf`,Vr=`adb-shell-perfetto`,Hr=15e3,P=3e4,Ur=`/data/local/tmp`;async function Wr(e,t){try{let n=await x(e,[`pidof`,t],{allowFailure:!0,timeoutMs:Hr}),r=Kr(n.stdout);if(n.exitCode===0&&r)return r}catch{}throw new n(`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 Gr(e,t,r){let i=await x(e,[v(`command -v ${y(t)} || which ${y(t)}`)],{allowFailure:!0,timeoutMs:Hr});if(!(i.exitCode===0&&i.stdout.trim()))throw new n(`UNSUPPORTED_OPERATION`,`Android device does not expose ${t}`,{package:r,tool:t,hint:Fr(t)})}function Kr(e){return e.trim().split(/\s+/).find(e=>/^\d+$/.test(e))}const qr=2e3,Jr=`android_snapshot_helper_runtime_occupied`,F=new Map;function Yr(e){return`${e.platform}:${e.id}`}async function Xr(e){await li({adb:e.adb,packageName:e.packageName}),await Qr({deviceKey:e.deviceKey,packageName:e.packageName,adb:e.adb,cause:e.cause})}async function Zr(e){let t=F.get(e.deviceKey);if(!t)return;await li({adb:e.adb,packageName:t.packageName,timeoutMs:5e3,...e.signal?{signal:e.signal}:{}}),e.signal?.throwIfAborted();let n=await ti({adb:e.adb,packageName:t.packageName});if(n===`occupied`&&(await _(250),n=await ti({adb:e.adb,packageName:t.packageName})),n===`occupied`)throw ei({deviceKey:e.deviceKey,packageName:t.packageName,cause:t.cause});n!==`unknown`&&F.delete(e.deviceKey)}async function Qr(e){let t=e.release??await ti({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 $r(e){return e instanceof n&&e.details?.reason===Jr}function ei(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);return new n(`COMMAND_FAILED`,`Android automation helper is still holding device automation ownership`,{reason:Jr,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 ti(e){try{let t=await x(e.adb,[`pidof`,e.packageName,v(`|| echo AGENT_DEVICE_NO_HELPER`)],{allowFailure:!0,timeoutMs:qr}),n=t.stdout.trim();return Kr(n)?`occupied`:n===`AGENT_DEVICE_NO_HELPER`&&t.stderr.trim().length===0?`released`:`unknown`}catch{return`unknown`}}async function ni(e){let t=AbortSignal.timeout(e.timeoutMs);return await Promise.all([...e.forceStopRuntime?[li({adb:e.adb,packageName:e.packageName,timeoutMs:e.timeoutMs,signal:t})]:[],ui({...e,signal:t})]),{timedOut:t.aborted}}function ri(e){let t=ii(e);return{ended:t?Promise.resolve():new Promise(t=>{e.once(`close`,()=>t()),e.once(`exit`,()=>t())}),hasEnded:()=>ii(e),completedCleanly:()=>!t&&e.exitCode===0&&e.signalCode==null}}function ii(e){return e.exitCode!=null||e.signalCode!=null}async function ai(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 oi(e){if(e.processExit.hasEnded())return!0;try{e.process.kill(`SIGTERM`)}catch{}return await ai(e.processExit.ended,e.timeoutMs)}function si(e){F.delete(e)}function ci(){F.clear()}async function li(e){await x(e.adb,[`am`,`force-stop`,e.packageName],{allowFailure:!0,timeoutMs:e.timeoutMs??2e3,...e.signal?{signal:e.signal}:{}}).catch(()=>{})}async function ui(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 di(e){let t=pi(e),r=e.deviceKey??`android:default`;await Zr({deviceKey:r,adb:e.adb,signal:e.signal});let i;try{i=await e.adb(mi(t),{allowFailure:!0,timeoutMs:t.commandTimeoutMs,signal:e.signal})}catch(n){throw e.signal?.aborted?(await Xr({deviceKey:r,packageName:t.packageName,adb:e.adb,cause:n}),e.signal.throwIfAborted(),n):n}e.signal?.aborted&&(await Xr({deviceKey:r,packageName:t.packageName,adb:e.adb,cause:e.signal.reason}),e.signal.throwIfAborted());let{output:a,cleanupDone:o}=await hi(e,t,i);if(t.outputPath&&!o&&await Si(e.adb,t.outputPath),i.exitCode!==0)throw new n(`COMMAND_FAILED`,`Android snapshot helper failed`,De(i,{helper:a.metadata}));return a}function fi(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:Yn,commandTimeoutMs:Xn,...e.signal?{signal:e.signal}:{}}}function pi(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 mi(e,t={}){return Ae(`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 hi(e,t,n){try{return{output:Ci(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await gi(e,t,n,r)}}async function gi(e,t,r,i){if(i instanceof n&&r.exitCode!==0&&i.details?.helper)throw i;let a=await _i(e,t,r);if(a)return{output:a,cleanupDone:!0};throw new n(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,...br(yr(r.exitCode))},i)}async function _i(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await yi(e.adb,t.outputPath,xi(`${n.stdout}\n${n.stderr}`)??vi(t))}function vi(e){return{outputFormat:Jn,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function yi(e,t,n){let r;try{r=await x(e,bi(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 bi(e){return[`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function xi(e){try{return ji(Ti(Dn(e).results))}catch{return null}}async function Si(e,t){try{await x(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function Ci(e){let t=Dn(e),n=Ti(t.results);return{xml:Di(wi(t.status),n),metadata:{...ji(n),transport:`instrumentation`}}}function wi(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 Ti(e){let t=e.find(e=>e.agentDeviceProtocol===qn);if(!t)throw new n(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(t.ok!==`true`)throw new n(`COMMAND_FAILED`,Ei(t),{errorType:t.errorType,helper:t,...br(vr(t))});return t}function Ei(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function Di(e,t){if(e.length===0)throw new n(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:t});let r=Oi(e),i=Buffer.concat(Ai(ki(e,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new n(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function Oi(e){let t=e[0]?.count??e.length;if(t<1||e.length!==t||e.some(e=>e.count!==t))throw new n(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:t,actualChunks:e.length});return t}function ki(e,t){let r=new Map;for(let i of e){if(i.index===void 0||i.index<0||i.index>=t)throw new n(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:t});if(r.has(i.index))throw new n(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function Ai(e,t){let r=[];for(let i=0;i<t;i+=1){let a=e.get(i);if(a===void 0)throw new n(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:t});r.push(Buffer.from(a,`base64`))}return r}function ji(e){return{helperApiVersion:e.helperApiVersion,outputFormat:Jn,waitForIdleTimeoutMs:L(e.waitForIdleTimeoutMs),waitForIdleQuietMs:L(e.waitForIdleQuietMs),timeoutMs:L(e.timeoutMs),maxDepth:L(e.maxDepth),maxNodes:L(e.maxNodes),rootPresent:Ni(e.rootPresent),captureMode:Mi(e.captureMode),windowCount:L(e.windowCount),nodeCount:L(e.nodeCount),truncated:Ni(e.truncated),elapsedMs:L(e.elapsedMs),pixelDensity:L(e.pixelDensity)}}function Mi(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const L=A,Ni=Nn,Pi=5e3,R=new Map,z=new Map;async function Fi(e){return await Ii(e)!==void 0}async function Ii(e){let t=e.deviceKey??`android:default`;if(await Zr({deviceKey:t,adb:e.adb,signal:e.signal}),!Ji()||!e.adbProvider?.spawn)return;let n=pi(e),r=Ki(n),i=await Ri({deviceKey:t,identity:Gi(t,r,e),options:e,resolved:r,startBudgetMs:qi(n.commandTimeoutMs)});return i?{session:i,resolved:r,deviceKey:t}:void 0}function Li(e){return R.get(e)}async function Ri(e){if(!Vi(e.identity))return await zi(e.deviceKey,e.identity),R.get(e.deviceKey)??await Bi(e)}async function zi(e,t){let n=R.get(e);!n||Ui(n,t)||await B(e,{force:ii(n.process)})}async function Bi(e){let t=Date.now();try{return await Wi(e)}catch(r){e.options.signal?.throwIfAborted(),z.set(e.identity,Date.now()+Hi(Date.now()-t)),g({level:`warn`,phase:`android_snapshot_helper_session_start_failed`,data:{deviceKey:e.deviceKey,reason:r instanceof n?r.details?.reason:void 0,detail:r instanceof Error?r.message:String(r)}});return}}function Vi(e){let t=z.get(e);return t===void 0?!1:t>Date.now()||(z.delete(e),!1)}function Hi(e){return Math.min(Math.max(e,1e4),6e4)}function Ui(e,t){return e.identity===t&&!ii(e.process)}async function Wi(e){let t=await xr();await e.options.adb([`forward`,`tcp:${t}`,`tcp:${t}`],{allowFailure:!1,timeoutMs:Pi,signal:e.options.signal});let n=mi({...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 Tr(r,e.startBudgetMs,e.options.signal),R.set(e.deviceKey,i),z.delete(e.identity),si(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=ri(r);try{r.kill(`SIGTERM`)}catch{}throw await Promise.all([ai(n.ended,250),ni({adb:i.adb,process:i.process,port:i.port,packageName:i.helper.packageName,timeoutMs:qr,forceStopRuntime:!0})]),await Qr({deviceKey:e.deviceKey,packageName:i.helper.packageName,adb:i.adb,cause:t}),t}}function Gi(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 Ki(e){let t=Math.min(e.timeoutMs,2e3);return{...e,timeoutMs:t,commandTimeoutMs:Math.min(e.commandTimeoutMs,t+3e3)}}function qi(e){return Math.min(e,Math.max(Math.floor(e/2),5e3))}function Ji(){let e=S().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=ri(n.process),i=t.force===!0||t.signal?.aborted===!0,a=await Yi(n,r,i,t.signal),o=r.hasEnded(),s=a.acknowledged&&a.exited,c=s&&await Wt({adb:n.adb,deviceKey:e,signal:t.signal}),l=i?t.signal?.aborted===!0?250:qr:Pi,u=i?250:2e3,[d,f]=await Promise.all([oi({process:n.process,processExit:r,timeoutMs:u}),ni({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 Yi(e,t,n,r){if(n)return{acknowledged:!1,exited:!1};let i=`quit-${Date.now()}`;try{let n=Or(await Sr(e.port,`quit ${i}`,1e3,r),i);return{acknowledged:n,exited:n&&await ai(t.ended,11e3,r)&&t.completedCleanly()}}catch{return{acknowledged:!1,exited:!1}}}async function Xi(e){await B(Yr(e))}async function Zi(){try{await Promise.allSettled([...R.keys()].map(async e=>{await B(e)}))}finally{R.clear(),z.clear(),ci(),Gt()}}async function Qi(e){let t=await Ii(e);if(t)return await $i({session:t.session,deviceKey:t.deviceKey,options:e,resolved:t.resolved})}async function $i(e){let{session:t,deviceKey:n,options:r,resolved:i}=e;try{let e=t.capturedCount>0,n=await Cr({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 B(n,{force:!0,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:ct(e)===`accessibility-timeout`}});return}}async function ea(e){let t=Li(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 B(e.deviceKey);return}let r=`${e.action}-${Date.now()}-${Math.random().toString(16).slice(2)}`,i=e.payloadBase64?`${e.action} ${r} ${e.payloadBase64}`:`${e.action} ${r}`,a;try{a=Er(await Sr(t.port,i,e.timeoutMs)),Dr(a,r)}catch(t){throw await B(e.deviceKey),t}if(a.ok!==`true`)throw new n(`COMMAND_FAILED`,a.message||a.errorType||`Android automation helper ${e.action} failed`,{errorType:a.errorType,helper:a});return a}function ta(e,t){return e.packageName===t.packageName&&e.runner===t.runner&&na(e.helperVersion,t.helperVersion)&&na(e.helperVersionCode,t.helperVersionCode)&&na(e.sha256,t.sha256)}function na(e,t){return e===void 0||t===void 0||e===t}const ra=`android-touch-plan-v1`,ia=45e3,aa=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,oa=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function sa(e,t){let n=await ua(e),r=fa(t),i=Math.max(45e3,r.durationMs+15e3),a=Buffer.from(JSON.stringify({protocol:ra,...r})).toString(`base64`),o=await h(`android_touch_helper_gesture`,async()=>{let e=await ea({deviceKey:n.deviceKey,action:`gesture`,helper:la(n.artifact),payloadBase64:a,timeoutMs:i});return e?{...ga(e),helperTransport:`persistent-session`}:{...await ma({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,a],timeoutMs:i,readResult:ga}),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 ca(e,t={}){let n=await ua(e);t.helperSessionScope===`daemon-session`&&await Fi(fi({adb:n.adb,adbProvider:n.adbProvider,artifact:n.artifact,deviceKey:n.deviceKey}));try{let e=await ea({deviceKey:n.deviceKey,action:`viewport`,helper:la(n.artifact),timeoutMs:ia});if(e)return _a(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 ma({adb:n.adb,runner:n.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:ia,readResult:_a})}function la(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function ua(e){let t=w(e),n=t.snapshotHelperArtifact??await da(),r=Yr(e);await Zr({deviceKey:r,adb:t.exec});let i=await h(`android_touch_helper_install`,async()=>await dr({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 da(){return await zn({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=Zn(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 fa(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(pa)}}function pa(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function ma(e){let t=await x(e.adb,[`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=ha(`${t.stdout}\n${t.stderr}`)}catch(e){if(e instanceof n){if(e.code===oa)throw new n(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==aa)throw e}throw new n(`COMMAND_FAILED`,t.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,De(t),e)}if(t.exitCode!==0)throw new n(`COMMAND_FAILED`,`Android automation helper failed`,De(t,{helper:r}));return e.readResult(r)}function ha(e){let t=Dn(e).results.find(e=>e.agentDeviceProtocol===qn);if(!t)throw new n(aa,`Android automation helper did not return a final result`);if(t.ok!==`true`)throw new n(oa,t.message&&t.message!==`null`?t.message:t.errorType||`Android automation helper returned an error`,{errorType:t.errorType,helper:t});return t}function ga(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:A(e.injectedEvents),elapsedMs:A(e.elapsedMs)}}function _a(e){let t=A(e.x),r=A(e.y),i=A(e.width),a=A(e.height);if(t===void 0||r===void 0||i===void 0||a===void 0)throw new n(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);let o=va(e);return{viewport:Pn({x:t,y:r,width:i,height:a}),...o?{keyboard:o}:{}}}function va(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 ya(e){if(e.topology===`two`||e.intent===`longPress`)return e;let{releaseBehavior:t,...n}=e,[{pointerId:r,samples:i}]=n.pointers,a=[...new Set([...at(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:st(n.point,r.point,t===`controlled`?ba(s,a):s)}}),c=[s[0],s[1],s[2],...s.slice(3)];return{...n,pointers:[{pointerId:r,samples:c}]}}function ba(e,t){let n=Math.min(16/t,.5);return e<n?e**2/n:1-(1-e)**2/(1-n)}async function xa(e,t){let n=ya(t),r=Ie(e);if(r){let e=n.intent===`longPress`?{...n,viewport:Pn(await r.gestureViewport())}:n;return{backend:`provider-native-touch`,...await r.touch(e)??{}}}return await sa(e,n)}async function Sa(e,t={}){return(await Ca(e,t)).viewport}async function Ca(e,t={}){let n=Ie(e);return n?{viewport:Pn(await n.gestureViewport())}:await ca(e,t)}async function wa(e,t,n){await E(e,[`input`,`tap`,t,n])}async function Ta(e,t,n){let r=ke(t);await E(e,[`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function Ea(e){await E(e,[`input`,`keyevent`,`4`])}async function Da(e){await E(e,[`input`,`keyevent`,`3`])}async function Oa(e){await E(e,[`input`,`keyevent`,`ENTER`])}async function ka(e,t){let n=za(t);await E(e,[`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await E(e,[`settings`,`put`,`system`,`user_rotation`,n]),await ja(e,t,n)}const Aa=15e3;async function ja(e,t,r){let i=Date.now()+Aa,a=await Ma(e,t,i);for(;a!==void 0&&a!==r&&Date.now()<i;)await _(Math.min(500,Na(i))),a=await Ma(e,t,i);if(a!==void 0&&a!==r)throw new n(`COMMAND_FAILED`,`orientation ${t} did not take effect: the display still reports rotation ${a} after ${Aa}ms`,{requestedRotation:Number(r),observedRotation:Number(a),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 Ma(e,t,r){try{let t=await E(e,[`dumpsys`,`display`],{timeoutMs:Na(r)});return/mCurrentOrientation=(\d)/.exec(t.stdout)?.[1]}catch(e){throw new n(`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 Na(e){return Math.max(1,e-Date.now())}async function Pa(e){await E(e,[`input`,`keyevent`,`187`])}async function Fa(e,t,n,r=800){let i={x:t,y:n};return await xa(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function Ia(e,t,n){await wa(e,t,n)}async function La(e,t,n){let{viewport:r,keyboard:i}=await Ca(e,{helperSessionScope:n?.helperSessionScope}),a=Ra(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 xa(e,{...ot({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 Ra(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 za(e){let t=Ce[e];if(t===void 0)throw new n(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`);return String(t)}async function Ba(e){let t=(await E(e,[`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new n(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(t[1]),height:Number(t[2])}}async function Va(e,t,n){return t===`wait`?await Ha(n.captureNodes,n.timeoutMs??1e4):t===`get`?Ja((await qa(n.captureNodes))?.alert??null):await Ua(e,t,n.captureNodes)}async function Ha(e,t){let r=Date.now(),i=await Ka(e,t);if(!i)throw new n(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...fe(`Alert visible`)}}async function Ua(e,t,r){let i=await Ka(r,pe);if(!i)throw new n(`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 a=on(i.buttons,t);if(a)return await wa(e,a.x,a.y),await Wa(i.alert,t,r),Ya(t,i.alert,a.label,{x:a.x,y:a.y});if(t===`dismiss`)return await Ea(e),await Wa(i.alert,t,r),Ya(t,i.alert,`Back`);throw new n(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:i.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function Wa(e,t,r){let i=Date.now();for(;;){let a=await qa(r);if(!a||!Ga(a.alert,e))return;if(Date.now()-i>=2e3)throw new n(`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 Ga(e,t){return e.title===t.title&&e.buttons.join(`\0`)===t.buttons.join(`\0`)}async function Ka(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await qa(e);if(t)return t;await _(300)}return null}async function qa(e){return rn(await h(`snapshot_capture`,e,{backend:`android`,purpose:`alert`}))}function Ja(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...fe(e?`Alert visible`:`No alert visible`)}}function Ya(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 Xa=`android.intent.category.LAUNCHER`,Za=`android.intent.category.DEFAULT`;async function Qa(e,t){await x(e,[`am`,`force-stop`,t])}async function $a(e,t,n=[Xa]){for(let r of n){let n=await x(e,[`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=mt(n.stdout);if(i)return i}return null}async function eo(e,t,r={}){let i=r.category??Xa;if(r.activity){await x(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Za,`-c`,i,`-n`,to(t,r.activity)]);return}let a=await x(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Za,`-c`,i,`-p`,t],{allowFailure:!0});if(a.exitCode===0&&!ht(a.stdout,a.stderr))return;let o=await $a(e,t,[i]);if(!o)throw new n(`COMMAND_FAILED`,`Failed to resolve Android launch component for ${t}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});await x(e,[`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,Za,`-c`,i,`-n`,o])}function to(e,t){return t.includes(`/`)?t:`${e}/${t.startsWith(`.`)?t:`.${t}`}`}let no=null;function ro(e){return`${e.PATH??``}::${e.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function io(e){let t=ro(e);if(no?.key===t)return no.invocation;if(await Ee(`bundletool`)){let e={cmd:`bundletool`,prefixArgs:[]};return no={key:t,invocation:e},e}let r=await Oe(e.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new n(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return no={key:t,invocation:i},i}async function ao(e,t,n){let r=await io(n);await Te(r.cmd,[...r.prefixArgs,...e],{signal:t})}function oo(e){return D.extname(e).toLowerCase()===`.aab`}async function so(e,t,n={}){let r=w(e),i=`universal`;if(r.installBundle){await r.installBundle(t,{mode:i,signal:n.signal});return}let a=S().files,o=await a.makeTempDirectory(`agent-device-aab-`),s=D.join(o,`bundle.apks`);try{await ao([`build-apks`,`--bundle`,t,`--output`,s,`--mode`,i],n.signal,n.environment??S().environment),await ao([`install-apks`,`--apks`,s,`--device-id`,e.id],n.signal,n.environment??S().environment)}finally{await a.remove(o,{recursive:!0,force:!0})}}async function co(e,t,n={}){if(oo(t)){await so(e,t,n);return}await We(t,{device:e,replace:!0,signal:n.signal})}async function lo(e,t,n={}){await yt(e,async()=>{e.booted||await ut(e.id,void 0,n.signal),await co(e,t,n)})}const uo=[`mInputShown`,`mIsInputViewShown`,`isInputViewShown`,`mDecorViewVisible`,`mWindowVisible`,`mInShowWindow`],fo=new Map([[2,`number`],[3,`phone`],[4,`datetime`]]),po=new Set([32,208]),mo=new Set([128,224,144]);async function ho(e){return await V(b(e))}async function V(e){let t=await x(e,[`dumpsys`,`input_method`],{allowFailure:!0});if(t.exitCode!==0)throw T(`Failed to query Android keyboard state`,t);return vo(t.stdout)}async function go(e){return await _o(b(e))}async function _o(e){let t=await V(e),r=t,i=0;for(;r.visible&&i<2;)await x(e,[`input`,`keyevent`,`111`]),i+=1,await _(120),r=await V(e);if(t.visible&&r.visible)throw new n(`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 vo(e){let t=Co(e)??yo(e),n=bo(e),r=xo(e,/\bpackageName=([A-Za-z0-9_.]+)\b/g),i=xo(e,/\b(?:resourceId|resource-id)=([^\s,}]+)/g),a=p(e),o=ee(r,i,a);return So(r,i,a),{visible:t??!1,inputType:n,type:n?Do(n):void 0,inputMethodPackage:a,focusedPackage:r,focusedResourceId:i,inputOwner:o}}function yo(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 bo(e){let t=xo(e,/\binputType=0x([0-9a-fA-F]+)\b/gi);return t?`0x${t.toLowerCase()}`:void 0}function xo(e,t){let n;for(let r of e.matchAll(t))n=r[1];return n}function So(e,t,n){n||!d(e)&&!l(t)||g({level:`warn`,phase:`android_input_ownership_fallback`,data:{focusedPackage:e,focusedResourceId:t}})}function Co(e){return To(wo(e,uo))}function wo(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 To(e){if(e.size===0)return null;let t=Eo(e,[`mWindowVisible`,`mDecorViewVisible`,`mInShowWindow`]);if(t!==void 0)return t;let n=e.get(`mInputShown`);return n===void 0?Eo(e,[`mIsInputViewShown`,`isInputViewShown`])??null:n}function Eo(e,t){for(let n of t){let t=e.get(n);if(t!==void 0)return t}}function Do(e){let t=Number.parseInt(e.replace(/^0x/i,``),16);if(Number.isNaN(t))return`unknown`;let n=t&15,r=fo.get(n);if(r)return r;if(n!==1)return`unknown`;let i=t&4080;return po.has(i)?`email`:mo.has(i)?`password`:`text`}async function Oo(e){return await ko(b(e))}async function ko(e){return No(await Mo(e,[`cmd`,`clipboard`,`get`,`text`],`read`))}async function Ao(e,t){await jo(b(e),t)}async function jo(e,t){await Mo(e,[`cmd`,`clipboard`,`set`,`text`,t],`write`)}async function Mo(e,t,n){let{androidClipboardShellCommandUnavailableError:r,classifyAndroidClipboardShellResponse:i}=await import(`./clipboard-shell-response.js`),a=await x(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 No(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}const Po=`com.callstack.agentdevice.imehelper`,Fo=`android-ime-helper-v1`;async function Io(e){return e.imeHelperArtifact??await Lo()}async function Lo(){return await S().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:Ro,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const H=`IME helper`;function Ro(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new
|
|
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 ds=2e3;async function fs(e=S().environment,t=S().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await ws(n,t),i=await Nt(`adb`,[`version`]);return i?bs({license:r,sdkRoot:n,versionLine:i}):Cs(n,r)}async function ps(e,t){if(e.platform!==`android`)return[];let n=b(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await ys(n,e.id,t.metroPort)),r.push(await ms(n,e)),r}async function ms(e,t){try{let n=await W(e),r=ns(t);return n===await hs()&&!r?await gs(e,t,n):_s(t,n,r)}catch(e){return vs(e)}}async function hs(){try{return(await Lo()).manifest.serviceComponent}catch{return}}async function gs(e,t,n){let r=(await x(e,[`settings`,`get`,`secure`,Yo.previousIme],{allowFailure:!0,timeoutMs:ds})).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 _s(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 vs(e){let t=n(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 ys(e,t,r){try{let n=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:ds}),i=`tcp:${r} tcp:${r}`,a=n.stdout.includes(i);return{id:`android-reverse`,status:a?`pass`:`warn`,summary:a?`Android adb reverse exists for Metro port ${r}.`:`Android adb reverse is missing for Metro port ${r}.`,command:a?void 0:`adb -s ${t} reverse tcp:${r} tcp:${r}`,evidence:{stdout:n.stdout.trim()}}}catch(e){let t=n(e);return{id:`android-reverse`,status:`warn`,summary:`Could not inspect Android adb reverse mappings.`,hint:t.message,evidence:{code:t.code}}}}function bs(e){return{id:`toolchain`,status:xs(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${Ss(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 xs(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function Ss(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function Cs(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 ws(e,t){if(!e)return`unknown`;try{return await t.access(D.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ts(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=ks(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Ds(t.targetInput),actualInput:Ds(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 q(e){return e?e.password?!0:Es(e.text):!1}function Es(e){return e?Array.from(e).every(Os):!1}function Ds(e){if(!e)return null;let t=q(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Os(e){return e===`•`||e===`*`||e===`●`}function ks(e){return e.masked===!0||q(e.targetInput)||q(e.actualInput)}const As=new WeakMap;function js(e,t){return t&&As.set(e,t),e}function Ms(e){return As.get(e)}function Ns(e){return e.clickable}function Ps(e){return e.focusable||e.focused===!0}function J(e){return Ns(e)||Ps(e)}function Fs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Is(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function Ls(e,t,n){if(!e)return;let r=Bs(e);return t&&(r=zs(r,t)),n&&(r=zs(r,n)),r}function Rs(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ie(e.effectiveRect)?!0:void 0}}function zs(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 Bs(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function Vs(e,t){let n=new Set;return Hs(e,n,t),Ws(e,n,t),n}function Hs(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Hs(r,t,n)}}function Us(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function Ws(e,t,n){let r=Us(e,t,n).filter(Ks);if(r.length<2)return;let i=r.filter(e=>qs(e)&&Js(e));if(i.length===0)return;let a=Gs(i);for(let r of Us(e,t,n))n?.check(`work`),qs(r)&&(Js(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function Gs(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Ks(e){return e.windowIndex!==void 0||e.windowType!==void 0}function qs(e){return e.windowType===1}function Js(e){return e.windowActive===!0||e.windowFocused===!0}function Ys(e,t,n,r,i){let a=new Set(e.sourceNodes),o=Zs(t,i),s=Xs(o,n,Qs(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(Zs([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:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function Xs(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function Zs(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 Qs(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 $s(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=ec(e);return t.interactiveOnly?tc(e,a,n,r,i):a.isStructural||a.isVisual?ic(e,a,r):!0}function ec(e){let t=oc(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Fs(e.label??``),hasMeaningfulId:r&&!Fs(e.identifier??``),isStructural:sc(t),isVisual:t===`imageview`||t===`imagebutton`}}function tc(e,t,n,r,i){return rc(e)?!1:J(e)||ne(t.type)&&r?!0:nc(t,n,r,i)}function nc(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function rc(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function ic(e,t,n){return J(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function ac(e){if(!e)return!1;let t=oc(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function oc(e){return e?e.toLowerCase():``}function sc(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function cc(e,t,n,r){return{...Is(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const lc=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var Y=class extends Error{code=lc;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function uc(e){return e instanceof Y?e.code===lc:!!(e&&typeof e==`object`&&e.code===lc)}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()+gc()}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 Y(`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 Y(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function fc(e,t){return new dc(e??{},t)}function pc(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=mc(i,r,t),a=i.effectiveRect;if(!a||!ie(a)){if(Rs(i).hittable===!0)throw new Y(`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&&!hc(a,e))throw new Y(`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 mc(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function hc(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 gc(){return 250}function _c(e,t,n){let r=n.depth??1/0,i=re(n.scope),a=Fc(e),o=fc(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=Oc(e,o),s.hidden=n.raw?new Set:Vs(e,o);for(let t of e.children)if(yc(s,t,0),s.truncated)break;n.raw||pc(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?Ys(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:vc(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw uc(e)&&(e.analysis??=s.analysis),e}}function vc(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Ms(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 yc(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),bc(e,t,n))return;let l=t.windowRect??s??e.viewport,u=xc(e,t,c,l),d=Sc(e,t,r,i,a,o,u,l),f=i||J(t),p=a||ac(t.type),m=Cc(e,t,u,c);wc(e,t,n,d,f,p,o||It(t.identifier),l,m)}function bc(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 xc(e,t,n,r){return e.options.raw?t.rect:Ls(t.rect,r,n)}function Sc(e,t,n,r,i,a,o,s){return!e.options.raw&&!$s(t,e.options,r,jc(e,t),i)?n:Tc(e,t,n,a||It(t.identifier),o,s)}function Cc(e,t,n,r){return e.options.raw||!kc(t)?r:n}function wc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(yc(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Tc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Dc(e,t,Ec(e,t,n,r),i,a),o}function Ec(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,contentDescription:t.contentDescription,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,heading:t.heading,roleDescription:t.roleDescription,checked:t.checked,editable:t.editable,password:t.password,hintShowing:t.hintShowing,placeholder:t.placeholder,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:J(t)||void 0,depth:Ac(e.nodes,n),parentIndex:n,...Mc(t,e.hidden),...r?{systemChrome:!0}:{}}}function Dc(e,t,n,r,i){let a=cc(n,r,!e.options.raw&&kc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:Rs(a))}function Oc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ie(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ce(n)??void 0}function kc(e){return e.scrollable===!0&&ne(e.type)}function Ac(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function jc(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&&(J(n)||jc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Mc(e,t){return Nc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Nc(e,t){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Pc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Pc(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 Fc(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 Ic(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||It(n);return r||e.push(i),i},close(){e.pop()}}}function*Lc(e){let t=/<node\b[^>]*>|<\/node>/g,n=Ic(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=Rc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function Rc(e){let t=zc(e),n=Lt(t.bounds);return{...t,...n?{rect:n}:{}}}function zc(e){let t=Bc(e),n=e=>Jc(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=Lt(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 Bc(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=Vc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function Vc(e,t,n){if(t=Uc(e,t,n),t>=n||Wc(e[t]))return;let r=t;t=Hc(e,t,n);let i=e.slice(r,t);if(t=Uc(e,t,n),!i||e[t]!==`=`)return;t=Uc(e,t+1,n);let a=e[t];if(!Gc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Rt(e.slice(o,s)),nextCursor:s+1}}function Hc(e,t,n){for(;t<n&&!qc(e[t]??``);)t+=1;return t}function Uc(e,t,n){for(;t<n&&Kc(e[t]??``);)t+=1;return t}function Wc(e){return e===`/`||e===`>`}function Gc(e){return e===`"`||e===`'`}function Kc(e){return e===` `||e===`
|
|
12
|
-
`||e===`\r`||e===` `}function qc(e){return e===`=`||e===`/`||e===`>`||Kc(e)}function Jc(e,t){return e.get(t)??null}function Yc(e){let t={type:null,label:null,value:null,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=Rc(t),o=n.at(-1),s=Xc(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function Xc(e,t,n){let r=e.text||e.desc;return js({type:e.className,label:r,value:e.text,...e.desc&&e.desc!==r?{contentDescription:e.desc}:{},identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,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,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 Zc(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 Qc=new Set([`android`,`com.android.systemui`]);function $c(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=ul(e,n.foregroundAppPackage);return nl(r,t)?el(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):cl(r)?{outcome:`ok`}:tl(r)?{outcome:`system-surface-only`}:rl(r)?{outcome:`ok`}:il(r)?el(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):al(r)||ol(r,t)?el(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):sl(r)?el(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function el(e,t,n,r){return{outcome:`unusable`,decision:ll(e,t,n,r)}}function tl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function nl(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function rl(e){return il(e)&&e.inputMethodMeaningfulNodeCount>=2}function il(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function al(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function ol(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function sl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function cl(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function ll(e,t,n,r){return{reason:n,failureReason:r,diagnostics:wl(e,t)}}function ul(e,t){let n=dl(t);for(let t of Lc(e))fl(n,t);return yl(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 fl(e,t){e.nodeCount+=1,Cl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&pl(e,t.resourceId),ml(e,t),hl(e,t)}function pl(e,t){let n=nn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function ml(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 hl(e,t){bl(t)&&(e.meaningfulNodeCount+=1,gl(e,t),vl(e,t))}function gl(e,t){e.currentWindowType===1&&!Sl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),_l(e)&&!Ft(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function _l(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function vl(e,t){Sl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),m({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function yl(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 bl(e){return e.visibleToUser===!1?!1:xl(e.text)||xl(e.desc)||xl(e.resourceId)}function xl(e){return e!==null&&e.trim()!==``}function Sl(e){return e===null||Qc.has(e)}function Cl(e){return e!==null&&Qc.has(e)}function wl(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 Tl(e){let t=await B(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await El(e.adb,e.packageName)}async function El(e,t){await li({adb:e,packageName:t}),await _(150),g({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const Dl=Symbol(`androidSnapshotCaptureEvidence`);function Ol(e,t){return Object.defineProperty(e,Dl,{value:t}),e}function kl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Dl];return te(t,n.clickability),n.occlusionContext&&u(t,n.occlusionContext),t}async function Al(e,t={}){let n=w(e,t.helperAdb).exec;return(await Rl(e,t,n)).xml}async function jl(e,t={}){let n=w(e,t.helperAdb).exec,r=await Rl(e,t,n),i=r.xml,a=Yc(i),o=Pl(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=_c(a,void 0,s),n=Nl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Ll({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return Ol({...u,...Il(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:Zc(e),occlusionContext:l})}catch(e){if(!uc(e))throw e;return Ml({failure:e,androidSnapshot:o})}}function Ml(e){return Ol({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}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Nl(e,t){return e===!0||t.helperTruncated===!0||e}function Pl(e,t){return Fl(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Fl(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Ms(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Il(e){return e===!0?{truncated:!0}:{}}function Ll(e){if(au(e.interactiveSnapshot.nodes).size>0||iu(e.xml))return;let t=_c(e.tree,void 0,{...e.options,interactiveOnly:!1});ou(Se(a(t.nodes)),t,e.interactiveSnapshot)}async function Rl(e,t,n){let r=w(e,t.helperAdb),i=await h(`android_snapshot_helper_artifact_resolution`,async()=>await nu(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await zl(e,t,n,i.artifact);throw g({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),ru(i.errorReason)}async function zl(e,t,n,r){let i=Yr(e),a=w(e,t.helperAdb),o=Bl(t,i);try{let e;for(let o=0;;o+=1){o>0&&await Kl(t.signal);let s=await Gl({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3||t.transient!==void 0&&Date.now()>=t.transient.settleBy)return await ql({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal,retireHelper:t.transient===void 0});e=s.decision.reason}}finally{o&&await B(i)}}function Bl(e,t){return e.transient?Li(t)===void 0:e.helperSessionScope!==`daemon-session`}function Vl(e){return e.transient?`current-only`:e.helperInstallPolicy??`missing-or-outdated`}async function Hl(e,t,n,r,i){let a=await h(`android_snapshot_helper_install`,async()=>await dr({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:Vl(e),timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:Vl(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 Ul(e){let{signal:t,adb:r,adbProvider:i,artifact:a,helperDeviceKey:o}=e,s=fi({adb:r,adbProvider:i,artifact:a,deviceKey:o,signal:t});try{let e=await h(`android_snapshot_helper_session_capture`,async()=>await Qi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Yn});if(e)return e}catch(e){if(t?.throwIfAborted(),$r(e))throw e;g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:n(e).message}}),await El(r,a.manifest.packageName)}return await h(`android_snapshot_helper_capture`,async()=>await di(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Yn,commandTimeoutMs:Xn})}function Wl(e,t,n){return{xml:e.xml,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 Gl(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await Hl(t,n,r,i,a);e.installed&&await B(a),s=Wl(await Ul({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){if(t.signal?.throwIfAborted(),or(e))throw e;return{outcome:`captured`,capture:await Yl({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=$c(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,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function Kl(e){e?.throwIfAborted(),await _(250),e?.throwIfAborted()}async function ql(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 Tl({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),Jl(e.contentRecovery,e.attempts)}function Jl(e,n){return new t(`COMMAND_FAILED`,e.failureReason,{...e.diagnostics,androidSnapshotHelperFailureReason:e.reason,attempts:n,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 Yl(e){let t=Xl(e.error);throw g({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await B(e.helperDeviceKey),await El(e.adb,e.artifact.manifest.packageName),ir({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),Zl(e.error,t)}function Xl(e){let t=n(e),r=tu(t.details?.helper);if(r&&r!==t.message)return`${t.message}: ${r}`;if(r)return r;let i=(typeof t.details?.stderr==`string`?t.details.stderr.trim():``).split(/\r?\n/).find(e=>e.trim());return i?`${t.message}: ${i}`:t.message}function Zl(e,r){let i=n(e),a=Ql(i);return new t(s(i.code),`Android snapshot helper failed: ${r}`,{...i.details,...eu(i),androidSnapshotHelperFailureReason:r,...a?{androidCaptureFailureReason:a}:{},hint:$l(i,a)},e)}function Ql(e){return ct(e)}function $l(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 eu(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 tu(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 nu(e){if(e)return{artifact:e};let t=je(),r=D.join(Me(),`android`,`snapshot-helper`,`dist`),i=D.join(r,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await S().files.access(i)}catch{return{}}try{let e=Zn(JSON.parse(await S().files.readText(i))),t=D.join(r,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await S().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:n(e).message}}}function ru(e){let n=e??`the bundled helper artifact was not found`;return new t(`COMMAND_FAILED`,`Android snapshot helper is unavailable: ${n}`,{androidSnapshotHelperFailureReason:n,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 iu(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function au(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 ou(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 su=Object.freeze({now:()=>Date.now(),sleep:_});async function cu(e,t,n,r,i={},a=su){let o=await Du(e),s=a.now()+1500,c=null;for(;;){let l=await _u(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 lu(e,t,n,r={}){return mu(await Al(e,r),t,n)}async function uu(e,t,n,r){let i=await Du(e);return vu(await Al(e,r),t,n,i).targetInput}async function du(e,t,n,r={}){try{return await uu(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 X(e,n,r){if(r?.ok)return;let i=r?fu(e,n,r):null;if(i)return i;throw new t(`COMMAND_FAILED`,hu(r),gu(e,r))}function fu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||q(t)||q(r)||q(i)||!Nu(t,r)||!Nu(t,i)||t.text===n.actual)return null;let a=Pu(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 pu(e,t,n,r,i={}){let a=vu(e,t,n,i);return yu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:bu(a,r)??xu(a,r)}function mu(e,t,n){return vu(e,t,n).targetInput?.text??null}function hu(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 gu(e,t){let n=Ts(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 _u(e,t,n,r,i,a){return pu(await Al(e,a),t,n,r,i)}function vu(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of Lc(e)){let e=Eu(a,r);e&&Ou(i,e,t,n)}return Au(i)}function yu(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||!Mu(n))return null;let r=n.text??null,i=Array.from(Su(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 xu(e,t){let n=e.actualInput;return{ok:n!==null&&Cu(Su(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Su(e){return e.hintShowing?``:e.text??``}function Cu(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||Tu(n,r))}function wu(e){return e.replaceAll(/\s+/g,` `).trim()}function Tu(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 Eu(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:m({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:ju(e.className??``),hintShowing:e.hintShowing===!0}}async function Du(e){try{return{activeInputMethodPackage:(await ho(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 Ou(e,t,n,r){let i=ae(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=ku(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=ku(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=ku(e.anyAtPoint,t))}function ku(e,t){return e&&e.area<t.area?e:t}function Au(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function ju(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Mu(e){return q(e)}function Nu(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 Pu(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Fu(e,t){return await zt(t.stateDir),await rs(t.stateDir,e.id,async()=>await Lu(e,t))}function Iu(e){let t=o(e).details?.hint;return{outcome:`helper-unavailable`,reason:n(e).message,...typeof t==`string`?{hint:t}:{}}}async function Lu(e,t){let n=S().imeRecoveryMarkers,r=b(e),i=w(e),a=U(e),o;try{o=await Io(i),await Bo({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return Iu(e)}let{manifest:s}=o,c=await W(r);if(c===s.serviceComponent){let i=await n.write(t.stateDir,e.id),o=await G(r);return i&&K.add(a),{outcome:`settled`,activated:!1,alreadyActive:!0,...i?{}:{persistFailed:!0},previousIme:o,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}let l=await G(r);if(!await Xo(r,c))return await Qo(r,l,e.id),C({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 Qo(r,l,e.id),C({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 x(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let d=await x(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),f=await W(r);return f===s.serviceComponent?(K.add(a),C({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}):(K.delete(a),await Qo(r,l,e.id),u||await n.clear(t.stateDir,e.id),C({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 Ru(e){return D.join(e,`android-test-ime-pending`)}function zu(e,t){return D.join(Ru(e),encodeURIComponent(t))}async function Bu(e,t){let r=S().files,i,a=!1;try{let n=Ru(e);if(i=zu(e,t),await r.ensureDirectory(n),(await Uu(i))?.serial===t)return!0;let o={version:1,serial:t};if(await r.writeAtomicText(i,`${JSON.stringify(o)}\n`,384),a=!0,(await Uu(i))?.serial!==t)throw Error(`Android test IME marker read-back did not match the requested device.`);return!0}catch(o){return a&&i&&await r.remove(i,{force:!0}).catch(()=>{}),g({level:`debug`,phase:`android_test_ime_marker_write_failed`,data:{stateDir:e,serial:t,error:n(o).message}}),!1}}async function Vu(e,t){await S().files.remove(zu(e,t),{force:!0}).catch(()=>{})}async function Hu(e){let t=S().files,n;try{n=await t.readDirectory(Ru(e))}catch{return[]}let r=[];for(let t of n)try{let n=D.join(Ru(e),t),i=await Uu(n);i&&zu(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function Uu(e){try{return Wu(await S().files.readText(e))}catch{return}}function Wu(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 Gu=new Ht(`utf-16le`);let Ku;async function qu(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await Ju(e,n,t);if(!r)continue;let i=Yu(r);if(i)return i}return await id(e,t)}async function Ju(e,t,n){try{let r=await Te(`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 Yu(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?Xu(e.toString(`utf8`)):Zu(e)}function Xu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function Zu(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=$u(e.subarray(n,n+a));else if(r===258&&t){let r=Qu(e,n,i,t);if(r)return r}n+=a}}function Qu(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function $u(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?ed(e,o):td(e,o))}return a}function ed(e,t){let[,n]=nd(e,t),[r,i]=nd(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function td(e,t){let[n,r]=rd(e,t),i=t+r;return Gu.decode(e.subarray(i,i+n*2))}function nd(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function rd(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function id(e,t){t?.throwIfAborted();let n=await ad();if(!n)return;let r=await Te(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function ad(){if(Ku!==void 0)return Ku??void 0;try{let e=S().files;for(let t of _t()){let n=D.join(t,`build-tools`);try{let t=(await e.readDirectory(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of t){let t=D.join(n,r,`aapt`);if(D.isAbsolute(t)&&await e.isExecutable(t))return Ku=t,t}}catch{}}}catch{}Ku=null}async function od(e,t){let n=e.kind===`url`&&Ne(e.url),r=await Pe({source:e,isInstallablePath:(e,t)=>t.isFile()&&sd(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await cd(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function sd(e){let t=D.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function cd(e,t){let n=D.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await qu(e,t)}}async function ld(e,n,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${n}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,a,`-p`,n],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new t(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(ud(o,e,t),u+=1);return await E(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function ud(e,n,r){if(typeof r==`string`){e.push(`--es`,n,r);return}if(typeof r==`boolean`){e.push(`--ez`,n,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,n,String(r));return}e.push(`--ef`,n,String(r));return}throw new t(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${n}". Use string, boolean, or number.`)}function Z(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function dd(e){let t=gd(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 _d(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 pd(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=>hd({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 md(e){return Math.round(e*10)/10}function hd(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:md(Math.max(...t.map(e=>e.durationNs))/1e6)}}function gd(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function _d(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){yd(e,t);let r=kd(e),i=Td(e),a=xd(i,r,t),o=Date.parse(n),s=jd({frames:i,measuredAtMs:o,summary:r}),c=fd({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??Fd(i),u=Sd(r,i,c),d=wd({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...Cd(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 yd(e,n){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android gfxinfo did not find a running process for ${n}`,{metric:`fps`,package:n,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 bd(e){throw new t(`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 xd(e,n,r){let i=dd(e);if(!n&&e.length===0&&bd(r),n||i!==void 0)return i;throw new t(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Sd(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Bt(i/r*100):0)}}function Cd(e){return{frameDeadlineMs:e===void 0?void 0:md(e/1e6),refreshRateHz:e===void 0?void 0:md(1e9/e)}}function wd(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=pd({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Td(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(Ed(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=Dd(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Ed(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function Dd(e,t){if(!t||e.length<t.size)return;let n=Od(e,t,`Flags`),r=Od(e,t,`IntendedVsync`),i=Od(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Od(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 kd(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=Id(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=Z(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=Id(t,`Uptime`),l=Id(t,`Stats since`);return{droppedFramePercent:Bt(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:Ad({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function Ad(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 jd(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=Md(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=Nd(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:Pd({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function Md(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function Nd(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function Pd(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 Fd(e){if(e.length===0)return;let t=Md(e);return Nd(t.firstFrameNs,t.lastFrameNs)}function Id(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:Z(i)??void 0}async function Ld(e,t,n={}){let r=b(e,n.adb);try{let i=vd((await x(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await Rd(e,t,n),i}catch(e){throw zd(t,e)}}async function Rd(e,t,n={}){let r=b(e,n.adb);try{await x(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function zd(e,n){return n instanceof t?new t(n.code,n.message,{...n.details??{},metric:`fps`,package:e},n):new t(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},n)}async function Bd(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 Vd(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 Vd(e,t,n){try{let r=await Ld(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 Hd(e,t,n){let r=b(e,n.adb);await Jd(r,t),await Zd(r,t),await Xd(r,t,n.files);let i=await qd(t.outPath,n.files);await Gd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await Bd(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?Br:Vr,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function Ud(e,t,n={}){let r=b(e,n.adb);try{t.state===`running`&&(await Jd(r,t),await Zd(r,t).catch(()=>{}))}finally{await Gd(r,t.remotePath)}}function Wd(e,t,n=Ur){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Gd(e,t){try{await x(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:Hr})}catch{}}async function Kd(e,t,n=S().files){await n.ensureDirectory(D.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function qd(e,n=S().files){try{return(await n.stat(e)).size}catch(n){throw new t(`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.`},n)}}async function Jd(e,t){try{await x(e,[v(Yd(t.profilerPid))],{timeoutMs:P})}catch(e){throw N(`stop`,t.kind,t.packageName,e)}}function Yd(e){return[`pid=${y(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 Xd(e,n,r){await(r??S().files).ensureDirectory(D.dirname(n.outPath));try{await e([`pull`,n.remotePath,n.outPath],{timeoutMs:P})}catch(e){throw new t(`COMMAND_FAILED`,`Failed to pull Android ${n.kind} artifact for ${n.packageName}`,{package:n.packageName,tool:n.kind,remotePath:n.remotePath,outPath:n.outPath,hint:`Check that the profiling command ran long enough to create an artifact, then retry stop with the same session.`},e)}}async function Zd(e,n){let r;for(let t=0;t<12;t+=1){let t=await Qd(e,n.remotePath);if(t!==void 0&&t>0&&t===r)return;r=t,await _(250)}throw new t(`COMMAND_FAILED`,`Android ${n.kind} artifact is not ready to pull`,{package:n.packageName,tool:n.kind,remotePath:n.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 Qd(e,t){let n=y(t),r=await x(e,[v(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:Hr});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function $d(e,t,n,r={}){let i=b(e,r.adb),a=await Wr(i,t);await Gr(i,`perfetto`,t);let o=Wd(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await Rd(e,t,{adb:i}),s=await tf(i,o,t)}catch(e){throw await Gd(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:Vr,message:`Started Android Perfetto trace for ${t}`}}async function ef(e,t,n,r={}){return await Hd(e,{...t,outPath:n},r)}async function tf(e,n,r){try{let i=Kr((await x(e,[`perfetto`,`--background-wait`,`-o`,n,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:P})).stdout);if(i)return i;throw new t(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw N(`start`,`perfetto`,r,e)}}function nf(e){let t=[];for(let n of c(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:Bt(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function rf(e,t,n,r={}){let i=b(e,r.adb),a=await Wr(i,t);await Gr(i,`simpleperf`,t);let o=Wd(t,`cpu.perf.data`),s;try{s=await sf(i,a,o,t)}catch(e){throw await Gd(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:Br,message:`Started Android Simpleperf CPU profile for ${t}`}}async function af(e,t,n,r={}){return await Hd(e,{...t,outPath:n},r)}async function of(e,t,n,r={}){let i=b(e,r.adb);await Gr(i,`simpleperf`,t.packageName);let a=await uf(i,t),o=new Date().toISOString(),s=nf(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Kd(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 qd(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:Br,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function sf(e,n,r,i){try{let a=Kr((await x(e,[v(cf(n,r))],{timeoutMs:P})).stdout);if(a)return a;throw new t(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,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`,i,e)}}function cf(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(y).join(` `),r=`${Ur}/agent-device-${t}-${Date.now()}.err`;return[`err=${y(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 uf(e,t){try{return await x(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:P})}catch(e){throw N(`report`,`simpleperf`,t.packageName,e)}}const df=15e3,ff=12e4;async function pf(e,t,n={}){let r=b(e,n.adb);try{return _f((await x(r,[`dumpsys`,`meminfo`,t],{timeoutMs:df})).stdout,t,new Date().toISOString())}catch(e){throw Tf(`memory`,t,e)}}async function mf(e,n,r,i={}){let a=b(e,i.adb),o=i.files??S().files,s=await vf(a,n),c=yf(n);await o.ensureDirectory(D.dirname(r));let l=await hf(o,r);try{we(await x(a,[`am`,`dumpheap`,n,c],{allowFailure:!0,timeoutMs:ff}),`Failed to capture Android heap dump for ${n}`,e=>({kind:`android-hprof`,package:n,pid:s,remotePath:c,hint:bf(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:ff});if(e.exitCode!==0)throw await gf(o,r,l),T(`Failed to pull Android heap dump for ${n}`,e,{kind:`android-hprof`,package:n,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await gf(o,r,l),new t(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:n,pid:s,path:r,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:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:n,pid:s,remotePath:c}}finally{await x(a,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:df}).catch(()=>{})}}async function hf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function gf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function _f(e,n,r){if(/no process found for:/i.test(e))throw new t(`COMMAND_FAILED`,`Android meminfo did not find a running process for ${n}`,{metric:`memory`,package:n,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf.`});let i=Ef(e,`TOTAL PSS`)??Df(e);if(i===void 0)throw new t(`COMMAND_FAILED`,`Failed to parse Android meminfo output for ${n}`,{metric:`memory`,package:n,hint:`Retry perf after reopening the app session. If the problem persists, capture adb shell dumpsys meminfo output for debugging.`});return{totalPssKb:i,totalRssKb:Ef(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:xf(e)}}async function vf(e,n){let r=await x(e,[`pidof`,n],{allowFailure:!0,timeoutMs:df}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new t(`COMMAND_FAILED`,`No running Android process found for ${n}`,{kind:`android-hprof`,package:n,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function yf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function bf(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 xf(e){let t=e.split(`
|
|
14
|
-
`).flatMap(e=>Sf(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Sf(e){let t=e.trim();if(Cf(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return wf(n[1],n[2])}function Cf(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 wf(e,t){let n=e?.trim(),r=t?Z(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 Tf(e,
|
|
10
|
+
`).replace(/\n$/,``),n=t.match(/^clipboard text:\s*(.*)$/i);return n?n[1]??``:t.trim().toLowerCase()===`null`?``:t}const Po=`com.callstack.agentdevice.imehelper`,Fo=`android-ime-helper-v1`;async function Io(e){return e.imeHelperArtifact??await Lo()}async function Lo(){return await S().resolveHelperArtifact({helperDirName:`ime-helper`,manifestFileName:e=>`agent-device-android-ime-helper-${e}.manifest.json`,parseManifest:Ro,unavailableMessage:`Android test IME text entry requires the bundled Android IME helper artifact, but it was not found or could not be read`})}const H=`IME helper`;function Ro(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new n(`INVALID_ARGS`,`Android IME helper manifest must be an object.`);let t=e;return{name:k(t.name,`name`,`android-ime-helper`,H),version:Tn(t.version,`version`,H),assetName:Tn(t.assetName,`assetName`,H),sha256:En(t.sha256,H),packageName:k(t.packageName,`packageName`,Po,H),versionCode:wn(t.versionCode,`versionCode`,H),serviceComponent:k(t.serviceComponent,`serviceComponent`,`com.callstack.agentdevice.imehelper/.TestInputMethodService`,H),broadcastProtocol:k(t.broadcastProtocol,`broadcastProtocol`,Fo,H)}}const zo=new Set;async function Bo(e){return await S().ensureHelperInstalled({cache:zo,installTimeoutMs:3e4,helperLabel:`Android IME helper`},e)}function Vo(){zo.clear()}function U(e){return`${e.platform}:${e.id}`}function Ho(e){return e===Po}async function Uo(e,t,n){await Go(e,t,`com.callstack.agentdevice.imehelper.ACTION_INPUT_TEXT_B64`,{text:Buffer.from(n,`utf8`).toString(`base64`)})}async function Wo(e,t){await Go(e,t,`com.callstack.agentdevice.imehelper.ACTION_CLEAR_TEXT`,{})}async function Go(e,t,n,r){let i=[`am`,`broadcast`,`-p`,t,`-a`,n];i.push(`--es`,`protocol`,Fo);for(let[e,t]of Object.entries(r))i.push(`--es`,e,t);let a=await x(e,i,{allowFailure:!0,timeoutMs:1e4});if(a.exitCode!==0)throw T(`Android IME helper broadcast failed`,a,{action:n,packageName:t})}const Ko=`agent_device_ime_helper_previous_ime`,qo=`secure`,Jo=`default_input_method`,Yo={previousIme:Ko,defaultInputMethod:Jo};async function W(e){let t=await x(e,[`settings`,`get`,qo,Jo],{allowFailure:!0,timeoutMs:5e3});return es(t.exitCode===0?t.stdout:``)}async function G(e){let t=await x(e,[`settings`,`get`,qo,Ko],{allowFailure:!0,timeoutMs:5e3});return es(t.exitCode===0?t.stdout:``)||void 0}async function Xo(e,t){return(await x(e,[`settings`,`put`,qo,Ko,t],{allowFailure:!0,timeoutMs:5e3})).exitCode===0&&await G(e)===t}async function Zo(e){await x(e,[`settings`,`delete`,qo,Ko],{allowFailure:!0,timeoutMs:5e3})}async function Qo(e,t,n){try{(t?await Xo(e,t):await $o(e))||C({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:n,hadPriorRecord:t!==void 0}})}catch(e){C({level:`warn`,phase:`android_test_ime_record_rollback_failed`,data:{device:n,hadPriorRecord:t!==void 0,error:i(e).message}})}}async function $o(e){return await Zo(e),await G(e)===void 0}function es(e){let t=e.trim();return!t||t===`null`?``:t}const K=new Set,ts=new Map;function ns(e){return K.has(U(e))}function rs(e,t,n){return Pt(ts,`${e}:${t}`,n)}function is(){K.clear()}function as(e,t){let n=U(e);t?K.add(n):K.delete(n)}async function os(e,t){return await rs(t.stateDir,e.id,async()=>{let n=U(e);if(!K.has(n))return{restored:!1,reason:`no-record`};K.delete(n);let r=await cs(b(e),e);return ss(r.reason)&&await S().imeRecoveryMarkers.clear(t.stateDir,e.id),r})}function ss(e){return e===`ok`||e===`helper-not-active`||e===`no-record`}async function cs(e,t){let n=t.id;if(K.has(U(t)))return{restored:!1,reason:`owned-by-live-session`};let r=await G(e);if(!r)return{restored:!1,reason:`no-record`};let i=await W(e);if(i!==`com.callstack.agentdevice.imehelper/.TestInputMethodService`)return C({level:`debug`,phase:`android_test_ime_restore_skipped`,data:{device:n,currentIme:i,previousIme:r}}),{restored:!1,previousIme:r,reason:`helper-not-active`};await x(e,[`ime`,`set`,r],{allowFailure:!0,timeoutMs:1e4});let a=await W(e);return a===r?(await Zo(e).catch(()=>{}),C({phase:`android_test_ime_restored`,data:{device:n,previousIme:r}}),{restored:!0,previousIme:r,reason:`ok`}):(C({level:`warn`,phase:`android_test_ime_restore_failed`,data:{device:n,previousIme:r,afterIme:a}}),{restored:!1,previousIme:r,reason:`set-failed`})}async function ls(e){let t=S().imeRecoveryMarkers,n=await t.read(e.stateDir);if(n.length===0)return;let r;try{r=new Set(await e.listSerials())}catch(e){C({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 rs(e.stateDir,a,async()=>{let r=await cs(b(n),n);r.restored&&C({level:`warn`,phase:`android_test_ime_orphan_restored`,data:{device:a,previousIme:r.previousIme}}),ss(r.reason)&&await t.clear(e.stateDir,a)})}catch(e){C({level:`debug`,phase:`android_test_ime_orphan_restore_failed`,data:{device:a,error:i(e).message}})}}}async function us(){S();try{return(await Fe(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 ds=2e3;async function fs(e=S().environment,t=S().files){let n=e.ANDROID_HOME||e.ANDROID_SDK_ROOT,r=await ws(n,t),i=await Nt(`adb`,[`version`]);return i?bs({license:r,sdkRoot:n,versionLine:i}):Cs(n,r)}async function ps(e,t){if(e.platform!==`android`)return[];let n=b(e,t.transportOverrides.androidAdb),r=[];return t.shouldProbeMetro&&r.push(await ys(n,e.id,t.metroPort)),r.push(await ms(n,e)),r}async function ms(e,t){try{let n=await W(e),r=ns(t);return n===await hs()&&!r?await gs(e,t,n):_s(t,n,r)}catch(e){return vs(e)}}async function hs(){try{return(await Lo()).manifest.serviceComponent}catch{return}}async function gs(e,t,n){let r=(await x(e,[`settings`,`get`,`secure`,Yo.previousIme],{allowFailure:!0,timeoutMs:ds})).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 _s(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 vs(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 ys(e,t,n){try{let r=await e([`reverse`,`--list`],{allowFailure:!0,timeoutMs:ds}),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 bs(e){return{id:`toolchain`,status:xs(e),summary:e.versionLine?`Android toolchain: ${e.versionLine}; ${Ss(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 xs(e){return e.versionLine&&e.sdkRoot&&e.license!==`missing`?`pass`:`info`}function Ss(e){return e?`ANDROID_HOME/ANDROID_SDK_ROOT set`:`ANDROID_HOME unset`}function Cs(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 ws(e,t){if(!e)return`unknown`;try{return await t.access(D.join(e,`licenses`,`android-sdk-license`)),`accepted`}catch{return`missing`}}function Ts(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=ks(t),r={failureReason:t.reason??`text_mismatch`,targetInput:Ds(t.targetInput),actualInput:Ds(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 q(e){return e?e.password?!0:Es(e.text):!1}function Es(e){return e?Array.from(e).every(Os):!1}function Ds(e){if(!e)return null;let t=q(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function Os(e){return e===`•`||e===`*`||e===`●`}function ks(e){return e.masked===!0||q(e.targetInput)||q(e.actualInput)}const As=new WeakMap;function js(e,t){return t&&As.set(e,t),e}function Ms(e){return As.get(e)}function Ns(e){return e.clickable}function Ps(e){return e.focusable||e.focused===!0}function J(e){return Ns(e)||Ps(e)}function Fs(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Is(e,t){return{raw:e,...t?{effectiveRect:t}:{}}}function Ls(e,t,n){if(!e)return;let r=Bs(e);return t&&(r=zs(r,t)),n&&(r=zs(r,n)),r}function Rs(e){return{...e.raw,...e.effectiveRect?{rect:e.effectiveRect}:{rect:void 0},hittable:e.raw.hittable===!0&&ie(e.effectiveRect)?!0:void 0}}function zs(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 Bs(e){return{x:e.x,y:e.y,width:Math.max(0,e.width),height:Math.max(0,e.height)}}function Vs(e,t){let n=new Set;return Hs(e,n,t),Ws(e,n,t),n}function Hs(e,t,n){for(let r of e.children){if(n?.check(`work`),r.visibleToUser===!1){t.add(r);continue}Hs(r,t,n)}}function Us(e,t,n){return n?.check(`work`),e.children.filter(e=>!t.has(e)&&e.visibleToUser!==!1)}function Ws(e,t,n){let r=Us(e,t,n).filter(Ks);if(r.length<2)return;let i=r.filter(e=>qs(e)&&Js(e));if(i.length===0)return;let a=Gs(i);for(let r of Us(e,t,n))n?.check(`work`),qs(r)&&(Js(r)&&(a===void 0||r.windowLayer===a)||t.add(r))}function Gs(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Ks(e){return e.windowIndex!==void 0||e.windowType!==void 0}function qs(e){return e.windowType===1}function Js(e){return e.windowActive===!0||e.windowFocused===!0}function Ys(e,t,n,r,i){let a=new Set(e.sourceNodes),o=Zs(t,i),s=Xs(o,n,Qs(o,a,i),i);if(!s)return{nodes:[],sourceNodes:[]};let c=new Set(Zs([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:oe(d.map(t=>e.nodes[t]),u),sourceNodes:d.map(t=>e.sourceNodes[t])}}function Xs(e,t,n,r){for(let i of e)if(r.check(`work`),se(i,t)&&n.has(i))return i;return null}function Zs(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 Qs(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 $s(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=ec(e);return t.interactiveOnly?tc(e,a,n,r,i):a.isStructural||a.isVisual?ic(e,a,r):!0}function ec(e){let t=oc(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!Fs(e.label??``),hasMeaningfulId:r&&!Fs(e.identifier??``),isStructural:sc(t),isVisual:t===`imageview`||t===`imagebutton`}}function tc(e,t,n,r,i){return rc(e)?!1:J(e)||ne(t.type)&&r?!0:nc(t,n,r,i)}function nc(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r&&!t?!1:t||n||r}function rc(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function ic(e,t,n){return J(e)||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function ac(e){if(!e)return!1;let t=oc(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function oc(e){return e?e.toLowerCase():``}function sc(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function cc(e,t,n,r){return{...Is(e,t),...n?{clipsDescendants:!0}:{},...r?{windowRect:r}:{}}}const lc=`ANDROID_SNAPSHOT_PRESENTATION_FAILED`;var Y=class extends Error{code=lc;qualityReasonCode=`presentation-failed`;details;analysis;constructor(e,t,n){super(e),this.name=`AndroidSnapshotPresentationFailure`,this.details=t,this.analysis=n}};function uc(e){return e instanceof Y?e.code===lc:!!(e&&typeof e==`object`&&e.code===lc)}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()+gc()}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 Y(`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 Y(`Android snapshot presentation exceeded its cooperative deadline`,{phase:`deadline`,workUnits:this.workUnits,deadlineAtMs:this.deadlineAtMs,maxWorkUnits:t})}};function fc(e,t){return new dc(e??{},t)}function pc(e,t,n){let r=new Map;for(let i of e){n.check(`regular-invariant`);let e=mc(i,r,t),a=i.effectiveRect;if(!a||!ie(a)){if(Rs(i).hittable===!0)throw new Y(`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&&!hc(a,e))throw new Y(`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 mc(e,t,n){let r=e.raw.parentIndex;return r===void 0?e.windowRect??n:t.get(r)??e.windowRect??n}function hc(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 gc(){return 250}function _c(e,t,n){let r=n.depth??1/0,i=re(n.scope),a=Fc(e),o=fc(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=Oc(e,o),s.hidden=n.raw?new Set:Vs(e,o);for(let t of e.children)if(yc(s,t,0),s.truncated)break;n.raw||pc(s.presentationNodes,s.viewport,o);let t=s.nodes,a=new Map(s.sourceNodes.map((e,t)=>[e,t])),{nodes:c,sourceNodes:l}=i?Ys(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:vc(s.sourceNodes)},analysis:s.analysis};return s.truncated?{...u,truncated:!0}:u}catch(e){throw uc(e)&&(e.analysis??=s.analysis),e}}function vc(e){let t=new Map,n=new Map;for(let[r,i]of e.entries()){let e=Ms(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 yc(e,t,n,r,i=!1,a=!1,o=!1,s,c){if(e.presentationBudget.check(`work`),bc(e,t,n))return;let l=t.windowRect??s??e.viewport,u=xc(e,t,c,l),d=Sc(e,t,r,i,a,o,u,l),f=i||J(t),p=a||ac(t.type),m=Cc(e,t,u,c);wc(e,t,n,d,f,p,o||It(t.identifier),l,m)}function bc(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 xc(e,t,n,r){return e.options.raw?t.rect:Ls(t.rect,r,n)}function Sc(e,t,n,r,i,a,o,s){return!e.options.raw&&!$s(t,e.options,r,jc(e,t),i)?n:Tc(e,t,n,a||It(t.identifier),o,s)}function Cc(e,t,n,r){return e.options.raw||!kc(t)?r:n}function wc(e,t,n,r,i,a,o,s,c){for(let l of t.children)if(yc(e,l,n+1,r,i,a,o,s,c),e.truncated)return}function Tc(e,t,n,r,i,a){let o=e.nodes.length;return e.sourceNodes.push(t),Dc(e,t,Ec(e,t,n,r),i,a),o}function Ec(e,t,n,r){return{index:e.nodes.length,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,contentDescription:t.contentDescription,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,focused:t.focused,selected:t.selected,heading:t.heading,roleDescription:t.roleDescription,checked:t.checked,editable:t.editable,password:t.password,hintShowing:t.hintShowing,placeholder:t.placeholder,selectionStart:t.selectionStart,selectionEnd:t.selectionEnd,visibleToUser:t.visibleToUser,hittable:J(t)||void 0,depth:Ac(e.nodes,n),parentIndex:n,...Mc(t,e.hidden),...r?{systemChrome:!0}:{}}}function Dc(e,t,n,r,i){let a=cc(n,r,!e.options.raw&&kc(t),i);e.presentationNodes.push(a),e.nodes.push(e.options.raw?a.raw:Rs(a))}function Oc(e,t){let n=[],r=[...e.children];for(;r.length>0;){t.check(`work`);let e=r.pop();ie(e.windowRect)&&n.push(e.windowRect),r.push(...e.children)}return ce(n)??void 0}function kc(e){return e.scrollable===!0&&ne(e.type)}function Ac(e,t){return t===void 0?0:(e[t]?.depth??-1)+1}function jc(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&&(J(n)||jc(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function Mc(e,t){return Nc(e,t)?{...e.canScrollBackward?{hiddenContentAbove:!0}:{},...e.canScrollForward?{hiddenContentBelow:!0}:{}}:{}}function Nc(e,t){if(!e.scrollable||!ne(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let n=Pc(e,t);return!(n&&n.horizontal>n.vertical&&n.horizontal>16)}function Pc(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 Fc(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 Ic(){let e=[],t=()=>e.at(-1)===!0;return{open(n,r){let i=t()||It(n);return r||e.push(i),i},close(){e.pop()}}}function*Lc(e){let t=/<node\b[^>]*>|<\/node>/g,n=Ic(),r=t.exec(e);for(;r;){let i=r[0];if(i.startsWith(`</node`))n.close();else{let e=Rc(i);yield n.open(e.resourceId,i.endsWith(`/>`))?{...e,systemChrome:!0}:e}r=t.exec(e)}}function Rc(e){let t=zc(e),n=Lt(t.bounds);return{...t,...n?{rect:n}:{}}}function zc(e){let t=Bc(e),n=e=>Jc(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=Lt(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 Bc(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=Vc(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function Vc(e,t,n){if(t=Uc(e,t,n),t>=n||Wc(e[t]))return;let r=t;t=Hc(e,t,n);let i=e.slice(r,t);if(t=Uc(e,t,n),!i||e[t]!==`=`)return;t=Uc(e,t+1,n);let a=e[t];if(!Gc(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:Rt(e.slice(o,s)),nextCursor:s+1}}function Hc(e,t,n){for(;t<n&&!qc(e[t]??``);)t+=1;return t}function Uc(e,t,n){for(;t<n&&Kc(e[t]??``);)t+=1;return t}function Wc(e){return e===`/`||e===`>`}function Gc(e){return e===`"`||e===`'`}function Kc(e){return e===` `||e===`
|
|
12
|
+
`||e===`\r`||e===` `}function qc(e){return e===`=`||e===`/`||e===`>`||Kc(e)}function Jc(e,t){return e.get(t)??null}function Yc(e){let t={type:null,label:null,value:null,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=Rc(t),o=n.at(-1),s=Xc(a,o.depth+1,o);o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return t}function Xc(e,t,n){let r=e.text||e.desc;return js({type:e.className,label:r,value:e.text,...e.desc&&e.desc!==r?{contentDescription:e.desc}:{},identifier:e.resourceId,packageName:e.packageName,rect:e.rect,enabled:e.enabled,focused:e.focused,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,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 Zc(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 Qc=new Set([`android`,`com.android.systemui`]);function $c(e,t,n={}){if(t.backend!==`android-helper`)return{outcome:`ok`};let r=ul(e,n.foregroundAppPackage);return nl(r,t)?el(r,t,`empty-helper-output`,`Android snapshot helper returned no accessibility nodes`):cl(r)?{outcome:`ok`}:tl(r)?{outcome:`system-surface-only`}:rl(r)?{outcome:`ok`}:il(r)?el(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient foreground app content`):al(r)||ol(r,t)?el(r,t,`content-poor-app-window`,`Android snapshot helper returned insufficient application window content`):sl(r)?el(r,t,`system-window-only`,`Android snapshot helper returned only non-application windows`):{outcome:`ok`}}function el(e,t,n,r){return{outcome:`unusable`,decision:ll(e,t,n,r)}}function tl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0&&e.activeSystemSurfaceMeaningfulNodeCount>=3}function nl(e,t){return e.nodeCount===0||t.nodeCount===0||t.rootPresent===!1}function rl(e){return il(e)&&e.inputMethodMeaningfulNodeCount>=2}function il(e){let t=e.foregroundAppMeaningfulNodeCount;return t===void 0?!1:t===0?e.applicationMeaningfulNodeCount<2:t<2&&e.meaningfulNodeCount>t}function al(e){return e.foregroundAppMeaningfulNodeCount===void 0&&e.applicationWindowRootCount>0&&e.applicationMeaningfulNodeCount<2}function ol(e,t){return e.foregroundAppMeaningfulNodeCount===void 0&&e.windowRootCount===0&&(t.windowCount??0)>1&&e.nonSystemMeaningfulNodeCount<2}function sl(e){return e.windowRootCount>0&&e.applicationWindowRootCount===0||e.windowRootCount===0&&e.nodeCount>0&&e.systemUiNodeCount===e.nodeCount}function cl(e){return e.hasAlertButtonIdentifier&&e.hasAlertContentIdentifier}function ll(e,t,n,r){return{reason:n,failureReason:r,diagnostics:wl(e,t)}}function ul(e,t){let n=dl(t);for(let t of Lc(e))fl(n,t);return yl(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 fl(e,t){e.nodeCount+=1,Cl(t.packageName)&&(e.systemUiNodeCount+=1),t.visibleToUser!==!1&&pl(e,t.resourceId),ml(e,t),hl(e,t)}function pl(e,t){let n=nn(t);n===`button`&&(e.hasAlertButtonIdentifier=!0),n===`content`&&(e.hasAlertContentIdentifier=!0)}function ml(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 hl(e,t){bl(t)&&(e.meaningfulNodeCount+=1,gl(e,t),vl(e,t))}function gl(e,t){e.currentWindowType===1&&!Sl(t.packageName)&&(e.applicationMeaningfulNodeCount+=1),_l(e)&&!Ft(t)&&(e.activeSystemSurfaceMeaningfulNodeCount+=1)}function _l(e){return e.currentWindowType!==void 0&&e.currentWindowType!==1&&e.currentWindowActiveOrFocused===!0}function vl(e,t){Sl(t.packageName)||(e.nonSystemMeaningfulNodeCount+=1),m({packageName:t.packageName,resourceId:t.resourceId})&&(e.inputMethodMeaningfulNodeCount+=1),e.foregroundAppPackage!==void 0&&t.packageName===e.foregroundAppPackage&&(e.foregroundAppMeaningfulNodeCount=(e.foregroundAppMeaningfulNodeCount??0)+1)}function yl(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 bl(e){return e.visibleToUser===!1?!1:xl(e.text)||xl(e.desc)||xl(e.resourceId)}function xl(e){return e!==null&&e.trim()!==``}function Sl(e){return e===null||Qc.has(e)}function Cl(e){return e!==null&&Qc.has(e)}function wl(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 Tl(e){let t=await B(e.deviceKey,{resetRuntime:!0,signal:e.signal,cause:e.cause});e.signal?.throwIfAborted(),t||await El(e.adb,e.packageName)}async function El(e,t){await li({adb:e,packageName:t}),await _(150),g({level:`debug`,phase:`android_snapshot_helper_runtime_reset`,data:{packageName:t}})}const Dl=Symbol(`androidSnapshotCaptureEvidence`);function Ol(e,t){return Object.defineProperty(e,Dl,{value:t}),e}function kl(e){let t={...e,backend:`android`,producer:`android-uiautomator`},n=e[Dl];return te(t,n.clickability),n.occlusionContext&&u(t,n.occlusionContext),t}async function Al(e,t={}){let n=w(e,t.helperAdb).exec;return(await Rl(e,t,n)).xml}async function jl(e,t={}){let n=w(e,t.helperAdb).exec,r=await Rl(e,t,n),i=r.xml,a=Yc(i),o=Pl(r.metadata,a),s={...t,androidPresentation:{...t.androidPresentation,deadlineAtMs:t.androidPresentation?.deadlineAtMs??Date.now()+250}};try{let e=_c(a,void 0,s),n=Nl(e.truncated,r.metadata);t.interactiveOnly&&t.includeHiddenContentHints!==!1&&Ll({options:s,tree:a,xml:i,interactiveSnapshot:e});let{sourceNodes:c,occlusionContext:l,...u}=e;return Ol({...u,...Il(n),androidSnapshot:o,quality:{state:`healthy`,backend:`android-helper`}},{clickability:Zc(e),occlusionContext:l})}catch(e){if(!uc(e))throw e;return Ml({failure:e,androidSnapshot:o})}}function Ml(e){return Ol({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}},{clickability:{kind:`exact`,provider:`android-helper`,clickableByNodeIndex:new Map}})}function Nl(e,t){return e===!0||t.helperTruncated===!0||e}function Pl(e,t){return Fl(t)===!1?{...e,occlusionScanUnavailable:!0}:e}function Fl(e){let t=[...e.children];if(t.length!==0){for(;t.length>0;){let e=t.pop();if(Ms(e)!==void 0)return!0;t.push(...e.children)}return!1}}function Il(e){return e===!0?{truncated:!0}:{}}function Ll(e){if(au(e.interactiveSnapshot.nodes).size>0||iu(e.xml))return;let t=_c(e.tree,void 0,{...e.options,interactiveOnly:!1});ou(Se(o(t.nodes)),t,e.interactiveSnapshot)}async function Rl(e,t,n){let r=w(e,t.helperAdb),i=await h(`android_snapshot_helper_artifact_resolution`,async()=>await nu(t.helperArtifact??r.snapshotHelperArtifact));if(i.artifact)return await zl(e,t,n,i.artifact);throw g({level:`error`,phase:`android_snapshot_helper_unavailable`,data:{reason:i.errorReason??`artifact_not_found`}}),ru(i.errorReason)}async function zl(e,t,n,r){let i=Yr(e),a=w(e,t.helperAdb),o=Bl(t,i);try{let e;for(let o=0;;o+=1){o>0&&await Kl(t.signal);let s=await Gl({options:t,adb:n,adbProvider:a,artifact:r,helperDeviceKey:i,attempt:o,previousContentReason:e});if(s.outcome===`captured`)return s.capture;if(o+1>=3||t.transient!==void 0&&Date.now()>=t.transient.settleBy)return await ql({contentRecovery:s.decision,attempts:o+1,helperDeviceKey:i,artifact:r,adb:n,signal:t.signal,retireHelper:t.transient===void 0});e=s.decision.reason}}finally{o&&await B(i)}}function Bl(e,t){return e.transient?Li(t)===void 0:e.helperSessionScope!==`daemon-session`}function Vl(e){return e.transient?`current-only`:e.helperInstallPolicy??`missing-or-outdated`}async function Hl(e,t,n,r,i){let a=await h(`android_snapshot_helper_install`,async()=>await dr({adb:t,adbProvider:n,artifact:r,deviceKey:i,installPolicy:Vl(e),timeoutMs:3e4,signal:e.signal}),{packageName:r.manifest.packageName,versionCode:r.manifest.versionCode,installPolicy:Vl(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 Ul(e){let{signal:t,adb:n,adbProvider:r,artifact:a,helperDeviceKey:o}=e,s=fi({adb:n,adbProvider:r,artifact:a,deviceKey:o,signal:t});try{let e=await h(`android_snapshot_helper_session_capture`,async()=>await Qi(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Yn});if(e)return e}catch(e){if(t?.throwIfAborted(),$r(e))throw e;g({level:`warn`,phase:`android_snapshot_helper_session_fallback`,data:{reason:i(e).message}}),await El(n,a.manifest.packageName)}return await h(`android_snapshot_helper_capture`,async()=>await di(s),{packageName:a.manifest.packageName,version:a.manifest.version,timeoutMs:Yn,commandTimeoutMs:Xn})}function Wl(e,t,n){return{xml:e.xml,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 Gl(e){let{options:t,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a,attempt:o}=e,s;try{let e=await Hl(t,n,r,i,a);e.installed&&await B(a),s=Wl(await Ul({signal:t.signal,adb:n,adbProvider:r,artifact:i,helperDeviceKey:a}),i,e.reason)}catch(e){if(t.signal?.throwIfAborted(),or(e))throw e;return{outcome:`captured`,capture:await Yl({error:e,helperDeviceKey:a,artifact:i,adb:n})}}let c=$c(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,metadata:l?{...s.metadata,systemSurfaceOnly:!0}:s.metadata}}}async function Kl(e){e?.throwIfAborted(),await _(250),e?.throwIfAborted()}async function ql(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 Tl({adb:e.adb,deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,signal:e.signal,cause:e.contentRecovery.failureReason}),Jl(e.contentRecovery,e.attempts)}function Jl(e,t){return new n(`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 Yl(e){let t=Xl(e.error);throw g({level:`error`,phase:`android_snapshot_helper_failed`,data:{reason:t}}),await B(e.helperDeviceKey),await El(e.adb,e.artifact.manifest.packageName),ir({deviceKey:e.helperDeviceKey,packageName:e.artifact.manifest.packageName,versionCode:e.artifact.manifest.versionCode}),Zl(e.error,t)}function Xl(e){let t=i(e),n=tu(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 Zl(e,t){let r=i(e),o=Ql(r);return new n(a(r.code),`Android snapshot helper failed: ${t}`,{...r.details,...eu(r),androidSnapshotHelperFailureReason:t,...o?{androidCaptureFailureReason:o}:{},hint:$l(r,o)},e)}function Ql(e){return ct(e)}function $l(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 eu(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 tu(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 nu(e){if(e)return{artifact:e};let t=je(),n=D.join(Me(),`android`,`snapshot-helper`,`dist`),r=D.join(n,`agent-device-android-snapshot-helper-${t}.manifest.json`);try{await S().files.access(r)}catch{return{}}try{let e=Zn(JSON.parse(await S().files.readText(r))),t=D.join(n,e.assetName??`agent-device-android-snapshot-helper-${e.version}.apk`);return await S().files.access(t),{artifact:{apkPath:t,manifest:e}}}catch(e){return{errorReason:i(e).message}}}function ru(e){let t=e??`the bundled helper artifact was not found`;return new n(`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 iu(e){return e.includes(` can-scroll-forward=`)||e.includes(` can-scroll-backward=`)}function au(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 ou(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 su=Object.freeze({now:()=>Date.now(),sleep:_});async function cu(e,t,n,r,i={},a=su){let o=await Du(e),s=a.now()+1500,c=null;for(;;){let l=await _u(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 lu(e,t,n,r={}){return mu(await Al(e,r),t,n)}async function uu(e,t,n,r){let i=await Du(e);return vu(await Al(e,r),t,n,i).targetInput}async function du(e,t,n,r={}){try{return await uu(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 X(e,t,r){if(r?.ok)return;let i=r?fu(e,t,r):null;if(i)return i;throw new n(`COMMAND_FAILED`,hu(r),gu(e,r))}function fu(e,t,n){let r=n.targetInput,i=n.actualInput;if(e.length===0||n.reason===`ime_capture`||!t||!r||!i||q(t)||q(r)||q(i)||!Nu(t,r)||!Nu(t,i)||t.text===n.actual)return null;let a=Pu(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 pu(e,t,n,r,i={}){let a=vu(e,t,n,i);return yu(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:bu(a,r)??xu(a,r)}function mu(e,t,n){return vu(e,t,n).targetInput?.text??null}function hu(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 gu(e,t){let n=Ts(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 _u(e,t,n,r,i,a){return pu(await Al(e,a),t,n,r,i)}function vu(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of Lc(e)){let e=Eu(a,r);e&&Ou(i,e,t,n)}return Au(i)}function yu(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||!Mu(n))return null;let r=n.text??null,i=Array.from(Su(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 xu(e,t){let n=e.actualInput;return{ok:n!==null&&Cu(Su(n),t),actual:n?.text??null,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:n}}function Su(e){return e.hintShowing?``:e.text??``}function Cu(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||Tu(n,r))}function wu(e){return e.replaceAll(/\s+/g,` `).trim()}function Tu(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 Eu(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:m({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:ju(e.className??``),hintShowing:e.hintShowing===!0,placeholder:e.hint??null}}async function Du(e){try{return{activeInputMethodPackage:(await ho(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 Ou(e,t,n,r){let i=ae(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=ku(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=ku(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=ku(e.anyAtPoint,t))}function ku(e,t){return e&&e.area<t.area?e:t}function Au(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function ju(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Mu(e){return q(e)}function Nu(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 Pu(e){return{resourceId:e.resourceId,className:e.className,packageName:e.packageName,rect:e.rect}}async function Fu(e,t){return await zt(t.stateDir),await rs(t.stateDir,e.id,async()=>await Lu(e,t))}function Iu(e){let t=r(e).details?.hint;return{outcome:`helper-unavailable`,reason:i(e).message,...typeof t==`string`?{hint:t}:{}}}async function Lu(e,t){let n=S().imeRecoveryMarkers,r=b(e),i=w(e),a=U(e),o;try{o=await Io(i),await Bo({adb:r,adbProvider:i,artifact:o,deviceKey:a})}catch(e){return Iu(e)}let{manifest:s}=o,c=await W(r);if(c===s.serviceComponent){let i=await n.write(t.stateDir,e.id),o=await G(r);return i&&K.add(a),{outcome:`settled`,activated:!1,alreadyActive:!0,...i?{}:{persistFailed:!0},previousIme:o,helperServiceComponent:s.serviceComponent,helperPackageName:s.packageName}}let l=await G(r);if(!await Xo(r,c))return await Qo(r,l,e.id),C({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 Qo(r,l,e.id),C({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 x(r,[`ime`,`enable`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4});let d=await x(r,[`ime`,`set`,s.serviceComponent],{allowFailure:!0,timeoutMs:1e4}),f=await W(r);return f===s.serviceComponent?(K.add(a),C({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}):(K.delete(a),await Qo(r,l,e.id),u||await n.clear(t.stateDir,e.id),C({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 Ru(e){return D.join(e,`android-test-ime-pending`)}function zu(e,t){return D.join(Ru(e),encodeURIComponent(t))}async function Bu(e,t){let n=S().files,r,a=!1;try{let i=Ru(e);if(r=zu(e,t),await n.ensureDirectory(i),(await Uu(r))?.serial===t)return!0;let o={version:1,serial:t};if(await n.writeAtomicText(r,`${JSON.stringify(o)}\n`,384),a=!0,(await Uu(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 Vu(e,t){await S().files.remove(zu(e,t),{force:!0}).catch(()=>{})}async function Hu(e){let t=S().files,n;try{n=await t.readDirectory(Ru(e))}catch{return[]}let r=[];for(let t of n)try{let n=D.join(Ru(e),t),i=await Uu(n);i&&zu(e,i.serial)===n&&r.push(i.serial)}catch{}return[...new Set(r)].sort()}async function Uu(e){try{return Wu(await S().files.readText(e))}catch{return}}function Wu(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 Gu=new Ht(`utf-16le`);let Ku;async function qu(e,t){for(let n of[`AndroidManifest.xml`,`base/manifest/AndroidManifest.xml`]){let r=await Ju(e,n,t);if(!r)continue;let i=Yu(r);if(i)return i}return await id(e,t)}async function Ju(e,t,n){try{let r=await Te(`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 Yu(e){return e.subarray(0,Math.min(e.length,128)).toString(`utf8`).trimStart().startsWith(`<`)?Xu(e.toString(`utf8`)):Zu(e)}function Xu(e){return e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i)?.[1]}function Zu(e){if(e.length<8||e.readUInt16LE(0)!==3)return;let t;for(let n=e.readUInt16LE(2);n+8<=e.length;){let r=e.readUInt16LE(n),i=e.readUInt16LE(n+2),a=e.readUInt32LE(n+4);if(a<=0||n+a>e.length)return;if(r===1)t=$u(e.subarray(n,n+a));else if(r===258&&t){let r=Qu(e,n,i,t);if(r)return r}n+=a}}function Qu(e,t,n,r){if(n<36||t+n>e.length||r[e.readUInt32LE(t+20)]!==`manifest`)return;let i=e.readUInt16LE(t+24),a=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let n=s+t*a;if(n+20>e.length)return;if(r[e.readUInt32LE(n+4)]!==`package`)continue;let i=e.readUInt32LE(n+8);if(i!==4294967295)return r[i];let o=e.readUInt8(n+15),c=e.readUInt32LE(n+16);return o===3?r[c]:void 0}}function $u(e){if(e.length<28)return[];let t=e.readUInt32LE(8),n=e.readUInt32LE(16),r=e.readUInt32LE(20),i=!!(n&256),a=[];for(let n=0;n<t;n+=1){let t=28+n*4;if(t+4>e.length)return a;let o=r+e.readUInt32LE(t);a.push(i?ed(e,o):td(e,o))}return a}function ed(e,t){let[,n]=nd(e,t),[r,i]=nd(e,t+n),a=t+n+i;return e.subarray(a,a+r).toString(`utf8`)}function td(e,t){let[n,r]=rd(e,t),i=t+r;return Gu.decode(e.subarray(i,i+n*2))}function nd(e,t){let n=e.readUInt8(t);if(!(n&128))return[n,1];let r=e.readUInt8(t+1);return[(n&127)<<8|r,2]}function rd(e,t){let n=e.readUInt16LE(t);if(!(n&32768))return[n,2];let r=e.readUInt16LE(t+2);return[(n&32767)<<16|r,4]}async function id(e,t){t?.throwIfAborted();let n=await ad();if(!n)return;let r=await Te(n,[`dump`,`badging`,e],{allowFailure:!0,signal:t});if(r.exitCode===0)return r.stdout.match(/package:\s+name='([^']+)'/)?.[1]}async function ad(){if(Ku!==void 0)return Ku??void 0;try{let e=S().files;for(let t of _t()){let n=D.join(t,`build-tools`);try{let t=(await e.readDirectory(n)).sort((e,t)=>t.localeCompare(e,void 0,{numeric:!0}));for(let r of t){let t=D.join(n,r,`aapt`);if(D.isAbsolute(t)&&await e.isExecutable(t))return Ku=t,t}}catch{}}}catch{}Ku=null}async function od(e,t){let n=e.kind===`url`&&Ne(e.url),r=await Pe({source:e,isInstallablePath:(e,t)=>t.isFile()&&sd(e),installableLabel:`Android installable (.apk or .aab)`,allowArchiveExtraction:e.kind!==`url`||n,signal:t?.signal});try{let e=t?.resolveIdentity===!1?{}:await cd(r.installablePath,t?.signal);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:e.packageName,cleanup:r.cleanup}}catch(e){throw await r.cleanup(),e}}function sd(e){let t=D.extname(e).toLowerCase();return t===`.apk`||t===`.aab`}async function cd(e,t){let n=D.extname(e).toLowerCase();return n!==`.apk`&&n!==`.aab`?{}:{packageName:await qu(e,t)}}async function ld(e,t,r,i={}){let a=typeof r.action==`string`&&r.action.trim()?r.action.trim():`${t}.TEST_PUSH`,o=[`am`,`broadcast`,`-a`,a,`-p`,t],s=typeof r.receiver==`string`?r.receiver.trim():``;s&&o.push(`-n`,s);let c=r.extras;if(c!==void 0&&(typeof c!=`object`||!c||Array.isArray(c)))throw new n(`INVALID_ARGS`,`Android push payload extras must be an object`);let l=c??{},u=0;for(let[e,t]of Object.entries(l))e&&(ud(o,e,t),u+=1);return await E(e,o,{signal:i.signal}),{action:a,extrasCount:u}}function ud(e,t,r){if(typeof r==`string`){e.push(`--es`,t,r);return}if(typeof r==`boolean`){e.push(`--ez`,t,r?`true`:`false`);return}if(typeof r==`number`&&Number.isFinite(r)){if(Number.isInteger(r)){e.push(`--ei`,t,String(r));return}e.push(`--ef`,t,String(r));return}throw new n(`INVALID_ARGS`,`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}function Z(e){let t=e.replaceAll(`,`,``).match(/^-?\d+(?:\.\d+)?/);if(!t)return null;let n=Number(t[0]);return Number.isFinite(n)?n:null}function dd(e){let t=gd(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 _d(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 pd(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=>hd({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 md(e){return Math.round(e*10)/10}function hd(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:md(Math.max(...t.map(e=>e.durationNs))/1e6)}}function gd(e){return[...new Set(e.filter(e=>Number.isFinite(e)))].sort((e,t)=>e-t)}function _d(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){yd(e,t);let r=kd(e),i=Td(e),a=xd(i,r,t),o=Date.parse(n),s=jd({frames:i,measuredAtMs:o,summary:r}),c=fd({frames:i,frameDeadlineNs:a,summaryDroppedFrameCount:r?.droppedFrameCount}),l=r?.sampleWindowMs??s.sampleWindowMs??Fd(i),u=Sd(r,i,c),d=wd({droppedFrames:c,timing:s,measuredAtMs:o,summary:r});return{...u,sampleWindowMs:l,...Cd(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 yd(e,t){if(/no process found for:/i.test(e))throw new n(`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 bd(e){throw new n(`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 xd(e,t,r){let i=dd(e);if(!t&&e.length===0&&bd(r),t||i!==void 0)return i;throw new n(`COMMAND_FAILED`,`Failed to infer Android frame deadline from framestats output for ${r}`,{metric:`fps`,package:r,hint:`Retry perf after a longer interaction window so consecutive Android frame timestamps are available.`})}function Sd(e,t,n){let r=e?.totalFrameCount??t.length,i=e?.droppedFrameCount??n.length;return{totalFrameCount:r,droppedFrameCount:i,droppedFramePercent:e?.droppedFramePercent??(r>0?Bt(i/r*100):0)}}function Cd(e){return{frameDeadlineMs:e===void 0?void 0:md(e/1e6),refreshRateHz:e===void 0?void 0:md(1e9/e)}}function wd(e){let{droppedFrames:t,timing:n,measuredAtMs:r,summary:i}=e;if(t.length===0)return;let a=pd({frames:t,windowStartNs:n.windowStartNs,measuredAtMs:r,uptimeMs:i?.uptimeMs});return a.length>0?a:void 0}function Td(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(Ed(i)){n=new Map(i.map((e,t)=>[e,t]));continue}let a=Dd(i,n);a&&t.push(a)}return t.sort((e,t)=>e.intendedVsyncNs-t.intendedVsyncNs)}function Ed(e){return e.includes(`IntendedVsync`)&&e.includes(`FrameCompleted`)}function Dd(e,t){if(!t||e.length<t.size)return;let n=Od(e,t,`Flags`),r=Od(e,t,`IntendedVsync`),i=Od(e,t,`FrameCompleted`);if(!(n!==0||r===null||i===null||r<=0||i<=r))return{intendedVsyncNs:r,frameCompletedNs:i,durationNs:i-r}}function Od(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 kd(e){let t=e.split(/\nProfile data in ms:\n/i)[0]??``,n=Id(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=Z(i)??void 0,s=Number(a);if(o===void 0||!Number.isFinite(s)||n<0)return;let c=Id(t,`Uptime`),l=Id(t,`Stats since`);return{droppedFramePercent:Bt(s),droppedFrameCount:o,totalFrameCount:n,sampleWindowMs:Ad({uptimeMs:c,statsSinceNs:l}),uptimeMs:c,statsSinceNs:l}}function Ad(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 jd(e){let{frames:t,measuredAtMs:n,summary:r}=e,i=Md(t),a=r?.statsSinceNs,o=a??i.firstFrameNs,s=Nd(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:Pd({deviceBootWallClockMs:l,measuredAtMs:n,summaryStartNs:a,lastFrameNs:i.lastFrameNs}),timestampSource:`estimated-from-device-uptime`}}function Md(e){return e.length===0?{}:{firstFrameNs:Math.min(...e.map(e=>e.intendedVsyncNs)),lastFrameNs:Math.max(...e.map(e=>e.frameCompletedNs))}}function Nd(e,t){if(e!==void 0&&t!==void 0)return Math.max(0,Math.round((t-e)/1e6))}function Pd(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 Fd(e){if(e.length===0)return;let t=Md(e);return Nd(t.firstFrameNs,t.lastFrameNs)}function Id(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:Z(i)??void 0}async function Ld(e,t,n={}){let r=b(e,n.adb);try{let i=vd((await x(r,[`dumpsys`,`gfxinfo`,t,`framestats`],{timeoutMs:15e3})).stdout,t,new Date().toISOString());return await Rd(e,t,n),i}catch(e){throw zd(t,e)}}async function Rd(e,t,n={}){let r=b(e,n.adb);try{await x(r,[`dumpsys`,`gfxinfo`,t,`reset`],{allowFailure:!0,timeoutMs:3e3})}catch{}}function zd(e,t){return t instanceof n?new n(t.code,t.message,{...t.details??{},metric:`fps`,package:e},t):new n(`COMMAND_FAILED`,`Failed to sample Android fps for ${e}`,{metric:`fps`,package:e},t)}async function Bd(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 Vd(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 Vd(e,t,n){try{let r=await Ld(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 Hd(e,t,n){let r=b(e,n.adb);await Jd(r,t),await Zd(r,t),await Xd(r,t,n.files);let i=await qd(t.outPath,n.files);await Gd(r,t.remotePath);let a=Date.now(),o=Math.max(0,a-t.startedAt),s=await Bd(e,t,i,o,{adb:r});return{...t,action:`stop`,platform:`android`,state:`stopped`,stoppedAt:a,durationMs:o,sizeBytes:i,method:t.kind===`simpleperf`?Br:Vr,artifact:{path:t.outPath,sizeBytes:i},summary:s,message:`Stopped Android ${t.kind} ${t.type} for ${t.packageName}`}}async function Ud(e,t,n={}){let r=b(e,n.adb);try{t.state===`running`&&(await Jd(r,t),await Zd(r,t).catch(()=>{}))}finally{await Gd(r,t.remotePath)}}function Wd(e,t,n=Ur){return`${n}/agent-device-${e.replaceAll(/[^A-Za-z0-9_.-]/g,`_`)}-${Date.now()}-${t}`}async function Gd(e,t){try{await x(e,[`rm`,`-f`,t],{allowFailure:!0,timeoutMs:Hr})}catch{}}async function Kd(e,t,n=S().files){await n.ensureDirectory(D.dirname(e)),await n.writeBytes(e,Buffer.from(`${JSON.stringify(t,null,2)}\n`))}async function qd(e,t=S().files){try{return(await t.stat(e)).size}catch(t){throw new n(`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 Jd(e,t){try{await x(e,[v(Yd(t.profilerPid))],{timeoutMs:P})}catch(e){throw N(`stop`,t.kind,t.packageName,e)}}function Yd(e){return[`pid=${y(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 Xd(e,t,r){await(r??S().files).ensureDirectory(D.dirname(t.outPath));try{await e([`pull`,t.remotePath,t.outPath],{timeoutMs:P})}catch(e){throw new n(`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 Zd(e,t){let r;for(let n=0;n<12;n+=1){let n=await Qd(e,t.remotePath);if(n!==void 0&&n>0&&n===r)return;r=n,await _(250)}throw new n(`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 Qd(e,t){let n=y(t),r=await x(e,[v(`if [ -f ${n} ]; then stat -c %s ${n} 2>/dev/null || wc -c < ${n}; fi`)],{allowFailure:!0,timeoutMs:Hr});if(r.exitCode!==0)return;let i=Number(r.stdout.trim().split(/\s+/)[0]);return Number.isFinite(i)?i:void 0}async function $d(e,t,n,r={}){let i=b(e,r.adb),a=await Wr(i,t);await Gr(i,`perfetto`,t);let o=Wd(t,`app.perfetto-trace`,`/data/misc/perfetto-traces`),s;try{await Rd(e,t,{adb:i}),s=await tf(i,o,t)}catch(e){throw await Gd(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:Vr,message:`Started Android Perfetto trace for ${t}`}}async function ef(e,t,n,r={}){return await Hd(e,{...t,outPath:n},r)}async function tf(e,t,r){try{let i=Kr((await x(e,[`perfetto`,`--background-wait`,`-o`,t,`-t`,`3600s`,`sched`,`freq`,`idle`,`am`,`wm`,`gfx`,`view`,`binder_driver`,`hal`,`dalvik`],{timeoutMs:P})).stdout);if(i)return i;throw new n(`COMMAND_FAILED`,`Android perfetto did not return a profiler pid`,{package:r,tool:`perfetto`,hint:`Retry perf trace start. If perfetto exits immediately, verify the device permits trace capture.`})}catch(e){throw N(`start`,`perfetto`,r,e)}}function nf(e){let t=[];for(let n of c(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:Bt(r),command:a[0],dso:a[1],symbol:a.slice(2).join(` `)||void 0}),t.length>=50)break}return t}async function rf(e,t,n,r={}){let i=b(e,r.adb),a=await Wr(i,t);await Gr(i,`simpleperf`,t);let o=Wd(t,`cpu.perf.data`),s;try{s=await sf(i,a,o,t)}catch(e){throw await Gd(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:Br,message:`Started Android Simpleperf CPU profile for ${t}`}}async function af(e,t,n,r={}){return await Hd(e,{...t,outPath:n},r)}async function of(e,t,n,r={}){let i=b(e,r.adb);await Gr(i,`simpleperf`,t.packageName);let a=await uf(i,t),o=new Date().toISOString(),s=nf(a.stdout),c=s.slice(0,10).map(e=>({symbol:e.symbol??`<unknown>`,binary:e.dso,selfSamplePercent:e.percentage}));await Kd(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 qd(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:Br,message:`Wrote Android Simpleperf report for ${t.packageName}`}}async function sf(e,t,r,i){try{let a=Kr((await x(e,[v(cf(t,r))],{timeoutMs:P})).stdout);if(a)return a;throw new n(`COMMAND_FAILED`,`Android simpleperf did not return a profiler pid`,{package:i,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`,i,e)}}function cf(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(y).join(` `),r=`${Ur}/agent-device-${t}-${Date.now()}.err`;return[`err=${y(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 uf(e,t){try{return await x(e,[`simpleperf`,`report`,`-i`,t.remotePath,`--stdio`,`--sort`,`comm,dso,symbol`],{timeoutMs:P})}catch(e){throw N(`report`,`simpleperf`,t.packageName,e)}}const df=15e3,ff=12e4;async function pf(e,t,n={}){let r=b(e,n.adb);try{return _f((await x(r,[`dumpsys`,`meminfo`,t],{timeoutMs:df})).stdout,t,new Date().toISOString())}catch(e){throw Tf(`memory`,t,e)}}async function mf(e,t,r,i={}){let a=b(e,i.adb),o=i.files??S().files,s=await vf(a,t),c=yf(t);await o.ensureDirectory(D.dirname(r));let l=await hf(o,r);try{we(await x(a,[`am`,`dumpheap`,t,c],{allowFailure:!0,timeoutMs:ff}),`Failed to capture Android heap dump for ${t}`,e=>({kind:`android-hprof`,package:t,pid:s,remotePath:c,hint:bf(e.stdout,e.stderr)}));let e=await a([`pull`,c,r],{allowFailure:!0,timeoutMs:ff});if(e.exitCode!==0)throw await gf(o,r,l),T(`Failed to pull Android heap dump for ${t}`,e,{kind:`android-hprof`,package:t,pid:s,remotePath:c,path:r,hint:`Verify the daemon can write the requested --out path and retry. The heap dump stays on-device only until cleanup runs.`});let i=await o.stat(r).catch(()=>null);if(!i?.isFile||i.size<=0)throw await gf(o,r,l),new n(`COMMAND_FAILED`,`Android heap dump artifact is missing or empty`,{kind:`android-hprof`,package:t,pid:s,path:r,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:r,sizeBytes:i.size,measuredAt:new Date().toISOString(),method:`adb-shell-am-dumpheap`,packageName:t,pid:s,remotePath:c}}finally{await x(a,[`rm`,`-f`,c],{allowFailure:!0,timeoutMs:df}).catch(()=>{})}}async function hf(e,t){return await e.stat(t).then(e=>e.isFile).catch(()=>!1)}async function gf(e,t,n){n||await e.remove(t,{force:!0}).catch(()=>{})}function _f(e,t,r){if(/no process found for:/i.test(e))throw new n(`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 i=Ef(e,`TOTAL PSS`)??Df(e);if(i===void 0)throw new n(`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:i,totalRssKb:Ef(e,`TOTAL RSS`),measuredAt:r,method:`adb-shell-dumpsys-meminfo`,topConsumers:xf(e)}}async function vf(e,t){let r=await x(e,[`pidof`,t],{allowFailure:!0,timeoutMs:df}),i=r.stdout.trim().split(/\s+/).map(Number).find(e=>Number.isInteger(e)&&e>0);if(r.exitCode===0&&i!==void 0)return i;throw new n(`COMMAND_FAILED`,`No running Android process found for ${t}`,{kind:`android-hprof`,package:t,stdout:r.stdout,stderr:r.stderr,hint:`Run open <app> for this session again to ensure the Android app is active, then retry perf memory snapshot.`})}function yf(e){return`/data/local/tmp/agent-device-${e.replaceAll(/[^a-zA-Z0-9._-]/g,`_`)}-${Date.now()}.hprof`}function bf(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 xf(e){let t=e.split(`
|
|
14
|
+
`).flatMap(e=>Sf(e)??[]).sort((e,t)=>t.pssKb-e.pssKb).slice(0,5);return t.length>0?t:void 0}function Sf(e){let t=e.trim();if(Cf(t))return;let n=t.match(/^(.+?)\s+([0-9][0-9,]*(?:\(\d+\))?)(?:\s|$)/);if(n)return wf(n[1],n[2])}function Cf(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 wf(e,t){let n=e?.trim(),r=t?Z(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 Tf(e,t,r){return r instanceof n?new n(r.code,r.message,{...r.details??{},metric:e,package:t},r):new n(`COMMAND_FAILED`,`Failed to sample Android ${e} for ${t}`,{metric:e,package:t},r)}function Ef(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:Z(i)??void 0}function Df(e){for(let t of e.split(`
|
|
15
15
|
`)){let e=t.trim();if(!/^TOTAL\b(?!\s+PSS:)/.test(e))continue;let n=e.split(/\s+/).slice(1).find(e=>Z(e)!==null);return n?Z(n)??void 0:void 0}}async function Of(e,t,n){let r=await E(e,[`dumpsys`,`package`,t],{allowFailure:!0});return r.exitCode===0?Rf(r.stdout,n):{requested:void 0,grants:void 0}}async function kf(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 Af=/^\s*User (\d+):/,jf=/^\s*runtime permissions:\s*$/,Mf=/^\s*([\w.]+): granted=(true|false)\b/,Nf=/^\s*Package \[.+?\]/,Pf=/^\s*requested permissions:\s*$/,Ff=/^\s*([A-Za-z][\w.]*)/;function If(e){return e.split(`
|
|
16
|
-
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function Lf(e,t){let n=Q(Q(Q(If(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>Af.exec(e.text)?.[1]===String(t)),e=>jf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=Mf.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 Rf(e,t){return{requested:zf(e),grants:Lf(e,t)}}function zf(e){let t=Q(Q(Q(If(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>Nf.test(e.text)),e=>Pf.test(e.text));if(!t)return;let n=[];for(let{text:e}of t){let t=Ff.exec(e)?.[1];t&&t.includes(`.`)&&!n.includes(t)&&n.push(t)}return n}function Bf(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 Vf=[`all`,`camera`,`microphone`,`photos`,`contacts`,`notifications`,`calendar`,`location`,`media-library`],Hf={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 Uf(e){let
|
|
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 ip(e,t,n,r,i){if(n.kind===`notifications`)await pp(e,t,`grant`,n,i);else if(n.kind===`photos`)await fp(e,t,`grant`,i);else if(n.kind===`pm`)for(let a of await sp(e,t,n.values,r))await E(e,[`pm`,`grant`,...i,t,a]);else if(n.kind===`all`)throw Error(`Unhandled Android permission target: all is resolved by the caller.`);else throw Error(`Unhandled Android permission target: ${JSON.stringify(n)}`)}async function ap(e,t,n,r,i){if(r.kind===`notifications`)return await pp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await fp(e,t,`revoke`,i);return n===`reset`&&await mp(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 op(e,n){let r=ye(e);if(n?.trim())throw new t(`INVALID_ARGS`,`Android does not support permission modes. Received: ${n}.`);if(r===`all`)return{kind:`all`};if(r===`photos`)return{kind:`photos`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let i=r in Hf?Hf[r]:void 0;if(i)return{kind:`pm`,values:i};throw new t(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${Vf.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function sp(e,t,n,r){let{requested:i}=await Of(e,t,r);return cp(i,n,t)}function cp(e,n,r){if(e===void 0)return n;let i=n.filter(t=>e.includes(t));if(i.length===0)throw new t(`COMMAND_FAILED`,`Package ${r} has not requested permission ${n.join(`, `)}, so no permission was changed.`,{appPackage:r,permission:n.join(`,`)});return i}async function lp(e,t,n,r,i,a){let{requested:o,grants:s}=await Of(e,t,i),c=cp(o,r.values,t);await up(e,t,c,n,a);let{priorGrantState:l,warnings:u}=dp(t,c,c.map(e=>s?.get(e)??`unknown`));return{permission:[...c].join(`,`),priorGrantState:l,...u.length>0?{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 mp(e,t,r,i)}function dp(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=Bf(e,t,n[r]);return i?[i]:[]})}}async function fp(e,n,r,i){let a=await hp(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let t of o){let a=await E(e,[`pm`,r,...i,n,t],{allowFailure:!0});if(a.exitCode===0)return t;s.push({permission:t,stderr:a.stderr,exitCode:a.exitCode})}throw new t(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:n,sdkInt:a,attempts:s})}async function pp(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 mp(e,t,r.permission,i)),await E(e,[`appops`,`set`,...i,t,r.appOps,a])}async function mp(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 gp=[`cmd`,`connectivity`,`airplane-mode`];async function _p(e,n){let r=n?`enabled`:`disabled`;await vp(e),await E(e,[...gp,n?`enable`:`disable`]);let i=await yp(e);if(i!==r)throw new t(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function vp(e){let{state:n,result:r}=await bp(e);if(!n)throw r.exitCode!==0&&it(r.stdout,r.stderr)?new t(`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:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):T(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function yp(e){let{state:t,result:n}=await bp(e);if(t)return t;throw T(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function bp(e){let t=await E(e,[...gp],{allowFailure:!0});return{state:t.exitCode===0?xp(t.stdout):void 0,result:t}}function xp(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Sp=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`],Cp={"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`},wp=Cp.large;async function Tp(e,n,r,i,a){switch(n.toLowerCase()){case`wifi`:{let t=be(r);await E(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await _p(e,be(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new t(`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:n,longitude:r}=xe(a);return await rt(e,[`emu`,`geo`,`fix`,String(r),String(n)]),{latitude:n,longitude:r}}let n=be(r)?`3`:`0`;await E(e,[`settings`,`put`,`secure`,`location_mode`,n]);return}case`animations`:{let t=be(r)?`1`:`0`;for(let n of Sp)await E(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Sp]}}case`appearance`:{let t=await Fp(e,r);await E(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await St(e,i);if(n.type===`intent`)throw new t(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await E(e,[`am`,`force-stop`,n.value],{allowFailure:!0});let a=await E(e,[`pm`,`clear`,n.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new t(`COMMAND_FAILED`,`Failed to clear Android app data for ${n.value}`,{package:n.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:n.value,cleared:!0}}case`fingerprint`:await Mp(e,jp(r));return;case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);return await Wf(e,i,r,a);case`text-size`:return await Op(e,r);default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}const Ep={"text-size":kp};async function Dp(e,t){return await Ep[t](e)}async function Op(e,t){let n=ge(t),r=Cp[n];return await E(e,[`settings`,`put`,`system`,`font_scale`,r]),me(n,r)}async function kp(e){let n=(await E(e,[`settings`,`get`,`system`,`font_scale`])).stdout.trim(),r=n===`null`?wp:n,i=/^(\d+(\.\d+)?)$/.test(r)?Number(r):NaN;if(!Number.isFinite(i)||i<=0)throw new t(`COMMAND_FAILED`,`Android reported an unusable font scale: ${n||`(empty)`}`,{deviceId:e.id,fontScale:n,hint:"Run `adb shell settings get system font_scale` to see what the device holds."});return me(Ap(i),r)}function Ap(e){let t=ve[0],n=1/0;for(let r of ve){let i=Math.abs(Number.parseFloat(Cp[r])-e);i>=n||(t=r,n=i)}return t}function jp(e){let n=e.trim().toLowerCase();if(n===`match`)return`match`;if(n===`nonmatch`)return`nonmatch`;throw new t(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function Mp(e,n){let i=Np(e,n),a=[];for(let t of i){let n=await rt(e,t,{allowFailure:!0});if(n.exitCode===0)return;a.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let o=r(a);throw a.length>0&&a.every(e=>Pp(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:n,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:o}):new t(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:n,attempts:o})}function Np(e,t){let n=t===`match`?`1`:`9999`,r=[Ae(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),Ae(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function Pp(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 Fp(e,n){let r=_e(n);if(r!==`toggle`)return r;let i=await E(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw T(`Failed to read current Android appearance`,i);let a=Ip(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function Ip(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 Lp=Buffer.from([137,80,78,71,13,10,26,10]);async function Rp(e,t,n={}){if(n.stabilize===!1){await Vp(e,t);return}await zp(e);try{await _(1e3),await Vp(e,t)}finally{await Bp(e).catch(()=>{})}}async function zp(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 Bp(e){await E(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function Vp(e,n){let r=await nt(e,[`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new t(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Lp);if(i<0)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=Hp(r.stdoutBuffer,i);if(!a)throw new t(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await S().files.writeBytes(n,r.stdoutBuffer.subarray(i,a))}function Hp(e,t){let n=t+Lp.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 Up(e,t,n=0){let r=Ue(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await Jp(e,`type`,t);if(i.backend===`test-ime`){await Yp(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await Zp(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Zp(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Wp(e,t,n,r,i=0,a={}){let o=await du(e,t,n,a),s=Ue(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),X(r,o,await cu(e,t,n,r,a));let c=null;for(let s of Gp(i)){await Ia(e,t,n);let i=await Jp(e,`fill`,r);if(i.backend===`test-ime`)return X(r,o,await Xp(e,i.packageName,t,n,r,o,a));let l=await Kp(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return X(r,o,l);let u=fu(r,o,l);if(u)return u}return X(r,o,c)}function Gp(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 Kp(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await $p(e,qp(a,o,s)),await Zp(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),cu(e,r,i,a,n)}function qp(e,t,n){let r=Array.from(e).length;return cm(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function Jp(e,t,n){if(ns(e))return{backend:`test-ime`,packageName:(await Io(w(e))).manifest.packageName};let r=await em(e,t),i=r?.inputMethodPackage;return Ho(i)?{backend:`test-ime`,packageName:i}:(nm(n),tm(r,t),{backend:`adb-shell`})}async function Yp(e,t,n,r){let i=b(e),a=n.split(`
|
|
18
|
-
`);for(let[n,o]of a.entries()){let s=r>0?
|
|
19
|
-
`);for(let[r,i]of n.entries()){let a=
|
|
20
|
-
`&&(e<32||e>126))return!1}return!0}function
|
|
16
|
+
`).filter(e=>e.trim().length>0).map(e=>({text:e,indent:e.length-e.trimStart().length}))}function Lf(e,t){let n=Q(Q(Q(If(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>Af.exec(e.text)?.[1]===String(t)),e=>jf.test(e.text));if(!n)return;let r=new Map;for(let{text:e}of n){let t=Mf.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 Rf(e,t){return{requested:zf(e),grants:Lf(e,t)}}function zf(e){let t=Q(Q(Q(If(e),e=>e.indent===0&&e.text.trim()===`Packages:`),e=>Nf.test(e.text)),e=>Pf.test(e.text));if(!t)return;let n=[];for(let{text:e}of t){let t=Ff.exec(e)?.[1];t&&t.includes(`.`)&&!n.includes(t)&&n.push(t)}return n}function Bf(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 Vf=[`all`,`camera`,`microphone`,`photos`,`contacts`,`notifications`,`calendar`,`location`,`media-library`],Hf={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 Uf(e){let t=await kf(e);if(t!==void 0)return t;throw new n(`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 Wf(e,t,n,r){let i=ve(n),a=dp(r?.permissionTarget,r?.permissionMode),o=await Uf(e),s=[`--user`,String(o)];if(a.kind===`all`)return await qf(e,t,i,o,s);if(i===`grant`){let n=await lp(e,t,a,o,s);return Kf(Gf(a),n)}if(a.kind===`pm`)return await mp(e,t,i,a,o,s);let{grants:c}=await Of(e,t,o),l=await up(e,t,i,a,s),{priorGrantState:u,warnings:d}=gp(t,l,l.map(e=>c?.get(e)??`unknown`));return Kf(a.kind,l,{priorGrantState:u,warnings:d})}function Gf(e){return e.kind===`pm`?e.name:e.kind}function Kf(e,t,n){return{permission:e,permissions:[...t],...n?{priorGrantState:n.priorGrantState,...n.warnings.length>0?{warnings:n.warnings}:{}}:{}}}async function qf(e,t,r,i,a){let{requested:o,grants:s}=await Of(e,t,i);if(o===void 0)throw new n(`COMMAND_FAILED`,`Could not read declared permissions for ${t}, so no permission was changed.`,{appPackage:t});let c=r===`grant`?void 0:s,l=[],u=[];for(let n of ep(o))await Jf({device:e,appPackage:t,action:r,userArgs:a,grants:c,applied:l,warnings:u},n);return{permission:`all`,permissions:l,...u.length>0?{warnings:u}:{}}}async function Jf(e,t){return t.kind===`notification`?await Yf(e):t.kind===`photos`?await Xf(e):await Zf(e,t.value)}async function Yf(e){let{device:t,appPackage:n,action:r,userArgs:i}=e;await vp(t,n,r,{appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`},i),Qf(e,`android.permission.POST_NOTIFICATIONS`)}async function Xf(e){let{device:t,appPackage:n,action:r,userArgs:i,warnings:a}=e,o=await ap(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 $f(e,o)}async function Zf(e,t){let{device:n,appPackage:r,action:i,userArgs:a,warnings:o}=e,s=await ip(n,i===`grant`?`grant`:`revoke`,a,r,t);if(s.kind===`skipped`){o.push(`Skipped ${t} for ${r}: ${s.detail}`);return}await $f(e,t)}function Qf(e,t){let{appPackage:n,action:r,grants:i,applied:a,warnings:o}=e;a.push(t),r!==`grant`&&tp(o,i,n,t)}async function $f(e,t){Qf(e,t),e.action===`reset`&&await yp(e.device,e.appPackage,t,e.userArgs)}function ep(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 tp(e,t,n,r){let i=Bf(n,r,t?.get(r)??`unknown`);i&&e.push(i)}const np=[[/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 rp(e){let t=e.toLowerCase();return np.find(([e])=>e.test(t))?.[1]}async function ip(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=rp(a.stderr);if(o)return{kind:`skipped`,reason:o,detail:cp(a.stderr)};throw T(`Failed to ${t} Android permission ${i} for ${r}`,a,{appPackage:r,permission:i})}async function ap(e,t,n,r){try{return await _p(e,t,n,r)}catch(e){if(op(e))return;throw e}}function op(e){if(!(e instanceof n)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.attempts;return sp(t)&&t.length>0&&t.every(e=>e.reason!==void 0)}function sp(e){return Array.isArray(e)&&e.every(e=>typeof e==`object`&&!!e&&typeof e.permission==`string`&&typeof e.detail==`string`)}function cp(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 lp(e,t,n,r,i){if(n.kind===`notifications`)return await vp(e,t,`grant`,n,i),[n.permission];if(n.kind===`photos`)return[await _p(e,t,`grant`,i)];if(n.kind===`pm`){let a=[...await fp(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 up(e,t,n,r,i){if(r.kind===`notifications`)return await vp(e,t,n,r,i),[r.permission];if(r.kind===`photos`){let r=await _p(e,t,`revoke`,i);return n===`reset`&&await yp(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 dp(e,t){let r=be(e);if(t?.trim())throw new n(`INVALID_ARGS`,`Android does not support permission modes. Received: ${t}.`);if(r===`all`)return{kind:`all`};if(r===`photos`)return{kind:`photos`};if(r===`notifications`)return{kind:`notifications`,appOps:`POST_NOTIFICATION`,permission:`android.permission.POST_NOTIFICATIONS`};let i=r in Hf?Hf[r]:void 0;if(i)return{kind:`pm`,name:r,values:i};throw new n(`INVALID_ARGS`,`Unsupported permission target on Android: ${e}. Use ${Vf.join(`|`)}.`,{hint:`Android custom permission ids are attempted through all, not individually.`})}async function fp(e,t,n,r){let{requested:i}=await Of(e,t,r);return pp(i,n,t)}function pp(e,t,r){if(e===void 0)return t;let i=t.filter(t=>e.includes(t));if(i.length===0)throw new n(`COMMAND_FAILED`,`Package ${r} has not requested permission ${t.join(`, `)}, so no permission was changed.`,{appPackage:r,permissions:t});return i}async function mp(e,t,n,r,i,a){let{requested:o,grants:s}=await Of(e,t,i),c=pp(o,r.values,t);await hp(e,t,c,n,a);let{priorGrantState:l,warnings:u}=gp(t,c,c.map(e=>s?.get(e)??`unknown`));return Kf(r.name,c,{priorGrantState:l,warnings:u})}async function hp(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 yp(e,t,r,i)}function gp(e,t,n){return{priorGrantState:n.includes(`granted`)?`granted`:n.includes(`unknown`)?`unknown`:`not_granted`,warnings:t.flatMap((t,r)=>{let i=Bf(e,t,n[r]);return i?[i]:[]})}}async function _p(e,t,r,i){let a=await bp(e),o=a!==null&&a>=33?[`android.permission.READ_MEDIA_IMAGES`,`android.permission.READ_EXTERNAL_STORAGE`]:[`android.permission.READ_EXTERNAL_STORAGE`,`android.permission.READ_MEDIA_IMAGES`],s=[];for(let n of o){let a=await E(e,[`pm`,r,...i,t,n],{allowFailure:!0});if(a.exitCode===0)return n;s.push({permission:n,reason:rp(a.stderr),detail:cp(a.stderr)})}throw new n(`COMMAND_FAILED`,`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:a,attempts:s})}async function vp(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 yp(e,t,r.permission,i)),await E(e,[`appops`,`set`,...i,t,r.appOps,a])}async function yp(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 bp(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 xp=[`cmd`,`connectivity`,`airplane-mode`];async function Sp(e,t){let r=t?`enabled`:`disabled`;await Cp(e),await E(e,[...xp,t?`enable`:`disable`]);let i=await wp(e);if(i!==r)throw new n(`COMMAND_FAILED`,`Android airplane mode reads ${i} after requesting ${r}.`,{deviceId:e.id,requested:r,airplaneMode:i});return{airplaneMode:i}}async function Cp(e){let{state:t,result:r}=await Tp(e);if(!t)throw r.exitCode!==0&&it(r.stdout,r.stderr)?new n(`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:r.stdout,stderr:r.stderr,exitCode:r.exitCode}):T(`Failed to read Android airplane mode`,r,{deviceId:e.id})}async function wp(e){let{state:t,result:n}=await Tp(e);if(t)return t;throw T(`Failed to read Android airplane mode after changing it`,n,{deviceId:e.id})}async function Tp(e){let t=await E(e,[...xp],{allowFailure:!0});return{state:t.exitCode===0?Ep(t.stdout):void 0,result:t}}function Ep(e){let t=e.trim().toLowerCase();if(t===`enabled`)return`enabled`;if(t===`disabled`)return`disabled`}const Dp=[`window_animation_scale`,`transition_animation_scale`,`animator_duration_scale`],Op={"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`},kp=Op.large;async function Ap(e,t,r,i,a){switch(t.toLowerCase()){case`wifi`:{let t=ge(r);await E(e,[`svc`,`wifi`,t?`enable`:`disable`]);return}case`airplane`:return await Sp(e,ge(r));case`location`:{if(r.toLowerCase()===`set`){if(e.kind!==`emulator`)throw new n(`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:r}=xe(a);return await rt(e,[`emu`,`geo`,`fix`,String(r),String(t)]),{latitude:t,longitude:r}}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 Dp)await E(e,[`settings`,`put`,`global`,n,t]);return{scale:t,keys:[...Dp]}}case`appearance`:{let t=await Bp(e,r);await E(e,[`cmd`,`uimode`,`night`,t===`dark`?`yes`:`no`]);return}case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new n(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new n(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let t=await St(e,i);if(t.type===`intent`)throw new n(`INVALID_ARGS`,`settings clear-app-state requires a package name, not an intent.`);await E(e,[`am`,`force-stop`,t.value],{allowFailure:!0});let a=await E(e,[`pm`,`clear`,t.value],{allowFailure:!0});if(a.exitCode!==0||!/\bSuccess\b/i.test(a.stdout))throw new n(`COMMAND_FAILED`,`Failed to clear Android app data for ${t.value}`,{package:t.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:t.value,cleared:!0}}case`fingerprint`:await Lp(e,Ip(r));return;case`permission`:if(!i)throw new n(`INVALID_ARGS`,`permission setting requires an active app in session`);return await Wf(e,i,r,a);case`text-size`:return await Np(e,r);default:throw new n(`INVALID_ARGS`,`Unsupported setting: ${t}`)}}const jp={"text-size":Pp};async function Mp(e,t){return await jp[t](e)}async function Np(e,t){let n=ye(t),r=Op[n];return await E(e,[`settings`,`put`,`system`,`font_scale`,r]),me(n,r)}async function Pp(e){let t=(await E(e,[`settings`,`get`,`system`,`font_scale`])).stdout.trim(),r=t===`null`?kp:t,i=/^(\d+(\.\d+)?)$/.test(r)?Number(r):NaN;if(!Number.isFinite(i)||i<=0)throw new n(`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(Fp(i),r)}function Fp(e){let t=_e[0],n=1/0;for(let r of _e){let i=Math.abs(Number.parseFloat(Op[r])-e);i>=n||(t=r,n=i)}return t}function Ip(e){let t=e.trim().toLowerCase();if(t===`match`)return`match`;if(t===`nonmatch`)return`nonmatch`;throw new n(`INVALID_ARGS`,`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}async function Lp(e,r){let i=Rp(e,r),a=[];for(let t of i){let n=await rt(e,t,{allowFailure:!0});if(n.exitCode===0)return;a.push({args:t,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})}let o=t(a);throw a.length>0&&a.every(e=>zp(e.stdout,e.stderr))?new n(`UNSUPPORTED_OPERATION`,`Android fingerprint simulation is not supported on this target/runtime.`,{deviceId:e.id,action:r,hint:`Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.`,attempts:o}):new n(`COMMAND_FAILED`,`Failed to simulate Android fingerprint.`,{deviceId:e.id,action:r,attempts:o})}function Rp(e,t){let n=t===`match`?`1`:`9999`,r=[Ae(`adb`,`shell`,[`cmd`,`fingerprint`,`touch`,n]),Ae(`adb`,`shell`,[`cmd`,`fingerprint`,`finger`,n])];return e.kind===`emulator`&&r.push([`emu`,`finger`,`touch`,n]),r}function zp(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 Bp(e,t){let r=he(t);if(r!==`toggle`)return r;let i=await E(e,[`cmd`,`uimode`,`night`],{allowFailure:!0});if(i.exitCode!==0)throw T(`Failed to read current Android appearance`,i);let a=Vp(i.stdout,i.stderr);if(!a)throw new n(`COMMAND_FAILED`,`Unable to determine current Android appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`auto`?`dark`:a===`dark`?`light`:`dark`}function Vp(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 Hp=Buffer.from([137,80,78,71,13,10,26,10]);async function Up(e,t,n={}){if(n.stabilize===!1){await Kp(e,t);return}await Wp(e);try{await _(1e3),await Kp(e,t)}finally{await Gp(e).catch(()=>{})}}async function Wp(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 Gp(e){await E(e,[`am`,`broadcast`,`-a`,`com.android.systemui.demo`,`-e`,`command`,`exit`],{allowFailure:!0})}async function Kp(e,t){let r=await nt(e,[`screencap`,`-p`],{binaryStdout:!0});if(!r.stdoutBuffer)throw new n(`COMMAND_FAILED`,`Failed to capture screenshot`);let i=r.stdoutBuffer.indexOf(Hp);if(i<0)throw new n(`COMMAND_FAILED`,`Screenshot data does not contain a valid PNG header`);let a=qp(r.stdoutBuffer,i);if(!a)throw new n(`COMMAND_FAILED`,`Screenshot data does not contain a complete PNG payload`);await S().files.writeBytes(t,r.stdoutBuffer.subarray(i,a))}function qp(e,t){let n=t+Hp.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 Jp(e,t,n=0){let r=Ue(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}let i=await $p(e,`type`,t);if(i.backend===`test-ime`){await em(e,i.packageName,t,n);return}if(n>0&&Array.from(t).length>1){await nm(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await nm(e,{action:`type`,text:t,chunkSize:8,delayMs:0})}async function Yp(e,t,n,r,i=0,a={}){let o=await du(e,t,n,a),s=Ue(e);if(s)return await s({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r),X(r,o,await cu(e,t,n,r,a));let c=null;for(let s of Xp(i)){await Ia(e,t,n);let i=await $p(e,`fill`,r);if(i.backend===`test-ime`)return X(r,o,await tm(e,i.packageName,t,n,r,o,a));let l=await Zp(e,{x:t,y:n,text:r,beforeTarget:o,attempt:s},a);if(c=l,l.ok)return;if(l.reason===`ime_capture`)return X(r,o,l);let u=fu(r,o,l);if(u)return u}return X(r,o,c)}function Xp(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 Zp(e,t,n){let{x:r,y:i,text:a,beforeTarget:o,attempt:s}=t;return await im(e,Qp(a,o,s)),await nm(e,{action:`fill`,text:a,chunkSize:s.chunkSize,delayMs:s.inputDelayMs}),cu(e,r,i,a,n)}function Qp(e,t,n){let r=Array.from(e).length;return pm(r>0?r+n.clearPadding:t?.text?Array.from(t.text).length+n.clearPadding:n.maxClear,n.minClear,n.maxClear)}async function $p(e,t,n){if(ns(e))return{backend:`test-ime`,packageName:(await Io(w(e))).manifest.packageName};let r=await am(e,t),i=r?.inputMethodPackage;return Ho(i)?{backend:`test-ime`,packageName:i}:(sm(n),om(r,t),{backend:`adb-shell`})}async function em(e,t,n,r){let i=b(e),a=n.split(`
|
|
18
|
+
`);for(let[n,o]of a.entries()){let s=r>0?fm(o,1):[o];for(let[e,o]of s.entries())o&&await Uo(i,t,o),r>0&&(e+1<s.length||n+1<a.length)&&await _(r);n+1<a.length&&await E(e,[`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,n)}async function tm(e,t,n,r,i,a,o){let s=b(e),c=null;for(let l=0;l<2;l+=1){l>0&&await Ia(e,n,r),await Wo(s,t),i&&await Uo(s,t,i);let u=await cu(e,n,r,i,o);if(c=u,u.ok||fu(i,a,u))break}return $(`fill`,`test-ime`,i),c}async function nm(e,t){let n=t.text.split(`
|
|
19
|
+
`);for(let[r,i]of n.entries()){let a=fm(i,t.chunkSize);for(let[i,o]of a.entries())await rm(e,o),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await _(t.delayMs);r+1<n.length&&await E(e,[`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function rm(e,t){if(t)try{await E(e,[`input`,`text`,lm(t)])}catch(e){throw um(e)?dm(t,e):e}}async function im(e,t){let n=Math.max(0,t);await E(e,[`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await E(e,[`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}async function am(e,t){try{return await ho(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 om(e,t){if(!(!e||e.inputOwner!==`ime`))throw new n(`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 sm(e){if(!cm(e))throw dm(e)}function cm(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
|
|
20
|
+
`&&(e<32||e>126))return!1}return!0}function lm(e){return e.replaceAll(` `,`%s`)}function um(e){if(!(e instanceof n)||e.code!==`COMMAND_FAILED`)return!1;let t=e.details?.stderr,r=(typeof t==`string`?t:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function dm(e,t){return new n(`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. 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).",{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},t instanceof Error?t:void 0)}function fm(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 pm(e,t,n){return Math.max(t,Math.min(n,e))}var mm=e({ANDROID_FOCUSED_WINDOW_MARKER:()=>Ot,ANDROID_FOCUS_MARKERS:()=>Et,ANDROID_IME_HELPER_SERVICE_COMPONENT:()=>`com.callstack.agentdevice.imehelper/.TestInputMethodService`,ANDROID_SNAPSHOT_PRESENTATION_DEFAULT_DEADLINE_MS:()=>250,ANDROID_TEST_IME_SETTINGS_KEYS:()=>Yo,ANDROID_TOUCH_PLAN_PROTOCOL:()=>ra,AndroidSnapshotPresentationFailure:()=>Y,activateAndroidTestIme:()=>Fu,androidAdbForwardsDeviceExitStatus:()=>Wt,androidAdbHostTarget:()=>Ze,androidAdbInvocation:()=>Ye,androidAdbResultError:()=>T,androidAdbSerialTarget:()=>Xe,androidAppsDiscoveryHint:()=>Ct,androidCaptureFailureReasonDetail:()=>br,androidCaptureFailureReasonFromExitCode:()=>yr,androidCaptureFailureReasonFromHelperResult:()=>vr,androidClipboardShellSupportForResult:()=>gm,androidDeviceChecks:()=>ps,androidFillFailureDetails:()=>gu,androidFillFailureMessage:()=>hu,androidRevokedPermissionWarning:()=>Bf,androidSnapshotPublicationInput:()=>kl,androidToolchainCheck:()=>fs,androidUiNodes:()=>Lc,annotateAndroidNativePerfError:()=>N,appSwitcherAndroid:()=>Pa,attachAdbFailureHint:()=>$e,backAndroid:()=>Ea,buildAndroidFillUnconfirmedVerification:()=>fu,buildAndroidNativeToolUnavailableHint:()=>Fr,buildAndroidSnapshotClickabilityEvidence:()=>Zc,buildAndroidSnapshotHelperArgs:()=>mi,buildAndroidSnapshotHelperCaptureOptions:()=>fi,buildUiHierarchySnapshot:()=>_c,captureAndroidHeapSnapshot:()=>mf,captureAndroidLogcatWithAdb:()=>_m,captureAndroidSnapshotWithHelper:()=>di,captureAndroidSnapshotWithHelperSession:()=>Qi,classifyAdbFailure:()=>tt,classifyAndroidAlertIdentifier:()=>nn,classifyAndroidAppTarget:()=>vt,classifyAndroidHelperContent:()=>$c,cleanupAndroidNativePerfSession:()=>Ud,clearAndroidImeHelperText:()=>Wo,clearAndroidTestImeRecoveryMarker:()=>Vu,closeAndroidApp:()=>pt,completeAndroidFillVerification:()=>X,createAndroidPortReverseManager:()=>Ve,createAndroidSnapshotCapture:()=>Ol,createAndroidSnapshotPresentationBudget:()=>fc,createAndroidSnapshotPresentationNode:()=>cc,createAndroidWindowDumpReader:()=>Mt,createDeviceAdbExecutor:()=>He,createLocalAndroidAdbProvider:()=>Re,dismissAndroidKeyboard:()=>go,dismissAndroidKeyboardWithAdb:()=>_o,ensureAndroidEmulatorBooted:()=>gt,ensureAndroidImeHelper:()=>Bo,ensureAndroidSdkPathConfigured:()=>ft,ensureAndroidSnapshotHelper:()=>dr,executeAndroidTouchHelperPlan:()=>sa,executeAndroidTouchPlan:()=>xa,fillAndroid:()=>Yp,findAndroidAlertCandidate:()=>rn,focusAndroid:()=>Ia,forceStopAndroidAppWithAdb:()=>Qa,forgetAndroidSnapshotHelperInstall:()=>ir,formatAndroidInstalledPackageRequiredMessage:()=>xt,getAndroidAppState:()=>At,getAndroidBlockingDialogObservation:()=>jt,getAndroidImeHelperDeviceKey:()=>U,getAndroidKeyboardState:()=>ho,getAndroidKeyboardStatusWithAdb:()=>V,getAndroidScreenSize:()=>Ba,handleAndroidAlert:()=>Va,homeAndroid:()=>Da,inferAndroidAppName:()=>bt,inferAndroidPackageAfterOpen:()=>ym,inspectInstalledAndroidHelper:()=>Rn,installAndroidAdbPackage:()=>We,installAndroidInstallablePath:()=>lo,isAmStartError:()=>ht,isAndroidImeHelperPackage:()=>Ho,isAndroidPermissionPackage:()=>Jt,isAndroidSnapshotPresentationFailure:()=>uc,isAndroidTestImeActive:()=>ns,listAndroidAdbSerialsQuick:()=>us,listAndroidAppsWithAdb:()=>hm,longPressAndroid:()=>Fa,lowerAndroidAdbInvocation:()=>qe,lowerAndroidTouchPlan:()=>ya,makeEnsureAndroidHelperInstalled:()=>Bn,normalizeAndroidTouchHelperGestureRequest:()=>fa,openAndroidApp:()=>dt,openAndroidAppWithAdb:()=>eo,openAndroidDevice:()=>lt,parseAndroidAdbArgv:()=>Qe,parseAndroidHelperManifest:()=>Zn,parseAndroidLaunchComponent:()=>mt,parseAndroidLaunchablePackages:()=>Tt,parseAndroidSnapshotHelperManifest:()=>Zn,parseAndroidSnapshotHelperOutput:()=>Ci,parseAndroidUserInstalledPackages:()=>wt,parseInstrumentationRecords:()=>Dn,parseUiHierarchyTree:()=>Yc,prepareAndroidInstallArtifact:()=>od,pressAndroid:()=>wa,pressAndroidEnter:()=>Oa,pressAndroidTvRemote:()=>Ta,pullAndroidAdbFile:()=>Be,pushAndroidNotification:()=>ld,readAndroidBlockingDialogFocus:()=>Dt,readAndroidClipboardText:()=>Oo,readAndroidClipboardWithAdb:()=>ko,readAndroidDefaultInputMethod:()=>W,readAndroidFillTargetBeforeMutation:()=>du,readAndroidGestureViewport:()=>Sa,readAndroidHelperManifestInteger:()=>wn,readAndroidHelperManifestLiteral:()=>k,readAndroidSetting:()=>Mp,readAndroidTestImeRecoveryMarkers:()=>Hu,readAndroidTextAtPoint:()=>lu,readAndroidTextAtPointInHierarchy:()=>mu,readAndroidTouchHelperFinalRecord:()=>ha,readAndroidTouchHelperViewportReading:()=>ca,readInstrumentationResultBoolean:()=>Nn,readInstrumentationResultNumber:()=>A,resetAndroidAdbShellProtocolProbes:()=>Gt,resetAndroidFramePerfStats:()=>Rd,resetAndroidImeHelperInstallCache:()=>Vo,resetAndroidSnapshotHelperInstallCache:()=>sr,resetAndroidSnapshotHelperRuntime:()=>El,resetAndroidSnapshotHelperSessions:()=>Zi,resetAndroidTestImeActivationCacheForTests:()=>is,resetAndroidWindowDumpFocusMemoForTests:()=>kt,resolveAndroidAdbExecutor:()=>b,resolveAndroidAdbProvider:()=>w,resolveAndroidApp:()=>St,resolveAndroidArchivePackageName:()=>qu,resolveAndroidHelperArtifact:()=>zn,resolveAndroidImeHelperArtifact:()=>Lo,resolveAndroidPackageForOpen:()=>vm,resolveAndroidSnapshotHelperCaptureOptions:()=>pi,resolveAndroidTextInjector:()=>Ue,resolveAndroidTouchProvider:()=>Ie,resolveScopedAndroidAdbBackgroundTransport:()=>ze,restoreAndroidTestIme:()=>os,restoreOrphanedAndroidTestImeOnDaemonStartup:()=>ls,retireAndroidSnapshotHelperAfterContentFailure:()=>Tl,runAdbExecOut:()=>Ge,runAdbShell:()=>x,runAndroidAdb:()=>rt,runAndroidExecOut:()=>nt,runAndroidHostAdb:()=>Fe,runAndroidShell:()=>E,runAndroidSnapshotHelperSessionTouchCommand:()=>ea,sampleAndroidFramePerf:()=>Ld,sampleAndroidMemoryPerf:()=>pf,screenshotAndroid:()=>Up,scrollAndroid:()=>La,selectAndroidImeHelperArtifact:()=>Io,sendAndroidImeHelperText:()=>Uo,serializeAndroidAdbInvocation:()=>Je,setAndroidOrientation:()=>ka,setAndroidPermission:()=>Wf,setAndroidSetting:()=>Ap,setAndroidTestImeActiveForTests:()=>as,sleep:()=>_,snapshotAndroid:()=>jl,startAndroidPerfettoTrace:()=>$d,startAndroidSimpleperfProfile:()=>rf,stopAndroidPerfettoTrace:()=>ef,stopAndroidSimpleperfProfile:()=>af,stopAndroidSnapshotHelperSession:()=>B,stopAndroidSnapshotHelperSessionForDevice:()=>Xi,typeAndroid:()=>Jp,validateAndroidGestureViewport:()=>Pn,validateAndroidRegularPresentation:()=>pc,verifyAndroidFilledText:()=>cu,verifyAndroidFilledTextInHierarchy:()=>pu,verifyAndroidHelperApkChecksum:()=>Wn,waitForAndroidBoot:()=>ut,withAndroidAdbProvider:()=>Le,withAndroidAppResolutionCacheInvalidated:()=>yt,withAndroidHostAdbTransport:()=>Ke,writeAndroidClipboardText:()=>Ao,writeAndroidClipboardWithAdb:()=>jo,writeAndroidSimpleperfReport:()=>of,writeAndroidTestImeRecoveryMarker:()=>Bu});async function hm(...e){let{listAndroidAppsWithAdb:t}=await import(`./app-helpers.js`);return await t(...e)}async function gm(...e){let{androidClipboardShellSupportForResult:t}=await import(`./clipboard-shell-response.js`);return t(...e)}async function _m(...e){let{captureAndroidLogcatWithAdb:t}=await import(`./logcat.js`);return await t(...e)}async function vm(...e){let{resolveAndroidPackageForOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}async function ym(...e){let{inferAndroidPackageAfterOpen:t}=await import(`./open-target-resolution.js`);return await t(...e)}export{La as A,Ea as C,wa as D,Fa as E,xa as M,Sa as N,Oa as O,Pa as S,Da as T,Ao as _,Jp as a,eo as b,Ap as c,go as d,_o as f,ko as g,Oo as h,Yp as i,ka as j,Ta as k,jl as l,V as m,hm as n,Up as o,ho as p,mm as r,Mp as s,_m as t,kl as u,jo as v,Ia as w,Va as x,Qa as y};
|