
    2BhS                         S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	J
r
  S SKJr  S SKJrJrJr  S SKJrJr   " S S5      rg)    N)
HaltServerAppImportError)Pidfile)socksystemdutil)__version__SERVER_SOFTWAREc                      \ rS rSrSrSrSr0 r/ r0 r	/ r
/ rSR                  5        V VVVs/ s H  n[        [        SU-  5      PM     snnnn r\" S \" \5       5       5      rS rS	 rS
 r\" \\5      rS rS rS rS rS rS rS rS rS rS r S r!S r"S r#S r$S r%S r&S r'S*S jr(S r)S+S jr*S  r+S! r,S" r-S# r.S$ r/S% r0S& r1S' r2S( r3S)r4gs  snnnn f ),Arbiter   z
Arbiter maintain the workers processes alive. It launches or
kills them if needed. It also manages application reloading
via SIGHUP/USR2.
      z+HUP QUIT INT TERM TTIN TTOU USR1 USR2 WINCHzSIG%sc              #      #    U  H>  nUS S S:X  d  M  US   S:w  d  M  [        [        U5      USS  R                  5       4v   M@     g 7f)Nr   SIG_)getattrsignallower).0names     B/var/www/html/env/lib/python3.13/site-packages/gunicorn/arbiter.py	<genexpr>Arbiter.<genexpr>-   sO      >Id8u 	2!%aC 	2	QR 01ks   AA*Ac                    [         [        R                  S'   S U l        S U l        S U l        U R                  U5        S U l        SU l        SU l	        SU l
        SU l        SU l        [        R                  " 5       n[        R                   S S  nUR#                  S[        R$                  5        UU[        R$                  S.U l        g )Nr
   Fr   Master)argscwdr   )r
   osenviron_num_workers _last_logged_active_worker_countlogsetuppidfiler   
worker_age
reexec_pid
master_pidmaster_namer   getcwdsysargvinsert
executable	START_CTX)selfappr   r   s       r   __init__Arbiter.__init__2   s    (7

$% 04-

3#kkmxx{As~~& ~~
    c                     U R                   $ N)r!   r0   s    r   _get_num_workersArbiter._get_num_workersN   s       r4   c                 `    U R                   nXl         U R                  R                  XU5        g r6   )r!   cfgnworkers_changed)r0   value	old_values      r   _set_num_workersArbiter._set_num_workersQ   s'    %%	!!!$y9r4   c                    Xl         UR                  U l        U R                  c*  U R                  R                  UR                  5      U l        S[        R
                  ;   a  U R                  R                  5         U R                  R                  U l        U R                  R                  U l        U R                  R                  U l
        U R                  R                  U l        U R                  R                  U l        U R                  R                  SR                  SR                  S [!        U R                  R"                  R%                  5       S S9 5       5      5      5        U R                  R&                  (       a@  U R                  R&                  R%                  5        H  u  p#U[        R
                  U'   M     U R                  R(                  (       a  U R                   R+                  5         g g )NGUNICORN_PIDzCurrent configuration:
{0}
c              3   \   #    U  H"  u  pS R                  XR                  5      v   M$     g7f)z
  {0}: {1}N)formatr=   )r   configr=   s      r   r    Arbiter.setup.<locals>.<genexpr>i   s2      ;: "F ##FKK88:s   *,c                     U S   $ N    )settings    r   <lambda>Arbiter.setup.<locals>.<lambda>m   s    gajr4   key)r1   r;   r#   logger_classr   r    reopen_filesworker_classaddressworkersnum_workerstimeout	proc_namedebugrE   joinsortedsettingsitemsenvpreload_appwsgi)r0   r1   kvs       r   r$   Arbiter.setupW   sY   7788xx,,SWW5DH RZZ'HH!!# HH11xx''88++xx''++4;;II ; $((++1138:; ;< 	= 88<<**, !

1 - 88HHMMO  r4   c                    U R                   R                  S[        5        S[        R                  ;   aH  [        [        R                  R                  S5      5      U l        U R                  S-   U l        SU l	        [        R                  " 5       U l        U R                  R                  b`  U R                  R                  nU R                  S:w  a  US-  n[        U5      U l        U R                  R                  U R                  5        U R                  R!                  U 5        U R#                  5         U R$                  (       d  Sn[&        R(                  " 5       nU(       a3  SU l        [+        [&        R,                  [&        R,                  U-   5      nObU R                  (       aQ  / n[        R                  R/                  S5      R1                  S	5       H  nUR3                  [        U5      5        M     [4        R6                  " U R                  U R                   U5      U l        S	R9                  U R$                   Vs/ s H  n[;        U5      PM     sn5      nU R                   R=                  S
5        U R                   R                  SX`R                  5        U R                   R                  SU R                  R>                  5        [&        R@                  " SU R                   5        [C        U RD                  S5      (       a0  U RD                  RG                  U R                  U R                   5        U R                  RI                  U 5        gs  snf )zKInitialize the arbiter. Start listening and set pidfile if needed.
        zStarting gunicorn %srB   z.2zMaster.2Nr   TGUNICORN_FD,zArbiter bootedzListening at: %s (%s)zUsing worker: %sz&READY=1
STATUS=Gunicorn arbiter bootedcheck_config)%r#   infor	   r   r    intgetr(   rX   r)   getpidpidr;   r%   r   createon_startinginit_signals	LISTENERSr   
listen_fdsrangeSD_LISTEN_FDS_STARTpopsplitappendr   create_socketsrZ   strrY   worker_class_str	sd_notifyhasattrrS   rg   
when_ready)r0   pidnamefdsrq   fdlnrlisteners_strs          r   startArbiter.startw   sE    	,k:RZZ'!"**.."@ADO!^^d2DN)D99;88'hh&&G!#4"7+DLLL)T"~~C ++-J#G77#77*DF **..7==cBBJJs2w' C "00488SIDNdnn!Ens#c(n!EF'(-}hhG($((*C*CDCTXXN 4$$n55**488TXX>D! "Fs   Mc                    U R                    H  n[        R                  " U5        M     [        R                  " 5       =U l         nU H/  n[        R
                  " U5        [        R                  " U5        M1     U R                  R                  5         U R                   H#  n[        R                  " X0R                  5        M%     [        R                  " [        R                  U R                  5        g)zjInitialize master signal handling. Most of the signals
are queued. Child signals only wake up the master.
N)PIPEr   closepiper   set_non_blockingclose_on_execr#   SIGNALSr   SIGCHLDhandle_chld)r0   ppairss       r   ro   Arbiter.init_signals   s     AHHQK  779$	DA!!!$q!  	  AMM![[) fnnd&6&67r4   c                     [        U R                  5      S:  a,  U R                  R                  U5        U R                  5         g g )N   )len	SIG_QUEUErv   wakeupr0   sigframes      r   r   Arbiter.signal   s3    t~~"NN!!#&KKM #r4   c                    U R                  5         [        R                  " SU R                  -  5         U R	                  5          U R                  5         U R                  (       a  U R                  R                  S5      OSnUc2  U R                  5         U R                  5         U R	                  5         Mt  XR                  ;  a  U R                  R                  SU5        M  U R                  R                  U5      n[        U SU-  S5      nU(       d  U R                  R                  SU5        M  U R                  R                  SU5        U" 5         U R!                  5         GM&  ! ["        [$        4 a    U R'                  5          g[(         a.  nU R'                  UR*                  UR,                  S	9   SnAgSnAf[.         a    e [0         ak    U R                  R                  S
SS9  U R3                  S5        U R4                  b  U R4                  R7                  5         [8        R:                  " S5         gf = f)zMain master loop.master [%s]Tr   NzIgnoring unknown signal: %sz	handle_%szUnhandled signal: %szHandling signal: %s)reasonexit_statusz Unhandled exception in main loopexc_infoF)r   r   _setproctitlerX   manage_workersmaybe_promote_masterr   rt   sleepmurder_workers	SIG_NAMESr#   rh   rj   r   errorr   StopIterationKeyboardInterrupthaltr   r   r   
SystemExit	Exceptionstopr%   unlinkr+   exit)r0   r   signamehandlerinsts        r   runArbiter.run   s   

=4>>9:%	!))+/3~~dnn((+4;JJL'')'')nn,HHMM"?E..,,S1!$g(=tDHHNN#97C3W=	+ , 01 	IIK 	HIIT[[d6F6FIG 	 	HHNN=$(  *IIe||'##%HHRL	s%   D7E, , I	I$G  A?IIc                 D    U R                  5         U R                  5         g)zSIGCHLD handlingN)reap_workersr   r   s      r   r   Arbiter.handle_chld   s    r4   c                 p    U R                   R                  SU R                  5        U R                  5         g)zHUP handling.
- Reload configuration
- Start the new worker processes with a new configuration
- Gracefully shutdown the old worker processes
zHang up: %sN)r#   rh   r)   reloadr7   s    r   
handle_hupArbiter.handle_hup   s%     	mT%5%56r4   c                     [         e)zSIGTERM handling)r   r7   s    r   handle_termArbiter.handle_term   s    r4   c                 0    U R                  S5        [        e)zSIGINT handlingFr   r   r7   s    r   
handle_intArbiter.handle_int      		%r4   c                 0    U R                  S5        [        e)zSIGQUIT handlingFr   r7   s    r   handle_quitArbiter.handle_quit  r   r4   c                 N    U =R                   S-  sl         U R                  5         g)z:SIGTTIN handling.
Increases the number of workers by one.
rJ   NrV   r   r7   s    r   handle_ttinArbiter.handle_ttin  s!    
 	Ar4   c                 p    U R                   S::  a  gU =R                   S-  sl         U R                  5         g)z:SIGTTOU handling.
Decreases the number of workers by one.
rJ   Nr   r7   s    r   handle_ttouArbiter.handle_ttou  s2    
 q Ar4   c                 v    U R                   R                  5         U R                  [        R                  5        g)z=SIGUSR1 handling.
Kill all workers by sending them a SIGUSR1
N)r#   rR   kill_workersr   SIGUSR1r7   s    r   handle_usr1Arbiter.handle_usr1  s&    
 	&..)r4   c                 $    U R                  5         g)zSIGUSR2 handling.
Creates a new arbiter/worker set as a fork of the current
arbiter without affecting old workers. Use this to do live
deployment with the ability to backout a change.
N)reexecr7   s    r   handle_usr2Arbiter.handle_usr2&  s     	r4   c                     U R                   R                  (       aB  U R                  R                  S5        SU l        U R                  [        R                  5        gU R                  R                  S5        g)zSIGWINCH handlingzgraceful stop of workersr   z SIGWINCH ignored. Not daemonizedN)	r;   daemonr#   rh   rV   r   r   SIGTERMrY   r7   s    r   handle_winchArbiter.handle_winch/  sI    88??HHMM45 Dfnn-HHNN=>r4   c                    U R                   S:X  a  g U R                   [        R                  " 5       :w  a  U R                  R	                  S5        SU l        SU l         U R                  R                  U l        [        R                  S	 U R                  b/  U R                  R                  U R                  R                  5        [        R                  " SU R                  -  5        g g )Nr   zMaster has been promoted.r   rB   r   )r(   r   getppidr#   rh   r)   r;   rX   r    r%   renamer   r   r7   s    r   r   Arbiter.maybe_promote_master8  s    ??a??bjjl*HHMM56'DDO!XX//DN

>*||'##DHH$4$45}t~~=> +r4   c                      [         R                  " U R                  S   S5        g! [         a9  nUR                  [        R
                  [        R                  4;  a  e  SnAgSnAff = f)z3Wake up the arbiter by writing to the PIPE
        rJ      .N)r   writer   OSErrorerrnoEAGAINEINTR)r0   es     r   r   Arbiter.wakeupI  sN    	HHTYYq\4( 	wwu||U[[99 :	s   $' 
A*/A%%A*Nc                 v   U R                  5         US:X  a  U R                  R                  OU R                  R                  nU" SU R                  5        Ub	  U" SU5        U R
                  b  U R
                  R                  5         U R                  R                  U 5        [        R                  " U5        g)zhalt arbiter r   zShutting down: %sNz
Reason: %s)r   r#   rh   r   r)   r%   r   r;   on_exitr+   r   )r0   r   r   log_funcs       r   r   Arbiter.haltS  s    		$/1$4488==$((..$d&6&67\6*<<#LL!r4   c                     [         R                   " U R                  S   // / S5      nUS   (       d  g[        R                  " U R                  S   S5      (       a-   [        R                  " U R                  S   S5      (       a  M,  gg! [         aI  n[        USUR                  S   5      nU[        R                  [        R                  4;  a  e  SnAgSnAf[         a    [        R                  " 5          gf = f)zUSleep until PIPE is readable or we timeout.
A readable PIPE means a signal occurred.
r   g      ?NrJ   r   )selectr   r   readr   r   r   r   r   r   r   r+   r   )r0   readyr   error_numbers       r   r   Arbiter.sleepa  s    
	MM499Q<."b#>E8''$))A,** ''$))A,** 	"1gqvvay9LELL%++#>> ?  	HHJ	s#   1B AB 
C>?C"C>=C>c                    U R                   U R                  s=:H  =(       a    S:H  Os  =(       a3    U R                  (       + =(       a    U R                  R                  (       + n[
        R                  " U R                  U5        / U l        [        R                  nU(       d  [        R                  n[        R                  " 5       U R                  R                  -   nU R                  U5        U R                  (       a[  [        R                  " 5       U:  aB  [        R                  " S5        U R                  (       a  [        R                  " 5       U:  a  MB  U R                  [        R                   5        g)zStop workers

:attr graceful: boolean, If True (the default) workers will be
killed gracefully  (ie. trying to wait for the current connection)
r   皙?N)r'   r(   r   r;   
reuse_portr   close_socketsrp   r   r   SIGQUITtimegraceful_timeoutr   WORKERSr   SIGKILL)r0   gracefulr   r   limits        r   r   Arbiter.stopt  s     OOt33!3 (LL (HH''' 	
 	4>>62nn..C		dhh777#lltyy{U2JJsO lltyy{U2 	&..)r4   c                 j   U R                   S:w  a  U R                  R                  S5        gU R                  S:w  a  U R                  R                  S5        g[        R
                  " 5       n[        R                  " 5       U l         U R                   S:w  a  gU R                  R                  U 5        U R                  R                  R                  5       n[        U5      US'   U R                  (       aC  [        [        R
                  " 5       5      US'   [        [        U R                  5      5      US'   O%SR                  S	 U R                   5       5      US
'   [        R                   " U R"                  S   5        [        R$                  " U R"                  S   U R"                  S   U5        g)z)Relaunch the master and workers.
        r   z"USR2 signal ignored. Child exists.Nz#USR2 signal ignored. Parent exists.rB   
LISTEN_PID
LISTEN_FDSrf   c              3   T   #    U  H  n[        UR                  5       5      v   M      g 7fr6   )rx   fileno)r   r   s     r   r   !Arbiter.reexec.<locals>.<genexpr>  s!      .=-;cCJJL!!^s   &(re   r   r   )r'   r#   warningr(   r   rk   forkr;   pre_execenv_origcopyrx   r   r   rp   rZ   chdirr/   execvpe)r0   r(   r    s      r   r   Arbiter.reexec  s:    ??aHHAB??aHHBCYY[
'')??a$((##((*"%j/<<$'		$4GL!$'DNN(;$<GL!%(XX .=-1^^.= &=GM" 	&' 	

4>>!$dnnV&<gFr4   c                 t   U R                   R                  nU R                   R                   HZ  nX R                   R                  ;   a,  U R                   R                  U   [        R
                  U'   MH   [        R
                  U	 M\     U R                  R                  5         U R                  U R                  5        U R                  R                  5         XR                   R                  :w  a  U R                   H  nUR                  5         M     [        R                  " U R                   U R                  5      U l        SR!                  U R                   Vs/ s H  n[#        U5      PM     sn5      nU R                  R%                  SU5        U R                   R'                  U 5        U R(                  b  U R(                  R+                  5         U R                   R(                  bI  [-        U R                   R(                  5      U l        U R(                  R/                  U R0                  5        [2        R4                  " SU R6                  -  5        [9        U R                   R:                  5       H  nU R=                  5         M     U R?                  5         g ! [         a     GM  f = fs  snf )Nrf   zListening at: %sr   ) r;   rT   r^   r  r   r    KeyErrorr1   r   r$   r#   rR   rp   r   r   rw   rZ   rx   rh   	on_reloadr%   r   r   rm   rl   r   r   rX   rr   rU   spawn_workerr   )r0   old_addressra   r   r   r   s         r   r   Arbiter.reload  s   hh&& AHH%%% !% 1 1! 4

1

1  	

488 	 ((***~~		 & "00488DDNHH$..%I.3c#h.%IJMHHMM,m< 	4  <<#LL! 88'"488#3#34DLLL) 	=4>>9: txx''(A ) 	Q   " &Js   6J#J5#
J21J2c                 "   U R                   (       d  g[        U R                  R                  5       5      nU H  u  p# [        R
                  " 5       UR                  R                  5       -
  U R                   ::  a  MF   UR                  (       dE  U R                  R                  SU5        SUl
        U R                  U[        R                  5        M  U R                  U[        R                   5        M     g! [        [        4 a     M  f = f)z!Kill unused/idle workers
        NzWORKER TIMEOUT (pid:%s)T)rW   listr   r]   r   	monotonictmplast_updater   
ValueErrorabortedr#   criticalkill_workerr   SIGABRTr   )r0   rU   rl   workers       r   r   Arbiter.murder_workers  s     ||t||))+,$MS>>#fjj&<&<&>>$,,N O
 >>!!";SA!%  fnn5  fnn5 % Z( s   >C::DDc                      [         R                  " S[         R                  5      u  pU(       d  gU R                  U:X  a	  SU l        GO]US-	  nUS:w  a  U R                  R                  SX5        X0R                  :X  a  Sn[        X@R                  5      eX0R                  :X  a  Sn[        X@R                  5      eUS:  a  U R                  R                  SX5        OlUS:  af   [        R                  " U5      R                  nS	R                  X5      nU[        R                  :X  a  US
-  nU R                  R                  U5        U R                  R!                  US5      nU(       d  GMq  UR"                  R%                  5         U R&                  R)                  X5        GM  ! [         a    SR                  U5      n Nf = f! [*         a)  nUR,                  [,        R.                  :w  a  e  SnAgSnAff = f)z/Reap workers to avoid zombie processes
        r   r      z#Worker (pid:%s) exited with code %szWorker failed to boot.zApp failed to load.z$Worker (pid:%s) exited with code %s.zcode {}zWorker (pid:{}) was sent {}!z Perhaps out of memory?N)r   waitpidWNOHANGr'   r#   r   WORKER_BOOT_ERRORr   APP_LOAD_ERRORr   Signalsr   r  rE   r   r   rt   r  r   r;   
child_exitr   r   ECHILD)	r0   wpidstatusexitcoder   sig_namemsgr  r   s	            r   r   Arbiter.reap_workers  s   1	!zz"bjj9??d*&'DO
  &{H1}'Ld]#9#99!9(1G1GHH#6#66!6(1D1DEE!| 'M'+7!@'-~~f'='B'BH =CC , "V^^3#<<Cs+!\\--dD9F! JJ$$&HH''5[ >  * @'0'7'7'?H@  	ww%,,& '	sB   /G B5G ( F+ B#G +G	G G		G 
G?G::G?c                     [        U R                  5      U R                  :  a  U R                  5         U R                  R	                  5       n[        US S9n[        U5      U R                  :  aN  UR                  S5      u  p#U R                  U[        R                  5        [        U5      U R                  :  a  MN  [        U5      nU R                  U:w  a4  X@l
        U R                  R                  SR                  U5      SUSS.S9  g	g	)
zCMaintain the number of workers by spawning or killing
as required.
c                      U S   R                   $ rI   )age)ws    r   rM   (Arbiter.manage_workers.<locals>.<lambda>=  s    !r4   rO   r   z{0} workerszgunicorn.workersgauge)metricr=   mtype)extraN)r   r   rV   spawn_workersr]   r[   rt   r  r   r   r"   r#   rY   rE   )r0   rU   rl   r   active_worker_counts        r   r   Arbiter.manage_workers4  s    
 t||t/// ,,$$&&89'lT---{{1~HSS&..1 'lT--- "'l004GG4G1HHNN=//0CD,>+>+2"4  5 Hr4   c           	         U =R                   S-  sl         U R                  U R                   U R                  U R                  U R                  U R
                  S-  U R                  U R                  5      nU R                  R                  X5        [        R                  " 5       nUS:w  a  X!l        XR                  U'   U$ U R                  R                  5        H  nUR                  R                  5         M     [        R                  " 5       Ul         [         R"                  " SU R$                  -  5        U R                  R'                  SUR                  5        U R                  R)                  X5        UR+                  5         [,        R.                  " S5        U R                  R'                  SUR                  5         UR                  R                  5         U R                  RG                  X5        g ! [0         a    e [2         a}  nU R                  R5                  SSS9  [7        S	U-  [,        R8                  S
9  [,        R8                  R;                  5         [,        R.                  " U R<                  5         S nANS nAf[>         af    U R                  RA                  S5        URB                  (       d   [,        R.                  " U RD                  5        [,        R.                  " S5         GN[f = f! [>         a2    U R                  RI                  S[J        RL                  " 5       5         g f = f! U R                  R'                  SUR                  5         UR                  R                  5         U R                  RG                  X5        f ! [>         a2    U R                  RI                  S[J        RL                  " 5       5         f f = f= f)NrJ   g       @r   zworker [%s]zBooting worker with pid: %sz'Exception while loading the applicationTr   z%s)filezException in worker processr   zWorker exiting (pid: %s)z Exception during worker exit:
%s)'r&   rS   rl   rp   r1   rW   r;   r#   pre_forkr   r  r   valuesr  r   rk   r   r   rX   rh   	post_forkinit_processr+   r   r   r   rY   printstderrflushr$  r   	exceptionbootedr#  worker_exitr  	traceback
format_exc)r0   r  rl   siblingr   s        r   r  Arbiter.spawn_workerJ  s   1""4??DHHdnn#'88T\\C-?#'88TXX7 	$'ggi!8J &LLJ ||**,GKK - YY[
	9}t~~=>HHMM7DHHt,!HHQK HHMM4fjjA9

  "$$T2#  	 	*HHNND$(  *$(,JJHHT(()) 	HH<===//0HHRL		  9  !D!*!5!5!799	 HHMM4fjjA9

  "$$T2 9  !D!*!5!5!799so   B
G? 	5L ?K>A3JM  A/K>:M  =K>>M  9L=<L= 'O(5NO9OOOOc                     [        U R                  [        U R                  5      -
  5       H?  nU R	                  5         [
        R                  " S[        R                  " 5       -  5        MA     g)ziSpawn new workers as needed.

This is where a worker process leaves the main loop
of the master process.
r   N)rr   rV   r   r   r  r   r   random)r0   r   s     r   r7  Arbiter.spawn_workersx  sJ     t''#dll*;;<AJJsV]]_,- =r4   c                 ~    [        U R                  R                  5       5      nU H  nU R                  X15        M     g)zFKill all workers with the signal `sig`
:attr sig: `signal.SIG*` value
N)r  r   keysr  )r0   r   worker_pidsrl   s       r   r   Arbiter.kill_workers  s3    
 4<<,,./CS& r4   c                 t    [         R                  " X5        g! [         a  nUR                  [        R                  :X  ap   U R
                  R                  U5      nUR                  R                  5         U R                  R                  X5         SnAg! [        [        4 a      SnAgf = fe SnAff = f)zJKill a worker

:attr pid: int, worker pid
:attr sig: `signal.SIG*` value
 N)r   killr   r   ESRCHr   rt   r  r   r;   rE  r  )r0   rl   r   r   r  s        r   r  Arbiter.kill_worker  s    	GGC 		ww%++%!\\--c2FJJ$$&HH((6 '* 		s3    
B7B2ABB.'B2-B..B22B7)rp   r   r/   r"   r!   rT   r1   r;   r#   r)   r(   rV   rl   r%   rX   r'   r   rW   r&   rS   )Nr   )T)5__name__
__module____qualname____firstlineno____doc__r#  r$  r/   rp   r   r   r   ru   r   r   r   dictdirr   r2   r8   r?   propertyrV   r$   r   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r7  r   r  __static_attributes__)r   xr   r   s   0000r   r   r      s>     NIIGD IEKKMOM1 vw{+MOG >A&k I

8!: +-=>K@/"b8,
*X


*??"&*6 GD5n6*5n5,,9\
.'EOs   C
r   )r   r   rK  r   r   r+   r   rF  gunicorn.errorsr   r   gunicorn.pidfiler   gunicornr   r   r   r	   r
   r   rK   r4   r   <module>rb     s:     	    
   6 $ ( ( 1K
 K
r4   