@kaeawc/auto-mobile 0.0.57 → 0.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.md.backup +1 -1
- package/dist/src/index.js +4 -4
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -16,7 +16,7 @@ and limitations under the License.
|
|
|
16
16
|
***************************************************************************** */var Rw$;(function($){(function(J){var X=typeof globalThis==="object"?globalThis:typeof global==="object"?global:typeof self==="object"?self:typeof this==="object"?this:Z(),Q=Y($);if(typeof X.Reflect<"u")Q=Y(X.Reflect,Q);if(J(Q,X),typeof X.Reflect>"u")X.Reflect=$;function Y(j,V){return function(K,z){if(Object.defineProperty(j,K,{configurable:!0,writable:!0,value:z}),V)V(K,z)}}function W(){try{return Function("return this;")()}catch(j){}}function G(){try{return(0,eval)("(function() { return this; })()")}catch(j){}}function Z(){return W()||G()}})(function(J,X){var Q=Object.prototype.hasOwnProperty,Y=typeof Symbol==="function",W=Y&&typeof Symbol.toPrimitive<"u"?Symbol.toPrimitive:"@@toPrimitive",G=Y&&typeof Symbol.iterator<"u"?Symbol.iterator:"@@iterator",Z=typeof Object.create==="function",j={__proto__:[]}instanceof Array,V=!Z&&!j,K={create:Z?function(){return aW(Object.create(null))}:j?function(){return aW({__proto__:null})}:function(){return aW({})},has:V?function(V$,B$){return Q.call(V$,B$)}:function(V$,B$){return B$ in V$},get:V?function(V$,B$){return Q.call(V$,B$)?V$[B$]:void 0}:function(V$,B$){return V$[B$]}},z=Object.getPrototypeOf(Function),L=typeof Map==="function"&&typeof Map.prototype.entries==="function"?Map:pj(),H=typeof Set==="function"&&typeof Set.prototype.entries==="function"?Set:BU(),O=typeof WeakMap==="function"?WeakMap:l2(),B=Y?Symbol.for("@reflect-metadata:registry"):void 0,F=rW(),A=tW(F);function _(V$,B$,I$,X0){if(!n$(I$)){if(!A4(V$))throw TypeError();if(!B0(B$))throw TypeError();if(!B0(X0)&&!n$(X0)&&!d0(X0))throw TypeError();if(d0(X0))X0=void 0;return I$=b0(I$),Y$(V$,B$,I$,X0)}else{if(!A4(V$))throw TypeError();if(!d6(B$))throw TypeError();return a(V$,B$)}}J("decorate",_);function w(V$,B$){function I$(X0,X1){if(!B0(X0))throw TypeError();if(!n$(X1)&&!M8(X1))throw TypeError();R$(V$,B$,X0,X1)}return I$}J("metadata",w);function q(V$,B$,I$,X0){if(!B0(I$))throw TypeError();if(!n$(X0))X0=b0(X0);return R$(V$,B$,I$,X0)}J("defineMetadata",q);function M(V$,B$,I$){if(!B0(B$))throw TypeError();if(!n$(I$))I$=b0(I$);return J$(V$,B$,I$)}J("hasMetadata",M);function C(V$,B$,I$){if(!B0(B$))throw TypeError();if(!n$(I$))I$=b0(I$);return L$(V$,B$,I$)}J("hasOwnMetadata",C);function y(V$,B$,I$){if(!B0(B$))throw TypeError();if(!n$(I$))I$=b0(I$);return O$(V$,B$,I$)}J("getMetadata",y);function I(V$,B$,I$){if(!B0(B$))throw TypeError();if(!n$(I$))I$=b0(I$);return _$(V$,B$,I$)}J("getOwnMetadata",I);function d(V$,B$){if(!B0(V$))throw TypeError();if(!n$(B$))B$=b0(B$);return j0(V$,B$)}J("getMetadataKeys",d);function u(V$,B$){if(!B0(V$))throw TypeError();if(!n$(B$))B$=b0(B$);return V0(V$,B$)}J("getOwnMetadataKeys",u);function r(V$,B$,I$){if(!B0(B$))throw TypeError();if(!n$(I$))I$=b0(I$);if(!B0(B$))throw TypeError();if(!n$(I$))I$=b0(I$);var X0=wQ(B$,I$,!1);if(n$(X0))return!1;return X0.OrdinaryDeleteMetadata(V$,B$,I$)}J("deleteMetadata",r);function a(V$,B$){for(var I$=V$.length-1;I$>=0;--I$){var X0=V$[I$],X1=X0(B$);if(!n$(X1)&&!d0(X1)){if(!d6(X1))throw TypeError();B$=X1}}return B$}function Y$(V$,B$,I$,X0){for(var X1=V$.length-1;X1>=0;--X1){var A6=V$[X1],S6=A6(B$,I$,X0);if(!n$(S6)&&!d0(S6)){if(!B0(S6))throw TypeError();X0=S6}}return X0}function J$(V$,B$,I$){var X0=L$(V$,B$,I$);if(X0)return!0;var X1=G5(B$);if(!d0(X1))return J$(V$,X1,I$);return!1}function L$(V$,B$,I$){var X0=wQ(B$,I$,!1);if(n$(X0))return!1;return F$(X0.OrdinaryHasOwnMetadata(V$,B$,I$))}function O$(V$,B$,I$){var X0=L$(V$,B$,I$);if(X0)return _$(V$,B$,I$);var X1=G5(B$);if(!d0(X1))return O$(V$,X1,I$);return}function _$(V$,B$,I$){var X0=wQ(B$,I$,!1);if(n$(X0))return;return X0.OrdinaryGetOwnMetadata(V$,B$,I$)}function R$(V$,B$,I$,X0){var X1=wQ(I$,X0,!0);X1.OrdinaryDefineOwnMetadata(V$,B$,I$,X0)}function j0(V$,B$){var I$=V0(V$,B$),X0=G5(V$);if(X0===null)return I$;var X1=j0(X0,B$);if(X1.length<=0)return I$;if(I$.length<=0)return X1;var A6=new H,S6=[];for(var b1=0,R0=I$;b1<R0.length;b1++){var m0=R0[b1],n0=A6.has(m0);if(!n0)A6.add(m0),S6.push(m0)}for(var Q1=0,S1=X1;Q1<S1.length;Q1++){var m0=S1[Q1],n0=A6.has(m0);if(!n0)A6.add(m0),S6.push(m0)}return S6}function V0(V$,B$){var I$=wQ(V$,B$,!1);if(!I$)return[];return I$.OrdinaryOwnMetadataKeys(V$,B$)}function s0(V$){if(V$===null)return 1;switch(typeof V$){case"undefined":return 0;case"boolean":return 2;case"string":return 3;case"symbol":return 4;case"number":return 5;case"object":return V$===null?1:6;default:return 6}}function n$(V$){return V$===void 0}function d0(V$){return V$===null}function Q0(V$){return typeof V$==="symbol"}function B0(V$){return typeof V$==="object"?V$!==null:typeof V$==="function"}function c(V$,B$){switch(s0(V$)){case 0:return V$;case 1:return V$;case 2:return V$;case 3:return V$;case 4:return V$;case 5:return V$}var I$=B$===3?"string":B$===5?"number":"default",X0=u0(V$,W);if(X0!==void 0){var X1=X0.call(V$,I$);if(B0(X1))throw TypeError();return X1}return h(V$,I$==="default"?"number":I$)}function h(V$,B$){if(B$==="string"){var I$=V$.toString;if(_4(I$)){var X0=I$.call(V$);if(!B0(X0))return X0}var X1=V$.valueOf;if(_4(X1)){var X0=X1.call(V$);if(!B0(X0))return X0}}else{var X1=V$.valueOf;if(_4(X1)){var X0=X1.call(V$);if(!B0(X0))return X0}var A6=V$.toString;if(_4(A6)){var X0=A6.call(V$);if(!B0(X0))return X0}}throw TypeError()}function F$(V$){return!!V$}function Q$(V$){return""+V$}function b0(V$){var B$=c(V$,3);if(Q0(B$))return B$;return Q$(B$)}function A4(V$){return Array.isArray?Array.isArray(V$):V$ instanceof Object?V$ instanceof Array:Object.prototype.toString.call(V$)==="[object Array]"}function _4(V$){return typeof V$==="function"}function d6(V$){return typeof V$==="function"}function M8(V$){switch(s0(V$)){case 3:return!0;case 4:return!0;default:return!1}}function jJ(V$,B$){return V$===B$||V$!==V$&&B$!==B$}function u0(V$,B$){var I$=V$[B$];if(I$===void 0||I$===null)return;if(!_4(I$))throw TypeError();return I$}function q1(V$){var B$=u0(V$,G);if(!_4(B$))throw TypeError();var I$=B$.call(V$);if(!B0(I$))throw TypeError();return I$}function w1(V$){return V$.value}function b8(V$){var B$=V$.next();return B$.done?!1:B$}function P7(V$){var B$=V$.return;if(B$)B$.call(V$)}function G5(V$){var B$=Object.getPrototypeOf(V$);if(typeof V$!=="function"||V$===z)return B$;if(B$!==z)return B$;var I$=V$.prototype,X0=I$&&Object.getPrototypeOf(I$);if(X0==null||X0===Object.prototype)return B$;var X1=X0.constructor;if(typeof X1!=="function")return B$;if(X1===V$)return B$;return X1}function oW(){var V$;if(!n$(B)&&typeof X.Reflect<"u"&&!(B in X.Reflect)&&typeof X.Reflect.defineMetadata==="function")V$=qQ(X.Reflect);var B$,I$,X0,X1=new O,A6={registerProvider:S6,getProvider:R0,setProvider:n0};return A6;function S6(Q1){if(!Object.isExtensible(A6))throw Error("Cannot add provider to a frozen registry.");switch(!0){case V$===Q1:break;case n$(B$):B$=Q1;break;case B$===Q1:break;case n$(I$):I$=Q1;break;case I$===Q1:break;default:if(X0===void 0)X0=new H;X0.add(Q1);break}}function b1(Q1,S1){if(!n$(B$)){if(B$.isProviderFor(Q1,S1))return B$;if(!n$(I$)){if(I$.isProviderFor(Q1,S1))return B$;if(!n$(X0)){var b4=q1(X0);while(!0){var T1=b8(b4);if(!T1)return;var D8=w1(T1);if(D8.isProviderFor(Q1,S1))return P7(b4),D8}}}}if(!n$(V$)&&V$.isProviderFor(Q1,S1))return V$;return}function R0(Q1,S1){var b4=X1.get(Q1),T1;if(!n$(b4))T1=b4.get(S1);if(!n$(T1))return T1;if(T1=b1(Q1,S1),!n$(T1)){if(n$(b4))b4=new L,X1.set(Q1,b4);b4.set(S1,T1)}return T1}function m0(Q1){if(n$(Q1))throw TypeError();return B$===Q1||I$===Q1||!n$(X0)&&X0.has(Q1)}function n0(Q1,S1,b4){if(!m0(b4))throw Error("Metadata provider not registered.");var T1=R0(Q1,S1);if(T1!==b4){if(!n$(T1))return!1;var D8=X1.get(Q1);if(n$(D8))D8=new L,X1.set(Q1,D8);D8.set(S1,b4)}return!0}}function rW(){var V$;if(!n$(B)&&B0(X.Reflect)&&Object.isExtensible(X.Reflect))V$=X.Reflect[B];if(n$(V$))V$=oW();if(!n$(B)&&B0(X.Reflect)&&Object.isExtensible(X.Reflect))Object.defineProperty(X.Reflect,B,{enumerable:!1,configurable:!1,writable:!1,value:V$});return V$}function tW(V$){var B$=new O,I$={isProviderFor:function(m0,n0){var Q1=B$.get(m0);if(n$(Q1))return!1;return Q1.has(n0)},OrdinaryDefineOwnMetadata:S6,OrdinaryHasOwnMetadata:X1,OrdinaryGetOwnMetadata:A6,OrdinaryOwnMetadataKeys:b1,OrdinaryDeleteMetadata:R0};return F.registerProvider(I$),I$;function X0(m0,n0,Q1){var S1=B$.get(m0),b4=!1;if(n$(S1)){if(!Q1)return;S1=new L,B$.set(m0,S1),b4=!0}var T1=S1.get(n0);if(n$(T1)){if(!Q1)return;if(T1=new L,S1.set(n0,T1),!V$.setProvider(m0,n0,I$)){if(S1.delete(n0),b4)B$.delete(m0);throw Error("Wrong provider for target.")}}return T1}function X1(m0,n0,Q1){var S1=X0(n0,Q1,!1);if(n$(S1))return!1;return F$(S1.has(m0))}function A6(m0,n0,Q1){var S1=X0(n0,Q1,!1);if(n$(S1))return;return S1.get(m0)}function S6(m0,n0,Q1,S1){var b4=X0(Q1,S1,!0);b4.set(m0,n0)}function b1(m0,n0){var Q1=[],S1=X0(m0,n0,!1);if(n$(S1))return Q1;var b4=S1.keys(),T1=q1(b4),D8=0;while(!0){var NQ=b8(T1);if(!NQ)return Q1.length=D8,Q1;var sW=w1(NQ);try{Q1[D8]=sW}catch(p2){try{P7(T1)}finally{throw p2}}D8++}}function R0(m0,n0,Q1){var S1=X0(n0,Q1,!1);if(n$(S1))return!1;if(!S1.delete(m0))return!1;if(S1.size===0){var b4=B$.get(n0);if(!n$(b4)){if(b4.delete(Q1),b4.size===0)B$.delete(b4)}}return!0}}function qQ(V$){var{defineMetadata:B$,hasOwnMetadata:I$,getOwnMetadata:X0,getOwnMetadataKeys:X1,deleteMetadata:A6}=V$,S6=new O,b1={isProviderFor:function(R0,m0){var n0=S6.get(R0);if(!n$(n0)&&n0.has(m0))return!0;if(X1(R0,m0).length){if(n$(n0))n0=new H,S6.set(R0,n0);return n0.add(m0),!0}return!1},OrdinaryDefineOwnMetadata:B$,OrdinaryHasOwnMetadata:I$,OrdinaryGetOwnMetadata:X0,OrdinaryOwnMetadataKeys:X1,OrdinaryDeleteMetadata:A6};return b1}function wQ(V$,B$,I$){var X0=F.getProvider(V$,B$);if(!n$(X0))return X0;if(I$){if(F.setProvider(V$,B$,A))return A;throw Error("Illegal state.")}return}function pj(){var V$={},B$=[],I$=function(){function b1(R0,m0,n0){this._index=0,this._keys=R0,this._values=m0,this._selector=n0}return b1.prototype["@@iterator"]=function(){return this},b1.prototype[G]=function(){return this},b1.prototype.next=function(){var R0=this._index;if(R0>=0&&R0<this._keys.length){var m0=this._selector(this._keys[R0],this._values[R0]);if(R0+1>=this._keys.length)this._index=-1,this._keys=B$,this._values=B$;else this._index++;return{value:m0,done:!1}}return{value:void 0,done:!0}},b1.prototype.throw=function(R0){if(this._index>=0)this._index=-1,this._keys=B$,this._values=B$;throw R0},b1.prototype.return=function(R0){if(this._index>=0)this._index=-1,this._keys=B$,this._values=B$;return{value:R0,done:!0}},b1}(),X0=function(){function b1(){this._keys=[],this._values=[],this._cacheKey=V$,this._cacheIndex=-2}return Object.defineProperty(b1.prototype,"size",{get:function(){return this._keys.length},enumerable:!0,configurable:!0}),b1.prototype.has=function(R0){return this._find(R0,!1)>=0},b1.prototype.get=function(R0){var m0=this._find(R0,!1);return m0>=0?this._values[m0]:void 0},b1.prototype.set=function(R0,m0){var n0=this._find(R0,!0);return this._values[n0]=m0,this},b1.prototype.delete=function(R0){var m0=this._find(R0,!1);if(m0>=0){var n0=this._keys.length;for(var Q1=m0+1;Q1<n0;Q1++)this._keys[Q1-1]=this._keys[Q1],this._values[Q1-1]=this._values[Q1];if(this._keys.length--,this._values.length--,jJ(R0,this._cacheKey))this._cacheKey=V$,this._cacheIndex=-2;return!0}return!1},b1.prototype.clear=function(){this._keys.length=0,this._values.length=0,this._cacheKey=V$,this._cacheIndex=-2},b1.prototype.keys=function(){return new I$(this._keys,this._values,X1)},b1.prototype.values=function(){return new I$(this._keys,this._values,A6)},b1.prototype.entries=function(){return new I$(this._keys,this._values,S6)},b1.prototype["@@iterator"]=function(){return this.entries()},b1.prototype[G]=function(){return this.entries()},b1.prototype._find=function(R0,m0){if(!jJ(this._cacheKey,R0)){this._cacheIndex=-1;for(var n0=0;n0<this._keys.length;n0++)if(jJ(this._keys[n0],R0)){this._cacheIndex=n0;break}}if(this._cacheIndex<0&&m0)this._cacheIndex=this._keys.length,this._keys.push(R0),this._values.push(void 0);return this._cacheIndex},b1}();return X0;function X1(b1,R0){return b1}function A6(b1,R0){return R0}function S6(b1,R0){return[b1,R0]}}function BU(){var V$=function(){function B$(){this._map=new L}return Object.defineProperty(B$.prototype,"size",{get:function(){return this._map.size},enumerable:!0,configurable:!0}),B$.prototype.has=function(I$){return this._map.has(I$)},B$.prototype.add=function(I$){return this._map.set(I$,I$),this},B$.prototype.delete=function(I$){return this._map.delete(I$)},B$.prototype.clear=function(){this._map.clear()},B$.prototype.keys=function(){return this._map.keys()},B$.prototype.values=function(){return this._map.keys()},B$.prototype.entries=function(){return this._map.entries()},B$.prototype["@@iterator"]=function(){return this.keys()},B$.prototype[G]=function(){return this.keys()},B$}();return V$}function l2(){var V$=16,B$=K.create(),I$=X0();return function(){function R0(){this._key=X0()}return R0.prototype.has=function(m0){var n0=X1(m0,!1);return n0!==void 0?K.has(n0,this._key):!1},R0.prototype.get=function(m0){var n0=X1(m0,!1);return n0!==void 0?K.get(n0,this._key):void 0},R0.prototype.set=function(m0,n0){var Q1=X1(m0,!0);return Q1[this._key]=n0,this},R0.prototype.delete=function(m0){var n0=X1(m0,!1);return n0!==void 0?delete n0[this._key]:!1},R0.prototype.clear=function(){this._key=X0()},R0}();function X0(){var R0;do R0="@@WeakMap@@"+b1();while(K.has(B$,R0));return B$[R0]=!0,R0}function X1(R0,m0){if(!Q.call(R0,I$)){if(!m0)return;Object.defineProperty(R0,I$,{value:K.create()})}return R0[I$]}function A6(R0,m0){for(var n0=0;n0<m0;++n0)R0[n0]=Math.random()*255|0;return R0}function S6(R0){if(typeof Uint8Array==="function"){var m0=new Uint8Array(R0);if(typeof crypto<"u")crypto.getRandomValues(m0);else if(typeof msCrypto<"u")msCrypto.getRandomValues(m0);else A6(m0,R0);return m0}return A6(Array(R0),R0)}function b1(){var R0=S6(V$);R0[6]=R0[6]&79|64,R0[8]=R0[8]&191|128;var m0="";for(var n0=0;n0<V$;++n0){var Q1=R0[n0];if(n0===4||n0===6||n0===8)m0+="-";if(Q1<16)m0+="0";m0+=Q1.toString(16).toLowerCase()}return m0}}function aW(V$){return V$.__=void 0,delete V$.__,V$}})})(Rw$||(Rw$={}))});import{existsSync as BH0}from"fs";import{homedir as DH0}from"os";import qe from"path";function h_($="/"){try{return process.cwd()}catch{return $}}function Lb($=DH0()){if($.length>0&&BH0($))return $;return"/"}function bB($=h_()){let J=process.env[c2]?.trim();return J&&qe.isAbsolute(J)?J:$}function x4($){if(qe.isAbsolute($))return $;return qe.resolve(bB(),$)}var c2="AUTOMOBILE_DAEMON_LAUNCH_CWD";var E9=()=>{};function Cw$($,J){let X=(Y)=>$.includes(Y.cli)||J[Y.env]==="1",Q={observeResultIncludeElements:!1,toolResultsNoStructuredContent:!1,actionsDiffObserve:!1,actionsNoObserve:!1};for(let Y of yB)Q[Y.field]=X(Y);return Q}function Sw$($){let J=[];for(let X of yB)if($[X.field])J.push(X.cli);return J}var yB;var g_=D(()=>{yB=[{field:"observeResultIncludeElements",cli:"--observe-result-include-elements",env:"AUTOMOBILE_OBSERVE_RESULT_INCLUDE_ELEMENTS",featureFlagKey:"observe-result-include-elements",label:"--observe-result-include-elements"},{field:"toolResultsNoStructuredContent",cli:"--tool-results-no-structured-content",env:"AUTOMOBILE_TOOL_RESULTS_NO_STRUCTURED_CONTENT",featureFlagKey:"tool-results-no-structured-content",label:"--tool-results-no-structured-content"},{field:"actionsDiffObserve",cli:"--actions-diff-observe",env:"AUTOMOBILE_ACTIONS_DIFF_OBSERVE",featureFlagKey:"actions-diff-observe",label:"--actions-diff-observe"},{field:"actionsNoObserve",cli:"--actions-no-observe",env:"AUTOMOBILE_ACTIONS_NO_OBSERVE",featureFlagKey:"actions-no-observe",label:"--actions-no-observe"}]});import{performance as qH0}from"perf_hooks";import wH0 from"fs";import NH0 from"path";function _H0($,J){if($.includes("--startup-benchmark"))return!0;let X=(J.AUTOMOBILE_STARTUP_BENCHMARK??J.AUTO_MOBILE_STARTUP_BENCHMARK??"").toLowerCase();return $.includes("--daemon-mode")&&(X==="1"||X==="true"||X==="yes")}class kw${marks=new Map;phaseStarts=new Map;phases=new Map;emitted=!1;emittedReport;enabled;outputPath;label;now;fileSystem;constructor($,J={}){this.enabled=$;let X=J.outputPath??RH0;this.outputPath=X?x4(X):void 0,this.label=J.label??EH0,this.now=J.now??qH0.now,this.fileSystem=J.fileSystem??wH0}isEnabled(){return this.enabled}mark($){if(!this.enabled||this.marks.has($))return;this.marks.set($,this.now()),this.persistCheckpoint()}startPhase($){if(!this.enabled||this.phases.has($)||this.phaseStarts.has($))return;this.phaseStarts.set($,this.now()),this.persistCheckpoint()}async runPhase($,J){this.startPhase($);let X=await J();return this.endPhase($),X}endPhase($){if(!this.enabled||this.phases.has($))return;let J=this.phaseStarts.get($);if(J===void 0)return;this.phases.set($,this.now()-J),this.phaseStarts.delete($),this.persistCheckpoint()}recordPhase($,J){if(!this.enabled||this.phases.has($))return;this.phases.set($,J),this.persistCheckpoint()}emit($,J={}){if(!this.enabled||this.emitted)return;this.emitted=!0,this.emittedReport={type:$,meta:J};let X=this.createReport($,"ready",J),Q=JSON.stringify(X);this.writeReport(Q),process.stderr.write(`${AH0} ${Q}
|
|
17
17
|
`)}persistCheckpoint(){if(!this.enabled)return;let $=this.emittedReport?this.createReport(this.emittedReport.type,"ready",this.emittedReport.meta):this.createReport("startup-checkpoint","in_progress");this.writeReport(JSON.stringify($))}createReport($,J,X={}){let Q=Object.fromEntries(this.marks.entries()),Y=Object.fromEntries(this.phases.entries());return{type:$,state:J,timestamp:new Date().toISOString(),pid:process.pid,label:this.label,marks:Q,phases:Y,activePhases:[...this.phaseStarts.keys()],memoryUsage:process.memoryUsage(),meta:X}}writeReport($){if(!this.outputPath)return;let J=NH0.dirname(this.outputPath);if(!this.fileSystem.existsSync(J))this.fileSystem.mkdirSync(J,{recursive:!0});let X=`${this.outputPath}.${process.pid}.tmp`;this.fileSystem.writeFileSync(X,$,"utf-8"),this.fileSystem.renameSync(X,this.outputPath)}}var AH0="STARTUP_BENCHMARK",MH0,RH0,EH0,y4;var Hb=D(()=>{E9();MH0=_H0(process.argv,process.env),RH0=process.env.AUTOMOBILE_STARTUP_BENCHMARK_OUTPUT??process.env.AUTO_MOBILE_STARTUP_BENCHMARK_OUTPUT,EH0=process.env.AUTOMOBILE_STARTUP_BENCHMARK_LABEL??process.env.AUTO_MOBILE_STARTUP_BENCHMARK_LABEL;y4=new kw$(MH0)});import{createHash as PH0}from"crypto";import{spawnSync as TH0}from"child_process";class xw${run;constructor($=IH0){this.run=$}readVersion($,J){if($.split(/[\\/]/).includes("node_modules"))return null;let X=this.execute($,["rev-parse","--show-toplevel"]);if(!X||J(X)!==CH0)return null;let Q=this.execute($,["rev-parse","--short=12","HEAD"]);if(!Q)return null;let Y=this.execute($,["status","--porcelain","--untracked-files=no"]),W=Y!==null&&Y.length>0,G=null;if(W){let Z=this.execute($,["diff","HEAD"]);if(Z)G=PH0("sha256").update(Z).digest("hex").slice(0,12)}return{shortSha:Q,dirty:W,dirtyHash:G}}execute($,J){return this.run("git",J,{cwd:$,timeoutMs:SH0})}}var CH0="@kaeawc/auto-mobile",SH0=2000,IH0=($,J,{cwd:X,timeoutMs:Q})=>{let Y=null;try{Y=TH0("git",J,{cwd:X,encoding:"utf-8",timeout:Q,killSignal:"SIGTERM"})}catch(W){}if(!Y||Y.status!==0||Y.error)return null;return(typeof Y.stdout==="string"?Y.stdout:Y.stdout.toString()).trim()},bw$;var yw$=D(()=>{bw$=new xw$});import we from"fs";import Bb from"path";import{fileURLToPath as kH0}from"url";var Ob=null,fw$=($)=>{let J=$;for(let X=0;X<6;X++){let Q=Bb.join(J,"package.json");if(we.existsSync(Q))return Q;let Y=Bb.dirname(J);if(Y===J)break;J=Y}return null},vw$=()=>Bb.dirname(kH0(import.meta.url)),xH0=($)=>{try{let J=we.readFileSync(Bb.join($,"package.json"),"utf-8");return JSON.parse(J).name??null}catch{}return null},bH0=()=>{let $=fw$(vw$())??fw$(process.cwd());if(!$)return null;try{let J=we.readFileSync($,"utf-8");return JSON.parse(J).version??null}catch{}return null},yH0=($=vw$(),J=bw$,X=xH0)=>J.readVersion($,X),VJ=($)=>$.split("+")[0],fH0=($,J)=>{if(!J||J.shortSha.length===0)return $;let X=J.dirty?J.dirtyHash?`.dirty.${J.dirtyHash}`:".dirty":"";return`${$}+g${J.shortSha}${X}`},vH0=($)=>{let J=$.env.MCP_SERVER_VERSION;if(J)return J;let X=$.env.npm_package_version||$.readPackageVersion()||"unknown";if(X==="unknown")return X;return fH0(X,$.readGitVersion())},P9=()=>{if(Ob)return Ob;return Ob=vH0({env:{MCP_SERVER_VERSION:process.env.MCP_SERVER_VERSION,npm_package_version:process.env.npm_package_version},readPackageVersion:bH0,readGitVersion:()=>yH0()}),Ob};var T7=D(()=>{yw$()});function AQ($){return $==="1"||$?.toLowerCase()==="true"}function Db($,J=process.env){return $.includes("--skip-ctrl-proxy-download")||$.includes("--skip-accessibility-download")||AQ(J.AUTOMOBILE_SKIP_CTRL_PROXY_DOWNLOAD)}var Ne="--skip-ctrl-proxy-download",DU="AUTOMOBILE_SKIP_CTRL_PROXY_DOWNLOAD";function m4($,J){if($ instanceof R)return $;let X=$ instanceof Error?$.message:String($);return new R(`${J}: ${X}`)}var R;var l4=D(()=>{R=class R extends Error{constructor($){super($)}}});import{promises as d2}from"fs";var cj,hw$,FU,qU,gw$,u_,uw$=async($)=>{await d2.mkdir($,{recursive:!0})};var wU=D(()=>{cj=d2.readFile,hw$=d2.writeFile,FU=d2.stat,qU=d2.readdir,gw$=d2.rename,u_=d2.unlink});import hH0 from"fs";import mw$ from"os";import Fb from"path";function uH0($=process.env,J=mw$.homedir()){let X=($.AUTOMOBILE_DATA_DIR??$.AUTO_MOBILE_DATA_DIR)?.trim();if(X&&X.length>0)return Fb.resolve(X);if(J&&J.length>0)return Fb.join(J,".auto-mobile");return Fb.join(mw$.tmpdir(),"auto-mobile")}function D9($){return Fb.join(uH0(),$)}function NU($){let J=D9($);return hH0.mkdirSync(J,{recursive:!0,mode:gH0}),J}var gH0=448,KJ;var MX=D(()=>{KJ={LOGS:"logs",TOOL_LOGS:"tool_logs",SCREENSHOTS:"screenshots",NAVIGATION_SCREENSHOTS:"navigation-screenshots",VIEW_HIERARCHY:"view_hierarchy",OBSERVE_RESULTS:"observe_results",TOOL_OUTPUTS:"tool_outputs",WINDOW:"window",CACHE:"cache",STATE:"state"}});import lw$ from"path";function mH0($){try{return process.kill($,0),!0}catch(J){return J?.code==="EPERM"}}function pw$($,J){return $===`${J}.log`||$.startsWith(`${J}-`)}function lH0($){let J=/^(?:stdio|server|daemon-launch)-(\d+)(?:-.*)?\.log$/.exec($);return J?Number(J[1]):void 0}async function cw$($){let J=$.now??Date.now(),X=$.isProcessAlive??mH0,Q;try{Q=await qU($.dir)}catch(G){$.logger?.debug(`log pruning skipped because the log directory could not be read: ${G}`,G);return}let Y=Q.filter((G)=>G.endsWith(".log")),W=Y.filter((G)=>pw$(G,$.ownPrefix)).sort();if(W.length>$.maxOwnFiles)for(let G of W.slice(0,W.length-$.maxOwnFiles))await u_(lw$.join($.dir,G)).catch(()=>{});for(let G of Y){if(pw$(G,$.ownPrefix))continue;let Z=lH0(G);if(Z===void 0)continue;if(X(Z))continue;let j=lw$.join($.dir,G);try{let V=await FU(j);if(J-V.mtimeMs>$.abandonedMaxAgeMs)await u_(j).catch(()=>{})}catch{}}}var dw$=D(()=>{wU()});var sw$={};m1(sw$,{sanitizeMessage:()=>Nb,safeStringify:()=>aw$,resolveProcessLogPrefix:()=>ow$,parseAutomobileLogLevel:()=>iw$,logger:()=>U,SENSITIVE_ENV_KEYS:()=>tw$,LogLevel:()=>RX});import o2 from"fs";import nw$ from"path";function iw$($){if($===void 0)return null;let J=$.trim().toLowerCase();if(J.length===0)return null;switch(J){case"debug":return RX.DEBUG;case"info":return RX.INFO;case"warn":case"warning":return RX.WARN;case"error":return RX.ERROR;case"none":case"silent":return RX.NONE;default:return null}}function ow$($,J){return $.includes("--daemon-mode")?"daemon":`stdio-${J}`}var RX,fB,Ae=!1,_e,qb=($)=>{_e=_e.then(()=>$)},vB,Me,n2,i2,pH0=10485760,cH0=10,dH0=86400000,rw$=()=>cw$({dir:vB,ownPrefix:Me,maxOwnFiles:cH0,abandonedMaxAgeMs:dH0}),nH0=async()=>{try{if(o2.existsSync(n2)){if((await FU(n2)).size>=pH0){i2.end();let J=new Date().toISOString().replace(/:/g,"-"),X=nw$.join(vB,`${Me}-${J}.log`);if(o2.existsSync(n2))await gw$(n2,X);i2=o2.createWriteStream(n2,{flags:"a"}),await rw$()}}}catch($){if(i2.destroyed||!i2.writable)i2=o2.createWriteStream(n2,{flags:"a"});console.error("Log rotation failed:",$)}},tw$,aw$=($)=>{if(typeof $!=="object"||$===null)return String($);return JSON.stringify($,(J,X)=>{if(typeof X==="object"&&X!==null){let Q={};for(let[Y,W]of Object.entries(X))if(!tw$.has(Y.toUpperCase()))Q[Y]=W;return Q}return X})},Nb=($)=>{return $.replace(/[\r\n\t]/g," ")},wb=async($,J,X)=>{try{await nH0();let Q=new Date().toISOString(),Y=Nb(J),W=`${Q} [${$}] ${Y}`;if(X.length>0){let Z=X.map((j)=>{if(typeof j==="object")return Nb(aw$(j));return Nb(String(j))}).join(" ");W+=` ${Z}`}if(W.length>1000)W=W.substring(0,1000)+"... (truncated)";let G=W.replace(/[\r\n\t]/g," ");if(i2.write(G+`
|
|
18
18
|
`),Ae)process.stdout.write(`${G}
|
|
19
|
-
`)}catch(Q){console.error("Failed to write log:",Q)}},U;var n=D(()=>{wU();MX();dw$();RX={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};fB=iw$(process.env.AUTOMOBILE_LOG_LEVEL)??RX.INFO,_e=Promise.resolve(),vB=D9(KJ.LOGS);if(!o2.existsSync(vB))o2.mkdirSync(vB,{recursive:!0});uw$(vB).catch(($)=>{console.error("Failed to create logs directory:",$)});Me=ow$(process.argv,process.pid),n2=nw$.join(vB,`${Me}.log`),i2=o2.createWriteStream(n2,{flags:"a"});rw$().catch(()=>{});tw$=new Set(["PASSWORD","TOKEN","SECRET","KEY","CREDENTIAL","AUTH","API_KEY","PRIVATE_KEY","ACCESS_TOKEN","REFRESH_TOKEN","CLIENT_SECRET","DATABASE_URL","DB_PASSWORD","GITHUB_TOKEN","NPM_TOKEN","AWS_SECRET_ACCESS_KEY"]),U={setLogLevel($){fB=$},getLogLevel(){return fB},enableStdoutLogging(){Ae=!0},disableStdoutLogging(){Ae=!1},debug($,...J){if(fB<=RX.DEBUG)qb(wb("DEBUG",$,J).catch((X)=>{console.error("Failed to write debug log:",X)}))},info($,...J){if(fB<=RX.INFO)qb(wb("INFO",$,J).catch((X)=>{console.error("Failed to write info log:",X)}))},warn($,...J){if(fB<=RX.WARN)qb(wb("WARN",$,J).catch((X)=>{console.error("Failed to write warn log:",X)}))},error($,...J){if(fB<=RX.ERROR)qb(wb("ERROR",$,J).catch((X)=>{console.error("Failed to write error log:",X)}))},async flush(){await _e},close(){i2.end()}}});var Re=o((ZC1,ew$)=>{ew$.exports={LOCHDR:30,LOCSIG:67324752,LOCVER:4,LOCFLG:6,LOCHOW:8,LOCTIM:10,LOCCRC:14,LOCSIZ:18,LOCLEN:22,LOCNAM:26,LOCEXT:28,EXTSIG:134695760,EXTHDR:16,EXTCRC:4,EXTSIZ:8,EXTLEN:12,CENHDR:46,CENSIG:33639248,CENVEM:4,CENVER:6,CENFLG:8,CENHOW:10,CENTIM:12,CENCRC:16,CENSIZ:20,CENLEN:24,CENNAM:28,CENEXT:30,CENCOM:32,CENDSK:34,CENATT:36,CENATX:38,CENOFF:42,ENDHDR:22,ENDSIG:101010256,ENDSUB:8,ENDTOT:10,ENDSIZ:12,ENDOFF:16,ENDCOM:20,END64HDR:20,END64SIG:117853008,END64START:4,END64OFF:8,END64NUMDISKS:16,ZIP64SIG:101075792,ZIP64HDR:56,ZIP64LEAD:12,ZIP64SIZE:4,ZIP64VEM:12,ZIP64VER:14,ZIP64DSK:16,ZIP64DSKDIR:20,ZIP64SUB:24,ZIP64TOT:32,ZIP64SIZB:40,ZIP64OFF:48,ZIP64EXTRA:56,STORED:0,SHRUNK:1,REDUCED1:2,REDUCED2:3,REDUCED3:4,REDUCED4:5,IMPLODED:6,DEFLATED:8,ENHANCED_DEFLATED:9,PKWARE:10,BZIP2:12,LZMA:14,IBM_TERSE:18,IBM_LZ77:19,AES_ENCRYPT:99,FLG_ENC:1,FLG_COMP1:2,FLG_COMP2:4,FLG_DESC:8,FLG_ENH:16,FLG_PATCH:32,FLG_STR:64,FLG_EFS:2048,FLG_MSK:4096,FILE:2,BUFFER:1,NONE:0,EF_ID:0,EF_SIZE:2,ID_ZIP64:1,ID_AVINFO:7,ID_PFS:8,ID_OS2:9,ID_NTFS:10,ID_OPENVMS:12,ID_UNIX:13,ID_FORK:14,ID_PATCH:15,ID_X509_PKCS7:20,ID_X509_CERTID_F:21,ID_X509_CERTID_C:22,ID_STRONGENC:23,ID_RECORD_MGT:24,ID_X509_PKCS7_RL:25,ID_IBM1:101,ID_IBM2:102,ID_POSZIP:18064,EF_ZIP64_OR_32:4294967295,EF_ZIP64_OR_16:65535,EF_ZIP64_SUNCOMP:0,EF_ZIP64_SCOMP:8,EF_ZIP64_RHO:16,EF_ZIP64_DSN:24}});var Ab=o((JN$)=>{var $N$={INVALID_LOC:"Invalid LOC header (bad signature)",INVALID_CEN:"Invalid CEN header (bad signature)",INVALID_END:"Invalid END header (bad signature)",DESCRIPTOR_NOT_EXIST:"No descriptor present",DESCRIPTOR_UNKNOWN:"Unknown descriptor format",DESCRIPTOR_FAULTY:"Descriptor data is malformed",NO_DATA:"Nothing to decompress",BAD_CRC:"CRC32 checksum failed {0}",FILE_IN_THE_WAY:"There is a file in the way: {0}",UNKNOWN_METHOD:"Invalid/unsupported compression method",AVAIL_DATA:"inflate::Available inflate data did not terminate",INVALID_DISTANCE:"inflate::Invalid literal/length or distance code in fixed or dynamic block",TO_MANY_CODES:"inflate::Dynamic block code description: too many length or distance codes",INVALID_REPEAT_LEN:"inflate::Dynamic block code description: repeat more than specified lengths",INVALID_REPEAT_FIRST:"inflate::Dynamic block code description: repeat lengths with no first length",INCOMPLETE_CODES:"inflate::Dynamic block code description: code lengths codes incomplete",INVALID_DYN_DISTANCE:"inflate::Dynamic block code description: invalid distance code lengths",INVALID_CODES_LEN:"inflate::Dynamic block code description: invalid literal/length code lengths",INVALID_STORE_BLOCK:"inflate::Stored block length did not match one's complement",INVALID_BLOCK_TYPE:"inflate::Invalid block type (type == 3)",CANT_EXTRACT_FILE:"Could not extract the file",CANT_OVERRIDE:"Target file already exists",DISK_ENTRY_TOO_LARGE:"Number of disk entries is too large",NO_ZIP:"No zip file was loaded",NO_ENTRY:"Entry doesn't exist",DIRECTORY_CONTENT_ERROR:"A directory cannot have content",FILE_NOT_FOUND:'File not found: "{0}"',NOT_IMPLEMENTED:"Not implemented",INVALID_FILENAME:"Invalid filename",INVALID_FORMAT:"Invalid or unsupported zip format. No END header found",INVALID_PASS_PARAM:"Incompatible password parameter",WRONG_PASSWORD:"Wrong Password",COMMENT_TOO_LONG:"Comment is too long",EXTRA_FIELD_PARSE_ERROR:"Extra field parsing error"};function iH0($){return function(...J){if(J.length)$=$.replace(/\{(\d)\}/g,(X,Q)=>J[Q]||"");return Error("ADM-ZIP: "+$)}}for(let $ of Object.keys($N$))JN$[$]=iH0($N$[$])});var GN$=o((VC1,WN$)=>{var oH0=N0("fs"),T9=N0("path"),XN$=Re(),rH0=Ab(),tH0=typeof process==="object"&&process.platform==="win32",QN$=($)=>typeof $==="object"&&$!==null,YN$=new Uint32Array(256).map(($,J)=>{for(let X=0;X<8;X++)if((J&1)!==0)J=3988292384^J>>>1;else J>>>=1;return J>>>0});function y8($){if(this.sep=T9.sep,this.fs=oH0,QN$($)){if(QN$($.fs)&&typeof $.fs.statSync==="function")this.fs=$.fs}}WN$.exports=y8;y8.prototype.makeDir=function($){let J=this;function X(Q){let Y=Q.split(J.sep)[0];Q.split(J.sep).forEach(function(W){if(!W||W.substr(-1,1)===":")return;Y+=J.sep+W;var G;try{G=J.fs.statSync(Y)}catch(Z){if(Z.message&&Z.message.startsWith("ENOENT"))J.fs.mkdirSync(Y);else throw Z}if(G&&G.isFile())throw rH0.FILE_IN_THE_WAY(`"${Y}"`)})}X($)};y8.prototype.writeFileTo=function($,J,X,Q){let Y=this;if(Y.fs.existsSync($)){if(!X)return!1;var W=Y.fs.statSync($);if(W.isDirectory())return!1}var G=T9.dirname($);if(!Y.fs.existsSync(G))Y.makeDir(G);var Z;try{Z=Y.fs.openSync($,"w",438)}catch(j){Y.fs.chmodSync($,438),Z=Y.fs.openSync($,"w",438)}if(Z)try{Y.fs.writeSync(Z,J,0,J.length,0)}finally{Y.fs.closeSync(Z)}return Y.fs.chmodSync($,Q||438),!0};y8.prototype.writeFileToAsync=function($,J,X,Q,Y){if(typeof Q==="function")Y=Q,Q=void 0;let W=this;W.fs.exists($,function(G){if(G&&!X)return Y(!1);W.fs.stat($,function(Z,j){if(G&&j&&j.isDirectory())return Y(!1);var V=T9.dirname($);W.fs.exists(V,function(K){if(!K)try{W.makeDir(V)}catch(L){return Y(!1)}let z=function(L){W.fs.write(L,J,0,J.length,0,function(H){W.fs.close(L,function(){if(H)return Y(!1);W.fs.chmod($,Q||438,function(){Y(!0)})})})};W.fs.open($,"w",438,function(L,H){if(L)W.fs.chmod($,438,function(){W.fs.open($,"w",438,function(O,B){if(O||!B)return Y(!1);z(B)})});else if(H)z(H);else Y(!1)})})})})};y8.prototype.findFiles=function($){let J=this;function X(Q,Y,W,G){if(typeof Y==="boolean")W=Y,Y=void 0;let Z=[];return J.fs.readdirSync(Q).forEach(function(j){let V=T9.join(Q,j),K=J.fs.statSync(V);if(!Y||Y.test(V))Z.push(T9.normalize(V)+(K.isDirectory()?J.sep:""));if(K.isDirectory()&&W){let z=J.fs.realpathSync(V);if(!G.has(z))G.add(z),Z=Z.concat(X(V,Y,W,G))}}),Z}return X($,void 0,!0,new Set([J.fs.realpathSync($)]))};y8.prototype.findFilesAsync=function($,J){let X=this,Q=[],Y=!1,W=function(Z){if(Y)return;Y=!0,J(Z,Z?void 0:Q)},G=function(Z,j,V){X.fs.readdir(Z,function(K,z){if(K)return V(K);let L=z.length;if(!L)return V();z.forEach(function(H){let O=T9.join(Z,H);X.fs.stat(O,function(B,F){if(B)return V(B);if(!F){if(!--L)V();return}if(Q.push(T9.normalize(O)+(F.isDirectory()?X.sep:"")),!F.isDirectory()){if(!--L)V();return}X.fs.realpath(O,function(A,_){if(A)return V(A);if(j.has(_)){if(!--L)V();return}j.add(_),G(O,j,function(w){if(w)return V(w);if(!--L)V()})})})})})};X.fs.realpath($,function(Z,j){if(Z)return W(Z);G($,new Set([j]),W)})};y8.prototype.getAttributes=function(){};y8.prototype.setAttributes=function(){};y8.crc32update=function($,J){return YN$[($^J)&255]^$>>>8};y8.crc32=function($){if(typeof $==="string")$=Buffer.from($,"utf8");let J=$.length,X=-1;for(let Q=0;Q<J;)X=y8.crc32update(X,$[Q++]);return~X>>>0};y8.methodToString=function($){switch($){case XN$.STORED:return"STORED ("+$+")";case XN$.DEFLATED:return"DEFLATED ("+$+")";default:return"UNSUPPORTED ("+$+")"}};y8.canonical=function($){if(!$)return"";let J=T9.posix.normalize("/"+$.split("\\").join("/"));return T9.join(".",J)};y8.zipnamefix=function($){if(!$)return"";let J=T9.posix.normalize("/"+$.split("\\").join("/"));return T9.posix.join(".",J)};y8.findLast=function($,J){if(!Array.isArray($))throw TypeError("arr is not array");let X=$.length>>>0;for(let Q=X-1;Q>=0;Q--)if(J($[Q],Q,$))return $[Q];return};y8.sanitize=function($,J){$=T9.resolve(T9.normalize($));var X=J.split("/");for(var Q=0,Y=X.length;Q<Y;Q++){var W=T9.normalize(T9.join($,X.slice(Q,Y).join(T9.sep)));if(W===$||W.startsWith($+T9.sep))return W}return T9.normalize(T9.join($,T9.basename(J)))};y8.toBuffer=function(J,X){if(Buffer.isBuffer(J))return J;else if(J instanceof Uint8Array)return Buffer.from(J);else return typeof J==="string"?X(J):Buffer.alloc(0)};y8.readBigUInt64LE=function($,J){let X=$.readUInt32LE(J);return $.readUInt32LE(J+4)*4294967296+X};y8.writeBigUInt64LE=function($,J,X){let Q=J>>>0,Y=Math.floor(J/4294967296)>>>0;$.writeUInt32LE(Q,X),$.writeUInt32LE(Y,X+4)};y8.fromDOS2Date=function($){return new Date(($>>25&127)+1980,Math.max(($>>21&15)-1,0),Math.max($>>16&31,1),$>>11&31,$>>5&63,($&31)<<1)};y8.fromDate2DOS=function($){let J=0,X=0;if($.getFullYear()>1979)J=($.getFullYear()-1980&127)<<9|$.getMonth()+1<<5|$.getDate(),X=$.getHours()<<11|$.getMinutes()<<5|$.getSeconds()>>1;return J<<16|X};y8.isWin=tH0;y8.crcTable=YN$});var jN$=o((KC1,ZN$)=>{var aH0=N0("path");ZN$.exports=function($,{fs:J}){var X=$||"",Q=W(),Y=null;function W(){return{directory:!1,readonly:!1,hidden:!1,executable:!1,mtime:0,atime:0}}if(X&&J.existsSync(X))Y=J.statSync(X),Q.directory=Y.isDirectory(),Q.mtime=Y.mtime,Q.atime=Y.atime,Q.executable=(73&Y.mode)!==0,Q.readonly=(128&Y.mode)===0,Q.hidden=aH0.basename(X)[0]===".";else console.warn("Invalid path: "+X);return{get directory(){return Q.directory},get readOnly(){return Q.readonly},get hidden(){return Q.hidden},get mtime(){return Q.mtime},get atime(){return Q.atime},get executable(){return Q.executable},decodeAttributes:function(){},encodeAttributes:function(){},toJSON:function(){return{path:X,isDirectory:Q.directory,isReadOnly:Q.readonly,isHidden:Q.hidden,isExecutable:Q.executable,mTime:Q.mtime,aTime:Q.atime}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var KN$=o((UC1,VN$)=>{VN$.exports={efs:!0,encode:($)=>Buffer.from($,"utf8"),decode:($)=>$.toString("utf8")}});var gB=o((zC1,hB)=>{hB.exports=GN$();hB.exports.Constants=Re();hB.exports.Errors=Ab();hB.exports.FileAttr=jN$();hB.exports.decoder=KN$()});var zN$=o((LC1,UN$)=>{var AU=gB(),x0=AU.Constants;UN$.exports=function(){var $=20,J=10,X=0,Q=0,Y=0,W=0,G=0,Z=0,j=0,V=0,K=0,z=0,L=0,H=0,O=0;$|=AU.isWin?2560:768,X|=x0.FLG_EFS;let B={extraLen:0},F=(w)=>Math.max(0,w)>>>0,A=(w)=>Math.max(0,w)&65535,_=(w)=>Math.max(0,w)&255;return Y=AU.fromDate2DOS(new Date),{get made(){return $},set made(w){$=w},get version(){return J},set version(w){J=w},get flags(){return X},set flags(w){X=w},get flags_efs(){return(X&x0.FLG_EFS)>0},set flags_efs(w){if(w)X|=x0.FLG_EFS;else X&=~x0.FLG_EFS},get flags_desc(){return(X&x0.FLG_DESC)>0},set flags_desc(w){if(w)X|=x0.FLG_DESC;else X&=~x0.FLG_DESC},get method(){return Q},set method(w){switch(w){case x0.STORED:this.version=10;break;case x0.DEFLATED:default:this.version=20}Q=w},get time(){return AU.fromDOS2Date(this.timeval)},set time(w){w=new Date(w),this.timeval=AU.fromDate2DOS(w)},get timeval(){return Y},set timeval(w){Y=F(w)},get timeHighByte(){return _(Y>>>8)},get crc(){return W},set crc(w){W=F(w)},get compressedSize(){return G},set compressedSize(w){G=F(w)},get size(){return Z},set size(w){Z=F(w)},get fileNameLength(){return j},set fileNameLength(w){j=w},get extraLength(){return V},set extraLength(w){V=w},get extraLocalLength(){return B.extraLen},set extraLocalLength(w){B.extraLen=w},get commentLength(){return K},set commentLength(w){K=w},get diskNumStart(){return z},set diskNumStart(w){z=F(w)},get inAttr(){return L},set inAttr(w){L=F(w)},get attr(){return H},set attr(w){H=F(w)},get fileAttr(){return(H||0)>>16&4095},get offset(){return O},set offset(w){O=F(w)},get encrypted(){return(X&x0.FLG_ENC)===x0.FLG_ENC},get centralHeaderSize(){return x0.CENHDR+j+V+K},get realDataOffset(){return O+x0.LOCHDR+B.fnameLen+B.extraLen},get localHeader(){return B},loadLocalHeaderFromBinary:function(w){var q=w.slice(O,O+x0.LOCHDR);if(q.readUInt32LE(0)!==x0.LOCSIG)throw AU.Errors.INVALID_LOC();B.version=q.readUInt16LE(x0.LOCVER),B.flags=q.readUInt16LE(x0.LOCFLG),B.flags_desc=(B.flags&x0.FLG_DESC)>0,B.method=q.readUInt16LE(x0.LOCHOW),B.time=q.readUInt32LE(x0.LOCTIM),B.crc=q.readUInt32LE(x0.LOCCRC),B.compressedSize=q.readUInt32LE(x0.LOCSIZ),B.size=q.readUInt32LE(x0.LOCLEN),B.fnameLen=q.readUInt16LE(x0.LOCNAM),B.extraLen=q.readUInt16LE(x0.LOCEXT);let M=O+x0.LOCHDR+B.fnameLen,C=M+B.extraLen;return w.slice(M,C)},loadFromBinary:function(w){if(w.length!==x0.CENHDR||w.readUInt32LE(0)!==x0.CENSIG)throw AU.Errors.INVALID_CEN();$=w.readUInt16LE(x0.CENVEM),J=w.readUInt16LE(x0.CENVER),X=w.readUInt16LE(x0.CENFLG),Q=w.readUInt16LE(x0.CENHOW),Y=w.readUInt32LE(x0.CENTIM),W=w.readUInt32LE(x0.CENCRC),G=w.readUInt32LE(x0.CENSIZ),Z=w.readUInt32LE(x0.CENLEN),j=w.readUInt16LE(x0.CENNAM),V=w.readUInt16LE(x0.CENEXT),K=w.readUInt16LE(x0.CENCOM),z=w.readUInt16LE(x0.CENDSK),L=w.readUInt16LE(x0.CENATT),H=w.readUInt32LE(x0.CENATX),O=w.readUInt32LE(x0.CENOFF)},localHeaderToBinary:function(){var w=Buffer.alloc(x0.LOCHDR);return w.writeUInt32LE(x0.LOCSIG,0),w.writeUInt16LE(J,x0.LOCVER),w.writeUInt16LE(X&~x0.FLG_DESC,x0.LOCFLG),w.writeUInt16LE(Q,x0.LOCHOW),w.writeUInt32LE(Y,x0.LOCTIM),w.writeUInt32LE(W,x0.LOCCRC),w.writeUInt32LE(G,x0.LOCSIZ),w.writeUInt32LE(Z,x0.LOCLEN),w.writeUInt16LE(j,x0.LOCNAM),w.writeUInt16LE(B.extraLen,x0.LOCEXT),w},centralHeaderToBinary:function(){var w=Buffer.alloc(x0.CENHDR+j+V+K);return w.writeUInt32LE(x0.CENSIG,0),w.writeUInt16LE($,x0.CENVEM),w.writeUInt16LE(J,x0.CENVER),w.writeUInt16LE(X&~x0.FLG_DESC,x0.CENFLG),w.writeUInt16LE(Q,x0.CENHOW),w.writeUInt32LE(Y,x0.CENTIM),w.writeUInt32LE(W,x0.CENCRC),w.writeUInt32LE(G,x0.CENSIZ),w.writeUInt32LE(Z,x0.CENLEN),w.writeUInt16LE(j,x0.CENNAM),w.writeUInt16LE(V,x0.CENEXT),w.writeUInt16LE(K,x0.CENCOM),w.writeUInt16LE(z,x0.CENDSK),w.writeUInt16LE(L,x0.CENATT),w.writeUInt32LE(H,x0.CENATX),w.writeUInt32LE(O,x0.CENOFF),w},toJSON:function(){let w=function(q){return q+" bytes"};return{made:$,version:J,flags:X,method:AU.methodToString(Q),time:this.time,crc:"0x"+W.toString(16).toUpperCase(),compressedSize:w(G),size:w(Z),fileNameLength:w(j),extraLength:w(V),commentLength:w(K),diskNumStart:z,inAttr:L,attr:H,offset:O,centralHeaderSize:w(x0.CENHDR+j+V+K)}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var HN$=o((HC1,LN$)=>{var _Q=gB(),z1=_Q.Constants;LN$.exports=function(){var $=0,J=0,X=0,Q=0,Y=0;let W=()=>$>z1.EF_ZIP64_OR_16||J>z1.EF_ZIP64_OR_16||X>z1.EF_ZIP64_OR_32||Q>z1.EF_ZIP64_OR_32;return{get diskEntries(){return $},set diskEntries(G){$=J=G},get totalEntries(){return J},set totalEntries(G){J=$=G},get size(){return X},set size(G){X=G},get offset(){return Q},set offset(G){Q=G},get commentLength(){return Y},set commentLength(G){Y=G},get mainHeaderSize(){return(W()?z1.ZIP64HDR+z1.END64HDR:0)+z1.ENDHDR+Y},loadFromBinary:function(G){if((G.length!==z1.ENDHDR||G.readUInt32LE(0)!==z1.ENDSIG)&&(G.length<z1.ZIP64HDR||G.readUInt32LE(0)!==z1.ZIP64SIG))throw _Q.Errors.INVALID_END();if(G.readUInt32LE(0)===z1.ENDSIG)$=G.readUInt16LE(z1.ENDSUB),J=G.readUInt16LE(z1.ENDTOT),X=G.readUInt32LE(z1.ENDSIZ),Q=G.readUInt32LE(z1.ENDOFF),Y=G.readUInt16LE(z1.ENDCOM);else $=_Q.readBigUInt64LE(G,z1.ZIP64SUB),J=_Q.readBigUInt64LE(G,z1.ZIP64TOT),X=_Q.readBigUInt64LE(G,z1.ZIP64SIZB),Q=_Q.readBigUInt64LE(G,z1.ZIP64OFF),Y=0},toBinary:function(){if(!W()){var G=Buffer.alloc(z1.ENDHDR+Y);return G.writeUInt32LE(z1.ENDSIG,0),G.writeUInt32LE(0,4),G.writeUInt16LE($,z1.ENDSUB),G.writeUInt16LE(J,z1.ENDTOT),G.writeUInt32LE(X,z1.ENDSIZ),G.writeUInt32LE(Q,z1.ENDOFF),G.writeUInt16LE(Y,z1.ENDCOM),G.fill(" ",z1.ENDHDR),G}var G=Buffer.alloc(this.mainHeaderSize);let Z=0;G.writeUInt32LE(z1.ZIP64SIG,Z),_Q.writeBigUInt64LE(G,z1.ZIP64HDR-z1.ZIP64LEAD,Z+z1.ZIP64SIZE),G.writeUInt16LE(45,Z+z1.ZIP64VEM),G.writeUInt16LE(45,Z+z1.ZIP64VER),G.writeUInt32LE(0,Z+z1.ZIP64DSK),G.writeUInt32LE(0,Z+z1.ZIP64DSKDIR),_Q.writeBigUInt64LE(G,$,Z+z1.ZIP64SUB),_Q.writeBigUInt64LE(G,J,Z+z1.ZIP64TOT),_Q.writeBigUInt64LE(G,X,Z+z1.ZIP64SIZB),_Q.writeBigUInt64LE(G,Q,Z+z1.ZIP64OFF);let j=Q+X;return Z+=z1.ZIP64HDR,G.writeUInt32LE(z1.END64SIG,Z),G.writeUInt32LE(0,Z+z1.END64START),_Q.writeBigUInt64LE(G,j,Z+z1.END64OFF),G.writeUInt32LE(1,Z+z1.END64NUMDISKS),Z+=z1.END64HDR,G.writeUInt32LE(z1.ENDSIG,Z),G.writeUInt32LE(0,Z+4),G.writeUInt16LE(Math.min($,z1.EF_ZIP64_OR_16),Z+z1.ENDSUB),G.writeUInt16LE(Math.min(J,z1.EF_ZIP64_OR_16),Z+z1.ENDTOT),G.writeUInt32LE(Math.min(X,z1.EF_ZIP64_OR_32),Z+z1.ENDSIZ),G.writeUInt32LE(Math.min(Q,z1.EF_ZIP64_OR_32),Z+z1.ENDOFF),G.writeUInt16LE(Y,Z+z1.ENDCOM),G.fill(" ",Z+z1.ENDHDR),G},toJSON:function(){let G=function(Z,j){let V=Z.toString(16).toUpperCase();while(V.length<j)V="0"+V;return"0x"+V};return{diskEntries:$,totalEntries:J,size:X+" bytes",offset:G(Q,4),commentLength:Y}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var Ee=o((sH0)=>{sH0.EntryHeader=zN$();sH0.MainHeader=HN$()});var BN$=o((BC1,ON$)=>{ON$.exports=function($){var J=N0("zlib"),X={chunkSize:(parseInt($.length/1024)+1)*1024};return{deflate:function(){return J.deflateRawSync($,X)},deflateAsync:function(Q){var Y=J.createDeflateRaw(X),W=[],G=0;Y.on("data",function(Z){W.push(Z),G+=Z.length}),Y.on("end",function(){var Z=Buffer.alloc(G),j=0;Z.fill(0);for(var V=0;V<W.length;V++){var K=W[V];K.copy(Z,j),j+=K.length}Q&&Q(Z)}),Y.end($)}}}});var FN$=o((DC1,DN$)=>{var JO0=+(process?.versions?.node??"").split(".")[0]||0;DN$.exports=function($,J){var X=N0("zlib");let Q=JO0>=15&&J>0?{maxOutputLength:J}:{};return{inflate:function(){return X.inflateRawSync($,Q)},inflateAsync:function(Y){var W=X.createInflateRaw(Q),G=[],Z=0;W.on("data",function(j){G.push(j),Z+=j.length}),W.on("end",function(){var j=Buffer.alloc(Z),V=0;j.fill(0);for(var K=0;K<G.length;K++){var z=G[K];z.copy(j,V),V+=z.length}Y&&Y(j)}),W.end($)}}}});var _N$=o((FC1,AN$)=>{var{randomFillSync:qN$}=N0("crypto"),XO0=Ab(),QO0=new Uint32Array(256).map(($,J)=>{for(let X=0;X<8;X++)if((J&1)!==0)J=J>>>1^3988292384;else J>>>=1;return J>>>0}),NN$=($,J)=>Math.imul($,J)>>>0,wN$=($,J)=>{return QO0[($^J)&255]^$>>>8},m_=()=>{if(typeof qN$==="function")return qN$(Buffer.alloc(12));else return m_.node()};m_.node=()=>{let $=Buffer.alloc(12),J=$.length;for(let X=0;X<J;X++)$[X]=Math.random()*256&255;return $};var _b={genSalt:m_};function Mb($){let J=Buffer.isBuffer($)?$:Buffer.from($);this.keys=new Uint32Array([305419896,591751049,878082192]);for(let X=0;X<J.length;X++)this.updateKeys(J[X])}Mb.prototype.updateKeys=function($){let J=this.keys;return J[0]=wN$(J[0],$),J[1]+=J[0]&255,J[1]=NN$(J[1],134775813)+1,J[2]=wN$(J[2],J[1]>>>24),$};Mb.prototype.next=function(){let $=(this.keys[2]|2)>>>0;return NN$($,$^1)>>8&255};function YO0($){let J=new Mb($);return function(X){let Q=Buffer.alloc(X.length),Y=0;for(let W of X)Q[Y++]=J.updateKeys(W^J.next());return Q}}function WO0($){let J=new Mb($);return function(X,Q,Y=0){if(!Q)Q=Buffer.alloc(X.length);for(let W of X){let G=J.next();Q[Y++]=W^G,J.updateKeys(W)}return Q}}function GO0($,J,X){if(!$||!Buffer.isBuffer($)||$.length<12)return Buffer.alloc(0);let Q=YO0(X),Y=Q($.slice(0,12)),W=(J.flags&8)===8?J.timeHighByte:J.crc>>>24;if(Y[11]!==W)throw XO0.WRONG_PASSWORD();return Q($.slice(12))}function ZO0($){if(Buffer.isBuffer($)&&$.length>=12)_b.genSalt=function(){return $.slice(0,12)};else if($==="node")_b.genSalt=m_.node;else _b.genSalt=m_}function jO0($,J,X,Q=!1){if($==null)$=Buffer.alloc(0);if(!Buffer.isBuffer($))$=Buffer.from($.toString());let Y=WO0(X),W=_b.genSalt();if(W[11]=J.crc>>>24&255,Q)W[10]=J.crc>>>16&255;let G=Buffer.alloc($.length+12);return Y(W,G),Y($,G,12)}AN$.exports={decrypt:GO0,encrypt:jO0,_salter:ZO0}});var MN$=o((VO0)=>{VO0.Deflater=BN$();VO0.Inflater=FN$();VO0.ZipCrypto=_N$()});var Te=o((wC1,RN$)=>{var z8=gB(),LO0=Ee(),EX=z8.Constants,Pe=MN$();RN$.exports=function($,J){var X=new LO0.EntryHeader,Q=Buffer.alloc(0),Y=Buffer.alloc(0),W=!1,G=null,Z=Buffer.alloc(0),j=Buffer.alloc(0),V=!0;let K=$,z=typeof K.decoder==="object"?K.decoder:z8.decoder;V=z.hasOwnProperty("efs")?z.efs:!1;function L(){if(!J||!(J instanceof Uint8Array))return Buffer.alloc(0);return j=X.loadLocalHeaderFromBinary(J),J.slice(X.realDataOffset,X.realDataOffset+X.compressedSize)}function H(w){let q=X.flags_desc||X.localHeader.flags_desc?X.crc:X.localHeader.crc;return z8.crc32(w)===q}function O(w,q,M){if(typeof q>"u"&&typeof w==="string")M=w,w=void 0;if(W){if(w&&q)q(Buffer.alloc(0),z8.Errors.DIRECTORY_CONTENT_ERROR());return Buffer.alloc(0)}var C=L();if(C.length===0){if(w&&q)q(C);return C}if(X.encrypted){if(typeof M!=="string"&&!Buffer.isBuffer(M))throw z8.Errors.INVALID_PASS_PARAM();C=Pe.ZipCrypto.decrypt(C,X,M)}var y;switch(X.method){case z8.Constants.STORED:if(y=Buffer.alloc(C.length),C.copy(y),!H(y)){if(w&&q)q(y,z8.Errors.BAD_CRC());throw z8.Errors.BAD_CRC()}else{if(w&&q)q(y);return y}case z8.Constants.DEFLATED:var I=new Pe.Inflater(C,X.size);if(!w){if(y=I.inflate(),!H(y))throw z8.Errors.BAD_CRC(`"${z.decode(Q)}"`);return y}else I.inflateAsync(function(d){if(q)if(!H(d))q(d,z8.Errors.BAD_CRC());else q(d)});break;default:if(w&&q)q(Buffer.alloc(0),z8.Errors.UNKNOWN_METHOD());throw z8.Errors.UNKNOWN_METHOD()}}function B(w,q){if((!G||!G.length)&&Buffer.isBuffer(J)){if(w&&q)q(L());return L()}if(G.length&&!W){var M;switch(X.method){case z8.Constants.STORED:if(X.compressedSize=X.size,M=Buffer.alloc(G.length),G.copy(M),w&&q)q(M);return M;default:case z8.Constants.DEFLATED:var C=new Pe.Deflater(G);if(!w){var y=C.deflate();return X.compressedSize=y.length,y}else C.deflateAsync(function(I){M=Buffer.alloc(I.length),X.compressedSize=I.length,I.copy(M),q&&q(M)});C=null;break}}else if(w&&q)q(Buffer.alloc(0));else return Buffer.alloc(0)}function F(w,q){return z8.readBigUInt64LE(w,q)}function A(w){try{var q=0,M,C,y;while(q+4<w.length)if(M=w.readUInt16LE(q),q+=2,C=w.readUInt16LE(q),q+=2,y=w.slice(q,q+C),q+=C,EX.ID_ZIP64===M)_(y)}catch(I){throw z8.Errors.EXTRA_FIELD_PARSE_ERROR()}}function _(w){var q,M,C,y;if(w.length>=EX.EF_ZIP64_SCOMP){if(q=F(w,EX.EF_ZIP64_SUNCOMP),X.size===EX.EF_ZIP64_OR_32)X.size=q}if(w.length>=EX.EF_ZIP64_RHO){if(M=F(w,EX.EF_ZIP64_SCOMP),X.compressedSize===EX.EF_ZIP64_OR_32)X.compressedSize=M}if(w.length>=EX.EF_ZIP64_DSN){if(C=F(w,EX.EF_ZIP64_RHO),X.offset===EX.EF_ZIP64_OR_32)X.offset=C}if(w.length>=EX.EF_ZIP64_DSN+4){if(y=w.readUInt32LE(EX.EF_ZIP64_DSN),X.diskNumStart===EX.EF_ZIP64_OR_16)X.diskNumStart=y}}return{get entryName(){return z.decode(Q)},get rawEntryName(){return Q},set entryName(w){Q=z8.toBuffer(w,z.encode);var q=Q[Q.length-1];W=q===47||q===92,X.fileNameLength=Q.length},get efs(){if(typeof V==="function")return V(this.entryName);else return V},get extra(){return Z},set extra(w){Z=w,X.extraLength=w.length,A(w)},get comment(){return z.decode(Y)},set comment(w){if(Y=z8.toBuffer(w,z.encode),X.commentLength=Y.length,Y.length>65535)throw z8.Errors.COMMENT_TOO_LONG()},get name(){let w=z.decode(Q);return W?w.replace(/[/\\]$/,"").split("/").pop():w.split("/").pop()},get isDirectory(){return W},getCompressedData:function(){return B(!1,null)},getCompressedDataAsync:function(w){B(!0,w)},setData:function(w){if(G=z8.toBuffer(w,z8.decoder.encode),!W&&G.length)X.size=G.length,X.method=z8.Constants.DEFLATED,X.crc=z8.crc32(w),X.changed=!0;else X.method=z8.Constants.STORED},getData:function(w){if(X.changed)return G;else return O(!1,null,w)},getDataAsync:function(w,q){if(X.changed)w(G);else O(!0,w,q)},set attr(w){X.attr=w},get attr(){return X.attr},set header(w){X.loadFromBinary(w)},get header(){return X},packCentralHeader:function(){X.flags_efs=this.efs,X.extraLength=Z.length;var w=X.centralHeaderToBinary(),q=z8.Constants.CENHDR;return Q.copy(w,q),q+=Q.length,Z.copy(w,q),q+=X.extraLength,Y.copy(w,q),w},packLocalHeader:function(){let w=0;X.flags_efs=this.efs,X.extraLocalLength=j.length;let q=X.localHeaderToBinary(),M=Buffer.alloc(q.length+Q.length+X.extraLocalLength);return q.copy(M,w),w+=q.length,Q.copy(M,w),w+=Q.length,j.copy(M,w),w+=j.length,M},toJSON:function(){let w=function(q){return"<"+(q&&q.length+" bytes buffer"||"null")+">"};return{entryName:this.entryName,name:this.name,comment:this.comment,isDirectory:this.isDirectory,header:X.toJSON(),compressedData:w(J),data:w(G)}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var TN$=o((NC1,PN$)=>{var EN$=Te(),HO0=Ee(),c5=gB();PN$.exports=function($,J){var X=[],Q=Object.create(null),Y=Buffer.alloc(0),W=new HO0.MainHeader,G=!1,Z=null;let j=new Set,V=J,{noSort:K,decoder:z}=V;if($)O(V.readEntries);else G=!0;function L(){let F=new Set;for(let A of Object.keys(Q)){let _=A.split("/");if(_.pop(),!_.length)continue;for(let w=0;w<_.length;w++){let q=_.slice(0,w+1).join("/")+"/";F.add(q)}}for(let A of F)if(!(A in Q)){let _=new EN$(V);_.entryName=A,_.attr=16,_.temporary=!0,X.push(_),Q[_.entryName]=_,j.add(_)}}function H(){if(G=!0,Q=Object.create(null),W.diskEntries>($.length-W.offset)/c5.Constants.CENHDR)throw c5.Errors.DISK_ENTRY_TOO_LARGE();X=Array(W.diskEntries);var F=W.offset;for(var A=0;A<X.length;A++){var _=F,w=new EN$(V,$);if(w.header=$.slice(_,_+=c5.Constants.CENHDR),w.entryName=$.slice(_,_+=w.header.fileNameLength),w.header.extraLength)w.extra=$.slice(_,_+=w.header.extraLength);if(w.header.commentLength)w.comment=$.slice(_,_+w.header.commentLength);F+=w.header.centralHeaderSize,X[A]=w,Q[w.entryName]=w}j.clear(),L()}function O(F){var A=$.length-c5.Constants.ENDHDR,_=Math.max(0,A-65535),w=_,q=$.length,M=-1,C=0;if(typeof V.trailingSpace==="boolean"?V.trailingSpace:!1)_=0;for(A;A>=w;A--){if($[A]!==80)continue;if($.readUInt32LE(A)===c5.Constants.ENDSIG){M=A,C=A,q=A+c5.Constants.ENDHDR,w=A-c5.Constants.END64HDR;continue}if($.readUInt32LE(A)===c5.Constants.END64SIG){w=_;continue}if($.readUInt32LE(A)===c5.Constants.ZIP64SIG){M=A,q=A+c5.readBigUInt64LE($,A+c5.Constants.ZIP64SIZE)+c5.Constants.ZIP64LEAD;break}}if(M==-1)throw c5.Errors.INVALID_FORMAT();if(W.loadFromBinary($.slice(M,q)),W.commentLength)Y=$.slice(C+c5.Constants.ENDHDR);if(F)H()}function B(){if(X.length>1&&!K)X=X.map((F)=>({entry:F,key:F.entryName.toLowerCase()})).sort((F,A)=>F.key.localeCompare(A.key)).map((F)=>F.entry)}return{get entries(){if(!G)H();return X.filter((F)=>!j.has(F))},get comment(){return z.decode(Y)},set comment(F){Y=c5.toBuffer(F,z.encode),W.commentLength=Y.length},getEntryCount:function(){if(!G)return W.diskEntries;return X.length},forEach:function(F){this.entries.forEach(F)},getEntry:function(F){if(!G)H();return Q[F]||null},setEntry:function(F){if(!G)H();X.push(F),Q[F.entryName]=F,W.totalEntries=X.length},deleteFile:function(F,A=!0){if(!G)H();let _=Q[F];this.getEntryChildren(_,A).map((q)=>q.entryName).forEach(this.deleteEntry)},deleteEntry:function(F){if(!G)H();let A=Q[F],_=X.indexOf(A);if(_>=0)X.splice(_,1),delete Q[F],W.totalEntries=X.length},getEntryChildren:function(F,A=!0){if(!G)H();if(typeof F==="object")if(F.isDirectory&&A){let _=[],w=F.entryName;for(let q of X)if(q.entryName.startsWith(w))_.push(q);return _}else return[F];return[]},getChildCount:function(F){if(F&&F.isDirectory){let A=this.getEntryChildren(F);return A.includes(F)?A.length-1:A.length}return 0},compressToBuffer:function(){if(!G)H();B();let F=[],A=[],_=0,w=0;W.size=0,W.offset=0;let q=0;for(let y of this.entries){let I=y.getCompressedData();y.header.offset=w;let d=y.packLocalHeader(),u=d.length+I.length;w+=u,F.push(d),F.push(I);let r=y.packCentralHeader();A.push(r),W.size+=r.length,_+=u+r.length,q++}_+=W.mainHeaderSize,W.offset=w,W.totalEntries=q,w=0;let M=Buffer.alloc(_);for(let y of F)y.copy(M,w),w+=y.length;for(let y of A)y.copy(M,w),w+=y.length;let C=W.toBinary();if(Y)Y.copy(C,C.length-Y.length);return C.copy(M,w),$=M,G=!1,M},toAsyncBuffer:function(F,A,_,w){try{if(!G)H();B();let q=[],M=[],C=0,y=0,I=0;W.size=0,W.offset=0;let d=function(u){if(u.length>0){let r=u.shift(),a=r.entryName+r.extra.toString();if(_)_(a);r.getCompressedDataAsync(function(Y$){if(w)w(a);r.header.offset=y;let J$=r.packLocalHeader(),L$=J$.length+Y$.length;y+=L$,q.push(J$),q.push(Y$);let O$=r.packCentralHeader();M.push(O$),W.size+=O$.length,C+=L$+O$.length,I++,d(u)})}else{C+=W.mainHeaderSize,W.offset=y,W.totalEntries=I,y=0;let r=Buffer.alloc(C);q.forEach(function(Y$){Y$.copy(r,y),y+=Y$.length}),M.forEach(function(Y$){Y$.copy(r,y),y+=Y$.length});let a=W.toBinary();if(Y)Y.copy(a,a.length-Y.length);a.copy(r,y),$=r,G=!1,F(r)}};d(Array.from(this.entries))}catch(q){A(q)}}}}});var l_=o((AC1,SN$)=>{var e8=gB(),s8=N0("path"),OO0=Te(),BO0=TN$(),r2=(...$)=>e8.findLast($,(J)=>typeof J==="boolean"),CN$=(...$)=>e8.findLast($,(J)=>typeof J==="string"),DO0=(...$)=>e8.findLast($,(J)=>typeof J==="function"),FO0={noSort:!1,readEntries:!1,method:e8.Constants.NONE,fs:null};SN$.exports=function($,J){let X=null,Q=Object.assign(Object.create(null),FO0);if($&&typeof $==="object"){if(!($ instanceof Uint8Array)){if(Object.assign(Q,$),$=Q.input?Q.input:void 0,Q.input)delete Q.input}if(Buffer.isBuffer($))X=$,Q.method=e8.Constants.BUFFER,$=void 0}Object.assign(Q,J);let Y=new e8(Q),W=(O)=>{O.filter((B)=>B.attr).sort((B,F)=>F.path.length-B.path.length).forEach((B)=>Y.fs.chmodSync(B.path,B.attr))};if(typeof Q.decoder!=="object"||typeof Q.decoder.encode!=="function"||typeof Q.decoder.decode!=="function")Q.decoder=e8.decoder;if($&&typeof $==="string")if(Y.fs.existsSync($))Q.method=e8.Constants.FILE,Q.filename=$,X=Y.fs.readFileSync($);else throw e8.Errors.INVALID_FILENAME();let G=new BO0(X,Q),{canonical:Z,sanitize:j,zipnamefix:V}=e8;function K(O){if(O&&G){var B;if(typeof O==="string")B=G.getEntry(s8.posix.normalize(O));if(typeof O==="object"&&typeof O.entryName<"u"&&typeof O.header<"u")B=G.getEntry(O.entryName);if(B)return B}return null}function z(O){let{join:B,normalize:F,sep:A}=s8.posix;return B(s8.isAbsolute(O)?"/":".",F(A+O.split("\\").join(A)+A))}function L(O){if(O instanceof RegExp)return function(B){return function(F){return B.test(F)}}(O);else if(typeof O!=="function")return()=>!0;return O}let H=(O,B)=>{let F=B.slice(-1);return F=F===Y.sep?Y.sep:"",s8.relative(O,B)+F};return{readFile:function(O,B){var F=K(O);return F&&F.getData(B)||null},childCount:function(O){let B=K(O);if(B)return G.getChildCount(B)},readFileAsync:function(O,B){var F=K(O);if(F)F.getDataAsync(B);else B(null,"getEntry failed for:"+O)},readAsText:function(O,B){var F=K(O);if(F){var A=F.getData();if(A&&A.length)return A.toString(B||"utf8")}return""},readAsTextAsync:function(O,B,F){var A=K(O);if(A)A.getDataAsync(function(_,w){if(w){B(_,w);return}if(_&&_.length)B(_.toString(F||"utf8"));else B("")});else B("")},deleteFile:function(O,B=!0){var F=K(O);if(F)G.deleteFile(F.entryName,B)},deleteEntry:function(O){var B=K(O);if(B)G.deleteEntry(B.entryName)},addZipComment:function(O){G.comment=O},getZipComment:function(){return G.comment||""},addZipEntryComment:function(O,B){var F=K(O);if(F)F.comment=B},getZipEntryComment:function(O){var B=K(O);if(B)return B.comment||"";return""},updateFile:function(O,B){var F=K(O);if(F)F.setData(B)},addLocalFile:function(O,B,F,A){if(Y.fs.existsSync(O)){B=B?z(B):"";let _=s8.win32.basename(s8.win32.normalize(O));B+=F?F:_;let w=Y.fs.statSync(O),q=w.isFile()?Y.fs.readFileSync(O):Buffer.alloc(0);if(w.isDirectory())B+=Y.sep;this.addFile(B,q,A,w)}else throw e8.Errors.FILE_NOT_FOUND(O)},addLocalFileAsync:function(O,B){O=typeof O==="object"?O:{localPath:O};let F=s8.resolve(O.localPath),{comment:A}=O,{zipPath:_,zipName:w}=O,q=this;Y.fs.stat(F,function(M,C){if(M)return B(M,!1);_=_?z(_):"";let y=s8.win32.basename(s8.win32.normalize(F));if(_+=w?w:y,C.isFile())Y.fs.readFile(F,function(I,d){if(I)return B(I,!1);return q.addFile(_,d,A,C),setImmediate(B,void 0,!0)});else if(C.isDirectory())return _+=Y.sep,q.addFile(_,Buffer.alloc(0),A,C),setImmediate(B,void 0,!0)})},addLocalFolder:function(O,B,F){if(F=L(F),B=B?z(B):"",O=s8.normalize(O),Y.fs.existsSync(O)){let A=Y.findFiles(O),_=this;if(A.length)for(let w of A){let q=s8.join(B,H(O,w));if(F(q))_.addLocalFile(w,s8.dirname(q))}}else throw e8.Errors.FILE_NOT_FOUND(O)},addLocalFolderAsync:function(O,B,F,A){A=L(A),F=F?z(F):"",O=s8.normalize(O);var _=this;Y.fs.open(O,"r",function(w){if(w&&w.code==="ENOENT")B(void 0,e8.Errors.FILE_NOT_FOUND(O));else if(w)B(void 0,w);else{var q=Y.findFiles(O),M=-1,C=function(){if(M+=1,M<q.length){var y=q[M],I=H(O,y).split("\\").join("/");if(I=I.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^\x20-\x7E]/g,""),A(I))Y.fs.stat(y,function(d,u){if(d)B(void 0,d);if(u.isFile())Y.fs.readFile(y,function(r,a){if(r)B(void 0,r);else _.addFile(F+I,a,"",u),C()});else _.addFile(F+I+"/",Buffer.alloc(0),"",u),C()});else process.nextTick(()=>{C()})}else B(!0,void 0)};C()}})},addLocalFolderAsync2:function(O,B){let F=this;O=typeof O==="object"?O:{localPath:O};let A=s8.resolve(z(O.localPath)),{zipPath:_,filter:w,namefix:q}=O;if(w instanceof RegExp)w=function(y){return function(I){return y.test(I)}}(w);else if(typeof w!=="function")w=function(){return!0};if(_=_?z(_):"",q==="latin1")q=(y)=>y.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^\x20-\x7E]/g,"");if(typeof q!=="function")q=(y)=>y;let M=(y)=>s8.join(_,q(H(A,y))),C=(y)=>s8.win32.basename(s8.win32.normalize(q(y)));Y.fs.open(A,"r",function(y){if(y&&y.code==="ENOENT")B(void 0,e8.Errors.FILE_NOT_FOUND(A));else if(y)B(void 0,y);else Y.findFilesAsync(A,function(I,d){if(I)return B(I);if(d=d.filter((u)=>w(M(u))),!d.length)B(void 0,!1);setImmediate(d.reverse().reduce(function(u,r){return function(a,Y$){if(a||Y$===!1)return setImmediate(u,a,!1);F.addLocalFileAsync({localPath:r,zipPath:s8.dirname(M(r)),zipName:C(r)},u)}},B))})})},addLocalFolderPromise:function(O,B){return new Promise((F,A)=>{this.addLocalFolderAsync2(Object.assign({localPath:O},B),(_,w)=>{if(_)A(_);if(w)F(this)})})},addFile:function(O,B,F,A){O=V(O);let _=K(O),w=_!=null;if(!w)_=new OO0(Q),_.entryName=O;_.comment=F||"";let q=typeof A==="object"&&A instanceof Y.fs.Stats;if(q)_.header.time=A.mtime;var M=_.isDirectory?16:0;let C=_.isDirectory?16384:32768;if(q)C|=4095&A.mode;else if(typeof A==="number")C|=4095&A;else C|=_.isDirectory?493:420;if(M=(M|C<<16)>>>0,_.attr=M,_.setData(B),!w)G.setEntry(_);return _},getEntries:function(O){return G.password=O,G?G.entries:[]},getEntry:function(O){return K(O)},getEntryCount:function(){return G.getEntryCount()},forEach:function(O){return G.forEach(O)},extractEntryTo:function(O,B,F,A,_,w){A=r2(!1,A),_=r2(!1,_),F=r2(!0,F),w=CN$(_,w);var q=K(O);if(!q)throw e8.Errors.NO_ENTRY();var M=Z(q.entryName),C=j(B,w&&!q.isDirectory?Z(w):F?M:s8.basename(M));if(q.isDirectory){var y=G.getEntryChildren(q);return y.forEach(function(u){if(u.isDirectory)return;var r=u.getData();if(!r)throw e8.Errors.CANT_EXTRACT_FILE();var a=Z(F?u.entryName:u.entryName.substring(q.entryName.length)),Y$=j(B,a);let J$=_?u.header.fileAttr:void 0;Y.writeFileTo(Y$,r,A,J$)}),!0}var I=q.getData(G.password);if(!I)throw e8.Errors.CANT_EXTRACT_FILE();if(Y.fs.existsSync(C)&&!A)throw e8.Errors.CANT_OVERRIDE();let d=_?O.header.fileAttr:void 0;return Y.writeFileTo(C,I,A,d),!0},test:function(O){if(!G)return!1;for(var B of G.entries)try{if(B.isDirectory)continue;var F=B.getData(O);if(!F)return!1}catch(A){return!1}return!0},extractAllTo:function(O,B,F,A){if(F=r2(!1,F),A=CN$(F,A),B=r2(!1,B),!G)throw e8.Errors.NO_ZIP();let _=[];G.entries.forEach(function(w){var q=j(O,Z(w.entryName));if(w.isDirectory){if(Y.makeDir(q),F)_.push({path:q,attr:w.header.fileAttr});return}var M=w.getData(A);if(!M)throw e8.Errors.CANT_EXTRACT_FILE();let C=F?w.header.fileAttr:void 0;Y.writeFileTo(q,M,B,C);try{Y.fs.utimesSync(q,w.header.time,w.header.time)}catch(y){}}),W(_)},extractAllToAsync:function(O,B,F,A){if(A=DO0(B,F,A),F=r2(!1,F),B=r2(!1,B),!A)return new Promise((I,d)=>{this.extractAllToAsync(O,B,F,function(u){if(u)d(u);else I(this)})});if(!G){A(e8.Errors.NO_ZIP());return}O=s8.resolve(O);let _=(I)=>j(O,s8.normalize(Z(I.entryName))),w=(I,d)=>Error(I+': "'+d+'"'),q=[],M=[];G.entries.forEach((I)=>{if(I.isDirectory)q.push(I);else M.push(I)});let C=[];for(let I of q){let d=_(I),u=F?I.header.fileAttr:void 0;try{Y.makeDir(d)}catch(r){A(w("Unable to create folder",d));continue}if(u)C.push({path:d,attr:u});try{Y.fs.utimesSync(d,I.header.time,I.header.time)}catch(r){}}let y=(I)=>{if(!I)try{W(C)}catch(d){return A(w("Unable to set folder permissions",d.path||""))}A(I)};M.reverse().reduce(function(I,d){return function(u){if(u)I(u);else{let r=s8.normalize(Z(d.entryName)),a=j(O,r);d.getDataAsync(function(Y$,J$){if(J$)I(J$);else if(!Y$)I(e8.Errors.CANT_EXTRACT_FILE());else{let L$=F?d.header.fileAttr:void 0;Y.writeFileToAsync(a,Y$,B,L$,function(O$){if(!O$)return I(w("Unable to write file",a));Y.fs.utimes(a,d.header.time,d.header.time,function(){I()})})}})}}},y)()},writeZip:function(O,B){if(arguments.length===1){if(typeof O==="function")B=O,O=""}if(!O&&Q.filename)O=Q.filename;if(!O)return;var F=G.compressToBuffer();if(F){var A=Y.writeFileTo(O,F,!0);if(typeof B==="function")B(!A?Error("failed"):null,"")}},writeZipPromise:function(O,B){let{overwrite:F,perm:A}=Object.assign({overwrite:!0},B);return new Promise((_,w)=>{if(!O&&Q.filename)O=Q.filename;if(!O)w("ADM-ZIP: ZIP File Name Missing");this.toBufferPromise().then((q)=>{let M=(C)=>C?_(C):w("ADM-ZIP: Wasn't able to write zip file");Y.writeFileToAsync(O,q,F,A,M)},w)})},toBufferPromise:function(){return new Promise((O,B)=>{G.toAsyncBuffer(O,B)})},toBuffer:function(O,B,F,A){if(typeof O==="function")return G.toAsyncBuffer(O,B,F,A),null;return G.compressToBuffer()}}}});function IN$($,J,X=z5){if(X.length===0)return"";let Y=$.trim().toLowerCase()===U5?X[0]:X.find((W)=>W.version===$);if(!Y)return"";return J==="android"?Y.apkSha256:Y.ipaSha256}function Eb($=process.env,J=z5){if(J.length===0)return;let X=Z4($);return X===U5?J[0]:J.find((Q)=>Q.version===X)}function Se($=process.env,J=z5){return Eb($,J)?.runnerSha256??""}function kN$($=process.env,J=z5){return Eb($,J)?.runnerSha256Target??"runner"}function qO0($=z5){if($.length===0)return U5;return $[0].version}function C9($,J=z5){if($===U5)return qO0(J);return $}function AO0($){let J=$[xN$];return J==="1"||J?.toLowerCase()==="true"}function Ie($,J,X=process.env){let Q;try{Q=new URL($)}catch{throw new R(`${J} must be an absolute URL, for example https://mirror.example/auto-mobile.`)}if(Q.protocol==="https:")return;if(AO0(X))return;throw new R(`${J} must use https:// (got ${Q.protocol}//). Plaintext/non-TLS asset downloads are a confidentiality and downgrade risk. Set ${xN$}=1 to opt out for a trusted loopback/dev mirror.`)}function Z4($=process.env){let J=$[NO0]?.trim();if(!J||J.length===0)return U5;return J.toLowerCase()===U5?U5:J}function dj($=process.env){return Z4($)!==U5}function t2($=process.env,J=z5){let X=Z4($);if(X===U5)return J.length>0;return J.some((Q)=>Q.version===X)}function Pb($=process.env){let J=$[Rb]?.trim();if(J&&J.length>0){let X;try{X=new URL(J)}catch{throw new R(`${Rb} must be an absolute URL, for example https://mirror.example/auto-mobile.`)}if(J.includes("?")||J.includes("#"))throw new R(`${Rb} must not include a query string or fragment; use a path-only base URL such as ${X.origin}${X.pathname.replace(/\/+$/,"")}.`);return Ie(`${X.origin}${X.pathname}`,Rb,$),`${X.origin}${X.pathname}`.replace(/\/+$/,"")}return Ce}function Tb($,J,X=Ce,Q=z5){let Y=C9(J,Q);if(Y===U5){if(X===Ce)return`https://github.com/kaeawc/auto-mobile/releases/latest/download/${$}`;return`${X}/latest/${$}`}return`${X}/${Y}/${$}`}function nj($=process.env,J=z5){return Tb("control-proxy-debug.apk",Z4($),Pb($),J)}function a2($=process.env,J=z5){return Tb("control-proxy.ipa",Z4($),Pb($),J)}function _U($=process.env){return IN$(Z4($),"android")}function s2($=process.env){return IN$(Z4($),"ios")}function bN$($=process.env,J=z5){return Tb(_O0,Z4($),Pb($),J)}function yN$($=process.env,J=z5){return Eb($,J)?.videoJarSha256??""}function fN$($=process.env,J=z5){return Tb(ke,Z4($),Pb($),J)}function vN$($=process.env,J=z5){return Eb($,J)?.screenCaptureHelperSha256??""}function C7($=process.env){return`${wO0}@${C9(Z4($))}`}var U5="latest",z5,wO0="@kaeawc/auto-mobile",NO0="AUTOMOBILE_VERSION",Rb="AUTOMOBILE_ASSET_BASE_URL",xN$="AUTOMOBILE_ALLOW_INSECURE_ASSET_URL",Ce="https://github.com/kaeawc/auto-mobile/releases/download",_O0="automobile-video.jar",ke="screen-capture-helper-macos-universal.zip",MC1,RC1,EC1,PC1,Cb="",TC1;var IJ=D(()=>{l4();z5=[{version:"0.0.57",apkSha256:"97595fe23177ce5c8e44b7a50a1061ea5804797764fee0062dd5553720e4894c",ipaSha256:"13c3b995c2ac6f32cbc9f7f56fe97335025d570a5b9a968aa14b5ccf8e1d129f",runnerSha256:"898af838e3c5e41576dc2cd98dd46d059fe690c7a3db27306bf6c4f62d493f17",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"bd230276077391a5e97a2034e950c03714f8798bab8c94f5ce7bdd56cd70b585"},{version:"0.0.56",apkSha256:"cf3d479a44637ec2b8c05888207b5e3a20fb7f67f0706ac65c2274beb61ab944",ipaSha256:"621c6cdeb6d9e88b04072f9daf7f955051129be16fddd1c3828620a47e4aaa37",runnerSha256:"31094d3e12b1678252bbc27170e3d2a4c38818cea6b3c10e6cfbadf1e6051761",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"41c42eb5896e09f33ca2d09ef712217ef59cbd5f7b4abc2df812e77fc463bed5"},{version:"0.0.55",apkSha256:"c12f8f5d47a252c3128d5f71bcae56fb586c6c34c573fc6d5f7a2d19e108c6c8",ipaSha256:"73560b76e2dcb707ff0a0724214deb77bdceedebfbffb7ebd02d5942a48661da",runnerSha256:"c56afd1de9fa4fc8bee260b8c73b8da61eefd931e42330c906982fb8796ac00f",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"7d97186fca4d74a223a027a563e96d7879248f17979ead5bdf68c927522a9c3b"},{version:"0.0.54",apkSha256:"75289f35aa378d5bf335c9f4479f94012ebd3c20987ea47cb8ab961de38712d2",ipaSha256:"2810e3752c7fe1d3bf018f4ed34679a8b9aca6d696e0f4699b1ba74d8e5c2c38",runnerSha256:"4a0541207649738137b1c9f249496bbb8f22e8fcea09a0bea22f419716a6123f",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"2e2f4ede42ebc510fb9997c36e0838ee67e09ca93e18d7dedf68a91635413753"},{version:"0.0.53",apkSha256:"90abd8d18acb664e4bca01f0ff3c6b62356bf38c422850c5e81cea02a99aba83",ipaSha256:"f59df4678c2d92b9c0572599e4babdffa3125343cf49f74a47b97635131ae003",runnerSha256:"be40cd445514b83a9d5fae54cbd1688fc5f20292d2f70f8016a473644d371b72",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"038046ef2f043729f9cf38f1bdc7d7bbe6070a919759105a5470df2c0fb14fb3"},{version:"0.0.52",apkSha256:"b733c267e42d4af3b24ba15ae7c94393cdf775018c3167deb13d06f33c6d5124",ipaSha256:"f8c9d00607dfc9c25bd7ee3de785f5a0f7e516ee90c6a7209ae5af9129063be5",runnerSha256:"7573432ea9c86c29acec30662ad7512cdb299150bc607350c7e3361882577f1c",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"f15e2bc4f4b2fece0daa85cb3fa3acbfcd08318cc420fc0637b469cd078d34b8"},{version:"0.0.51",apkSha256:"e9da610303113dd13094b3f885090b846f5b8705ac203b09deeb267801049255",ipaSha256:"db5606723087f7b973893d4adefcdeb6aadf1da0e2bcc435ce1fe8787bafb712",runnerSha256:"abba47298118068aaad3b8ea4502d685263b6e83cd2c30bb0518840cb8443202",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"a46ec61cdd2c3ab64e0f621f3498726578e52bee407d16cd90cde32ca8164798"},{version:"0.0.50",apkSha256:"8007f267d566144d805d29d22fb0e69790d34edcdbdd0d444bad6d80175943e2",ipaSha256:"838025a37b8a9f0d15b0b1ad06ff40e5a2b0b3e09eeca845f9a874d3bac4030d",runnerSha256:"5e53b1614986f90b875e5ada0a8c97f5343c22e70bdaeafd9a8389e5b6ef78ae",runnerSha256Target:"xctest",videoJarSha256:"254d1bad102a96b1e8e90ee9ff6ff991aa6d65f7a36a35c3887db91f369ea12e",screenCaptureHelperSha256:"965a49653d0c8bc8a88d45e1919ef0a62267d6774c50579411076dbe397bb89d"},{version:"0.0.49",apkSha256:"c1023110ebbd12c012880b08be6715d2389294fd24c4a147a40d1d342ec473da",ipaSha256:"dbeacd346a39976414432964de1250a3f356baf783cd3a83d916f0117e772d5b",runnerSha256:"fc033a529c67d373c6eca965ec063343b6164628d62e14eca220385810427ae6",runnerSha256Target:"xctest",videoJarSha256:"254d1bad102a96b1e8e90ee9ff6ff991aa6d65f7a36a35c3887db91f369ea12e",screenCaptureHelperSha256:"67079809a52e3cad50a38f04e4e25d795c0756b35352b377ba9609bebb62ab0f"},{version:"0.0.48",apkSha256:"059162e622fbe25bce40b32658c9749318a909eb8b48398648c77a84cf3c25aa",ipaSha256:"86558163f69a0bf36e69546dbf685d16d8f3bf05385f1f7795a164e3a5fddf96",runnerSha256:"ff000ff053a57a1dac1d552463e474fdea5346acb08c96051695554e73428317",runnerSha256Target:"xctest",videoJarSha256:"1cada2f3bc86cacbed76efc8e46c1e110cb0b046036502b422d67cce0725cf4b",screenCaptureHelperSha256:"f284e9863cedb2e02de25f526114fd4017eece1ce1e19337210647c7b49d1898"},{version:"0.0.47",apkSha256:"aa50a056447337ca14c251795b064e792879a28d088fe484fe57893a020b9323",ipaSha256:"ef5d10dd97d78d8e372680fffbb511335781b03ffbf0c91e2692048da4c5f143",runnerSha256:"078375d34d3e8bfa0c3171e3f1a6558d0ca2c0ca1f0c5999cb49077934fbfc0a",runnerSha256Target:"xctest",videoJarSha256:"5e3760d04436af89ec909586bd244d79cd7acec9b84993f4302fa7bf480916cb",screenCaptureHelperSha256:"501e1253ded9fa2f331051b88013b47ca37343a1966fc106d4fcaa5e9bbe4c39"},{version:"0.0.46",apkSha256:"00771c13f372baff325c659e2b40050e72951fd8adfc395cff667850a2a9b376",ipaSha256:"ef353a4f14fa7615810de891595d118ff193d43fcc940f936f4d11ae311dd563",screenCaptureHelperSha256:"da7e138266156eedda9f8cb98bb7d5b63f29ad28746a1c144a16122a1639e2b2",runnerSha256:"b0eb970aad424d1c0dd84261c26d74b8c95570ba0f3866f18f1755586184c51a",runnerSha256Target:"xctest",videoJarSha256:"3f3135e22fffed1e088bd434545eec873a5aec48c7c038cd2ffecdeb6b642c06"},{version:"0.0.45",apkSha256:"68dbf04ba3c1871da0ed9ec540e1dbfec08610dd2afc1706d4a7fd94d1c3b5b1",ipaSha256:"8c678b2d7ae4b5c25400f8fd53cb5e1f12d730950e0eef4e608dfb8b50dcd773",runnerSha256:"bb5234ca32636506e5b8e02662381895eaedeefbcf007598e3ee9b9ac3c501b5",runnerSha256Target:"xctest",videoJarSha256:"bae314fbaa3f3101ab5f7ba5eddc9bd77bb927c54cb508d38ed04ca9544b9a51"},{version:"0.0.44",apkSha256:"e95f2b14e218bc51e92a44680cf38ceca9c9143014b2f74b803f47650614cf39",ipaSha256:"73dd4551ef7226d67a46423f6925775fc10d68198913b5b23bc1cbdceb50b663",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.43",apkSha256:"7e4e2ce3c19b7473d171433186dbc7487df60ff6045dba66da7a320d31e63cd3",ipaSha256:"db0e3c4c172681068ae7ae24182f5569519b5fab034fbcf0e85abdc952b398dd",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.42",apkSha256:"cb00a835f58ce2d0344483f27b7c35036bb6faa973aa3fcc66fe67e75428abb0",ipaSha256:"de55b77ee0e821b4f08b7cd1b84f9a2706f69279422901546e2dc6fdd4cc3f0f",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.41",apkSha256:"ee1dff240e4dfc89b016197c80e929797485aa23292e061eee361b7404c772b4",ipaSha256:"01eaedef0cfcf38acd0a1fa8eebe08c3009e5db59320b23a045cd26506eb235c",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.40",apkSha256:"8e89fbab6462ac1ead1f3f0a334aff4f5f299e7ae72e192045cf75e893ca87aa",ipaSha256:"38adaed641ac6a8590773682e127a80a86c54e5804d47394e1b0cd437009b9ff",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.39",apkSha256:"eaad59dd85e17c4633098b772b9f761f2124ffb73a5ca7ede703a9b435046942",ipaSha256:"87a720544c83718e5b70c987aecf30d2e43bdb0f23163ac75ac225bb4aec0ae4",runnerSha256:""},{version:"0.0.38",apkSha256:"0fb955a617654695036642662634d042c2e3d278b8e1dce20ccb37e425f059f3",ipaSha256:"f5a4a485ff8ebf3bfd0d73c8b7b10769177b419ccd62e48db188bb5122a2fcde",runnerSha256:""},{version:"0.0.37",apkSha256:"f9b0cc92bf8f7416cdb0c458e16c7a41e4fdeefb80bb9429ab7c603388c99083",ipaSha256:"caccbfaa4da0015bab701a36b81ac87e3f3f3330cee77bb10ec8553724275f4f",runnerSha256:""},{version:"0.0.36",apkSha256:"b5f56bb0ab065c60385a22013c97ee706213eb16deb5d4bcfa42f0a707b8620a",ipaSha256:"40e973dc8c87149e40a616658c74d90e648c6514cc642a5c3dd4a45a187e7600",runnerSha256:""},{version:"0.0.35",apkSha256:"039b359bcf35f1ab6cc666005a57823d71a771a96bd9bcaf4f82f2ec945e306d",ipaSha256:"e6afdfd04a90d2388dc4604e7957d3eef87b90a51ca37c5457b8139a54728108",runnerSha256:""},{version:"0.0.34",apkSha256:"4dcee4f6a7359847d081c5e184c57ed100ad135af2e62f3abfc7b0defaa1153c",ipaSha256:"c2a26ca065c85e9f8d5cfcd6dbad1dbaf3ce38b18d770b0983f7bad62129e4a3",runnerSha256:""},{version:"0.0.33",apkSha256:"7289eba90b22890d3c36e05e99db72a545fa4becdf46df079885783a919e6aed",ipaSha256:"425dfa4db4ad5a4febc9f05ffc97df38f3a1098ccdd9330adff1c0b5c877697d",runnerSha256:""},{version:"0.0.32",apkSha256:"4c4a743af5d18ed58214e64b85986c9e2f2332b015edcf7d9d68a24cd6dfda21",ipaSha256:"40f4d9084d3368995b57c0e81c4fe85f38851353da9f789eaff93027aee456a0",runnerSha256:""},{version:"0.0.31",apkSha256:"0b5802ada8d9adccdb69ee140ae788b3251832c0605d2f6baa3e9b7a78260764",ipaSha256:"e60f8689fb6ddd5c06a5d2ff57569b264f407229afb986258d1ce20326dc24c7",runnerSha256:""},{version:"0.0.30",apkSha256:"a1be5e6240f204ee99540e99cc198f7c0b592dbaf3699330c14f6ded7d333ec3",ipaSha256:"5ac285dd5be16439d3a8a8973c98606920461acfce489830e54ee20759a7b235",runnerSha256:""},{version:"0.0.29",apkSha256:"b33a67c7efa84aca2b07faa965aecb3b1819b4defd441dcc8d3bf7e2af209cd8",ipaSha256:"d47c1aea4495270c1489cae361286ea1439c2ba4e7d5bcfd73f66e4580a6c45d",runnerSha256:""},{version:"0.0.28",apkSha256:"0f683d5939bc308afe038ea1259eb29997dff38af0795136a281ad305986e40e",ipaSha256:"eee7accfbca717bb8b89fafd0676f10d8bb08561c3fbd7a04750c9b12c2a7104",runnerSha256:""},{version:"0.0.27",apkSha256:"9966113ae44f38f3cf34544b1375d3c9a3706701edba45a1eec1f220b9c676cc",ipaSha256:"8620de6b014df18465876334f9ba8c106292f6c3059370eea2349f1e44db4f4d",runnerSha256:""},{version:"0.0.26",apkSha256:"2eb2f156fd27602c85003ab8f6e00d3e06850e84f5453d75b7494aa5bbed7be0",ipaSha256:"905df276d2224d31cbc5aa2258d2dcc60eaeb9813727081ddd32c95394fec411",runnerSha256:""},{version:"0.0.25",apkSha256:"f727079edb4906e3b7928dbb641e788543e86b11fff3fc1b76f0c51b9c8d6e5d",ipaSha256:"d8032cc1cebcb456b7232aa67fc42c89ff62729bacf141aa8f594ce6f8bcd980",runnerSha256:""},{version:"0.0.24",apkSha256:"9047795bc6098f4ec687c126123c73c423806a9fd52888af391d6fb5b94ac93f",ipaSha256:"1dd3e0370cb8ed01d8e1020558d8a2808f208bd947bafcf6688211eddc928bf8",runnerSha256:""},{version:"0.0.18",apkSha256:"fd3c8d9f0b8542eaad56c78b18cf8e5666367b04ae8c4af74d8aa6dd1c8d1834",ipaSha256:"2a5eec63bce2f9dfc227c0732fcce67378305e945604d5eedd0e3df48e37fd39",runnerSha256:""},{version:"0.0.17",apkSha256:"916033440931666644474f227c8e39d13d9c80c3515e4292cc5581fd5bd4cc2f",ipaSha256:"e4dcf064d024f2371b8fd79281000e2d49751ef95b8817d1494d685aeda746ac",runnerSha256:""}];MC1=nj({}),RC1=_U({}),EC1=a2({}),PC1=s2({}),TC1=Se({})});import{createReadStream as MO0}from"fs";import{createHash as RO0}from"crypto";class d5{async computeFileSha256($){let J=RO0("sha256");return await new Promise((X,Q)=>{let Y=MO0($);Y.on("data",(W)=>J.update(W)),Y.on("error",Q),Y.on("end",()=>X())}),{checksum:J.digest("hex"),source:"node"}}}var MU=()=>{};import{AsyncLocalStorage as EO0}from"async_hooks";var hN$,uB=async($,J)=>{return hN$.run({signal:$},J)},PX=()=>{return hN$.getStore()?.signal};var ij=D(()=>{hN$=new EO0});import{execFile as PO0}from"child_process";import{createWriteStream as TO0}from"fs";import*as uN$ from"fs/promises";import CO0 from"http";import SO0 from"https";import*as mN$ from"path";import{promisify as IO0}from"util";class DY{async download($,J,X){if(X??=PX(),X?.aborted)throw Error(`Download aborted before starting: ${$}`);await uN$.mkdir(mN$.dirname(J),{recursive:!0});try{await this.downloadWithCurl($,J,X);return}catch(Q){if(!this.isCommandUnavailable(Q,"curl"))throw Q;U.warn("[FileDownloader] curl unavailable, falling back to wget",{error:Q instanceof Error?Q.message:String(Q)})}try{await this.downloadWithWget($,J,X);return}catch(Q){if(!this.isCommandUnavailable(Q,"wget"))throw Q;U.warn("[FileDownloader] wget unavailable, falling back to Node HTTP",{error:Q instanceof Error?Q.message:String(Q)})}await this.downloadWithNodeHttp($,J,0,X)}async downloadWithCurl($,J,X){await gN$("curl",["--fail","--location","--retry","3","--retry-delay","1","--silent","--show-error","-o",J,$],{timeout:120000,maxBuffer:10485760,signal:X})}async downloadWithWget($,J,X){await gN$("wget",["--tries=3","--timeout=30","-O",J,$],{timeout:120000,maxBuffer:10485760,signal:X})}async downloadWithNodeHttp($,J,X,Q){if(X>5)throw Error(`Too many redirects while downloading ${$}`);await new Promise((Y,W)=>{let G=$.startsWith("https:")?SO0:CO0,Z=()=>{j.destroy(Error(`Download aborted: ${$}`))},j=G.get($,{headers:{"User-Agent":"auto-mobile"}},(V)=>{let K=V.statusCode??0;if(K>=300&&K<400&&V.headers.location){V.resume();let L=new URL(V.headers.location,$).toString();this.downloadWithNodeHttp(L,J,X+1,Q).then(Y).catch(W);return}if(K<200||K>=300){V.resume(),W(Error(`Download failed with status ${K} from ${$}`));return}let z=TO0(J);V.pipe(z),z.on("finish",()=>z.close(()=>Y())),z.on("error",(L)=>{z.close(),W(L)})});if(j.setTimeout(30000,()=>{j.destroy(Error(`Download request timed out for ${$}`))}),j.on("error",W),j.once("close",()=>Q?.removeEventListener("abort",Z)),Q?.addEventListener("abort",Z,{once:!0}),Q?.aborted)Z()})}isCommandUnavailable($,J){if(!$||typeof $!=="object")return!1;let X=$,Q=typeof X.code==="number"?X.code:Number(X.code);if(X.code==="ENOENT"||!Number.isNaN(Q)&&Q===127)return!0;let Y=`${X.message??""} ${X.stderr??""}`.toLowerCase();if(Y.includes("command not found")||Y.includes("not recognized as an internal or external command")||Y.includes(`${J}: not found`)||Y.includes(`not found: ${J}`))return!0;return!1}}var gN$;var mB=D(()=>{n();ij();gN$=IO0(PO0)});import{setTimeout as kO0}from"timers/promises";class lB{async sleep($){return kO0($)}setTimeout($,J){return global.setTimeout($,J)}clearTimeout($){global.clearTimeout($)}setInterval($,J){return global.setInterval($,J)}clearInterval($){global.clearInterval($)}now(){return Date.now()}}var g;var U$=D(()=>{g=new lB});import*as L5 from"fs/promises";import Sb from"path";class S7{static instance=null;static expectedChecksumOverride=null;downloader;checksumCalculator;cacheDir;usesDefaultCacheDir;timer;env;inFlight=null;constructor($={}){this.downloader=$.downloader??new DY,this.checksumCalculator=$.checksumCalculator??new d5,this.timer=$.timer??g,this.env=$.env??process.env,this.usesDefaultCacheDir=$.cacheDir===void 0,this.cacheDir=$.cacheDir??D9(pN$)}static getInstance(){if(S7.instance===null)S7.instance=new S7;return S7.instance}static resetInstances(){S7.instance=null,S7.expectedChecksumOverride=null}static setExpectedChecksumForTesting($){S7.expectedChecksumOverride=$}async computeLocalJarIntegrity($){let[{checksum:J},X]=await Promise.all([this.checksumCalculator.computeFileSha256($),L5.stat($)]);return{sha256:J.toLowerCase(),size:X.size}}get cachedJarPath(){return Sb.join(this.cacheDir,cN$)}get metadataPath(){return Sb.join(this.cacheDir,dN$)}expectedChecksum(){return S7.expectedChecksumOverride??yN$(this.env)}async ensure(){if(this.inFlight!==null)return this.inFlight;return this.inFlight=this.doEnsure().finally(()=>{this.inFlight=null}),this.inFlight}async doEnsure(){let $=this.expectedChecksum();if($.length===0)return U.info("[VIDEO_JAR] Expected checksum unknown for the pinned version; returning null without touching the network (jar is integrity-unverifiable)"),null;let J=await this.tryCache($);if(J)return U.info("[VIDEO_JAR] Reusing verified cached jar",{path:J}),J;return this.download($)}async tryCache($){let J;try{J=JSON.parse(await L5.readFile(this.metadataPath,"utf8"))}catch(Q){return U.debug(`[VIDEO_JAR] No usable cache metadata (cache miss): ${Q}`),null}if(J.sha256.toLowerCase()!==$.toLowerCase())return null;let X;try{X=await L5.stat(this.cachedJarPath)}catch(Q){return U.debug(`[VIDEO_JAR] Cached jar file missing despite metadata: ${Q}`),null}if(X.size!==J.size)return U.warn("[VIDEO_JAR] Cached jar size differs from sidecar; will re-download",{expected:J.size,actual:X.size}),null;return this.cachedJarPath}async ensureSecureCacheDir(){if(this.usesDefaultCacheDir)return NU(pN$);return await L5.mkdir(this.cacheDir,{recursive:!0,mode:xO0}),this.cacheDir}async download($){let J=bN$(this.env),X=await this.ensureSecureCacheDir(),Q=Sb.join(X,cN$),Y=`${Q}.download`;U.info("[VIDEO_JAR] Downloading persistent-encoder jar",{url:J,destination:Y});try{await this.downloader.download(J,Y),await L5.chmod(Y,lN$);let{checksum:W}=await this.checksumCalculator.computeFileSha256(Y);if(W.toLowerCase()!==$.toLowerCase())throw new R(`video-server jar checksum verification failed. Expected: ${$}, Got: ${W}. The downloaded automobile-video.jar does not match the pinned release checksum; this indicates a corrupted or tampered download and is never silently accepted.`);if(!this.hasClassesDex(Y))throw new R("video-server jar is not a valid zip containing classes.dex (truncated or error-page download).");let{size:G}=await L5.stat(Y);return await L5.rename(Y,Q),await this.writeMetadata(X,W,G),U.info("[VIDEO_JAR] Downloaded, verified, and cached jar",{path:Q,sha256:W}),Q}catch(W){throw await L5.rm(Y,{force:!0}).catch(()=>{}),W}}async writeMetadata($,J,X){let Q={version:Z4(this.env),sha256:J,size:X,downloadedAt:this.timer.now()};await L5.writeFile(Sb.join($,dN$),JSON.stringify(Q,null,2),{encoding:"utf8",mode:lN$})}hasClassesDex($){try{return new nN$.default($).getEntries().some((X)=>X.entryName===bO0)}catch(J){return U.warn("[VIDEO_JAR] Structural check failed (not a valid zip)",{path:$,error:J instanceof Error?J.message:String(J)}),!1}}}var nN$,lN$=384,xO0=448,pN$="video-server",cN$="automobile-video.jar",dN$="video-server-jar.json",bO0="classes.dex";var Ib=D(()=>{IJ();l4();MU();mB();n();U$();MX();nN$=f1(l_(),1)});function $9($){return $===!0||$==="true"}function iN$($){return $===!1||$==="false"}function xe($){return typeof $==="string"&&yO0.has($)}var yO0;var be=D(()=>{yO0=new Set(["done","go","search","send"])});function FY($){if(!$)return null;let{nativeScale:J,pixelWidth:X,pixelHeight:Q}=$;if(typeof J!=="number"||!Number.isFinite(J)||J<=0||typeof X!=="number"||!Number.isFinite(X)||X<=0||typeof Q!=="number"||!Number.isFinite(Q)||Q<=0)return null;return{nativeScale:J,pixelWidth:X,pixelHeight:Q}}function p_($){return FY($)??{}}var ye="immediate";var r$=D(()=>{l4();be()});function rN$($){return $==="main"?"4d002a":"42e02a"}function pB($,J){return Math.ceil($/16)*Math.ceil(J/16)}function tN$($){return $.length>=4&&($[0]&31)===7?$.subarray(1,4).toString("hex"):void 0}function fO0($){let J=tN$($);return J?Number.parseInt(J.slice(4,6),16):void 0}function aN$($,J="constrained-baseline"){let X=tN$($);if(X&&!ve(X,J))return{compatible:!1,reason:`H.264 SPS profile ${X.slice(0,4)} is incompatible with negotiated ${J}.`};let Q=fO0($);if(Q!==void 0&&Q>42)return{compatible:!1,reason:`H.264 SPS level ${Q} exceeds negotiated level 42.`};return{compatible:!0}}function ve($,J){return J==="main"?hO0($):vO0($)}function vO0($){return Number.parseInt($.slice(0,2),16)===66}function hO0($){return Number.parseInt($.slice(0,2),16)===77}var oN$="constrained-baseline",fe=42,eW=8192;class c_{chunks=[];headOffset=0;length=0;append($){if($.length===0)return;this.chunks.push($),this.length+=$.length}peek($){if($>this.length)throw RangeError(`cannot peek ${$} bytes from ${this.length}-byte queue`);let J=this.chunks[0];if(J.length-this.headOffset>=$)return J.subarray(this.headOffset,this.headOffset+$);let Q=Buffer.allocUnsafe($);return this.copyTo(Q,$),Q}takeDetached($){if($>this.length)throw RangeError(`cannot take ${$} bytes from ${this.length}-byte queue`);let J=Buffer.allocUnsafe($);return this.copyTo(J,$),this.discard($),J}discard($){if($>this.length)throw RangeError(`cannot discard ${$} bytes from ${this.length}-byte queue`);let J=$;while(J>0){let Q=this.chunks[0].length-this.headOffset;if(J<Q){this.headOffset+=J,this.length-=J;return}this.chunks.shift(),this.headOffset=0,this.length-=Q,J-=Q}}toBuffer(){if(this.length===0)return Buffer.alloc(0);let $=this.chunks[0];if(this.chunks.length===1)return $.subarray(this.headOffset);let J=Buffer.allocUnsafe(this.length);return this.copyTo(J,this.length),J}replace($){this.chunks=$.length===0?[]:[$],this.headOffset=0,this.length=$.length}copyTo($,J){let X=0;for(let Q=0;X<J;Q++){let Y=this.chunks[Q],W=Q===0?this.headOffset:0,G=Y.length-W,Z=Math.min(G,J-X);Y.copy($,X,W,W+Z),X+=Z}}}class xb{buffer=new c_;pendingHeader=null;highWaterMarkBytes=0;resynchronizing=!1;push($,J,X,Q,Y){let W=[],G=0;while(G<$.length){let Z=RU+kb-this.buffer.length;if(Z===0){if(!this.decodeAvailable(W,J,X,Q,Y))throw Error("FrameDecoder reached its raw-frame buffer limit without a complete frame");continue}let j=Math.min($.length,G+Z);this.buffer.append($.subarray(G,j)),this.highWaterMarkBytes=Math.max(this.highWaterMarkBytes,this.buffer.length),G=j,this.decodeAvailable(W,J,X,Q,Y)}return W}getMetrics(){return{bufferedBytes:this.buffer.length,highWaterMarkBytes:this.highWaterMarkBytes,maxBufferedBytes:RU+kb}}decodeAvailable($,J,X,Q,Y){let W=!1;while(!0){if(this.resynchronizing&&!this.resynchronize())return W;if(this.pendingHeader===null){let V=this.takeHeader(J);if(V==="starved")return W;if(V==="malformed"){W=!0;continue}this.pendingHeader=V,W=!0}let G=this.pendingHeader,Z=cO0(G);if(this.buffer.length<Z)return W;let j=this.buffer.takeDetached(Z);this.emitRecord(G,j,$,X,Q,Y),this.pendingHeader=null,W=!0}}emitRecord($,J,X,Q,Y,W){if(ue($)){Q?.({pcm16le:J});return}if(me($)){W?.({keyframe:($.height&pO0)!==0,presentationTimestampMs:$.timestampMs,payload:J});return}let G={header:$,pixels:J};if(Y)Y(G);else X.push(G)}takeHeader($){if(this.buffer.length<RU)return"starved";let J=this.buffer.peek(RU),X=eN$(J,0);if(X)return this.resynchronizing=!0,$?.({reason:X,header:ge(J,0)}),"malformed";let Q=ge(J,0);return this.buffer.discard(RU),Q}resynchronize(){let $=this.buffer.toBuffer(),J=0;while(J<=$.length-he.length){let X=$.indexOf(he,J);if(X<0)break;if(X+RU>$.length)return this.replaceBuffer($.subarray(X)),!1;if(eN$($,X)===null)return this.replaceBuffer($.subarray(X)),this.resynchronizing=!1,!0;J=X+1}return this.replaceBuffer($.subarray(Math.max(0,$.length-(he.length-1)))),!1}replaceBuffer($){this.buffer.replace($.length===0?Buffer.alloc(0):Buffer.from($))}}function ue($){return $.width===0&&$.height===8000&&$.bytesPerRow===1}function me($){return $.width===0&&($.height&XA$)>>>0===JA$}function cO0($){if(ue($))return $.timestampMs;if(me($))return $.bytesPerRow;return $.height*$.bytesPerRow}function ge($,J){return{width:$.readUInt32LE(J+8),height:$.readUInt32LE(J+12),bytesPerRow:$.readUInt32LE(J+16),timestampMs:$.readUInt32LE(J+20)}}function eN$($,J){if($.readUInt32LE(J)!==$A$)return"header_magic_mismatch";if($.readUInt32LE(J+4)!==QA$($.subarray(J+gO0,J+RU)))return"header_checksum_mismatch";return dO0(ge($,J))}function dO0($){if(ue($))return $.timestampMs>mO0?"audio_payload_too_large":null;if(me($))return $.bytesPerRow>lO0?"encoded_video_payload_too_large":null;if($.width===0)return"header_width_zero";if($.height===0)return"header_height_zero";if($.bytesPerRow<$.width*4)return"header_bytes_per_row_too_small";if($.width>sN$||$.height>sN$)return"header_dimensions_out_of_range";if($.bytesPerRow>$.width*4+uO0)return"header_bytes_per_row_too_large";if($.height*$.bytesPerRow>kb)return"header_payload_too_large";return null}function iO0(){let $=new Uint32Array(256);for(let J=0;J<256;J++){let X=J;for(let Q=0;Q<8;Q++)X=(X&1)!==0?3988292384^X>>>1:X>>>1;$[J]=X>>>0}return $}function QA$($){let J=4294967295;for(let X=0;X<$.length;X++)J=J>>>8^nO0[(J^$[X])&255];return(J^4294967295)>>>0}var $A$=826690881,he,RU=24,gO0=8,sN$=16384,uO0=4096,kb=33554432,mO0=16777216,lO0=16777216,JA$=3798204416,XA$=4294967294,pO0=1,nO0;var le=D(()=>{he=Buffer.from([65,77,70,49]);nO0=iO0()});class cB{options;pending=null;droppedFrames=0;highWaterMarkBytes=0;lastCaptureTimestampMs=null;constructor($){this.options=$}enqueue($){if(this.lastCaptureTimestampMs=$.header.timestampMs,$.pixels.length>this.options.maxFrameBytes)return this.droppedFrames++,!1;if(this.pending!==null)this.droppedFrames++;return this.pending={frame:$,enqueuedAtMs:this.options.now()},this.highWaterMarkBytes=Math.max(this.highWaterMarkBytes,$.pixels.length),!0}take(){let $=this.pending;return this.pending=null,$?.frame??null}clear($=!1){if($&&this.pending!==null)this.droppedFrames++;this.pending=null}metrics(){let $=this.pending;return{captureTimestampMs:$?.frame.header.timestampMs??this.lastCaptureTimestampMs,frameAgeMs:$===null?null:Math.max(0,this.options.now()-$.enqueuedAtMs),queueDepth:$===null?0:1,droppedFrames:this.droppedFrames,bytesQueued:$?.frame.pixels.length??0,highWaterMarkBytes:this.highWaterMarkBytes,maxFrameBytes:this.options.maxFrameBytes}}}import{spawn as oO0}from"child_process";import{EventEmitter as rO0}from"events";function tO0($){let J=$.trim();if(!J.startsWith(ne))return null;let X=J.slice(ne.length).trim();return X.length>0?X:null}function aO0($){let J=$.trim();if(!J.startsWith(d_))return null;let X=J.slice(d_.length).trim();return X==="screen-recording"?X:null}function sO0($){let J=$.trim();if(!J.startsWith(dB))return null;let X=J.slice(dB.length).trim();return X.length>0?X:null}function eO0($){if(!$.startsWith(de))return null;try{let J=JSON.parse($.slice(de.length));if(!$B0(J))return null;return J}catch(J){return U.debug(`[IOSScreenCaptureHelper] ignored malformed native frame metrics: ${J instanceof Error?J.message:String(J)}`),null}}function $B0($){if($===null||typeof $!=="object")return!1;let J=$;return pe(J.captureTimestampMs)&&pe(J.frameQueueAgeMs)&&(J.frameQueueDepth===0||J.frameQueueDepth===1)&&ce(J.droppedFrames)&&ce(J.bytesQueued)&&ce(J.highWaterMarkBytes)&&pe(J.lastOutputWriteDurationMs)}function pe($){return $===null||typeof $==="number"&&Number.isFinite($)}function ce($){return typeof $==="number"&&Number.isFinite($)&&$>=0}function YB0($){switch($.kind){case"device":return $.deviceId!==void 0?["--device-id",$.deviceId]:[];case"simulator":{let J=["--simulator-window",String($.windowID)];if($.fps!==void 0){if(!Number.isInteger($.fps)||$.fps<n_||$.fps>i_)throw RangeError(`simulator fps must be an integer in [${n_}, ${i_}]; got ${$.fps}`);J.push("--simulator-fps",String($.fps))}if($.audio===!0)J.push("--audio");return WB0(J,$.encode),J}}}function WB0($,J){if(J===void 0)return;switch($.push("--encode",J.codec),J.bitrate.kind){case"explicitBps":$.push("--bitrate-bps",String(Math.round(J.bitrate.bps)));break;case"bitsPerPixel":$.push("--bits-per-pixel",String(J.bitrate.bpp));break;case"videoToolboxDefault":break}}var YA$=33554432,de="automobile-frame-metrics:",ne="capture-capability:",e2="encoded-video-h264",d_="capture-permission:",dB="capture-permission-target:",n_=5,i_=60,ie=5,$L,JB0,WA$=2000,XB0=($,J,X)=>oO0($,J,X),QB0=($,J)=>{process.kill(-$,J)};var nB=D(()=>{l4();n();U$();le();$L=class $L extends rO0{binaryPath;target;spawner;timer;stopGraceMs;processGroupKiller;decoder=new xb;frameQueue;frameDeliveryScheduler;process=null;helperCapabilities=new Set;stderrBuffer="";exitPromise=null;frameDeliveryScheduled=!1;constructor($){super();this.binaryPath=$.binaryPath,this.target=$.target,this.spawner=$.spawner??XB0,this.timer=$.timer??g,this.stopGraceMs=$.stopGraceMs??WA$,this.processGroupKiller=$.processGroupKiller??QB0,this.frameQueue=new cB({maxFrameBytes:YA$,now:$.now??Date.now}),this.frameDeliveryScheduler=$.frameDeliveryScheduler??JB0}on($,J){return super.on($,J)}emit($,...J){return super.emit($,...J)}get isRunning(){return this.process!==null&&this.process.exitCode===null&&!this.process.killed}getFrameMetrics(){return this.frameQueue.metrics()}start(){if(this.process!==null)throw Error("IOSScreenCaptureHelper already started");let $=YB0(this.target);this.emitReadiness("helper-executable-found",this.binaryPath);let J=this.spawner(this.binaryPath,$,{detached:process.platform==="darwin",stdio:["pipe","pipe","pipe"]});this.process=J,this.emitReadiness("helper-process-spawned",`pid=${J.pid??"?"}`),J.stdout.on("data",(X)=>{let Q=Buffer.isBuffer(X)?X:Buffer.from(X),Y=this.decoder.push(Q,(W)=>this.emit("malformed",W),(W)=>this.emit("audio",W),(W)=>this.enqueueFrame(W),(W)=>this.emit("encodedVideo",W));for(let W of Y)this.enqueueFrame(W)}),J.stderr.on("data",(X)=>{let Q=Buffer.isBuffer(X)?X.toString("utf8"):String(X);this.appendStderr(Q)}),J.once("error",(X)=>{this.emit("error",X instanceof Error?X:Error(String(X)))}),this.exitPromise=new Promise((X)=>{J.once("exit",(Q,Y)=>{if(this.stderrBuffer.length>0)this.handleStderrLine(this.stderrBuffer),this.stderrBuffer="";let W={code:Q,signal:Y};this.emit("exit",W),X(W)})}),U.debug(`[IOSScreenCaptureHelper] spawned ${this.binaryPath} pid=${J.pid??"?"}`)}async stop(){let $=this.process;if($===null)return null;if($.exitCode!==null||$.killed){let X=await this.waitForExitWithinGrace();return this.cleanupProcess($),X??{code:$.exitCode,signal:$.signalCode}}$.kill("SIGTERM");let J=await this.waitForExitWithinGrace();if(J!==null)return this.cleanupProcess($),J;if(U.warn(`[IOSScreenCaptureHelper] helper pid=${$.pid??"?"} did not exit after SIGTERM; escalating to SIGKILL`),$.kill("SIGKILL"),process.platform==="darwin")if($.pid!==void 0)try{this.processGroupKiller($.pid,"SIGKILL")}catch(X){U.warn(`[IOSScreenCaptureHelper] process-group cleanup failed for pid=${$.pid}; detached children may leak: ${X}`)}else U.warn("[IOSScreenCaptureHelper] helper pid unknown after SIGKILL; cannot group-kill, detached children may leak");return this.cleanupProcess($),{code:$.exitCode,signal:$.signalCode??"SIGKILL"}}appendStderr($){if(this.stderrBuffer+=$,this.stderrBuffer.length>$L.STDERR_BUFFER_MAX){this.emit("stderr",this.stderrBuffer),this.stderrBuffer="";return}let J=this.stderrBuffer.split(`
|
|
19
|
+
`)}catch(Q){console.error("Failed to write log:",Q)}},U;var n=D(()=>{wU();MX();dw$();RX={DEBUG:0,INFO:1,WARN:2,ERROR:3,NONE:4};fB=iw$(process.env.AUTOMOBILE_LOG_LEVEL)??RX.INFO,_e=Promise.resolve(),vB=D9(KJ.LOGS);if(!o2.existsSync(vB))o2.mkdirSync(vB,{recursive:!0});uw$(vB).catch(($)=>{console.error("Failed to create logs directory:",$)});Me=ow$(process.argv,process.pid),n2=nw$.join(vB,`${Me}.log`),i2=o2.createWriteStream(n2,{flags:"a"});rw$().catch(()=>{});tw$=new Set(["PASSWORD","TOKEN","SECRET","KEY","CREDENTIAL","AUTH","API_KEY","PRIVATE_KEY","ACCESS_TOKEN","REFRESH_TOKEN","CLIENT_SECRET","DATABASE_URL","DB_PASSWORD","GITHUB_TOKEN","NPM_TOKEN","AWS_SECRET_ACCESS_KEY"]),U={setLogLevel($){fB=$},getLogLevel(){return fB},enableStdoutLogging(){Ae=!0},disableStdoutLogging(){Ae=!1},debug($,...J){if(fB<=RX.DEBUG)qb(wb("DEBUG",$,J).catch((X)=>{console.error("Failed to write debug log:",X)}))},info($,...J){if(fB<=RX.INFO)qb(wb("INFO",$,J).catch((X)=>{console.error("Failed to write info log:",X)}))},warn($,...J){if(fB<=RX.WARN)qb(wb("WARN",$,J).catch((X)=>{console.error("Failed to write warn log:",X)}))},error($,...J){if(fB<=RX.ERROR)qb(wb("ERROR",$,J).catch((X)=>{console.error("Failed to write error log:",X)}))},async flush(){await _e},close(){i2.end()}}});var Re=o((ZC1,ew$)=>{ew$.exports={LOCHDR:30,LOCSIG:67324752,LOCVER:4,LOCFLG:6,LOCHOW:8,LOCTIM:10,LOCCRC:14,LOCSIZ:18,LOCLEN:22,LOCNAM:26,LOCEXT:28,EXTSIG:134695760,EXTHDR:16,EXTCRC:4,EXTSIZ:8,EXTLEN:12,CENHDR:46,CENSIG:33639248,CENVEM:4,CENVER:6,CENFLG:8,CENHOW:10,CENTIM:12,CENCRC:16,CENSIZ:20,CENLEN:24,CENNAM:28,CENEXT:30,CENCOM:32,CENDSK:34,CENATT:36,CENATX:38,CENOFF:42,ENDHDR:22,ENDSIG:101010256,ENDSUB:8,ENDTOT:10,ENDSIZ:12,ENDOFF:16,ENDCOM:20,END64HDR:20,END64SIG:117853008,END64START:4,END64OFF:8,END64NUMDISKS:16,ZIP64SIG:101075792,ZIP64HDR:56,ZIP64LEAD:12,ZIP64SIZE:4,ZIP64VEM:12,ZIP64VER:14,ZIP64DSK:16,ZIP64DSKDIR:20,ZIP64SUB:24,ZIP64TOT:32,ZIP64SIZB:40,ZIP64OFF:48,ZIP64EXTRA:56,STORED:0,SHRUNK:1,REDUCED1:2,REDUCED2:3,REDUCED3:4,REDUCED4:5,IMPLODED:6,DEFLATED:8,ENHANCED_DEFLATED:9,PKWARE:10,BZIP2:12,LZMA:14,IBM_TERSE:18,IBM_LZ77:19,AES_ENCRYPT:99,FLG_ENC:1,FLG_COMP1:2,FLG_COMP2:4,FLG_DESC:8,FLG_ENH:16,FLG_PATCH:32,FLG_STR:64,FLG_EFS:2048,FLG_MSK:4096,FILE:2,BUFFER:1,NONE:0,EF_ID:0,EF_SIZE:2,ID_ZIP64:1,ID_AVINFO:7,ID_PFS:8,ID_OS2:9,ID_NTFS:10,ID_OPENVMS:12,ID_UNIX:13,ID_FORK:14,ID_PATCH:15,ID_X509_PKCS7:20,ID_X509_CERTID_F:21,ID_X509_CERTID_C:22,ID_STRONGENC:23,ID_RECORD_MGT:24,ID_X509_PKCS7_RL:25,ID_IBM1:101,ID_IBM2:102,ID_POSZIP:18064,EF_ZIP64_OR_32:4294967295,EF_ZIP64_OR_16:65535,EF_ZIP64_SUNCOMP:0,EF_ZIP64_SCOMP:8,EF_ZIP64_RHO:16,EF_ZIP64_DSN:24}});var Ab=o((JN$)=>{var $N$={INVALID_LOC:"Invalid LOC header (bad signature)",INVALID_CEN:"Invalid CEN header (bad signature)",INVALID_END:"Invalid END header (bad signature)",DESCRIPTOR_NOT_EXIST:"No descriptor present",DESCRIPTOR_UNKNOWN:"Unknown descriptor format",DESCRIPTOR_FAULTY:"Descriptor data is malformed",NO_DATA:"Nothing to decompress",BAD_CRC:"CRC32 checksum failed {0}",FILE_IN_THE_WAY:"There is a file in the way: {0}",UNKNOWN_METHOD:"Invalid/unsupported compression method",AVAIL_DATA:"inflate::Available inflate data did not terminate",INVALID_DISTANCE:"inflate::Invalid literal/length or distance code in fixed or dynamic block",TO_MANY_CODES:"inflate::Dynamic block code description: too many length or distance codes",INVALID_REPEAT_LEN:"inflate::Dynamic block code description: repeat more than specified lengths",INVALID_REPEAT_FIRST:"inflate::Dynamic block code description: repeat lengths with no first length",INCOMPLETE_CODES:"inflate::Dynamic block code description: code lengths codes incomplete",INVALID_DYN_DISTANCE:"inflate::Dynamic block code description: invalid distance code lengths",INVALID_CODES_LEN:"inflate::Dynamic block code description: invalid literal/length code lengths",INVALID_STORE_BLOCK:"inflate::Stored block length did not match one's complement",INVALID_BLOCK_TYPE:"inflate::Invalid block type (type == 3)",CANT_EXTRACT_FILE:"Could not extract the file",CANT_OVERRIDE:"Target file already exists",DISK_ENTRY_TOO_LARGE:"Number of disk entries is too large",NO_ZIP:"No zip file was loaded",NO_ENTRY:"Entry doesn't exist",DIRECTORY_CONTENT_ERROR:"A directory cannot have content",FILE_NOT_FOUND:'File not found: "{0}"',NOT_IMPLEMENTED:"Not implemented",INVALID_FILENAME:"Invalid filename",INVALID_FORMAT:"Invalid or unsupported zip format. No END header found",INVALID_PASS_PARAM:"Incompatible password parameter",WRONG_PASSWORD:"Wrong Password",COMMENT_TOO_LONG:"Comment is too long",EXTRA_FIELD_PARSE_ERROR:"Extra field parsing error"};function iH0($){return function(...J){if(J.length)$=$.replace(/\{(\d)\}/g,(X,Q)=>J[Q]||"");return Error("ADM-ZIP: "+$)}}for(let $ of Object.keys($N$))JN$[$]=iH0($N$[$])});var GN$=o((VC1,WN$)=>{var oH0=N0("fs"),T9=N0("path"),XN$=Re(),rH0=Ab(),tH0=typeof process==="object"&&process.platform==="win32",QN$=($)=>typeof $==="object"&&$!==null,YN$=new Uint32Array(256).map(($,J)=>{for(let X=0;X<8;X++)if((J&1)!==0)J=3988292384^J>>>1;else J>>>=1;return J>>>0});function y8($){if(this.sep=T9.sep,this.fs=oH0,QN$($)){if(QN$($.fs)&&typeof $.fs.statSync==="function")this.fs=$.fs}}WN$.exports=y8;y8.prototype.makeDir=function($){let J=this;function X(Q){let Y=Q.split(J.sep)[0];Q.split(J.sep).forEach(function(W){if(!W||W.substr(-1,1)===":")return;Y+=J.sep+W;var G;try{G=J.fs.statSync(Y)}catch(Z){if(Z.message&&Z.message.startsWith("ENOENT"))J.fs.mkdirSync(Y);else throw Z}if(G&&G.isFile())throw rH0.FILE_IN_THE_WAY(`"${Y}"`)})}X($)};y8.prototype.writeFileTo=function($,J,X,Q){let Y=this;if(Y.fs.existsSync($)){if(!X)return!1;var W=Y.fs.statSync($);if(W.isDirectory())return!1}var G=T9.dirname($);if(!Y.fs.existsSync(G))Y.makeDir(G);var Z;try{Z=Y.fs.openSync($,"w",438)}catch(j){Y.fs.chmodSync($,438),Z=Y.fs.openSync($,"w",438)}if(Z)try{Y.fs.writeSync(Z,J,0,J.length,0)}finally{Y.fs.closeSync(Z)}return Y.fs.chmodSync($,Q||438),!0};y8.prototype.writeFileToAsync=function($,J,X,Q,Y){if(typeof Q==="function")Y=Q,Q=void 0;let W=this;W.fs.exists($,function(G){if(G&&!X)return Y(!1);W.fs.stat($,function(Z,j){if(G&&j&&j.isDirectory())return Y(!1);var V=T9.dirname($);W.fs.exists(V,function(K){if(!K)try{W.makeDir(V)}catch(L){return Y(!1)}let z=function(L){W.fs.write(L,J,0,J.length,0,function(H){W.fs.close(L,function(){if(H)return Y(!1);W.fs.chmod($,Q||438,function(){Y(!0)})})})};W.fs.open($,"w",438,function(L,H){if(L)W.fs.chmod($,438,function(){W.fs.open($,"w",438,function(O,B){if(O||!B)return Y(!1);z(B)})});else if(H)z(H);else Y(!1)})})})})};y8.prototype.findFiles=function($){let J=this;function X(Q,Y,W,G){if(typeof Y==="boolean")W=Y,Y=void 0;let Z=[];return J.fs.readdirSync(Q).forEach(function(j){let V=T9.join(Q,j),K=J.fs.statSync(V);if(!Y||Y.test(V))Z.push(T9.normalize(V)+(K.isDirectory()?J.sep:""));if(K.isDirectory()&&W){let z=J.fs.realpathSync(V);if(!G.has(z))G.add(z),Z=Z.concat(X(V,Y,W,G))}}),Z}return X($,void 0,!0,new Set([J.fs.realpathSync($)]))};y8.prototype.findFilesAsync=function($,J){let X=this,Q=[],Y=!1,W=function(Z){if(Y)return;Y=!0,J(Z,Z?void 0:Q)},G=function(Z,j,V){X.fs.readdir(Z,function(K,z){if(K)return V(K);let L=z.length;if(!L)return V();z.forEach(function(H){let O=T9.join(Z,H);X.fs.stat(O,function(B,F){if(B)return V(B);if(!F){if(!--L)V();return}if(Q.push(T9.normalize(O)+(F.isDirectory()?X.sep:"")),!F.isDirectory()){if(!--L)V();return}X.fs.realpath(O,function(A,_){if(A)return V(A);if(j.has(_)){if(!--L)V();return}j.add(_),G(O,j,function(w){if(w)return V(w);if(!--L)V()})})})})})};X.fs.realpath($,function(Z,j){if(Z)return W(Z);G($,new Set([j]),W)})};y8.prototype.getAttributes=function(){};y8.prototype.setAttributes=function(){};y8.crc32update=function($,J){return YN$[($^J)&255]^$>>>8};y8.crc32=function($){if(typeof $==="string")$=Buffer.from($,"utf8");let J=$.length,X=-1;for(let Q=0;Q<J;)X=y8.crc32update(X,$[Q++]);return~X>>>0};y8.methodToString=function($){switch($){case XN$.STORED:return"STORED ("+$+")";case XN$.DEFLATED:return"DEFLATED ("+$+")";default:return"UNSUPPORTED ("+$+")"}};y8.canonical=function($){if(!$)return"";let J=T9.posix.normalize("/"+$.split("\\").join("/"));return T9.join(".",J)};y8.zipnamefix=function($){if(!$)return"";let J=T9.posix.normalize("/"+$.split("\\").join("/"));return T9.posix.join(".",J)};y8.findLast=function($,J){if(!Array.isArray($))throw TypeError("arr is not array");let X=$.length>>>0;for(let Q=X-1;Q>=0;Q--)if(J($[Q],Q,$))return $[Q];return};y8.sanitize=function($,J){$=T9.resolve(T9.normalize($));var X=J.split("/");for(var Q=0,Y=X.length;Q<Y;Q++){var W=T9.normalize(T9.join($,X.slice(Q,Y).join(T9.sep)));if(W===$||W.startsWith($+T9.sep))return W}return T9.normalize(T9.join($,T9.basename(J)))};y8.toBuffer=function(J,X){if(Buffer.isBuffer(J))return J;else if(J instanceof Uint8Array)return Buffer.from(J);else return typeof J==="string"?X(J):Buffer.alloc(0)};y8.readBigUInt64LE=function($,J){let X=$.readUInt32LE(J);return $.readUInt32LE(J+4)*4294967296+X};y8.writeBigUInt64LE=function($,J,X){let Q=J>>>0,Y=Math.floor(J/4294967296)>>>0;$.writeUInt32LE(Q,X),$.writeUInt32LE(Y,X+4)};y8.fromDOS2Date=function($){return new Date(($>>25&127)+1980,Math.max(($>>21&15)-1,0),Math.max($>>16&31,1),$>>11&31,$>>5&63,($&31)<<1)};y8.fromDate2DOS=function($){let J=0,X=0;if($.getFullYear()>1979)J=($.getFullYear()-1980&127)<<9|$.getMonth()+1<<5|$.getDate(),X=$.getHours()<<11|$.getMinutes()<<5|$.getSeconds()>>1;return J<<16|X};y8.isWin=tH0;y8.crcTable=YN$});var jN$=o((KC1,ZN$)=>{var aH0=N0("path");ZN$.exports=function($,{fs:J}){var X=$||"",Q=W(),Y=null;function W(){return{directory:!1,readonly:!1,hidden:!1,executable:!1,mtime:0,atime:0}}if(X&&J.existsSync(X))Y=J.statSync(X),Q.directory=Y.isDirectory(),Q.mtime=Y.mtime,Q.atime=Y.atime,Q.executable=(73&Y.mode)!==0,Q.readonly=(128&Y.mode)===0,Q.hidden=aH0.basename(X)[0]===".";else console.warn("Invalid path: "+X);return{get directory(){return Q.directory},get readOnly(){return Q.readonly},get hidden(){return Q.hidden},get mtime(){return Q.mtime},get atime(){return Q.atime},get executable(){return Q.executable},decodeAttributes:function(){},encodeAttributes:function(){},toJSON:function(){return{path:X,isDirectory:Q.directory,isReadOnly:Q.readonly,isHidden:Q.hidden,isExecutable:Q.executable,mTime:Q.mtime,aTime:Q.atime}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var KN$=o((UC1,VN$)=>{VN$.exports={efs:!0,encode:($)=>Buffer.from($,"utf8"),decode:($)=>$.toString("utf8")}});var gB=o((zC1,hB)=>{hB.exports=GN$();hB.exports.Constants=Re();hB.exports.Errors=Ab();hB.exports.FileAttr=jN$();hB.exports.decoder=KN$()});var zN$=o((LC1,UN$)=>{var AU=gB(),x0=AU.Constants;UN$.exports=function(){var $=20,J=10,X=0,Q=0,Y=0,W=0,G=0,Z=0,j=0,V=0,K=0,z=0,L=0,H=0,O=0;$|=AU.isWin?2560:768,X|=x0.FLG_EFS;let B={extraLen:0},F=(w)=>Math.max(0,w)>>>0,A=(w)=>Math.max(0,w)&65535,_=(w)=>Math.max(0,w)&255;return Y=AU.fromDate2DOS(new Date),{get made(){return $},set made(w){$=w},get version(){return J},set version(w){J=w},get flags(){return X},set flags(w){X=w},get flags_efs(){return(X&x0.FLG_EFS)>0},set flags_efs(w){if(w)X|=x0.FLG_EFS;else X&=~x0.FLG_EFS},get flags_desc(){return(X&x0.FLG_DESC)>0},set flags_desc(w){if(w)X|=x0.FLG_DESC;else X&=~x0.FLG_DESC},get method(){return Q},set method(w){switch(w){case x0.STORED:this.version=10;break;case x0.DEFLATED:default:this.version=20}Q=w},get time(){return AU.fromDOS2Date(this.timeval)},set time(w){w=new Date(w),this.timeval=AU.fromDate2DOS(w)},get timeval(){return Y},set timeval(w){Y=F(w)},get timeHighByte(){return _(Y>>>8)},get crc(){return W},set crc(w){W=F(w)},get compressedSize(){return G},set compressedSize(w){G=F(w)},get size(){return Z},set size(w){Z=F(w)},get fileNameLength(){return j},set fileNameLength(w){j=w},get extraLength(){return V},set extraLength(w){V=w},get extraLocalLength(){return B.extraLen},set extraLocalLength(w){B.extraLen=w},get commentLength(){return K},set commentLength(w){K=w},get diskNumStart(){return z},set diskNumStart(w){z=F(w)},get inAttr(){return L},set inAttr(w){L=F(w)},get attr(){return H},set attr(w){H=F(w)},get fileAttr(){return(H||0)>>16&4095},get offset(){return O},set offset(w){O=F(w)},get encrypted(){return(X&x0.FLG_ENC)===x0.FLG_ENC},get centralHeaderSize(){return x0.CENHDR+j+V+K},get realDataOffset(){return O+x0.LOCHDR+B.fnameLen+B.extraLen},get localHeader(){return B},loadLocalHeaderFromBinary:function(w){var q=w.slice(O,O+x0.LOCHDR);if(q.readUInt32LE(0)!==x0.LOCSIG)throw AU.Errors.INVALID_LOC();B.version=q.readUInt16LE(x0.LOCVER),B.flags=q.readUInt16LE(x0.LOCFLG),B.flags_desc=(B.flags&x0.FLG_DESC)>0,B.method=q.readUInt16LE(x0.LOCHOW),B.time=q.readUInt32LE(x0.LOCTIM),B.crc=q.readUInt32LE(x0.LOCCRC),B.compressedSize=q.readUInt32LE(x0.LOCSIZ),B.size=q.readUInt32LE(x0.LOCLEN),B.fnameLen=q.readUInt16LE(x0.LOCNAM),B.extraLen=q.readUInt16LE(x0.LOCEXT);let M=O+x0.LOCHDR+B.fnameLen,C=M+B.extraLen;return w.slice(M,C)},loadFromBinary:function(w){if(w.length!==x0.CENHDR||w.readUInt32LE(0)!==x0.CENSIG)throw AU.Errors.INVALID_CEN();$=w.readUInt16LE(x0.CENVEM),J=w.readUInt16LE(x0.CENVER),X=w.readUInt16LE(x0.CENFLG),Q=w.readUInt16LE(x0.CENHOW),Y=w.readUInt32LE(x0.CENTIM),W=w.readUInt32LE(x0.CENCRC),G=w.readUInt32LE(x0.CENSIZ),Z=w.readUInt32LE(x0.CENLEN),j=w.readUInt16LE(x0.CENNAM),V=w.readUInt16LE(x0.CENEXT),K=w.readUInt16LE(x0.CENCOM),z=w.readUInt16LE(x0.CENDSK),L=w.readUInt16LE(x0.CENATT),H=w.readUInt32LE(x0.CENATX),O=w.readUInt32LE(x0.CENOFF)},localHeaderToBinary:function(){var w=Buffer.alloc(x0.LOCHDR);return w.writeUInt32LE(x0.LOCSIG,0),w.writeUInt16LE(J,x0.LOCVER),w.writeUInt16LE(X&~x0.FLG_DESC,x0.LOCFLG),w.writeUInt16LE(Q,x0.LOCHOW),w.writeUInt32LE(Y,x0.LOCTIM),w.writeUInt32LE(W,x0.LOCCRC),w.writeUInt32LE(G,x0.LOCSIZ),w.writeUInt32LE(Z,x0.LOCLEN),w.writeUInt16LE(j,x0.LOCNAM),w.writeUInt16LE(B.extraLen,x0.LOCEXT),w},centralHeaderToBinary:function(){var w=Buffer.alloc(x0.CENHDR+j+V+K);return w.writeUInt32LE(x0.CENSIG,0),w.writeUInt16LE($,x0.CENVEM),w.writeUInt16LE(J,x0.CENVER),w.writeUInt16LE(X&~x0.FLG_DESC,x0.CENFLG),w.writeUInt16LE(Q,x0.CENHOW),w.writeUInt32LE(Y,x0.CENTIM),w.writeUInt32LE(W,x0.CENCRC),w.writeUInt32LE(G,x0.CENSIZ),w.writeUInt32LE(Z,x0.CENLEN),w.writeUInt16LE(j,x0.CENNAM),w.writeUInt16LE(V,x0.CENEXT),w.writeUInt16LE(K,x0.CENCOM),w.writeUInt16LE(z,x0.CENDSK),w.writeUInt16LE(L,x0.CENATT),w.writeUInt32LE(H,x0.CENATX),w.writeUInt32LE(O,x0.CENOFF),w},toJSON:function(){let w=function(q){return q+" bytes"};return{made:$,version:J,flags:X,method:AU.methodToString(Q),time:this.time,crc:"0x"+W.toString(16).toUpperCase(),compressedSize:w(G),size:w(Z),fileNameLength:w(j),extraLength:w(V),commentLength:w(K),diskNumStart:z,inAttr:L,attr:H,offset:O,centralHeaderSize:w(x0.CENHDR+j+V+K)}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var HN$=o((HC1,LN$)=>{var _Q=gB(),z1=_Q.Constants;LN$.exports=function(){var $=0,J=0,X=0,Q=0,Y=0;let W=()=>$>z1.EF_ZIP64_OR_16||J>z1.EF_ZIP64_OR_16||X>z1.EF_ZIP64_OR_32||Q>z1.EF_ZIP64_OR_32;return{get diskEntries(){return $},set diskEntries(G){$=J=G},get totalEntries(){return J},set totalEntries(G){J=$=G},get size(){return X},set size(G){X=G},get offset(){return Q},set offset(G){Q=G},get commentLength(){return Y},set commentLength(G){Y=G},get mainHeaderSize(){return(W()?z1.ZIP64HDR+z1.END64HDR:0)+z1.ENDHDR+Y},loadFromBinary:function(G){if((G.length!==z1.ENDHDR||G.readUInt32LE(0)!==z1.ENDSIG)&&(G.length<z1.ZIP64HDR||G.readUInt32LE(0)!==z1.ZIP64SIG))throw _Q.Errors.INVALID_END();if(G.readUInt32LE(0)===z1.ENDSIG)$=G.readUInt16LE(z1.ENDSUB),J=G.readUInt16LE(z1.ENDTOT),X=G.readUInt32LE(z1.ENDSIZ),Q=G.readUInt32LE(z1.ENDOFF),Y=G.readUInt16LE(z1.ENDCOM);else $=_Q.readBigUInt64LE(G,z1.ZIP64SUB),J=_Q.readBigUInt64LE(G,z1.ZIP64TOT),X=_Q.readBigUInt64LE(G,z1.ZIP64SIZB),Q=_Q.readBigUInt64LE(G,z1.ZIP64OFF),Y=0},toBinary:function(){if(!W()){var G=Buffer.alloc(z1.ENDHDR+Y);return G.writeUInt32LE(z1.ENDSIG,0),G.writeUInt32LE(0,4),G.writeUInt16LE($,z1.ENDSUB),G.writeUInt16LE(J,z1.ENDTOT),G.writeUInt32LE(X,z1.ENDSIZ),G.writeUInt32LE(Q,z1.ENDOFF),G.writeUInt16LE(Y,z1.ENDCOM),G.fill(" ",z1.ENDHDR),G}var G=Buffer.alloc(this.mainHeaderSize);let Z=0;G.writeUInt32LE(z1.ZIP64SIG,Z),_Q.writeBigUInt64LE(G,z1.ZIP64HDR-z1.ZIP64LEAD,Z+z1.ZIP64SIZE),G.writeUInt16LE(45,Z+z1.ZIP64VEM),G.writeUInt16LE(45,Z+z1.ZIP64VER),G.writeUInt32LE(0,Z+z1.ZIP64DSK),G.writeUInt32LE(0,Z+z1.ZIP64DSKDIR),_Q.writeBigUInt64LE(G,$,Z+z1.ZIP64SUB),_Q.writeBigUInt64LE(G,J,Z+z1.ZIP64TOT),_Q.writeBigUInt64LE(G,X,Z+z1.ZIP64SIZB),_Q.writeBigUInt64LE(G,Q,Z+z1.ZIP64OFF);let j=Q+X;return Z+=z1.ZIP64HDR,G.writeUInt32LE(z1.END64SIG,Z),G.writeUInt32LE(0,Z+z1.END64START),_Q.writeBigUInt64LE(G,j,Z+z1.END64OFF),G.writeUInt32LE(1,Z+z1.END64NUMDISKS),Z+=z1.END64HDR,G.writeUInt32LE(z1.ENDSIG,Z),G.writeUInt32LE(0,Z+4),G.writeUInt16LE(Math.min($,z1.EF_ZIP64_OR_16),Z+z1.ENDSUB),G.writeUInt16LE(Math.min(J,z1.EF_ZIP64_OR_16),Z+z1.ENDTOT),G.writeUInt32LE(Math.min(X,z1.EF_ZIP64_OR_32),Z+z1.ENDSIZ),G.writeUInt32LE(Math.min(Q,z1.EF_ZIP64_OR_32),Z+z1.ENDOFF),G.writeUInt16LE(Y,Z+z1.ENDCOM),G.fill(" ",Z+z1.ENDHDR),G},toJSON:function(){let G=function(Z,j){let V=Z.toString(16).toUpperCase();while(V.length<j)V="0"+V;return"0x"+V};return{diskEntries:$,totalEntries:J,size:X+" bytes",offset:G(Q,4),commentLength:Y}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var Ee=o((sH0)=>{sH0.EntryHeader=zN$();sH0.MainHeader=HN$()});var BN$=o((BC1,ON$)=>{ON$.exports=function($){var J=N0("zlib"),X={chunkSize:(parseInt($.length/1024)+1)*1024};return{deflate:function(){return J.deflateRawSync($,X)},deflateAsync:function(Q){var Y=J.createDeflateRaw(X),W=[],G=0;Y.on("data",function(Z){W.push(Z),G+=Z.length}),Y.on("end",function(){var Z=Buffer.alloc(G),j=0;Z.fill(0);for(var V=0;V<W.length;V++){var K=W[V];K.copy(Z,j),j+=K.length}Q&&Q(Z)}),Y.end($)}}}});var FN$=o((DC1,DN$)=>{var JO0=+(process?.versions?.node??"").split(".")[0]||0;DN$.exports=function($,J){var X=N0("zlib");let Q=JO0>=15&&J>0?{maxOutputLength:J}:{};return{inflate:function(){return X.inflateRawSync($,Q)},inflateAsync:function(Y){var W=X.createInflateRaw(Q),G=[],Z=0;W.on("data",function(j){G.push(j),Z+=j.length}),W.on("end",function(){var j=Buffer.alloc(Z),V=0;j.fill(0);for(var K=0;K<G.length;K++){var z=G[K];z.copy(j,V),V+=z.length}Y&&Y(j)}),W.end($)}}}});var _N$=o((FC1,AN$)=>{var{randomFillSync:qN$}=N0("crypto"),XO0=Ab(),QO0=new Uint32Array(256).map(($,J)=>{for(let X=0;X<8;X++)if((J&1)!==0)J=J>>>1^3988292384;else J>>>=1;return J>>>0}),NN$=($,J)=>Math.imul($,J)>>>0,wN$=($,J)=>{return QO0[($^J)&255]^$>>>8},m_=()=>{if(typeof qN$==="function")return qN$(Buffer.alloc(12));else return m_.node()};m_.node=()=>{let $=Buffer.alloc(12),J=$.length;for(let X=0;X<J;X++)$[X]=Math.random()*256&255;return $};var _b={genSalt:m_};function Mb($){let J=Buffer.isBuffer($)?$:Buffer.from($);this.keys=new Uint32Array([305419896,591751049,878082192]);for(let X=0;X<J.length;X++)this.updateKeys(J[X])}Mb.prototype.updateKeys=function($){let J=this.keys;return J[0]=wN$(J[0],$),J[1]+=J[0]&255,J[1]=NN$(J[1],134775813)+1,J[2]=wN$(J[2],J[1]>>>24),$};Mb.prototype.next=function(){let $=(this.keys[2]|2)>>>0;return NN$($,$^1)>>8&255};function YO0($){let J=new Mb($);return function(X){let Q=Buffer.alloc(X.length),Y=0;for(let W of X)Q[Y++]=J.updateKeys(W^J.next());return Q}}function WO0($){let J=new Mb($);return function(X,Q,Y=0){if(!Q)Q=Buffer.alloc(X.length);for(let W of X){let G=J.next();Q[Y++]=W^G,J.updateKeys(W)}return Q}}function GO0($,J,X){if(!$||!Buffer.isBuffer($)||$.length<12)return Buffer.alloc(0);let Q=YO0(X),Y=Q($.slice(0,12)),W=(J.flags&8)===8?J.timeHighByte:J.crc>>>24;if(Y[11]!==W)throw XO0.WRONG_PASSWORD();return Q($.slice(12))}function ZO0($){if(Buffer.isBuffer($)&&$.length>=12)_b.genSalt=function(){return $.slice(0,12)};else if($==="node")_b.genSalt=m_.node;else _b.genSalt=m_}function jO0($,J,X,Q=!1){if($==null)$=Buffer.alloc(0);if(!Buffer.isBuffer($))$=Buffer.from($.toString());let Y=WO0(X),W=_b.genSalt();if(W[11]=J.crc>>>24&255,Q)W[10]=J.crc>>>16&255;let G=Buffer.alloc($.length+12);return Y(W,G),Y($,G,12)}AN$.exports={decrypt:GO0,encrypt:jO0,_salter:ZO0}});var MN$=o((VO0)=>{VO0.Deflater=BN$();VO0.Inflater=FN$();VO0.ZipCrypto=_N$()});var Te=o((wC1,RN$)=>{var z8=gB(),LO0=Ee(),EX=z8.Constants,Pe=MN$();RN$.exports=function($,J){var X=new LO0.EntryHeader,Q=Buffer.alloc(0),Y=Buffer.alloc(0),W=!1,G=null,Z=Buffer.alloc(0),j=Buffer.alloc(0),V=!0;let K=$,z=typeof K.decoder==="object"?K.decoder:z8.decoder;V=z.hasOwnProperty("efs")?z.efs:!1;function L(){if(!J||!(J instanceof Uint8Array))return Buffer.alloc(0);return j=X.loadLocalHeaderFromBinary(J),J.slice(X.realDataOffset,X.realDataOffset+X.compressedSize)}function H(w){let q=X.flags_desc||X.localHeader.flags_desc?X.crc:X.localHeader.crc;return z8.crc32(w)===q}function O(w,q,M){if(typeof q>"u"&&typeof w==="string")M=w,w=void 0;if(W){if(w&&q)q(Buffer.alloc(0),z8.Errors.DIRECTORY_CONTENT_ERROR());return Buffer.alloc(0)}var C=L();if(C.length===0){if(w&&q)q(C);return C}if(X.encrypted){if(typeof M!=="string"&&!Buffer.isBuffer(M))throw z8.Errors.INVALID_PASS_PARAM();C=Pe.ZipCrypto.decrypt(C,X,M)}var y;switch(X.method){case z8.Constants.STORED:if(y=Buffer.alloc(C.length),C.copy(y),!H(y)){if(w&&q)q(y,z8.Errors.BAD_CRC());throw z8.Errors.BAD_CRC()}else{if(w&&q)q(y);return y}case z8.Constants.DEFLATED:var I=new Pe.Inflater(C,X.size);if(!w){if(y=I.inflate(),!H(y))throw z8.Errors.BAD_CRC(`"${z.decode(Q)}"`);return y}else I.inflateAsync(function(d){if(q)if(!H(d))q(d,z8.Errors.BAD_CRC());else q(d)});break;default:if(w&&q)q(Buffer.alloc(0),z8.Errors.UNKNOWN_METHOD());throw z8.Errors.UNKNOWN_METHOD()}}function B(w,q){if((!G||!G.length)&&Buffer.isBuffer(J)){if(w&&q)q(L());return L()}if(G.length&&!W){var M;switch(X.method){case z8.Constants.STORED:if(X.compressedSize=X.size,M=Buffer.alloc(G.length),G.copy(M),w&&q)q(M);return M;default:case z8.Constants.DEFLATED:var C=new Pe.Deflater(G);if(!w){var y=C.deflate();return X.compressedSize=y.length,y}else C.deflateAsync(function(I){M=Buffer.alloc(I.length),X.compressedSize=I.length,I.copy(M),q&&q(M)});C=null;break}}else if(w&&q)q(Buffer.alloc(0));else return Buffer.alloc(0)}function F(w,q){return z8.readBigUInt64LE(w,q)}function A(w){try{var q=0,M,C,y;while(q+4<w.length)if(M=w.readUInt16LE(q),q+=2,C=w.readUInt16LE(q),q+=2,y=w.slice(q,q+C),q+=C,EX.ID_ZIP64===M)_(y)}catch(I){throw z8.Errors.EXTRA_FIELD_PARSE_ERROR()}}function _(w){var q,M,C,y;if(w.length>=EX.EF_ZIP64_SCOMP){if(q=F(w,EX.EF_ZIP64_SUNCOMP),X.size===EX.EF_ZIP64_OR_32)X.size=q}if(w.length>=EX.EF_ZIP64_RHO){if(M=F(w,EX.EF_ZIP64_SCOMP),X.compressedSize===EX.EF_ZIP64_OR_32)X.compressedSize=M}if(w.length>=EX.EF_ZIP64_DSN){if(C=F(w,EX.EF_ZIP64_RHO),X.offset===EX.EF_ZIP64_OR_32)X.offset=C}if(w.length>=EX.EF_ZIP64_DSN+4){if(y=w.readUInt32LE(EX.EF_ZIP64_DSN),X.diskNumStart===EX.EF_ZIP64_OR_16)X.diskNumStart=y}}return{get entryName(){return z.decode(Q)},get rawEntryName(){return Q},set entryName(w){Q=z8.toBuffer(w,z.encode);var q=Q[Q.length-1];W=q===47||q===92,X.fileNameLength=Q.length},get efs(){if(typeof V==="function")return V(this.entryName);else return V},get extra(){return Z},set extra(w){Z=w,X.extraLength=w.length,A(w)},get comment(){return z.decode(Y)},set comment(w){if(Y=z8.toBuffer(w,z.encode),X.commentLength=Y.length,Y.length>65535)throw z8.Errors.COMMENT_TOO_LONG()},get name(){let w=z.decode(Q);return W?w.replace(/[/\\]$/,"").split("/").pop():w.split("/").pop()},get isDirectory(){return W},getCompressedData:function(){return B(!1,null)},getCompressedDataAsync:function(w){B(!0,w)},setData:function(w){if(G=z8.toBuffer(w,z8.decoder.encode),!W&&G.length)X.size=G.length,X.method=z8.Constants.DEFLATED,X.crc=z8.crc32(w),X.changed=!0;else X.method=z8.Constants.STORED},getData:function(w){if(X.changed)return G;else return O(!1,null,w)},getDataAsync:function(w,q){if(X.changed)w(G);else O(!0,w,q)},set attr(w){X.attr=w},get attr(){return X.attr},set header(w){X.loadFromBinary(w)},get header(){return X},packCentralHeader:function(){X.flags_efs=this.efs,X.extraLength=Z.length;var w=X.centralHeaderToBinary(),q=z8.Constants.CENHDR;return Q.copy(w,q),q+=Q.length,Z.copy(w,q),q+=X.extraLength,Y.copy(w,q),w},packLocalHeader:function(){let w=0;X.flags_efs=this.efs,X.extraLocalLength=j.length;let q=X.localHeaderToBinary(),M=Buffer.alloc(q.length+Q.length+X.extraLocalLength);return q.copy(M,w),w+=q.length,Q.copy(M,w),w+=Q.length,j.copy(M,w),w+=j.length,M},toJSON:function(){let w=function(q){return"<"+(q&&q.length+" bytes buffer"||"null")+">"};return{entryName:this.entryName,name:this.name,comment:this.comment,isDirectory:this.isDirectory,header:X.toJSON(),compressedData:w(J),data:w(G)}},toString:function(){return JSON.stringify(this.toJSON(),null,"\t")}}}});var TN$=o((NC1,PN$)=>{var EN$=Te(),HO0=Ee(),c5=gB();PN$.exports=function($,J){var X=[],Q=Object.create(null),Y=Buffer.alloc(0),W=new HO0.MainHeader,G=!1,Z=null;let j=new Set,V=J,{noSort:K,decoder:z}=V;if($)O(V.readEntries);else G=!0;function L(){let F=new Set;for(let A of Object.keys(Q)){let _=A.split("/");if(_.pop(),!_.length)continue;for(let w=0;w<_.length;w++){let q=_.slice(0,w+1).join("/")+"/";F.add(q)}}for(let A of F)if(!(A in Q)){let _=new EN$(V);_.entryName=A,_.attr=16,_.temporary=!0,X.push(_),Q[_.entryName]=_,j.add(_)}}function H(){if(G=!0,Q=Object.create(null),W.diskEntries>($.length-W.offset)/c5.Constants.CENHDR)throw c5.Errors.DISK_ENTRY_TOO_LARGE();X=Array(W.diskEntries);var F=W.offset;for(var A=0;A<X.length;A++){var _=F,w=new EN$(V,$);if(w.header=$.slice(_,_+=c5.Constants.CENHDR),w.entryName=$.slice(_,_+=w.header.fileNameLength),w.header.extraLength)w.extra=$.slice(_,_+=w.header.extraLength);if(w.header.commentLength)w.comment=$.slice(_,_+w.header.commentLength);F+=w.header.centralHeaderSize,X[A]=w,Q[w.entryName]=w}j.clear(),L()}function O(F){var A=$.length-c5.Constants.ENDHDR,_=Math.max(0,A-65535),w=_,q=$.length,M=-1,C=0;if(typeof V.trailingSpace==="boolean"?V.trailingSpace:!1)_=0;for(A;A>=w;A--){if($[A]!==80)continue;if($.readUInt32LE(A)===c5.Constants.ENDSIG){M=A,C=A,q=A+c5.Constants.ENDHDR,w=A-c5.Constants.END64HDR;continue}if($.readUInt32LE(A)===c5.Constants.END64SIG){w=_;continue}if($.readUInt32LE(A)===c5.Constants.ZIP64SIG){M=A,q=A+c5.readBigUInt64LE($,A+c5.Constants.ZIP64SIZE)+c5.Constants.ZIP64LEAD;break}}if(M==-1)throw c5.Errors.INVALID_FORMAT();if(W.loadFromBinary($.slice(M,q)),W.commentLength)Y=$.slice(C+c5.Constants.ENDHDR);if(F)H()}function B(){if(X.length>1&&!K)X=X.map((F)=>({entry:F,key:F.entryName.toLowerCase()})).sort((F,A)=>F.key.localeCompare(A.key)).map((F)=>F.entry)}return{get entries(){if(!G)H();return X.filter((F)=>!j.has(F))},get comment(){return z.decode(Y)},set comment(F){Y=c5.toBuffer(F,z.encode),W.commentLength=Y.length},getEntryCount:function(){if(!G)return W.diskEntries;return X.length},forEach:function(F){this.entries.forEach(F)},getEntry:function(F){if(!G)H();return Q[F]||null},setEntry:function(F){if(!G)H();X.push(F),Q[F.entryName]=F,W.totalEntries=X.length},deleteFile:function(F,A=!0){if(!G)H();let _=Q[F];this.getEntryChildren(_,A).map((q)=>q.entryName).forEach(this.deleteEntry)},deleteEntry:function(F){if(!G)H();let A=Q[F],_=X.indexOf(A);if(_>=0)X.splice(_,1),delete Q[F],W.totalEntries=X.length},getEntryChildren:function(F,A=!0){if(!G)H();if(typeof F==="object")if(F.isDirectory&&A){let _=[],w=F.entryName;for(let q of X)if(q.entryName.startsWith(w))_.push(q);return _}else return[F];return[]},getChildCount:function(F){if(F&&F.isDirectory){let A=this.getEntryChildren(F);return A.includes(F)?A.length-1:A.length}return 0},compressToBuffer:function(){if(!G)H();B();let F=[],A=[],_=0,w=0;W.size=0,W.offset=0;let q=0;for(let y of this.entries){let I=y.getCompressedData();y.header.offset=w;let d=y.packLocalHeader(),u=d.length+I.length;w+=u,F.push(d),F.push(I);let r=y.packCentralHeader();A.push(r),W.size+=r.length,_+=u+r.length,q++}_+=W.mainHeaderSize,W.offset=w,W.totalEntries=q,w=0;let M=Buffer.alloc(_);for(let y of F)y.copy(M,w),w+=y.length;for(let y of A)y.copy(M,w),w+=y.length;let C=W.toBinary();if(Y)Y.copy(C,C.length-Y.length);return C.copy(M,w),$=M,G=!1,M},toAsyncBuffer:function(F,A,_,w){try{if(!G)H();B();let q=[],M=[],C=0,y=0,I=0;W.size=0,W.offset=0;let d=function(u){if(u.length>0){let r=u.shift(),a=r.entryName+r.extra.toString();if(_)_(a);r.getCompressedDataAsync(function(Y$){if(w)w(a);r.header.offset=y;let J$=r.packLocalHeader(),L$=J$.length+Y$.length;y+=L$,q.push(J$),q.push(Y$);let O$=r.packCentralHeader();M.push(O$),W.size+=O$.length,C+=L$+O$.length,I++,d(u)})}else{C+=W.mainHeaderSize,W.offset=y,W.totalEntries=I,y=0;let r=Buffer.alloc(C);q.forEach(function(Y$){Y$.copy(r,y),y+=Y$.length}),M.forEach(function(Y$){Y$.copy(r,y),y+=Y$.length});let a=W.toBinary();if(Y)Y.copy(a,a.length-Y.length);a.copy(r,y),$=r,G=!1,F(r)}};d(Array.from(this.entries))}catch(q){A(q)}}}}});var l_=o((AC1,SN$)=>{var e8=gB(),s8=N0("path"),OO0=Te(),BO0=TN$(),r2=(...$)=>e8.findLast($,(J)=>typeof J==="boolean"),CN$=(...$)=>e8.findLast($,(J)=>typeof J==="string"),DO0=(...$)=>e8.findLast($,(J)=>typeof J==="function"),FO0={noSort:!1,readEntries:!1,method:e8.Constants.NONE,fs:null};SN$.exports=function($,J){let X=null,Q=Object.assign(Object.create(null),FO0);if($&&typeof $==="object"){if(!($ instanceof Uint8Array)){if(Object.assign(Q,$),$=Q.input?Q.input:void 0,Q.input)delete Q.input}if(Buffer.isBuffer($))X=$,Q.method=e8.Constants.BUFFER,$=void 0}Object.assign(Q,J);let Y=new e8(Q),W=(O)=>{O.filter((B)=>B.attr).sort((B,F)=>F.path.length-B.path.length).forEach((B)=>Y.fs.chmodSync(B.path,B.attr))};if(typeof Q.decoder!=="object"||typeof Q.decoder.encode!=="function"||typeof Q.decoder.decode!=="function")Q.decoder=e8.decoder;if($&&typeof $==="string")if(Y.fs.existsSync($))Q.method=e8.Constants.FILE,Q.filename=$,X=Y.fs.readFileSync($);else throw e8.Errors.INVALID_FILENAME();let G=new BO0(X,Q),{canonical:Z,sanitize:j,zipnamefix:V}=e8;function K(O){if(O&&G){var B;if(typeof O==="string")B=G.getEntry(s8.posix.normalize(O));if(typeof O==="object"&&typeof O.entryName<"u"&&typeof O.header<"u")B=G.getEntry(O.entryName);if(B)return B}return null}function z(O){let{join:B,normalize:F,sep:A}=s8.posix;return B(s8.isAbsolute(O)?"/":".",F(A+O.split("\\").join(A)+A))}function L(O){if(O instanceof RegExp)return function(B){return function(F){return B.test(F)}}(O);else if(typeof O!=="function")return()=>!0;return O}let H=(O,B)=>{let F=B.slice(-1);return F=F===Y.sep?Y.sep:"",s8.relative(O,B)+F};return{readFile:function(O,B){var F=K(O);return F&&F.getData(B)||null},childCount:function(O){let B=K(O);if(B)return G.getChildCount(B)},readFileAsync:function(O,B){var F=K(O);if(F)F.getDataAsync(B);else B(null,"getEntry failed for:"+O)},readAsText:function(O,B){var F=K(O);if(F){var A=F.getData();if(A&&A.length)return A.toString(B||"utf8")}return""},readAsTextAsync:function(O,B,F){var A=K(O);if(A)A.getDataAsync(function(_,w){if(w){B(_,w);return}if(_&&_.length)B(_.toString(F||"utf8"));else B("")});else B("")},deleteFile:function(O,B=!0){var F=K(O);if(F)G.deleteFile(F.entryName,B)},deleteEntry:function(O){var B=K(O);if(B)G.deleteEntry(B.entryName)},addZipComment:function(O){G.comment=O},getZipComment:function(){return G.comment||""},addZipEntryComment:function(O,B){var F=K(O);if(F)F.comment=B},getZipEntryComment:function(O){var B=K(O);if(B)return B.comment||"";return""},updateFile:function(O,B){var F=K(O);if(F)F.setData(B)},addLocalFile:function(O,B,F,A){if(Y.fs.existsSync(O)){B=B?z(B):"";let _=s8.win32.basename(s8.win32.normalize(O));B+=F?F:_;let w=Y.fs.statSync(O),q=w.isFile()?Y.fs.readFileSync(O):Buffer.alloc(0);if(w.isDirectory())B+=Y.sep;this.addFile(B,q,A,w)}else throw e8.Errors.FILE_NOT_FOUND(O)},addLocalFileAsync:function(O,B){O=typeof O==="object"?O:{localPath:O};let F=s8.resolve(O.localPath),{comment:A}=O,{zipPath:_,zipName:w}=O,q=this;Y.fs.stat(F,function(M,C){if(M)return B(M,!1);_=_?z(_):"";let y=s8.win32.basename(s8.win32.normalize(F));if(_+=w?w:y,C.isFile())Y.fs.readFile(F,function(I,d){if(I)return B(I,!1);return q.addFile(_,d,A,C),setImmediate(B,void 0,!0)});else if(C.isDirectory())return _+=Y.sep,q.addFile(_,Buffer.alloc(0),A,C),setImmediate(B,void 0,!0)})},addLocalFolder:function(O,B,F){if(F=L(F),B=B?z(B):"",O=s8.normalize(O),Y.fs.existsSync(O)){let A=Y.findFiles(O),_=this;if(A.length)for(let w of A){let q=s8.join(B,H(O,w));if(F(q))_.addLocalFile(w,s8.dirname(q))}}else throw e8.Errors.FILE_NOT_FOUND(O)},addLocalFolderAsync:function(O,B,F,A){A=L(A),F=F?z(F):"",O=s8.normalize(O);var _=this;Y.fs.open(O,"r",function(w){if(w&&w.code==="ENOENT")B(void 0,e8.Errors.FILE_NOT_FOUND(O));else if(w)B(void 0,w);else{var q=Y.findFiles(O),M=-1,C=function(){if(M+=1,M<q.length){var y=q[M],I=H(O,y).split("\\").join("/");if(I=I.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^\x20-\x7E]/g,""),A(I))Y.fs.stat(y,function(d,u){if(d)B(void 0,d);if(u.isFile())Y.fs.readFile(y,function(r,a){if(r)B(void 0,r);else _.addFile(F+I,a,"",u),C()});else _.addFile(F+I+"/",Buffer.alloc(0),"",u),C()});else process.nextTick(()=>{C()})}else B(!0,void 0)};C()}})},addLocalFolderAsync2:function(O,B){let F=this;O=typeof O==="object"?O:{localPath:O};let A=s8.resolve(z(O.localPath)),{zipPath:_,filter:w,namefix:q}=O;if(w instanceof RegExp)w=function(y){return function(I){return y.test(I)}}(w);else if(typeof w!=="function")w=function(){return!0};if(_=_?z(_):"",q==="latin1")q=(y)=>y.normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^\x20-\x7E]/g,"");if(typeof q!=="function")q=(y)=>y;let M=(y)=>s8.join(_,q(H(A,y))),C=(y)=>s8.win32.basename(s8.win32.normalize(q(y)));Y.fs.open(A,"r",function(y){if(y&&y.code==="ENOENT")B(void 0,e8.Errors.FILE_NOT_FOUND(A));else if(y)B(void 0,y);else Y.findFilesAsync(A,function(I,d){if(I)return B(I);if(d=d.filter((u)=>w(M(u))),!d.length)B(void 0,!1);setImmediate(d.reverse().reduce(function(u,r){return function(a,Y$){if(a||Y$===!1)return setImmediate(u,a,!1);F.addLocalFileAsync({localPath:r,zipPath:s8.dirname(M(r)),zipName:C(r)},u)}},B))})})},addLocalFolderPromise:function(O,B){return new Promise((F,A)=>{this.addLocalFolderAsync2(Object.assign({localPath:O},B),(_,w)=>{if(_)A(_);if(w)F(this)})})},addFile:function(O,B,F,A){O=V(O);let _=K(O),w=_!=null;if(!w)_=new OO0(Q),_.entryName=O;_.comment=F||"";let q=typeof A==="object"&&A instanceof Y.fs.Stats;if(q)_.header.time=A.mtime;var M=_.isDirectory?16:0;let C=_.isDirectory?16384:32768;if(q)C|=4095&A.mode;else if(typeof A==="number")C|=4095&A;else C|=_.isDirectory?493:420;if(M=(M|C<<16)>>>0,_.attr=M,_.setData(B),!w)G.setEntry(_);return _},getEntries:function(O){return G.password=O,G?G.entries:[]},getEntry:function(O){return K(O)},getEntryCount:function(){return G.getEntryCount()},forEach:function(O){return G.forEach(O)},extractEntryTo:function(O,B,F,A,_,w){A=r2(!1,A),_=r2(!1,_),F=r2(!0,F),w=CN$(_,w);var q=K(O);if(!q)throw e8.Errors.NO_ENTRY();var M=Z(q.entryName),C=j(B,w&&!q.isDirectory?Z(w):F?M:s8.basename(M));if(q.isDirectory){var y=G.getEntryChildren(q);return y.forEach(function(u){if(u.isDirectory)return;var r=u.getData();if(!r)throw e8.Errors.CANT_EXTRACT_FILE();var a=Z(F?u.entryName:u.entryName.substring(q.entryName.length)),Y$=j(B,a);let J$=_?u.header.fileAttr:void 0;Y.writeFileTo(Y$,r,A,J$)}),!0}var I=q.getData(G.password);if(!I)throw e8.Errors.CANT_EXTRACT_FILE();if(Y.fs.existsSync(C)&&!A)throw e8.Errors.CANT_OVERRIDE();let d=_?O.header.fileAttr:void 0;return Y.writeFileTo(C,I,A,d),!0},test:function(O){if(!G)return!1;for(var B of G.entries)try{if(B.isDirectory)continue;var F=B.getData(O);if(!F)return!1}catch(A){return!1}return!0},extractAllTo:function(O,B,F,A){if(F=r2(!1,F),A=CN$(F,A),B=r2(!1,B),!G)throw e8.Errors.NO_ZIP();let _=[];G.entries.forEach(function(w){var q=j(O,Z(w.entryName));if(w.isDirectory){if(Y.makeDir(q),F)_.push({path:q,attr:w.header.fileAttr});return}var M=w.getData(A);if(!M)throw e8.Errors.CANT_EXTRACT_FILE();let C=F?w.header.fileAttr:void 0;Y.writeFileTo(q,M,B,C);try{Y.fs.utimesSync(q,w.header.time,w.header.time)}catch(y){}}),W(_)},extractAllToAsync:function(O,B,F,A){if(A=DO0(B,F,A),F=r2(!1,F),B=r2(!1,B),!A)return new Promise((I,d)=>{this.extractAllToAsync(O,B,F,function(u){if(u)d(u);else I(this)})});if(!G){A(e8.Errors.NO_ZIP());return}O=s8.resolve(O);let _=(I)=>j(O,s8.normalize(Z(I.entryName))),w=(I,d)=>Error(I+': "'+d+'"'),q=[],M=[];G.entries.forEach((I)=>{if(I.isDirectory)q.push(I);else M.push(I)});let C=[];for(let I of q){let d=_(I),u=F?I.header.fileAttr:void 0;try{Y.makeDir(d)}catch(r){A(w("Unable to create folder",d));continue}if(u)C.push({path:d,attr:u});try{Y.fs.utimesSync(d,I.header.time,I.header.time)}catch(r){}}let y=(I)=>{if(!I)try{W(C)}catch(d){return A(w("Unable to set folder permissions",d.path||""))}A(I)};M.reverse().reduce(function(I,d){return function(u){if(u)I(u);else{let r=s8.normalize(Z(d.entryName)),a=j(O,r);d.getDataAsync(function(Y$,J$){if(J$)I(J$);else if(!Y$)I(e8.Errors.CANT_EXTRACT_FILE());else{let L$=F?d.header.fileAttr:void 0;Y.writeFileToAsync(a,Y$,B,L$,function(O$){if(!O$)return I(w("Unable to write file",a));Y.fs.utimes(a,d.header.time,d.header.time,function(){I()})})}})}}},y)()},writeZip:function(O,B){if(arguments.length===1){if(typeof O==="function")B=O,O=""}if(!O&&Q.filename)O=Q.filename;if(!O)return;var F=G.compressToBuffer();if(F){var A=Y.writeFileTo(O,F,!0);if(typeof B==="function")B(!A?Error("failed"):null,"")}},writeZipPromise:function(O,B){let{overwrite:F,perm:A}=Object.assign({overwrite:!0},B);return new Promise((_,w)=>{if(!O&&Q.filename)O=Q.filename;if(!O)w("ADM-ZIP: ZIP File Name Missing");this.toBufferPromise().then((q)=>{let M=(C)=>C?_(C):w("ADM-ZIP: Wasn't able to write zip file");Y.writeFileToAsync(O,q,F,A,M)},w)})},toBufferPromise:function(){return new Promise((O,B)=>{G.toAsyncBuffer(O,B)})},toBuffer:function(O,B,F,A){if(typeof O==="function")return G.toAsyncBuffer(O,B,F,A),null;return G.compressToBuffer()}}}});function IN$($,J,X=z5){if(X.length===0)return"";let Y=$.trim().toLowerCase()===U5?X[0]:X.find((W)=>W.version===$);if(!Y)return"";return J==="android"?Y.apkSha256:Y.ipaSha256}function Eb($=process.env,J=z5){if(J.length===0)return;let X=Z4($);return X===U5?J[0]:J.find((Q)=>Q.version===X)}function Se($=process.env,J=z5){return Eb($,J)?.runnerSha256??""}function kN$($=process.env,J=z5){return Eb($,J)?.runnerSha256Target??"runner"}function qO0($=z5){if($.length===0)return U5;return $[0].version}function C9($,J=z5){if($===U5)return qO0(J);return $}function AO0($){let J=$[xN$];return J==="1"||J?.toLowerCase()==="true"}function Ie($,J,X=process.env){let Q;try{Q=new URL($)}catch{throw new R(`${J} must be an absolute URL, for example https://mirror.example/auto-mobile.`)}if(Q.protocol==="https:")return;if(AO0(X))return;throw new R(`${J} must use https:// (got ${Q.protocol}//). Plaintext/non-TLS asset downloads are a confidentiality and downgrade risk. Set ${xN$}=1 to opt out for a trusted loopback/dev mirror.`)}function Z4($=process.env){let J=$[NO0]?.trim();if(!J||J.length===0)return U5;return J.toLowerCase()===U5?U5:J}function dj($=process.env){return Z4($)!==U5}function t2($=process.env,J=z5){let X=Z4($);if(X===U5)return J.length>0;return J.some((Q)=>Q.version===X)}function Pb($=process.env){let J=$[Rb]?.trim();if(J&&J.length>0){let X;try{X=new URL(J)}catch{throw new R(`${Rb} must be an absolute URL, for example https://mirror.example/auto-mobile.`)}if(J.includes("?")||J.includes("#"))throw new R(`${Rb} must not include a query string or fragment; use a path-only base URL such as ${X.origin}${X.pathname.replace(/\/+$/,"")}.`);return Ie(`${X.origin}${X.pathname}`,Rb,$),`${X.origin}${X.pathname}`.replace(/\/+$/,"")}return Ce}function Tb($,J,X=Ce,Q=z5){let Y=C9(J,Q);if(Y===U5){if(X===Ce)return`https://github.com/kaeawc/auto-mobile/releases/latest/download/${$}`;return`${X}/latest/${$}`}return`${X}/${Y}/${$}`}function nj($=process.env,J=z5){return Tb("control-proxy-debug.apk",Z4($),Pb($),J)}function a2($=process.env,J=z5){return Tb("control-proxy.ipa",Z4($),Pb($),J)}function _U($=process.env){return IN$(Z4($),"android")}function s2($=process.env){return IN$(Z4($),"ios")}function bN$($=process.env,J=z5){return Tb(_O0,Z4($),Pb($),J)}function yN$($=process.env,J=z5){return Eb($,J)?.videoJarSha256??""}function fN$($=process.env,J=z5){return Tb(ke,Z4($),Pb($),J)}function vN$($=process.env,J=z5){return Eb($,J)?.screenCaptureHelperSha256??""}function C7($=process.env){return`${wO0}@${C9(Z4($))}`}var U5="latest",z5,wO0="@kaeawc/auto-mobile",NO0="AUTOMOBILE_VERSION",Rb="AUTOMOBILE_ASSET_BASE_URL",xN$="AUTOMOBILE_ALLOW_INSECURE_ASSET_URL",Ce="https://github.com/kaeawc/auto-mobile/releases/download",_O0="automobile-video.jar",ke="screen-capture-helper-macos-universal.zip",MC1,RC1,EC1,PC1,Cb="",TC1;var IJ=D(()=>{l4();z5=[{version:"0.0.58",apkSha256:"fcace1ddf3bde22b780190f4fad5ecc4e8e85321881eece1203805d0578eb5ca",ipaSha256:"09e53b39283117782c0db99c57bf36163d91582c47989fd784e981b114069ad3",runnerSha256:"e4c016a662246c72455b0231714f26a9b283086ef571a7d912dc7c8ffff6a2ec",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"01f97581849f1cf3a0a258e4cd71434f7798b5dc11dab99ff760be757c765f6d"},{version:"0.0.57",apkSha256:"97595fe23177ce5c8e44b7a50a1061ea5804797764fee0062dd5553720e4894c",ipaSha256:"13c3b995c2ac6f32cbc9f7f56fe97335025d570a5b9a968aa14b5ccf8e1d129f",runnerSha256:"898af838e3c5e41576dc2cd98dd46d059fe690c7a3db27306bf6c4f62d493f17",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"bd230276077391a5e97a2034e950c03714f8798bab8c94f5ce7bdd56cd70b585"},{version:"0.0.56",apkSha256:"cf3d479a44637ec2b8c05888207b5e3a20fb7f67f0706ac65c2274beb61ab944",ipaSha256:"621c6cdeb6d9e88b04072f9daf7f955051129be16fddd1c3828620a47e4aaa37",runnerSha256:"31094d3e12b1678252bbc27170e3d2a4c38818cea6b3c10e6cfbadf1e6051761",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"41c42eb5896e09f33ca2d09ef712217ef59cbd5f7b4abc2df812e77fc463bed5"},{version:"0.0.55",apkSha256:"c12f8f5d47a252c3128d5f71bcae56fb586c6c34c573fc6d5f7a2d19e108c6c8",ipaSha256:"73560b76e2dcb707ff0a0724214deb77bdceedebfbffb7ebd02d5942a48661da",runnerSha256:"c56afd1de9fa4fc8bee260b8c73b8da61eefd931e42330c906982fb8796ac00f",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"7d97186fca4d74a223a027a563e96d7879248f17979ead5bdf68c927522a9c3b"},{version:"0.0.54",apkSha256:"75289f35aa378d5bf335c9f4479f94012ebd3c20987ea47cb8ab961de38712d2",ipaSha256:"2810e3752c7fe1d3bf018f4ed34679a8b9aca6d696e0f4699b1ba74d8e5c2c38",runnerSha256:"4a0541207649738137b1c9f249496bbb8f22e8fcea09a0bea22f419716a6123f",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"2e2f4ede42ebc510fb9997c36e0838ee67e09ca93e18d7dedf68a91635413753"},{version:"0.0.53",apkSha256:"90abd8d18acb664e4bca01f0ff3c6b62356bf38c422850c5e81cea02a99aba83",ipaSha256:"f59df4678c2d92b9c0572599e4babdffa3125343cf49f74a47b97635131ae003",runnerSha256:"be40cd445514b83a9d5fae54cbd1688fc5f20292d2f70f8016a473644d371b72",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"038046ef2f043729f9cf38f1bdc7d7bbe6070a919759105a5470df2c0fb14fb3"},{version:"0.0.52",apkSha256:"b733c267e42d4af3b24ba15ae7c94393cdf775018c3167deb13d06f33c6d5124",ipaSha256:"f8c9d00607dfc9c25bd7ee3de785f5a0f7e516ee90c6a7209ae5af9129063be5",runnerSha256:"7573432ea9c86c29acec30662ad7512cdb299150bc607350c7e3361882577f1c",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"f15e2bc4f4b2fece0daa85cb3fa3acbfcd08318cc420fc0637b469cd078d34b8"},{version:"0.0.51",apkSha256:"e9da610303113dd13094b3f885090b846f5b8705ac203b09deeb267801049255",ipaSha256:"db5606723087f7b973893d4adefcdeb6aadf1da0e2bcc435ce1fe8787bafb712",runnerSha256:"abba47298118068aaad3b8ea4502d685263b6e83cd2c30bb0518840cb8443202",runnerSha256Target:"xctest",videoJarSha256:"e5ce791aed17a1bf391db5737367a8ca2d7792b805f2fa4235e4ec7f8cee062c",screenCaptureHelperSha256:"a46ec61cdd2c3ab64e0f621f3498726578e52bee407d16cd90cde32ca8164798"},{version:"0.0.50",apkSha256:"8007f267d566144d805d29d22fb0e69790d34edcdbdd0d444bad6d80175943e2",ipaSha256:"838025a37b8a9f0d15b0b1ad06ff40e5a2b0b3e09eeca845f9a874d3bac4030d",runnerSha256:"5e53b1614986f90b875e5ada0a8c97f5343c22e70bdaeafd9a8389e5b6ef78ae",runnerSha256Target:"xctest",videoJarSha256:"254d1bad102a96b1e8e90ee9ff6ff991aa6d65f7a36a35c3887db91f369ea12e",screenCaptureHelperSha256:"965a49653d0c8bc8a88d45e1919ef0a62267d6774c50579411076dbe397bb89d"},{version:"0.0.49",apkSha256:"c1023110ebbd12c012880b08be6715d2389294fd24c4a147a40d1d342ec473da",ipaSha256:"dbeacd346a39976414432964de1250a3f356baf783cd3a83d916f0117e772d5b",runnerSha256:"fc033a529c67d373c6eca965ec063343b6164628d62e14eca220385810427ae6",runnerSha256Target:"xctest",videoJarSha256:"254d1bad102a96b1e8e90ee9ff6ff991aa6d65f7a36a35c3887db91f369ea12e",screenCaptureHelperSha256:"67079809a52e3cad50a38f04e4e25d795c0756b35352b377ba9609bebb62ab0f"},{version:"0.0.48",apkSha256:"059162e622fbe25bce40b32658c9749318a909eb8b48398648c77a84cf3c25aa",ipaSha256:"86558163f69a0bf36e69546dbf685d16d8f3bf05385f1f7795a164e3a5fddf96",runnerSha256:"ff000ff053a57a1dac1d552463e474fdea5346acb08c96051695554e73428317",runnerSha256Target:"xctest",videoJarSha256:"1cada2f3bc86cacbed76efc8e46c1e110cb0b046036502b422d67cce0725cf4b",screenCaptureHelperSha256:"f284e9863cedb2e02de25f526114fd4017eece1ce1e19337210647c7b49d1898"},{version:"0.0.47",apkSha256:"aa50a056447337ca14c251795b064e792879a28d088fe484fe57893a020b9323",ipaSha256:"ef5d10dd97d78d8e372680fffbb511335781b03ffbf0c91e2692048da4c5f143",runnerSha256:"078375d34d3e8bfa0c3171e3f1a6558d0ca2c0ca1f0c5999cb49077934fbfc0a",runnerSha256Target:"xctest",videoJarSha256:"5e3760d04436af89ec909586bd244d79cd7acec9b84993f4302fa7bf480916cb",screenCaptureHelperSha256:"501e1253ded9fa2f331051b88013b47ca37343a1966fc106d4fcaa5e9bbe4c39"},{version:"0.0.46",apkSha256:"00771c13f372baff325c659e2b40050e72951fd8adfc395cff667850a2a9b376",ipaSha256:"ef353a4f14fa7615810de891595d118ff193d43fcc940f936f4d11ae311dd563",screenCaptureHelperSha256:"da7e138266156eedda9f8cb98bb7d5b63f29ad28746a1c144a16122a1639e2b2",runnerSha256:"b0eb970aad424d1c0dd84261c26d74b8c95570ba0f3866f18f1755586184c51a",runnerSha256Target:"xctest",videoJarSha256:"3f3135e22fffed1e088bd434545eec873a5aec48c7c038cd2ffecdeb6b642c06"},{version:"0.0.45",apkSha256:"68dbf04ba3c1871da0ed9ec540e1dbfec08610dd2afc1706d4a7fd94d1c3b5b1",ipaSha256:"8c678b2d7ae4b5c25400f8fd53cb5e1f12d730950e0eef4e608dfb8b50dcd773",runnerSha256:"bb5234ca32636506e5b8e02662381895eaedeefbcf007598e3ee9b9ac3c501b5",runnerSha256Target:"xctest",videoJarSha256:"bae314fbaa3f3101ab5f7ba5eddc9bd77bb927c54cb508d38ed04ca9544b9a51"},{version:"0.0.44",apkSha256:"e95f2b14e218bc51e92a44680cf38ceca9c9143014b2f74b803f47650614cf39",ipaSha256:"73dd4551ef7226d67a46423f6925775fc10d68198913b5b23bc1cbdceb50b663",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.43",apkSha256:"7e4e2ce3c19b7473d171433186dbc7487df60ff6045dba66da7a320d31e63cd3",ipaSha256:"db0e3c4c172681068ae7ae24182f5569519b5fab034fbcf0e85abdc952b398dd",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.42",apkSha256:"cb00a835f58ce2d0344483f27b7c35036bb6faa973aa3fcc66fe67e75428abb0",ipaSha256:"de55b77ee0e821b4f08b7cd1b84f9a2706f69279422901546e2dc6fdd4cc3f0f",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.41",apkSha256:"ee1dff240e4dfc89b016197c80e929797485aa23292e061eee361b7404c772b4",ipaSha256:"01eaedef0cfcf38acd0a1fa8eebe08c3009e5db59320b23a045cd26506eb235c",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.40",apkSha256:"8e89fbab6462ac1ead1f3f0a334aff4f5f299e7ae72e192045cf75e893ca87aa",ipaSha256:"38adaed641ac6a8590773682e127a80a86c54e5804d47394e1b0cd437009b9ff",runnerSha256:"b281f9fd516116164a76dc049a413d5123bfb7bf96c79c6ad654ba90c08ed982"},{version:"0.0.39",apkSha256:"eaad59dd85e17c4633098b772b9f761f2124ffb73a5ca7ede703a9b435046942",ipaSha256:"87a720544c83718e5b70c987aecf30d2e43bdb0f23163ac75ac225bb4aec0ae4",runnerSha256:""},{version:"0.0.38",apkSha256:"0fb955a617654695036642662634d042c2e3d278b8e1dce20ccb37e425f059f3",ipaSha256:"f5a4a485ff8ebf3bfd0d73c8b7b10769177b419ccd62e48db188bb5122a2fcde",runnerSha256:""},{version:"0.0.37",apkSha256:"f9b0cc92bf8f7416cdb0c458e16c7a41e4fdeefb80bb9429ab7c603388c99083",ipaSha256:"caccbfaa4da0015bab701a36b81ac87e3f3f3330cee77bb10ec8553724275f4f",runnerSha256:""},{version:"0.0.36",apkSha256:"b5f56bb0ab065c60385a22013c97ee706213eb16deb5d4bcfa42f0a707b8620a",ipaSha256:"40e973dc8c87149e40a616658c74d90e648c6514cc642a5c3dd4a45a187e7600",runnerSha256:""},{version:"0.0.35",apkSha256:"039b359bcf35f1ab6cc666005a57823d71a771a96bd9bcaf4f82f2ec945e306d",ipaSha256:"e6afdfd04a90d2388dc4604e7957d3eef87b90a51ca37c5457b8139a54728108",runnerSha256:""},{version:"0.0.34",apkSha256:"4dcee4f6a7359847d081c5e184c57ed100ad135af2e62f3abfc7b0defaa1153c",ipaSha256:"c2a26ca065c85e9f8d5cfcd6dbad1dbaf3ce38b18d770b0983f7bad62129e4a3",runnerSha256:""},{version:"0.0.33",apkSha256:"7289eba90b22890d3c36e05e99db72a545fa4becdf46df079885783a919e6aed",ipaSha256:"425dfa4db4ad5a4febc9f05ffc97df38f3a1098ccdd9330adff1c0b5c877697d",runnerSha256:""},{version:"0.0.32",apkSha256:"4c4a743af5d18ed58214e64b85986c9e2f2332b015edcf7d9d68a24cd6dfda21",ipaSha256:"40f4d9084d3368995b57c0e81c4fe85f38851353da9f789eaff93027aee456a0",runnerSha256:""},{version:"0.0.31",apkSha256:"0b5802ada8d9adccdb69ee140ae788b3251832c0605d2f6baa3e9b7a78260764",ipaSha256:"e60f8689fb6ddd5c06a5d2ff57569b264f407229afb986258d1ce20326dc24c7",runnerSha256:""},{version:"0.0.30",apkSha256:"a1be5e6240f204ee99540e99cc198f7c0b592dbaf3699330c14f6ded7d333ec3",ipaSha256:"5ac285dd5be16439d3a8a8973c98606920461acfce489830e54ee20759a7b235",runnerSha256:""},{version:"0.0.29",apkSha256:"b33a67c7efa84aca2b07faa965aecb3b1819b4defd441dcc8d3bf7e2af209cd8",ipaSha256:"d47c1aea4495270c1489cae361286ea1439c2ba4e7d5bcfd73f66e4580a6c45d",runnerSha256:""},{version:"0.0.28",apkSha256:"0f683d5939bc308afe038ea1259eb29997dff38af0795136a281ad305986e40e",ipaSha256:"eee7accfbca717bb8b89fafd0676f10d8bb08561c3fbd7a04750c9b12c2a7104",runnerSha256:""},{version:"0.0.27",apkSha256:"9966113ae44f38f3cf34544b1375d3c9a3706701edba45a1eec1f220b9c676cc",ipaSha256:"8620de6b014df18465876334f9ba8c106292f6c3059370eea2349f1e44db4f4d",runnerSha256:""},{version:"0.0.26",apkSha256:"2eb2f156fd27602c85003ab8f6e00d3e06850e84f5453d75b7494aa5bbed7be0",ipaSha256:"905df276d2224d31cbc5aa2258d2dcc60eaeb9813727081ddd32c95394fec411",runnerSha256:""},{version:"0.0.25",apkSha256:"f727079edb4906e3b7928dbb641e788543e86b11fff3fc1b76f0c51b9c8d6e5d",ipaSha256:"d8032cc1cebcb456b7232aa67fc42c89ff62729bacf141aa8f594ce6f8bcd980",runnerSha256:""},{version:"0.0.24",apkSha256:"9047795bc6098f4ec687c126123c73c423806a9fd52888af391d6fb5b94ac93f",ipaSha256:"1dd3e0370cb8ed01d8e1020558d8a2808f208bd947bafcf6688211eddc928bf8",runnerSha256:""},{version:"0.0.18",apkSha256:"fd3c8d9f0b8542eaad56c78b18cf8e5666367b04ae8c4af74d8aa6dd1c8d1834",ipaSha256:"2a5eec63bce2f9dfc227c0732fcce67378305e945604d5eedd0e3df48e37fd39",runnerSha256:""},{version:"0.0.17",apkSha256:"916033440931666644474f227c8e39d13d9c80c3515e4292cc5581fd5bd4cc2f",ipaSha256:"e4dcf064d024f2371b8fd79281000e2d49751ef95b8817d1494d685aeda746ac",runnerSha256:""}];MC1=nj({}),RC1=_U({}),EC1=a2({}),PC1=s2({}),TC1=Se({})});import{createReadStream as MO0}from"fs";import{createHash as RO0}from"crypto";class d5{async computeFileSha256($){let J=RO0("sha256");return await new Promise((X,Q)=>{let Y=MO0($);Y.on("data",(W)=>J.update(W)),Y.on("error",Q),Y.on("end",()=>X())}),{checksum:J.digest("hex"),source:"node"}}}var MU=()=>{};import{AsyncLocalStorage as EO0}from"async_hooks";var hN$,uB=async($,J)=>{return hN$.run({signal:$},J)},PX=()=>{return hN$.getStore()?.signal};var ij=D(()=>{hN$=new EO0});import{execFile as PO0}from"child_process";import{createWriteStream as TO0}from"fs";import*as uN$ from"fs/promises";import CO0 from"http";import SO0 from"https";import*as mN$ from"path";import{promisify as IO0}from"util";class DY{async download($,J,X){if(X??=PX(),X?.aborted)throw Error(`Download aborted before starting: ${$}`);await uN$.mkdir(mN$.dirname(J),{recursive:!0});try{await this.downloadWithCurl($,J,X);return}catch(Q){if(!this.isCommandUnavailable(Q,"curl"))throw Q;U.warn("[FileDownloader] curl unavailable, falling back to wget",{error:Q instanceof Error?Q.message:String(Q)})}try{await this.downloadWithWget($,J,X);return}catch(Q){if(!this.isCommandUnavailable(Q,"wget"))throw Q;U.warn("[FileDownloader] wget unavailable, falling back to Node HTTP",{error:Q instanceof Error?Q.message:String(Q)})}await this.downloadWithNodeHttp($,J,0,X)}async downloadWithCurl($,J,X){await gN$("curl",["--fail","--location","--retry","3","--retry-delay","1","--silent","--show-error","-o",J,$],{timeout:120000,maxBuffer:10485760,signal:X})}async downloadWithWget($,J,X){await gN$("wget",["--tries=3","--timeout=30","-O",J,$],{timeout:120000,maxBuffer:10485760,signal:X})}async downloadWithNodeHttp($,J,X,Q){if(X>5)throw Error(`Too many redirects while downloading ${$}`);await new Promise((Y,W)=>{let G=$.startsWith("https:")?SO0:CO0,Z=()=>{j.destroy(Error(`Download aborted: ${$}`))},j=G.get($,{headers:{"User-Agent":"auto-mobile"}},(V)=>{let K=V.statusCode??0;if(K>=300&&K<400&&V.headers.location){V.resume();let L=new URL(V.headers.location,$).toString();this.downloadWithNodeHttp(L,J,X+1,Q).then(Y).catch(W);return}if(K<200||K>=300){V.resume(),W(Error(`Download failed with status ${K} from ${$}`));return}let z=TO0(J);V.pipe(z),z.on("finish",()=>z.close(()=>Y())),z.on("error",(L)=>{z.close(),W(L)})});if(j.setTimeout(30000,()=>{j.destroy(Error(`Download request timed out for ${$}`))}),j.on("error",W),j.once("close",()=>Q?.removeEventListener("abort",Z)),Q?.addEventListener("abort",Z,{once:!0}),Q?.aborted)Z()})}isCommandUnavailable($,J){if(!$||typeof $!=="object")return!1;let X=$,Q=typeof X.code==="number"?X.code:Number(X.code);if(X.code==="ENOENT"||!Number.isNaN(Q)&&Q===127)return!0;let Y=`${X.message??""} ${X.stderr??""}`.toLowerCase();if(Y.includes("command not found")||Y.includes("not recognized as an internal or external command")||Y.includes(`${J}: not found`)||Y.includes(`not found: ${J}`))return!0;return!1}}var gN$;var mB=D(()=>{n();ij();gN$=IO0(PO0)});import{setTimeout as kO0}from"timers/promises";class lB{async sleep($){return kO0($)}setTimeout($,J){return global.setTimeout($,J)}clearTimeout($){global.clearTimeout($)}setInterval($,J){return global.setInterval($,J)}clearInterval($){global.clearInterval($)}now(){return Date.now()}}var g;var U$=D(()=>{g=new lB});import*as L5 from"fs/promises";import Sb from"path";class S7{static instance=null;static expectedChecksumOverride=null;downloader;checksumCalculator;cacheDir;usesDefaultCacheDir;timer;env;inFlight=null;constructor($={}){this.downloader=$.downloader??new DY,this.checksumCalculator=$.checksumCalculator??new d5,this.timer=$.timer??g,this.env=$.env??process.env,this.usesDefaultCacheDir=$.cacheDir===void 0,this.cacheDir=$.cacheDir??D9(pN$)}static getInstance(){if(S7.instance===null)S7.instance=new S7;return S7.instance}static resetInstances(){S7.instance=null,S7.expectedChecksumOverride=null}static setExpectedChecksumForTesting($){S7.expectedChecksumOverride=$}async computeLocalJarIntegrity($){let[{checksum:J},X]=await Promise.all([this.checksumCalculator.computeFileSha256($),L5.stat($)]);return{sha256:J.toLowerCase(),size:X.size}}get cachedJarPath(){return Sb.join(this.cacheDir,cN$)}get metadataPath(){return Sb.join(this.cacheDir,dN$)}expectedChecksum(){return S7.expectedChecksumOverride??yN$(this.env)}async ensure(){if(this.inFlight!==null)return this.inFlight;return this.inFlight=this.doEnsure().finally(()=>{this.inFlight=null}),this.inFlight}async doEnsure(){let $=this.expectedChecksum();if($.length===0)return U.info("[VIDEO_JAR] Expected checksum unknown for the pinned version; returning null without touching the network (jar is integrity-unverifiable)"),null;let J=await this.tryCache($);if(J)return U.info("[VIDEO_JAR] Reusing verified cached jar",{path:J}),J;return this.download($)}async tryCache($){let J;try{J=JSON.parse(await L5.readFile(this.metadataPath,"utf8"))}catch(Q){return U.debug(`[VIDEO_JAR] No usable cache metadata (cache miss): ${Q}`),null}if(J.sha256.toLowerCase()!==$.toLowerCase())return null;let X;try{X=await L5.stat(this.cachedJarPath)}catch(Q){return U.debug(`[VIDEO_JAR] Cached jar file missing despite metadata: ${Q}`),null}if(X.size!==J.size)return U.warn("[VIDEO_JAR] Cached jar size differs from sidecar; will re-download",{expected:J.size,actual:X.size}),null;return this.cachedJarPath}async ensureSecureCacheDir(){if(this.usesDefaultCacheDir)return NU(pN$);return await L5.mkdir(this.cacheDir,{recursive:!0,mode:xO0}),this.cacheDir}async download($){let J=bN$(this.env),X=await this.ensureSecureCacheDir(),Q=Sb.join(X,cN$),Y=`${Q}.download`;U.info("[VIDEO_JAR] Downloading persistent-encoder jar",{url:J,destination:Y});try{await this.downloader.download(J,Y),await L5.chmod(Y,lN$);let{checksum:W}=await this.checksumCalculator.computeFileSha256(Y);if(W.toLowerCase()!==$.toLowerCase())throw new R(`video-server jar checksum verification failed. Expected: ${$}, Got: ${W}. The downloaded automobile-video.jar does not match the pinned release checksum; this indicates a corrupted or tampered download and is never silently accepted.`);if(!this.hasClassesDex(Y))throw new R("video-server jar is not a valid zip containing classes.dex (truncated or error-page download).");let{size:G}=await L5.stat(Y);return await L5.rename(Y,Q),await this.writeMetadata(X,W,G),U.info("[VIDEO_JAR] Downloaded, verified, and cached jar",{path:Q,sha256:W}),Q}catch(W){throw await L5.rm(Y,{force:!0}).catch(()=>{}),W}}async writeMetadata($,J,X){let Q={version:Z4(this.env),sha256:J,size:X,downloadedAt:this.timer.now()};await L5.writeFile(Sb.join($,dN$),JSON.stringify(Q,null,2),{encoding:"utf8",mode:lN$})}hasClassesDex($){try{return new nN$.default($).getEntries().some((X)=>X.entryName===bO0)}catch(J){return U.warn("[VIDEO_JAR] Structural check failed (not a valid zip)",{path:$,error:J instanceof Error?J.message:String(J)}),!1}}}var nN$,lN$=384,xO0=448,pN$="video-server",cN$="automobile-video.jar",dN$="video-server-jar.json",bO0="classes.dex";var Ib=D(()=>{IJ();l4();MU();mB();n();U$();MX();nN$=f1(l_(),1)});function $9($){return $===!0||$==="true"}function iN$($){return $===!1||$==="false"}function xe($){return typeof $==="string"&&yO0.has($)}var yO0;var be=D(()=>{yO0=new Set(["done","go","search","send"])});function FY($){if(!$)return null;let{nativeScale:J,pixelWidth:X,pixelHeight:Q}=$;if(typeof J!=="number"||!Number.isFinite(J)||J<=0||typeof X!=="number"||!Number.isFinite(X)||X<=0||typeof Q!=="number"||!Number.isFinite(Q)||Q<=0)return null;return{nativeScale:J,pixelWidth:X,pixelHeight:Q}}function p_($){return FY($)??{}}var ye="immediate";var r$=D(()=>{l4();be()});function rN$($){return $==="main"?"4d002a":"42e02a"}function pB($,J){return Math.ceil($/16)*Math.ceil(J/16)}function tN$($){return $.length>=4&&($[0]&31)===7?$.subarray(1,4).toString("hex"):void 0}function fO0($){let J=tN$($);return J?Number.parseInt(J.slice(4,6),16):void 0}function aN$($,J="constrained-baseline"){let X=tN$($);if(X&&!ve(X,J))return{compatible:!1,reason:`H.264 SPS profile ${X.slice(0,4)} is incompatible with negotiated ${J}.`};let Q=fO0($);if(Q!==void 0&&Q>42)return{compatible:!1,reason:`H.264 SPS level ${Q} exceeds negotiated level 42.`};return{compatible:!0}}function ve($,J){return J==="main"?hO0($):vO0($)}function vO0($){return Number.parseInt($.slice(0,2),16)===66}function hO0($){return Number.parseInt($.slice(0,2),16)===77}var oN$="constrained-baseline",fe=42,eW=8192;class c_{chunks=[];headOffset=0;length=0;append($){if($.length===0)return;this.chunks.push($),this.length+=$.length}peek($){if($>this.length)throw RangeError(`cannot peek ${$} bytes from ${this.length}-byte queue`);let J=this.chunks[0];if(J.length-this.headOffset>=$)return J.subarray(this.headOffset,this.headOffset+$);let Q=Buffer.allocUnsafe($);return this.copyTo(Q,$),Q}takeDetached($){if($>this.length)throw RangeError(`cannot take ${$} bytes from ${this.length}-byte queue`);let J=Buffer.allocUnsafe($);return this.copyTo(J,$),this.discard($),J}discard($){if($>this.length)throw RangeError(`cannot discard ${$} bytes from ${this.length}-byte queue`);let J=$;while(J>0){let Q=this.chunks[0].length-this.headOffset;if(J<Q){this.headOffset+=J,this.length-=J;return}this.chunks.shift(),this.headOffset=0,this.length-=Q,J-=Q}}toBuffer(){if(this.length===0)return Buffer.alloc(0);let $=this.chunks[0];if(this.chunks.length===1)return $.subarray(this.headOffset);let J=Buffer.allocUnsafe(this.length);return this.copyTo(J,this.length),J}replace($){this.chunks=$.length===0?[]:[$],this.headOffset=0,this.length=$.length}copyTo($,J){let X=0;for(let Q=0;X<J;Q++){let Y=this.chunks[Q],W=Q===0?this.headOffset:0,G=Y.length-W,Z=Math.min(G,J-X);Y.copy($,X,W,W+Z),X+=Z}}}class xb{buffer=new c_;pendingHeader=null;highWaterMarkBytes=0;resynchronizing=!1;push($,J,X,Q,Y){let W=[],G=0;while(G<$.length){let Z=RU+kb-this.buffer.length;if(Z===0){if(!this.decodeAvailable(W,J,X,Q,Y))throw Error("FrameDecoder reached its raw-frame buffer limit without a complete frame");continue}let j=Math.min($.length,G+Z);this.buffer.append($.subarray(G,j)),this.highWaterMarkBytes=Math.max(this.highWaterMarkBytes,this.buffer.length),G=j,this.decodeAvailable(W,J,X,Q,Y)}return W}getMetrics(){return{bufferedBytes:this.buffer.length,highWaterMarkBytes:this.highWaterMarkBytes,maxBufferedBytes:RU+kb}}decodeAvailable($,J,X,Q,Y){let W=!1;while(!0){if(this.resynchronizing&&!this.resynchronize())return W;if(this.pendingHeader===null){let V=this.takeHeader(J);if(V==="starved")return W;if(V==="malformed"){W=!0;continue}this.pendingHeader=V,W=!0}let G=this.pendingHeader,Z=cO0(G);if(this.buffer.length<Z)return W;let j=this.buffer.takeDetached(Z);this.emitRecord(G,j,$,X,Q,Y),this.pendingHeader=null,W=!0}}emitRecord($,J,X,Q,Y,W){if(ue($)){Q?.({pcm16le:J});return}if(me($)){W?.({keyframe:($.height&pO0)!==0,presentationTimestampMs:$.timestampMs,payload:J});return}let G={header:$,pixels:J};if(Y)Y(G);else X.push(G)}takeHeader($){if(this.buffer.length<RU)return"starved";let J=this.buffer.peek(RU),X=eN$(J,0);if(X)return this.resynchronizing=!0,$?.({reason:X,header:ge(J,0)}),"malformed";let Q=ge(J,0);return this.buffer.discard(RU),Q}resynchronize(){let $=this.buffer.toBuffer(),J=0;while(J<=$.length-he.length){let X=$.indexOf(he,J);if(X<0)break;if(X+RU>$.length)return this.replaceBuffer($.subarray(X)),!1;if(eN$($,X)===null)return this.replaceBuffer($.subarray(X)),this.resynchronizing=!1,!0;J=X+1}return this.replaceBuffer($.subarray(Math.max(0,$.length-(he.length-1)))),!1}replaceBuffer($){this.buffer.replace($.length===0?Buffer.alloc(0):Buffer.from($))}}function ue($){return $.width===0&&$.height===8000&&$.bytesPerRow===1}function me($){return $.width===0&&($.height&XA$)>>>0===JA$}function cO0($){if(ue($))return $.timestampMs;if(me($))return $.bytesPerRow;return $.height*$.bytesPerRow}function ge($,J){return{width:$.readUInt32LE(J+8),height:$.readUInt32LE(J+12),bytesPerRow:$.readUInt32LE(J+16),timestampMs:$.readUInt32LE(J+20)}}function eN$($,J){if($.readUInt32LE(J)!==$A$)return"header_magic_mismatch";if($.readUInt32LE(J+4)!==QA$($.subarray(J+gO0,J+RU)))return"header_checksum_mismatch";return dO0(ge($,J))}function dO0($){if(ue($))return $.timestampMs>mO0?"audio_payload_too_large":null;if(me($))return $.bytesPerRow>lO0?"encoded_video_payload_too_large":null;if($.width===0)return"header_width_zero";if($.height===0)return"header_height_zero";if($.bytesPerRow<$.width*4)return"header_bytes_per_row_too_small";if($.width>sN$||$.height>sN$)return"header_dimensions_out_of_range";if($.bytesPerRow>$.width*4+uO0)return"header_bytes_per_row_too_large";if($.height*$.bytesPerRow>kb)return"header_payload_too_large";return null}function iO0(){let $=new Uint32Array(256);for(let J=0;J<256;J++){let X=J;for(let Q=0;Q<8;Q++)X=(X&1)!==0?3988292384^X>>>1:X>>>1;$[J]=X>>>0}return $}function QA$($){let J=4294967295;for(let X=0;X<$.length;X++)J=J>>>8^nO0[(J^$[X])&255];return(J^4294967295)>>>0}var $A$=826690881,he,RU=24,gO0=8,sN$=16384,uO0=4096,kb=33554432,mO0=16777216,lO0=16777216,JA$=3798204416,XA$=4294967294,pO0=1,nO0;var le=D(()=>{he=Buffer.from([65,77,70,49]);nO0=iO0()});class cB{options;pending=null;droppedFrames=0;highWaterMarkBytes=0;lastCaptureTimestampMs=null;constructor($){this.options=$}enqueue($){if(this.lastCaptureTimestampMs=$.header.timestampMs,$.pixels.length>this.options.maxFrameBytes)return this.droppedFrames++,!1;if(this.pending!==null)this.droppedFrames++;return this.pending={frame:$,enqueuedAtMs:this.options.now()},this.highWaterMarkBytes=Math.max(this.highWaterMarkBytes,$.pixels.length),!0}take(){let $=this.pending;return this.pending=null,$?.frame??null}clear($=!1){if($&&this.pending!==null)this.droppedFrames++;this.pending=null}metrics(){let $=this.pending;return{captureTimestampMs:$?.frame.header.timestampMs??this.lastCaptureTimestampMs,frameAgeMs:$===null?null:Math.max(0,this.options.now()-$.enqueuedAtMs),queueDepth:$===null?0:1,droppedFrames:this.droppedFrames,bytesQueued:$?.frame.pixels.length??0,highWaterMarkBytes:this.highWaterMarkBytes,maxFrameBytes:this.options.maxFrameBytes}}}import{spawn as oO0}from"child_process";import{EventEmitter as rO0}from"events";function tO0($){let J=$.trim();if(!J.startsWith(ne))return null;let X=J.slice(ne.length).trim();return X.length>0?X:null}function aO0($){let J=$.trim();if(!J.startsWith(d_))return null;let X=J.slice(d_.length).trim();return X==="screen-recording"?X:null}function sO0($){let J=$.trim();if(!J.startsWith(dB))return null;let X=J.slice(dB.length).trim();return X.length>0?X:null}function eO0($){if(!$.startsWith(de))return null;try{let J=JSON.parse($.slice(de.length));if(!$B0(J))return null;return J}catch(J){return U.debug(`[IOSScreenCaptureHelper] ignored malformed native frame metrics: ${J instanceof Error?J.message:String(J)}`),null}}function $B0($){if($===null||typeof $!=="object")return!1;let J=$;return pe(J.captureTimestampMs)&&pe(J.frameQueueAgeMs)&&(J.frameQueueDepth===0||J.frameQueueDepth===1)&&ce(J.droppedFrames)&&ce(J.bytesQueued)&&ce(J.highWaterMarkBytes)&&pe(J.lastOutputWriteDurationMs)}function pe($){return $===null||typeof $==="number"&&Number.isFinite($)}function ce($){return typeof $==="number"&&Number.isFinite($)&&$>=0}function YB0($){switch($.kind){case"device":return $.deviceId!==void 0?["--device-id",$.deviceId]:[];case"simulator":{let J=["--simulator-window",String($.windowID)];if($.fps!==void 0){if(!Number.isInteger($.fps)||$.fps<n_||$.fps>i_)throw RangeError(`simulator fps must be an integer in [${n_}, ${i_}]; got ${$.fps}`);J.push("--simulator-fps",String($.fps))}if($.audio===!0)J.push("--audio");return WB0(J,$.encode),J}}}function WB0($,J){if(J===void 0)return;switch($.push("--encode",J.codec),J.bitrate.kind){case"explicitBps":$.push("--bitrate-bps",String(Math.round(J.bitrate.bps)));break;case"bitsPerPixel":$.push("--bits-per-pixel",String(J.bitrate.bpp));break;case"videoToolboxDefault":break}}var YA$=33554432,de="automobile-frame-metrics:",ne="capture-capability:",e2="encoded-video-h264",d_="capture-permission:",dB="capture-permission-target:",n_=5,i_=60,ie=5,$L,JB0,WA$=2000,XB0=($,J,X)=>oO0($,J,X),QB0=($,J)=>{process.kill(-$,J)};var nB=D(()=>{l4();n();U$();le();$L=class $L extends rO0{binaryPath;target;spawner;timer;stopGraceMs;processGroupKiller;decoder=new xb;frameQueue;frameDeliveryScheduler;process=null;helperCapabilities=new Set;stderrBuffer="";exitPromise=null;frameDeliveryScheduled=!1;constructor($){super();this.binaryPath=$.binaryPath,this.target=$.target,this.spawner=$.spawner??XB0,this.timer=$.timer??g,this.stopGraceMs=$.stopGraceMs??WA$,this.processGroupKiller=$.processGroupKiller??QB0,this.frameQueue=new cB({maxFrameBytes:YA$,now:$.now??Date.now}),this.frameDeliveryScheduler=$.frameDeliveryScheduler??JB0}on($,J){return super.on($,J)}emit($,...J){return super.emit($,...J)}get isRunning(){return this.process!==null&&this.process.exitCode===null&&!this.process.killed}getFrameMetrics(){return this.frameQueue.metrics()}start(){if(this.process!==null)throw Error("IOSScreenCaptureHelper already started");let $=YB0(this.target);this.emitReadiness("helper-executable-found",this.binaryPath);let J=this.spawner(this.binaryPath,$,{detached:process.platform==="darwin",stdio:["pipe","pipe","pipe"]});this.process=J,this.emitReadiness("helper-process-spawned",`pid=${J.pid??"?"}`),J.stdout.on("data",(X)=>{let Q=Buffer.isBuffer(X)?X:Buffer.from(X),Y=this.decoder.push(Q,(W)=>this.emit("malformed",W),(W)=>this.emit("audio",W),(W)=>this.enqueueFrame(W),(W)=>this.emit("encodedVideo",W));for(let W of Y)this.enqueueFrame(W)}),J.stderr.on("data",(X)=>{let Q=Buffer.isBuffer(X)?X.toString("utf8"):String(X);this.appendStderr(Q)}),J.once("error",(X)=>{this.emit("error",X instanceof Error?X:Error(String(X)))}),this.exitPromise=new Promise((X)=>{J.once("exit",(Q,Y)=>{if(this.stderrBuffer.length>0)this.handleStderrLine(this.stderrBuffer),this.stderrBuffer="";let W={code:Q,signal:Y};this.emit("exit",W),X(W)})}),U.debug(`[IOSScreenCaptureHelper] spawned ${this.binaryPath} pid=${J.pid??"?"}`)}async stop(){let $=this.process;if($===null)return null;if($.exitCode!==null||$.killed){let X=await this.waitForExitWithinGrace();return this.cleanupProcess($),X??{code:$.exitCode,signal:$.signalCode}}$.kill("SIGTERM");let J=await this.waitForExitWithinGrace();if(J!==null)return this.cleanupProcess($),J;if(U.warn(`[IOSScreenCaptureHelper] helper pid=${$.pid??"?"} did not exit after SIGTERM; escalating to SIGKILL`),$.kill("SIGKILL"),process.platform==="darwin")if($.pid!==void 0)try{this.processGroupKiller($.pid,"SIGKILL")}catch(X){U.warn(`[IOSScreenCaptureHelper] process-group cleanup failed for pid=${$.pid}; detached children may leak: ${X}`)}else U.warn("[IOSScreenCaptureHelper] helper pid unknown after SIGKILL; cannot group-kill, detached children may leak");return this.cleanupProcess($),{code:$.exitCode,signal:$.signalCode??"SIGKILL"}}appendStderr($){if(this.stderrBuffer+=$,this.stderrBuffer.length>$L.STDERR_BUFFER_MAX){this.emit("stderr",this.stderrBuffer),this.stderrBuffer="";return}let J=this.stderrBuffer.split(`
|
|
20
20
|
`);this.stderrBuffer=J.pop()??"";for(let X of J)this.handleStderrLine(X)}enqueueFrame($){if(!this.frameQueue.enqueue($)){this.emit("frameMetrics",this.frameQueue.metrics());return}if(this.emit("frameMetrics",this.frameQueue.metrics()),this.frameDeliveryScheduled)return;this.frameDeliveryScheduled=!0,this.frameDeliveryScheduler.schedule(()=>this.deliverLatestFrame())}deliverLatestFrame(){this.frameDeliveryScheduled=!1;let $=this.frameQueue.take();if($===null)return;if(this.emit("frame",$),this.emit("frameMetrics",this.frameQueue.metrics()),this.frameQueue.metrics().queueDepth===1)this.frameDeliveryScheduled=!0,this.frameDeliveryScheduler.schedule(()=>this.deliverLatestFrame())}handleStderrLine($){let J=eO0($);if(J!==null){this.emit("captureMetrics",J);return}let X=tO0($);if(X!==null){this.helperCapabilities.add(X),this.emit("capability",X);return}let Q=aO0($);if(Q!==null){this.emit("permission",Q);return}let Y=sO0($);if(Y!==null){this.emit("permissionTarget",Y);return}this.emit("stderr",$),this.emitReadinessFromMarker($)}get capabilities(){return this.helperCapabilities}supportsEncodedVideo(){return this.helperCapabilities.has(e2)}requestKeyFrame(){let $=this.process;if($===null||!this.isRunning)return!1;try{return $.stdin.write(`${JSON.stringify({cmd:"forceKeyFrame"})}
|
|
21
21
|
`),!0}catch(J){return U.debug(`[IOSScreenCaptureHelper] forceKeyFrame control write failed: ${J}`),!1}}assertSupportsEncodedVideo(){if(this.supportsEncodedVideo())return;throw new R("The screen-capture-helper did not advertise the '"+e2+"' capability at startup, so it cannot emit encoded H.264 video. This is an outdated helper. Unset AUTOMOBILE_IOS_SCREEN_CAPTURE_HELPER to use the checksum-pinned release helper, or point it at a build that advertises '"+e2+"'.")}async waitForExitWithinGrace(){let $=this.exitPromise??Promise.resolve(null),J,X=new Promise((Q)=>{J=this.timer.setTimeout(()=>Q(null),this.stopGraceMs)});try{return await Promise.race([$,X])}finally{if(J)this.timer.clearTimeout(J)}}cleanupProcess($){if($.stdout.removeAllListeners(),$.stderr.removeAllListeners(),$.removeAllListeners(),this.frameQueue.clear(),this.frameDeliveryScheduled=!1,this.process===$)this.process=null}emitReadinessFromMarker($){let J=$.trim();if(J.startsWith("capture-phase: permission-ready"))this.emitReadiness("permission-ready");else if(J.startsWith("capture-phase: resolved-window"))this.emitReadiness("target-resolved",J);else if(J.startsWith("capture-phase: capture-started"))this.emitReadiness("capture-started",J);else if(J.startsWith("capture-phase: first-frame"))this.emitReadiness("first-frame",J)}emitReadiness($,J){this.emit("readiness",{phase:$,atMs:this.timer.now(),detail:J})}static STDERR_BUFFER_MAX=65536};JB0={schedule($){setImmediate($)}}});function jB0($){if(!$||!$.trim())return;let J=$.trim();if(J.startsWith("[")){let X;try{X=JSON.parse(J)}catch{throw new R(`Invalid JSON in ${Q8.ICE_SERVERS}.`)}if(!Array.isArray(X))throw new R(`${Q8.ICE_SERVERS} JSON must be an array of { urls } objects.`);let Q=[];for(let Y of X){let{username:W,credential:G}=Y??{};if(typeof Y?.urls==="string")Q.push({urls:Y.urls,username:W,credential:G});else if(Array.isArray(Y?.urls)&&Y.urls.every((Z)=>typeof Z==="string"))for(let Z of Y.urls)Q.push({urls:Z,username:W,credential:G});else throw new R(`${Q8.ICE_SERVERS} JSON entries must have a string or string[] "urls".`)}return Q}return J.split(",").map((X)=>X.trim()).filter((X)=>X.length>0).map((X)=>({urls:X}))}function VB0($){if(!$||!$.trim())return;let J=/^(\d+)\s*x\s*(\d+)$/i.exec($.trim());if(!J)throw new R(`Invalid size "${$}"; expected WIDTHxHEIGHT (e.g. 1280x720).`);return HA$({width:Number(J[1]),height:Number(J[2])})}function oe($){if(!$)return!1;return["1","true","yes","on"].includes($.trim().toLowerCase())}function KB0($){if(!$||!$.trim())return;let J=Number($.trim());if(!Number.isFinite(J)||J<=0)throw new R(`Invalid bitrate "${$}"; expected a positive number of kbps.`);return Math.round(J)}function UA$($={},J=process.env){let X=$.whipEndpoint??J[Q8.WHIP_ENDPOINT];if(!X||!X.trim())throw new R(`No WHIP endpoint configured. Set ${Q8.WHIP_ENDPOINT} or pass whipEndpoint.`);let Q=$.iceServers??jB0(J[Q8.ICE_SERVERS])??ZB0,Y=$.bitrateKbps===void 0?KB0(J[Q8.BITRATE_KBPS]):LB0($.bitrateKbps),W=$.size===void 0?VB0(J[Q8.MAX_SIZE]):HA$($.size),G=$.iosSimulatorFps===void 0?UB0(J[Q8.IOS_SIMULATOR_FPS])??re:zA$($.iosSimulatorFps),Z=$.androidFps===void 0?zB0(J[Q8.ANDROID_FPS])??GB0:LA$($.androidFps),j=$.trickleIce??oe(J[Q8.TRICKLE_ICE]),V=$.audioEnabled??oe(J[Q8.AUDIO]);return{whipEndpoint:OB0(X,J),bearerToken:$.bearerToken??J[Q8.WHIP_TOKEN]??void 0,iceServers:Q,bitrateKbps:Y,size:W,iosSimulatorFps:G,androidFps:Z,trickleIce:j,audioEnabled:V}}function UB0($){if(!$||!$.trim())return;return zA$(Number($.trim()),$.trim())}function zA$($,J=String($)){if(!Number.isInteger($)||$<GA$||$>ZA$)throw new R(`Invalid iOS Simulator capture fps "${J}"; expected an integer in [${GA$}, ${ZA$}]. Set ${Q8.IOS_SIMULATOR_FPS} or pass iosSimulatorFps.`);return $}function zB0($){if(!$||!$.trim())return;return LA$(Number($.trim()),$.trim())}function LA$($,J=String($)){if(!Number.isInteger($)||$<jA$||$>VA$)throw new R(`Invalid Android capture fps "${J}"; expected an integer in [${jA$}, ${VA$}]. Set ${Q8.ANDROID_FPS} or pass androidFps.`);return $}function LB0($){if(!Number.isFinite($)||$<=0)throw new R(`Invalid bitrate "${$}"; expected a positive number of kbps.`);return Math.round($)}function HA$($){let{width:J,height:X}=$;if(!Number.isSafeInteger(J)||!Number.isSafeInteger(X)||J<=0||X<=0||J%2!==0||X%2!==0||pB(J,X)>eW)throw new R(`Invalid size "${J}x${X}"; width and height must be positive even integers within the H.264 Level 4.2 frame limit.`);return{width:J,height:X}}function OA$($){let J=$.toLowerCase().replace(/^\[/,"").replace(/\]$/,"");if(HB0.has(J))return!0;return/^127(?:\.\d{1,3}){3}$/.test(J)}function BA$($=process.env){return oe($[Q8.ALLOW_INSECURE_WHIP])}function DA$($){let J=$.trim(),X;try{X=new URL(J)}catch{throw new R(`Invalid WHIP endpoint "${J}"; expected an absolute http(s) URL.`)}if(X.protocol!=="http:"&&X.protocol!=="https:")throw new R(`Invalid WHIP endpoint "${J}"; expected an absolute http(s) URL.`);return X}function OB0($,J=process.env){let X=DA$($);if(X.protocol==="http:"&&!OA$(X.hostname)&&!BA$(J))throw new R(`Refusing plaintext WHIP endpoint "${$.trim()}": http:// is only permitted for loopback (127.0.0.1/localhost/::1) because the bearer token and SDP would travel in cleartext. Use https://, or set ${Q8.ALLOW_INSECURE_WHIP}=1 to allow insecure endpoints (not recommended).`);return $.trim()}function BB0($){if(!$||!$.trim())return[];return $.split(",").map((J)=>J.trim()).filter((J)=>J.length>0)}function KA$($){let J=$.includes("://")?$:`https://${$}`;if(!URL.canParse(J))return;let X=new URL(J).origin;return X==="null"?void 0:X}function FA$($,J=process.env){if(BA$(J))return;let X=DA$($);if(OA$(X.hostname))return;let Q=new Set,Y=J[Q8.WHIP_ENDPOINT];if(Y&&Y.trim()){let W=KA$(Y.trim());if(W)Q.add(W)}for(let W of BB0(J[Q8.WHIP_ALLOWED_ORIGINS])){let G=KA$(W);if(G)Q.add(G)}if(!Q.has(X.origin))throw new R(`Refusing WHIP endpoint override "${$.trim()}": its origin ${X.origin} is not allow-listed. Add it to ${Q8.WHIP_ALLOWED_ORIGINS} (comma-separated origins), align it with the daemon's ${Q8.WHIP_ENDPOINT}, or set ${Q8.ALLOW_INSECURE_WHIP}=1 to accept arbitrary destinations (not recommended).`)}var GA$,ZA$,re=15,jA$=1,VA$=60,GB0=30,Q8,ZB0,HB0;var iB=D(()=>{r$();nB();GA$=n_,ZA$=i_,Q8={WHIP_ENDPOINT:"AUTOMOBILE_WEBRTC_WHIP_ENDPOINT",WHIP_TOKEN:"AUTOMOBILE_WEBRTC_WHIP_TOKEN",ICE_SERVERS:"AUTOMOBILE_WEBRTC_ICE_SERVERS",BITRATE_KBPS:"AUTOMOBILE_WEBRTC_BITRATE_KBPS",MAX_SIZE:"AUTOMOBILE_WEBRTC_MAX_SIZE",IOS_SIMULATOR_FPS:"AUTOMOBILE_WEBRTC_IOS_SIMULATOR_FPS",ANDROID_FPS:"AUTOMOBILE_WEBRTC_ANDROID_FPS",TRICKLE_ICE:"AUTOMOBILE_WEBRTC_TRICKLE_ICE",AUDIO:"AUTOMOBILE_WEBRTC_AUDIO",ALLOW_INSECURE_WHIP:"AUTOMOBILE_WEBRTC_ALLOW_INSECURE_WHIP",WHIP_ALLOWED_ORIGINS:"AUTOMOBILE_WEBRTC_WHIP_ALLOWED_ORIGINS"},ZB0=[{urls:"stun:stun.l.google.com:19302"}];HB0=new Set(["localhost","127.0.0.1","::1"])});import{existsSync as qA$}from"fs";import DB0 from"path";function NA$($){let J=$[wA$];return J&&qA$(J)?J:null}function FB0($){let J=DB0.resolve($,"android","video-server","build","libs","automobile-video.jar");return qA$(J)?J:null}async function bb($={}){let J=$.env??process.env,X=$.cwd??process.cwd(),Q=NA$(J);if(Q)return U.info("[VIDEO_JAR] Using AUTOMOBILE_VIDEO_SERVER_JAR override",{path:Q}),Q;let Y=AQ(J[ae]),W=AQ(J[te]);if(!Y){let j=await($.provider??S7.getInstance()).ensure();if(j)return j}else U.info("[VIDEO_JAR] AUTOMOBILE_SKIP_VIDEO_SERVER_DOWNLOAD set; resolving local sources only");let G=FB0(X);if(G)return U.info("[VIDEO_JAR] Using local Gradle build output",{path:G}),G;if(W)throw new R(`${te} is set but no verifiable automobile-video.jar is available (no override, no ${Y?"":"downloadable or "}locally-built jar). Provide ${wA$}, build \`:video-server:d8Dex\`, pin a release whose checksum registry includes videoJarSha256, or unset ${te} to allow the screenrecord fallback.`);return U.info("[VIDEO_JAR] No verifiable jar available; degrading to screenrecord"),null}async function AA$($={}){let J=$.env??process.env;if(!J[Q8.WHIP_ENDPOINT]?.trim()){U.debug("[VIDEO_JAR] No WHIP endpoint configured; skipping background jar prefetch");return}if(AQ(J[ae])){U.debug(`[VIDEO_JAR] ${ae} set; skipping background jar prefetch`);return}if(NA$(J)){U.debug("[VIDEO_JAR] Local override present; skipping background jar prefetch (download unused)");return}let Q=$.provider??S7.getInstance();U.info("[VIDEO_JAR] Prefetching video-server jar in the background (WebRTC streaming configured)");try{let Y=await Q.ensure();if(Y)U.info("[VIDEO_JAR] Background prefetch warmed the jar cache",{path:Y})}catch(Y){U.warn(`[VIDEO_JAR] Background jar prefetch failed: ${Y instanceof Error?Y.message:String(Y)}`,Y)}}var wA$="AUTOMOBILE_VIDEO_SERVER_JAR",te="AUTOMOBILE_REQUIRE_VIDEO_SERVER",ae="AUTOMOBILE_SKIP_VIDEO_SERVER_DOWNLOAD";var yb=D(()=>{l4();n();Ib();iB()});import*as UJ from"fs/promises";import o_ from"path";class $G{static instance=null;downloader;checksumCalculator;cacheDir;usesDefaultCacheDir;timer;env;expectedChecksumOverride;releaseUrlOverride;downloadTimeoutMs;platform;inFlight=null;constructor($={}){this.downloader=$.downloader??new DY,this.checksumCalculator=$.checksumCalculator??new d5,this.cacheDir=$.cacheDir??D9(_A$),this.usesDefaultCacheDir=$.cacheDir===void 0,this.timer=$.timer??g,this.env=$.env??process.env,this.expectedChecksumOverride=$.expectedChecksum,this.releaseUrlOverride=$.releaseUrl,this.downloadTimeoutMs=$.downloadTimeoutMs??wB0,this.platform=$.platform??process.platform}static getInstance(){return $G.instance??=new $G,$G.instance}static resetInstances(){$G.instance=null}async ensure(){if(this.inFlight)return this.inFlight;return this.inFlight=this.doEnsure().finally(()=>{this.inFlight=null}),this.inFlight}async doEnsure(){let $=this.expectedChecksumOverride??vN$(this.env);if($.length===0)return U.info("[SCREEN_CAPTURE_HELPER] Expected checksum unknown for the pinned version; no release helper can be trusted."),null;let J=await this.tryCache($);if(J)return U.info("[SCREEN_CAPTURE_HELPER] Reusing verified release helper",{path:J}),J;return this.download($)}get helperPath(){return o_.join(this.cacheDir,r_)}get metadataPath(){return o_.join(this.cacheDir,TA$)}async tryCache($){let J;try{J=JSON.parse(await UJ.readFile(this.metadataPath,"utf8"))}catch(X){return U.debug("[SCREEN_CAPTURE_HELPER] No usable cached helper metadata",{error:X instanceof Error?X.message:String(X)}),null}if(J.sha256.toLowerCase()!==$.toLowerCase())return null;try{let X=await UJ.stat(this.helperPath);if(!X.isFile()||X.size!==J.size||this.platform!=="win32"&&(X.mode&73)===0)return null}catch(X){return U.debug("[SCREEN_CAPTURE_HELPER] No usable cached helper executable",{error:X instanceof Error?X.message:String(X)}),null}return this.helperPath}async ensureSecureCacheDir(){if(this.usesDefaultCacheDir)return NU(_A$);return await UJ.mkdir(this.cacheDir,{recursive:!0,mode:qB0}),this.cacheDir}async download($){let J=await this.ensureSecureCacheDir(),X=o_.join(J,`${PA$}.download`),Q=o_.join(J,`${r_}.download`),Y=new AbortController,W=this.timer.setTimeout(()=>Y.abort(),this.downloadTimeoutMs);try{await this.downloader.download(this.releaseUrlOverride??fN$(this.env),X,Y.signal),await UJ.chmod(X,MA$);let{checksum:G}=await this.checksumCalculator.computeFileSha256(X);if(G.toLowerCase()!==$.toLowerCase())throw new R(`screen-capture-helper checksum verification failed. Expected: ${$}, Got: ${G}. The downloaded release asset is corrupted or tampered.`);await UJ.writeFile(Q,NB0(X),{mode:RA$}),await UJ.chmod(Q,RA$);let{size:Z}=await UJ.stat(Q);return await UJ.rename(Q,this.helperPath),await UJ.writeFile(this.metadataPath,JSON.stringify({version:Z4(this.env),sha256:G,size:Z,downloadedAt:this.timer.now()},null,2),{encoding:"utf8",mode:MA$}),U.info("[SCREEN_CAPTURE_HELPER] Downloaded and verified release helper",{path:this.helperPath,sha256:G}),this.helperPath}catch(G){if(await Promise.all([UJ.rm(X,{force:!0}),UJ.rm(Q,{force:!0})]),Y.signal.aborted)throw new R(`Timed out downloading screen-capture-helper after ${this.downloadTimeoutMs}ms. Check GitHub Release asset availability or set AUTOMOBILE_IOS_SCREEN_CAPTURE_HELPER for local development.`);throw G}finally{this.timer.clearTimeout(W)}}}function NB0($){let J;try{J=new EA$.default($)}catch(Q){throw new R(`screen-capture-helper release asset is not a valid zip archive: ${Q instanceof Error?Q.message:String(Q)}`)}let X=J.getEntries().filter((Q)=>!Q.isDirectory&&o_.posix.basename(Q.entryName)===r_);if(X.length!==1)throw new R(`screen-capture-helper release asset must contain exactly one ${r_}.`);try{return X[0].getData()}catch(Q){if(Q instanceof R)throw Q;throw new R(`Unable to extract screen-capture-helper release asset: ${Q instanceof Error?Q.message:String(Q)}`)}}var EA$,_A$="screen-capture-helper",qB0=448,MA$=384,RA$=448,wB0=30000,PA$,r_="screen-capture-helper",TA$="screen-capture-helper.json";var fb=D(()=>{IJ();l4();MU();mB();n();U$();MX();EA$=f1(l_(),1),PA$=ke});function vb($,J){for(let X=0;X<$.length;X++){let Q=$[X];if(J.includes(Q)){let W=$[X+1];if(!W||W.startsWith("--"))return;return W}let Y=J.find((W)=>Q.startsWith(`${W}=`));if(Y)return Q.slice(Y.length+1)}return}function hb($){for(let J=0;J<$.length;J++){let X=$[J];if(X.startsWith(`${JG}=`))return!0;if(X===JG){let Q=$[J+1];return Q!==void 0&&!Q.startsWith("--")}}return!1}function _B0($){return $.split(",").map((J)=>J.trim()).filter((J)=>J.length>0)}function gb($,J){let X=vb($,[JG])??J[AB0];if(!X)return[];return _B0(X)}var JG="--event-all-markers",AB0="AUTOMOBILE_EVENT_ALL_MARKERS";var ub=()=>{};function EU($){if($===void 0||$==="")return;let J=typeof $==="number"?$:Number($);if(!Number.isInteger(J)||J<1000||J>120000)return;return J}var t_="AUTOMOBILE_RUNNER_READINESS_TIMEOUT_MS",a_="--runner-readiness-timeout-ms",mb=30000,oB=1000,rB=120000;var CA$={};m1(CA$,{serverConfig:()=>b$});class tB{static instance;_uiPerfModeEnabled=!0;_accessibilityAuditConfig=null;_memPerfAuditEnabled=!1;_predictiveUiEnabled=!1;_rawElementSearchEnabled=!1;_planExecutionLockScope="session";_videoRecordingDefaults={};_deviceSnapshotDefaults={};_appearanceDefaults={};_skipCtrlProxyDownload=!1;_embeddedSdkEnabled=!1;_networkMockableEnabled=!1;_mcpRecordingEnabled=!1;_dismissKeyboardAfterInputEnabled=!1;_eventAllMarkers=[];_navigationScreenshotsEnabled=!0;_waitForPollingOverheadEnabled=!0;_a11yIncludeNotImportantViews=!0;_a11yReportViewIds=!0;_a11yRetrieveInteractiveWindows=!0;_occlusionEnabled=!0;_planExecutionActive=!1;_observeResultIncludeElements=!1;_toolResultsNoStructuredContent=!1;_actionsDiffObserve=!1;_actionsNoObserve=!1;_toolOutputsDir;_runnerReadinessTimeoutMs=mb;constructor(){}static getInstance(){if(!tB.instance)tB.instance=new tB;return tB.instance}setUiPerfMode($){this._uiPerfModeEnabled=$}isUiPerfModeEnabled(){return this._uiPerfModeEnabled}setAccessibilityAuditConfig($){this._accessibilityAuditConfig=$}getAccessibilityAuditConfig(){return this._accessibilityAuditConfig}isAccessibilityAuditEnabled(){return this._accessibilityAuditConfig!==null}setMemPerfAuditMode($){this._memPerfAuditEnabled=$}isMemPerfAuditEnabled(){return this._memPerfAuditEnabled}setPredictiveUiEnabled($){this._predictiveUiEnabled=$}isPredictiveUiEnabled(){return this._predictiveUiEnabled}setRawElementSearchEnabled($){this._rawElementSearchEnabled=$}isRawElementSearchEnabled(){return this._rawElementSearchEnabled}setPlanExecutionLockScope($){this._planExecutionLockScope=$}getPlanExecutionLockScope(){return this._planExecutionLockScope}setVideoRecordingDefaults($){this._videoRecordingDefaults={...$}}getVideoRecordingDefaults(){return{...this._videoRecordingDefaults}}setDeviceSnapshotDefaults($){this._deviceSnapshotDefaults={...$}}getDeviceSnapshotDefaults(){return{...this._deviceSnapshotDefaults}}setAppearanceDefaults($){this._appearanceDefaults={...$}}getAppearanceDefaults(){return{...this._appearanceDefaults}}setToolOutputsDir($){this._toolOutputsDir=$}getToolOutputsDir(){return this._toolOutputsDir}isToolOutputArtifactModeEnabled(){return this._toolOutputsDir!==void 0}setSkipCtrlProxyDownload($){this._skipCtrlProxyDownload=$}isSkipCtrlProxyDownloadEnabled(){return this._skipCtrlProxyDownload}setRunnerReadinessTimeoutMs($){let J=EU($);if(J===void 0)throw RangeError(`Invalid runner readiness timeout: ${$}`);this._runnerReadinessTimeoutMs=J}getRunnerReadinessTimeoutMs(){return this._runnerReadinessTimeoutMs}setEmbeddedSdkEnabled($){this._embeddedSdkEnabled=$}isEmbeddedSdkEnabled(){return this._embeddedSdkEnabled}setNetworkMockableEnabled($){this._networkMockableEnabled=$}isNetworkMockableEnabled(){return this._networkMockableEnabled}setMcpRecordingEnabled($){this._mcpRecordingEnabled=$}isMcpRecordingEnabled(){return this._mcpRecordingEnabled}setDismissKeyboardAfterInputEnabled($){this._dismissKeyboardAfterInputEnabled=$}isDismissKeyboardAfterInputEnabled(){return this._dismissKeyboardAfterInputEnabled}setEventAllMarkers($){this._eventAllMarkers=[...$]}getEventAllMarkers(){return this._eventAllMarkers}setNavigationScreenshotsEnabled($){this._navigationScreenshotsEnabled=$}isNavigationScreenshotsEnabled(){return this._navigationScreenshotsEnabled}setWaitForPollingOverheadEnabled($){this._waitForPollingOverheadEnabled=$}isWaitForPollingOverheadEnabled(){return this._waitForPollingOverheadEnabled}setA11yIncludeNotImportantViews($){this._a11yIncludeNotImportantViews=$}setA11yReportViewIds($){this._a11yReportViewIds=$}setA11yRetrieveInteractiveWindows($){this._a11yRetrieveInteractiveWindows=$}setOcclusionEnabled($){this._occlusionEnabled=$}getAccessibilityFlagsConfig(){return{includeNotImportantViews:this._a11yIncludeNotImportantViews,reportViewIds:this._a11yReportViewIds,retrieveInteractiveWindows:this._a11yRetrieveInteractiveWindows,occlusionEnabled:this._occlusionEnabled}}setPlanExecutionActive($){this._planExecutionActive=$}isPlanExecutionActive(){return this._planExecutionActive}setObserveResultIncludeElementsEnabled($){this._observeResultIncludeElements=$}isObserveResultIncludeElementsEnabled(){return this._observeResultIncludeElements}setToolResultsNoStructuredContentEnabled($){this._toolResultsNoStructuredContent=$}isToolResultsNoStructuredContentEnabled(){return this._toolResultsNoStructuredContent}setActionsDiffObserveEnabled($){this._actionsDiffObserve=$}isActionsDiffObserveEnabled(){return this._actionsDiffObserve}setActionsNoObserveEnabled($){this._actionsNoObserve=$}isActionsNoObserveEnabled(){return this._actionsNoObserve}}var b$;var p4=D(()=>{b$=tB.getInstance()});import SA$ from"path";function RB0($,J){let X=$?.trim();if(!X)return;return SA$.isAbsolute(X)?X:SA$.resolve(J,X)}function lb($,J,X){let Q=vb($,[se,ee]);return RB0(Q??J[$$$]??J[MB0],X)}function IA$(){return D9(KJ.TOOL_OUTPUTS)}var se="--tool-outputs-dir",ee="--tool-output-dir",$$$="AUTOMOBILE_TOOL_OUTPUTS_DIR",MB0="AUTO_MOBILE_TOOL_OUTPUTS_DIR";var pb=D(()=>{r$();p4();MX()});class xA${lifecycleProcess;installed=!1;shutdownInProgress=!1;shutdownHandler;fatalProcessHandler;constructor($){this.lifecycleProcess=$}install(){if(this.installed)return;this.installed=!0,this.lifecycleProcess.on("SIGINT",()=>{this.shutdown("SIGINT")}),this.lifecycleProcess.on("SIGTERM",()=>{this.shutdown("SIGTERM")}),this.lifecycleProcess.on("uncaughtException",($)=>{this.handleFatalProcessEvent({type:"uncaughtException",error:$})}),this.lifecycleProcess.on("unhandledRejection",($,J)=>{this.handleFatalProcessEvent({type:"unhandledRejection",reason:$,promise:J})})}setShutdownHandler($){this.shutdownHandler=$}setFatalProcessHandler($){this.fatalProcessHandler=$}async shutdown($){if(this.shutdownInProgress)return;this.shutdownInProgress=!0;try{await this.shutdownHandler?.($),this.lifecycleProcess.exit(0)}catch(J){console.error(`Error during ${$} shutdown:`,J),this.lifecycleProcess.exit(1)}}async handleFatalProcessEvent($){let J=this.fatalProcessHandler;if(!J){if($.type==="uncaughtException")console.error("Uncaught exception:",$.error);else console.error("Unhandled rejection at:",$.promise,"reason:",$.reason);this.lifecycleProcess.exit(1);return}try{await J($)}catch(X){console.error("Error in fatal process handler:",X),this.lifecycleProcess.exit(1)}}}function cb(){J$$.install()}function db($){J$$.setShutdownHandler($)}function nb($){J$$.setFatalProcessHandler($)}var J$$;var X$$=D(()=>{J$$=new xA$(process)});function hA$($,J){for(let X of J)if($[X]!==void 0)return $[X];return}function Y$$($){let J=[],X=hA$($,["AUTOMOBILE_DEVICE_RECOVERY_ON_LOSS","AUTO_MOBILE_DEVICE_RECOVERY_ON_LOSS","AUTOMOBILE_ANDROID_REBOOT_ON_DEATH","AUTO_MOBILE_ANDROID_REBOOT_ON_DEATH"]),Q=!1;if(X!==void 0){if(X==="1")Q=!0;else if(X!=="0")J.push(`Invalid AUTOMOBILE_DEVICE_RECOVERY_ON_LOSS value ${JSON.stringify(X)}; using 0.`)}let Y=hA$($,["AUTOMOBILE_DEVICE_RECOVERY_MAX_ATTEMPTS","AUTO_MOBILE_DEVICE_RECOVERY_MAX_ATTEMPTS"]),W=2;if(Y!==void 0)if(/^[1-9]\d*$/.test(Y)){let G=Number(Y);if(G<=10)W=G;else J.push(`Invalid AUTOMOBILE_DEVICE_RECOVERY_MAX_ATTEMPTS value ${JSON.stringify(Y)}; using 2.`)}else J.push(`Invalid AUTOMOBILE_DEVICE_RECOVERY_MAX_ATTEMPTS value ${JSON.stringify(Y)}; using 2.`);return{policy:{onLoss:Q,maxAttempts:W},warnings:J}}function gA$(){return Y$$(process.env).policy}function oj(){return(process.env.AUTOMOBILE_DEVICE_POOL_AUTOLOCK??process.env.AUTO_MOBILE_DEVICE_POOL_AUTOLOCK)==="1"}function uA$(){let $=process.env.AUTOMOBILE_DEVICE_POOL_TIMEOUT??process.env.AUTO_MOBILE_DEVICE_POOL_TIMEOUT,J=$?Number.parseInt($,10):NaN;return Number.isFinite(J)&&J>0?J*1000:60000}var Q$$,TB0,ib;var aB=D(()=>{Q$$=process.env.AUTOMOBILE_DEVICE_POOL_MATCHING??process.env.AUTO_MOBILE_DEVICE_POOL_MATCHING,TB0=["LATEST","RANDOM","MINIMUM"],ib=Q$$&&TB0.includes(Q$$)?Q$$:"LATEST"});class pA${get($){return process.env[$]}}class cA${environment;constructor($=new pA$){this.environment=$}isCreationAllowed($){if(typeof $==="boolean")return $;return SB0(this.environment.get("AUTOMOBILE_ALLOW_DEVICE_CREATE"))}describeSource($){if(typeof $==="boolean")return`--create-if-missing=${$}`;let J=this.environment.get("AUTOMOBILE_ALLOW_DEVICE_CREATE");if(J===void 0)return"default (off)";return`AUTOMOBILE_ALLOW_DEVICE_CREATE=${J}`}}function SB0($){if($===void 0)return!1;return CB0.has($.trim().toLowerCase())}function sB(){if(!W$$)W$$=new cA$;return W$$}var mA$="AUTOMOBILE_ALLOW_DEVICE_CREATE",CB0,lA$="AutoMobile",W$$=null;var s_=D(()=>{CB0=new Set(["1","true"])});import{existsSync as IB0}from"fs";import{access as kB0}from"fs/promises";import{homedir as xB0,platform as bB0}from"os";import{execFile as yB0}from"child_process";import{promisify as fB0}from"util";class qY{getCurrentPlatform(){return bB0()}getHomeDir(){return xB0()}getEnvVar($){return process.env[$]}fileExistsSync($){return IB0($)}async fileExists($){return kB0($).then(()=>!0,()=>!1)}async executeCommand($,J=[]){return fB0(yB0)($,J)}}var eB=()=>{};import{join as rj,dirname as dA$}from"path";function vB0($){return $ instanceof JL||$ instanceof XL}function e_($){if(vB0($))throw $}function iA$($){return $.replace(/\\/g,"/")}function $D($){let J=iA$($);if(J.endsWith("/cmdline-tools/latest"))return J.replace(/\/cmdline-tools\/latest$/,"");if(J.endsWith("/cmdline-tools"))return J.replace(/\/cmdline-tools$/,"");return J}function JD($){let J=iA$($).toLowerCase();return J.includes("/homebrew/")||J.includes("/share/android-commandlinetools/")}function PU($=tj()){let J=QL($);if(!J)return null;let X=rj(J,"system-images");if(!$.fileExistsSync(X))return null;return{androidHome:J,systemImagesPath:X}}function Z$$($=tj()){let J=$.getCurrentPlatform(),X=$.getHomeDir();switch(J){case"darwin":return[rj(X,"Library/Android/sdk"),"/opt/android-sdk","/usr/local/android-sdk"];case"linux":return[rj(X,"Android/Sdk"),"/opt/android-sdk","/usr/local/android-sdk"];case"win32":return[rj(X,"AppData/Local/Android/Sdk"),"C:/Android/Sdk","C:/android-sdk"];default:return[]}}async function gB0($){if($.getCurrentPlatform()!=="darwin")return null;let J=["/opt/homebrew/share/android-commandlinetools/cmdline-tools/latest","/usr/local/share/android-commandlinetools/cmdline-tools/latest"];for(let X of J)if(await $.fileExists(X))return X;return null}function QL($=tj()){let J=$.getEnvVar("ANDROID_HOME");if(J&&$.fileExistsSync(J))return J;let X=$.getEnvVar("ANDROID_SDK_ROOT");if(X&&$.fileExistsSync(X))return X;return null}async function uB0($){let J=$.getEnvVar("ANDROID_HOME");if(J&&await $.fileExists(J))return J;let X=$.getEnvVar("ANDROID_SDK_ROOT");if(X&&await $.fileExists(X))return X;return null}async function $M($,J=tj()){try{let X=J.getCurrentPlatform()==="win32"?"where":"which";return await J.executeCommand(X,[$]),!0}catch(X){return e_(X),U.debug(`src/utils/android-cmdline-tools/detection.ts fallback failed: ${X}`,X),!1}}async function j$$($,J=tj()){try{let X=J.getCurrentPlatform()==="win32"?"where":"which";return(await J.executeCommand(X,[$])).stdout.trim().split(`
|
|
22
22
|
`)[0]||null}catch(X){return e_(X),U.debug(`src/utils/android-cmdline-tools/detection.ts fallback failed: ${X}`,X),null}}async function G$$($,J){if(!await J.fileExists($))return[];let X=[],Q=rj($,"bin");if(!await J.fileExists(Q))return[];for(let Y of Object.keys(oA$)){let W=rj(Q,Y),G=rj(Q,`${Y}.bat`);if(await J.fileExists(W)||await J.fileExists(G))X.push(Y)}return X}async function V$$($=tj()){let J=await gB0($);if(!J)return null;let X=await G$$(J,$);if(X.length===0)return null;return{path:J,source:"homebrew",available_tools:X}}async function K$$($=tj()){let J=[];U.debug("Looking for Android SDK tools");let X=await uB0($);if(X){let Y=rj(X,"cmdline-tools","latest"),W=await G$$(Y,$);if(W.length>0){let G=$.getEnvVar("ANDROID_HOME")?"android_home":"android_sdk_root";J.push({path:Y,source:G,available_tools:W})}}let Q=Z$$($);for(let Y of Q){U.debug(`Checking typical path for Android SDK: ${Y}`);let W=$.getEnvVar("ANDROID_HOME"),G=$.getEnvVar("ANDROID_SDK_ROOT");if(W===Y||G===Y)continue;let Z=rj(Y,"cmdline-tools","latest"),j=await G$$(Z,$);if(j.length>0)J.push({path:Z,source:"typical",available_tools:j})}return J}async function mB0($=tj()){let J=[],X={};U.debug("Looking for Android SDK tools in PATH");for(let Z of Object.keys(oA$))if(await $M(Z,$)){let j=await j$$(Z,$);if(j)U.debug(`Tool ${Z} was in PATH`),J.push(Z),X[Z]=j}if(J.length===0)return null;let Y=Object.values(X).map((Z)=>dA$(Z)).reduce((Z,j)=>{return Z[j]=(Z[j]||0)+1,Z},{}),W=Object.entries(Y).sort(([,Z],[,j])=>j-Z)[0]?.[0];return{path:W?dA$(W):"",source:"path",available_tools:J}}async function MQ($=hB0){let J=nA$.get($);if(J!==void 0)return U.debug("Already cached Android tools locations. Returning cached result."),J;let X=[];U.debug("Starting Android command line tools detection...");try{let W=await V$$($);if(W)X.push(W),U.debug(`Found Homebrew Android tools at: ${W.path}`)}catch(W){e_(W),U.warn(`Error detecting Homebrew Android tools: ${W.message}`)}try{let W=await K$$($);X.push(...W);for(let G of W)U.debug(`Found Android SDK tools at: ${G.path} (source: ${G.source})`)}catch(W){e_(W),U.warn(`Error detecting Android SDK tools: ${W.message}`)}try{let W=await mB0($);if(W)X.push(W),U.debug(`Found Android tools in PATH: ${W.available_tools.join(", ")}`)}catch(W){e_(W),U.warn(`Error detecting Android tools in PATH: ${W.message}`)}let Q=new Map;for(let W of X)if(!Q.has(W.path))Q.set(W.path,W);let Y=Array.from(Q.values());return U.debug(`Detection complete. Found ${Y.length} unique Android tools installations.`),nA$.set($,Y),Y}function RQ($){if($.length===0)return null;let J={android_home:1,android_sdk_root:2,typical:3,homebrew:4,path:5,manual:6},X=$.map((Q)=>{let Y=J[Q.source]||10,W=Q.available_tools.length,G=Y*100-W;return{location:Q,score:G}});return X.sort((Q,Y)=>Q.score-Y.score),X[0]?.location||null}function XD($,J){let X=J.filter((Q)=>!$.available_tools.includes(Q));return{valid:X.length===0,missing:X}}var JL,XL,tj=()=>new qY,hB0,nA$,oA$;var aj=D(()=>{n();eB();JL=class JL extends Error{constructor($){super($);this.name="AndroidToolsDetectionTimeoutError"}};XL=class XL extends Error{abortError;constructor($){super($.message);this.abortError=$;this.name="AndroidToolsDetectionAbortError"}};hB0=tj();nA$=new WeakMap,oA$={apkanalyzer:{name:"apkanalyzer",description:"APK analysis and inspection"},avdmanager:{name:"avdmanager",description:"Android Virtual Device management"},sdkmanager:{name:"sdkmanager",description:"SDK package management"},lint:{name:"lint",description:"Static code analysis"},screenshot2:{name:"screenshot2",description:"Device screenshot capture"},d8:{name:"d8",description:"DEX compiler"},r8:{name:"r8",description:"Code shrinking and obfuscation"},resourceshrinker:{name:"resourceshrinker",description:"Resource optimization"},retrace:{name:"retrace",description:"Stack trace de-obfuscation"},profgen:{name:"profgen",description:"ART profile generation"}}});var QD=0.02,zJ="Operation cancelled";var lB0=($)=>{let J=YD($);return{delayForAttempt(X){return ob(X),J}}},JM=($)=>{if($.length===0)throw Error("sequenceBackoff requires at least one delay");let J=$.map(YD);return{delayForAttempt(X){return ob(X),J[Math.min(X-1,J.length-1)]}}},kJ=($)=>{let J=YD($.initialDelayMs),X=$.multiplier??2,Q=$.maxDelayMs===void 0?Number.POSITIVE_INFINITY:YD($.maxDelayMs);if(!Number.isFinite(X)||X<1)throw Error(`exponentialBackoff multiplier must be >= 1, got ${X}`);return{delayForAttempt(Y){return ob(Y),YD(Math.min(J*X**(Y-1),Q))}}},sj=($)=>{if(typeof $==="number")return lB0($);if(Array.isArray($))return JM($);if(typeof $==="function")return{delayForAttempt(J){return ob(J),YD($(J))}};return $},rA$=($,J)=>sj($).delayForAttempt(J),ob=($)=>{if(!Number.isInteger($)||$<1)throw Error(`Backoff attempt must be a positive integer, got ${$}`)},YD=($)=>{if(!Number.isFinite($))throw Error(`Backoff delay must be finite, got ${$}`);return Math.max(0,Math.floor($))};class aA${timer;constructor($=g){this.timer=$}async execute($,J){let X=J?.maxAttempts??tA$.maxAttempts,Q=J?.delays??tA$.delays,Y=J?.shouldRetry??(()=>!0),W=J?.onRetry,G=J?.signal,Z=this.timer.now(),j;for(let V=1;V<=X;V++){if(G?.aborted)return{success:!1,error:Error("Operation aborted"),attempts:V,totalTimeMs:this.timer.now()-Z};try{return{success:!0,value:await $(V),attempts:V,totalTimeMs:this.timer.now()-Z}}catch(K){if(j=K instanceof Error?K:Error(String(K)),V<X){if(!Y(j,V))return{success:!1,error:j,attempts:V,totalTimeMs:this.timer.now()-Z};let z=rA$(Q,V);if(W?.(j,V,z),z>0)if(G){if(await Promise.race([this.timer.sleep(z).then(()=>!1),new Promise((H)=>{if(G.aborted){H(!0);return}G.addEventListener("abort",()=>H(!0),{once:!0})})]))return{success:!1,error:Error("Operation aborted"),attempts:V,totalTimeMs:this.timer.now()-Z}}else await this.timer.sleep(z)}}}return{success:!1,error:j,attempts:X,totalTimeMs:this.timer.now()-Z}}async executeOrThrow($,J){let X=await this.execute($,J);if(!X.success)throw X.error??Error("Operation failed after retries");return X.value}}var tA$,TU;var XM=D(()=>{U$();tA$={maxAttempts:3,delays:1000};TU=new aA$});class CU{timer;entries=new Map;ttlMs;maxEntries;maxSizeBytes;currentSizeBytes=0;stats={hits:0,misses:0,size:0,ttlEvictions:0,sizeEvictions:0};constructor($=g,J){this.timer=$;this.ttlMs=J?.ttlMs??sA$.ttlMs,this.maxEntries=J?.maxEntries??sA$.maxEntries,this.maxSizeBytes=J?.maxSizeBytes??1/0}get($){let J=this.entries.get($);if(!J){this.stats.misses++;return}let X=this.timer.now();if(X-J.createdAt>=this.ttlMs){this.entries.delete($),this.currentSizeBytes-=J.sizeBytes??0,this.stats.ttlEvictions++,this.stats.misses++,this.updateSizeStats();return}return J.lastAccessedAt=X,this.stats.hits++,J.value}set($,J,X){let Q=this.timer.now(),Y=this.entries.get($);if(Y)this.currentSizeBytes-=Y.sizeBytes??0,this.entries.delete($);if(X!==void 0&&this.maxSizeBytes!==1/0)while(this.currentSizeBytes+X>this.maxSizeBytes&&this.entries.size>0)this.evictOldest(),this.stats.sizeEvictions++;while(this.maxEntries>0&&this.entries.size>=this.maxEntries&&this.entries.size>0)this.evictOldest(),this.stats.sizeEvictions++;if(this.maxEntries<=0)return;let W={value:J,createdAt:Q,lastAccessedAt:Q,sizeBytes:X};this.entries.set($,W),this.currentSizeBytes+=X??0,this.updateSizeStats()}has($){let J=this.entries.get($);if(!J)return!1;if(this.timer.now()-J.createdAt>=this.ttlMs)return this.entries.delete($),this.currentSizeBytes-=J.sizeBytes??0,this.stats.ttlEvictions++,this.updateSizeStats(),!1;return!0}delete($){let J=this.entries.get($);if(J)return this.currentSizeBytes-=J.sizeBytes??0,this.entries.delete($),this.updateSizeStats(),!0;return!1}clear(){this.entries.clear(),this.currentSizeBytes=0,this.updateSizeStats()}size(){return this.entries.size}getStats(){return{...this.stats}}cleanup(){let $=this.timer.now(),J=0;for(let[X,Q]of this.entries)if($-Q.createdAt>=this.ttlMs)this.entries.delete(X),this.currentSizeBytes-=Q.sizeBytes??0,this.stats.ttlEvictions++,J++;return this.updateSizeStats(),J}getCurrentSizeBytes(){return this.currentSizeBytes}keys(){return Array.from(this.entries.keys())}evictOldest(){let $,J=1/0;for(let[X,Q]of this.entries)if(Q.lastAccessedAt<J)J=Q.lastAccessedAt,$=X;if($!==void 0){let X=this.entries.get($);if(X)this.currentSizeBytes-=X.sizeBytes??0;this.entries.delete($)}}updateSizeStats(){this.stats.size=this.entries.size}}var sA$;var rb=D(()=>{U$();sA$={ttlMs:60000,maxEntries:1/0}});function tb($){if(typeof $==="string")return $;if(Buffer.isBuffer($))return $.toString();return""}function U$$($){let J=$.trim();if(J.length<=4000)return J;return`...${J.slice(-4000)}`}function pB0($,J=[]){return[$,...J].join(" ")}function cB0($,J){let X=$??{},Q=U$$($ instanceof Error?$.message:String($)),Y=tb(J.stdout)||tb(X.stdout),W=tb(J.stderr)||tb(X.stderr),G=[`Command failed: ${pB0(J.command,J.args)}`];if(J.cwd)G.push(`cwd: ${J.cwd}`);if(typeof X.code==="number")G.push(`exit code: ${X.code}`);else if(typeof X.code==="string")G.push(`error code: ${X.code}`);if(X.signal)G.push(`signal: ${X.signal}`);if(G.push(`raw error: (last 4000 chars) ${Q}`),Y.trim().length>0)G.push("stdout: (last 4000 chars)",U$$(Y));if(W.trim().length>0)G.push("stderr: (last 4000 chars)",U$$(W));return G.join(`
|
|
@@ -205,7 +205,7 @@ ${J}</dict>`}return`${J}<string>${String($)}</string>`},Wy0=($)=>{return['<?xml
|
|
|
205
205
|
`)},Vy0=($)=>{let J=$.toLowerCase();return em($)||J.includes("nsposixerrordomain error 3")||/process (?:is )?no longer running/.test(J)},Ky0=($)=>{let J=$?.result?.process?.processIdentifier;if(typeof J==="number")return J;let X=(Q)=>{if(!Q||typeof Q!=="object")return;if(Array.isArray(Q)){for(let W of Q){let G=X(W);if(G!==void 0)return G}return}let Y=Q;if(typeof Y.processIdentifier==="number")return Y.processIdentifier;for(let W of Object.values(Y)){let G=X(W);if(G!==void 0)return G}return};return X($)},Uy0=($)=>{let J=$.executable??$.executablePath??$.executableURL??$.path;if(typeof J==="string")return $l(J);if(J&&typeof J==="object"){let X=J.url??J.path;if(typeof X==="string")return $l(X)}return null},zy0=($)=>{let J=$.processIdentifier??$.pid??$.processID;if(typeof J==="number"&&Number.isInteger(J))return J;if(typeof J==="string"&&/^\d+$/.test(J.trim()))return Number(J.trim());return},Fg$=($)=>{let J=$.replace(/\/+$/,""),X=J.lastIndexOf("/");return X>=0?J.slice(X+1):J},Ly0=($,J)=>{let X=$l(J).replace(/\/+$/,"");if(!X)return null;let Q=`${X}/`,Y=Fg$(X).replace(/\.app$/i,""),W=(j)=>{if(!j.startsWith(Q))return!1;return!j.slice(Q.length).includes("/")},G=(j,V)=>{if(!j||typeof j!=="object")return null;if(Array.isArray(j)){for(let H of j){let O=G(H,V);if(O!==null)return O}return null}let K=j,z=Uy0(K),L=zy0(K);if(z!==null&&L!==void 0&&V(z))return L;for(let H of Object.values(K)){let O=G(H,V);if(O!==null)return O}return null},Z=G($,W);if(Z!==null)return Z;if(!Y)return null;return G($,(j)=>Fg$(j)===Y)},Hy0=($,J)=>$.endsWith(".XCTestServiceApp")&&(J.includes("No such file or directory")||J.includes("NSPOSIXErrorDomain, code=2"));var yV=D(()=>{l4();Im();bQ$();n();lQ();Zy0={platform:()=>process.platform,execute:($,J)=>new g8().executeCommand($,J),readFile:async($)=>pP.readFile($,"utf-8"),mkdtemp:async($)=>pP.mkdtemp($),rm:async($)=>pP.rm($,{recursive:!0,force:!0}),readdir:async($)=>pP.readdir($),stat:async($)=>pP.stat($),tmpdir:Gy0,logger:U}});class Xl{options;monitorInterval=null;restartTimeout=null;restartAttempts=0;isStopping=!1;autoRestartEnabled=!0;constructor($){this.options=$}async start(){this.isStopping=!1,this.startMonitoring()}stop(){this.isStopping=!0,this.stopMonitoring(),this.clearRestartTimeout(),this.restartAttempts=0}processExited(){this.handleProcessExit()}async handleProcessExit(){if(this.stopMonitoring(),await this.options.onExit?.(),this.autoRestartEnabled&&!this.isStopping)this.scheduleRestart()}isAlive(){return this.options.isAlive()}setAutoRestart($){if(this.autoRestartEnabled=$,!$)this.clearRestartTimeout()}isAutoRestartEnabled(){return this.autoRestartEnabled}startMonitoring(){this.stopMonitoring(),this.monitorInterval=this.options.timer.setInterval(()=>{this.checkLiveness()},this.options.monitorIntervalMs)}stopMonitoring(){if(this.monitorInterval)this.options.timer.clearInterval(this.monitorInterval),this.monitorInterval=null}async checkLiveness(){try{if(!await this.options.isAlive())U.warn(`[ProcessSupervisor] ${this.options.name} is no longer alive`),this.processExited()}catch($){U.warn(`[ProcessSupervisor] ${this.options.name} liveness check failed: ${$ instanceof Error?$.message:String($)}`)}}scheduleRestart(){if(this.restartTimeout||this.isStopping||!this.autoRestartEnabled)return;let $=this.options.maxRestartAttempts;if($!==void 0&&this.restartAttempts>=$){U.warn(`[ProcessSupervisor] ${this.options.name} max restart attempts (${$}) reached`),this.restartAttempts=0;return}this.restartAttempts++;let J=this.restartAttempts,X=this.options.restartBackoff.delayForAttempt(J);U.info(`[ProcessSupervisor] Scheduling ${this.options.name} restart in ${X}ms (attempt ${J})`),this.restartTimeout=this.options.timer.setTimeout(()=>{if(this.restartTimeout=null,this.isStopping)return;this.restart(J)},X)}async restart($){try{if(await this.options.restart(),this.isStopping)return;this.restartAttempts=0,await this.options.onRestartSuccess?.(),this.startMonitoring()}catch(J){await this.options.onRestartFailure?.(J),U.warn(`[ProcessSupervisor] ${this.options.name} restart attempt ${$} failed: ${J instanceof Error?J.message:String(J)}`),this.scheduleRestart()}}clearRestartTimeout(){if(this.restartTimeout)this.options.timer.clearTimeout(this.restartTimeout),this.restartTimeout=null}}var wg$=D(()=>{n()});import{createConnection as Oy0}from"net";class Ql{static CONNECT_TIMEOUT_MS=1000;isAvailable($,J){return new Promise((X)=>{let Q=Oy0({host:$,port:J}),Y=!1,W=(G)=>{if(Y)return;Y=!0,Q.destroy(),X(G)};Q.setTimeout(Ql.CONNECT_TIMEOUT_MS),Q.once("connect",()=>W(!1)),Q.once("timeout",()=>W(!1)),Q.once("error",(G)=>{let Z=G.code;W(Z==="ECONNREFUSED")})})}}var Ng$=()=>{};function fQ$($){return typeof $==="number"&&Number.isInteger($)&&$>0&&$<=65535}class cP{processExecutor;timer;context;static FETCH_TIMEOUT_MS=2000;constructor($=new g8,J,X){this.processExecutor=$;this.timer=J;this.context=X}async checkHealthEndpointOnPort($){let J=await this.readHealthEndpointBodyOnPort($);return J!==null&&(J.includes("ok")||J.includes("healthy"))}async checkHealthEndpointOnPortForDevice($,J){let X=await this.readHealthEndpointBodyOnPort($);if(X===null)return!1;try{let Q=JSON.parse(X);return Q.status==="ok"&&Q.deviceId===J}catch(Q){return U.debug(`src/utils/ios/IOSCtrlProxyHealthClient.ts fallback failed: ${Q}`,Q),!1}}async readReportedPortFromHealth($){let J=await this.readHealthEndpointBodyOnPort($);if(J===null)return null;try{let X=JSON.parse(J);if(X.status!=="ok")return null;if(X.deviceId!==this.context.deviceId)return null;return fQ$(X.port)?X.port:null}catch(X){return U.debug(`src/utils/ios/IOSCtrlProxyHealthClient.ts fallback failed: ${X}`,X),null}}async readHealthEndpointBodyOnPort($){try{let J=this.context.useRemoteRunner()?this.context.getHost():"localhost";if(this.context.useRemoteRunner()){let Q=new AbortController,Y=this.timer.setTimeout(()=>Q.abort(),cP.FETCH_TIMEOUT_MS);try{return await(await fetch(`http://${J}:${$}/health`,{signal:Q.signal})).text()}finally{this.timer.clearTimeout(Y)}}let{stdout:X}=await this.processExecutor.executeCommand("curl",["-s","--max-time","2",`http://${J}:${$}/health`],{timeoutMs:cP.FETCH_TIMEOUT_MS});return X}catch(J){return U.debug(`src/utils/ios/IOSCtrlProxyHealthClient.ts fallback failed: ${J}`,J),null}}}var Ag$=D(()=>{lQ();n()});class sL{host;timer;static DEFAULT_PORT=8765;releaseAttempts;releaseGraceMs;constructor($=new g8,J=g,X={}){this.host=$;this.timer=J;this.releaseAttempts=X.releaseAttempts??4,this.releaseGraceMs=X.releaseGraceMs??250}async findExternalXcodebuildCtrlProxyProcess($,J){let X=await this.findPids("xcodebuild",!0);for(let Q of X){if(Q===J)continue;let Y=await this.getProcessInfo(Q);if(!Y||!Y.command.includes("CtrlProxy"))continue;if(this.isDaemonManagedSimulatorXcodebuildProcess(Y))continue;if(!this.hasDeviceIdentity(`${Y.command} ${Y.environment??""}`,$))continue;return{pid:Q,port:this.parseCtrlProxyPort(Y.command)??this.parseCtrlProxyPort(Y.environment??"")??sL.DEFAULT_PORT}}return null}async findStartupCandidatePids($){return this.findPids("CtrlProxy",!1,$)}async findXcodebuildPids(){return this.findPids("xcodebuild",!0)}async findListeningPids($){try{let{stdout:J}=await this.host.executeCommand("lsof",["-nP",`-iTCP:${$}`,"-sTCP:LISTEN","-Fp"]);return[...new Set(J.split(`
|
|
206
206
|
`).flatMap((X)=>{let Q=X.match(/^p(\d+)$/);return Q?[Number.parseInt(Q[1],10)]:[]}))]}catch(J){return U.debug(`[IOSCtrlProxy] Failed to find listener PIDs for port ${$}: ${J}`),[]}}async getProcessInfo($,J){try{let{stdout:X}=await this.executeCommand("ps",["-p",String($),"-o","ppid=","-o","args="],J),Q=X.trim();if(!Q)return null;let Y=await this.getProcessEnvironment($,J),W=Q.match(/^(\d+)\s+([\s\S]+)$/);return W?{ppid:Number.parseInt(W[1],10),command:W[2],environment:Y}:{command:Q,environment:Y}}catch(X){return U.debug(`[IOSCtrlProxy] Failed to inspect PID ${$}: ${X}`),null}}async isRunning($,J){try{let X=await this.executeCommand("kill",["-0",String($)],J);return!/operation not permitted|permission denied/i.test(X.stderr)}catch(X){return this.remainingTimeoutMs(J),U.debug(`[IOSCtrlProxy] Failed to check PID ${$}: ${X}`),!1}}async isOwnedRunnerAlive($,J){if(!await this.isRunning($))return!1;let X=await this.getProcessInfo($);return!!X&&this.isCtrlProxyRunnerCommand(X.command)&&this.hasDeviceIdentity(`${X.command} ${X.environment??""}`,J)}async findDescendantProcessIds($,J){try{let{stdout:X}=await this.executeCommand("ps",["-axo","pid=,ppid="],J),Q=new Map;for(let Z of X.trim().split(`
|
|
207
207
|
`)){let j=Z.trim().match(/^(\d+)\s+(\d+)$/);if(!j)continue;let V=Number(j[1]),K=Number(j[2]);Q.set(K,[...Q.get(K)??[],V])}let Y=[],W=[...Q.get($)??[]],G=new Set;while(W.length>0){let Z=W.shift();if(G.has(Z))continue;G.add(Z),Y.push(Z),W.push(...Q.get(Z)??[])}return Y}catch(X){return U.debug(`[IOSCtrlProxy] Failed to enumerate descendants of PID ${$}: ${X}`),[]}}async terminateProcessTree($,J){let X=await this.findDescendantProcessIds($,J),Q=[...X].reverse().concat($);if(await this.signalGroup($,"TERM",J),await this.signalPids(Q,"TERM",J),await this.waitForExit([$,...X],J))return;await this.signalGroup($,"KILL",J),await this.signalPids(Q,"KILL",J),await this.waitForExit([$,...X],J)}async terminateProcess($){if(await this.signalPids([$],"TERM"),await this.waitForExit([$]))return;await this.signalPids([$],"KILL"),await this.waitForExit([$])}hasDeviceIdentity($,J){return $.includes(`id=${J}`)||$.includes(`AUTOMOBILE_DEVICE_ID=${J}`)||$.includes(`SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=${J}`)}isCtrlProxyRunnerCommand($){return $.includes("CtrlProxy")&&($.includes("xcodebuild")||$.includes("CtrlProxyUITests")||$.includes("CtrlProxyUITests-Runner")||$.includes(".xctestrun"))}isDirectCtrlProxyRunnerCommand($){return $.includes("CtrlProxyUITests-Runner")}isDaemonManagedSimulatorXcodebuildProcess($){let J=$.command;return J.includes("xcodebuild")&&J.includes("test-without-building")&&J.includes("-xctestrun")&&J.includes("platform=iOS Simulator")&&J.includes("-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService")&&!J.includes("CTRL_PROXY_IOS_PORT=")&&!J.includes("AUTOMOBILE_DEVICE_ID=")&&($.ppid===1||!this.hasExternalXcodebuildIdentity($.environment??""))}async findPids($,J,X){try{let{stdout:Q}=await this.executeCommand("pgrep",[J?"-x":"-f",$],X);return Q.trim().split(`
|
|
208
|
-
`).flatMap((Y)=>{let W=Number.parseInt(Y,10);return Number.isNaN(W)?[]:[W]})}catch(Q){return U.debug(`[IOSCtrlProxy] Failed to enumerate ${$} PIDs: ${Q}`),[]}}async getProcessEnvironment($,J){try{let{stdout:X}=await this.executeCommand("ps",["eww","-p",String($),"-o","command="],J);return X.trim()||void 0}catch(X){U.debug(`[IOSCtrlProxy] Failed to inspect environment for PID ${$}: ${X}`);return}}parseCtrlProxyPort($){let J=$.match(/(?:^|\s)(?:SIMCTL_CHILD_)?CTRL_PROXY_IOS_PORT=(\d+)(?:\s|$)/);return J?Number.parseInt(J[1],10):null}hasExternalXcodebuildIdentity($){return $.includes("CTRL_PROXY_IOS_PORT=")||$.includes("AUTOMOBILE_DEVICE_ID=")||$.includes("SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=")}async signalGroup($,J,X){try{await this.executeCommand("kill",[`-${J}`,"--",`-${$}`],X)}catch(Q){U.debug(`[IOSCtrlProxy] PID ${$} is not a signalable process group: ${Q}`)}}async signalPids($,J,X){for(let Q of $)try{await this.executeCommand("kill",[`-${J}`,String(Q)],X)}catch(Y){U.debug(`[IOSCtrlProxy] PID ${Q} exited before ${J}: ${Y}`)}}async waitForExit($,J){for(let X=0;X<this.releaseAttempts;X++){if(await this.haveExited($,J))return!0;let Q=this.remainingTimeoutMs(J);await this.timer.sleep(Q===void 0?this.releaseGraceMs:Math.min(this.releaseGraceMs,Q))}return this.haveExited($,J)}async haveExited($,J){for(let X of $)if(await this.isRunning(X,J))return!1;return!0}async executeCommand($,J,X){let Q=this.remainingTimeoutMs(X);return this.host.executeCommand($,J,Q===void 0?void 0:{timeoutMs:Q})}remainingTimeoutMs($){if($===void 0)return;let J=$-this.timer.now();if(J<=0)throw Error("Startup CtrlProxy runner sweep deadline elapsed");return J}}var _g$=D(()=>{lQ();U$();n()});var Mg$={};m1(Mg$,{STARTUP_ORPHAN_RUNNER_REAP_DEADLINE_MS:()=>Yl,MAX_STARTUP_ORPHAN_RUNNER_CANDIDATES:()=>vQ$,IOSCtrlProxyManager:()=>m$});var vQ$=20,Yl=5000,Wl,m$;var XW=D(()=>{n();M0();U$();vP();hP();l4();IJ();am();lQ();Lg$();sm();yV();E8();wg$();Ng$();Ag$();_g$();Wl=class Wl extends Error{constructor($,J){super(`Remote runner port ${J} is already in use on ${$}`);this.name="RemoteServicePortUnavailableError"}};m$=class m${device;timer;servicePort;builder;processExecutor;xcodebuild;processClient;signingManager;deviceAppManager;remoteRunner;hostPortAvailabilityChecker;healthClient;remoteRunnerAvailability=null;static instances=new Map;static startupOrphanRunnerReap=null;cachedAvailability=null;cachedInstalled=null;cachedRunning=null;static AVAILABILITY_CACHE_TTL=3600000;static STATUS_CACHE_TTL=30000;static IMPORTANT_OUTPUT_MARKERS=["error","failed","failure","fatal","exception","crash","panic","timed out","timeout","denied","unable","not found","xctestconfiguration"];attemptedSetup=!1;xcTestProcessId=null;xcTestProcess=null;processSupervisor;iproxySupervisor;isProcessSupervisorRestarting=!1;static MAX_RESTART_ATTEMPTS=5;static RESTART_BASE_DELAY_MS=2000;static RESTART_MAX_DELAY_MS=30000;static PORT_RELEASE_GRACE_MS=250;static PORT_RELEASE_ATTEMPTS=4;iproxyProcessId=null;iproxyProcess=null;iproxyDevicePort=null;isStopping=!1;startPromise=null;targetBundleId=null;static DEFAULT_PORT=8765;static DEFAULT_HEALTH_POLL_MAX_ATTEMPTS=60;static BUNDLE_ID="dev.jasonpearson.automobile.ctrlproxy";static APP_BUNDLE_ID="dev.jasonpearson.automobile.ctrlproxy";static LEGACY_APP_BUNDLE_ID="dev.jasonpearson.automobile.XCTestServiceApp";static IPROXY_MONITOR_INTERVAL_MS=5000;static IPROXY_RESTART_BASE_DELAY_MS=1000;static IPROXY_RESTART_MAX_DELAY_MS=15000;static DEFAULT_IPROXY_START_TIMEOUT_MS=5000;constructor($,J=g,X,Q=new g8,Y=new kQ$,W=new cJ,G,Z=new Ql,j=new gz,V){this.device=$,this.timer=J,this.servicePort=this.allocateServicePort(),this.builder=X||p0.getInstance(),this.processExecutor=Q,this.xcodebuild=j,this.processClient=V??new sL,this.signingManager=Y,this.deviceAppManager=W,this.hostPortAvailabilityChecker=Z,this.remoteRunner=G||{isEnabled:()=>!1,isRunningInDocker:()=>!1,isAvailable:async()=>!1,getHost:()=>"localhost",runIdeviceId:async()=>({success:!1,error:"Remote runner is disabled"}),runIdeviceInstaller:async()=>({success:!1,error:"Remote runner is disabled"}),runSimctl:async()=>({success:!1,error:"Remote runner is disabled"}),startIproxy:async()=>({success:!1,error:"Remote runner is disabled"}),stopIproxy:async()=>({success:!1,error:"Remote runner is disabled"}),getIproxyStatus:async()=>({success:!1,error:"Remote runner is disabled"}),start:async()=>({success:!1,error:"Remote runner is disabled"}),stop:async()=>({success:!1,error:"Remote runner is disabled"}),status:async()=>({success:!1,error:"Remote runner is disabled"})},this.healthClient=new cP(this.processExecutor,this.timer,{useRemoteRunner:()=>this.useRemoteRunner(),getHost:()=>this.remoteRunner.getHost(),deviceId:this.device.deviceId}),this.processSupervisor=new Xl({name:"iOS CtrlProxy XCTest runner",timer:this.timer,monitorIntervalMs:30000,maxRestartAttempts:m$.MAX_RESTART_ATTEMPTS,restartBackoff:kJ({initialDelayMs:m$.RESTART_BASE_DELAY_MS,maxDelayMs:m$.RESTART_MAX_DELAY_MS}),restart:async()=>{this.isProcessSupervisorRestarting=!0;try{await this.start()}finally{this.isProcessSupervisorRestarting=!1}},isAlive:()=>this.isSupervisedCtrlProxyProcessAlive(),onExit:()=>{this.xcTestProcessId=null,this.xcTestProcess=null,this.clearCaches()},onRestartSuccess:()=>{U.info("[IOSCtrlProxy] Auto-restart successful")},onRestartFailure:(K)=>{U.warn(`[IOSCtrlProxy] Auto-restart failed: ${K instanceof Error?K.message:String(K)}`)}}),this.iproxySupervisor=new Xl({name:"iOS iproxy tunnel",timer:this.timer,monitorIntervalMs:m$.IPROXY_MONITOR_INTERVAL_MS,restartBackoff:kJ({initialDelayMs:m$.IPROXY_RESTART_BASE_DELAY_MS,maxDelayMs:m$.IPROXY_RESTART_MAX_DELAY_MS}),restart:()=>this.restartIproxyTunnel(),isAlive:()=>this.isSupervisedIproxyTunnelAlive(),onExit:()=>{this.iproxyProcessId=null,this.iproxyProcess=null},onRestartFailure:(K)=>{U.warn(`[IOSCtrlProxy] Failed to restart iproxy: ${K instanceof Error?K.message:String(K)}`)}})}static getInstance($,J){if(bG($,"IOSCtrlProxyManager.getInstance"),!m$.instances.has($.deviceId))m$.instances.set($.deviceId,new m$($,J));return m$.instances.get($.deviceId)}static createForTesting($,J,X){return new m$($,J,X)}static createForTestingWithDeps($,J,X,Q,Y,W,G,Z,j,V){return new m$($,J,X,Q,Y,W,G,Z,j??new gz(async(K,z)=>Q.executeCommand(K,z),J,(K,z,L)=>Q.spawn(K,z,L)),V??new sL(Q,J))}static resetInstances(){m$.instances.clear(),m$.startupOrphanRunnerReap=null}static async shutdownAll(){let $=Array.from(m$.instances.values());await Promise.all($.map((J)=>J.stop())),m$.instances.clear()}static startOrphanRunnerReapOnStartup($=new sL,J=g){let Q=m$.reapOrphanedRunnerProcessesOnStartup($,J).catch((Y)=>{U.debug(`[IOSCtrlProxy] Startup orphan runner sweep failed: ${Y}`)});return m$.startupOrphanRunnerReap=m$.completeWithinStartupReapDeadline(Q,J),m$.startupOrphanRunnerReap}static async reapOrphanedRunnerProcessesOnStartup($=new sL,J=g){let X=J.now()+Yl,Q=[];try{Q=await $.findStartupCandidatePids(X)}catch(W){U.debug(`[IOSCtrlProxy] Failed to enumerate CtrlProxy iOS processes during startup sweep: ${W}`);return}let Y=new Set;for(let W of Q){if(J.now()>=X){m$.logStartupOrphanRunnerReapDeadline();return}try{if(!await m$.reapStartupOrphanRunnerCandidate($,W,X,J,Y))return}catch(G){if(U.debug(`[IOSCtrlProxy] Failed to reap orphaned CtrlProxy iOS process ${W}: ${G}`),J.now()>=X){m$.logStartupOrphanRunnerReapDeadline();return}}}}static async reapStartupOrphanRunnerCandidate($,J,X,Q,Y){let W=await m$.findStartupOrphanRunnerRoot($,J,X,Q);if(W.kind==="deadline_exhausted"||Q.now()>=X)return m$.logStartupOrphanRunnerReapDeadline(),!1;if(W.kind!=="root"||Y.has(W.pid))return!0;if(Y.size>=vQ$)return U.warn(`[IOSCtrlProxy] startup sweep skipped 1 startup CtrlProxy runner candidate after reaching the ${vQ$}-candidate cap`),!1;if(Y.add(W.pid),U.info(`[IOSCtrlProxy] Reaping orphaned CtrlProxy iOS process tree rooted at ${W.pid}`),await $.terminateProcessTree(W.pid,X),Q.now()>=X)return m$.logStartupOrphanRunnerReapDeadline(),!1;return!0}static async findStartupOrphanRunnerRoot($,J,X,Q){let Y=await $.getProcessInfo(J,X);if(!Y||!$.isCtrlProxyRunnerCommand(Y.command))return{kind:"not_daemon_managed"};return m$.findDaemonManagedRunnerTreeRoot($,{pid:J,port:m$.DEFAULT_PORT,command:Y.command,environment:Y.environment,ppid:Y.ppid},{requireOrphanedRoot:!0,shouldContinue:()=>Q.now()<X,deadline:X})}getServicePort(){return this.servicePort}setTargetBundleId($){this.targetBundleId=$,U.info(`[IOSCtrlProxy] Target bundle ID set to ${$}`)}getTargetBundleId(){return this.resolveTargetBundleId()}static getExistingTargetBundleId($){return m$.instances.get($.deviceId)?.getTargetBundleId()??process.env.CTRL_PROXY_IOS_BUNDLE_ID??void 0}resolveTargetBundleId(){return this.targetBundleId??process.env.CTRL_PROXY_IOS_BUNDLE_ID??void 0}clearCaches(){this.cachedAvailability=null,this.cachedInstalled=null,this.cachedRunning=null,U.info("[IOSCtrlProxy] Cleared all caches")}resetSetupState(){this.attemptedSetup=!1,this.clearCaches(),U.info("[IOSCtrlProxy] Reset setup state")}async isInstalled(){if(this.cachedInstalled){if(this.timer.now()-this.cachedInstalled.timestamp<m$.STATUS_CACHE_TTL)return this.cachedInstalled.isInstalled}try{if(U.debug("[IOSCtrlProxy] Checking if CtrlProxy is installed"),this.isSimulator())return this.cachedInstalled={isInstalled:!0,timestamp:this.timer.now()},!0;else{if(this.useRemoteRunner()){let X=await this.remoteRunner.runIdeviceInstaller(["-u",this.device.deviceId,"-l"]);if(!X.success||!X.data)return this.cachedInstalled={isInstalled:!1,timestamp:this.timer.now()},!1;let Q=X.data.stdout.includes(m$.BUNDLE_ID);return this.cachedInstalled={isInstalled:Q,timestamp:this.timer.now()},Q}let{stdout:$}=await this.processExecutor.executeCommand("ideviceinstaller",["-u",this.device.deviceId,"-l"]),J=$.includes(m$.BUNDLE_ID);return this.cachedInstalled={isInstalled:J,timestamp:this.timer.now()},J}}catch($){return U.warn(`[IOSCtrlProxy] Error checking installation: ${$}`),!1}}async isRunning(){if(this.cachedRunning){if(this.timer.now()-this.cachedRunning.timestamp<m$.STATUS_CACHE_TTL)return this.cachedRunning.isRunning}try{U.info("[IOSCtrlProxy] Checking if CtrlProxy is running");let $=await this.checkHealthEndpoint();return this.cachedRunning={isRunning:$,timestamp:this.timer.now()},$}catch($){return U.warn(`[IOSCtrlProxy] Error checking running status: ${$}`),!1}}async isAvailable(){if(this.cachedAvailability&&this.cachedAvailability.isAvailable){if(this.timer.now()-this.cachedAvailability.timestamp<m$.AVAILABILITY_CACHE_TTL)return this.cachedAvailability.isAvailable}let[$,J]=await Promise.all([this.isInstalled(),this.isRunning()]),X=$&&J;return this.cachedAvailability={isAvailable:X,timestamp:this.timer.now()},X}async start(){if(this.startPromise)return U.info("[IOSCtrlProxy] Start already in progress, waiting for it to complete"),this.startPromise;this.startPromise=this.startInternal();try{await this.startPromise}finally{this.startPromise=null}}async startInternal(){let $=await wq();if($.present&&!$.usable)throw new R(`AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH / _IPA_PATH is set but unusable: ${$.reason}`);await this.awaitStartupOrphanRunnerReap(),U.info("[IOSCtrlProxy] Starting CtrlProxy"),this.isStopping=!1;let J=U0();J.startOperation("processAliveCheck");let X=await this.isCtrlProxyProcessAlive();J.endOperation("processAliveCheck");let Q=!1,Y=!1;if(X){if(U.info("[IOSCtrlProxy] CtrlProxy process is alive, skipping start"),!this.isSimulator()){J.startOperation("iproxyTunnel");try{await this.startIproxyTunnel({allowServicePortReallocation:!1})}catch(V){if(J.endOperation("iproxyTunnel"),!(V instanceof Wl))throw V;U.warn("[IOSCtrlProxy] Existing CtrlProxy process uses a host port that is no longer available; restarting"),J.startOperation("spawnRunner"),await this.restartDeviceProcessAfterHostPortCollision(),J.endOperation("spawnRunner"),Q=!0}if(!Q)J.endOperation("iproxyTunnel"),await this.iproxySupervisor.start()}if(!Q){await this.startProcessSupervision();return}}if(!Q){J.startOperation("runningCheck");let V=await this.isRunning();if(J.endOperation("runningCheck"),V){U.info("[IOSCtrlProxy] Service is already running"),await this.startProcessSupervision();return}if(this.isSimulator())if(await this.isOwnRunnerProcessAlive())U.info(`[IOSCtrlProxy] Own CtrlProxy runner (PID ${this.xcTestProcessId}) is still starting; waiting for its health endpoint instead of respawning`),Y=!0;else{J.startOperation("externalProcessCheck");let K=await this.findExternalCtrlProxyProcess(),z=K===null&&!this.useRemoteRunner()&&this.servicePort!==m$.DEFAULT_PORT&&await this.checkHealthEndpointOnPortForDevice(m$.DEFAULT_PORT,this.device.deviceId);if(J.endOperation("externalProcessCheck"),K||z){let L=K?.port??m$.DEFAULT_PORT;if(U.info(`[IOSCtrlProxy] External CtrlProxy process detected on port ${L}, skipping spawn`),L!==this.servicePort)this.adoptServicePort(L)}else await this.ensureServicePortReadyForLaunch(),J.startOperation("spawnRunner"),await this.startOnSimulator(),J.endOperation("spawnRunner")}else J.startOperation("spawnRunner"),await this.startOnDevice(),J.endOperation("spawnRunner")}let W=500,G=m$.resolveHealthPollMaxAttempts(),Z=Math.round(G*W/1000);J.startOperation("healthPolling");for(let V=0;V<G;V++){if(await this.checkHealthEndpoint()){if(J.endOperation("healthPolling"),U.info("[IOSCtrlProxy] HTTP health endpoint is ready"),this.clearCaches(),await this.startProcessSupervision(),U.info("[IOSCtrlProxy] Waiting for WebSocket server initialization"),J.startOperation("websocketInit"),await this.timer.sleep(500),J.endOperation("websocketInit"),!this.isSimulator())await this.iproxySupervisor.start();return}if(V>0&&V%10===0)U.info(`[IOSCtrlProxy] Still waiting for service... (attempt ${V}/${G})`);await this.timer.sleep(W)}if(J.endOperation("healthPolling"),Y&&this.xcTestProcessId!==null){if(this.servicePort!==m$.DEFAULT_PORT&&await this.checkHealthEndpointOnPortForDevice(m$.DEFAULT_PORT,this.device.deviceId)){U.info(`[IOSCtrlProxy] Deferred-to runner is healthy on default port ${m$.DEFAULT_PORT}; adopting it instead of terminating`),this.adoptServicePort(m$.DEFAULT_PORT),this.clearCaches(),await this.timer.sleep(500),await this.startProcessSupervision();return}let V=this.xcTestProcessId,K=await this.isOwnRunnerProcessAlive();this.isStopping=!0;try{if(K)if(U.warn(`[IOSCtrlProxy] Deferred-to CtrlProxy runner (PID ${V}) never became healthy within ${Z}s; terminating it so the next start spawns a fresh runner`),this.useRemoteRunner())try{await this.remoteRunner.stop({deviceId:this.device.deviceId,pid:V})}catch(z){U.warn(`[IOSCtrlProxy] Remote runner stop of hung runner ${V} failed: ${z instanceof Error?z.message:String(z)}`)}else await this.processClient.terminateProcessTree(V);else U.warn(`[IOSCtrlProxy] Tracked runner PID ${V} is no longer our CtrlProxy runner (exited/PID-reused); un-tracking without terminating`);this.xcTestProcessId=null,this.xcTestProcess=null,this.clearCaches(),this.processSupervisor.stop(),await this.processSupervisor.start()}finally{this.isStopping=!1}}let j=await this.findListeningProcessesOnPort(this.servicePort);if(j.length>0)throw Error(`CtrlProxy failed to start within timeout (${Z}s); port ${this.servicePort} still held by ${this.formatListeningProcesses(j)}`);throw Error(`CtrlProxy failed to start within timeout (${Z}s)`)}async stop(){if(U.info("[IOSCtrlProxy] Stopping CtrlProxy"),this.isStopping=!0,this.processSupervisor.stop(),this.useRemoteRunner()){try{if(this.xcTestProcessId)await this.remoteRunner.stop({deviceId:this.device.deviceId,pid:this.xcTestProcessId})}catch($){U.warn(`[IOSCtrlProxy] Remote runner stop failed: ${$ instanceof Error?$.message:String($)}`)}if(!this.isSimulator())await this.stopIproxyTunnel({clearDevicePort:!0});this.xcTestProcessId=null,this.xcTestProcess=null,this.clearCaches(),R6.release(this.device.deviceId),this.isStopping=!1,U.info("[IOSCtrlProxy] Service stopped");return}if(await this.stopIproxyTunnel({clearDevicePort:!0}),this.xcTestProcessId){try{if(await this.isOwnRunnerProcessAlive())await this.processClient.terminateProcessTree(this.xcTestProcessId);else U.debug(`[IOSCtrlProxy] Tracked runner PID ${this.xcTestProcessId} is not an owned CtrlProxy runner; clearing without terminating`)}catch($){U.warn(`[IOSCtrlProxy] Failed to terminate tracked CtrlProxy runner ${this.xcTestProcessId}: ${$ instanceof Error?$.message:String($)}`)}this.xcTestProcessId=null,this.xcTestProcess=null}this.clearCaches(),R6.release(this.device.deviceId),this.isStopping=!1,U.info("[IOSCtrlProxy] Service stopped")}async uninstallLegacyAppIfPresent(){try{let $=this.isSimulator();if(await this.deviceAppManager.getInstalledAppBundleHash(this.device.deviceId,m$.LEGACY_APP_BUNDLE_ID,$)===null)return;U.info(`[IOSCtrlProxy] Found legacy app ${m$.LEGACY_APP_BUNDLE_ID}, uninstalling`),await this.deviceAppManager.uninstallApp(this.device.deviceId,m$.LEGACY_APP_BUNDLE_ID,$),U.info("[IOSCtrlProxy] Legacy app uninstalled")}catch($){U.warn(`[IOSCtrlProxy] Failed to check/uninstall legacy app: ${$}`)}}async setup($=!1,J=new E$){if(J.serial("xcTestServiceSetup"),p0.isPinnedVersionUnverifiable())return J.end(),{success:!1,message:`AUTOMOBILE_VERSION=${Z4()} is not in the AutoMobile release checksum registry, so the CtrlProxy bundle cannot be integrity-verified. Pin a released version, or vendor a trusted bundle via AUTOMOBILE_CTRL_PROXY_IOS_IPA_PATH.`,perfTiming:J.getTimings()};if(await this.uninstallLegacyAppIfPresent(),this.attemptedSetup&&!$){if(await this.isAvailable())return J.end(),{success:!0,message:"CtrlProxy was already running",perfTiming:J.getTimings()};return J.end(),{success:!1,message:"Setup already attempted",perfTiming:J.getTimings()}}try{this.attemptedSetup=!0;let X=await J.track("checkRunning",()=>this.isRunning());if(!$&&X)return J.end(),{success:!0,message:"CtrlProxy was already running",perfTiming:J.getTimings()};let Q=this.useRemoteRunner()?!1:await J.track("checkBuild",()=>this.builder.needsRebuild(this.isSimulator()?"simulator":"device")),Y=null;if(Q){let W=p0.getPrefetchedResult();if(W&&W.success)U.info("[IOSCtrlProxy] Using prefetched build result"),Y=W;else{let G=await J.track("waitForPrefetch",()=>p0.waitForPrefetch());if(G&&G.success)U.info("[IOSCtrlProxy] Using completed prefetch build result"),Y=G;else if(U.info("[IOSCtrlProxy] Downloading CtrlProxy bundle"),Y=await J.track("build",()=>this.builder.build(this.isSimulator()?"simulator":"device",J)),!Y.success)return this.attemptedSetup=!1,J.end(),{success:!1,message:Y.message,error:Y.error,buildResult:Y,perfTiming:J.getTimings()}}}return await J.track("startService",()=>this.start()),J.end(),{success:!0,message:Q?"CtrlProxy downloaded and started successfully":"CtrlProxy started successfully",buildResult:Y||void 0,perfTiming:J.getTimings()}}catch(X){this.attemptedSetup=!1;let Q=X instanceof Error?X.message:String(X);return J.end(),{success:!1,message:"Failed to setup CtrlProxy",error:Q,perfTiming:J.getTimings()}}}isSimulator(){return l1(this.device.deviceId)}useRemoteRunner(){return this.remoteRunner.isEnabled()&&this.remoteRunner.isRunningInDocker()}allocateServicePort($=[]){return R6.allocate(this.device.deviceId,{reservedPorts:[...hz,...$]})}ensureLocalServicePortAllocatedAndAvailable(){let $=R6.getPort(this.device.deviceId),J=R6.isPortAvailable(this.servicePort);if($===this.servicePort&&J)return;let X=J?[]:[this.servicePort];R6.release(this.device.deviceId);let Q=this.allocateServicePort(X);if(Q!==this.servicePort)U.info(`[IOSCtrlProxy] Reallocated service port from ${this.servicePort} to ${Q} before runner launch`),this.servicePort=Q,this.clearCaches()}adoptServicePort($){if(R6.getPort(this.device.deviceId)!==$)R6.reserve(this.device.deviceId,$);if(this.servicePort!==$)this.servicePort=$,this.clearCaches()}async ensureRemoteServicePortAvailable($={}){let J=$.allowReallocation??!0,X=this.remoteRunner.getHost(),Q=new Set;for(let Y=0;Y<R6.getMaxDevices();Y++){if(await this.hostPortAvailabilityChecker.isAvailable(X,this.servicePort))return;let W=this.servicePort;if(U.warn(`[IOSCtrlProxy] Remote runner port ${W} is already in use on ${X}; reallocating`),!J)throw new Wl(X,W);Q.add(W),R6.release(this.device.deviceId),this.servicePort=this.allocateServicePort(Q)}throw Error(`No remote iOS CtrlProxy ports are available for device ${this.device.deviceId}.`)}async isRemoteRunnerAvailable(){if(!this.remoteRunnerAvailability)this.remoteRunnerAvailability=this.remoteRunner.isAvailable();return this.remoteRunnerAvailability}async restartDeviceProcessAfterHostPortCollision(){await this.stop(),this.isStopping=!1,await this.startOnDevice()}async startOnSimulator(){if(U.info("[IOSCtrlProxy] Starting CtrlProxy on simulator"),this.useRemoteRunner()){if(!await this.isRemoteRunnerAvailable())throw Error("Remote runner not available for CtrlProxy startup");let Z=await this.remoteRunner.status({deviceId:this.device.deviceId}),j=Z.data?.port;if(Z.success&&Z.data?.running&&typeof j==="number"){U.info(`[IOSCtrlProxy] Reusing remote CtrlProxy process on service port ${j}`),this.adoptServicePort(j),this.xcTestProcessId=Z.data.pid??null,this.xcTestProcess=null;return}await this.ensureRemoteServicePortAvailable();let V=await this.builder.getXctestrunPath("simulator"),K=this.resolveTargetBundleId(),z=await this.remoteRunner.start({deviceId:this.device.deviceId,port:this.servicePort,xctestrunPath:V||void 0,bundleId:K});if(!z.success||!z.data)throw Error(z.error||"Remote runner failed to start CtrlProxy");if(typeof z.data.port==="number")this.adoptServicePort(z.data.port);this.xcTestProcessId=z.data.pid,this.xcTestProcess=null;return}let $=await this.builder.getXctestrunPath("simulator");if(!$)throw Error("CtrlProxy xctestrun not found for simulator. Download the CtrlProxy bundle before starting.");await this.builder.verifyRunnerBinaryBeforeLaunch("simulator");let J=process.env.CTRL_PROXY_IOS_TIMEOUT||"86400",X=this.resolveTargetBundleId();this.ensureLocalServicePortAllocatedAndAvailable();let Q={CTRL_PROXY_IOS_PORT:String(this.servicePort),CTRL_PROXY_IOS_TIMEOUT:J,AUTOMOBILE_DEVICE_ID:this.device.deviceId};if(X)Q.CTRL_PROXY_IOS_BUNDLE_ID=X,U.info(`[IOSCtrlProxy] Passing CTRL_PROXY_IOS_BUNDLE_ID=${X} to runner via xctestrun`);let W=["test-without-building","-xctestrun",await this.builder.writeRunnerEnvironment($,Q,this.device.deviceId),"-destination",`platform=iOS Simulator,id=${this.device.deviceId}`,"-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService"];U.info("[IOSCtrlProxy] Using xcodebuild test-without-building to start runner on simulator");let G=await this.xcodebuild.startStreaming(W,{detached:!0,env:{...process.env,...Q},stdio:["ignore","pipe","pipe"]});if(G.on("error",(Z)=>{if(this.xcTestProcess!==G)return;U.warn(`[IOSCtrlProxy] xcodebuild test error: ${Z.message}`),this.handleProcessExit()}),G.on("exit",(Z,j)=>{if(Z!==0||j)U.warn(`[IOSCtrlProxy] xcodebuild test exited: code=${Z}, signal=${j}`);if(this.xcTestProcess!==G)return;this.handleProcessExit()}),G.pid)this.xcTestProcessId=G.pid,this.xcTestProcess=G,U.info(`[IOSCtrlProxy] Started xcodebuild test with PID ${G.pid}`),this.captureProcessOutput(G)}captureProcessOutput($){if($.stdout)$.stdout.on("data",(J)=>{let X=J.toString().trim();if(X&&this.shouldPromoteCtrlProxyOutput(X))U.info(`[CtrlProxy stdout] ${X.slice(0,500)}`)});if($.stderr)$.stderr.on("data",(J)=>{let X=J.toString().trim();if(X&&!X.includes("Build Succeeded"))if(this.shouldPromoteCtrlProxyOutput(X))U.warn(`[CtrlProxy stderr] ${X.slice(0,500)}`);else U.debug(`[CtrlProxy stderr] ${X.slice(0,500)}`)})}shouldPromoteCtrlProxyOutput($){if(process.env.AUTOMOBILE_CTRLPROXY_VERBOSE==="true")return!0;let J=$.toLowerCase();return m$.IMPORTANT_OUTPUT_MARKERS.some((X)=>J.includes(X))}handleProcessExit(){this.processSupervisor.processExited()}async startProcessSupervision(){if(!this.isProcessSupervisorRestarting)await this.processSupervisor.start()}async isSupervisedCtrlProxyProcessAlive(){if(await this.checkHealthEndpoint()||!this.xcTestProcessId)return!0;let J=this.useRemoteRunner()?await this.isOwnRunnerProcessAlive():await this.isProcessRunning(this.xcTestProcessId);if(!J)U.warn("[IOSCtrlProxy] XCTest process crashed, health endpoint not responding");return J}setAutoRestart($){this.processSupervisor.setAutoRestart($),U.info(`[IOSCtrlProxy] Auto-restart ${$?"enabled":"disabled"}`)}isAutoRestartEnabled(){return this.processSupervisor.isAutoRestartEnabled()}async forceRestart(){U.info("[IOSCtrlProxy] Force restart requested"),await this.stop(),await this.start()}async isProcessRunning($){return this.processClient.isRunning($)}async isOwnRunnerProcessAlive(){if(!this.xcTestProcessId)return!1;if(this.useRemoteRunner())try{let J=await this.remoteRunner.status({deviceId:this.device.deviceId,pid:this.xcTestProcessId});return J.success&&(J.data?.running??!1)&&J.data?.pid===this.xcTestProcessId}catch(J){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${J}`,J),!1}if(!await this.isProcessRunning(this.xcTestProcessId))return!1;let $=await this.processClient.getProcessInfo(this.xcTestProcessId);if(!$)return!1;return this.isOwnedCtrlProxyRunnerProcess({pid:this.xcTestProcessId,port:this.servicePort,command:$.command,environment:$.environment})}static resolveHealthPollMaxAttempts(){let $=process.env.AUTOMOBILE_CTRL_PROXY_HEALTH_MAX_ATTEMPTS??process.env.AUTO_MOBILE_CTRL_PROXY_HEALTH_MAX_ATTEMPTS;if($!==void 0){let J=Number.parseInt($,10);if(Number.isFinite(J)&&J>0)return J}return m$.DEFAULT_HEALTH_POLL_MAX_ATTEMPTS}async isCtrlProxyProcessAlive(){if(!this.xcTestProcessId)return!1;if(this.useRemoteRunner())try{let $=await this.remoteRunner.status({deviceId:this.device.deviceId,pid:this.xcTestProcessId});return $.success&&($.data?.running??!1)&&$.data?.pid===this.xcTestProcessId}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}if(!await this.isProcessRunning(this.xcTestProcessId))return!1;return this.checkHealthEndpoint()}async findExternalCtrlProxyProcess(){if(this.useRemoteRunner())return null;let $=await this.findExternalXcodebuildCtrlProxyProcess();if($)return $;return this.findExternalDirectCtrlProxyProcess()}async findExternalXcodebuildCtrlProxyProcess(){for(let $ of await this.processClient.findXcodebuildPids()){if($===this.xcTestProcessId)continue;let J=await this.processClient.getProcessInfo($),X=J?.command??"";if(!X.includes("CtrlProxy")||await this.isDaemonManagedSimulatorXcodebuildProcess(X,J))continue;let Q=`${X} ${J?.environment??""}`;if(!m$.hasDeviceIdentity(Q,this.device.deviceId))continue;let Y=this.parseCtrlProxyPortFromProcessArgs(X)??this.parseCtrlProxyPortFromProcessArgs(J?.environment??"")??m$.DEFAULT_PORT;return U.info(`[IOSCtrlProxy] Found external xcodebuild CtrlProxy process: ${$}`),{pid:$,port:Y}}return null}async findExternalDirectCtrlProxyProcess(){let $=new Set([this.servicePort,m$.DEFAULT_PORT]);for(let J of $){let X=await this.findListeningProcessesOnPort(J);for(let Q of X){if(!m$.isDirectCtrlProxyRunnerCommand(Q.command))continue;let Y=await m$.findDaemonManagedRunnerTreeRoot(this.processClient,Q);if(Y.kind==="root"&&Y.pid!==Q.pid)continue;if(!await this.processAncestryContainsDeviceId(Q))continue;return U.info(`[IOSCtrlProxy] Found external direct CtrlProxy runner: ${Q.pid}`),{pid:Q.pid,port:J}}}return null}parseCtrlProxyPortFromProcessArgs($){let J=$.match(/(?:^|\s)(?:SIMCTL_CHILD_)?CTRL_PROXY_IOS_PORT=(\d+)(?:\s|$)/);if(!J)return null;let X=Number.parseInt(J[1],10);return fQ$(X)?X:null}async ensureServicePortReadyForLaunch(){if(this.useRemoteRunner())return;let $=new Set;for(let J=0;J<R6.getMaxDevices();J++){let X=await this.findListeningProcessesOnPort(this.servicePort);if(X.length===0)return;let Q=X.filter((Y)=>this.isOwnedCtrlProxyRunnerProcess(Y));if(Q.length>0){for(let Z of Q){let j=await this.findDaemonManagedRunnerTreeRoot(Z);U.warn(`[IOSCtrlProxy] Terminating stale CtrlProxy process tree rooted at ${j} for listener ${Z.pid} on port ${this.servicePort}`),await this.processClient.terminateProcessTree(j)}let Y=await this.findListeningProcessesOnPort(this.servicePort);if(Y.length===0)return;let W=Y.filter((Z)=>this.isOwnedCtrlProxyRunnerProcess(Z));if(W.length>0)for(let Z of W)U.warn(`[IOSCtrlProxy] CtrlProxy listener ${Z.pid} still holds port ${this.servicePort}; force-terminating remaining owned process tree`),await this.processClient.terminateProcessTree(Z.pid);let G=await this.findListeningProcessesOnPort(this.servicePort);if(G.length===0)return;if(G.some((Z)=>this.isOwnedCtrlProxyRunnerProcess(Z)))throw Error(`CtrlProxy recovery failed, port ${this.servicePort} still held by `+this.formatListeningProcesses(G))}$.add(this.servicePort),U.warn(`[IOSCtrlProxy] Port ${this.servicePort} is held by a foreign process; reallocating CtrlProxy port`),R6.release(this.device.deviceId),this.servicePort=this.allocateServicePort($),this.clearCaches()}throw Error(`No iOS CtrlProxy ports are available for device ${this.device.deviceId}.`)}async findListeningProcessesOnPort($){let J=[];for(let X of await this.processClient.findListeningPids($)){let Q=await this.processClient.getProcessInfo(X);if(Q)J.push({pid:X,port:$,...Q})}return J}isOwnedCtrlProxyRunnerProcess($){if(!m$.isCtrlProxyRunnerCommand($.command))return!1;return m$.hasDeviceIdentity($.command,this.device.deviceId)||m$.hasDeviceIdentity($.environment??"",this.device.deviceId)}async processAncestryContainsDeviceId($){let J=$.ppid,X=new Set;while(J!==void 0&&J>1&&!X.has(J)){X.add(J);let Q=await this.processClient.getProcessInfo(J);if(!Q)return!1;if(m$.hasDeviceIdentity(Q.command,this.device.deviceId)||Q.command.includes(this.device.deviceId))return!0;J=Q.ppid}return!1}async findDaemonManagedRunnerTreeRoot($){let J=await m$.findDaemonManagedRunnerTreeRoot(this.processClient,$);return J.kind==="root"?J.pid:$.pid}static async findDaemonManagedRunnerTreeRoot($,J,X={}){if(!m$.isCtrlProxyRunnerCommand(J.command))return{kind:"not_daemon_managed"};let Q=J.ppid===1?J.pid:null,Y=J.ppid,W=new Set([J.pid]);if(m$.isDaemonManagedSimulatorXcodebuildCommandShape(J.command))Q=m$.rootPidForDaemonManagedProcess(J.pid,J.ppid,X.requireOrphanedRoot);while(Y!==void 0&&Y>1&&!W.has(Y)){if(!m$.shouldContinueStartupOrphanRunnerTraversal(X))return{kind:"deadline_exhausted"};W.add(Y);let G=await $.getProcessInfo(Y,X.deadline);if(!G)break;let Z=m$.daemonManagedParentRoot(G,Y,X.requireOrphanedRoot);if(Z){if(Z.terminal)return m$.toDaemonManagedRunnerTreeRoot(Z.rootPid);Q=Z.rootPid}Y=G.ppid}return m$.toDaemonManagedRunnerTreeRoot(Q)}async awaitStartupOrphanRunnerReap(){if(this.isSimulator())await m$.awaitStartupOrphanRunnerReap()}static async awaitStartupOrphanRunnerReap(){await m$.startupOrphanRunnerReap}static async completeWithinStartupReapDeadline($,J){let X;try{await Promise.race([$,new Promise((Q)=>{X=J.setTimeout(()=>{m$.logStartupOrphanRunnerReapDeadline(),Q()},Yl),X.unref?.()})])}finally{if(X)J.clearTimeout(X)}}static logStartupOrphanRunnerReapDeadline(){U.warn(`[IOSCtrlProxy] startup CtrlProxy runner sweep timed out after ${Yl}ms`)}static shouldContinueStartupOrphanRunnerTraversal($){return $.shouldContinue?.()??!0}static daemonManagedParentRoot($,J,X){if(!m$.isDaemonManagedSimulatorXcodebuildCommandShape($.command))return null;return{rootPid:m$.rootPidForDaemonManagedProcess(J,$.ppid,X),terminal:m$.isShellCommand($.command)}}static rootPidForDaemonManagedProcess($,J,X){return X&&J!==1?null:$}static toDaemonManagedRunnerTreeRoot($){return $===null?{kind:"not_daemon_managed"}:{kind:"root",pid:$}}formatListeningProcesses($){return $.map((J)=>`PID ${J.pid} (cmd: ${J.command})`).join(", ")}static hasDeviceIdentity($,J){return $.includes(`id=${J}`)||$.includes(`AUTOMOBILE_DEVICE_ID=${J}`)||$.includes(`SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=${J}`)}async isDaemonManagedSimulatorXcodebuildProcess($,J){let X=J?.environment??"";if(!m$.isDaemonManagedSimulatorXcodebuildCommandShape($))return!1;if(J?.ppid===1)return!0;if(await this.hasOrphanedDaemonManagedShellParent(J?.ppid))return!0;return!m$.hasExternalXcodebuildIdentity(X)}async hasOrphanedDaemonManagedShellParent($){if($===void 0||$<=1)return!1;let J=await this.processClient.getProcessInfo($);if(!J||J.ppid!==1)return!1;return m$.isShellCommand(J.command)&&m$.isDaemonManagedSimulatorXcodebuildCommandShape(J.command)}static isDaemonManagedSimulatorXcodebuildCommandShape($){return $.includes("xcodebuild")&&$.includes("test-without-building")&&$.includes("-xctestrun")&&$.includes("platform=iOS Simulator")&&$.includes("-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService")&&!$.includes("CTRL_PROXY_IOS_PORT=")&&!$.includes("AUTOMOBILE_DEVICE_ID=")}static isShellCommand($){return/(?:^|\/)(?:ba|z|c|t?c|k)?sh(?:\s|$)/.test($)}static hasExternalXcodebuildIdentity($){return $.includes("CTRL_PROXY_IOS_PORT=")||$.includes("AUTOMOBILE_DEVICE_ID=")||$.includes("SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=")}static isCtrlProxyRunnerCommand($){return $.includes("CtrlProxy")&&($.includes("xcodebuild")||$.includes("CtrlProxyUITests")||$.includes("CtrlProxyUITests-Runner")||$.includes(".xctestrun"))}static isDirectCtrlProxyRunnerCommand($){return $.includes("CtrlProxyUITests-Runner")}async isIproxyProcessAlive(){if(!this.iproxyProcessId)return!1;if(this.useRemoteRunner())try{let $=await this.remoteRunner.getIproxyStatus({pid:this.iproxyProcessId});return $.success&&($.data?.running??!1)}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}return this.isProcessRunning(this.iproxyProcessId)}async startOnDevice(){if(U.info("[IOSCtrlProxy] Starting CtrlProxy on physical device"),this.useRemoteRunner()){if(!await this.isRemoteRunnerAvailable())throw Error("Remote runner not available for CtrlProxy startup");let j=await this.remoteRunner.status({deviceId:this.device.deviceId}),V=j.data?.port;if(j.success&&j.data?.running&&typeof V==="number"){U.info(`[IOSCtrlProxy] Reusing remote CtrlProxy process on device port ${V}`),this.xcTestProcessId=j.data.pid??null,this.xcTestProcess=null,await this.startIproxyTunnel({devicePort:V});return}let K=await this.builder.getXctestrunPath("device");await this.startIproxyTunnel(),await this.verifyInstalledAppBundle();let z=this.resolveTargetBundleId(),L=await this.remoteRunner.start({deviceId:this.device.deviceId,port:this.servicePort,xctestrunPath:K||void 0,bundleId:z});if(!L.success||!L.data)throw Error(L.error||"Remote runner failed to start CtrlProxy");let H=L.data.port;if(typeof H==="number"&&H!==this.servicePort)U.info(`[IOSCtrlProxy] Host-control CtrlProxy process is listening on device port ${H}; restarting tunnel`),await this.stopIproxyTunnel(),await this.startIproxyTunnel({devicePort:H});this.xcTestProcessId=L.data.pid,this.xcTestProcess=null;return}let $=await this.builder.getXctestrunPath("device");if(!$)throw Error("CtrlProxy xctestrun not found for device. Download the CtrlProxy bundle before starting.");this.ensureLocalServicePortAllocatedAndAvailable(),await this.startIproxyTunnel(),await this.verifyInstalledAppBundle();let J=await this.signingManager.resolveSigningForDevice(this.device.deviceId);J.warnings.forEach((j)=>U.warn(`[IOSCtrlProxy] ${j}`));let X=[...J.buildSettings];if(J.allowProvisioningUpdates)X.unshift("-allowProvisioningUpdates");let Q=this.resolveTargetBundleId(),Y={CTRL_PROXY_IOS_PORT:String(this.servicePort),CTRL_PROXY_IOS_TIMEOUT:process.env.CTRL_PROXY_IOS_TIMEOUT||"86400",AUTOMOBILE_DEVICE_ID:this.device.deviceId};if(Q)Y.CTRL_PROXY_IOS_BUNDLE_ID=Q,U.info(`[IOSCtrlProxy] Passing CTRL_PROXY_IOS_BUNDLE_ID=${Q} to runner via xctestrun`);let G=["test-without-building","-xctestrun",await this.builder.writeRunnerEnvironment($,Y,this.device.deviceId),"-destination",`id=${this.device.deviceId}`,"-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService",...X],Z=await this.xcodebuild.startStreaming(G,{detached:!0,env:{...process.env,...Y},stdio:["ignore","pipe","pipe"]});if(Z.on("error",(j)=>{U.warn(`[IOSCtrlProxy] xcodebuild test error: ${j.message}`),this.handleProcessExit()}),Z.on("exit",(j,V)=>{if(j!==0||V)U.warn(`[IOSCtrlProxy] xcodebuild test exited: code=${j}, signal=${V}`);this.handleProcessExit()}),Z.pid)this.xcTestProcessId=Z.pid,this.xcTestProcess=Z,U.info(`[IOSCtrlProxy] Started xcodebuild test with PID ${Z.pid}`),this.captureProcessOutput(Z)}async verifyInstalledAppBundle(){if(process.env.AUTOMOBILE_IOS_SKIP_CTRL_PROXY_APP_HASH==="true"||process.env.AUTOMOBILE_IOS_SKIP_CTRL_PROXY_APP_HASH==="1")return;let $=this.isSimulator(),J=this.builder.getExpectedAppHash($?"simulator":"device");if(!J){U.warn("[IOSCtrlProxy] CtrlProxy app hash verification skipped (no expected hash configured)");return}let X=await this.deviceAppManager.getInstalledAppBundleHash(this.device.deviceId,m$.APP_BUNDLE_ID,$);if(!X){U.warn("[IOSCtrlProxy] Unable to read installed CtrlProxy app hash from device");return}if(X.toLowerCase()!==J.toLowerCase()){U.warn("[IOSCtrlProxy] Installed CtrlProxy app hash mismatch",{deviceHash:X,expectedHash:J});try{await this.deviceAppManager.uninstallApp(this.device.deviceId,m$.APP_BUNDLE_ID,$),U.info("[IOSCtrlProxy] Uninstalled CtrlProxy app to force reinstall")}catch(Q){U.warn(`[IOSCtrlProxy] Failed to uninstall CtrlProxy app: ${Q instanceof Error?Q.message:String(Q)}`)}return}U.info("[IOSCtrlProxy] Installed CtrlProxy app hash matches expected bundle")}async checkHealthEndpoint(){return this.healthClient.checkHealthEndpointOnPort(this.servicePort)}async getReportedRunnerPort(){let $=new Set([this.servicePort,m$.DEFAULT_PORT]);for(let J of $){let X=await this.healthClient.readReportedPortFromHealth(J);if(X!==null)return X}return null}async checkHealthEndpointOnPortForDevice($,J){return this.healthClient.checkHealthEndpointOnPortForDevice($,J)}getIproxyStartTimeoutMs(){let $=process.env.AUTOMOBILE_IPROXY_START_TIMEOUT_MS??process.env.AUTO_MOBILE_IPROXY_START_TIMEOUT_MS;if(!$)return m$.DEFAULT_IPROXY_START_TIMEOUT_MS;let J=Number.parseInt($,10);if(Number.isNaN(J)||J<=0)return U.warn(`[IOSCtrlProxy] Invalid iproxy timeout '${$}', using default ${m$.DEFAULT_IPROXY_START_TIMEOUT_MS}ms`),m$.DEFAULT_IPROXY_START_TIMEOUT_MS;return J}async startIproxyTunnel($={}){if(this.isSimulator())return;if(this.useRemoteRunner()){if(this.iproxyProcessId){let W=await this.remoteRunner.getIproxyStatus({pid:this.iproxyProcessId});if(W.success&&W.data?.running){if($.supervise!==!1)await this.iproxySupervisor.start();return}}let X=$.devicePort??this.iproxyDevicePort;await this.stopIproxyTunnel({stopSupervisor:$.supervise!==!1}),await this.ensureRemoteServicePortAvailable({allowReallocation:$.allowServicePortReallocation??!0});let Q=X??this.servicePort,Y=await this.remoteRunner.startIproxy({deviceId:this.device.deviceId,localPort:this.servicePort,devicePort:Q});if(!Y.success||!Y.data)throw Error(Y.error||"Failed to start iproxy tunnel via remote runner");if(this.iproxyProcessId=Y.data.pid,this.iproxyProcess=null,this.iproxyDevicePort=Q,await this.waitForIproxyStartup(),$.supervise!==!1)await this.iproxySupervisor.start();return}if(this.iproxyProcessId&&await this.isProcessRunning(this.iproxyProcessId)){if($.supervise!==!1)await this.iproxySupervisor.start();return}await this.stopIproxyTunnel({stopSupervisor:$.supervise!==!1}),U.info(`[IOSCtrlProxy] Starting iproxy tunnel (localhost:${this.servicePort} -> device:${this.servicePort})`);let J=this.processExecutor.spawn("iproxy",[String(this.servicePort),String(this.servicePort),this.device.deviceId],{stdio:["ignore","pipe","pipe"]});if(!J.pid)throw Error("Failed to start iproxy tunnel (no PID)");if(this.iproxyProcessId=J.pid,this.iproxyProcess=J,this.captureIproxyOutput(J),J.on("exit",()=>{if(this.iproxyProcess!==J)return;if(!this.isStopping)U.warn("[IOSCtrlProxy] iproxy exited unexpectedly"),this.iproxySupervisor.processExited()}),J.on("error",(X)=>{if(this.iproxyProcess!==J)return;if(!this.isStopping)U.warn(`[IOSCtrlProxy] iproxy error: ${X.message}`),this.iproxySupervisor.processExited()}),await this.waitForIproxyStartup(),$.supervise!==!1)await this.iproxySupervisor.start()}async stopIproxyTunnel($={}){if($.stopSupervisor!==!1)this.iproxySupervisor.stop();if(this.useRemoteRunner()){if(this.iproxyProcessId){let J=await this.remoteRunner.stopIproxy({pid:this.iproxyProcessId});if(!J.success)U.warn(`[IOSCtrlProxy] Failed to stop host iproxy: ${J.error||"Unknown error"}`)}}else if(this.iproxyProcess&&typeof this.iproxyProcess.kill==="function")try{this.iproxyProcess.kill()}catch{}else if(this.iproxyProcessId)try{process.kill(this.iproxyProcessId)}catch{}if(this.iproxyProcessId=null,this.iproxyProcess=null,$.clearDevicePort)this.iproxyDevicePort=null}async waitForIproxyStartup(){let $=this.getIproxyStartTimeoutMs(),J=this.timer.now()+$;while(this.timer.now()<J){if(this.iproxyProcessId){if(this.useRemoteRunner()){let X=await this.remoteRunner.getIproxyStatus({pid:this.iproxyProcessId});if(X.success&&X.data?.running)return}else if(await this.isProcessRunning(this.iproxyProcessId))return}await this.timer.sleep(100)}throw Error(`iproxy failed to stay running within ${$}ms`)}async restartIproxyTunnel(){try{await this.startIproxyTunnel({allowServicePortReallocation:!1,devicePort:this.iproxyDevicePort??void 0,supervise:!1})}catch($){if(!($ instanceof Wl))throw $;U.warn("[IOSCtrlProxy] Existing CtrlProxy process uses a host port that is no longer available during iproxy restart; restarting"),await this.restartDeviceProcessAfterHostPortCollision(),await this.processSupervisor.start()}}async isSupervisedIproxyTunnelAlive(){if(this.isSimulator())return!0;if(!await this.isDeviceDetected())return U.warn(`[IOSCtrlProxy] Device ${this.device.deviceId} not detected, stopping iproxy monitoring`),await this.stopIproxyTunnel({clearDevicePort:!0}),!0;let J=await this.isIproxyProcessAlive();if(!J)U.warn("[IOSCtrlProxy] iproxy process is no longer running, scheduling restart"),await this.stopIproxyTunnel({stopSupervisor:!1});return J}async isDeviceDetected(){if(this.isSimulator())try{if(this.useRemoteRunner()){let J=await this.remoteRunner.runSimctl(["list","devices"]);if(!J.success||!J.data)return!1;return J.data.stdout.includes(this.device.deviceId)}let{stdout:$}=await this.processExecutor.executeCommand("xcrun",["simctl","list","devices"]);return $.includes(this.device.deviceId)}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}try{if(this.useRemoteRunner()){let J=await this.remoteRunner.runIdeviceId(["-l"]);if(!J.success||!J.data)return!1;return J.data.stdout.split(`
|
|
208
|
+
`).flatMap((Y)=>{let W=Number.parseInt(Y,10);return Number.isNaN(W)?[]:[W]})}catch(Q){return U.debug(`[IOSCtrlProxy] Failed to enumerate ${$} PIDs: ${Q}`),[]}}async getProcessEnvironment($,J){try{let{stdout:X}=await this.executeCommand("ps",["eww","-p",String($),"-o","command="],J);return X.trim()||void 0}catch(X){U.debug(`[IOSCtrlProxy] Failed to inspect environment for PID ${$}: ${X}`);return}}parseCtrlProxyPort($){let J=$.match(/(?:^|\s)(?:SIMCTL_CHILD_)?CTRL_PROXY_IOS_PORT=(\d+)(?:\s|$)/);return J?Number.parseInt(J[1],10):null}hasExternalXcodebuildIdentity($){return $.includes("CTRL_PROXY_IOS_PORT=")||$.includes("AUTOMOBILE_DEVICE_ID=")||$.includes("SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=")}async signalGroup($,J,X){try{await this.executeCommand("kill",[`-${J}`,"--",`-${$}`],X)}catch(Q){U.debug(`[IOSCtrlProxy] PID ${$} is not a signalable process group: ${Q}`)}}async signalPids($,J,X){for(let Q of $)try{await this.executeCommand("kill",[`-${J}`,String(Q)],X)}catch(Y){U.debug(`[IOSCtrlProxy] PID ${Q} exited before ${J}: ${Y}`)}}async waitForExit($,J){for(let X=0;X<this.releaseAttempts;X++){if(await this.haveExited($,J))return!0;let Q=this.remainingTimeoutMs(J);await this.timer.sleep(Q===void 0?this.releaseGraceMs:Math.min(this.releaseGraceMs,Q))}return this.haveExited($,J)}async haveExited($,J){for(let X of $)if(await this.isRunning(X,J))return!1;return!0}async executeCommand($,J,X){let Q=this.remainingTimeoutMs(X);return this.host.executeCommand($,J,Q===void 0?void 0:{timeoutMs:Q})}remainingTimeoutMs($){if($===void 0)return;let J=$-this.timer.now();if(J<=0)throw Error("Startup CtrlProxy runner sweep deadline elapsed");return J}}var _g$=D(()=>{lQ();U$();n()});var Mg$={};m1(Mg$,{STARTUP_ORPHAN_RUNNER_REAP_DEADLINE_MS:()=>Yl,MAX_STARTUP_ORPHAN_RUNNER_CANDIDATES:()=>vQ$,IOSCtrlProxyManager:()=>m$});var vQ$=20,Yl=5000,Wl,m$;var XW=D(()=>{n();M0();U$();vP();hP();l4();IJ();am();lQ();Lg$();sm();yV();E8();wg$();Ng$();Ag$();_g$();Wl=class Wl extends Error{constructor($,J){super(`Remote runner port ${J} is already in use on ${$}`);this.name="RemoteServicePortUnavailableError"}};m$=class m${device;timer;servicePort;builder;processExecutor;xcodebuild;processClient;signingManager;deviceAppManager;remoteRunner;hostPortAvailabilityChecker;healthClient;remoteRunnerAvailability=null;static instances=new Map;static startupOrphanRunnerReap=null;cachedAvailability=null;cachedInstalled=null;cachedRunning=null;static AVAILABILITY_CACHE_TTL=3600000;static STATUS_CACHE_TTL=30000;static IMPORTANT_OUTPUT_MARKERS=["error","failed","failure","fatal","exception","crash","panic","timed out","timeout","denied","unable","not found","xctestconfiguration"];attemptedSetup=!1;xcTestProcessId=null;xcTestProcess=null;processSupervisor;iproxySupervisor;isProcessSupervisorRestarting=!1;static MAX_RESTART_ATTEMPTS=5;static RESTART_BASE_DELAY_MS=2000;static RESTART_MAX_DELAY_MS=30000;static PORT_RELEASE_GRACE_MS=250;static PORT_RELEASE_ATTEMPTS=4;iproxyProcessId=null;iproxyProcess=null;iproxyDevicePort=null;isStopping=!1;sharedStart=null;targetBundleId=null;static DEFAULT_PORT=8765;static DEFAULT_HEALTH_POLL_MAX_ATTEMPTS=60;static BUNDLE_ID="dev.jasonpearson.automobile.ctrlproxy";static APP_BUNDLE_ID="dev.jasonpearson.automobile.ctrlproxy";static LEGACY_APP_BUNDLE_ID="dev.jasonpearson.automobile.XCTestServiceApp";static IPROXY_MONITOR_INTERVAL_MS=5000;static IPROXY_RESTART_BASE_DELAY_MS=1000;static IPROXY_RESTART_MAX_DELAY_MS=15000;static DEFAULT_IPROXY_START_TIMEOUT_MS=5000;constructor($,J=g,X,Q=new g8,Y=new kQ$,W=new cJ,G,Z=new Ql,j=new gz,V){this.device=$,this.timer=J,this.servicePort=this.allocateServicePort(),this.builder=X||p0.getInstance(),this.processExecutor=Q,this.xcodebuild=j,this.processClient=V??new sL,this.signingManager=Y,this.deviceAppManager=W,this.hostPortAvailabilityChecker=Z,this.remoteRunner=G||{isEnabled:()=>!1,isRunningInDocker:()=>!1,isAvailable:async()=>!1,getHost:()=>"localhost",runIdeviceId:async()=>({success:!1,error:"Remote runner is disabled"}),runIdeviceInstaller:async()=>({success:!1,error:"Remote runner is disabled"}),runSimctl:async()=>({success:!1,error:"Remote runner is disabled"}),startIproxy:async()=>({success:!1,error:"Remote runner is disabled"}),stopIproxy:async()=>({success:!1,error:"Remote runner is disabled"}),getIproxyStatus:async()=>({success:!1,error:"Remote runner is disabled"}),start:async()=>({success:!1,error:"Remote runner is disabled"}),stop:async()=>({success:!1,error:"Remote runner is disabled"}),status:async()=>({success:!1,error:"Remote runner is disabled"})},this.healthClient=new cP(this.processExecutor,this.timer,{useRemoteRunner:()=>this.useRemoteRunner(),getHost:()=>this.remoteRunner.getHost(),deviceId:this.device.deviceId}),this.processSupervisor=new Xl({name:"iOS CtrlProxy XCTest runner",timer:this.timer,monitorIntervalMs:30000,maxRestartAttempts:m$.MAX_RESTART_ATTEMPTS,restartBackoff:kJ({initialDelayMs:m$.RESTART_BASE_DELAY_MS,maxDelayMs:m$.RESTART_MAX_DELAY_MS}),restart:async()=>{this.isProcessSupervisorRestarting=!0;try{await this.start()}finally{this.isProcessSupervisorRestarting=!1}},isAlive:()=>this.isSupervisedCtrlProxyProcessAlive(),onExit:()=>{this.xcTestProcessId=null,this.xcTestProcess=null,this.clearCaches()},onRestartSuccess:()=>{U.info("[IOSCtrlProxy] Auto-restart successful")},onRestartFailure:(K)=>{U.warn(`[IOSCtrlProxy] Auto-restart failed: ${K instanceof Error?K.message:String(K)}`)}}),this.iproxySupervisor=new Xl({name:"iOS iproxy tunnel",timer:this.timer,monitorIntervalMs:m$.IPROXY_MONITOR_INTERVAL_MS,restartBackoff:kJ({initialDelayMs:m$.IPROXY_RESTART_BASE_DELAY_MS,maxDelayMs:m$.IPROXY_RESTART_MAX_DELAY_MS}),restart:()=>this.restartIproxyTunnel(),isAlive:()=>this.isSupervisedIproxyTunnelAlive(),onExit:()=>{this.iproxyProcessId=null,this.iproxyProcess=null},onRestartFailure:(K)=>{U.warn(`[IOSCtrlProxy] Failed to restart iproxy: ${K instanceof Error?K.message:String(K)}`)}})}static getInstance($,J){if(bG($,"IOSCtrlProxyManager.getInstance"),!m$.instances.has($.deviceId))m$.instances.set($.deviceId,new m$($,J));return m$.instances.get($.deviceId)}static createForTesting($,J,X){return new m$($,J,X)}static createForTestingWithDeps($,J,X,Q,Y,W,G,Z,j,V){return new m$($,J,X,Q,Y,W,G,Z,j??new gz(async(K,z)=>Q.executeCommand(K,z),J,(K,z,L)=>Q.spawn(K,z,L)),V??new sL(Q,J))}static resetInstances(){m$.instances.clear(),m$.startupOrphanRunnerReap=null}static async shutdownAll(){let $=Array.from(m$.instances.values());await Promise.all($.map((J)=>J.stop())),m$.instances.clear()}static startOrphanRunnerReapOnStartup($=new sL,J=g){let Q=m$.reapOrphanedRunnerProcessesOnStartup($,J).catch((Y)=>{U.debug(`[IOSCtrlProxy] Startup orphan runner sweep failed: ${Y}`)});return m$.startupOrphanRunnerReap=m$.completeWithinStartupReapDeadline(Q,J),m$.startupOrphanRunnerReap}static async reapOrphanedRunnerProcessesOnStartup($=new sL,J=g){let X=J.now()+Yl,Q=[];try{Q=await $.findStartupCandidatePids(X)}catch(W){U.debug(`[IOSCtrlProxy] Failed to enumerate CtrlProxy iOS processes during startup sweep: ${W}`);return}let Y=new Set;for(let W of Q){if(J.now()>=X){m$.logStartupOrphanRunnerReapDeadline();return}try{if(!await m$.reapStartupOrphanRunnerCandidate($,W,X,J,Y))return}catch(G){if(U.debug(`[IOSCtrlProxy] Failed to reap orphaned CtrlProxy iOS process ${W}: ${G}`),J.now()>=X){m$.logStartupOrphanRunnerReapDeadline();return}}}}static async reapStartupOrphanRunnerCandidate($,J,X,Q,Y){let W=await m$.findStartupOrphanRunnerRoot($,J,X,Q);if(W.kind==="deadline_exhausted"||Q.now()>=X)return m$.logStartupOrphanRunnerReapDeadline(),!1;if(W.kind!=="root"||Y.has(W.pid))return!0;if(Y.size>=vQ$)return U.warn(`[IOSCtrlProxy] startup sweep skipped 1 startup CtrlProxy runner candidate after reaching the ${vQ$}-candidate cap`),!1;if(Y.add(W.pid),U.info(`[IOSCtrlProxy] Reaping orphaned CtrlProxy iOS process tree rooted at ${W.pid}`),await $.terminateProcessTree(W.pid,X),Q.now()>=X)return m$.logStartupOrphanRunnerReapDeadline(),!1;return!0}static async findStartupOrphanRunnerRoot($,J,X,Q){let Y=await $.getProcessInfo(J,X);if(!Y||!$.isCtrlProxyRunnerCommand(Y.command))return{kind:"not_daemon_managed"};return m$.findDaemonManagedRunnerTreeRoot($,{pid:J,port:m$.DEFAULT_PORT,command:Y.command,environment:Y.environment,ppid:Y.ppid},{requireOrphanedRoot:!0,shouldContinue:()=>Q.now()<X,deadline:X})}getServicePort(){return this.servicePort}setTargetBundleId($){this.targetBundleId=$,U.info(`[IOSCtrlProxy] Target bundle ID set to ${$}`)}getTargetBundleId(){return this.resolveTargetBundleId()}static getExistingTargetBundleId($){return m$.instances.get($.deviceId)?.getTargetBundleId()??process.env.CTRL_PROXY_IOS_BUNDLE_ID??void 0}resolveTargetBundleId(){return this.targetBundleId??process.env.CTRL_PROXY_IOS_BUNDLE_ID??void 0}clearCaches(){this.cachedAvailability=null,this.cachedInstalled=null,this.cachedRunning=null,U.info("[IOSCtrlProxy] Cleared all caches")}resetSetupState(){this.attemptedSetup=!1,this.clearCaches(),U.info("[IOSCtrlProxy] Reset setup state")}async isInstalled(){if(this.cachedInstalled){if(this.timer.now()-this.cachedInstalled.timestamp<m$.STATUS_CACHE_TTL)return this.cachedInstalled.isInstalled}try{if(U.debug("[IOSCtrlProxy] Checking if CtrlProxy is installed"),this.isSimulator())return this.cachedInstalled={isInstalled:!0,timestamp:this.timer.now()},!0;else{if(this.useRemoteRunner()){let X=await this.remoteRunner.runIdeviceInstaller(["-u",this.device.deviceId,"-l"]);if(!X.success||!X.data)return this.cachedInstalled={isInstalled:!1,timestamp:this.timer.now()},!1;let Q=X.data.stdout.includes(m$.BUNDLE_ID);return this.cachedInstalled={isInstalled:Q,timestamp:this.timer.now()},Q}let{stdout:$}=await this.processExecutor.executeCommand("ideviceinstaller",["-u",this.device.deviceId,"-l"]),J=$.includes(m$.BUNDLE_ID);return this.cachedInstalled={isInstalled:J,timestamp:this.timer.now()},J}}catch($){return U.warn(`[IOSCtrlProxy] Error checking installation: ${$}`),!1}}async isRunning(){if(this.cachedRunning){if(this.timer.now()-this.cachedRunning.timestamp<m$.STATUS_CACHE_TTL)return this.cachedRunning.isRunning}try{U.info("[IOSCtrlProxy] Checking if CtrlProxy is running");let $=await this.checkHealthEndpoint();return this.cachedRunning={isRunning:$,timestamp:this.timer.now()},$}catch($){return U.warn(`[IOSCtrlProxy] Error checking running status: ${$}`),!1}}async isAvailable(){if(this.cachedAvailability&&this.cachedAvailability.isAvailable){if(this.timer.now()-this.cachedAvailability.timestamp<m$.AVAILABILITY_CACHE_TTL)return this.cachedAvailability.isAvailable}let[$,J]=await Promise.all([this.isInstalled(),this.isRunning()]),X=$&&J;return this.cachedAvailability={isAvailable:X,timestamp:this.timer.now()},X}async start($={}){if($.signal?.aborted)throw $.signal.reason??Error("iOS CtrlProxy startup was aborted");let J=await this.waitForNonJoinableStart($.signal);if(J)U.info("[IOSCtrlProxy] Start already in progress, waiting for it to complete");else{let Y={controller:new AbortController,completion:Promise.resolve(),healthPollDeadlineMs:null,defaultHealthPollDeadlineMs:null,callerHealthPollDeadlinesMs:new Map,teardownCommitted:!1,waitingCallers:0,completed:!1};this.sharedStart=Y,Y.completion=this.startInternal(Y),Y.completion.finally(()=>{if(Y.completed=!0,this.sharedStart===Y)this.sharedStart=null}).catch(()=>{}),J=Y}let X=Symbol("CtrlProxy startup caller");return this.extendHealthPollDeadline(J,X,$.minimumHealthPollDurationMs),this.waitForSharedStart(J,$.signal,X)}async waitForNonJoinableStart($){let J=this.sharedStart;if(!J||!J.controller.signal.aborted&&!J.teardownCommitted)return J;U.info("[IOSCtrlProxy] Waiting for a non-joinable startup to settle before retrying");try{await this.waitForSharedStart(J,$)}catch(X){if($?.aborted)throw X}if(this.sharedStart===J)this.sharedStart=null;return this.sharedStart}async startInternal($){let J=await wq();if(J.present&&!J.usable)throw new R(`AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH / _IPA_PATH is set but unusable: ${J.reason}`);await this.awaitStartupOrphanRunnerReap(),U.info("[IOSCtrlProxy] Starting CtrlProxy"),this.isStopping=!1;let X=U0();X.startOperation("processAliveCheck");let Q=await this.isCtrlProxyProcessAlive();X.endOperation("processAliveCheck");let Y=!1,W=!1;if(Q){if(U.info("[IOSCtrlProxy] CtrlProxy process is alive, skipping start"),!this.isSimulator()){X.startOperation("iproxyTunnel");try{await this.startIproxyTunnel({allowServicePortReallocation:!1})}catch(K){if(X.endOperation("iproxyTunnel"),!(K instanceof Wl))throw K;U.warn("[IOSCtrlProxy] Existing CtrlProxy process uses a host port that is no longer available; restarting"),X.startOperation("spawnRunner"),await this.restartDeviceProcessAfterHostPortCollision(),X.endOperation("spawnRunner"),Y=!0}if(!Y)X.endOperation("iproxyTunnel"),await this.iproxySupervisor.start()}if(!Y){await this.startProcessSupervision();return}}if(!Y){X.startOperation("runningCheck");let K=await this.isRunning();if(X.endOperation("runningCheck"),K){U.info("[IOSCtrlProxy] Service is already running"),await this.startProcessSupervision();return}if(this.isSimulator())if(await this.isOwnRunnerProcessAlive())U.info(`[IOSCtrlProxy] Own CtrlProxy runner (PID ${this.xcTestProcessId}) is still starting; waiting for its health endpoint instead of respawning`),W=!0;else{X.startOperation("externalProcessCheck");let z=await this.findExternalCtrlProxyProcess(),L=z===null&&!this.useRemoteRunner()&&this.servicePort!==m$.DEFAULT_PORT&&await this.checkHealthEndpointOnPortForDevice(m$.DEFAULT_PORT,this.device.deviceId);if(X.endOperation("externalProcessCheck"),z||L){let H=z?.port??m$.DEFAULT_PORT;if(U.info(`[IOSCtrlProxy] External CtrlProxy process detected on port ${H}, skipping spawn`),H!==this.servicePort)this.adoptServicePort(H)}else await this.ensureServicePortReadyForLaunch(),X.startOperation("spawnRunner"),await this.startOnSimulator(),X.endOperation("spawnRunner")}else X.startOperation("spawnRunner"),await this.startOnDevice(),X.endOperation("spawnRunner")}let G=500,Z=m$.resolveHealthPollMaxAttempts()*G;$.defaultHealthPollDeadlineMs=this.timer.now()+Z,this.refreshHealthPollDeadline($);let j=Math.round((($.healthPollDeadlineMs??0)-this.timer.now())/1000);if(await this.waitForHealthEndpoint($,X,G)){await this.completeHealthStartup($,X);return}if(W&&this.xcTestProcessId!==null){if(this.servicePort!==m$.DEFAULT_PORT&&await this.checkHealthEndpointOnPortForDevice(m$.DEFAULT_PORT,this.device.deviceId)){U.info(`[IOSCtrlProxy] Deferred-to runner is healthy on default port ${m$.DEFAULT_PORT}; adopting it instead of terminating`),this.adoptServicePort(m$.DEFAULT_PORT),this.clearCaches(),await this.sleepForHealthPoll(500,$.controller.signal),await this.startProcessSupervision();return}if(await this.completeHealthStartupIfDeadlineExtended($,X,G))return;let K=this.xcTestProcessId,z=await this.isOwnRunnerProcessAlive();if(await this.completeHealthStartupIfDeadlineExtended($,X,G))return;$.teardownCommitted=!0,this.isStopping=!0;try{if(z)if(U.warn(`[IOSCtrlProxy] Deferred-to CtrlProxy runner (PID ${K}) never became healthy within ${j}s; terminating it so the next start spawns a fresh runner`),this.useRemoteRunner())try{await this.remoteRunner.stop({deviceId:this.device.deviceId,pid:K})}catch(L){U.warn(`[IOSCtrlProxy] Remote runner stop of hung runner ${K} failed: ${L instanceof Error?L.message:String(L)}`)}else await this.processClient.terminateProcessTree(K);else U.warn(`[IOSCtrlProxy] Tracked runner PID ${K} is no longer our CtrlProxy runner (exited/PID-reused); un-tracking without terminating`);this.xcTestProcessId=null,this.xcTestProcess=null,this.clearCaches(),this.processSupervisor.stop(),await this.processSupervisor.start()}finally{this.isStopping=!1}}let V=await this.findListeningProcessesOnPort(this.servicePort);if(await this.completeHealthStartupIfDeadlineExtended($,X,G))return;if(V.length>0)throw Error(`CtrlProxy failed to start within timeout (${j}s); port ${this.servicePort} still held by ${this.formatListeningProcesses(V)}`);throw Error(`CtrlProxy failed to start within timeout (${j}s)`)}async stop(){if(U.info("[IOSCtrlProxy] Stopping CtrlProxy"),this.isStopping=!0,this.processSupervisor.stop(),this.useRemoteRunner()){try{if(this.xcTestProcessId)await this.remoteRunner.stop({deviceId:this.device.deviceId,pid:this.xcTestProcessId})}catch($){U.warn(`[IOSCtrlProxy] Remote runner stop failed: ${$ instanceof Error?$.message:String($)}`)}if(!this.isSimulator())await this.stopIproxyTunnel({clearDevicePort:!0});this.xcTestProcessId=null,this.xcTestProcess=null,this.clearCaches(),R6.release(this.device.deviceId),this.isStopping=!1,U.info("[IOSCtrlProxy] Service stopped");return}if(await this.stopIproxyTunnel({clearDevicePort:!0}),this.xcTestProcessId){try{if(await this.isOwnRunnerProcessAlive())await this.processClient.terminateProcessTree(this.xcTestProcessId);else U.debug(`[IOSCtrlProxy] Tracked runner PID ${this.xcTestProcessId} is not an owned CtrlProxy runner; clearing without terminating`)}catch($){U.warn(`[IOSCtrlProxy] Failed to terminate tracked CtrlProxy runner ${this.xcTestProcessId}: ${$ instanceof Error?$.message:String($)}`)}this.xcTestProcessId=null,this.xcTestProcess=null}this.clearCaches(),R6.release(this.device.deviceId),this.isStopping=!1,U.info("[IOSCtrlProxy] Service stopped")}async uninstallLegacyAppIfPresent(){try{let $=this.isSimulator();if(await this.deviceAppManager.getInstalledAppBundleHash(this.device.deviceId,m$.LEGACY_APP_BUNDLE_ID,$)===null)return;U.info(`[IOSCtrlProxy] Found legacy app ${m$.LEGACY_APP_BUNDLE_ID}, uninstalling`),await this.deviceAppManager.uninstallApp(this.device.deviceId,m$.LEGACY_APP_BUNDLE_ID,$),U.info("[IOSCtrlProxy] Legacy app uninstalled")}catch($){U.warn(`[IOSCtrlProxy] Failed to check/uninstall legacy app: ${$}`)}}async setup($=!1,J=new E$,X,Q){if(J.serial("xcTestServiceSetup"),p0.isPinnedVersionUnverifiable())return J.end(),{success:!1,message:`AUTOMOBILE_VERSION=${Z4()} is not in the AutoMobile release checksum registry, so the CtrlProxy bundle cannot be integrity-verified. Pin a released version, or vendor a trusted bundle via AUTOMOBILE_CTRL_PROXY_IOS_IPA_PATH.`,perfTiming:J.getTimings()};if(await this.uninstallLegacyAppIfPresent(),this.attemptedSetup&&!$){if(await this.isAvailable())return J.end(),{success:!0,message:"CtrlProxy was already running",perfTiming:J.getTimings()};return J.end(),{success:!1,message:"Setup already attempted",perfTiming:J.getTimings()}}try{this.attemptedSetup=!0;let Y=await J.track("checkRunning",()=>this.isRunning());if(!$&&Y)return J.end(),{success:!0,message:"CtrlProxy was already running",perfTiming:J.getTimings()};let W=this.useRemoteRunner()?!1:await J.track("checkBuild",()=>this.builder.needsRebuild(this.isSimulator()?"simulator":"device")),G=null;if(W){let Z=p0.getPrefetchedResult();if(Z&&Z.success)U.info("[IOSCtrlProxy] Using prefetched build result"),G=Z;else{let j=await J.track("waitForPrefetch",()=>p0.waitForPrefetch());if(j&&j.success)U.info("[IOSCtrlProxy] Using completed prefetch build result"),G=j;else if(U.info("[IOSCtrlProxy] Downloading CtrlProxy bundle"),G=await J.track("build",()=>this.builder.build(this.isSimulator()?"simulator":"device",J)),!G.success)return this.attemptedSetup=!1,J.end(),{success:!1,message:G.message,error:G.error,buildResult:G,perfTiming:J.getTimings()}}}return await J.track("startService",()=>this.start({minimumHealthPollDurationMs:Q,signal:X})),J.end(),{success:!0,message:W?"CtrlProxy downloaded and started successfully":"CtrlProxy started successfully",buildResult:G||void 0,perfTiming:J.getTimings()}}catch(Y){this.attemptedSetup=!1;let W=Y instanceof Error?Y.message:String(Y);return J.end(),{success:!1,message:"Failed to setup CtrlProxy",error:W,perfTiming:J.getTimings()}}}isSimulator(){return l1(this.device.deviceId)}useRemoteRunner(){return this.remoteRunner.isEnabled()&&this.remoteRunner.isRunningInDocker()}allocateServicePort($=[]){return R6.allocate(this.device.deviceId,{reservedPorts:[...hz,...$]})}ensureLocalServicePortAllocatedAndAvailable(){let $=R6.getPort(this.device.deviceId),J=R6.isPortAvailable(this.servicePort);if($===this.servicePort&&J)return;let X=J?[]:[this.servicePort];R6.release(this.device.deviceId);let Q=this.allocateServicePort(X);if(Q!==this.servicePort)U.info(`[IOSCtrlProxy] Reallocated service port from ${this.servicePort} to ${Q} before runner launch`),this.servicePort=Q,this.clearCaches()}adoptServicePort($){if(R6.getPort(this.device.deviceId)!==$)R6.reserve(this.device.deviceId,$);if(this.servicePort!==$)this.servicePort=$,this.clearCaches()}async ensureRemoteServicePortAvailable($={}){let J=$.allowReallocation??!0,X=this.remoteRunner.getHost(),Q=new Set;for(let Y=0;Y<R6.getMaxDevices();Y++){if(await this.hostPortAvailabilityChecker.isAvailable(X,this.servicePort))return;let W=this.servicePort;if(U.warn(`[IOSCtrlProxy] Remote runner port ${W} is already in use on ${X}; reallocating`),!J)throw new Wl(X,W);Q.add(W),R6.release(this.device.deviceId),this.servicePort=this.allocateServicePort(Q)}throw Error(`No remote iOS CtrlProxy ports are available for device ${this.device.deviceId}.`)}async isRemoteRunnerAvailable(){if(!this.remoteRunnerAvailability)this.remoteRunnerAvailability=this.remoteRunner.isAvailable();return this.remoteRunnerAvailability}async restartDeviceProcessAfterHostPortCollision(){await this.stop(),this.isStopping=!1,await this.startOnDevice()}async startOnSimulator(){if(U.info("[IOSCtrlProxy] Starting CtrlProxy on simulator"),this.useRemoteRunner()){if(!await this.isRemoteRunnerAvailable())throw Error("Remote runner not available for CtrlProxy startup");let Z=await this.remoteRunner.status({deviceId:this.device.deviceId}),j=Z.data?.port;if(Z.success&&Z.data?.running&&typeof j==="number"){U.info(`[IOSCtrlProxy] Reusing remote CtrlProxy process on service port ${j}`),this.adoptServicePort(j),this.xcTestProcessId=Z.data.pid??null,this.xcTestProcess=null;return}await this.ensureRemoteServicePortAvailable();let V=await this.builder.getXctestrunPath("simulator"),K=this.resolveTargetBundleId(),z=await this.remoteRunner.start({deviceId:this.device.deviceId,port:this.servicePort,xctestrunPath:V||void 0,bundleId:K});if(!z.success||!z.data)throw Error(z.error||"Remote runner failed to start CtrlProxy");if(typeof z.data.port==="number")this.adoptServicePort(z.data.port);this.xcTestProcessId=z.data.pid,this.xcTestProcess=null;return}let $=await this.builder.getXctestrunPath("simulator");if(!$)throw Error("CtrlProxy xctestrun not found for simulator. Download the CtrlProxy bundle before starting.");await this.builder.verifyRunnerBinaryBeforeLaunch("simulator");let J=process.env.CTRL_PROXY_IOS_TIMEOUT||"86400",X=this.resolveTargetBundleId();this.ensureLocalServicePortAllocatedAndAvailable();let Q={CTRL_PROXY_IOS_PORT:String(this.servicePort),CTRL_PROXY_IOS_TIMEOUT:J,AUTOMOBILE_DEVICE_ID:this.device.deviceId};if(X)Q.CTRL_PROXY_IOS_BUNDLE_ID=X,U.info(`[IOSCtrlProxy] Passing CTRL_PROXY_IOS_BUNDLE_ID=${X} to runner via xctestrun`);let W=["test-without-building","-xctestrun",await this.builder.writeRunnerEnvironment($,Q,this.device.deviceId),"-destination",`platform=iOS Simulator,id=${this.device.deviceId}`,"-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService"];U.info("[IOSCtrlProxy] Using xcodebuild test-without-building to start runner on simulator");let G=await this.xcodebuild.startStreaming(W,{detached:!0,env:{...process.env,...Q},stdio:["ignore","pipe","pipe"]});if(G.on("error",(Z)=>{if(this.xcTestProcess!==G)return;U.warn(`[IOSCtrlProxy] xcodebuild test error: ${Z.message}`),this.handleProcessExit()}),G.on("exit",(Z,j)=>{if(Z!==0||j)U.warn(`[IOSCtrlProxy] xcodebuild test exited: code=${Z}, signal=${j}`);if(this.xcTestProcess!==G)return;this.handleProcessExit()}),G.pid)this.xcTestProcessId=G.pid,this.xcTestProcess=G,U.info(`[IOSCtrlProxy] Started xcodebuild test with PID ${G.pid}`),this.captureProcessOutput(G)}captureProcessOutput($){if($.stdout)$.stdout.on("data",(J)=>{let X=J.toString().trim();if(X&&this.shouldPromoteCtrlProxyOutput(X))U.info(`[CtrlProxy stdout] ${X.slice(0,500)}`)});if($.stderr)$.stderr.on("data",(J)=>{let X=J.toString().trim();if(X&&!X.includes("Build Succeeded"))if(this.shouldPromoteCtrlProxyOutput(X))U.warn(`[CtrlProxy stderr] ${X.slice(0,500)}`);else U.debug(`[CtrlProxy stderr] ${X.slice(0,500)}`)})}shouldPromoteCtrlProxyOutput($){if(process.env.AUTOMOBILE_CTRLPROXY_VERBOSE==="true")return!0;let J=$.toLowerCase();return m$.IMPORTANT_OUTPUT_MARKERS.some((X)=>J.includes(X))}handleProcessExit(){this.processSupervisor.processExited()}async startProcessSupervision(){if(!this.isProcessSupervisorRestarting)await this.processSupervisor.start()}async isSupervisedCtrlProxyProcessAlive(){if(await this.checkHealthEndpoint()||!this.xcTestProcessId)return!0;let J=this.useRemoteRunner()?await this.isOwnRunnerProcessAlive():await this.isProcessRunning(this.xcTestProcessId);if(!J)U.warn("[IOSCtrlProxy] XCTest process crashed, health endpoint not responding");return J}setAutoRestart($){this.processSupervisor.setAutoRestart($),U.info(`[IOSCtrlProxy] Auto-restart ${$?"enabled":"disabled"}`)}isAutoRestartEnabled(){return this.processSupervisor.isAutoRestartEnabled()}async forceRestart(){U.info("[IOSCtrlProxy] Force restart requested"),await this.stop(),await this.start()}async isProcessRunning($){return this.processClient.isRunning($)}async isOwnRunnerProcessAlive(){if(!this.xcTestProcessId)return!1;if(this.useRemoteRunner())try{let J=await this.remoteRunner.status({deviceId:this.device.deviceId,pid:this.xcTestProcessId});return J.success&&(J.data?.running??!1)&&J.data?.pid===this.xcTestProcessId}catch(J){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${J}`,J),!1}if(!await this.isProcessRunning(this.xcTestProcessId))return!1;let $=await this.processClient.getProcessInfo(this.xcTestProcessId);if(!$)return!1;return this.isOwnedCtrlProxyRunnerProcess({pid:this.xcTestProcessId,port:this.servicePort,command:$.command,environment:$.environment})}static resolveHealthPollMaxAttempts(){let $=process.env.AUTOMOBILE_CTRL_PROXY_HEALTH_MAX_ATTEMPTS??process.env.AUTO_MOBILE_CTRL_PROXY_HEALTH_MAX_ATTEMPTS,J=m$.DEFAULT_HEALTH_POLL_MAX_ATTEMPTS;if($!==void 0){let X=Number.parseInt($,10);if(Number.isFinite(X)&&X>0)J=X}return J}extendHealthPollDeadline($,J,X){if(!X||X<=0)return;$.callerHealthPollDeadlinesMs.set(J,this.timer.now()+X),this.refreshHealthPollDeadline($)}removeHealthPollDeadline($,J){if(!J)return;$.callerHealthPollDeadlinesMs.delete(J),this.refreshHealthPollDeadline($)}refreshHealthPollDeadline($){$.healthPollDeadlineMs=Math.max($.defaultHealthPollDeadlineMs??0,...$.callerHealthPollDeadlinesMs.values())}async waitForHealthEndpoint($,J,X){J.startOperation("healthPolling");let Q=0;for(;;){if($.controller.signal.aborted)throw $.controller.signal.reason??Error("iOS CtrlProxy startup was aborted");if(Q++,await this.checkHealthEndpoint())return J.endOperation("healthPolling"),!0;if(Q>1&&Q%10===0)U.info(`[IOSCtrlProxy] Still waiting for service... (attempt ${Q}, ${Math.max(0,($.healthPollDeadlineMs??0)-this.timer.now())}ms remaining)`);let Y=($.healthPollDeadlineMs??0)-this.timer.now();if(Y<=0)return J.endOperation("healthPolling"),!1;await this.sleepForHealthPoll(Math.min(X,Y),$.controller.signal)}}async completeHealthStartup($,J){if(U.info("[IOSCtrlProxy] HTTP health endpoint is ready"),this.clearCaches(),await this.startProcessSupervision(),U.info("[IOSCtrlProxy] Waiting for WebSocket server initialization"),J.startOperation("websocketInit"),await this.sleepForHealthPoll(500,$.controller.signal),J.endOperation("websocketInit"),!this.isSimulator())await this.iproxySupervisor.start()}async completeHealthStartupIfDeadlineExtended($,J,X){if(($.healthPollDeadlineMs??0)<=this.timer.now())return!1;if(!await this.waitForHealthEndpoint($,J,X))return!1;return await this.completeHealthStartup($,J),!0}waitForSharedStart($,J,X){return $.waitingCallers++,new Promise((Q,Y)=>{let W=!1,G=(j)=>{if(W)return;if(W=!0,J?.removeEventListener("abort",Z),$.waitingCallers--,this.removeHealthPollDeadline($,X),!$.completed&&$.waitingCallers===0)$.controller.abort(J?.reason??Error("iOS CtrlProxy startup has no remaining callers"));j()},Z=()=>G(()=>{Y(J?.reason??Error("iOS CtrlProxy startup was aborted"))});if(J?.aborted){Z();return}J?.addEventListener("abort",Z,{once:!0}),$.completion.then(()=>G(Q),(j)=>G(()=>Y(j)))})}async sleepForHealthPoll($,J){if(!J){await this.timer.sleep($);return}if(J.aborted)throw J.reason??Error("iOS CtrlProxy startup was aborted");await new Promise((X,Q)=>{let Y=!1,W=(Z)=>{if(Y)return;Y=!0,J.removeEventListener("abort",G),Z()},G=()=>W(()=>{Q(J.reason??Error("iOS CtrlProxy startup was aborted"))});J.addEventListener("abort",G,{once:!0}),this.timer.sleep($).then(()=>W(X),(Z)=>W(()=>Q(Z)))})}async isCtrlProxyProcessAlive(){if(!this.xcTestProcessId)return!1;if(this.useRemoteRunner())try{let $=await this.remoteRunner.status({deviceId:this.device.deviceId,pid:this.xcTestProcessId});return $.success&&($.data?.running??!1)&&$.data?.pid===this.xcTestProcessId}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}if(!await this.isProcessRunning(this.xcTestProcessId))return!1;return this.checkHealthEndpoint()}async findExternalCtrlProxyProcess(){if(this.useRemoteRunner())return null;let $=await this.findExternalXcodebuildCtrlProxyProcess();if($)return $;return this.findExternalDirectCtrlProxyProcess()}async findExternalXcodebuildCtrlProxyProcess(){for(let $ of await this.processClient.findXcodebuildPids()){if($===this.xcTestProcessId)continue;let J=await this.processClient.getProcessInfo($),X=J?.command??"";if(!X.includes("CtrlProxy")||await this.isDaemonManagedSimulatorXcodebuildProcess(X,J))continue;let Q=`${X} ${J?.environment??""}`;if(!m$.hasDeviceIdentity(Q,this.device.deviceId))continue;let Y=this.parseCtrlProxyPortFromProcessArgs(X)??this.parseCtrlProxyPortFromProcessArgs(J?.environment??"")??m$.DEFAULT_PORT;return U.info(`[IOSCtrlProxy] Found external xcodebuild CtrlProxy process: ${$}`),{pid:$,port:Y}}return null}async findExternalDirectCtrlProxyProcess(){let $=new Set([this.servicePort,m$.DEFAULT_PORT]);for(let J of $){let X=await this.findListeningProcessesOnPort(J);for(let Q of X){if(!m$.isDirectCtrlProxyRunnerCommand(Q.command))continue;let Y=await m$.findDaemonManagedRunnerTreeRoot(this.processClient,Q);if(Y.kind==="root"&&Y.pid!==Q.pid)continue;if(!await this.processAncestryContainsDeviceId(Q))continue;return U.info(`[IOSCtrlProxy] Found external direct CtrlProxy runner: ${Q.pid}`),{pid:Q.pid,port:J}}}return null}parseCtrlProxyPortFromProcessArgs($){let J=$.match(/(?:^|\s)(?:SIMCTL_CHILD_)?CTRL_PROXY_IOS_PORT=(\d+)(?:\s|$)/);if(!J)return null;let X=Number.parseInt(J[1],10);return fQ$(X)?X:null}async ensureServicePortReadyForLaunch(){if(this.useRemoteRunner())return;let $=new Set;for(let J=0;J<R6.getMaxDevices();J++){let X=await this.findListeningProcessesOnPort(this.servicePort);if(X.length===0)return;let Q=X.filter((Y)=>this.isOwnedCtrlProxyRunnerProcess(Y));if(Q.length>0){for(let Z of Q){let j=await this.findDaemonManagedRunnerTreeRoot(Z);U.warn(`[IOSCtrlProxy] Terminating stale CtrlProxy process tree rooted at ${j} for listener ${Z.pid} on port ${this.servicePort}`),await this.processClient.terminateProcessTree(j)}let Y=await this.findListeningProcessesOnPort(this.servicePort);if(Y.length===0)return;let W=Y.filter((Z)=>this.isOwnedCtrlProxyRunnerProcess(Z));if(W.length>0)for(let Z of W)U.warn(`[IOSCtrlProxy] CtrlProxy listener ${Z.pid} still holds port ${this.servicePort}; force-terminating remaining owned process tree`),await this.processClient.terminateProcessTree(Z.pid);let G=await this.findListeningProcessesOnPort(this.servicePort);if(G.length===0)return;if(G.some((Z)=>this.isOwnedCtrlProxyRunnerProcess(Z)))throw Error(`CtrlProxy recovery failed, port ${this.servicePort} still held by `+this.formatListeningProcesses(G))}$.add(this.servicePort),U.warn(`[IOSCtrlProxy] Port ${this.servicePort} is held by a foreign process; reallocating CtrlProxy port`),R6.release(this.device.deviceId),this.servicePort=this.allocateServicePort($),this.clearCaches()}throw Error(`No iOS CtrlProxy ports are available for device ${this.device.deviceId}.`)}async findListeningProcessesOnPort($){let J=[];for(let X of await this.processClient.findListeningPids($)){let Q=await this.processClient.getProcessInfo(X);if(Q)J.push({pid:X,port:$,...Q})}return J}isOwnedCtrlProxyRunnerProcess($){if(!m$.isCtrlProxyRunnerCommand($.command))return!1;return m$.hasDeviceIdentity($.command,this.device.deviceId)||m$.hasDeviceIdentity($.environment??"",this.device.deviceId)}async processAncestryContainsDeviceId($){let J=$.ppid,X=new Set;while(J!==void 0&&J>1&&!X.has(J)){X.add(J);let Q=await this.processClient.getProcessInfo(J);if(!Q)return!1;if(m$.hasDeviceIdentity(Q.command,this.device.deviceId)||Q.command.includes(this.device.deviceId))return!0;J=Q.ppid}return!1}async findDaemonManagedRunnerTreeRoot($){let J=await m$.findDaemonManagedRunnerTreeRoot(this.processClient,$);return J.kind==="root"?J.pid:$.pid}static async findDaemonManagedRunnerTreeRoot($,J,X={}){if(!m$.isCtrlProxyRunnerCommand(J.command))return{kind:"not_daemon_managed"};let Q=J.ppid===1?J.pid:null,Y=J.ppid,W=new Set([J.pid]);if(m$.isDaemonManagedSimulatorXcodebuildCommandShape(J.command))Q=m$.rootPidForDaemonManagedProcess(J.pid,J.ppid,X.requireOrphanedRoot);while(Y!==void 0&&Y>1&&!W.has(Y)){if(!m$.shouldContinueStartupOrphanRunnerTraversal(X))return{kind:"deadline_exhausted"};W.add(Y);let G=await $.getProcessInfo(Y,X.deadline);if(!G)break;let Z=m$.daemonManagedParentRoot(G,Y,X.requireOrphanedRoot);if(Z){if(Z.terminal)return m$.toDaemonManagedRunnerTreeRoot(Z.rootPid);Q=Z.rootPid}Y=G.ppid}return m$.toDaemonManagedRunnerTreeRoot(Q)}async awaitStartupOrphanRunnerReap(){if(this.isSimulator())await m$.awaitStartupOrphanRunnerReap()}static async awaitStartupOrphanRunnerReap(){await m$.startupOrphanRunnerReap}static async completeWithinStartupReapDeadline($,J){let X;try{await Promise.race([$,new Promise((Q)=>{X=J.setTimeout(()=>{m$.logStartupOrphanRunnerReapDeadline(),Q()},Yl),X.unref?.()})])}finally{if(X)J.clearTimeout(X)}}static logStartupOrphanRunnerReapDeadline(){U.warn(`[IOSCtrlProxy] startup CtrlProxy runner sweep timed out after ${Yl}ms`)}static shouldContinueStartupOrphanRunnerTraversal($){return $.shouldContinue?.()??!0}static daemonManagedParentRoot($,J,X){if(!m$.isDaemonManagedSimulatorXcodebuildCommandShape($.command))return null;return{rootPid:m$.rootPidForDaemonManagedProcess(J,$.ppid,X),terminal:m$.isShellCommand($.command)}}static rootPidForDaemonManagedProcess($,J,X){return X&&J!==1?null:$}static toDaemonManagedRunnerTreeRoot($){return $===null?{kind:"not_daemon_managed"}:{kind:"root",pid:$}}formatListeningProcesses($){return $.map((J)=>`PID ${J.pid} (cmd: ${J.command})`).join(", ")}static hasDeviceIdentity($,J){return $.includes(`id=${J}`)||$.includes(`AUTOMOBILE_DEVICE_ID=${J}`)||$.includes(`SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=${J}`)}async isDaemonManagedSimulatorXcodebuildProcess($,J){let X=J?.environment??"";if(!m$.isDaemonManagedSimulatorXcodebuildCommandShape($))return!1;if(J?.ppid===1)return!0;if(await this.hasOrphanedDaemonManagedShellParent(J?.ppid))return!0;return!m$.hasExternalXcodebuildIdentity(X)}async hasOrphanedDaemonManagedShellParent($){if($===void 0||$<=1)return!1;let J=await this.processClient.getProcessInfo($);if(!J||J.ppid!==1)return!1;return m$.isShellCommand(J.command)&&m$.isDaemonManagedSimulatorXcodebuildCommandShape(J.command)}static isDaemonManagedSimulatorXcodebuildCommandShape($){return $.includes("xcodebuild")&&$.includes("test-without-building")&&$.includes("-xctestrun")&&$.includes("platform=iOS Simulator")&&$.includes("-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService")&&!$.includes("CTRL_PROXY_IOS_PORT=")&&!$.includes("AUTOMOBILE_DEVICE_ID=")}static isShellCommand($){return/(?:^|\/)(?:ba|z|c|t?c|k)?sh(?:\s|$)/.test($)}static hasExternalXcodebuildIdentity($){return $.includes("CTRL_PROXY_IOS_PORT=")||$.includes("AUTOMOBILE_DEVICE_ID=")||$.includes("SIMCTL_CHILD_AUTOMOBILE_DEVICE_ID=")}static isCtrlProxyRunnerCommand($){return $.includes("CtrlProxy")&&($.includes("xcodebuild")||$.includes("CtrlProxyUITests")||$.includes("CtrlProxyUITests-Runner")||$.includes(".xctestrun"))}static isDirectCtrlProxyRunnerCommand($){return $.includes("CtrlProxyUITests-Runner")}async isIproxyProcessAlive(){if(!this.iproxyProcessId)return!1;if(this.useRemoteRunner())try{let $=await this.remoteRunner.getIproxyStatus({pid:this.iproxyProcessId});return $.success&&($.data?.running??!1)}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}return this.isProcessRunning(this.iproxyProcessId)}async startOnDevice(){if(U.info("[IOSCtrlProxy] Starting CtrlProxy on physical device"),this.useRemoteRunner()){if(!await this.isRemoteRunnerAvailable())throw Error("Remote runner not available for CtrlProxy startup");let j=await this.remoteRunner.status({deviceId:this.device.deviceId}),V=j.data?.port;if(j.success&&j.data?.running&&typeof V==="number"){U.info(`[IOSCtrlProxy] Reusing remote CtrlProxy process on device port ${V}`),this.xcTestProcessId=j.data.pid??null,this.xcTestProcess=null,await this.startIproxyTunnel({devicePort:V});return}let K=await this.builder.getXctestrunPath("device");await this.startIproxyTunnel(),await this.verifyInstalledAppBundle();let z=this.resolveTargetBundleId(),L=await this.remoteRunner.start({deviceId:this.device.deviceId,port:this.servicePort,xctestrunPath:K||void 0,bundleId:z});if(!L.success||!L.data)throw Error(L.error||"Remote runner failed to start CtrlProxy");let H=L.data.port;if(typeof H==="number"&&H!==this.servicePort)U.info(`[IOSCtrlProxy] Host-control CtrlProxy process is listening on device port ${H}; restarting tunnel`),await this.stopIproxyTunnel(),await this.startIproxyTunnel({devicePort:H});this.xcTestProcessId=L.data.pid,this.xcTestProcess=null;return}let $=await this.builder.getXctestrunPath("device");if(!$)throw Error("CtrlProxy xctestrun not found for device. Download the CtrlProxy bundle before starting.");this.ensureLocalServicePortAllocatedAndAvailable(),await this.startIproxyTunnel(),await this.verifyInstalledAppBundle();let J=await this.signingManager.resolveSigningForDevice(this.device.deviceId);J.warnings.forEach((j)=>U.warn(`[IOSCtrlProxy] ${j}`));let X=[...J.buildSettings];if(J.allowProvisioningUpdates)X.unshift("-allowProvisioningUpdates");let Q=this.resolveTargetBundleId(),Y={CTRL_PROXY_IOS_PORT:String(this.servicePort),CTRL_PROXY_IOS_TIMEOUT:process.env.CTRL_PROXY_IOS_TIMEOUT||"86400",AUTOMOBILE_DEVICE_ID:this.device.deviceId};if(Q)Y.CTRL_PROXY_IOS_BUNDLE_ID=Q,U.info(`[IOSCtrlProxy] Passing CTRL_PROXY_IOS_BUNDLE_ID=${Q} to runner via xctestrun`);let G=["test-without-building","-xctestrun",await this.builder.writeRunnerEnvironment($,Y,this.device.deviceId),"-destination",`id=${this.device.deviceId}`,"-only-testing:CtrlProxyUITests/CtrlProxyUITests/testRunService",...X],Z=await this.xcodebuild.startStreaming(G,{detached:!0,env:{...process.env,...Y},stdio:["ignore","pipe","pipe"]});if(Z.on("error",(j)=>{U.warn(`[IOSCtrlProxy] xcodebuild test error: ${j.message}`),this.handleProcessExit()}),Z.on("exit",(j,V)=>{if(j!==0||V)U.warn(`[IOSCtrlProxy] xcodebuild test exited: code=${j}, signal=${V}`);this.handleProcessExit()}),Z.pid)this.xcTestProcessId=Z.pid,this.xcTestProcess=Z,U.info(`[IOSCtrlProxy] Started xcodebuild test with PID ${Z.pid}`),this.captureProcessOutput(Z)}async verifyInstalledAppBundle(){if(process.env.AUTOMOBILE_IOS_SKIP_CTRL_PROXY_APP_HASH==="true"||process.env.AUTOMOBILE_IOS_SKIP_CTRL_PROXY_APP_HASH==="1")return;let $=this.isSimulator(),J=this.builder.getExpectedAppHash($?"simulator":"device");if(!J){U.warn("[IOSCtrlProxy] CtrlProxy app hash verification skipped (no expected hash configured)");return}let X=await this.deviceAppManager.getInstalledAppBundleHash(this.device.deviceId,m$.APP_BUNDLE_ID,$);if(!X){U.warn("[IOSCtrlProxy] Unable to read installed CtrlProxy app hash from device");return}if(X.toLowerCase()!==J.toLowerCase()){U.warn("[IOSCtrlProxy] Installed CtrlProxy app hash mismatch",{deviceHash:X,expectedHash:J});try{await this.deviceAppManager.uninstallApp(this.device.deviceId,m$.APP_BUNDLE_ID,$),U.info("[IOSCtrlProxy] Uninstalled CtrlProxy app to force reinstall")}catch(Q){U.warn(`[IOSCtrlProxy] Failed to uninstall CtrlProxy app: ${Q instanceof Error?Q.message:String(Q)}`)}return}U.info("[IOSCtrlProxy] Installed CtrlProxy app hash matches expected bundle")}async checkHealthEndpoint(){return this.healthClient.checkHealthEndpointOnPort(this.servicePort)}async getReportedRunnerPort(){let $=new Set([this.servicePort,m$.DEFAULT_PORT]);for(let J of $){let X=await this.healthClient.readReportedPortFromHealth(J);if(X!==null)return X}return null}async checkHealthEndpointOnPortForDevice($,J){return this.healthClient.checkHealthEndpointOnPortForDevice($,J)}getIproxyStartTimeoutMs(){let $=process.env.AUTOMOBILE_IPROXY_START_TIMEOUT_MS??process.env.AUTO_MOBILE_IPROXY_START_TIMEOUT_MS;if(!$)return m$.DEFAULT_IPROXY_START_TIMEOUT_MS;let J=Number.parseInt($,10);if(Number.isNaN(J)||J<=0)return U.warn(`[IOSCtrlProxy] Invalid iproxy timeout '${$}', using default ${m$.DEFAULT_IPROXY_START_TIMEOUT_MS}ms`),m$.DEFAULT_IPROXY_START_TIMEOUT_MS;return J}async startIproxyTunnel($={}){if(this.isSimulator())return;if(this.useRemoteRunner()){if(this.iproxyProcessId){let W=await this.remoteRunner.getIproxyStatus({pid:this.iproxyProcessId});if(W.success&&W.data?.running){if($.supervise!==!1)await this.iproxySupervisor.start();return}}let X=$.devicePort??this.iproxyDevicePort;await this.stopIproxyTunnel({stopSupervisor:$.supervise!==!1}),await this.ensureRemoteServicePortAvailable({allowReallocation:$.allowServicePortReallocation??!0});let Q=X??this.servicePort,Y=await this.remoteRunner.startIproxy({deviceId:this.device.deviceId,localPort:this.servicePort,devicePort:Q});if(!Y.success||!Y.data)throw Error(Y.error||"Failed to start iproxy tunnel via remote runner");if(this.iproxyProcessId=Y.data.pid,this.iproxyProcess=null,this.iproxyDevicePort=Q,await this.waitForIproxyStartup(),$.supervise!==!1)await this.iproxySupervisor.start();return}if(this.iproxyProcessId&&await this.isProcessRunning(this.iproxyProcessId)){if($.supervise!==!1)await this.iproxySupervisor.start();return}await this.stopIproxyTunnel({stopSupervisor:$.supervise!==!1}),U.info(`[IOSCtrlProxy] Starting iproxy tunnel (localhost:${this.servicePort} -> device:${this.servicePort})`);let J=this.processExecutor.spawn("iproxy",[String(this.servicePort),String(this.servicePort),this.device.deviceId],{stdio:["ignore","pipe","pipe"]});if(!J.pid)throw Error("Failed to start iproxy tunnel (no PID)");if(this.iproxyProcessId=J.pid,this.iproxyProcess=J,this.captureIproxyOutput(J),J.on("exit",()=>{if(this.iproxyProcess!==J)return;if(!this.isStopping)U.warn("[IOSCtrlProxy] iproxy exited unexpectedly"),this.iproxySupervisor.processExited()}),J.on("error",(X)=>{if(this.iproxyProcess!==J)return;if(!this.isStopping)U.warn(`[IOSCtrlProxy] iproxy error: ${X.message}`),this.iproxySupervisor.processExited()}),await this.waitForIproxyStartup(),$.supervise!==!1)await this.iproxySupervisor.start()}async stopIproxyTunnel($={}){if($.stopSupervisor!==!1)this.iproxySupervisor.stop();if(this.useRemoteRunner()){if(this.iproxyProcessId){let J=await this.remoteRunner.stopIproxy({pid:this.iproxyProcessId});if(!J.success)U.warn(`[IOSCtrlProxy] Failed to stop host iproxy: ${J.error||"Unknown error"}`)}}else if(this.iproxyProcess&&typeof this.iproxyProcess.kill==="function")try{this.iproxyProcess.kill()}catch{}else if(this.iproxyProcessId)try{process.kill(this.iproxyProcessId)}catch{}if(this.iproxyProcessId=null,this.iproxyProcess=null,$.clearDevicePort)this.iproxyDevicePort=null}async waitForIproxyStartup(){let $=this.getIproxyStartTimeoutMs(),J=this.timer.now()+$;while(this.timer.now()<J){if(this.iproxyProcessId){if(this.useRemoteRunner()){let X=await this.remoteRunner.getIproxyStatus({pid:this.iproxyProcessId});if(X.success&&X.data?.running)return}else if(await this.isProcessRunning(this.iproxyProcessId))return}await this.timer.sleep(100)}throw Error(`iproxy failed to stay running within ${$}ms`)}async restartIproxyTunnel(){try{await this.startIproxyTunnel({allowServicePortReallocation:!1,devicePort:this.iproxyDevicePort??void 0,supervise:!1})}catch($){if(!($ instanceof Wl))throw $;U.warn("[IOSCtrlProxy] Existing CtrlProxy process uses a host port that is no longer available during iproxy restart; restarting"),await this.restartDeviceProcessAfterHostPortCollision(),await this.processSupervisor.start()}}async isSupervisedIproxyTunnelAlive(){if(this.isSimulator())return!0;if(!await this.isDeviceDetected())return U.warn(`[IOSCtrlProxy] Device ${this.device.deviceId} not detected, stopping iproxy monitoring`),await this.stopIproxyTunnel({clearDevicePort:!0}),!0;let J=await this.isIproxyProcessAlive();if(!J)U.warn("[IOSCtrlProxy] iproxy process is no longer running, scheduling restart"),await this.stopIproxyTunnel({stopSupervisor:!1});return J}async isDeviceDetected(){if(this.isSimulator())try{if(this.useRemoteRunner()){let J=await this.remoteRunner.runSimctl(["list","devices"]);if(!J.success||!J.data)return!1;return J.data.stdout.includes(this.device.deviceId)}let{stdout:$}=await this.processExecutor.executeCommand("xcrun",["simctl","list","devices"]);return $.includes(this.device.deviceId)}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}try{if(this.useRemoteRunner()){let J=await this.remoteRunner.runIdeviceId(["-l"]);if(!J.success||!J.data)return!1;return J.data.stdout.split(`
|
|
209
209
|
`).some((X)=>X.trim()===this.device.deviceId)}let{stdout:$}=await this.processExecutor.executeCommand("idevice_id",["-l"]);return $.split(`
|
|
210
210
|
`).some((J)=>J.trim()===this.device.deviceId)}catch($){return U.debug(`src/utils/IOSCtrlProxyManager.ts fallback failed: ${$}`,$),!1}}captureIproxyOutput($){if($.stdout)$.stdout.on("data",(J)=>{let X=J.toString().trim();if(X)U.info(`[iproxy stdout] ${X.slice(0,500)}`)});if($.stderr)$.stderr.on("data",(J)=>{let X=J.toString().trim();if(X)U.warn(`[iproxy stderr] ${X.slice(0,500)}`)})}async getCapabilities(){return{supportsXCTest:!0,deviceType:this.isSimulator()?"simulator":"physical",iosVersion:null}}}});function Gl($,J){let X=/^Unknown command type: (.+)$/.exec($);if(!X)return $;let Q=X[1];if(J==="android")return`Android CtrlProxy APK rejected ${Q} as unknown. The runner is likely older than this daemon; rebuild and redeploy android/control-proxy, or point the daemon at a fresh APK with AUTOMOBILE_CTRL_PROXY_APK_PATH.`;return`iOS CtrlProxy runner rejected ${Q} as unknown. The runner is likely older than this daemon; rebuild and redeploy the iOS CtrlProxy runner from this source checkout, or run the iOS hot-reload watcher with --manage-ios-runner.`}class Aq{db;constructor($){this.db=$??null}getDb(){if(this.db)return this.db;return N1()}resolveConnection(){return this.getDb()}withExecutor($){return new Aq($)}async runInTransaction($){return this.getDb().transaction().execute($)}async getOrCreateApp($){let J=this.getDb(),X=new Date().toISOString(),Q={app_id:$,updated_at:X};return await J.insertInto("navigation_apps").values(Q).onConflict((W)=>W.column("app_id").doUpdateSet((G)=>({updated_at:G.ref("navigation_apps.updated_at")}))).returningAll().executeTakeFirstOrThrow()}async touchApp($){await this.getDb().updateTable("navigation_apps").set({updated_at:new Date().toISOString()}).where("app_id","=",$).execute()}async listApps(){return this.getDb().selectFrom("navigation_apps").select(["app_id","updated_at"]).where(({exists:J,selectFrom:X})=>J(X("navigation_nodes").select("navigation_nodes.id").whereRef("navigation_nodes.app_id","=","navigation_apps.app_id"))).orderBy("updated_at","desc").execute()}async getOrCreateNode($,J,X){let Q=this.getDb(),Y={app_id:$,screen_name:J,first_seen_at:X,last_seen_at:X,visit_count:1};return await Q.insertInto("navigation_nodes").values(Y).onConflict((G)=>G.columns(["app_id","screen_name"]).doUpdateSet((Z)=>({last_seen_at:X,visit_count:Z("navigation_nodes.visit_count","+",1)}))).returningAll().executeTakeFirstOrThrow()}async getNode($,J){return this.getDb().selectFrom("navigation_nodes").selectAll().where("app_id","=",$).where("screen_name","=",J).executeTakeFirst()}async getNodeById($,J){return this.getDb().selectFrom("navigation_nodes").selectAll().where("app_id","=",$).where("id","=",J).executeTakeFirst()}async updateNodeBackStack($,J,X,Q){await this.getDb().updateTable("navigation_nodes").set({back_stack_depth:X,task_id:Q}).where("app_id","=",$).where("screen_name","=",J).execute(),U.debug(`[NAV_REPO] Updated back stack for ${J}: depth=${X}, taskId=${Q}`)}async getNodes($){return this.getDb().selectFrom("navigation_nodes").selectAll().where("app_id","=",$).orderBy("screen_name","asc").execute()}async getNodesByScreenNames($,J){if(J.length===0)return[];return this.getDb().selectFrom("navigation_nodes").selectAll().where("app_id","=",$).where("screen_name","in",J).execute()}async createEdge($,J,X,Q,Y,W){let G=this.getDb(),Z={app_id:$,from_screen:J,to_screen:X,tool_name:Q,tool_args:Y?JSON.stringify(Y):null,timestamp:W},j=await G.insertInto("navigation_edges").values(Z).returningAll().executeTakeFirstOrThrow(),V=Q?` via ${Q}`:" (unknown)";return U.debug(`[NAV_REPO] Edge created: ${J} \u2192 ${X}${V} (id=${j.id})`),j}async getEdges($){return this.getDb().selectFrom("navigation_edges").selectAll().where("app_id","=",$).orderBy("timestamp","asc").execute()}async getEdgesPage($,J){let Q=this.getDb().selectFrom("navigation_edges").selectAll().where("app_id","=",$);if(J.cursor)Q=Q.where(({eb:Z,or:j,and:V})=>j([Z("timestamp",">",J.cursor.timestamp),V([Z("timestamp","=",J.cursor.timestamp),Z("id",">",J.cursor.id)])]));let Y=await Q.orderBy("timestamp","asc").orderBy("id","asc").limit(J.limit+1).execute(),W=Y.length>J.limit;return{edges:W?Y.slice(0,J.limit):Y,hasMore:W}}async getEdgesFrom($,J){return this.getDb().selectFrom("navigation_edges").selectAll().where("app_id","=",$).where("from_screen","=",J).execute()}async getEdgesTo($,J){return this.getDb().selectFrom("navigation_edges").selectAll().where("app_id","=",$).where("to_screen","=",J).execute()}async getOrCreateUIElement($,J,X){let Q=this.getDb();if(Q.isTransaction)return this.getOrCreateUIElementWithin(Q,$,J,X);return Q.transaction().execute((Y)=>this.getOrCreateUIElementWithin(Y,$,J,X))}async getOrCreateUIElementWithin($,J,X,Q){let Y=$.selectFrom("ui_elements").selectAll().where("app_id","=",J);if(X.text!==void 0)Y=Y.where("text","=",X.text);if(X.resourceId!==void 0)Y=Y.where("resource_id","=",X.resourceId);if(X.contentDescription!==void 0)Y=Y.where("content_description","=",X.contentDescription);if(X.className!==void 0)Y=Y.where("class_name","=",X.className);if(X.bounds)Y=Y.where("bounds_left","=",X.bounds.left).where("bounds_top","=",X.bounds.top).where("bounds_right","=",X.bounds.right).where("bounds_bottom","=",X.bounds.bottom);let W=await Y.executeTakeFirst();if(W)return await $.updateTable("ui_elements").set({last_seen_at:Q}).where("id","=",W.id).execute(),{...W,last_seen_at:Q};let G={app_id:J,text:X.text||null,resource_id:X.resourceId||null,content_description:X.contentDescription||null,class_name:X.className||null,bounds_left:X.bounds?.left||null,bounds_top:X.bounds?.top||null,bounds_right:X.bounds?.right||null,bounds_bottom:X.bounds?.bottom||null,clickable:X.clickable!==void 0?X.clickable?1:0:null,scrollable:X.scrollable!==void 0?X.scrollable?1:0:null,first_seen_at:Q,last_seen_at:Q};return await $.insertInto("ui_elements").values(G).returningAll().executeTakeFirstOrThrow()}async linkUIElementsToEdge($,J){if(J.length===0)return;let X=this.getDb(),Q=J.map((Y,W)=>({edge_id:$,ui_element_id:Y,selection_order:W}));await X.insertInto("edge_ui_elements").values(Q).execute()}async getUIElementsForEdge($){return this.getDb().selectFrom("edge_ui_elements").innerJoin("ui_elements","ui_elements.id","edge_ui_elements.ui_element_id").selectAll("ui_elements").where("edge_id","=",$).orderBy("selection_order","asc").execute()}async setNodeModals($,J){let X=this.getDb();if(await X.deleteFrom("node_modals").where("node_id","=",$).execute(),J.length===0)return;let Q=J.map((Y,W)=>({node_id:$,modal_identifier:Y,stack_level:W}));await X.insertInto("node_modals").values(Q).execute()}async getNodeModals($){return(await this.getDb().selectFrom("node_modals").select("modal_identifier").where("node_id","=",$).orderBy("stack_level","asc").execute()).map((Q)=>Q.modal_identifier)}async setEdgeModals($,J,X){let Q=this.getDb();if(await Q.deleteFrom("edge_modals").where("edge_id","=",$).where("position","=",J).execute(),X.length===0)return;let Y=X.map((W,G)=>({edge_id:$,position:J,modal_identifier:W,stack_level:G}));await Q.insertInto("edge_modals").values(Y).execute()}async getEdgeModals($,J){return(await this.getDb().selectFrom("edge_modals").select("modal_identifier").where("edge_id","=",$).where("position","=",J).orderBy("stack_level","asc").execute()).map((Y)=>Y.modal_identifier)}async setScrollPosition($,J,X,Q,Y,W){let G=this.getDb(),Z={edge_id:$,target_element_id:J,container_element_id:Q||null,direction:X,speed:Y||null,swipe_count:W||null};await G.deleteFrom("scroll_positions").where("edge_id","=",$).execute(),await G.insertInto("scroll_positions").values(Z).execute()}async getScrollPosition($){let X=await this.getDb().selectFrom("scroll_positions").innerJoin("ui_elements as target","target.id","scroll_positions.target_element_id").leftJoin("ui_elements as container","container.id","scroll_positions.container_element_id").select(["scroll_positions.direction","scroll_positions.speed","scroll_positions.swipe_count"]).selectAll("target").select(["container.id as container_id","container.text as container_text","container.resource_id as container_resource_id","container.content_description as container_content_description"]).where("edge_id","=",$).executeTakeFirst();if(!X)return null;let Q={targetElement:{id:X.id,app_id:X.app_id,text:X.text,resource_id:X.resource_id,content_description:X.content_description,class_name:X.class_name,bounds_left:X.bounds_left,bounds_top:X.bounds_top,bounds_right:X.bounds_right,bounds_bottom:X.bounds_bottom,clickable:X.clickable,scrollable:X.scrollable,first_seen_at:X.first_seen_at,last_seen_at:X.last_seen_at,created_at:X.created_at},direction:X.direction,speed:X.speed||void 0,swipeCount:X.swipe_count||void 0};if(X.container_id)Q.containerElement={id:X.container_id,app_id:X.app_id,text:X.container_text,resource_id:X.container_resource_id,content_description:X.container_content_description,class_name:null,bounds_left:null,bounds_top:null,bounds_right:null,bounds_bottom:null,clickable:null,scrollable:null,first_seen_at:0,last_seen_at:0,created_at:""};return Q}async getStats($){let J=this.getDb(),X=await J.selectFrom("navigation_nodes").select(J.fn.countAll().as("count")).where("app_id","=",$).executeTakeFirst(),Q=await J.selectFrom("navigation_edges").select(J.fn.countAll().as("count")).where("app_id","=",$).executeTakeFirst(),Y=await J.selectFrom("navigation_edges").select(J.fn.countAll().as("count")).where("app_id","=",$).where("tool_name","is not",null).executeTakeFirst(),W=await J.selectFrom("navigation_edges").select(J.fn.countAll().as("count")).where("app_id","=",$).where("tool_name","is",null).executeTakeFirst();return{nodeCount:Number(X?.count||0),edgeCount:Number(Q?.count||0),toolEdgeCount:Number(Y?.count||0),unknownEdgeCount:Number(W?.count||0)}}async clearApp($){await this.getDb().deleteFrom("navigation_apps").where("app_id","=",$).execute(),U.info(`[NAV_REPO] Cleared navigation data for app: ${$}`)}async updateNodeScreenshot($,J,X){await this.getDb().updateTable("navigation_nodes").set({screenshot_path:X}).where("app_id","=",$).where("screen_name","=",J).execute(),U.debug(`[NAV_REPO] Updated screenshot for ${J}: ${X}`)}async updateNodeScreenshotById($,J){await this.getDb().updateTable("navigation_nodes").set({screenshot_path:J}).where("id","=",$).execute(),U.debug(`[NAV_REPO] Updated screenshot for node ${$}: ${J}`)}async clearAppGraph($){let J=this.getDb();await J.deleteFrom("navigation_edges").where("app_id","=",$).execute(),await J.deleteFrom("navigation_nodes").where("app_id","=",$).execute(),await J.deleteFrom("ui_elements").where("app_id","=",$).execute(),await J.deleteFrom("navigation_suggestions").where("app_id","=",$).execute(),U.info(`[NAV_REPO] Cleared graph data for app: ${$}`)}async getOrCreateFingerprint($,J,X,Q,Y){let W=this.getDb(),G={app_id:$,node_id:J,fingerprint_hash:X,fingerprint_data:Q,first_seen_at:Y,last_seen_at:Y,occurrence_count:1};return await W.insertInto("navigation_node_fingerprints").values(G).onConflict((j)=>j.columns(["app_id","fingerprint_hash"]).doUpdateSet((V)=>({last_seen_at:Y,occurrence_count:V("navigation_node_fingerprints.occurrence_count","+",1)}))).returningAll().executeTakeFirstOrThrow()}async getNodeByFingerprint($,J){let X=this.getDb(),Q=await X.selectFrom("navigation_node_fingerprints").select("node_id").where("app_id","=",$).where("fingerprint_hash","=",J).executeTakeFirst();if(!Q)return;return X.selectFrom("navigation_nodes").selectAll().where("id","=",Q.node_id).executeTakeFirst()}async getFingerprintsForNode($){return this.getDb().selectFrom("navigation_node_fingerprints").selectAll().where("node_id","=",$).execute()}async addOrUpdateSuggestion($,J,X,Q){let Y=this.getDb(),W={app_id:$,fingerprint_hash:J,fingerprint_data:X,first_seen_at:Q,last_seen_at:Q,occurrence_count:1,promoted_to_fingerprint_id:null};return await Y.insertInto("navigation_suggestions").values(W).onConflict((Z)=>Z.columns(["app_id","fingerprint_hash"]).doUpdateSet((j)=>({last_seen_at:Q,occurrence_count:j("navigation_suggestions.occurrence_count","+",1)}))).returningAll().executeTakeFirstOrThrow()}async promoteSuggestion($,J,X){let Q=this.getDb();if(Q.isTransaction)return this.promoteSuggestionWithin(Q,$,J,X);return Q.transaction().execute((Y)=>this.withExecutor(Y).promoteSuggestionWithin(Y,$,J,X))}async promoteSuggestionWithin($,J,X,Q){let Y=await $.selectFrom("navigation_suggestions").selectAll().where("id","=",J).executeTakeFirst();if(!Y)throw Error(`Suggestion not found: ${J}`);let W=await this.withExecutor($).getOrCreateFingerprint(Y.app_id,X,Y.fingerprint_hash,Y.fingerprint_data,Q);return await $.updateTable("navigation_suggestions").set({promoted_to_fingerprint_id:W.id}).where("id","=",J).execute(),U.info(`[NAV_REPO] Promoted suggestion ${J} to node ${X}`),W}async hasNamedNodes($){let J=this.getDb(),X=await J.selectFrom("navigation_nodes").select(J.fn.countAll().as("count")).where("app_id","=",$).executeTakeFirst();return Number(X?.count||0)>0}async getSuggestions($){return this.getDb().selectFrom("navigation_suggestions").selectAll().where("app_id","=",$).where("promoted_to_fingerprint_id","is",null).orderBy("occurrence_count","desc").execute()}async getOrCreateBuildKey($,J,X){let Q=this.getDb(),Y={app_id:$,version_code:J,content_hash:X};return Q.insertInto("navigation_build_keys").values(Y).onConflict((W)=>W.columns(["app_id","version_code","content_hash"]).doUpdateSet((G)=>({app_id:G.ref("navigation_build_keys.app_id")}))).returningAll().executeTakeFirstOrThrow()}async recordNodeObservation($,J,X,Q,Y){let W=this.getDb(),G={node_id:$,build_key_id:J,device_id:X,session_uuid:Q,first_seen_at:Y,last_seen_at:Y};await W.insertInto("navigation_node_observations").values(G).onConflict((Z)=>Z.columns(["node_id","build_key_id","device_id","session_uuid"]).doUpdateSet({first_seen_at:J0`min(navigation_node_observations.first_seen_at, ${Y})`,last_seen_at:J0`max(navigation_node_observations.last_seen_at, ${Y})`})).execute()}async recordEdgeObservation($,J,X,Q,Y){let W=this.getDb(),G={edge_id:$,build_key_id:J,device_id:X,session_uuid:Q,first_seen_at:Y,last_seen_at:Y};await W.insertInto("navigation_edge_observations").values(G).onConflict((Z)=>Z.columns(["edge_id","build_key_id","device_id","session_uuid"]).doUpdateSet({first_seen_at:J0`min(navigation_edge_observations.first_seen_at, ${Y})`,last_seen_at:J0`max(navigation_edge_observations.last_seen_at, ${Y})`})).execute()}async updateNodeVisit($,J){await this.getDb().updateTable("navigation_nodes").set((Q)=>({last_seen_at:J,visit_count:Q("visit_count","+",1)})).where("id","=",$).execute()}}var hQ$=D(()=>{vX();r6();n()});async function Rg$($,J,X,Q=By0,Y=Dy0,W=1){if(X.insertsSinceCleanup+=W,X.insertsSinceCleanup<Y)return;if(X.insertsSinceCleanup=0,X.cleanupInProgress)return;X.cleanupInProgress=!0;try{let G=$??N1(),Z=await G.selectFrom(J).select(G.fn.countAll().as("count")).executeTakeFirstOrThrow();if(Number(Z.count)>Q){let j=await G.selectFrom(J).select(["id","timestamp"]).orderBy("timestamp","desc").orderBy("id","desc").limit(1).offset(Q-1).executeTakeFirst();if(j)await G.deleteFrom(J).where((V)=>V.or([V("timestamp","<",j.timestamp),V.and([V("timestamp","=",j.timestamp),V("id","<",j.id)])])).execute()}}catch(G){U.warn(`${J} retention cleanup failed: ${G}`,G)}finally{X.cleanupInProgress=!1}}var By0=1e4,Dy0=256;var Eg$=D(()=>{r6();n()});function d9($){return $??N1()}function cQ(){return{cleanupInProgress:!1,insertsSinceCleanup:0}}async function dQ($,J,X,Q,Y,W){await Rg$(X,$,J,Q,Y,W)}var eL=D(()=>{r6();Eg$()});function dP($,J=10240){if($===null||$.length<=J)return $;let X=J,Q=$.charCodeAt(X-1);if(Q>=55296&&Q<=56319)X-=1;else if(Q>=56320&&Q<=57343){let Y=X>=2?$.charCodeAt(X-2):0;if(Y<55296||Y>56319)X-=1}return $.slice(0,X)}function uQ$($,J=!1,X=Fy0){if($===null||$===void 0)return $;let Q;if(J){if(typeof $!=="string")return $;Q=$.length}else{let W;try{W=JSON.stringify($)}catch{return $}if(W===void 0)return $;Q=W.length}if(Q<=X)return $;return{_truncated:!0,bytes:Q}}var gQ$=10240,Fy0=10240;async function Pg$($,J){let X=await d9(J).insertInto("network_events").values({device_id:$.deviceId,timestamp:$.timestamp,application_id:$.applicationId,session_id:$.sessionId,url:$.url,method:$.method,status_code:$.statusCode,duration_ms:$.durationMs,request_body_size:$.requestBodySize,response_body_size:$.responseBodySize,protocol:$.protocol,host:$.host,path:$.path,error:$.error,request_headers_json:$.requestHeaders?JSON.stringify($.requestHeaders):null,response_headers_json:$.responseHeaders?JSON.stringify($.responseHeaders):null,request_body:$.requestBody??null,response_body:$.responseBody??null,content_type:$.contentType??null}).returning("id").executeTakeFirstOrThrow();return wy0(J),X.id}function Tg$($){return{id:$.id,deviceId:$.device_id,timestamp:$.timestamp,applicationId:$.application_id,sessionId:$.session_id,url:$.url,method:$.method,statusCode:$.status_code,durationMs:$.duration_ms,requestBodySize:$.request_body_size??-1,responseBodySize:$.response_body_size??-1,protocol:$.protocol,host:$.host,path:$.path,error:$.error,requestHeaders:$.request_headers_json?JSON.parse($.request_headers_json):null,responseHeaders:$.response_headers_json?JSON.parse($.response_headers_json):null,requestBody:dP($.request_body??null),responseBody:dP($.response_body??null),contentType:$.content_type??null}}async function Cg$($,J){let X=await d9(J).selectFrom("network_events").selectAll().where("id","=",$).executeTakeFirst();if(!X)return null;return Tg$(X)}async function fG($,J){let X=d9(J).selectFrom("network_events").selectAll();if($.deviceId)X=X.where("device_id","=",$.deviceId);if($.sinceTimestamp)X=X.where("timestamp",">=",$.sinceTimestamp);if($.host)X=X.where("host","=",$.host);if($.method)X=X.where("method","=",$.method.toUpperCase());if($.statusCode){if(/^\d+$/.test($.statusCode))X=X.where("status_code","=",parseInt($.statusCode,10));else if(/^\dxx$/i.test($.statusCode)){let Y=parseInt($.statusCode[0],10)*100;X=X.where("status_code",">=",Y).where("status_code","<",Y+100)}}if($.minStatusCode!==void 0)X=X.where("status_code",">=",$.minStatusCode);return X=X.orderBy("timestamp","desc").limit($.limit??100),(await X.execute()).map(Tg$)}async function wy0($,J,X){await dQ("network_events",qy0,$,J,X)}var qy0;var nP=D(()=>{eL();qy0=cQ()});function Sg$($){for(let[J,X]of Object.entries(mQ$))if(X===$)return J;return}class Ig${listeners=new Set;subscribe($){return this.listeners.add($),()=>{this.listeners.delete($)}}emit($){for(let J of this.listeners)try{J($)}catch(X){U.warn(`[ListChangedBroadcaster] listener failed for ${$} list_changed: ${X}`)}}clearForTesting(){this.listeners.clear()}}var mQ$,$H;var iP=D(()=>{n();mQ$={tools:"notifications/tools/list_changed",resources:"notifications/resources/list_changed"};$H=new Ig$});function Ny0($){let J=[],Q=$.replace(/\{(\w+)\}/g,(W,G)=>{return J.push(G),`__PARAM_${J.length-1}__`}).replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),Y=Q.replace(/__PARAM_(\d+)__/g,(W,G)=>{let Z=Number(G);return J[Z]==="path"&&Q.endsWith(`__PARAM_${Z}__`)?"(.+)":"([^/&]+)"});return{regex:new RegExp(`^${Y}$`),paramNames:J}}function Ay0($,J){let X=J.match($.regex);if(!X)return null;let Q={};return $.paramNames.forEach((Y,W)=>{Q[Y]=X[W+1]}),Q}class kg${resources=new Map;templates=new Map;servers=new Set;subscriptions=new Set;register($,J,X,Q,Y){this.resources.set($,{uri:$,name:J,description:X,mimeType:Q,handler:Y})}registerTemplate($,J,X,Q,Y){let{regex:W,paramNames:G}=Ny0($);this.templates.set($,{uriTemplate:$,name:J,description:X,mimeType:Q,handler:Y,regex:W,paramNames:G})}getAllTemplates(){return Array.from(this.templates.values())}getTemplate($){return this.templates.get($)}matchTemplate($){for(let J of this.templates.values()){let X=Ay0(J,$);if(X)return{template:J,params:X}}return}getAllResources(){return Array.from(this.resources.values())}getResource($){return this.resources.get($)}unregister($){this.resources.delete($)}getResourceDefinitions(){return Array.from(this.resources.values()).map(($)=>({uri:$.uri,name:$.name,description:$.description,mimeType:$.mimeType}))}getTemplateDefinitions(){return Array.from(this.templates.values()).map(($)=>({uriTemplate:$.uriTemplate,name:$.name,description:$.description,mimeType:$.mimeType}))}trackServer($){if(this.servers.has($))return;this.servers.add($);let J=$.server,X=J.onclose;J.onclose=()=>{this.servers.delete($),X?.()}}registerWithServer($){this.trackServer($),$.server.setRequestHandler(Bz,async()=>{return{resources:this.getResourceDefinitions()}}),$.server.setRequestHandler(Fz,async(J)=>{let{uri:X}=J.params;U.info(`[ResourceRegistry] ReadResource request for URI: ${X}`);let Q=X.match(/^([a-z][a-z0-9+.-]*):\/?\/?/i);if(Q){let G=Q[1].toLowerCase();if(G!=="automobile"&&G!=="ui"&&!this.getResource(X)){let Z=X.replace(/^[a-z][a-z0-9+.-]*:\/?\/?/i,"automobile:");throw Error(`Unknown URI scheme '${G}://'. AutoMobile resources use the 'automobile:' prefix. Try: ${Z}`)}}let Y=this.getResource(X);if(Y)return{contents:[await Y.handler()]};let W=this.matchTemplate(X);if(W)return{contents:[await W.template.handler(W.params)]};throw Error(`Resource not found: ${X}
|
|
211
211
|
|
|
@@ -596,7 +596,7 @@ Error: ${$}`)}}async checkFfmpegVersion(){let{version:$}=await this.ffmpegClient
|
|
|
596
596
|
${X.stderr.join("").trim()||"(empty)"}`].filter((W)=>Boolean(W)).join(`
|
|
597
597
|
`)}buildProcessFailureMessage($,J,X,Q,Y){return[$,Y?`output: ${Y}`:void 0,`command: ${J} ${X.join(" ")}`,`exitCode: ${Q.exitState.exitCode??"null"}`,`signal: ${Q.exitState.signal??"null"}`,`stderr:
|
|
598
598
|
${Q.stderr.join("").trim()||"(empty)"}`].filter((G)=>Boolean(G)).join(`
|
|
599
|
-
`)}logProcessWarnings($,J){if($s$(J.exitState.exitCode))U.warn(`[FfmpegVideo] ${$} exited with code ${J.exitState.exitCode}: ${J.stderr.join("")}`);if(J.stderr.length>0)U.info(`[FfmpegVideo] ${$} stderr: ${J.stderr.join("")}`)}}var Ds0=30000,Fs0=15000,qs0=100,ws0=1000,Ns0=60000,As0=30000,_s0=2,Ms0=5000,Rs0,Ps0;var CU$=D(()=>{QW();r$();U$();E0();L8();n();PU$();Gn();Rs0=["Recording started"];Ps0={async size($){try{return(await ea$.stat($)).size}catch(J){return U.debug(`src/features/video/FfmpegVideoProcessingBackend.ts recording file stat failed: ${J}`,J),null}}}});class Vn{ffmpegBackend;platformBackend;constructor($=new jn,J=new Zn){this.ffmpegBackend=$,this.platformBackend=J}async start($){let J=$.device;if(!J)throw new R("Device is required to start video recording.");let X=this.selectBackend(J),Q=await X.start($);return{...Q,backendHandle:{kind:"hybrid",backend:X===this.ffmpegBackend?"ffmpeg":"platform",handle:Q}}}async stop($){let J=$.backendHandle;if(!J||J.kind!=="hybrid")throw Error("Missing backend handle for hybrid video recording.");if(J.backend==="ffmpeg")return this.ffmpegBackend.stop(J.handle);return this.platformBackend.stop(J.handle)}selectBackend($){if($.platform==="ios")return this.ffmpegBackend;if($.platform==="android"){if(process.env.AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE==="1"||process.env.AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE==="true")return U.info("[VideoCapture] Android: using exec-out screenrecord \u2192 ffmpeg (AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE)"),this.ffmpegBackend}return this.platformBackend}}var Xs$=D(()=>{r$();n();CU$();RU$()});var SU$=D(()=>{_U$();_U$();RU$();CU$();Xs$()});function Ss0($){try{let J=JSON.parse($);return HK(J)}catch(J){return U.warn(`[VideoRecordingRepository] Failed to parse config JSON: ${J}`),HK(null)}}function Is0($){if(!$)return;try{let J=JSON.parse($);return Array.isArray(J)?J:void 0}catch(J){U.warn(`[VideoRecordingRepository] Failed to parse highlights JSON: ${J}`);return}}function Qs$($){return{recordingId:$.recording_id,deviceId:$.device_id,platform:$.platform,status:$.status,outputName:$.output_name??void 0,fileName:$.file_name,filePath:$.file_path,format:$.format,sizeBytes:$.size_bytes,durationMs:$.duration_ms??void 0,codec:$.codec??void 0,createdAt:$.created_at,startedAt:$.started_at,endedAt:$.ended_at??void 0,lastAccessedAt:$.last_accessed_at,config:Ss0($.config_json),highlights:Is0($.highlights_json??null),ownerSessionUuid:$.owner_session_uuid??void 0}}function Ys$($,J){if(!J)return $;return $.where((X)=>X.or([X("owner_session_uuid","is",null),X("owner_session_uuid","=",J)]))}function ks0($){let J={};if($.deviceId!==void 0)J.device_id=$.deviceId;if($.platform!==void 0)J.platform=$.platform;if($.status!==void 0)J.status=$.status;if($.outputName!==void 0)J.output_name=$.outputName??null;if($.fileName!==void 0)J.file_name=$.fileName;if($.filePath!==void 0)J.file_path=$.filePath;if($.format!==void 0)J.format=$.format;if($.sizeBytes!==void 0)J.size_bytes=$.sizeBytes;if($.durationMs!==void 0)J.duration_ms=$.durationMs??null;if($.codec!==void 0)J.codec=$.codec??null;if($.createdAt!==void 0)J.created_at=$.createdAt;if($.startedAt!==void 0)J.started_at=$.startedAt;if($.endedAt!==void 0)J.ended_at=$.endedAt??null;if($.lastAccessedAt!==void 0)J.last_accessed_at=$.lastAccessedAt;if($.config!==void 0)J.config_json=JSON.stringify($.config);if($.highlights!==void 0)J.highlights_json=JSON.stringify($.highlights??[]);if($.ownerSessionUuid!==void 0)J.owner_session_uuid=$.ownerSessionUuid??null;return J}class IU${db;constructor($){this.db=$??null}async getDb(){if(this.db)return this.db;return await AJ(),N1()}async insertRecording($){let J=await this.getDb(),X={recording_id:$.recordingId,device_id:$.deviceId,platform:$.platform,status:$.status,output_name:$.outputName??null,file_name:$.fileName,file_path:$.filePath,format:$.format,size_bytes:$.sizeBytes,duration_ms:$.durationMs??null,codec:$.codec??null,created_at:$.createdAt,started_at:$.startedAt,ended_at:$.endedAt??null,last_accessed_at:$.lastAccessedAt,config_json:JSON.stringify($.config),highlights_json:$.highlights?JSON.stringify($.highlights):null,owner_session_uuid:$.ownerSessionUuid??null};await J.insertInto("video_recordings").values(X).onConflict((Q)=>Q.column("recording_id").doUpdateSet({device_id:X.device_id,platform:X.platform,status:X.status,output_name:X.output_name,file_name:X.file_name,file_path:X.file_path,format:X.format,size_bytes:X.size_bytes,duration_ms:X.duration_ms,codec:X.codec,started_at:X.started_at,ended_at:X.ended_at,last_accessed_at:X.last_accessed_at,config_json:X.config_json,highlights_json:X.highlights_json,owner_session_uuid:X.owner_session_uuid})).execute()}async updateRecording($,J){let X=await this.getDb(),Q=ks0(J);if(Object.keys(Q).length===0)return;await X.updateTable("video_recordings").set(Q).where("recording_id","=",$).execute()}async getRecording($,J={}){let Q=(await this.getDb()).selectFrom("video_recordings").selectAll().where("recording_id","=",$);Q=Ys$(Q,J.ownerSessionUuid);let Y=await Q.executeTakeFirst();return Y?Qs$(Y):null}async listRecordings($={}){let X=(await this.getDb()).selectFrom("video_recordings").selectAll();if(X=Ys$(X,$.ownerSessionUuid),$.status!==void 0){let Y=Array.isArray($.status)?$.status:[$.status];X=X.where("status","in",Y)}if($.deviceId)X=X.where("device_id","=",$.deviceId);if($.platform)X=X.where("platform","=",$.platform);if($.orderByLastAccessed)X=X.orderBy("last_accessed_at",$.orderByLastAccessed);if($.limit&&$.limit>0)X=X.limit($.limit);return(await X.execute()).map(Qs$)}async getLatestRecording(){return(await this.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"desc",limit:1}))[0]??null}async touchRecording($,J){await this.updateRecording($,{lastAccessedAt:J})}async deleteRecording($){let X=await(await this.getDb()).deleteFrom("video_recordings").where("recording_id","=",$).executeTakeFirst();return Number(X.numDeletedRows??0)>0}}var Ws$=D(()=>{r6();SU$();n()});function cS($){return`automobile:video/archive/${$}`}var ZX;var kU$=D(()=>{ZX={LATEST:"automobile:video/latest",ARCHIVE:"automobile:video/archive",ARCHIVE_ITEM:"automobile:video/archive/{recordingId}"}});class Gs${device;adbFactory;highlightClient;constructor($,J=j$,X){if(this.device=$,$.platform==="ios")this.adbFactory=j$;else if(J&&typeof J.create==="function")this.adbFactory=J;else if(J){let Q=J;this.adbFactory={create:()=>Q}}else this.adbFactory=j$;this.highlightClient=X||this.createDefaultHighlightClient($)}async addHighlight($,J,X={}){let Q=this.parseHighlightId($),Y=this.parseHighlightShape(J),W=X.timeoutMs??xs0,G=await this.highlightClient.requestAddHighlight(Q,Y,W,new E$);return this.parseHighlightResponse(G)}parseHighlightId($){let J=N.string().min(1,"Highlight id must be a non-empty string").safeParse($);if(!J.success)throw new R(J.error.issues.map((X)=>X.message).join("; "));return J.data}parseHighlightShape($){let J=dS.safeParse($);if(!J.success){let X=J.error.issues.map((Q)=>Q.message).join("; ");throw new R(X)}return J.data}parseHighlightResponse($){let J=gs0.safeParse($);if(!J.success){let X=J.error.issues.map((Q)=>Q.message).join("; ");throw new R(`Invalid highlight response: ${X}`)}return J.data}createDefaultHighlightClient($){if($.platform==="android")return P$.getInstance($,this.adbFactory);if($.platform==="ios")return M$.getInstance($);throw new R(`Visual highlights are not supported on ${$.platform} devices.`)}}class nS{deviceSessionManager;visualHighlightFactory;constructor($=m6.getInstance(),J=(X)=>new Gs$(X)){this.deviceSessionManager=$,this.visualHighlightFactory=J}async addHighlight($,J,X){let Y=await(await this.resolveHighlight(X)).addHighlight($,J,{timeoutMs:X.timeoutMs});if(!Y.success)throw new R(Y.error||"Failed to add highlight");return Y}async resolveHighlight($){if($.device){if($.device.platform!==$.platform)throw new R(`Highlight platform mismatch: requested ${$.platform}, device is ${$.device.platform}.`);return this.visualHighlightFactory($.device)}if($.platform!=="android"&&$.platform!=="ios")throw new R(`Visual highlights are not supported on ${$.platform} devices.`);let J=await this.deviceSessionManager.ensureDeviceReady($.platform,$.deviceId);return this.visualHighlightFactory(J)}}var xs0=5000,Kn=($)=>$===null?void 0:$,bs0=($)=>$===null?void 0:$,xU$,bU$,ys0,fs0,vs0,hs0,dS,gs0;var Un=D(()=>{g4();E0();iG();M0();U4();J4();r$();xU$=N.object({x:N.number().int(),y:N.number().int(),width:N.number().int().positive("bounds.width must be a positive integer"),height:N.number().int().positive("bounds.height must be a positive integer"),sourceWidth:N.number().int().positive().nullable().optional(),sourceHeight:N.number().int().positive().nullable().optional()}).superRefine(($,J)=>{let X=Kn($.sourceWidth),Q=Kn($.sourceHeight);if(X!==void 0!==(Q!==void 0))J.addIssue({code:N.ZodIssueCode.custom,message:"bounds.sourceWidth and bounds.sourceHeight must be provided together"})}),bU$=N.object({strokeColor:N.string().min(1).nullable().optional(),strokeWidth:N.number().positive().nullable().optional(),dashPattern:N.array(N.number().positive()).nonempty().nullable().optional(),smoothing:N.enum(["none","catmull-rom","bezier","douglas-peucker"]).nullable().optional(),tension:N.number().min(0).max(1).nullable().optional(),capStyle:N.enum(["butt","round","square"]).nullable().optional(),joinStyle:N.enum(["miter","round","bevel"]).nullable().optional()}).superRefine(($,J)=>{let X=bs0($.strokeColor),Q=Kn($.strokeWidth),Y=$.dashPattern??void 0,W=$.smoothing??void 0,G=Kn($.tension),Z=$.capStyle??void 0,j=$.joinStyle??void 0;if(!(X!==void 0||Q!==void 0||Y!==void 0||W!==void 0||G!==void 0||Z!==void 0||j!==void 0))J.addIssue({code:N.ZodIssueCode.custom,message:"Highlight style must include stroke settings"})}),ys0=N.object({x:N.number(),y:N.number()}),fs0=N.object({type:N.literal("box"),bounds:xU$,style:bU$.nullable().optional()}),vs0=N.object({type:N.literal("circle"),bounds:xU$,style:bU$.nullable().optional()}),hs0=N.object({type:N.literal("path"),points:N.array(ys0).min(2),bounds:xU$.nullable().optional(),style:bU$.nullable().optional()}),dS=N.discriminatedUnion("type",[fs0,vs0,hs0]),gs0=N.object({success:N.boolean(),error:N.string().nullable().optional(),requestId:N.string().optional(),timestamp:N.number().optional()}).passthrough()});import{promises as Ks$}from"fs";import us0 from"path";function yU$($,J,X){if($===void 0||$.trim()==="")return J;let Q=Number($);if(!Number.isFinite(Q)||Q<0||!X&&Q===0)return U.warn(`[VideoRecording] Ignoring invalid retention env value "${$}"; using ${J}`),J;return Q}function rs0($=process.env){let J=yU$($.AUTOMOBILE_VIDEO_RETENTION_DAYS??$.AUTO_MOBILE_VIDEO_RETENTION_DAYS,ns0,!0),X=yU$($.AUTOMOBILE_VIDEO_RETENTION_SWEEP_MINUTES??$.AUTO_MOBILE_VIDEO_RETENTION_SWEEP_MINUTES,is0,!1),Q=yU$($.AUTOMOBILE_VIDEO_INPROGRESS_CHECK_SECONDS??$.AUTO_MOBILE_VIDEO_INPROGRESS_CHECK_SECONDS,os0,!1);return{ttlMs:Math.max(0,Math.floor(J*ds0)),sweepIntervalMs:Math.max(1000,Math.floor(X*60000)),inProgressCheckIntervalMs:Math.max(1000,Math.floor(Q*1000))}}async function ts0(){return U.debug("[VideoRecording] Using HybridVideoCaptureBackend (iOS FFmpeg, Android platform)"),new Vn}async function as0(){let $=await ts0();return new Yn({backend:$})}async function ss0($){if(Zs$)return;Zs$=!0,Xe0($);let J=await $.recordingRepository.listRecordings({status:"recording"});if(J.length===0)return;let X=$.now().toISOString();for(let Q of J){let Y=await pU$(Q.filePath),W=Fs$(Q.startedAt,X);await $.recordingRepository.updateRecording(Q.recordingId,{status:"interrupted",endedAt:X,lastAccessedAt:X,sizeBytes:Y,durationMs:W})}U.info(`[VideoRecording] Marked ${J.length} recording(s) as interrupted after restart`)}async function tJ(){if(!zn)zn={videoRecorderService:await as0(),recordingRepository:new IU$,configRepository:ol(),highlightClient:new nS,timer:g,now:()=>new Date,retentionPolicy:rs0(),statFileSize:pU$};return await ss0(zn),zn}function Us$($,J){return{qualityPreset:J.qualityPreset??$.qualityPreset,targetBitrateKbps:J.targetBitrateKbps??$.targetBitrateKbps,maxThroughputMbps:J.maxThroughputMbps??$.maxThroughputMbps,fps:J.fps??$.fps,maxArchiveSizeMb:J.maxArchiveSizeMb??$.maxArchiveSizeMb,format:J.format??$.format,resolution:J.resolution??$.resolution}}function zs$($){return{qualityPreset:$.qualityPreset,targetBitrateKbps:$.targetBitrateKbps,maxThroughputMbps:$.maxThroughputMbps,fps:$.fps,maxArchiveSizeMb:$.maxArchiveSizeMb,format:$.format,resolution:$.resolution}}function es0($,J){if($===void 0)return ms0;if(!Number.isFinite($)||$<=0)throw new R("maxDuration must be a positive number of seconds.");let X=J==="ios"?gU$:ls0;if($>X)throw new R(`maxDuration must be <= ${X} seconds.`);return Math.round($)}async function $e0($){if($)return $;let{recordingRepository:J}=await tJ(),X=await J.listRecordings({status:"recording"});if(X.length===0)throw new R("No active video recording found. Provide recordingId.");if(X.length>1)throw new R("Multiple active video recordings found. Provide recordingId.");return X[0].recordingId}async function Je0($,J){if(!Number.isFinite(J)||J<=0)return;let{timer:X}=await tJ(),Q=Math.max(1,Math.round(J*1000)),Y=X.setTimeout(()=>{XQ($).catch((W)=>{U.warn(`[VideoRecording] Failed to auto-stop recording ${$}: ${W}`)})},Q);fU$.set($,{timer:X,handle:Y})}function Ls$($){let J=fU$.get($);if(J)J.timer.clearTimeout(J.handle),fU$.delete($)}function Xe0($){if(js$)return;let{retentionPolicy:J,timer:X}=$;if(J.ttlMs<=0)return;let Q=X.setInterval(()=>{Qe0().catch((Y)=>{U.warn(`[VideoRecording] TTL retention sweep failed: ${Y}`)})},J.sweepIntervalMs);js$={timer:X,handle:Q}}async function Qe0(){let $=await tJ(),{recordingRepository:J,retentionPolicy:X,now:Q}=$;if(X.ttlMs<=0)return[];let Y=Q().getTime()-X.ttlMs,W=await J.listRecordings({status:["completed","interrupted"]}),G=[];for(let Z of W){let j=Date.parse(Z.createdAt);if(Number.isNaN(j)||j>Y)continue;try{if(await Rs$(Z.recordingId))G.push(Z.recordingId)}catch(V){U.warn(`[VideoRecording] Failed to prune expired recording ${Z.recordingId}: ${V}`)}}if(G.length>0)U.info(`[VideoRecording] TTL sweep pruned ${G.length} recording(s) older than ${X.ttlMs} ms`);return G}function Ye0($,J,X,Q){if(!Number.isFinite(X)||X<=0)return;let{timer:Y,retentionPolicy:W}=Q,G=Y.setInterval(()=>{We0($,J,X).catch((Z)=>{U.warn(`[VideoRecording] In-progress size check failed for ${$}: ${Z}`)})},W.inProgressCheckIntervalMs);Hn.set($,{timer:Y,handle:G})}function mU$($){let J=Hn.get($);if(J)J.timer.clearInterval(J.handle),Hn.delete($)}async function We0($,J,X){if(!Hn.has($))return;let{statFileSize:Q}=await tJ(),Y=await Q(J);if(Y<X)return;U.warn(`[VideoRecording] In-progress recording ${$} reached size cap (${Y} >= ${X} bytes); stopping to protect disk.`),mU$($),await XQ($)}function Ge0($){let J=uU$.get($);if(!J)return null;return Ln.get(J)??null}function Hs$($,J){if(!Number.isFinite(J))return 0;return Math.max(0,Math.round(J-$.startedAtMs))}function Vs$($){let J=Math.max(0,Math.round($));return Number((J/1000).toFixed(3))}function Os$($,J,X){let Q=Hs$($,X);$.highlights.push({description:J.description,shape:J.shape,appearedAtMs:Q,disappearedAtMs:Q+Ze0($.platform)})}function Ze0($){return $==="ios"?cs0:ps0}function lU$($=g){return df("highlight",$)}function Bs$($,J){if($.highlights.length===0)return;let X=Date.parse(J),Q=Hs$($,X);return $.highlights.map((Y)=>{let W=Math.min(Y.disappearedAtMs,Q);return{description:Y.description,shape:Y.shape,timeline:{appearedAtSeconds:Vs$(Y.appearedAtMs),disappearedAtSeconds:Vs$(W)}}}).sort((Y,W)=>Y.timeline.appearedAtSeconds-W.timeline.appearedAtSeconds)}function je0($,J,X,Q){let Y=Date.parse(X);return{recordingId:$,deviceId:J.deviceId,platform:J.platform,startedAtMs:Number.isNaN(Y)?Q.now():Y,highlights:[],timer:Q,timers:new Set}}function vU$($){let J=Ln.get($);if(!J)return null;for(let X of J.timers)J.timer.clearTimeout(X);return J.timers.clear(),Ln.delete($),uU$.delete(J.deviceId),J}function Ds$($){let J=$.timing?.startTimeMs??0;if(!Number.isFinite(J)||J<0)throw new R("highlight.timing.startTimeMs must be >= 0.");return{startMs:J}}async function Ve0($,J,X,Q){let Y={device:J,deviceId:J.deviceId,platform:J.platform},W=[],G=(j,V)=>{let K=Math.max(0,Math.round(j));if(K===0){W.push(V());return}let z=$.timer.setTimeout(()=>{V()},K);$.timers.add(z)},Z=async(j)=>{try{let V=lU$();await Q.highlightClient.addHighlight(V,j.shape,Y),Os$($,j,Q.now().getTime())}catch(V){U.warn(`[VideoRecording] Failed to add highlight: ${V}`)}};for(let j of X){let{startMs:V}=Ds$(j);G(V,()=>Z(j))}if(W.length>0)await Promise.all(W)}async function Ke0($){let{configRepository:J}=await tJ(),X=await J.getConfig(),Q=X?zs$(X):b$.getVideoRecordingDefaults();return Us$(Q,$)}async function pU$($){try{return(await Ks$.stat($)).size}catch{return U.warn(`[VideoRecording] Missing recording file at ${Wv($)}`),0}}function Fs$($,J){let X=Date.parse($),Q=Date.parse(J);if(Number.isNaN(X)||Number.isNaN(Q))return;return Math.max(0,Q-X)}function cU$($){return{recordingId:$.recordingId,fileName:$.fileName,filePath:$.filePath,format:$.format,sizeBytes:$.sizeBytes,durationMs:$.durationMs,codec:$.codec,outputName:$.outputName,createdAt:$.createdAt,startedAt:$.startedAt,endedAt:$.endedAt,lastAccessedAt:$.lastAccessedAt,config:$.config,highlights:$.highlights}}async function dU$($){let J=new Set([ZX.LATEST,ZX.ARCHIVE]);for(let X of $)J.add(cS(X));await h$.notifyResourcesUpdated(Array.from(J))}async function nU$(){let{configRepository:$}=await tJ(),J=await $.getConfig();if(J)return J;return HK(b$.getVideoRecordingDefaults())}async function qs$($){let{configRepository:J}=await tJ();if($===null){await J.clearConfig();let G=HK(b$.getVideoRecordingDefaults()),Z=await hU$(G.maxArchiveSizeMb);return{config:G,evictedRecordingIds:Z.evictedRecordingIds}}let X=await nU$(),Q=Us$(zs$(X),$),Y=HK(Q);await J.setConfig(Y);let W=await hU$(Y.maxArchiveSizeMb);return{config:Y,evictedRecordingIds:W.evictedRecordingIds}}async function zN($){let J=await tJ(),{videoRecorderService:X,recordingRepository:Q,timer:Y}=J;if((await Q.listRecordings({status:"recording",deviceId:$.device.deviceId})).length>0)throw new R(`Video recording already active for device ${$.device.deviceId}.`);let G=$.configOverrides??{},Z=await Ke0(G),j=es0($.maxDurationSeconds,$.device.platform),V=$.highlights??[];for(let H of V)Ds$(H);let K=await X.startRecording({outputName:$.outputName,config:Z,device:$.device,maxDurationSeconds:j});await Q.insertRecording({recordingId:K.recordingId,deviceId:$.device.deviceId,platform:$.device.platform,status:"recording",outputName:K.outputName,fileName:K.fileName,filePath:K.outputPath,format:K.config.format,sizeBytes:0,durationMs:void 0,codec:void 0,createdAt:K.startedAt,startedAt:K.startedAt,endedAt:void 0,lastAccessedAt:K.startedAt,config:K.config,ownerSessionUuid:$.ownerSessionUuid});let z=je0(K.recordingId,$.device,K.startedAt,Y);if(Ln.set(K.recordingId,z),uU$.set($.device.deviceId,K.recordingId),V.length>0)await Ve0(z,$.device,V,J);await Je0(K.recordingId,j);let L=Math.floor((K.config.maxArchiveSizeMb??0)*1024*1024);return Ye0(K.recordingId,K.outputPath,L,J),K}async function XQ($){let{videoRecorderService:J,recordingRepository:X,now:Q}=await tJ(),Y=await $e0($);Ls$(Y),mU$(Y);let W=await J.stopRecording(Y),G=vU$(Y);if(G){let j=Bs$(G,W.endedAt??Q().toISOString());if(j)W.highlights=j}await X.updateRecording(Y,{status:"completed",outputName:W.outputName,fileName:W.fileName,filePath:W.filePath,format:W.format,sizeBytes:W.sizeBytes,durationMs:W.durationMs,codec:W.codec,endedAt:W.endedAt,lastAccessedAt:W.lastAccessedAt,config:W.config,highlights:W.highlights});let Z=await hU$(W.config.maxArchiveSizeMb);return await dU$([W.recordingId]),{metadata:W,evictedRecordingIds:Z.evictedRecordingIds}}async function ws$($){let{recordingRepository:J,now:X}=await tJ();Ls$($),mU$($);let Q=await J.getRecording($);if(!Q||Q.status!=="recording"){vU$($);return}let Y=X().toISOString(),W=vU$($),G=W?Bs$(W,Y):Q.highlights;await J.updateRecording($,{status:"interrupted",endedAt:Y,lastAccessedAt:Y,sizeBytes:await pU$(Q.filePath),durationMs:Fs$(Q.startedAt,Y),highlights:G}),await dU$([$])}async function Ns$($,J){let X=Ge0($.deviceId);if(!X)return;let{now:Q}=await tJ();Os$(X,J,Q().getTime())}async function ZO($={}){let{recordingRepository:J}=await tJ();return J.listRecordings({status:"recording",deviceId:$.deviceId,platform:$.platform})}async function As$($={}){let{recordingRepository:J}=await tJ();return(await J.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"desc",ownerSessionUuid:$.ownerSessionUuid})).map(cU$)}async function _s$($,J){let{recordingRepository:X,now:Q}=await tJ(),Y=await X.getRecording($,{ownerSessionUuid:J?.ownerSessionUuid});if(!Y||Y.status==="recording")return null;let W=cU$(Y);if(J?.touch!==!1){let G=Q().toISOString();await X.touchRecording($,G),W.lastAccessedAt=G}return W}async function Ms$($={}){let{recordingRepository:J}=await tJ(),X=await J.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"desc",limit:1,ownerSessionUuid:$.ownerSessionUuid});return X[0]?cU$(X[0]):null}async function Rs$($){let{recordingRepository:J}=await tJ(),X=await J.getRecording($);if(!X)return!1;if(X.status==="recording")throw Error(`Cannot delete active recording ${$}`);let Q=us0.dirname(X.filePath);if(await n9(Q))await Ks$.rm(Q,{recursive:!0,force:!0});let Y=await J.deleteRecording($);if(Y)await dU$([$]);return Y}async function hU$($){let J=Math.max(0,Math.floor($*1024*1024)),{recordingRepository:X}=await tJ(),Q=await X.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"asc"}),Y=Q.reduce((G,Z)=>G+(Z.sizeBytes??0),0);if(J===0||Y<=J)return{evictedRecordingIds:[],currentSizeBytes:Y,maxSizeBytes:J};let W=[];for(let G of Q){if(Y<=J)break;try{if(await Rs$(G.recordingId))W.push(G.recordingId),Y-=G.sizeBytes??0}catch(Z){U.warn(`[VideoRecording] Failed to evict recording ${G.recordingId}: ${Z}`)}}if(Y>J)U.warn(`[VideoRecording] Archive size ${Y} bytes still exceeds limit ${J} bytes after eviction`);return{evictedRecordingIds:W,currentSizeBytes:Y,maxSizeBytes:J}}var ms0=30,ls0=300,gU$=3600,ps0=6000,cs0=3000,ds0=86400000,ns0=7,is0=60,os0=15,zn=null,Zs$=!1,fU$,Ln,uU$,Hn,js$=null;var OK=D(()=>{QW();r$();SU$();p4();n();d4$();U$();F5();q8();Ws$();zT();kU$();Un();fU$=new Map,Ln=new Map,uU$=new Map,Hn=new Map});class Ps${dependencies;constructor($){this.dependencies=$}async ensureReady($){let J=Math.min($.totalDeadlineMs,this.dependencies.timer.now()+$.readinessTimeoutMs),X={...$,readinessDeadlineMs:J},Q=`${$.device.platform}:${$.device.deviceId}`,Y=await this.acquireReadinessTurn(X,Q);try{await this.ensureReadyUncoordinated(X)}finally{Y()}}async ensureReadyUncoordinated($){if($.device.platform==="android"){await this.ensureAndroidReady($);return}await this.ensureIosReady($)}async acquireReadinessTurn($,J){if(this.remaining($)<=0)this.fail($,"runner-setup",1,"readiness budget exhausted before setup lock");let X=On.get(J)??{locked:!1,waiters:[]};if(On.set(J,X),!X.locked)return X.locked=!0,this.createReadinessRelease(J,X);try{return await new Promise((Q,Y)=>{let W={active:!0,resolve:Q,reject:Y,timer:this.dependencies.timer,signal:$.signal},G=(Z)=>{if(!W.active)return;W.active=!1,this.removeReadinessWaiter(X,W),this.cleanupReadinessWaiter(W),Y(Z)};if(W.timeoutHandle=this.dependencies.timer.setTimeout(()=>G(Error("readiness setup lock exceeded this request's deadline")),this.remaining($)),W.abortListener=()=>G($.signal?.reason),$.signal?.addEventListener("abort",W.abortListener,{once:!0}),X.waiters.push(W),$.signal?.aborted)W.abortListener()})}catch(Q){this.fail($,"runner-setup",1,iU$(Q))}}createReadinessRelease($,J){let X=!1;return()=>{if(X)return;X=!0;let Q=J.waiters.shift();while(Q&&!Q.active)Q=J.waiters.shift();if(Q){Q.active=!1,this.cleanupReadinessWaiter(Q),Q.resolve(this.createReadinessRelease($,J));return}if(J.locked=!1,On.get($)===J)On.delete($)}}removeReadinessWaiter($,J){let X=$.waiters.indexOf(J);if(X>=0)$.waiters.splice(X,1)}cleanupReadinessWaiter($){if($.timeoutHandle)$.timer.clearTimeout($.timeoutHandle);if($.abortListener)$.signal?.removeEventListener("abort",$.abortListener)}async ensureAndroidReady($){let J=this.dependencies.getAndroidManager($.device),X=this.dependencies.getAndroidClient($.device);if($.skipCtrlProxyDownload){await this.ensureAndroidReadyWithoutDownloads($,J,X);return}let Q=await this.runPhase($,"package-compatibility",1,(G)=>J.ensureCompatibleVersion({allowDownloadWhenInstalled:!0,bypassVersionCheckCache:!1},G));this.assertAndroidCompatibility($,Q);let[Y,W]=await this.runPhase($,"runner-setup",1,(G)=>Promise.all([J.isInstalled(G),J.isEnabled(G)]));if(await this.isResponsiveFastPath($,X,Y&&W))return;if(Y&&W)J.resetSetupState();await this.setupAndroidRunner($,J),await this.waitForResponsiveClient($,X)}async ensureAndroidReadyWithoutDownloads($,J,X){let[Q,Y]=await this.runPhase($,"runner-setup",1,(G)=>Promise.all([J.isInstalled(G),J.isEnabled(G)]));if(!Q)this.fail($,"runner-setup",1,"CtrlProxy is not installed and runner downloads are disabled");if(!await this.runPhase($,"package-compatibility",1,()=>J.isVersionCompatible()))this.fail($,"package-compatibility",1,"CtrlProxy version mismatch; run without skipCtrlProxyDownload to install a compatible version");if(await this.isResponsiveFastPath($,X,Y))return;if(!Y)await this.runPhase($,"runner-setup",1,()=>J.enable());await this.waitForResponsiveClient($,X)}assertAndroidCompatibility($,J){if(!(J.status==="failed"||J.status==="skipped"||J.acceptedPreinstalled===!0))return;let Q=[J.error,J.upgradeError,J.reinstallError,J.acceptedPreinstalled?"installed package compatibility was not verified":void 0,J.status==="skipped"?"package compatibility check was skipped":void 0].filter((Y)=>Boolean(Y));this.fail($,"package-compatibility",1,Q.join("; "))}async isResponsiveFastPath($,J,X){if(!X||!J.isConnected())return!1;return this.runPhase($,"runner-health",1,()=>J.verifyServiceReady(1,0,this.probeTimeout($)))}async setupAndroidRunner($,J){let X=await this.runPhase($,"runner-setup",1,(W)=>J.setup(!1,$.perf,W));if(!X.success)this.fail($,"runner-setup",1,X.error??X.message);let[Q,Y]=await this.runPhase($,"runner-setup",1,(W)=>Promise.all([J.isInstalled(W),J.isEnabled(W)]));if(!Q||!Y)this.fail($,"runner-setup",1,`CtrlProxy state after setup: installed=${Q}, enabled=${Y}`)}async ensureIosReady($){let J=await this.runPhase($,"runner-setup",1,()=>this.dependencies.checkIosOverride());if(J.present&&!J.usable)this.fail($,"runner-setup",1,`AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH / _IPA_PATH is set but unusable: ${J.reason??"unknown reason"}`);await this.runPhase($,"runner-setup",1,()=>this.dependencies.awaitIosStartupMaintenance());let X=this.dependencies.getIosManager($.device),Q=this.dependencies.getIosClient($.device,X.getServicePort());if(Q.isConnected()){if(await this.runPhase($,"runner-health",1,()=>Q.verifyServiceReady(1,0,this.probeTimeout($))))return}if($.skipCtrlProxyDownload){await this.ensureIosReadyWithoutDownloads($,X,Q);return}let Y=await this.runPhase($,"runner-setup",1,(W)=>X.setup(!1,$.perf,W));if(!Y.success)this.fail($,"runner-setup",1,Y.error??Y.message);await this.waitForResponsiveClient($,Q)}async ensureIosReadyWithoutDownloads($,J,X){if(!await this.runPhase($,"runner-setup",1,()=>J.isInstalled()))this.fail($,"runner-setup",1,"CtrlProxy iOS runner is not installed and runner downloads are disabled");await this.runPhase($,"runner-setup",1,()=>J.start()),await this.waitForResponsiveClient($,X)}async waitForResponsiveClient($,J){let X=0,Q=J.isConnected(),Y=Q?"runner-health":"runner-connect";while(this.remaining($)>0){if(X++,Q=J.isConnected(),!Q)Y="runner-connect",Q=await this.runPhase($,Y,X,()=>J.waitForConnection(1,0));if(Q){if(Y="runner-health",await this.runPhase($,Y,X,()=>J.verifyServiceReady(1,0,this.probeTimeout($))))return}let W=this.remaining($);if(W>0)await this.dependencies.timer.sleep(Math.min(Ue0,W))}this.fail($,Y,X,"runner did not become responsive before the readiness deadline")}async runPhase($,J,X,Q){if(this.remaining($)<=0)this.fail($,J,X,"readiness budget exhausted before phase started");let Y=this.remaining($),W=new AbortController,G=$.signal?AbortSignal.any([$.signal,W.signal]):W.signal,Z,j=uB(G,()=>Q(G));j.catch(()=>{});try{return await Promise.race([j,new Promise((V,K)=>{Z=this.dependencies.timer.setTimeout(()=>{W.abort(Error("readiness phase exceeded the remaining deadline")),K(Error("readiness phase exceeded the remaining deadline"))},Y)})])}catch(V){if(W.signal.aborted)await this.awaitAbortSettlement(j);return this.fail($,J,X,iU$(V))}finally{if(Z)this.dependencies.timer.clearTimeout(Z)}}async awaitAbortSettlement($){let J;try{await Promise.race([$.then(()=>{return},()=>{return}),new Promise((X)=>{J=this.dependencies.timer.setTimeout(X,Le0)})])}finally{if(J)this.dependencies.timer.clearTimeout(J)}}probeTimeout($){return Math.max(1,Math.min(ze0,this.remaining($)))}remaining($){return Math.max(0,$.readinessDeadlineMs-this.dependencies.timer.now())}fail($,J,X,Q){let{device:Y}=$,W=`platform=${Y.platform} requested=[${$.requestedIdentity}] resolved=[${Y.name} (${Y.deviceId})]`;throw new R(`startDevice automation runner readiness failed: ${W} phase=${J} attempts=${X} remainingBudgetMs=${this.remaining($)}: ${iU$(Q)}`)}}function iU$($){let J=$ instanceof Error?$.message:String($),X=yQ(J);if(X.length<=Es$)return X;let Q=Math.floor((Es$-32)/2);return`${X.slice(0,Q)}
|
|
599
|
+
`)}logProcessWarnings($,J){if($s$(J.exitState.exitCode))U.warn(`[FfmpegVideo] ${$} exited with code ${J.exitState.exitCode}: ${J.stderr.join("")}`);if(J.stderr.length>0)U.info(`[FfmpegVideo] ${$} stderr: ${J.stderr.join("")}`)}}var Ds0=30000,Fs0=15000,qs0=100,ws0=1000,Ns0=60000,As0=30000,_s0=2,Ms0=5000,Rs0,Ps0;var CU$=D(()=>{QW();r$();U$();E0();L8();n();PU$();Gn();Rs0=["Recording started"];Ps0={async size($){try{return(await ea$.stat($)).size}catch(J){return U.debug(`src/features/video/FfmpegVideoProcessingBackend.ts recording file stat failed: ${J}`,J),null}}}});class Vn{ffmpegBackend;platformBackend;constructor($=new jn,J=new Zn){this.ffmpegBackend=$,this.platformBackend=J}async start($){let J=$.device;if(!J)throw new R("Device is required to start video recording.");let X=this.selectBackend(J),Q=await X.start($);return{...Q,backendHandle:{kind:"hybrid",backend:X===this.ffmpegBackend?"ffmpeg":"platform",handle:Q}}}async stop($){let J=$.backendHandle;if(!J||J.kind!=="hybrid")throw Error("Missing backend handle for hybrid video recording.");if(J.backend==="ffmpeg")return this.ffmpegBackend.stop(J.handle);return this.platformBackend.stop(J.handle)}selectBackend($){if($.platform==="ios")return this.ffmpegBackend;if($.platform==="android"){if(process.env.AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE==="1"||process.env.AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE==="true")return U.info("[VideoCapture] Android: using exec-out screenrecord \u2192 ffmpeg (AUTOMOBILE_ANDROID_VIDEO_USE_FFMPEG_PIPE)"),this.ffmpegBackend}return this.platformBackend}}var Xs$=D(()=>{r$();n();CU$();RU$()});var SU$=D(()=>{_U$();_U$();RU$();CU$();Xs$()});function Ss0($){try{let J=JSON.parse($);return HK(J)}catch(J){return U.warn(`[VideoRecordingRepository] Failed to parse config JSON: ${J}`),HK(null)}}function Is0($){if(!$)return;try{let J=JSON.parse($);return Array.isArray(J)?J:void 0}catch(J){U.warn(`[VideoRecordingRepository] Failed to parse highlights JSON: ${J}`);return}}function Qs$($){return{recordingId:$.recording_id,deviceId:$.device_id,platform:$.platform,status:$.status,outputName:$.output_name??void 0,fileName:$.file_name,filePath:$.file_path,format:$.format,sizeBytes:$.size_bytes,durationMs:$.duration_ms??void 0,codec:$.codec??void 0,createdAt:$.created_at,startedAt:$.started_at,endedAt:$.ended_at??void 0,lastAccessedAt:$.last_accessed_at,config:Ss0($.config_json),highlights:Is0($.highlights_json??null),ownerSessionUuid:$.owner_session_uuid??void 0}}function Ys$($,J){if(!J)return $;return $.where((X)=>X.or([X("owner_session_uuid","is",null),X("owner_session_uuid","=",J)]))}function ks0($){let J={};if($.deviceId!==void 0)J.device_id=$.deviceId;if($.platform!==void 0)J.platform=$.platform;if($.status!==void 0)J.status=$.status;if($.outputName!==void 0)J.output_name=$.outputName??null;if($.fileName!==void 0)J.file_name=$.fileName;if($.filePath!==void 0)J.file_path=$.filePath;if($.format!==void 0)J.format=$.format;if($.sizeBytes!==void 0)J.size_bytes=$.sizeBytes;if($.durationMs!==void 0)J.duration_ms=$.durationMs??null;if($.codec!==void 0)J.codec=$.codec??null;if($.createdAt!==void 0)J.created_at=$.createdAt;if($.startedAt!==void 0)J.started_at=$.startedAt;if($.endedAt!==void 0)J.ended_at=$.endedAt??null;if($.lastAccessedAt!==void 0)J.last_accessed_at=$.lastAccessedAt;if($.config!==void 0)J.config_json=JSON.stringify($.config);if($.highlights!==void 0)J.highlights_json=JSON.stringify($.highlights??[]);if($.ownerSessionUuid!==void 0)J.owner_session_uuid=$.ownerSessionUuid??null;return J}class IU${db;constructor($){this.db=$??null}async getDb(){if(this.db)return this.db;return await AJ(),N1()}async insertRecording($){let J=await this.getDb(),X={recording_id:$.recordingId,device_id:$.deviceId,platform:$.platform,status:$.status,output_name:$.outputName??null,file_name:$.fileName,file_path:$.filePath,format:$.format,size_bytes:$.sizeBytes,duration_ms:$.durationMs??null,codec:$.codec??null,created_at:$.createdAt,started_at:$.startedAt,ended_at:$.endedAt??null,last_accessed_at:$.lastAccessedAt,config_json:JSON.stringify($.config),highlights_json:$.highlights?JSON.stringify($.highlights):null,owner_session_uuid:$.ownerSessionUuid??null};await J.insertInto("video_recordings").values(X).onConflict((Q)=>Q.column("recording_id").doUpdateSet({device_id:X.device_id,platform:X.platform,status:X.status,output_name:X.output_name,file_name:X.file_name,file_path:X.file_path,format:X.format,size_bytes:X.size_bytes,duration_ms:X.duration_ms,codec:X.codec,started_at:X.started_at,ended_at:X.ended_at,last_accessed_at:X.last_accessed_at,config_json:X.config_json,highlights_json:X.highlights_json,owner_session_uuid:X.owner_session_uuid})).execute()}async updateRecording($,J){let X=await this.getDb(),Q=ks0(J);if(Object.keys(Q).length===0)return;await X.updateTable("video_recordings").set(Q).where("recording_id","=",$).execute()}async getRecording($,J={}){let Q=(await this.getDb()).selectFrom("video_recordings").selectAll().where("recording_id","=",$);Q=Ys$(Q,J.ownerSessionUuid);let Y=await Q.executeTakeFirst();return Y?Qs$(Y):null}async listRecordings($={}){let X=(await this.getDb()).selectFrom("video_recordings").selectAll();if(X=Ys$(X,$.ownerSessionUuid),$.status!==void 0){let Y=Array.isArray($.status)?$.status:[$.status];X=X.where("status","in",Y)}if($.deviceId)X=X.where("device_id","=",$.deviceId);if($.platform)X=X.where("platform","=",$.platform);if($.orderByLastAccessed)X=X.orderBy("last_accessed_at",$.orderByLastAccessed);if($.limit&&$.limit>0)X=X.limit($.limit);return(await X.execute()).map(Qs$)}async getLatestRecording(){return(await this.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"desc",limit:1}))[0]??null}async touchRecording($,J){await this.updateRecording($,{lastAccessedAt:J})}async deleteRecording($){let X=await(await this.getDb()).deleteFrom("video_recordings").where("recording_id","=",$).executeTakeFirst();return Number(X.numDeletedRows??0)>0}}var Ws$=D(()=>{r6();SU$();n()});function cS($){return`automobile:video/archive/${$}`}var ZX;var kU$=D(()=>{ZX={LATEST:"automobile:video/latest",ARCHIVE:"automobile:video/archive",ARCHIVE_ITEM:"automobile:video/archive/{recordingId}"}});class Gs${device;adbFactory;highlightClient;constructor($,J=j$,X){if(this.device=$,$.platform==="ios")this.adbFactory=j$;else if(J&&typeof J.create==="function")this.adbFactory=J;else if(J){let Q=J;this.adbFactory={create:()=>Q}}else this.adbFactory=j$;this.highlightClient=X||this.createDefaultHighlightClient($)}async addHighlight($,J,X={}){let Q=this.parseHighlightId($),Y=this.parseHighlightShape(J),W=X.timeoutMs??xs0,G=await this.highlightClient.requestAddHighlight(Q,Y,W,new E$);return this.parseHighlightResponse(G)}parseHighlightId($){let J=N.string().min(1,"Highlight id must be a non-empty string").safeParse($);if(!J.success)throw new R(J.error.issues.map((X)=>X.message).join("; "));return J.data}parseHighlightShape($){let J=dS.safeParse($);if(!J.success){let X=J.error.issues.map((Q)=>Q.message).join("; ");throw new R(X)}return J.data}parseHighlightResponse($){let J=gs0.safeParse($);if(!J.success){let X=J.error.issues.map((Q)=>Q.message).join("; ");throw new R(`Invalid highlight response: ${X}`)}return J.data}createDefaultHighlightClient($){if($.platform==="android")return P$.getInstance($,this.adbFactory);if($.platform==="ios")return M$.getInstance($);throw new R(`Visual highlights are not supported on ${$.platform} devices.`)}}class nS{deviceSessionManager;visualHighlightFactory;constructor($=m6.getInstance(),J=(X)=>new Gs$(X)){this.deviceSessionManager=$,this.visualHighlightFactory=J}async addHighlight($,J,X){let Y=await(await this.resolveHighlight(X)).addHighlight($,J,{timeoutMs:X.timeoutMs});if(!Y.success)throw new R(Y.error||"Failed to add highlight");return Y}async resolveHighlight($){if($.device){if($.device.platform!==$.platform)throw new R(`Highlight platform mismatch: requested ${$.platform}, device is ${$.device.platform}.`);return this.visualHighlightFactory($.device)}if($.platform!=="android"&&$.platform!=="ios")throw new R(`Visual highlights are not supported on ${$.platform} devices.`);let J=await this.deviceSessionManager.ensureDeviceReady($.platform,$.deviceId);return this.visualHighlightFactory(J)}}var xs0=5000,Kn=($)=>$===null?void 0:$,bs0=($)=>$===null?void 0:$,xU$,bU$,ys0,fs0,vs0,hs0,dS,gs0;var Un=D(()=>{g4();E0();iG();M0();U4();J4();r$();xU$=N.object({x:N.number().int(),y:N.number().int(),width:N.number().int().positive("bounds.width must be a positive integer"),height:N.number().int().positive("bounds.height must be a positive integer"),sourceWidth:N.number().int().positive().nullable().optional(),sourceHeight:N.number().int().positive().nullable().optional()}).superRefine(($,J)=>{let X=Kn($.sourceWidth),Q=Kn($.sourceHeight);if(X!==void 0!==(Q!==void 0))J.addIssue({code:N.ZodIssueCode.custom,message:"bounds.sourceWidth and bounds.sourceHeight must be provided together"})}),bU$=N.object({strokeColor:N.string().min(1).nullable().optional(),strokeWidth:N.number().positive().nullable().optional(),dashPattern:N.array(N.number().positive()).nonempty().nullable().optional(),smoothing:N.enum(["none","catmull-rom","bezier","douglas-peucker"]).nullable().optional(),tension:N.number().min(0).max(1).nullable().optional(),capStyle:N.enum(["butt","round","square"]).nullable().optional(),joinStyle:N.enum(["miter","round","bevel"]).nullable().optional()}).superRefine(($,J)=>{let X=bs0($.strokeColor),Q=Kn($.strokeWidth),Y=$.dashPattern??void 0,W=$.smoothing??void 0,G=Kn($.tension),Z=$.capStyle??void 0,j=$.joinStyle??void 0;if(!(X!==void 0||Q!==void 0||Y!==void 0||W!==void 0||G!==void 0||Z!==void 0||j!==void 0))J.addIssue({code:N.ZodIssueCode.custom,message:"Highlight style must include stroke settings"})}),ys0=N.object({x:N.number(),y:N.number()}),fs0=N.object({type:N.literal("box"),bounds:xU$,style:bU$.nullable().optional()}),vs0=N.object({type:N.literal("circle"),bounds:xU$,style:bU$.nullable().optional()}),hs0=N.object({type:N.literal("path"),points:N.array(ys0).min(2),bounds:xU$.nullable().optional(),style:bU$.nullable().optional()}),dS=N.discriminatedUnion("type",[fs0,vs0,hs0]),gs0=N.object({success:N.boolean(),error:N.string().nullable().optional(),requestId:N.string().optional(),timestamp:N.number().optional()}).passthrough()});import{promises as Ks$}from"fs";import us0 from"path";function yU$($,J,X){if($===void 0||$.trim()==="")return J;let Q=Number($);if(!Number.isFinite(Q)||Q<0||!X&&Q===0)return U.warn(`[VideoRecording] Ignoring invalid retention env value "${$}"; using ${J}`),J;return Q}function rs0($=process.env){let J=yU$($.AUTOMOBILE_VIDEO_RETENTION_DAYS??$.AUTO_MOBILE_VIDEO_RETENTION_DAYS,ns0,!0),X=yU$($.AUTOMOBILE_VIDEO_RETENTION_SWEEP_MINUTES??$.AUTO_MOBILE_VIDEO_RETENTION_SWEEP_MINUTES,is0,!1),Q=yU$($.AUTOMOBILE_VIDEO_INPROGRESS_CHECK_SECONDS??$.AUTO_MOBILE_VIDEO_INPROGRESS_CHECK_SECONDS,os0,!1);return{ttlMs:Math.max(0,Math.floor(J*ds0)),sweepIntervalMs:Math.max(1000,Math.floor(X*60000)),inProgressCheckIntervalMs:Math.max(1000,Math.floor(Q*1000))}}async function ts0(){return U.debug("[VideoRecording] Using HybridVideoCaptureBackend (iOS FFmpeg, Android platform)"),new Vn}async function as0(){let $=await ts0();return new Yn({backend:$})}async function ss0($){if(Zs$)return;Zs$=!0,Xe0($);let J=await $.recordingRepository.listRecordings({status:"recording"});if(J.length===0)return;let X=$.now().toISOString();for(let Q of J){let Y=await pU$(Q.filePath),W=Fs$(Q.startedAt,X);await $.recordingRepository.updateRecording(Q.recordingId,{status:"interrupted",endedAt:X,lastAccessedAt:X,sizeBytes:Y,durationMs:W})}U.info(`[VideoRecording] Marked ${J.length} recording(s) as interrupted after restart`)}async function tJ(){if(!zn)zn={videoRecorderService:await as0(),recordingRepository:new IU$,configRepository:ol(),highlightClient:new nS,timer:g,now:()=>new Date,retentionPolicy:rs0(),statFileSize:pU$};return await ss0(zn),zn}function Us$($,J){return{qualityPreset:J.qualityPreset??$.qualityPreset,targetBitrateKbps:J.targetBitrateKbps??$.targetBitrateKbps,maxThroughputMbps:J.maxThroughputMbps??$.maxThroughputMbps,fps:J.fps??$.fps,maxArchiveSizeMb:J.maxArchiveSizeMb??$.maxArchiveSizeMb,format:J.format??$.format,resolution:J.resolution??$.resolution}}function zs$($){return{qualityPreset:$.qualityPreset,targetBitrateKbps:$.targetBitrateKbps,maxThroughputMbps:$.maxThroughputMbps,fps:$.fps,maxArchiveSizeMb:$.maxArchiveSizeMb,format:$.format,resolution:$.resolution}}function es0($,J){if($===void 0)return ms0;if(!Number.isFinite($)||$<=0)throw new R("maxDuration must be a positive number of seconds.");let X=J==="ios"?gU$:ls0;if($>X)throw new R(`maxDuration must be <= ${X} seconds.`);return Math.round($)}async function $e0($){if($)return $;let{recordingRepository:J}=await tJ(),X=await J.listRecordings({status:"recording"});if(X.length===0)throw new R("No active video recording found. Provide recordingId.");if(X.length>1)throw new R("Multiple active video recordings found. Provide recordingId.");return X[0].recordingId}async function Je0($,J){if(!Number.isFinite(J)||J<=0)return;let{timer:X}=await tJ(),Q=Math.max(1,Math.round(J*1000)),Y=X.setTimeout(()=>{XQ($).catch((W)=>{U.warn(`[VideoRecording] Failed to auto-stop recording ${$}: ${W}`)})},Q);fU$.set($,{timer:X,handle:Y})}function Ls$($){let J=fU$.get($);if(J)J.timer.clearTimeout(J.handle),fU$.delete($)}function Xe0($){if(js$)return;let{retentionPolicy:J,timer:X}=$;if(J.ttlMs<=0)return;let Q=X.setInterval(()=>{Qe0().catch((Y)=>{U.warn(`[VideoRecording] TTL retention sweep failed: ${Y}`)})},J.sweepIntervalMs);js$={timer:X,handle:Q}}async function Qe0(){let $=await tJ(),{recordingRepository:J,retentionPolicy:X,now:Q}=$;if(X.ttlMs<=0)return[];let Y=Q().getTime()-X.ttlMs,W=await J.listRecordings({status:["completed","interrupted"]}),G=[];for(let Z of W){let j=Date.parse(Z.createdAt);if(Number.isNaN(j)||j>Y)continue;try{if(await Rs$(Z.recordingId))G.push(Z.recordingId)}catch(V){U.warn(`[VideoRecording] Failed to prune expired recording ${Z.recordingId}: ${V}`)}}if(G.length>0)U.info(`[VideoRecording] TTL sweep pruned ${G.length} recording(s) older than ${X.ttlMs} ms`);return G}function Ye0($,J,X,Q){if(!Number.isFinite(X)||X<=0)return;let{timer:Y,retentionPolicy:W}=Q,G=Y.setInterval(()=>{We0($,J,X).catch((Z)=>{U.warn(`[VideoRecording] In-progress size check failed for ${$}: ${Z}`)})},W.inProgressCheckIntervalMs);Hn.set($,{timer:Y,handle:G})}function mU$($){let J=Hn.get($);if(J)J.timer.clearInterval(J.handle),Hn.delete($)}async function We0($,J,X){if(!Hn.has($))return;let{statFileSize:Q}=await tJ(),Y=await Q(J);if(Y<X)return;U.warn(`[VideoRecording] In-progress recording ${$} reached size cap (${Y} >= ${X} bytes); stopping to protect disk.`),mU$($),await XQ($)}function Ge0($){let J=uU$.get($);if(!J)return null;return Ln.get(J)??null}function Hs$($,J){if(!Number.isFinite(J))return 0;return Math.max(0,Math.round(J-$.startedAtMs))}function Vs$($){let J=Math.max(0,Math.round($));return Number((J/1000).toFixed(3))}function Os$($,J,X){let Q=Hs$($,X);$.highlights.push({description:J.description,shape:J.shape,appearedAtMs:Q,disappearedAtMs:Q+Ze0($.platform)})}function Ze0($){return $==="ios"?cs0:ps0}function lU$($=g){return df("highlight",$)}function Bs$($,J){if($.highlights.length===0)return;let X=Date.parse(J),Q=Hs$($,X);return $.highlights.map((Y)=>{let W=Math.min(Y.disappearedAtMs,Q);return{description:Y.description,shape:Y.shape,timeline:{appearedAtSeconds:Vs$(Y.appearedAtMs),disappearedAtSeconds:Vs$(W)}}}).sort((Y,W)=>Y.timeline.appearedAtSeconds-W.timeline.appearedAtSeconds)}function je0($,J,X,Q){let Y=Date.parse(X);return{recordingId:$,deviceId:J.deviceId,platform:J.platform,startedAtMs:Number.isNaN(Y)?Q.now():Y,highlights:[],timer:Q,timers:new Set}}function vU$($){let J=Ln.get($);if(!J)return null;for(let X of J.timers)J.timer.clearTimeout(X);return J.timers.clear(),Ln.delete($),uU$.delete(J.deviceId),J}function Ds$($){let J=$.timing?.startTimeMs??0;if(!Number.isFinite(J)||J<0)throw new R("highlight.timing.startTimeMs must be >= 0.");return{startMs:J}}async function Ve0($,J,X,Q){let Y={device:J,deviceId:J.deviceId,platform:J.platform},W=[],G=(j,V)=>{let K=Math.max(0,Math.round(j));if(K===0){W.push(V());return}let z=$.timer.setTimeout(()=>{V()},K);$.timers.add(z)},Z=async(j)=>{try{let V=lU$();await Q.highlightClient.addHighlight(V,j.shape,Y),Os$($,j,Q.now().getTime())}catch(V){U.warn(`[VideoRecording] Failed to add highlight: ${V}`)}};for(let j of X){let{startMs:V}=Ds$(j);G(V,()=>Z(j))}if(W.length>0)await Promise.all(W)}async function Ke0($){let{configRepository:J}=await tJ(),X=await J.getConfig(),Q=X?zs$(X):b$.getVideoRecordingDefaults();return Us$(Q,$)}async function pU$($){try{return(await Ks$.stat($)).size}catch{return U.warn(`[VideoRecording] Missing recording file at ${Wv($)}`),0}}function Fs$($,J){let X=Date.parse($),Q=Date.parse(J);if(Number.isNaN(X)||Number.isNaN(Q))return;return Math.max(0,Q-X)}function cU$($){return{recordingId:$.recordingId,fileName:$.fileName,filePath:$.filePath,format:$.format,sizeBytes:$.sizeBytes,durationMs:$.durationMs,codec:$.codec,outputName:$.outputName,createdAt:$.createdAt,startedAt:$.startedAt,endedAt:$.endedAt,lastAccessedAt:$.lastAccessedAt,config:$.config,highlights:$.highlights}}async function dU$($){let J=new Set([ZX.LATEST,ZX.ARCHIVE]);for(let X of $)J.add(cS(X));await h$.notifyResourcesUpdated(Array.from(J))}async function nU$(){let{configRepository:$}=await tJ(),J=await $.getConfig();if(J)return J;return HK(b$.getVideoRecordingDefaults())}async function qs$($){let{configRepository:J}=await tJ();if($===null){await J.clearConfig();let G=HK(b$.getVideoRecordingDefaults()),Z=await hU$(G.maxArchiveSizeMb);return{config:G,evictedRecordingIds:Z.evictedRecordingIds}}let X=await nU$(),Q=Us$(zs$(X),$),Y=HK(Q);await J.setConfig(Y);let W=await hU$(Y.maxArchiveSizeMb);return{config:Y,evictedRecordingIds:W.evictedRecordingIds}}async function zN($){let J=await tJ(),{videoRecorderService:X,recordingRepository:Q,timer:Y}=J;if((await Q.listRecordings({status:"recording",deviceId:$.device.deviceId})).length>0)throw new R(`Video recording already active for device ${$.device.deviceId}.`);let G=$.configOverrides??{},Z=await Ke0(G),j=es0($.maxDurationSeconds,$.device.platform),V=$.highlights??[];for(let H of V)Ds$(H);let K=await X.startRecording({outputName:$.outputName,config:Z,device:$.device,maxDurationSeconds:j});await Q.insertRecording({recordingId:K.recordingId,deviceId:$.device.deviceId,platform:$.device.platform,status:"recording",outputName:K.outputName,fileName:K.fileName,filePath:K.outputPath,format:K.config.format,sizeBytes:0,durationMs:void 0,codec:void 0,createdAt:K.startedAt,startedAt:K.startedAt,endedAt:void 0,lastAccessedAt:K.startedAt,config:K.config,ownerSessionUuid:$.ownerSessionUuid});let z=je0(K.recordingId,$.device,K.startedAt,Y);if(Ln.set(K.recordingId,z),uU$.set($.device.deviceId,K.recordingId),V.length>0)await Ve0(z,$.device,V,J);await Je0(K.recordingId,j);let L=Math.floor((K.config.maxArchiveSizeMb??0)*1024*1024);return Ye0(K.recordingId,K.outputPath,L,J),K}async function XQ($){let{videoRecorderService:J,recordingRepository:X,now:Q}=await tJ(),Y=await $e0($);Ls$(Y),mU$(Y);let W=await J.stopRecording(Y),G=vU$(Y);if(G){let j=Bs$(G,W.endedAt??Q().toISOString());if(j)W.highlights=j}await X.updateRecording(Y,{status:"completed",outputName:W.outputName,fileName:W.fileName,filePath:W.filePath,format:W.format,sizeBytes:W.sizeBytes,durationMs:W.durationMs,codec:W.codec,endedAt:W.endedAt,lastAccessedAt:W.lastAccessedAt,config:W.config,highlights:W.highlights});let Z=await hU$(W.config.maxArchiveSizeMb);return await dU$([W.recordingId]),{metadata:W,evictedRecordingIds:Z.evictedRecordingIds}}async function ws$($){let{recordingRepository:J,now:X}=await tJ();Ls$($),mU$($);let Q=await J.getRecording($);if(!Q||Q.status!=="recording"){vU$($);return}let Y=X().toISOString(),W=vU$($),G=W?Bs$(W,Y):Q.highlights;await J.updateRecording($,{status:"interrupted",endedAt:Y,lastAccessedAt:Y,sizeBytes:await pU$(Q.filePath),durationMs:Fs$(Q.startedAt,Y),highlights:G}),await dU$([$])}async function Ns$($,J){let X=Ge0($.deviceId);if(!X)return;let{now:Q}=await tJ();Os$(X,J,Q().getTime())}async function ZO($={}){let{recordingRepository:J}=await tJ();return J.listRecordings({status:"recording",deviceId:$.deviceId,platform:$.platform})}async function As$($={}){let{recordingRepository:J}=await tJ();return(await J.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"desc",ownerSessionUuid:$.ownerSessionUuid})).map(cU$)}async function _s$($,J){let{recordingRepository:X,now:Q}=await tJ(),Y=await X.getRecording($,{ownerSessionUuid:J?.ownerSessionUuid});if(!Y||Y.status==="recording")return null;let W=cU$(Y);if(J?.touch!==!1){let G=Q().toISOString();await X.touchRecording($,G),W.lastAccessedAt=G}return W}async function Ms$($={}){let{recordingRepository:J}=await tJ(),X=await J.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"desc",limit:1,ownerSessionUuid:$.ownerSessionUuid});return X[0]?cU$(X[0]):null}async function Rs$($){let{recordingRepository:J}=await tJ(),X=await J.getRecording($);if(!X)return!1;if(X.status==="recording")throw Error(`Cannot delete active recording ${$}`);let Q=us0.dirname(X.filePath);if(await n9(Q))await Ks$.rm(Q,{recursive:!0,force:!0});let Y=await J.deleteRecording($);if(Y)await dU$([$]);return Y}async function hU$($){let J=Math.max(0,Math.floor($*1024*1024)),{recordingRepository:X}=await tJ(),Q=await X.listRecordings({status:["completed","interrupted"],orderByLastAccessed:"asc"}),Y=Q.reduce((G,Z)=>G+(Z.sizeBytes??0),0);if(J===0||Y<=J)return{evictedRecordingIds:[],currentSizeBytes:Y,maxSizeBytes:J};let W=[];for(let G of Q){if(Y<=J)break;try{if(await Rs$(G.recordingId))W.push(G.recordingId),Y-=G.sizeBytes??0}catch(Z){U.warn(`[VideoRecording] Failed to evict recording ${G.recordingId}: ${Z}`)}}if(Y>J)U.warn(`[VideoRecording] Archive size ${Y} bytes still exceeds limit ${J} bytes after eviction`);return{evictedRecordingIds:W,currentSizeBytes:Y,maxSizeBytes:J}}var ms0=30,ls0=300,gU$=3600,ps0=6000,cs0=3000,ds0=86400000,ns0=7,is0=60,os0=15,zn=null,Zs$=!1,fU$,Ln,uU$,Hn,js$=null;var OK=D(()=>{QW();r$();SU$();p4();n();d4$();U$();F5();q8();Ws$();zT();kU$();Un();fU$=new Map,Ln=new Map,uU$=new Map,Hn=new Map});class Ps${dependencies;constructor($){this.dependencies=$}async ensureReady($){let J=Math.min($.totalDeadlineMs,this.dependencies.timer.now()+$.readinessTimeoutMs),X={...$,readinessDeadlineMs:J},Q=`${$.device.platform}:${$.device.deviceId}`,Y=await this.acquireReadinessTurn(X,Q);try{await this.ensureReadyUncoordinated(X)}finally{Y()}}async ensureReadyUncoordinated($){if($.device.platform==="android"){await this.ensureAndroidReady($);return}await this.ensureIosReady($)}async acquireReadinessTurn($,J){if(this.remaining($)<=0)this.fail($,"runner-setup",1,"readiness budget exhausted before setup lock");let X=On.get(J)??{locked:!1,waiters:[]};if(On.set(J,X),!X.locked)return X.locked=!0,this.createReadinessRelease(J,X);try{return await new Promise((Q,Y)=>{let W={active:!0,resolve:Q,reject:Y,timer:this.dependencies.timer,signal:$.signal},G=(Z)=>{if(!W.active)return;W.active=!1,this.removeReadinessWaiter(X,W),this.cleanupReadinessWaiter(W),Y(Z)};if(W.timeoutHandle=this.dependencies.timer.setTimeout(()=>G(Error("readiness setup lock exceeded this request's deadline")),this.remaining($)),W.abortListener=()=>G($.signal?.reason),$.signal?.addEventListener("abort",W.abortListener,{once:!0}),X.waiters.push(W),$.signal?.aborted)W.abortListener()})}catch(Q){this.fail($,"runner-setup",1,iU$(Q))}}createReadinessRelease($,J){let X=!1;return()=>{if(X)return;X=!0;let Q=J.waiters.shift();while(Q&&!Q.active)Q=J.waiters.shift();if(Q){Q.active=!1,this.cleanupReadinessWaiter(Q),Q.resolve(this.createReadinessRelease($,J));return}if(J.locked=!1,On.get($)===J)On.delete($)}}removeReadinessWaiter($,J){let X=$.waiters.indexOf(J);if(X>=0)$.waiters.splice(X,1)}cleanupReadinessWaiter($){if($.timeoutHandle)$.timer.clearTimeout($.timeoutHandle);if($.abortListener)$.signal?.removeEventListener("abort",$.abortListener)}async ensureAndroidReady($){let J=this.dependencies.getAndroidManager($.device),X=this.dependencies.getAndroidClient($.device);if($.skipCtrlProxyDownload){await this.ensureAndroidReadyWithoutDownloads($,J,X);return}let Q=await this.runPhase($,"package-compatibility",1,(G)=>J.ensureCompatibleVersion({allowDownloadWhenInstalled:!0,bypassVersionCheckCache:!1},G));this.assertAndroidCompatibility($,Q);let[Y,W]=await this.runPhase($,"runner-setup",1,(G)=>Promise.all([J.isInstalled(G),J.isEnabled(G)]));if(await this.isResponsiveFastPath($,X,Y&&W))return;if(Y&&W)J.resetSetupState();await this.setupAndroidRunner($,J),await this.waitForResponsiveClient($,X)}async ensureAndroidReadyWithoutDownloads($,J,X){let[Q,Y]=await this.runPhase($,"runner-setup",1,(G)=>Promise.all([J.isInstalled(G),J.isEnabled(G)]));if(!Q)this.fail($,"runner-setup",1,"CtrlProxy is not installed and runner downloads are disabled");if(!await this.runPhase($,"package-compatibility",1,()=>J.isVersionCompatible()))this.fail($,"package-compatibility",1,"CtrlProxy version mismatch; run without skipCtrlProxyDownload to install a compatible version");if(await this.isResponsiveFastPath($,X,Y))return;if(!Y)await this.runPhase($,"runner-setup",1,()=>J.enable());await this.waitForResponsiveClient($,X)}assertAndroidCompatibility($,J){if(!(J.status==="failed"||J.status==="skipped"||J.acceptedPreinstalled===!0))return;let Q=[J.error,J.upgradeError,J.reinstallError,J.acceptedPreinstalled?"installed package compatibility was not verified":void 0,J.status==="skipped"?"package compatibility check was skipped":void 0].filter((Y)=>Boolean(Y));this.fail($,"package-compatibility",1,Q.join("; "))}async isResponsiveFastPath($,J,X){if(!X||!J.isConnected())return!1;return this.runPhase($,"runner-health",1,()=>J.verifyServiceReady(1,0,this.probeTimeout($)))}async setupAndroidRunner($,J){let X=await this.runPhase($,"runner-setup",1,(W)=>J.setup(!1,$.perf,W));if(!X.success)this.fail($,"runner-setup",1,X.error??X.message);let[Q,Y]=await this.runPhase($,"runner-setup",1,(W)=>Promise.all([J.isInstalled(W),J.isEnabled(W)]));if(!Q||!Y)this.fail($,"runner-setup",1,`CtrlProxy state after setup: installed=${Q}, enabled=${Y}`)}async ensureIosReady($){let J=await this.runPhase($,"runner-setup",1,()=>this.dependencies.checkIosOverride());if(J.present&&!J.usable)this.fail($,"runner-setup",1,`AUTOMOBILE_CTRL_PROXY_IOS_BUNDLE_PATH / _IPA_PATH is set but unusable: ${J.reason??"unknown reason"}`);await this.runPhase($,"runner-setup",1,()=>this.dependencies.awaitIosStartupMaintenance());let X=this.dependencies.getIosManager($.device),Q=this.dependencies.getIosClient($.device,X.getServicePort());if(Q.isConnected()){if(await this.runPhase($,"runner-health",1,()=>Q.verifyServiceReady(1,0,this.probeTimeout($))))return}if($.skipCtrlProxyDownload){await this.ensureIosReadyWithoutDownloads($,X,Q);return}let Y=await this.runPhase($,"runner-setup",1,(W)=>X.setup(!1,$.perf,W,this.remaining($)));if(!Y.success)this.fail($,"runner-setup",1,Y.error??Y.message);await this.waitForResponsiveClient($,Q)}async ensureIosReadyWithoutDownloads($,J,X){if(!await this.runPhase($,"runner-setup",1,()=>J.isInstalled()))this.fail($,"runner-setup",1,"CtrlProxy iOS runner is not installed and runner downloads are disabled");await this.runPhase($,"runner-setup",1,(Y)=>J.start({signal:Y,minimumHealthPollDurationMs:this.remaining($)})),await this.waitForResponsiveClient($,X)}async waitForResponsiveClient($,J){let X=0,Q=J.isConnected(),Y=Q?"runner-health":"runner-connect";while(this.remaining($)>0){if(X++,Q=J.isConnected(),!Q)Y="runner-connect",Q=await this.runPhase($,Y,X,()=>J.waitForConnection(1,0));if(Q){if(Y="runner-health",await this.runPhase($,Y,X,()=>J.verifyServiceReady(1,0,this.probeTimeout($))))return}let W=this.remaining($);if(W>0)await this.dependencies.timer.sleep(Math.min(Ue0,W))}this.fail($,Y,X,"runner did not become responsive before the readiness deadline")}async runPhase($,J,X,Q){if(this.remaining($)<=0)this.fail($,J,X,"readiness budget exhausted before phase started");let Y=this.remaining($),W=new AbortController,G=$.signal?AbortSignal.any([$.signal,W.signal]):W.signal,Z,j=uB(G,()=>Q(G));j.catch(()=>{});try{return await Promise.race([j,new Promise((V,K)=>{Z=this.dependencies.timer.setTimeout(()=>{W.abort(Error("readiness phase exceeded the remaining deadline")),K(Error("readiness phase exceeded the remaining deadline"))},Y)})])}catch(V){if(W.signal.aborted)await this.awaitAbortSettlement(j);return this.fail($,J,X,iU$(V))}finally{if(Z)this.dependencies.timer.clearTimeout(Z)}}async awaitAbortSettlement($){let J;try{await Promise.race([$.then(()=>{return},()=>{return}),new Promise((X)=>{J=this.dependencies.timer.setTimeout(X,Le0)})])}finally{if(J)this.dependencies.timer.clearTimeout(J)}}probeTimeout($){return Math.max(1,Math.min(ze0,this.remaining($)))}remaining($){return Math.max(0,$.readinessDeadlineMs-this.dependencies.timer.now())}fail($,J,X,Q){let{device:Y}=$,W=`platform=${Y.platform} requested=[${$.requestedIdentity}] resolved=[${Y.name} (${Y.deviceId})]`;throw new R(`startDevice automation runner readiness failed: ${W} phase=${J} attempts=${X} remainingBudgetMs=${this.remaining($)}: ${iU$(Q)}`)}}function iU$($){let J=$ instanceof Error?$.message:String($),X=yQ(J);if(X.length<=Es$)return X;let Q=Math.floor((Es$-32)/2);return`${X.slice(0,Q)}
|
|
600
600
|
...[diagnostic truncated]...
|
|
601
601
|
${X.slice(-Q)}`}function Ts$($=g){return new Ps$({timer:$,getAndroidManager:(J)=>x$.getInstance(J),getAndroidClient:(J)=>P$.getInstance(J),getIosManager:(J)=>m$.getInstance(J),getIosClient:(J,X)=>M$.getInstance(J,X),checkIosOverride:wq,awaitIosStartupMaintenance:()=>m$.awaitStartupOrphanRunnerReap()})}var Ue0=250,ze0=2000,Es$=4000,Le0=1000,On;var Cs$=D(()=>{r$();U4();J4();o7();XW();hP();Zv();U$();ij();On=new Map});function qe0($,J,X){let Q=String(X instanceof Error?X.message:X).toLowerCase();if($==="android")return Q.includes("not running")&&Q.includes("emulator")||QM(X,J);if($==="ios")return Q.includes("already shut down")||Q.includes("already shutdown")||Q.includes("not booted")||Q.includes("invalid device state")||Q.includes("current state: shutdown");return!1}function we0($,J){return{isError:!0,content:[{type:"text",text:JSON.stringify({success:!1,message:J,error:{code:$,message:J}})}]}}function Ne0($,J,X){if(X!==void 0)return we0(Fe0,X);return e$({message:`${$.device.platform} '${$.device.name}' shutdown successfully`,udid:$.device.deviceId,name:$.device.name,timing:J,platform:$.device.platform})}async function Ae0(){await na$(),await ta$(),await GU$()}async function _e0($){let{InstalledAppsRepository:J}=await Promise.resolve().then(() => (pV(),dY$)),X=new J;await I8().invalidate($,()=>f6().track(()=>X.clearDeviceSession($)).then(()=>{return}))}async function Me0($,J){try{await $.clearInstalledAppsForDevice(J)}catch(X){U.warn(`[DeviceTools] Failed to clear installed apps for ${J} after shutdown: ${X}`,X)}}async function Re0($){try{await $.notifyResourcesChanged()}catch(J){U.warn(`[DeviceTools] Failed to notify resource changes after shutdown: ${J}`,J)}}function iS(){if(!oU$)oU$={deviceManagerFactory:()=>new q9,deviceMatcherFactory:()=>new MR,notifyResourcesChanged:Ae0,deviceCreationGateFactory:()=>sB(),deviceProvisionerFactory:()=>jF(),clearInstalledAppsForDevice:_e0,idGenerator:U6,timer:g};return oU$}function ks$($){return[`platform=${$.platform}`,$.deviceId?`deviceId=${$.deviceId}`:void 0,$.name?`name=${$.name}`:void 0,$.minOsVersion?`minOsVersion=${$.minOsVersion}`:void 0,$.maxOsVersion?`maxOsVersion=${$.maxOsVersion}`:void 0,$.formFactor?`formFactor=${$.formFactor}`:void 0].filter((J)=>J!==void 0).join(" ")}function Ee0($){return $.runnerReadinessTimeoutMs??$.timeoutMs??b$.getRunnerReadinessTimeoutMs()}function Pe0($,J,X,Q){let Y=ks$($),W=`${J.platform} ${J.name} (${J.deviceId})`;if(J.platform!==$.platform)throw new R(`startDevice identity mismatch: requested=[${Y}] resolved=[${W}] phase=pool-match: resolved platform differs from requested platform`);if(X==="booted"&&$.deviceId&&J.deviceId!==$.deviceId)throw new R(`startDevice identity mismatch: requested=[${Y}] resolved=[${W}] phase=pool-match: running device ID differs from the requested device ID`);if(X==="cold-boot"&&J.platform==="ios"&&Q?.deviceId&&Q.deviceId!==J.deviceId)throw new R(`startDevice identity mismatch: requested=[${Y}] selected=[${Q.name} (${Q.deviceId})] resolved=[${W}] phase=pool-match: iOS runtime UDID differs from the selected simulator UDID`)}function Is$($,J){let X=S0.getInstance();if(!X.isInitialized())return;let Q=X.getDevicePool().getDevice($.deviceId);if(Q&&(Q.platform!==$.platform||Q.name!==$.name))throw new R(`startDevice identity mismatch: requested=[${J}] resolved=[${$.name} (${$.deviceId}) platform=${$.platform}] pooled=[${Q.name} (${Q.id}) platform=${Q.platform}] phase=pool-match: stale pool identity conflicts with the resolved runtime`)}function Te0($){if($?.source!=="cold-boot"||!$.processHandle)return;try{$.processHandle.kill()}catch(J){U.warn(`[DeviceTools] Failed to cancel unowned cold boot ${$.device.deviceId}: ${J}`,J)}}function Ce0($,J){let X=S0.getInstance();if($==="cold-boot"&&X.isInitialized())X.getDevicePool().clearIntentionalShutdown(J)}function Se0($,J){let X=S0.getInstance();if($==="booted"&&X.isInitialized())X.getDevicePool().notifyDeviceReady(J)}function Bn(){let $=async(Z)=>{try{let K=await iS().deviceManagerFactory().listDeviceImages(Z.platform);return e$({message:`Found ${K.length} available ${Z.platform} AVDs`,images:K,count:K.length,platform:Z.platform})}catch(j){throw new R(`Failed to list ${Z.platform} AVDs: ${j}`)}},J=async(Z)=>{let j=Z.platform?` (${Z.platform} only)`:"";return e$({message:`To list devices${j}, use these MCP resources:
|
|
602
602
|
|
|
@@ -1145,4 +1145,4 @@ ${Q.stderr}`;if(Q.exitCode!==0||!Y.includes("h264_videotoolbox"))throw new R("iO
|
|
|
1145
1145
|
|
|
1146
1146
|
`)},zT1):void 0,V=()=>{if(j)g.clearInterval(j)};J.on("close",V),J.on("finish",V);try{await Y.handleRequest($,J,W)}catch(K){U.error("Streamable HTTP request handling failed:",K),Z("Server error",K)}finally{V()}}else J.writeHead(404,{"Content-Type":"application/json"}),J.end(JSON.stringify({error:"Not found"}))}),new Promise(($,J)=>{this.httpServer.listen(this.port,this.host,()=>{U.info(`automobile:${this.host}:${this.port}${aD}`),$()}),this.httpServer.on("error",(X)=>{U.error(`HTTP server error: ${X}`),J(X)})})}async persistPidFileData($){await jT1(KT1(fJ),{recursive:!0}),await VT1(fJ,JSON.stringify($,null,2),{encoding:"utf-8",mode:384}),this.pidFileWritten=!0}async writeEarlyOwnerRecord(){let $={pid:process.pid,socketPath:o6,port:this.port,dbPath:BV(),startedAt:this.timer.now(),version:gY,assetVersion:C9(Z4()),options:this.options};await this.persistPidFileData($),U.info(`Early daemon owner record written to ${fJ} (dbPath ${$.dbPath})`)}async writePidFile(){let $=GY(),J={pid:process.pid,socketPath:o6,sockets:fL0(),port:this.port,dbPath:BV(),startedAt:this.timer.now(),version:gY,assetVersion:C9(Z4()),entryScript:$.entryScript,buildId:$.buildId,options:this.options};await this.persistPidFileData(J),U.info(`PID file written to ${fJ}`)}setupDeviceDataStreamCallback(){let $=E6();if(!$){U.warn("[Daemon] Observation stream server not available for callback setup");return}$.setOnSubscriberConnected((J)=>{U.info(`[Daemon] IDE plugin subscribed to observation stream (device: ${J??"all"}), ensuring WebSocket connections...`);let X=this.devicePool.getAllDevices();if(hL0(J,X,{streamServer:$,androidClientFactory:(Q)=>P$.getInstance(Q,j$),iosClientFactory:(Q)=>this.createObservationStreamIosClient(Q)}).catch((Q)=>{U.warn(`[Daemon] Error pushing initial observation frame: ${Q}`)}),X.length===0)U.info("[Daemon] No devices in pool to connect")}),$.setOnScreenshotCadenceChanged((J)=>{let X=this.devicePool.getAllDevices().filter((Q)=>J===null||Q.id===J);for(let Q of X)if(Q.platform==="android")P$.getExistingInstance(Q.id)?.refreshObservationStreamScreenshotCadence();else if(Q.platform==="ios")M$.getExistingInstance(Q.id)?.refreshObservationStreamScreenshotCadence()}),$.setOnHierarchyCadenceChanged((J)=>{let X=this.devicePool.getAllDevices().filter((Q)=>J===null||Q.id===J);for(let Q of X)if(Q.platform==="android")P$.getExistingInstance(Q.id)?.refreshObservationStreamHierarchyCadence();else if(Q.platform==="ios"){let Y=M$.getExistingInstance(Q.id);if(!Y)continue;let W=$.getHierarchyIntervalMsForDevice(Q.id);Y.ensureConnected().then((G)=>{if(G)Y.refreshObservationStreamHierarchyCadence(W)}).catch((G)=>{U.warn(`[Daemon] Failed to refresh iOS hierarchy cadence for ${Q.id}: ${G}`)})}}),$.setOnObservationRequested(async({deviceId:J,signal:X})=>{let Q=J?[this.devicePool.getDevice(J)].filter((G)=>G!==null):this.devicePool.getAllDevices();if(Q.length===0)throw Error(J?`Device ${J} is not available`:"No devices are available");let Y=this.timer.now(),W=[];for(let G of Q){if(X.aborted)throw Error("Observation request was aborted");let Z={deviceId:G.id,name:G.name,platform:G.platform,iosVersion:G.iosVersion},V=await new B4(Z).execute({skipWaitForFresh:!1,minTimestamp:Y,signal:X});W.push({deviceId:G.id,observation:V})}return W}),U.info("[Daemon] Observation stream callback configured"),this.setupNavigationGraphStreamListener($)}createObservationStreamIosClient($){let J=M$.getInstance($);return{ensureConnected:async()=>{let X=await J.ensureConnected(),Q=E6();if(X&&Q)J.refreshObservationStreamHierarchyCadence(Q.getHierarchyIntervalMsForDevice($.deviceId));return X},getLatestHierarchy:(...X)=>J.getLatestHierarchy(...X),requestHierarchySyncWithoutObservationStreamPush:async(...X)=>{let Q=await J.requestHierarchySyncWithoutObservationStreamPush(...X);return Q?{hierarchy:Q.hierarchy,...Q.frameContext===void 0?{}:{frameContext:Q.frameContext}}:null},convertToViewHierarchyResult:(X)=>J.convertToViewHierarchyResult(X),recordInitialObservationStreamHierarchy:(X,Q)=>J.recordInitialObservationStreamHierarchy(X,Q),requestScreenshotWithoutObservationStreamPush:(...X)=>J.requestScreenshotWithoutObservationStreamPush(...X)}}setupNavigationGraphStreamListener($){if(!$)return;let J=i0.getInstance();J.setGraphUpdateListener(async()=>{U.info("[Daemon] Navigation graph listener triggered, exporting summary...");try{let X=await J.exportGraphSummary();U.info(`[Daemon] Got summary: appId=${X.appId}, nodes=${X.nodes.length}, edges=${X.edges.length}`);let Q=Bw$(X);$.pushNavigationGraphUpdate(Q),U.info(`[Daemon] Pushed navigation graph update: ${X.nodes.length} nodes, ${X.edges.length} edges`)}catch(X){U.warn(`[Daemon] Failed to push navigation graph update: ${X}`)}}),$.setOnNavigationGraphRequested(lL0(J)),U.info("[Daemon] Navigation graph stream listener configured")}startHealthCheckTimer(){let X=0,Q="unknown",Y=(G)=>{if(Q!==G)X=0;Q=G,X++},W=()=>{X=0,Q="unknown"};if(this.healthCheckTimer=this.timer.setInterval(async()=>{try{if(!this.httpServer)U.warn("Health check failed: HTTP server not initialized"),Y("http");else if(!this.httpServer.listening)U.warn("Health check failed: HTTP server not listening"),Y("http");else if(!this.socketServer||!this.socketServer.isListening())U.warn("Health check failed: Socket server not listening"),Y("socket");else if(!this.observationStreamHealth.isHealthy())U.warn("Health check failed: Observation stream socket unavailable"),Y("socket");else try{await this.databaseHealthProbe.check(),W(),U.debug("Health check passed")}catch(G){U.warn(`Health check failed: Database probe failed: ${G}`),Y("database")}if(X>=3)U.error(`Health check failed ${X} times, attempting recovery...`),await this.attemptRecovery(Q),W()}catch(G){U.warn(`Health check error: ${G}`),Y("unknown")}},30000),typeof this.healthCheckTimer.unref==="function")this.healthCheckTimer.unref()}stopHealthCheckTimer(){if(this.healthCheckTimer)this.timer.clearInterval(this.healthCheckTimer),this.healthCheckTimer=null}startHeartbeatMonitor(){this.heartbeatMonitor=new PL$(this.sessionManager,($)=>xG.hasActiveSessionUuidExecutions($),($)=>this.cancelAndReleaseSession($),this.timer),this.heartbeatMonitor.start()}startDeviceDisconnectMonitor(){if(this.deviceDisconnectTimer)return;let $=new q9;this.deviceDisconnectTimer=g.setInterval(async()=>{try{if(b$.isPlanExecutionActive()){U.debug("[DisconnectMonitor] Skipping \u2014 plan execution active");return}let J=await $.getBootedDevicesDetailed("either"),X=J.devices,Q=J.succeededPlatforms,Y=new Set(X.map((z)=>z.deviceId)),W=await ZO(),G=new Map,Z=new Set,j=new Map,V=new Set;for(let z of W)Z.add(z.deviceId),j.set(z.deviceId,z.platform);for(let z of this.devicePool.getAllDevices())if(Z.add(z.id),j.set(z.id,z.platform),z.status==="idle")V.add(z.id);for(let z of this.sessionManager.getAssignedDevices())Z.add(z);let K=cL0({deviceDisconnectMisses:this.deviceDisconnectMisses,confirmedDisconnectedDeviceIds:this.confirmedDisconnectedDeviceIds,bootedDeviceIds:Y,candidateDeviceIds:Z,succeededPlatforms:Q,candidatePlatforms:j,idleCandidateIds:V,forceDisconnectedDeviceIds:this.forceDisconnectedDeviceIds,missThreshold:Be});if(K.skippedAdbUnreachable){U.warn(`[DisconnectMonitor] ADB returned 0 devices but ${Z.size} tracked \u2014 skipping miss count (ADB likely unreachable)`);return}for(let{deviceId:z,misses:L}of K.missed)U.info(`[DisconnectMonitor] Device ${z} not in booted list (miss ${L}/${Be}, booted=${Y.size})`);for(let z of K.disconnected)G.set(z,[]);for(let z of W)if(G.has(z.deviceId))G.get(z.deviceId).push(z.recordingId);for(let[z,L]of G.entries()){let H=this.devicePool.getDevice(z);if(await this.shouldSkipStaleDisconnectCleanup(H,z))continue;let O=!0;dz().stopMonitoring(z);for(let F of L){if(this.stoppingRecordings.has(F)){O=!1;continue}this.stoppingRecordings.add(F);try{await XQ(F),U.warn(`[Daemon] Stopped recording ${F} after device ${z} disconnected`)}catch(A){U.warn(`[Daemon] Failed to stop recording ${F} after device ${z} disconnected: ${A}`);try{await ws$(F),U.warn(`[Daemon] Marked recording ${F} interrupted after device ${z} disconnected`)}catch(_){O=!1,U.warn(`[Daemon] Failed to mark recording ${F} interrupted after device ${z} disconnected: ${_}`)}}finally{this.stoppingRecordings.delete(F)}}if(await this.shouldSkipStaleDisconnectCleanup(H,z))continue;let B=this.sessionManager.getSessionForDevice(z);if(B)U.warn(`[DisconnectMonitor] Device ${z} confirmed disconnected after ${Be} consecutive misses \u2014 cancelling session ${B}`),await this.cancelAndReleaseSession(B,`device-disconnected:${z}`);if(await this.devicePool.removeDisconnectedDevice(z),this.socketServer?.evictDeviceInputCache(z),this.devicePool.getDevice(z))O=!1;if(O)this.confirmedDisconnectedDeviceIds.add(z),this.deviceDisconnectMisses.delete(z),this.forceDisconnectedDeviceIds.delete(z)}}catch(J){U.warn(`[Daemon] Device disconnect monitor failed: ${J}`)}},UT1),this.deviceDisconnectTimer.unref()}async shouldSkipStaleDisconnectCleanup($,J){if(!$||await this.devicePool.isCurrentDisconnectedDevice($))return!1;return U.info(`[DisconnectMonitor] Skipping stale disconnect cleanup for recovered device ${J}`),!0}startAdbMissingDeviceListener(){if(this.unsubscribeAdbMissingDevice)return;this.unsubscribeAdbMissingDevice=$_$(($)=>{if(!this.devicePool.getDevice($.deviceId)&&!this.sessionManager.getSessionForDevice($.deviceId))return;U.warn(`[Daemon] ADB reported tracked device ${$.deviceId} missing: ${$.message}`),this.forceDisconnectedDeviceIds.add($.deviceId),this.deviceDisconnectMisses.set($.deviceId,Be)})}async cancelAndReleaseSession($,J="explicit-release"){let X=await xG.cancelSessionUuidExecutions($,J),Q=await this.sessionManager.releaseSession($,J);if(Q)await this.devicePool.releaseDevice(Q);U.info(`Cancelled session ${$} (${X} executions) and released device ${Q??"unknown"} (reason=${J})`)}async attemptRecovery($="unknown"){try{if(U.info("Attempting daemon recovery..."),$==="database"){U.error("Database health check failed repeatedly; exiting daemon for a clean restart."),this.recoverFromDatabaseHealthFailure(1);return}if(this.socketServer&&!this.socketServer.isListening()){U.info("Restarting socket server...");try{await this.socketServer.close()}catch(X){U.warn(`Error closing socket server during recovery: ${X}`)}let J=`http://${this.host}:${this.port}${aD}`;this.socketServer=new PI(o6,J,void 0,void 0,m8.getInstance());try{await this.socketServer.start(),U.info("Socket server restarted successfully")}catch(X){U.error(`Failed to restart socket server: ${X}`)}}if(!this.observationStreamHealth.isHealthy()){U.info("Restarting observation stream socket server...");try{await this.observationStreamHealth.recover(),U.info("Observation stream socket server restarted successfully")}catch(J){U.error(`Failed to restart observation stream socket server: ${J}`)}}}catch(J){U.error(`Recovery attempt failed: ${J}`)}}async initializeDevicePoolWithTimeout($){let J,X=new Promise((W)=>{if(J=g.setTimeout(()=>{U.warn(`Device pool initialization timed out after ${$}ms`),W()},$),typeof J.unref==="function")J.unref()}),Q=this.initializeDevicePool();try{await Promise.race([Q,X])}finally{if(J!==void 0)g.clearTimeout(J)}let Y=this.devicePool.getTotalDeviceCount();if(Y===0)U.warn("Device pool is empty after initialization."),U.warn("Tests will fail until devices are available."),U.warn("Start an emulator or connect a physical device, then restart the daemon.");else U.info(`Device pool ready with ${Y} device(s)`)}async initializeDevicePool(){try{let J=await new q9().getBootedDevices("either");if(J.length>0)await this.devicePool.initializeWithDevices(J),U.info(`Device pool initialized with ${J.length} devices: ${J.map((X)=>X.deviceId).join(", ")}`);else U.warn("No devices detected during daemon startup. Device pool is empty."),U.warn("Start an emulator or connect a physical device before creating sessions.")}catch($){U.error(`Failed to initialize device pool: ${$}`)}}async initializeIosServices(){let J=this.devicePool.getAllDevices().filter((Y)=>Y.platform==="ios");if(J.length===0){U.debug("[Daemon] No iOS devices to initialize CtrlProxy iOS for");return}U.info(`[Daemon] Initializing CtrlProxy iOS for ${J.length} iOS device(s)...`);let X=m6.getInstance(),Q=5000;for(let Y of J)try{U.info(`[Daemon] Setting up CtrlProxy iOS for iOS device ${Y.id}`);let W=new Promise((G,Z)=>{let j=g.setTimeout(()=>{Z(Error(`Timeout after ${Q}ms`))},Q);if(typeof j.unref==="function")j.unref()});await Promise.race([X.verifyIosDevice(Y.id,{skipCtrlProxyDownload:!0}),W]),U.info(`[Daemon] CtrlProxy iOS ready for iOS device ${Y.id}`)}catch(W){U.warn(`[Daemon] Failed to initialize CtrlProxy iOS for ${Y.id}: ${W}`)}}async initializeDatabase(){try{await this.databaseInitializer.initialize(),await this.installedAppsRepository.clearOldDaemonSessions(this.daemonSessionId),await this.deviceSessionRepository.markStaleActiveSessionsExpired(this.daemonSessionId,this.timer.now(),"daemon-restart"),U.info(`[Daemon] Cleared old daemon session caches, current session: ${this.daemonSessionId}`)}catch($){await Sr($,this.startupFailureTracker,this.timer)}}setupShutdownHandlers(){if(this.shutdownHandlersRegistered)return;this.shutdownHandlersRegistered=!0,cb(),db(async(J)=>{if(this.shutdownInProgress)return;this.shutdownInProgress=!0,U.info(`Received ${J}, shutting down daemon...`),await this.stop()}),process.once("exit",()=>{lf(this.getDaemonFileCleanupOptions())}),nb(K70(U))}async stop(){if(U.info("Stopping daemon..."),this.stopHealthCheckTimer(),this.heartbeatMonitor)this.heartbeatMonitor.stop(),this.heartbeatMonitor=null;if(this.deviceDisconnectTimer)clearInterval(this.deviceDisconnectTimer),this.deviceDisconnectTimer=null;if(this.unsubscribeAdbMissingDevice)this.unsubscribeAdbMissingDevice(),this.unsubscribeAdbMissingDevice=null;if(this.sessionManager.stopCleanupTimer(),this.socketServer)await this.socketServer.close();await hL$(),await lL$(),await nL$(),await eL$(),await _70(),await uu$(),await HY$(),await P70(),await Wm$(),await og$(),await Uw$(),await yL0(),await Kb.shutdown(),rL$(),AY$();for(let[X,Q]of this.transports)try{await Q.close()}catch(Y){U.warn(`Error closing Streamable HTTP session ${X}:`,Y)}if(this.transports.clear(),this.httpServer)await new Promise((X)=>{this.httpServer.close(()=>{U.info("HTTP server stopped"),X()})});if(await _L(this.getDaemonFileCleanupOptions()),!await f6().drain(iL0))U.warn(`Timed out after ${iL0}ms draining in-flight DB writes; closing database anyway`);if(!await Qv(oL0))U.warn(`Timed out after ${oL0}ms awaiting in-flight startup migration; closing database anyway`);await Yv(),U.info("Daemon stopped"),U.close()}getDaemonFileCleanupOptions(){if(this.pidFileWritten)return{expectedPid:process.pid};let $=JF();return $&&$.pid!==process.pid?{expectedPid:process.pid}:{}}getSessionManager(){return this.sessionManager}getDevicePool(){return this.devicePool}}async function LT1($={}){await new Fw$($).start()}var UT1=5000,Be=3,zT1=30000,iL0=1000,oL0=5000;var tL0=D(()=>{N50();P2$();n();mY();$70();EL$();J70();Y70();aB();kQ();kQ();g3();NJ();Tm();kP();rl();IL$();G70();xL$();Ir();U70();Hb();kr();xr();br();vr();JH$();Nl();gV();YH$();pl();Zl();Le();Ow$();vL0();U4();E0();J4();mL0();Z7();pL0();s7();pV();Er();iG();fr();QH();OK();U$();F5();iV();p4();M0();X$$();E9();IJ();sb();dL0()});var aL0={};m1(aL0,{runDirectModeStartup:()=>HT1});async function HT1($){if($.noProxy)await $.assertDbOwnership();await $.applyFeatureFlagStartup()}var JH0={};m1(JH0,{findConflictingDaemons:()=>DT1,createDefaultDirectModeGuardDeps:()=>qT1,assertDirectModeDbOwnership:()=>FT1});import{realpathSync as sL0}from"fs";import{basename as OT1,dirname as BT1,resolve as eL0}from"path";function qw$($){let J=eL0($);try{return sL0(J)}catch{try{return eL0(sL0(BT1(J)),OT1(J))}catch{return J}}}function $H0($,J){return $.filter((X)=>X.dbPath!==void 0&&qw$(X.dbPath)===J)}function DT1($){return $H0($.findLiveDaemonDbOwners(),qw$($.resolveDbPath()))}function FT1($){let J=qw$($.resolveDbPath()),X=$.findLiveDaemonDbOwners(),Q=$H0(X,J);if(Q.length>0){let W=Q.map((G)=>G.pid).join(", ");throw new R(`A live AutoMobile daemon (pid ${W}) already owns the database at ${J}. Direct mode (--no-proxy/--direct) would open a second writer on the same SQLite file, causing SQLITE_BUSY stalls and competing migrations. Resolve this by either running without --no-proxy/--direct to share the daemon, stopping the daemon, or setting AUTOMOBILE_DB_PATH (or AUTOMOBILE_DB_DIR) to an isolated database for this direct-mode instance.`)}let Y=X.filter((W)=>W.dbPath===void 0);if(Y.length>0){let W=Y.map((G)=>G.pid).join(", ");throw new R(`Cannot safely start direct mode (--no-proxy/--direct): a live AutoMobile daemon (pid ${W}) is running but its database path could not be determined (it may still be starting up, or is using a non-default PID file), so a collision on ${J} cannot be ruled out. Wait for the daemon to finish starting and retry, stop the daemon, or set AUTOMOBILE_DB_PATH (or AUTOMOBILE_DB_DIR) to an isolated database for this direct-mode instance.`)}}function qT1($={}){let J=$.manager??new Vj,X=$.readPidFileData??JF;return{resolveDbPath:$.resolveDbPath??BV,findLiveDaemonDbOwners:()=>{let Y;try{Y=J.findLiveDaemonProcesses()}catch(V){let K=V instanceof Error?V.message:String(V);throw U.warn(`Direct-mode guard: process-table scan failed; refusing direct mode because same-DB daemon ownership cannot be verified. ${K}`,V),new R(`Cannot verify daemon ownership before starting direct mode (--no-proxy/--direct): failed to inspect the process table (${K}). Retry, stop any running daemon, or set AUTOMOBILE_DB_PATH (or AUTOMOBILE_DB_DIR) to an isolated database.`)}if(Y.length===0)return[];let W=[],G=new Set,Z=X();if(Z&&typeof Z.pid==="number"&&Z.dbPath!==void 0&&Y.includes(Z.pid))W.push({pid:Z.pid,dbPath:Z.dbPath}),G.add(Z.pid);let j=Y.filter((V)=>!G.has(V));if(j.length>0){U.debug(`Direct-mode guard: ${j.length} live daemon(s) could not be mapped to a DB path (starting up or non-default PID file); direct mode will refuse to be safe: ${j.join(", ")}`);for(let V of j)W.push({pid:V,dbPath:void 0})}return W}}}var XH0=D(()=>{r$();rl();n();NI();NJ()});var MT1=f1(De(),1);import*as Ew$ from"fs";import*as Fe from"os";import*as K5 from"path";function Pw$(){zH0(),LH0()}function zH0(){let $=K5.delimiter,J=process.env.PATH??"",X=new Set(J.split($).filter(Boolean)),Q=HH0(),Y=[];for(let W of Q)if(!X.has(W)&&Tw$(W))Y.push(W),X.add(W);if(Y.length===0)return;process.env.PATH=J.length>0?`${J}${$}${Y.join($)}`:Y.join($)}function LH0(){if(process.env.ANDROID_HOME||process.env.ANDROID_SDK_ROOT)return;for(let $ of OH0())if(Tw$($)){process.env.ANDROID_HOME=$;return}}function HH0(){let $=process.platform,J=Fe.homedir();if($==="darwin")return["/usr/bin","/bin","/usr/sbin","/sbin","/usr/local/bin","/usr/local/sbin","/opt/homebrew/bin","/opt/homebrew/sbin",K5.join(J,"Library/Android/sdk/platform-tools"),K5.join(J,"Library/Android/sdk/emulator"),K5.join(J,"Library/Android/sdk/cmdline-tools/latest/bin")];if($==="linux")return["/usr/bin","/bin","/usr/sbin","/sbin","/usr/local/bin","/usr/local/sbin",K5.join(J,"Android/Sdk/platform-tools"),K5.join(J,"Android/Sdk/emulator"),K5.join(J,"Android/Sdk/cmdline-tools/latest/bin")];if($==="win32"){let X=process.env.LOCALAPPDATA,Q=X?K5.join(X,"Android","Sdk"):"";return[...Q?[K5.join(Q,"platform-tools"),K5.join(Q,"emulator"),K5.join(Q,"cmdline-tools","latest","bin")]:[]]}return[]}function OH0(){let $=Fe.homedir(),J=process.platform;if(J==="darwin")return[K5.join($,"Library/Android/sdk")];if(J==="linux")return[K5.join($,"Android/Sdk")];if(J==="win32"){let X=process.env.LOCALAPPDATA;return X?[K5.join(X,"Android","Sdk")]:[]}return[]}function Tw$($){try{return Ew$.statSync($).isDirectory()}catch{}return!1}E9();g_();function FH0($){let J=$.findIndex((Q)=>Q==="--cli"||Q==="--daemon"),X=J>=0?$.slice(0,J):$;return X.includes("--version")||X.includes("-v")}function Iw$($,J){return FH0($)?J:void 0}Hb();T7();yb();fb();iB();ub();ub();g_();pb();E9();import{parseArgs as EB0}from"util";var PB0=Object.fromEntries(["cli","daemon-mode","no-proxy","direct","no-daemon","debug-perf","ui-perf-debug","debug","no-ui-perf-mode","mem-perf-audit","accessibility-audit","predictive","predictive-ui","raw-element-search","embedded-sdk","network-mockable","dismiss-keyboard-after-input","mcp-recording","no-navigation-screenshots","no-waitfor-polling-overhead","no-include-not-important-views","no-report-view-ids","no-retrieve-interactive-windows","no-occlusion"].map(($)=>[$,{type:"boolean"}]));function kA$($,J,X=process.env){let{values:Q}=EB0({args:$,options:PB0,allowPositionals:!0,strict:!1}),Y=(u0)=>Q[u0]===!0,W,G,Z,j=Y("cli"),V=Y("daemon-mode"),K=Y("no-proxy")||Y("direct"),z=Y("no-daemon"),L=$.indexOf("--daemon"),H=L>=0?$[L+1]:void 0,O=L>=0?$.slice(L+2):[],B=Y("debug-perf")||Y("ui-perf-debug")||process.env.AUTOMOBILE_DEBUG_PERF==="1",F=Y("debug")||process.env.AUTOMOBILE_DEBUG==="1",A=!Y("no-ui-perf-mode"),_=Y("mem-perf-audit"),w=Y("accessibility-audit"),q,M,C,y=!1,I=Y("predictive")||Y("predictive-ui"),d=Y("raw-element-search"),u=Db($),r=Y("embedded-sdk"),a=Y("network-mockable"),Y$=Y("dismiss-keyboard-after-input"),J$=gb($,process.env),L$=hb($),O$=Y("mcp-recording"),_$=!Y("no-navigation-screenshots"),R$=Y("no-waitfor-polling-overhead"),j0=Y("no-include-not-important-views"),V0=Y("no-report-view-ids"),s0=Y("no-retrieve-interactive-windows"),n$=Y("no-occlusion"),d0=Cw$($,process.env),Q0=lb($,process.env,bB()),B0=X[t_]??X.AUTO_MOBILE_RUNNER_READINESS_TIMEOUT_MS,c=EU(B0),h=c;if(B0!==void 0&&c===void 0)J.warn(`Invalid ${t_}: ${B0}; expected an integer from ${oB} to ${rB}`);let F$="session",Q$={},b0=(u0,q1,w1)=>{if(!u0)return;let b8=w1?Number(u0):parseInt(u0,10);if(!Number.isFinite(b8)||b8<=0){J.warn(`Invalid ${q1}: ${u0}`);return}return w1?b8:Math.round(b8)},A4=(u0,q1)=>{if(!u0)return;if(!new Set(["low","medium","high"]).has(u0)){J.warn(`Invalid video quality preset (${q1}): ${u0}`);return}Q$.qualityPreset=u0},_4=(u0,q1)=>{if(!u0)return;if(u0!=="mp4"){J.warn(`Invalid video format (${q1}): ${u0}`);return}Q$.format=u0};A4(process.env.AUTOMOBILE_VIDEO_QUALITY_PRESET??process.env.AUTO_MOBILE_VIDEO_QUALITY_PRESET,"env");let d6=[[process.env.AUTOMOBILE_VIDEO_TARGET_BITRATE_KBPS??process.env.AUTO_MOBILE_VIDEO_TARGET_BITRATE_KBPS,"video target bitrate",!1,"targetBitrateKbps"],[process.env.AUTOMOBILE_VIDEO_MAX_THROUGHPUT_MBPS??process.env.AUTO_MOBILE_VIDEO_MAX_THROUGHPUT_MBPS,"video max throughput",!0,"maxThroughputMbps"],[process.env.AUTOMOBILE_VIDEO_FPS??process.env.AUTO_MOBILE_VIDEO_FPS,"video fps",!1,"fps"],[process.env.AUTOMOBILE_VIDEO_MAX_ARCHIVE_MB??process.env.AUTO_MOBILE_VIDEO_MAX_ARCHIVE_MB,"video max archive size",!0,"maxArchiveSizeMb"]];for(let[u0,q1,w1,b8]of d6){let P7=b0(u0,q1,w1);if(P7!==void 0)Q$[b8]=P7}_4(process.env.AUTOMOBILE_VIDEO_FORMAT??process.env.AUTO_MOBILE_VIDEO_FORMAT,"env");let M8=$.indexOf("--cli"),jJ=j?$.slice(M8+1):[];for(let u0=0;u0<$.length;u0++){let q1=$[u0];if(q1==="--cli")break;if(q1==="--port"){let w1=parseInt($[u0+1],10);if(!isNaN(w1)&&w1>0&&w1<65536)W=w1;else J.warn(`Invalid port: ${$[u0+1]}`);u0++}else if(q1==="--host"){let w1=$[u0+1];if(w1&&!w1.startsWith("--"))G=w1;else J.warn(`Invalid host: ${w1}`);u0++}else if(q1==="--initial-session-uuid"){let w1=$[u0+1];if(w1&&!w1.startsWith("--"))Z=w1;else J.warn(`Invalid initial session UUID: ${w1}`);u0++}else if(q1==="--a11y-level")q=$[++u0];else if(q1==="--a11y-failure-mode")M=$[++u0];else if(q1==="--a11y-min-severity")C=$[++u0];else if(q1==="--a11y-use-baseline")y=!0;else if(q1==="--plan-execution-lock-scope"){let w1=$[++u0];if(w1==="global"||w1==="session")F$=w1;else J.warn(`Invalid plan execution lock scope: ${w1}. Using default: ${F$}`)}else if(q1===a_){let w1=$[++u0],b8=EU(w1);if(b8!==void 0)h=b8;else J.warn(`Invalid runner readiness timeout: ${w1}; expected an integer from ${oB} to ${rB}`)}else if(q1==="--video-quality"||q1==="--video-quality-preset")A4($[++u0],"cli");else if(q1==="--video-target-bitrate-kbps"){let w1=b0($[++u0],"video target bitrate",!1);if(w1!==void 0)Q$.targetBitrateKbps=w1}else if(q1==="--video-max-throughput-mbps"){let w1=b0($[++u0],"video max throughput",!0);if(w1!==void 0)Q$.maxThroughputMbps=w1}else if(q1==="--video-fps"){let w1=b0($[++u0],"video fps",!1);if(w1!==void 0)Q$.fps=w1}else if(q1==="--video-format")_4($[++u0],"cli");else if(q1==="--video-archive-size-mb"){let w1=b0($[++u0],"video max archive size",!0);if(w1!==void 0)Q$.maxArchiveSizeMb=w1}}return{cliMode:j,cliArgs:jJ,daemonPort:W,daemonHost:G,initialSessionUuid:Z,debugPerf:B,debug:F,uiPerfMode:A,memPerfAuditMode:_,a11yAuditMode:w,a11yLevel:q,a11yFailureMode:M,a11yMinSeverity:C,a11yUseBaseline:y,predictiveUi:I,rawElementSearch:d,planExecutionLockScope:F$,videoRecordingDefaults:Q$,runnerReadinessTimeoutMs:h,daemonMode:V,daemonCommand:H,daemonArgs:O,skipCtrlProxyDownload:u,embeddedSdk:r,networkMockable:a,dismissKeyboardAfterInput:Y$,eventAllMarkers:J$,eventAllMarkersCliOverride:L$,mcpRecording:O$,navigationScreenshots:_$,noWaitForPollingOverhead:R$,noProxy:K,noDaemon:z,noA11yIncludeNotImportantViews:j0,noA11yReportViewIds:V0,noA11yRetrieveInteractiveWindows:s0,noOcclusion:n$,outputReduction:d0,toolOutputsDir:Q0}}X$$();U$();n();var bA$=5000;function vA$($){let J=$.timer??g,X=$.logger??U;if(yA$("Android CtrlProxy prefetch cleanup",$.startAndroidSweep,J,X),$.platform==="darwin")yA$("iOS CtrlProxy runner cleanup",$.startIosReap,J,X)}function yA$($,J,X,Q){let Y;try{Y=J()}catch(G){Q.warn(`[STARTUP_MAINTENANCE] ${$} failed: ${fA$(G)}`);return}let W=X.setTimeout(()=>{Q.warn(`[STARTUP_MAINTENANCE] ${$} exceeded ${bA$}ms; continuing startup`)},bA$);W.unref?.(),Y.catch((G)=>{Q.warn(`[STARTUP_MAINTENANCE] ${$} failed: ${fA$(G)}`)}).finally(()=>{X.clearTimeout(W)})}function fA$($){return $ instanceof Error?$.message:String($)}Pw$();process.env[c2]??=h_();var zb;function QH0($,J){let X=J instanceof Error?J.stack??J.message:String(J);if(zb)zb.error(`${$}: ${X}`);else console.error(`${$}: ${X}`)}var YH0=Iw$(process.argv.slice(2),P9());if(YH0!==void 0)console.log(YH0),process.exit(0);cb();nb(($)=>{if($.type==="uncaughtException"){QH0("Uncaught exception",$.error);return}QH0("Unhandled rejection",$.reason)});async function wT1(){y4.mark("processEntry"),y4.startPhase("moduleImports");let $=process.argv.slice(2),J=$.indexOf("--boot-device");if(J>=0){let{runBootDeviceCommand:j0}=await Promise.resolve().then(() => (CP$(),TP$));y4.endPhase("moduleImports"),await j0($.slice(J+1)),process.exit(0)}let{StdioServerTransport:X}=await Promise.resolve().then(() => (zI$(),UI$)),{createMcpServer:Q}=await Promise.resolve().then(() => (P2$(),a90)),{createProxyMcpServer:Y}=await Promise.resolve().then(() => (TJ0(),PJ0)),{logger:W,LogLevel:G}=await Promise.resolve().then(() => (n(),sw$));zb=W;let{runCliCommand:Z}=await Promise.resolve().then(() => (X50(),J50)),{runDaemonCommand:j}=await Promise.resolve().then(() => (NI(),DJ0)),{startDaemon:V}=await Promise.resolve().then(() => (tL0(),rL0)),{guardDatabaseStartup:K}=await Promise.resolve().then(() => (Ir(),bL$)),{DefaultDatabaseInitializer:z}=await Promise.resolve().then(() => (IL$(),W70)),L=await Promise.resolve().then(() => (kr(),H70)),H=await Promise.resolve().then(() => (xr(),O70)),O=await Promise.resolve().then(() => (br(),B70)),B=await Promise.resolve().then(() => (vr(),q70)),F=await Promise.resolve().then(() => (Le(),RL0)),A=await Promise.resolve().then(() => (fr(),F70)),{FeatureFlagService:_}=await Promise.resolve().then(() => (iV(),El$)),{serverConfig:w}=await Promise.resolve().then(() => (p4(),CA$)),{AndroidCtrlProxyManager:q}=await Promise.resolve().then(() => (o7(),Ov$)),{IOSCtrlProxyBuilder:M}=await Promise.resolve().then(() => (vP(),Wg$)),{IOSCtrlProxyManager:C}=await Promise.resolve().then(() => (XW(),Mg$));y4.endPhase("moduleImports");let{startVideoRecordingSocketServer:y,stopVideoRecordingSocketServer:I}=L,{startTestRecordingSocketServer:d,stopTestRecordingSocketServer:u}=H,{startDeviceSnapshotSocketServer:r,stopDeviceSnapshotSocketServer:a}=O,{startAppearanceSocketServer:Y$,stopAppearanceSocketServer:J$}=B,{startWebRtcStreamSocketServer:L$,stopWebRtcStreamSocketServer:O$}=F,{startAppearanceSyncScheduler:_$,stopAppearanceSyncScheduler:R$}=A;db(async(j0)=>{W.info(`Received ${j0} signal, shutting down`),await I(),await u(),await a(),await J$(),await O$(),R$(),await q.cleanupPrefetchedApk(),W.close()});try{let{cliMode:j0,cliArgs:V0,daemonPort:s0,daemonHost:n$,initialSessionUuid:d0,debugPerf:Q0,debug:B0,uiPerfMode:c,memPerfAuditMode:h,a11yAuditMode:F$,a11yLevel:Q$,a11yFailureMode:b0,a11yMinSeverity:A4,a11yUseBaseline:_4,predictiveUi:d6,rawElementSearch:M8,planExecutionLockScope:jJ,runnerReadinessTimeoutMs:u0,videoRecordingDefaults:q1,daemonMode:w1,daemonCommand:b8,daemonArgs:P7,skipCtrlProxyDownload:G5,embeddedSdk:oW,networkMockable:rW,dismissKeyboardAfterInput:tW,eventAllMarkers:qQ,eventAllMarkersCliOverride:wQ,mcpRecording:pj,navigationScreenshots:BU,noWaitForPollingOverhead:l2,noProxy:aW,noDaemon:V$,noA11yIncludeNotImportantViews:B$,noA11yReportViewIds:I$,noA11yRetrieveInteractiveWindows:X0,noOcclusion:X1,outputReduction:A6,toolOutputsDir:S6}=kA$(process.argv.slice(2),W);if(B0)W.setLogLevel(G.DEBUG);if(w.setPlanExecutionLockScope(jJ),u0!==void 0)w.setRunnerReadinessTimeoutMs(u0);if(w.setVideoRecordingDefaults(q1),w.setToolOutputsDir(S6),w.setSkipCtrlProxyDownload(G5),w.setEmbeddedSdkEnabled(oW),w.setNetworkMockableEnabled(rW),w.setDismissKeyboardAfterInputEnabled(tW),w.setEventAllMarkers(qQ),vA$({platform:process.platform,startAndroidSweep:()=>q.sweepStalePrefetchDirsOnStartup(),startIosReap:()=>C.startOrphanRunnerReapOnStartup()}),G5)W.info(`CtrlProxy downloads disabled (${Ne} or ${DU})`),y4.recordPhase("androidCtrlProxyPrefetch",0);else y4.startPhase("androidCtrlProxyPrefetch"),q.prefetchApk().then(()=>{y4.endPhase("androidCtrlProxyPrefetch")});if(process.platform==="darwin")if(G5)W.info(`CtrlProxy iOS prefetch disabled (${Ne} or ${DU})`),y4.recordPhase("iosCtrlProxyPrefetch",0);else y4.startPhase("iosCtrlProxyPrefetch"),M.prefetchBuild().then(()=>{y4.endPhase("iosCtrlProxyPrefetch")});if(AA$(),process.platform==="darwin"&&process.env[Q8.WHIP_ENDPOINT]?.trim()&&!process.env.AUTOMOBILE_IOS_SCREEN_CAPTURE_HELPER&&!process.env.AUTO_MOBILE_IOS_SCREEN_CAPTURE_HELPER)$G.getInstance().ensure().catch((T1)=>{W.warn(`[SCREEN_CAPTURE_HELPER] Background prefetch failed: ${T1 instanceof Error?T1.message:String(T1)}`)});let b1=_.getInstance(),m0=[["debug",B0,"--debug"],["debug-perf",Q0,"--debug-perf/--ui-perf-debug"],["ui-perf-mode",c,"--ui-perf-mode"],["mem-perf-audit",h,"--mem-perf-audit"],["accessibility-audit",F$,"--accessibility-audit",F$?{level:Q$||"AA",failureMode:b0||"report",minSeverity:A4||(b0==="strict"?"error":"warning"),useBaseline:_4}:null],["predictive-ui",d6,"--predictive/--predictive-ui"],["raw-element-search",M8,"--raw-element-search"],["mcp-recording",pj,"--mcp-recording"],...yB.map((T1)=>[T1.featureFlagKey,A6[T1.field],T1.label,void 0])],n0=async()=>{await b1.initialize();for(let[T1,D8,NQ,sW]of m0){if(!D8)continue;await b1.setFlag(T1,!0,sW),W.info(`Feature flag enabled (${NQ})`)}if(!BU)await b1.setFlag("navigation-screenshots",!1),W.info("Navigation screenshots disabled (--no-navigation-screenshots)")};if(await y4.runPhase("databasePreflight",async()=>{if(w1)await K(async()=>{await new z().initialize(),await n0()});else{let{runDirectModeStartup:T1}=await Promise.resolve().then(() => aL0);await T1({noProxy:aW,assertDbOwnership:async()=>{let{assertDirectModeDbOwnership:D8,createDefaultDirectModeGuardDeps:NQ}=await Promise.resolve().then(() => (XH0(),JH0));D8(NQ())},applyFeatureFlagStartup:n0})}}),l2)w.setWaitForPollingOverheadEnabled(!1),W.info("WaitFor polling overhead disabled (--no-waitfor-polling-overhead): screenshots and back stack skipped during observe waitFor polling");let Q1=[[!c,"UI perf mode disabled (--no-ui-perf-mode): skipping selection-state visual capture on taps and UI perf auditing"],[oW,"Embedded SDK tools enabled (--embedded-sdk)"],[tW,"Dismiss keyboard after inputText enabled (--dismiss-keyboard-after-input)"],[B$,"Accessibility includeNotImportantViews disabled (--no-include-not-important-views)"],[I$,"Accessibility reportViewIds disabled (--no-report-view-ids)"],[X0,"Accessibility retrieveInteractiveWindows disabled (--no-retrieve-interactive-windows)"],[X1,"Observe occlusion pass disabled (--no-occlusion)"]];for(let[T1,D8]of Q1)if(T1)W.info(D8);if(qQ.length>0)W.info(`inputText eventAll auto-promotion markers configured (--event-all-markers): ${JSON.stringify(qQ)}`);else if(process.argv.slice(2).some((T1)=>T1===JG||T1.startsWith(`${JG}=`)))W.warn(`${JG} was provided but resolved to no markers; inputText eventAll auto-promotion stays disabled`);let S1=qQ.length>0||wQ?{eventAllMarkers:qQ,eventAllMarkersCliOverride:wQ}:{};if(w1){await V({port:s0,...n$!==void 0?{host:n$}:{},debug:B0,debugPerf:Q0,planExecutionLockScope:jJ,...u0!==void 0?{runnerReadinessTimeoutMs:u0}:{},videoQualityPreset:q1.qualityPreset,videoTargetBitrateKbps:q1.targetBitrateKbps,videoMaxThroughputMbps:q1.maxThroughputMbps,videoFps:q1.fps,videoFormat:q1.format,videoMaxArchiveSizeMb:q1.maxArchiveSizeMb,toolOutputsDir:S6,networkMockable:rW,embeddedSdk:oW,dismissKeyboardAfterInput:tW,...S1,noUiPerfMode:!c,memPerfAudit:h,accessibilityAudit:F$,accessibilityLevel:Q$,accessibilityFailureMode:b0,accessibilityMinSeverity:A4,accessibilityUseBaseline:_4,predictiveUi:d6,rawElementSearch:M8,skipCtrlProxyDownload:G5,mcpRecording:pj,noNavigationScreenshots:!BU,noWaitForPollingOverhead:l2,noA11yIncludeNotImportantViews:B$,noA11yReportViewIds:I$,noA11yRetrieveInteractiveWindows:X0,noOcclusion:X1,...A6});return}if(b8)await j(b8,P7),W.close(),process.exit(0);let b4={debug:B0,debugPerf:Q0,planExecutionLockScope:jJ,...u0!==void 0?{runnerReadinessTimeoutMs:u0}:{},mcpRecording:pj,videoQualityPreset:q1.qualityPreset,videoTargetBitrateKbps:q1.targetBitrateKbps,videoMaxThroughputMbps:q1.maxThroughputMbps,videoFps:q1.fps,videoFormat:q1.format,videoMaxArchiveSizeMb:q1.maxArchiveSizeMb,toolOutputsDir:S6,networkMockable:rW,embeddedSdk:oW,dismissKeyboardAfterInput:tW,...S1,noUiPerfMode:!c,memPerfAudit:h,accessibilityAudit:F$,accessibilityLevel:Q$,accessibilityFailureMode:b0,accessibilityMinSeverity:A4,accessibilityUseBaseline:_4,predictiveUi:d6,rawElementSearch:M8,skipCtrlProxyDownload:G5,noNavigationScreenshots:!BU,noWaitForPollingOverhead:l2,noA11yIncludeNotImportantViews:B$,noA11yReportViewIds:I$,noA11yRetrieveInteractiveWindows:X0,noOcclusion:X1,...A6};if(j0)W.info("Running in CLI mode"),await Z(V0,b4),W.close(),process.exit(0);else{let T1=!aW;if(T1)W.info("Starting MCP server in proxy mode (connecting to daemon)");else W.info("Starting MCP server in direct mode (--no-proxy flag)"),await y(),await d(),await r(),await Y$(),await L$(),_$();let D8=()=>{W.info("stdin closed \u2014 MCP client disconnected, shutting down"),W.close(),process.exit(0)};process.stdin.on("end",D8),process.stdin.on("error",D8),process.stdin.on("close",D8);let NQ=new X,sW,p2;try{if(T1){let R8=Y({proxyConfig:{autoStartDaemon:!V$,daemonOptions:b4,initialSessionUuid:d0}});sW=R8.server,p2=R8.proxy}else sW=Q({debug:B0})}catch(R8){throw W.error("Failed to create MCP server:",R8),R8}try{if(W.info("Connecting MCP server to stdio transport"),y4.startPhase("serverListening"),await sW.connect(NQ),y4.endPhase("serverListening"),W.info("MCP server connected to stdio transport"),W.info(`AutoMobile MCP server running on stdio (${T1?"proxy":"direct"} mode)`),y4.emit("mcp-server",{transport:"stdio",mode:T1?"proxy":"direct"}),p2){let R8=async()=>{await p2.close()};process.on("beforeExit",R8)}}catch(R8){throw W.error("MCP server connect failed:",R8),R8}}}catch(j0){throw W.error("Error initializing server:",j0),j0}}if(import.meta.main)wT1().catch(async($)=>{console.error("Fatal error in main():",$),zb?.error("Fatal error in main():",$),zb?.close();let{resolveDaemonStartupExitCode:J}=await Promise.resolve().then(() => (Ir(),bL$));process.exit(J($))});
|
|
1147
1147
|
|
|
1148
|
-
//# debugId=
|
|
1148
|
+
//# debugId=6E45D53AF93AC53D64756E2164756E21
|