B 0‘c.}ã@sJddlmZddlZddlZddlZddlmZmZddlZddlm Z ddlZddl m Z ej Z e j ZiZe d¡Zed<e d¡Zed<e d¡Zed <e d¡Zed <d d „Zd d„ZGdd„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZedkrFejdddS)é)ÚconfigN)Úcaptured_stderrÚfindfile)Úmock)ÚFuncÚÚmainÚ highlightÚkeysÚ extensionscCstt_dt_dS)NT)ÚtestcfgÚidleConfÚuserCfgÚidlelibÚtesting©rrúB/opt/alt/python37/lib64/python3.7/idlelib/idle_test/test_config.pyÚ setUpModulesrcCstt_dt_dS)NF)Úusercfgr rrrrrrrÚtearDownModule!src@s0eZdZdZdd„Zdd„Zdd„Zdd „Zd S) ÚIdleConfParserTestzœ [one] one = false two = true three = 10 [two] one = a string two = true three = false cCsôt d¡}| |j¡|j}| |jddddd¡| |jddddd¡||jddd dd ƒ|| dd¡d ƒ| |jddddd¡| |jddddd¡|| dd¡d ƒ|| dd¡d ƒ| | dd¡¡||jdddddƒdS)NrÚoneÚbool)ÚtypeFÚtwoTÚthreeÚinté za stringÚtrueÚfalseÚnotZexistZDEFAULT)Údefault)rÚIdleConfParserÚ read_stringÚ assertEqualZassertIsÚGetZ assertIsNone)ÚselfÚparserÚeqrrrÚtest_get5s  zIdleConfParserTest.test_getcCs\t d¡}| |j¡|j}| |dƒdddg¡| |dƒdddg¡| |dƒg¡dS)Nrrrrz not exist)rr"r#Ú GetOptionListÚassertCountEqualr$)r&r'Zget_listrrrÚtest_get_option_listJs   z'IdleConfParserTest.test_get_option_listcCs&t d¡}| ¡| | ¡g¡dS)Nr)rr"ÚLoadr$Úsections)r&r'rrrÚtest_load_nothingRs z$IdleConfParserTest.test_load_nothingcCsFtdƒ}t |¡}| ¡| | dd¡d¡| | d¡dg¡dS)Nz cfgparser.1zFoo BarÚfooÚnewbar)rrr"r-r$r%r*)r&Ú config_pathr'rrrÚtest_load_fileWs  z!IdleConfParserTest.test_load_fileN)Ú__name__Ú __module__Ú __qualname__rr)r,r/r3rrrrr&s  rc@sFeZdZddd„Zdd„Zdd„Zdd „Zd d „Zd d „Zdd„Z dS)ÚIdleUserConfParserTestrcCs t |¡S)N)rÚIdleUserConfParser)r&ÚpathrrrÚ new_parserdsz!IdleUserConfParserTest.new_parsercCs¢| ¡}| d¡| | ddd¡¡| | ddd¡¡| | ddd¡¡| | dd¡d¡| | ddd¡¡| | ¡ddg¡| | dd¡d¡dS)NÚFooÚbarrrÚBar) r:Ú add_sectionÚ assertTrueÚ SetOptionÚ assertFalser$r%r+r.)r&r'rrrÚtest_set_optiongs z&IdleUserConfParserTest.test_set_optioncCsZ| ¡}| d¡| ddd¡| | dd¡¡| | dd¡¡| | dd¡¡dS)Nr;r<rZNotZExist)r:Ú AddSectionr@r?Z RemoveOptionrA)r&r'rrrÚtest_remove_optionws  z)IdleUserConfParserTest.test_remove_optioncCsN| ¡}| | ¡g¡| d¡| d¡| d¡| | ¡ddg¡dS)Nr;r=)r:r$r.rCr+)r&r'rrrÚtest_add_section€s    z'IdleUserConfParserTest.test_add_sectioncCs^| ¡}| d¡| d¡| ddd¡| | ¡dddg¡| ¡| | ¡dg¡dS)Nr;r=ZIdleÚnameÚval)r:rCr@r+r.ZRemoveEmptySectionsr$)r&r'rrrÚtest_remove_empty_sections‹s  z1IdleUserConfParserTest.test_remove_empty_sectionscCsv| ¡}| d¡| d¡| | ¡¡| | ¡g¡| ddd¡| d¡| | ¡¡| | ¡dg¡dS)Nr;r=r<r) r:rCr?ZIsEmptyr$r.r@rAr+)r&r'rrrÚ test_is_empty•s   z$IdleUserConfParserTest.test_is_emptyc Cs˜t ¡†}tj |d¡}| |¡}| d¡| ddd¡| tj  |¡¡|  ¡|  tj  |¡¡|  d¡|  ¡| tj  |¡¡WdQRXdS)Nztest.cfgr;r<r) ÚtempfileZTemporaryDirectoryÚosr9Újoinr:rCr@rAÚexistsZSaver?Úremove_section)r&Ztdirr9r'rrrÚ test_save¢s    z IdleUserConfParserTest.test_saveN)r) r4r5r6r:rBrDrErHrIrOrrrrr7as     r7c@s(eZdZedd„ƒZedd„ƒZd@dd„Zdd „Ze  e j   d ¡d ¡d d „ƒZ e  e j   d ¡ d¡dd„ƒZdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„Zd3d4„Z d5d6„Z!d7d8„Z"d9d:„Z#d;d<„Z$d=d>„Z%d?S)AÚ IdleConfTestc Cs”i|_tjdd}tdkr(tj t¡}ntj t jd¡}xD|j D]:}tj  |d|¡}t |dƒ}|  ¡|j|<WdQRXqBWtj|_tƒt_dS)NT)Ú_utestÚ__main__rz../config-%s.defÚr)Ú config_stringrÚIdleConfr4rKr9ÚdirnameÚ__file__ÚabspathÚsysÚ config_typesrLÚopenÚreadÚ_warnÚ orig_warnr)ÚclsÚconfÚidle_dirÚctyper2ÚfrrrÚ setUpClass·s   zIdleConfTest.setUpClasscCs |jt_dS)N)r^rr])r_rrrÚ tearDownClassÈszIdleConfTest.tearDownClassFcCs tj|dS)N)rQ)rrU)r&rQrrrÚ new_configÌszIdleConfTest.new_configcCsltjdd}xZ|jD]P}t d¡|j|<|j| |j|¡t d¡|j|<|j| |j|¡qW|S)NT)rQr) rrUrZr"Ú defaultCfgr#rTr8r)r&r`rbrrrÚ mock_configÏs  zIdleConfTest.mock_configÚwinzthis is test for unix systemc Csü|jdd}tjddd0tjddd| | ¡d¡WdQRXWdQRXtjdddFtjd d d,t d ¡| | ¡d ¡WdQRXWdQRXWdQRXtjd dd:| t¡$| t¡| ¡WdQRXWdQRXWdQRXdS)NT)rQzos.path.expanduserz /home/foo)Ú return_valuezos.path.existsz/home/foo/.idlercú~z os.getcwdz/home/foo/cpythonzos.mkdirz/home/foo/cpython/.idlercz os.path.joinz/path/not/exists)rfrÚpatchr$Ú GetUserCfgDirÚ assertRaisesÚ SystemExitÚFileNotFoundError)r&r`rrrÚtest_get_user_cfg_dir_unixÝs $  $  z'IdleConfTest.test_get_user_cfg_dir_unixzthis is test for Windows systemc Csü|jdd}tjddd0tjddd| | ¡d¡WdQRXWdQRXtjdddFtjd d d,t d ¡| | ¡d ¡WdQRXWdQRXWdQRXtjd dd:| t¡$| t¡| ¡WdQRXWdQRXWdQRXdS)NT)rQzos.path.expanduserzC:\foo)rjzos.path.existszC:\foo\.idlercrkz os.getcwdzC:\foo\cpythonzos.mkdirzC:\foo\cpython\.idlercz os.path.joinz/path/not/exists)rfrrlr$rmrnrorp)r&r`rrrÚtest_get_user_cfg_dir_windowsôs $  $  z*IdleConfTest.test_get_user_cfg_dir_windowsc Cs6|jdd}d}tj ddi¡(tjd|d| ¡WdQRXWdQRX| |j ¡|j¡| |j  ¡|j¡x |j  ¡D]}|  |t j ¡q‚Wx |j   ¡D]}|  |t j¡q¤Wx6|j ¡D](\}}| |jtj |d|›d ¡¡qÆWx>|j  ¡D]0\}}| |jtj |jpd d|›d ¡¡qþWdS) NT)rQz /home/foor4Z__foo__zos.path.dirname)rjzconfig-z.defú#z.cfg)rfrrlÚdictZCreateConfigHandlersr+rgr rZrÚvaluesZassertIsInstancerr"r8Úitemsr$ÚfilerKr9rLZuserdir)r&r`raZdefault_parserZ user_parserZcfg_typer'rrrÚtest_create_config_handlers s" z(IdleConfTest.test_create_config_handlerscCs¦|jdd}tdƒ}t |¡|jd<t |¡|jd<| ¡|j}||jd  dd¡dƒ||jd  d¡dgƒ||jd  dd¡dƒ||jd  d¡dgƒdS)NT)rQz cfgparser.1r0zFoo Barr1) rfrrr"rgr8rZ LoadCfgFilesr$r%r*)r&r`r2r(rrrÚtest_load_cfg_files&s z IdleConfTest.test_load_cfg_filesc Cs>| ¡}t d¡"}| ¡| |jt|jƒ¡WdQRXdS)Nz&idlelib.config.IdleUserConfParser.Save)rhrrlZSaveUserCfgFilesr$Ú call_countÚlenr)r&r`ÚmrrrÚtest_save_user_cfg_files;s z%IdleConfTest.test_save_user_cfg_filesc Cs¤| ¡}|j}|| ddd¡dƒ||jddddddƒt d¡V}||jddd dddƒ|| ddd ¡dƒ||jddd d d d ƒ||jd ƒWdQRXdS)NrÚ EditorWindowÚwidthZ80r)réPzidlelib.config._warnZfontÚ NotExistsZNE)r!é)rhr$Ú GetOptionrrlrz)r&r`r(r]rrrÚtest_get_optionBs zIdleConfTest.test_get_optioncCs2| ¡}| dddd¡| | ddd¡d¡dS)Nrr;r<r1)rhr@r$rƒ)r&r`rrrrBNszIdleConfTest.test_set_optionc Csœ| ¡}| | dd¡ddddddd d g¡| | d d¡ddddddd d g¡| tj¡| d d¡WdQRX| tj¡| dd ¡WdQRXdS)Nr!rZGeneralr~ZPyShellÚIndentÚThemeÚKeysZHistoryÚ HelpFilesÚuserZfoobarZ notexists)rhr+ÚGetSectionListrnrÚInvalidConfigSetZInvalidConfigType)r&r`rrrÚtest_get_section_listTs      z"IdleConfTest.test_get_section_listc Cs| ¡}|j}|| dd¡dddœƒ|| dd¡dddœƒ| dd d d ¡| dd d d ¡t d¡|| d d¡d d dœƒWdQRXdS)Nz IDLE ClassicZnormalz#000000z#ffffff)Z foregroundZ backgroundZcursorZblackr ÚFoobarznormal-foregroundz#747474znormal-backgroundz#171717zidlelib.config._warn)rhr$Z GetHighlightr@rrl)r&r`r(rrrÚtest_get_highlightes   zIdleConfTest.test_get_highlightc CsL| ¡}| | dd¡| dd¡¡| tj¡| dd¡WdQRXdS)Nr!z IDLE Classicr‰Úbad)rhr$Z GetThemeDictrnrZ InvalidTheme)r&r`rrrÚtest_get_theme_dictws  z IdleConfTest.test_get_theme_dictcCs8| ¡}| | ¡| d¡¡| | ¡| d¡¡dS)Nr†r‡)rhr$Z CurrentThemeÚcurrent_colors_and_keysÚ CurrentKeys)r&r`rrrÚtest_get_current_theme_and_keysƒsz,IdleConfTest.test_get_current_theme_and_keyscCs| ¡}| | d¡d¡dS)Nr†z IDLE Classic)rhr$r‘)r&r`rrrÚtest_current_colors_and_keys‰sz)IdleConfTest.test_current_colors_and_keyscCs^tj}|jdd}dt_| | ¡d¡dt_| | ¡d¡dt_| | ¡d¡|t_dS) NT)rQÚwin32zIDLE Classic WindowsÚdarwinzIDLE Classic OSXz some-linuxzIDLE Modern Unix)rYÚplatformrfr$Ú default_keys)r&Úcurrent_platformr`rrrÚtest_default_keysŽs zIdleConfTest.test_default_keyscCsˆt d¡|j}tj}||ddgƒ||ƒdgƒ||dddgƒ||ddddgƒ||ddd ddgƒt d¡t d¡dS) Nzn [ZzDummy] enable = True [DISABLE] enable = False T)Z shell_onlyÚZzDummy)Ú editor_onlyF)Ú active_onlyZDISABLE)rrœ)Úuserextnr#r$r Z GetExtensionsrN)r&r(ZiGErrrÚtest_get_extensionsžs z IdleConfTest.test_get_extensionscCs0| ¡}| | | dd¡¡dddddg¡dS)Nr!r Z AutoCompleteZ CodeContextZFormatParagraphZ ParenMatchr›)rhr+ZRemoveKeyBindNamesrŠ)r&r`rrrÚtest_remove_key_bind_names°sz'IdleConfTest.test_remove_key_bind_namescCs>t d¡|j}|t d¡dƒ|t d¡dƒt d¡dS)Nz= [ZzDummy] enable = True zz-inr›zz-out)ržr#r$r ZGetExtnNameForEventrN)r&r(rrrÚtest_get_extn_name_for_event·s z)IdleConfTest.test_get_extn_name_for_eventcCs0t d¡| t d¡ddgi¡t d¡dS)Nz= [ZzDummy] enable = True r›z<>z!)ržr#r$r ZGetExtensionKeysrN)r&rrrÚtest_get_extension_keysÁs   z$IdleConfTest.test_get_extension_keyscCsNt d¡|j}tj}||dƒiƒdgdgdœ}||dƒ|ƒt d¡dS)Nz= [ZzDummy] enable = True rz!z!)z<>z <>r›)ržr#r$r ZGetExtensionBindingsrN)r&r(ZiGEBÚexpectrrrÚtest_get_extension_bindingsÍs z(IdleConfTest.test_get_extension_bindingscCs | ¡}|j}|| dd¡ddgƒ|| dd¡ddgƒ|| dd¡d d gƒ|| d d¡d gƒ|| d d¡d gƒ|| dd¡gƒ|| dd¡gƒdS)NzIDLE Modern Unixz<>zzzIDLE Classic Unixz z zIDLE Classic WindowszzzIDLE Classic MaczzIDLE Classic OSXz NOT EXISTS)rhr$Z GetKeyBinding)r&r`r(rrrÚtest_get_keybindingÚs      z IdleConfTest.test_get_keybindingcCs8tj}| ¡}dt_| | ¡| | ¡¡¡|t_dS)Nz some-linux)rYr—rhr$ZGetCurrentKeySetÚ GetKeySetr’)r&r™r`rrrÚtest_get_current_keysetës  z$IdleConfTest.test_get_current_keysetcCsj| ¡}|jd d¡|jd d¡|jd ddd¡|jd ddd¡| | d¡d d ¡dS) Nr rZFoobar_cfgBindingsZenableÚTrueZnewfoozzIDLE Modern Unixz <>r)rhrgr>Úsetr$r¦)r&r`rrrÚtest_get_keysetüs zIdleConfTest.test_get_keysetcCsL| ¡}| | d¡¡| | d¡¡| | d¡¡| | d¡¡dS)NÚcopyZcutzdel-word-rightz not-exists)rhr?Z IsCoreBindingrA)r&r`rrrÚtest_is_core_bindings z!IdleConfTest.test_is_core_bindingc Cs| ¡}| | d¡g¡| | d¡g¡| tj¡| | d¡g¡WdQRX| | ¡| d¡| d¡¡|jd  ddd¡|jd  ddd ¡|jd  dd d ¡|jd  dd d ¡| | d¡dddg¡| | ¡| d¡| d¡¡dS)Nr!r‰rrrˆÚ4zPython;https://python.orgÚ3zPython:https://python.orgÚ2z/Pillow;https://pillow.readthedocs.io/en/latest/Ú1z/IDLE;C:/Programs/Python36/Lib/idlelib/help.html)ÚIDLEz*C:/Programs/Python36/Lib/idlelib/help.htmlr°)ZPillowz(https://pillow.readthedocs.io/en/latest/r¯)ÚPythonzhttps://python.orgr­) rhr$ZGetExtraHelpSourceListrnrr‹r+ZGetAllExtraHelpSourcesListrr@)r&r`rrrÚtest_extra_help_source_lists& z(IdleConfTest.test_extra_help_source_listcCsœddlm}ddlm}ddlm}| ¡}|dƒ|ƒ}| ¡| |dd|d¡}|  |  |d d ¡|d |d dkr|d n|d |df¡|  ¡~dS)Nr)Úrequires)ÚTk)ÚFontZguiZ TkFixedFontT)rFrMÚrootrr~ZfamilyÚsizerZweight) Ú test.supportr´ZtkinterrµZ tkinter.fontr¶rhZwithdrawÚactualr$ZGetFontZdestroy)r&r´rµr¶r`r·rcrrrÚ test_get_font*s    (zIdleConfTest.test_get_fontcCs®| ¡}|j}|| ¡ddgƒ|| ¡dddgƒ|| ¡ddgƒ|| d¡dd d gƒ|| d ¡dd gƒ|| d ¡dddgƒ|| d¡dddgƒdS)Nz<>z z<>z z z<>zzIDLE Classic WindowszzzIDLE Classic OSXzzIDLE Classic Unixz z zIDLE Modern Unix)rhr$Z GetCoreKeys)r&r`r(rrrÚtest_get_core_keys=s  zIdleConfTest.test_get_core_keysN)F)&r4r5r6Ú classmethodrdrerfrhÚunittestZskipIfrYr—Ú startswithrqrrrxryr}r„rBrŒrŽrr“r”ršrŸr r¡r¢r¤r¥r§rªr¬r³r»r¼rrrrrP´s:          rPc@sNeZdZejZdZe ¡Zdd„Zdd„Z dd„Z dd „Z d d „Z d d „Z dS)ÚCurrentColorKeysTestz IDLE ClassiccCs~| | d¡|j¡t d¡| | d¡|j¡dtdd<| | d¡d¡dtdd<| | d¡|j¡t d¡dS)Nr†z< [Theme] default = True zIDLE NewrFz non-existent)r$Ú colorkeysÚ default_themeÚusermainr#rN)r&rrrÚtest_old_builtin_themeXs  z+CurrentColorKeysTest.test_old_builtin_themecCsht d¡| | d¡d¡dtdd<| | d¡d¡dtdd<| | d¡|j¡t d¡dS)NzZ [Theme] default = True name2 = IDLE Dark r†z IDLE DarkzIDLE NewrFz non-existentÚname2)rÃr#r$rÁrÂrN)r&rrrÚtest_new_builtin_themejs  z+CurrentColorKeysTest.test_new_builtin_themecCspt d¡| | d¡|j¡t d¡| | d¡d¡dtdd<| | d¡d¡t d¡t d¡dS)Nz\ [Theme] default = False name = Custom Dark r†z[Custom Dark] a=bz Custom Darkz non-existentrÅ)rÃr#r$rÁrÂÚuserhighrN)r&rrrÚtest_user_override_themezs   z-CurrentColorKeysTest.test_user_override_themecCs^| | d¡|j¡t d¡| | d¡d¡dtdd<| | d¡|j¡t d¡dS)Nr‡z` [Keys] default = True name = IDLE Classic Unix zIDLE Classic Unixz non-existentrF)r$rÁr˜rÃr#rN)r&rrrÚtest_old_builtin_keys‹s z*CurrentColorKeysTest.test_old_builtin_keyscCsht d¡| | d¡d¡dtdd<| | d¡d¡dtdd<| | d¡|j¡t d¡dS)Nz` [Keys] default = True name2 = IDLE Modern Unix r‡zIDLE Modern UnixzIDLE Classic UnixrFz non-existentrÅ)rÃr#r$rÁr˜rN)r&rrrÚtest_new_builtin_keysšs  z*CurrentColorKeysTest.test_new_builtin_keyscCspt d¡| | d¡|j¡t d¡| | d¡d¡dtdd<| | d¡d¡t d¡t d¡dS)Nz[ [Keys] default = False name = Custom Keys r‡z[Custom Keys] a=bz Custom Keysz non-existentrÅ)rÃr#r$rÁr˜ÚuserkeysrN)r&rrrÚtest_user_override_keysªs   z,CurrentColorKeysTest.test_user_override_keysN)r4r5r6r r‘rÁrÂr˜rÄrÆrÈrÉrÊrÌrrrrrÀMsrÀc@seZdZiiiidœZdd„Zdddiiddd iid d d iiidœZd d„Zdd„Zdd„Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„ZdS) Ú ChangesTest)rr r r cCs:|j}| dddd¡| dddd¡| d d d d ¡|S) NrÚMsecÚmitemÚmvalr ÚHsecÚhitemÚhvalr ÚKsecÚkitemÚkval)ÚchangesÚ add_option)r&r×rrrÚloadÀs zChangesTest.loadrÎrÏrÐrÑrÒrÓrÔrÕrÖcCst ¡|_dS)N)rZ ConfigChangesr×)r&rrrÚsetUpÌszChangesTest.setUpcCs| |j|j¡dS)N)r$r×Úempty)r&rrrÚ test_initÏszChangesTest.test_initcCs8| ¡}| ||j¡| dddd¡| ||j¡dS)NrrÎrÏrÐ)rÙr$ÚloadedrØ)r&r×rrrÚtest_add_optionÒszChangesTest.test_add_optioncCs |jj}| |ddddƒ¡| |ddddƒ¡| tddd¡| |ddddƒ¡| tddd¡| |ddddƒ¡| t dd¡¡t d¡dS)Nrr…ZwhatÚ0z use-spacesr°)r×Ú save_optionr?rAr$rÃÚ has_optionrN)r&ràrrrÚtest_save_optionØszChangesTest.test_save_optioncCs’| ¡}| | ¡¡| tddd¡| tddd¡| tddd ¡| d ddd¡| | ¡¡t  d¡t  d¡t  d¡dS) NrÎrÏrÐrÑrÒrÓrÔrÕrÖr) rÙr?Úsave_allr$rÃrÇrËrØrArN)r&r×rrrÚtest_save_addedäs  zChangesTest.test_save_addedcCsV|j}| dddd¡| dddd¡| ¡| t dd¡¡| t dd¡¡dS)Nrrˆr±ZidledocZELDIZcodeldi)r×ràrØrãrArÃrár?)r&r×rrrÚtest_save_helpðs zChangesTest.test_save_helpcCs|j}| dddd¡dS)Nrr…z use-spacesr°)r×rØ)r&r×rrrÚtest_save_defaultùszChangesTest.test_save_defaultc Cs„| ¡}| dd¡| ||j¡x\dD]T\}}t| |dd¡| ||¡| t¡|||t||WdQRXq(WdS)NrZfake))rrÎ)r rÔrFÚvalue)rÙZdelete_sectionr$rÝr r@rnÚKeyError)r&r×ZcfgtypeÚsectionrrrÚtest_delete_sections    zChangesTest.test_delete_sectioncCs"| ¡}| ¡| ||j¡dS)N)rÙÚclearr$rÛ)r&r×rrrÚ test_clear szChangesTest.test_clearN)r4r5r6rÛrÙrÝrÚrÜrÞrârärårærêrìrrrrrͼs       rÍc@seZdZdd„ZdS)Ú WarningTestc Cs´|j}tƒt_tƒ}t dd¡WdQRX|tjdhƒ|| ¡dƒtƒ}t dd¡WdQRX|| ¡dƒtƒ}t dd¡WdQRX|tjddhƒ|| ¡d ƒdS) NÚwarningÚkey)rîrïzwarning rÚwarn2Úyek)rðrñzwarn2 )r$r©rZ_warnedrr]Úgetvalue)r&ZEqualÚstderrrrrÚ test_warnszWarningTest.test_warnN)r4r5r6rôrrrrrísrírRé)Ú verbosity) rrrYrKrJr¹rrr¾rZidlelib.idle_test.mock_idlerr rrr r8rÃrÇrËržrrZTestCaserr7rPrÀrÍrír4rrrrrÚs8   ;SoV