
    f[                        d Z ddlmZmZmZ ddlZddlmZ  e        ddlm	Z	m
Z
mZmZ ddlmZmZmZ ddlmZ ddlmZmZmZmZmZmZ dd	lmZ dd
lmZ ddlmZm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z( ddl)Z) e)jT                  e+      Z,ddl-m.Z.  e.       Z/e	j`                  jb                  e	j`                  jd                  z  e	j`                  jf                  z  Z4 G d d      Z5 G d dee
jl                        Z7 G d de7      Z8 G d de7e"e      Z9 G d d      Z: G d de:      Z; G d de;      Z< G d de7      Z=y) z GTK keyboard widget     )divisionprint_functionunicode_literalsN)require_gi_versions)GdkGtkPango
PangoCairo)Rectroundrect_arcVersion)Timer)limit_window_positionget_monitor_rectscanvas_to_root_window_rectget_monitor_dimensionsWindowRectTrackergtk_has_resize_grip_support)
TouchInput)	KeyCommon)
LayoutRootLayoutPanel)
LayoutView)RectKey)	ImageSlot)Configc                   6    e Zd ZdZd Zd Zd	dZd Zd Zd Z	y)
TouchFeedbackz, Display magnified labels as touch feedback c                      g | _         i | _        y N)_key_feedback_popup_pool_visible_key_feedback_popupsselfs    8/usr/lib/python3/dist-packages/Onboard/KeyboardPopups.py__init__zTouchFeedback.__init__B   s    (*%,.)    c                    || j                   vra|j                         }t        ||      }|j                         }| j	                         }|Ft               }|j                  |       | j                  j                  |       |j                          | j                  |      \  }}|j                  ||       |j                  ||       |j                  |       |j                  |j                  |j                   dz  z   |j"                  dd       |j$                  |_        |j$                  r|j'                  |j)                                |j+                          || j                   |<   y y )N      ?   )r"   get_canvas_border_rectr   get_toplevel_get_free_key_feedback_popup
LabelPopupset_transient_forr!   appendrealize_get_popup_sizeset_default_sizeresizeset_keyposition_atxwysupports_alphaset_opacityget_opacityshow_all)	r$   keyviewr	root_recttoplevelpopupr8   hs	            r%   showzTouchFeedback.showF   s7   d777**,A24;I((*H557E}"''1--44U; ''.DAq""1a(LLAMM#ikkIKK#,=='kk33#'#6#6E ##!!("6"6"89NN5:D--c23 8r'   Nc                     |r|gn"t        | j                  j                               }|D ]N  }| j                  j                  |      }|s!|j	                          |j                  d        | j                  |= P y r    )listr"   keysgethider5   )r$   r>   rH   _keyrC   s        r%   rJ   zTouchFeedback.hideb   sl    ud&G&G&L&L&N!O 	<D5599$?E

d#55d;	<r'   c                     | j                   j                         D ](  \  }}|j                         }|s|j                          * y r    )r"   items
get_windowraise_)r$   r>   rC   wins       r%   	raise_allzTouchFeedback.raise_allk   s>    ;;AAC 	JC""$C

	r'   c                 N    | j                   D ]  }|j                         r|c S  y)z5 Get a currently unused one from the pool of popups. N)r!   get_key)r$   rC   s     r%   r-   z*TouchFeedback._get_free_key_feedback_popupq   s*    22 	E==?	 r'   c                 z   d}d}|j                         }t        j                  j                  }|dk(  rbt	        |      \  }}|d   dkD  r/|d   dkD  r'|}|r	 ||j                         z  }|d   |z  |d   z  }n|d   dkD  rt        |d   dz  |      }n|}||dt        j                  z   z  fS # t        $ r Y Ow xY w)Ng      2@g      ^@r   g      (@      ?)
rN   configkeyboardtouch_feedback_sizer   get_scale_factorAttributeErrorminr.   ARROW_HEIGHT)	r$   windowDEFAULT_POPUP_SIZE_MMMAX_POPUP_SIZE_PXgdk_winr8   szsz_mmdefault_size_mms	            r%   r2   zTouchFeedback._get_popup_sizex   s     $!##%OO//6.v6IB!uqyU1X\"7 '7+C+C+EE qEO+eAh6A1&78%!sZ444555 * s   B. .	B:9B:r    )
__name__
__module____qualname____doc__r&   rE   rJ   rQ   r-   r2    r'   r%   r   r   ?   s#    6/;8<6r'   r   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	KeyboardPopupz! Abstract base class for popups. c           	         d| _         t        j                  |        dddddddd}t               rd|d<   t	        j
                  j                  | fi | | j                  d       t	        j                         | _        | j                  | j                         | j                  j                  d| j                         t        j                  j                         }|j                         }d| _        |r| j#                  |       | j                  j#                  |       t%        t        j&                  t        j(                        }|t%        dd      k  r| j+                  t        j,                  j.                  t        j0                  d	d	d	d	             | j                  j+                  t        j,                  j.                  t        j0                  d	d	d	d	             d| _        y y )
NrU   TF)skip_taskbar_hintskip_pager_hinturgency_hint	decoratedaccept_focusopacityapp_paintablehas_resize_gripdraw      r   )_opacityr   r&   r   r   Windowset_keep_aboveDrawingAreadrawing_areaaddconnecton_drawr   Screenget_defaultget_rgba_visualr:   
set_visualr   MAJOR_VERSIONMINOR_VERSIONoverride_background_color
StateFlagsNORMALRGBA)r$   argsscreenvisualgtk_versions        r%   r&   zKeyboardPopup.__init__   s   ""4( #' $"""
 '(&+D"#

D)D)D!  OO-""#!!&$,,7 '')'')#OOF#((0
 "#"3"3S5F5FGKWQ^+..NN))388Aq!Q+?A!!;;NN))388Aq!Q+?A"&D r'   c                     || _         y)3 Override deprecated Gtk function of the same name Nrw   )r$   rq   s     r%   r;   zKeyboardPopup.set_opacity   s	    r'   c                     | j                   S )r   r   r#   s    r%   r<   zKeyboardPopup.get_opacity   s    }}r'   c                     t               r    )NotImplementedErrorr$   widgetcontexts      r%   r~   zKeyboardPopup.on_draw   s    !##r'   c                     t        j                  | j                         | j                               }|j	                  ||||      }| j                  |      }|j                         \  }}| j                  ||       y)za
        Align the window with the given point.
        x, y in root window coordinates.
        N)r   from_position_sizeget_positionget_sizealign_at_pointlimit_to_workareamove)r$   r7   r9   x_aligny_alignrects         r%   r6   zKeyboardPopup.position_at   sj    
 &&t'8'8':DMMOL""1a':%%d+  "1		!Qr'   c           	         t        dd|j                  |j                        }t        |j                  |j
                  |t        | j                                     \  }}t        |||j                  |j                        S )Nr   )r   r8   rD   r   r7   r9   r   
get_screen)r$   r   visible_rectr7   r9   s        r%   r   zKeyboardPopup.limit_to_workarea   s_    Aq$&&$&&1$TVVTVV\%6t7H%IK1Aq$&&$&&))r'   N)
rd   re   rf   rg   r&   r;   r<   r~   r6   r   rh   r'   r%   rj   rj      s$    +0'd $
*r'   rj   c                       e Zd ZdZdZdZdZdZ ej                         Z
d Zd Zd Zd	 Zed
        Zed        Zd Zd Zy)r.   zB Ephemeral popup displaying a key label without user interaction. gp=
ף?g333333?g?Nc                 t    t         j                  |        d | _        | j                  d| j                         y )Nr1   )rj   r&   rK   r}   _on_realize_eventr#   s    r%   r&   zLabelPopup.__init__   s+    t$	Y 6 67r'   c                     | j                  d       | j                         }| j                  j                  |dddd       y NTr   r*   set_override_redirectrN   	_osk_utilset_input_rectr$   	user_datarP   s      r%   r   zLabelPopup._on_realize_event   8    ""4( oo%%c1aA6r'   c                 |   t         j                  s1t        j                  t	        j
                               t         _        t        dd| j                         | j                               }t        |j                  |j                  |j                  |j                  |j                  | j                  z  z
        }t        |j                  |j                         |j                  |j                  | j                  z        j                  |j                  |j                  | j                   z  z
  dz  d      }|j                  |j                  | j"                  z        }| j$                  j'                         }|j)                          |j+                  t,        j.                         |j1                          |j3                          |j5                           |j6                  |  t9        ||t:        j<                         |j?                          |jA                         \  }}	}
}|	dz  }	|jC                  ||	       |jE                  |
|	       |jE                  ||
z   dz  |       |j?                          | j$                  jG                         }| j$                  jI                  |j                  |j                        }|r|jK                  |||       n7| j$                  jM                         }|r|dk(  rd}| jO                  ||||       |jQ                          |jS                  | jT                         y )N)r   r          @r*       u   ␣)+r.   _pango_layoutr	   Layoutr   pango_context_getr   get_allocated_widthget_allocated_heightr7   r9   r8   rD   r\   bottomdeflateARROW_WIDTHLABEL_MARGINrK   get_fill_colorsaveset_operatorcairoOPERATOR_CLEARpaintrestore
push_groupset_source_rgbar   rV   CORNER_RADIUSfill
to_extentsmove_toline_toget_label_color	get_imagert   	get_label
_draw_textpop_group_to_sourcepaint_with_alpharw   )r$   r   r   r   content_rect
arrow_rect
label_rectr   ltr@   blabel_colorpixbuflabels                  r%   r~   zLabelPopup.on_draw   sm   ''',||C<Q<Q<S'TJ$Aq$2243357DFFDFFDFF FFTVVd.?.?%??ADFFL$7$7$9466 FFT%6%668$&&43C3C*C!Cs JAN 	 "))$&&43D3D*DE
 yy'')U112&g|V-A-AB**,
1a	Q111	1% ii//1$$Z\\:<<@KK[9II'')EC<!E
KH##%  /r'   c                 j   | j                   }|j                  |d       t        j                  t        j
                  j                        }| j                  ||      }| j                  ||      }|j                  t        d|             |j                  |       |j                         \  }	}
|	t        j                  z  }	|
t        j                  z  }
|j                  t        dd|	|
            j!                         } |j"                  |   |j$                  |  t'        j(                  ||       y )Nr*   r   )r   set_textr	   FontDescriptionrV   theme_settingskey_label_font_calc_base_layout_extents_calc_font_sizeset_sizemaxset_font_descriptionr   SCALE
align_rectr   r   r   r   r
   show_layout)r$   r   textr   rgbalayoutfont_descriptionbase_extents	font_sizer8   rD   offsets               r%   r   zLabelPopup._draw_text/  s	   ##b! !00(.(=(=(L(LN55f>NO ((|<	!!#a"34##$45  1	U[[	U[[aAq!12??A 	 &w/r'   c                     | j                   |d   z  }| j                  |d   z  }||k  rt        |      S t        |      S )Nr   r*   )r8   rD   int)r   r   size_for_maximum_widthsize_for_maximum_heights       r%   r   zLabelPopup._calc_font_sizeH  sI    "&&&<?":"&&&<?":!$;;-...//r'   c                     d}|j                  |       | j                  |       | j                         \  }}|xs d}|xs d}|t        j                  |z  z  |t        j                  |z  z  f}|S )Ni rU   )r   r   r   r	   r   )r   r   BASE_FONTDESCRIPTION_SIZEr8   rD   extentss         r%   r   z$LabelPopup._calc_base_layout_extentsQ  sy    $,!!!";<##$45 1HH&??@&??@Br'   c                     | j                   S r    rK   r#   s    r%   rS   zLabelPopup.get_key_  s    yyr'   c                     || _         y r    r   )r$   r>   s     r%   r5   zLabelPopup.set_keyb  s	    	r'   )rd   re   rf   rg   r\   r   r   r   oskUtilr   r&   r   r~   r   staticmethodr   r   rS   r5   rh   r'   r%   r.   r.      sm    LLKLM
I8
7/0b02 0 0  r'   r.   c                        e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Z fd
Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )LayoutPopupz$ Popup showing a (sub-)layout tree. r   c                 $   d | _         || _        d| _        t        j	                  |        t        j                  | |       t        j                  |        | j                  d| j                         t               | _
        | j                          y )NFdestroy)_layout_notify_done_callback_drag_selectedrj   r&   r   r   r}   _on_destroy_eventr   _close_timerstart_close_timer)r$   rW   notify_done_callbacks      r%   r&   zLayoutPopup.__init__k  so    %9"#t$D(+D!Y 6 67!G r'   c                     | j                          | j                  j                          t        j                  |        y r    )stop_close_timerrW   hide_touch_feedbackr   cleanupr#   s    r%   r	  zLayoutPopup.cleanupy  s.     	))+4 r'   c                     | S r    rh   r#   s    r%   r,   zLayoutPopup.get_toplevel  s    r'   c                     || _         || _        | j                          |j                         }|j	                  |      }|j                         \  }}| j                  |dz   |dz          y )Nr*   )r   _frame_widthupdate_labelsr+   inflater   r3   )r$   r   frame_widthlayout_canvas_rectcanvas_rectr8   rD   s          r%   
set_layoutzLayoutPopup.set_layout  sh    ' $::<(00=##%1a!eQU+r'   c                     | j                   S r    )r   r#   s    r%   
get_layoutzLayoutPopup.get_layout  s    ||r'   c                     | j                   S r    )r  r#   s    r%   get_frame_widthzLayoutPopup.get_frame_width  s       r'   c                     | j                   S )z) Has the pointer ever entered the popup? )r  r#   s    r%   
got_motionzLayoutPopup.got_motion  s    """r'   c                 L    | j                  d       t        t        |           y NT)r   superr   handle_realize_event)r$   	__class__s    r%   r  z LayoutPopup.handle_realize_event  s    ""4(k457r'   c                 $    | j                          y r    )r	  )r$   r   s     r%   r  zLayoutPopup._on_destroy_event  s    r'   c                 $    | j                          y r    )r  r$   r   events      r%   on_enter_notifyzLayoutPopup.on_enter_notify  s    r'   c                 $    | j                          y r    )r  r   s      r%   on_leave_notifyzLayoutPopup.on_leave_notify  s     r'   c                     | j                          | j                  |j                        }|r%||_        | j                  j                  || |       y y r    )r  get_key_at_locationpoint
active_keyrW   key_down)r$   sequencer>   s      r%   on_input_sequence_beginz#LayoutPopup.on_input_sequence_begin  sH    &&x~~6"%HMM""3h7 r'   c                 6   |j                   t        z  r| j                  |j                        }|j                  }||urZ||j
                  sK||_        | j                  j                  || |d       | j                  j                  || |d       d| _	        y y y y )NFT)
stateBUTTON123_MASKr&  r'  r(  	activatedrW   key_upr)  r  )r$   r*  r>   r(  s       r%   on_input_sequence_updatez$LayoutPopup.on_input_sequence_update  s    >>N***8>>:C ",,J$"**>*>&)#$$ZxG&&sD(EB&*#	 +? % +r'   c                     |j                   }|r| j                  }|j                  || |       |r1| j                  s%t	        t
        j                  | j                         y | j                          y r    )r(  rW   r0  r  r   rV   UNPRESS_DELAYclose_window)r$   r*  r>   rW   s       r%   on_input_sequence_endz!LayoutPopup.on_input_sequence_end  sW    !!}}HOOCx0""&&&(9(9:r'   c                     |j                          t        j                  | ||       |j                          |j	                  | j
                         y r    )r   r   rt   r   r   rw   r   s      r%   r~   zLayoutPopup.on_draw  s<    fg.##%  /r'   c                 r   t         j                  }| j                  d      }|d   }ddd|gddg|ddgg}t        dd| j	                         | j                               }|D ]T  \  }}	}
|j                  |
      }t        |||       |j                  |
        |j                  |  |j                          V y )Nborderru   r)   r   r*   g      ?r   )rV   r   get_popup_window_rgbar   r   r   r   r   set_line_widthr   stroke)r$   r   lodcorner_radiusborder_rgbaalphacolorsr   r   poswidthr@   s               r%   draw_window_framezLayoutPopup.draw_window_frame  s    ,,00:A c5)1234
 Aq$2243357 !' 	D#uU#A'1m4""5)#G##T*NN	r'   c                 $    | j                          y r    )r   r#   s    r%   r4  zLayoutPopup.close_window  s    ""$r'   c                 ~    | j                   r1| j                  j                  | j                   | j                         y y r    )IDLE_CLOSE_DELAYr  startr4  r#   s    r%   r  zLayoutPopup.start_close_timer  s2      ##D$9$94;L;LM !r'   c                 8    | j                   j                          y r    )r  stopr#   s    r%   r  zLayoutPopup.stop_close_timer  s     r'   )rd   re   rf   rg   rF  r&   r	  r,   r  r  r  r  r  r  r"  r$  r+  r1  r5  r~   rC  r4  r  r  __classcell__)r  s   @r%   r   r   f  sl    .!!
,!#8 !8+
 0(%N!r'   r   c                   ,    e Zd Zed        Zed        Zy)LayoutBuilderc           	      P   | j                   }t        j                  |      }t        |      }|j	                          |j                         }t        |||j                  |j                  d      z  |j                  |j                  d      z        }|j                  |       ||fS )NrU   )r   rL  _calc_frame_widthr   update_log_rectget_border_rectr   r8   scale_log_to_canvas_xrD   scale_log_to_canvas_yfit_inside_canvas)
source_keycolor_schemer   r   r  log_rectr  s          r%   buildzLayoutBuilder.build  s    $$#55g>F# ))+;#::(E(Ec(JJ#::(E(Ec(JJL 	  -{""r'   c                 \    | j                  d      }t        j                  t        |      z   S )Nr*   r*   )scale_log_to_canvasrV   POPUP_FRAME_WIDTHr[   )r   canvas_borders     r%   rN  zLayoutBuilder._calc_frame_width   s*      33F;''#m*<<<r'   N)rd   re   rf   r   rW  rN  rh   r'   r%   rL  rL    s(    # # = =r'   rL  c                   @    e Zd ZdZed        Zed        Zed        Zy)LayoutBuilderKeySequence   c                 b    t         j                  |      \  }}t         j                  | |||      S r    )r^  _layout_sequence_create_layout)rT  rU  key_sequencelinesncolumnss        r%   rW  zLayoutBuilderKeySequence.build  s:     %66|D 	x'66z7C7<hH 	Hr'   c           	         | j                   }t        j                  |      }t        |      }d}| j	                         }t        |||j                  |z  |d   |dz
  z  z   |j                  |z  |d   |dz
  z  z         }	|j                  |	      }
 |
j                  ||g| }g }t        |      D ]X  \  }}t        |      D ]E  \  }}||z  |z   }|s|}|j                  ||          d|_        ||_        |j                  |       G Z t               }d|_        |j#                  |       t%        |      }|j'                  |	       ||fS )NrY  r   r*   alternatives)r   r^  rN  lenr+   r   r8   rD   canvas_to_log_rect	subdivide	enumerateset_border_rectgrouprU  r0   r   r8  	set_itemsr   rS  )rT  rU  rd  re  r   r  nrowsspacingr   r  layout_rect	key_rectsrH   ilinejitemslotr>   r   s                       r%   rb  z'LayoutBuilderKeySequence._create_layout  sk   $$.@@IE
 002!+{"ffx/'!*12MM"ffunwqzUQY/GGI
 001CD)K))(EDGD	  ' 		%GAt$T? %48|a'C''	$8 .CI'3C$KK$%		% }tD!  !34{""r'   c                    t         j                  }|dz  }d}d}t        |       }|r|dz  }d}|}t        ||d      D ]  }||z  }	|	dk(  r|	}|} n||	k  s|	}|} t	        ||      }g }
g }d}| D ]3  }|j                  |       |dz  }||k\  s|
j                  |       g }d}5 |rut        |      }|j                  dg||dz   z
  z         t        d      }i |_        t        j                  d	i|_        t        j                  |_        |j                  |       |rCt        |      }|r6t        ||z
        D ]%  }t        d
      }d|_        |j                  |       ' |r|
j                  |       |
|fS )z,
        Split sequence into lines.
        r   FTr*   r   r   N_close_z	close.svg_dummy_)LayoutBuilderAlternativesMAX_KEY_COLUMNSrh  ranger[   r0   extendr   labelsr   r   image_filenamesr   BUTTON_TYPEtype	sensitive)r*  max_columnsmin_columns	add_close	fill_gapsnmax_modre  rs  mrd  rt  columnrv  r>   s                  r%   ra  z)LayoutBuilderKeySequence._layout_sequence<  s   
 0??!Q&		 MFA{K4 	AAAAv{	 q(#  	DKKaKF!T"	 D	AKKAaC 012)$CCJ#,#3#3k"BC ,,CHKK D	Ax!|, %A!),C$)CMKK$%
 LLhr'   N)rd   re   rf   r|  r   rW  rb  ra  rh   r'   r%   r^  r^    sF    OH H %# %#N @ @r'   r^  c                       e Zd Zed        Zy)r{  c                     g }t        |      D ]U  \  }}t        dt        |      z         }t        j                  |_        d|i|_        |d   |_        |j                  |       W t        j                  | ||      S )N_alternativer   )rk  r   strr   	CHAR_TYPEr  r  coder0   r^  rW  )rT  rU  rg  rc  rs  r   r>   s          r%   rW  zLayoutBuilderAlternatives.build  s    !,/ 	%HAu.3q612C **CHUCJaCH$	% (--j,.:< 	<r'   N)rd   re   rf   r   rW  rh   r'   r%   r{  r{    s    
< 
<r'   r{  c                   V    e Zd ZdZ ej
                         Zd Zd Zd Z	d Z
d Zd Zy)	PendingSeparatorPopupz8 Ephemeral popup displaying the pending word separator. c                 t    t         j                  |        | j                  d| j                         d| _        y )Nr1   F)rj   r&   r}   r   _visibler#   s    r%   r&   zPendingSeparatorPopup.__init__  s+    t$Y 6 67r'   c                    |j                         }| j                  |       | j                          |\  }}}}| j                  ||       | j	                  ||       | j                  ||       |j                  | _        | j                  r| j                  |j                                | j                          d| _
        y r  )r,   r/   r1   r3   r4   r   r:   r;   r<   r=   r  )r$   r?   character_rectrB   r7   r9   r8   rD   s           r%   show_atzPendingSeparatorPopup.show_at  s    $$&x(#
1aa#Aq		!Q"11X1134r'   c                 <    t         j                  |        d| _        y )NF)rj   rJ   r  r#   s    r%   rJ   zPendingSeparatorPopup.hide  s    4 r'   c                     | j                   S r    )r  r#   s    r%   
is_visiblez PendingSeparatorPopup.is_visible  s    }}r'   c                     | j                  d       | j                         }| j                  j                  |dddd       y r   r   r   s      r%   r   z'PendingSeparatorPopup._on_realize_event  r   r'   c                    t        dd| j                         | j                               }d}d} |j                  |   |j                  |  |j                          |}|j                  |j                  dz  z   }|j                         } |j                  |  |j                  t        d|j                  dz               |j                  |j                         |       |j                  |j                         |       |j                  |j                         |       |j                  |j                         |       |j                          y )Nr   )rU   r)   r)   g?)rU   r)   r)   gffffff?g      ?r*      )r   r   r   r   	rectangler   r9   rD   r   r:  r   r   leftr   rightr;  )	r$   r   crr   	fill_rgbastroke_rgbar@   topr   s	            r%   r~   zPendingSeparatorPopup.on_draw  s   Aq,,.0I0I0KM )	*I&d
	ccACC$JK(
#aq/*


1668S!


1668V$


1779f%


1779c"
		r'   N)rd   re   rf   rg   r   r   r   r&   r  rJ   r  r   r~   rh   r'   r%   r  r    s0    B
I
"7r'   r  )>rg   
__future__r   r   r   r   Onboard.Versionr   gi.repositoryr   r   r	   r
   Onboard.utilsr   r   r   Onboard.Timerr   Onboard.WindowUtilsr   r   r   r   r   r   Onboard.TouchInputr   Onboardr   Onboard.Layoutr   r   Onboard.LayoutViewr   Onboard.KeyGtkr   Onboard.KeyCommonr   Onboard.oskr   logging	getLoggerrd   _loggerOnboard.Configr   rV   ModifierTypeBUTTON1_MASKBUTTON2_MASKBUTTON3_MASKr.  r   rx   rj   r.   r   rL  r^  r{  r  rh   r'   r%   <module>r     s!  (  A A  /   > > ? ? (? ? . , : - * ,  
'

H
% "	 !!..!!../!!../
R6 R6jQ*%szz Q*h{ {|E!-Z E!P= =2v} vr< 8 < =M =r'   