
    
BjR                       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  ej*                  e      Zd9d	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:d	ed
edefdZd;d	ed
edefdZ da!ee"   e#d<    G d de      Z$ e%d e$jL                  jO                         D              Z(e G d d             Z)e G d d             Z*e G d d             Z+dZ,ee#d<   dZ-ee#d<   dZ.ee#d <   e G d! d"             Z/e$j`                  d# e$jb                  d$ e$jd                  d% e$jf                  d& e$jh                  d' e$jj                  d( e$jl                  d) e$jn                  d* e$jp                  d+ e$jr                  d, e$jt                  d- e$jv                  d. e$jx                  d/ e$jz                  d0 e$j|                  d1 iZ?e@e$ee+gef   f   e#d2<   e G d3 d4             ZAdeAfd5ZBd<d7ZCd6eAddfd8ZDy)=z
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)is_truthy_valuevaluedefaultreturnc                     | |S t        | t              r*| j                         j                         }|dv ry|dv ry|S t	        | |      S )zDCoerce bool-ish config values, preserving a caller-provided default.>   1onyestrueT>   0noofffalseF)r   )
isinstancestrstriplowerr   )r   r   lowereds      3/home/ubuntu/.hermes/hermes-agent/gateway/config.py_coerce_boolr!      sT    }%++-%%'00115'22    c                 P    | |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(   '   s4    }U|z"    
 %%c                 P    | |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   s4    }5zz" r)   c                 n    t        | t              r$| j                         j                         }|dv r|S |S )z8Normalize unauthorized DM behavior to a supported value.>   pairignorer   r   r   r   r   r   
normalizeds      r    #_normalize_unauthorized_dm_behaviorr3   ;   s4    %[[]((*
++Nr"   c                 n    t        | t              r$| j                         j                         }|dv r|S |S )z4Normalize notice delivery mode to a supported value.>   publicprivater0   r1   s      r    _normalize_notice_deliveryr7   D   s4    %[[]((*
..Nr"   _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ed        Zedefd       Zy)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slacksignal
mattermostmatrixhomeassistantemailsmsdingtalk
api_serverwebhookmsgraph_webhookfeishuwecomwecom_callbackweixinbluebubblesqqbotyuanbaoc                 4   t        |t              r|j                         sy|j                         j                         }|| j                  v r| j                  |   S t
        | j                         a|t
        v r{t        j                  |       }||_	        |j                         j                  dd      j                  dd      |_        || j                  |<   || j                  |j                  <   |S 	 ddlm} |j!                  |      r{t        j                  |       }||_	        |j                         j                  dd      j                  dd      |_        || j                  |<   || j                  |j                  <   |S 	 y# t"        $ r Y yw xY w)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_r8   _scan_bundled_plugin_platformsobject__new___value_upperreplace_name__member_map_gateway.platform_registryrV   is_registered	Exception)clsr   pseudorV   s       r    	_missing_zPlatform._missing_p   sm    %%U[[]##%C***))%00
 +2.1.P.P.R+33^^C(F"FN!KKM11#s;CCCMFM,2C""5).4CV]]+M
	C ..u5,!& % 5 5c3 ? G GS Q06&&u-28  / 6   		s   7BF 	FFr   c                    t               }	 t        t              j                  j                  dz  dz  }|j	                         r|j                         D ]w  }|j	                         s|dz  j                         s(|dz  j                         s|dz  j                         sO|j                  |j                  j                                y |S # t        $ r Y |S w xY w)zFReturn names of bundled platform plugins under ``plugins/platforms/``.plugins	platformsz__init__.pyzplugin.yamlz
plugin.yml)setr   __file__parentis_diriterdirexistsaddnamer   rb   )rc   namesplatforms_dirchilds       r    rX   z'Platform._scan_bundled_plugin_platforms   s     U	 N11889D{RM##%*224 	6E"]2::<"]2::< % 4<<> 		%**"2"2"45	6   		s$   AC )C =&C $+C 	CCN)__name__
__module____qualname____doc__LOCALTELEGRAMDISCORDWHATSAPPSLACKSIGNAL
MATTERMOSTMATRIXHOMEASSISTANTEMAILSMSDINGTALK
API_SERVERWEBHOOKMSGRAPH_WEBHOOKFEISHUWECOMWECOM_CALLBACKWEIXINBLUEBUBBLESQQBOTYUANBAOclassmethodre   ri   rX    r"   r    r:   r:   R   s     EHGHEFJF#ME
CHJG'OFE%NFKEG* *X s  r"   r:   c              #   4   K   | ]  }|j                     y wN)r   ).0ms     r    	<genexpr>r      s     $TQWW$Ts   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y)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_idrp   N	thread_idr   c                     | j                   j                  | j                  | j                  d}| j                  r| j                  |d<   |S )N)r   r   rp   r   )r   r   r   rp   r   selfresults     r    to_dictzHomeChannel.to_dict   s@    ++||II

 >>"&..F;r"   datac           	           | t        |d         t        |d         |j                  dd      |j                  d      rt        |d               S d       S )Nr   r   rp   Homer   r   r   rp   r   )r:   r   getrc   r   s     r    	from_dictzHomeChannel.from_dict   s_    d:./Y(&&)040Ec${+,	
 	
 LP	
 	
r"   )rt   ru   rv   rw   r:   __annotations__r   r   r   r   r	   r   r   r   r   r"   r    r   r      se     L
I#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eeef   fdZedeeef   dd fd       Zy)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rG   rH   notify_exclude_platformsr   c                     | j                   | j                  | j                  | j                  t	        | j
                        dS )Nr   r   r   r   r   )r   r   r   r   listr   r   s    r    r   zSessionResetPolicy.to_dict   s8    II|| --kk(,T-J-J(K
 	
r"   r   c           	         |j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      } | ||nd||nd||ndt        |d	      |t        |            S d
      S )Nr   r   r   r   r   r   r   r   Tr   r   )r   r!   tuple)rc   r   r   r   r   r   excludes          r    r   zSessionResetPolicy.from_dict   s     xx((9%xx/(#((56)v&2G)5)At-7>7JU7^
 	

 Qj
 	
r"   N)rt   ru   rv   rw   r   r   r   r   r+   r   r   boolr   r   r   r	   r   r   r   r   r"   r    r   r      s{     D#GSL#FD&?e?
c3h 
 
T#s(^ 
0D 
 
r"   r   c                       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<    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y)PlatformConfigz.Configuration for a single messaging platform.FenabledNtokenapi_keyhome_channelfirstreply_to_modeTgateway_restart_notificationdefault_factoryextrar   c                 "   | j                   | j                  | j                  | j                  d}| j                  r| j                  |d<   | j
                  r| j
                  |d<   | j                  r| j                  j                         |d<   |S )N)r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   s     r    r   zPlatformConfig.to_dict  s{    ||ZZ!//,0,M,M	
 ::"jjF7O<< $F9%)%6%6%>%>%@F>"r"   r   c                 <   d }d|v rt         j                  |d         } | t        |j                  d      d      |j                  d      |j                  d      ||j                  dd      t        |j                  d      d	      |j                  d
i             S )Nr   r   Fr   r   r   r   r   Tr   )r   r   r   r   r   r   r   )r   r   r!   r   )rc   r   r   s      r    r   zPlatformConfig.from_dict-  s    T!&00n1EFL )!4e<((7#HHY'%((?G<)578$* ((7B'

 
	
r"   )rt   ru   rv   rw   r   r   r   r   r   r   r   r   r   r   r   r   dictr   r   r	   r   r   r   r   r"   r    r   r     s    8GTE8C=!GXc]!*.L(;'. !M3  *. $- "$7E4S>7c3h  
T#s(^ 
0@ 
 
r"   r   g?DEFAULT_STREAMING_EDIT_INTERVAL   "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y)StreamingConfigzCConfiguration for real-time token streaming to messaging platforms.Fr   auto	transportedit_intervalbuffer_thresholdcursor      N@fresh_final_after_secondsr   c                     | j                   | j                  | j                  | j                  | j                  | j
                  dS )Nr   r   r   r   r   r   r   r   s    r    r   zStreamingConfig.to_dictc  s<    ||!// $ 5 5kk)-)G)G
 	
r"   r   c                 P   |s |        S  | t        |j                  d      d      |j                  dd      t        |j                  d      t              t	        |j                  d      t
              |j                  dt              t        |j                  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_dictm  s    5L )!4e<hh{F3')+J )+,.P 88H&>?&345t'
 	
r"   N)rt   ru   rv   rw   r   r   r   r   r   r   r   r$   r   r   r+   r   r   r   r   r	   r   r   r   r   r"   r    r   r   J  s    MGT Is:M5:>c>*FC* (,u+
c3h 
 
T#s(^ 
0A 
 
r"   r   c                     t        | j                  j                  d      xr) | j                  xs | j                  j                  d            S )N
account_idr   )r   r   r   r   cfgs    r    <lambda>r     s6    		l#M)LciimmG6L" r"   c                      yNTr   r   s    r    r   r         r"   c                 J    t        | j                  j                  d            S )Nhttp_urlr   r   r   r   s    r    r   r     s    ciimmJ&?!@ r"   c                 J    t        | j                  j                  d            S )Naddressr   r   s    r    r   r     s    SYY]]9%= > r"   c                 >    t        t        j                  d            S )NTWILIO_ACCOUNT_SID)r   osgetenvr   s    r    r   r     s    d299-A#BC r"   c                      yr   r   r   s    r    r   r     r   r"   c                      yr   r   r   s    r    r   r     r   r"   c                      yr   r   r   s    r    r   r     r   r"   c                 J    t        | j                  j                  d            S )Napp_idr   r   s    r    r   r     s    ciimmH&=!> r"   c                 J    t        | j                  j                  d            S )Nbot_idr   r   s    r    r   r     s    SYY]]8%< = r"   c                     t        | j                  j                  d      xs | j                  j                  d            S )Ncorp_idappsr   r   s    r    r   r     s-    		i 9CIIMM&$9* r"   c                     t        | j                  j                  d      xr | j                  j                  d            S )N
server_urlpasswordr   r   s    r    r   r     s-    d		l#A		j(A' r"   c                     t        | j                  j                  d      xr | j                  j                  d            S )Nr   client_secretr   r   s    r    r   r     s-    		hBCIIMM/$B! r"   c                     t        | j                  j                  d      xr | j                  j                  d            S )Nr   
app_secretr   r   s    r    r   r     s-    $		h?CIIMM,$?# r"   c                     t        | j                  j                  d      xs t        j                  d      xr2 | j                  j                  d      xs t        j                  d            S )N	client_idDINGTALK_CLIENT_IDr   DINGTALK_CLIENT_SECRET)r   r   r   r   r   r   s    r    r   r     sO    4	{	#	Fryy1E'F 	TYY]]?+Rryy9Q/R$ r"   _PLATFORM_CONNECTED_CHECKERSc                   D   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<    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*y)'GatewayConfigzy
    Main gateway configuration.
    
    Manages all platform connections, session policies, and delivery settings.
    r   rh   default_reset_policyreset_by_typereset_by_platformc                  
    ddgS )N/new/resetr   r   r"   r    r   zGatewayConfig.<lambda>  s    vx>P r"   reset_triggersquick_commandsc                      t               dz  S )Nsessionsr   r   r"   r    r   zGatewayConfig.<lambda>  s    7H:7U r"   sessions_dirTalways_log_localstt_enabledgroup_sessions_per_userFthread_sessions_per_userr.   unauthorized_dm_behavior	streamingZ   session_store_max_age_daysr   c                     g }| j                   j                         D ]6  \  }}|j                  s| j                  ||      s&|j	                  |       8 |S )z9Return list of platforms that are enabled and configured.)rh   itemsr   _is_platform_connectedappend)r   	connectedr   configs       r    get_connected_platformsz%GatewayConfig.get_connected_platforms  sX    	 $ 4 4 6 	+Hf>>**8V<  *		+
 r"   r   r  c                    |t         j                  k(  rOt        |j                  j	                  d      xr) |j
                  xs |j                  j	                  d            S |j
                  s|j                  ryt        j	                  |      }| ||      S 	 ddlm	} |j	                  |j                        }|r;|j                  |j                  |      S |j                  |j                  |      S y	 y# t        $ r Y yw xY w)z;Check whether a single platform is sufficiently configured.r   r   Tr   rU   F)r:   r   r   r   r   r   r   r   r`   rV   r   is_connectedvalidate_configrb   )r   r   r  checkerrV   entrys         r    r  z$GatewayConfig._is_platform_connected  s    x&  . @\\>V\\%5%5g%>  <<6>> /228<6?"
	C%))(..9E%%1 --f55((4 0088    		s   ?C< C< <	DDc                 V    | j                   j                  |      }|r|j                  S y)z$Get the home channel for a platform.N)rh   r   r   )r   r   r  s      r    get_home_channelzGatewayConfig.get_home_channel  s(    ##H-&&&r"   Nsession_typec                     |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   r#  s      r    get_reset_policyzGatewayConfig.get_reset_policy
  sT     D$:$::))(33 LD,>,>>%%l33(((r"   c                    | j                   j                         D ci c]   \  }}|j                  |j                         " c}}| j                  j                         | j
                  j                         D ci c]  \  }}||j                          c}}| j                  j                         D ci c]   \  }}|j                  |j                         " c}}| j                  | j                  t        | j                        | j                  | j                  | j                  | j                  | j                  | j                   j                         | j"                  dS c c}}w c c}}w c c}}w )Nrh   r  r  r  r  r	  r  r  r  r  r  r  r  r  )rh   r  r   r   r  r  r  r  r	  r   r  r  r  r  r  r  r  r  )r   pckvs        r    r   zGatewayConfig.to_dict  s3    261E1E1G)-A$ %)$=$=$E$E$G+/+=+=+C+C+E#'1a199; 261G1G1M1M1O")-A$" #11"11 1 12 $ 5 5++'+'C'C(,(E(E(,(E(E//1*.*I*I)
 	
"s   %E'<E-
7%E3r   c                 v   i }|j                  di       j                         D ])  \  }}	 t        |      }t        j	                  |      ||<   + i }|j                  di       j                         D ]  \  }}t        j	                  |      ||<    i }	|j                  di       j                         D ])  \  }}	 t        |      }t        j	                  |      |	|<   + t               }
d|v rt        j	                  |d         }
t               dz  }d|v rt        |d         }|j                  di       }t        |t              si }|j                  d      }|Bt        |j                  d	      t              r!|j                  d	i       j                  d
      nd }|j                  d      }|j                  d      }t        |j                  d      d      }	 t        |j                  dd            }t        |d      } | ||
||	|j                  dddg      ||t        |j                  d      d      t        |d      t        |d      t        |d      |t         j	                  |j                  di             |      S # t
        $ r Y mw xY w# t
        $ r Y w xY w# t        t
        f$ r d}Y w xY w)Nrh   r  r  r  r  r  r	  r  sttr   r  r  r  r.   r  r  r   r  r  r  r  TFr  r'  )r   r  r:   r   r   r&   r   r   r   r   r   r3   r+   maxr%   r!   r   )rc   r   rh   platform_nameplatform_datar   r  	type_namepolicy_datar  default_policyr  r	  r  r  r  r  r  s                     r    r   zGatewayConfig.from_dict6  s   	,0HH[",E,K,K,M 	(M=#M2&4&>&>}&M	(#	 &*hh&C&I&I&K 	Q"I{'9'C'CK'PM)$	Q *.((3F*K*Q*Q*S 	&M;#M2.@.J.J;.W!(+	 ,-!T)/99$?U:VWN&(:5T!^ 45L"2B7.$/Nhh}-@J488TY?\`@a$((5"-11)<gkK"&((+D"E#'88,F#G #FHH/0$
 
	,),TXX6RTV-W)X&),-G)K& !/'/88$4vx6HI)%)$((3E*FM$[$7$01H$$O%12JE%R%=%//b0IJ'A
 	
Y    : :& 	,)+&	,s5   #J:#J'J$ 	JJ	J! J!$J87J8c                     |rZ| j                   j                  |      }|r=d|j                  v r/t        |j                  j                  d      | j                        S | j                  S )z=Return the effective unauthorized-DM behavior for a platform.r  )rh   r   r   r3   r  r   r   platform_cfgs      r    get_unauthorized_dm_behaviorz*GatewayConfig.get_unauthorized_dm_behaviorz  sc    >>--h7L :l>P>P P: &&**+EF11  ,,,r"   c                     |rP| j                   j                  |      }|r3d|j                  v r%t        |j                  j                  d      d      S y)z9Return the effective notice-delivery mode for a platform.notice_deliveryr5   )rh   r   r   r7   r5  s      r    get_notice_deliveryz!GatewayConfig.get_notice_delivery  sT    >>--h7L 1\5G5G G1 &&**+<=  r"   )NNr   )+rt   ru   rv   rw   r   r   rh   r   r:   r   r   r   r  r  r   r  r  r   r	  r	   r  r   r  r   r  r  r  r  r   r  r  r+   r  r  r   r   r"  r%  r   r   r   r7  r:  r   r"   r    r  r    s    16d0KItHn,-K 05EW/X,X383NM4//0N<ARV<WtH&889W !&6P QNDIQ &+4%@NDcN@ /UVL$V "d! K %)T(%*d* %+c* "'!GIG ')(h  x    TX  D h{6K  (,&*)8$) sm) 
	)(
c3h 
0 A
T#s(^ A
 A
 A
F	-Xh5G 	-SV 	-	HX,> 	# 	r"   r  c                  f2   t               } i }| dz  }|j                         rG	 t        |dd      5 }t        j                  |      xs i }ddd       t
        j                  d|       	 ddl	}| d	z  }|j                         rt        |d      5 }|j                  |      xs i }ddd       j                  d
      }|rt        |t              r||d<   |j                  d      }	|	?t        |	t              r|	|d<   n)t
        j                  dt        |	      j                         |j                  d      }
t        |
t              r|
|d<   d|v r|d   |d<   d|v r|d   |d<   |j                  d      }t        |t              r||d<   d|v r|d   |d<   d|v r|d   |d<   d|v rt!        |j                  d      d      |d<   |j                  d      }|j#                  di       }t        |t              si }||d<   t        |t              r|j%                         D ]  \  }}t        |t              s|j                  |i       }t        |t              si }i |j                  di       |j                  di       }|t&        j(                  j*                  k(  r	d|v rd|d<   i ||}|r||d<   |||<    ||d<   t&        D ]W  }|t&        j,                  k(  r|j                  |j*                        }t        |t              sDi }d|v r.t!        |j                  d      |j                  dd            |d<   d|v rt/        |j                  d      d      |d<   d|v r|d   |d<   d|v r|d   |d<   d|v r|d   |d<   d |v r|d    |d <   d!|v r|d!   |d!<   d"|v r|d"   |d"<   d#|v r|d#   |d#<   d$|v r|d$   |d$<   d%|v r|d%   |d%<   d&|v r|d&   |d&<   d'|v r|d'   |d'<   d(|v r|d(   |d(<   d)|v r|d)   |d)<   |t&        j0                  t&        j(                  hv rd*|v r|d*   |d*<   d+|v rK|d+   }t        |t              r1|j%                         D ci c]  \  }}t3        |      | c}}|d+<   n||d+<   d|v }|s|s|j#                  |j*                  i       }t        |t              si }|||j*                  <   |r|d   |d<   |j#                  di       }t        |t              si }||d<   |t&        j(                  k(  r|rd|d<   |j5                  |       Z |j                  d,i       }t        |t              rd|v rBt7        j8                  d-      s-t3        |d         j;                         t6        j<                  d-<   d.|v rBt7        j8                  d/      s-t3        |d.         j;                         t6        j<                  d/<   d0|v rBt7        j8                  d1      s-t3        |d0         j;                         t6        j<                  d1<   |j                  d       }|Yt7        j8                  d2      sDt        |t>              rd3jA                  d4 |D              }t3        |      t6        j<                  d2<   d5|v rBt7        j8                  d6      s-t3        |d5         j;                         t6        j<                  d6<   |j                  d7      }|Yt7        j8                  d8      sDt        |t>              rd3jA                  d9 |D              }t3        |      t6        j<                  d8<   |j                  d:i       }t        |t              rd|v rBt7        j8                  d;      s-t3        |d         j;                         t6        j<                  d;<   |j                  d       }|Yt7        j8                  d<      sDt        |t>              rd3jA                  d= |D              }t3        |      t6        j<                  d<<   d>|v rBt7        j8                  d?      s-t3        |d>         j;                         t6        j<                  d?<   d5|v rBt7        j8                  d@      s-t3        |d5         j;                         t6        j<                  d@<   |j                  dA      } | Yt7        j8                  dB      sDt        | t>              rd3jA                  dC | D              } t3        |       t6        j<                  dB<   |j                  d7      }|Yt7        j8                  dD      sDt        |t>              rd3jA                  dE |D              }t3        |      t6        j<                  dD<   |j                  dF      }!|!Yt7        j8                  dG      sDt        |!t>              rd3jA                  dH |!D              }!t3        |!      t6        j<                  dG<   |j                  dI      }"t        |"t              rRdJD ]M  \  }#}$|#|"v st7        j8                  |$      r!t3        |"|#         j;                         t6        j<                  |$<   O t        |j                  d      t              r|j                  d      ni }%dK|v r|dK   n|%j                  dK      }&|&Gt7        j8                  dL      s2|&dMu rdNnt3        |&      j;                         }'|'t6        j<                  dL<   |j                  d      }(|(g|j                  dO      xs i })d|)vrN|j#                  t&        jB                  j*                  i       }*|*j#                  di       }+|+j#                  d|(       |j                  dOi       },t        |,t              r)|,j                  d|j                  d            }-|-?t7        j8                  dP      s*t3        |-      j;                         t6        j<                  dP<   d!|,v r>t7        j8                  dQ      s)t        jD                  |,d!         t6        j<                  dQ<   dR|,v rBt7        j8                  dS      s-t3        |,dR         j;                         t6        j<                  dS<   |,j                  dT      }|Yt7        j8                  dU      sDt        |t>              rd3jA                  dV |D              }t3        |      t6        j<                  dU<   |,j                  dW      }|Yt7        j8                  dX      sDt        |t>              rd3jA                  dY |D              }t3        |      t6        j<                  dX<   |,j                  dZ      }.|.Yt7        j8                  d[      sDt        |.t>              rd3jA                  d\ |.D              }.t3        |.      t6        j<                  d[<   d5|,v rBt7        j8                  d]      s-t3        |,d5         j;                         t6        j<                  d]<   d^|,v rBt7        j8                  d_      s-t3        |,d^         jG                         t6        j<                  d_<   t        |,j                  d      t              r|,j                  d      ni }/dK|,v r|,dK   n|/j                  dK      }0|0Gt7        j8                  d`      s2|0dMu rdNnt3        |0      j;                         }'|'t6        j<                  d`<   |,j                  d#      }1|1Yt7        j8                  da      sDt        |1t>              rd3jA                  db |1D              }1t3        |1      t6        j<                  da<   |,j                  d'      }2|2Yt7        j8                  dc      sDt        |2t>              rd3jA                  dd |2D              }2t3        |2      t6        j<                  dc<   |,j                  de      }3|3Yt7        j8                  df      sDt        |3t>              rd3jA                  dg |3D              }3t3        |3      t6        j<                  df<   dhD ]  }4|4|,v s|j#                  t&        jB                  j*                  i       }t        |t              si }||t&        jB                  j*                  <   |j#                  di       }t        |t              si }||d<   |,|4   ||4<    |j                  dii       }5t        |5t              rXd|5v rBt7        j8                  dj      s-t3        |5d         j;                         t6        j<                  dj<   d!|5v r>t7        j8                  dk      s)t        jD                  |5d!         t6        j<                  dk<   |5j                  dT      }|Yt7        j8                  dl      sDt        |t>              rd3jA                  dm |D              }t3        |      t6        j<                  dl<   d"|5v rBt7        j8                  dn      s-t3        |5d"         j;                         t6        j<                  dn<   |5j                  d#      }6|6Yt7        j8                  do      sDt        |6t>              rd3jA                  dp |6D              }6t3        |6      t6        j<                  do<   d&|5v rBt7        j8                  dq      s-t3        |5d&         j;                         t6        j<                  dq<   |5j                  d'      }7|7Yt7        j8                  dr      sDt        |7t>              rd3jA                  ds |7D              }7t3        |7      t6        j<                  dr<   |j                  dti       }8t        |8t              rd|8v rBt7        j8                  du      s-t3        |8d         j;                         t6        j<                  du<   d!|8v r>t7        j8                  dv      s)t        jD                  |8d!         t6        j<                  dv<   |8j                  dT      }|Yt7        j8                  dw      sDt        |t>              rd3jA                  dx |D              }t3        |      t6        j<                  dw<   |8j                  dW      }|Yt7        j8                  dy      sDt        |t>              rd3jA                  dz |D              }t3        |      t6        j<                  dy<   |8j                  d{      }9|9Yt7        j8                  d|      sDt        |9t>              rd3jA                  d} |9D              }9t3        |9      t6        j<                  d|<   |j                  d~i       }:t        |:t              rd|:v rBt7        j8                  d      s-t3        |:d         j;                         t6        j<                  d<   |:j                  d       }|Yt7        j8                  d      sDt        |t>              rd3jA                  d |D              }t3        |      t6        j<                  d<   |:j                  d7      }|Yt7        j8                  d      sDt        |t>              rd3jA                  d |D              }t3        |      t6        j<                  d<   |j                  di       };t        |;t              rd|;v rBt7        j8                  d      s-t3        |;d         j;                         t6        j<                  d<   |;j                  d      }|Yt7        j8                  d      sDt        |t>              rd3jA                  d |D              }t3        |      t6        j<                  d<   |;j                  d      }<|<Yt7        j8                  d      sDt        |<t>              rd3jA                  d |<D              }<t3        |<      t6        j<                  d<   d>|;v rBt7        j8                  d      s-t3        |;d>         j;                         t6        j<                  d<   d|;v rBt7        j8                  d      s-t3        |;d         j;                         t6        j<                  d<   |j                  di       }=t        |=t              rFd0|=v rBt7        j8                  d      s-t3        |=d0         j;                         t6        j<                  d<   tH        jK                  |      }>tM        |>       tO        |>       |>S # 1 sw Y   lxY w# t        $ r"}t
        j                  d||       Y d}~d}~ww xY w# 1 sw Y   KxY wc c}}w # t        $ r$}t
        j                  d| d	z  |       Y d}~d}~ww xY w)u  
    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session_resetr  r	  zIIgnoring invalid quick_commands in config.yaml (expected mapping, got %s)r-  r  r  r  r  r  r  r.   rh   r   r   T_enabled_explicitr9  r5   reply_prefixreply_in_threadrequire_mentionfree_response_channelsmention_patterns	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_promptsr?   SLACK_REQUIRE_MENTIONstrict_mentionSLACK_STRICT_MENTION
allow_botsSLACK_ALLOW_BOTSSLACK_FREE_RESPONSE_CHANNELS,c              3   2   K   | ]  }t        |        y wr   r   r   r+  s     r    r   z&load_gateway_config.<locals>.<genexpr>G       &;!s1v&;   	reactionsSLACK_REACTIONSallowed_channelsSLACK_ALLOWED_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>O       %9c!f%9rZ  r=   DISCORD_REQUIRE_MENTIONDISCORD_FREE_RESPONSE_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>Z  rY  rZ  auto_threadDISCORD_AUTO_THREADDISCORD_REACTIONSignored_channelsDISCORD_IGNORED_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>d  r`  rZ  DISCORD_ALLOWED_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>j  r`  rZ  no_thread_channelsDISCORD_NO_THREAD_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>p  rY  rZ  allow_mentions))everyoneDISCORD_ALLOW_MENTION_EVERYONE)rolesDISCORD_ALLOW_MENTION_ROLES)usersDISCORD_ALLOW_MENTION_USERS)replied_user"DISCORD_ALLOW_MENTION_REPLIED_USERr   DISCORD_REPLY_TO_MODEFr   r<   TELEGRAM_REQUIRE_MENTIONTELEGRAM_MENTION_PATTERNS
guest_modeTELEGRAM_GUEST_MODEfree_response_chatsTELEGRAM_FREE_RESPONSE_CHATSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  rY  rZ  allowed_chatsTELEGRAM_ALLOWED_CHATSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  r`  rZ  ignored_threadsTELEGRAM_IGNORED_THREADSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  s     2Sa3q62SrZ  TELEGRAM_REACTIONS	proxy_urlTELEGRAM_PROXYTELEGRAM_REPLY_TO_MODETELEGRAM_ALLOWED_USERSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  s     0OAQ0OrZ  TELEGRAM_GROUP_ALLOWED_USERSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>       6[!s1v6[rZ  group_allowed_chatsTELEGRAM_GROUP_ALLOWED_CHATSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  r  rZ  )r{  disable_link_previewsr>   WHATSAPP_REQUIRE_MENTIONWHATSAPP_MENTION_PATTERNSWHATSAPP_FREE_RESPONSE_CHATSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  rY  rZ  WHATSAPP_DM_POLICYWHATSAPP_ALLOWED_USERSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  r`  rZ  WHATSAPP_GROUP_POLICYWHATSAPP_GROUP_ALLOWED_USERSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  rY  rZ  rF   DINGTALK_REQUIRE_MENTIONDINGTALK_MENTION_PATTERNSDINGTALK_FREE_RESPONSE_CHATSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  rY  rZ  DINGTALK_ALLOWED_CHATSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  r`  rZ  allowed_usersDINGTALK_ALLOWED_USERSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>
  s     *Ca3q6*CrZ  rA   MATTERMOST_REQUIRE_MENTION!MATTERMOST_FREE_RESPONSE_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  rY  rZ  MATTERMOST_ALLOWED_CHANNELSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>  r`  rZ  rB   MATRIX_REQUIRE_MENTIONfree_response_roomsMATRIX_FREE_RESPONSE_ROOMSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>&  rY  rZ  allowed_roomsMATRIX_ALLOWED_ROOMSc              3   2   K   | ]  }t        |        y wr   rW  rX  s     r    r   z&load_gateway_config.<locals>.<genexpr>,  r`  rZ  MATRIX_AUTO_THREADdm_mention_threadsMATRIX_DM_MENTION_THREADSrJ   FEISHU_ALLOW_BOTSus   Failed to process config.yaml — falling back to .env / gateway.json values. Check %s for syntax errors. Error: %s)(r   rn   openjsonloadloggerinforb   warningyaml	safe_loadr   r   r   typert   r3   
setdefaultr  r:   r|   r   rx   r7   rz   r   updater   r   r   environr   joinry   dumpsr   r  r   _apply_env_overrides_validate_gateway_config)?_homegw_datagateway_json_pathfer  config_yaml_pathyaml_cfgsrqcstt_cfgstreaming_cfgyaml_platformsplatforms_data	plat_name
plat_blockexistingmerged_extramergedplatr6  bridgedrN  r*  r+  enabled_was_explicit	plat_datar   	slack_cfgfrcacdiscord_cfgicntcallow_mentions_cfgyaml_keyenv_key_discord_extra_discord_rtm_rtm_str_tl_require_mention_tg_section_tg_plat	_tg_extratelegram_cfg_effective_rmr  _telegram_extra_telegram_rtmr  group_allowed_usersr  _telegram_extra_keywhatsapp_cfgafgafdingtalk_cfgallowedmattermost_cfg
matrix_cfgar
feishu_cfgr  s?                                                                  r    load_gateway_configr    s:    EG .!	J'w? -1))A,,"-KKN!R
 =0""$&9 3Q>>!,23
 o.BjT*24././B~b$'02G,-NN5R)) ll5)G'4(!((H45=>W5X12)X56>?Y6Z23$LL5M-.'4$8+,45E,F()!X-.67I.J*+)X56YLL!;<723 &\\+6N$//R@Nnd3!#'5$.$/-;-A-A-C 7)Iz%j$7 -11)R@H%h5#%#_hll7B&?#_:>>RY[]C^#_L HNN$8$88Y*=T<@%8977J7F#*6w06N9-7 (6$  C&8>>)'||DJJ7!,5-=:]$(()CD$>G;G67 %41K$(():; 2G-. "\1.:>.JGN+$41=>O1PG-.$41=>O1PG-.+|;8DE]8^G45%52>?Q2RG./,.+7+DGK(</,8,FGL)%52>?Q2RG./*l:7CD[7\G34!\1.:>.JGN+%52>?Q2RG./+|;8DE]8^G450L@=IJg=hG9:H,,hnn==BZ^jBj8DE]8^G45$4&23D&EO!/48L[LaLaLc5dDAqc!fai5d 125D 12'0L'@$';*55djj"E	!)T2 "I1:N4::.'+7	+BIi(!,,Wb9!%.E).Ig&8>>).B15E-.W%GC&L !Wb1I)T*$	1"))D[:\:=iHY>Z:[:a:a:cBJJ67#y0CY9Z9<YGW=X9Y9_9_9aBJJ569,RYY?Q5R58<9P5Q5W5W5YBJJ12mm$<=?2995S+T!#t,!hh&;s&;;ADSBJJ=>)+BII>O4P47	+8N4O4U4U4WBJJ01]]#56>"))4L*M!"d+ XX%9b%99;>r7BJJ78 #,,y"5K+t,$3BIIF_<`<?L]@^<_<e<e<gBJJ89!oo&>??2995U+V!#t,!hh&;s&;;CFs8BJJ?@ K/		BW8X8;K<V8W8]8]8_BJJ45+-bii@S6T69+k:R6S6Y6Y6[BJJ23 __%78>"))4N*O!"d+ XX%9b%99=@WBJJ9: __%78>"))4N*O!"d+ XX%9b%99=@WBJJ9:!oo&:;?2995Q+R!#t,!hh&;s&;;?B3xBJJ;<
 &1__5E%F"0$7. \)' $'99"))GBT256H6R2S2Y2Y2[BJJw/\ >HX_H`bf=g!9mo4C{4RK0'++O<   +BII>U4V(4(=u3|CTCZCZC\H:BBJJ67 #+,,/@"A".&ll:6<"$K7-889J9J9P9PRTUH ( 3 3GR @I(():<OP $<<
B7L,- , 0 01BHLLQbDc d ,RYY?Y5Z=@=O=U=U=WBJJ9:%5biiHc>d>BjjVhIi>jBJJ:;</		BW8X8;L<V8W8]8]8_BJJ45"&&'<=?2995S+T!#t,!hh&;s&;;ADSBJJ=>!%%o6>"))4L*M!"d+ XX%9b%99;>r7BJJ78"."2"23D"E".ryyA[7\!/48*-((2S?2S*S=@=QBJJ9:,.ryyAU7V7:<;T7U7[7[7]BJJ34,.ryyAQ7R36|K7P3Q3W3W3YBJJ/0 @J,JZJZ[bJcei?j,"2"27";pr5D5TL1(,,_=  !,RYY?W5X(5(>uCDVD\D\D^H;CBJJ78 , 0 0 > ,RYY?W5X!-6(+0O0O(O;>};MBJJ78&2&6&67I&J#&2299Ec;d!"5t<.1hh6[GZ6[.[+ADEXAYBJJ=>&2&6&67L&M#&2299Ec;d!"5t<.1hh6[GZ6[.[+ADEXAYBJJ=>+R 
W'*l:$2$=$=h>O>O>U>UWY$Z	))T:(*IFON8+<+<+B+BC ) 4 4Wb A)%6$&E16Ig.5ABU5V12
W $<<
B7L,-$4RYYGa=b=@N_A`=a=g=g=iBJJ9:%5biiHc>d>BjjVhIi>jBJJ:;"&&'<=?2995S+T!#t,!hh&;s&;;ADSBJJ=>,.ryyAU7V7:<;T7U7[7[7]BJJ34!%%l3>"))4L*M!"d+ XX%9b%99;>r7BJJ78!\1"))D[:\:=l>>Z:[:a:a:cBJJ67"&&'9:?2995S+T!#t,!hh&;s&;;ADSBJJ=> $<<
B7L,-$4RYYGa=b=@N_A`=a=g=g=iBJJ9:%5biiHc>d>BjjVhIi>jBJJ:;"&&'<=?2995S+T!#t,!hh&;s&;;ADSBJJ=>!%%o6>"))4L*M!"d+ XX%9b%99;>r7BJJ78&**?;&ryy9Q/R!'40"%((*C7*C"C;>w<BJJ78 &\\,;N.$/$6ryyIe?f?B>RcCd?e?k?k?mBJJ;<$(()AB?2995X+Y!#t,!hh&;s&;;FI#hBJJBC#''(:;>"))4Q*R!"d+ XX%9b%99@CBBJJ<= "h3J*d+$
2299E];^;>zJ[?\;];c;c;eBJJ78 nn%:;?2995Q+R!#t,!hh&;s&;;?B3xBJJ;<^^O4>"))4J*K!"d+ XX%9b%999<RBJJ56 J.ryyAU7V7::m;T7U7[7[7]BJJ34':5biiHc>d>A*MaBb>c>i>i>kBJJ:; "h3J*d+:-bii@S6T69*\:R6S6Y6Y6[BJJ23 $$W-F   V$MM- -  	JNN24EqII	J3 3l 6ed  
4M!		
 	

s   Ac Ab5Ac *'Ad Ac0'N0Ad Ac=-VAd Ad W=Ad @a,Ad b5Ab?b:Ac c	Ac-cAc(c(Ac-c0Ac:c5Ad d	Ad0dAd+d+Ad0r  c                    | j                   }d|j                  cxk  rdk  s)n t        j                  d|j                         d|_        |j                  |j                  dk  r't        j                  d|j                         d|_        t
        j                  dt
        j                  d	t
        j                  d
t
        j                  dt
        j                  dt
        j                  di}| j                  j                         D ]o  \  }}|j                  s|j                  |      }|s'|j                   4|j                   j#                         rOt        j                  d|j$                  |       q 	 ddlm} || j                  j                         D ]  \  }}|j                  s|j                  |      }|s'|j                   }|s6|j#                         sG ||d      rRt        j-                  d|j$                  ||j#                         dd dz          d|_         yy# t*        $ r d}Y w xY w)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   r  r  r   r:   ry   rz   r|   r~   r   r   rh   r  r   r   r   r   r   hermes_cli.authr  ImportErrorerror)r  policy_token_env_namesr   pconfigenv_namer  r   s           r    r  r  L  s    ((F%2%A6>>	
 "f&9&9Q&>M	
 #
 	/-)/. $--335 	'#''11'--:M:M:ONN;	!5 $!'!1!1!7!7!9 	(Hg??'++H5HMME/@ST/U7 NNHekkmBQ.?%.G	 #(	( %  ! !s   <H1 1H?>H?c                 &Q   t        j                  d      }|rt        j                  | j                  vr%t               | j                  t        j                  <   d| j                  t        j                     _        || j                  t        j                     _        t        j                  dd      j                         }|dv rct        j                  | j                  vr%t               | j                  t        j                  <   || j                  t        j                     _	        t        j                  dd      }|rt        j                  | j                  vr%t               | j                  t        j                  <   |j                  d      D cg c]#  }|j                         s|j                         % c}| j                  t        j                     j                  d<   t        j                  d	      }|rt        j                  | j                  v rht        t        j                  |t        j                  d
d      t        j                  d      xs 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      }|rt        j                  | j                  v rht        t        j                  |t        j                  dd      t        j                  d      xs d      | j                  t        j                     _        t        j                  dd      j                         }|dv rct        j                  | j                  vr%t               | j                  t        j                  <   || j                  t        j                     _	        t        j                  dd      j                         dv }	t        j                  dd      j                         dv }
t        j                   | j                  v r1| j                  t        j                      }|
rd|_        n3|	r1d|_        n)|	r't        d      | j                  t        j                   <   t        j                  d      }|rt        j                   | j                  v rht        t        j                   |t        j                  dd      t        j                  d      xs d      | j                  t        j                      _        t        j                  d      }|rt        j"                  | j                  vrHt               | j                  t        j"                  <   d| j                  t        j"                     _        nW| j                  t        j"                     }t%        |j                  j'                  dd            }|j                  s	|sd|_        || j                  t        j"                     _        t        j                  d      }|rt        j"                  | j                  v rht        t        j"                  |t        j                  dd      t        j                  d       xs d      | j                  t        j"                     _        t        j                  d!      }t        j                  d"      }|r|rt        j(                  | j                  vr%t               | j                  t        j(                  <   d| j                  t        j(                     _        | j                  t        j(                     j                  j+                  ||t        j                  d#d$      j                         dv d%       t        j                  d&      }|rt        j(                  | j                  v rht        t        j(                  |t        j                  d'd      t        j                  d(      xs d      | j                  t        j(                     _        t        j                  d)      }|rt        j                  d*d      }|st,        j/                  d+       t        j0                  | j                  vr%t               | j                  t        j0                  <   d| j                  t        j0                     _        || j                  t        j0                     _        || j                  t        j0                     j                  d,<   t        j                  d-      }|rt        j0                  | j                  v rht        t        j0                  |t        j                  d.d      t        j                  d/      xs d      | j                  t        j0                     _        t        j                  d0      }t        j                  d1d      }|st        j                  d2      r|st,        j/                  d3       t        j2                  | j                  vr%t               | j                  t        j2                  <   d| j                  t        j2                     _        |r"|| j                  t        j2                     _        || j                  t        j2                     j                  d4<   t        j                  d5d      }|r*|| j                  t        j2                     j                  d6<   t        j                  d2d      }|r*|| j                  t        j2                     j                  d7<   t        j                  d8d      j                         dv }|| j                  t        j2                     j                  d9<   t        j                  d:d      }|r*|| j                  t        j2                     j                  d;<   t        j                  d<      }|rt        j2                  | j                  v rht        t        j2                  |t        j                  d=d      t        j                  d>      xs d      | j                  t        j2                     _        t        j                  d?      }|rt        j4                  | j                  vr%t               | j                  t        j4                  <   d| j                  t        j4                     _        || j                  t        j4                     _        t        j                  d@      }|r*|| j                  t        j4                     j                  d,<   t        j                  dA      } t        j                  dB      }!t        j                  dC      }"t        j                  dD      }#t7        | |!|"|#g      rt        j8                  | j                  vr%t               | j                  t        j8                  <   d| j                  t        j8                     _        | j                  t        j8                     j                  j+                  | |"|#dE       t        j                  dF      }$|$rt        j8                  | j                  v rht        t        j8                  |$t        j                  dGd      t        j                  dH      xs d      | j                  t        j8                     _        t        j                  dI      }%|%rt        j:                  | j                  vr%t               | j                  t        j:                  <   d| j                  t        j:                     _        t        j                  dJd      | j                  t        j:                     _        t        j                  dK      }&|&rt        j:                  | j                  v rht        t        j:                  |&t        j                  dLd      t        j                  dM      xs d      | j                  t        j:                     _        t        j                  dNd      j                         dv }'t        j                  dOd      }(t        j                  dPd      })t        j                  dQ      }*t        j                  dR      }+|'s|(rt        j>                  | j                  vr%t               | j                  t        j>                  <   d| j                  t        j>                     _        |(r*|(| j                  t        j>                     j                  dS<   |)ri|)j                  d      D ,cg c]#  },|,j                         s|,j                         % }-},|-r*|-| j                  t        j>                     j                  dT<   |*r4	 tA        |*      | j                  t        j>                     j                  dU<   |+r*|+| j                  t        j>                     j                  dV<   t        j                  dWd      }.|.r*|.| j                  t        j>                     j                  dX<   t        j                  dYd      j                         dv }/t        j                  dZ      }0t        j                  d[d      }1|/rt        jD                  | j                  vr%t               | j                  t        jD                  <   d| j                  t        jD                     _        |0r4	 tA        |0      | j                  t        jD                     j                  dU<   |1r*|1| j                  t        jD                     j                  d\<   t        j                  d]d      j                         dv }2t        j                  d^      }3t        j                  d_d      }4t        j                  d`d      }5t        j                  dad      }6|2s%t        jF                  | j                  v s	|3s|4s|5s|6rt        jF                  | j                  vr%t               | j                  t        jF                  <   |2r"d| j                  t        jF                     _        |3r4	 tA        |3      | j                  t        jF                     j                  dU<   |4r*|4| j                  t        jF                     j                  db<   |5rh|5j                  d      D 7cg c]"  }7|7j                         r|7j                         $ }8}7|8r*|8| j                  t        jF                     j                  dc<   |6rh|6j                  d      D 9cg c]"  }9|9j                         r|9j                         $ }:}9|:r*|:| j                  t        jF                     j                  dd<   t        j                  de      };t        j                  df      }<|;r|<rt        jH                  | j                  vr%t               | j                  t        jH                  <   d| j                  t        jH                     _        | j                  t        jH                     j                  j+                  |;|<dg       t        j                  dh      }=|=rht        t        jH                  |=t        j                  did      t        j                  dj      xs d      | j                  t        jH                     _        t        j                  dk      }>t        j                  dl      }?|>r|?rt        jJ                  | j                  vr%t               | j                  t        jJ                  <   d| j                  t        jJ                     _        | j                  t        jJ                     j                  j+                  |>|?t        j                  dmdn      t        j                  dodp      dq       t        j                  drd      }@|@r*@| j                  t        jJ                     j                  ds<   t        j                  dtd      }A|Ar*A| j                  t        jJ                     j                  du<   t        j                  dv      }B|Brht        t        jJ                  Bt        j                  dwd      t        j                  dx      xs d      | j                  t        jJ                     _        t        j                  dy      }Ct        j                  dz      }D|Cr`Dr]t        jL                  | j                  vr%t               | j                  t        jL                  <   d| j                  t        jL                     _        | j                  t        jL                     j                  j+                  CDd{       t        j                  d|d      }E|Er*E| j                  t        jL                     j                  d}<   t        j                  d~      }F|Frht        t        jL                  Ft        j                  dd      t        j                  d      xs d      | j                  t        jL                     _        t        j                  d      }Gt        j                  d      }H|GrHrt        jN                  | j                  vr%t               | j                  t        jN                  <   d| j                  t        jN                     _        | j                  t        jN                     j                  j+                  GHt        j                  dd      t        j                  dd      t        j                  dd      t        j                  dd      tA        t        j                  dd            d       t        j                  d      }It        j                  d      }J|IsJrt        jP                  | j                  vr%t               | j                  t        jP                  <   d| j                  t        jP                     _        Ir"I| j                  t        jP                     _        | j                  t        jP                     j                  }KJrJKd<   t        j                  dd      j                         }L|LrLjS                  d      Kd<   t        j                  dd      j                         }M|MrMjS                  d      Kd<   t        j                  dd      j                         j                         }N|NrNKd<   t        j                  dd      j                         j                         }O|OrOKd<   t        j                  dd      j                         }P|PrPKd<   t        j                  dd      j                         }Q|QrQKd<   t        j                  dd      j                         }R|RrRKd<   t        j                  dd      j                         }S|Srht        t        jP                  St        j                  dd      t        j                  d      xs d      | j                  t        jP                     _        t        j                  d      }Tt        j                  d      }U|TrUrt        jT                  | j                  vr%t               | j                  t        jT                  <   d| j                  t        jT                     _        | j                  t        jT                     j                  j+                  TjS                  d      Ut        j                  dd      tA        t        j                  dd            t        j                  dd      t        j                  dd$      j                         dv d       t        j                  d      }V|Vrt        jT                  | j                  v rht        t        jT                  Vt        j                  dd      t        j                  d      xs d      | j                  t        jT                     _        t        j                  d      }Wt        j                  d      }X|WsXr t        jV                  | j                  vr%t               | j                  t        jV                  <   d| j                  t        jV                     _        | j                  t        jV                     j                  }KWrWKd<   XrXKd<   t        j                  dd      j                         }Y|YrYKd<   t        j                  dd      j                         }Z|ZrZKd<   t        j                  dd      j                         }[d}\|[sRt        j                  dd      j                         }]|]r,]}[d}\tY        jZ                  t\              j/                  d       [rt        t        jV                  [t        j                  d      xs t        j                  \d      t        j                  d      xs t        j                  d      xs d      | j                  t        jV                     _        t        j                  d      xs t        j                  d      }^t        j                  d      }_|^r._r+t        j^                  | j                  vr%t               | j                  t        j^                  <   d| j                  t        j^                     _        | j                  t        j^                     j                  }K^|Kd<   _|Kd<   t        j                  d      }`|`r`Kd<   t        j                  d      }a|araKd<   t        j                  d      }b|brbKd<   t        j                  dë      }c|crcKd<   t        j                  dū      }d|drht        t        j^                  dt        j                  dd      t        j                  dǫ      xs d      | j                  t        j^                     _        t        j                  dȫ      }e|er!ej                         j                         Kd<   t        j                  dɫ      }f|frfKd<   t        j                  d˫      }g|gr!gj                         j                         Kd<   t        j                  d̫      }h|hrhKd<   t        j                  dͫ      }i|ir	 tA        i      | j`                  _1        t        j                  dΫ      }j|jr	 tA        j      | j`                  _2        	 ddl3m4}k  |k        ddl5m6}l |ljo                         D ][  }m	 mjq                         s	 t        mjv                        }o|o| j                  vrt               | j                  o<   d| j                  o   _        mjx                  r	 mjy                         }pt{        pt|              spspj'                  dd      }q| j                  o   j                  j+                  |p       t{        |qt|              sqj                  dի      st        ot        qd         t        |qj                  d֫      xs d      qj                  d׫      rt        qd         nd      | j                  o   _        ^ yc c}w c c},w # tB        $ r Y /w xY w# tB        $ r Y w xY w# tB        $ r Y w xY wc c}7w c c}9w # tB        $ r Y w xY w# tB        $ r Y w xY w# tr        $ r,}nt,        ju                  dmjv                  n       Y d}n~nd}n~nww xY w# tr        $ r.}nt,        ju                  dmjv                  n       d}pY d}n~nd}n~nww xY w# tr        $ r }nt,        ju                  dn       Y d}n~nyd}n~nww xY w)z/Apply environment variable overrides to config.r  Tr   >   allr   r   TELEGRAM_FALLBACK_IPSrU  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_IDrx  WHATSAPP_ENABLED>   r   r   r   >   r   r   r   F)r   WHATSAPP_HOME_CHANNELWHATSAPP_HOME_CHANNEL_NAMEWHATSAPP_HOME_CHANNEL_THREAD_IDr   r?  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 missingurl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_ENCRYPTION
encryption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)r   	imap_host	smtp_hostEMAIL_HOME_ADDRESSEMAIL_HOME_ADDRESS_NAMEEMAIL_HOME_ADDRESS_THREAD_IDr   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_HOSTkey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_CIDRSclient_stateaccepted_resourcesallowed_source_cidrsr   r   )r   r   DINGTALK_HOME_CHANNELDINGTALK_HOME_CHANNEL_NAMEDINGTALK_HOME_CHANNEL_THREAD_IDFEISHU_APP_IDFEISHU_APP_SECRETFEISHU_DOMAINrJ   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)r   rV  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_PORT8645)r   corp_secretagent_idr   encoding_aes_keyrP  rO  r  WEIXIN_ACCOUNT_IDr   WEIXIN_BASE_URL/base_urlWEIXIN_CDN_BASE_URLcdn_base_urlWEIXIN_DM_POLICYrE  WEIXIN_GROUP_POLICYrI  WEIXIN_ALLOWED_USERSrF  WEIXIN_GROUP_ALLOWED_USERSrJ  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   webhook_hostwebhook_portwebhook_pathsend_read_receiptsBLUEBUBBLES_HOME_CHANNELBLUEBUBBLES_HOME_CHANNEL_NAME"BLUEBUBBLES_HOME_CHANNEL_THREAD_ID	QQ_APP_IDQQ_CLIENT_SECRETr   r   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_SECRETr   YUANBAO_BOT_IDr   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   )discover_pluginsrU   zcheck_fn for %s raised: %sz#env_enablement_fn for %s raised: %sr   r   rp   r   z&Plugin platform enable pass failed: %s)Ar   r   r:   ry   rh   r   r   r   r   r   splitr   r   r   r   rz   r{   r|   r   popr}   r  r  r  r~   r   r   r  r   r   r   r   r+   r&   r   r   r   r   r   r   r   rstripr   r   logging	getLoggerrt   r   r  r   r   hermes_cli.pluginsr  r`   rV   plugin_entriescheck_fnrb   debugrp   env_enablement_fnr   r   r   r   )rr  telegram_tokentelegram_reply_modetelegram_fallback_ipsiptelegram_homediscord_tokendiscord_homediscord_reply_modewhatsapp_enabledwhatsapp_disabled_explicitlywa_cfgwhatsapp_homeslack_tokenslack_configr  
slack_home
signal_urlsignal_accountsignal_homemattermost_tokenmattermost_urlmattermost_homematrix_tokenmatrix_homeservermatrix_usermatrix_password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origin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resource	resourcescidr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_idr   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_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_hourr  rV   r   r  r   seedhomesr                                                                                                                     r    r  r    s    YY34NF$4$442@2BFX../6:**+34B**+1 ))$<bAGGI55F$4$442@2BFX../<O**+9II&=rBF$4$442@2BFX../!6!<!<S!AE
RXXZBHHJE
**+11.A II56M**f.>.>>;F&&!7@ii ABJd	<
**+8 II12M6#3#331?1AFX--.59))*23@))*09934L((F,<,<<:E%% 6?ii @AIT	;
))*7 #:B?EEG446#3#331?1AFX--.;M))*8 yy!3R8>>@DXX#%99-?#D#J#J#LPd#d F,,,!!("3"34'"FN!FN	.<T.J**+II56M**f.>.>>;F&&!7@ii ABJd	<
**+8 ))-.K>>!1!11/=/?FX^^,7;FX^^,4!++HNN;L#'(:(:(>(>?RTY(Z#[ ''0D (,$ 2=(./0Jhnn(8(888C^^4b9ii >?G4	9
(5 ,-JYY/0Nn??&"2"220>0@FX__-48)1)//66"% ii(?HNNPThh8
 	
 ))12Kx&*:*::9D__5v>ii ?@HD	:
)6 yy!34#3R8NNOPf&6&664B4DFX0018<,,-56F,,-3=K,,-33E:ii 9:O8..&2B2BB=H((#96Bii CDL	>
,,-: 9923L		"5r:ryy!23 NNef??&"2"220>0@FX__-48)16BFX__-3@Q)//=ii 0"5ALFX__-33I>))$5r:BQFX__-33J?ii 3R8>>@DXX@K)//=99%7<CSFX__-33K@))./Kx&*:*::9D__2F;ii <=E	:
)6 <(J!!)9)997E7GFX334;?//089C//0699Z(DLFX334::5A ?+J		*+I,-J,-J
J	:z:;>>!1!11/=/?FX^^,37(0(..55!##7
 	
 /0Jhnn(8(888C^^4f=ii >?G4	9
(5 /0J<<v///-;-=FX\\*15&.13;NPR1S&.yy+,HHLLF$4$446A\\2F;ii <=E	7
&3 #7<BBDH\\YY/4N ii(A2Fii 12Oii 12O^f&6&664B4DFX0018<,,-5AOFX00177>"4K4Q4QRU4Vi&Z`ZfZfZhv||~iGiNU  !4!45;;NKFI/FZ  !4!45;;FC BQFX00177? "		*A2 F H]FX00177E ii 126<<>BVVO99^,LYY/4N6#3#331?1AFX--.59))*2CF|CT  !1!1288@ AOFX--.44X> !ii(A2FLLN S 
 99%;<#%99-KR#P  "		*NPR S$&II.%! 	 ##v'7'77'$(##6+;+;;9G9IFX556"AEFX556>KN(L  !9!9:@@H
 (, X556<<^L % !: ? ? D>>#  I 
     !9!9:@@( ) :??D::< 

E 
     !9!9:@@*
 #78YY'?@4F$4$442@2BFX../6:**+3**+1188+3:
 	 		"9:?J!**%YY;VD))$EFN$	@FX../< IIo.M		"56*??&"2"220>0@FX__-48)1)//66#+ii:!yy)A;O	8
 	  YY';R@EWFX__-33MB$&II.I2$N!$LeFX__-334HIii 56=H!#YY96B))$CDL	>FX__-: 99^,L99^,L>>!1!11/=/?FX^^,37(0(..55""7
 	 yy!6;FRFX^^,22?CYY34
<G!"YY8&A))$BCKt	=FX^^,9  YY'?@!#+G!H"<""&*:*::8F8HFX445<@001900177>>-5		";R@YY5r: "		*KR PII3Y?		"7@A@
 	 99^,L		"56(??&"2"220>0@FX__-48)16BFX__-3  177"3E,))$5r:@@B / 6 6s ;E* ii(=rBHHJ$7$>$>s$CE.!99%7<BBDJJL!1E+ ii(=rBHHJPPR$7E.!!yy)?DJJL"6E,%'YY/KR%P%V%V%X"%(BE$%!#+Lb!Q!W!W!Y!0FE,-ii 5r:@@B=H!#YY96B))$CDL	>FX__-:  YY'?@99%;<"6v'7'775C5EFX1129=--.6--.44;;077<,II&@+N		*Df MNII&@BXY"$)),Lf"U"["["]au"u=
 	 yy!;<H00F4D4DD>I))$:FCii DEM	?
--.; 		+&Iyy!34$>>!1!11/=/?FX^^,37(0  066'E(O%5E/"99%7<BBD"2E,99%=rBHHJ(8E$%))0"5;;=4))$5r:@@BK%#9 !!(+33J <G!YY89`RYYGWY_=`II<= yy!<=	=FX^^,9 YY/0PBII>O4PN#78,6#3#331?1AFX--.59))*2  !1!1288(h0l#34,E(O#34,E(OYY';<"4E,II&9:!2E+yy!78>I!))$YY:FC))$DEM	?FX--.; II&9:!2!8!8!:!@!@!BE+ "		*A B %:E/"!yy)?@$8$>$>$@$F$F$HE.!#%99-G#H #(@E$% 9934L	7:<7HF''4 /0J	25j/F''/*B7?&557 $	E~~' (
  

+Hv///-;-=  *15FX&.&&2  224D dD)d  88ND9D$$X.44;;DA!$-$((92EBM%-$'Y$8!$TXXf%5%?!@ $(88K#8 !$D$5 6%)	C((2?7$	}E
~ j  &  D  |  		  		$  95::qI !  LL=uzz1  D	 ,  B=qAABsY  B^*B^G,B^HB^I3B^ N3B^+ T
3B^; U>'B_W('B_WB_ W3B_% X'Ba' X6B_5YABa' Z$B`-Z4Ba' [Ba' [A
Ba' \Ba' \%A+Ba' ^	B^(^'B^(^+	B^8^7B^8^;	B__B__	B_"_!B_"_%	B_2_1B_2_5	B`*_>!B`%`Ba' `%B`*`*Ba' `-	Ba$`6#BaaBa' aBa$a$Ba' a'	Bba0BbbBb)T)r.   )r5   )r  r  r   N)Erw   r  r   r  pathlibr   dataclassesr   r   typingr   r   r   r	   r
   enumr   hermes_cli.configr   utilsr   r  rt   r  r   r!   r$   r(   r+   r,   r   r3   r7   r8   ri   r   r:   	frozenset__members__values_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  r  r  r   r"   r    <module>r9     s    	   ( 6 6  - !			8	$3 3d 3d 3 u  s S S s S c c C s  26 # 5^t ^F %$Th6J6J6Q6Q6S$TT  
 
 
D '
 '
 '
T 6
 6
 6
| *-  ,*, "C , & # & 3
 3
 3
| OO  'OO@NN>LLC)&.OO>NN=    NN     3R d8X~6F6L-M#MN @ e e ePx] xvB(Jz	B z	B4 z	Br"   