+
    °Š·jx*  ã                   óì   € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
HtHtHtHt ^xtRtRt0 Rmt]P&                  ! R4      tR tR tR tR	 t ! R
 R4      t ! R R4      t]! 4       tR# )u™  Restricted shell for the MCP bridge: a virtual MCP server with one tool, `run`, that runs
a command line typed in the page â€” but only if its program is on the config's allowlist,
and only after the user approves it in the terminal where serve.py runs.

    {"id": "shell", "name": "å�—é™� shell",
     "shell": {"allow": ["ls", "cat", "git"], "cwd": ".", "timeout_s": 30}}

The command line is split like a shell would split words (shlex), then run directly: no
shell ever sees it, so pipes, redirects, globs, variables and substitutions are passed to
the program as literal text. The program must be the very file an allowlist entry resolves
to on PATH (a same-named file elsewhere, e.g. ./ls, doesn't count). The allowlist says which
programs, not which arguments â€” `git` still runs hooks and `find` still has -exec â€” so the
terminal confirmation, on by default, is the real guard; "confirm": false turns it off.
N)ÚDEFAULT_TIMEOUTÚPROTOCOL_VERSIONSÚ
is_requestÚrun_programÚ
tool_errori,  iÐ  u   [ --ÂŸØœâ€Žâ€�â€ª-â€®â�¦-â�©]c           
     ó´  € \        V\        4      '       d   \        V4      \        ,
          '       d/   \	        RV : RRP                  \        \        4      4       24      hVP                  R4      p\        V\        4      '       dC   V'       d;   \        ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      '       g   \	        RV : R24      hR	V9   d.   \        VR	,          \        4      '       g   \	        RV : R
24      hRV9   dD   \        VR,          \        \        34      '       d   VR,          ^ 8”  g   \	        RV : R24      hR# R# )zCRaise ValueError unless `shell` is a valid restricted-shell config.zserver z: "shell" takes only z, Úallowc              3   óž   "  € T FC  p\        V\        4      ;'       d'    T;'       d    \        P                  ! R V4      '       * x € KE  	  R# 5i)z\sN)Ú
isinstanceÚstrÚreÚsearch)Ú.0Úps   & Ú)/work/data/stt/webtt/scripts/mcp_shell.pyÚ	<genexpr>Úvalidate.<locals>.<genexpr>(   s@   é € Ð5zÑtyÐop´jÀÄCÓ6H×6jÐ6jÈQ×6jÐ6jÔWY×W`ÒW`ÐafÐhiÓWjÔSjÔ6jÓtyùs   ‚Až	A¨%AFTzB: "shell.allow" must be a non-empty list of program names or pathsÚconfirmz': "shell.confirm" must be true or falseÚ	timeout_sz-: "shell.timeout_s" must be a positive numberN)r
   ÚdictÚsetÚKEYSÚ
ValueErrorÚjoinÚsortedÚgetÚlistÚallÚboolÚintÚfloat)ÚsidÚshellr   s   && r   Úvalidater#   #   s  € ä�eœT×"Ò"¤c¨%£j´4×&7Ô&7Ü˜7 3¡'Ð)>¸t¿y¹yÌÔPTËÓ?VÐ>WÐXÓYÐYØ�I‰I�gÓ€EÜ�uœd×#Ò#¯·#³#Ñ5zÑtyÓ5z·#·#²#Ñ5zÑtyÓ5z×2zÒ2zÜ˜7 3¡'Ð)kÐlÓmÐmØ�EÔ¤*¨U°9Õ-=¼t×"DÒ"DÜ˜7 3¡'Ð)PÐQÓRÐRØ�eÔ¤Z°°kÕ0BÄSÌ%ÀL×%QÒ%QÐV[Ð\gÕVhÐklÔVlÜ˜7 3¡'Ð)VÐWÓXÐXñ WmÑó    c                ó0   € \         P                  R V 4      # )z�Text safe to print on a terminal: control characters (escape sequences, carriage
returns that could overwrite what the user reads) are shown as \x.. escapes.c                 ó²   € \        V P                  4       4      R 8  d   R\        V P                  4       4      R 2# R\        V P                  4       4      R 2# )é   z\xÚ02xz\uÚ04x)ÚordÚgroup)Úms   &r   Ú<lambda>Úvisible.<locals>.<lambda>3   sN   € Ä#ÀaÇgÁgÃiÃ.ÐSXÔBX c¬#¨a¯g©g«i«.¸Ð)=Ð$>Ð$xÐ`cÔdgÐhi×hoÑhoÓhqÓdrÐsvÐcwÐ^xÐ$xr$   )Ú
CONTROL_REÚsub)Útexts   &r   Úvisibler2   0   s   € ô �>‰>ÑxÐz~ÓÐr$   c                ó®  € RV 9   d‘   \         P                  P                  \         P                  P                  W4      4      p\         P                  P	                  V4      '       d.   \         P
                  ! V\         P                  4      '       d   V# R# \        P                  ! V 4      pV'       d    \         P                  P                  V4      # R# )z¤The absolute path a program name would run, without resolving the final symlink (so a
multi-call binary such as busybox isn't mistaken for every name linked to it).Ú/N)
ÚosÚpathÚnormpathr   ÚisfileÚaccessÚX_OKÚshutilÚwhichÚabspath)ÚprogramÚcwdr6   Úfounds   &&  r   ÚlocaterA   6   s…   € ð ˆg„~Ü�w‰w×Ñ¤§¡§¡¨SÓ :Ó;ˆÜ—w‘w—~‘~ d×+Ò+´·	²	¸$ÄÇÁ×0HÒ0HˆtÐRÈdÐRÜ�LŠL˜Ó!€Eß%*Œ2�7‰7�?‰?˜5Ó!Ð4°Ð4r$   c                ó°   €  \         P                  ! V 4      pTP                  TP                  TP
                  TP                  3#   \         d     R# i ; i)zHWhat makes a file the same file: device, inode, size, modification time.N)r5   ÚstatÚOSErrorÚst_devÚst_inoÚst_sizeÚst_mtime_ns)r6   Ústs   & r   ÚidentityrJ   @   sI   € ðÜ�WŠW�T‹]ˆð �9‰9�b—i‘i §¡¨R¯^©^Ð;Ð;øô ô Úðús   ‚A ÁAÁAc                   óD   a € ] tR t^It o RtR]3R ltR tR tR t	Rt
V tR# )	ÚTerminalConfirma  Asks on the controlling terminal (/dev/tty) and waits for "y". Anything else, no answer
within the timeout, or no terminal at all counts as a refusal. One question at a time: a
request arriving while another waits is refused at once, so prompts can't pile up.z/dev/ttyc                óV   € WuV n         V n        \        P                  ! 4       V n        R # ©N)ÚttyÚtimeoutÚ	threadingÚLockÚlock)ÚselfrO   rP   s   &&&r   Ú__init__ÚTerminalConfirm.__init__N   s   € Ø!$ÐˆŒ�$”,Ü—N’NÓ$ˆŽ	r$   c                óà   € V P                   P                  R R7      '       g   R#  V P                  V4      V P                   P                  4        #   T P                   P                  4        i ; i)F)Úblocking)FuB   å�¦ä¸€æ�¡å‘½ä»¤æ­£åœ¨ç­‰å¾…ç»ˆç«¯ç¡®è®¤ï¼Œè¯·å…ˆåœ¨ç»ˆç«¯å›žç­”å®ƒ)rS   ÚacquireÚ_askÚrelease)rT   Úquestions   &&r   Ú__call__ÚTerminalConfirm.__call__R   sR   € Ø�y‰y× Ñ ¨%Ð ×0Ò0Ø^Ð^ð	 Ø—9‘9˜XÓ&à�I‰I×ÑÕøˆD�I‰I×ÑÕús   ¦A ÁA-c                ó  €  \         P                  ! V P                  \         P                  \         P                  ,          4      p ^ RIpTP                  Y$P                  4       \         P                  ! TRT R2P                  4       4       T P                  T4      pTfN   \         P                  ! TRP                  4       4       R T P                  R R23\         P                  ! T4       # TP                  4       P!                  4       R	9   d   R
\         P                  ! T4       # R\         P                  ! T4       #   \
         d   pR RTP                   R23u Rp?# Rp?ii ; i  \         P                  ! T4       i ; i)Fu!   æ²¡æœ‰å�¯ç”¨çš„ç»ˆç«¯æ�¥ç¡®è®¤ï¼ˆuM   ï¼‰ï¼šè¯·åœ¨å‰�å�°ç»ˆç«¯è¿�è¡Œ serve.pyï¼Œæˆ–åœ¨é…�ç½®é‡Œè®¾ "confirm": falseNz
z [y/N] u   
ï¼ˆè¶…æ—¶ï¼Œå·²æ‹’ç»�ï¼‰
Úgu(    ç§’å†…ç»ˆç«¯é‡Œæ²¡æœ‰å›žç­”ï¼Œå·²æ‹’ç»�)ÚyÚyes)TN)Fu   ç»ˆç«¯é‡Œæ‹’ç»�äº†è¿™æ�¡å‘½ä»¤)r5   ÚopenrO   ÚO_RDWRÚO_NOCTTYrD   ÚstrerrorÚtermiosÚtcflushÚTCIFLUSHÚwriteÚencodeÚ
_read_linerP   ÚcloseÚstripÚlower)rT   r\   ÚfdÚerg   Úanswers   &&    r   rZ   ÚTerminalConfirm._askZ   s4  € ð	XÜ—’˜Ÿ™¤2§9¡9¬r¯{©{Õ#:Ó;ˆBð	ÛØ�O‰O˜B× 0Ñ 0Ô1Ü�HŠH�R˜4 ˜z¨Ð1×8Ñ8Ó:Ô;Ø—_‘_ RÓ(ˆFØŠ~Ü—’˜Ð;×BÑBÓDÔEØ §¡¨aÐ 0Ð0XÐYÐYô
 �HŠH�R�Lð	 �|‰|‹~×#Ñ#Ó%¨Ô5Ø!ô �HŠH�R�Lð ;ä�HŠH�R�Løô ô 	XØÐ=¸a¿j¹j¸\ð  JWð  Xð  Xõ  Xûð	Xûô �HŠH�R�Lús7   ‚AE ÁBE. Ã1$E. Ä,E. ÅE+ÅE&Å E+Å&E+Å.Fc                óª  € \         P                  ! 4       V P                  ,           pR pRV9  d   RV9  dx   V\         P                  ! 4       ,
          pV^ 8:  g(   \        P                  ! V.. . V4      ^ ,          '       g   R# \        P
                  ! VR4      pV'       g   R# W5,          pK…  VP                  RR4      P                  4       ^ ,          # )r$   ó   
ó   Ni   zutf-8Úreplace)ÚtimeÚ	monotonicrP   Úselectr5   ÚreadÚdecodeÚ
splitlines)rT   rp   ÚdeadlineÚdataÚleftÚchunks   &&    r   rl   ÚTerminalConfirm._read_linem   s�   € Ü—>’>Ó# d§l¡lÕ2ˆØˆØ˜4Ô E°Ô$5ØœdŸnšnÓ.Õ.ˆDØ�qŒy¤§¢¨r¨d°B¸¸DÓ AÀ!× DÔ DÙÜ—G’G˜B Ó%ˆEßÙØ�MŠDØ�{‰{˜7 IÓ.×9Ñ9Ó;¸AÕ>Ð>r$   )rS   rP   rO   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚCONFIRM_TIMEOUTrU   r]   rZ   rl   Ú__static_attributes__Ú__classdictcell__©Ú__classdict__s   @r   rL   rL   I   s+   ø‡ € ñZð &¨ô %ò ò÷&?ð ?r$   rL   c                   óN   a € ] tR t^{t o R
R ltR tR tR tR tR t	R t
R	tV tR# )ÚShellSessionNc                óì   € WVuV n         V n        V n        WPn        VR ,          V n        T;'       g    \
        V n        W P                  P                  RR4      ,          P                  4       V n	        R# )r"   r?   Ú.N)
ÚcfgÚbaseÚeventsÚsourcer"   ÚTERMINALr   r   Úresolver?   )rT   r‘   r’   r“   r   r”   s   &&&&&&r   rU   ÚShellSession.__init__|   sW   € Ø+.°fÐ(ˆŒ�$”)˜Tœ[ØŒØ˜•\ˆŒ
Ø×*Ð*¤(ˆŒØŸ:™:Ÿ>™>¨%°Ó5Õ5×>Ñ>Ó@ˆŽr$   c                óô   € R P                  V P                  R,          4      pV P                  P                  RR4      '       d   RMRpRRRR	R
RV P                   RV RV R2RRRRRRRR
R/RRRR
R//RR.//# )õ   ã€�r   r   TuC   æ¯�æ�¡å‘½ä»¤éƒ½è¦�åœ¨è¿�è¡Œ serve.py çš„ç»ˆç«¯é‡Œè¾“å…¥ y ç¡®è®¤ã€‚Ú ÚnameÚrunÚtitleu   è¿�è¡Œå‘½ä»¤Údescriptionu   åœ¨ u(    è¿�è¡Œä¸€æ�¡å‘½ä»¤ã€‚å…�è®¸çš„ç¨‹åº�ï¼šu   ã€‚uZ   ä¸�ç»�è¿‡ shellï¼šç®¡é�“ã€�é‡�å®šå�‘ã€�é€šé…�ç¬¦ã€�å�˜é‡�éƒ½æŒ‰æ™®é€šæ–‡å­—ä¼ ç»™ç¨‹åº�ã€‚ÚinputSchemaÚtypeÚobjectÚ
propertiesÚcommandÚstringu,   ä¸€æ�¡å‘½ä»¤ï¼Œä¾‹å¦‚ git log --oneline -n 5Ústdinu'   å�¯é€‰ï¼Œä½œä¸ºæ ‡å‡†è¾“å…¥ä¼ ç»™ç¨‹åº�Úrequired)r   r"   r   r?   )rT   r   r   s   &  r   ÚtoolÚShellSession.toolƒ   s»   € Ø—
‘
˜4Ÿ:™: gÕ.Ó/ˆØ[_×[eÑ[e×[iÑ[iÐjsÐuy×[zÒ[zÑWð  ACˆØ˜˜w¨Ø  d§h¡h ZÐ/WÐX]ÐW^Ð^aÐbiÐajð  kEð   FØ ¨°,Ø ¨°-ÐAoÐpØ˜f h°Ð?hÐiðAkð   ð -ð.ð 	.r$   c                óè  a€ \        S4      '       g   R # SR,          SP                  R4      ;'       g    / rCV3R lpVR8X  d‚   VP                  R4      pT! RV\        9   d   TM\        ^ ,          RR/ /RR	R
V P                  R,           2RV P                  P                  R	V P                  R,          4      RR/RR/R7      # VR8X  d
   V! / R7      # VR8X  d   V! RV P	                  4       ./R7      # VR8X  dg   VP                  R	4      R8w  d    V! RRRRVP                  R	4       2/R7      # T! T P                  VP                  R4      ;'       g    / 4      R7      # V! RRRRV 2/R7      # )NÚmethodÚparamsc                  óN   <€ \         P                  ! R RRSR,          /V CRR7      # )Újsonrpcz2.0ÚidF)Úensure_ascii)ÚjsonÚdumps)ÚbodyÚmsgs   ,€r   r-   Ú"ShellSession.rpc.<locals>.<lambda>‘   s$   ø€ œtŸzšz¨9°e¸TÀ3ÀtÅ9Ð*UÐPTÐ*UÐdiÕjr$   Ú
initializeÚprotocolVersionÚcapabilitiesÚtoolsÚ
serverInfor›   zshell:r®   r�   Úversionz1.0.0ÚinstructionsuT   å�—é™� shellï¼šå�ªèƒ½è¿�è¡Œç™½å��å�•é‡Œçš„ç¨‹åº�ï¼Œæ¯�æ�¡å‘½ä»¤å…ˆåœ¨ç»ˆç«¯ç¡®è®¤ã€‚)ÚresultÚpingz
tools/listz
tools/callrœ   ÚcodeÚmessagezUnknown tool: )ÚerrorÚ	argumentszMethod not found: i¦€ÿÿi§€ÿÿ)r   r   r   r‘   r§   rœ   )rT   r³   Úrawrª   r«   ÚreplyÚaskeds   &f&    r   ÚrpcÚShellSession.rpc�   s’  ø€ Ü˜#�ŠÙØ˜X�¨¯©°Ó(9×(?Ð(?¸R�ÜjˆØ�\Ô!Ø—J‘JÐ0Ó1ˆEÙÐ!2¸UÔFWÔ=W±EÔ]nÐopÕ]qØ!/°'¸2°Ø!-°¸&ÀÇÁÈ$ÅÐ@PÐ8QÐSZÐ\`×\dÑ\d×\hÑ\hÐioÐqu×qyÑqyÐz~Õqó  ]Að  CLð  NUð  0VØ!/ð  2Hð!Iô Jð Jð �VÔÙ Ô#Ð#Ø�\Ô!Ù ¨4¯9©9«;¨-Ð 8Ô9Ð9Ø�\Ô!Ø�z‰z˜&Ó! UÔ*Ù F¨F°IÀÐPV×PZÑPZÐ[aÓPbÐOcÐ?dÐ#eÔfÐfÙ §¡¨¯©°KÓ)@×)FÐ)FÀBÓ GÔHÐHÙ˜F F¨IÐ9KÈFÈ8Ð7TÐUÔVÐVr$   c                óÖ   € \        V^ ,          V P                  4      pV P                  R,           Uu0 uF  p\        W0P                  4      kK  	  upR0,
          pW$9   d   V# R# u upi )zMThe absolute path to run for argv[0], or None if it isn't an allowed program.r   N)rA   r?   r"   )rT   Úargvr6   r   Úalloweds   &&   r   r–   ÚShellSession.resolve¢   sZ   € ä�d˜1•g˜tŸx™xÓ(ˆØ04·
±
¸7Ö0CÓDÑ0C¨1”6˜!ŸX™XÖ&Ñ0CÑDÈÀvÕMˆØ”ˆtÐ0¨DÐ0ùò Es   ³A&c                ó²  € VP                  R 4      VP                  R4      r2\        V\        4      '       d   Ve"   \        V\        4      '       g   \        R4      #  \        P
                  ! V4      pT'       g   \        R4      # \        T4      \        8”  d    \        R\        T4       R\         R24      # T P                  T4      pTf8   \        T^ ,           R	R
P                  T P                  R,          4       24      # \        T4      pT.TR,          OpT P                  P                  RR4      '       d¬   T P                  P                  RRRRRT/4       T P                  T P!                  YC4      4      w  r‰T'       g-   T P                  P                  RRRRRT/4       \        T	4      # T P                  T4      T8w  g   \        T4      T8w  d   \        T R24      # \#        Y@P$                  T\'        T P                  P                  R\(        4      4      T P                  4      #   \         d   p\        RT 24      u Rp?# Rp?ii ; i)r£   r¥   Nu$   command å’Œ stdin å¿…é¡»æ˜¯å­—ç¬¦ä¸²u-   æ— æ³•è§£æž�å‘½ä»¤ï¼ˆå¼•å�·ä¸�é…�å¯¹ï¼Ÿï¼‰ï¼šu   å‘½ä»¤ä¸ºç©ºu   å‘½ä»¤å¤ªé•¿ï¼ˆu    ä¸ªå­—ç¬¦ï¼Œä¸Šé™� u   ï¼‰u(    ä¸�åœ¨ç™½å��å�•é‡Œã€‚å…�è®¸çš„ç¨‹åº�ï¼šr™   r   :é   NNr   Tr    ÚstatusrÈ   Úrefusedu:    åœ¨ç­‰å¾…ç¡®è®¤æœŸé—´è¢«æ›¿æ�¢æˆ–ç§»èµ°äº†ï¼Œæ²¡æœ‰è¿�è¡Œr   )r   r
   r   r   ÚshlexÚsplitr   ÚlenÚMAX_COMMANDr–   r   r"   rJ   r“   Úpublishr   r\   r   r?   r    r   )
rT   Úargsr£   r¥   rÈ   rq   r>   ÚcheckedÚokÚwhys
   &&        r   rœ   ÚShellSession.run¨   sÿ  € ØŸ™ )Ó,¨d¯h©h°wÓ.?�Ü˜'¤3×'Ò'¨EÒ,=ÄjÐQVÔX[×F\ÒF\ÜÐDÓEÐEð	SÜ—;’;˜wÓ'ˆD÷ Ü˜nÓ-Ð-Üˆw‹<œ+Ô%Ü ´°G³¨~Ð=QÔR]ÐQ^Ð^aÐbÓcÐcØ—,‘,˜tÓ$ˆØŠ?Ü  a¥ 	Ð)QÐRW×R\ÑR\Ð]a×]gÑ]gÐhoÕ]pÓRqÐQrÐsÓtÐtÜ˜7Ó#ˆØÐ#˜$˜r�(Ð#ˆØ�:‰:�>‰>˜) T×*Ò*Ø�K‰K×Ñ ¨°8¸YÈÐPTÐ UÔVØ—l‘l 4§=¡=°Ó#=Ó>‰GˆBßØ—‘×#Ñ# V¨X°xÀÈFÐTXÐ$YÔZÜ! #“Ð&à�|‰|˜DÓ! WÔ,´¸Ó0AÀWÔ0LÜ! W IÐ-gÐ"hÓiÐiÜ˜4§¡¨5´%¸¿
¹
¿¹À{ÔTcÓ8dÓ2eÐgk×grÑgrÓsÐsøô) ô 	SÜÐ MÈaÈSÐQÓRÕRûð	Sús   ÁH3 È3IÈ>IÉIÉIc                ój  € R \        V P                  R,          4       R2R\        \        V P                  4      4       2R\        \        P
                  ! V4      4       2.pV P                  e2   VP                  R\        \        V P                  4      4       R24       Ven   VP                  R\        VR\         4       24       \        V4      \        8”  d6   VP                  R	\        V4       R
\        V4      \        ,
           R24       VP                  R4       RP                  V4      # )u   [MCP å�—é™� shell Â· r®   u   ] é¡µé�¢è¯·æ±‚è¿�è¡Œï¼šu     ç›®å½•ï¼šu     å‘½ä»¤ï¼šNu     é…�ç½®ï¼šu%   ï¼ˆè¿™ä¸ªæœ�åŠ¡ç«¯ "confirm": trueï¼‰u     æ ‡å‡†è¾“å…¥ï¼šu     âš  æ ‡å‡†è¾“å…¥å…± u    ä¸ªå­—ç¬¦ï¼Œå�Žé�¢ u    ä¸ªæ²¡æœ‰æ˜¾ç¤ºu   å…�è®¸è¿�è¡Œå�—ï¼ŸÚ
)
r2   r‘   r   r?   rÏ   r   r”   ÚappendÚMAX_PREVIEWrÑ   )rT   rÈ   r¥   Úliness   &&& r   r\   ÚShellSession.questionÄ   s  € Ø(¬°·±¸$µÓ)@Ð(AÐAXÐYØœw¤s¨4¯8©8£}Ó5Ð6Ð7Øœw¤u§z¢z°$Ó'7Ó8Ð9Ð:ð<ˆð �;‰;Ò"Ø�L‰L˜;¤w¬s°4·;±;Ó/?Ó'@Ð&AÐAfÐgÔhØÒØ�L‰LÐ,¬W°U¸<¼KÐ5HÓ-IÐ,JÐKÔLÜ�5‹zœKÔ'Ø—‘Ð5´c¸%³j°\ÐAUÔVYÐZ_ÓV`ÔcnÕVnÐUoÐoð  Aô  BØ�‰Ð)Ô*Ø�y‰y˜ÓÐr$   c                ó   € R # rN   © )rT   s   &r   ÚstopÚShellSession.stopÑ   s   € Ùr$   )r’   r‘   r   r?   r“   r"   r”   )NN)rƒ   r„   r…   r†   rU   r§   rÅ   r–   rœ   r\   rá   r‰   rŠ   r‹   s   @r   rŽ   rŽ   {   s0   ø‡ € ôAò.òWò*1òtò8 ÷ð r$   rŽ   >   r?   r   r   r   )r‡   r°   r5   r   rz   rÏ   r;   rQ   rx   Ú
mcp_bridger   r   r   r   r   rˆ   rÜ   rÒ   r   Úcompiler/   r#   r2   rA   rJ   rL   rŽ   r•   rà   r$   r   Ú<module>rå      s‡   ðñó Û 	Û 	Û Û Û Û Û ç ^Õ ^à€Ø€Ø€Ú/€ð �ZŠZÐZÓ[€
ò
Yò@ò5ò<÷/?ñ /?÷dWñ Wñt Ó‚r$   