,` :;:;;,:,,:,,:,,.` `` `````````````.` ```.`````````````.,......., ``````` ` ` `.'''+...``````````` ::,....`````` `,;;'+;,..................,,,,,,,,,,,,,,,,, ,,` :;,:,,,....````` ````````````````..` ```` `````````````.,:,,..... `````` ..''++.....``````` ,,,......`````` ``,';'+;,,.................,,,,,,,,,,,,,,,,, :,, ;;`...,........``````````````````. `` `` ``````````````.,;;:,:::, ` ..'';+...```.```` ,,,,......````````.;;'+;,,..................,,,,,,,,,,,,,,,, ,:, ;;.,,,,,::,,,,.`````````.``````.``` ``.`` `````````.``.,;,;,`::, ` ` .....`````````` `` ` :,,,......````````.';;+',,..................,,,,,,,,,,,,,,,, ,,: ';,,,,:::::,,,.`````````.` .``. `` ``` ` ````.```````.,::::;;;, ````````` .............```` ` ` ,,,,,.....````` ```;;;+',,................,,.,,,,,,,,,,,,,,, ,,, ';,,,,,,,,,,,,.````````..` ....```` ` ` `` `` ``````.,,....,,, `` ``````` .........`````````` :,,,..........``.``';'++:,................,.,,,,,,,,,,,,,,,, ;,, ';,,,,,,,:,,,,,``````````` ``` `````` ```` ` ````.` `;'''..```..` ..............``` :,,,,,,....`````.``';;++:,................,,,,,,,,,,,,,,,,,, ;;. ';:;;;;::.,,,,.```.`..`.., ` ` `.`,,`````..` `' `...,,,:..`; ` `,` .............`` ``` ;:,,,,.......```.``'''++:,..............,,,,,,,,,,,,,,,,,,,, ;:.``` ';.,.......,..````.. .,..`` ``... ``.` ;, ``.....;',,,:,'```````` :. .......``````..```` ::::,,.......```.``'''++:,....,.........,,,,,,,,,,,,,,,,,,,, ;:.``` ` ;:,,...`` . `` ..`. ` `..` ```````;.:,..:;;''::;;;::;;;;``````` :, ` .............````` ;:::,,,,.....`..```'''++:,,,...........,,,,,,,,,,,,,,,,,,,,, ;:.``` .`` `````,` .`` `` ` `````` ``` `'`` ```,::,:::::;:;;,`,;;;..,;`; ............`.`` :::,,,,.........```'''++:,,,,,.......,,,,,,,,,,,,,,,,,,,,,,, ;:.``` .`` ```` ;` ... ` ` ` ` ` `` `````` `+````.``.,,,::::::::;::.`` ..``;`` ...,...```````` :::,,,,,......`````;;'++:,,,,,,.,,..,,..,,,,,,,,,,,,,,,,,,,, ;,.```` ````` `` ` ...``` `,```` `` ``` ``` ```` `' ` `.`...,,,:::::::::::.````` `' ` `..,.,````````````` :,,,,,,,....```````;''++:,,,,,,,,,,,,,.,,,,,,,,,,,,,,,,,,,,, ;,.````` ``` ..,..` ` ` ` `` .` ` ``` ````+ ` ......,,:,:::::::::::,```` `+` `.........`...`` :,,,........```````;';++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;,.``````` .....`, `` `` `` ` ` `` `````` ' ``....,::::::::::::;:::,```` +``` ......````````````` :::,,,,....````````;''++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:..`````` ```., ........` ``` ..````````.`,` `` .....,:::::::::;;;;;;;;::,.```+````.......`````.`.`` ,,,.........``.````;';++;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;,..```````` ` ``` `` ```` ........`.` ` ``````.````````,``.`.`..,,::::::;;;;;;;;;;;;;;:..`,````.......`````.`````` ,::,,,,.,.....`````;''++;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,.`````````` ``` ``` `` `........ ``. ` ``.`. ```..`. .`...,:::::::;:;;;;;;;;;;;;::```````........````.````` ,,,,,..........````:';++;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,..`````````` `.......,` .` ` `.`````````` :```..,::::::::;:;;;;;;;;;;;;;:;``.```.......`````.````` ,:::,,,,.....``````;'''+;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,...`````````` `.......,``` ` ``.`..``...`;.`..,,::::::::;;;;;;;;;;;;;;;;:;`,```.........```.``````` ,:,,........,.```.`:'''+',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,...``````````` .,..,,,,::,.,....``,.``` `` `.,`..,,:::::::::;;:;;;;;;;';'';;;;,;```........````..`````` .:::,,,......``.`.`:'''+',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:::,...``````````` ` ..`````..,:.,.`` ` ``````` `````..,,,,:::;;:::;;;;;;;;;;;''''';;;;'```........````.`````` .::,,.....,..,```.`:'''+':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,....````````````` ```````````` ,.```....,,.`` ```` ````.````.`...,,:::::;;;:;;;:;;;;;;;;'''''';;;;```......``````.`````` ` .;,,,,.......`.``.`:'''+':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,....`````````````` `` :.......,,..`` ` ```````` ````..,::,,::::;;:;;;;;;;;;;;;;'''''';;;````......`````..````` .:::,,:,,,...,``.``,';;++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,.....`````````````` ````````` :.........,.`` ````````..` .`...,,,,:::::::;;;;;;;;;;;;;;''''''';;;,``.........```.``````` `:,,,,.........````,'''++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,......```````````````` `````````` ;..........,,.` `` `...,````..,,:,:,:::::;;;;;;;;;;;;;;;;''''''';;;``.......```````.````` .:,,,,,,......```.`.';;++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,.......``````````````` `````````` `````:.......,,,``` ```.,`..`,....,,::,::::::;;;;;;;;;;;;;;;;;'''''''';.``......`````.`````` ` ,:,,,........``...`.'''++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,.........```````````````````````````````````:........., ``` .````` ````.`.,:::,:::::::;;;;;;;;;;;;;;;'''''''''';,``....```````````` ::::,,,........``````.';;++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,........```````````````...``..```````````` :.........,`.`````````,``````.,,::,,::;;;;;;;;;;;;;;;;;'';''';''''';:`...`..``````````. ` ::::,,,,.......``````.'';++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :;:,,.........````````````````````` `````````:.........` . ```:``````...``,,::,::;;;;;;;;;;;;;;;;;;''''''''''''';;`...````````.:';. ` ::::,,,,........````.+'''++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :;:,,.........```````````````````````````````` :........,`.``` ``` .```..`,..:::,;;;;;;'''';;;';;;''''''''+++'''''';`.`......,,,,,. :,,,,,,,,.........`;+'';'++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :::,,..........````````````````````````` :........,.` `````...```.``.`.::::';'+++'''';;';;;''''+++++++''''''';;...````````;` ;;,,,,,,....,..,;'''+''';++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :;:,............```````````````` ````````` :........, ` ``````````.,,.``.:::;;;'+++++++';;;;''+++++++++'++''''';:....```````:` ` ` ''++';';;;;;;:;;;;'''':..++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;;:,...........````````````````````````` :.........``````..`````.,.:...:::;;'''++++++'';;;'+++++++++++++'''''',.....```````` ` ;'';;;;;;:::;;:;;;;,.....++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;;:,...........```````````````````````````` `` :........``````````.````.``..,:::;''''+++++++'''''++++##+++++++'''''',..;...`.```` ` ` :;'';;;:::::::,..........'+;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;;:,,...........```````````` ` ```````````````` :.`....,,` ```````.````````...:::;'''+;;'++++;;'''+++#+++'+++++'''''',..;...,,.,`` ` ::::,,,,.................'+;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,............```````````````````````` :.``..,,,``.````````````..:,,.:,:;'++;;;'++++';;;'+###+++++'++++''''',............` ` ;:::,,,,.................'+;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,............```````````````` ```````` :.`````..```.`````..```.,,,:,,:,:;'';;+#+++++';;;'+###+####+++++''''',.....`````` ``` ':::,,,,.................'+',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,..............``````````````````````` :..````..````...``.```.,:,..,,:,:;'+;+++#++++';;;'+###+###++++++'''''....,,`...`` ``` '';:,,,,......,,,..,.....'+':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,..............`````````` `` ````` :```````...`,.`````````,,.,,,,:,:;''+''#++++';;:;'+++++'''++++++''''',.,.,..````` ``` '''+''''':,,,,,,,.,,.....;++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;;:,,..............```````````````` `` :``````...`..`...`````.:,,,,,,:,:;'';'''''+';;;:;''+++++''++++++'''''.....``....` `` ''''''''':::,,,,,,,,.....:++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,..............`````````````` ` `` ;,,...`...``.`......``.,,,,,,,,:;:;:;;;;'+'';;;::;'++''+++'+'''''''''......``..`` `` ''''+'''';,,,,,,,,,,.....,++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,...............```````````` ` ```` :,..```...`.........:`..,,,.,,,::;:;;'''''';;;::;;'++''''''''''''''''`.....``.``` ` ''''+'''';,,,,,,,,,,......++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,................``````..`````` ` ``````` :...............```....,.,,,:,,:::::;;;;;;;;;;,:;;''+'''';;;;;;'''''''''..```::.` ``` +'''+''';::::::,,,,,.....`++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,..............```````...`````````````.:;'':,.``..........., `.:;;;;;:;;,::::,::;;;;;;::,:;;;''''';;;;;;''''''++'+..``.;;,`` `` ''''''''.,:,,,,,,,,,.....`++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,..............```````..,,,,::,,,,.``.`.....````;;;;;:;;;;;, `````````,.+'::::::::;;;;;:;:::;;'''''';;;;;''''''''+++`.``.;;:`` `` '''''''+.,:,,,,,,,:,......++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,...............`````..,::...`` `. .....`` `,:::::::::. `````````;.';:::::::::;;;:;::;;;;''++'';;;;''''''''++'+`.```,,.`` ` ` ';;'+''+,,::;:,,,.........++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,................`````...,,```` ` ````.,::::::,````````````.':::::::::;;;;;;:;;;;''''+'';;;;''''''''++'+`.```````.. `` ` ';;;:::::,,,,,,...........++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;::,,................```......`` ``,,,:::,,:`````..`````.':::::::::;:;;':;'''''+++++'';;'''''''''++'+,.``````` ``';;;;:::::,,.,,:;;;;,.....++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,.................````.....`` ` . ` ````````` ``..````````.;;;:::::;;;;;'''+#+''++#+++'''''''''''''++'+,```````` ``;;;;;::;::''''''';;;:.....++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,.................``......``` ` ` . . `````````:`````````````.;;:::::;;;;;'+'++#++++##++++''''''''''''++'+......``` `` ```;;;;;::;:,'''''''';;:.....++::,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,.................``......``` ` ` ` .` `,:::::,,,,:,``..`````````:;:::::;;;''+';++''++++++++++'''''''''''++'+.........```` ```;;;;;::;::'''''''';;;.....'+;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,..........................``` ` ` ` .`` ``,::,`,:::::,`````````````;'::;;;;;''++;;''''+++++++++++''''''+'''+++,........````` ```;;;;;::;::+''''''';;;.....'+;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,...................``....````` ` `` ```````,:,`..:,,,:,`````````````:':;;;;;;''+';;;'''+++++++++'++'''''''''+++.,.......```` ```;;;;;;:;::'''''''''';.....;+;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,...................````````.`` ``` ``` ``:::...:::::.``...````````:;::;;;;'+++;;;;;''+++++++++'+++++++'''+++',.....```````` ````;;'';;::::+'''''''';;.....:#':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,....................``.```````` ``. `` ```:::::::,:::``````````````:,:;;;;''++''';;;'''''++++++++++++++'''++''..`.......``.` ````;;+'';::::+'''''''';'.....:#':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,...................```````````` ` . .`````::::,,:,,,,```````````` `,:;;;;'''+'''';;;;;'''+++'++++++++++'''++'',.......```````````:;;;;:::::+'''''''';'.....:#':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,.....................``.```..`` . ,`````::::,,,,,,,``````````````,::;;;;;'+'''''''''''++++++++++++++++''+'',..........`````````;:;;;::;::';;''''';;'.....,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,......................`.````.`` ` ,`````;:,,:,,,,,,``````````````.::;;;;;'+'++'''++''++++++++#+++'++'+''+''`.........``````````::::::::::+'''''';;;;.....,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,.....................``.```..``` ` .`````;::,,,,,,,,`.````````````.::;;;;;'''+##++##+###########++'''++''+',.....```````````````'::::::,,,,,,..............#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,........................```````` ` ``````;:,:,,,,,,,..`.`````````` ;;;;;;;;;'';'''';'''''''+++++++''++'''#'..........`..````````'':::::,,,,,,,,,,.........,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ;:,,,......................`.`````````` ` `.````;:::,,:,,,,...`````````` `;;:;;;;;';;;'';;;;;'''+++++'+'''++''';;.........``````.`````'+#':::,,,,,,,,,,.......`:+##:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ::,,,......................`.```.`.````` `, .````;::::;::::......`````````` ,;;;;;;;;;;'''''''''''+++'+''''++'''::...,,.......`````````++++#++';::,,,,,::;''+'++'+##:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ::,,,,.......................`````.``` ` ` .````;:.,..;:::.......`.````` ``.;;;;;;;;;;;'''''''''++++++'''++'''';:.............````````++++++++';';;;:;;;;;';;''''##:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,......................`.```...``` ` ..```;;:;;;;;::.......````````` ;;;;;;;;;;;;''''''''+''+++'''+'+''':;.........`````.``````'+++++'';;;;;;;;;;;;;;;;;;;#+::,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ::,,,,......................````....`` ` ,````;;;;:::;:;..`....``````` ` ;;;;;';;;;;;;''''''''''+++''++++'':.....`.```````.`` ````:++;::::::,,,,,........,,,,.#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ::,,,,.......................````.`.`` ` ..```;;:::,,:::......`.`.````` ` ;;;;;';;;;;;''''''''''++++''++++'',...................``::++::::::,,,,,+.',,,,,,,,,:,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,.......................`````````` .````:,.::::::,.,,::.```````` ;;;';;;;;;;;;;';;'''''+'''++++++'',....`.``````````...,;++++::::::,:,,,:,,...,,,,,:,.+#:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,.....................````....`` .````,...,,::,.,:;;''''':,:,..,:::;;;;;;';;;;;;;;;';'''''''''++++''+,,....:``.......`.,,;+++++::::,,,,,,,,,,...,,.,,,,,+#::,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,.....................````...`````` `` .,`.``;;;;;::;;;;;;;;;;;;..'::,,::::;';;;;;;;;;;;;;;;;'''''''+++++''+.,.....```........,,:+++++::::::::::,,...,,,,,,,,..+#;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,.....................```````.``````:;';:.``.;;;;;:;;::::;;;;;;;.`'::,...,:;';';;';;;;;;;;;'''''''''+++++'+':::,........;;:,..,,,+++++:::,,,,,,,,,,,.,,,,,,,,..++;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,.,..................````.....`.:;'';;,.:``.;;;::::::::::::;;;;``;::.....,;''''''';;;;;;;;'''''''+++++++++'#+';,..````````...,,,+++++:::,::::,,,.,,.,.,,,,..,,'+;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,...................`````.....:;;:,::,;;,``.;:::::,,,;;;:;;;;;:``;::....,.:'''''''';;;;;;''''''++++++++++++,...,,:;;'''''''+.,,,'++++:::,::::::,::,,,,,,,,,,,,'+;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,..................````````.......;';:,,``.;:::::;;;:::;;;;;;;``;::``,...,'''''''''';;''''''''++++++++++++,,,,..`,..``...,..,,,+'+'+,,,,::,,,,,,,,,,,,,,,::,,;#':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,..................````........,;;;,.....`.;:::;;;;;;:::::;;:;``;::``..,.,''''''''''''''''''++++++++++++++,,,....;;;;;;::::.,,,+'''',,,,:::,,,,,,,,,,,,,,,,,,;+':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,.................````````...,;;:,.....``,;:;:;;;;;::;:;;;;;;``:::``...,.''''''''+''''''+++++++#+++++++++,,,..........;;:;.,,,+'''',,,,,::,:,:,,,:,,,,,,,,,,:++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,................````````...,,........``,;::::::;;;:;:;;;:;;`.:::``,,..,:''''+'+++++++++++++#######+++++',........,.`;:;'.,,,+'''',,,,,,,,,,,,,,,,,,,:::,,,:++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,.................```````.............``,;:::;;;;;:::;;;;;;;`.;::``....,;''''+++++++++++++#####+#####+++#++,``:;:.'.'';;'.,,,''''+,,,,,,,,,,,,,,,,:::::::,,,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,.................``````.``.............`:;;:::,:::::::;;;;;:`.;::``..:;'+'''++++++++++##+############+####++++';+;;+++:;+.,,,+'''',,,,:::,:,,,,,,,,,,.......++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,.................``....................:;;::::::::::::;:;;;``::::'+++''+;''+++++++++++++#+#########++##@##++++++'.```;++.,,.+'';',,,,,,,,,,,....,,....,,.,.++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,...................`````...............:;::;;,;,.;,:;.;.,,;`,;'''++++'++;'''++++++++++++###########+###@####++###++'.'++.,..''';;,,,,,,,:,,,,,:,:,,,:,,,,..#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,....................``...............`.;;;;:;,;,,;,;;.;;'''++''''+''+++#;'''++++++++++#+###########+########+++###++++'+.,..'';';,,,,,,,,,,,,,,,,,,,,.,,,..++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,................,..................,...,:::;:;;;;;;';;'''++''''''''++++#''''+++++++++++############+###@##########++++++;,..+'';',,,,,,:,,:,,,,::,,::,,,,,.++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,.,.............,,;''''+++'';;;;:,,..`......``;'''''+''+'''''''''''++++#';'''+++++++++##############################+++++++'++;;':,,,,,,,,,,,,,,,,,...,,,,.++:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,................,'+;;;;;;;;;;:,,,,,,.......'''+++'''++++++++''''''++++++;''''++++++++++########++#####@##########+++++++++++'+'';.,,,,,,,,,,,,,,,,,,,,,,.,++::,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,.,..............,++;;;;;'+;;;::,:::,:;;;''''+++++++++++++++++'''''++++++;;''''++++++++++###+##++###################+++##+#++++++++'..,:,,:::::,:,:,:,:,,,,+#;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,.,...............,++;;;';;';;:::::::::;;;;''''+++++++++++++++++++''++++'#;;;;''+++++++++++#++++++#+####@############+++#+++++++++++++',,,,,,,,,,,,,,,,,,,.,'+;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,..............,,++;;:;;;:;;:::::::::;:''+'''++++++++++++++++++++'++++'+;;;;;'''+++++++++++++++##+#####################++++++'++++++++,::::::::;:::;,,,,,,'#;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,,...............,++:;+++::::;::::::::;''''++'+++++++++++++++++++++++++++;;;;;''''''++++++++++++########################+++#++++++++++#+.,,:::,:,,,:,,,::::;#;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,.,.............,,++:;#++:;:'',::::::;'''''++++++++++++++++++++++++++++++;;;;;;;''''++++++++++++++#######################++#+++++++++##++,,,,,,,,,,,,:.,,.,:#;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,...............,++;'##:;:;'':,::::'''''''++++++++++++++++++++++'++++++';;;;;;;;''''+++++++++++++#######################+##++#++##+##++++.,,,.,,,,,,,,,.,,,#;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,,..............,,+';'+#++++++,,,,,'''''''+++++++++++++++#####++'+++++++';;;;;;;;''''+++++++++++++##########################++#++#####+++++........,,..,..,,+':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,...............+':+++++++++,,,,''''''''++++++#+++++++++####+''++++++++;;;;;;;;'''''''''++++++++#+########################+##++#####+++###,,,,:::::,,,,,,,#':,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,.................+';'+:'+++++.,:'+'''''''++++++#+++++++++####+'++++++++#;;;;;;;;''''''''''''+++++++#######################++##+#####+++####:,,,,,,,,,.,,,,,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,................+';:;::++++++''''++'''''++++++##++++++++###+++++++++++#':;;;;;;;''''+''''''+++++++######################+++##+#####++###++#,,,,,,,,..,,,,,#+:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,,................+';#;;;+++'++;'''+++''''+++#++#++++++++###++++++++++++#+::;;;;;;''''''''''++++++'#######################++###+####+++###+#+;,,,,,,,......,##:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,...............,+';'';':'++++''''++++'''+++#++##++++++####+++++++#+++++++;;;;;;;;''''';;''+++'''+#######################+####+####+++##+++++,,,,,,,,,,,,,,##::,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,..,..............,+;;:,..''#++'''+++++++''+++#++##+++++++###+++++++#++++++#'::;;;;;;';;;;;''''''''############################+####+++####+++++,,,,,,...,.,,##:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,.,..............:+......;+++'''''++#+#++++++##++#+++++++###+++++++#++##++++;::;;;;;;;;;;''''''''#############################+####+++###++++++;,:,:,,....,.##:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,,,..............;+...,..++++''''+++++#+##+++##++##++++++##++++++++##++#+++++':;;;;;;;;;;;;';;;'###################################++####++++#++,,,,,....,,,+#:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,..............;+......;;:;'''+++++#+####++###+##++++++##+++++++###++#+++++++;:;:;;;;;;;;;;;'###################################+++####+++##+++,,,,.,,...,'#:,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,...............'+.........''''+++++#+#########+##+++++###+++++++###+##+++++++++++':;;;;;;;;+###################################++++###+++###+++',,,,,,.,,,'#::,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,..............'+........'''''+++++#+#########+##+++++###+++++++###++#+++++++######;;;;;;'#####################################+++#####+###+++++,...,.,,,,;#::,,,,,,,,,,,,,,,,,,,,,,,,,,,,, :,,,,,,,,,,,,,..............++,.....,,''++++++++###########+##+++++###+++#+++###+##+++++++#+######+##########################################+#####++###++++++.,,,,,,,,:#::,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,..............++,.....;'''++++++++###########+##+++++###+++#+++###++#+##+++++################################################+############++##++;.,,,,,,,:#;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,..............++,.....;''++++++++############+###+++####++##+++###++#+######+++###########################################################+###++#.,.,,,,,,@;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,..............++:..,,.''+++++++++############+###++####+++##+++###++##+#####+################################################+################+++;...,..,:;;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,.............:::...,.''+++++++++################++####+++##+++####++########################################################################++++++######+;;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,..............;:+'''''''++++++++#################++###+++###+++###+++########################################################################+++##+######';;:,,,,,,,,,,,,,,,,,,,,,,,,,,,,: ,,,,,,,,,,,,,,,.............::+''''''+++++++++#################++###+++###++#####++##++####################################################################++###+'+++'+''':,,,,,,,,,,,,,,,,,,,,,,,,,,,,: ,,,,,,,,,,,,,,,,..,.........;'++++'''+++++++#+#################++##+++####++######+###+#####################################################################+###++;;;;;;;;:,,,,,,,,,,,,,,,,,,,,,,,,,,,:: ,,,,,,,,,,,,,,,,,...........,;;;;;''++++++#########################++#####++######+#############################################################################+#,::::::::,,,,,,,,,,,,,,,,,,,,,,,,,,::: ,,,,,,,,,,,,,,,,............,,,,,,''++++++++#######################+######++#####++############################################################################++#'::::::::,,,,,,,,,,,,,,,,,,,,,,,,,,::: ,,,,,,,,,,,,,,,,,,..........,,,,,'''++++++++##############################++#####++###############################################################################+::::::::,,,,,,,,,,,,,,,,,,,,,,,:,,::: :,,,,,,,,,,,,,,,,...........,,,,:''+++++++++#############################+++######+##############################################################################+++,:::::::,,,,,,,,,,,,,,,,,,,,,,,::::: :,,,,,,,,,,,,,,,,,,.........,,,,'''++++++##+#############################++######++##############################################################################++#,:::::::,,,,,,,,,,,,,,,,,,,,,,,::::: :,,,,,,,,,,,,,,,,,,,,.......,,,,'''++++++###+###########################+++#####################################################################################++##;:::::::,,,,,,,,,,,,,,,,,,,,:,::,::: ::,,,,,,,,,,,,,,,,,.........,,,''''+++++++###########@#####+#############++#####################################################################################+####:::::::,:,,,,,,,,,,,,,,:,,::::::::: ::::,,,,,,,,,,,,,,,,,..........'''+++++#++++#########@####################+#########################################################################################+:::::::::,,,,,,,,,,,,,,,,:,:::::::: ::::::,,,,,,,,,,,,,,,..........'''+++++####++########@#######@############+#####+##############################################################################+###++;,:::::,,,,,,,,,,,,,,,:,,:::::::::: ::::::::,,,,,,,,,,,,,.........,''+'++++##############@######@@###########++#######+################################################################################+++,,,,,,,,,,,,,,,,,,:,,::,:::::::::: :::;::::::,,,,,,,,,,,,........'''+++++++####################@############++#######################################################################################+#+#:,,,,,,,,,,,,,,:,,,:,,:::::::::::: ;;;;;:::::::,,,,,,,,,........;''++++++#+####################@############+#############################################################@#####@@####################++#+,,,,,,,,,,,,,,,:,,,:::::::::::::: ;;;;;;::::::,,,,,,,,,,......,''+++++++++##+##########@@#####@###########++#############################################################@#####@####################+###++,,,,,,,,,,,,,::::::::::::::::::: ;;;;:::::::::,,,,,,,,,,,....''+++++++++++#############@####@@###########++#############################################################@##@##@########################++:,,,,,,,,,,,,::::::::::::::::::: ;;:::::::::::,,,,,,,,,,,....''+++++++#++#############@@####@@###########++#############################################################@##@##@#######################+#++,,,,,,,,,,,:::::::::::::::::::: ;;:::::::::,,,,,,,,,,,,,...:''+++++++++++#############@####@@###########+##############################################################@##@##@#########################++;,:::,::::::::::::::::,:::::::: ::::::::::::,,,,,,,,,,,....'''+++++++##+##############@####@@###########+##############################################################@##@##@####################+#+##++#,::::,,:::::::::::::::;:;;;::, :::::::::::,,,,,,,,,,,,,,,,+'+++++++++##+############@@###@@@##########+############################################################@##@##@@#@##########################+#::::::::::::::::::::::,;:,,,,: ;::::,:::::,,,,::::,,,,,..'+++++++++++##############@@@###@@###########+#########################################+#####+;'+####';:'+#@@@##@@@#############################+,::::::::::::::::::,,,,,,:;;; ;::::,,::,.,,,,::::,,,,,,:++++++++++++##############@#@###@@###########+########################################:,::;,;,':::;;;::::##@@@##@@@##@#########################+#:::::::::::::,:::,,,,,:;;::;; ;::::,::,,.,,,,,:::,,,,,.''+++++++++++#############@@@@####@##########++####################################:;+',..,,:';,';;+,::;''##@@###@@@#@###########################++,:::::::,,,,,,,,,,,,;#'++++' ;;:::;;:,...,,,,::::,,,,;'++++++++++++#############@@@@####@@#########+#####################################:;;;,,,'++##'############@####@@@#############################+#::,,,,::';:,,,,,,;##@@@@@@@@ ;;::';;:,,..,,,,::::::,,'''++++++++++#############@@@@@####@################################################++##+,+#######################@@@##############################++::,,;:::,,,,,'#@@@@@@@@@@@@ :;;:';::,...,,,,::::::,,++++++++++++++############@@@@#####@@########++####################################################################@@################################:;,::,,,,,:+@@@@@@@@@@@@@@@ :;';';::,,..,,,,::::;:::++'+++++++++++############@@@@###@#@@########+#####################################################################@@##########################+#####+;;,,,,##@@@##@@@@@@@@@@@@@ :;;+';;:,,..,,,,,::::::;'++'+++++++++###########@@@@@@#####@#########+#####################################################################@@@@@###################+##########:,,,,####@@@#@@@@@@@@@@@@@ :;;+';::,,..,,,,,:::;:;''''+++++++++++###########@@@@@#####@@#############################################################################@@@@@############################++++,,:++'#@@@@#@@@@@@@@@@@@@ :;;++;::,,..,,,,::::::'''''++++++++#+############@@@@@##################################################################################@@@@@@@##################+#############':;'+@@@@@@@@@@@@@@@@@@@@ ::;'+;::,,...,,,,::::''+'+++++++++++############@@@@@@##################################################################################@@@@@@@########################+###+''';;+@@@@@@@@@@@@@@@@@@@@@@ ::;'+;::,,..,,,,,:::;++++++++++++++++#########@@@@@@@@@##################################################################################@@@@@@######################+##+''';;''+##@@#@@@@@@@@@@@@@@@@@@ ::;'#;::,,...,,,,:::+;::;;'+++++++#+###########@@@@@@@@#####@############################################################################@@@@@####################+#+#+';;;;;''''+@@@@@@@@@@@@@@@@@@@@@@ ::;;+;::,,...,,,,:::;::::::;;'##++#############@@@@@@@###@@@@############################################################################@@@@@@@@################+###;;;;;;;;;;''#@@@@@@@@@@@@@@@@@@@@@@ ::;;#;::,,...,,,::::::::::::::;'################@@@@@@@@@@@@##############################################################################@@@@@@@@#################';;;;;;;;;;''''@@@@@@@@@@@@@@@@@@@@@@ :::;+;::,,...,,,,::::::::::::::;;+###########@@##@@@@@@@@@@@###############################################################################@@@@@@@@@#############+;;;;;;;;;;';;''''@@@@@@@@@@@@@@@@@@@@@ :::;+;;:,,...,,,,:::::::::::::::;;'###########@@@@@@@@@@@@@@###############################################################################@@@@@@@@###########+#';;::;;;;;;;;;;''''#@@@@@@@@@@@@@@@@@@@# :::;+';:,,,..,,,,:::::::::::::::;;;;##########@@@@@@@@@@@@@#################################################################################@@@@@@@############;:;;:;;;;;;;;;;;'''''@;+@@@@@@@@@@@@@@@#@ :::;'+;::,,..,,,,::::::::::::::::;;;'+######@@@@@@@@@@@@@@@####################################################################################@@@@###########;;:;:;::;;';;;;;;;'''''';#@@@@@@@@@@@@@@## :::;'+;::,,..,,,:::::::::::::::;;;;;;'+###@@@@@@@@@@@@@@@@#####################################################################################@@@@##########;;:::;;;:;;;;;;;;;;'''''++'+@@@@@@@@@@@@@## :::;'+;::,,..,,,:::::::::::::::;;;;;'''###@@@@@@@@@@@@@@@@######################################################################################@@@#########;;;;:::::;;;:;;;;;;;'''''+@@+#@@@@@@@@@@@@@# :::;;+;::,,,..,:::::::::::::::;;;;;''''+##@@@@@'@@@@@@@@#######################################################################################@@@@#@######';;;;;:;:::;;;;;;;;;;;'''''#@@@@@@@@@@@@@@@@# :::;;#;::,,,..,::::::::::::::;;;;;;''''++#@@@@@:@@@@@@@@####################################################################################@@@@@@:@@#####+;;;;;;;:::::;;;;;;;;;'''''''@@@@@@@@@@@@@@@@@ ::::;+;::,,,.,:::::::::::::::;;;;;'''''++#@@@@@,#@@@@@@@####################################################################################@@@@@@:;:@####;;;;;;;;;:;::;;;;;;;;;;;'''''#@@@@@@@@@@@@@@@@ ::::;+;::,,,,,:::::::::::::::;;;;;'''''++#@@@@:,;@@@@@@@####################################################################################@@@@@@;;;'@##';;;;;;;:;;:;::;;:;;;;;;;'''''+@@@@@@@@@@@@@@@@ ::::;+';::,,,:::::::::::::::;;;;;''''++++##@#;,,,@@@@@@@####################################################################################@@@@@@:;::###'';;;;;;;:;:;;;;:;;;;;;;;;'''''#@@@@@@@@@@@@@@@ ::::;'';::,,,::::::::::::::;;;;;'''''++++##@#.,,:@@@@@@####################################################################################@@@@@@@';;:;@+'';;;;;;;;;;:::;:;;;;;;;;;'''''+@@@@@@@@@@@@@@@ ::::;'+;::,,:::::::::::::::;;;;;'''''++++##@:,,,:@@@@@@###################################################################################@@@@@@@++;;;:#+''';;;;;;;;;;::::;;;;;;;;;;'''''#@@@@@@@@@@@@@@ ::::;'+;::,:::::::::::::::;;;;''''''++++####.,,,;#@@@@###################################################################################@@@@@@@#++;;;;;@''';;;;;;;;;:;:::::::;;;;;;''''''###@@@@@@@@@@@ ::::;;+;:::::::::::::::::;;;;''''''++++####',,,,,@@@@@#################################################################################@@@@@@@@@##+;;;;:'+''';;;;;;;;;:::;;:;:;;;;;;;';''';;;;;;;''''''+ ::::;;+;:::::::::::::::::;;;;''''''++++####,,,,,,#@@@@##############################################################################@@@@@@@@@@@@###;;;;;;;'''';;;;;;;:;:::::::;;;;;;;;''''';;;;;;;;;;;;;
Christophe Cérin
christophe.cerin@lipn.univ-paris13.fr
Jan 23, 2018
Dans un article de IEEE Spectrum de décembre 2017, Luke Wagner explique son travail et celui de Alon Zakai de Mozilla pour faire en sorte que les applications développées en C ou C++ puissent s'exécuter dans le navigateur. La finalité de leur travail consiste donc à compiler les code C/C++ en JavaScript qui est vu comme l'assembleur du système d'exploitation i.e. le navigateur.
Les outils discutés dans l'article permettent de gérer à la fois la couche de présentation (HTML et Javacript) et la couche de programmation (au sens de la programmation impérative C/C++ i.e. au sens du contrôle du flux d'execution d'un programme C/C++). C'est aussi un des avantages de ce genre d'outil qui pousse à une certaine convergence des langages.
L'argumentaire donné dans l'article concerne principalement les questions de performance que l'on peut attendre des codes issus des langages du Web mais la réalité profonde du travail est bien celle-ci : faire en sorte que le navigateur soit le système d'exploitation dans lequel tourne des services JavaScripts. Comme C/C++ sont connus pour être des langages performants (pour la gestion mémoire, pour ce qui concerne l'optimisation de code que l'on peut effectuer sur le code), les auteurs proposent un compilateur de C/C++ vers Javascript. Les projets dont ils parlent sont :
A titre d'exemple, vous pouvez lancer le projet tutoré du Takuzu (il vous faut le navigateur Firefox). Attention, il semble qu'il y ait aussi un bug sur le scanf() : vous allez voir une première fenêtre input (il faudra entrer votre valeur puis faire ok). A ce moment une deuxiàme fenêtre de dialogue va apparaitre et là il faudra faire annuler. J'ai ajouté une temporisation de 5 secondes après chaque saisie. Les sources en C du projet Takuzu sont ici. La commande Emscripten pour compiler le source en HTML et Javascript est :
emcc takuzu_orig.c -o takuzu_orig.html
Une autre version du Takuzu est disponible avec les sources.
Une horloge digitale est également disponible. Les sources sont dans ce répertoire ainsi que le fichier pour construire le fichier HTML. Bien entendu il faut adapter les chemins d'accès.
Pour aller plus loin et afficher du texte en couleur il faut programmer avec la librairie C curses (ou ncurses). Les versions Javascript sont :
Attention, à cause des virus Meltdown et Spectre il n'est actuellement plus possible (janvier 2018) de programmer avec des pthreads. Voir la note https://blog.mozilla.org/security/2018/01/03/mitigations-landing-new-class-timing-attack/. Ainsi le code suivant va générer une erreur :
A packaging (31MB) of Curses.js, a Javascript porting of curses library using Emscripten is available.
The initial version of Curses.js we are working with is available through https://github.com/mad4j/curses.js?files=1
In our packaging, we use:
See file build.sh in the distribution. Launch it to build Curses.js
Directory PDCurses-3.5/demos/ contains the sources of C files (including two new demos related to the Takuzu game). The HTML+JS output files are placed in directory demos/
To succeed with the compilation, the following files have been modified regarding the initial distributions:
#define SDL_DisplayFormat SDL_DisplayFormatAlpha #define SDL_Delay emscripten_sleep
#include <stdlib.h>to be able to compile with emcc.
// if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_EVENTS) < 0) if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)