
    ;^hP                    
   S 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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  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJ r   SSKJ!r!  SSKJ"r"  SSKJ#r#  SSKJ$r$  SSKJ%r%  SSKJ&r&  SSKJ'r'  SSKJ(r(  SSKJ)r)  SSKJ*r*  SSKJ+r+  / SQr,\-" \	S 5      (       aV  \,R]                  \/" \5       V s/ s H3  o Ra                  S!5      (       d  M  U Rc                  5       (       d  M1  U PM5     sn 5        S"r2\Rf                  Ri                  S#\Rj                  " 5        S$35      r6\Rf                  Ri                  S#\Rj                  " 5        S%35      r7\-" \S&5      r8\-" \S'5      r9\Rt                  " S(5      r;\Rx                  " 5       r=Sq>\R~                  S):H  r@S*rA\R                  " S+S,\C" \
R                  5      05      rE\ER                  rF " S- S.\R                  5      rG\H" 5       R                  \GR                  5        \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  S/.rV\R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  S0.rb\" S1/ S2Q5      rc\" S3/ S4Q5      rd\" S5/ S6Q5      re\" S7S85      rf\" S9\fR                  S:-   5      rh\" S;/ S<Q5      ri\" S=S>S?R                  \iR                  5      -   5      rk\" S@/ SAQ5      rl\" SB/ SCQ5      rmSD rnSE roSF rp\$SG 5       rq \q" SH5        SM ruSN rvSO rwSP rxSQ rySR rzSS r{ST r|SU r}\Rf                  Ri                  SV5      (       d   \Rf                  Ri                  SW5      (       a  SX r~OSY r~\R                  r " SZ S[\r5      r " S\ S]5      r\" 5       rSpS^ jrS_ rS` r\GR                  rSqSa jr " Sb Sc5      rSqSd jrSe rSf rSg rSh rSi rSj rSk rSl rSm r " Sn So5      rgs  sn f ! \r a(  rs\ " SI\s< 35        \" SJSK5      " SLSLSL5      qt SrsCsGN
SrsCsff = f)rzLinux platform implementation.    N)defaultdict)
namedtuple   )_common)_psposix)_psutil_linux)_psutil_posix)ENCODING)NIC_DUPLEX_FULL)NIC_DUPLEX_HALF)NIC_DUPLEX_UNKNOWN)AccessDenied)NoSuchProcess)ZombieProcess)bcat)cat)debug)decode)get_procfs_path)isfile_strict)memoize)memoize_when_activated)open_binary)	open_text)parse_environ_block)path_exists_strict)supports_ipv6)usage_percent)PROCFS_PATHIOPRIO_CLASS_NONEIOPRIO_CLASS_RTIOPRIO_CLASS_BEIOPRIO_CLASS_IDLECONN_ESTABLISHEDCONN_SYN_SENTCONN_SYN_RECVCONN_FIN_WAIT1CONN_FIN_WAIT2CONN_TIME_WAIT
CONN_CLOSECONN_CLOSE_WAITCONN_LAST_ACKCONN_LISTENCONN_CLOSINGprlimitRLIMz/sys/class/power_supply/proc//smaps/smaps_rollupproc_ioprio_getproc_cpu_affinity_get
SC_CLK_TCKlittlei   AddressFamilyAF_LINKc                   $    \ rS rSrSrSrSrSrSrg)
IOPriorityk   r   r          N)	__name__
__module____qualname____firstlineno__r    r!   r"   r#   __static_attributes__r?       A/var/www/html/env/lib/python3.13/site-packages/psutil/_pslinux.pyr;   r;   k   s    OOrE   r;   )RSDTtZXxKWIP)0102030405060708090A0Bsvmem)total	availablepercentusedfreeactiveinactivebufferscachedsharedslabsdiskio)	
read_countwrite_count
read_byteswrite_bytes	read_time
write_timeread_merged_countwrite_merged_count	busy_time	popenfile)pathfdpositionmodeflagspmemz"rss vms shared text lib data dirtypfullmem)usspssswappmmap_grouped)ru   rsssizer}   shared_cleanshared_dirtyprivate_cleanprivate_dirty
referenced	anonymousr~   	pmmap_extzaddr perms  pio)rk   rl   rm   rn   
read_charswrite_chars	pcputimes)usersystemchildren_userchildren_systemiowaitc                     [        U [        5      (       d   U 5       e[        R                  " U 5      n U R	                  S5      S   n U R                  S5      (       a  [        U 5      (       d  U SS n U $ )zWrapper around os.readlink(). r   
 (deleted)N)
isinstancestrosreadlinksplitendswithr   )ru   s    rF   r   r      si    dC  &$& ;;tD ::fa D }}\""+=d+C+CDSzKrE   c                 R   [         R                  S[         R                  S[         R                  S0nX[         R                  [         R                  -  [         R                  -  -     nU [         R                  -  (       a  UR                  SSS5      nUR                  SS5      nU$ )zRConvert file's open() flags into a readable string.
Used by Process.open_files().
rwzw+ar   zr+)r   O_RDONLYO_WRONLYO_RDWRO_APPENDreplace)ry   	modes_maprx   s      rF   file_flags_to_moder      sx     c2;;RYYEIbkkBKK7"))CDEDr{{||Ca(<<d#DKrE   c                     U R                  SS5      n SnU(       a  SU  3nOSU  S3n[        R                  " U[        R                  5      $ )zReturn True if the given name refers to a root device (e.g.
"sda", "nvme0n1") as opposed to a logical partition (e.g.  "sda1",
"nvme0n1p1"). If name is a virtual device (e.g. "loop1", "ram")
return True.
/!Tz/sys/block/z/device)r   r   accessF_OK)nameincluding_virtualru   s      rF   is_storage_devicer      sL     <<S!DTF#TF'*99T277##rE   c                 V   [        U  S35       nUR                  5       R                  5       SS nSSS5        / SQn[        W5      nUS:  a  UR	                  S5        US:  a  UR	                  S5        US	:  a  UR	                  S
5        [        SU5      qg! , (       d  f       No= f)zSet a namedtuple of variable fields depending on the CPU times
available on this Linux kernel version which may be:
(user, nice, system, idle, iowait, irq, softirq, [steal, [guest,
 [guest_nice]]])
Used by cpu_times() function.
/statr   N)r   nicer   idler   irqsoftirq   steal	   guest
   
guest_nice	scputimes)r   readliner   lenappendr   r   )procfs_pathfvaluesfieldsvlens        rF   set_scputimes_ntupler      s     
}E*	+q##%ab) 
,KFv;Dqygqygrzl#;/I 
,	+s   "B
B(/proczignoring exception on import: r   zuser system idle        c                 v   U S   nXR                  SS5      -   n U S   nU S   nU S   n [	        [        5        S	35      nSnU   U HJ  n	U	R                  5       n	U	R                  S
5      (       d  M+  U[        U	R                  5       S   5      -  nML     SSS5        U[        -  nX-
  n
X4-   nU[        US-  U5      -  nX-  n
X[        US-  U5      -
  -  n
[        U
5      $ ! [         a'  n[        UR                  S    S35        Us SnA$ SnAff = f! [         a    Us $ f = f! , (       d  f       N= f)a9  Fallback for kernels < 3.14 where /proc/meminfo does not provide
"MemAvailable", see:
https://blog.famzah.net/2014/09/24/.

This code reimplements the algorithm outlined here:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
    commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773

We use this function also when "MemAvailable" returns 0 (possibly a
kernel bug, see: https://github.com/giampaolo/psutil/issues/1915).
In that case this routine matches "free" CLI tool result ("available"
column).

XXX: on recent kernels this calculation may differ by ~1.5% compared
to "MemAvailable:", as it's calculated slightly differently.
It is still way more realistic than doing (free + cached) though.
See:
* https://gitlab.com/procps-ng/procps/issues/42
* https://github.com/famzah/linux-memavailable-procfs/issues/2
   MemFree:   Cached:r   s   Active(file):s   Inactive(file):   SReclaimable:zW is missing from /proc/meminfo; using an approximation for calculating available memoryNz	/zoneinfos   lowr   r=   g       @)getKeyErrorr   argsr   r   OSErrorstrip
startswithintr   PAGESIZEmin)memsrc   fallbacklru_active_filelru_inactive_fileslab_reclaimableerrr   watermark_lowlineavail	pagecaches               rF   calculate_avail_vmemr   !  sa   < Dhhz1--H	/0 !34 01?,-Y78 M	
D::<Dv&&TZZ\!_!55  

 XM E3IY]M22I	E	$4s$:M JJJEu:1  xx{m > >	
    
s@   C$ D *D*3#D*$
D.D
DDD'&D'*
D8c                     / n 0 n[        [        5        S35       nU H)  nUR                  5       n[        US   5      S-  XS   '   M+     SSS5        US   nUS   n US   n US
   nXR                  SS5      -  n US   n	 US   n
 US   n US   nXV-
  U-
  U-
  nUS:  a  XV-
  n US   nUS:X  a  [        U5      nUS:  a  SnU R                  S5        OX:  a  Un[        X^-
  USS9nU (       aL  SR                  SR                  U 5      [        U 5      S:X  a  SOS5      n[        R                  " U[        SS 9  [        UUUUUU
UUUU	U5      $ ! , (       d  f       GN= f! [         a    SnU R                  S	5         GN%f = f! [         a    SnU R                  S5         GN/f = f! [         a/     US   n	 GN@! [         a    Sn	U R                  S5          GNaf = ff = f! [         a    Sn
U R                  S5         GNf = f! [         a;     US   US   -   US   -   n GN! [         a    SnU R                  S5          GNf = ff = f! [         a    Sn GNf = f! [         a    [        U5      n GNf = f)!a  Report virtual memory stats.
This implementation mimics procps-ng-3.3.12, aka "free" CLI tool:
https://gitlab.com/procps-ng/procps/blob/
    24fd2605c51fccc375ab0287cec33aa767f06718/proc/sysinfo.c#L778-791
The returned values are supposed to match both "free" and "vmstat -s"
CLI tools.
/meminfor      r   Ns	   MemTotal:r   s   Buffers:rf   r   r   rg   s   Shmem:s
   MemShared:rh   s   Active:rd   s	   Inactive:s   Inact_dirty:s   Inact_clean:s   Inact_laundry:re   s   Slab:s   MemAvailable:r`   round_z6{} memory stats couldn't be determined and {} set to 0z, waswerer=   
stacklevel)r   r   r   r   r   r   r   r   r   formatjoinr   warningswarnRuntimeWarningr^   )missing_fieldsr   r   r   r   r_   rc   rf   rg   rh   rd   re   ri   rb   r   ra   msgs                    rF   virtual_memoryr   `  s    ND	)*(3	4DZZ\F!&)nt3DO  
5 ED){#
0j! 	((+Q//,i(j!
.%H~ <& 7*Dax |
/%& A:
 ).Eqyk*	 U]U1=G FMMIIn%(A-E6
 	c>a8 Y 
5	4  )i()  (h'(  ,	,-(F 	,F!!(++	,,  (h'(  	.	._%'(()* 
  	.H!!*--	.	.  $  +$T*+s   0EE( $F >F0 G, 
H I *I+ 
E%(F	F	F-,F-0
G);GG% G)$G%%G),HH
IH//IIIII('I(+JJc                     0 n [        [        5        S35       nU H)  nUR                  5       n[        US   5      S-  XS   '   M+     SSS5         U S   nU S   nXE-
  n[        XSS9n	 [        [        5        S	35      nU   S=pU H  nUR                  S
5      (       a$  [        UR                  S5      S   5      S-  S-  n
O9UR                  S5      (       a#  [        UR                  S5      S   5      S-  S-  nU
c  M{  Uc  M    O&   SnUS-  n[        R                  " U[        SS9  S=pSSS5        [        R                  " XHXYW
W5      $ ! , (       d  f       GN= f! [         a'    [
        R                  " 5       u        pdpWXG-  nXW-  n GN8f = f! , (       d  f       Nm= f! [         a-  nSU S3n[        R                  " U[        SS9  S=p SnANSnAff = f)zReturn swap memory metrics.r   r   r   r   Ns
   SwapTotal:s	   SwapFree:r   z/vmstats   pswpin       s   pswpoutz,'sin' and 'sout' swap memory stats couldn't zbe determined and were set to 0r=   r   zM'sin' and 'sout' swap memory stats couldn't be determined and were set to 0 ())r   r   r   r   r   cextlinux_sysinfor   r   r   r   r   r   r   sswap)r   r   r   r   r_   rc   _unit_multiplierrb   ra   sinsoutr   r   s                 rF   swap_memoryr     s   D	)*(3	4DZZ\F!&)nt3DO  
5 ]#L! <DD2G?,-W56 C ??9--djj.q12Q6=C__Z00tzz$/23a7$>D?t'7  E88c>a@% & ==dS$??c 
5	4   373E3E3G01a4  & Q  003uA7 	 	c>a8dsN   0E
E$ +F) A=FF	(F
E!$-FF
F&)
G 3#GG c                  T   [        5       n [        U 5        [        U  S35       nUR                  5       R	                  5       nSSS5        WS[        [        R                  5      S-    nU Vs/ s H  n[        U5      [        -  PM     nn[        U6 $ ! , (       d  f       NW= fs  snf )zReturn a named tuple representing the following system-wide
CPU times:
(user, nice, system, idle, iowait, irq, softirq [steal, [guest,
 [guest_nice]]])
Last 3 fields may not be available on all Linux kernel versions.
r   Nr   )
r   r   r   r   r   r   r   _fieldsfloatCLOCK_TICKS)r   r   r   r   rN   s        rF   	cpu_timesr  !  s     "#K%	}E*	+q##% 
,AI--.23F.45feAh$fF5f	 
,	+ 6s   B.B%
B"c                     [        5       n [        U 5        / n[        U  S35       nUR                  5         U H  nUR	                  S5      (       d  M  UR                  5       nUS[        [        R                  5      S-    nU Vs/ s H  n[        U5      [        -  PM     nn[        U6 nUR                  U5        M     UsSSS5        $ s  snf ! , (       d  f       g= f)z^Return a list of namedtuple representing the CPU times
for every CPU available on the system.
r   s   cpur   N)r   r   r   r   r   r   r   r   r   r   r   r   )r   cpusr   r   r   r   rN   entrys           rF   per_cpu_timesr  1  s     "#K%D	}E*	+q	

Dv&&C	(9(9$:Q$>?:@A&Q%([0&A!6*E"   
,	+ B 
,	+s#   *C3CC# CC
C c                  @    [         R                  " S5      $ ! [         a    Sn [        [	        5        S35       nU H.  nUR                  5       R                  S5      (       d  M)  U S-  n M0     SSS5        O! , (       d  f       O= fU S:X  a  [        R                  " S5      n[        [	        5        S35       nU H4  nUR                  S	5      S   nUR                  U5      (       d  M/  U S-  n M6     SSS5        O! , (       d  f       O= fU S:X  a   gU s $ f = f)
z0Return the number of logical CPUs in the system.SC_NPROCESSORS_ONLNr   /cpuinfos	   processorr   Nzcpu\dr   r   )r   sysconf
ValueErrorr   r   lowerr   recompiler   r   match)numr   r   searchs       rF   cpu_count_logicalr  E  s    zz/00 O-.h78A::<**<881HC  988 !8ZZ)Fo/0671D::c?1-D||D))q  877 !8
-sP    "D(A8&	A8/	D8
B	9D;.C?-	C?6	D?
D		DDDc                     [        5       n SnSn[        R                  " U5      =(       d    [        R                  " U5       HD  n[        U5       nU R                  UR	                  5       R                  5       5        SSS5        MF     [        U 5      nUS:w  a  U$ 0 n0 n[        [        5        S35       nU Hp  nUR                  5       R                  5       nU(       d   US   XgS   '   0 nM7  UR                  S5      (       d  MO  UR                  S	S
5      u  p[        U
5      Xy'   Mr     SSS5        [        UR                  5       5      nU=(       d    S$ ! , (       d  f       GM(  = f! [         a     Nf = f! , (       d  f       NU= f)z-Return the number of CPU cores in the system.z9/sys/devices/system/cpu/cpu[0-9]*/topology/core_cpus_listz?/sys/devices/system/cpu/cpu[0-9]*/topology/thread_siblings_listNr   r  	   cpu cores   physical id)r  r  s   	:r   )setglobr   addreadr   r   r   r  r   r   r   r   sumr   )lsp1p2ru   r   resultmappingcurrent_infor   keyvalues              rF   cpu_count_coresr"  b  sT    
B 
EB	JB		".2.!FF1668>>#$  / WF{ GL	)*(3	4D::<%%'D<H$=G89
  "!?@@!ZZ2
$'J!  
5" !"F>T7 $    
5	4sB   .E7+E=#
E--E=	%E=
E*	-
E:7E=9E::E==
Fc                     [        [        5        S35       n SnSnSnU  H  nUR                  S5      (       a  [        UR	                  5       S   5      nOeUR                  S5      (       a  [        UR	                  5       S   5      nO2UR                  S5      (       a  [        UR	                  5       S   5      nUc  M  Uc  M  Uc  M    O   SSS5        Sn[
        R                  " WWWU5      $ ! , (       d  f       N)= f)z*Return various CPU stats as a named tuple.r   Ns   ctxtr   s   intrs   softirqr   )r   r   r   r   r   r   	scpustats)r   ctx_switches
interruptssoft_interruptsr   syscallss         rF   	cpu_statsr)    s    	)*%0	1Q
Dw''"4::<?3)) a1
,,"%djjl1o"6(#/* 	 
2" Hj/8 % 
2	1s   B%C1 C1C1
C11
C?c            
         [        [        5        S35       n U  Vs/ s HG  nUR                  5       R                  S5      (       d  M)  [	        UR                  SS5      S   5      PMI     snsSSS5        $ s  snf ! , (       d  f       g= f)z7Return current CPU frequency from cpuinfo if available.r  s   cpu mhz   :r   N)r   r   r  r   r   r   )r   r   s     rF   _cpu_get_cpuinfo_freqr,    su    	)*(3	4 
zz|&&z2 *E$**T1%a()
 
5	4
 
5	4s"   A;(A6"A6*A;6A;;
B	z'/sys/devices/system/cpu/cpufreq/policy0z$/sys/devices/system/cpu/cpu0/cpufreqc            	         [        5       n [        R                  " S5      =(       d    [        R                  " S5      nUR                  S S9  / n[        R                  R
                  n[        U5       GH  u  pE[        U5      [        U 5      :X  a  X   S-  nO[        U" US5      SS9nUc^  [        U" US	5      SS9nUcJ  S
U S3n[        USS9S:X  a)  UR                  [        R                  " SSS5      5        M  Sn[        U5      e[        U5      S-  n[        [        U" US5      5      5      S-  n	[        [        U" US5      5      5      S-  n
UR                  [        R                  " XjU	5      5        GM     U$ )zjReturn frequency metrics for all CPUs.
Contrarily to other OSes, Linux updates these values in
real-time.
z,/sys/devices/system/cpu/cpufreq/policy[0-9]*z)/sys/devices/system/cpu/cpu[0-9]*/cpufreqc                 ^    [        [        R                  " SU 5      R                  5       5      $ )Nz[0-9]+)r   r  r  grouprN   s    rF   <lambda>cpu_freq.<locals>.<lambda>  s    RYYy!%<%B%B%D!ErE   )r   i  scaling_cur_freqNr   cpuinfo_cur_freqz/sys/devices/system/cpu/cpuz/onlinez0
r   z!can't find current frequency filescaling_max_freqscaling_min_freq)r,  r  sortr   ru   r   	enumerater   r   r   r   r   scpufreqNotImplementedErrorr   )cpuinfo_freqspathsretpjoiniru   curronline_pathr   max_min_s              rF   cpu_freqrE    sl   
 ./		:
 DYYBC 	 	

E
F 'GA5zS// %'$.E$(:;dK| E$(:;dK<$?s'"JK;6%?

7#3#3Cc#BC =C-c22t9t#DtE$(:;<=DDtE$(:;<=DDJJw''D9:- (. 
rE   c                  n    [        5        V s/ s H  n [        R                  " U SS5      PM     sn $ s  sn f )zmAlternate implementation using /proc/cpuinfo.
min and max frequencies are not available and are set to None.
r   )r,  r   r:  r0  s    rF   rE  rE    s1     8M7NO7N!  C-7NOOOs   "2c                       \ rS rSrSrg)_Ipv6UnsupportedErrori  r?   N)r@   rA   rB   rC   rD   r?   rE   rF   rH  rH    s    rE   rH  c                   l    \ rS rSrSrS rS rS r\S 5       r	\SS j5       r
\SS	 j5       rSS
 jrSrg)NetConnectionsi  a[  A wrapper on top of /proc/net/* files, retrieving per-process
and system-wide open connections (TCP, UDP, UNIX) similarly to
"netstat -an".

Note: in case of UNIX sockets we're only able to determine the
local endpoint/path, not the one it's connected to.
According to [1] it would be possible but not easily.

[1] http://serverfault.com/a/417946
c                    S[         R                  [         R                  4nS[         R                  [         R                  4nS[         R                  [         R                  4nS[         R                  [         R                  4nS[         R
                  S 4nXX4U4X4U4U4X44U4U4U4XX44X4X$4S.U l        S U l        g )Ntcptcp6udpudp6unix)allrL  tcp4rM  rN  udp4rO  rP  inetinet4inet6)socketAF_INETSOCK_STREAMAF_INET6
SOCK_DGRAMAF_UNIXtmap_procfs_path)selfrR  rM  rS  rO  rP  s         rF   __init__NetConnections.__init__  s     v~~v'9'9:););<v~~v'8'89):):;-D1<GG<GGG,\\
	 !rE   c                 &   [        [        5      n[        R                  " U R                   SU S35       H_  n [        U R                   SU SU 35      nUR                  S5      (       a(  USS  S S nX$   R                  U[        U5      45        M_  Ma     U$ ! [        [        4 a     Mx  [         aY  nUR                  [        R                  :X  a   S nAM  UR                  [        R                  :X  a  [        U5         S nAM  e S nAff = f)Nr   /fd/fd/zsocket:[r   )r   listr   listdirr^  r   r   r   r   FileNotFoundErrorProcessLookupErrorr   errnoEINVALENAMETOOLONGr   )r_  pidinodesrv   inoder   s         rF   get_proc_inodesNetConnections.get_proc_inodes  s    T"** 1 12!C5<=B9 D$5$5#6auD!EF  ##J//!!"IcrNEM((#s2w8 0% >, ' &'9:   99,99 2 22#Js)   BD.	D7D)D
DDc                     0 n[        5        H$  n UR                  U R                  U5      5        M&     U$ ! [        [        [
        4 a     MB  f = fN)pidsupdaterp  rh  ri  PermissionError)r_  rn  rm  s      rF   get_all_inodesNetConnections.get_all_inodes*  sT    6C
d22378   &'9?K  s    7AAc           
      f   U R                  S5      u  p#[        US5      nU(       d  gUR                  S5      nU[        R                  :X  ai  [
        (       a2  [        R                  " U[        R                  " U5      SSS2   5      nO[        R                  " U[        R                  " U5      5      nO[        R                  " U5      n [
        (       aP  [        R                  " [        R                  [        R                  " S/[        R                  " SU5      Q76 5      nOP[        R                  " [        R                  [        R                  " S/[        R                  " SU5      Q76 5      n [         R"                  " X#5      $ ! [         a    [        5       (       d  [        See f = f)	a.  Accept an "ip:port" address as displayed in /proc/net/*
and convert it into a human readable form, like:

"0500000A:0016" -> ("10.0.0.5", 22)
"0000000000000000FFFF00000100007F:9E49" -> ("::ffff:127.0.0.1", 40521)

The IP address portion is a little or big endian four-byte
hexadecimal number; that is, the least significant byte is listed
first, so we need to reverse the order of the bytes to convert it
to an IP address.
The port is represented as a two-byte hexadecimal number.

Reference:
http://linuxdevcenter.com/pub/a/linux/2000/11/16/LinuxAdmin.html
:   r?   asciiNre  z>4Iz<4I)r   r   encoderW  rX  LITTLE_ENDIAN	inet_ntopbase64	b16decoderZ  structpackunpackr
  r   rH  r   addr)r  familyipports       rF   decode_addressNetConnections.decode_address:  s>   " ::c?4} YYwV^^#}%%ff.>.>r.B4R4.HI%%ff.>.>r.BC!!"%B =))EEFMM%,DEB
  ))EEFMM%,DEB ||B%%  $/T9	s   AF (AF "F0Nc              #     #    U R                  S5      (       a%  [        R                  R                  U 5      (       d  g[	        U 5       nUR                  5         [        US5       H  u  pg UR                  5       SS u
  pp        pX;   a
  X<   S   u  pOS	u  pUb  XN:w  a  M>  U[        R                  :X  a
  [        U   nO[        R                  n [        R!                  X5      n	[        R!                  X5      n
XX)XU4v   M     SSS5        g! [         a    SU  SU SU< 3n[        U5      Sef = f! ["         a     M  f = f! , (       d  f       g= f7f)
z.Parse /proc/net/tcp* and /proc/net/udp* files.6Nr   r   error while parsing ; malformed line r   r   Nre  )r   r   ru   existsr   r   r9  r   r
  RuntimeErrorrW  rY  TCP_STATUSESr   	CONN_NONErJ  r  rH  )filer  type_rn  
filter_pidr   linenor   r   laddrraddrstatusro  r   rm  rv   s                   rF   process_inetNetConnections.process_inetm  sc     ==bggnnT&:&:t_JJL )!Q	6

Sb) BAeQ1a ? %mA.GC&GC)j.? 2 22!-f!5!(!2!2! . = =e L . = =e L uUCHHC !0 _ " 6.tf 5"81TH.  's+564 1 ! !C _s[   AE	"E	,DAE	*D8=E			E#D55E	8
EE	EE		
EEc           
   #     #    [        U 5       nUR                  5         U H  nUR                  5       n USS u        pxpyX;   a  X)   nOS/nU H_  u  pUb  X<:w  a  M  [        U5      S:X  a  US	   OS
n[        R                  " [        U5      5      nS
n[        R                  nXXUUU4v   Ma     M     SSS5        g! [         a    SU;  a   M  SU  SU< 3n
[	        U
5      ef = f! , (       d  f       g= f7f)zParse /proc/net/unix files.r      r   r  r  r  Nr   re   )
r   r   r   r
  r  r   r   socktype_to_enumr   r  )r  r  rn  r  r   r   tokensr   r  ro  r   pairsrm  rv   ru   r  r  s                    rF   process_unixNetConnections.process_unix  s     t_JJL	,281+/Aq!Qq ? #ME'LE$GC!-*2C -0[A-=vbz2 ' 8 8U D !#!(!2!2!5vsKK  %%  _ " ,$ .tf4EdXN  's++, _s@   C;&C*B? A6C*6	C;?C'C*C''C**
C84C;c                 6   [        5       U l        Ub  U R                  U5      nU(       d  / $ OU R                  5       n[	        5       nU R
                  U    H  u  pVnU R                   SU 3nU[        R                  [        R                  1;   a  U R                  XXsUS9n	OU R                  XX2S9n	U	 HR  u  pp{pnU(       a  [        R                  " XX{X5      nO[        R                  " XX{XU5      nUR                  U5        MT     M     [        U5      $ )Nz/net/)r  )r   r^  rp  rw  r  r]  rW  rX  rZ  r  r  r   pconnsconnr  rf  )r_  kindrm  rn  r>  
proto_namer  r  ru   r  rv   r  r  r  	bound_pidconns                   rF   retrieveNetConnections.retrieve  s   +-?))#.F	  ((*Fe)-4%J''(j\:D&..&//::&&%C '  &&tV&LFHBE%"==E%D #==E%D  GI *9$ CyrE   )r^  r]  rs  )r@   rA   rB   rC   __doc__r`  rp  rw  staticmethodr  r  r  r  rD   r?   rE   rF   rJ  rJ    s^    	!.4  0& 0&d (I (IT !L !LFrE   rJ  c                 ,    [         R                  U 5      $ )z$Return system-wide open connections.)_net_connectionsr  )r  s    rF   net_connectionsr    s    $$T**rE   c                     [        [        5        S35       n U R                  5       nSSS5        0 nWSS  H  nUR                  S5      nUS:  d   [	        U5      5       eUSU R                  5       nX4S-   S R                  5       R                  5       n[        [        U5      u  nnn	n
nnnnnnnnnnnnUUUUU	UU
U4X%'   M     U$ ! , (       d  f       N= f)zkReturn network I/O statistics for every network interface
installed on the system as a dict of raw tuples.
z/net/devNr=   rz  r   r   )	r   r   	readlinesrfindreprr   r   mapr   )r   linesretdictr   colonr   r   
bytes_recvpackets_recverrindropin_fifoin_framein_compressedin_multicastin
bytes_sentpackets_senterroutdropout_fifoout_collisionsout_carrierout_compressedouts                          rF   net_io_countersr    s
    
o'(1	2a 
3Gab	

3qy$$t*$yFU|!!#aik"((*002* V'	
 	
7 J NQ 
3	2s   C


Cc                  <   [         R                  [        [         R                  [        [         R
                  [        0n [        5       R                  5       n0 nU H{  n [        R                  " U5      n[        R                  " U5      n[         R                  " U5      u  pgSR                  U5      nSU;   n	[        R                  " XU   XtU5      X#'   M}     U$ ! [          a5  n
U
R"                  ["        R$                  :w  a  e ['        U
5         Sn
A
M  Sn
A
ff = f)z)Get NIC stats (isup, duplex, speed, mtu).,runningN)r   DUPLEX_FULLr   DUPLEX_HALFr   DUPLEX_UNKNOWNr   r  keys
cext_posix
net_if_mtunet_if_flagsnet_if_duplex_speedr   r   	snicstatsr   rj  ENODEVr   )
duplex_mapnamesr>  r   mtury   duplexspeedoutput_flagsisupr   s              rF   net_if_statsr    s     	///J
 ""$E
C	''-C++D1E 44T:MF 88E?L%D))(%lCI   J  	yyELL(#JJ		s   AC
D&*DDc                    S nS n[         R                  R                  [        5        S35      (       a  U" 5       nOD[         R                  R                  S5      (       a  U" 5       nO[        5        S3n[	        U5      e0 nU H@  nUu
  pxpppnnU (       d  [        U5      (       d  M%  U
[        -  n
U[        -  nXXXXU4	XW'   MB     U$ )z[Return disk I/O statistics for every disk installed on the
system as a dict of raw tuples.
c               3      #    [        [        5        S35       n U R                  5       nS S S 5        W H  nUR                  5       n[	        U5      nUS:X  a.  US   n[        US   5      n[        [
        USS 5      u
  pxpnppnOhUS:X  d  US:  a   US   n[        [
        USS 5      u  pgppppnO<US:X  a%  US   n[        [
        USS  5      u  phpS	=n	=n=n=pOS
U< 3n[        U5      eXVXXUX{U4
v   M     g ! , (       d  f       N= f7f)N
/diskstats   r>   r=   r         r  r   znot sure how to interpret line )r   r   r  r   r   r   r  r
  )r   r  r   r   flenr   readsreads_mergedrbytesrtimewriteswrites_mergedwbyteswtimer   rs   r   s                    rF   read_procfs%disk_io_counters.<locals>.read_procfs;  s7    " /+,J78AKKME 9DZZ\Fv;DrzayF1I69#va|6L4um1trzay69#va|6L4fV1ay03C0D-vKLLLLL}y7x@ o%u	; ;/  98s   DC=CD=
DDc               3   2  #    [         R                  " S5       H  n [         R                  " [         R                  R	                  SU 5      5       H  u  pnSU;  a  M  [        [         R                  R	                  US5      5       nUR                  5       R                  5       R                  5       nS S S 5        [         R                  R                  U5      n[        [        WS S 5      u
  pxpppp/XgXXXX4
v   M     M     g ! , (       d  f       NX= f7f)N
/sys/blockstatr   )r   rg  walkru   r   r   r  r   r   basenamer  r   )blockrootr   filesr   r   r   r  r  r  r  r  r  r  r  rs   s                   rF   
read_sysfs$disk_io_counters.<locals>.read_sysfsi  s     ZZ-E"$''"'',,|U*K"L&rww||D&9:aVVX^^-335F ;ww''- 47sF3BK3H1fV1FFMF F #M . ;:s   BD-D4AD
DDr  r  z6/diskstats nor /sys/block are available on this system)r   ru   r  r   r;  r   DISK_SECTOR_SIZE)perdiskr  r  genr   r  r  r   r  r  r  r  r  r  r  r  rs   s                    rF   disk_io_countersr  6  s    
+;\F 
ww~~*+:677m		%	%l  ! "  	 "#&&G ).	&ffU9066 """"%iA) 0 NrE   c                   >    \ rS rSrSrSS/rS rS rS rS r	S	 r
S
rg)RootFsDeviceFinderi  a2  disk_partitions() may return partitions with device == "/dev/root"
or "rootfs". This container class uses different strategies to try to
obtain the real device path. Resources:
https://bootlin.com/blog/find-root-device/
https://www.systutorials.com/how-to-find-the-disk-where-root-is-on-in-bash-on-linux/.
majorminorc                     [         R                  " S5      R                  n[         R                  " U5      U l        [         R                  " U5      U l        g )Nr   )r   r  st_devr  r  )r_  devs     rF   r`  RootFsDeviceFinder.__init__  s3    ggcl!!XXc]
XXc]
rE   c                    [        [        5        S35       nUR                  5       SS   H  nUR                  5       n[	        U5      S:  a  M$  US   R                  5       (       a  [        US   5      OS nUS   R                  5       (       a  [        US   5      OS nUS   nX@R                  :X  d  M  XPR                  :X  d  M  U(       d  M  SU 3s  sS S S 5        $    S S S 5        g ! , (       d  f       g = f)Nz/partitionsr=   r   r   r   r>   /dev/)	r   r   r  r   r   isdigitr   r  r  )r_  r   r   r   r  r  r   s          rF   ask_proc_partitions&RootFsDeviceFinder.ask_proc_partitions  s    /+,K89Qab)v;?*0)*;*;*=*=F1I4*0)*;*;*=*=F1I4ayJJ&5JJ+>t!&tf~- :9) :99s$   BC*5C*C*C*C**
C8c                 <   SU R                    SU R                   S3n[        U5       nU HT  nUR                  S5      (       d  M  UR	                  5       R                  S5      S   nU(       d  MF  SU 3s  sS S S 5        $    S S S 5        g ! , (       d  f       g = f)Nz/sys/dev/block/rz  z/ueventzDEVNAME=r=   r	  )r  r  r   r   r   
rpartition)r_  ru   r   r   r   s        rF   ask_sys_dev_block$RootFsDeviceFinder.ask_sys_dev_block  s{     Adjj\At_??:..::<22:>qADt!&tf~- _ __s   B'B2BB
Bc                    U R                    SU R                   3n[        R                  " S5      nU H  n [	        U5      nU   UR                  5       R                  5       nXQ:X  aL  [        R                  R                  [        R                  R                  U5      5      nSU 3sS S S 5        s  $  S S S 5        M     g ! , (       d  f       M  = f! [         a     M  f = f)Nrz  z/sys/class/block/*/devr	  )r  r  r  iglobr   r  r   r   ru   r  dirnamerh  )r_  needler  r  r   datar   s          rF   ask_sys_class_block&RootFsDeviceFinder.ask_sys_class_block  s    JJ<q-

34D	.dO 668>>+D~!ww//0EF!&tf~	 Q% Q  Q % s   CA$C
C	
C#"C#c                    S nUc   U R                  5       nUc   U R                  5       nUc   U R	                  5       nUb'  [
        R                  R                  U5      (       a  U$ g g ! [         a  n[        U5         S nANmS nAff = f! [         a  n[        U5         S nAN{S nAff = f! [         a  n[        U5         S nANS nAff = frs  )r  r   r   r  r  r   ru   r  )r_  ru   r   s      rF   findRootFsDeviceFinder.find  s    <//1 <--/ <//1
 t 4 4K !5  c


  c


  c

sE   A* B B. *
B	4BB	
B+B&&B+.
C8CC)r  r  N)r@   rA   rB   rC   r  	__slots__r`  r  r  r  r  rD   r?   rE   rF   r  r    s,     '"I#
...rE   r  c                    [        5       n[        5       nU (       d  [        U S35       nU Hw  nUR                  5       nUR	                  S5      (       d!  UR                  UR                  5       5        MJ  UR                  S5      S   nUS:X  d  Mf  UR                  S5        My     SSS5        US:X  aD  [        R                  R                  S5      (       a   [        R                  R                  S5      nO"[        R                  R                  U S	35      n/ n[        R                  " U5      nU Ht  n	U	u  pp\U
S
:X  a  Sn
U
S;   a!  [        5       R                  5       =(       d    U
n
U (       d  U
(       a  XQ;  a  ML  [        R                   " XX\5      nUR#                  U5        Mv     U$ ! , (       d  f       GN= f)z8Return mounted disk partitions as a list of namedtuples.z/filesystemsnodev	r   zfsNr   z	/etc/mtabz/self/mountsnoner  >   rootfs	/dev/root)r  r   r   r   r   r  r   r   ru   isfilerealpathr   disk_partitionsr  r  r   	sdiskpartr   )rQ  fstypesr   r   r   fstypemounts_pathretlist
partitions	partitiondevice
mountpointoptsntuples                 rF   r%  r%    sd   eG!#K+l34zz|w//KK

- "ZZ-a0FE*  5 g"''.."="=gg&&{3gg&&+l'CDG%%k2J	+4(FVF,,')..0:FFV2""6vDv   N? 54s   A%F0F00
F?c            	         [         R                  " [        5      n [        R                  " S5      nUR	                  [        R                  " S5      5        [        U Vs1 s H  o"R                  S5      S   iM     sn5      n[        R                  " S5      n[        R                  " S5      nU H-  nUR                  SU5      nXa;  d  M  UR                  U5        M/     U H  n US-   n[        [        U5      5      S	-  n	[        R                  R                  [        R                  R!                  U5      S
5      n[#        U5      R%                  5       n
[        US-   SS9n[        US-   SS9n[#        US-   SS9R%                  5       nUb   [        U5      S	-  nUb   [        U5      S	-  nX
   R                  XX45        M     U(       Gd  [        R                  " S5      n[        [+        U5      5      nU GH  n [        R                  R                  US5      n[        [        U5      5      S	-  n	[        R                  R                  US5      n[#        U5      R%                  5       n
[        R                  " US-   5      nU Vs1 s HC  nSR                  [        R                  R/                  U5      R                  S5      SS 5      iME     nnSnSnU H  n[        R                  R                  UUS-   5      n[#        USS9R%                  5       nUS:X  a,  [        [        R                  R                  UUS-   5      SS9nO1US:X  a+  [        [        R                  R                  UUS-   5      SS9nUb   [        U5      S	-  nUc  M   [        U5      S	-  nM     X
   R                  SXU45        GM     [1        U 5      $ s  snf ! [&        [(        4 a     GM
  f = f! [(         a    Sn GN`f = f! [(         a    Sn GNaf = f! [&        [(        4 a  n[-        U5         SnAGM:  SnAff = fs  snf ! [(         a    Sn Nf = f! [(         a    Sn GM  f = f)a  Return hardware (CPU and others) temperatures as a dict
including hardware name, label, current, max and critical
temperatures.

Implementation notes:
- /sys/class/hwmon looks like the most recent interface to
  retrieve this info, and this implementation relies on it
  only (old distros will probably use something else)
- lm-sensors on Ubuntu 16.04 relies on /sys/class/hwmon
- /sys/class/thermal/thermal_zone* is another one but it's more
  difficult to parse
z/sys/class/hwmon/hwmon*/temp*_*z&/sys/class/hwmon/hwmon*/device/temp*_*r   r   z5/sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_*z'/sys/devices/platform/coretemp.*/hwmon/z/sys/class/hwmon/_inputg     @@r   _maxNr4  _crit_labelr  z /sys/class/thermal/thermal_zone*temptypez/trip_point*r>   _typecritical_temphigh)collectionsr   rf  r  extendsortedr   r  r  subr   r   r   r   ru   r   r  r   r   r   r
  r  r   r  dict)r>  	basenamesrN   
basenames2replr   altnamebaseru   current	unit_namer;  r9  labelr   
trip_pathsptrip_points
trip_point	trip_types                       rF   sensors_temperaturesrN    s	    
!
!$
'C		;<I TYYGHI;AQ;<I ?J ::@AD((.5#T" 
 	(?DDJ'&0G77<< 5v>DD	)I D6MD1w6D8Ob1779T{V+   ?V3 	ut>?A F II@A	3y>*	Dww||D&1T
+f4ww||D&1IOO-	
 4.#89J $#A ))!,2237!<=#   HD)
ww||D*w*>?r288:	
*#T:+?@4 H &(T:+?@4D #$$T{V3 '(#(?V#;' *. N!!2wh"?@Q T 9A <* $ 		 		$  
      Z( c

* & $#$
 & (#'(s   O(A2OO2%PA0PA
Q	QQO/.O/2PPPPP?(P::P?QQQ*)Q*c                     [         R                  " [        5      n [        R                  " S5      nU(       d  [        R                  " S5      n[	        U Vs1 s H  o"R                  S5      S   iM     sn5      nU H  n [        [        US-   5      5      n[        [        R                  R                  [        R                  R                  U5      S5      5      R                  5       n[        US-   S	S
9R                  5       nX   R!                  ["        R$                  " Xt5      5        M     ['        U 5      $ s  snf ! [         a  n[        U5         SnAM  SnAff = f)ak  Return hardware fans info (for CPU and other peripherals) as a
dict including hardware label and current speed.

Implementation notes:
- /sys/class/hwmon looks like the most recent interface to
  retrieve this info, and this implementation relies on it
  only (old distros will probably use something else)
- lm-sensors on Ubuntu 16.04 relies on /sys/class/hwmon
z/sys/class/hwmon/hwmon*/fan*_*z%/sys/class/hwmon/hwmon*/device/fan*_*r   r   r2  Nr   r5  r  r4  )r<  r   rf  r  r>  r   r   r   r   r   r   r   ru   r   r  r   r   r   sfanr@  )r>  rA  rN   rE  rF  r   rG  rH  s           rF   sensors_fansrQ    s    
!
!$
'C		:;I IIEF	;AQ;<I	$th/0G RWW__T%:FCDJJL	D8Ob1779gll5:;  9 <  	#J	s   D=E
E"EE"c                    ^ [        5       mU4S jn [        R                  " [        5       Vs/ s H1  nUR	                  S5      (       d  SUR                  5       ;   d  M/  UPM3     nnU(       d  g[        R                  R                  [        [        U5      5      nU " US-   US-   5      nU " US-   US-   5      nU " US	-   US
-   5      nU " US-   5      nUb  Ub
   SU-  U-  nO[        [        US-   SS95      nUS:X  a  gSn	U " [        R                  R                  [        S5      [        R                  R                  [        S5      5      n
U
b  U
S:H  n	O:[        US-   SS9R                  5       R                  5       nUS:X  a  Sn	OUS;   a  Sn	U	(       a  [        R                  nOPUb  Ub   [        XE-  S-  5      nO8Ub%  [        US-  5      nUS:  a  [        R                  nO[        R                  n[        R                   " XU	5      $ s  snf ! [         a    Sn GN%f = f! [         a    [        R                  n NKf = f)zReturn battery information.
Implementation note: it appears /sys/class/power_supply/BAT0/
directory structure may vary and provide files with the same
meaning but under different names, see:
https://github.com/giampaolo/psutil/issues/966.
c                     > U  H!  n[        UTS9nUT:w  d  M   [        U5      s  $    g! [         a    UR                  5       s s  $ f = f)zfAttempt to read the content of multiple files which may
not exist. If none of them exist return None.
r4  N)r   r   r
  r   )r=  ru   r>  nulls      rF   
multi_bcat#sensors_battery.<locals>.multi_bcat  sR     Dtd+Cd{'s8O	   " '99;&'s   
*A	A	BATbatteryNz/energy_nowz/charge_nowz
/power_nowz/current_nowz/energy_fullz/charge_fullz/time_to_empty_nowg      Y@r   z	/capacityre  r4  z
AC0/onlinez	AC/onliner   /statusr  dischargingF>   fullchargingTi  <   r   )objectr   rg  POWER_SUPPLY_PATHr   r  ru   r   r   ZeroDivisionErrorr   r   r   r   POWER_TIME_UNLIMITEDPOWER_TIME_UNKNOWNsbattery)rU  rN   batsr  
energy_now	power_nowenergy_fulltime_to_emptyra   power_pluggedonliner  secsleftrT  s                @rF   sensors_batteryrl    sK    8D -..A<<)qwwy"8 	
. 	 
  77<<)3t95D D=0$2FGJ4,.~0EFITN2D>4IJKt&::;M :#9	j(;6G c$,r:;b=
 M
&5
&4F !TI%399;AAC]"!M++ M //		I$9	2:1D89H 
	"}r)*a<11H--G}==C. ! 	G	B ! 	211H	2s/   .H HH 3H+ H('H(+IIc                      / n [         R                  " 5       nU H;  nUu  p4pVn[        R                  " X4=(       d    SXVU5      nU R	                  U5        M=     U $ )z:Return currently connected users as a list of namedtuples.N)r   usersr   suserr   )	r*  rawlistitemr   ttyhostnametstamprm  nts	            rF   rn  rn  
  sQ    GjjlG+/(8S]]4hDr  NrE   c                  &   [        5        S3n [        U 5       nU HR  nUR                  S5      (       d  M  [        UR	                  5       R                  5       S   5      nUqUs  sSSS5        $    SU  3n[        U5      e! , (       d  f       g= f)zAReturn the system boot time expressed in seconds since the epoch.r   s   btimer   Nzline 'btime' not found in )r   r   r   r   r   r   	BOOT_TIMEr  )ru   r   r   r>  r   s        rF   	boot_timerx    s      &D	T	aDx((DJJL..034	
 
	
 +4&13 
	s   B/B0B
Bc                      [        5       R                  [        5      n [        R                  " U 5       Vs/ s H$  oR                  5       (       d  M  [        U5      PM&     sn$ s  snf )z7Returns a list of PIDs currently running on the system.)r   r}  r
   r   rg  r
  r   )ru   rN   s     rF   rt  rt  (  sD    ##H-DJJt,<,q		FCF,<<<s   A$A$c                    [         R                  " U 5      (       d  g [        5        SU  S3n[        U5       nU HD  nUR	                  S5      (       d  M  [        UR                  5       S   5      nX@:H  s  sSSS5        $    SU 3n[        U5      e! , (       d  f       g= f! [        [        4 a    U [        5       ;   s $ f = f)z[Check for the existence of a unix PID. Linux TIDs are not
supported (always return False).
Fr   rY  s   Tgid:r   Nz'Tgid' line not found in )
r   
pid_existsr   r   r   r   r   r
  r   rt  )rm  ru   r   r   tgidr   s         rF   r{  r{  .  s     s##	! &'(#g6DT"aDx00"4::<?3  ${* #" 2$8 o% #" $ 	!$&= 	!s:   B% B!B8	B% B
B"B% "B% %CCc                  V   0 n [        5       n[        5        Hf  n [        U SU S35       nUR                  5       nSSS5        WR	                  S5      nXES-   S R                  5       n[        US   5      nXpU'   Mh     U $ ! , (       d  f       NL= f! [        [        4 a     M  f = f)zkObtain a {pid: ppid, ...} dict for all running processes in
one shot. Used to speed up Process.children().
r   r   N   )r=   r   )	r   rt  r   r  r  r   r   rh  ri  )r>  r   rm  r   r  rpardsetppids           rF   ppid_mapr  O  s     C!#Kv	}AcU%89Qvvx : ::d#Dq
#))+DtAw<DH  J :9!#56 	 	s'   BBB
B	BB('B(c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )zdDecorator which translates bare OSError and OSError exceptions
into NoSuchProcess and AccessDenied.
c                   > U R                   U R                  pC T" U /UQ70 UD6$ ! [         a  n[        X45      UeS nAf[         a!  nU R                  5         [        X45      UeS nAf[         aV  nU R                  5         [        R                  R                  U R                   SU S35      (       d  [        X45      Uee S nAff = f)Nr   r   )rm  _namerv  r   ri  _raise_if_zombier   rh  r   ru   r  r^  )r_  r   kwargsrm  r   r   funs         rF   wrapper wrap_exceptions.<locals>.wrapperj  s    HHdjjT	t-d-f-- 	3s)s2! 	4!!#*3  	!!# 77>>T%6%6$7qU"CDD#C.C7	s+   & 
C<C	A%%C2ACC)	functoolswraps)r  r  s   ` rF   wrap_exceptionsr  e  s'    
 __S $ NrE   c                      \ rS rSrSr/ SQrS rS rS rS r	\
\S 5       5       r\
\S	 5       5       r\
\S
 5       5       rS rS r\
S 5       r\
S 5       r\
S 5       r\
S 5       r\
S 5       r\R.                  R1                  S\R2                  " 5        S35      (       a  \
S 5       r\
S 5       r\
S 5       r\
S<S j5       r\
S 5       r\
S 5       r\ (       d  \!(       aI  S r"\
\#RH                  " S5      \#RH                  " S5      \#RH                  " S5      4S j5       r%\
S  5       r&O\r&\!(       a  \
S! 5       r'\
S" 5       r(\
\#RH                  " S#5      4S$ j5       r)\
\#RH                  " S%5      4S& j5       r*\
S' 5       r+\
S( 5       r,\
S) 5       r-\.(       a&  \
S* 5       r/\#RH                  " S+5      4S, jr0\
S- 5       r1\2(       a  \
S. 5       r3\
S/ 5       r4\5" \6S05      (       a
  \
S<S1 j5       r7\
S2 5       r8\
S3 5       r9\
S=S4 j5       r:\
S5 5       r;\
S6 5       r<\
\#RH                  " S75      4S8 j5       r=\
\#RH                  " S95      4S: j5       r>S;r?g)>Processi  zLinux process implementation.)_cacher  _ppidr^  rm  c                 J    Xl         S U l        S U l        [        5       U l        g rs  )rm  r  r  r   r^  )r_  rm  s     rF   r`  Process.__init__  s     

+-rE   c                      [        U R                   SU R                   S35      nUR                  S5      nXS-   US-    nUS:H  $ ! [         a     gf = f)Nr   r   r~  r=   r>      ZF)r   r^  rm  r  r   )r_  r  r  r  s       rF   
_is_zombieProcess._is_zombie  si    	"4,,-Qtxxj>?D ::d#D(TAX.FT>!  		s   %A 
AAc                     U R                  5       (       a+  [        U R                  U R                  U R                  5      eg rs  )r  r   rm  r  r  r_  s    rF   r  Process._raise_if_zombie  s/    ??$**djjAA rE   c                 b    [         R                  " U R                   SU R                   35        g)z+Raise NSP if the process disappeared on us.r   N)r   r  r^  rm  r  s    rF   _raise_if_not_aliveProcess._raise_if_not_alive  s&     	4$$%Qtxxj12rE   c                    [        U R                   SU R                   S35      nUR                  S5      nXR	                  S5      S-   U nXS-   S R                  5       n0 nX5S'   US	   US
'   US   US'   US   US'   US   US'   US   US'   US   US'   US   US'   US   US'   US   US'    US   US'   U$ ! [         a    [        S5        S	US'    U$ f = f)a!  Parse /proc/{pid}/stat file and return a dict with various
process info.
Using "man proc" as a reference: where "man proc" refers to
position N always subtract 3 (e.g ppid position 4 in
'man proc' == position 1 in here).
The return value is cached in case oneshot() ctx manager is
in use.
r   r   r~     (r   r=   Nr   r   r  r  r   ttynr   utime   stime   children_utimer  children_stime   create_time$   cpu_num'   blkio_ticksz&can't get blkio_ticks, set iowait to 0)r   r^  rm  r  r  r   
IndexErrorr   )r_  r  r  r   r   r>  s         rF   _parse_stat_fileProcess._parse_stat_file  s-    t(()488*E:; zz$IIdOa'$/Qhj!'')Fq	HQiFayGbzGbzG &r
 &r
#BZMI	#!'C 
  	#:;!"C
	#s   1B; ;CCc                     [        U R                   SU R                   S35       nUR                  5       sSSS5        $ ! , (       d  f       g= f)zwRead /proc/{pid}/stat file and return its content.
The return value is cached in case oneshot() ctx manager is
in use.
r   rY  N)r   r^  rm  r  r_  r   s     rF   _read_status_fileProcess._read_status_file  s<     D--.azABa668 CBBs   A  
Ac                     [        U R                   SU R                   S35       nUR                  5       R	                  5       sS S S 5        $ ! , (       d  f       g = f)Nr   r2   )r   r^  rm  r  r   r  s     rF   _read_smaps_fileProcess._read_smaps_file  sC     D--.az@AQ668>># BAAs   A
Ac                     U R                   R                  U 5        U R                  R                  U 5        U R                  R                  U 5        g rs  )r  cache_activater  r  r  s    rF   oneshot_enterProcess.oneshot_enter  s>    ,,T2--d3,,T2rE   c                     U R                   R                  U 5        U R                  R                  U 5        U R                  R                  U 5        g rs  )r  cache_deactivater  r  r  s    rF   oneshot_exitProcess.oneshot_exit  s>    ..t4//5..t4rE   c                 :    [        U R                  5       S   5      $ )Nr   )r   r  r  s    rF   r   Process.name  s     d++-f566rE   c                     [        U R                   SU R                   S35      $ ! [        [        4 aQ    U R                  5         [        R                  R                  U R                   SU R                   35      (       a   ge f = f)Nr   z/exer  )	r   r^  rm  rh  ri  r  r   ru   lexistsr  s    rF   exeProcess.exe  s|    		t001488*DABB!#56 	!!# ww$"3"3!4AdhhZ@AA	s   $' ABBc                    [        U R                   SU R                   S35       nUR                  5       nS S S 5        W(       d  U R	                  5         / $ UR                  S5      (       a  SOSnUR                  U5      (       a  US S nUR                  U5      nUS:X  a&  [        U5      S:X  a  SU;   a  UR                  S5      nU$ ! , (       d  f       N= f)Nr   z/cmdliner   r   re  r   )r   r^  rm  r  r  r   r   r   )r_  r   r  sepcmdlines        rF   r  Process.cmdline  s    $++,AdhhZx@AQ668D B!!#I f--f3==9D**S/ &=S\Q.3$;jjoG- BAs   C
Cc                     [        U R                   SU R                   S35       nUR                  5       nS S S 5        [	        W5      $ ! , (       d  f       N= f)Nr   z/environ)r   r^  rm  r  r   )r_  r   r  s      rF   environProcess.environ  sJ    $++,AdhhZx@AQ668D B"4(( BAs   A


Ac                     [        U R                  5       S   5      n[        R                  " 5       n X!   $ ! [         a     g f = f)Nr  )r   r  r   get_terminal_mapr   )r_  tty_nrr]  s      rF   terminalProcess.terminal  sG    T**,W56((*	< 		s   7 
AAr1   /ioc           	         U R                    SU R                   S3n0 n[        U5       nU H=  nUR                  5       nU(       d  M   UR	                  S5      u  pV[        U5      X%'   M?     S S S 5        U(       d  U S3n[        U5      e [        US   US   US   US   US	   US
   5      $ ! [         a     M  f = f! , (       d  f       NY= f! [         a*  nUR                  S   < SU SU< 3n[        U5      S eS nAff = f)Nr   r  s   : z file was emptys   syscrs   syscws
   read_bytess   write_bytess   rchars   wcharr   z field was not found in z; found fields are )r^  rm  r   r   r   r   r
  r  r   r   r   )	r_  fnamer   r   r   r   r!  r   r   s	            rF   io_countersProcess.io_counters$  s2   (()488*C8EFU#qD::<Dt6*.**U*;KD
 ,/u:FL  $ /"3''08$8$=)>*8$8$   * %$% $#0  0xx{o%=eW E##)*.  !o4/0sG   C
B0C!C 0
B>:C=B>>C
C
D%DDc                    U R                  5       n[        US   5      [        -  n[        US   5      [        -  n[        US   5      [        -  n[        US   5      [        -  n[        US   5      [        -  n[        X#XEU5      $ )Nr  r  r  r  r  )r  r   r   r   )r_  r   r  r  r  r  r   s          rF   r  Process.cpu_timesG  s    &&(fWo&4fWo&4v&678;Fv&678;Fvm,-;~vNNrE   c                 :    [        U R                  5       S   5      $ )zWhat CPU the process is on.r  r   r  r  s    rF   r  Process.cpu_numQ  s     4((*9566rE   Nc                 X    [         R                  " U R                  XR                  5      $ rs  )r   wait_pidrm  r  )r_  timeouts     rF   waitProcess.waitV  s      7JJ??rE   c                     [        U R                  5       S   5      n[        =(       d
    [        5       nU[        -  U-   $ )Nr  )r   r  rw  rx  r   )r_  ctimebts      rF   r  Process.create_timeZ  s8    d++-m<= %)+#r))rE   c           	          [        U R                   SU R                   S35       nS UR                  5       R	                  5       S S  5       u  p#pEpgnS S S 5        [        WWWWWWW5      $ ! , (       d  f       N= f)Nr   z/statmc              3   F   #    U  H  n[        U5      [        -  v   M     g 7frs  )r   r   ).0rN   s     rF   	<genexpr>&Process.memory_info.<locals>.<genexpr>s  s      8+CaA!+Cs   !r  )r   r^  rm  r   r   rz   )	r_  r   vmsr   rh   textlibr  dirtys	            rF   memory_infoProcess.memory_infoe  s}     D--.az@AQ8+,::<+=+=+?+C84CfCu B CfdCu==	 BAs   .A--
A;c                    S=n=p#[        U R                   SU R                   S35       nU H  nUR                  S5      (       a$  U[	        UR                  5       S   5      S-  -  nM=  UR                  S5      (       a!  [	        UR                  5       S   5      S-  nMt  UR                  S5      (       d  M  [	        UR                  5       S   5      S-  nM     S S S 5        XU4$ ! , (       d  f       N= f)	Nr   r   r3   s   Private_r   r      Pss:   Swap:)r   r^  rm  r   r   r   )r_  r|   r}   r~   r   r   s         rF   _parse_smaps_rollupProcess._parse_smaps_rollupz  s      ! C #$$%Qtxxj>D{33s4::<?3d::11!$**,q/2T922"4::<?3d:  d## s   BC):#C))
C7s   \nPrivate.*:\s+(\d+)s   \nPss\:\s+(\d+)s   \nSwap\:\s+(\d+)c                 ,   U R                  5       n[        [        [        UR	                  U5      5      5      S-  n[        [        [        UR	                  U5      5      5      S-  n[        [        [        UR	                  U5      5      5      S-  nXVU4$ )Nr   )r  r  r  r   findall)r_  _private_re_pss_re_swap_re
smaps_datar|   r}   r~   s           rF   _parse_smapsProcess._parse_smaps  s    * ..0J c#{22:>?@4GCc#wz:;<tCCs3 0 0 <=>EDd##rE   c                     [         (       a   U R                  5       u  pnOU R	                  5       u  pnU R                  5       n[        XAX#4-   6 $ ! [        [        4 a    U R	                  5       u  pn NAf = frs  )HAS_PROC_SMAPS_ROLLUPr  ri  rh  r  r  r{   )r_  r|   r}   r~   	basic_mems        rF   memory_full_infoProcess.memory_full_info  s}    $$9%)%=%=%?NCd "&!2!2!4$((*IYs)99:: +,=> 9%)%6%6%8NCd9s   A #A65A6c                 ~   S nU R                  5       nU(       d  U R                  5         / $ UR                  S5      n/ nUR                  S5      nU/nU" X65       GHA  u  prUR                  SS5      n Uu  pppU(       d  SnOF[        U5      nUR                  5       nUR                  S5      (       a  [        U5      (       d  USS	 n[        U	5      [        U
5      UUR                  S
S5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      UR                  SS5      4nUR                  U5        GMD     U$ ! [         a    US/-   u  ppp GN@f = f)a  Return process's mapped memory regions as a list of named
tuples. Fields are explained in 'man proc'; here is an updated
(Apr 2012) version: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/proc.txt?id=b76437579d1344b612cf1851ae610c636cec7db0.

/proc/{PID}/smaps does not exist on kernels < 2.6.14 or if
CONFIG_MMU kernel configuration option is not enabled.
c              3     #    0 nU  Hl  nUR                  S S5      nUS   R                  S5      (       d'  UR                  5       U4v   UR                  U5        MU   [	        US   5      S-  X$S   '   Mn     UR                  5       U4v   g ! [
         a/    US   R                  S5      (       a   M  SU< 3n[        U5      S ef = f7f)N   r   r+  r   r   s   VmFlags:z!don't know how to interpret line )r   r   popr   r   r
  r   )r  current_blockr  r   r   r   s         rF   
get_blocks'Process.memory_maps.<locals>.get_blocks  s     !D!ZZa0F!!9--d33,002D99%,,T2<.1&)nt.CDO " %((*D11  * <%ay33K@@ ($EdX"NC",S/t;<s*   ACB3C#C/C2CC   
r   Nr  r  z[anon]r   r   s   Rss:s   Size:r  s   Shared_Clean:s   Shared_Dirty:s   Private_Clean:s   Private_Dirty:s   Referenced:s
   Anonymous:r  )r  r  r   r  r
  r   r   r   r   r   r   )r_  r  r  r  r  
first_liner  headerhfieldsr  perms_offset_dev_inoderu   rq  s                   rF   memory_mapsProcess.memory_maps  s   2& ((*D %%'	JJu%EB1J'LM *5 @ ,,tQ/N?F<D #D!$<D::<D}}\22;M< <  $DSz4L5MHHWa(HHXq)HHWa(HH-q1HH-q1HH.2HH.2HH^Q/HH]A.HHXq) 		$= !A> I7 " N?F"~<DNs   5F$$F<;F<c                 L    [        U R                   SU R                   S35      $ )Nr   z/cwd)r   r^  rm  r  s    rF   cwdProcess.cwd  s%    4,,-Qtxxj=>>rE   s   ctxt_switches:\t(\d+)c                     U R                  5       nUR                  U5      nU(       d(  SU R                   SU R                   S3n[	        U5      e[
        R                  " [        US   5      [        US   5      5      $ )NzR'voluntary_ctxt_switches' and 'nonvoluntary_ctxt_switches'lines were not found in r   z1/status; the kernel is probably older than 2.6.23r   r   )r  r  r^  rm  r;  r   pctxswr   )r_  	_ctxsw_rer  ctxswr   s        rF   num_ctx_switchesProcess.num_ctx_switches  s}     %%'!!$'%%&az 2..  &c**~~c%(mSq];;rE   s   Threads:\t(\d+)c                 \    U R                  5       n[        UR                  U5      S   5      $ Nr   )r  r   r  )r_  _num_threads_rer  s      rF   num_threadsProcess.num_threads  s-     %%'?**40344rE   c                    [         R                  " U R                   SU R                   S35      nUR	                  5         / nSnU H  nU R                   SU R                   SU S3n [        U5       nUR                  5       R                  5       nS S S 5        WUR                  S5      S-   S  nUR                  S	5      n[        US
   5      [        -  n	[        US   5      [        -  n
[        R                  " [!        U5      X5      nUR#                  U5        M     U(       a  U R%                  5         U$ ! , (       d  f       N= f! [        [        4 a    Sn GM  f = f)Nr   z/taskFz/task/r   Tr~  r=   r   r  r  )r   rg  r^  rm  r8  r   r  r   rh  ri  r  r   r   r   r   pthreadr   r   r  )r_  
thread_idsr*  
hit_enoent	thread_idr  r   str   r  r  r0  s               rF   threadsProcess.threads!  s;   ZZ4#4#4"5Qtxxj FG

#I(()488*F9+UKE '1)B ( BGGDMA%'(BXXd^F&*%3E&*%3E__S^UBFNN6"! $" $$&! ('%'9:  "
	s0   *E5D<E<
E
	E
EE$#E$c                 B    [         R                  " U R                  5      $ rs  )r  getpriorityrm  r  s    rF   nice_getProcess.nice_get<  s     %%dhh//rE   c                 D    [         R                  " U R                  U5      $ rs  )r  setpriorityrm  )r_  r!  s     rF   nice_setProcess.nice_setE  s    %%dhh66rE   c                 B    [         R                  " U R                  5      $ rs  )r   r5   rm  r  s    rF   cpu_affinity_getProcess.cpu_affinity_getL  s    --dhh77rE   s   Cpus_allowed_list:\t(\d+)-(\d+)c           	         U R                  5       nUR                  U5      nU(       a6  [        [        [	        US   S   5      [	        US   S   5      S-   5      5      $ [        [        [        [        5       5      5      5      $ )Nr   r   )r  r  rf  ranger   r   r  )r_  _rer  r  s       rF   _get_eligible_cpusProcess._get_eligible_cpusP  sk     ))+DKK%EE#eAhqk"2Ca4Dq4HIJJE#mo"6788rE   c           	          [         R                  " U R                  U5        g ! [        [        4 a  n[        U[        5      (       d  UR                  [        R                  :X  ar  U R                  5       n[        [        [        [        5       5      5      5      nU H7  nXT;  a  SU< SU< 3n[	        U5      S eXS;  d  M%  SU SU 3n[	        U5      Ue   e S nAff = f)Nzinvalid CPU z; choose between zCPU number z! is not eligible; choose between )r   proc_cpu_affinity_setrm  r   r
  r   rj  rk  r7  tupler5  r   r  )r_  r  r   eligible_cpusall_cpuscpur   s          rF   cpu_affinity_setProcess.cpu_affinity_set[  s    **488T:Z( c:..#))u||2K$($;$;$=M$U3}+?%@AH#.".sg 6$$1#4!6   #-S/t;3"-cU 3,,9?!<   #-S/s:  $ #s   !$ CBCCCc                     [         R                  " U R                  5      u  p[        U5      n[        R
                  " X5      $ rs  )r   r4   rm  r;   r   pionice)r_  ioclassr!  s      rF   
ionice_getProcess.ionice_getu  s1    !11$((;NG )G??722rE   c                     Uc  SnU(       a5  U[         R                  [         R                  1;   a  U< S3n[        U5      eUS:  d  US:  a  Sn[        U5      e[        R
                  " U R                  X5      $ )Nr   z ioclass accepts no valuer  zvalue not in 0-7 range)r;   r#   r    r
  r   proc_ioprio_setrm  )r_  rC  r!  r   s       rF   
ionice_setProcess.ionice_set{  sy    },,,,%  !#<= o%qyEAI. o%'''AArE   r/   c                    U R                   S:X  a  Sn[        U5      e Uc!  [        R                  " U R                   U5      $ [	        U5      S:w  a  SU< 3n[        U5      e[        R                  " U R                   X5        g ! [
         a4  nUR                  [        R                  :X  a  U R                  5         e S nAff = f)Nr   z)can't use prlimit() against PID 0 processr=   z2second argument must be a (soft, hard) tuple, got )	rm  r
  resourcer/   r   r   rj  ENOSYSr  )r_  	resource_limitsr   r   s        rF   rlimitProcess.rlimit  s    
 xx1}A o%>#++DHHi@@ 6{a'**05  )o-$$TXXyA 99, ))+s   #B AB 
C/B>>Cc                 t    U R                  5       S   nUR                  5       n[        R                  US5      $ )Nr  ?)r  r   PROC_STATUSESr   )r_  letters     rF   r  Process.status  s3    &&(2  --rE   c                 6   / n[         R                  " U R                   SU R                   S35      nSnU GH  nU R                   SU R                   SU 3n [	        U5      nUR                  S5      (       a  [        U5      (       a  U R                   SU R                   SU 3n [        U5       n[        UR                  5       R                  5       S   5      n[        UR                  5       R                  5       S   S5      n	S S S 5        [        W	5      n
[        U[        U5      [        W5      X5      nUR                  U5        GM  GM  GM!     U(       a  U R+                  5         U$ ! , (       d  f       Nn= f! [        [        4 a    Sn GMc  f = f! [        [        4 a    Sn GM}  [          a[  nUR"                  ["        R$                  :X  a   S nAGM  UR"                  ["        R&                  :X  a  [)        U5         S nAGM  e S nAff = f)	Nr   rc  Frd  z/fdinfo/r   r   T)r   rg  r^  rm  r   r   r   r   r   r   r   r   rt   r   rh  ri  r   rj  rk  rl  r   r  )r_  r*  r  r$  rv   r  ru   r   posry   rx   r0  r   s                rF   
open_filesProcess.open_files  s   

d//0$((3?@
B''($((4t<D$/~& ??3''M$,?,?"//0$((8B4HD/(.!"%ajjl&8&8&:1&=">C$'

(:(:(<Q(?$CE /  2%8!* #b'3s8T"  v.! -@'- N $$& /. ./AB * &*
*3 &'9: !
 99,99 2 22#JsU   F*F5AE3F3
F	=FFFH4	H=H")HHHc                 d    [         R                  XR                  5      nU R                  5         U$ rs  )r  r  rm  r  )r_  r  r>  s      rF   r  Process.net_connections  s'    ''hh7  "
rE   c                 t    [        [        R                  " U R                   SU R                   S35      5      $ )Nr   rc  )r   r   rg  r^  rm  r  s    rF   num_fdsProcess.num_fds  s.    2::!2!2 31TXXJcBCDDrE   c                 :    [        U R                  5       S   5      $ )Nr  r  r  s    rF   r  Process.ppid  s    4((*6233rE   s   Uid:\t(\d+)\t(\d+)\t(\d+)c                     U R                  5       nUR                  U5      S   u  p4n[        R                  " [	        U5      [	        U5      [	        U5      5      $ r  )r  r  r   puidsr   )r_  _uids_rer  real	effectivesaveds         rF   uidsProcess.uids  I    %%'!)!1!1$!7!:}}SYIE
CCrE   s   Gid:\t(\d+)\t(\d+)\t(\d+)c                     U R                  5       nUR                  U5      S   u  p4n[        R                  " [	        U5      [	        U5      [	        U5      5      $ r  )r  r  r   pgidsr   )r_  _gids_rer  rd  re  rf  s         rF   gidsProcess.gids  ri  rE   )r  r  r^  rm  rs  rT  )@r@   rA   rB   rC   r  r  r`  r  r  r  r  r   r  r  r  r  r  r   r  r  r  r  r   ru   r  getpidr  r  r  r  r  r  r  HAS_PROC_SMAPSr  r  r  r  r   r  r  r  r  r'  r+  r/  HAS_CPU_AFFINITYr2  r7  r?  HAS_PROC_IO_PRIORITYrD  rH  hasattrrK  rO  r  rX  r  r]  r  rg  rm  rD   r?   rE   rF   r  r    s   'CI." B3 #  #J    $  $3
5
 7 7 
 
  2 ) )
   
ww~~ryy{m3/00	 	0 
 	0D O O 7 7 @ @ * * > >$ 	$. 
 

#;<JJ23ZZ 45	$ 
	$8 
		; 
		; '	E	 
E	N ? ? 

#<=< < *,**5H*I 5 5
  4 0 0 7 7 		8 
	8 jj!DE		9 
	 
	. 		3 
	3
 
	B 
	B x##		 
	6 . . - -^  
 E E 4 4 JJ'DE D D
 JJ'DE D DrE   r  ro  )F)r  r  r<  enumrj  r  r  r   r  rK  rW  r  sysr   r   r   r  r   r   r   r   r	   r  r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __extra__all__rt  r=  dirr   isupperr_  ru   r  rp  rq  r  rs  rr  r	  r   getpagesizer   rw  	byteorderr~  r  IntEnumr   	AF_PACKETr8   r9   r;   globalsru  __members__STATUS_RUNNINGSTATUS_SLEEPINGSTATUS_DISK_SLEEPSTATUS_STOPPEDSTATUS_TRACING_STOPSTATUS_ZOMBIESTATUS_DEADSTATUS_WAKE_KILLSTATUS_WAKINGSTATUS_IDLESTATUS_PARKEDrS  r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r  r^   rj   rt   rz   r   r{   r   r   r   r   r   r   r   r   r   	Exceptionr   r   r   r   r   r  r  r  r"  r)  r,  rE  net_if_addrsrH  rJ  r  r  r  r  
disk_usager  r  r%  rN  rQ  rl  rn  rx  rt  r{  r  r  r  r0  s   0rF   <module>r     s  
 %       	 	    
  # "   # )  $ $ ' ! " "     $ "  +    ( ' " "	 8YIFIqf!5!))+IF . &V <=		}M'JK t%67 4!89  jj&!!#	)  iV%5%5!67 

  	  '' ( 
				 	 		"	"					$	$											!	!									" 
"
"







 
 

 
 

 
 




!
!








, 	 K	L   <>	 &>?j$,,1G"GHJK
 -*?*?!@@B	  6 7 {"#	(
$& 	0 	00K!<~BJ4@x (:'T2
 77>>;<<*A A#NP &&	I 	k k\ "# +
,^B   
fRH HV$Xsl>W>~ &=!B,6w	D w	D1 	Gj  K	*3'
23;(:;CcJIKs*    SS4S(S S?S::S?