You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <!-- $Id: index.html 595 2015-04-17 09:50:36Z imoore76 $ -->
  4. <!-- Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com) -->
  5. <head>
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
  7. <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
  8. <meta http-equiv="Expires" content="0"/>
  9. <meta http-equiv="Cache-Control" content ="no-cache"/>
  10. <meta http-equiv="Cache-Control" content ="no-store, must-revalidate, max-age=0"/>
  11. <meta http-equiv="Cache-Control" content ="post-check=0, pre-check=0"/>
  12. <meta http-equiv="Pragma" content="no-cache"/>
  13. <meta name="viewport" content="width=device-width, initial-scale=1">
  14. <!-- Icon && title -->
  15. <link rel="shortcut icon" href="images/vbox/OSE/VirtualBox_win.ico"/>
  16. <link rel="icon" href="images/vbox/OSE/VirtualBox_win.ico"/>
  17. <title>phpVirtualBox - VirtualBox Web Console</title>
  18. <!-- Style sheets -->
  19. <link rel="stylesheet" type="text/css" href="css/jquery-ui.css"/>
  20. <link rel="stylesheet" type="text/css" href="css/jquery.projectPlugins.css"/>
  21. <link rel="stylesheet" type="text/css" href="css/tipped.css" />
  22. <link rel="stylesheet" type="text/css" href="css/layout.css"/>
  23. <!-- External or jQuery related scripts -->
  24. <script type="text/javascript" src="js/jquery-1.11.2.min.js"></script>
  25. <script type="text/javascript" src="js/jquery-ui-1.11.4.min.js"></script>
  26. <script type="text/javascript" src="js/jquery.tipped-2.1b.min.js"></script>
  27. <script type="text/javascript" src="js/jquery.scrollTo-min.js"></script>
  28. <script type="text/javascript" src="js/jquery.jec-1.3.1.js"></script>
  29. <!-- Oracle RDP Control -->
  30. <script type="text/javascript" src="rdpweb/webclient.js"></script>
  31. <script type="text/javascript" src="rdpweb/swfobject.js"></script>
  32. <!-- Internal / project related scripts -->
  33. <script type="text/javascript" src="endpoints/config.js"></script>
  34. <script type="text/javascript" src="js/jquery.projectPlugins.js"></script>
  35. <script type="text/javascript" src="js/phpvirtualbox.js"></script>
  36. <script type="text/javascript" src="js/utils.js"></script>
  37. <script type="text/javascript" src="js/eventlistener.js"></script>
  38. <script type="text/javascript" src="js/chooser.js"></script>
  39. <script type="text/javascript" src="js/datamediator.js"></script>
  40. <script type="text/javascript" src="js/dialogs.js"></script>
  41. <script type="text/javascript" src="js/canvasimages.js"></script>
  42. <!-- Main Setup -->
  43. <script type='text/javascript'>
  44. $(document).ready(function(){
  45. /* Synchronously load requirements */
  46. for(var i = 0; i < vboxEndpointConfig.require.length; i++) {
  47. $.ajax({
  48. type: "GET",
  49. url: vboxEndpointConfig.require[i],
  50. async: false,
  51. dataType: "script"
  52. });
  53. }
  54. /*
  55. * Parse cookies
  56. */
  57. vboxParseCookies();
  58. /*
  59. *
  60. * Begin sanity checks
  61. *
  62. */
  63. /**
  64. * Check that someone isn't accessing this from their local filesystem
  65. */
  66. try {
  67. if(window.location.toString().search('file:') == 0) {
  68. vboxAlert("You are accessing phpVirtualBox from your local filesystem.\
  69. phpVirtualBox must be accessed through your web browser. E.g. \
  70. http://localhost/phpVirtualBox (its actual URL may vary).");
  71. return;
  72. }
  73. } catch(err) {
  74. // noop
  75. }
  76. /*
  77. * If everything loaded correctly, trans() should be defined in
  78. * js/language.php and language data should be present.
  79. * If not, there is a PHP error somewhere.
  80. */
  81. if(typeof trans != "function" || typeof __vboxLangData == "undefined") {
  82. trans = function(s){return s;};
  83. vboxAlert("An unknown PHP error occurred. This is most likely a syntax error in\
  84. config.php in phpVirtualBox's folder. The most common errors are an unclosed\
  85. quote or a missing\
  86. semicolon in a configuration item that has been entered (e.g.\
  87. location, username, or password).<p>Depending on your PHP configuration,\
  88. navigating directly to <a href='config.php'>config.php</a> in your web\
  89. browser may display the PHP error message.</p>\
  90. <p>If find that this is not the case,\
  91. or have no idea what this error message means, please raise the issue\
  92. at <a href='http://sourceforge.net/p/phpvirtualbox/discussion/help/'\
  93. >http://sourceforge.net/p/phpvirtualbox/discussion/help/",{'width':'50%'});
  94. return;
  95. }
  96. // Sanity checks passed. Begin processing
  97. // Check for server setting (?server=xxxx in URL)
  98. if(location.search) {
  99. var query = location.search.substr(1).split('&');
  100. for(var kv in query) {
  101. kv = query[kv].split('=');
  102. if(kv[0] == 'server') {
  103. vboxSetCookie('vboxServer',unescape(kv[1]));
  104. location = location.href.substr(0,location.href.length-location.search.length);
  105. return;
  106. }
  107. }
  108. }
  109. /*
  110. * Resizable panes functionality
  111. */
  112. $('#vboxResizeBar').draggable({cursor:(jQuery.browser.opera ? 'e-resize' : 'col-resize'),axis:'x',zIndex:99,helper:function(){
  113. $('#vboxResizeBarTmp').remove();
  114. var h = $('#vboxResizeBar').parent().height();
  115. return $('#vboxResizeBar').clone(false)
  116. .attr({'id':'vboxResizeBarTmp'}).unbind('mouseleave')
  117. .css({'background':'#ccc','height':h+'px'});
  118. },scroll:false,'start':function(e,ui){
  119. $('#vboxResizeOverlay').remove();
  120. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'e-resize' : 'col-resize')});
  121. $('#vboxPane').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:100%;height:100%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;cursor:'+(jQuery.browser.opera ? 'e-resize' : 'col-resize')}));
  122. $('#vboxResizeBar').data('vboxX',e.pageX);
  123. },'stop':function(e){
  124. $('#vboxResizeBarTmp').remove();
  125. $('#vboxResizeOverlay').remove();
  126. $('body').enableSelection().css({'cursor':'default'});
  127. var nx = $('#vboxChooserDiv').width() + (e.pageX - $('#vboxResizeBar').data('vboxX'));
  128. $('#vboxChooserDiv').css('width',(nx)+'px');
  129. vboxSetLocalDataItem("vboxPaneX",($('#vboxChooserDiv').width()));
  130. $('#vboxChooserPane').css('width',$('#vboxChooserDiv').css('width'));
  131. $(window).trigger('resize');
  132. }}).css('cursor',(jQuery.browser.opera ? 'e-resize' : 'col-resize')).parent().disableSelection();
  133. /*
  134. progress resize n / s
  135. */
  136. $('#vboxResizeBarProgress').draggable({cursor:(jQuery.browser.opera ? 'n-resize' : 'row-resize'),axis:'y',zIndex:99,helper:function(){
  137. $('#vboxResizeBarTmp').remove();
  138. return $('#vboxResizeBarProgress').clone(false)
  139. .attr({'id':'vboxResizeBarTmp'})
  140. .css({'background':'#ccc','position':'absolute','left':'0','right':'0','margin-left':'auto','margin-right':'auto'});
  141. },scroll:false,'start':function(e,ui){
  142. $('#vboxResizeOverlay').remove();
  143. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'n-resize' : 'row-resize')});
  144. $('#vboxPane').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:100%;height:100%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;cursor:'+(jQuery.browser.opera ? 'n-resize' : 'row-resize')}));
  145. $('#vboxResizeBarProgress').data('vboxY',e.pageY);
  146. },'stop':function(e){
  147. $('#vboxResizeBarTmp').remove();
  148. $('#vboxResizeOverlay').remove();
  149. $('body').enableSelection().css({'cursor':'default'});
  150. var nx = $('#vboxProgressOps').height() + ($('#vboxResizeBarProgress').data('vboxY') - e.pageY);
  151. $('#vboxProgressOps').css({'height':(nx)+'px','overflow':'auto'}).parent().css({'height':(nx)+'px'});
  152. vboxSetLocalDataItem("vboxPaneY",($('#vboxProgressOps').height()));
  153. $('#vboxResizeBarProgressEW').css({'height':(vboxGetLocalDataItem("vboxPaneY")-4)+'px'});
  154. $(window).trigger('resize');
  155. }}).css('cursor',(jQuery.browser.opera ? 'n-resize' : 'row-resize')).parent().disableSelection();
  156. /*
  157. Progress resize E / W
  158. */
  159. var vboxOpsPaneEW = 400;
  160. if(vboxGetLocalDataItem('vboxOpsPaneEW')) {
  161. vboxOpsPaneEW = vboxGetLocalDataItem('vboxOpsPaneEW');
  162. } else {
  163. vboxSetLocalDataItem('vboxOpsPaneEW', vboxOpsPaneEW);
  164. }
  165. $('#vboxResizeBarProgressEW').css({'left':vboxOpsPaneEW+'px','top':'0'});
  166. // inject CSS
  167. $('head').append('<style type="text/css" id="vboxProgressOpsStyle">div.vboxProgressOpTitle { width: '+vboxOpsPaneEW+'px; }</style>');
  168. // Show draggablebar onmouseenter
  169. $('#vboxProgressOps').hover(function(){
  170. if($(this).children().length == 1) return;
  171. $('#vboxResizeBarProgressEW').css({'display':'inline-block','height':($(this)[0].scrollHeight-2)+'px'});
  172. },function(){
  173. $('#vboxResizeBarProgressEW').css({'display':'none'});
  174. });
  175. // Draggable bar
  176. $('#vboxResizeBarProgressEW').draggable({cursor:(jQuery.browser.opera ? 'e-resize' : 'col-resize'),axis:'x',zIndex:99,helper:function(){
  177. $('#vboxResizeBarTmp').remove();
  178. return $('#vboxResizeBarProgressEW').clone(false)
  179. .attr({'id':'vboxResizeBarProgressEWTmp'}).css({'background':'#ccc'});
  180. },scroll:false,'start':function(e,ui){
  181. $('#vboxResizeOverlay').remove();
  182. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'e-resize' : 'col-resize')});
  183. $('#vboxPane').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:100%;height:100%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;z-index:10;cursor:'+(jQuery.browser.opera ? 'e-resize' : 'col-resize')}));
  184. $('#vboxResizeBarProgressEW').data('vboxX',e.pageX);
  185. },'stop':function(e){
  186. $('#vboxResizeBarTmp').remove();
  187. $('#vboxResizeOverlay').remove();
  188. $('body').enableSelection().css({'cursor':'default'});
  189. var nx = parseInt(vboxGetLocalDataItem('vboxOpsPaneEW')) + (e.pageX - $('#vboxResizeBarProgressEW').data('vboxX'));
  190. $('#vboxResizeBarProgressEW').css({'left':nx+'px'});
  191. vboxSetLocalDataItem('vboxOpsPaneEW',nx);
  192. // re-inject CSS
  193. $('#vboxProgressOpsStyle').empty().remove();
  194. $('head').append('<style type="text/css" id="vboxProgressOpsStyle">div.vboxProgressOpTitle { width: '+nx+'px; }</style>');
  195. }}).css('cursor',(jQuery.browser.opera ? 'e-resize' : 'col-resize'));
  196. /*
  197. * Resize panes when the window changes sizes
  198. */
  199. $(window).resize(function(){
  200. // Hide
  201. $('#vboxChooserResizePane').children().children().css({'display':'none'});
  202. var h = $('#vboxResize').innerHeight();
  203. $('#vboxChooserResizePane').children().children().css({'height':h+'px','overflow-y':'auto','overflow-x':'hidden','display':''});
  204. // special for resize bar
  205. $('#vboxResizeBar').css({'height':(h-10)+'px'});
  206. });
  207. /*
  208. * Refresh data when host changes
  209. */
  210. $('#vboxPane').on('hostChange',function(){
  211. var l = new vboxLoader();
  212. l.add('getConfig',function(d){$('#vboxPane').data('vboxConfig',d.responseData);$('#vboxPane').trigger('configLoaded');});
  213. l.add('vboxGetGuestOSTypes',function(d){$('#vboxPane').data('vboxOSTypes',d.responseData);});
  214. l.add('vboxSystemPropertiesGet',function(d){$('#vboxPane').data('vboxSystemProperties',d.responseData);});
  215. l.add('vboxGetMedia',function(d){$('#vboxPane').data('vboxMedia',d.responseData);});
  216. l.add('hostGetDetails',function(d){$('#vboxPane').data('vboxHostDetails',d.responseData);});
  217. l.add('vboxRecentMediaGet',function(d){$('#vboxPane').data('vboxRecentMedia',d.responseData);});
  218. l.add('vboxRecentMediaPathsGet',function(d){$('#vboxPane').data('vboxRecentMediaPaths',d.responseData);});
  219. l.add('vboxGetEnumerationMap',function(d){$('#vboxPane').data('vboxMediumVariants',d.responseData);},{'class':'MediumVariant','ValueMap':1});
  220. l.onLoad = function(){
  221. $('#vboxPane').trigger('hostChanged');
  222. };
  223. l.run();
  224. });
  225. /*
  226. * Load panes all and data after valid login
  227. */
  228. $('#vboxPane').on('login', function() {
  229. var l = new vboxLoader();
  230. // Get data and store it using data()
  231. l.add('getConfig',function(d){$('#vboxPane').data('vboxConfig',d.responseData);$('#vboxPane').trigger('configLoaded');});
  232. l.add('vboxGetGuestOSTypes',function(d){$('#vboxPane').data('vboxOSTypes',d.responseData);});
  233. l.add('vboxSystemPropertiesGet',function(d){$('#vboxPane').data('vboxSystemProperties',d.responseData);});
  234. l.add('vboxGetMedia',function(d){$('#vboxPane').data('vboxMedia',d.responseData);});
  235. l.add('hostGetDetails',function(d){$('#vboxPane').data('vboxHostDetails',d.responseData);});
  236. l.add('vboxRecentMediaGet',function(d){$('#vboxPane').data('vboxRecentMedia',d.responseData);});
  237. l.add('vboxRecentMediaPathsGet',function(d){$('#vboxPane').data('vboxRecentMediaPaths',d.responseData);});
  238. l.add('vboxGetEnumerationMap',function(d){$('#vboxPane').data('vboxMediumVariants',d.responseData);},{'class':'MediumVariant','ValueMap':1});
  239. // Load HTML panes and append them to their respective locations
  240. l.addFileToDOM('panes/chooser.html',$('#vboxChooserPane'));
  241. l.addFileToDOM('panes/topmenu.html');
  242. l.addFileToDOM('panes/toolbar.html');
  243. l.addFileToDOM('panes/tabs.html',$('#vboxPaneTabContent'));
  244. l.onLoad = function() {
  245. // Resize to last setting
  246. if(vboxGetLocalDataItem('vboxPaneX')) {
  247. $('#vboxChooserDiv').css('width',(vboxGetLocalDataItem('vboxPaneX'))+'px');
  248. } else {
  249. vboxSetLocalDataItem('vboxPaneX', $('#vboxChooserDiv').innerWidth());
  250. }
  251. if(vboxGetLocalDataItem('vboxPaneY')) {
  252. var nx = vboxGetLocalDataItem('vboxPaneY');
  253. $('#vboxProgressOps').css({'height':(nx)+'px'}).parent().css({'height':(nx)+'px'});
  254. } else {
  255. vboxSetLocalDataItem('vboxPaneY', $('#vboxProgressOps').height());
  256. }
  257. $('#vboxResizeBarProgressEW').css({'height':(vboxGetLocalDataItem("vboxPaneY")-4)+'px'});
  258. // Let everyone know that no vms are selected
  259. $('#vboxPane').trigger('vmSelectionListChanged',[vboxChooser]);
  260. };
  261. // Trigger resize event to size panes
  262. l.onShow = function() { $(window).trigger('resize'); };
  263. l.hideRoot = true;
  264. l.run();
  265. });
  266. /**
  267. * Check for valid session and display login box if one does not exist
  268. * @params {Boolean} tried - true if login was attempted before this call
  269. */
  270. var vboxCheckSession = function(tried) {
  271. // check session info
  272. if($('#vboxPane').data('vboxSession') && $('#vboxPane').data('vboxSession').valid) {
  273. // Session is valid, trigger login
  274. $('#vboxPane').trigger('login');
  275. return;
  276. }
  277. // Was there an error? Assume it was displayed and just return from function
  278. if($('#vboxPane').data('vboxSession') && !$('#vboxPane').data('vboxSession').success) {
  279. return;
  280. }
  281. // No valid session. Show login pane
  282. $('#vboxLogin').find('input[name=password]').val('');
  283. $('#vboxLogin').dialog('open');
  284. if(!$('#vboxLogin').find('input[name=username]').val()) $('#vboxLogin').find('input[name=username]').focus();
  285. else $('#vboxLogin').find('input[name=password]').focus();
  286. // Display error if we tried to log in
  287. if(tried) {
  288. vboxAlert(trans('Invalid username or password.','UIUsers'),{'width':'400px'});
  289. }
  290. };
  291. /** Load login form */
  292. var login = new vboxLoader();
  293. login.add('getSession',function(d){$('#vboxPane').data('vboxSession',$.extend({'success':d.success},d.responseData));});
  294. login.addFileToDOM('panes/login.html');
  295. login.onLoad = function(loader) {
  296. var buttons = {};
  297. buttons[trans('Log in','UIUsers')] = function() {
  298. // Login button triggers login attempt
  299. var u = $('#vboxLogin').find('input[name=username]').val();
  300. var p = $('#vboxLogin').find('input[name=password]').val();
  301. if(!(u&&p)) return;
  302. $('#vboxLogin').dialog('close');
  303. // A valid login should create a valid session
  304. var trylogin = new vboxLoader();
  305. trylogin.add('login',function(d){$('#vboxPane').data('vboxSession',$.extend({'success':d.success},d.responseData));},{'u':u,'p':p});
  306. trylogin.onLoad = function() { vboxCheckSession(true);};
  307. trylogin.run();
  308. };
  309. // Create but do not open dialog
  310. if($.browser.webkit) heightadd = 5;
  311. else heightadd = 0;
  312. $('#vboxLogin').dialog({'closeOnEscape':false,'width':300,'height':'auto','buttons':buttons,'modal':true,'autoOpen':false,'dialogClass':'vboxDialogContent','title':'<img src="images/vbox/OSE/about_16px.png" class="vboxDialogTitleIcon" /> phpVirtualBox :: ' + trans('Log in','UIUsers')});
  313. $('#vboxLogin').find('input[name=username]').first().focus();
  314. // Trick loader into not showing root pane again
  315. loader.hideRoot = false;
  316. // Login form is loaded, run check for valid session
  317. vboxCheckSession();
  318. };
  319. login.hideRoot = true;
  320. login.run();
  321. }); // </ document.ready event >
  322. </script>
  323. </head>
  324. <body>
  325. <div id='vboxPane' style='height: 100%; margin: 0px; padding: 0px;'>
  326. <table id='vboxTableMain' cellpadding=0 cellspacing=0 style="height: 100%; width: 100%; padding: 0px; margin: 0px; border: 0px; border-spacing: 0px;">
  327. <tr style='vertical-align: middle;'>
  328. <td style='height:20px;border:0px;padding:0px;margin:0px;border-spacing:0px;'>
  329. <div id='vboxMenu'>
  330. <!--
  331. Top menu bar
  332. -->
  333. </div>
  334. </td>
  335. </tr>
  336. <tr style='vertical-align: middle;'>
  337. <td id='vboxToolbarMain' style='height: 1%' class='vboxToolbarGrad'>
  338. <!--
  339. VM list toolbar
  340. -->
  341. <div id='vboxPaneToolbar'></div>
  342. <!--
  343. Tabs / buttons
  344. -->
  345. <div id='vboxTabsList'></div>
  346. </td>
  347. </tr>
  348. <tr style='vertical-align: top;'>
  349. <td style='border:0px;padding:0px;margin:0px;border-spacing:0px;' id='vboxResize'>
  350. <table style='width:100%;border:0px;padding:0px;border-spacing:0px;'>
  351. <tr id='vboxChooserResizePane' style='vertical-align: top;'>
  352. <td id="vboxChooserPane" style='padding:0px;border-spacing:0px;margin:0px;'>
  353. <!--
  354. VM List
  355. -->
  356. </td>
  357. <td id='vboxResizeTD' style='border: 0px; margin: 0px; padding: 0px; text-align: center;'>
  358. <div style='margin:0px;padding:0px;width:4px;height:100%;'>
  359. <div style='position: absolute; margin: 0px; padding:2px; width: 0px; height: 100%;' id='vboxResizeBar' ></div>
  360. </div>
  361. </td>
  362. <td id="vboxPaneTabContent" style='width:100%;border:0px;padding:0px;border-spacing:0px;margin:0px'>
  363. <!--
  364. Tab content
  365. -->
  366. </td>
  367. </tr>
  368. </table>
  369. </td>
  370. </tr>
  371. <!--
  372. Progress operation list resize bar
  373. -->
  374. <tr style='padding: 0px; margin: 0px; vertical-align: middle;'>
  375. <td id='vboxResizeTDProgress' style='border: 0px; margin: 0px; padding: 0px; text-align: center; height: 5px; vertical-align: middle'>
  376. <div style='width:99%; margin:0 auto; padding:2px;' id='vboxResizeBarProgress' ></div>
  377. </td>
  378. </tr>
  379. <tr style='vertical-align: top; padding: 0px;'>
  380. <td style='border:0px;padding:0px;margin:0px;border-spacing:0px;height:1%'>
  381. <div id='vboxProgressOps' style='height:80px;overflow:auto;position:relative'>
  382. <!--
  383. Resize bar for E/ W
  384. -->
  385. <div style="position:absolute;z-index:1;margin:0px;border:0px;padding:1px;width: 0px;background:#aaa;display:none;" id='vboxResizeBarProgressEW' ></div>
  386. <!--
  387. Progress operation list
  388. -->
  389. </div>
  390. </td>
  391. </tr>
  392. </table>
  393. </div>
  394. <div onclick="javascript:window.location.href='./';" style="height:100%; cursor:pointer;">&nbsp;</div>
  395. </body>
  396. </html>