Index: plugins/aboutConfig/_define.php
===================================================================
--- plugins/aboutConfig/_define.php	(revision 967)
+++ plugins/aboutConfig/_define.php	(revision 589)
@@ -16,5 +16,5 @@
 	/* Description*/		"Manage every blog configuration directive",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'0.5'
+	/* Version */			'0.4'
 );
 ?>
Index: plugins/aboutConfig/index.php
===================================================================
--- plugins/aboutConfig/index.php	(revision 907)
+++ plugins/aboutConfig/index.php	(revision 589)
@@ -121,9 +121,9 @@
 <?php
 if (!empty($_GET['upd'])) {
-	dcPage::message(__('Configuration successfully updated'));
+	echo '<p class="message">'.__('Configuration successfully updated').'</p>';
 }
 
 if (!empty($_GET['upda'])) {
-	dcPage::message(__('Settings definition successfully updated'));
+	echo '<p class="message">'.__('Settings definition successfully updated').'</p>';
 }
 ?>
Index: plugins/antispam/_define.php
===================================================================
--- plugins/antispam/_define.php	(revision 967)
+++ plugins/antispam/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Generic antispam plugin for Dotclear",
 	/* Author */			"Alain Vagner",
-	/* Version */			'1.4',
+	/* Version */			'1.3.1',
 	array(
 		'permissions' =>	'usage,contentadmin',
Index: plugins/antispam/_prepend.php
===================================================================
--- plugins/antispam/_prepend.php	(revision 920)
+++ plugins/antispam/_prepend.php	(revision 270)
@@ -24,5 +24,5 @@
 $__autoload['dcFilterWords'] = dirname(__FILE__).'/filters/class.dc.filter.words.php';
 
-$core->spamfilters = array('dcFilterIP','dcFilterIpLookup','dcFilterWords','dcFilterLinksLookup');
+$core->spamfilters = array('dcFilterIP','dcFilterWords','dcFilterIpLookup','dcFilterLinksLookup');
 
 $core->url->register('spamfeed','spamfeed','^spamfeed/(.+)$',array('dcAntispamURL','spamFeed'));
Index: plugins/antispam/filters/class.dc.filter.ip.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.ip.php	(revision 907)
+++ plugins/antispam/filters/class.dc.filter.ip.php	(revision 536)
@@ -103,8 +103,8 @@
 
 		if (!empty($_GET['added'])) {
-			$res .= dcPage::message(__('IP address has been successfully added.'),true,false,false);
+			$res .= '<p class="message">'.__('IP address has been successfully added.').'</p>';
 		}
 		if (!empty($_GET['removed'])) {
-			$res .= dcPage::message(__('IP addresses have been successfully removed.'),true,false,false);
+			$res .= '<p class="message">'.__('IP addresses have been successfully removed.').'</p>';
 		}
 
@@ -130,5 +130,5 @@
 		if ($core->auth->isSuperAdmin()) {
 			$res .= '<label class="classic" for="globalip_'.$type.'">'.form::checkbox(array('globalip', 'globalip_'.$type),1).' '.
-			__('Global IP (used for all blogs)').'</label> ';
+			__('Global IP').'</label> ';
 		}
 
@@ -152,6 +152,4 @@
 			'<div style="'.$this->style_list.'">';
 
-			$res_global = '';
-			$res_local = '';
 			while ($rs->fetch())
 			{
@@ -168,26 +166,10 @@
 				}
 
-				$item =
+				$res .=
 				'<p style="'.$p_style.'"><label class="classic" for="'.$type.'-ip-'.$rs->rule_id.'">'.
 				form::checkbox(array('delip[]',$type.'-ip-'.$rs->rule_id),$rs->rule_id,false,'','',$disabled_ip).' '.
 				html::escapeHTML($pattern).
 				'</label></p>';
-
-				if ($rs->blog_id) {
-					// local list
-					if ($res_local == '') {
-						$res_local = '<h4>'.__('Local IPs (used only for this blog)').'</h4>';
-					}
-					$res_local .= $item;
-				} else {
-					// global list
-					if ($res_global == '') {
-						$res_global = '<h4>'.__('Global IPs (used for all blogs)').'</h4>';
-					}
-					$res_global .= $item;
-				}
-			}
-			$res .= $res_local.$res_global;
-
+			}
 			$res .=
 			'</div>'.
Index: plugins/antispam/filters/class.dc.filter.linkslookup.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.linkslookup.php	(revision 913)
+++ plugins/antispam/filters/class.dc.filter.linkslookup.php	(revision 270)
@@ -43,20 +43,12 @@
 				continue;
 			}
-
-			$domain = preg_replace('/^[\w]{2,6}:\/\/([\w\d\.\-]+).*$/','$1',$b['host']);
-			$domain_elem = explode(".",$domain);
-
-			$i = count($domain_elem) - 1;
-			$host = $domain_elem[$i];
-			do
-			{
-				$host = $domain_elem[$i - 1].'.'.$host;
-				$i--;
-				if (substr(gethostbyname($host.'.'.$this->server),0,3) == "127" ) 
-				{
-					$status = substr($domain,0,128);
-					return true;
-				}				
-			} while ($i > 0);
+			
+			$domain = preg_replace('/^(.*\.)([^.]+\.[^.]+)$/','$2',$b['host']);
+			$host = $domain.'.'.$this->server;
+			
+			if (gethostbyname($host) != $host) {
+				$status = substr($domain,0,128);
+				return true;
+			}
 		}
 	}
Index: plugins/antispam/filters/class.dc.filter.words.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.words.php	(revision 907)
+++ plugins/antispam/filters/class.dc.filter.words.php	(revision 536)
@@ -109,11 +109,11 @@
 
 		if (!empty($_GET['list'])) {
-			$res .= dcPage::message(__('Words have been successfully added.'),true,false,false);
+			$res .= '<p class="message">'.__('Words have been successfully added.').'</p>';
 		}
 		if (!empty($_GET['added'])) {
-			$res .= dcPage::message(__('Word has been successfully added.'),true,false,false);
+			$res .= '<p class="message">'.__('Word has been successfully added.').'</p>';
 		}
 		if (!empty($_GET['removed'])) {
-			$res .= dcPage::message(__('Words have been successfully removed.'),true,false,false);
+			$res .= '<p class="message">'.__('Words have been successfully removed.').'</p>';
 		}
 
@@ -124,5 +124,5 @@
 		if ($core->auth->isSuperAdmin()) {
 			$res .= '<label class="classic" for="globalsw">'.form::checkbox('globalsw',1).' '.
-			__('Global word (used for all blogs)').'</label> ';
+			__('Global word').'</label> ';
 		}
 
@@ -145,6 +145,4 @@
 			'<div style="'.$this->style_list.'">';
 
-			$res_global = '';
-			$res_local = '';
 			while ($rs->fetch())
 			{
@@ -156,24 +154,10 @@
 				}
 
-				$item = '<p style="'.$p_style.'"><label class="classic" for="word-'.$rs->rule_id.'">'.
-					form::checkbox(array('swd[]', 'word-'.$rs->rule_id),$rs->rule_id,false,'','',$disabled_word).' '.
-					html::escapeHTML($rs->rule_content).
-					'</label></p>';
-
-				if ($rs->blog_id) {
-					// local list
-					if ($res_local == '') {
-						$res_local = '<h4>'.__('Local words (used only for this blog)').'</h4>';
-					}
-					$res_local .= $item;
-				} else {
-					// global list
-					if ($res_global == '') {
-						$res_global = '<h4>'.__('Global words (used for all blogs)').'</h4>';
-					}
-					$res_global .= $item;
-				}
-			}
-			$res .= $res_local.$res_global;
+				$res .=
+				'<p style="'.$p_style.'"><label class="classic" for="word-'.$rs->rule_id.'">'.
+				form::checkbox(array('swd[]', 'word-'.$rs->rule_id),$rs->rule_id,false,'','',$disabled_word).' '.
+				html::escapeHTML($rs->rule_content).
+				'</label></p>';
+			}
 
 			$res .=
Index: plugins/antispam/index.php
===================================================================
--- plugins/antispam/index.php	(revision 907)
+++ plugins/antispam/index.php	(revision 776)
@@ -99,5 +99,5 @@
 <html>
 <head>
-  <title><?php echo ($filter_gui !== false ? sprintf(__('%s configuration'),$filter->name).' - ' : '').$page_name; ?></title>
+  <title><?php echo $page_name; ?></title>
   <?php
   echo
@@ -132,5 +132,5 @@
 
 	if (!empty($_GET['del'])) {
-		dcPage::message(__('Spam comments have been successfully deleted.'));
+		echo '<p class="message">'.__('Spam comments have been successfully deleted.').'</p>';
 	}
 
@@ -163,5 +163,5 @@
 
 	if (!empty($_GET['upd'])) {
-		dcPage::message(__('Filters configuration has been successfully saved.'));
+		echo '<p class="message">'.__('Filters configuration has been successfully saved.').'</p>';
 	}
 
Index: plugins/attachments/_define.php
===================================================================
--- plugins/attachments/_define.php	(revision 967)
+++ plugins/attachments/_define.php	(revision 843)
@@ -16,5 +16,5 @@
 	/* Description*/	"Manage post attachments",
 	/* Author */		"Dotclear Team",
-	/* Version */		'1.1',
+	/* Version */		'1.0',
 	array(
 		'permissions' =>	'usage,contentadmin,pages',
Index: plugins/attachments/_public.php
===================================================================
--- plugins/attachments/_public.php	(revision 944)
+++ plugins/attachments/_public.php	(revision 464)
@@ -89,5 +89,5 @@
 		$if = array();
 		
-		$operator = isset($attr['operator']) ? dcTemplate::getOperator($attr['operator']) : '&&';
+		$operator = isset($attr['operator']) ? $this->getOperator($attr['operator']) : '&&';
 		
 		if (isset($attr['is_image'])) {
Index: plugins/blogroll/_define.php
===================================================================
--- plugins/blogroll/_define.php	(revision 965)
+++ plugins/blogroll/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Manage your blogroll",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'1.3',
+	/* Version */			'1.2',
 	array(
 		'permissions' =>	'blogroll'
Index: plugins/blogroll/_public.php
===================================================================
--- plugins/blogroll/_public.php	(revision 945)
+++ plugins/blogroll/_public.php	(revision 776)
@@ -140,6 +140,5 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -152,5 +151,5 @@
 		
 		return
-		'<div class="links'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="links">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		$links.
Index: plugins/blogroll/_widgets.php
===================================================================
--- plugins/blogroll/_widgets.php	(revision 954)
+++ plugins/blogroll/_widgets.php	(revision 270)
@@ -19,5 +19,5 @@
 	public static function initWidgets($w)
 	{
-		$w->create('links',__('Blogroll'),array('tplBlogroll','linksWidget'),null,'Blogroll list');
+		$w->create('links',__('Blogroll'),array('tplBlogroll','linksWidget'));
 		$w->links->setting('title',__('Title:'),__('Links'));
 		
@@ -34,12 +34,5 @@
 		$w->links->setting('category',__('Category'),'','combo',$categories);
 		
-		$w->links->setting('homeonly',__('Display on:'),1,'combo',
-			array(
-				__('All pages') => 0,
-				__('Home page only') => 1,
-				__('Except on home page') => 2
-				)
-		);
-		$w->links->setting('class',__('CSS class:'),'');
+		$w->links->setting('homeonly',__('Home page only'),1,'check');
 	}
 	
Index: plugins/blogroll/edit.php
===================================================================
--- plugins/blogroll/edit.php	(revision 907)
+++ plugins/blogroll/edit.php	(revision 270)
@@ -101,5 +101,5 @@
 {
 	if (!empty($_GET['upd'])) {
-		dcPage::message(__('Category has been successfully updated'));
+		echo '<p class="message">'.__('Category has been successfully updated').'</p>';
 	}
 	
@@ -121,5 +121,5 @@
 {
 	if (!empty($_GET['upd'])) {
-		dcPage::message(__('Link has been successfully updated'));
+		echo '<p class="message">'.__('Link has been successfully updated').'</p>';
 	}
 	
Index: plugins/blogroll/index.php
===================================================================
--- plugins/blogroll/index.php	(revision 987)
+++ plugins/blogroll/index.php	(revision 717)
@@ -219,21 +219,21 @@
 <?php
 if (!empty($_GET['neworder'])) {
-	dcPage::message(__('Items order has been successfully updated'));
+	echo '<p class="message">'.__('Items order has been successfully updated').'</p>';
 }
 
 if (!empty($_GET['removed'])) {
-	dcPage::message(__('Items have been successfully removed.'));
+		echo '<p class="message">'.__('Items have been successfully removed.').'</p>';
 }
 
 if (!empty($_GET['addlink'])) {
-	dcPage::message(__('Link has been successfully created.'));
+		echo '<p class="message">'.__('Link has been successfully created.').'</p>';
 }
 
 if (!empty($_GET['addcat'])) {
-	dcPage::message(__('category has been successfully created.'));
+		echo '<p class="message">'.__('category has been successfully created.').'</p>';
 }
 
 if (!empty($_GET['importlinks'])) {
-	dcPage::message(__('links have been successfully imported.'));
+		echo '<p class="message">'.__('links have been successfully imported.').'</p>';
 }
 ?>
@@ -309,5 +309,5 @@
 '<div class="multi-part clear" id="add-link" title="'.__('Add a link').'">'.
 '<form action="plugin.php" method="post" id="add-link-form">'.
-'<fieldset><legend>'.__('Add a new link').'</legend>'.
+'<fieldset class="two-cols"><legend>'.__('Add a new link').'</legend>'.
 '<p class="col"><label for="link_title" class="required"><abbr title="'.__('Required field').'">*</abbr> '.__('Title:').' '.
 form::field('link_title',30,255,$link_title).
Index: plugins/blowupConfig/_define.php
===================================================================
--- plugins/blowupConfig/_define.php	(revision 967)
+++ plugins/blowupConfig/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Configure your Blowup Theme",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'1.2',
+	/* Version */			'1.1',
 	array(
 		'permissions' =>	'admin'
Index: plugins/blowupConfig/index.php
===================================================================
--- plugins/blowupConfig/index.php	(revision 994)
+++ plugins/blowupConfig/index.php	(revision 683)
@@ -228,10 +228,11 @@
 
 if (!$can_write_images) {
-	dcPage::message(__('For the following reasons, images cannot be created. You won\'t be able to change some background properties.').
-		$notices,false,true);
+	echo '<div class="message">'.
+		__('For the following reasons, images cannot be created. You won\'t be able to change some background properties.').
+		$notices.'</div>';
 }
 
 if (!empty($_GET['upd'])) {
-	dcPage::message(__('Theme configuration has been successfully updated.'));
+	echo '<p class="message">'.__('Theme configuration has been successfully updated.').'</p>';
 }
 
@@ -431,7 +432,5 @@
 echo
 '<fieldset><legend>'.__('Additional CSS').'</legend>'.
-'<p><label for="extra_css">'.__('Any additional CSS styles (must be written using the CSS syntax):').' '.
-form::textarea('extra_css',72,5,html::escapeHTML($blowup_user['extra_css']),'maximal','',false,'title="'.__('Additional CSS').'"').
-'</label></p>'.
+'<p>'.form::textarea('extra_css',72,5,html::escapeHTML($blowup_user['extra_css']),'maximal','',false,'title="'.__('Additional CSS').'"').'</p>'.
 '</fieldset>';
 
Index: plugins/importExport/_define.php
===================================================================
--- plugins/importExport/_define.php	(revision 967)
+++ plugins/importExport/_define.php	(revision 841)
@@ -16,5 +16,5 @@
 	/* Description*/		"Import and Export your blog",
 	/* Author */			"Olivier Meunier & Contributors",
-	/* Version */			'3.2',
+	/* Version */			'3.1',
 	/* Perm */			'admin'
 );
Index: plugins/importExport/_prepend.php
===================================================================
--- plugins/importExport/_prepend.php	(revision 891)
+++ plugins/importExport/_prepend.php	(revision 857)
@@ -32,12 +32,12 @@
 function registerIeModules($modules)
 {
-	$modules['import'] = array_merge($modules['import'],array('dcImportFlat'));
-	$modules['import'] = array_merge($modules['import'],array('dcImportFeed'));
+	$modules['import'][] = 'dcImportFlat';
+	$modules['import'][] = 'dcImportFeed';
 	
-	$modules['export'] = array_merge($modules['export'],array('dcExportFlat'));
+	$modules['export'][] = 'dcExportFlat';
 	
 	if ($GLOBALS['core']->auth->isSuperAdmin()) {
-		$modules['import'] = array_merge($modules['import'],array('dcImportDC1'));
-		$modules['import'] = array_merge($modules['import'],array('dcImportWP'));
+		$modules['import'][] = 'dcImportDC1';
+		$modules['import'][] = 'dcImportWP';
 	}
 }
Index: plugins/importExport/inc/class.dc.import.feed.php
===================================================================
--- plugins/importExport/inc/class.dc.import.feed.php	(revision 907)
+++ plugins/importExport/inc/class.dc.import.feed.php	(revision 840)
@@ -77,5 +77,5 @@
 	{
 		if ($this->status) {
-			dcPage::message(__('Content successfully imported.'));
+			echo '<p class="message">'.__('Content successfully imported.').'</p>';
 		}
 		
Index: plugins/importExport/inc/class.dc.import.flat.php
===================================================================
--- plugins/importExport/inc/class.dc.import.flat.php	(revision 939)
+++ plugins/importExport/inc/class.dc.import.flat.php	(revision 840)
@@ -142,10 +142,10 @@
 		if ($this->status == 'single')
 		{
-			dcPage::message(__('Single blog successfully imported.'));
+			echo '<p class="message">'.__('Single blog successfully imported.').'</p>';
 			return;
 		}
 		if ($this->status == 'full')
 		{
-			dcPage::message(__('Content successfully imported.'));
+			echo '<p class="message">'.__('Content successfully imported.').'</p>';
 			return;
 		}
@@ -184,6 +184,5 @@
 		'<p>'.sprintf(__('This will import a single blog backup as new content in the current blog: %s.'),html::escapeHTML($this->core->blog->name)).'</p>'.
 		
-		'<p><label for="up_single_file">'.__('Upload a backup file').
-		' ('.sprintf(__('Maximum size %s'),files::size(DC_MAX_UPLOAD_SIZE)).')'.'</label>'.
+		'<p><label for="up_single_file">'.__('Upload a backup file').'</label>'.
 		'<input type="file" id="up_single_file" name="up_single_file" size="20" />'.
 		'</p>';
@@ -213,6 +212,5 @@
 			'<p>'.__('This will reset all the content of your database, except users.').'</p>'.
 			
-			'<p><label for="up_full_file">'.__('Upload a backup file').
-			' ('.sprintf(__('Maximum size %s'),files::size(DC_MAX_UPLOAD_SIZE)).')'.'</label>'.
+			'<p><label for="up_full_file">'.__('Upload a backup file').'</label>'.
 			'<input type="file" id="up_full_file" name="up_full_file" size="20" />'.
 			'</p>';
Index: plugins/importExport/inc/flat/class.flat.backup.php
===================================================================
--- plugins/importExport/inc/flat/class.flat.backup.php	(revision 894)
+++ plugins/importExport/inc/flat/class.flat.backup.php	(revision 841)
@@ -61,5 +61,5 @@
 		{
 			$line = preg_replace('/^"|"$/','',$line);
-			$line = preg_split('/(^"|","|(?<!\\\)\"$)/m',$line);
+			$line = preg_split('/(^"|","|"$)/m',$line);
 			
 			if (count($this->line_cols) != count($line)) {
Index: plugins/importExport/style.css
===================================================================
--- plugins/importExport/style.css	(revision 951)
+++ plugins/importExport/style.css	(revision 840)
@@ -22,7 +22,4 @@
 	color: white;
 	font-weight: bold;
-	border-radius: 2px;
-	-o-border-radius: 2px;
 	-moz-border-radius: 2px;
-	-webkit-border-radius: 2px;
 }
Index: plugins/maintenance/_define.php
===================================================================
--- plugins/maintenance/_define.php	(revision 967)
+++ plugins/maintenance/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Maintain your database",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'1.2'
+	/* Version */			'1.1'
 );
 ?>
Index: plugins/maintenance/index.php
===================================================================
--- plugins/maintenance/index.php	(revision 907)
+++ plugins/maintenance/index.php	(revision 500)
@@ -73,14 +73,14 @@
 <?php
 if (!empty($_GET['vacuum'])) {
-	dcPage::message(__('Optimization successful.'));
+	echo '<p class="message">'.__('Optimization successful.').'</p>';
 }
 if (!empty($_GET['commentscount'])) {
-	dcPage::message(__('Comments and trackback counted.'));
+	echo '<p class="message">'.__('Comments and trackback counted.').'</p>';
 }
 if (!empty($_GET['empty_cache'])) {
-	dcPage::message(__('Templates cache directory emptied.'));
+	echo '<p class="message">'.__('Templates cache directory emptied.').'</p>';
 }
 if (!empty($_GET['delete_logs'])) {
-	dcPage::message(__('Logs deleted.'));
+	echo '<p class="message">'.__('Logs deleted.').'</p>';
 }
 
@@ -105,5 +105,5 @@
 	else
 	{
-		dcPage::message(__('Entries index done.'));
+		echo '<p class="message">'.__('Entries index done.').'</p>';
 		echo '<p><a class="back" href="'.$p_url.'">'.__('Back').'</a></p>';
 	}
@@ -129,5 +129,5 @@
 	else
 	{
-		dcPage::message(__('Comments index done.'));
+		echo '<p class="message">'.__('Comments index done.').'</p>';
 		echo '<p><a class="back" href="'.$p_url.'">'.__('Back').'</a></p>';
 	}
Index: plugins/pages/_define.php
===================================================================
--- plugins/pages/_define.php	(revision 965)
+++ plugins/pages/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/	"Serve entries as simple web pages",
 	/* Author */		"Olivier Meunier",
-	/* Version */		'1.2',
+	/* Version */		'1.1.1',
 	array(
 		'permissions' =>	'contentadmin,pages',
Index: plugins/pages/_public.php
===================================================================
--- plugins/pages/_public.php	(revision 945)
+++ plugins/pages/_public.php	(revision 727)
@@ -221,6 +221,5 @@
 		global $core, $_ctx;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -229,5 +228,4 @@
 		$params['limit'] = abs((integer) $w->limit);
 		$params['no_content'] = true;
-		$params['post_selected'] = false;
 		
 		$sort = $w->sortby;
@@ -249,5 +247,5 @@
 		
 		$res =
-		'<div class="pages'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="pages">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
Index: plugins/pages/_widgets.php
===================================================================
--- plugins/pages/_widgets.php	(revision 954)
+++ plugins/pages/_widgets.php	(revision 270)
@@ -19,13 +19,7 @@
 	public static function initWidgets($w)
 	{
-		$w->create('pages',__('Pages'),array('tplPages','pagesWidget'),null,'List of published pages');
+		$w->create('pages',__('Pages'),array('tplPages','pagesWidget'));
 		$w->pages->setting('title',__('Title:'),__('Pages'));
-		$w->pages->setting('homeonly',__('Display on:'),1,'combo',
-			array(
-				__('All pages') => 0,
-				__('Home page only') => 1,
-				__('Except on home page') => 2
-				)
-		);
+		$w->pages->setting('homeonly',__('Home page only'),1,'check');
 		$w->pages->setting('sortby',__('Order by:'),'post_title','combo',
 			array(
@@ -38,5 +32,4 @@
 			array(__('Ascending') => 'asc', __('Descending') => 'desc')
 		);
-		$w->pages->setting('class',__('CSS class:'),'');
 	}
 	
Index: plugins/pages/list.php
===================================================================
--- plugins/pages/list.php	(revision 911)
+++ plugins/pages/list.php	(revision 578)
@@ -86,5 +86,5 @@
 		$selected = '';
 		if ($this->rs->post_selected) {
-			$selected = sprintf($img,__('hidden'),'hidden.png');
+			$selected = sprintf($img,__('selected'),'selected.png');
 		}
 		
Index: plugins/pages/page.php
===================================================================
--- plugins/pages/page.php	(revision 986)
+++ plugins/pages/page.php	(revision 776)
@@ -31,5 +31,4 @@
 $post_open_comment = false;
 $post_open_tb = false;
-$post_selected = false;
 
 $post_media = array();
@@ -56,5 +55,4 @@
 	$status_combo[$v] = (string) $k;
 }
-$img_status_pattern = '<img class="img_select_option" alt="%1$s" title="%1$s" src="images/%2$s" />';
 
 # Formaters combo
@@ -78,6 +76,4 @@
 unset($rs);
 
-# Validation flag
-$bad_dt = false;
 
 # Get page informations
@@ -112,5 +108,4 @@
 		$post_open_comment = (boolean) $post->post_open_comment;
 		$post_open_tb = (boolean) $post->post_open_tb;
-		$post_selected = (boolean) $post->post_selected;
 		
 		$page_title = __('Edit page');
@@ -159,22 +154,10 @@
 		$post_dt = '';
 	} else {
-		try
-		{
-			$post_dt = strtotime($_POST['post_dt']);
-			if ($post_dt == false || $post_dt == -1) {
-				$bad_dt = true;
-				throw new Exception(__('Invalid publication date'));
-			}
-			$post_dt = date('Y-m-d H:i',$post_dt);
-		}
-		catch (Exception $e)
-		{
-			$core->error->add($e->getMessage());
-		}
+		$post_dt = strtotime($_POST['post_dt']);
+		$post_dt = date('Y-m-d H:i',$post_dt);
 	}
 	
 	$post_open_comment = !empty($_POST['post_open_comment']);
 	$post_open_tb = !empty($_POST['post_open_tb']);
-	$post_selected = !empty($_POST['post_selected']);
 	$post_lang = $_POST['post_lang'];
 	$post_password = !empty($_POST['post_password']) ? $_POST['post_password'] : null;
@@ -194,5 +177,5 @@
 
 # Create or update post
-if (!empty($_POST) && !empty($_POST['save']) && $can_edit_page && !$bad_dt)
+if (!empty($_POST) && !empty($_POST['save']) && $can_edit_page)
 {
 	$cur = $core->con->openCursor($core->prefix.'post');
@@ -217,5 +200,4 @@
 	$cur->post_open_comment = (integer) $post_open_comment;
 	$cur->post_open_tb = (integer) $post_open_tb;
-	$cur->post_selected = (integer) $post_selected;
 	
 	if (isset($_POST['post_url'])) {
@@ -315,14 +297,14 @@
 
 if (!empty($_GET['upd'])) {
-	dcPage::message(__('Page has been successfully updated.'));
+		echo '<p class="message">'.__('Page has been successfully updated.').'</p>';
 }
 elseif (!empty($_GET['crea'])) {
-	dcPage::message(__('Page has been successfully created.'));
+		echo '<p class="message">'.__('Page has been successfully created.').'</p>';
 }
 elseif (!empty($_GET['attached'])) {
-	dcPage::message(__('File has been successfully attached.'));
+	echo '<p class="message">'.__('File has been successfully attached.').'</p>';
 }
 elseif (!empty($_GET['rmattach'])) {
-	dcPage::message(__('Attachment has been successfully removed.'));
+	echo '<p class="message">'.__('Attachment has been successfully removed.').'</p>';
 }
 
@@ -334,5 +316,5 @@
 	$post_format = 'xhtml';
 	
-	dcPage::message(__('Don\'t forget to validate your XHTML conversion by saving your post.'));
+	echo '<p class="message">'.__('Don\'t forget to validate your XHTML conversion by saving your post.').'</p>';
 }
 
@@ -340,21 +322,5 @@
 ' &rsaquo; <a href="'.$p_url.'">'.__('Pages').'</a> &rsaquo; <span class="page-title">'.$page_title; 
 	if ($post_id) {
-		switch ($post_status) {
-			case 1:
-				$img_status = sprintf($img_status_pattern,__('published'),'check-on.png');
-				break;
-			case 0:
-				$img_status = sprintf($img_status_pattern,__('unpublished'),'check-off.png');
-				break;
-			case -1:
-				$img_status = sprintf($img_status_pattern,__('scheduled'),'scheduled.png');
-				break;
-			case -2:
-				$img_status = sprintf($img_status_pattern,__('pending'),'check-wrn.png');
-				break;
-			default:
-				$img_status = '';
-		}
-		echo ' &ldquo;'.$post_title.'&rdquo;'.' '.$img_status;
+		echo ' &ldquo;'.$post_title.'&rdquo;';
 	}
 echo	'</span></h2>';
@@ -449,5 +415,5 @@
 	
 	'<p><label for="post_dt">'.__('Published on:').
-	form::field('post_dt',16,16,$post_dt,($bad_dt ? 'invalid' : '')).'</label></p>'.
+	form::field('post_dt',16,16,$post_dt).'</label></p>'.
 	
 	'<p><label for="post_format">'.__('Text formating:').
@@ -458,24 +424,7 @@
 	'<p><label for="post_open_comment" class="classic">'.form::checkbox('post_open_comment',1,$post_open_comment).' '.
 	__('Accept comments').'</label></p>'.
-	($core->blog->settings->system->allow_comments ? 
-		(isContributionAllowed($post_id,strtotime($post_dt),true) ? 
-			'' :
-			'<p class="form-note warn">'.__('Warning: Comments are not more accepted for this page.').'</p>') : 
-		'<p class="form-note warn">'.__('Warning: Comments are not accepted on this blog.').'</p>').
-
 	'<p><label for="post_open_tb" class="classic">'.form::checkbox('post_open_tb',1,$post_open_tb).' '.
 	__('Accept trackbacks').'</label></p>'.
-	($core->blog->settings->system->allow_trackbacks ? 
-		(isContributionAllowed($post_id,strtotime($post_dt),false) ? 
-			'' :
-			'<p class="form-note warn">'.__('Warning: Trackbacks are not more accepted for this page.').'</p>') : 
-		'<p class="form-note warn">'.__('Warning: Trackbacks are not accepted on this blog.').'</p>').
-	
-	'<p><label for="post_selected" class="classic">'.form::checkbox('post_selected',1,$post_selected).' '.
-	__('Hide').'</label></p>'.
-	'<p class="form-note">'.
-	__('If checked this page will be active but not listed in widget Pages.').
-	'</p>'.
-
+	
 	'<p><label for="post_position" class="classic">'.__('Page position:').' '.
 	form::field('post_position',3,3,(string) $post_position).
@@ -654,25 +603,4 @@
 }
 
-# Controls comments or trakbacks capabilities
-function isContributionAllowed($id,$dt,$com=true)
-{
-	global $core;
-
-	if (!$id) {
-		return true;
-	}
-	if ($com) {
-		if (($core->blog->settings->system->comments_ttl == 0) || 
-			(time() - $core->blog->settings->system->comments_ttl*86400 < $dt)) {
-			return true;
-		}
-	} else {
-		if (($core->blog->settings->system->trackbacks_ttl == 0) || 
-			(time() - $core->blog->settings->system->trackbacks_ttl*86400 < $dt)) {
-			return true;
-		}
-	}
-	return false;
-}
 
 # Show comments or trackbacks
Index: plugins/pings/_define.php
===================================================================
--- plugins/pings/_define.php	(revision 967)
+++ plugins/pings/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Ping services",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'1.2',
+	/* Version */			'1.1',
 	array(
 		'permissions' =>	'usage,contentadmin'
Index: plugins/pings/index.php
===================================================================
--- plugins/pings/index.php	(revision 907)
+++ plugins/pings/index.php	(revision 500)
@@ -54,5 +54,5 @@
 
 if (!empty($_GET['up'])) {
-	dcPage::message(__('Settings have been successfully updated.'));
+	echo '<p class="message">'.__('Settings have been successfully updated.').'</p>';
 }
 
Index: plugins/simpleMenu/_define.php
===================================================================
--- plugins/simpleMenu/_define.php	(revision 967)
+++ plugins/simpleMenu/_define.php	(revision 685)
@@ -16,5 +16,5 @@
 	/* Description*/		"Simple menu for Dotclear",
 	/* Author */			"Franck Paul",
-	/* Version */			'1.1',
+	/* Version */			'1.0',
 	array(
 		'permissions' =>	'admin'
Index: plugins/simpleMenu/_public.php
===================================================================
--- plugins/simpleMenu/_public.php	(revision 945)
+++ plugins/simpleMenu/_public.php	(revision 683)
@@ -42,6 +42,5 @@
 		global $core, $_ctx;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -52,7 +51,5 @@
 		}
 
-		return '<div class="simple-menu'.
-			($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
-			($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').$menu.'</div>';
+		return '<div class="simple-menu">'.($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').$menu.'</div>';
 	}
 	
Index: plugins/simpleMenu/_widgets.php
===================================================================
--- plugins/simpleMenu/_widgets.php	(revision 954)
+++ plugins/simpleMenu/_widgets.php	(revision 587)
@@ -18,14 +18,7 @@
 	public static function initWidgets($w)
 	{
-		$w->create('simplemenu',__('Simple menu'),array('tplSimpleMenu','simpleMenuWidget'),null,'List of simple menu items');
+		$w->create('simplemenu',__('Simple menu'),array('tplSimpleMenu','simpleMenuWidget'));
 		$w->simplemenu->setting('title',__('Title:'),__('Menu'));
-		$w->simplemenu->setting('homeonly',__('Display on:'),0,'combo',
-			array(
-				__('All pages') => 0,
-				__('Home page only') => 1,
-				__('Except on home page') => 2
-				)
-		);
-		$w->simplemenu->setting('class',__('CSS class:'),'');
+		$w->simplemenu->setting('homeonly',__('Home page only'),1,'check');
 	}
 }
Index: plugins/simpleMenu/index.php
===================================================================
--- plugins/simpleMenu/index.php	(revision 1011)
+++ plugins/simpleMenu/index.php	(revision 790)
@@ -412,14 +412,14 @@
 
 if (!empty($_GET['added'])) {
-	dcPage::message(__('Menu item has been successfully added.'));
+	echo '<p class="message">'.__('Menu item has been successfully added.').'</p>';
 }
 if (!empty($_GET['removed'])) {
-	dcPage::message(__('Menu items have been successfully removed.'));
+	echo '<p class="message">'.__('Menu items have been successfully removed.').'</p>';
 }
 if (!empty($_GET['neworder'])) {
-	dcPage::message(__('Menu items have been successfully updated.'));
+	echo '<p class="message">'.__('Menu items have been successfully updated.').'</p>';
 }
 if (!empty($_GET['updated'])) {
-	dcPage::message(__('Menu items have been successfully updated.'));
+	echo '<p class="message">'.__('Menu items have been successfully updated.').'</p>';
 }
 
@@ -434,5 +434,5 @@
 			echo '<form id="additem" action="'.$p_url.'&add=2" method="post">';
 			echo '<fieldset><legend>'.__('Select type').'</legend>';
-			echo '<p class="field"><label for="item_type" class="classic">'.__('Type of item menu:').'</label>'.form::combo('item_type',$items_combo,'').'</p>';
+			echo '<p class="field"><label for"item_type" class="classic">'.__('Type of item menu:').'</label>'.form::combo('item_type',$items_combo,'').'</p>';
 			echo '<p>'.$core->formNonce().'<input type="submit" name="appendaction" value="'.__('Continue...').'" />'.'</p>';
 			echo '</fieldset>';
@@ -446,21 +446,21 @@
 				switch ($item_type) {
 					case 'lang':
-						echo '<p class="field"><label for="item_select" class="classic">'.__('Select language:').'</label>'.
+						echo '<p class="field"><label for"item_select" class="classic">'.__('Select language:').'</label>'.
 							form::combo('item_select',$langs_combo,'');
 						break;
 					case 'category':
-						echo '<p class="field"><label for="item_select" class="classic">'.__('Select category:').'</label>'.
+						echo '<p class="field"><label for"item_select" class="classic">'.__('Select category:').'</label>'.
 							form::combo('item_select',$categories_combo,'');
 						break;
 					case 'archive':
-						echo '<p class="field"><label for="item_select" class="classic">'.__('Select month (if necessary):').'</label>'.
+						echo '<p class="field"><label for"item_select" class="classic">'.__('Select month (if necessary):').'</label>'.
 							form::combo('item_select',$months_combo,'');
 						break;
 					case 'pages':
-						echo '<p class="field"><label for="item_select" class="classic">'.__('Select page:').'</label>'.
+						echo '<p class="field"><label for"item_select" class="classic">'.__('Select page:').'</label>'.
 							form::combo('item_select',$pages_combo,'');
 						break;
 					case 'tags':
-						echo '<p class="field"><label for="item_select" class="classic">'.__('Select tag (if necessary):').'</label>'.
+						echo '<p class="field"><label for"item_select" class="classic">'.__('Select tag (if necessary):').'</label>'.
 							form::combo('item_select',$tags_combo,'');
 						break;
@@ -481,9 +481,9 @@
 			echo '<form id="additem" action="'.$p_url.'&add=4" method="post">';
 			echo '<fieldset><legend>'.$item_type_label.($item_select_label != '' ? ' ('.$item_select_label.')' : '').'</legend>';
-			echo '<p class="field"><label for="item_label" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.
+			echo '<p class="field"><label for"item_label" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.
 				__('Label of item menu:').'</label>'.form::field('item_label',20,255,$item_label).'</p>';
-			echo '<p class="field"><label for="item_descr" class="classic">'.
+			echo '<p class="field"><label for"item_descr" class="classic">'.
 				__('Description of item menu:').'</label>'.form::field('item_descr',30,255,$item_descr).'</p>';
-			echo '<p class="field"><label for="item_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.
+			echo '<p class="field"><label for"item_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.
 				__('URL of item menu:').'</label>'.form::field('item_url',40,255,$item_url).'</p>';
 			echo form::hidden('item_type',$item_type).form::hidden('item_select',$item_select);
Index: plugins/tags/_admin.php
===================================================================
--- plugins/tags/_admin.php	(revision 897)
+++ plugins/tags/_admin.php	(revision 818)
@@ -31,7 +31,6 @@
 
 $core->addBehavior('adminPreferencesForm',array('tagsBehaviors','adminUserForm'));
-$core->addBehavior('adminBeforeUserOptionsUpdate',array('tagsBehaviors','setTagListFormat'));
-
-$core->addBehavior('adminUserForm',array('tagsBehaviors','adminUserForm'));
+// $core->addBehavior('adminUserForm',array('tagsBehaviors','adminUserForm'));
+
 $core->addBehavior('adminBeforeUserCreate',array('tagsBehaviors','setTagListFormat'));
 $core->addBehavior('adminBeforeUserUpdate',array('tagsBehaviors','setTagListFormat'));
Index: plugins/tags/_define.php
===================================================================
--- plugins/tags/_define.php	(revision 965)
+++ plugins/tags/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Tags for posts",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'1.2',
+	/* Version */			'1.1',
 	array(
 		'permissions' =>	'usage,contentadmin'
Index: plugins/tags/_public.php
===================================================================
--- plugins/tags/_public.php	(revision 945)
+++ plugins/tags/_public.php	(revision 816)
@@ -23,7 +23,5 @@
 $core->tpl->addBlock('TagsFooter',array('tplTags','TagsFooter'));
 $core->tpl->addBlock('EntryTags',array('tplTags','EntryTags'));
-$core->tpl->addBlock('TagIf',array('tplTags','TagIf'));
 $core->tpl->addValue('TagID',array('tplTags','TagID'));
-$core->tpl->addValue('TagCount',array('tplTags','TagCount'));
 $core->tpl->addValue('TagPercent',array('tplTags','TagPercent'));
 $core->tpl->addValue('TagRoundPercent',array('tplTags','TagRoundPercent'));
@@ -46,4 +44,5 @@
 
 $core->addBehavior('templateBeforeBlock',array('behaviorsTags','templateBeforeBlock'));
+$core->addBehavior('tplSysIfConditions',array('behaviorsTags','tplSysIfConditions'));
 $core->addBehavior('publicBeforeDocument',array('behaviorsTags','addTplPath'));
 
@@ -74,4 +73,16 @@
 	}
 	
+	public static function tplSysIfConditions($tag, $attr,$content,$if)
+	{
+		if ($tag == 'Sys' && isset($attr['has_tag'])) {
+			$sign = '';
+			if (substr($attr['has_tag'],0,1) == '!') {
+				$sign = '!';
+				$attr['has_tag'] = substr($attr['has_tag'],1);
+			}
+			$if[] =  $sign."(\$core->tpl->tagExists('".addslashes($attr['has_tag'])."') )";
+		}
+	}
+	
 	public static function addTplPath($core)
 	{
@@ -155,22 +166,5 @@
 		return $res;
 	}
-
-	public static function TagIf($attr,$content) 
-	{ 
-		$if = array();
-		$operateur = isset($attr['operator']) ? dcTemplate::getOperator($attr['operator']) : '&&';
-
-		if (isset($attr['has_entries'])) {
-			$sign = (boolean) $attr['has_entries'] ? '' : '!';
-			$if[] = $sign.'$_ctx->meta->count';
-		}
-
-		if (!empty($if)) {
-			return '<?php if('.implode(' '.$operateur.' ',$if).') : ?>'.$content.'<?php endif; ?>';
-		} else {
-			return $content;
-		}
-	}
-
+	
 	public static function TagID($attr)
 	{
@@ -179,9 +173,4 @@
 	}
 	
-	public static function TagCount($attr)
-	{
-		return '<?php echo $_ctx->meta->count; ?>';
-	}
-
 	public static function TagPercent($attr)
 	{
@@ -225,9 +214,4 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
-			return;
-		}
-
 		$params = array('meta_type' => 'tag');
 		
@@ -256,5 +240,5 @@
 		
 		$res =
-		'<div class="tags'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="tags">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -264,5 +248,5 @@
 			$res .=
 			'<li><a href="'.$core->blog->url.$core->url->getURLFor('tag',rawurlencode($rs->meta_id)).'" '.
-			'class="tag'.$rs->roundpercent.'">'.
+			'class="tag'.$rs->roundpercent.'" rel="tag">'.
 			$rs->meta_id.'</a> </li>';
 		}
Index: plugins/tags/_widgets.php
===================================================================
--- plugins/tags/_widgets.php	(revision 954)
+++ plugins/tags/_widgets.php	(revision 270)
@@ -19,5 +19,5 @@
 	public static function initWidgets($w)
 	{
-		$w->create('tags',__('Tags'),array('tplTags','tagsWidget'),null,'Tags cloud');
+		$w->create('tags',__('Tags'),array('tplTags','tagsWidget'));
 		$w->tags->setting('title',__('Title:'),__('Tags'));
 		$w->tags->setting('limit',__('Limit (empty means no limit):'),'20');
@@ -29,12 +29,4 @@
 		);
 		$w->tags->setting('alltagslinktitle',__('Link to all tags:'),__('All tags'));
-		$w->tags->setting('homeonly',__('Display on:'),0,'combo',
-			array(
-				__('All pages') => 0,
-				__('Home page only') => 1,
-				__('Except on home page') => 2
-				)
-		);
-		$w->tags->setting('class',__('CSS class:'),'');
 	}
 	
Index: plugins/tags/tag_posts.php
===================================================================
--- plugins/tags/tag_posts.php	(revision 907)
+++ plugins/tags/tag_posts.php	(revision 793)
@@ -114,5 +114,5 @@
 <?php
 if (!empty($_GET['renamed'])) {
-	dcPage::message(__('Tag has been successfully renamed'));
+	echo '<p class="message">'.__('Tag has been successfully renamed').'</p>';
 }
 
Index: plugins/tags/tags.php
===================================================================
--- plugins/tags/tags.php	(revision 907)
+++ plugins/tags/tags.php	(revision 711)
@@ -25,5 +25,5 @@
 <?php
 if (!empty($_GET['del'])) {
-	dcPage::message(__('Tag has been successfully removed'));
+	echo '<p class="message">'.__('Tag has been successfully removed').'</p>';
 }
 
Index: plugins/themeEditor/_admin.php
===================================================================
--- plugins/themeEditor/_admin.php	(revision 998)
+++ plugins/themeEditor/_admin.php	(revision 270)
@@ -16,47 +16,10 @@
 }
 
-$core->addBehavior('adminCurrentThemeDetails', array('themeEditorBehaviors','theme_editor_details'));
+$core->addBehavior('adminCurrentThemeDetails','theme_editor_details');
 
-$core->addBehavior('adminBeforeUserOptionsUpdate',array('themeEditorBehaviors','adminBeforeUserUpdate'));
-$core->addBehavior('adminPreferencesForm',array('themeEditorBehaviors','adminPreferencesForm'));
-
-class themeEditorBehaviors
+function theme_editor_details($core,$id)
 {
-	public static function theme_editor_details($core,$id)
-	{
-		if ($id != 'default' && $core->auth->isSuperAdmin()) {
-			return '<p><a href="plugin.php?p=themeEditor" class="button">'.__('Theme Editor').'</a></p>';
-		}
-	}
-
-	public static function adminBeforeUserUpdate($cur,$userID)
-	{
-		global $core;
-
-		// Get and store user's prefs for plugin options
-		$core->auth->user_prefs->addWorkspace('interface');
-		try {
-			$core->auth->user_prefs->interface->put('colorsyntax',!empty($_POST['colorsyntax']),'boolean');
-		} 
-		catch (Exception $e)
-		{
-			$core->error->add($e->getMessage());
-		}
-	}
-	
-	public static function adminPreferencesForm($core)
-	{
-		// Add fieldset for plugin options
-		$core->auth->user_prefs->addWorkspace('interface');
-
-		echo
-		'<fieldset><legend>'.__('Theme Editor').'</legend>'.
-		
-		'<p><label for="colorsyntax" class="classic">'.
-		form::checkbox('colorsyntax',1,$core->auth->user_prefs->interface->colorsyntax).' '.
-		__('Syntax color').'</label></p>'.
-
-		'<br class="clear" />'. //Opera sucks
-		'</fieldset>';
+	if ($id != 'default' && $core->auth->isSuperAdmin()) {
+		return '<p><a href="plugin.php?p=themeEditor" class="button">'.__('Theme Editor').'</a></p>';
 	}
 }
Index: plugins/themeEditor/_define.php
===================================================================
--- plugins/themeEditor/_define.php	(revision 965)
+++ plugins/themeEditor/_define.php	(revision 464)
@@ -16,5 +16,5 @@
 	/* Description*/		"Theme Editor",
 	/* Author */			"Olivier Meunier",
-	/* Version */			'1.0'
+	/* Version */			'0.9'
 );
 ?>
Index: plugins/themeEditor/codemirror.css
===================================================================
--- plugins/themeEditor/codemirror.css	(revision 948)
+++ 	(revision )
@@ -1,7 +1,0 @@
-.CodeMirror {
-	font-size: 1.4em;
-	background: #fff;
-}
-.CodeMirror .CodeMirror-wrap, .CodeMirror .CodeMirror-scroll {
-	height: 30em;
-}
Index: plugins/themeEditor/codemirror/LICENSE
===================================================================
--- plugins/themeEditor/codemirror/LICENSE	(revision 948)
+++ 	(revision )
@@ -1,23 +1,0 @@
-Copyright (C) 2012 by Marijn Haverbeke <marijnh@gmail.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-Please note that some subdirectories of the CodeMirror distribution
-include their own LICENSE files, and are released under different
-licences.
Index: plugins/themeEditor/codemirror/codemirror.css
===================================================================
--- plugins/themeEditor/codemirror/codemirror.css	(revision 948)
+++ 	(revision )
@@ -1,174 +1,0 @@
-.CodeMirror {
-  line-height: 1em;
-  font-family: monospace;
-
-  /* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion. */
-  position: relative;
-  /* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
-  overflow: hidden;
-}
-
-.CodeMirror-scroll {
-  overflow: auto;
-  height: 300px;
-  /* This is needed to prevent an IE[67] bug where the scrolled content
-     is visible outside of the scrolling box. */
-  position: relative;
-  outline: none;
-}
-
-/* Vertical scrollbar */
-.CodeMirror-scrollbar {
-  position: absolute;
-  right: 0; top: 0;
-  overflow-x: hidden;
-  overflow-y: scroll;
-  z-index: 5;
-}
-.CodeMirror-scrollbar-inner {
-  /* This needs to have a nonzero width in order for the scrollbar to appear
-     in Firefox and IE9. */
-  width: 1px;
-}
-.CodeMirror-scrollbar.cm-sb-overlap {
-  /* Ensure that the scrollbar appears in Lion, and that it overlaps the content
-     rather than sitting to the right of it. */
-  position: absolute;
-  z-index: 1;
-  float: none;
-  right: 0;
-  min-width: 12px;
-}
-.CodeMirror-scrollbar.cm-sb-nonoverlap {
-  min-width: 12px;
-}
-.CodeMirror-scrollbar.cm-sb-ie7 {
-  min-width: 18px;
-}
-
-.CodeMirror-gutter {
-  position: absolute; left: 0; top: 0;
-  z-index: 10;
-  background-color: #f7f7f7;
-  border-right: 1px solid #eee;
-  min-width: 2em;
-  height: 100%;
-}
-.CodeMirror-gutter-text {
-  color: #aaa;
-  text-align: right;
-  padding: .4em .2em .4em .4em;
-  white-space: pre !important;
-  cursor: default;
-}
-.CodeMirror-lines {
-  padding: .4em;
-  white-space: pre;
-  cursor: text;
-}
-
-.CodeMirror pre {
-  -moz-border-radius: 0;
-  -webkit-border-radius: 0;
-  -o-border-radius: 0;
-  border-radius: 0;
-  border-width: 0; margin: 0; padding: 0; background: transparent;
-  font-family: inherit;
-  font-size: inherit;
-  padding: 0; margin: 0;
-  white-space: pre;
-  word-wrap: normal;
-  line-height: inherit;
-  color: inherit;
-  overflow: visible;
-}
-
-.CodeMirror-wrap pre {
-  word-wrap: break-word;
-  white-space: pre-wrap;
-  word-break: normal;
-}
-.CodeMirror-wrap .CodeMirror-scroll {
-  overflow-x: hidden;
-}
-
-.CodeMirror textarea {
-  outline: none !important;
-}
-
-.CodeMirror pre.CodeMirror-cursor {
-  z-index: 10;
-  position: absolute;
-  visibility: hidden;
-  border-left: 1px solid black;
-  border-right: none;
-  width: 0;
-}
-.cm-keymap-fat-cursor pre.CodeMirror-cursor {
-  width: auto;
-  border: 0;
-  background: transparent;
-  background: rgba(0, 200, 0, .4);
-  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
-}
-/* Kludge to turn off filter in ie9+, which also accepts rgba */
-.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
-  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-}
-.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
-.CodeMirror-focused pre.CodeMirror-cursor {
-  visibility: visible;
-}
-
-div.CodeMirror-selected { background: #d9d9d9; }
-.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
-
-.CodeMirror-searching {
-  background: #ffa;
-  background: rgba(255, 255, 0, .4);
-}
-
-/* Default theme */
-
-.cm-s-default span.cm-keyword {color: #708;}
-.cm-s-default span.cm-atom {color: #219;}
-.cm-s-default span.cm-number {color: #164;}
-.cm-s-default span.cm-def {color: #00f;}
-.cm-s-default span.cm-variable {color: black;}
-.cm-s-default span.cm-variable-2 {color: #05a;}
-.cm-s-default span.cm-variable-3 {color: #085;}
-.cm-s-default span.cm-property {color: black;}
-.cm-s-default span.cm-operator {color: black;}
-.cm-s-default span.cm-comment {color: #a50;}
-.cm-s-default span.cm-string {color: #a11;}
-.cm-s-default span.cm-string-2 {color: #f50;}
-.cm-s-default span.cm-meta {color: #555;}
-.cm-s-default span.cm-error {color: #f00;}
-.cm-s-default span.cm-qualifier {color: #555;}
-.cm-s-default span.cm-builtin {color: #30a;}
-.cm-s-default span.cm-bracket {color: #997;}
-.cm-s-default span.cm-tag {color: #170;}
-.cm-s-default span.cm-attribute {color: #00c;}
-.cm-s-default span.cm-header {color: blue;}
-.cm-s-default span.cm-quote {color: #090;}
-.cm-s-default span.cm-hr {color: #999;}
-.cm-s-default span.cm-link {color: #00c;}
-
-span.cm-header, span.cm-strong {font-weight: bold;}
-span.cm-em {font-style: italic;}
-span.cm-emstrong {font-style: italic; font-weight: bold;}
-span.cm-link {text-decoration: underline;}
-
-span.cm-invalidchar {color: #f00;}
-
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
-
-@media print {
-
-  /* Hide the cursor when printing */
-  .CodeMirror pre.CodeMirror-cursor {
-    visibility: hidden;
-  }
-
-}
Index: plugins/themeEditor/codemirror/codemirror.js
===================================================================
--- plugins/themeEditor/codemirror/codemirror.js	(revision 948)
+++ 	(revision )
@@ -1,3165 +1,0 @@
-// CodeMirror version 2.35
-//
-// All functions that need access to the editor's state live inside
-// the CodeMirror function. Below that, at the bottom of the file,
-// some utilities are defined.
-
-// CodeMirror is the only global var we claim
-window.CodeMirror = (function() {
-  "use strict";
-  // This is the function that produces an editor instance. Its
-  // closure is used to store the editor state.
-  function CodeMirror(place, givenOptions) {
-    // Determine effective options based on given values and defaults.
-    var options = {}, defaults = CodeMirror.defaults;
-    for (var opt in defaults)
-      if (defaults.hasOwnProperty(opt))
-        options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
-
-    var input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em");
-    input.setAttribute("wrap", "off"); input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off");
-    // Wraps and hides input textarea
-    var inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
-    // The empty scrollbar content, used solely for managing the scrollbar thumb.
-    var scrollbarInner = elt("div", null, "CodeMirror-scrollbar-inner");
-    // The vertical scrollbar. Horizontal scrolling is handled by the scroller itself.
-    var scrollbar = elt("div", [scrollbarInner], "CodeMirror-scrollbar");
-    // DIVs containing the selection and the actual code
-    var lineDiv = elt("div"), selectionDiv = elt("div", null, null, "position: relative; z-index: -1");
-    // Blinky cursor, and element used to ensure cursor fits at the end of a line
-    var cursor = elt("pre", "\u00a0", "CodeMirror-cursor"), widthForcer = elt("pre", "\u00a0", "CodeMirror-cursor", "visibility: hidden");
-    // Used to measure text size
-    var measure = elt("div", null, null, "position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden;");
-    var lineSpace = elt("div", [measure, cursor, widthForcer, selectionDiv, lineDiv], null, "position: relative; z-index: 0");
-    var gutterText = elt("div", null, "CodeMirror-gutter-text"), gutter = elt("div", [gutterText], "CodeMirror-gutter");
-    // Moved around its parent to cover visible view
-    var mover = elt("div", [gutter, elt("div", [lineSpace], "CodeMirror-lines")], null, "position: relative");
-    // Set to the height of the text, causes scrolling
-    var sizer = elt("div", [mover], null, "position: relative");
-    // Provides scrolling
-    var scroller = elt("div", [sizer], "CodeMirror-scroll");
-    scroller.setAttribute("tabIndex", "-1");
-    // The element in which the editor lives.
-    var wrapper = elt("div", [inputDiv, scrollbar, scroller], "CodeMirror" + (options.lineWrapping ? " CodeMirror-wrap" : ""));
-    if (place.appendChild) place.appendChild(wrapper); else place(wrapper);
-
-    themeChanged(); keyMapChanged();
-    // Needed to hide big blue blinking cursor on Mobile Safari
-    if (ios) input.style.width = "0px";
-    if (!webkit) scroller.draggable = true;
-    lineSpace.style.outline = "none";
-    if (options.tabindex != null) input.tabIndex = options.tabindex;
-    if (options.autofocus) focusInput();
-    if (!options.gutter && !options.lineNumbers) gutter.style.display = "none";
-    // Needed to handle Tab key in KHTML
-    if (khtml) inputDiv.style.height = "1px", inputDiv.style.position = "absolute";
-
-    // Check for OS X >= 10.7. This has transparent scrollbars, so the
-    // overlaying of one scrollbar with another won't work. This is a
-    // temporary hack to simply turn off the overlay scrollbar. See
-    // issue #727.
-    if (mac_geLion) { scrollbar.style.zIndex = -2; scrollbar.style.visibility = "hidden"; }
-    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
-    else if (ie_lt8) scrollbar.style.minWidth = "18px";
-
-    // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.
-    var poll = new Delayed(), highlight = new Delayed(), blinker;
-
-    // mode holds a mode API object. doc is the tree of Line objects,
-    // frontier is the point up to which the content has been parsed,
-    // and history the undo history (instance of History constructor).
-    var mode, doc = new BranchChunk([new LeafChunk([new Line("")])]), frontier = 0, focused;
-    loadMode();
-    // The selection. These are always maintained to point at valid
-    // positions. Inverted is used to remember that the user is
-    // selecting bottom-to-top.
-    var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};
-    // Selection-related flags. shiftSelecting obviously tracks
-    // whether the user is holding shift.
-    var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0, draggingText,
-        overwrite = false, suppressEdits = false, pasteIncoming = false;
-    // Variables used by startOperation/endOperation to track what
-    // happened during the operation.
-    var updateInput, userSelChange, changes, textChanged, selectionChanged,
-        gutterDirty, callbacks;
-    // Current visible range (may be bigger than the view window).
-    var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;
-    // bracketHighlighted is used to remember that a bracket has been
-    // marked.
-    var bracketHighlighted;
-    // Tracks the maximum line length so that the horizontal scrollbar
-    // can be kept static when scrolling.
-    var maxLine = getLine(0), updateMaxLine = false, maxLineChanged = true;
-    var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll
-    var goalColumn = null;
-
-    // Initialize the content.
-    operation(function(){setValue(options.value || ""); updateInput = false;})();
-    var history = new History();
-
-    // Register our event handlers.
-    connect(scroller, "mousedown", operation(onMouseDown));
-    connect(scroller, "dblclick", operation(onDoubleClick));
-    connect(lineSpace, "selectstart", e_preventDefault);
-    // Gecko browsers fire contextmenu *after* opening the menu, at
-    // which point we can't mess with it anymore. Context menu is
-    // handled in onMouseDown for Gecko.
-    if (!gecko) connect(scroller, "contextmenu", onContextMenu);
-    connect(scroller, "scroll", onScrollMain);
-    connect(scrollbar, "scroll", onScrollBar);
-    connect(scrollbar, "mousedown", function() {if (focused) setTimeout(focusInput, 0);});
-    var resizeHandler = connect(window, "resize", function() {
-      if (wrapper.parentNode) updateDisplay(true);
-      else resizeHandler();
-    }, true);
-    connect(input, "keyup", operation(onKeyUp));
-    connect(input, "input", fastPoll);
-    connect(input, "keydown", operation(onKeyDown));
-    connect(input, "keypress", operation(onKeyPress));
-    connect(input, "focus", onFocus);
-    connect(input, "blur", onBlur);
-
-    function drag_(e) {
-      if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
-      e_stop(e);
-    }
-    if (options.dragDrop) {
-      connect(scroller, "dragstart", onDragStart);
-      connect(scroller, "dragenter", drag_);
-      connect(scroller, "dragover", drag_);
-      connect(scroller, "drop", operation(onDrop));
-    }
-    connect(scroller, "paste", function(){focusInput(); fastPoll();});
-    connect(input, "paste", function(){pasteIncoming = true; fastPoll();});
-    connect(input, "cut", operation(function(){
-      if (!options.readOnly) replaceSelection("");
-    }));
-
-    // Needed to handle Tab key in KHTML
-    if (khtml) connect(sizer, "mouseup", function() {
-        if (document.activeElement == input) input.blur();
-        focusInput();
-    });
-
-    // IE throws unspecified error in certain cases, when
-    // trying to access activeElement before onload
-    var hasFocus; try { hasFocus = (document.activeElement == input); } catch(e) { }
-    if (hasFocus || options.autofocus) setTimeout(onFocus, 20);
-    else onBlur();
-
-    function isLine(l) {return l >= 0 && l < doc.size;}
-    // The instance object that we'll return. Mostly calls out to
-    // local functions in the CodeMirror function. Some do some extra
-    // range checking and/or clipping. operation is used to wrap the
-    // call so that changes it makes are tracked, and the display is
-    // updated afterwards.
-    var instance = wrapper.CodeMirror = {
-      getValue: getValue,
-      setValue: operation(setValue),
-      getSelection: getSelection,
-      replaceSelection: operation(replaceSelection),
-      focus: function(){window.focus(); focusInput(); onFocus(); fastPoll();},
-      setOption: function(option, value) {
-        var oldVal = options[option];
-        options[option] = value;
-        if (option == "mode" || option == "indentUnit") loadMode();
-        else if (option == "readOnly" && value == "nocursor") {onBlur(); input.blur();}
-        else if (option == "readOnly" && !value) {resetInput(true);}
-        else if (option == "theme") themeChanged();
-        else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)();
-        else if (option == "tabSize") updateDisplay(true);
-        else if (option == "keyMap") keyMapChanged();
-        else if (option == "tabindex") input.tabIndex = value;
-        if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" ||
-            option == "theme" || option == "lineNumberFormatter") {
-          gutterChanged();
-          updateDisplay(true);
-        }
-      },
-      getOption: function(option) {return options[option];},
-      getMode: function() {return mode;},
-      undo: operation(undo),
-      redo: operation(redo),
-      indentLine: operation(function(n, dir) {
-        if (typeof dir != "string") {
-          if (dir == null) dir = options.smartIndent ? "smart" : "prev";
-          else dir = dir ? "add" : "subtract";
-        }
-        if (isLine(n)) indentLine(n, dir);
-      }),
-      indentSelection: operation(indentSelected),
-      historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
-      clearHistory: function() {history = new History();},
-      setHistory: function(histData) {
-        history = new History();
-        history.done = histData.done;
-        history.undone = histData.undone;
-      },
-      getHistory: function() {
-        function cp(arr) {
-          for (var i = 0, nw = [], nwelt; i < arr.length; ++i) {
-            nw.push(nwelt = []);
-            for (var j = 0, elt = arr[i]; j < elt.length; ++j) {
-              var old = [], cur = elt[j];
-              nwelt.push({start: cur.start, added: cur.added, old: old});
-              for (var k = 0; k < cur.old.length; ++k) old.push(hlText(cur.old[k]));
-            }
-          }
-          return nw;
-        }
-        return {done: cp(history.done), undone: cp(history.undone)};
-      },
-      matchBrackets: operation(function(){matchBrackets(true);}),
-      getTokenAt: operation(function(pos) {
-        pos = clipPos(pos);
-        return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), options.tabSize, pos.ch);
-      }),
-      getStateAfter: function(line) {
-        line = clipLine(line == null ? doc.size - 1: line);
-        return getStateBefore(line + 1);
-      },
-      cursorCoords: function(start, mode) {
-        if (start == null) start = sel.inverted;
-        return this.charCoords(start ? sel.from : sel.to, mode);
-      },
-      charCoords: function(pos, mode) {
-        pos = clipPos(pos);
-        if (mode == "local") return localCoords(pos, false);
-        if (mode == "div") return localCoords(pos, true);
-        return pageCoords(pos);
-      },
-      coordsChar: function(coords) {
-        var off = eltOffset(lineSpace);
-        return coordsChar(coords.x - off.left, coords.y - off.top);
-      },
-      markText: operation(markText),
-      setBookmark: setBookmark,
-      findMarksAt: findMarksAt,
-      setMarker: operation(addGutterMarker),
-      clearMarker: operation(removeGutterMarker),
-      setLineClass: operation(setLineClass),
-      hideLine: operation(function(h) {return setLineHidden(h, true);}),
-      showLine: operation(function(h) {return setLineHidden(h, false);}),
-      onDeleteLine: function(line, f) {
-        if (typeof line == "number") {
-          if (!isLine(line)) return null;
-          line = getLine(line);
-        }
-        (line.handlers || (line.handlers = [])).push(f);
-        return line;
-      },
-      lineInfo: lineInfo,
-      getViewport: function() { return {from: showingFrom, to: showingTo};},
-      addWidget: function(pos, node, scroll, vert, horiz) {
-        pos = localCoords(clipPos(pos));
-        var top = pos.yBot, left = pos.x;
-        node.style.position = "absolute";
-        sizer.appendChild(node);
-        if (vert == "over") top = pos.y;
-        else if (vert == "near") {
-          var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),
-              hspace = Math.max(sizer.clientWidth, lineSpace.clientWidth) - paddingLeft();
-          if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
-            top = pos.y - node.offsetHeight;
-          if (left + node.offsetWidth > hspace)
-            left = hspace - node.offsetWidth;
-        }
-        node.style.top = (top + paddingTop()) + "px";
-        node.style.left = node.style.right = "";
-        if (horiz == "right") {
-          left = sizer.clientWidth - node.offsetWidth;
-          node.style.right = "0px";
-        } else {
-          if (horiz == "left") left = 0;
-          else if (horiz == "middle") left = (sizer.clientWidth - node.offsetWidth) / 2;
-          node.style.left = (left + paddingLeft()) + "px";
-        }
-        if (scroll)
-          scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
-      },
-
-      lineCount: function() {return doc.size;},
-      clipPos: clipPos,
-      getCursor: function(start) {
-        if (start == null) start = sel.inverted;
-        return copyPos(start ? sel.from : sel.to);
-      },
-      somethingSelected: function() {return !posEq(sel.from, sel.to);},
-      setCursor: operation(function(line, ch, user) {
-        if (ch == null && typeof line.line == "number") setCursor(line.line, line.ch, user);
-        else setCursor(line, ch, user);
-      }),
-      setSelection: operation(function(from, to, user) {
-        (user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));
-      }),
-      getLine: function(line) {if (isLine(line)) return getLine(line).text;},
-      getLineHandle: function(line) {if (isLine(line)) return getLine(line);},
-      setLine: operation(function(line, text) {
-        if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});
-      }),
-      removeLine: operation(function(line) {
-        if (isLine(line)) replaceRange("", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));
-      }),
-      replaceRange: operation(replaceRange),
-      getRange: function(from, to, lineSep) {return getRange(clipPos(from), clipPos(to), lineSep);},
-
-      triggerOnKeyDown: operation(onKeyDown),
-      execCommand: function(cmd) {return commands[cmd](instance);},
-      // Stuff used by commands, probably not much use to outside code.
-      moveH: operation(moveH),
-      deleteH: operation(deleteH),
-      moveV: operation(moveV),
-      toggleOverwrite: function() {
-        if(overwrite){
-          overwrite = false;
-          cursor.className = cursor.className.replace(" CodeMirror-overwrite", "");
-        } else {
-          overwrite = true;
-          cursor.className += " CodeMirror-overwrite";
-        }
-      },
-
-      posFromIndex: function(off) {
-        var lineNo = 0, ch;
-        doc.iter(0, doc.size, function(line) {
-          var sz = line.text.length + 1;
-          if (sz > off) { ch = off; return true; }
-          off -= sz;
-          ++lineNo;
-        });
-        return clipPos({line: lineNo, ch: ch});
-      },
-      indexFromPos: function (coords) {
-        if (coords.line < 0 || coords.ch < 0) return 0;
-        var index = coords.ch;
-        doc.iter(0, coords.line, function (line) {
-          index += line.text.length + 1;
-        });
-        return index;
-      },
-      scrollTo: function(x, y) {
-        if (x != null) scroller.scrollLeft = x;
-        if (y != null) scrollbar.scrollTop = scroller.scrollTop = y;
-        updateDisplay([]);
-      },
-      getScrollInfo: function() {
-        return {x: scroller.scrollLeft, y: scrollbar.scrollTop,
-                height: scrollbar.scrollHeight, width: scroller.scrollWidth};
-      },
-      setSize: function(width, height) {
-        function interpret(val) {
-          val = String(val);
-          return /^\d+$/.test(val) ? val + "px" : val;
-        }
-        if (width != null) wrapper.style.width = interpret(width);
-        if (height != null) scroller.style.height = interpret(height);
-        instance.refresh();
-      },
-
-      operation: function(f){return operation(f)();},
-      compoundChange: function(f){return compoundChange(f);},
-      refresh: function(){
-        updateDisplay(true, null, lastScrollTop);
-        if (scrollbar.scrollHeight > lastScrollTop)
-          scrollbar.scrollTop = lastScrollTop;
-      },
-      getInputField: function(){return input;},
-      getWrapperElement: function(){return wrapper;},
-      getScrollerElement: function(){return scroller;},
-      getGutterElement: function(){return gutter;}
-    };
-
-    function getLine(n) { return getLineAt(doc, n); }
-    function updateLineHeight(line, height) {
-      gutterDirty = true;
-      var diff = height - line.height;
-      for (var n = line; n; n = n.parent) n.height += diff;
-    }
-
-    function lineContent(line, wrapAt) {
-      if (!line.styles)
-        line.highlight(mode, line.stateAfter = getStateBefore(lineNo(line)), options.tabSize);
-      return line.getContent(options.tabSize, wrapAt, options.lineWrapping);
-    }
-
-    function setValue(code) {
-      var top = {line: 0, ch: 0};
-      updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},
-                  splitLines(code), top, top);
-      updateInput = true;
-    }
-    function getValue(lineSep) {
-      var text = [];
-      doc.iter(0, doc.size, function(line) { text.push(line.text); });
-      return text.join(lineSep || "\n");
-    }
-
-    function onScrollBar(e) {
-      if (scrollbar.scrollTop != lastScrollTop) {
-        lastScrollTop = scroller.scrollTop = scrollbar.scrollTop;
-        updateDisplay([]);
-      }
-    }
-
-    function onScrollMain(e) {
-      if (options.fixedGutter && gutter.style.left != scroller.scrollLeft + "px")
-        gutter.style.left = scroller.scrollLeft + "px";
-      if (scroller.scrollTop != lastScrollTop) {
-        lastScrollTop = scroller.scrollTop;
-        if (scrollbar.scrollTop != lastScrollTop)
-          scrollbar.scrollTop = lastScrollTop;
-        updateDisplay([]);
-      }
-      if (options.onScroll) options.onScroll(instance);
-    }
-
-    function onMouseDown(e) {
-      setShift(e_prop(e, "shiftKey"));
-      // Check whether this is a click in a widget
-      for (var n = e_target(e); n != wrapper; n = n.parentNode)
-        if (n.parentNode == sizer && n != mover) return;
-
-      // See if this is a click in the gutter
-      for (var n = e_target(e); n != wrapper; n = n.parentNode)
-        if (n.parentNode == gutterText) {
-          if (options.onGutterClick)
-            options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
-          return e_preventDefault(e);
-        }
-
-      var start = posFromMouse(e);
-
-      switch (e_button(e)) {
-      case 3:
-        if (gecko) onContextMenu(e);
-        return;
-      case 2:
-        if (start) setCursor(start.line, start.ch, true);
-        setTimeout(focusInput, 20);
-        e_preventDefault(e);
-        return;
-      }
-      // For button 1, if it was clicked inside the editor
-      // (posFromMouse returning non-null), we have to adjust the
-      // selection.
-      if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
-
-      if (!focused) onFocus();
-
-      var now = +new Date, type = "single";
-      if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
-        type = "triple";
-        e_preventDefault(e);
-        setTimeout(focusInput, 20);
-        selectLine(start.line);
-      } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
-        type = "double";
-        lastDoubleClick = {time: now, pos: start};
-        e_preventDefault(e);
-        var word = findWordAt(start);
-        setSelectionUser(word.from, word.to);
-      } else { lastClick = {time: now, pos: start}; }
-
-      function dragEnd(e2) {
-        if (webkit) scroller.draggable = false;
-        draggingText = false;
-        up(); drop();
-        if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
-          e_preventDefault(e2);
-          setCursor(start.line, start.ch, true);
-          focusInput();
-        }
-      }
-      var last = start, going;
-      if (options.dragDrop && dragAndDrop && !options.readOnly && !posEq(sel.from, sel.to) &&
-          !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
-        // Let the drag handler handle this.
-        if (webkit) scroller.draggable = true;
-        var up = connect(document, "mouseup", operation(dragEnd), true);
-        var drop = connect(scroller, "drop", operation(dragEnd), true);
-        draggingText = true;
-        // IE's approach to draggable
-        if (scroller.dragDrop) scroller.dragDrop();
-        return;
-      }
-      e_preventDefault(e);
-      if (type == "single") setCursor(start.line, start.ch, true);
-
-      var startstart = sel.from, startend = sel.to;
-
-      function doSelect(cur) {
-        if (type == "single") {
-          setSelectionUser(start, cur);
-        } else if (type == "double") {
-          var word = findWordAt(cur);
-          if (posLess(cur, startstart)) setSelectionUser(word.from, startend);
-          else setSelectionUser(startstart, word.to);
-        } else if (type == "triple") {
-          if (posLess(cur, startstart)) setSelectionUser(startend, clipPos({line: cur.line, ch: 0}));
-          else setSelectionUser(startstart, clipPos({line: cur.line + 1, ch: 0}));
-        }
-      }
-
-      function extend(e) {
-        var cur = posFromMouse(e, true);
-        if (cur && !posEq(cur, last)) {
-          if (!focused) onFocus();
-          last = cur;
-          doSelect(cur);
-          updateInput = false;
-          var visible = visibleLines();
-          if (cur.line >= visible.to || cur.line < visible.from)
-            going = setTimeout(operation(function(){extend(e);}), 150);
-        }
-      }
-
-      function done(e) {
-        clearTimeout(going);
-        var cur = posFromMouse(e);
-        if (cur) doSelect(cur);
-        e_preventDefault(e);
-        focusInput();
-        updateInput = true;
-        move(); up();
-      }
-      var move = connect(document, "mousemove", operation(function(e) {
-        clearTimeout(going);
-        e_preventDefault(e);
-        if (!ie && !e_button(e)) done(e);
-        else extend(e);
-      }), true);
-      var up = connect(document, "mouseup", operation(done), true);
-    }
-    function onDoubleClick(e) {
-      for (var n = e_target(e); n != wrapper; n = n.parentNode)
-        if (n.parentNode == gutterText) return e_preventDefault(e);
-      e_preventDefault(e);
-    }
-    function onDrop(e) {
-      if (options.onDragEvent && options.onDragEvent(instance, addStop(e))) return;
-      e_preventDefault(e);
-      var pos = posFromMouse(e, true), files = e.dataTransfer.files;
-      if (!pos || options.readOnly) return;
-      if (files && files.length && window.FileReader && window.File) {
-        var n = files.length, text = Array(n), read = 0;
-        var loadFile = function(file, i) {
-          var reader = new FileReader;
-          reader.onload = function() {
-            text[i] = reader.result;
-            if (++read == n) {
-              pos = clipPos(pos);
-              operation(function() {
-                var end = replaceRange(text.join(""), pos, pos);
-                setSelectionUser(pos, end);
-              })();
-            }
-          };
-          reader.readAsText(file);
-        };
-        for (var i = 0; i < n; ++i) loadFile(files[i], i);
-      } else {
-        // Don't do a replace if the drop happened inside of the selected text.
-        if (draggingText && !(posLess(pos, sel.from) || posLess(sel.to, pos))) return;
-        try {
-          var text = e.dataTransfer.getData("Text");
-          if (text) {
-            compoundChange(function() {
-              var curFrom = sel.from, curTo = sel.to;
-              setSelectionUser(pos, pos);
-              if (draggingText) replaceRange("", curFrom, curTo);
-              replaceSelection(text);
-              focusInput();
-            });
-          }
-        }
-        catch(e){}
-      }
-    }
-    function onDragStart(e) {
-      var txt = getSelection();
-      e.dataTransfer.setData("Text", txt);
-
-      // Use dummy image instead of default browsers image.
-      if (e.dataTransfer.setDragImage)
-        e.dataTransfer.setDragImage(elt('img'), 0, 0);
-    }
-
-    function doHandleBinding(bound, dropShift) {
-      if (typeof bound == "string") {
-        bound = commands[bound];
-        if (!bound) return false;
-      }
-      var prevShift = shiftSelecting;
-      try {
-        if (options.readOnly) suppressEdits = true;
-        if (dropShift) shiftSelecting = null;
-        bound(instance);
-      } catch(e) {
-        if (e != Pass) throw e;
-        return false;
-      } finally {
-        shiftSelecting = prevShift;
-        suppressEdits = false;
-      }
-      return true;
-    }
-    var maybeTransition;
-    function handleKeyBinding(e) {
-      // Handle auto keymap transitions
-      var startMap = getKeyMap(options.keyMap), next = startMap.auto;
-      clearTimeout(maybeTransition);
-      if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
-        if (getKeyMap(options.keyMap) == startMap) {
-          options.keyMap = (next.call ? next.call(null, instance) : next);
-        }
-      }, 50);
-
-      var name = keyNames[e_prop(e, "keyCode")], handled = false;
-      var flipCtrlCmd = opera && mac;
-      if (name == null || e.altGraphKey) return false;
-      if (e_prop(e, "altKey")) name = "Alt-" + name;
-      if (e_prop(e, flipCtrlCmd ? "metaKey" : "ctrlKey")) name = "Ctrl-" + name;
-      if (e_prop(e, flipCtrlCmd ? "ctrlKey" : "metaKey")) name = "Cmd-" + name;
-
-      var stopped = false;
-      function stop() { stopped = true; }
-
-      if (e_prop(e, "shiftKey")) {
-        handled = lookupKey("Shift-" + name, options.extraKeys, options.keyMap,
-                            function(b) {return doHandleBinding(b, true);}, stop)
-               || lookupKey(name, options.extraKeys, options.keyMap, function(b) {
-                 if (typeof b == "string" && /^go[A-Z]/.test(b)) return doHandleBinding(b);
-               }, stop);
-      } else {
-        handled = lookupKey(name, options.extraKeys, options.keyMap, doHandleBinding, stop);
-      }
-      if (stopped) handled = false;
-      if (handled) {
-        e_preventDefault(e);
-        restartBlink();
-        if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
-      }
-      return handled;
-    }
-    function handleCharBinding(e, ch) {
-      var handled = lookupKey("'" + ch + "'", options.extraKeys,
-                              options.keyMap, function(b) { return doHandleBinding(b, true); });
-      if (handled) {
-        e_preventDefault(e);
-        restartBlink();
-      }
-      return handled;
-    }
-
-    var lastStoppedKey = null;
-    function onKeyDown(e) {
-      if (!focused) onFocus();
-      if (ie && e.keyCode == 27) { e.returnValue = false; }
-      if (pollingFast) { if (readInput()) pollingFast = false; }
-      if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
-      var code = e_prop(e, "keyCode");
-      // IE does strange things with escape.
-      setShift(code == 16 || e_prop(e, "shiftKey"));
-      // First give onKeyEvent option a chance to handle this.
-      var handled = handleKeyBinding(e);
-      if (opera) {
-        lastStoppedKey = handled ? code : null;
-        // Opera has no cut event... we try to at least catch the key combo
-        if (!handled && code == 88 && e_prop(e, mac ? "metaKey" : "ctrlKey"))
-          replaceSelection("");
-      }
-    }
-    function onKeyPress(e) {
-      if (pollingFast) readInput();
-      if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
-      var keyCode = e_prop(e, "keyCode"), charCode = e_prop(e, "charCode");
-      if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
-      if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(e)) return;
-      var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
-      if (options.electricChars && mode.electricChars && options.smartIndent && !options.readOnly) {
-        if (mode.electricChars.indexOf(ch) > -1)
-          setTimeout(operation(function() {indentLine(sel.to.line, "smart");}), 75);
-      }
-      if (handleCharBinding(e, ch)) return;
-      fastPoll();
-    }
-    function onKeyUp(e) {
-      if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;
-      if (e_prop(e, "keyCode") == 16) shiftSelecting = null;
-    }
-
-    function onFocus() {
-      if (options.readOnly == "nocursor") return;
-      if (!focused) {
-        if (options.onFocus) options.onFocus(instance);
-        focused = true;
-        if (scroller.className.search(/\bCodeMirror-focused\b/) == -1)
-          scroller.className += " CodeMirror-focused";
-      }
-      slowPoll();
-      restartBlink();
-    }
-    function onBlur() {
-      if (focused) {
-        if (options.onBlur) options.onBlur(instance);
-        focused = false;
-        if (bracketHighlighted)
-          operation(function(){
-            if (bracketHighlighted) { bracketHighlighted(); bracketHighlighted = null; }
-          })();
-        scroller.className = scroller.className.replace(" CodeMirror-focused", "");
-      }
-      clearInterval(blinker);
-      setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);
-    }
-
-    // Replace the range from from to to by the strings in newText.
-    // Afterwards, set the selection to selFrom, selTo.
-    function updateLines(from, to, newText, selFrom, selTo) {
-      if (suppressEdits) return;
-      var old = [];
-      doc.iter(from.line, to.line + 1, function(line) {
-        old.push(newHL(line.text, line.markedSpans));
-      });
-      if (history) {
-        history.addChange(from.line, newText.length, old);
-        while (history.done.length > options.undoDepth) history.done.shift();
-      }
-      var lines = updateMarkedSpans(hlSpans(old[0]), hlSpans(lst(old)), from.ch, to.ch, newText);
-      updateLinesNoUndo(from, to, lines, selFrom, selTo);
-    }
-    function unredoHelper(from, to) {
-      if (!from.length) return;
-      var set = from.pop(), out = [];
-      for (var i = set.length - 1; i >= 0; i -= 1) {
-        var change = set[i];
-        var replaced = [], end = change.start + change.added;
-        doc.iter(change.start, end, function(line) { replaced.push(newHL(line.text, line.markedSpans)); });
-        out.push({start: change.start, added: change.old.length, old: replaced});
-        var pos = {line: change.start + change.old.length - 1,
-                   ch: editEnd(hlText(lst(replaced)), hlText(lst(change.old)))};
-        updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length},
-                          change.old, pos, pos);
-      }
-      updateInput = true;
-      to.push(out);
-    }
-    function undo() {unredoHelper(history.done, history.undone);}
-    function redo() {unredoHelper(history.undone, history.done);}
-
-    function updateLinesNoUndo(from, to, lines, selFrom, selTo) {
-      if (suppressEdits) return;
-      var recomputeMaxLength = false, maxLineLength = maxLine.text.length;
-      if (!options.lineWrapping)
-        doc.iter(from.line, to.line + 1, function(line) {
-          if (!line.hidden && line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}
-        });
-      if (from.line != to.line || lines.length > 1) gutterDirty = true;
-
-      var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);
-      var lastHL = lst(lines);
-
-      // First adjust the line structure
-      if (from.ch == 0 && to.ch == 0 && hlText(lastHL) == "") {
-        // This is a whole-line replace. Treated specially to make
-        // sure line objects move the way they are supposed to.
-        var added = [], prevLine = null;
-        for (var i = 0, e = lines.length - 1; i < e; ++i)
-          added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
-        lastLine.update(lastLine.text, hlSpans(lastHL));
-        if (nlines) doc.remove(from.line, nlines, callbacks);
-        if (added.length) doc.insert(from.line, added);
-      } else if (firstLine == lastLine) {
-        if (lines.length == 1) {
-          firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]) + firstLine.text.slice(to.ch), hlSpans(lines[0]));
-        } else {
-          for (var added = [], i = 1, e = lines.length - 1; i < e; ++i)
-            added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
-          added.push(new Line(hlText(lastHL) + firstLine.text.slice(to.ch), hlSpans(lastHL)));
-          firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
-          doc.insert(from.line + 1, added);
-        }
-      } else if (lines.length == 1) {
-        firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]) + lastLine.text.slice(to.ch), hlSpans(lines[0]));
-        doc.remove(from.line + 1, nlines, callbacks);
-      } else {
-        var added = [];
-        firstLine.update(firstLine.text.slice(0, from.ch) + hlText(lines[0]), hlSpans(lines[0]));
-        lastLine.update(hlText(lastHL) + lastLine.text.slice(to.ch), hlSpans(lastHL));
-        for (var i = 1, e = lines.length - 1; i < e; ++i)
-          added.push(new Line(hlText(lines[i]), hlSpans(lines[i])));
-        if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);
-        doc.insert(from.line + 1, added);
-      }
-      if (options.lineWrapping) {
-        var perLine = Math.max(5, scroller.clientWidth / charWidth() - 3);
-        doc.iter(from.line, from.line + lines.length, function(line) {
-          if (line.hidden) return;
-          var guess = Math.ceil(line.text.length / perLine) || 1;
-          if (guess != line.height) updateLineHeight(line, guess);
-        });
-      } else {
-        doc.iter(from.line, from.line + lines.length, function(line) {
-          var l = line.text;
-          if (!line.hidden && l.length > maxLineLength) {
-            maxLine = line; maxLineLength = l.length; maxLineChanged = true;
-            recomputeMaxLength = false;
-          }
-        });
-        if (recomputeMaxLength) updateMaxLine = true;
-      }
-
-      // Adjust frontier, schedule worker
-      frontier = Math.min(frontier, from.line);
-      startWorker(400);
-
-      var lendiff = lines.length - nlines - 1;
-      // Remember that these lines changed, for updating the display
-      changes.push({from: from.line, to: to.line + 1, diff: lendiff});
-      if (options.onChange) {
-        // Normalize lines to contain only strings, since that's what
-        // the change event handler expects
-        for (var i = 0; i < lines.length; ++i)
-          if (typeof lines[i] != "string") lines[i] = lines[i].text;
-        var changeObj = {from: from, to: to, text: lines};
-        if (textChanged) {
-          for (var cur = textChanged; cur.next; cur = cur.next) {}
-          cur.next = changeObj;
-        } else textChanged = changeObj;
-      }
-
-      // Update the selection
-      function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}
-      setSelection(clipPos(selFrom), clipPos(selTo),
-                   updateLine(sel.from.line), updateLine(sel.to.line));
-    }
-
-    function needsScrollbar() {
-      var realHeight = doc.height * textHeight() + 2 * paddingTop();
-      return realHeight * .99 > scroller.offsetHeight ? realHeight : false;
-    }
-
-    function updateVerticalScroll(scrollTop) {
-      var scrollHeight = needsScrollbar();
-      scrollbar.style.display = scrollHeight ? "block" : "none";
-      if (scrollHeight) {
-        scrollbarInner.style.height = sizer.style.minHeight = scrollHeight + "px";
-        scrollbar.style.height = scroller.clientHeight + "px";
-        if (scrollTop != null) {
-          scrollbar.scrollTop = scroller.scrollTop = scrollTop;
-          // 'Nudge' the scrollbar to work around a Webkit bug where,
-          // in some situations, we'd end up with a scrollbar that
-          // reported its scrollTop (and looked) as expected, but
-          // *behaved* as if it was still in a previous state (i.e.
-          // couldn't scroll up, even though it appeared to be at the
-          // bottom).
-          if (webkit) setTimeout(function() {
-            if (scrollbar.scrollTop != scrollTop) return;
-            scrollbar.scrollTop = scrollTop + (scrollTop ? -1 : 1);
-            scrollbar.scrollTop = scrollTop;
-          }, 0);
-        }
-      } else {
-        sizer.style.minHeight = "";
-      }
-      // Position the mover div to align with the current virtual scroll position
-      mover.style.top = displayOffset * textHeight() + "px";
-    }
-
-    function computeMaxLength() {
-      maxLine = getLine(0); maxLineChanged = true;
-      var maxLineLength = maxLine.text.length;
-      doc.iter(1, doc.size, function(line) {
-        var l = line.text;
-        if (!line.hidden && l.length > maxLineLength) {
-          maxLineLength = l.length; maxLine = line;
-        }
-      });
-      updateMaxLine = false;
-    }
-
-    function replaceRange(code, from, to) {
-      from = clipPos(from);
-      if (!to) to = from; else to = clipPos(to);
-      code = splitLines(code);
-      function adjustPos(pos) {
-        if (posLess(pos, from)) return pos;
-        if (!posLess(to, pos)) return end;
-        var line = pos.line + code.length - (to.line - from.line) - 1;
-        var ch = pos.ch;
-        if (pos.line == to.line)
-          ch += lst(code).length - (to.ch - (to.line == from.line ? from.ch : 0));
-        return {line: line, ch: ch};
-      }
-      var end;
-      replaceRange1(code, from, to, function(end1) {
-        end = end1;
-        return {from: adjustPos(sel.from), to: adjustPos(sel.to)};
-      });
-      return end;
-    }
-    function replaceSelection(code, collapse) {
-      replaceRange1(splitLines(code), sel.from, sel.to, function(end) {
-        if (collapse == "end") return {from: end, to: end};
-        else if (collapse == "start") return {from: sel.from, to: sel.from};
-        else return {from: sel.from, to: end};
-      });
-    }
-    function replaceRange1(code, from, to, computeSel) {
-      var endch = code.length == 1 ? code[0].length + from.ch : lst(code).length;
-      var newSel = computeSel({line: from.line + code.length - 1, ch: endch});
-      updateLines(from, to, code, newSel.from, newSel.to);
-    }
-
-    function getRange(from, to, lineSep) {
-      var l1 = from.line, l2 = to.line;
-      if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);
-      var code = [getLine(l1).text.slice(from.ch)];
-      doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });
-      code.push(getLine(l2).text.slice(0, to.ch));
-      return code.join(lineSep || "\n");
-    }
-    function getSelection(lineSep) {
-      return getRange(sel.from, sel.to, lineSep);
-    }
-
-    function slowPoll() {
-      if (pollingFast) return;
-      poll.set(options.pollInterval, function() {
-        readInput();
-        if (focused) slowPoll();
-      });
-    }
-    function fastPoll() {
-      var missed = false;
-      pollingFast = true;
-      function p() {
-        var changed = readInput();
-        if (!changed && !missed) {missed = true; poll.set(60, p);}
-        else {pollingFast = false; slowPoll();}
-      }
-      poll.set(20, p);
-    }
-
-    // Previnput is a hack to work with IME. If we reset the textarea
-    // on every change, that breaks IME. So we look for changes
-    // compared to the previous content instead. (Modern browsers have
-    // events that indicate IME taking place, but these are not widely
-    // supported or compatible enough yet to rely on.)
-    var prevInput = "";
-    function readInput() {
-      if (!focused || hasSelection(input) || options.readOnly) return false;
-      var text = input.value;
-      if (text == prevInput) return false;
-      if (!nestedOperation) startOperation();
-      shiftSelecting = null;
-      var same = 0, l = Math.min(prevInput.length, text.length);
-      while (same < l && prevInput[same] == text[same]) ++same;
-      if (same < prevInput.length)
-        sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};
-      else if (overwrite && posEq(sel.from, sel.to) && !pasteIncoming)
-        sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};
-      replaceSelection(text.slice(same), "end");
-      if (text.length > 1000) { input.value = prevInput = ""; }
-      else prevInput = text;
-      if (!nestedOperation) endOperation();
-      pasteIncoming = false;
-      return true;
-    }
-    function resetInput(user) {
-      if (!posEq(sel.from, sel.to)) {
-        prevInput = "";
-        input.value = getSelection();
-        if (focused) selectInput(input);
-      } else if (user) prevInput = input.value = "";
-    }
-
-    function focusInput() {
-      if (options.readOnly != "nocursor") input.focus();
-    }
-
-    function scrollCursorIntoView() {
-      var coords = calculateCursorCoords();
-      scrollIntoView(coords.x, coords.y, coords.x, coords.yBot);
-      if (!focused) return;
-      var box = sizer.getBoundingClientRect(), doScroll = null;
-      if (coords.y + box.top < 0) doScroll = true;
-      else if (coords.y + box.top + textHeight() > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
-      if (doScroll != null) {
-        var hidden = cursor.style.display == "none";
-        if (hidden) {
-          cursor.style.display = "";
-          cursor.style.left = coords.x + "px";
-          cursor.style.top = (coords.y - displayOffset) + "px";
-        }
-        cursor.scrollIntoView(doScroll);
-        if (hidden) cursor.style.display = "none";
-      }
-    }
-    function calculateCursorCoords() {
-      var cursor = localCoords(sel.inverted ? sel.from : sel.to);
-      var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;
-      return {x: x, y: cursor.y, yBot: cursor.yBot};
-    }
-    function scrollIntoView(x1, y1, x2, y2) {
-      var scrollPos = calculateScrollPos(x1, y1, x2, y2);
-      if (scrollPos.scrollLeft != null) {scroller.scrollLeft = scrollPos.scrollLeft;}
-      if (scrollPos.scrollTop != null) {scrollbar.scrollTop = scroller.scrollTop = scrollPos.scrollTop;}
-    }
-    function calculateScrollPos(x1, y1, x2, y2) {
-      var pl = paddingLeft(), pt = paddingTop();
-      y1 += pt; y2 += pt; x1 += pl; x2 += pl;
-      var screen = scroller.clientHeight, screentop = scrollbar.scrollTop, result = {};
-      var docBottom = needsScrollbar() || Infinity;
-      var atTop = y1 < pt + 10, atBottom = y2 + pt > docBottom - 10;
-      if (y1 < screentop) result.scrollTop = atTop ? 0 : Math.max(0, y1);
-      else if (y2 > screentop + screen) result.scrollTop = (atBottom ? docBottom : y2) - screen;
-
-      var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
-      var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
-      var atLeft = x1 < gutterw + pl + 10;
-      if (x1 < screenleft + gutterw || atLeft) {
-        if (atLeft) x1 = 0;
-        result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
-      } else if (x2 > screenw + screenleft - 3) {
-        result.scrollLeft = x2 + 10 - screenw;
-      }
-      return result;
-    }
-
-    function visibleLines(scrollTop) {
-      var lh = textHeight(), top = (scrollTop != null ? scrollTop : scrollbar.scrollTop) - paddingTop();
-      var fromHeight = Math.max(0, Math.floor(top / lh));
-      var toHeight = Math.ceil((top + scroller.clientHeight) / lh);
-      return {from: lineAtHeight(doc, fromHeight),
-              to: lineAtHeight(doc, toHeight)};
-    }
-    // Uses a set of changes plus the current scroll position to
-    // determine which DOM updates have to be made, and makes the
-    // updates.
-    function updateDisplay(changes, suppressCallback, scrollTop) {
-      if (!scroller.clientWidth) {
-        showingFrom = showingTo = displayOffset = 0;
-        return;
-      }
-      // Compute the new visible window
-      // If scrollTop is specified, use that to determine which lines
-      // to render instead of the current scrollbar position.
-      var visible = visibleLines(scrollTop);
-      // Bail out if the visible area is already rendered and nothing changed.
-      if (changes !== true && changes.length == 0 && visible.from > showingFrom && visible.to < showingTo) {
-        updateVerticalScroll(scrollTop);
-        return;
-      }
-      var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);
-      if (showingFrom < from && from - showingFrom < 20) from = showingFrom;
-      if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);
-
-      // Create a range of theoretically intact lines, and punch holes
-      // in that using the change info.
-      var intact = changes === true ? [] :
-        computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);
-      // Clip off the parts that won't be visible
-      var intactLines = 0;
-      for (var i = 0; i < intact.length; ++i) {
-        var range = intact[i];
-        if (range.from < from) {range.domStart += (from - range.from); range.from = from;}
-        if (range.to > to) range.to = to;
-        if (range.from >= range.to) intact.splice(i--, 1);
-        else intactLines += range.to - range.from;
-      }
-      if (intactLines == to - from && from == showingFrom && to == showingTo) {
-        updateVerticalScroll(scrollTop);
-        return;
-      }
-      intact.sort(function(a, b) {return a.domStart - b.domStart;});
-
-      var th = textHeight(), gutterDisplay = gutter.style.display;
-      lineDiv.style.display = "none";
-      patchDisplay(from, to, intact);
-      lineDiv.style.display = gutter.style.display = "";
-
-      var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;
-      // This is just a bogus formula that detects when the editor is
-      // resized or the font size changes.
-      if (different) lastSizeC = scroller.clientHeight + th;
-      if (from != showingFrom || to != showingTo && options.onViewportChange)
-        setTimeout(function(){
-          if (options.onViewportChange) options.onViewportChange(instance, from, to);
-        });
-      showingFrom = from; showingTo = to;
-      displayOffset = heightAtLine(doc, from);
-      startWorker(100);
-
-      // Since this is all rather error prone, it is honoured with the
-      // only assertion in the whole file.
-      if (lineDiv.childNodes.length != showingTo - showingFrom)
-        throw new Error("BAD PATCH! " + JSON.stringify(intact) + " size=" + (showingTo - showingFrom) +
-                        " nodes=" + lineDiv.childNodes.length);
-
-      function checkHeights() {
-        var curNode = lineDiv.firstChild, heightChanged = false;
-        doc.iter(showingFrom, showingTo, function(line) {
-          // Work around bizarro IE7 bug where, sometimes, our curNode
-          // is magically replaced with a new node in the DOM, leaving
-          // us with a reference to an orphan (nextSibling-less) node.
-          if (!curNode) return;
-          if (!line.hidden) {
-            var height = Math.round(curNode.offsetHeight / th) || 1;
-            if (line.height != height) {
-              updateLineHeight(line, height);
-              gutterDirty = heightChanged = true;
-            }
-          }
-          curNode = curNode.nextSibling;
-        });
-        return heightChanged;
-      }
-
-      if (options.lineWrapping) checkHeights();
-
-      gutter.style.display = gutterDisplay;
-      if (different || gutterDirty) {
-        // If the gutter grew in size, re-check heights. If those changed, re-draw gutter.
-        updateGutter() && options.lineWrapping && checkHeights() && updateGutter();
-      }
-      updateVerticalScroll(scrollTop);
-      updateSelection();
-      if (!suppressCallback && options.onUpdate) options.onUpdate(instance);
-      return true;
-    }
-
-    function computeIntact(intact, changes) {
-      for (var i = 0, l = changes.length || 0; i < l; ++i) {
-        var change = changes[i], intact2 = [], diff = change.diff || 0;
-        for (var j = 0, l2 = intact.length; j < l2; ++j) {
-          var range = intact[j];
-          if (change.to <= range.from && change.diff)
-            intact2.push({from: range.from + diff, to: range.to + diff,
-                          domStart: range.domStart});
-          else if (change.to <= range.from || change.from >= range.to)
-            intact2.push(range);
-          else {
-            if (change.from > range.from)
-              intact2.push({from: range.from, to: change.from, domStart: range.domStart});
-            if (change.to < range.to)
-              intact2.push({from: change.to + diff, to: range.to + diff,
-                            domStart: range.domStart + (change.to - range.from)});
-          }
-        }
-        intact = intact2;
-      }
-      return intact;
-    }
-
-    function patchDisplay(from, to, intact) {
-      function killNode(node) {
-        var tmp = node.nextSibling;
-        node.parentNode.removeChild(node);
-        return tmp;
-      }
-      // The first pass removes the DOM nodes that aren't intact.
-      if (!intact.length) removeChildren(lineDiv);
-      else {
-        var domPos = 0, curNode = lineDiv.firstChild, n;
-        for (var i = 0; i < intact.length; ++i) {
-          var cur = intact[i];
-          while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}
-          for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}
-        }
-        while (curNode) curNode = killNode(curNode);
-      }
-      // This pass fills in the lines that actually changed.
-      var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;
-      doc.iter(from, to, function(line) {
-        if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();
-        if (!nextIntact || nextIntact.from > j) {
-          if (line.hidden) var lineElement = elt("pre");
-          else {
-            var lineElement = lineContent(line);
-            if (line.className) lineElement.className = line.className;
-            // Kludge to make sure the styled element lies behind the selection (by z-index)
-            if (line.bgClassName) {
-              var pre = elt("pre", "\u00a0", line.bgClassName, "position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: -2");
-              lineElement = elt("div", [pre, lineElement], null, "position: relative");
-            }
-          }
-          lineDiv.insertBefore(lineElement, curNode);
-        } else {
-          curNode = curNode.nextSibling;
-        }
-        ++j;
-      });
-    }
-
-    function updateGutter() {
-      if (!options.gutter && !options.lineNumbers) return;
-      var hText = mover.offsetHeight, hEditor = scroller.clientHeight;
-      gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + "px";
-      var fragment = document.createDocumentFragment(), i = showingFrom, normalNode;
-      doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {
-        if (line.hidden) {
-          fragment.appendChild(elt("pre"));
-        } else {
-          var marker = line.gutterMarker;
-          var text = options.lineNumbers ? options.lineNumberFormatter(i + options.firstLineNumber) : null;
-          if (marker && marker.text)
-            text = marker.text.replace("%N%", text != null ? text : "");
-          else if (text == null)
-            text = "\u00a0";
-          var markerElement = fragment.appendChild(elt("pre", null, marker && marker.style));
-          markerElement.innerHTML = text;
-          for (var j = 1; j < line.height; ++j) {
-            markerElement.appendChild(elt("br"));
-            markerElement.appendChild(document.createTextNode("\u00a0"));
-          }
-          if (!marker) normalNode = i;
-        }
-        ++i;
-      });
-      gutter.style.display = "none";
-      removeChildrenAndAdd(gutterText, fragment);
-      // Make sure scrolling doesn't cause number gutter size to pop
-      if (normalNode != null && options.lineNumbers) {
-        var node = gutterText.childNodes[normalNode - showingFrom];
-        var minwidth = String(doc.size).length, val = eltText(node.firstChild), pad = "";
-        while (val.length + pad.length < minwidth) pad += "\u00a0";
-        if (pad) node.insertBefore(document.createTextNode(pad), node.firstChild);
-      }
-      gutter.style.display = "";
-      var resized = Math.abs((parseInt(lineSpace.style.marginLeft) || 0) - gutter.offsetWidth) > 2;
-      lineSpace.style.marginLeft = gutter.offsetWidth + "px";
-      gutterDirty = false;
-      return resized;
-    }
-    function updateSelection() {
-      var collapsed = posEq(sel.from, sel.to);
-      var fromPos = localCoords(sel.from, true);
-      var toPos = collapsed ? fromPos : localCoords(sel.to, true);
-      var headPos = sel.inverted ? fromPos : toPos, th = textHeight();
-      var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);
-      inputDiv.style.top = Math.max(0, Math.min(scroller.offsetHeight, headPos.y + lineOff.top - wrapOff.top)) + "px";
-      inputDiv.style.left = Math.max(0, Math.min(scroller.offsetWidth, headPos.x + lineOff.left - wrapOff.left)) + "px";
-      if (collapsed) {
-        cursor.style.top = headPos.y + "px";
-        cursor.style.left = (options.lineWrapping ? Math.min(headPos.x, lineSpace.offsetWidth) : headPos.x) + "px";
-        cursor.style.display = "";
-        selectionDiv.style.display = "none";
-      } else {
-        var sameLine = fromPos.y == toPos.y, fragment = document.createDocumentFragment();
-        var clientWidth = lineSpace.clientWidth || lineSpace.offsetWidth;
-        var clientHeight = lineSpace.clientHeight || lineSpace.offsetHeight;
-        var add = function(left, top, right, height) {
-          var rstyle = quirksMode ? "width: " + (!right ? clientWidth : clientWidth - right - left) + "px"
-                                  : "right: " + right + "px";
-          fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
-                                   "px; top: " + top + "px; " + rstyle + "; height: " + height + "px"));
-        };
-        if (sel.from.ch && fromPos.y >= 0) {
-          var right = sameLine ? clientWidth - toPos.x : 0;
-          add(fromPos.x, fromPos.y, right, th);
-        }
-        var middleStart = Math.max(0, fromPos.y + (sel.from.ch ? th : 0));
-        var middleHeight = Math.min(toPos.y, clientHeight) - middleStart;
-        if (middleHeight > 0.2 * th)
-          add(0, middleStart, 0, middleHeight);
-        if ((!sameLine || !sel.from.ch) && toPos.y < clientHeight - .5 * th)
-          add(0, toPos.y, clientWidth - toPos.x, th);
-        removeChildrenAndAdd(selectionDiv, fragment);
-        cursor.style.display = "none";
-        selectionDiv.style.display = "";
-      }
-    }
-
-    function setShift(val) {
-      if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);
-      else shiftSelecting = null;
-    }
-    function setSelectionUser(from, to) {
-      var sh = shiftSelecting && clipPos(shiftSelecting);
-      if (sh) {
-        if (posLess(sh, from)) from = sh;
-        else if (posLess(to, sh)) to = sh;
-      }
-      setSelection(from, to);
-      userSelChange = true;
-    }
-    // Update the selection. Last two args are only used by
-    // updateLines, since they have to be expressed in the line
-    // numbers before the update.
-    function setSelection(from, to, oldFrom, oldTo) {
-      goalColumn = null;
-      if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}
-      if (posEq(sel.from, from) && posEq(sel.to, to)) return;
-      if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}
-
-      // Skip over hidden lines.
-      if (from.line != oldFrom) {
-        var from1 = skipHidden(from, oldFrom, sel.from.ch);
-        // If there is no non-hidden line left, force visibility on current line
-        if (!from1) setLineHidden(from.line, false);
-        else from = from1;
-      }
-      if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);
-
-      if (posEq(from, to)) sel.inverted = false;
-      else if (posEq(from, sel.to)) sel.inverted = false;
-      else if (posEq(to, sel.from)) sel.inverted = true;
-
-      if (options.autoClearEmptyLines && posEq(sel.from, sel.to)) {
-        var head = sel.inverted ? from : to;
-        if (head.line != sel.from.line && sel.from.line < doc.size) {
-          var oldLine = getLine(sel.from.line);
-          if (/^\s+$/.test(oldLine.text))
-            setTimeout(operation(function() {
-              if (oldLine.parent && /^\s+$/.test(oldLine.text)) {
-                var no = lineNo(oldLine);
-                replaceRange("", {line: no, ch: 0}, {line: no, ch: oldLine.text.length});
-              }
-            }, 10));
-        }
-      }
-
-      sel.from = from; sel.to = to;
-      selectionChanged = true;
-    }
-    function skipHidden(pos, oldLine, oldCh) {
-      function getNonHidden(dir) {
-        var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;
-        while (lNo != end) {
-          var line = getLine(lNo);
-          if (!line.hidden) {
-            var ch = pos.ch;
-            if (toEnd || ch > oldCh || ch > line.text.length) ch = line.text.length;
-            return {line: lNo, ch: ch};
-          }
-          lNo += dir;
-        }
-      }
-      var line = getLine(pos.line);
-      var toEnd = pos.ch == line.text.length && pos.ch != oldCh;
-      if (!line.hidden) return pos;
-      if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);
-      else return getNonHidden(-1) || getNonHidden(1);
-    }
-    function setCursor(line, ch, user) {
-      var pos = clipPos({line: line, ch: ch || 0});
-      (user ? setSelectionUser : setSelection)(pos, pos);
-    }
-
-    function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}
-    function clipPos(pos) {
-      if (pos.line < 0) return {line: 0, ch: 0};
-      if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};
-      var ch = pos.ch, linelen = getLine(pos.line).text.length;
-      if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};
-      else if (ch < 0) return {line: pos.line, ch: 0};
-      else return pos;
-    }
-
-    function findPosH(dir, unit) {
-      var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;
-      var lineObj = getLine(line);
-      function findNextLine() {
-        for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {
-          var lo = getLine(l);
-          if (!lo.hidden) { line = l; lineObj = lo; return true; }
-        }
-      }
-      function moveOnce(boundToLine) {
-        if (ch == (dir < 0 ? 0 : lineObj.text.length)) {
-          if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;
-          else return false;
-        } else ch += dir;
-        return true;
-      }
-      if (unit == "char") moveOnce();
-      else if (unit == "column") moveOnce(true);
-      else if (unit == "word") {
-        var sawWord = false;
-        for (;;) {
-          if (dir < 0) if (!moveOnce()) break;
-          if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;
-          else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}
-          if (dir > 0) if (!moveOnce()) break;
-        }
-      }
-      return {line: line, ch: ch};
-    }
-    function moveH(dir, unit) {
-      var pos = dir < 0 ? sel.from : sel.to;
-      if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);
-      setCursor(pos.line, pos.ch, true);
-    }
-    function deleteH(dir, unit) {
-      if (!posEq(sel.from, sel.to)) replaceRange("", sel.from, sel.to);
-      else if (dir < 0) replaceRange("", findPosH(dir, unit), sel.to);
-      else replaceRange("", sel.from, findPosH(dir, unit));
-      userSelChange = true;
-    }
-    function moveV(dir, unit) {
-      var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);
-      if (goalColumn != null) pos.x = goalColumn;
-      if (unit == "page") {
-        var screen = Math.min(scroller.clientHeight, window.innerHeight || document.documentElement.clientHeight);
-        var target = coordsChar(pos.x, pos.y + screen * dir);
-      } else if (unit == "line") {
-        var th = textHeight();
-        var target = coordsChar(pos.x, pos.y + .5 * th + dir * th);
-      }
-      if (unit == "page") scrollbar.scrollTop += localCoords(target, true).y - pos.y;
-      setCursor(target.line, target.ch, true);
-      goalColumn = pos.x;
-    }
-
-    function findWordAt(pos) {
-      var line = getLine(pos.line).text;
-      var start = pos.ch, end = pos.ch;
-      if (line) {
-        if (pos.after === false || end == line.length) --start; else ++end;
-        var startChar = line.charAt(start);
-        var check = isWordChar(startChar) ? isWordChar :
-                    /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} :
-                    function(ch) {return !/\s/.test(ch) && isWordChar(ch);};
-        while (start > 0 && check(line.charAt(start - 1))) --start;
-        while (end < line.length && check(line.charAt(end))) ++end;
-      }
-      return {from: {line: pos.line, ch: start}, to: {line: pos.line, ch: end}};
-    }
-    function selectLine(line) {
-      setSelectionUser({line: line, ch: 0}, clipPos({line: line + 1, ch: 0}));
-    }
-    function indentSelected(mode) {
-      if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);
-      var e = sel.to.line - (sel.to.ch ? 0 : 1);
-      for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);
-    }
-
-    function indentLine(n, how) {
-      if (!how) how = "add";
-      if (how == "smart") {
-        if (!mode.indent) how = "prev";
-        else var state = getStateBefore(n);
-      }
-
-      var line = getLine(n), curSpace = line.indentation(options.tabSize),
-          curSpaceString = line.text.match(/^\s*/)[0], indentation;
-      if (how == "smart") {
-        indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);
-        if (indentation == Pass) how = "prev";
-      }
-      if (how == "prev") {
-        if (n) indentation = getLine(n-1).indentation(options.tabSize);
-        else indentation = 0;
-      }
-      else if (how == "add") indentation = curSpace + options.indentUnit;
-      else if (how == "subtract") indentation = curSpace - options.indentUnit;
-      indentation = Math.max(0, indentation);
-      var diff = indentation - curSpace;
-
-      var indentString = "", pos = 0;
-      if (options.indentWithTabs)
-        for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += "\t";}
-      if (pos < indentation) indentString += spaceStr(indentation - pos);
-
-      if (indentString != curSpaceString)
-        replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});
-      line.stateAfter = null;
-    }
-
-    function loadMode() {
-      mode = CodeMirror.getMode(options, options.mode);
-      doc.iter(0, doc.size, function(line) { line.stateAfter = null; });
-      frontier = 0;
-      startWorker(100);
-    }
-    function gutterChanged() {
-      var visible = options.gutter || options.lineNumbers;
-      gutter.style.display = visible ? "" : "none";
-      if (visible) gutterDirty = true;
-      else lineDiv.parentNode.style.marginLeft = 0;
-    }
-    function wrappingChanged(from, to) {
-      if (options.lineWrapping) {
-        wrapper.className += " CodeMirror-wrap";
-        var perLine = scroller.clientWidth / charWidth() - 3;
-        doc.iter(0, doc.size, function(line) {
-          if (line.hidden) return;
-          var guess = Math.ceil(line.text.length / perLine) || 1;
-          if (guess != 1) updateLineHeight(line, guess);
-        });
-        lineSpace.style.minWidth = widthForcer.style.left = "";
-      } else {
-        wrapper.className = wrapper.className.replace(" CodeMirror-wrap", "");
-        computeMaxLength();
-        doc.iter(0, doc.size, function(line) {
-          if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);
-        });
-      }
-      changes.push({from: 0, to: doc.size});
-    }
-    function themeChanged() {
-      scroller.className = scroller.className.replace(/\s*cm-s-\S+/g, "") +
-        options.theme.replace(/(^|\s)\s*/g, " cm-s-");
-    }
-    function keyMapChanged() {
-      var style = keyMap[options.keyMap].style;
-      wrapper.className = wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
-        (style ? " cm-keymap-" + style : "");
-    }
-
-    function TextMarker(type, style) { this.lines = []; this.type = type; if (style) this.style = style; }
-    TextMarker.prototype.clear = operation(function() {
-      var min, max;
-      for (var i = 0; i < this.lines.length; ++i) {
-        var line = this.lines[i];
-        var span = getMarkedSpanFor(line.markedSpans, this);
-        if (span.from != null) min = lineNo(line);
-        if (span.to != null) max = lineNo(line);
-        line.markedSpans = removeMarkedSpan(line.markedSpans, span);
-      }
-      if (min != null) changes.push({from: min, to: max + 1});
-      this.lines.length = 0;
-      this.explicitlyCleared = true;
-    });
-    TextMarker.prototype.find = function() {
-      var from, to;
-      for (var i = 0; i < this.lines.length; ++i) {
-        var line = this.lines[i];
-        var span = getMarkedSpanFor(line.markedSpans, this);
-        if (span.from != null || span.to != null) {
-          var found = lineNo(line);
-          if (span.from != null) from = {line: found, ch: span.from};
-          if (span.to != null) to = {line: found, ch: span.to};
-        }
-      }
-      if (this.type == "bookmark") return from;
-      return from && {from: from, to: to};
-    };
-
-    function markText(from, to, className, options) {
-      from = clipPos(from); to = clipPos(to);
-      var marker = new TextMarker("range", className);
-      if (options) for (var opt in options) if (options.hasOwnProperty(opt))
-        marker[opt] = options[opt];
-      var curLine = from.line;
-      doc.iter(curLine, to.line + 1, function(line) {
-        var span = {from: curLine == from.line ? from.ch : null,
-                    to: curLine == to.line ? to.ch : null,
-                    marker: marker};
-        line.markedSpans = (line.markedSpans || []).concat([span]);
-        marker.lines.push(line);
-        ++curLine;
-      });
-      changes.push({from: from.line, to: to.line + 1});
-      return marker;
-    }
-
-    function setBookmark(pos) {
-      pos = clipPos(pos);
-      var marker = new TextMarker("bookmark"), line = getLine(pos.line);
-      history.addChange(pos.line, 1, [newHL(line.text, line.markedSpans)], true);
-      var span = {from: pos.ch, to: pos.ch, marker: marker};
-      line.markedSpans = (line.markedSpans || []).concat([span]);
-      marker.lines.push(line);
-      return marker;
-    }
-
-    function findMarksAt(pos) {
-      pos = clipPos(pos);
-      var markers = [], spans = getLine(pos.line).markedSpans;
-      if (spans) for (var i = 0; i < spans.length; ++i) {
-        var span = spans[i];
-        if ((span.from == null || span.from <= pos.ch) &&
-            (span.to == null || span.to >= pos.ch))
-          markers.push(span.marker);
-      }
-      return markers;
-    }
-
-    function addGutterMarker(line, text, className) {
-      if (typeof line == "number") line = getLine(clipLine(line));
-      line.gutterMarker = {text: text, style: className};
-      gutterDirty = true;
-      return line;
-    }
-    function removeGutterMarker(line) {
-      if (typeof line == "number") line = getLine(clipLine(line));
-      line.gutterMarker = null;
-      gutterDirty = true;
-    }
-
-    function changeLine(handle, op) {
-      var no = handle, line = handle;
-      if (typeof handle == "number") line = getLine(clipLine(handle));
-      else no = lineNo(handle);
-      if (no == null) return null;
-      if (op(line, no)) changes.push({from: no, to: no + 1});
-      else return null;
-      return line;
-    }
-    function setLineClass(handle, className, bgClassName) {
-      return changeLine(handle, function(line) {
-        if (line.className != className || line.bgClassName != bgClassName) {
-          line.className = className;
-          line.bgClassName = bgClassName;
-          return true;
-        }
-      });
-    }
-    function setLineHidden(handle, hidden) {
-      return changeLine(handle, function(line, no) {
-        if (line.hidden != hidden) {
-          line.hidden = hidden;
-          if (!options.lineWrapping) {
-            if (hidden && line.text.length == maxLine.text.length) {
-              updateMaxLine = true;
-            } else if (!hidden && line.text.length > maxLine.text.length) {
-              maxLine = line; updateMaxLine = false;
-            }
-          }
-          updateLineHeight(line, hidden ? 0 : 1);
-          var fline = sel.from.line, tline = sel.to.line;
-          if (hidden && (fline == no || tline == no)) {
-            var from = fline == no ? skipHidden({line: fline, ch: 0}, fline, 0) : sel.from;
-            var to = tline == no ? skipHidden({line: tline, ch: 0}, tline, 0) : sel.to;
-            // Can't hide the last visible line, we'd have no place to put the cursor
-            if (!to) return;
-            setSelection(from, to);
-          }
-          return (gutterDirty = true);
-        }
-      });
-    }
-
-    function lineInfo(line) {
-      if (typeof line == "number") {
-        if (!isLine(line)) return null;
-        var n = line;
-        line = getLine(line);
-        if (!line) return null;
-      } else {
-        var n = lineNo(line);
-        if (n == null) return null;
-      }
-      var marker = line.gutterMarker;
-      return {line: n, handle: line, text: line.text, markerText: marker && marker.text,
-              markerClass: marker && marker.style, lineClass: line.className, bgClass: line.bgClassName};
-    }
-
-    function measureLine(line, ch) {
-      if (ch == 0) return {top: 0, left: 0};
-      var pre = lineContent(line, ch);
-      removeChildrenAndAdd(measure, pre);
-      var anchor = pre.anchor;
-      var top = anchor.offsetTop, left = anchor.offsetLeft;
-      // Older IEs report zero offsets for spans directly after a wrap
-      if (ie && top == 0 && left == 0) {
-        var backup = elt("span", "x");
-        anchor.parentNode.insertBefore(backup, anchor.nextSibling);
-        top = backup.offsetTop;
-      }
-      return {top: top, left: left};
-    }
-    function localCoords(pos, inLineWrap) {
-      var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));
-      if (pos.ch == 0) x = 0;
-      else {
-        var sp = measureLine(getLine(pos.line), pos.ch);
-        x = sp.left;
-        if (options.lineWrapping) y += Math.max(0, sp.top);
-      }
-      return {x: x, y: y, yBot: y + lh};
-    }
-    // Coords must be lineSpace-local
-    function coordsChar(x, y) {
-      var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);
-      if (heightPos < 0) return {line: 0, ch: 0};
-      var lineNo = lineAtHeight(doc, heightPos);
-      if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};
-      var lineObj = getLine(lineNo), text = lineObj.text;
-      var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;
-      if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};
-      var wrongLine = false;
-      function getX(len) {
-        var sp = measureLine(lineObj, len);
-        if (tw) {
-          var off = Math.round(sp.top / th);
-          wrongLine = off != innerOff;
-          return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);
-        }
-        return sp.left;
-      }
-      var from = 0, fromX = 0, to = text.length, toX;
-      // Guess a suitable upper bound for our search.
-      var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));
-      for (;;) {
-        var estX = getX(estimated);
-        if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));
-        else {toX = estX; to = estimated; break;}
-      }
-      if (x > toX) return {line: lineNo, ch: to};
-      // Try to guess a suitable lower bound as well.
-      estimated = Math.floor(to * 0.8); estX = getX(estimated);
-      if (estX < x) {from = estimated; fromX = estX;}
-      // Do a binary search between these bounds.
-      for (;;) {
-        if (to - from <= 1) {
-          var after = x - fromX < toX - x;
-          return {line: lineNo, ch: after ? from : to, after: after};
-        }
-        var middle = Math.ceil((from + to) / 2), middleX = getX(middle);
-        if (middleX > x) {to = middle; toX = middleX; if (wrongLine) toX += 1000; }
-        else {from = middle; fromX = middleX;}
-      }
-    }
-    function pageCoords(pos) {
-      var local = localCoords(pos, true), off = eltOffset(lineSpace);
-      return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};
-    }
-
-    var cachedHeight, cachedHeightFor, measurePre;
-    function textHeight() {
-      if (measurePre == null) {
-        measurePre = elt("pre");
-        for (var i = 0; i < 49; ++i) {
-          measurePre.appendChild(document.createTextNode("x"));
-          measurePre.appendChild(elt("br"));
-        }
-        measurePre.appendChild(document.createTextNode("x"));
-      }
-      var offsetHeight = lineDiv.clientHeight;
-      if (offsetHeight == cachedHeightFor) return cachedHeight;
-      cachedHeightFor = offsetHeight;
-      removeChildrenAndAdd(measure, measurePre.cloneNode(true));
-      cachedHeight = measure.firstChild.offsetHeight / 50 || 1;
-      removeChildren(measure);
-      return cachedHeight;
-    }
-    var cachedWidth, cachedWidthFor = 0;
-    function charWidth() {
-      if (scroller.clientWidth == cachedWidthFor) return cachedWidth;
-      cachedWidthFor = scroller.clientWidth;
-      var anchor = elt("span", "x");
-      var pre = elt("pre", [anchor]);
-      removeChildrenAndAdd(measure, pre);
-      return (cachedWidth = anchor.offsetWidth || 10);
-    }
-    function paddingTop() {return lineSpace.offsetTop;}
-    function paddingLeft() {return lineSpace.offsetLeft;}
-
-    function posFromMouse(e, liberal) {
-      var offW = eltOffset(scroller, true), x, y;
-      // Fails unpredictably on IE[67] when mouse is dragged around quickly.
-      try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
-      // This is a mess of a heuristic to try and determine whether a
-      // scroll-bar was clicked or not, and to return null if one was
-      // (and !liberal).
-      if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))
-        return null;
-      var offL = eltOffset(lineSpace, true);
-      return coordsChar(x - offL.left, y - offL.top);
-    }
-    var detectingSelectAll;
-    function onContextMenu(e) {
-      var pos = posFromMouse(e), scrollPos = scrollbar.scrollTop;
-      if (!pos || opera) return; // Opera is difficult.
-      if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
-        operation(setCursor)(pos.line, pos.ch);
-
-      var oldCSS = input.style.cssText;
-      inputDiv.style.position = "absolute";
-      input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
-        "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
-        "border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
-      focusInput();
-      resetInput(true);
-      // Adds "Select all" to context menu in FF
-      if (posEq(sel.from, sel.to)) input.value = prevInput = " ";
-
-      function rehide() {
-        inputDiv.style.position = "relative";
-        input.style.cssText = oldCSS;
-        if (ie_lt9) scrollbar.scrollTop = scrollPos;
-        slowPoll();
-
-        // Try to detect the user choosing select-all 
-        if (input.selectionStart != null) {
-          clearTimeout(detectingSelectAll);
-          var extval = input.value = " " + (posEq(sel.from, sel.to) ? "" : input.value), i = 0;
-          prevInput = " ";
-          input.selectionStart = 1; input.selectionEnd = extval.length;
-          detectingSelectAll = setTimeout(function poll(){
-            if (prevInput == " " && input.selectionStart == 0)
-              operation(commands.selectAll)(instance);
-            else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
-            else resetInput();
-          }, 200);
-        }
-      }
-
-      if (gecko) {
-        e_stop(e);
-        var mouseup = connect(window, "mouseup", function() {
-          mouseup();
-          setTimeout(rehide, 20);
-        }, true);
-      } else {
-        setTimeout(rehide, 50);
-      }
-    }
-
-    // Cursor-blinking
-    function restartBlink() {
-      clearInterval(blinker);
-      var on = true;
-      cursor.style.visibility = "";
-      blinker = setInterval(function() {
-        cursor.style.visibility = (on = !on) ? "" : "hidden";
-      }, options.cursorBlinkRate);
-    }
-
-    var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"};
-    function matchBrackets(autoclear) {
-      var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;
-      var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];
-      if (!match) return;
-      var ch = match.charAt(0), forward = match.charAt(1) == ">", d = forward ? 1 : -1, st = line.styles;
-      for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)
-        if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}
-
-      var stack = [line.text.charAt(pos)], re = /[(){}[\]]/;
-      function scan(line, from, to) {
-        if (!line.text) return;
-        var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;
-        for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {
-          var text = st[i];
-          if (st[i+1] != style) {pos += d * text.length; continue;}
-          for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {
-            if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {
-              var match = matching[cur];
-              if (match.charAt(1) == ">" == forward) stack.push(cur);
-              else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};
-              else if (!stack.length) return {pos: pos, match: true};
-            }
-          }
-        }
-      }
-      for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {
-        var line = getLine(i), first = i == head.line;
-        var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);
-        if (found) break;
-      }
-      if (!found) found = {pos: null, match: false};
-      var style = found.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
-      var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),
-          two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);
-      var clear = operation(function(){one.clear(); two && two.clear();});
-      if (autoclear) setTimeout(clear, 800);
-      else bracketHighlighted = clear;
-    }
-
-    // Finds the line to start with when starting a parse. Tries to
-    // find a line with a stateAfter, so that it can start with a
-    // valid state. If that fails, it returns the line with the
-    // smallest indentation, which tends to need the least context to
-    // parse correctly.
-    function findStartLine(n) {
-      var minindent, minline;
-      for (var search = n, lim = n - 40; search > lim; --search) {
-        if (search == 0) return 0;
-        var line = getLine(search-1);
-        if (line.stateAfter) return search;
-        var indented = line.indentation(options.tabSize);
-        if (minline == null || minindent > indented) {
-          minline = search - 1;
-          minindent = indented;
-        }
-      }
-      return minline;
-    }
-    function getStateBefore(n) {
-      var pos = findStartLine(n), state = pos && getLine(pos-1).stateAfter;
-      if (!state) state = startState(mode);
-      else state = copyState(mode, state);
-      doc.iter(pos, n, function(line) {
-        line.process(mode, state, options.tabSize);
-        line.stateAfter = (pos == n - 1 || pos % 5 == 0) ? copyState(mode, state) : null;
-      });
-      return state;
-    }
-    function highlightWorker() {
-      if (frontier >= showingTo) return;
-      var end = +new Date + options.workTime, state = copyState(mode, getStateBefore(frontier));
-      var startFrontier = frontier;
-      doc.iter(frontier, showingTo, function(line) {
-        if (frontier >= showingFrom) { // Visible
-          line.highlight(mode, state, options.tabSize);
-          line.stateAfter = copyState(mode, state);
-        } else {
-          line.process(mode, state, options.tabSize);
-          line.stateAfter = frontier % 5 == 0 ? copyState(mode, state) : null;
-        }
-        ++frontier;
-        if (+new Date > end) {
-          startWorker(options.workDelay);
-          return true;
-        }
-      });
-      if (showingTo > startFrontier && frontier >= showingFrom)
-        operation(function() {changes.push({from: startFrontier, to: frontier});})();
-    }
-    function startWorker(time) {
-      if (frontier < showingTo)
-        highlight.set(time, highlightWorker);
-    }
-
-    // Operations are used to wrap changes in such a way that each
-    // change won't have to update the cursor and display (which would
-    // be awkward, slow, and error-prone), but instead updates are
-    // batched and then all combined and executed at once.
-    function startOperation() {
-      updateInput = userSelChange = textChanged = null;
-      changes = []; selectionChanged = false; callbacks = [];
-    }
-    function endOperation() {
-      if (updateMaxLine) computeMaxLength();
-      if (maxLineChanged && !options.lineWrapping) {
-        var cursorWidth = widthForcer.offsetWidth, left = measureLine(maxLine, maxLine.text.length).left;
-        if (!ie_lt8) {
-          widthForcer.style.left = left + "px";
-          lineSpace.style.minWidth = (left + cursorWidth) + "px";
-        }
-        maxLineChanged = false;
-      }
-      var newScrollPos, updated;
-      if (selectionChanged) {
-        var coords = calculateCursorCoords();
-        newScrollPos = calculateScrollPos(coords.x, coords.y, coords.x, coords.yBot);
-      }
-      if (changes.length || newScrollPos && newScrollPos.scrollTop != null)
-        updated = updateDisplay(changes, true, newScrollPos && newScrollPos.scrollTop);
-      if (!updated) {
-        if (selectionChanged) updateSelection();
-        if (gutterDirty) updateGutter();
-      }
-      if (newScrollPos) scrollCursorIntoView();
-      if (selectionChanged) restartBlink();
-
-      if (focused && (updateInput === true || (updateInput !== false && selectionChanged)))
-        resetInput(userSelChange);
-
-      if (selectionChanged && options.matchBrackets)
-        setTimeout(operation(function() {
-          if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}
-          if (posEq(sel.from, sel.to)) matchBrackets(false);
-        }), 20);
-      var sc = selectionChanged, cbs = callbacks; // these can be reset by callbacks
-      if (textChanged && options.onChange && instance)
-        options.onChange(instance, textChanged);
-      if (sc && options.onCursorActivity)
-        options.onCursorActivity(instance);
-      for (var i = 0; i < cbs.length; ++i) cbs[i](instance);
-      if (updated && options.onUpdate) options.onUpdate(instance);
-    }
-    var nestedOperation = 0;
-    function operation(f) {
-      return function() {
-        if (!nestedOperation++) startOperation();
-        try {var result = f.apply(this, arguments);}
-        finally {if (!--nestedOperation) endOperation();}
-        return result;
-      };
-    }
-
-    function compoundChange(f) {
-      history.startCompound();
-      try { return f(); } finally { history.endCompound(); }
-    }
-
-    for (var ext in extensions)
-      if (extensions.propertyIsEnumerable(ext) &&
-          !instance.propertyIsEnumerable(ext))
-        instance[ext] = extensions[ext];
-    for (var i = 0; i < initHooks.length; ++i) initHooks[i](instance);
-    return instance;
-  } // (end of function CodeMirror)
-
-  // The default configuration options.
-  CodeMirror.defaults = {
-    value: "",
-    mode: null,
-    theme: "default",
-    indentUnit: 2,
-    indentWithTabs: false,
-    smartIndent: true,
-    tabSize: 4,
-    keyMap: "default",
-    extraKeys: null,
-    electricChars: true,
-    autoClearEmptyLines: false,
-    onKeyEvent: null,
-    onDragEvent: null,
-    lineWrapping: false,
-    lineNumbers: false,
-    gutter: false,
-    fixedGutter: false,
-    firstLineNumber: 1,
-    readOnly: false,
-    dragDrop: true,
-    onChange: null,
-    onCursorActivity: null,
-    onViewportChange: null,
-    onGutterClick: null,
-    onUpdate: null,
-    onFocus: null, onBlur: null, onScroll: null,
-    matchBrackets: false,
-    cursorBlinkRate: 530,
-    workTime: 100,
-    workDelay: 200,
-    pollInterval: 100,
-    undoDepth: 40,
-    tabindex: null,
-    autofocus: null,
-    lineNumberFormatter: function(integer) { return integer; }
-  };
-
-  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
-  var mac = ios || /Mac/.test(navigator.platform);
-  var win = /Win/.test(navigator.platform);
-
-  // Known modes, by name and by MIME
-  var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
-  CodeMirror.defineMode = function(name, mode) {
-    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
-    if (arguments.length > 2) {
-      mode.dependencies = [];
-      for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
-    }
-    modes[name] = mode;
-  };
-  CodeMirror.defineMIME = function(mime, spec) {
-    mimeModes[mime] = spec;
-  };
-  CodeMirror.resolveMode = function(spec) {
-    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
-      spec = mimeModes[spec];
-    else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec))
-      return CodeMirror.resolveMode("application/xml");
-    if (typeof spec == "string") return {name: spec};
-    else return spec || {name: "null"};
-  };
-  CodeMirror.getMode = function(options, spec) {
-    var spec = CodeMirror.resolveMode(spec);
-    var mfactory = modes[spec.name];
-    if (!mfactory) return CodeMirror.getMode(options, "text/plain");
-    var modeObj = mfactory(options, spec);
-    if (modeExtensions.hasOwnProperty(spec.name)) {
-      var exts = modeExtensions[spec.name];
-      for (var prop in exts) if (exts.hasOwnProperty(prop)) modeObj[prop] = exts[prop];
-    }
-    modeObj.name = spec.name;
-    return modeObj;
-  };
-  CodeMirror.listModes = function() {
-    var list = [];
-    for (var m in modes)
-      if (modes.propertyIsEnumerable(m)) list.push(m);
-    return list;
-  };
-  CodeMirror.listMIMEs = function() {
-    var list = [];
-    for (var m in mimeModes)
-      if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
-    return list;
-  };
-
-  var extensions = CodeMirror.extensions = {};
-  CodeMirror.defineExtension = function(name, func) {
-    extensions[name] = func;
-  };
-
-  var initHooks = [];
-  CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
-
-  var modeExtensions = CodeMirror.modeExtensions = {};
-  CodeMirror.extendMode = function(mode, properties) {
-    var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
-    for (var prop in properties) if (properties.hasOwnProperty(prop))
-      exts[prop] = properties[prop];
-  };
-
-  var commands = CodeMirror.commands = {
-    selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},
-    killLine: function(cm) {
-      var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
-      if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange("", from, {line: from.line + 1, ch: 0});
-      else cm.replaceRange("", from, sel ? to : {line: from.line});
-    },
-    deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange("", {line: l, ch: 0}, {line: l});},
-    undo: function(cm) {cm.undo();},
-    redo: function(cm) {cm.redo();},
-    goDocStart: function(cm) {cm.setCursor(0, 0, true);},
-    goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},
-    goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},
-    goLineStartSmart: function(cm) {
-      var cur = cm.getCursor();
-      var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\S/));
-      cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);
-    },
-    goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},
-    goLineUp: function(cm) {cm.moveV(-1, "line");},
-    goLineDown: function(cm) {cm.moveV(1, "line");},
-    goPageUp: function(cm) {cm.moveV(-1, "page");},
-    goPageDown: function(cm) {cm.moveV(1, "page");},
-    goCharLeft: function(cm) {cm.moveH(-1, "char");},
-    goCharRight: function(cm) {cm.moveH(1, "char");},
-    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
-    goColumnRight: function(cm) {cm.moveH(1, "column");},
-    goWordLeft: function(cm) {cm.moveH(-1, "word");},
-    goWordRight: function(cm) {cm.moveH(1, "word");},
-    delCharLeft: function(cm) {cm.deleteH(-1, "char");},
-    delCharRight: function(cm) {cm.deleteH(1, "char");},
-    delWordLeft: function(cm) {cm.deleteH(-1, "word");},
-    delWordRight: function(cm) {cm.deleteH(1, "word");},
-    indentAuto: function(cm) {cm.indentSelection("smart");},
-    indentMore: function(cm) {cm.indentSelection("add");},
-    indentLess: function(cm) {cm.indentSelection("subtract");},
-    insertTab: function(cm) {cm.replaceSelection("\t", "end");},
-    defaultTab: function(cm) {
-      if (cm.somethingSelected()) cm.indentSelection("add");
-      else cm.replaceSelection("\t", "end");
-    },
-    transposeChars: function(cm) {
-      var cur = cm.getCursor(), line = cm.getLine(cur.line);
-      if (cur.ch > 0 && cur.ch < line.length - 1)
-        cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
-                        {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});
-    },
-    newlineAndIndent: function(cm) {
-      cm.replaceSelection("\n", "end");
-      cm.indentLine(cm.getCursor().line);
-    },
-    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
-  };
-
-  var keyMap = CodeMirror.keyMap = {};
-  keyMap.basic = {
-    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
-    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
-    "Delete": "delCharRight", "Backspace": "delCharLeft", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
-    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
-  };
-  // Note that the save and find-related commands aren't defined by
-  // default. Unknown commands are simply ignored.
-  keyMap.pcDefault = {
-    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
-    "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
-    "Ctrl-Left": "goWordLeft", "Ctrl-Right": "goWordRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
-    "Ctrl-Backspace": "delWordLeft", "Ctrl-Delete": "delWordRight", "Ctrl-S": "save", "Ctrl-F": "find",
-    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
-    "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
-    fallthrough: "basic"
-  };
-  keyMap.macDefault = {
-    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
-    "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goWordLeft",
-    "Alt-Right": "goWordRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delWordLeft",
-    "Ctrl-Alt-Backspace": "delWordRight", "Alt-Delete": "delWordRight", "Cmd-S": "save", "Cmd-F": "find",
-    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
-    "Cmd-[": "indentLess", "Cmd-]": "indentMore",
-    fallthrough: ["basic", "emacsy"]
-  };
-  keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
-  keyMap.emacsy = {
-    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
-    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
-    "Ctrl-V": "goPageUp", "Shift-Ctrl-V": "goPageDown", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft",
-    "Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
-  };
-
-  function getKeyMap(val) {
-    if (typeof val == "string") return keyMap[val];
-    else return val;
-  }
-  function lookupKey(name, extraMap, map, handle, stop) {
-    function lookup(map) {
-      map = getKeyMap(map);
-      var found = map[name];
-      if (found === false) {
-        if (stop) stop();
-        return true;
-      }
-      if (found != null && handle(found)) return true;
-      if (map.nofallthrough) {
-        if (stop) stop();
-        return true;
-      }
-      var fallthrough = map.fallthrough;
-      if (fallthrough == null) return false;
-      if (Object.prototype.toString.call(fallthrough) != "[object Array]")
-        return lookup(fallthrough);
-      for (var i = 0, e = fallthrough.length; i < e; ++i) {
-        if (lookup(fallthrough[i])) return true;
-      }
-      return false;
-    }
-    if (extraMap && lookup(extraMap)) return true;
-    return lookup(map);
-  }
-  function isModifierKey(event) {
-    var name = keyNames[e_prop(event, "keyCode")];
-    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
-  }
-  CodeMirror.isModifierKey = isModifierKey;
-
-  CodeMirror.fromTextArea = function(textarea, options) {
-    if (!options) options = {};
-    options.value = textarea.value;
-    if (!options.tabindex && textarea.tabindex)
-      options.tabindex = textarea.tabindex;
-    // Set autofocus to true if this textarea is focused, or if it has
-    // autofocus and no other element is focused.
-    if (options.autofocus == null) {
-      var hasFocus = document.body;
-      // doc.activeElement occasionally throws on IE
-      try { hasFocus = document.activeElement; } catch(e) {}
-      options.autofocus = hasFocus == textarea ||
-        textarea.getAttribute("autofocus") != null && hasFocus == document.body;
-    }
-
-    function save() {textarea.value = instance.getValue();}
-    if (textarea.form) {
-      // Deplorable hack to make the submit method do the right thing.
-      var rmSubmit = connect(textarea.form, "submit", save, true);
-      if (typeof textarea.form.submit == "function") {
-        var realSubmit = textarea.form.submit;
-        textarea.form.submit = function wrappedSubmit() {
-          save();
-          textarea.form.submit = realSubmit;
-          textarea.form.submit();
-          textarea.form.submit = wrappedSubmit;
-        };
-      }
-    }
-
-    textarea.style.display = "none";
-    var instance = CodeMirror(function(node) {
-      textarea.parentNode.insertBefore(node, textarea.nextSibling);
-    }, options);
-    instance.save = save;
-    instance.getTextArea = function() { return textarea; };
-    instance.toTextArea = function() {
-      save();
-      textarea.parentNode.removeChild(instance.getWrapperElement());
-      textarea.style.display = "";
-      if (textarea.form) {
-        rmSubmit();
-        if (typeof textarea.form.submit == "function")
-          textarea.form.submit = realSubmit;
-      }
-    };
-    return instance;
-  };
-
-  var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
-  var ie = /MSIE \d/.test(navigator.userAgent);
-  var ie_lt8 = /MSIE [1-7]\b/.test(navigator.userAgent);
-  var ie_lt9 = /MSIE [1-8]\b/.test(navigator.userAgent);
-  var quirksMode = ie && document.documentMode == 5;
-  var webkit = /WebKit\//.test(navigator.userAgent);
-  var chrome = /Chrome\//.test(navigator.userAgent);
-  var opera = /Opera\//.test(navigator.userAgent);
-  var safari = /Apple Computer/.test(navigator.vendor);
-  var khtml = /KHTML\//.test(navigator.userAgent);
-  var mac_geLion = /Mac OS X 10\D([7-9]|\d\d)\D/.test(navigator.userAgent);
-
-  // Utility functions for working with state. Exported because modes
-  // sometimes need to do this.
-  function copyState(mode, state) {
-    if (state === true) return state;
-    if (mode.copyState) return mode.copyState(state);
-    var nstate = {};
-    for (var n in state) {
-      var val = state[n];
-      if (val instanceof Array) val = val.concat([]);
-      nstate[n] = val;
-    }
-    return nstate;
-  }
-  CodeMirror.copyState = copyState;
-  function startState(mode, a1, a2) {
-    return mode.startState ? mode.startState(a1, a2) : true;
-  }
-  CodeMirror.startState = startState;
-  CodeMirror.innerMode = function(mode, state) {
-    while (mode.innerMode) {
-      var info = mode.innerMode(state);
-      state = info.state;
-      mode = info.mode;
-    }
-    return info || {mode: mode, state: state};
-  };
-
-  // The character stream used by a mode's parser.
-  function StringStream(string, tabSize) {
-    this.pos = this.start = 0;
-    this.string = string;
-    this.tabSize = tabSize || 8;
-  }
-  StringStream.prototype = {
-    eol: function() {return this.pos >= this.string.length;},
-    sol: function() {return this.pos == 0;},
-    peek: function() {return this.string.charAt(this.pos) || undefined;},
-    next: function() {
-      if (this.pos < this.string.length)
-        return this.string.charAt(this.pos++);
-    },
-    eat: function(match) {
-      var ch = this.string.charAt(this.pos);
-      if (typeof match == "string") var ok = ch == match;
-      else var ok = ch && (match.test ? match.test(ch) : match(ch));
-      if (ok) {++this.pos; return ch;}
-    },
-    eatWhile: function(match) {
-      var start = this.pos;
-      while (this.eat(match)){}
-      return this.pos > start;
-    },
-    eatSpace: function() {
-      var start = this.pos;
-      while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
-      return this.pos > start;
-    },
-    skipToEnd: function() {this.pos = this.string.length;},
-    skipTo: function(ch) {
-      var found = this.string.indexOf(ch, this.pos);
-      if (found > -1) {this.pos = found; return true;}
-    },
-    backUp: function(n) {this.pos -= n;},
-    column: function() {return countColumn(this.string, this.start, this.tabSize);},
-    indentation: function() {return countColumn(this.string, null, this.tabSize);},
-    match: function(pattern, consume, caseInsensitive) {
-      if (typeof pattern == "string") {
-        var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
-        if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
-          if (consume !== false) this.pos += pattern.length;
-          return true;
-        }
-      } else {
-        var match = this.string.slice(this.pos).match(pattern);
-        if (match && match.index > 0) return null;
-        if (match && consume !== false) this.pos += match[0].length;
-        return match;
-      }
-    },
-    current: function(){return this.string.slice(this.start, this.pos);}
-  };
-  CodeMirror.StringStream = StringStream;
-
-  function MarkedSpan(from, to, marker) {
-    this.from = from; this.to = to; this.marker = marker;
-  }
-
-  function getMarkedSpanFor(spans, marker) {
-    if (spans) for (var i = 0; i < spans.length; ++i) {
-      var span = spans[i];
-      if (span.marker == marker) return span;
-    }
-  }
-
-  function removeMarkedSpan(spans, span) {
-    var r;
-    for (var i = 0; i < spans.length; ++i)
-      if (spans[i] != span) (r || (r = [])).push(spans[i]);
-    return r;
-  }
-
-  function markedSpansBefore(old, startCh, endCh) {
-    if (old) for (var i = 0, nw; i < old.length; ++i) {
-      var span = old[i], marker = span.marker;
-      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
-      if (startsBefore || marker.type == "bookmark" && span.from == startCh && span.from != endCh) {
-        var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
-        (nw || (nw = [])).push({from: span.from,
-                                to: endsAfter ? null : span.to,
-                                marker: marker});
-      }
-    }
-    return nw;
-  }
-
-  function markedSpansAfter(old, endCh) {
-    if (old) for (var i = 0, nw; i < old.length; ++i) {
-      var span = old[i], marker = span.marker;
-      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
-      if (endsAfter || marker.type == "bookmark" && span.from == endCh) {
-        var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
-        (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
-                                to: span.to == null ? null : span.to - endCh,
-                                marker: marker});
-      }
-    }
-    return nw;
-  }
-
-  function updateMarkedSpans(oldFirst, oldLast, startCh, endCh, newText) {
-    if (!oldFirst && !oldLast) return newText;
-    // Get the spans that 'stick out' on both sides
-    var first = markedSpansBefore(oldFirst, startCh);
-    var last = markedSpansAfter(oldLast, endCh);
-
-    // Next, merge those two ends
-    var sameLine = newText.length == 1, offset = lst(newText).length + (sameLine ? startCh : 0);
-    if (first) {
-      // Fix up .to properties of first
-      for (var i = 0; i < first.length; ++i) {
-        var span = first[i];
-        if (span.to == null) {
-          var found = getMarkedSpanFor(last, span.marker);
-          if (!found) span.to = startCh;
-          else if (sameLine) span.to = found.to == null ? null : found.to + offset;
-        }
-      }
-    }
-    if (last) {
-      // Fix up .from in last (or move them into first in case of sameLine)
-      for (var i = 0; i < last.length; ++i) {
-        var span = last[i];
-        if (span.to != null) span.to += offset;
-        if (span.from == null) {
-          var found = getMarkedSpanFor(first, span.marker);
-          if (!found) {
-            span.from = offset;
-            if (sameLine) (first || (first = [])).push(span);
-          }
-        } else {
-          span.from += offset;
-          if (sameLine) (first || (first = [])).push(span);
-        }
-      }
-    }
-
-    var newMarkers = [newHL(newText[0], first)];
-    if (!sameLine) {
-      // Fill gap with whole-line-spans
-      var gap = newText.length - 2, gapMarkers;
-      if (gap > 0 && first)
-        for (var i = 0; i < first.length; ++i)
-          if (first[i].to == null)
-            (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
-      for (var i = 0; i < gap; ++i)
-        newMarkers.push(newHL(newText[i+1], gapMarkers));
-      newMarkers.push(newHL(lst(newText), last));
-    }
-    return newMarkers;
-  }
-
-  // hl stands for history-line, a data structure that can be either a
-  // string (line without markers) or a {text, markedSpans} object.
-  function hlText(val) { return typeof val == "string" ? val : val.text; }
-  function hlSpans(val) {
-    if (typeof val == "string") return null;
-    var spans = val.markedSpans, out = null;
-    for (var i = 0; i < spans.length; ++i) {
-      if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
-      else if (out) out.push(spans[i]);
-    }
-    return !out ? spans : out.length ? out : null;
-  }
-  function newHL(text, spans) { return spans ? {text: text, markedSpans: spans} : text; }
-
-  function detachMarkedSpans(line) {
-    var spans = line.markedSpans;
-    if (!spans) return;
-    for (var i = 0; i < spans.length; ++i) {
-      var lines = spans[i].marker.lines;
-      var ix = indexOf(lines, line);
-      lines.splice(ix, 1);
-    }
-    line.markedSpans = null;
-  }
-
-  function attachMarkedSpans(line, spans) {
-    if (!spans) return;
-    for (var i = 0; i < spans.length; ++i)
-      var marker = spans[i].marker.lines.push(line);
-    line.markedSpans = spans;
-  }
-
-  // When measuring the position of the end of a line, different
-  // browsers require different approaches. If an empty span is added,
-  // many browsers report bogus offsets. Of those, some (Webkit,
-  // recent IE) will accept a space without moving the whole span to
-  // the next line when wrapping it, others work with a zero-width
-  // space.
-  var eolSpanContent = " ";
-  if (gecko || (ie && !ie_lt8)) eolSpanContent = "\u200b";
-  else if (opera) eolSpanContent = "";
-
-  // Line objects. These hold state related to a line, including
-  // highlighting info (the styles array).
-  function Line(text, markedSpans) {
-    this.text = text;
-    this.height = 1;
-    attachMarkedSpans(this, markedSpans);
-  }
-  Line.prototype = {
-    update: function(text, markedSpans) {
-      this.text = text;
-      this.stateAfter = this.styles = null;
-      detachMarkedSpans(this);
-      attachMarkedSpans(this, markedSpans);
-    },
-    // Run the given mode's parser over a line, update the styles
-    // array, which contains alternating fragments of text and CSS
-    // classes.
-    highlight: function(mode, state, tabSize) {
-      var stream = new StringStream(this.text, tabSize), st = this.styles || (this.styles = []);
-      var pos = st.length = 0;
-      if (this.text == "" && mode.blankLine) mode.blankLine(state);
-      while (!stream.eol()) {
-        var style = mode.token(stream, state), substr = stream.current();
-        stream.start = stream.pos;
-        if (pos && st[pos-1] == style) {
-          st[pos-2] += substr;
-        } else if (substr) {
-          st[pos++] = substr; st[pos++] = style;
-        }
-        // Give up when line is ridiculously long
-        if (stream.pos > 5000) {
-          st[pos++] = this.text.slice(stream.pos); st[pos++] = null;
-          break;
-        }
-      }
-    },
-    process: function(mode, state, tabSize) {
-      var stream = new StringStream(this.text, tabSize);
-      if (this.text == "" && mode.blankLine) mode.blankLine(state);
-      while (!stream.eol() && stream.pos <= 5000) {
-        mode.token(stream, state);
-        stream.start = stream.pos;
-      }
-    },
-    // Fetch the parser token for a given character. Useful for hacks
-    // that want to inspect the mode state (say, for completion).
-    getTokenAt: function(mode, state, tabSize, ch) {
-      var txt = this.text, stream = new StringStream(txt, tabSize);
-      while (stream.pos < ch && !stream.eol()) {
-        stream.start = stream.pos;
-        var style = mode.token(stream, state);
-      }
-      return {start: stream.start,
-              end: stream.pos,
-              string: stream.current(),
-              className: style || null,
-              state: state};
-    },
-    indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},
-    // Produces an HTML fragment for the line, taking selection,
-    // marking, and highlighting into account.
-    getContent: function(tabSize, wrapAt, compensateForWrapping) {
-      var first = true, col = 0, specials = /[\t\u0000-\u0019\u200b\u2028\u2029\uFEFF]/g;
-      var pre = elt("pre");
-      function span_(html, text, style) {
-        if (!text) return;
-        // Work around a bug where, in some compat modes, IE ignores leading spaces
-        if (first && ie && text.charAt(0) == " ") text = "\u00a0" + text.slice(1);
-        first = false;
-        if (!specials.test(text)) {
-          col += text.length;
-          var content = document.createTextNode(text);
-        } else {
-          var content = document.createDocumentFragment(), pos = 0;
-          while (true) {
-            specials.lastIndex = pos;
-            var m = specials.exec(text);
-            var skipped = m ? m.index - pos : text.length - pos;
-            if (skipped) {
-              content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
-              col += skipped;
-            }
-            if (!m) break;
-            pos += skipped + 1;
-            if (m[0] == "\t") {
-              var tabWidth = tabSize - col % tabSize;
-              content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
-              col += tabWidth;
-            } else {
-              var token = elt("span", "\u2022", "cm-invalidchar");
-              token.title = "\\u" + m[0].charCodeAt(0).toString(16);
-              content.appendChild(token);
-              col += 1;
-            }
-          }
-        }
-        if (style) html.appendChild(elt("span", [content], style));
-        else html.appendChild(content);
-      }
-      var span = span_;
-      if (wrapAt != null) {
-        var outPos = 0, anchor = pre.anchor = elt("span");
-        span = function(html, text, style) {
-          var l = text.length;
-          if (wrapAt >= outPos && wrapAt < outPos + l) {
-            var cut = wrapAt - outPos;
-            if (cut) {
-              span_(html, text.slice(0, cut), style);
-              // See comment at the definition of spanAffectsWrapping
-              if (compensateForWrapping) {
-                var view = text.slice(cut - 1, cut + 1);
-                if (spanAffectsWrapping.test(view)) html.appendChild(elt("wbr"));
-                else if (!ie_lt8 && /\w\w/.test(view)) html.appendChild(document.createTextNode("\u200d"));
-              }
-            }
-            html.appendChild(anchor);
-            span_(anchor, opera ? text.slice(cut, cut + 1) : text.slice(cut), style);
-            if (opera) span_(html, text.slice(cut + 1), style);
-            wrapAt--;
-            outPos += l;
-          } else {
-            outPos += l;
-            span_(html, text, style);
-            if (outPos == wrapAt && outPos == len) {
-              setTextContent(anchor, eolSpanContent);
-              html.appendChild(anchor);
-            }
-            // Stop outputting HTML when gone sufficiently far beyond measure
-            else if (outPos > wrapAt + 10 && /\s/.test(text)) span = function(){};
-          }
-        };
-      }
-
-      var st = this.styles, allText = this.text, marked = this.markedSpans;
-      var len = allText.length;
-      function styleToClass(style) {
-        if (!style) return null;
-        return "cm-" + style.replace(/ +/g, " cm-");
-      }
-      if (!allText && wrapAt == null) {
-        span(pre, " ");
-      } else if (!marked || !marked.length) {
-        for (var i = 0, ch = 0; ch < len; i+=2) {
-          var str = st[i], style = st[i+1], l = str.length;
-          if (ch + l > len) str = str.slice(0, len - ch);
-          ch += l;
-          span(pre, str, styleToClass(style));
-        }
-      } else {
-        marked.sort(function(a, b) { return a.from - b.from; });
-        var pos = 0, i = 0, text = "", style, sg = 0;
-        var nextChange = marked[0].from || 0, marks = [], markpos = 0;
-        var advanceMarks = function() {
-          var m;
-          while (markpos < marked.length &&
-                 ((m = marked[markpos]).from == pos || m.from == null)) {
-            if (m.marker.type == "range") marks.push(m);
-            ++markpos;
-          }
-          nextChange = markpos < marked.length ? marked[markpos].from : Infinity;
-          for (var i = 0; i < marks.length; ++i) {
-            var to = marks[i].to;
-            if (to == null) to = Infinity;
-            if (to == pos) marks.splice(i--, 1);
-            else nextChange = Math.min(to, nextChange);
-          }
-        };
-        var m = 0;
-        while (pos < len) {
-          if (nextChange == pos) advanceMarks();
-          var upto = Math.min(len, nextChange);
-          while (true) {
-            if (text) {
-              var end = pos + text.length;
-              var appliedStyle = style;
-              for (var j = 0; j < marks.length; ++j) {
-                var mark = marks[j];
-                appliedStyle = (appliedStyle ? appliedStyle + " " : "") + mark.marker.style;
-                if (mark.marker.endStyle && mark.to === Math.min(end, upto)) appliedStyle += " " + mark.marker.endStyle;
-                if (mark.marker.startStyle && mark.from === pos) appliedStyle += " " + mark.marker.startStyle;
-              }
-              span(pre, end > upto ? text.slice(0, upto - pos) : text, appliedStyle);
-              if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
-              pos = end;
-            }
-            text = st[i++]; style = styleToClass(st[i++]);
-          }
-        }
-      }
-      return pre;
-    },
-    cleanUp: function() {
-      this.parent = null;
-      detachMarkedSpans(this);
-    }
-  };
-
-  // Data structure that holds the sequence of lines.
-  function LeafChunk(lines) {
-    this.lines = lines;
-    this.parent = null;
-    for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
-      lines[i].parent = this;
-      height += lines[i].height;
-    }
-    this.height = height;
-  }
-  LeafChunk.prototype = {
-    chunkSize: function() { return this.lines.length; },
-    remove: function(at, n, callbacks) {
-      for (var i = at, e = at + n; i < e; ++i) {
-        var line = this.lines[i];
-        this.height -= line.height;
-        line.cleanUp();
-        if (line.handlers)
-          for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);
-      }
-      this.lines.splice(at, n);
-    },
-    collapse: function(lines) {
-      lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
-    },
-    insertHeight: function(at, lines, height) {
-      this.height += height;
-      this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
-      for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
-    },
-    iterN: function(at, n, op) {
-      for (var e = at + n; at < e; ++at)
-        if (op(this.lines[at])) return true;
-    }
-  };
-  function BranchChunk(children) {
-    this.children = children;
-    var size = 0, height = 0;
-    for (var i = 0, e = children.length; i < e; ++i) {
-      var ch = children[i];
-      size += ch.chunkSize(); height += ch.height;
-      ch.parent = this;
-    }
-    this.size = size;
-    this.height = height;
-    this.parent = null;
-  }
-  BranchChunk.prototype = {
-    chunkSize: function() { return this.size; },
-    remove: function(at, n, callbacks) {
-      this.size -= n;
-      for (var i = 0; i < this.children.length; ++i) {
-        var child = this.children[i], sz = child.chunkSize();
-        if (at < sz) {
-          var rm = Math.min(n, sz - at), oldHeight = child.height;
-          child.remove(at, rm, callbacks);
-          this.height -= oldHeight - child.height;
-          if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
-          if ((n -= rm) == 0) break;
-          at = 0;
-        } else at -= sz;
-      }
-      if (this.size - n < 25) {
-        var lines = [];
-        this.collapse(lines);
-        this.children = [new LeafChunk(lines)];
-        this.children[0].parent = this;
-      }
-    },
-    collapse: function(lines) {
-      for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
-    },
-    insert: function(at, lines) {
-      var height = 0;
-      for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
-      this.insertHeight(at, lines, height);
-    },
-    insertHeight: function(at, lines, height) {
-      this.size += lines.length;
-      this.height += height;
-      for (var i = 0, e = this.children.length; i < e; ++i) {
-        var child = this.children[i], sz = child.chunkSize();
-        if (at <= sz) {
-          child.insertHeight(at, lines, height);
-          if (child.lines && child.lines.length > 50) {
-            while (child.lines.length > 50) {
-              var spilled = child.lines.splice(child.lines.length - 25, 25);
-              var newleaf = new LeafChunk(spilled);
-              child.height -= newleaf.height;
-              this.children.splice(i + 1, 0, newleaf);
-              newleaf.parent = this;
-            }
-            this.maybeSpill();
-          }
-          break;
-        }
-        at -= sz;
-      }
-    },
-    maybeSpill: function() {
-      if (this.children.length <= 10) return;
-      var me = this;
-      do {
-        var spilled = me.children.splice(me.children.length - 5, 5);
-        var sibling = new BranchChunk(spilled);
-        if (!me.parent) { // Become the parent node
-          var copy = new BranchChunk(me.children);
-          copy.parent = me;
-          me.children = [copy, sibling];
-          me = copy;
-        } else {
-          me.size -= sibling.size;
-          me.height -= sibling.height;
-          var myIndex = indexOf(me.parent.children, me);
-          me.parent.children.splice(myIndex + 1, 0, sibling);
-        }
-        sibling.parent = me.parent;
-      } while (me.children.length > 10);
-      me.parent.maybeSpill();
-    },
-    iter: function(from, to, op) { this.iterN(from, to - from, op); },
-    iterN: function(at, n, op) {
-      for (var i = 0, e = this.children.length; i < e; ++i) {
-        var child = this.children[i], sz = child.chunkSize();
-        if (at < sz) {
-          var used = Math.min(n, sz - at);
-          if (child.iterN(at, used, op)) return true;
-          if ((n -= used) == 0) break;
-          at = 0;
-        } else at -= sz;
-      }
-    }
-  };
-
-  function getLineAt(chunk, n) {
-    while (!chunk.lines) {
-      for (var i = 0;; ++i) {
-        var child = chunk.children[i], sz = child.chunkSize();
-        if (n < sz) { chunk = child; break; }
-        n -= sz;
-      }
-    }
-    return chunk.lines[n];
-  }
-  function lineNo(line) {
-    if (line.parent == null) return null;
-    var cur = line.parent, no = indexOf(cur.lines, line);
-    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
-      for (var i = 0, e = chunk.children.length; ; ++i) {
-        if (chunk.children[i] == cur) break;
-        no += chunk.children[i].chunkSize();
-      }
-    }
-    return no;
-  }
-  function lineAtHeight(chunk, h) {
-    var n = 0;
-    outer: do {
-      for (var i = 0, e = chunk.children.length; i < e; ++i) {
-        var child = chunk.children[i], ch = child.height;
-        if (h < ch) { chunk = child; continue outer; }
-        h -= ch;
-        n += child.chunkSize();
-      }
-      return n;
-    } while (!chunk.lines);
-    for (var i = 0, e = chunk.lines.length; i < e; ++i) {
-      var line = chunk.lines[i], lh = line.height;
-      if (h < lh) break;
-      h -= lh;
-    }
-    return n + i;
-  }
-  function heightAtLine(chunk, n) {
-    var h = 0;
-    outer: do {
-      for (var i = 0, e = chunk.children.length; i < e; ++i) {
-        var child = chunk.children[i], sz = child.chunkSize();
-        if (n < sz) { chunk = child; continue outer; }
-        n -= sz;
-        h += child.height;
-      }
-      return h;
-    } while (!chunk.lines);
-    for (var i = 0; i < n; ++i) h += chunk.lines[i].height;
-    return h;
-  }
-
-  // The history object 'chunks' changes that are made close together
-  // and at almost the same time into bigger undoable units.
-  function History() {
-    this.time = 0;
-    this.done = []; this.undone = [];
-    this.compound = 0;
-    this.closed = false;
-  }
-  History.prototype = {
-    addChange: function(start, added, old) {
-      this.undone.length = 0;
-      var time = +new Date, cur = lst(this.done), last = cur && lst(cur);
-      var dtime = time - this.time;
-
-      if (cur && !this.closed && this.compound) {
-        cur.push({start: start, added: added, old: old});
-      } else if (dtime > 400 || !last || this.closed ||
-                 last.start > start + old.length || last.start + last.added < start) {
-        this.done.push([{start: start, added: added, old: old}]);
-        this.closed = false;
-      } else {
-        var startBefore = Math.max(0, last.start - start),
-            endAfter = Math.max(0, (start + old.length) - (last.start + last.added));
-        for (var i = startBefore; i > 0; --i) last.old.unshift(old[i - 1]);
-        for (var i = endAfter; i > 0; --i) last.old.push(old[old.length - i]);
-        if (startBefore) last.start = start;
-        last.added += added - (old.length - startBefore - endAfter);
-      }
-      this.time = time;
-    },
-    startCompound: function() {
-      if (!this.compound++) this.closed = true;
-    },
-    endCompound: function() {
-      if (!--this.compound) this.closed = true;
-    }
-  };
-
-  function stopMethod() {e_stop(this);}
-  // Ensure an event has a stop method.
-  function addStop(event) {
-    if (!event.stop) event.stop = stopMethod;
-    return event;
-  }
-
-  function e_preventDefault(e) {
-    if (e.preventDefault) e.preventDefault();
-    else e.returnValue = false;
-  }
-  function e_stopPropagation(e) {
-    if (e.stopPropagation) e.stopPropagation();
-    else e.cancelBubble = true;
-  }
-  function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
-  CodeMirror.e_stop = e_stop;
-  CodeMirror.e_preventDefault = e_preventDefault;
-  CodeMirror.e_stopPropagation = e_stopPropagation;
-
-  function e_target(e) {return e.target || e.srcElement;}
-  function e_button(e) {
-    var b = e.which;
-    if (b == null) {
-      if (e.button & 1) b = 1;
-      else if (e.button & 2) b = 3;
-      else if (e.button & 4) b = 2;
-    }
-    if (mac && e.ctrlKey && b == 1) b = 3;
-    return b;
-  }
-
-  // Allow 3rd-party code to override event properties by adding an override
-  // object to an event object.
-  function e_prop(e, prop) {
-    var overridden = e.override && e.override.hasOwnProperty(prop);
-    return overridden ? e.override[prop] : e[prop];
-  }
-
-  // Event handler registration. If disconnect is true, it'll return a
-  // function that unregisters the handler.
-  function connect(node, type, handler, disconnect) {
-    if (typeof node.addEventListener == "function") {
-      node.addEventListener(type, handler, false);
-      if (disconnect) return function() {node.removeEventListener(type, handler, false);};
-    } else {
-      var wrapHandler = function(event) {handler(event || window.event);};
-      node.attachEvent("on" + type, wrapHandler);
-      if (disconnect) return function() {node.detachEvent("on" + type, wrapHandler);};
-    }
-  }
-  CodeMirror.connect = connect;
-
-  function Delayed() {this.id = null;}
-  Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
-
-  var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
-
-  // Detect drag-and-drop
-  var dragAndDrop = function() {
-    // There is *some* kind of drag-and-drop support in IE6-8, but I
-    // couldn't get it to work yet.
-    if (ie_lt9) return false;
-    var div = elt('div');
-    return "draggable" in div || "dragDrop" in div;
-  }();
-
-  // Feature-detect whether newlines in textareas are converted to \r\n
-  var lineSep = function () {
-    var te = elt("textarea");
-    te.value = "foo\nbar";
-    if (te.value.indexOf("\r") > -1) return "\r\n";
-    return "\n";
-  }();
-
-  // For a reason I have yet to figure out, some browsers disallow
-  // word wrapping between certain characters *only* if a new inline
-  // element is started between them. This makes it hard to reliably
-  // measure the position of things, since that requires inserting an
-  // extra span. This terribly fragile set of regexps matches the
-  // character combinations that suffer from this phenomenon on the
-  // various browsers.
-  var spanAffectsWrapping = /^$/; // Won't match any two-character string
-  if (gecko) spanAffectsWrapping = /$'/;
-  else if (safari) spanAffectsWrapping = /\-[^ \-?]|\?[^ !'\"\),.\-\/:;\?\]\}]/;
-  else if (chrome) spanAffectsWrapping = /\-[^ \-\.?]|\?[^ \-\.?\]\}:;!'\"\),\/]|[\.!\"#&%\)*+,:;=>\]|\}~][\(\{\[<]|\$'/;
-
-  // Counts the column offset in a string, taking tabs into account.
-  // Used mostly to find indentation.
-  function countColumn(string, end, tabSize) {
-    if (end == null) {
-      end = string.search(/[^\s\u00a0]/);
-      if (end == -1) end = string.length;
-    }
-    for (var i = 0, n = 0; i < end; ++i) {
-      if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
-      else ++n;
-    }
-    return n;
-  }
-
-  function eltOffset(node, screen) {
-    // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,
-    // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)
-    try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }
-    catch(e) { box = {top: 0, left: 0}; }
-    if (!screen) {
-      // Get the toplevel scroll, working around browser differences.
-      if (window.pageYOffset == null) {
-        var t = document.documentElement || document.body.parentNode;
-        if (t.scrollTop == null) t = document.body;
-        box.top += t.scrollTop; box.left += t.scrollLeft;
-      } else {
-        box.top += window.pageYOffset; box.left += window.pageXOffset;
-      }
-    }
-    return box;
-  }
-
-  function eltText(node) {
-    return node.textContent || node.innerText || node.nodeValue || "";
-  }
-
-  var spaceStrs = [""];
-  function spaceStr(n) {
-    while (spaceStrs.length <= n)
-      spaceStrs.push(lst(spaceStrs) + " ");
-    return spaceStrs[n];
-  }
-
-  function lst(arr) { return arr[arr.length-1]; }
-
-  function selectInput(node) {
-    if (ios) { // Mobile Safari apparently has a bug where select() is broken.
-      node.selectionStart = 0;
-      node.selectionEnd = node.value.length;
-    } else node.select();
-  }
-
-  // Operations on {line, ch} objects.
-  function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
-  function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
-  function copyPos(x) {return {line: x.line, ch: x.ch};}
-
-  function elt(tag, content, className, style) {
-    var e = document.createElement(tag);
-    if (className) e.className = className;
-    if (style) e.style.cssText = style;
-    if (typeof content == "string") setTextContent(e, content);
-    else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
-    return e;
-  }
-  function removeChildren(e) {
-    e.innerHTML = "";
-    return e;
-  }
-  function removeChildrenAndAdd(parent, e) {
-    removeChildren(parent).appendChild(e);
-  }
-  function setTextContent(e, str) {
-    if (ie_lt9) {
-      e.innerHTML = "";
-      e.appendChild(document.createTextNode(str));
-    } else e.textContent = str;
-  }
-
-  // Used to position the cursor after an undo/redo by finding the
-  // last edited character.
-  function editEnd(from, to) {
-    if (!to) return 0;
-    if (!from) return to.length;
-    for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)
-      if (from.charAt(i) != to.charAt(j)) break;
-    return j + 1;
-  }
-
-  function indexOf(collection, elt) {
-    if (collection.indexOf) return collection.indexOf(elt);
-    for (var i = 0, e = collection.length; i < e; ++i)
-      if (collection[i] == elt) return i;
-    return -1;
-  }
-  function isWordChar(ch) {
-    return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase() || /[\u4E00-\u9FA5]/.test(ch);
-  }
-
-  // See if "".split is the broken IE version, if so, provide an
-  // alternative way to split lines.
-  var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
-    var pos = 0, result = [], l = string.length;
-    while (pos <= l) {
-      var nl = string.indexOf("\n", pos);
-      if (nl == -1) nl = string.length;
-      var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
-      var rt = line.indexOf("\r");
-      if (rt != -1) {
-        result.push(line.slice(0, rt));
-        pos += rt + 1;
-      } else {
-        result.push(line);
-        pos = nl + 1;
-      }
-    }
-    return result;
-  } : function(string){return string.split(/\r\n?|\n/);};
-  CodeMirror.splitLines = splitLines;
-
-  var hasSelection = window.getSelection ? function(te) {
-    try { return te.selectionStart != te.selectionEnd; }
-    catch(e) { return false; }
-  } : function(te) {
-    try {var range = te.ownerDocument.selection.createRange();}
-    catch(e) {}
-    if (!range || range.parentElement() != te) return false;
-    return range.compareEndPoints("StartToEnd", range) != 0;
-  };
-
-  CodeMirror.defineMode("null", function() {
-    return {token: function(stream) {stream.skipToEnd();}};
-  });
-  CodeMirror.defineMIME("text/plain", "null");
-
-  var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
-                  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
-                  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
-                  46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
-                  186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
-                  221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
-                  63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
-  CodeMirror.keyNames = keyNames;
-  (function() {
-    // Number keys
-    for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
-    // Alphabetic keys
-    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
-    // Function keys
-    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
-  })();
-
-  CodeMirror.version = "2.35";
-
-  return CodeMirror;
-})();
Index: plugins/themeEditor/codemirror/css.js
===================================================================
--- plugins/themeEditor/codemirror/css.js	(revision 948)
+++ 	(revision )
@@ -1,448 +1,0 @@
-CodeMirror.defineMode("css", function(config) {
-  var indentUnit = config.indentUnit, type;
-  
-  var atMediaTypes = keySet([
-    "all", "aural", "braille", "handheld", "print", "projection", "screen",
-    "tty", "tv", "embossed"
-  ]);
-  
-  var atMediaFeatures = keySet([
-    "width", "min-width", "max-width", "height", "min-height", "max-height",
-    "device-width", "min-device-width", "max-device-width", "device-height",
-    "min-device-height", "max-device-height", "aspect-ratio",
-    "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
-    "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
-    "max-color", "color-index", "min-color-index", "max-color-index",
-    "monochrome", "min-monochrome", "max-monochrome", "resolution",
-    "min-resolution", "max-resolution", "scan", "grid"
-  ]);
-
-  var propertyKeywords = keySet([
-    "align-content", "align-items", "align-self", "alignment-adjust",
-    "alignment-baseline", "anchor-point", "animation", "animation-delay",
-    "animation-direction", "animation-duration", "animation-iteration-count",
-    "animation-name", "animation-play-state", "animation-timing-function",
-    "appearance", "azimuth", "backface-visibility", "background",
-    "background-attachment", "background-clip", "background-color",
-    "background-image", "background-origin", "background-position",
-    "background-repeat", "background-size", "baseline-shift", "binding",
-    "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
-    "bookmark-target", "border", "border-bottom", "border-bottom-color",
-    "border-bottom-left-radius", "border-bottom-right-radius",
-    "border-bottom-style", "border-bottom-width", "border-collapse",
-    "border-color", "border-image", "border-image-outset",
-    "border-image-repeat", "border-image-slice", "border-image-source",
-    "border-image-width", "border-left", "border-left-color",
-    "border-left-style", "border-left-width", "border-radius", "border-right",
-    "border-right-color", "border-right-style", "border-right-width",
-    "border-spacing", "border-style", "border-top", "border-top-color",
-    "border-top-left-radius", "border-top-right-radius", "border-top-style",
-    "border-top-width", "border-width", "bottom", "box-decoration-break",
-    "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
-    "caption-side", "clear", "clip", "color", "color-profile", "column-count",
-    "column-fill", "column-gap", "column-rule", "column-rule-color",
-    "column-rule-style", "column-rule-width", "column-span", "column-width",
-    "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
-    "cue-after", "cue-before", "cursor", "direction", "display",
-    "dominant-baseline", "drop-initial-after-adjust",
-    "drop-initial-after-align", "drop-initial-before-adjust",
-    "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
-    "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
-    "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
-    "float", "float-offset", "font", "font-feature-settings", "font-family",
-    "font-kerning", "font-language-override", "font-size", "font-size-adjust",
-    "font-stretch", "font-style", "font-synthesis", "font-variant",
-    "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
-    "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
-    "font-weight", "grid-cell", "grid-column", "grid-column-align",
-    "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
-    "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
-    "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
-    "icon", "image-orientation", "image-rendering", "image-resolution",
-    "inline-box-align", "justify-content", "left", "letter-spacing",
-    "line-break", "line-height", "line-stacking", "line-stacking-ruby",
-    "line-stacking-shift", "line-stacking-strategy", "list-style",
-    "list-style-image", "list-style-position", "list-style-type", "margin",
-    "margin-bottom", "margin-left", "margin-right", "margin-top",
-    "marker-offset", "marks", "marquee-direction", "marquee-loop",
-    "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
-    "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
-    "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
-    "outline-color", "outline-offset", "outline-style", "outline-width",
-    "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
-    "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
-    "page", "page-break-after", "page-break-before", "page-break-inside",
-    "page-policy", "pause", "pause-after", "pause-before", "perspective",
-    "perspective-origin", "pitch", "pitch-range", "play-during", "position",
-    "presentation-level", "punctuation-trim", "quotes", "rendering-intent",
-    "resize", "rest", "rest-after", "rest-before", "richness", "right",
-    "rotation", "rotation-point", "ruby-align", "ruby-overhang",
-    "ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
-    "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
-    "tab-size", "table-layout", "target", "target-name", "target-new",
-    "target-position", "text-align", "text-align-last", "text-decoration",
-    "text-decoration-color", "text-decoration-line", "text-decoration-skip",
-    "text-decoration-style", "text-emphasis", "text-emphasis-color",
-    "text-emphasis-position", "text-emphasis-style", "text-height",
-    "text-indent", "text-justify", "text-outline", "text-shadow",
-    "text-space-collapse", "text-transform", "text-underline-position",
-    "text-wrap", "top", "transform", "transform-origin", "transform-style",
-    "transition", "transition-delay", "transition-duration",
-    "transition-property", "transition-timing-function", "unicode-bidi",
-    "vertical-align", "visibility", "voice-balance", "voice-duration",
-    "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
-    "voice-volume", "volume", "white-space", "widows", "width", "word-break",
-    "word-spacing", "word-wrap", "z-index"
-  ]);
-
-  var colorKeywords = keySet([
-    "black", "silver", "gray", "white", "maroon", "red", "purple", "fuchsia",
-    "green", "lime", "olive", "yellow", "navy", "blue", "teal", "aqua"
-  ]);
-  
-  var valueKeywords = keySet([
-    "above", "absolute", "activeborder", "activecaption", "afar",
-    "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
-    "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
-    "arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
-    "backwards", "baseline", "below", "bidi-override", "binary", "bengali",
-    "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
-    "both", "bottom", "break-all", "break-word", "button", "button-bevel",
-    "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
-    "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
-    "cell", "center", "checkbox", "circle", "cjk-earthly-branch",
-    "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
-    "col-resize", "collapse", "compact", "condensed", "contain", "content",
-    "content-box", "context-menu", "continuous", "copy", "cover", "crop",
-    "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
-    "decimal-leading-zero", "default", "default-button", "destination-atop",
-    "destination-in", "destination-out", "destination-over", "devanagari",
-    "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
-    "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
-    "element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
-    "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
-    "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
-    "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
-    "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
-    "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
-    "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
-    "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
-    "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
-    "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
-    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
-    "help", "hidden", "hide", "higher", "highlight", "highlighttext",
-    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
-    "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
-    "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
-    "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
-    "italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
-    "landscape", "lao", "large", "larger", "left", "level", "lighter",
-    "line-through", "linear", "lines", "list-item", "listbox", "listitem",
-    "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
-    "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
-    "lower-roman", "lowercase", "ltr", "malayalam", "match",
-    "media-controls-background", "media-current-time-display",
-    "media-fullscreen-button", "media-mute-button", "media-play-button",
-    "media-return-to-realtime-button", "media-rewind-button",
-    "media-seek-back-button", "media-seek-forward-button", "media-slider",
-    "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
-    "media-volume-slider-container", "media-volume-sliderthumb", "medium",
-    "menu", "menulist", "menulist-button", "menulist-text",
-    "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
-    "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
-    "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
-    "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
-    "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
-    "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
-    "outside", "overlay", "overline", "padding", "padding-box", "painted",
-    "paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
-    "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
-    "radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
-    "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
-    "ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
-    "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
-    "searchfield-cancel-button", "searchfield-decoration",
-    "searchfield-results-button", "searchfield-results-decoration",
-    "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
-    "single", "skip-white-space", "slide", "slider-horizontal",
-    "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
-    "small", "small-caps", "small-caption", "smaller", "solid", "somali",
-    "source-atop", "source-in", "source-out", "source-over", "space", "square",
-    "square-button", "start", "static", "status-bar", "stretch", "stroke",
-    "sub", "subpixel-antialiased", "super", "sw-resize", "table",
-    "table-caption", "table-cell", "table-column", "table-column-group",
-    "table-footer-group", "table-header-group", "table-row", "table-row-group",
-    "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
-    "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
-    "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
-    "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
-    "transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
-    "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
-    "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
-    "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
-    "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider",
-    "window", "windowframe", "windowtext", "x-large", "x-small", "xor",
-    "xx-large", "xx-small", "yellow"
-  ]);
-
-  function keySet(array) { var keys = {}; for (var i = 0; i < array.length; ++i) keys[array[i]] = true; return keys; }
-  function ret(style, tp) {type = tp; return style;}
-
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
-    else if (ch == "/" && stream.eat("*")) {
-      state.tokenize = tokenCComment;
-      return tokenCComment(stream, state);
-    }
-    else if (ch == "<" && stream.eat("!")) {
-      state.tokenize = tokenSGMLComment;
-      return tokenSGMLComment(stream, state);
-    }
-    else if (ch == "=") ret(null, "compare");
-    else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
-    else if (ch == "\"" || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    }
-    else if (ch == "#") {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("atom", "hash");
-    }
-    else if (ch == "!") {
-      stream.match(/^\s*\w*/);
-      return ret("keyword", "important");
-    }
-    else if (/\d/.test(ch)) {
-      stream.eatWhile(/[\w.%]/);
-      return ret("number", "unit");
-    }
-    else if (ch === "-") {
-      if (/\d/.test(stream.peek())) {
-        stream.eatWhile(/[\w.%]/);
-        return ret("number", "unit");
-      } else if (stream.match(/^[^-]+-/)) {
-        return ret("meta", type);
-      }
-    }
-    else if (/[,+>*\/]/.test(ch)) {
-      return ret(null, "select-op");
-    }
-    else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
-      return ret("qualifier", type);
-    }
-    else if (ch == ":") {
-      return ret("operator", ch);
-    }
-    else if (/[;{}\[\]\(\)]/.test(ch)) {
-      return ret(null, ch);
-    }
-    else {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("property", "variable");
-    }
-  }
-
-  function tokenCComment(stream, state) {
-    var maybeEnd = false, ch;
-    while ((ch = stream.next()) != null) {
-      if (maybeEnd && ch == "/") {
-        state.tokenize = tokenBase;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return ret("comment", "comment");
-  }
-
-  function tokenSGMLComment(stream, state) {
-    var dashes = 0, ch;
-    while ((ch = stream.next()) != null) {
-      if (dashes >= 2 && ch == ">") {
-        state.tokenize = tokenBase;
-        break;
-      }
-      dashes = (ch == "-") ? dashes + 1 : 0;
-    }
-    return ret("comment", "comment");
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, ch;
-      while ((ch = stream.next()) != null) {
-        if (ch == quote && !escaped)
-          break;
-        escaped = !escaped && ch == "\\";
-      }
-      if (!escaped) state.tokenize = tokenBase;
-      return ret("string", "string");
-    };
-  }
-
-  return {
-    startState: function(base) {
-      return {tokenize: tokenBase,
-              baseIndent: base || 0,
-              stack: []};
-    },
-
-    token: function(stream, state) {
-      
-      // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
-      // 
-      // rule** or **ruleset:
-      // A selector + braces combo, or an at-rule.
-      // 
-      // declaration block:
-      // A sequence of declarations.
-      // 
-      // declaration:
-      // A property + colon + value combo.
-      // 
-      // property value:
-      // The entire value of a property.
-      // 
-      // component value:
-      // A single piece of a property value. Like the 5px in
-      // text-shadow: 0 0 5px blue;. Can also refer to things that are
-      // multiple terms, like the 1-4 terms that make up the background-size
-      // portion of the background shorthand.
-      // 
-      // term:
-      // The basic unit of author-facing CSS, like a single number (5),
-      // dimension (5px), string ("foo"), or function. Officially defined
-      //  by the CSS 2.1 grammar (look for the 'term' production)
-      // 
-      // 
-      // simple selector:
-      // A single atomic selector, like a type selector, an attr selector, a
-      // class selector, etc.
-      // 
-      // compound selector:
-      // One or more simple selectors without a combinator. div.example is
-      // compound, div > .example is not.
-      // 
-      // complex selector:
-      // One or more compound selectors chained with combinators.
-      // 
-      // combinator:
-      // The parts of selectors that express relationships. There are four
-      // currently - the space (descendant combinator), the greater-than
-      // bracket (child combinator), the plus sign (next sibling combinator),
-      // and the tilda (following sibling combinator).
-      // 
-      // sequence of selectors:
-      // One or more of the named type of selector chained with commas.
-
-      if (stream.eatSpace()) return null;
-      var style = state.tokenize(stream, state);
-
-      // Changing style returned based on context
-      var context = state.stack[state.stack.length-1];
-      if (style == "property") {
-        if (context == "propertyValue"){
-          if (valueKeywords[stream.current()]) {
-            style = "string-2";
-          } else if (colorKeywords[stream.current()]) {
-            style = "keyword";
-          } else {
-            style = "variable-2";
-          }
-        } else if (context == "rule") {
-          if (!propertyKeywords[stream.current()]) {
-            style += " error";
-          }
-        } else if (!context || context == "@media{") {
-          style = "tag";
-        } else if (context == "@media") {
-          if (atMediaTypes[stream.current()]) {
-            style = "attribute"; // Known attribute
-          } else if (/^(only|not)$/i.test(stream.current())) {
-            style = "keyword";
-          } else if (stream.current().toLowerCase() == "and") {
-            style = "error"; // "and" is only allowed in @mediaType
-          } else if (atMediaFeatures[stream.current()]) {
-            style = "error"; // Known property, should be in @mediaType(
-          } else {
-            // Unknown, expecting keyword or attribute, assuming attribute
-            style = "attribute error";
-          }
-        } else if (context == "@mediaType") {
-          if (atMediaTypes[stream.current()]) {
-            style = "attribute";
-          } else if (stream.current().toLowerCase() == "and") {
-            style = "operator";
-          } else if (/^(only|not)$/i.test(stream.current())) {
-            style = "error"; // Only allowed in @media
-          } else if (atMediaFeatures[stream.current()]) {
-            style = "error"; // Known property, should be in parentheses
-          } else {
-            // Unknown attribute or property, but expecting property (preceded
-            // by "and"). Should be in parentheses
-            style = "error";
-          }
-        } else if (context == "@mediaType(") {
-          if (propertyKeywords[stream.current()]) {
-            // do nothing, remains "property"
-          } else if (atMediaTypes[stream.current()]) {
-            style = "error"; // Known property, should be in parentheses
-          } else if (stream.current().toLowerCase() == "and") {
-            style = "operator";
-          } else if (/^(only|not)$/i.test(stream.current())) {
-            style = "error"; // Only allowed in @media
-          } else {
-            style += " error";
-          }
-        } else {
-          style = "error";
-        }
-      } else if (style == "atom") {
-        if(!context || context == "@media{") {
-          style = "builtin";
-        } else if (context == "propertyValue") {
-          if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
-            style += " error";
-          }
-        } else {
-          style = "error";
-        }
-      } else if (context == "@media" && type == "{") {
-        style = "error";
-      }
-
-      // Push/pop context stack
-      if (type == "{") {
-        if (context == "@media" || context == "@mediaType") {
-          state.stack.pop();
-          state.stack[state.stack.length-1] = "@media{";
-        }
-        else state.stack.push("rule");
-      }
-      else if (type == "}") {
-        state.stack.pop();
-        if (context == "propertyValue") state.stack.pop();
-      }
-      else if (type == "@media") state.stack.push("@media");
-      else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
-        state.stack.push("@mediaType");
-      else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
-      else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
-      else if (context == "@mediaType(" && type == ")") state.stack.pop();
-      else if (context == "rule" && type == ":") state.stack.push("propertyValue");
-      else if (context == "propertyValue" && type == ";") state.stack.pop();
-      return style;
-    },
-
-    indent: function(state, textAfter) {
-      var n = state.stack.length;
-      if (/^\}/.test(textAfter))
-        n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
-      return state.baseIndent + n * indentUnit;
-    },
-
-    electricChars: "}"
-  };
-});
-
-CodeMirror.defineMIME("text/css", "css");
Index: plugins/themeEditor/codemirror/htmlmixed.js
===================================================================
--- plugins/themeEditor/codemirror/htmlmixed.js	(revision 948)
+++ 	(revision )
@@ -1,84 +1,0 @@
-CodeMirror.defineMode("htmlmixed", function(config) {
-  var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
-  var jsMode = CodeMirror.getMode(config, "javascript");
-  var cssMode = CodeMirror.getMode(config, "css");
-
-  function html(stream, state) {
-    var style = htmlMode.token(stream, state.htmlState);
-    if (style == "tag" && stream.current() == ">" && state.htmlState.context) {
-      if (/^script$/i.test(state.htmlState.context.tagName)) {
-        state.token = javascript;
-        state.localState = jsMode.startState(htmlMode.indent(state.htmlState, ""));
-      }
-      else if (/^style$/i.test(state.htmlState.context.tagName)) {
-        state.token = css;
-        state.localState = cssMode.startState(htmlMode.indent(state.htmlState, ""));
-      }
-    }
-    return style;
-  }
-  function maybeBackup(stream, pat, style) {
-    var cur = stream.current();
-    var close = cur.search(pat), m;
-    if (close > -1) stream.backUp(cur.length - close);
-    else if (m = cur.match(/<\/?$/)) {
-      stream.backUp(cur[0].length);
-      if (!stream.match(pat, false)) stream.match(cur[0]);
-    }
-    return style;
-  }
-  function javascript(stream, state) {
-    if (stream.match(/^<\/\s*script\s*>/i, false)) {
-      state.token = html;
-      state.localState = null;
-      return html(stream, state);
-    }
-    return maybeBackup(stream, /<\/\s*script\s*>/,
-                       jsMode.token(stream, state.localState));
-  }
-  function css(stream, state) {
-    if (stream.match(/^<\/\s*style\s*>/i, false)) {
-      state.token = html;
-      state.localState = null;
-      return html(stream, state);
-    }
-    return maybeBackup(stream, /<\/\s*style\s*>/,
-                       cssMode.token(stream, state.localState));
-  }
-
-  return {
-    startState: function() {
-      var state = htmlMode.startState();
-      return {token: html, localState: null, mode: "html", htmlState: state};
-    },
-
-    copyState: function(state) {
-      if (state.localState)
-        var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);
-      return {token: state.token, localState: local, mode: state.mode,
-              htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
-    },
-
-    token: function(stream, state) {
-      return state.token(stream, state);
-    },
-
-    indent: function(state, textAfter) {
-      if (state.token == html || /^\s*<\//.test(textAfter))
-        return htmlMode.indent(state.htmlState, textAfter);
-      else if (state.token == javascript)
-        return jsMode.indent(state.localState, textAfter);
-      else
-        return cssMode.indent(state.localState, textAfter);
-    },
-
-    electricChars: "/{}:",
-
-    innerMode: function(state) {
-      var mode = state.token == html ? htmlMode : state.token == javascript ? jsMode : cssMode;
-      return {state: state.localState || state.htmlState, mode: mode};
-    }
-  };
-}, "xml", "javascript", "css");
-
-CodeMirror.defineMIME("text/html", "htmlmixed");
Index: plugins/themeEditor/codemirror/javascript.js
===================================================================
--- plugins/themeEditor/codemirror/javascript.js	(revision 948)
+++ 	(revision )
@@ -1,409 +1,0 @@
-// TODO actually recognize syntax of TypeScript constructs
-
-CodeMirror.defineMode("javascript", function(config, parserConfig) {
-  var indentUnit = config.indentUnit;
-  var jsonMode = parserConfig.json;
-  var isTS = parserConfig.typescript;
-
-  // Tokenizer
-
-  var keywords = function(){
-    function kw(type) {return {type: type, style: "keyword"};}
-    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
-    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
-    
-    var jsKeywords = {
-      "if": A, "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
-      "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
-      "var": kw("var"), "const": kw("var"), "let": kw("var"),
-      "function": kw("function"), "catch": kw("catch"),
-      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
-      "in": operator, "typeof": operator, "instanceof": operator,
-      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom
-    };
-
-    // Extend the 'normal' keywords with the TypeScript language extensions
-    if (isTS) {
-      var type = {type: "variable", style: "variable-3"};
-      var tsKeywords = {
-        // object-like things
-        "interface": kw("interface"),
-        "class": kw("class"),
-        "extends": kw("extends"),
-        "constructor": kw("constructor"),
-
-        // scope modifiers
-        "public": kw("public"),
-        "private": kw("private"),
-        "protected": kw("protected"),
-        "static": kw("static"),
-
-        "super": kw("super"),
-
-        // types
-        "string": type, "number": type, "bool": type, "any": type
-      };
-
-      for (var attr in tsKeywords) {
-        jsKeywords[attr] = tsKeywords[attr];
-      }
-    }
-
-    return jsKeywords;
-  }();
-
-  var isOperatorChar = /[+\-*&%=<>!?|]/;
-
-  function chain(stream, state, f) {
-    state.tokenize = f;
-    return f(stream, state);
-  }
-
-  function nextUntilUnescaped(stream, end) {
-    var escaped = false, next;
-    while ((next = stream.next()) != null) {
-      if (next == end && !escaped)
-        return false;
-      escaped = !escaped && next == "\\";
-    }
-    return escaped;
-  }
-
-  // Used as scratch variables to communicate multiple values without
-  // consing up tons of objects.
-  var type, content;
-  function ret(tp, style, cont) {
-    type = tp; content = cont;
-    return style;
-  }
-
-  function jsTokenBase(stream, state) {
-    var ch = stream.next();
-    if (ch == '"' || ch == "'")
-      return chain(stream, state, jsTokenString(ch));
-    else if (/[\[\]{}\(\),;\:\.]/.test(ch))
-      return ret(ch);
-    else if (ch == "0" && stream.eat(/x/i)) {
-      stream.eatWhile(/[\da-f]/i);
-      return ret("number", "number");
-    }      
-    else if (/\d/.test(ch) || ch == "-" && stream.eat(/\d/)) {
-      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
-      return ret("number", "number");
-    }
-    else if (ch == "/") {
-      if (stream.eat("*")) {
-        return chain(stream, state, jsTokenComment);
-      }
-      else if (stream.eat("/")) {
-        stream.skipToEnd();
-        return ret("comment", "comment");
-      }
-      else if (state.lastType == "operator" || state.lastType == "keyword c" ||
-               /^[\[{}\(,;:]$/.test(state.lastType)) {
-        nextUntilUnescaped(stream, "/");
-        stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
-        return ret("regexp", "string-2");
-      }
-      else {
-        stream.eatWhile(isOperatorChar);
-        return ret("operator", null, stream.current());
-      }
-    }
-    else if (ch == "#") {
-        stream.skipToEnd();
-        return ret("error", "error");
-    }
-    else if (isOperatorChar.test(ch)) {
-      stream.eatWhile(isOperatorChar);
-      return ret("operator", null, stream.current());
-    }
-    else {
-      stream.eatWhile(/[\w\$_]/);
-      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
-      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
-                     ret("variable", "variable", word);
-    }
-  }
-
-  function jsTokenString(quote) {
-    return function(stream, state) {
-      if (!nextUntilUnescaped(stream, quote))
-        state.tokenize = jsTokenBase;
-      return ret("string", "string");
-    };
-  }
-
-  function jsTokenComment(stream, state) {
-    var maybeEnd = false, ch;
-    while (ch = stream.next()) {
-      if (ch == "/" && maybeEnd) {
-        state.tokenize = jsTokenBase;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return ret("comment", "comment");
-  }
-
-  // Parser
-
-  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true};
-
-  function JSLexical(indented, column, type, align, prev, info) {
-    this.indented = indented;
-    this.column = column;
-    this.type = type;
-    this.prev = prev;
-    this.info = info;
-    if (align != null) this.align = align;
-  }
-
-  function inScope(state, varname) {
-    for (var v = state.localVars; v; v = v.next)
-      if (v.name == varname) return true;
-  }
-
-  function parseJS(state, style, type, content, stream) {
-    var cc = state.cc;
-    // Communicate our context to the combinators.
-    // (Less wasteful than consing up a hundred closures on every call.)
-    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
-  
-    if (!state.lexical.hasOwnProperty("align"))
-      state.lexical.align = true;
-
-    while(true) {
-      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
-      if (combinator(type, content)) {
-        while(cc.length && cc[cc.length - 1].lex)
-          cc.pop()();
-        if (cx.marked) return cx.marked;
-        if (type == "variable" && inScope(state, content)) return "variable-2";
-        return style;
-      }
-    }
-  }
-
-  // Combinator utils
-
-  var cx = {state: null, column: null, marked: null, cc: null};
-  function pass() {
-    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
-  }
-  function cont() {
-    pass.apply(null, arguments);
-    return true;
-  }
-  function register(varname) {
-    var state = cx.state;
-    if (state.context) {
-      cx.marked = "def";
-      for (var v = state.localVars; v; v = v.next)
-        if (v.name == varname) return;
-      state.localVars = {name: varname, next: state.localVars};
-    }
-  }
-
-  // Combinators
-
-  var defaultVars = {name: "this", next: {name: "arguments"}};
-  function pushcontext() {
-    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
-    cx.state.localVars = defaultVars;
-  }
-  function popcontext() {
-    cx.state.localVars = cx.state.context.vars;
-    cx.state.context = cx.state.context.prev;
-  }
-  function pushlex(type, info) {
-    var result = function() {
-      var state = cx.state;
-      state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info);
-    };
-    result.lex = true;
-    return result;
-  }
-  function poplex() {
-    var state = cx.state;
-    if (state.lexical.prev) {
-      if (state.lexical.type == ")")
-        state.indented = state.lexical.indented;
-      state.lexical = state.lexical.prev;
-    }
-  }
-  poplex.lex = true;
-
-  function expect(wanted) {
-    return function expecting(type) {
-      if (type == wanted) return cont();
-      else if (wanted == ";") return pass();
-      else return cont(arguments.callee);
-    };
-  }
-
-  function statement(type) {
-    if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
-    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
-    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
-    if (type == "{") return cont(pushlex("}"), block, poplex);
-    if (type == ";") return cont();
-    if (type == "function") return cont(functiondef);
-    if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
-                                      poplex, statement, poplex);
-    if (type == "variable") return cont(pushlex("stat"), maybelabel);
-    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
-                                         block, poplex, poplex);
-    if (type == "case") return cont(expression, expect(":"));
-    if (type == "default") return cont(expect(":"));
-    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
-                                        statement, poplex, popcontext);
-    return pass(pushlex("stat"), expression, expect(";"), poplex);
-  }
-  function expression(type) {
-    if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);
-    if (type == "function") return cont(functiondef);
-    if (type == "keyword c") return cont(maybeexpression);
-    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeoperator);
-    if (type == "operator") return cont(expression);
-    if (type == "[") return cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
-    if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeoperator);
-    return cont();
-  }
-  function maybeexpression(type) {
-    if (type.match(/[;\}\)\],]/)) return pass();
-    return pass(expression);
-  }
-    
-  function maybeoperator(type, value) {
-    if (type == "operator" && /\+\+|--/.test(value)) return cont(maybeoperator);
-    if (type == "operator" && value == "?") return cont(expression, expect(":"), expression);
-    if (type == ";") return;
-    if (type == "(") return cont(pushlex(")"), commasep(expression, ")"), poplex, maybeoperator);
-    if (type == ".") return cont(property, maybeoperator);
-    if (type == "[") return cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
-  }
-  function maybelabel(type) {
-    if (type == ":") return cont(poplex, statement);
-    return pass(maybeoperator, expect(";"), poplex);
-  }
-  function property(type) {
-    if (type == "variable") {cx.marked = "property"; return cont();}
-  }
-  function objprop(type) {
-    if (type == "variable") cx.marked = "property";
-    if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expression);
-  }
-  function commasep(what, end) {
-    function proceed(type) {
-      if (type == ",") return cont(what, proceed);
-      if (type == end) return cont();
-      return cont(expect(end));
-    }
-    return function commaSeparated(type) {
-      if (type == end) return cont();
-      else return pass(what, proceed);
-    };
-  }
-  function block(type) {
-    if (type == "}") return cont();
-    return pass(statement, block);
-  }
-  function maybetype(type) {
-    if (type == ":") return cont(typedef);
-    return pass();
-  }
-  function typedef(type) {
-    if (type == "variable"){cx.marked = "variable-3"; return cont();}
-    return pass();
-  }
-  function vardef1(type, value) {
-    if (type == "variable") {
-      register(value);
-      return isTS ? cont(maybetype, vardef2) : cont(vardef2);
-    }
-    return pass();
-  }
-  function vardef2(type, value) {
-    if (value == "=") return cont(expression, vardef2);
-    if (type == ",") return cont(vardef1);
-  }
-  function forspec1(type) {
-    if (type == "var") return cont(vardef1, expect(";"), forspec2);
-    if (type == ";") return cont(forspec2);
-    if (type == "variable") return cont(formaybein);
-    return cont(forspec2);
-  }
-  function formaybein(type, value) {
-    if (value == "in") return cont(expression);
-    return cont(maybeoperator, forspec2);
-  }
-  function forspec2(type, value) {
-    if (type == ";") return cont(forspec3);
-    if (value == "in") return cont(expression);
-    return cont(expression, expect(";"), forspec3);
-  }
-  function forspec3(type) {
-    if (type != ")") cont(expression);
-  }
-  function functiondef(type, value) {
-    if (type == "variable") {register(value); return cont(functiondef);}
-    if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
-  }
-  function funarg(type, value) {
-    if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
-  }
-
-  // Interface
-
-  return {
-    startState: function(basecolumn) {
-      return {
-        tokenize: jsTokenBase,
-        lastType: null,
-        cc: [],
-        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
-        localVars: parserConfig.localVars,
-        context: parserConfig.localVars && {vars: parserConfig.localVars},
-        indented: 0
-      };
-    },
-
-    token: function(stream, state) {
-      if (stream.sol()) {
-        if (!state.lexical.hasOwnProperty("align"))
-          state.lexical.align = false;
-        state.indented = stream.indentation();
-      }
-      if (stream.eatSpace()) return null;
-      var style = state.tokenize(stream, state);
-      if (type == "comment") return style;
-      state.lastType = type;
-      return parseJS(state, style, type, content, stream);
-    },
-
-    indent: function(state, textAfter) {
-      if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
-      if (state.tokenize != jsTokenBase) return 0;
-      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
-      if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
-      var type = lexical.type, closing = firstChar == type;
-      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
-      else if (type == "form" && firstChar == "{") return lexical.indented;
-      else if (type == "form") return lexical.indented + indentUnit;
-      else if (type == "stat")
-        return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? indentUnit : 0);
-      else if (lexical.info == "switch" && !closing)
-        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
-      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
-      else return lexical.indented + (closing ? 0 : indentUnit);
-    },
-
-    electricChars: ":{}"
-  };
-});
-
-CodeMirror.defineMIME("text/javascript", "javascript");
-CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
-CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
-CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
Index: plugins/themeEditor/codemirror/multiplex.js
===================================================================
--- plugins/themeEditor/codemirror/multiplex.js	(revision 997)
+++ 	(revision )
@@ -1,77 +1,0 @@
-CodeMirror.multiplexingMode = function(outer /*, others */) {
-  // Others should be {open, close, mode [, delimStyle]} objects
-  var others = Array.prototype.slice.call(arguments, 1);
-  var n_others = others.length;
-
-  function indexOf(string, pattern, from) {
-    if (typeof pattern == "string") return string.indexOf(pattern, from);
-    var m = pattern.exec(from ? string.slice(from) : string);
-    return m ? m.index + from : -1;
-  }
-
-  return {
-    startState: function() {
-      return {
-        outer: CodeMirror.startState(outer),
-        innerActive: null,
-        inner: null
-      };
-    },
-
-    copyState: function(state) {
-      return {
-        outer: CodeMirror.copyState(outer, state.outer),
-        innerActive: state.innerActive,
-        inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
-      };
-    },
-
-    token: function(stream, state) {
-      if (!state.innerActive) {
-        var cutOff = Infinity, oldContent = stream.string;
-        for (var i = 0; i < n_others; ++i) {
-          var other = others[i];
-          var found = indexOf(oldContent, other.open, stream.pos);
-          if (found == stream.pos) {
-            stream.match(other.open);
-            state.innerActive = other;
-            state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
-            return other.delimStyle;
-          } else if (found != -1 && found < cutOff) {
-            cutOff = found;
-          }
-        }
-        if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
-        var outerToken = outer.token(stream, state.outer);
-        if (cutOff != Infinity) stream.string = oldContent;
-        return outerToken;
-      } else {
-        var curInner = state.innerActive, oldContent = stream.string;
-        var found = indexOf(oldContent, curInner.close, stream.pos);
-        if (found == stream.pos) {
-          stream.match(curInner.close);
-          state.innerActive = state.inner = null;
-          return curInner.delimStyle;
-        }
-        if (found > -1) stream.string = oldContent.slice(0, found);
-        var innerToken = curInner.mode.token(stream, state.inner);
-        if (found > -1) stream.string = oldContent;
-        var cur = stream.current(), found = cur.indexOf(curInner.close);
-        if (found > -1) stream.backUp(cur.length - found);
-        return innerToken;
-      }
-    },
-    
-    indent: function(state, textAfter) {
-      var mode = state.innerActive ? state.innerActive.mode : outer;
-      if (!mode.indent) return CodeMirror.Pass;
-      return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
-    },
-
-    electricChars: outer.electricChars,
-
-    innerMode: function(state) {
-      return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
-    }
-  };
-};
Index: plugins/themeEditor/codemirror/php.js
===================================================================
--- plugins/themeEditor/codemirror/php.js	(revision 948)
+++ 	(revision )
@@ -1,148 +1,0 @@
-(function() {
-  function keywords(str) {
-    var obj = {}, words = str.split(" ");
-    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
-    return obj;
-  }
-  function heredoc(delim) {
-    return function(stream, state) {
-      if (stream.match(delim)) state.tokenize = null;
-      else stream.skipToEnd();
-      return "string";
-    };
-  }
-  var phpConfig = {
-    name: "clike",
-    keywords: keywords("abstract and array as break case catch class clone const continue declare default " +
-                       "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
-                       "for foreach function global goto if implements interface instanceof namespace " +
-                       "new or private protected public static switch throw trait try use var while xor " +
-                       "die echo empty exit eval include include_once isset list require require_once return " +
-                       "print unset __halt_compiler self static parent"),
-    blockKeywords: keywords("catch do else elseif for foreach if switch try while"),
-    atoms: keywords("true false null TRUE FALSE NULL"),
-    multiLineStrings: true,
-    hooks: {
-      "$": function(stream, state) {
-        stream.eatWhile(/[\w\$_]/);
-        return "variable-2";
-      },
-      "<": function(stream, state) {
-        if (stream.match(/<</)) {
-          stream.eatWhile(/[\w\.]/);
-          state.tokenize = heredoc(stream.current().slice(3));
-          return state.tokenize(stream, state);
-        }
-        return false;
-      },
-      "#": function(stream, state) {
-        while (!stream.eol() && !stream.match("?>", false)) stream.next();
-        return "comment";
-      },
-      "/": function(stream, state) {
-        if (stream.eat("/")) {
-          while (!stream.eol() && !stream.match("?>", false)) stream.next();
-          return "comment";
-        }
-        return false;
-      }
-    }
-  };
-
-  CodeMirror.defineMode("php", function(config, parserConfig) {
-    var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
-    var jsMode = CodeMirror.getMode(config, "javascript");
-    var cssMode = CodeMirror.getMode(config, "css");
-    var phpMode = CodeMirror.getMode(config, phpConfig);
-
-    function dispatch(stream, state) { // TODO open PHP inside text/css
-      var isPHP = state.curMode == phpMode;
-      if (stream.sol() && state.pending != '"') state.pending = null;
-      if (state.curMode == htmlMode) {
-        if (stream.match(/^<\?\w*/)) {
-          state.curMode = phpMode;
-          state.curState = state.php;
-          state.curClose = "?>";
-          return "meta";
-        }
-        if (state.pending == '"') {
-          while (!stream.eol() && stream.next() != '"') {}
-          var style = "string";
-        } else if (state.pending && stream.pos < state.pending.end) {
-          stream.pos = state.pending.end;
-          var style = state.pending.style;
-        } else {
-          var style = htmlMode.token(stream, state.curState);
-        }
-        state.pending = null;
-        var cur = stream.current(), openPHP = cur.search(/<\?/);
-        if (openPHP != -1) {
-          if (style == "string" && /\"$/.test(cur) && !/\?>/.test(cur)) state.pending = '"';
-          else state.pending = {end: stream.pos, style: style};
-          stream.backUp(cur.length - openPHP);
-        } else if (style == "tag" && stream.current() == ">" && state.curState.context) {
-          if (/^script$/i.test(state.curState.context.tagName)) {
-            state.curMode = jsMode;
-            state.curState = jsMode.startState(htmlMode.indent(state.curState, ""));
-            state.curClose = /^<\/\s*script\s*>/i;
-          }
-          else if (/^style$/i.test(state.curState.context.tagName)) {
-            state.curMode = cssMode;
-            state.curState = cssMode.startState(htmlMode.indent(state.curState, ""));
-            state.curClose = /^<\/\s*style\s*>/i;
-          }
-        }
-        return style;
-      } else if ((!isPHP || state.php.tokenize == null) &&
-                 stream.match(state.curClose, isPHP)) {
-        state.curMode = htmlMode;
-        state.curState = state.html;
-        state.curClose = null;
-        if (isPHP) return "meta";
-        else return dispatch(stream, state);
-      } else {
-        return state.curMode.token(stream, state.curState);
-      }
-    }
-
-    return {
-      startState: function() {
-        var html = htmlMode.startState();
-        return {html: html,
-                php: phpMode.startState(),
-                curMode: parserConfig.startOpen ? phpMode : htmlMode,
-                curState: parserConfig.startOpen ? phpMode.startState() : html,
-                curClose: parserConfig.startOpen ? /^\?>/ : null,
-		mode: parserConfig.startOpen ? "php" : "html",
-                pending: null};
-      },
-
-      copyState: function(state) {
-        var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
-            php = state.php, phpNew = CodeMirror.copyState(phpMode, php), cur;
-        if (state.curState == html) cur = htmlNew;
-        else if (state.curState == php) cur = phpNew;
-        else cur = CodeMirror.copyState(state.curMode, state.curState);
-        return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
-                curClose: state.curClose, mode: state.mode,
-                pending: state.pending};
-      },
-
-      token: dispatch,
-
-      indent: function(state, textAfter) {
-        if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
-            (state.curMode == phpMode && /^\?>/.test(textAfter)))
-          return htmlMode.indent(state.html, textAfter);
-        return state.curMode.indent(state.curState, textAfter);
-      },
-
-      electricChars: "/{}:",
-
-      innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
-    };
-  }, "xml", "clike", "javascript", "css");
-  CodeMirror.defineMIME("application/x-httpd-php", "php");
-  CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
-  CodeMirror.defineMIME("text/x-php", phpConfig);
-})();
Index: plugins/themeEditor/codemirror/xml.js
===================================================================
--- plugins/themeEditor/codemirror/xml.js	(revision 948)
+++ 	(revision )
@@ -1,318 +1,0 @@
-CodeMirror.defineMode("xml", function(config, parserConfig) {
-  var indentUnit = config.indentUnit;
-  var Kludges = parserConfig.htmlMode ? {
-    autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
-                      'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
-                      'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
-                      'track': true, 'wbr': true},
-    implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
-                       'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
-                       'th': true, 'tr': true},
-    contextGrabbers: {
-      'dd': {'dd': true, 'dt': true},
-      'dt': {'dd': true, 'dt': true},
-      'li': {'li': true},
-      'option': {'option': true, 'optgroup': true},
-      'optgroup': {'optgroup': true},
-      'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
-            'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
-            'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
-            'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
-            'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
-      'rp': {'rp': true, 'rt': true},
-      'rt': {'rp': true, 'rt': true},
-      'tbody': {'tbody': true, 'tfoot': true},
-      'td': {'td': true, 'th': true},
-      'tfoot': {'tbody': true},
-      'th': {'td': true, 'th': true},
-      'thead': {'tbody': true, 'tfoot': true},
-      'tr': {'tr': true}
-    },
-    doNotIndent: {"pre": true},
-    allowUnquoted: true,
-    allowMissing: true
-  } : {
-    autoSelfClosers: {},
-    implicitlyClosed: {},
-    contextGrabbers: {},
-    doNotIndent: {},
-    allowUnquoted: false,
-    allowMissing: false
-  };
-  var alignCDATA = parserConfig.alignCDATA;
-
-  // Return variables for tokenizers
-  var tagName, type;
-
-  function inText(stream, state) {
-    function chain(parser) {
-      state.tokenize = parser;
-      return parser(stream, state);
-    }
-
-    var ch = stream.next();
-    if (ch == "<") {
-      if (stream.eat("!")) {
-        if (stream.eat("[")) {
-          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
-          else return null;
-        }
-        else if (stream.match("--")) return chain(inBlock("comment", "-->"));
-        else if (stream.match("DOCTYPE", true, true)) {
-          stream.eatWhile(/[\w\._\-]/);
-          return chain(doctype(1));
-        }
-        else return null;
-      }
-      else if (stream.eat("?")) {
-        stream.eatWhile(/[\w\._\-]/);
-        state.tokenize = inBlock("meta", "?>");
-        return "meta";
-      }
-      else {
-        type = stream.eat("/") ? "closeTag" : "openTag";
-        stream.eatSpace();
-        tagName = "";
-        var c;
-        while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
-        state.tokenize = inTag;
-        return "tag";
-      }
-    }
-    else if (ch == "&") {
-      var ok;
-      if (stream.eat("#")) {
-        if (stream.eat("x")) {
-          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");          
-        } else {
-          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
-        }
-      } else {
-        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
-      }
-      return ok ? "atom" : "error";
-    }
-    else {
-      stream.eatWhile(/[^&<]/);
-      return null;
-    }
-  }
-
-  function inTag(stream, state) {
-    var ch = stream.next();
-    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
-      state.tokenize = inText;
-      type = ch == ">" ? "endTag" : "selfcloseTag";
-      return "tag";
-    }
-    else if (ch == "=") {
-      type = "equals";
-      return null;
-    }
-    else if (/[\'\"]/.test(ch)) {
-      state.tokenize = inAttribute(ch);
-      return state.tokenize(stream, state);
-    }
-    else {
-      stream.eatWhile(/[^\s\u00a0=<>\"\'\/?]/);
-      return "word";
-    }
-  }
-
-  function inAttribute(quote) {
-    return function(stream, state) {
-      while (!stream.eol()) {
-        if (stream.next() == quote) {
-          state.tokenize = inTag;
-          break;
-        }
-      }
-      return "string";
-    };
-  }
-
-  function inBlock(style, terminator) {
-    return function(stream, state) {
-      while (!stream.eol()) {
-        if (stream.match(terminator)) {
-          state.tokenize = inText;
-          break;
-        }
-        stream.next();
-      }
-      return style;
-    };
-  }
-  function doctype(depth) {
-    return function(stream, state) {
-      var ch;
-      while ((ch = stream.next()) != null) {
-        if (ch == "<") {
-          state.tokenize = doctype(depth + 1);
-          return state.tokenize(stream, state);
-        } else if (ch == ">") {
-          if (depth == 1) {
-            state.tokenize = inText;
-            break;
-          } else {
-            state.tokenize = doctype(depth - 1);
-            return state.tokenize(stream, state);
-          }
-        }
-      }
-      return "meta";
-    };
-  }
-
-  var curState, setStyle;
-  function pass() {
-    for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
-  }
-  function cont() {
-    pass.apply(null, arguments);
-    return true;
-  }
-
-  function pushContext(tagName, startOfLine) {
-    var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
-    curState.context = {
-      prev: curState.context,
-      tagName: tagName,
-      indent: curState.indented,
-      startOfLine: startOfLine,
-      noIndent: noIndent
-    };
-  }
-  function popContext() {
-    if (curState.context) curState.context = curState.context.prev;
-  }
-
-  function element(type) {
-    if (type == "openTag") {
-      curState.tagName = tagName;
-      return cont(attributes, endtag(curState.startOfLine));
-    } else if (type == "closeTag") {
-      var err = false;
-      if (curState.context) {
-        if (curState.context.tagName != tagName) {
-          if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
-            popContext();
-          }
-          err = !curState.context || curState.context.tagName != tagName;
-        }
-      } else {
-        err = true;
-      }
-      if (err) setStyle = "error";
-      return cont(endclosetag(err));
-    }
-    return cont();
-  }
-  function endtag(startOfLine) {
-    return function(type) {
-      if (type == "selfcloseTag" ||
-          (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase()))) {
-        maybePopContext(curState.tagName.toLowerCase());
-        return cont();
-      }
-      if (type == "endTag") {
-        maybePopContext(curState.tagName.toLowerCase());
-        pushContext(curState.tagName, startOfLine);
-        return cont();
-      }
-      return cont();
-    };
-  }
-  function endclosetag(err) {
-    return function(type) {
-      if (err) setStyle = "error";
-      if (type == "endTag") { popContext(); return cont(); }
-      setStyle = "error";
-      return cont(arguments.callee);
-    };
-  }
-  function maybePopContext(nextTagName) {
-    var parentTagName;
-    while (true) {
-      if (!curState.context) {
-        return;
-      }
-      parentTagName = curState.context.tagName.toLowerCase();
-      if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
-          !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
-        return;
-      }
-      popContext();
-    }
-  }
-
-  function attributes(type) {
-    if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
-    if (type == "endTag" || type == "selfcloseTag") return pass();
-    setStyle = "error";
-    return cont(attributes);
-  }
-  function attribute(type) {
-    if (type == "equals") return cont(attvalue, attributes);
-    if (!Kludges.allowMissing) setStyle = "error";
-    return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
-  }
-  function attvalue(type) {
-    if (type == "string") return cont(attvaluemaybe);
-    if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
-    setStyle = "error";
-    return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
-  }
-  function attvaluemaybe(type) {
-    if (type == "string") return cont(attvaluemaybe);
-    else return pass();
-  }
-
-  return {
-    startState: function() {
-      return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};
-    },
-
-    token: function(stream, state) {
-      if (stream.sol()) {
-        state.startOfLine = true;
-        state.indented = stream.indentation();
-      }
-      if (stream.eatSpace()) return null;
-
-      setStyle = type = tagName = null;
-      var style = state.tokenize(stream, state);
-      state.type = type;
-      if ((style || type) && style != "comment") {
-        curState = state;
-        while (true) {
-          var comb = state.cc.pop() || element;
-          if (comb(type || style)) break;
-        }
-      }
-      state.startOfLine = false;
-      return setStyle || style;
-    },
-
-    indent: function(state, textAfter, fullLine) {
-      var context = state.context;
-      if ((state.tokenize != inTag && state.tokenize != inText) ||
-          context && context.noIndent)
-        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
-      if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
-      if (context && /^<\//.test(textAfter))
-        context = context.prev;
-      while (context && !context.startOfLine)
-        context = context.prev;
-      if (context) return context.indent + indentUnit;
-      else return 0;
-    },
-
-    electricChars: "/"
-  };
-});
-
-CodeMirror.defineMIME("text/xml", "xml");
-CodeMirror.defineMIME("application/xml", "xml");
-if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
-  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
Index: plugins/themeEditor/help.html
===================================================================
--- plugins/themeEditor/help.html	(revision 989)
+++ plugins/themeEditor/help.html	(revision 100)
@@ -25,6 +25,4 @@
 <p>To help modify your templates, you may consult the <a href="http://doc.dotclear.net/2.0/resources/templates">template tag list</a>.</p>
 
-<p>Note: You can activate syntax coloration in your preferences (“My options” tab).</p>
-
 </body>
 </html>
Index: plugins/themeEditor/index.php
===================================================================
--- plugins/themeEditor/index.php	(revision 997)
+++ plugins/themeEditor/index.php	(revision 500)
@@ -15,8 +15,4 @@
 
 $file_default = $file = array('c'=>null, 'w'=>false, 'type'=>null, 'f'=>null, 'default_file'=>false);
-
-# Get interface setting
-$core->auth->user_prefs->addWorkspace('interface');
-$user_ui_colorsyntax = $core->auth->user_prefs->interface->colorsyntax;
 
 # Loading themes
@@ -66,19 +62,7 @@
   <?php echo dcPage::jsVar('dotclear.msg.document_saved',__("Document saved")); ?>
   <?php echo dcPage::jsVar('dotclear.msg.error_occurred',__("An error occurred:")); ?>
-  <?php echo dcPage::jsVar('dotclear.colorsyntax',$user_ui_colorsyntax); ?>
   //]]>
   </script>
   <script type="text/javascript" src="index.php?pf=themeEditor/script.js"></script>
-<?php if ($user_ui_colorsyntax) { ?>
-  <link rel="stylesheet" type="text/css" href="index.php?pf=themeEditor/codemirror/codemirror.css" />
-  <link rel="stylesheet" type="text/css" href="index.php?pf=themeEditor/codemirror.css" />
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/codemirror.js"></script>
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/multiplex.js"></script>
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/xml.js"></script>
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/javascript.js"></script>
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/css.js"></script>
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/php.js"></script>
-  <script type="text/JavaScript" src="index.php?pf=themeEditor/codemirror/htmlmixed.js"></script>
-<?php } ?>
 </head>
 
@@ -124,32 +108,4 @@
 	echo
 	'</fieldset></form>';
-
-	if ($user_ui_colorsyntax) {
-		$editorMode = (!empty($_REQUEST['css']) ? "css" : (!empty($_REQUEST['js']) ? "javascript" : "text/html"));
-		echo 
-		'<script>
-			window.CodeMirror.defineMode("dotclear", function(config) {
-				return CodeMirror.multiplexingMode(
-					CodeMirror.getMode(config, "'.$editorMode.'"),
-					{open: "{{tpl:", close: "}}",
-					 mode: CodeMirror.getMode(config, "text/plain"),
-					 delimStyle: "delimit"},
-					{open: "<tpl:", close: ">",
-					 mode: CodeMirror.getMode(config, "text/plain"),
-					 delimStyle: "delimit"},
-					{open: "</tpl:", close: ">",
-					 mode: CodeMirror.getMode(config, "text/plain"),
-					 delimStyle: "delimit"}
-					);
-			});
-	    	var editor = CodeMirror.fromTextArea(document.getElementById("file_content"), {
-	    		mode: "dotclear",
-	       		tabMode: "indent",
-	       		lineWrapping: "true",
-	       		lineNumbers: "true",
-	   			matchBrackets: "true"
-	   		});
-	    </script>';
-	}
 }
 ?>
Index: plugins/themeEditor/script.js
===================================================================
--- plugins/themeEditor/script.js	(revision 948)
+++ plugins/themeEditor/script.js	(revision 0)
@@ -5,5 +5,5 @@
 		
 		var data = {
-			file_content: (!dotclear.colorsyntax ? $(f).find('#file_content').get(0).value : editor.getValue()),
+			file_content: $(f).find('#file_content').get(0).value,
 			xd_check: $(f).find('input[name="xd_check"]').get(0).value,
 			write: 1
Index: plugins/userPref/_define.php
===================================================================
--- plugins/userPref/_define.php	(revision 967)
+++ plugins/userPref/_define.php	(revision 589)
@@ -16,5 +16,5 @@
 	/* Description*/		"Manage every user preference directive",
 	/* Author */			"Franck Paul",
-	/* Version */			'0.3'
+	/* Version */			'0.2'
 );
 ?>
Index: plugins/userPref/index.php
===================================================================
--- plugins/userPref/index.php	(revision 907)
+++ plugins/userPref/index.php	(revision 589)
@@ -117,9 +117,9 @@
 <?php
 if (!empty($_GET['upd'])) {
-	dcPage::message(__('Preferences successfully updated'));
+	echo '<p class="message">'.__('Preferences successfully updated').'</p>';
 }
 
 if (!empty($_GET['upda'])) {
-	dcPage::message(__('Preferences definition successfully updated'));
+	echo '<p class="message">'.__('Preferences definition successfully updated').'</p>';
 }
 ?>
Index: plugins/widgets/_default_widgets.php
===================================================================
--- plugins/widgets/_default_widgets.php	(revision 954)
+++ plugins/widgets/_default_widgets.php	(revision 665)
@@ -18,59 +18,40 @@
 $__widgets = new dcWidgets;
 
-$__widgets->create('search',__('Search engine'),array('defaultWidgets','search'),null,'Search engine form');
+$__widgets->create('search',__('Search engine'),array('defaultWidgets','search'));
 $__widgets->search->setting('title',__('Title:'),__('Search'));
-$__widgets->search->setting('homeonly',__('Display on:'),0,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->search->setting('class',__('CSS class:'),'');
 
-$__widgets->create('navigation',__('Navigation links'),array('defaultWidgets','navigation'),null,'List of navigation links');
+$__widgets->create('navigation',__('Navigation links'),array('defaultWidgets','navigation'));
 $__widgets->navigation->setting('title',__('Title:'),'');
-$__widgets->navigation->setting('homeonly',__('Display on:'),0,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->navigation->setting('class',__('CSS class:'),'');
 
-$__widgets->create('bestof',__('Selected entries'),array('defaultWidgets','bestof'),null,'List of selected entries');
+$__widgets->create('bestof',__('Selected entries'),array('defaultWidgets','bestof'));
 $__widgets->bestof->setting('title',__('Title:'),__('Best of me'));
 $__widgets->bestof->setting('orderby',__('Sort:'),'asc','combo',array(__('Ascending') => 'asc', __('Descending') => 'desc'));
-$__widgets->bestof->setting('homeonly',__('Display on:'),1,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->bestof->setting('class',__('CSS class:'),'');
+$__widgets->bestof->setting('homeonly',__('Home page only'),1,'check');
 
-$__widgets->create('langs',__('Blog languages'),array('defaultWidgets','langs'),null,'List of available languages');
+$__widgets->create('langs',__('Blog languages'),array('defaultWidgets','langs'));
 $__widgets->langs->setting('title',__('Title:'),__('Languages'));
-$__widgets->langs->setting('homeonly',__('Display on:'),1,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->langs->setting('class',__('CSS class:'),'');
+$__widgets->langs->setting('homeonly',__('Home page only'),1,'check');
 
-$__widgets->create('categories',__('Categories list'),array('defaultWidgets','categories'),null,'List of categories');
+$__widgets->create('categories',__('Categories list'),array('defaultWidgets','categories'));
 $__widgets->categories->setting('title',__('Title:'),__('Categories'));
 $__widgets->categories->setting('postcount',__('With entries counts'),0,'check');
-$__widgets->categories->setting('homeonly',__('Display on:'),0,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->categories->setting('class',__('CSS class:'),'');
 
-$__widgets->create('subscribe',__('Subscribe links'),array('defaultWidgets','subscribe'),null,'RSS or Atom feed subscription links');
+$__widgets->create('subscribe',__('Subscribe links'),array('defaultWidgets','subscribe'));
 $__widgets->subscribe->setting('title',__('Title:'),__('Subscribe'));
 $__widgets->subscribe->setting('type',__('Feeds type:'),'atom','combo',array('Atom' => 'atom', 'RSS' => 'rss2'));
-$__widgets->subscribe->setting('homeonly',__('Display on:'),1,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->subscribe->setting('class',__('CSS class:'),'');
+$__widgets->subscribe->setting('homeonly',__('Home page only'),0,'check');
 
-$__widgets->create('feed',__('Feed reader'),array('defaultWidgets','feed'),null,'Last entries from feed');
+$__widgets->create('feed',__('Feed reader'),array('defaultWidgets','feed'));
 $__widgets->feed->setting('title',__('Title:'),__('Somewhere else'));
 $__widgets->feed->setting('url',__('Feed URL:'),'');
 $__widgets->feed->setting('limit',__('Entries limit:'),10);
-$__widgets->feed->setting('homeonly',__('Display on:'),1,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->feed->setting('class',__('CSS class:'),'');
+$__widgets->feed->setting('homeonly',__('Home page only'),1,'check');
 
-$__widgets->create('text',__('Text'),array('defaultWidgets','text'),null,'Simple text');
+$__widgets->create('text',__('Text'),array('defaultWidgets','text'));
 $__widgets->text->setting('title',__('Title:'),'');
 $__widgets->text->setting('text',__('Text:'),'','textarea');
-$__widgets->text->setting('homeonly',__('Display on:'),0,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->text->setting('class',__('CSS class:'),'');
+$__widgets->text->setting('homeonly',__('Home page only'),0,'check');
 
-$__widgets->create('lastposts',__('Last entries'),array('defaultWidgets','lastposts'),null,'List of last entries published');
+$__widgets->create('lastposts',__('Last entries'),array('defaultWidgets','lastposts'));
 $__widgets->lastposts->setting('title',__('Title:'),__('Last entries'));
 $rs = $core->blog->getCategories(array('post_type'=>'post'));
@@ -85,14 +66,11 @@
 }
 $__widgets->lastposts->setting('limit',__('Entries limit:'),10);
-$__widgets->lastposts->setting('homeonly',__('Display on:'),1,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->lastposts->setting('class',__('CSS class:'),'');
+$__widgets->lastposts->setting('homeonly',__('Home page only'),1,'check');
 
-$__widgets->create('lastcomments',__('Last comments'),array('defaultWidgets','lastcomments'),null,'List of last comments posted');
+
+$__widgets->create('lastcomments',__('Last comments'),array('defaultWidgets','lastcomments'));
 $__widgets->lastcomments->setting('title',__('Title:'),__('Last comments'));
 $__widgets->lastcomments->setting('limit',__('Comments limit:'),10);
-$__widgets->lastcomments->setting('homeonly',__('Display on:'),1,'combo',
-	array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
-$__widgets->lastcomments->setting('class',__('CSS class:'),'');
+$__widgets->lastcomments->setting('homeonly',__('Home page only'),1,'check');
 
 # --BEHAVIOR-- initWidgets
Index: plugins/widgets/_define.php
===================================================================
--- plugins/widgets/_define.php	(revision 965)
+++ plugins/widgets/_define.php	(revision 665)
@@ -16,5 +16,5 @@
 	/* Description*/		"Widgets for your blog sidebars",
 	/* Author */			"Olivier Meunier & Dotclear Team",
-	/* Version */			'3.1',
+	/* Version */			'3',
 	array(
 		'permissions' =>	'admin',
Index: plugins/widgets/_public.php
===================================================================
--- plugins/widgets/_public.php	(revision 936)
+++ plugins/widgets/_public.php	(revision 671)
@@ -22,20 +22,13 @@
 	public static function tplWidgets($attr)
 	{
-		$type = isset($attr['type']) ? $attr['type'] : '';
-
+		$type = isset($attr['type']) ? $attr['type'] : 'nav';
+		
 		# widgets to disable
 		$disable = isset($attr['disable']) ? trim($attr['disable']) : '';
 		
-		if ($type == '') {
-			$res = "publicWidgets::widgetsHandler('nav','".addslashes($disable)."');"."\n".
-				"   publicWidgets::widgetsHandler('extra','".addslashes($disable)."');"."\n".
-				"   publicWidgets::widgetsHandler('custom','".addslashes($disable)."');"."\n";
-		} else {
-			if (!in_array($type, array('nav','extra','custom'))) {
-				$type = 'nav';
-			}
-			$res = "publicWidgets::widgetsHandler('".addslashes($type)."','".addslashes($disable)."');";
-		}
-		return '<?php '.$res.' ?>';
+		return
+		'<?php '.
+		"publicWidgets::widgetsHandler('".addslashes($type)."','".addslashes($disable)."'); ".
+		' ?>';
 	}
 	
Index: plugins/widgets/_widgets_functions.php
===================================================================
--- plugins/widgets/_widgets_functions.php	(revision 945)
+++ plugins/widgets/_widgets_functions.php	(revision 862)
@@ -18,13 +18,8 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
-			return;
-		}
-
 		$value = isset($GLOBALS['_search']) ? html::escapeHTML($GLOBALS['_search']) : '';
 		
 		return
-		'<div id="search"'.($w->class ? ' class="'.html::escapeHTML($w->class).'"' : '').'>'.
+		'<div id="search">'.
 		($w->title ? '<h2><label for="q">'.html::escapeHTML($w->title).'</label></h2>' : '').
 		'<form action="'.$core->blog->url.'" method="get">'.
@@ -41,11 +36,6 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
-			return;
-		}
-
-		$res =
-		'<div id="topnav"'.($w->class ? ' class="'.html::escapeHTML($w->class).'"' : '').'>'.
+		$res =
+		'<div id="topnav">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -72,9 +62,4 @@
 		global $core, $_ctx;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
-			return;
-		}
-
 		$rs = $core->blog->getCategories(array('post_type'=>'post'));
 		if ($rs->isEmpty()) {
@@ -83,5 +68,5 @@
 		
 		$res =
-		'<div class="categories'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="categories">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '');
 		
@@ -126,6 +111,5 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -144,5 +128,5 @@
 		
 		$res =
-		'<div class="selected'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="selected">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -161,6 +145,5 @@
 		global $core, $_ctx;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default' && $core->url->type != 'lang') ||
-			($w->homeonly == 2 && ($core->url->type == 'default' || $core->url->type == 'lang'))) {
+		if ($w->homeonly && $core->url->type != 'default' && $core->url->type != 'lang') {
 			return;
 		}
@@ -174,5 +157,5 @@
 		$langs = l10n::getISOcodes();
 		$res =
-		'<div class="langs'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="langs">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -202,6 +185,5 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -214,5 +196,5 @@
 		
 		$res =
-		'<div class="syndicate'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="syndicate">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -246,6 +228,5 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -263,5 +244,5 @@
 		
 		$res =
-		'<div class="feed'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="feed">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -297,11 +278,10 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
-			return;
-		}
-		
-		$res =
-		'<div class="text'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		if ($w->homeonly && $core->url->type != 'default') {
+			return;
+		}
+		
+		$res =
+		'<div class="text">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		$w->text.
@@ -315,6 +295,5 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -350,5 +329,5 @@
 		
 		$res =
-		'<div class="lastposts'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		'<div class="lastposts">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
@@ -368,6 +347,5 @@
 		global $core;
 		
-		if (($w->homeonly == 1 && $core->url->type != 'default') ||
-			($w->homeonly == 2 && $core->url->type == 'default')) {
+		if ($w->homeonly && $core->url->type != 'default') {
 			return;
 		}
@@ -381,5 +359,5 @@
 		}
 		
-		$res = '<div class="lastcomments'.($w->class ? ' '.html::escapeHTML($w->class) : '').'">'.
+		$res = '<div class="lastcomments">'.
 		($w->title ? '<h2>'.html::escapeHTML($w->title).'</h2>' : '').
 		'<ul>';
Index: plugins/widgets/class.widgets.php
===================================================================
--- plugins/widgets/class.widgets.php	(revision 954)
+++ plugins/widgets/class.widgets.php	(revision 270)
@@ -36,7 +36,7 @@
 	}
 	
-	public function create($id,$name,$callback,$append_callback=null,$desc='')
-	{
-		$this->__widgets[$id] = new dcWidget($id,$name,$callback,$desc);
+	public function create($id,$name,$callback,$append_callback=null)
+	{
+		$this->__widgets[$id] = new dcWidget($id,$name,$callback);
 		$this->__widgets[$id]->append_callback = $append_callback;
 	}
@@ -135,5 +135,4 @@
 	private $id;
 	private $name;
-	private $desc;
 	private $public_callback = null;
 	public $append_callback = null;
@@ -149,10 +148,9 @@
 	}
 	
-	public function __construct($id,$name,$callback,$desc='')
+	public function __construct($id,$name,$callback)
 	{
 		$this->public_callback = $callback;
 		$this->id = $id;
 		$this->name = $name;
-		$this->desc = $desc;
 	}
 	
@@ -165,9 +163,4 @@
 	{
 		return $this->name;
-	}
-
-	public function desc()
-	{
-		return $this->desc;
 	}
 	
Index: plugins/widgets/index.php
===================================================================
--- plugins/widgets/index.php	(revision 954)
+++ plugins/widgets/index.php	(revision 735)
@@ -34,12 +34,4 @@
 	__('custom') => 'custom'
 );
-
-function literalNullString($v)
-{
-	if ($v == '') {
-		return '&lt;'.__('empty string').'&gt;';
-	}
-	return $v;
-}
 
 # Adding widgets to sidebars
@@ -201,5 +193,5 @@
 	'<div>'.form::hidden(array('w[void][0][id]'),html::escapeHTML($w->id())).
 	'<p class="widget-name">'.form::field(array('w[void][0][order]'),2,3,0,'hideControl').' '.
-	$w->name().($w->desc() != '' ? ' <span class="form-note">('.__($w->desc()).')</span>' : '').'</p>'.
+	$w->name().'</p>'.
 	'<p class="js-remove"><label class="classic">'.__('Append to:').' '.
 	form::combo(array('addw['.$w->id().']'),$append_combo).'</label></p>'.
@@ -267,6 +259,5 @@
 	$widget_elements->content .=
 	'<dt><strong>'.html::escapeHTML($w->name()).'</strong> ('.
-	__('Widget ID:').' <strong>'.html::escapeHTML($w->id()).'</strong>)'.
-	($w->desc() != '' ? ' <span class="form-note">'.__($w->desc()).'</span>' : '').'</dt>'.
+	__('Widget ID:').' <strong>'.html::escapeHTML($w->id()).'</strong>)</dt>'.
 	'<dd>';
 	
@@ -283,14 +274,13 @@
 			switch ($s['type']) {
 				case 'check':
-					$s_type = __('boolean').", ".__('possible values:')." <code>0</code> ".__('or')." <code>1</code>";
+					$s_type = '0|1';
 					break;
 				case 'combo':
-					$s['options'] = array_map("literalNullString", $s['options']);
-					$s_type = __('listitem').", ".__('possible values:')." <code>".implode('</code>, <code>',$s['options'])."</code>";
+					$s_type = implode('|',$s['options']);
 					break;
 				case 'text':
 				case 'textarea':
 				default:
-					$s_type = __('string');
+					$s_type = 'text';
 					break;
 			}
@@ -331,9 +321,9 @@
 		'<div>'.form::hidden(array($iname.'[id]'),html::escapeHTML($w->id())).
 		'<p class="widget-name">'.form::field(array($iname.'[order]'),2,3,(string) $i,'js-hide','',0,'title="'.__('order').'"').' '.
-		$w->name().($w->desc() != '' ? ' <span class="form-note">('.__($w->desc()).')</span>' : '').'</p>'.
+		$w->name().'</p>'.
 		'<p class="removeWidget js-remove"><label class="classic">'.
 		form::checkbox(array($iname.'[_rem]'),'1',0).' '.__('Remove widget').
 		'</label></p>'.
-		'<div class="widgetSettings">'.$w->formSettings($iname,$j).'</div>'.
+		'<div class="widgetSettings">'.$w->formSettings($iname,&$j).'</div>'.
 		'</div>';
 		
