
    &ih                        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JrJrJrJrJr  SrSrSrSqSrSrS	rS
rSrSrS(S jrS\ SS4S jr!S r"S\R                  S\#4S jr$S\%S\&4S jr'S\%S\(4S jr)S\%S\(4S jr*S\%S\(4S jr+\"S\R                  S\,S\&S\&S\&SS4S j5       r-\"S\R                  S\&S\&S\&4S  j5       r.\"S)S\,S\&S!\,S"\,S\&S\&S#\,4S$ jj5       r/\"S*S\,S%\&S&\04S' jj5       r1g)+    N   )errors)ICMP_DEFAULT_CODE
IcmpV4Type IcmpV4DestinationUnreachableCodeIcmpTimeExceededCode
IcmpV6Type IcmpV6DestinationUnreachableCodez5.1.5Fz!BBHHHBBHIIz!IHBB16s16sz!BBHHHz!dz!16s16sIBBBB   returnc                      S n[         (       d  g[        =(       d    U" 5       qSR                  S U  5       5      n[        R                  U5        g)zPrint debug info to stdout if `ping3.DEBUG` is True.

Args:
    *args (any): Usually are strings or objects that can be converted to str.
c                     [         R                  " [        5      n U R                  [         R                  5        [         R
                  " S5      n[         R                  " 5       nUR                  [         R                  5        UR                  U5        U R                  U5        U R                  SR                  [        5      5        U R                  SR                  U 5      5        U $ )Nz[%(levelname)s] %(message)szPing3 Version: {}z
LOGGER: {})logging	getLogger__name__setLevelDEBUG	FormatterStreamHandlersetFormatter
addHandlerdebugformat__version__)logger	formattercout_handlers      8C:\MON_AGENTE\python\Lib\site-packages\ping3/__init__.py
get_logger_debug.<locals>.get_logger(   s    ""8,&%%&CD	,,.gmm,!!),,'(//<=\((01    N c              3   8   #    U  H  n[        U5      v   M     g 7fNstr).0items     r   	<genexpr>_debug.<locals>.<genexpr>8   s     2TTs4yyT   )r   LOGGERjoinr   )argsr   messages      r   _debugr0   !   s=    
 5#z|Fhh2T22G
LLr!   errc                     [         (       a  U eg)zRaise exception if `ping3.EXCEPTIONS` is True.

Args:
    err (Exception): Exception to be raised.

Raise:
    Exception: Exception passed in args will be raised if `ping3.EXCEPTIONS` is True.
N)
EXCEPTIONS)r1   s    r   _raiser4   <   s     z	 r!   c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )zDecorator that log function calls for debug

Args:
    func (callable): Function to be decorated.

Returns:
    callable: Decorated function.
c                  .  > SR                  S U  5       5      nU(       a  [        U5      OSnU(       a  U(       a  SR                  X#45      O
U=(       d    Un[        SSR                  UTS95        T" U 0 UD6n[        SSR                  TUS	95        U$ )
Nz, c              3   8   #    U  H  n[        U5      v   M     g 7fr$   r%   )r'   args     r   r)   0_func_logger.<locals>.wrapper.<locals>.<genexpr>U   s     3ds#c((dr+    zFunction called:z{func.__name__}({}))funczFunction returned:z{func.__name__} -> {rtrn})r;   rtrn)r-   r&   r0   r   )r.   kwargspargskargsall_argsfunc_returnr;   s         r   wrapper_func_logger.<locals>.wrapperS   s    		3d33%F2165499e^,QV!#8#?#?t#?#TUD+F+#%@%G%GTXc%G%der!   )	functoolswraps)r;   rB   s   ` r   _func_loggerrF   I   s'     __T  Nr!   sockc                 <    U R                   [        R                  :H  $ )zCheck if the socket is IPv4.

Args:
    sock (socket.socket): The socket to be checked.

Returns:
    bool: True if the socket is IPv4, False otherwise.
)familysocketAF_INET)rG   s    r   is_ipv4rL   `   s     ;;&..((r!   sourcec                     SnSU-  n[        U SSS2   5      [        U SSS2   5      US-  -  -   nX2:  a  [        [        X25      5      nX2:  a  M  U) SU-  S-
  -  $ )zCalculates the checksum of the input bytes.

RFC1071: https://tools.ietf.org/html/rfc1071
RFC792: https://tools.ietf.org/html/rfc792

Args:
    source (Bytes): The input to be calculated.

Returns:
    int: Calculated checksum.
   r   N   )sumdivmod)rM   BITScarryresults       r   checksumrV   l   sq     DIE!VADqD\!2tqy!ABF
/VF*+ /7qDyAo&&r!   rawc           	      b    Sn[        [        U[        R                  " [        U 5      5      5      $ )zGet information from raw ICMP header data.

Args:
    raw (Bytes): Raw data of ICMP header.

Returns:
    dict: A map contains the infos from the raw header.
)typecoderV   idseq)dictzipstructunpackICMP_HEADER_FORMAT)rW   icmp_header_keyss     r   read_icmp_headerrc      s*     A$fmm4F&LMNNr!   c           	          S[         S[        4S jnSn[        [        U[        R
                  " [        U 5      5      5      nU" US   5      US'   U" US   5      US'   U$ )zGet information from raw IPv4 header data.

Args:
    raw (Bytes): Raw data of IPv4 header.

Returns:
    dict: A map contains the infos from the raw header.
ipr   c                 :   ^  SR                  U 4S jS 5       5      $ )N.c              3   F   >#    U  H  n[        TU-	  S -  5      v   M     g7f)   Nr%   )r'   offsetre   s     r   r)   9read_ipv4_header.<locals>.stringify_ip.<locals>.<genexpr>   s"     N~VB&L4/00~s   !)   rO      r   )r-   )re   s   `r   stringify_ip&read_ipv4_header.<locals>.stringify_ip   s    xxN~NNNr!   )
versiontoslenr[   flagsttlprotocolrV   src_addr	dest_addrrv   rw   )intr&   r]   r^   r_   r`   IPV4_HEADER_FORMAT)rW   rn   ipv4_header_keysipv4_headers       r   read_ipv4_headerr|      sm    O O O xs+V]];Ms-STUK*;z+BCK
+K,DEKr!   c                    Sn[        [        U[        R                  " [        U SS 5      5      5      nUS   US   US   S.nUS   S	-	  S
-  US'   US   S-	  S-  US'   US   S-  US'   [
        R                  " [
        R                  US   5      US'   [
        R                  " [
        R                  US   5      US'   U$ )zGet information from raw IPv6 header data.

Args:
    raw (Bytes): Raw data of IPv6 header.

Returns:
    dict: A map contains the infos from the raw header.
)initialrr   next_header	hop_limitrv   rw   N(   rr   r   r   )rr   r   r   r~         rp      ri   traffic_classi 
flow_labelrv   rw   )r]   r^   r_   r`   IPV6_HEADER_FORMATrJ   	inet_ntopAF_INET6)rW   ipv6_header_keysipv6_header_unpackedipv6_headers       r   read_ipv6_headerr      s     _$4fmmDVX[\_]_X`6a bc#E*+M:)+6K
 39=CtKK	$8$Cr$IT#QK  4Y ?' IK$..v@TU_@`aK
%//AUVaAbcKr!   rw   icmp_idr\   sizec           
         [        SU5         [        U 5      (       a  [        R                  " U5      nUS4nOK[        R                  " US[        R
                  [        R                  [        R                  5      S   S   n [        SUS   5        Sn[        R                  " [        [        U 5      (       a  [        R                  O[         R                  ["        UUU5      nU[        R$                  " [&        5      -
  S-  n	[        R                  " [&        [(        R(                  " 5       5      U	R+                  5       -   n
[        U 5      (       a  [-        X-   5      nGO[        R                  " [        R
                  U R.                  U R0                  5       nUR3                  U5        UR5                  5       S   nSSS5        [        SR7                  W5      5        [        R                  " [8        [        R:                  " [        R
                  U5      [        R:                  " [        R
                  US   5      [=        U5      [=        U
5      -   SSS[         R                  5      n[-        X-   U
-   5      n[        R                  " [        [        U 5      (       a  [        R                  O[         R                  ["        [        R>                  " U5      UU5      n[        S	[A        U5      5        [        S
U
5        X-   nU RC                  X5        g! [        R                   a  n[        R                  " US9UeSnAff = f! , (       d  f       GN= f)a  Sends one ping to the given destination.

ICMP Header (bits): type (8), code (8), checksum (16), id (16), sequence (16)
ICMP Payload: time (double), data
ICMP Wikipedia: https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol
ICMPv6 Wikipedia: https://en.wikipedia.org/wiki/ICMPv6
IPv4 Wikipedia: https://en.wikipedia.org/wiki/IPv4
IPv6 Wikipedia: https://en.wikipedia.org/wiki/IPv6_packet

Args:
    sock (socket.socket): Socket.
    dest_addr: The destination address, can be an IPv4 address or an IPv6 address or a domain name. Ex. "192.168.1.1"/"example.com"/"2001:db8::1"
        Socket address is (dest_addr, port) with IPv4 and (dest_addr, port, flowinfo, scopeid) with IPv6. Port is 0 respectively the OS default behavior will be used. With IPv6, Flowinfo is 0, Scope ID is the interface index if dest_addr is a link-local address.
    icmp_id (int): ICMP packet id. Calculated from Process ID and Thread ID.
    seq (int): ICMP packet sequence, usually increases from 0 in the same process.
    size (int): The ICMP packet payload size in bytes. Note this is only for the payload part.

Raises:
    HostUnkown: If destination address is a domain name and cannot resolved.
zDestination address:r   N   )rw   zResolved destination address:QzSource Address: {}zSent ICMP header:zSent ICMP payload:)"r0   rL   rJ   gethostbynamegetaddrinfor   SOCK_RAWIPPROTO_ICMPV6gaierrorr   HostUnknownr_   packra   r   ECHO_REQUESTr	   r   calcsizeICMP_TIME_FORMATtimeencoderV   rY   protoconnectgetsocknamer   ICMPV6_PSEUDO_HEADER_FORMAT	inet_ptonrr   htonsrc   sendto)rG   rw   r   r\   r   	sock_addrr1   pseudo_checksumicmp_headerpaddingicmp_payloadreal_checksum
dummy_sockrv   pseudo_headerpackets                   r   send_one_pingr      s|   , !9-?4==,,Y7I"AI**9dFOOV__^d^s^stuvwxyzI *IaL9O++#*4==
j6M6MK foo&6773>G;;/=@PPLt}} !;<]]6??DIItzzBjy)!--/2H C 	#**845'V__h7V__il;s<00q!##
 !!<|!KL++#*4==
j6M6M]#K  0 =>
.'FKK"W ?? ?  953>?& CBs)   *L A
L %MM2MM
Mtimeoutc                 B
   S n[        U 5      (       a  [        O[        n[        R                  " 5       U-   n[	        SR                  [        R                  " U5      U5      5         U[        R                  " 5       -
  nUS:  a  UOSn[	        SR                  U5      5        [        R                  " U // / U5      nUS   / :X  a  [        R                  " US9e[        R                  " 5       n	[	        SR                  [        R                  " U	5      U	5      5        U R                  S5      u  p[        U 5      (       aW  [        R                  S:g  =(       d<    [        R                  " 5       S	:H  =(       d    U R                  [         R"                  :H  nOU" X
5      nU(       a  [	        S
5        [%        S[&        R(                  " [        U 5      (       a  [*        O[,        5      5      n[%        UR.                  UR.                  [&        R(                  " [0        5      -   5      nX   n[        U 5      (       a  [3        U5      O
[5        U5      n[	        SU5        O1[	        S5        Sn[%        S[&        R(                  " [0        5      5      nX   XR.                  S nn[7        U5      n[	        SU5        [	        SU5        US   UR8                  :X  aA  US   [:        R<                  :X  a  [        R>                  " UUS9e[        R@                  " 5       eUS   URB                  :X  a  [        U 5      (       a-  US   [D        RF                  :X  a  [        RH                  " UUS9eOXUS   [J        RL                  :X  a  [        RN                  " UUS9eUS   [J        RP                  :X  a  [        RR                  " UUS9e[        RT                  " UUS9eUS   (       Ga1  US   URV                  :X  a  [	        S5        GM  [	        SUS   SSU5        US   U:H  nU(       dC  U(       d<  U RY                  5       S   nUS   U:H  nU(       a  [	        SR                  U5      5        U(       d  [	        S5        GM  US   U:w  a  [	        S5        GM+  US   URZ                  :X  am  [&        R\                  " [^        US[&        R(                  " [^        5       5      S   n[	        SR                  [        R                  " U5      U5      5        U	U-
  $ [	        SU5        GM  )ai  Receives the ping from the socket.

IP Header (bits): version (8), type of service (8), length (16), id (16), flags (16), time to live (8), protocol (8), checksum (16), source ip (32), destination ip (32).
ICMP Packet (bytes): IP Header (20), ICMP Header (8), ICMP Payload (*).
Ping Wikipedia: https://en.wikipedia.org/wiki/Ping_(networking_utility)
ToS (Type of Service) in IP header for ICMP is 0. Protocol in IP header for ICMP is 1.

Args:
    sock (socket.socket): The same socket used for send the ping.
    icmp_id (int): ICMP packet id. Sent packet id should be identical with received packet id.
    seq (int): ICMP packet sequence. Sent packet sequence should be identical with received packet sequence.
    timeout (int): Timeout in seconds.

Returns:
    float | None: The delay in seconds or None on timeout.

Raises:
    TimeToLiveExpired: If the Time-To-Live in IP Header is not large enough for destination.
    TimeExceeded: If time exceeded but Time-To-Live does not expired.
    DestinationHostUnreachable: If the destination host is unreachable.
    DestinationUnreachable: If the destination is unreachable.
c                 x    US   S-	  n[        SR                  U5      5        U[        U 5      (       a  S:H  $ S:H  $ )a'  Detect if the received data has an IP header.

IPv4 header first 4 bits is 4 (0b0100). ICMPv4 Type starts with 4 (64~79) is unassigned. See https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#Control_messages
IPv6 header first 4 bits is 6 (0b0110). ICMPv6 Type starts with 6 (96~111) is unassigned. See https://en.wikipedia.org/wiki/ICMPv6#Types

Args:
    sock (socket.socket): The socket used to receive the data.
    recv_data (bytes): The received data.

Returns:
    bool: True if the received data has an IP header, False otherwise.
r   r   z:Detecting if received data has IP header. First 4 bits: {}   )r0   r   rL   )rG   	recv_datafirst_fields      r   detect_ip_header*receive_one_ping.<locals>.detect_ip_header  sB      la'KRRS^_`GDMMq99q99r!   zTimeout time: {} ({})r   zTimeout left: {:.2f}s)r   zReceived time: {} ({}))i  posixDarwinzHas IP header: TruezReceived IP header:zHas IP header: FalseNzReceived ICMP header:zReceived ICMP payload:rY   rZ   )	ip_headerr   r[   z+ECHO_REQUEST received. Packet filtered out.zICMP ID:,z	Expected:r   zICMP ID rewrited by kernel: {}z&ICMP ID dismatch. Packet filtered out.r\   z'IMCP SEQ dismatch. Packet filtered out.zReceived sent time: {} ({})zUncatched ICMP packet:)0rL   r   r	   r   r0   r   ctimeselectr   TimeoutrecvfromosnameplatformsystemrY   rJ   r   slicer_   r   ry   r   stopra   r|   r   rc   TIME_EXCEEDEDr   TTL_EXPIREDTimeToLiveExpiredTimeExceededDESTINATION_UNREACHABLEr   DESTINATION_HOST_UNREACHABLEDestinationHostUnreachabler
   ADDRESS_UNREACHABLEAddressUnreachablePORT_UNREACHABLEPortUnreachableDestinationUnreachabler   r   
ECHO_REPLYr`   r   )rG   r   r\   r   r   	icmp_typetimeout_timetimeout_leftselected	time_recvr   addrhas_ip_headerip_header_sliceicmp_header_sliceip_header_rawr   icmp_header_rawicmp_payload_rawr   is_icmp_id_matched	time_sents                         r   receive_one_pingr     sI   0:" &dmm
I99;(L
"))$**\*BLQR
#diik1'3a'7|Q&--l;<==$R>A;"..11IIK	(//

90EyQR---	4==WW/uX__5F(5RuX\XaXaeketetXtM,T=M()#AvWUY]]7I`r'stO %o&:&:O<P<PSYSbSbcuSv<v w%6M;B4==(7N^_lNmI()4)*I %a9K)L M,5,H)TjTjTkJl)&7&4')9:v)"9"996"&:&F&FF..P[\\%%''v)"C"CCt}}v&*J*g*gg ;;i]hii h v&*J*^*^^ 33iU`aa (,L,],]] 009R]^^//#  t6"i&<&<<DE:{40#{GL!,T!2g!=%m**,Q/%0%6'%A"%;BB7KL%?@5!S(@A6"i&:&::"MM*:<LQQWQ`Q`aqQr<stuvw	4;;DJJy<QS\]^ 9,,'5I r!   unitrv   	interfacec	           	      
   Uc#   [         R                  " U 5      n	U	R                  n[	        SR                  U5      U 5        US:X  a!  [        R                  n
[        R                  nOAUS:X  a!  [        R                  n
[        R                  nO[        SR                  U5      5      e [        R                  " U
[        R                  U5      nU   U(       Ga:  [!        U5      (       a   UR#                  [        R$                  [        R&                  5      (       a/  UR)                  [        R$                  [        R&                  U5         UR#                  [        R,                  [        R&                  5      (       a/  UR)                  [        R,                  [        R&                  U5        Oc UR#                  [        R.                  [        R0                  5      (       a/  UR)                  [        R.                  [        R0                  U5        U(       a?  UR)                  [        R2                  [4        UR7                  5       5        [	        S
U5        U(       a/  [!        U5      (       a  UR9                  US45        [	        SU5        [;        [<        S5      (       a  [<        R>                  " 5       O[<        R@                  " 5       RB                  n[D        RF                  " 5       n[H        RJ                  " SR                  X5      R7                  5       5      S-  n [M        XUXVS9  [O        UUXQS9nUc
   SSS5        gUS:X  a  US-  nUsSSS5        $ ! [         a    Sn GNHf = f! [         ak  nUR                  [        R                  :X  aF  [	        SR                  U5      5        [        R                  " U
[        R                  U5      n SnAGNUeSnAff = f! [*         a%  n[	        SR                  U5      5         SnAGNSnAff = f! [*         a%  n[	        SR                  U5      5         SnAGN1SnAff = f! [*         a%  n[	        S	R                  U5      5         SnAGNcSnAff = f! [P        RR                   a(  n[	        U5        [U        U5         SnASSS5        gSnAf[P        RV                   a(  n[	        U5        [U        U5         SnASSS5        gSnAff = f! , (       d  f       g= f)u$  
Send one ping to destination address with the given timeout.

Args:
    dest_addr (str): The destination address, can be an IP address or a domain name. Ex. "192.168.1.1"/"example.com"/“fd00::1“
    timeout (int): Time to wait for a response, in seconds. Default is 4s, same as Windows CMD. (default 4)
    unit (str): The unit of returned value. "s" for seconds, "ms" for milliseconds. (default "s")
    src_addr (str): The IP address to ping from. This is for multiple network interfaces. Ex. "192.168.1.20". (default "")
    ttl (int | None): The Time-To-Live of the outgoing packet. Default is None, which means using OS default ttl -- 64 onLinux and macOS, and 128 on Windows. (default None)
    seq (int): ICMP packet sequence, usually increases from 0 in the same process. (default 0)
    size (int): The ICMP packet payload size in bytes. If the input of this is less than the bytes of a double format (usually 8), the size of ICMP packet payload is 8 bytes to hold a time. The max should be the router_MTU(Usually 1480) - IP_Header(20) - ICMP_Header(8). Default is 56, same as in macOS. (default 56)
    interface (str): LINUX ONLY. The gateway network interface to ping from. Ex. "wlan0". (default "")
    ip_v (int | None): The IP version to use. 4 for IPv4, 6 for IPv6. If None, the function will try to determine the IP version from `dest_addr`. (default None)

Returns:
    float | None | False: The delay in seconds/milliseconds, False on error and None on timeout.

Raises:
    PingError: Any PingError will raise again if `ping3.EXCEPTIONS` is True.
Nr   zPing IPv{}:r   zUnsupported IP version: {}zB`{}` when create socket.SOCK_RAW, using socket.SOCK_DGRAM instead.z5Set Socket Option `IP_TTL` in `IPPROTO_IP` Failed: {}z1Set Socket Option `IP_TTL` in `SOL_IP` Failed: {}zBSet Socket Option `IPV6_UNICAST_HOPS` in `IPPROTO_IPV6` Failed: {}zSocket Interface Binded:r   zSocket Source Address Binded:get_native_idz{}{}i  )rG   rw   r   r\   r   )rG   r   r\   r   Fmsi  ),	ipaddress
ip_addressrp   
ValueErrorr0   r   rJ   rK   IPPROTO_ICMPr   r   r   PermissionErrorerrnoEPERM
SOCK_DGRAMrL   
getsockopt
IPPROTO_IPIP_TTL
setsockoptOSErrorSOL_IPIPPROTO_IPV6IPV6_UNICAST_HOPS
SOL_SOCKETSOCKET_SO_BINDTODEVICEr   bindhasattr	threadingr   current_threadidentr   getpidzlibcrc32r   r   r   r   r4   	PingError)rw   r   r   rv   rt   r\   r   r   rp   re   socket_familysocket_protocolrG   r1   	thread_id
process_idr   delays                     r   pingr  w  s   , 	%%i0BjjG =()4!| --	A //5<<WEFF}}]FOO_M 
t}}`v'8'8&--HH(9(96==#N\v}}fmmDDv}}cJmv':':F<T<TUU(;(;V=U=UWZ[ OOF--/EyGWGWGYZ-y9t}}		8Q-(6A29)_2U2UY,,.[d[s[s[u[{[{	YY[
**V]]:AHHJKfT
	t's^$$SZE =U 
V 4<TME[ 
'  	G	  99#W^^_bcd==0A0A?SDI  `RYYZ]^__`
  \NUUVYZ[[\  m_ffgjkllm  ~~ 	3K3KI 
J  	3K3KQ 
J	K 
s   "M  +&M3 S:-A"O+A"P2S:4A"QDS:'R=S:
S: M0/M03
O(=AO#!O##O(+
P5PS:PS:
Q'QS:QS:
Q>Q93S:9Q>>S:S7R8+S:8S7S2%S:2S77S::
Tcountintervalc                 B   UR                  S5      nUR                  S5      nUR                  SS5      nSnX:  d  US:X  a  US:  a  US:  a  [        R                  " U5        SR	                  U 5      n	X(       a  SR	                  U5      OS-  n	U	S	-  n	[        U /UQ7S
U0UD6n
[        U	SS9  U
c$  [        U(       a  SR	                  U5      OS5        O3U
SL a  [        S5        O"[        SR	                  [        U
5      US95        US-  nX:  a  M  US:X  a  M  gg)a\  
Send pings to destination address with the given timeout and display the result.

Args:
    dest_addr (str): The destination address. Ex. "192.168.1.1"/"example.com"
    count (int): How many pings should be sent. 0 means infinite loops until manually stopped. Default is 4, same as Windows CMD. (default 4)
    interval (float): How many seconds between two packets. Default is 0, which means send the next packet as soon as the previous one responsed. (default 0)
    *args and **kwargs (any): And all the other arguments available in ping() except `seq`.

Output:
    Formatted ping results printed.
r   rv   r   r   r   z	ping '{}'z
 from '{}'r:   z ... r\   )endNzTimeout > {}sr   FErrorz{value}{unit})valuer   r   )get
setdefaultr   sleepr   r  printrx   )rw   r  r	  r.   r=   r   srcr   ioutput_textr  s              r   verbose_pingr    s    jj#G
**Z
 CVT*D	A
)uza<AEJJx !((33|**3/B>wY77A77kr"=W/((1)Le^'N/((s5z(EF	Q )uzr!   )r   N)r   sr:   Nr   8   r:   N)r   r   )2r   rJ   r_   r   r   r   r   r   r   rD   r   r   r:   r   enumsr   r   r   r   r	   r
   r   r   r3   r,   ry   r   ra   r   r   r   r0   	Exceptionr4   rF   boolrL   bytesrx   rV   r]   rc   r|   r   r&   r   r   r  floatr   r!   r   <module>r     s   
             W  W
	 # "   ,  6
	 
d 
.	)&-- 	)D 	)'U 's '(
O% 
OD 
O% D (% D 0 G# G## G# G## G#UX G#]a G# G#T o66== o63 o6S o63 o6 o6d YC Y# Y Yc Y_b Ynq Y  DG Y Yx C  5  r!   