
    !/i                     ~   d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	m
Z
 ddlmZmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZ ddlmZ dd	lmZ ddlZdd
lmZ ddlm Z   ejB                  ejD                          ejF                  e$      Z% G d de      Z& G d de      Z'e G d d             Z(e G d d             Z)e G d d             Z* G d de	      Z+ G d de+      Z, G d de+      Z- G d de+      Z. G d d       Z/ed%d!ee(   fd"       Z0d# Z1e$d$k(  r ejd                   e1              yy)&a  
GENESIS BROWSER CONTROLLER
===========================
Unified resilient multi-leveled advanced browser automation with failsafe capabilities.

Multi-Level Architecture:
    Level 1: Playwright (Primary) - Fastest, most reliable
    Level 2: Selenium WebDriver - Wide browser support
    Level 3: CDP (Chrome DevTools Protocol) - Direct control
    Level 4: HTTP Client - Headless API fallback
    Level 5: Cached/Archive - Wayback Machine fallback

Failsafe Features:
    - Automatic level escalation on failure
    - Request retry with exponential backoff
    - Proxy rotation support
    - Anti-detection measures
    - Session persistence and recovery
    - Screenshot capture on errors
    - Automatic CAPTCHA detection
    - Resource timeout management

Usage:
    controller = BrowserController()
    result = await controller.navigate("https://example.com")
    content = await controller.get_content()
    N)ABCabstractmethod)	dataclassfield)datetime)Path)DictListAnyOptionalCallableTuple)Enum)asynccontextmanager)GHLSynergyBridge)VisionWorker)levelc                   $    e Zd ZdZdZdZdZdZdZy)BrowserLevelz+Browser automation levels (priority order).               N)	__name__
__module____qualname____doc__
PLAYWRIGHTSELENIUM
CDP_DIRECTHTTP_CLIENTARCHIVE     0/mnt/e/genesis-system/core/browser_controller.pyr   r   5   s    5JHJKGr%   r   c                   ,    e Zd ZdZdZdZdZdZdZdZ	dZ
y	)
NavigationStatuszNavigation result status.successtimeouterrorblockedcaptcharate_limited	not_foundN)r   r   r   r   SUCCESSTIMEOUTERRORBLOCKEDCAPTCHARATE_LIMITED	NOT_FOUNDr$   r%   r&   r(   r(   >   s(    #GGEGG!LIr%   r(   c                       e Zd ZU dZdZeed<   dZeed<   dZ	eed<   dZ
eed	<   d
Zee   ed<   d
Zee   ed<   d
Zee   ed<   dZeed<   dZeed<   dZeed<   dZeed<   d Zy
)BrowserConfigz,Browser configuration with validation logic.Theadlessi0u  
timeout_msi  viewport_widthi8  viewport_heightN
user_agentproxycookies_filescreenshot_on_errorr   max_retries  retry_delay_msanti_detectionc                    t        dt        | j                  d            | _        t        dt        | j                  d            | _        t        dt        | j                  d            | _        t        dt        | j
                  d            | _        t        d	t        | j                  d
            | _        | j                  r6t        | j                  t              st        | j                        | _        yyy)z"Validate configuration parameters.i   i   iX  ip    i r   
   d   i'  N)
maxminr;   r<   r:   rA   rC   r?   
isinstancer   selfs    r&   __post_init__zBrowserConfig.__post_init__X   s     "#s4+>+>'EF"3D,@,@$(GH dC$@A q#d&6&6";<!#s4+>+>'FG Z0A0A4%H $T%6%6 7D &Ir%   )r   r   r   r   r9   bool__annotations__r:   intr;   r<   r=   r   strr>   r?   r   r@   rA   rC   rD   rN   r$   r%   r&   r8   r8   I   s    6HdJNCOS $J$E8C=#'L(4.' $$KNCND8r%   r8   c                   "   e Zd ZU dZeed<   eed<   eed<   dZe	e   ed<   dZ
e	e   ed<   dZe	e   ed<   d	Zeed
<   d	Zeed<   dZe	e   ed<    ee      Zeeef   ed<    ee      Zeeef   ed<   dZe	e   ed<    ee      Zeeef   ed<   y)NavigationResultzResult from navigation attempt.urlstatus
level_usedNcontenthtmltitler   status_codeduration_msscreenshot_pathdefault_factorycookiesheadersr+   metadata)r   r   r   r   rR   rP   r(   r   rX   r   rY   rZ   r[   rQ   r\   r]   r   r   dictr`   r	   ra   r+   rb   r   r$   r%   r&   rT   rT   j   s    )	H!GXc]!D(3-E8C=KK&*OXd^*#D9GT#s(^9#D9GT#s(^9E8C=$T:Hd38n:r%   rT   c                   |    e Zd ZU dZeed<   eed<   dZee   ed<    e	e
      Zeeef   ed<   dZeed	<   dZeed
<   y)ElementResultz Result from element interaction.selectorfoundNtextr^   
attributesFvisible	clickable)r   r   r   r   rR   rP   rO   rh   r   r   rc   ri   r	   rj   rk   r$   r%   r&   re   re   |   sH    *MKD(3-!&t!<JS#X<GTItr%   re   c                   N   e Zd ZdZedefd       Zedefd       Zede	fd       Z
edede	fd       Zededefd	       Zedefd
       Zededee   fd       Zedede	fd       Zededede	fd       Zedede	fd       Zededefd       Zedefd       Zed        Zy)BrowserBackendz)Abstract base class for browser backends.returnc                      y)zBackend name.Nr$   rL   s    r&   namezBrowserBackend.name        	r%   c                      y)zBackend priority level.Nr$   rL   s    r&   r   zBrowserBackend.level   rq   r%   c                    K   yw)zCheck if backend is available.Nr$   rL   s    r&   is_availablezBrowserBackend.is_available         	   configc                    K   yw)zInitialize the browser.Nr$   )rM   rw   s     r&   
initializezBrowserBackend.initialize   ru   rv   rU   c                    K   yw)zNavigate to URL.Nr$   )rM   rU   s     r&   navigatezBrowserBackend.navigate   ru   rv   c                    K   yw)zGet page content.Nr$   rL   s    r&   get_contentzBrowserBackend.get_content   ru   rv   rf   c                    K   yw)zFind element by selector.Nr$   rM   rf   s     r&   find_elementzBrowserBackend.find_element   ru   rv   c                    K   yw)Click element.Nr$   r   s     r&   clickzBrowserBackend.click   ru   rv   rh   c                    K   yw)Type text into element.Nr$   rM   rf   rh   s      r&   	type_textzBrowserBackend.type_text   ru   rv   pathc                    K   yw)zTake screenshot.Nr$   rM   r   s     r&   
screenshotzBrowserBackend.screenshot   ru   rv   scriptc                    K   ywz(Evaluate JavaScript in the page context.Nr$   rM   r   s     r&   evaluatezBrowserBackend.evaluate   ru   rv   c                    K   yw)z/Add script to be evaluated on every navigation.Nr$   r   s     r&   add_init_scriptzBrowserBackend.add_init_script   ru   rv   c                    K   yw)zClose browser.Nr$   rL   s    r&   closezBrowserBackend.close   ru   rv   N)r   r   r   r   r   rR   rp   r   r   rO   rt   r8   ry   rT   r{   r}   r   re   r   r   r   r   r   r   r   r   r   r$   r%   r&   rm   rm      s   3c   |   D   }    # *:   3   3 8M3J   C D    3 4   T d   S S   C    r%   rm   c                      e Zd ZdZd ZdefdZdefdZde	fdZ
dede	fdZde	fd	Zdefd
ZdefdZdedefdZdede	fdZdefdZdedee   fdZdede	fdZdedede	fdZdede	fdZdedefdZdefdZd Zy)PlaywrightBackendz/Playwright browser backend (Level 1 - Primary).c                 <    d | _         d | _        d | _        d | _        y N)_browser_context_page
_availablerL   s    r&   __init__zPlaywrightBackend.__init__   s    
r%   rn   c                      y)N
Playwrightr$   rL   s    r&   rp   zPlaywrightBackend.name   s    r%   c                 "    t         j                  S r   )r   r   rL   s    r&   r   zPlaywrightBackend.level   s    &&&r%   c                    K   | j                   	 ddlm} d| _         | j                   S | j                   S # t        $ r d| _         Y | j                   S w xY ww)Nr   async_playwrightTF)r   playwright.async_apir   ImportError)rM   r   s     r&   rt   zPlaywrightBackend.is_available   sU     ??"(A"& t  ("'(s%   A5 AAAAArw   c                    K    j                          d{   syd}d}d}	 ddlm}  |       j                          d{    _        d} j                  j
                  j                  |j                         d{    _        d}d|j                  |j                  di}|j                  r|j                  |d	<   n|j                  r j                         |d	<   |j                  rd
|j                  i|d<     j                  j                  di | d{    _        d}t#         d      rNt#         j$                  d      r8	  j                   j'                   j$                  j(                         d{     j                   j1                          d{    _        t#         d      st5                _         fd} j2                  j9                  d|       |j:                  r=|j:                  j=                         r# j?                  |j:                         d{    y7 7 7 7 7 # t*        $ r"}t,        j/                  d|        Y d}~d}~ww xY w7 7 C# t*        $ ra}	t,        jA                  d|	        |rf j                   rZ	  j                   jC                          d{  7   n.# t*        $ r"}
t,        jE                  d|
        Y d}
~
nd}
~
ww xY wd _        |rf j                  rZ	  j                  jC                          d{  7   n.# t*        $ r"}
t,        jE                  d|
        Y d}
~
nd}
~
ww xY wd _        |rf j                  rZ	  j                  jG                          d{  7   n.# t*        $ r"}
t,        jE                  d|
        Y d}
~
nd}
~
ww xY wd _        d _        Y d}	~	yd}	~	ww xY ww)zu
        Initialize Playwright backend.

        UVS-H13: Proper resource cleanup on initialization failure.
        NFr   r   T)r9   viewport)widthheightr=   serverr>   
controller_sparkle_scriptz0Sparkle script injection failed (CSP-blocked?): _tracked_tasksc                 (   d| j                   v rt        d      rvj                  j                  r_t	        j
                  j                  j                               }j                  j                  |       fd}|j                  |       y y y y )NGENESIS_USER_ACTIVITYr   c                     j                   j                  |        | j                         r't        j	                  d| j                                 y y )NzUser activity task exception: )r   discard	exceptionloggerwarning)trM   s    r&   
_task_donezHPlaywrightBackend.initialize.<locals>.handle_console.<locals>._task_done%  sC     //77: {{} &1OPQP[P[P]/_ `  -r%   )	rh   hasattrr   on_user_activityasynciocreate_taskr   addadd_done_callback)msgtaskr   rM   s      r&   handle_consolez4PlaywrightBackend.initialize.<locals>.handle_console  sz    *chh6t\2t7W7W&224??3S3S3UV++//5a
 ..z: 8X2 7r%   consolez"Playwright initialization failed: zContext cleanup error: zBrowser cleanup error: zPlaywright cleanup error: r$   )$rt   r   r   start_playwrightchromiumlaunchr9   r   r;   r<   r=   rD   _generate_user_agentr>   new_contextr   r   r   r   r   	Exceptionr   r   new_pager   setr   onr?   exists_load_cookiesr+   r   debugstop)rM   rw   init_playwrightinit_browserinit_contextr   context_optionssparkle_errr   ecleanup_errs   `          r&   ry   zPlaywrightBackend.initialize   sn     &&(((  V	=%5%7%=%=%??D"O"&"2"2";";"B"B #C # DM  L #22$44O   060A0A-&&040I0I0K-||,4fll+C(";$--";";"No"NNDML t\*wtHY/Ze--778W8WXXX
  $}}5577DJ 4!12&)e#; JJMM)^4""v':':'A'A'C(()<)<===O )  @( O Y  eNN%UVaUb#cdde 80 >  	LL=aSABJ----///  JLL#:;-!HIIJ $J----///  JLL#:;-!HIIJ $4#3#3M**//111  MLL#=k]!KLLM#' DJ-	sl  O H2O I2 H5>I2 H8BI2 H; -I2 2I   H>I  I2 "I.#B	I2 ,I0-I2 1O 5I2 8I2 ;I2 >I   	I+	I&!I2 &I++I2 0I2 2
O<&O#K KKO	K2K-(O-K22OL/(L+)L/.O/	M8MOMO3NNNO	O N=8O=OOO OO c                    K   | j                   r| j                  sy	 | j                   j                         xr | j                  j                          S #  Y yxY ww)z+Check if browser and page are still active.F)r   r   is_connected	is_closedrL   s    r&   is_alivezPlaywrightBackend.is_aliveJ  sL     }}DJJ	==--/N

8L8L8N4NN	s   A6A AAAc                 4    g d}t        j                  |      S )zGenerate realistic user agent.)zoMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36zPMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0)randomchoice)rM   agentss     r&   r   z&PlaywrightBackend._generate_user_agentT  s    

 }}V$$r%   r?   c                    K   	 t        |d      5 }t        j                  |      }| j                  j	                  |       d{    ddd       y7 # 1 sw Y   yxY w# t
        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)zLoad cookies from file.rNzFailed to load cookies: )openjsonloadr   add_cookiesr   r   r   )rM   r?   fr`   r   s        r&   r   zPlaywrightBackend._load_cookies]  s     	;lC( 9A))A,mm//8889 989 9  	;NN5aS9::	;sc   BA  4AAA	A  BAAA  BA   	B)BBBBrU   c           
        K   | j                   s+t        |t        j                  | j	                         d      S t        j
                         }	 | j                   j                  |d       d {   }t        t        j
                         |z
  dz        }|r|j                  nd}| j                   j                          d {   }| j                   j                          d {   }t        j                  }|dk(  rt        j                  }nM|dk(  rt        j                  }n7|d	k(  rt        j                  }n!| j                  |      rt        j                   }t        ||| j	                         ||||
      S 7 7 7 # t"        j$                  $ rP t        |t        j&                  | j	                         t        t        j
                         |z
  dz        d      cY S t(        $ r`}	t        |t        j                  | j	                         t        t        j
                         |z
  dz        t+        |	            cY d }	~	S d }	~	ww xY ww)NzBrowser not initializedrU   rV   rW   r+   domcontentloaded)
wait_untilrB   r         )rU   rV   rW   rY   rZ   r[   r\   zNavigation timeoutrU   rV   rW   r\   r+   )r   rT   r(   r2   r   timegotorQ   rV   rZ   rX   r0   r3   r5   r6   _detect_captchar4   r   TimeoutErrorr1   r   rR   )
rM   rU   r   responser\   r[   rZ   rY   rV   r   s
             r&   r{   zPlaywrightBackend.navigatef  s    zz#'--::</	  		,	!ZZ__S=O_PPHtyy{U2d:;K-5(//1K****,,E++--D &--Fc!)11#)66#)33%%d+)11#::<'' % Q --. ## 	#'//::<u!4 <=*   	#'--::<u!4 <=!f 	s|   AI F /E>0AF F!F &F'BF =I>F F F A I%I'I/AI
II
IIrY   c                 T    g d}|j                         t        fd|D              S )zDetect CAPTCHA presence.)	recaptchar-   hcaptchazchallenge-runningzcf-turnstilezplease verifyzsecurity checkc              3   &   K   | ]  }|v  
 y wr   r$   ).0pattern
html_lowers     r&   	<genexpr>z4PlaywrightBackend._detect_captcha.<locals>.<genexpr>  s     IW7j(Is   )lowerany)rM   rY   captcha_patternsr   s      @r&   r   z!PlaywrightBackend._detect_captcha  s*    
 ZZ\
I8HIIIr%   c                 l   K   | j                   sy| j                   j                          d {   S 7 wN )r   rX   rL   s    r&   r}   zPlaywrightBackend.get_content  s)     zzZZ''))))s   +424rf   c                   K   | j                   sy 	 | j                   j                  |       d {   }|st        |d      S |j                          d {   }|j	                          d {   }|j                          d {   }t        |d|||      S 7 k7 F7 07 # t        $ r t        |d      cY S w xY ww)NFrf   rg   T)rf   rg   rh   rj   rk   )r   query_selectorre   text_content
is_visible
is_enabledr   )rM   rf   elementrh   rj   rk   s         r&   r   zPlaywrightBackend.find_element  s     zz	A JJ55h??G$heDD --//D#..00G%0022I !#  @ 002  	A (%@@	Asz   B?B# BB# B?B# BB# .B/B# B!B# B?B# B# B# !B# #B<9B?;B<<B?c                    K   | j                   sy	 | j                   j                  |       d {    y7 # t        $ r"}t        j	                  d|        Y d }~yd }~ww xY ww)NFTzClick failed: )r   r   r   r   r   )rM   rf   r   s      r&   r   zPlaywrightBackend.click  sZ     zz	**""8,,, - 	NN^A3/0	s7   A%7 57 A%7 	A" AA%A""A%rh   c                    K   | j                   sy	 | j                   j                  ||       d {    y7 # t        $ r"}t        j	                  d|        Y d }~yd }~ww xY ww)NFTzType failed: )r   fillr   r   r   )rM   rf   rh   r   s       r&   r   zPlaywrightBackend.type_text  sZ     zz	**//(D111 2 	NN]1#./	s7   A&8 68 A&8 	A#AA&A##A&r   c                    K   | j                   sy	 | j                   j                  t        |             d {    y7 # t        $ r"}t        j                  d|        Y d }~yd }~ww xY ww)NF)r   TzScreenshot failed: )r   r   rR   r   r   r   )rM   r   r   s      r&   r   zPlaywrightBackend.screenshot  sb     zz	**''SY'777 8 	NN045	s;   A/(A ?A A/A 	A,
A'"A/'A,,A/r   c                    K   | j                   sy 	 | j                   j                  |       d {   S 7 # t        $ r"}t        j	                  d|        Y d }~y d }~ww xY ww)NzEvaluation failed: )r   r   r   r   r   )rM   r   r   s      r&   r   zPlaywrightBackend.evaluate  sV     zz	,,V4444 	NN045	s6   A$6 46 A$6 	A!AA$A!!A$c                    K   | j                   r$| j                   j                  |       d {    y | j                  r$| j                  j                  |       d {    y y 7 67 wr   )r   r   r   r   s     r&   r   z!PlaywrightBackend.add_init_script  sR     ==--//777ZZ**,,V444  84s!   +A(A$/A(A&A(&A(c                    K   | j                   r"| j                   j                          d {    t        | d      r0| j                  r#| j                  j	                          d {    y y y 7 A7 	w)Nr   )r   r   r   r   r   rL   s    r&   r   zPlaywrightBackend.close  s^     ==--%%'''4'D,<,<""''))) -=' ()s!   *A2A.9A2&A0'A20A2N)r   r   r   r   r   rR   rp   r   r   rO   rt   r8   ry   r   r   r   r   rT   r{   r   r}   r   re   r   r   r   r   r   r   r   r   r$   r%   r&   r   r      s   9c '| 'D d} d dL %c %; ;6# 6*: 6pJC JD J*3 *
A3 A8M3J A.C D  3 4 T d S S 5C 5*r%   r   c                       e Zd ZdZd ZdefdZdefdZde	fdZ
dede	fdZd	edefd
ZdefdZdedee   fdZdede	fdZdedede	fdZdede	fdZdedefdZdefdZd Zy)HTTPClientBackendz2HTTP client backend (Level 4 - Headless fallback).c                 .    d | _         d | _        d | _        y r   )_session_last_responser   rL   s    r&   r   zHTTPClientBackend.__init__  s    "r%   rn   c                      y)NzHTTP Clientr$   rL   s    r&   rp   zHTTPClientBackend.name  s    r%   c                 "    t         j                  S r   )r   r"   rL   s    r&   r   zHTTPClientBackend.level  s    '''r%   c                    K   | j                   	 dd l}d| _         | j                   S | j                   S # t        $ r1 	 dd l}d| _         n# t        $ r
 d| _         Y nw xY wY | j                   S w xY wwNr   TF)r   httpxr   aiohttp)rM   r  r  s      r&   rt   zHTTPClientBackend.is_available  ss     ??","& t  ,,"&*DO" ,&+DO,,sH   A03 A0	A-A	A-	AA-AA-A0,A--A0rw   c                   K   | j                          d{   syd}	 ddl}d|j                  xs di}|j                  ||j                  dz  dd      | _        d}y7 H# t        $ r}t        j                  d	|        |rf| j
                  rZ	 | j
                  j                          d{  7   n.# t        $ r"}t        j                  d
|        Y d}~nd}~ww xY wd| _        Y d}~yd}~ww xY ww)zu
        Initialize HTTP client backend.

        UVS-H14: Proper session cleanup on initialization failure.
        NFr   z
User-Agentz<Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36rB   T)ra   r*   follow_redirectshttp2zHTTP client init failed: zSession cleanup error: )rt   r  r=   AsyncClientr:   r  r   r   r+   acloser   )rM   rw   session_createdr  ra   r   r   s          r&   ry   zHTTPClientBackend.initialize  s      &&(((	 f//q3qG "--))D0!%	 . DM #O' )(  		LL4QC894==J--..000  JLL#:;-!HIIJ $		sn   C7AC7?A! C7!	C4*&C/B5.B1/B54C/5	C >CC/C  
C/*C7/C44C7rU   c                   K   | j                   s+t        |t        j                  | j	                         d      S t        j
                         }	 | j                  r#	 | j                  j                          d {    | j                   j                  |       d {   }|| _        t        t        j
                         |z
  dz        }|j                  }t        j                  d|t        j                        }|r|j                  d      nd }t        j                   }|j"                  dk(  rt        j$                  }n_|j"                  dk(  rt        j&                  }n?|j"                  dk(  rt        j(                  }n|j"                  d	k\  rt        j                  }t        ||| j	                         |||j"                  |t+        |j,                        
      S 7 e# t        $ r Y ow xY w7 U# t        $ r`}	t        |t        j                  | j	                         t        t        j
                         |z
  dz        t/        |	            cY d }	~	S d }	~	ww xY ww)NClient not initializedr   rB   <title[^>]*>([^<]+)</title>r   r   r   r   i  )rU   rV   rW   rY   rZ   r[   r\   ra   r   )r  rT   r(   r2   r   r   r  r  r   getrQ   rh   research
IGNORECASEgroupr0   r[   r3   r5   r6   rc   ra   rR   )
rM   rU   r   r   r\   rY   title_matchrZ   rV   r   s
             r&   r{   zHTTPClientBackend.navigate7  s    }}#'--::<.	  		,	""--44666 "]]..s33H"*Dtyy{U2d:;K ==D))$BD"--XK,7K%%a(TE%--F##s*)11%%,)66%%,)33%%,)//#::<$00'X--.	 	- 7  3<  	#'--::<u!4 <=!f 	sz   AI G4 G! 9G:G! >G4 G1E G4 I G! !	G.*G4 -G..G4 4	I=AIII II c                 P   K   | j                   r| j                   j                  S ywr   )r  rh   rL   s    r&   r}   zHTTPClientBackend.get_contento  s$     &&+++s   $&rf   c                 $   K   t        |d      S wNFr  re   r   s     r&   r   zHTTPClientBackend.find_elementt  s     he<<   c                    K   ywNFr$   r   s     r&   r   zHTTPClientBackend.clickx  	     rv   rh   c                    K   ywr.  r$   r   s      r&   r   zHTTPClientBackend.type_text{  r/  rv   r   c                    K   ywr.  r$   r   s     r&   r   zHTTPClientBackend.screenshot~  r/  rv   r   c                    K   y wr   r$   r   s     r&   r   zHTTPClientBackend.evaluate  	     rv   c                    K   y wr   r$   r   s     r&   r   z!HTTPClientBackend.add_init_script  	     rv   c                 n   K   | j                   r#| j                   j                          d {    y y 7 wr   )r  r  rL   s    r&   r   zHTTPClientBackend.close  s+     ==--&&((( (   *535Nr   r   r   r   r   rR   rp   r   r   rO   rt   r8   ry   rT   r{   r}   r   re   r   r   r   r   r   r   r   r   r   r$   r%   r&   r  r    s    <
c (| (D #} # #J6# 6*: 6p3 
=3 =8M3J =C D  3 4 T d S S C )r%   r  c                       e Zd ZdZd ZdefdZdefdZde	fdZ
dede	fdZd	edefd
ZdefdZdedee   fdZdede	fdZdedede	fdZdede	fdZdedefdZdefdZd Zy)ArchiveBackendz1Wayback Machine fallback (Level 5 - Last resort).c                      d | _         d | _        y r   )_client_last_contentrL   s    r&   r   zArchiveBackend.__init__  s    !r%   rn   c                      y)NzWayback Archiver$   rL   s    r&   rp   zArchiveBackend.name  s     r%   c                 "    t         j                  S r   )r   r#   rL   s    r&   r   zArchiveBackend.level  s    ###r%   c                 4   K   	 dd l }y# t        $ r Y yw xY wwr  )r  r   )rM   r  s     r&   rt   zArchiveBackend.is_available  s"     	 		s   	 	rw   c                 |   K   	 dd l }|j                  |j                  dz        | _        y# t        $ r Y yw xY ww)Nr   rB   r*   TF)r  r  r:   r<  r   )rM   rw   r  s      r&   ry   zArchiveBackend.initialize  sB     	 ,,V5F5F5M,NDL 		s   <(- <	9<9<rU   c                   K   | j                   s+t        |t        j                  | j	                         d      S d}d}t        j
                         }	 d| }	 t        j                  | j                   j                  |      |       d{   }|j                         }|j                  di       }|j                  di       }	|	j                  d      sMt        |t        j                  | j	                         t        t        j
                         |z
  dz        d      S |	d   }
	 t        j                  | j                   j                  |
      |       d{   }|j                  | _        t        t        j
                         |z
  dz        }t!        j"                  d| j                  t         j$                        }|r|j'                  d      nd}t        |t        j(                  | j	                         | j                  ||j*                  ||
|	j                  d      d      S 7 # t        j                  $ rT t        |t        j                  | j	                         t        t        j
                         |z
  dz        d	| d
      cY S w xY w7 ?# t        j                  $ rT t        |t        j                  | j	                         t        t        j
                         |z
  dz        d| d
      cY S w xY w# t,        $ r`}t        |t        j                  | j	                         t        t        j
                         |z
  dz        t/        |            cY d}~S d}~ww xY ww)z
        Navigate via Wayback Machine archive.

        UVS-H21: Added asyncio.wait_for timeouts for API and content fetches.
        r   r   g      @g      $@z*https://archive.org/wayback/available?url=rB  NrB   zArchive API timeout after sr   archived_snapshotsclosest	availablezNo archive snapshot availablerU   zArchive fetch timeout after r!  r   	timestamp)archive_urlarchive_timestamp)rU   rV   rW   rY   rZ   r[   r\   rb   )r<  rT   r(   r2   r   r   r   wait_forr"  r   r1   rQ   r   r6   rh   r=  r#  r$  r%  r&  r0   r[   r   rR   )rM   rU   ARCHIVE_API_TIMEOUTARCHIVE_FETCH_TIMEOUTr   api_urlr   data	snapshotsrF  rI  archive_responser\   r'  rZ   r   s                   r&   r{   zArchiveBackend.navigate  s     ||#'--::<.	  " $		K	B3%HG!(!1!1LL$$W-/"  ==?D!5r:ImmIr2G;;{+'+55#zz| #TYY[5%8D$@ A9  "%.K)0)9)9LL$$[11* $  "2!6!6Dtyy{U2d:;K ))$BDDVDVXZXeXefK,7K%%a(TE#'//::<'',88'#.)0[)A e '' '+33#zz| #TYY[5%8D$@ A67J6K1M 4$ '' '+33#zz| #TYY[5%8D$@ A89N8OqQ <  	#'--::<u!4 <=!f 	s   AM4L 3H1 H.H1 BL "M4#L )3J JJ !CL -M4.H1 1A$JL M4JL J A$LL M4LL 	M1AM,&M1'M4,M11M4c                 *   K   | j                   xs dS wr   )r=  rL   s    r&   r}   zArchiveBackend.get_content  s     !!'R's   rf   c                 $   K   t        |d      S wr*  r+  r   s     r&   r   zArchiveBackend.find_element  s     he<<r,  c                    K   ywr.  r$   r   s     r&   r   zArchiveBackend.click  r/  rv   rh   c                    K   ywr.  r$   r   s      r&   r   zArchiveBackend.type_text  r/  rv   r   c                    K   ywr.  r$   r   s     r&   r   zArchiveBackend.screenshot  r/  rv   r   c                    K   y wr   r$   r   s     r&   r   zArchiveBackend.evaluate  r3  rv   c                    K   y wr   r$   r   s     r&   r   zArchiveBackend.add_init_script  r5  rv   c                 n   K   | j                   r#| j                   j                          d {    y y 7 wr   )r<  r  rL   s    r&   r   zArchiveBackend.close  s+     <<,,%%''' 'r7  Nr8  r$   r%   r&   r:  r:    s    ;"!c !$| $D }  ^# ^*: ^@(3 (=3 =8M3J =C D  3 4 T d S S C (r%   r:  c            	          e Zd ZdZ	 	 d.dee   dee   fdZdefdZ	de
e   fdZd	edefd
Zd ZdefdZ	 	 d.dedee   dee   defdZdefdZdedee   fdZdedefdZdededefdZdedefdZdefdZd/dee   dee   fdZd/dee   defdZ	 	 d0dedededefdZd efd!Zd1d"ed#efd$Zd%efd&Z d/d'edee   fd(Z!d'edee   fd)Z"d* Z#dedefd+Z$d, Z%de&eef   fd-Z'y)2BrowserControllerai  
    Unified resilient multi-leveled browser controller.

    Provides automatic failover across multiple browser backends,
    with retry logic, anti-detection, and session persistence.

    VERIFICATION_STAMP (UVS-H07, UVS-H12, UVS-H19)
    - UVS-H07: CSRF token handling
    - UVS-H12: Bounded history with deque
    - UVS-H19: Thread-safe stats updates
    Nrw   storage_dirc                    ddl m} dd l}|xs
 t               | _        d | _        |xs t        d      | _        | j                  j                  dd       t        j                         | _        t               t               t               g| _        d | _        d| _        |j%                         | _        ddt(        D ci c]  }|j*                  d c}dddd| _        i | _        t1               | _        | j2                  j5                          t7        |       | _         |d	      | _        d
| _        g | _        y c c}w )Nr   )dequez+/mnt/e/genesis-system/data/browser_sessionsT)parentsexist_okF)total_navigationssuccessful_navigationsby_levelerrorsretriescaptchas_detectedrH   )maxlenuJ  
(function() {
    const inject = () => {
        try {
            if (document.getElementById('genesis-sparkle-cursor')) return;
            if (!document.body) {
                setTimeout(inject, 50);
                return;
            }
            
            const cursor = document.createElement('div');
            cursor.id = 'genesis-sparkle-cursor';
            cursor.style.cssText = `
                position: fixed;
                width: 25px;
                height: 25px;
                background: radial-gradient(circle, rgba(0,242,255,1) 0%, rgba(0,242,255,0.2) 70%);
                border: 2px solid #00f2ff;
                border-radius: 50%;
                pointer-events: none;
                z-index: 999999;
                transition: transform 0.1s ease-out, left 0.1s linear, top 0.1s linear;
                box-shadow: 0 0 20px #00f2ff;
                display: none;
                left: 0;
                top: 0;
            `;
            
            const sparkle = document.createElement('div');
            sparkle.innerHTML = '✨';
            sparkle.style.cssText = `
                position: absolute;
                top: -10px;
                left: 20px;
                font-size: 20px;
                animation: sparkle-rotate 2s linear infinite;
            `;
            
            const style = document.createElement('style');
            style.id = 'genesis-sparkle-style';
            style.textContent = `
                @keyframes sparkle-rotate {
                    from { transform: rotate(0deg) scale(1); }
                    50% { transform: rotate(180deg) scale(1.2); }
                    to { transform: rotate(360deg) scale(1); }
                }
                @keyframes genesis-circle {
                    0% { transform: translate(0, 0); }
                    25% { transform: translate(30px, 0); }
                    50% { transform: translate(30px, 30px); }
                    75% { transform: translate(0, 30px); }
                    100% { transform: translate(0, 0); }
                }
                @keyframes genesis-underline {
                    0% { transform: translate(-50px, 20px); }
                    50% { transform: translate(50px, 20px); }
                    100% { transform: translate(-50px, 20px); }
                }
                #genesis-progress-pill {
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: rgba(0, 0, 0, 0.8);
                    backdrop-filter: blur(10px);
                    border: 1px solid #00f2ff;
                    border-radius: 20px;
                    padding: 8px 16px;
                    color: #00f2ff;
                    font-family: 'Inter', sans-serif;
                    font-size: 13px;
                    font-weight: 500;
                    z-index: 1000000;
                    display: none;
                    box-shadow: 0 4px 15px rgba(0, 242, 255, 0.3);
                    transition: all 0.3s ease;
                }
            `;
            
            const pill = document.createElement('div');
            pill.id = 'genesis-progress-pill';
            
            document.head.appendChild(style);
            cursor.appendChild(sparkle);
            document.body.appendChild(cursor);
            document.body.appendChild(pill);

            // MUTUAL AUTONOMY: Detect user activity
            let lastUserMove = 0;
            window.addEventListener('mousemove', (e) => {
                if (e.isTrusted) { // Only real user moves
                    const now = Date.now();
                    if (now - lastUserMove > 500) { // Throttle
                        console.log("GENESIS_USER_ACTIVITY: mousemove");
                        lastUserMove = now;
                    }
                }
            });

            window.clearGenesisAnchor = () => {
                if (window.genesisAnchorInterval) {
                    clearInterval(window.genesisAnchorInterval);
                    window.genesisAnchorInterval = null;
                }
                const c = document.getElementById('genesis-sparkle-cursor');
                if (c) {
                    c.style.animation = 'none';
                    c.style.borderColor = '#00f2ff'; 
                }
            };
            
            window.moveGenesisCursor = (x, y) => {
                window.clearGenesisAnchor();
                const c = document.getElementById('genesis-sparkle-cursor');
                if (c) {
                    c.style.display = 'block';
                    c.style.left = x + 'px';
                    c.style.top = y + 'px';
                    c.style.borderColor = '#ff004c'; 
                }
            };
            
            window.anchorGenesisCursor = (selector) => {
                const el = document.querySelector(selector);
                if (!el) return;
                window.clearGenesisAnchor();
                const c = document.getElementById('genesis-sparkle-cursor');
                if (!c) return;
                
                const updatePos = () => {
                    const rect = el.getBoundingClientRect();
                    c.style.display = 'block';
                    c.style.left = (rect.left + rect.width / 2) + 'px';
                    c.style.top = (rect.top + rect.height / 2) + 'px';
                };
                updatePos();
                window.genesisAnchorInterval = setInterval(updatePos, 50);
            };
            
            window.updateGenesisProgress = (text) => {
                const p = document.getElementById('genesis-progress-pill');
                if (p) {
                    if (text) {
                        p.innerText = "ANTIGRAVITY: " + text;
                        p.style.display = 'block';
                    } else {
                        p.style.display = 'none';
                    }
                }
            };

            window.gestureGenesisCursor = (type, selector) => {
                const el = document.querySelector(selector);
                const c = document.getElementById('genesis-sparkle-cursor');
                if (!el || !c) return;
                window.anchorGenesisCursor(selector);
                if (type === 'circle') {
                    c.style.animation = 'genesis-circle 1.5s ease-in-out infinite';
                } else if (type === 'underline') {
                    c.style.animation = 'genesis-underline 1.5s ease-in-out infinite';
                }
            };

            window.resetGenesisUI = () => {
                window.clearGenesisAnchor();
                window.updateGenesisProgress(null);
                const c = document.getElementById('genesis-sparkle-cursor');
                if (c) c.style.display = 'none';
                const p = document.getElementById('genesis-progress-pill');
                if (p) p.style.display = 'none';
            };
        } catch (e) { console.error("Sparkle injection error:", e); }
    };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', inject);
    } else {
        inject();
    }
})();
)collectionsr^  	threadingr8   rw   r   r   r\  mkdirr   Event_abort_signalr   r  r:  	_backends_active_backend_initializedLock_stats_lockr   rp   _stats_csrf_tokensr   
ghl_bridgeload_ghl_contextr   vision_historyr   )rM   rw   r\  r^  ri  r   s         r&   r   zBrowserController.__init__/  s&   
 	&/48&]$/\*]td;$]]_ 0
 :>! %>>+!"&'4@A5QA!"
 -/ +,((* #4(  %C0s l %'U Bs   >D<rn   c                 R  K   | j                   D ]{  }|j                          d{   s| |_        |j                  | j                         d{   sG|| _        d| _        t        j                  d|j                                  y t        j                  d       y7 }7 Tw)z.Initialize the best available browser backend.NTzInitialized browser with zNo browser backend availableF)rm  rt   r   ry   rw   rn  ro  r   inforp   r+   )rM   backends     r&   ry   zBrowserController.initialize  s     ~~ 	 G))+++%)" ++DKK888+2D((,D%KK";GLLN;K LM	  	34 , 9s-   #B'B#B'%B'B%B'AB'%B'c                    K   g }| j                   D ]X  }|j                          d{   s|j                  |j                          d|j	                         j
                   d       Z |S 7 Fw)zGet list of available backends.Nz (Level ))rm  rt   appendrp   r   value)rM   rG  rz  s      r&   get_available_backendsz(BrowserController.get_available_backends(  so     	~~ 	VG))+++  GLLN#38GMMO<Q<Q;RRS!TU	V  ,s   %A0A.A0AA0resource_namec                    K   | j                   j                  |      }|rd| }| j                  |       d{   S t        |t        j
                  t        j                  d      S 7 /w)z
        Navigates to a GHL resource using knowledge from the synergy bridge.
        Example: resource_name="settings/api"
        zhttps://app.gohighlevel.comNzResource not found in KBr   )rt  get_api_endpointr{   rT   r(   r2   r   r   )rM   r  endpoint
target_urls       r&   navigate_to_ghl_resourcez*BrowserController.navigate_to_ghl_resource0  sn     
 ??33MB 7xjAJz222M:J:P:P]i]t]t  }W  X  	X 3s   7A+A)0A+c                    K   t         j                  d       | j                  j                          t	        j
                  d       d{    | j                  j                          y7 w)z4Signals all pending AI actions to abort immediately.z$[PROTOCOL] Global Abort Signal Sent.g?N)r   r   rl  r   r   sleepclearrL   s    r&   stop_all_actionsz"BrowserController.stop_all_actions=  sN     => mmC     " 	!s   AA,
A* A,c                   K   | j                   rW| j                   j                          d{   ryt        j                  d       d| _        | j                          d{   S | j                          d{   S 7 Q7 7 w)z3Check if browser is alive and restart if necessary.NTz/Browser detected as dead. Attempting restart...F)rn  r   r   r   ro  ry   rL   s    r&   ensure_browser_alivez&BrowserController.ensure_browser_aliveE  sn     ))22444NNLM %D***__&&& 5 +&s3   *BA>4B!B "B9B:B BBrU   rA   rC   c                   K   | j                   j                         r+t        |t        j                  t
        j                  d      S | j                  s| j                          d{    |xs | j                  j                  }|xs | j                  j                  }| j                  d       d}| j                  D ]  }|j                          d{   st        |      D ]  }	 || j                   k7  r,|j                  | j                         d{   s a|| _        |j#                  |       d{   }|j$                  t        j&                  fv rM| j                  d       | j)                  |j*                  j,                         | j/                  |       |c c S |j$                  t        j0                  k(  r| j                  d       |} |j$                  t        j2                  t        j4                  fv r;|d|z  z  }t7        j8                  |dz         d{    | j                  d	       ]|j$                  t        j:                  k(  r|} |}  |r| j/                  |       |S t        |t        j                  t
        jF                  d      S 7 G7 7 7 |7 # t<        $ rx}	t>        jA                  |j-                          d
|	        | j                  d       t        |t        j                  |jC                         tE        |	            }Y d}	~	Qd}	~	ww xY ww)z
        Navigate to URL with automatic fallback and abort check.

        Tries each backend level in order until success.
        Abortedr   Nra  rb  rf  r   rB   re  z error: rd  zAll backends failed)$rl  is_setrT   r(   r2   r   r   ro  ry   rw   rA   rC   _update_statsrm  rt   rangern  r{   rV   r0   _update_stats_by_levelrW   rp   _record_historyr4   r3   r5   r   r  r6   r   r   r   r   rR   r#   )
rM   rU   rA   rC   last_resultrz  attemptresultdelayr   s
             r&   r{   zBrowserController.navigateO  s     $$&#4D4J4JWcWnWnv  A  A  //###!<T[[%<%<'E4;;+E+E 	./ ~~ 3	G --/// !- .-$"6"66%,%7%7%DDD!/6,#*#3#3C#88F }})9)A)A(BB**+CD33F4E4E4J4JK,,V4%}}(8(@(@@**+>?&,}})9)A)ACSC`C`(aa .!w, ?%mmEDL999**95 }}(8(B(BB&,"(KI.3	l   -#))#++'	
 	
I $ 0  E 9& : ! NNglln%5XaS#AB&&x0"2/55#*==?!!f	#Ks   A%M 'J.(A.M J1M ,-J<J4J<M  J<;J7<A)J<%M *0J<M AJ<,J:-J<M J<#M &J<(AM 1M 4J<7J<:J<<	L=A-L82M 8L==M c                 l   K   | j                   r"| j                   j                          d{   S y7 w)zGet current page content.Nr   )rn  r}   rL   s    r&   r}   zBrowserController.get_content  s/     --99;;; <s   *424rf   c                 n   K   | j                   r#| j                   j                  |       d{   S y7 w)zFind element by CSS selector.N)rn  r   r   s     r&   r   zBrowserController.find_element  s2     --::8DDD E   +535c                 n   K   | j                   r#| j                   j                  |       d{   S y7 w)r   NF)rn  r   r   s     r&   r   zBrowserController.click  s1     --33H=== >r  rh   c                 p   K   | j                   r$| j                   j                  ||       d{   S y7 w)r   NF)rn  r   r   s      r&   r   zBrowserController.type_text  s4     --77$GGG Hs   ,646r   c                 n   K   | j                   r#| j                   j                  |       d{   S y7 wr   )rn  r   r   s     r&   r   zBrowserController.evaluate  s1     --66v>>> ?r  c                 p   K   | j                   r$| j                   j                  |       d{    yy7 w)z5Add a script to be executed on every page navigation.N)rn  r   r   s     r&   r   z!BrowserController.add_init_script  s1     &&66v>>>  >s   +646rp   c                 f  K   | j                   s| j                          d{   sy|xs& dt        j                         j	                  d       }| j
                  | dz  }t        d      D ]d  }	 | j                   j                  |       d{   r|c S | j                   j                          d{   s| j                          d{    f y7 7 G7 #7 # t        $ rF}t        j                  d|dz    d|        t        j                  d	       d{  7   Y d}~d}~ww xY ww)
z!Take screenshot with retry logic.Nscreenshot_z%Y%m%d_%H%M%Sz.pngr   zScreenshot attempt r   z	 failed: g      ?)rn  r  r   nowstrftimer\  r  r   r   r   r   r   r   r  )rM   rp   r   r  r   s        r&   r   zBrowserController.screenshot  s    ##33555OX\\^%<%<_%M$NOTF$-/Qx 		)G)--88>>>K!11::<<<33555		) # 6 ? =5 )!4WQYKyLMmmC((()s    D1CAD13CCCD1C7C8CCCD1CCC	D.(6D)D!D)$D1)D..D1c                   K   | j                          d{   }|syt        j                  dd|t        j                  t        j                  z        }t        j                  dd|t        j                  t        j                  z        }t        j                  dd|      }t        j                  dd|      j                         }|S 7 w)	z*Extract text content from page or element.Nr   z<script[^>]*>.*?</script>)flagsz<style[^>]*>.*?</style>z<[^>]+> z\s+)r}   r#  subDOTALLr%  strip)rM   rf   rY   rh   s       r&   extract_textzBrowserController.extract_text  s     %%'' vv2BBIIPRP]P]D]^vv0"d"))bmmB[\ vvj#t, vvfc4(..0 (s   CCB6Cr:   check_interval_msc                     K    fd}	 t        j                   |       |dz         d{   S 7 # t         j                  $ r Y yw xY ww)z
        Wait for element to appear.

        UVS-H29: Uses asyncio.wait_for for precise timeout regardless of system load.
        c                     K   	 j                         d {   } | r| j                  ryt        j                  dz         d {    I7 47 w)NTrB   )r   rg   r   r  )r  r  rf   rM   s    r&   _poll_for_elementz>BrowserController.wait_for_selector.<locals>._poll_for_element  sO     #00::fllmm$5$<===	 : >s!   AA.AA	AArB   rB  NF)r   rK  r   )rM   rf   r:   r  r  s   `` ` r&   wait_for_selectorz#BrowserController.wait_for_selector  sU     	>	 ))!#"T)    ## 		s1   A"7 57 A7 A
AAAr  c           	         | j                   j                  t        j                         j	                         |j
                  |j                  j                  |j                  j                  |j                  |j                  d       y)zy
        Record navigation in history.

        UVS-H12: Uses deque with maxlen=100 - no manual trimming needed.
        )rH  rU   rV   r   r\   rZ   N)rw  r}  r   r  	isoformatrU   rV   r~  rW   rp   r\   rZ   )rM   r  s     r&   r  z!BrowserController._record_history  s`     	!113::mm))&&++!--\\
 	r%   key	incrementc                     | j                   5  || j                  v r| j                  |xx   |z  cc<   ddd       y# 1 sw Y   yxY w)z
        UVS-H19: Thread-safe stats update.

        Args:
            key: Stats key to update
            increment: Amount to increment by
        Nrq  rr  )rM   r  r  s      r&   r  zBrowserController._update_stats  sB      	.dkk!C I- 	. 	. 	.s	   &<A
level_namec                     | j                   5  || j                  d   v r| j                  d   |xx   dz  cc<   ddd       y# 1 sw Y   yxY w)z(UVS-H19: Thread-safe level stats update.rc  r   Nr  )rM   r  s     r&   r  z(BrowserController._update_stats_by_level*  sJ     	9T[[44J'
3q83	9 	9 	9s   ,AAdomainc                 L  K   | j                   sy	 || j                  d       d{   }|xs d}|| j                  v r| j                  |   S | j                  d       d{   }|r)|| j                  |<   t        j	                  d|        |S | j                  d       d{   }|r)|| j                  |<   t        j	                  d|        |S t        j	                  d|        y7 7 7 L# t
        $ r"}t        j                  d	|        Y d}~yd}~ww xY ww)
aq  
        UVS-H07: Extract CSRF token from current page.

        Searches for common CSRF token patterns in:
        - Meta tags (csrf-token, _csrf, X-CSRF-Token)
        - Hidden form inputs
        - Cookies

        Args:
            domain: Domain to cache token for (auto-detected if None)

        Returns:
            CSRF token if found, None otherwise
        Nzwindow.location.hostnameunknowna  
                (() => {
                    const metaNames = ['csrf-token', '_csrf', 'csrf', 'X-CSRF-Token', '_token'];
                    for (const name of metaNames) {
                        const meta = document.querySelector(`meta[name="${name}"]`);
                        if (meta && meta.content) return meta.content;
                    }
                    return null;
                })()
            z'CSRF token extracted from meta tag for a  
                (() => {
                    const inputNames = ['_token', 'csrf_token', '_csrf', 'csrfmiddlewaretoken'];
                    for (const name of inputNames) {
                        const input = document.querySelector(`input[name="${name}"]`);
                        if (input && input.value) return input.value;
                    }
                    return null;
                })()
            z)CSRF token extracted from form input for zNo CSRF token found for zCSRF token extraction failed: )rn  r   rs  r   r   r   r   )rM   r  current_urltokenr   s        r&   extract_csrf_tokenz$BrowserController.extract_csrf_token0  s=     ##1	~$(MM2L$MM$1	 ***((00 -- 	) 	 	E ,1!!&)FvhOP -- 	) 	 	E ,1!!&)HQRLL3F8<=U N	"	&  	NN;A3?@	s   D$C6 C0&C6 D$C6 #C2$.C6 D$C6 'C4(.C6 D$C6 /D$0C6 2C6 4C6 6	D!?DD$D!!D$c                 8    | j                   j                  |      S )z!Get cached CSRF token for domain.)rs  r"  )rM   r  s     r&   get_csrf_tokenz BrowserController.get_csrf_tokenu  s      $$V,,r%   c                 8    | j                   j                          y)zClear all cached CSRF tokens.N)rs  r  rL   s    r&   clear_csrf_tokensz#BrowserController.clear_csrf_tokensy  s    !r%   c                 4  K   	 | j                   d| dz  }| j                  5  t        | j                        }ddd       t	        j
                         j                         | j                  r| j                  j                         ndt        | j                        dd d}t        |d      5 }t        j                  ||d       ddd       y	# 1 sw Y   xY w# 1 sw Y   y	xY w# t        $ r"}t        j!                  d
|        Y d}~yd}~ww xY ww)zSave current session state.session_z.jsonNi)saved_atactive_backendhistorystatswr   indentTzFailed to save session: F)r\  rq  rc   rr  r   r  r  rn  rp   listrw  r   r   dumpr   r   r+   )rM   rp   session_file
stats_copyrO  r   r   s          r&   save_sessionzBrowserController.save_session}  s     	++e.DDL!! /!$++.
/ %LLN446AEAUAU$"6"6";";"=[_.st4#	D lC( -A		$!,-/ /- 	LL3A378	si   DC* CA7C* 0C	C* DCC* C'#C* &D'C* *	D3DDDDc                 ~  K   t        | d      r| j                  rt        j                  dt	        | j                         d       t        | j                        D ]#  }|j                         r|j                          % | j                  r't        j                  | j                  ddi d{    | j                  j                          | j                  D ]  }	 |j                          d{     y7 I7 	# t        $ r3}t        j                  d|j                          d|        Y d}~Zd}~ww xY ww)	zt
        Close all backends and cancel tracked tasks.

        UVS-H10: Cancel and await all tracked tasks.
        r   zCancelling z tracked tasksreturn_exceptionsTNzError closing z: )r   r   r   r   lenr  donecancelr   gatherr  rm  r   r   r   rp   )rM   r   rz  r   s       r&   r   zBrowserController.close  s     4)*t/B/BLL;s4+>+>'?&@OPT001 "yy{KKM" ""nnd&9&9RTRRR%%'~~ 	GGGmmo%%	G S
 & G/?r!EFFGsU   A-D=0A D=0C:1-D=C>2C<3C>7D=<C>>	D:)D50D=5D::D=c                 (   | j                   5  t        | j                        }t        | j                  d         |d<   ddd       i | j                  r| j                  j	                         ndt        | j                        dS # 1 sw Y   KxY w)zX
        Get controller statistics.

        UVS-H19: Thread-safe stats access.
        rc  N)r  history_entries)rq  rc   rr  rn  rp   r  rw  )rM   r  s     r&   	get_statszBrowserController.get_stats  s      	Cdkk*J%)$++j*A%BJz"	C

=A=Q=Qd22779W["4==1
 	
		C 	Cs   1BB)NNr   )rF   rH   )r   )(r   r   r   r   r   r8   r   r   rO   ry   r
   rR   r  rT   r  r  r  rQ   r{   r}   re   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r  r   r	   r  r$   r%   r&   r[  r[  "  s   
 +/&*h''h' d^h'T$ d3i XC XDT X#'D ' &*(,	X
X
 c]X
 !	X

 
X
t3 3 8M3J C D  3 4 S S ?C ?
Xc] htn ,8C= C * !$	  	
 
4&6  
. 
. 
.9 9Cs Chsm CJ-S -Xc] -"s t *G.
4S> 
r%   r[  rw   c                   K   t        |       }d}	 |j                          d{   }|st        d      | |r|j                          d{    yy7 27 # |r|j                          d{  7   w w xY ww)z
    Context manager for browser sessions.

    UVS-H22: Only call close() if initialize() succeeded to avoid cascading errors.
    FNzBrowser initialization failed)r[  ry   RuntimeErrorr   )rw   r   initializeds      r&   browser_sessionr    s      #6*JK%&1133>?? ""$$$  4 % ""$$$ sI   A<A AA A<AA<A A<A91A42A99A<c                    K   ddl } | j                  d      }|j                  dg d       |j                  dd	
       |j                  dd
       |j                  ddd       |j                         }t	               }|j
                  dk(  rD|j                          d{   }t        d       t        d       |D ]  }t        d|         y|j
                  dk(  r9|j                  st        d       yt        d|j                          |j                  |j                         d{   }t        d|j                  j                          t        d|j                  j                          t        d|j                          t        d|j                   d       |j                   rt        d|j                           |j"                  r(|j#                          d{   }|rt        d|        |j%                          d{    y|j
                  dk(  rEt        d        t        d       t        t'        j(                  |j+                         d!"             y|j
                  d#k(  rt        d$       t        d       d%}|j                  |       d{   }t        d&|        t        d'|j                  j                          t        d(|j                  j                          t        d|j                          |j-                          d{   }	t        d)|	dd*  d+       |j%                          d{    yy7 7 07 v7 Q7 7 >7 w),zCLI for Browser Controller.r   NzGenesis Browser Controller)descriptioncommand)r{   backendsr  test)choicesz--urlzURL to navigate to)helpz
--selectorzCSS selectorz--screenshot
store_truezTake screenshot)actionr  r  zAvailable Browser Backends:z(========================================z  - r{   z Usage: --url https://example.comzNavigating to: z	
Status: zLevel: zTitle: z
Duration: mszError: zScreenshot: r  zBrowser Controller Statistics:r   r  r  zTesting browser backends...zhttps://example.comzURL: zStatus: z	Backend: zText preview:    z...)argparseArgumentParseradd_argument
parse_argsr[  r  r  printrU   r{   rV   r~  rW   rp   rZ   r\   r+   r   r   r   dumpsr  r  )
r  parserargsr   r  br  r   test_urlrh   s
             r&   mainr    s    $$1M$NF
	+TU
&:;
>:
|BSTD"$J||z!#::<<+,h 	AD*	 
	#xx45z*+!**48844
6==../01))../01~&'
6--.b12<<GFLL>*+??#..00DTF+,   		 ./hdjj--/:;		+,h(!**844hZ !,,-./	&++00123~&'  ,,..tDSzl#./   ! 
 E = 5 1 	! 5 / 	!s   B"M2$M %BM23M#4B<M20M&1'M2M)BM2-M,.BM2/M.0)M2M0M2#M2&M2)M2,M2.M20M2__main__r   )3r   r   r   osr#  r   hashlibr   abcr   r   dataclassesr   r   r   pathlibr   typingr	   r
   r   r   r   r   enumr   
contextlibr   loggingcore.ghl_synergy_bridger   core.vision_workerr   basicConfigINFO	getLoggerr   r   r   r(   r8   rT   re   rm   r   r  r:  r[  r  r  runr$   r%   r&   <module>r     s]  8   	 	    # (   = =  *  4 +   ',, '			8	$4 t  8 8 8@ ; ; ;"   BS BJh* h*V	R) R)jS(^ S(lU

 U

p %(="9 % %&@!F zGKK r%   