
    Jj                       U d Z ddlZddlZddlZddlmZ ddlmZmZ ddl	m
Z
mZmZmZmZ ddlmZ ddlmZ ddlmZmZmZ  ej        e          Zd>d
ededefdZd
ededefdZd
ededefdZd
ede dee         fdZ!d?d
ede de fdZ"d@d
ede de fdZ#de$de de%e$e$f         fdZ&da'ee(         e)d<    G d de          Z* e+d e*j,        -                                D                       Z.e G d d                      Z/e G d d                       Z0e G d! d"                      Z1e G d# d$                      Z2d%Z3ee)d&<   d'Z4ee)d(<   d)Z5e e)d*<   e G d+ d,                      Z6e*j7        d- e*j8        d. e*j9        d/ e*j:        d0 e*j;        d1 e*j<        d2 e*j=        d3 e*j>        d4 e*j?        d5 e*j@        d6 i
ZAe$e*ee2gef         f         e)d7<   e G d8 d9                      ZBdeBfd:ZCdAd<ZDd;eBddfd=ZEdS )Bz
Gateway configuration management.

Handles loading and validating configuration for:
- Connected platforms (Telegram, Discord, WhatsApp, Weixin, and more)
- Home channels for each platform
- Session reset policies
- Delivery preferences
    N)Path)	dataclassfield)DictListOptionalAnyCallable)Enumget_hermes_home)env_intenv_var_enabledis_truthy_valueTvaluedefaultreturnc                     | |S t          | t                    r4|                                                                 }|dv rdS |dv rdS |S t	          | |          S )zDCoerce bool-ish config values, preserving a caller-provided default.N>   1onyestrueT>   0noofffalseF)r   )
isinstancestrstriplowerr   )r   r   lowereds      4/home/rurouni/.hermes/hermes-agent/gateway/config.py_coerce_boolr#      sq    }% ++--%%''000411155'2222    c                 \    | |S 	 t          |           S # t          t          f$ r |cY S w xY w)z>Coerce numeric config values, falling back on malformed input.)float	TypeError
ValueErrorr   r   s     r"   _coerce_floatr*   '   sF    }U||z"       ++c                 \    | |S 	 t          |           S # t          t          f$ r |cY S w xY w)z>Coerce integer config values, falling back on malformed input.)intr'   r(   r)   s     r"   _coerce_intr.   1   sF    }5zzz"   r+   keyc                    | dS t          | t                    rt                              d||            dS 	 t          | t                    r3|                                 st          |           t          |           }nGt          | t                    r#t          | 	                                d          }nt          |           }n4# t          t          f$ r  t                              d||            Y dS w xY w|dk    rdS |S )zCoerce an optional positive integer config value.

    ``None``/0/negative disable the setting. Malformed values are ignored with
    a warning so a typo never prevents the gateway from starting.
    NzEIgnoring invalid %s=%r (expected a positive integer; 0/null disables)
   r   )r   boolloggerwarningr&   
is_integerr(   r-   r   r   r'   )r   r/   parseds      r"   _coerce_optional_positive_intr7   ;   s     }t% S	
 	
 	

 teU## 	 ##%% ( '''ZZFFs## 	 ++FFZZFz"   S	
 	
 	

 tt {{tMs   BC	 	-C:9C:pairc                     t          | t                    r,|                                                                 }|dv r|S |S )z8Normalize unauthorized DM behavior to a supported value.>   r8   ignorer   r   r   r    r   r   
normalizeds      r"   #_normalize_unauthorized_dm_behaviorr>   _   sD    % [[]]((**
+++Nr$   publicc                     t          | t                    r,|                                                                 }|dv r|S |S )z4Normalize notice delivery mode to a supported value.>   r?   privater;   r<   s      r"   _normalize_notice_deliveryrB   h   sD    % [[]]((**
...Nr$   platforms_datanamec                     |                      |i           }t          |t                    si }|| |<   |                     di           }t          |t                    si }||d<   ||fS )a  Get-or-create ``platforms_data[name]`` and its nested ``extra`` dict.

    Both slots are coerced to ``{}`` if a non-dict value is encountered, so
    callers can safely write keys without type-checking.  Returns
    ``(plat_data, extra)`` for in-place mutation.
    extra)
setdefaultr   dict)rC   rD   	plat_datarF   s       r"   _ensure_platform_extra_dictrJ   q   s{     ))$33Ii&& )	(t  "--EeT"" #"	'er$   _Platform__bundled_plugin_namesc                       e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZed             Zedefd            ZdS )Platforma?  Supported messaging platforms.

    Built-in platforms have explicit members.  Plugin platforms use dynamic
    members created on-demand by ``_missing_()`` so that
    ``Platform("irc")`` works without modifying this enum.  Dynamic members
    are cached in ``_value2member_map_`` for identity-stable comparisons.
    localtelegramdiscordwhatsappwhatsapp_cloudslacksignal
mattermostmatrixhomeassistantemailsmsdingtalk
api_serverwebhookmsgraph_webhookfeishuwecomwecom_callbackweixinbluebubblesqqbotyuanbaorelayc                 j   t          |t                    r|                                sdS |                                                                }|| j        v r| j        |         S t
          |                                 a|t
          v r}t                              |           }||_	        |
                                                    dd                              dd          |_        || j        |<   || j        |j        <   |S 	 ddlm} |                    |          r}t                              |           }||_	        |
                                                    dd                              dd          |_        || j        |<   || j        |j        <   |S n# t"          $ r Y nw xY wdS )a  Accept unknown platform names only for known plugin adapters.

        Creates a pseudo-member cached in ``_value2member_map_`` so that
        ``Platform("irc") is Platform("irc")`` holds True (identity-stable).
        Arbitrary strings are rejected to prevent enum pollution.
        N-_ r   platform_registry)r   r   r   r    _value2member_map_rK   _scan_bundled_plugin_platformsobject__new___value_upperreplace_name__member_map_gateway.platform_registryrk   is_registered	Exception)clsr   pseudork   s       r"   	_missing_zPlatform._missing_   s    %%% 	U[[]] 	4##%%C***)%00
 +2.1.P.P.R.R+333^^C((F"FN!KKMM11#s;;CCCMMFM,2C"5).4CV]+M
	CCCCCC ..u55 ,,!& % 5 5c3 ? ? G GS Q Q06&u-28 /  	 	 	D	 ts   
BF# #
F0/F0r   c                    t                      }	 t          t                    j        j        dz  dz  }|                                r|                                D ]}|                                rq|dz                                  rZ|dz                                  s|dz                                  r,|                    |j        	                                           n# t          $ r Y nw xY w|S )zFReturn names of bundled platform plugins under ``plugins/platforms/``.plugins	platformsz__init__.pyzplugin.yamlz
plugin.yml)setr   __file__parentis_diriterdirexistsaddrD   r    rw   )rx   namesplatforms_dirchilds       r"   rm   z'Platform._scan_bundled_plugin_platforms   s    UU	 NN189D{RM##%% 
6*2244 	6 	6E6"]2::<<6 #]2::<<	6
 !& 4<<>>6 		%*"2"2"4"4555 	 	 	D	s   CC% %
C21C2N) __name__
__module____qualname____doc__LOCALTELEGRAMDISCORDWHATSAPPWHATSAPP_CLOUDSLACKSIGNAL
MATTERMOSTMATRIXHOMEASSISTANTEMAILSMSDINGTALK
API_SERVERWEBHOOKMSGRAPH_WEBHOOKFEISHUWECOMWECOM_CALLBACKWEIXINBLUEBUBBLESQQBOTYUANBAORELAYclassmethodrz   r~   rm    r$   r"   rM   rM      s          EHGH%NEFJF#ME
CHJG'OFE%NFKEGE* * [*X s    [  r$   rM   c              #   $   K   | ]}|j         V  d S N)r   ).0ms     r"   	<genexpr>r      s$      $T$TQW$T$T$T$T$T$Tr$   c                       e Zd ZU dZeed<   eed<   eed<   dZee         ed<   de	ee
f         fdZed	e	ee
f         dd fd
            ZdS )HomeChannela@  
    Default destination for a platform.
    
    When a cron job specifies deliver="telegram" without a specific chat ID,
    messages are sent to this home channel. Thread-aware platforms may also
    store a thread/topic ID so the bare platform target routes to the exact
    conversation where /sethome was run.
    platformchat_idrD   N	thread_idr   c                 \    | j         j        | j        | j        d}| j        r
| j        |d<   |S )N)r   r   rD   r   )r   r   r   rD   r   selfresults     r"   to_dictzHomeChannel.to_dict   s=    +|I
 

 > 	1"&.F;r$   datac           	           | t          |d                   t          |d                   |                    dd          |                    d          rt          |d                   nd           S )Nr   r   rD   Homer   r   r   rD   r   )rM   r   getrx   r   s     r"   	from_dictzHomeChannel.from_dict	  sq    sd:.//Y((&&))040E0EOc${+,,,4	
 
 
 	
r$   )r   r   r   r   rM   __annotations__r   r   r   r   r	   r   r   r   r   r$   r"   r   r      s           LLL
III#Ix}###c3h     
T#s(^ 
 
 
 
 [
 
 
r$   r   c                       e Zd ZU dZdZeed<   dZeed<   dZ	eed<   dZ
eed	<   d
Zeed<   dZeed<   deeef         fdZedeeef         dd fd            ZdS )SessionResetPolicya6  
    Controls when sessions reset (lose context).
    
    Modes:
    - "daily": Reset at a specific hour each day
    - "idle": Reset after N minutes of inactivity
    - "both": Whichever triggers first (daily boundary OR idle timeout)
    - "none": Never auto-reset (context managed only by compression)
    bothmode   at_hour  idle_minutesTnotifyr[   r\   notify_exclude_platforms   bg_process_max_age_hoursr   c                 j    | j         | j        | j        | j        t	          | j                  | j        dS )Nr   r   r   r   r   r   )r   r   r   r   listr   r   r   s    r"   r   zSessionResetPolicy.to_dict*  s:    I| -k(,T-J(K(K(,(E
 
 	
r$   r   c           	      ~   |                     d          }|                     d          }|                     d          }|                     d          }|                     d          }|                     d          } | ||nd||nd||nd	t          |d
          |t          |          nd||nd          S )Nr   r   r   r   r   r   r   r   r   Tr   r   r   )r   r#   tuple)rx   r   r   r   r   r   exclude
bg_max_ages           r"   r   zSessionResetPolicy.from_dict4  s     xx((9%%xx//(##((566XX899
s)v&2GG)5)At--7>7JU7^^^Pi3=3IZZr
 
 
 	
r$   N)r   r   r   r   r   r   r   r   r-   r   r   r2   r   r   r   r   r	   r   r   r   r   r$   r"   r   r     s           D#GSL#FD&?e??? %'c&&&
c3h 
 
 
 
 
T#s(^ 
0D 
 
 
 [
 
 
r$   r   c                       e Zd ZU dZdZee         ed<   dZee         ed<   dZ	ee         ed<   de
eef         fdZede
eef         dd fd	            ZdS )
ChannelOverridea"  
    Per-channel override for model, provider, and system prompt.

    Used in config under platforms.<name>.channel_overrides[channel_id].
    Enables different channels (e.g. Discord #daily vs #dev) to use different
    models and personas without running separate gateway instances.
    Nmodelprovidersystem_promptr   c                 p    i }| j         
| j         |d<   | j        
| j        |d<   | j        
| j        |d<   |S )Nr   r   r   r   r   r   )r   outs     r"   r   zChannelOverride.to_dictT  sH     :!:CL=$"mC
O)#'#5C 
r$   r   c                     |s
 |             S  | |                     d          |                     d          |                     d                    S )Nr   r   r   r   )r   r   s     r"   r   zChannelOverride.from_dict^  s[     	355Ls((7##XXj))((?33
 
 
 	
r$   )r   r   r   r   r   r   r   r   r   r   r   r	   r   r   r   r   r$   r"   r   r   G  s            E8C="Hhsm"""#'M8C='''c3h     
T#s(^ 
0A 
 
 
 [
 
 
r$   r   c                   J   e Zd ZU dZdZeed<   dZee	         ed<   dZ
ee	         ed<   dZee         ed<   dZe	ed	<   d
Zeed<   d
Zeed<    ee          Zee	ef         ed<    ee          Zee	ef         ed<   dee	ef         fdZedee	ef         dd fd            ZdS )PlatformConfigz.Configuration for a single messaging platform.FenabledNtokenapi_keyhome_channelfirstreply_to_modeTgateway_restart_notificationtyping_indicatordefault_factorychannel_overridesrF   r   c                 ,   | j         | j        | j        | j        | j        d}| j        r
| j        |d<   | j        r
| j        |d<   | j        r| j                                        |d<   | j	        r&d | j	        
                                D             |d<   |S )N)r   rF   r   r   r   r   r   r   c                 >    i | ]\  }}||                                 S r   r   )r   cidovs      r"   
<dictcomp>z*PlatformConfig.to_dict.<locals>.<dictcomp>  s3     + + +&-c2RZZ\\+ + +r$   r   )r   rF   r   r   r   r   r   r   r   r   itemsr   s     r"   r   zPlatformConfig.to_dict  s    |Z!/,0,M $ 5
 
 : 	)"jF7O< 	- $F9 	A%)%6%>%>%@%@F>"! 	+ +151G1M1M1O1O+ + +F&' r$   r   c                    d }d|v r t                               |d                   }|                    d          }|)|                    di                               d          }|                    d          }|)|                    di                               d          }i }|                    d          pi }t          |t                    rY|                                D ]D\  }}t          |t                    r*t                              |          |t          |          <   E | t          |                    d          d          |                    d          |                    d	          ||                    d
d          t          |d          t          |d          ||                    di           	  	        S )Nr   r   rF   r   r   r   Fr   r   r   r   T)	r   r   r   r   r   r   r   r   rF   )	r   r   r   r   rH   r   r   r   r#   )	rx   r   r   _grn_typingr   raw_overridesr   ov_datas	            r"   r   zPlatformConfig.from_dict  s   T!!&00n1EFFL xx677<88GR((,,-KLLD
 ((-..?hhw++//0BCCG8:!455;mT** 	U - 3 3 5 5 U UWgt,, U2A2K2KG2T2T%c#hh/s )!4!4e<<((7##HHY''%((?G<<)5dD)A)A)'488/((7B''

 

 

 
	
r$   )r   r   r   r   r   r2   r   r   r   r   r   r   r   r   r   r   r   rH   r   r   r   rF   r	   r   r   r   r   r$   r"   r   r   i  sL        88GTE8C=!GXc]!!!*.L(;'... !M3    *. $--- "d!!! 5:E$4O4O4OtC01OOO "E$777E4S>777c3h    ( %
T#s(^ %
0@ %
 %
 %
 [%
 %
 %
r$   r   g?DEFAULT_STREAMING_EDIT_INTERVALr   "DEFAULT_STREAMING_BUFFER_THRESHOLDu    ▉DEFAULT_STREAMING_CURSORc                       e Zd ZU dZdZeed<   dZeed<   e	Z
eed<   eZeed<   eZeed<   d	Zeed
<   deeef         fdZedeeef         dd fd            ZdS )StreamingConfigzCConfiguration for real-time token streaming to messaging platforms.Fr   auto	transportedit_intervalbuffer_thresholdcursor        fresh_final_after_secondsr   c                 P    | j         | j        | j        | j        | j        | j        dS )Nr   r   r   r   r   r   r  r   s    r"   r   zStreamingConfig.to_dict  s2    |!/ $ 5k)-)G
 
 	
r$   r   c                    |s
 |             S  | t          |                    d          d          |                    dd          t          |                    d          t                    t	          |                    d          t
                    |                    dt                    t          |                    d          d	          
          S )Nr   Fr   r   r   r   r   r   r   r  )r#   r   r*   r   r.   r   r   r   s     r"   r   zStreamingConfig.from_dict  s     	355Ls )!4!4e<<hh{F33'))+J  )+,,.P  88H&>??&3455s' '
 
 
 	
r$   N)r   r   r   r   r   r2   r   r   r   r   r   r&   r   r   r-   r   r   r   r   r	   r   r   r   r   r$   r"   r   r     s         MMGT" Is:M5:::>c>>>*FC*** (+u***
c3h 
 
 
 
 
T#s(^ 
0A 
 
 
 [
 
 
r$   r   c                     t          | j                            d          o | j        p| j                            d                    S )N
account_idr   )r2   rF   r   r   cfgs    r"   <lambda>r    s;    	l##M)LcimmG6L6L" " r$   c                     t          | j                            d          o| j                            d                    S )Nphone_number_idaccess_tokenr2   rF   r   r  s    r"   r  r    s5    	'((JSY]]>-J-J* * r$   c                 P    t          | j                            d                    S )Nhttp_urlr  r  s    r"   r  r  !  s    cimmJ&?&?!@!@ r$   c                     dS NTr   r  s    r"   r  r  "  s    T r$   c                     dS r  r   r  s    r"   r  r  #  s    $ r$   c                     t          t          | j                            d          pd                                                    S )Nclient_state )r2   r   rF   r   r   r  s    r"   r  r  $  s:    $CIMM.))/R006688+ + r$   c                     t          | j                            d          o| j                            d                    S )N
server_urlpasswordr  r  s    r"   r  r  '  s4    d	l##A	j(A(A' ' r$   c                     t          | j                            d          o| j                            d                    S )Napp_idclient_secretr  r  s    r"   r  r  *  s4    	hBCIMM/$B$B! ! r$   c                     t          | j                            d          o| j                            d                    S )Nr  
app_secretr  r  s    r"   r  r  -  s4    $	h?CIMM,$?$?# # r$   c                     t          | j                            d          p| j                            d                    S )N	relay_urlurlr  r  s    r"   r  r  4  s4    	k"":cimmE&:&:! ! r$   _PLATFORM_CONNECTED_CHECKERSc                      e Zd ZU dZ ee          Zeee	f         e
d<    ee          Zee
d<    ee          Zeeef         e
d<    ee          Zeeef         e
d<    ed           Zee         e
d<    ee          Zeeef         e
d	<    ed
           Zee
d<   dZee
d<   dZee
d<   dZee
d<   dZee
d<   dZee
d<   dZee
d<   dZee         e
d<   dZ ee
d<   dZ!ee
d<    ee"          Z#e"e
d<   dZ$ee
d<   dee         fdZ%dede	defd Z&dedee'         fd!Z(	 	 d)dee         d"ee         defd#Z)deeef         fd$Z*e+d%eeef         dd fd&            Z,d*dee         defd'Z-d*dee         defd(Z.dS )+GatewayConfigzy
    Main gateway configuration.
    
    Manages all platform connections, session policies, and delivery settings.
    r   r}   default_reset_policyreset_by_typereset_by_platformc                  
    ddgS )N/new/resetr   r   r$   r"   r  zGatewayConfig.<lambda>J  s    vx>P r$   reset_triggersquick_commandsc                  $    t                      dz  S )Nsessionsr   r   r$   r"   r  zGatewayConfig.<lambda>P  s    7H7H:7U r$   sessions_dirTalways_log_localfilter_silence_narrationstt_enabledstt_echo_transcriptsgroup_sessions_per_userFthread_sessions_per_userNmax_concurrent_sessionsmultiplex_profilesr8   unauthorized_dm_behavior	streamingZ   session_store_max_age_daysr   c                     g }| j                                         D ]8\  }}|j        s|                     ||          r|                    |           9|S )z9Return list of platforms that are enabled and configured.)r}   r   r   _is_platform_connectedappend)r   	connectedr   configs       r"   get_connected_platformsz%GatewayConfig.get_connected_platformsy  si    	 $ 4 4 6 6 	+ 	+Hf> **8V<< +  ***r$   r   r=  c                 D   |t           j        k    rHt          |j                            d          o |j        p|j                            d                    S |j        s|j        rdS t                              |          }| ||          S 	 ddlm	} 	 ddl
m}  |             n# t          $ r Y nw xY w|                    |j                  }|r:|j        |                    |          S |j        |                    |          S dS n# t          $ r Y nw xY wdS )	z;Check whether a single platform is sufficiently configured.r  r   TNr   rj   discover_pluginsF)rM   r   r2   rF   r   r   r   r  ru   rk   hermes_cli.pluginsrA  rw   r   is_connectedvalidate_config)r   r   r=  checkerrk   rA  entrys          r"   r:  z$GatewayConfig._is_platform_connected  s    x&&  .. @\>V\%5%5g%>%>   < 	6> 	4 /228<<76??"	CCCCCC??????  """"   %))(.99E %1 --f555(4 00888t  	 	 	D	 us<   D B) (D )
B63D 5B66:D 1D 
DDc                 L    | j                             |          }|r|j        S dS )z$Get the home channel for a platform.N)r}   r   r   )r   r   r=  s      r"   get_home_channelzGatewayConfig.get_home_channel  s-    ##H-- 	'&&tr$   session_typec                 p    |r|| j         v r| j         |         S |r|| j        v r| j        |         S | j        S )z
        Get the appropriate reset policy for a session.
        
        Priority: platform override > type override > default
        )r$  r#  r"  )r   r   rI  s      r"   get_reset_policyzGatewayConfig.get_reset_policy  sU      	4D$:::)(33  	4LD,>>>%l33((r$   c                 2   i dd | j                                         D             d| j                                        dd | j                                        D             dd | j                                        D             d| j        d	| j        d
t          | j	                  d| j
        d| j        d| j        d| j        d| j        d| j        d| j        d| j        d| j        d| j                                        d| j        iS )Nr}   c                 H    i | ]\  }}|j         |                                 S r   r   r   )r   pcs      r"   r   z)GatewayConfig.to_dict.<locals>.<dictcomp>  s5       )-A  r$   r"  r#  c                 >    i | ]\  }}||                                 S r   r   r   kvs      r"   r   z)GatewayConfig.to_dict.<locals>.<dictcomp>  s3       #'1a199;;  r$   r$  c                 H    i | ]\  }}|j         |                                 S r   rN  )r   rO  rT  s      r"   r   z)GatewayConfig.to_dict.<locals>.<dictcomp>  s5     " " ")-A" " "r$   r(  r)  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r8  )r}   r   r"  r   r#  r$  r(  r)  r   r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r8  r   s    r"   r   zGatewayConfig.to_dict  s   
  151E1E1G1G  
 #D$=$E$E$G$G	

   +/+=+C+C+E+E  
   " "151G1M1M1O1O" " "
 d1
 d1
 C 122
  5
 '(E
  4+!
" #D$=#
$ &t'C%
& '(E'
( &t'C)
* !$"9+
, '(E-
. //11/
0 )$*I1
 
 	
r$   r   c                 	   i }|                     di                                           D ]B\  }}	 t          |          }t                              |          ||<   3# t
          $ r Y ?w xY wi }|                     di                                           D ]"\  }}t                              |          ||<   #i }	|                     di                                           D ]B\  }}	 t          |          }t                              |          |	|<   3# t
          $ r Y ?w xY wt                      }
d|v r t                              |d                   }
t                      dz  }d|v rt          |d                   }|                     di           }t          |t                    si }|                     d          }|St          |                     d	          t                    r)|                     d	i                                d
          nd }|                     d          }|St          |                     d	          t                    r)|                     d	i                                d          nd }|                     d          }|                     d          }|                     d          }t          |                     d          t                    r|                     d          ni }|*t          |t                    r|                     d          }d|v r|                     d          }d}n|                     d          }d}t          ||          }t          |                     d          d          }	 t          |                     dd                    }t          |d          }n# t          t
          f$ r d}Y nw xY w | d i d|d|
d|d|	d|                     dddg          d|d|dt!          |                     d          d          dt!          |                     d          d          dt!          |d          dt!          |d          dt!          |d          dt!          |d          dt!          |d          d|d|dt"                              |                     di                     d|S )!Nr}   r#  r$  r"  r+  r,  r)  r/  sttr   r0  echo_transcriptsr1  r2  r4  gatewayr3  zgateway.max_concurrent_sessionsr5  r8   r8  r7  r   r(  r&  r'  r-  Tr.  Fr6  r   )r   r   rM   r   r   r(   r   r   r   r   rH   r7   r>   r-   maxr'   r#   r   )rx   r   r}   platform_nameplatform_datar   r#  	type_namepolicy_datar$  default_policyr,  r)  r/  r0  r1  r2  r4  nested_gatewaymax_concurrent_rawmax_concurrent_keyr3  r5  r8  s                           r"   r   zGatewayConfig.from_dict  s   	,0HH[",E,E,K,K,M,M 	 	(M=#M22&4&>&>}&M&M	(##    &*hh&C&C&I&I&K&K 	Q 	Q"I{'9'C'CK'P'PM)$$*.((3F*K*K*Q*Q*S*S 	 	&M;#M22.@.J.J;.W.W!(++    ,--!T))/99$?U:VWWN&((:5T!!^ 455L"2B77.$// 	 Nhh}--@J488TY??\`@a@ak$((5"--11)<<<gkK#xx(>??' dhhuoot44##''(:;;; ! #'((+D"E"E#'88,F#G#G !XX&:;;0:488I;N;NPT0U0U]),,,[]%*^T*J*J% "0!3!34H!I!I$,,!%*C!D!D!:!/!3!34M!N!N!B"?#
 #
 $GHH/00$
 $
 
	,),TXX6RTV-W-W)X)X&),-G)K)K&&:& 	, 	, 	,)+&&&	, s 
 
 
i
!/
 (-
 0/	

  88$4vx6HIII
 *>
 &
 *$((3E*F*FMMM
 &2344d& & &
 %[$777
 "..BD!I!I!I
 %11H$$O$O$O
 &22JE%R%R%R
   ,,>FFF!
" %<$;#
$ &>%=%
& &//b0I0IJJJ'
( (B'A)
 	
s5   ,A
A+*A++,D
D%$D%3O
 
O O c                     |rd| j                             |          }|r6d|j        v r-t          |j                            d          | j                  S |t
          j        k    rdS | j        S )a*  Return the effective unauthorized-DM behavior for a platform.

        Email is inbox-shaped, not chat-shaped, so it defaults to ``"ignore"``
        unless ``platforms.email.unauthorized_dm_behavior`` explicitly opts
        into pairing. A global default does not opt email into pairing.
        r5  r:   )r}   r   rF   r>   r5  rM   r   r   r   platform_cfgs      r"   get_unauthorized_dm_behaviorz*GatewayConfig.get_unauthorized_dm_behaviorE  s      	 >--h77L  :l>P P P: &**+EFF1   8>))x,,r$   c                     |rM| j                             |          }|r1d|j        v r(t          |j                            d          d          S dS )z9Return the effective notice-delivery mode for a platform.notice_deliveryr?   )r}   r   rF   rB   rd  s      r"   get_notice_deliveryz!GatewayConfig.get_notice_deliveryW  sf     	>--h77L  1\5G G G1 &**+<==   xr$   )NNr   )/r   r   r   r   r   rH   r}   r   rM   r   r   r   r"  r#  r   r$  r(  r   r)  r	   r,  r   r-  r2   r.  r/  r0  r1  r2  r3  r   r-   r4  r5  r   r6  r8  r>  r:  r   rH  rK  r   r   r   rf  ri  r   r$   r"   r!  r!  :  sx          16d0K0K0KItHn,-KKK 05uEW/X/X/X,XXX3853N3N3NM4//0NNN<AERV<W<W<WtH&889WWW !&6P6P Q Q QNDIQQQ &+U4%@%@%@NDcN@@@ /U/UVVVL$VVV "d!!! &*d))) K!%$%%% %)T(((%*d***-1Xc]111  %$$$ %+c*** "'!G!G!GIGGG ')(((h    (x ( (TX ( ( ( (T h{6K     (,&*) )8$) sm) 
	) ) ) )(
c3h 
 
 
 
8 ^
T#s(^ ^
 ^
 ^
 ^
 [^
@- -Xh5G -SV - - - -$	 	HX,> 	# 	 	 	 	 	 	r$   r!  c                    , t                      } i }| dz  }|                                r	 t          |dd          5 }t          j        |          pi }ddd           n# 1 swxY w Y   t
                              d|           n3# t          $ r&}t
                              d||           Y d}~nd}~ww xY w	 ddl	}| d	z  }|                                
r=t          |d          5 }|
                    |          pi }ddd           n# 1 swxY w Y   dd
lm} |                    |          }|                    d          }	|	rt          |	t                     r|	|d<   |                    d          }
|
Ht          |
t                     r|
|d<   n-t
                              dt#          |
          j                   |                    d          }t          |t                     r||d<   d|v r|d         |d<   d|v r|d         |d<   d|v r|d         |d<   d|v r|d         |d<   |                    d          }t          |t                     rd|v r|d         |d<   d|v r|d         |d<   |                    d          }t          |t                     s)|                    di                               d          }t          |t                     r||d<   d|v r|d         |d<   d|v r|d         |d<   d|v r|d         |d<   d|v r&t'          |                    d          d          |d<   |                    d          }t          |t                     r|                    d          nd}|                    di           ,t          ,t                     si ,,|d<   dt*          ddf,fd} ||            ||                    d                     ,r,|d<   	 dd lm}  |             dd!lm} n4# t          $ r'}t
                              d"|           d}Y d}~nd}~ww xY wt7          t8                    }|]|                                D ]H}	 t9          |j                  }n# t>          t@          f$ r Y +w xY w||vr|!                    |           I|D ]}|t8          j"        k    r|                    |j#                  }t          |t                     }|sb||                    d          fD ]J}t          |t                     r3|                    |j#                  }t          |t                     r|} nKt          |t                     si }d|v r:t'          |                    d          |                    dd                    |d<   d#|v r&tI          |                    d#          d$          |d#<   d%|v r|d%         |d%<   d&|v r|d&         |d&<   d'|v r|d'         |d'<   d(|v r|d(         |d(<   |t8          j%        k    rd)|v r|d)         |d)<   |t8          j%        k    rd*|v r|d*         |d*<   |t8          j%        k    rd+|v r|d+         |d+<   d,|v r|d,         |d,<   d-|v r|d-         |d-<   d.|v r|d.         |d.<   |t8          j%        k    rd/|v r|d/         |d/<   d0|v r|d0         |d0<   d1|v r|d1         |d1<   d2|v r|d2         |d2<   d3|v r|d3         |d3<   d4|v r|d4         |d4<   d5|v r|d5         |d5<   d6|v r|d6         |d6<   d7|v r|d7         |d7<   |t8          j&        t8          j'        hv rd8|v r|d8         |d8<   d9|v rD|d9         }t          |t                     r"d: |(                                D             |d9<   n||d9<   d;|v r|d;         |d;<   d<|v r|d<         |d<<   d=|v }|rc|                    d=          }t          |t                     r9tS          ,|j#                  \  }} d> |(                                D             |d=<   |od?|v }!|s|!s|stS          ,|j#                  \  }}"|!r|d?         |d?<   d@|"dA<   |"*                    |           |^|+                                D ]H}#|#j,        |                    |#j                  }t          |t                     sb||                    d          fD ]J}t          |t                     r3|                    |#j                  }t          |t                     r|} nKt          |t                     s	 |#,                    ||          }$n8# t          $ r+}t
                              dB|#j        |           Y d}~d}~ww xY wt          |$t                     r|$stS          ,|#j                  \  }%}"|"*                    |$           J|                    d(          }&|&|                    dC          pi }'d(|'vr,                    t8          j%        j#        i           }(|(                    dDi           })|)                    d(|&           t[          j.        dE          s.t_          |&          0                                tZ          j1        dE<   |                    dFi           }*t          |*t                     rLd(|*v rHt[          j.        dG          s4t_          |*d(                   0                                tZ          j1        dG<   n6# t          $ r)}t
                              dH| d	z  |           Y d}~nd}~ww xY wtd          3                    |          }+ti          |+           tk          |+           |+S )Iu  
    Load gateway configuration from multiple sources.

    Priority (highest to lowest):
    1. Environment variables
    2. ~/.hermes/config.yaml (primary user-facing config)
    3. ~/.hermes/gateway.json (legacy — provides defaults under config.yaml)
    4. Built-in defaults
    zgateway.jsonrzutf-8)encodingNu<   Loaded legacy %s — consider moving settings to config.yamlzFailed to load %s: %sr   zconfig.yaml)managed_scopesession_resetr"  r)  zIIgnoring invalid quick_commands in config.yaml (expected mapping, got %s)rW  r0  r1  r2  r4  rY  r3  r6  r(  r-  r.  r5  r8   r}   source_platformsr   c                    t          | t                    sd S |                                 D ]\  }}t          |t                    s                    |i           }t          |t                    si }i |                    di           |                    di           }d|v rd|d<   i ||}|r||d<   ||<   d S )NrF   r   T_enabled_explicit)r   rH   r   r   )ro  	plat_name
plat_blockexistingmerged_extramergedrC   s         r"   _merge_platform_mapz0load_gateway_config.<locals>._merge_platform_map  s    !"2D99 F-=-C-C-E-E 7 7)Iz%j$77 ! -11)R@@H%h55 &#%#_hll7B&?&?#_:>>RY[]C^C^#_L J..<@%8977J7F# 7*6w06N9--7 7r$   r@  rj   zplugin discovery skipped: %srh  r?   reply_prefixreply_in_threadcron_continuable_surfacerequire_mentionallowed_chatsgroup_allowed_chatsallowed_topicsfree_response_channelsmention_patternsexclusive_bot_mentions"observe_unmentioned_group_messages	dm_policy
allow_fromallow_admin_fromuser_allowed_commandsgroup_policygroup_allow_fromgroup_allow_admin_fromgroup_user_allowed_commandschannel_skill_bindingschannel_promptsc                 4    i | ]\  }}t          |          |S r   )r   rR  s      r"   r   z'load_gateway_config.<locals>.<dictcomp>W  s$    5d5d5dDAqc!ffa5d5d5dr$   r   r   r   c                 ^    i | ]*\  }}t          |t                    t          |          |+S r   )r   rH   r   )r   r   r   s      r"   r   z'load_gateway_config.<locals>.<dictcomp>e  sD     : : : ,W)'488:HHg: : :r$   r   Trq  z&apply_yaml_config_fn for %s raised: %srO   rF   TELEGRAM_REQUIRE_MENTIONrT   SIGNAL_REQUIRE_MENTIONus   Failed to process config.yaml — falling back to .env / gateway.json values. Check %s for syntax errors. Error: %s)6r   r   openjsonloadr3   inforw   r4   yaml	safe_load
hermes_clirm  apply_managed_overlayr   r   rH   typer   r>   rG   r	   rB  rA  ru   rk   debugr   rM   plugin_entriesrD   r(   KeyErrorr;  r   r   rB   r   r   r   r   rJ   updateall_entriesapply_yaml_config_fnosgetenvr   r    environr!  r   _apply_env_overrides_validate_gateway_config)-_homegw_datagateway_json_pathfer  config_yaml_pathyaml_cfgrm  srqcstt_cfggateway_sectionstreaming_cfggateway_cfggateway_platformsrw  rA  _pr_shared_loop_targets_entry_platplatre  _cfg_toplevel_src
_candidatebridgedr  has_channel_overridesr   rI   _extraenabled_was_explicitrF   rF  seededrh   _tl_require_mention_tg_section_tg_plat	_tg_extra
signal_cfgr=  rC   s-                                               @r"   load_gateway_configr  c  s    EG .!! 	J	J'w??? -1)A,,,"- - - - - - - - - - - - - - -KKN!     	J 	J 	JNN24EqIIIIIIII	JZ
 =0""$$ @	f&999 3Q>>!,,23 3 3 3 3 3 3 3 3 3 3 3 3 3 3 100000$::8DDH o..B 5jT** 524././/B~b$'' 02G,--NN5R)   ll5))G'4(( )!(%112:;Q2R./(H445=>W5X12)X556>?Y6Z23 $x//089M0N,-&ll955O/400 `5NRa5a5a5DE^5_12(H445=>W5X12$LL55MmT22 M !)Y ; ; ? ? L L-.. 5'4$8++,45E,F()!X--.67I.J*+)X556>.723 *X556YLL!;<<7 723 #,,y11K@J;X\@]@] g < < <cg$//R@@Nnd33 6!#'5$7c 7d 7 7 7 7 7 7$   1222[ 9 9::: 6'5$??????  """NNNNNNN   ;Q??? *.h !0022 ; ;F! ( 5 5&1 ! ! ! !$888,33E:::, o& o&8>))'||DJ77 *< > > % &!2HLL4M4M N & &%dD11 &)-$*)=)=J)*d;; &/9 %!,55 -==:]$(()CDD$>GG; ;G67 %441K$(():;; 2 2G-. "\11.:>.JGN+$441=>O1PG-.-==:FGa:bG67$441=>O1PG-.8,,,L1P1P/;O/LGO,8,,,1F,1V1V5ABW5XG128,,,1A\1Q1Q0<=M0NG,-+|;;8DE]8^G45%552>?Q2RG./+|;;8DE]8^G458,,,1UYe1e1eDPQuDvG@A,..+7+DGK(<//,8,FGL)%552>?Q2RG./*l::7CD[7\G34!\11.:>.JGN+%552>?Q2RG./+|;;8DE]8^G450L@@=IJg=hG9:H,hn===BZ^jBjBj8DE]8^G45$44&23D&EO!/488 E5d5dOLaLaLcLc5d5d5d 1225D 121\AA>JKi>jG:;%552>?Q2RG./(;|(K%( 
$0$4$45H$I$IM!-66 ,G*DJ- -)	6: :0=0C0C0E0E: : :	"56
 (5'Rl9R$ '; DY #>~tz#Z#Z 	5' 6+7	+BIi( 26E-.W%%%%  __.. ) )E19 #+<<
#;#;L &lD99 *%6[8Q8Q$R * *D)$55 *-1XXej-A-A
#-j$#?#? !*3=L$)E%lD99 ! !!&!;!;Hl!S!S$ ! ! !D!J   !! &fd33 !6 ! :>5:VVHAuLL(((( #+,,/@"A"A".&ll:66<"$K77-889J9PRTUUH ( 3 3GR @ @I(():<OPPP 9%?@@ bADEXAYAYA_A_AaAa
#=> "h33J*d++ f$
2229E];^;^2;>zJ[?\;];];c;c;e;eBJ78"  
 
 
4M!		
 	
 	
 	
 	
 	
 	
 	

 $$W--F     V$$$Ms   B A!B !A%%B (A%)B 
B8B33B8</l +Dl Dl DKl /P l 
P7P2-l 2P77/l 'Q<;l <Rl RR3l el 
f%!fl fFl 
m"mmr=  c                 (   | j         }d|j        cxk    rdk    s)n t                              d|j                   d|_        |j        |j        dk    r't                              d|j                   d|_        t
          j        dt
          j        d	t
          j        d
t
          j	        dt
          j
        dt
          j        di}| j                                        D ]e\  }}|j        s|                    |          }|rA|j        :|j                                        s!t                              d|j        |           f	 ddlm} n# t*          $ r d}Y nw xY w|| j                                        D ]\  }}|j        s|                    |          }|s%|j        }|rg|                                rS ||d          sFt                              d|j        ||                                dd         dz              d|_        dS dS )zValidate and sanitize a loaded GatewayConfig in place.

    Called by ``load_gateway_config()`` after all config sources are merged.
    Extracted as a separate function for testability.
    r      z3Invalid at_hour=%s (must be 0-23). Using default 4.r   Nz?Invalid idle_minutes=%s (must be positive). Using default 1440.r   TELEGRAM_BOT_TOKENDISCORD_BOT_TOKENSLACK_BOT_TOKENMATTERMOST_TOKENMATRIX_ACCESS_TOKENWEIXIN_TOKENzG%s is enabled but %s is empty. The adapter will likely fail to connect.)has_usable_secret)
min_lengthz%s is enabled but %s is set to a placeholder value ('%s'). Set a real bot token before starting the gateway. The adapter will NOT be started.   z...F)r"  r   r3   r4   r   rM   r   r   r   r   r   r   r}   r   r   r   r   r   r   hermes_cli.authr  ImportErrorerror)r=  policy_token_env_namesr   pconfigenv_namer  r   s           r"   r  r    s~    (F%%%%2%%%%A6>	
 	
 	
 "f&9Q&>&>M	
 	
 	
 #
 	/-)/. $-3355 	 	' 	#''11 	1'-:M:M:O:O1NN;  !5555555 ! ! ! ! $!'!1!7!7!9!9 	( 	(Hg? '++H55H ME ( (/@/@ST/U/U/U (7 NHekkmmBQB.?%.G	   #( %$	( 	(s   E EEc                 P    dt           dt          f fd}t          j        d          }|r |t           j                  }||_        t          j        dd                                          }|dv rOt           j         j        vr t                       j        t           j        <   | j        t           j                 _        t          j        dd          }|rot           j         j        vr t                       j        t           j        <   d	 |	                    d
          D              j        t           j                 j
        d<   t          j        d          }|rqt           j         j        v r^t          t           j        |t          j        dd          t          j        d          pd           j        t           j                 _        t          j        d          }|r |t           j                  }||_        t          j        d          }	|	rqt           j         j        v r^t          t           j        |	t          j        dd          t          j        d          pd           j        t           j                 _        t          j        dd                                          }
|
dv rOt           j         j        vr t                       j        t           j        <   |
 j        t           j                 _        t          d          }t          j        dd                                          dv }t           j         j        v r+ j        t           j                 }|rd|_        n.|rd|_        n$|r"t          d           j        t           j        <   t          j        d          }|rqt           j         j        v r^t          t           j        |t          j        dd          t          j        d          pd           j        t           j                 _        t          j        d          }t          j        d           }|rK|rHt           j         j        vr t                       j        t           j        <   d j        t           j                 _         j        t           j                 j
                            ||d!           t          j        d"          }|r| j        t           j                 j
        d#<   t          j        d$          }|r| j        t           j                 j
        d%<   t          j        d&          }|r| j        t           j                 j
        d'<   t          j        d(          }|r| j        t           j                 j
        d)<   t          j        d*          }|r| j        t           j                 j
        d+<   t          j        d,          }|r>	 t'          |           j        t           j                 j
        d-<   n# t(          $ r Y nw xY wt          j        d.          }|r| j        t           j                 j
        d/<   t          j        d0          }|r| j        t           j                 j
        d1<   t          j        d2          }|rqt           j         j        v r^t          t           j        |t          j        d3d          t          j        d4          pd           j        t           j                 _        t          j        d5          }|rt           j         j        vr=t                       j        t           j        <   d j        t           j                 _        nO j        t           j                 }t-          |j
                            d6d                    }|j        s	|sd|_        | j        t           j                 _        t          j        d7          }|rqt           j         j        v r^t          t           j        |t          j        d8d          t          j        d9          pd           j        t           j                 _        t          j        d:          }t          j        d;          }|rC|rA |t           j                  } | j
                            ||t          d<d=          d>           t          j        d?          }!|!rqt           j         j        v r^t          t           j        |!t          j        d@d          t          j        dA          pd           j        t           j                 _        t          j        dB          }"|"rWt          j        dCd          }#|#st2                              dD            |t           j                  }$|"|$_        |#|$j
        dE<   t          j        dF          }%|%rqt           j         j        v r^t          t           j        |%t          j        dGd          t          j        dH          pd           j        t           j                 _        t          j        dI          }&t          j        dJd          }'|&st          j        dK          r	|'st2                              dL            |t           j                  }(|&r|&|(_        |'|(j
        dM<   t          j        dNd          })|)r
|)|(j
        dO<   t          j        dKd          }*|*r
|*|(j
        dP<   t          j        dQd                                                                          }+|+dRv pt          dS          },|,|(j
        dT<   |+r
|+|(j
        dU<   t          j        dVd          }-|-r
|-|(j
        dW<   t          j        dX          }.|.rqt           j         j        v r^t          t           j        |.t          j        dYd          t          j        dZ          pd           j        t           j                 _        t          j        d[          }/|/rt           j         j        vr t                       j        t           j        <   d j        t           j                 _        |/ j        t           j                 _        t          j        d\          }0|0r|0 j        t           j                 j
        dE<   t          j        d]          }1t          j        d^          }2t          j        d_          }3t          j        d`          }4t?          |1|2|3|4g          rt           j          j        vr t                       j        t           j         <   d j        t           j                  _         j        t           j                  j
                            |1|3|4da           t          j        db          }5|5rqt           j          j        v r^t          t           j         |5t          j        dcd          t          j        dd          pd           j        t           j                  _        t          j        de          }6|6r~t           j!         j        vr t                       j        t           j!        <   d j        t           j!                 _        t          j        dfd           j        t           j!                 _"        t          j        dg          }7|7rqt           j!         j        v r^t          t           j!        |7t          j        dhd          t          j        di          pd           j        t           j!                 _        t          dj          }8t          j        dkd          }9t          j        dld          }:t          j        dm          };t          j        dn          }<|8s|9rIt           j#         j        vr t                       j        t           j#        <   d j        t           j#                 _        |9r|9 j        t           j#                 j
        do<   |:r@dp |:	                    d
          D             }=|=r|= j        t           j#                 j
        dq<   |;r>	 t'          |;           j        t           j#                 j
        dr<   n# t(          $ r Y nw xY w|<r|< j        t           j#                 j
        ds<   t          j        dtd          }>|>r|> j        t           j#                 j
        du<   t          dv          }?t          j        dw          }@t          j        dxd          }A|?rt           j$         j        vr t                       j        t           j$        <   d j        t           j$                 _        |@r>	 t'          |@           j        t           j$                 j
        dr<   n# t(          $ r Y nw xY w|Ar|A j        t           j$                 j
        dy<   t          dz          }Bt          j        d{          }Ct          j        d|d          }Dt          j        d}d          }Et          j        d~d          }F|Bst           j%         j        v s	|Cs|Ds|Es|Fr6t           j%         j        vr t                       j        t           j%        <   |Brd j        t           j%                 _        |Cr>	 t'          |C           j        t           j%                 j
        dr<   n# t(          $ r Y nw xY w|Dr|D j        t           j%                 j
        d<   |Er@d |E	                    d
          D             }G|Gr|G j        t           j%                 j
        d<   |Fr@d |F	                    d
          D             }H|Hr|H j        t           j%                 j
        d<   t          j        d          }It          j        d          }J|Ir|Jrt           j&         j        vr t                       j        t           j&        <   d j        t           j&                 _         j        t           j&                 j
                            |I|Jd           t          j        d          }K|Kr^t          t           j&        |Kt          j        dd          t          j        d          pd           j        t           j&                 _        t          j        d          }Lt          j        d          }M|Lr|Mrt           j'         j        vr t                       j        t           j'        <   d j        t           j'                 _         j        t           j'                 j
                            |L|Mt          j        dd          t          j        dd          d           t          j        dd          }N|Nr|N j        t           j'                 j
        d<   t          j        dd          }O|Or|O j        t           j'                 j
        d<   t          j        d          }P|Pr^t          t           j'        |Pt          j        dd          t          j        d          pd           j        t           j'                 _        t          j        d          }Qt          j        d          }R|Qr.|Rr+t           j(         j        vr t                       j        t           j(        <   d j        t           j(                 _         j        t           j(                 j
                            |Q|Rd           t          j        dd          }S|Sr|S j        t           j(                 j
        d<   t          j        d          }T|Tr^t          t           j(        |Tt          j        dd          t          j        d          pd           j        t           j(                 _        t          j        d          }Ut          j        d          }V|Ur|Vrt           j)         j        vr t                       j        t           j)        <   d j        t           j)                 _         j        t           j)                 j
                            |U|Vt          j        dd          t          j        dd          t          j        dd          t          j        dd          tU          dd          d           t          j        d          }Wt          j        d          }X|Ws|Xrt           j+         j        vr t                       j        t           j+        <   d j        t           j+                 _        |Wr|W j        t           j+                 _         j        t           j+                 j
        }Y|Xr|X|Yd<   t          j        dd                                          }Z|Zr|Z,                    d          |Yd<   t          j        dd                                          }[|[r|[,                    d          |Yd<   t          j        dd                                                                          }\|\r|\|Yd<   t          j        dd                                                                          }]|]r|]|Yd<   t          j        dd                                          }^|^r|^|Yd<   t          j        dd                                          }_|_r|_|Yd<   t          j        dd                                          }`|`r|`|Yd<   t          j        dd                                          }a|ar^t          t           j+        |at          j        dd          t          j        d          pd           j        t           j+                 _        t          j        d          }bt          j        d          }c|br|crt           j-         j        vr t                       j        t           j-        <   d j        t           j-                 _         j        t           j-                 j
                            |b,                    d          |ct          j        dd¦          tU          dd          t          j        ddŦ          t          dd=          dǜ           t          j        dȦ          }d|d3|d                                dv  j        t           j-                 j
        d<   t          j        d˦          }e|erx	 t]          j/        |e          }fnC# t`          $ r6 d̄ |e1                    dd
          	                    d
          D             }fY nw xY w|f j        t           j-                 j
        d<   t          j        dϦ          }g|grqt           j-         j        v r^t          t           j-        |gt          j        dd          t          j        dѦ          pd           j        t           j-                 _        t          j        dҦ          }ht          j        dӦ          }i|hs|irt           j2         j        vr t                       j        t           j2        <   d j        t           j2                 _         j        t           j2                 j
        }Y|hr|h|Yd#<   |ir|i|Yd<   t          j        dd                                          }j|jr|j|Yd<   t          j        dd                                          }k|kr|k|Yd<   t          j        dd                                          }ld}m|lsYt          j        dd                                          }n|nr0|n}ld}mtg          j4        tj                                        dۦ           |lrt          t           j2        |lt          j        dئ          pt          j        |md          t          j        dܦ          pt          j        dݦ          pd           j        t           j2                 _        t          j        dަ          pt          j        dߦ          }ot          j        d          }p|or|pr	t           j6         j        vr t                       j        t           j6        <   d j        t           j6                 _         j        t           j6                 j
        }Y|o|Yd#<   |p|Yd%<   t          j        d          }q|qr|q|Yd<   t          j        d          }r|rr|r|Yd<   t          j        d          }s|sr|s|Yd<   t          j        d          }t|tr|t|Yd<   t          j        d          }u|ur^t          t           j6        |ut          j        dd          t          j        d          pd           j        t           j6                 _        t          j        d          }v|vr)|v                                                                |Yd<   t          j        d          }w|wr|w|Yd<   t          j        d          }x|xr)|x                                                                |Yd<   t          j        d          }y|yr|y|Yd<   t          j        d          }z|zr+	 t'          |z           j7        _8        n# t(          $ r Y nw xY wt          j        d          }{|{r+	 t'          |{           j7        _9        n# t(          $ r Y nw xY w	 ddl:m;}|  ||             ddl<m=}} |}>                                D ]}~	 t          |~j?                  }n8# t`          $ r+}t2          @                    d|~j?        |           Y d}~Id}~ww xY w j                            |          }|2|j        s+t-          |j
        pi                     d6d                    rd}|~jA        P	 |~A                                }n:# t`          $ r-}t2          @                    d|~j?        |           d}Y d}~nd}~ww xY w||j        sJ|~jB        B	 |/|}|j        s%t          dt          |j
        pi                     }nt          d          }t          |t                    rj|rht          t          |di           pi           }|F                                D ]"\  }}|dk    r|G                    ||           #t          d|          }t-          |~B                    |                    }n:# t`          $ r-}t2          @                    d|~j?        |           d}Y d}~nd}~ww xY w|s"t2          @                    d|~j?                   L	 |~H                                scn9# t`          $ r,}t2          @                    d|~j?        |           Y d}~d}~ww xY w| j        vrt                       j        |<   d j        |         _        t          |t                    r|rt          |          }|I                    dd          } j        |         j
                            |           t          |t                    r|                    d          rt          |t          |d                   t          |                    d          pd          |                    d           rt          |d                    nd           j        |         _        n3# t`          $ r&}t2          @                    d|           Y d}~nd}~ww xY wt          j        dd                                          }d} j                            t           jK                  }|<t          |j
                            d          pd                                          }|p|}|r3 |t           jK                  }|,                    d          |j
        d<    j        L                                D ]}|j
        I                    d6d           dS (  z/Apply environment variable overrides to config.r   r   c                     | j         vr%t          d          j         | <   j         |          S j         |          }t          |j                            dd                    }|j        s	|sd|_        |S )NTr   rq  F)r}   r   r2   rF   r   r   )r   platform_configr  r=  s      r"   _enable_from_envz._apply_env_overrides.<locals>._enable_from_env.  s    6+++)7)E)E)EFX&#H-- *84  $O$9$=$=>QSX$Y$YZZ& 	+/C 	+&*O#r$   r  TELEGRAM_REPLY_TO_MODEr  >   allr   r   TELEGRAM_FALLBACK_IPSc                 ^    g | ]*}|                                 |                                 +S r   r   )r   ips     r"   
<listcomp>z(_apply_env_overrides.<locals>.<listcomp>P  sD     E
 E
 E
RXXZZE
HHJJE
 E
 E
r$   ,fallback_ipsTELEGRAM_HOME_CHANNELTELEGRAM_HOME_CHANNEL_NAMEr   TELEGRAM_HOME_CHANNEL_THREAD_IDNr   r  DISCORD_HOME_CHANNELDISCORD_HOME_CHANNEL_NAMEDISCORD_HOME_CHANNEL_THREAD_IDDISCORD_REPLY_TO_MODEWHATSAPP_ENABLED>   r   r   r   FTr  WHATSAPP_HOME_CHANNELWHATSAPP_HOME_CHANNEL_NAMEWHATSAPP_HOME_CHANNEL_THREAD_IDWHATSAPP_CLOUD_PHONE_NUMBER_IDWHATSAPP_CLOUD_ACCESS_TOKEN)r	  r
  WHATSAPP_CLOUD_APP_IDr  WHATSAPP_CLOUD_APP_SECRETr  WHATSAPP_CLOUD_WABA_IDwaba_idWHATSAPP_CLOUD_VERIFY_TOKENverify_tokenWHATSAPP_CLOUD_WEBHOOK_HOSTwebhook_hostWHATSAPP_CLOUD_WEBHOOK_PORTwebhook_portWHATSAPP_CLOUD_WEBHOOK_PATHwebhook_pathWHATSAPP_CLOUD_API_VERSIONapi_versionWHATSAPP_CLOUD_HOME_CHANNEL WHATSAPP_CLOUD_HOME_CHANNEL_NAME%WHATSAPP_CLOUD_HOME_CHANNEL_THREAD_IDr  rq  SLACK_HOME_CHANNELSLACK_HOME_CHANNEL_NAMESLACK_HOME_CHANNEL_THREAD_IDSIGNAL_HTTP_URLSIGNAL_ACCOUNTSIGNAL_IGNORE_STORIESr   )r  accountignore_storiesSIGNAL_HOME_CHANNELSIGNAL_HOME_CHANNEL_NAMESIGNAL_HOME_CHANNEL_THREAD_IDr  MATTERMOST_URLz2MATTERMOST_TOKEN set but MATTERMOST_URL is missingr  MATTERMOST_HOME_CHANNELMATTERMOST_HOME_CHANNEL_NAME!MATTERMOST_HOME_CHANNEL_THREAD_IDr  MATRIX_HOMESERVERMATRIX_PASSWORDzHMATRIX_ACCESS_TOKEN/MATRIX_PASSWORD set but MATRIX_HOMESERVER is missing
homeserverMATRIX_USER_IDuser_idr  MATRIX_E2EE_MODE)requiredrequireoptionalprefer	preferredMATRIX_ENCRYPTION
encryption	e2ee_modeMATRIX_DEVICE_ID	device_idMATRIX_HOME_ROOMMATRIX_HOME_ROOM_NAMEMATRIX_HOME_ROOM_THREAD_ID
HASS_TOKENHASS_URLEMAIL_ADDRESSEMAIL_PASSWORDEMAIL_IMAP_HOSTEMAIL_SMTP_HOST)address	imap_host	smtp_hostEMAIL_HOME_ADDRESSEMAIL_HOME_ADDRESS_NAMEEMAIL_HOME_ADDRESS_THREAD_IDTWILIO_ACCOUNT_SIDTWILIO_AUTH_TOKENSMS_HOME_CHANNELSMS_HOME_CHANNEL_NAMESMS_HOME_CHANNEL_THREAD_IDAPI_SERVER_ENABLEDAPI_SERVER_KEYAPI_SERVER_CORS_ORIGINSAPI_SERVER_PORTAPI_SERVER_HOSTr/   c                 ^    g | ]*}|                                 |                                 +S r   r  )r   origins     r"   r  z(_apply_env_overrides.<locals>.<listcomp>i  s2    iii&Z`ZfZfZhZhiv||~~iiir$   cors_originsporthostAPI_SERVER_MODEL_NAME
model_nameWEBHOOK_ENABLEDWEBHOOK_PORTWEBHOOK_SECRETsecretMSGRAPH_WEBHOOK_ENABLEDMSGRAPH_WEBHOOK_PORTMSGRAPH_WEBHOOK_CLIENT_STATE"MSGRAPH_WEBHOOK_ACCEPTED_RESOURCES$MSGRAPH_WEBHOOK_ALLOWED_SOURCE_CIDRSr  c                 ^    g | ]*}|                                 |                                 +S r   r  )r   resources     r"   r  z(_apply_env_overrides.<locals>.<listcomp>  sB       >>##    r$   accepted_resourcesc                 ^    g | ]*}|                                 |                                 +S r   r  )r   cidrs     r"   r  z(_apply_env_overrides.<locals>.<listcomp>  s>       ::<<

  r$   allowed_source_cidrsDINGTALK_CLIENT_IDDINGTALK_CLIENT_SECRET)	client_idr  DINGTALK_HOME_CHANNELDINGTALK_HOME_CHANNEL_NAMEDINGTALK_HOME_CHANNEL_THREAD_IDFEISHU_APP_IDFEISHU_APP_SECRETFEISHU_DOMAINr^   FEISHU_CONNECTION_MODE	websocket)r  r  domainconnection_modeFEISHU_ENCRYPT_KEYencrypt_keyFEISHU_VERIFICATION_TOKENverification_tokenFEISHU_HOME_CHANNELFEISHU_HOME_CHANNEL_NAMEFEISHU_HOME_CHANNEL_THREAD_IDWECOM_BOT_IDWECOM_SECRET)bot_idrF  WECOM_WEBSOCKET_URLwebsocket_urlWECOM_HOME_CHANNELWECOM_HOME_CHANNEL_NAMEWECOM_HOME_CHANNEL_THREAD_IDWECOM_CALLBACK_CORP_IDWECOM_CALLBACK_CORP_SECRETWECOM_CALLBACK_AGENT_IDWECOM_CALLBACK_TOKENWECOM_CALLBACK_ENCODING_AES_KEYWECOM_CALLBACK_HOSTz0.0.0.0WECOM_CALLBACK_PORTi!  )corp_idcorp_secretagent_idr   encoding_aes_keyr@  r?  r  WEIXIN_ACCOUNT_IDr  WEIXIN_BASE_URL/base_urlWEIXIN_CDN_BASE_URLcdn_base_urlWEIXIN_DM_POLICYr  WEIXIN_GROUP_POLICYr  WEIXIN_ALLOWED_USERSr  WEIXIN_GROUP_ALLOWED_USERSr  WEIXIN_SPLIT_MULTILINE_MESSAGESsplit_multiline_messagesWEIXIN_HOME_CHANNELWEIXIN_HOME_CHANNEL_NAMEWEIXIN_HOME_CHANNEL_THREAD_IDBLUEBUBBLES_SERVER_URLBLUEBUBBLES_PASSWORDBLUEBUBBLES_WEBHOOK_HOSTz	127.0.0.1BLUEBUBBLES_WEBHOOK_PORTBLUEBUBBLES_WEBHOOK_PATHz/bluebubbles-webhookBLUEBUBBLES_SEND_READ_RECEIPTS)r  r  r  r  r  send_read_receiptsBLUEBUBBLES_REQUIRE_MENTION>   r   r   r   r   r{  BLUEBUBBLES_MENTION_PATTERNSc                 ^    g | ]*}|                                 |                                 +S r   r  )r   parts     r"   r  z(_apply_env_overrides.<locals>.<listcomp>V  s>     # # #zz||#JJLL# # #r$   
r  BLUEBUBBLES_HOME_CHANNELBLUEBUBBLES_HOME_CHANNEL_NAME"BLUEBUBBLES_HOME_CHANNEL_THREAD_ID	QQ_APP_IDQQ_CLIENT_SECRETr  QQ_ALLOWED_USERSQQ_GROUP_ALLOWED_USERSQQBOT_HOME_CHANNELQQBOT_HOME_CHANNEL_NAMEQQ_HOME_CHANNELQQ_HOME_CHANNEL_NAMEzoQQ_HOME_CHANNEL is deprecated; rename to QQBOT_HOME_CHANNEL in your .env for consistency with the platform key.QQBOT_HOME_CHANNEL_THREAD_IDQQ_HOME_CHANNEL_THREAD_IDYUANBAO_APP_IDYUANBAO_APP_KEYYUANBAO_APP_SECRETYUANBAO_BOT_IDrh  YUANBAO_WS_URLws_urlYUANBAO_API_DOMAIN
api_domainYUANBAO_ROUTE_ENV	route_envYUANBAO_HOME_CHANNELYUANBAO_HOME_CHANNEL_NAMEYUANBAO_HOME_CHANNEL_THREAD_IDYUANBAO_DM_POLICYYUANBAO_DM_ALLOW_FROMdm_allow_fromYUANBAO_GROUP_POLICYYUANBAO_GROUP_ALLOW_FROMSESSION_IDLE_MINUTESSESSION_RESET_HOURr   r@  rj   zunknown platform name %r: %sz#env_enablement_fn for %s raised: %s)r   rF   rF   r   u6   is_connected for %s raised: %s — skipping enablementuc   Plugin platform '%s' available but not configured (is_connected returned False) — skipping enablezcheck_fn for %s raised: %sr   rD   r   z&Plugin platform enable pass failed: %sGATEWAY_RELAY_URLr  )MrM   r   r  r  r   r   r    r}   r   splitrF   r   r   r   r   r   r   r   r  r-   r(   r   r2   r   r   r3   r4   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r   r   rstripr   r  loadsrw   rr   r   logging	getLoggerr   r   r"  r   r   rB  rA  ru   rk   r  rD   r  env_enablement_fnrC  rH   r   getattrr   rG   check_fnpopr   r   values)r=  r  telegram_tokentelegram_configtelegram_reply_modetelegram_fallback_ipstelegram_homediscord_tokendiscord_configdiscord_homediscord_reply_modewhatsapp_enabledwhatsapp_disabled_explicitlywa_cfgwhatsapp_homewhatsapp_cloud_phone_idwhatsapp_cloud_tokenwa_cloud_app_idwa_cloud_app_secretwa_cloud_waba_idwa_cloud_verify_tokenwa_cloud_hostwa_cloud_portwa_cloud_pathwa_cloud_api_versionwhatsapp_cloud_homeslack_tokenslack_configr  
slack_home
signal_urlsignal_accountsignal_configsignal_homemattermost_tokenmattermost_urlmattermost_configmattermost_homematrix_tokenmatrix_homeservermatrix_configmatrix_usermatrix_passwordmatrix_e2ee_modematrix_e2eematrix_device_idmatrix_home
hass_tokenhass_url
email_addr	email_pwd
email_imap
email_smtp
email_home
twilio_sidsms_homeapi_server_enabledapi_server_keyapi_server_cors_originsapi_server_portapi_server_hostoriginsapi_server_model_namewebhook_enabledr  webhook_secretmsgraph_webhook_enabledmsgraph_webhook_portmsgraph_webhook_client_statemsgraph_webhook_resourcesmsgraph_webhook_allowed_cidrs	resourcescidrsdingtalk_client_iddingtalk_client_secretdingtalk_homefeishu_app_idfeishu_app_secretfeishu_encrypt_keyfeishu_verification_tokenfeishu_homewecom_bot_idwecom_secretwecom_ws_url
wecom_homewecom_callback_corp_idwecom_callback_corp_secretweixin_tokenweixin_account_idrF   weixin_base_urlweixin_cdn_base_urlweixin_dm_policyweixin_group_policyweixin_allowed_usersweixin_group_allowed_usersweixin_split_multilineweixin_homebluebubbles_server_urlbluebubbles_passwordbluebubbles_require_mentionbluebubbles_mention_patternsparsed_patternsbluebubbles_home	qq_app_idqq_client_secretqq_allowed_usersqq_group_allowedqq_homeqq_home_name_envlegacy_homeyuanbao_app_idyuanbao_app_secretyuanbao_bot_idyuanbao_ws_urlyuanbao_api_domainyuanbao_route_envyuanbao_homeyuanbao_dm_policyyuanbao_dm_allow_fromyuanbao_group_policyyuanbao_group_allow_fromr   
reset_hourrA  rk   rF  r   r  existing_cfgseed_for_probe	probe_cfgprobe_extrarS  rT  
configuredexcseedhomerelay_url_envrelay_url_yamlexisting_relayrelay_url_valrelay_configr  s   `                                                                                                                                                r"   r  r  +  s'   8       $ Y344N /**8+<== . )$<bAAGGII555F$4442@2B2BFX./<O*+9I&=rBB 
F$4442@2B2BFX./E
 E
!6!<!<S!A!AE
 E
 E
*+1.A I566M 
*f.>>>;F&!7@@i ABBJd	<
 <
 <
*+8 I122M -))(*:;;,9344L 
(F,<<<:E% 6??i @AAIT	;
 ;
 ;
)*7 #:B??EEGG4446#3331?1A1AFX-.;M)*8 ''9::#%9-?#D#D#J#J#L#LPd#d F,,,!("34' 	""FNN 	"!FN	 K.<T.J.J.J*+I566M 
*f.>>>;F&!7@@i ABBJd	<
 <
 <
*+8 !i(HII9%BCC 'b#7 'b"&*:::8F8H8HFX45<@019017>>60@
 @
 	 	 	
 )$;<< 	XHWFX45;HE i(CDD 	`L_FX45;LI9%=>> 	ZIYFX45;IF "	*G H H  	dNcFX45;NK	"?@@ 	\N[FX45;NK	"?@@ 	RUVcRdRd !89?OO   	"?@@ 	\N[FX45;NK!y)EFF 	bMaFX45;MJ)$ABB 
x6&:JJJAL,'=vFFi GHHPD	B
 B
 B
01> )-..K =>!111/=/?/?FX^,7;FX^,44!+HN;L $((:(>(>?RTY(Z(Z#[#[ ' ,0D , (,$ 2=(./00J 
hn(8888C^4b99i >??G4	9
 9
 9
(5 ,--JY/00N n ((99"""%-.EvNN$
 $
 	 	 	
 )122K 
x&*:::9D_5v>>i ?@@HD	:
 :
 :
)6 y!344 8#3R88 	QNNOPPP,,X-@AA"2)7&i 9::O 
8.&2BBB=H(#96BBi CDDL	>
 >
 >
,-: 9233L	"5r:: @ry!233 @  	gNNefff((99 	/".M,=L)i 0"55 	9-8M	*)$5r:: 	>.=M
+9%7<<BBDDJJLL ZZ 4233 	 -8L) 	@/?M,9%7<< 	@/?M,).//K 
x&*:::9D_2F;;i <==E	:
 :
 :
)6 <((J M!)9997E7G7GFX34;?/089C/069Z(( 	MDLFX34:5A ?++J	*++I,--J,--J
J	:z:;; >!111/=/?/?FX^,37(0(.55!##7
 7
 	 	 	
 /00J 
hn(8888C^4f==i >??G4	9
 9
 9
(5 /00J T<v///-;-=-=FX\*15&.13;NPR1S1S&.y+,,H 
HLF$4446A\2F;;i <==E	7
 7
 7
&3 ))=>>Y/44N i(A2FFi 122Oi 122O ^^ ^f&6664B4D4DFX018<,-5 	PAOFX017>" 	Vii4K4Q4QRU4V4ViiiG VNU !45;NK 	FI/FZFZ !45;FCC    	RBQFX017? "	*A2 F F  	^H]FX017E &&788O9^,,LY/44N 
P6#3331?1A1AFX-.59)*2 	CF|CTCT !128@@    	PAOFX-.4X> ..GHH9%;<<#%9-KR#P#P  "	*NPR S S$&I.% %! 	 *#v'777 8' 8 % 8 )	 8 #6+;;;9G9I9IFX56" 	FAEFX56> 	KN(L L !9:@HH    ' 	, X56<^L % 		  9 ? ? D D  I
     !9:@( ) 		 9??DD  E
     !9:@*
 #788Y'?@@ 4 F$4442@2B2BFX./6:*+3*+188+3:
 :
 	 	 	 	"9:: 	?J!*%Y;VDD)$EFFN$	@ @ @FX./< Io..M	"566 * ?&"2220>0@0@FX_-48)1)/66#+i::!y)A;OO	8
 8
 	 	 	  Y';R@@ 	XEWFX_-3MB$&I.I2$N$N!$ 	fLeFX_-34HIi 566 	=H!#Y96BB)$CDDL	> > >FX_-: 9^,,L9^,,L  >!111/=/?/?FX^,37(0(.55""7
 7
 	 	 	 y!6;; 	SFRFX^,2?CY344
 	<G!"Y8&AA)$BCCKt	= = =FX^,9  Y'?@@!#+G!H!H "< "&*:::8F8H8HFX45<@019017>>-5	";R@@Y5r:: "	*KR P PI3Y??1488@
 @
 	 	 	 9^,,L	"566 %( %?&"2220>0@0@FX_-48)1 	C6BFX_-3 17 	4"3E,)$5r::@@BB 	< / 6 6s ; ;E* i(=rBBHHJJ 	D$7$>$>s$C$CE.!9%7<<BBDDJJLL 	2!1E+ i(=rBBHHJJPPRR 	8$7E.!!y)?DDJJLL 	7"6E,%'Y/KR%P%P%V%V%X%X"% 	C(BE$%!#+Lb!Q!Q!W!W!Y!Y! 	G0FE,-i 5r::@@BB 	=H!#Y96BB)$CDDL	> > >FX_-:  Y'?@@9%;<< _"6 _v'7775C5E5EFX129=-.6-.4;;077<<,I&@+NN#$>EEI&@BXYY"12RTZ"["[=
 =
 	 	 	 ')i0M&N&N#&2+11337QQ X1289JK (*y1O'P'P$' 		_"&*-I"J"J   # # < D DT3 O O U UVY Z Z# # # P_FX1289KLy!;<< 
H0F4DDD>I)$:FCCi DEEM	?
 ?
 ?
-.; 	+&&Iy!344 %$ %>!111/=/?/?FX^,37(0 06 	('E(O 	6%5E/"9%7<<BBDD 	3"2E,9%=rBBHHJJ 	9(8E$%)0"55;;==4 		)$5r::@@BBK %#9 !(++33J    
	<G!Y899`RYGWY_=`=`I<== y!<==	= 	= 	=FX^,9 Y/00PBI>O4P4PN#788 &A, &A6#3331?1A1AFX-.59)*2 !128(h0l#344 	-,E(O#344 	-,E(OY';<< 	5"4E,I&9:: 	3!2E+y!788 	>I!)$Y:FCC)$DEEM	? ? ?FX-.; I&9:: 	C!2!8!8!:!:!@!@!B!BE+ "	*A B B  	;%:E/"!y)?@@ 	I$8$>$>$@$@$F$F$H$HE.!#%9-G#H#H # 	A(@E$% 9344L 	7:<7H7HF'44 	 	 	D	 /00J 	25j//F'// 	 	 	D	*FB777777??????&5577 @	 @	E#EJ//   ;UZKKK "+//99L ($, ),,2778KUSSTT )  "N&2*%*%<%<%>%>NN  * * *LL=uz1   &*NNNNNN	* #<+?#%1$+ (3(4I#,#4 ",:,0*.y/D"*E*E-" -" -"	
 )7t(D(D(DI%nd;;   +/wy'2/N/N/TRT*U*UK(6(<(<(>(> = =1#$#6#6$, + 6 6q! < < < <(6(,&1) ) )I &*%*<*<Y*G*G%H%H

$ + + +T!J   &+





+ & !P!J  
 !~~''    95:qIII v///-;-=-= *15FX&. .$// N N++ xx55 *077===dD)) 
dhhy.A.A 
>I!) #DO 4 4 &!1!1!;V<<  $xx44&C[ 1222!%	? 	? 	?F$X.;o@	B  B B B=qAAAAAAAAB I1266<<>>MN%))(.99N!^155kBBHbIIOOQQ!3^M D''77*7*>*>s*C*C;'!+2244 = =!!"5t<<<<= =s  2,X 
X,+X,B,AB5 B5
ACCACF(,AG G
AG"G!AG"K,AL L
ALLALt1Au u=AvvAvJBJ9 J9
BKKBKK BK: K:
BLLBLL-B\ L9BMMB\ M
BNM!BM>M9B\ M>BNNAB\ OBO3O2B\ O3
BP*O=#BP%P B\ P%BP*P*B\ Q C"BT#T"B\ T#
BUT-#BUUB\ UBUU'B\ VBVVB\ V
BWV#!BW
WB\ W
BWWEB\ \
B]\B] ] B])T)r8   )r?   )r=  r!  r   N)Fr   r  r  r  pathlibr   dataclassesr   r   typingr   r   r   r	   r
   enumr   hermes_cli.configr   utilsr   r   r   r  r   r3   r2   r#   r&   r*   r-   r.   r   r7   r>   rB   rH   r   rJ   rK   r~   r   rM   	frozenset__members__r  _BUILTIN_PLATFORM_VALUESr   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"   <module>rL     sQ      				        ( ( ( ( ( ( ( ( 6 6 6 6 6 6 6 6 6 6 6 6 6 6       - - - - - - ; ; ; ; ; ; ; ; ; ;		8	$	$3 3 3d 3d 3 3 3 3 u     s S S    ! !3 !8C= ! ! ! !H s S c     c C s     C E$PT*DU    ( 26 # 5 5 5` ` ` ` `t ` ` `J %9$T$Th6J6Q6Q6S6S$T$T$TTT  
 
 
 
 
 
 
 
D 0
 0
 0
 0
 0
 0
 0
 0
f 
 
 
 
 
 
 
 
B ]
 ]
 ]
 ]
 ]
 ]
 ]
 ]
J *-  , , ,*, "C , , , & # & & & ;
 ;
 ;
 ;
 ;
 ;
 ;
 ;
L O      O@@))&&      N      N  5R d8X~6F6L-M#MN   @ e e e e e e e eP	@] @ @ @ @FB( B( B( B(JL= L=4 L= L= L= L= L= L=r$   