Index: /extensions/EasyCaptcha/admin.php
===================================================================
--- /extensions/EasyCaptcha/admin.php	(revision 26024)
+++ /extensions/EasyCaptcha/admin.php	(revision 26025)
@@ -20,5 +20,5 @@
 
   $conf['EasyCaptcha'] = array(
-    'activate_on'     => array(
+    'activate_on' => array(
       'picture'     => in_array('picture', $_POST['activate_on']),
       'category'    => in_array('category', $_POST['activate_on']) || !$loaded['category'],
@@ -49,8 +49,9 @@
       'sel'   => check_color($_POST['tictac']['sel']),
       ),
+    'lastmod' => time(),
     );
 
   conf_update_param('EasyCaptcha', serialize($conf['EasyCaptcha']));
-  array_push($page['infos'], l10n('Information data registered in database'));
+  $page['infos'][] = l10n('Information data registered in database');
 }
 
@@ -63,5 +64,7 @@
   while (($item = readdir($dh)) !== false )
   {
-    if ($item!=='.' && $item!=='..' && is_dir($dir.'/'.$item) && file_exists($dir.'/'.$item.'/conf.inc.php'))
+    if ($item!=='.' && $item!=='..' &&
+        is_dir($dir.'/'.$item) && file_exists($dir.'/'.$item.'/conf.inc.php')
+      )
     {
       $drag_images = include($dir.'/'.$item.'/conf.inc.php');
@@ -80,10 +83,11 @@
   'easycaptcha' => $conf['EasyCaptcha'],
   'loaded' => $loaded,
-  'THEMES' => list_themes(EASYCAPTCHA_PATH.'drag'),
+  'THEMES' => list_themes(EASYCAPTCHA_PATH . 'drag'),
   'EASYCAPTCHA_PATH' => EASYCAPTCHA_PATH,
-  'EASYCAPTCHA_ABS_PATH' => realpath(EASYCAPTCHA_PATH).'/',
+  'EASYCAPTCHA_ABS_PATH' => realpath(EASYCAPTCHA_PATH) . '/',
+  'DRAG_CSS' => file_get_contents(EASYCAPTCHA_PATH . 'template/drag.css'),
   ));
 
-$template->set_filename('plugin_admin_content', realpath(EASYCAPTCHA_PATH.'template/admin.tpl'));
+$template->set_filename('plugin_admin_content', realpath(EASYCAPTCHA_PATH . 'template/admin.tpl'));
 $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
 
@@ -101,5 +105,5 @@
   else if (strlen($hex) != 6)
   {
-    $page['errors'][] = sprintf(l10n('Invalid color code <i>%s</i>'), '#'.$hex);
+    $page['errors'][] = l10n('Invalid color code <i>%s</i>', '#'.$hex);
     $hex = '000000';
   }
Index: /extensions/EasyCaptcha/include/category.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/category.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/include/category.inc.php	(revision 26025)
@@ -15,5 +15,5 @@
 {
   $search = '{$comment_add.CONTENT}</textarea></p>';
-  return str_replace($search, $search."\n{\$EASYCAPTCHA}", $content);
+  return str_replace($search, $search."\n{\$EASYCAPTCHA_CONTENT}", $content);
 }
 
Index: /extensions/EasyCaptcha/include/common.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/common.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/include/common.inc.php	(revision 26025)
@@ -28,13 +28,10 @@
   $conf['EasyCaptcha']['drag']['selected'] = array_rand($conf['EasyCaptcha']['drag']['selection']);
   $conf['EasyCaptcha']['drag']['text']     = l10n($drag_images[ $conf['EasyCaptcha']['drag']['selected'] ]);
-  $conf['EasyCaptcha']['drag']['key']      = $conf['EasyCaptcha']['challenge'] .'-'. pwg_password_hash($conf['secret_key'] . $conf['EasyCaptcha']['drag']['selected']);
-
-  $template->assign('EASYCAPTCHA_CONF', $conf['EasyCaptcha']['drag']);
+  $conf['EasyCaptcha']['key']      = $conf['EasyCaptcha']['challenge'] .'-'. pwg_password_hash($conf['secret_key'] . $conf['EasyCaptcha']['drag']['selected']);
 }
 // Tic-tac-toe
 else if ($conf['EasyCaptcha']['challenge'] == 'tictac')
 {
-  $conf['EasyCaptcha']['tictac']['key'] = $conf['EasyCaptcha']['challenge'] .'-0';
-  $template->assign('EASYCAPTCHA_CONF', $conf['EasyCaptcha']['tictac']);
+  $conf['EasyCaptcha']['key'] = $conf['EasyCaptcha']['challenge'] .'-0';
 }
 else
@@ -46,5 +43,5 @@
 
 $template->assign(array(
-  'EASYCAPTCHA_CHALLENGE' => $conf['EasyCaptcha']['challenge'],
+  'EASYCAPTCHA' => $conf['EasyCaptcha'],
   'EASYCAPTCHA_PATH' => EASYCAPTCHA_PATH,
   'EASYCAPTCHA_ABS_PATH' => realpath(EASYCAPTCHA_PATH).'/',
@@ -52,5 +49,5 @@
 
 $template->set_filename('EasyCaptcha', realpath(EASYCAPTCHA_PATH.'template/'.$conf['EasyCaptcha']['template'].'.tpl'));
-$template->assign_var_from_handle('EASYCAPTCHA', 'EasyCaptcha');
+$template->assign_var_from_handle('EASYCAPTCHA_CONTENT', 'EasyCaptcha');
 
 
Index: /extensions/EasyCaptcha/include/contactform.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/contactform.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/include/contactform.inc.php	(revision 26025)
@@ -15,5 +15,5 @@
 {
   $search = '{$contact.content}</textarea></td>';
-  return str_replace($search, $search."\n{\$EASYCAPTCHA}", $content);
+  return str_replace($search, $search."\n{\$EASYCAPTCHA_CONTENT}", $content);
 }
 
Index: /extensions/EasyCaptcha/include/guestbook.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/guestbook.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/include/guestbook.inc.php	(revision 26025)
@@ -15,5 +15,5 @@
 {
   $search = '#{\$comment_add\.CONTENT}</textarea>(\s*)</td>(\s*)</tr>#';
-  $replace = '{\$comment_add.CONTENT}</textarea>$1</td>$2</tr>'."\n".'{\$EASYCAPTCHA}';
+  $replace = '{\$comment_add.CONTENT}</textarea>$1</td>$2</tr>'."\n".'{\$EASYCAPTCHA_CONTENT}';
   return preg_replace($search, $replace, $content);
 }
Index: tensions/EasyCaptcha/include/install.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/install.inc.php	(revision 26024)
+++ 	(revision )
@@ -1,45 +1,0 @@
-<?php
-defined('EASYCAPTCHA_ID') or die('Hacking attempt!');
-
-function easycaptcha_install()
-{
-  global $conf;
-
-  if (empty($conf['EasyCaptcha']))
-  {
-    $easycaptcha_default_config = array(
-      'activate_on' => array(
-        'picture'     => true,
-        'category'    => true,
-        'register'    => true,
-        'contactform' => true,
-        'guestbook'   => true,
-        ),
-      'comments_action' => 'reject',
-      'challenge' => 'random',
-      'drag' => array(
-        'theme' => 'icons',
-        'size'  => 50,
-        'nb'    => 5,
-        'bg1'   => '#F7F7F7',
-        'bg2'   => '#E5E5E5',
-        'obj'   => '#FFFFFF',
-        'sel'   => '#C8FF96',
-        'bd1'   => '#DDDDDD',
-        'bd2'   => '#555555',
-        'txt'   => '#222222',
-        ),
-      'tictac' => array(
-        'size'  => 128,
-        'bg1'   => '#F7F7F7',
-        'bg2'   => '#E5E5E5',
-        'bd'    => '#DDDDDD',
-        'obj'   => '#00B4F7',
-        'sel'   => '#F7B400',
-        ),
-      );
-
-    $conf['EasyCaptcha'] = serialize($easycaptcha_default_config);
-    conf_update_param('EasyCaptcha', $conf['EasyCaptcha']);
-  }
-}
Index: /extensions/EasyCaptcha/include/picture.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/picture.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/include/picture.inc.php	(revision 26025)
@@ -15,5 +15,5 @@
 {
   $search = '{$comment_add.CONTENT}</textarea></p>';
-  return str_replace($search, $search."\n{\$EASYCAPTCHA}", $content);
+  return str_replace($search, $search."\n{\$EASYCAPTCHA_CONTENT}", $content);
 }
 
Index: /extensions/EasyCaptcha/include/register.inc.php
===================================================================
--- /extensions/EasyCaptcha/include/register.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/include/register.inc.php	(revision 26025)
@@ -15,5 +15,5 @@
 {
   $search = '<input type="checkbox" name="send_password_by_mail" id="send_password_by_mail" value="1" checked="checked">';
-  return str_replace($search, $search."\n{\$EASYCAPTCHA}", $content);
+  return str_replace($search, $search."\n{\$EASYCAPTCHA_CONTENT}", $content);
 }
 
Index: /extensions/EasyCaptcha/language/en_UK/plugin.lang.php
===================================================================
--- /extensions/EasyCaptcha/language/en_UK/plugin.lang.php	(revision 26024)
+++ /extensions/EasyCaptcha/language/en_UK/plugin.lang.php	(revision 26025)
@@ -35,3 +35,4 @@
 $lang['This challenge requires that JavaScript is enabled on the visitor browser. About 1% of Internet users have Javascript disabled.'] = 'This challenge requires that JavaScript is enabled in the visitor\'s browser. About 1% of Internet users have JavaScript disabled.';
 $lang['We detected that Crypto Captcha plugin is available on your gallery. Both plugins can be used at the same time, but you should not under any circumstances activate both of them on the same page.'] = 'We detected that Crypto Captcha plugin is available in your gallery. Both plugins can be used at the same time, but you should not under any circumstances activate both of them on the same page.';
+$lang['Nowhere'] = 'Nowhere';
 ?>
Index: /extensions/EasyCaptcha/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/EasyCaptcha/language/fr_FR/plugin.lang.php	(revision 26024)
+++ /extensions/EasyCaptcha/language/fr_FR/plugin.lang.php	(revision 26025)
@@ -35,3 +35,4 @@
 $lang['This challenge requires that JavaScript is enabled on the visitor browser. About 1% of Internet users have Javascript disabled.'] = 'Ce test requiert que JavaScript soit activé sur le navigateur du visiteur. Environ 1% des utilisateurs d\'Internet ont JavaScript désactivé.';
 $lang['We detected that Crypto Captcha plugin is available on your gallery. Both plugins can be used at the same time, but you should not under any circumstances activate both of them on the same page.'] = 'Nous avons détecté que Crypto Captcha est activé sur votre galerie. Les deux plugins peuvent fonctionner en même temps, mais sous aucun prétexte ils ne doivent être activés sur les mêmes pages.';
+$lang['Nowhere'] = 'Nulle part';
 ?>
Index: /extensions/EasyCaptcha/main.inc.php
===================================================================
--- /extensions/EasyCaptcha/main.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/main.inc.php	(revision 26025)
@@ -11,5 +11,5 @@
 defined('PHPWG_ROOT_PATH') or die('Hacking attempt!');
 
-// TODO : test on mobile
+// TODO : captcha on mobile
 if (mobile_theme())
 {
@@ -17,7 +17,7 @@
 }
 
-defined('EASYCAPTCHA_ID') or define('EASYCAPTCHA_ID', basename(dirname(__FILE__)));
-define('EASYCAPTCHA_PATH' , PHPWG_PLUGINS_PATH . EASYCAPTCHA_ID . '/');
-define('EASYCAPTCHA_ADMIN', get_root_url() . 'admin.php?page=plugin-' . EASYCAPTCHA_ID);
+define('EASYCAPTCHA_ID',      basename(dirname(__FILE__)));
+define('EASYCAPTCHA_PATH' ,   PHPWG_PLUGINS_PATH . EASYCAPTCHA_ID . '/');
+define('EASYCAPTCHA_ADMIN',   get_root_url() . 'admin.php?page=plugin-' . EASYCAPTCHA_ID);
 define('EASYCAPTCHA_VERSION', 'auto');
 
@@ -40,24 +40,7 @@
   global $conf, $pwg_loaded_plugins;
 
-  if (
-    EASYCAPTCHA_VERSION == 'auto' or
-    $pwg_loaded_plugins[EASYCAPTCHA_ID]['version'] == 'auto' or
-    version_compare($pwg_loaded_plugins[EASYCAPTCHA_ID]['version'], EASYCAPTCHA_VERSION, '<')
-  )
-  {
-    include_once(EASYCAPTCHA_PATH . 'include/install.inc.php');
-    easycaptcha_install();
-
-    if ( $pwg_loaded_plugins[EASYCAPTCHA_ID]['version'] != 'auto' && EASYCAPTCHA_VERSION != 'auto' )
-    {
-      $query = '
-UPDATE '. PLUGINS_TABLE .'
-SET version = "'. EASYCAPTCHA_VERSION .'"
-WHERE id = "'. EASYCAPTCHA_ID .'"';
-      pwg_query($query);
-
-      $pwg_loaded_plugins[EASYCAPTCHA_ID]['version'] = EASYCAPTCHA_VERSION;
-    }
-  }
+  include_once(EASYCAPTCHA_PATH . 'maintain.inc.php');
+  $maintain = new EasyCaptcha_maintain(EASYCAPTCHA_ID);
+  $maintain->autoUpdate(EASYCAPTCHA_VERSION, 'install');
 
   load_language('plugin.lang', EASYCAPTCHA_PATH);
@@ -71,12 +54,15 @@
   global $conf, $pwg_loaded_plugins, $page;
 
-  if (!is_a_guest()) return;
+  if (!is_a_guest())
+  {
+    return;
+  }
 
-  if ( script_basename() == 'register' && $conf['EasyCaptcha']['activate_on']['register'] )
+  if (script_basename() == 'register' && $conf['EasyCaptcha']['activate_on']['register'])
   {
     $conf['EasyCaptcha']['template'] = 'register';
     include(EASYCAPTCHA_PATH . 'include/register.inc.php');
   }
-  else if ( script_basename() == 'picture' && $conf['EasyCaptcha']['activate_on']['picture'] )
+  else if (script_basename() == 'picture' && $conf['EasyCaptcha']['activate_on']['picture'])
   {
     $conf['EasyCaptcha']['template'] = 'comment';
@@ -95,10 +81,10 @@
       include(EASYCAPTCHA_PATH . 'include/category.inc.php');
     }
-    else if ( $page['section'] == 'contact' && $conf['EasyCaptcha']['activate_on']['contactform'] )
+    else if ($page['section'] == 'contact' && $conf['EasyCaptcha']['activate_on']['contactform'])
     {
       $conf['EasyCaptcha']['template'] = 'contactform';
       include(EASYCAPTCHA_PATH . 'include/contactform.inc.php');
     }
-    else if ( $page['section'] == 'guestbook' && $conf['EasyCaptcha']['activate_on']['guestbook'] )
+    else if ($page['section'] == 'guestbook' && $conf['EasyCaptcha']['activate_on']['guestbook'])
     {
       $conf['EasyCaptcha']['template'] = 'guestbook';
@@ -112,8 +98,8 @@
 function easycaptcha_plugin_admin_menu($menu)
 {
-  array_push($menu, array(
+  $menu[] = array(
     'NAME' => 'Easy Captcha',
     'URL' => EASYCAPTCHA_ADMIN,
-    ));
+    );
   return $menu;
 }
Index: /extensions/EasyCaptcha/maintain.inc.php
===================================================================
--- /extensions/EasyCaptcha/maintain.inc.php	(revision 26024)
+++ /extensions/EasyCaptcha/maintain.inc.php	(revision 26025)
@@ -2,23 +2,81 @@
 defined('PHPWG_ROOT_PATH') or die('Hacking attempt!');
 
-defined('EASYCAPTCHA_ID') or define('EASYCAPTCHA_ID', basename(dirname(__FILE__)));
-include_once(PHPWG_PLUGINS_PATH . EASYCAPTCHA_ID . '/include/install.inc.php');
+class EasyCaptcha_maintain extends PluginMaintain
+{
+  private $installed = false;
 
-function plugin_install()
-{
-  easycaptcha_install();
-  define('easycaptcha_installed', true);
-}
+  function install($plugin_version, &$errors=array())
+  {
+    global $conf;
 
-function plugin_activate()
-{
-  if (!defined('easycaptcha_installed'))
+    if (empty($conf['EasyCaptcha']))
+    {
+      $default_config = array(
+        'activate_on' => array(
+          'picture'     => true,
+          'category'    => true,
+          'register'    => true,
+          'contactform' => true,
+          'guestbook'   => true,
+          ),
+        'comments_action' => 'reject',
+        'challenge' => 'random',
+        'drag' => array(
+          'theme' => 'icons',
+          'size'  => 50,
+          'nb'    => 5,
+          'bg1'   => '#F7F7F7',
+          'bg2'   => '#E5E5E5',
+          'obj'   => '#FFFFFF',
+          'sel'   => '#C8FF96',
+          'bd1'   => '#DDDDDD',
+          'bd2'   => '#555555',
+          'txt'   => '#222222',
+          ),
+        'tictac' => array(
+          'size'  => 128,
+          'bg1'   => '#F7F7F7',
+          'bg2'   => '#E5E5E5',
+          'bd'    => '#DDDDDD',
+          'obj'   => '#00B4F7',
+          'sel'   => '#F7B400',
+          ),
+        'lastmod' => time(),
+        );
+
+      $conf['EasyCaptcha'] = serialize($default_config);
+      conf_update_param('EasyCaptcha', $conf['EasyCaptcha']);
+    }
+    else
+    {
+      $old_conf = is_string($conf['EasyCaptcha']) ? unserialize($conf['EasyCaptcha']) : $conf['EasyCaptcha'];
+
+      if (empty($old_conf['lastmod']))
+      {
+        $old_conf['lastmod'] = time();
+      }
+
+      $conf['EasyCaptcha'] = serialize($old_conf);
+      conf_update_param('EasyCaptcha', $conf['EasyCaptcha']);
+    }
+
+    $this->installed = true;
+  }
+
+  function activate($plugin_version, &$errors=array())
   {
-    easycaptcha_install();
+    if (!$this->installed)
+    {
+      $this->install($plugin_version, $errors);
+    }
+  }
+
+  function deactivate()
+  {
+  }
+
+  function uninstall()
+  {
+    conf_delete_param('EasyCaptcha');
   }
 }
-
-function plugin_uninstall()
-{
-  pwg_query('DELETE FROM '.CONFIG_TABLE.' WHERE param="EasyCaptcha" LIMIT 1');
-}
Index: /extensions/EasyCaptcha/template/admin.tpl
===================================================================
--- /extensions/EasyCaptcha/template/admin.tpl	(revision 26024)
+++ /extensions/EasyCaptcha/template/admin.tpl	(revision 26025)
@@ -1,5 +1,5 @@
-{combine_css path=$EASYCAPTCHA_PATH|@cat:"template/style.css"}
-
-{combine_css path="themes/default/js/plugins/chosen.css"}
+{combine_css path=$EASYCAPTCHA_PATH|cat:'template/style.css'}
+
+{combine_css path='themes/default/js/plugins/chosen.css'}
 {combine_script id='jquery.chosen' load='footer' path='themes/default/js/plugins/chosen.jquery.min.js'}
 
@@ -8,15 +8,16 @@
 
 {assign var="spectrum_language" value=$EASYCAPTCHA_PATH|cat:'template/bgrins-spectrum/i18n/jquery.spectrum-'|cat:$lang_info.code|cat:'.js'}
-{if 'PHPWG_ROOT_PATH'|@constant|@cat:$spectrum_language|file_exists}
+{if 'PHPWG_ROOT_PATH'|constant|cat:$spectrum_language|file_exists}
 {combine_script id='jquery.spectrum.'|cat:$lang_info.code load='footer' require='jquery.spectrum' path=$spectrum_language}
 {/if}
 
 
-{footer_script}{literal}
+{footer_script}
 // multiselect
 $("select").css({
-    "width":"700px"
+    width: 300
 }).chosen({
     disable_search:true,
+    placeholder_text_multiple: '{'Nowhere'|translate}'
 });
 
@@ -33,5 +34,5 @@
 $('.preview-tictac').on('change', function() {
     var inputs = ['size','bg1','bg2','bd','obj','sel'],
-        url = '{/literal}{$EASYCAPTCHA_PATH}{literal}' + 'tictac/gen_admin.php?t='+ new Date().getTime();
+        url = '{$EASYCAPTCHA_PATH}' + 'tictac/gen_admin.php?t='+ new Date().getTime();
 
     for (var i=0; i<inputs.length; i++) {
@@ -44,11 +45,9 @@
 
 // Drag & drop preview
-{/literal}
-var themes = {ldelim}
+var themes = {
 {foreach from=$THEMES key=theme item=params}
   '{$theme}': '{$EASYCAPTCHA_PATH}drag/{$theme}/{$params.image}',
 {/foreach}
 };
-{literal}
 
 $('.preview-drag').on('change', function() {
@@ -59,5 +58,5 @@
 
     for (var i=0; i<inputs.length; i++) {
-        search = '{\\$EASYCAPTCHA_CONF\\.'+ inputs[i] +'}';
+        search = '{ldelim}\\$EASYCAPTCHA.drag\\.'+ inputs[i] +'}';
         replace = $('input[name="drag['+ inputs[i] +']"]').val();
         style = style.replace(new RegExp(search, 'g'), replace);
@@ -67,7 +66,7 @@
         y = parseInt($('input[name="drag[nb]"]').val());
 
-    search = '{dat_equation}',
+    search = '{ldelim}math equation=\'15+(x+5)*y\' x=$EASYCAPTCHA.drag.size y=$EASYCAPTCHA.drag.nb}',
     replace = 15+(x+5)*y;
-    style = style.replace(new RegExp(search, 'g'), replace);
+    style = style.replace(search, replace);
 
     $('#drag_style').text(style);
@@ -107,5 +106,5 @@
     $(this).nextAll('.preview').slideDown();
 });
-{/literal}{/footer_script}
+{/footer_script}
 
 
@@ -233,5 +232,6 @@
         <a class="buttonLike">{'Preview'|translate}</a>
         <div class="preview">
-          {include file=$EASYCAPTCHA_ABS_PATH|cat:'template/common.inc.tpl' EASYCAPTCHA_CHALLENGE='drag' EASYCAPTCHA_CONF=$easycaptcha.drag}
+          {$easycaptcha.challenge = 'drag'}
+          {include file=$EASYCAPTCHA_ABS_PATH|cat:'template/common.inc.tpl' EASYCAPTCHA=$easycaptcha}
           {$smarty.capture.easycaptcha}
         </div>
@@ -251,53 +251,14 @@
     [<a href="https://www.iconfinder.com/iconsets/ie_Bright" class="externalLink">#4</a>]
   | Libraries
-    [<a href="http://bgrins.github.io/spectrum"class="externalLink">Spectrum.js</a>]
-    [<a href="http://threedubmedia.com"class="externalLink">jQuery.events</a>]
+    [<a href="http://bgrins.github.io/spectrum" class="externalLink">Spectrum.js</a>]
+    [<a href="http://threedubmedia.com" class="externalLink">jQuery.events</a>]
 </div>
 
 
 {* <!-- weird thing to update bunch of CSS --> *}
-{html_head}{literal}
+{html_head}
 <style id="drag_style"></style>
 <script type="text/template" id="drag_style_src">
-#easycaptcha, #easycaptcha_noscript {
-  background: {$EASYCAPTCHA_CONF.bg1};
-  background: -webkit-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -moz-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -ms-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -o-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: linear-gradient(to bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  color:{$EASYCAPTCHA_CONF.txt};
-}
-#easycaptcha .drag_item {
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-  border:1px solid {$EASYCAPTCHA_CONF.bd1};
-  background:{$EASYCAPTCHA_CONF.obj};
-}
-#easycaptcha .drag_item img {
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-}
-#easycaptcha .drop_zone {
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-  margin-left:{dat_equation}px;
-  line-height:{$EASYCAPTCHA_CONF.size}px;
-  background: {$EASYCAPTCHA_CONF.bg1};
-  background: -webkit-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -moz-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -ms-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -o-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: linear-gradient(to top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  border:1px dotted {$EASYCAPTCHA_CONF.bd2};
-  color:{$EASYCAPTCHA_CONF.txt};
-}
-#easycaptcha .drop_zone.active {
-  background:{$EASYCAPTCHA_CONF.sel};
-}
-#easycaptcha .drop_zone.valid {
-  background:{$EASYCAPTCHA_CONF.sel};
-  box-shadow:0 0 0 2px {$EASYCAPTCHA_CONF.sel};
-}
+{$DRAG_CSS}
 </script>
-{/literal}{/html_head}
+{/html_head}
Index: /extensions/EasyCaptcha/template/comment.tpl
===================================================================
--- /extensions/EasyCaptcha/template/comment.tpl	(revision 26024)
+++ /extensions/EasyCaptcha/template/comment.tpl	(revision 26025)
@@ -2,9 +2,9 @@
 
 {* <!-- DRAG & DROP --> *}
-{if $EASYCAPTCHA_CHALLENGE == 'drag'}
-<p><label>{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate|sprintf:$EASYCAPTCHA_CONF.text}</label></p>
+{if $EASYCAPTCHA.challenge == 'drag'}
+<p><label>{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate:$EASYCAPTCHA.drag.text}</label></p>
 
 {* <!-- TIC TAC TOE --> *}
-{else if $EASYCAPTCHA_CHALLENGE == 'tictac'}
+{else if $EASYCAPTCHA.challenge == 'tictac'}
 <p><label>{'You are player X, click on the right case to complete the line.'|translate}</label></p>
 
Index: /extensions/EasyCaptcha/template/common.inc.tpl
===================================================================
--- /extensions/EasyCaptcha/template/common.inc.tpl	(revision 26024)
+++ /extensions/EasyCaptcha/template/common.inc.tpl	(revision 26025)
@@ -1,71 +1,9 @@
 {* <!-- DRAG & DROP --> *}
-{if $EASYCAPTCHA_CHALLENGE == 'drag'}
+{if $EASYCAPTCHA.challenge == 'drag'}
 {combine_script id='jquery.event.drag' load='footer' require='jquery' path=$EASYCAPTCHA_PATH|cat:'template/jquery.events/jquery.event.drag-2.2.js'}
 {combine_script id='jquery.event.drop' load='footer' require='jquery' path=$EASYCAPTCHA_PATH|cat:'template/jquery.events/jquery.event.drop-2.2.js'}
 
 {combine_script id='easycaptcha.drag' load='footer' require='jquery.event.drag,jquery.event.drop' path=$EASYCAPTCHA_PATH|cat:'template/drag.js'}
-
-{html_style}
-#easycaptcha, #easycaptcha_noscript {ldelim}
-  display:inline-block;
-  position:relative;
-  padding:10px;
-  border-radius:8px;
-  background: {$EASYCAPTCHA_CONF.bg1};
-  background: -webkit-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -moz-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -ms-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -o-linear-gradient(top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: linear-gradient(to bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  color:{$EASYCAPTCHA_CONF.txt};
-}
-#easycaptcha .drag_item {ldelim}
-  position:absolute;
-  top:15px;
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-  border-radius:5px;
-  border:1px solid {$EASYCAPTCHA_CONF.bd1};
-  background:{$EASYCAPTCHA_CONF.obj};
-  z-index:10;
-  cursor:move;
-}
-#easycaptcha .drag_item.active {ldelim}
-  z-index:100;
-  opacity:0.75;
-}
-#easycaptcha .drag_item img {ldelim}
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-  border-radius:5px;
-}
-#easycaptcha .drop_zone {ldelim}
-  -moz-box-sizing:borderbox;
-  box-sizing:borderbox;
-  padding:5px;
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-  margin-left:{math equation='15+(x+5)*y' x=$EASYCAPTCHA_CONF.size y=$EASYCAPTCHA_CONF.nb}px;
-  line-height:{$EASYCAPTCHA_CONF.size}px;
-  background: {$EASYCAPTCHA_CONF.bg1};
-  background: -webkit-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -moz-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -ms-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: -o-linear-gradient(bottom, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  background: linear-gradient(to top, {$EASYCAPTCHA_CONF.bg1} 0%, {$EASYCAPTCHA_CONF.bg2} 100%);
-  border:1px dotted {$EASYCAPTCHA_CONF.bd2};
-  border-radius:5px;
-  text-align:center;
-  text-transform:uppercase;
-  color:{$EASYCAPTCHA_CONF.txt};
-}
-#easycaptcha .drop_zone.active {ldelim}
-  background:{$EASYCAPTCHA_CONF.sel};
-}
-#easycaptcha .drop_zone.valid {ldelim}
-  background:{$EASYCAPTCHA_CONF.sel};
-  box-shadow:0 0 0 2px {$EASYCAPTCHA_CONF.sel};
-}
-{/html_style}
+{combine_css id='easycaptcha.drag' path=$EASYCAPTCHA_PATH|cat:'template/drag.css' template=true version=$EASYCAPTCHA.lastmod}
 
 {capture name=easycaptcha}
@@ -76,7 +14,7 @@
 <div id="easycaptcha" style="display:none;">
 {counter start=0 assign=i}
-{foreach from=$EASYCAPTCHA_CONF.selection item=image}
-  <div class="drag_item" style="left:{math equation='10+(x+5)*y' x=$EASYCAPTCHA_CONF.size y=$i}px;" data-id="{$image}">
-    <img src="{$ROOT_URL}{$EASYCAPTCHA_PATH}drag/get.php?{$EASYCAPTCHA_CONF.theme}&amp;{$image}">
+{foreach from=$EASYCAPTCHA.drag.selection item=image}
+  <div class="drag_item" style="left:{math equation='10+(x+5)*y' x=$EASYCAPTCHA.drag.size y=$i}px;" data-id="{$image}">
+    <img src="{$ROOT_URL}{$EASYCAPTCHA_PATH}drag/get.php?{$EASYCAPTCHA.drag.theme}&amp;{$image}">
   </div>
   {counter}
@@ -87,38 +25,13 @@
 {* <!-- fields are not type "hidden" for LiveValidation in GuestBook and ContactForm --> *}
 <input type="text" name="easycaptcha" value="" style="display:none;">
-<input type="text" name="easycaptcha_key" value="{$EASYCAPTCHA_CONF.key}" style="display:none;">
+<input type="text" name="easycaptcha_key" value="{$EASYCAPTCHA.key}" style="display:none;">
 {/capture}
 
 
 {* <!-- TIC TAC TOE --> *}
-{else if $EASYCAPTCHA_CHALLENGE == 'tictac'}
-{html_style}
-#easycaptcha table {ldelim}
-  width:{$EASYCAPTCHA_CONF.size}px;
-  height:{$EASYCAPTCHA_CONF.size}px;
-  border-collapse:collapse;
-  display:inline-block;
-  margin:0;
-  background:url('{$ROOT_URL}{$EASYCAPTCHA_PATH}tictac/gen.php?t={$smarty.now}') no-repeat;
-}
-#easycaptcha td {ldelim}
-  border:none;
-  padding:0;
-}
-#easycaptcha label {ldelim}
-  display:block;
-  width:{math equation="floor(x/3)" x=$EASYCAPTCHA_CONF.size}px;
-  height:{math equation="floor(x/3)" x=$EASYCAPTCHA_CONF.size}px;
-  cursor:url('{$ROOT_URL}{$EASYCAPTCHA_PATH}tictac/gen.php?cross=96') 16 16, pointer;
-}
-#easycaptcha input {ldelim}
-  display:none;
-}
-#easycaptcha label.selected {ldelim}
-  background:url('{$ROOT_URL}{$EASYCAPTCHA_PATH}tictac/gen.php?cross={$EASYCAPTCHA_CONF.size}') no-repeat;
-}
-{/html_style}
+{else if $EASYCAPTCHA.challenge == 'tictac'}
+{combine_css id='easycaptcha.tictac' path=$EASYCAPTCHA_PATH|cat:'template/tictac.css' template=true version=$EASYCAPTCHA.lastmod}
 
-{footer_script require='jquery'}{literal}
+{footer_script require='jquery'}
 (function($){
 $('#easycaptcha input').on('change', function() {
@@ -127,5 +40,5 @@
 });
 }(jQuery));
-{/literal}{/footer_script}
+{/footer_script}
 
 {capture name=easycaptcha}
@@ -150,5 +63,5 @@
 </div>
 
-<input type="text" name="easycaptcha_key" value="{$EASYCAPTCHA_CONF.key}" style="display:none;">
+<input type="text" name="easycaptcha_key" value="{$EASYCAPTCHA.key}" style="display:none;">
 {/capture}
 
Index: /extensions/EasyCaptcha/template/contactform.tpl
===================================================================
--- /extensions/EasyCaptcha/template/contactform.tpl	(revision 26024)
+++ /extensions/EasyCaptcha/template/contactform.tpl	(revision 26025)
@@ -4,6 +4,6 @@
 
   {* <!-- DRAG & DROP --> *}
-  {if $EASYCAPTCHA_CHALLENGE == 'drag'}
-  <td class="title">{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate|sprintf:$EASYCAPTCHA_CONF.text}</td>
+  {if $EASYCAPTCHA.challenge == 'drag'}
+  <td class="title">{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate:$EASYCAPTCHA.drag.text}</td>
 
   {footer_script}
@@ -13,5 +13,5 @@
 
   {* <!-- TIC TAC TOE --> *}
-  {else if $EASYCAPTCHA_CHALLENGE == 'tictac'}
+  {else if $EASYCAPTCHA..challenge == 'tictac'}
   <td class="title">{'You are player X, click on the right case to complete the line.'|translate}</td>
 
Index: /extensions/EasyCaptcha/template/drag.css
===================================================================
--- /extensions/EasyCaptcha/template/drag.css	(revision 26025)
+++ /extensions/EasyCaptcha/template/drag.css	(revision 26025)
@@ -0,0 +1,58 @@
+#easycaptcha, #easycaptcha_noscript {
+  display: inline-block;
+  position: relative;
+  padding: 10px;
+  border-radius: 8px;
+  background: {$EASYCAPTCHA.drag.bg1};
+  background: -webkit-linear-gradient(top, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: -moz-linear-gradient(top, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: -ms-linear-gradient(top, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: -o-linear-gradient(top, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: linear-gradient(to bottom, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  color: {$EASYCAPTCHA.drag.txt};
+}
+#easycaptcha .drag_item {
+  position: absolute;
+  top: 15px;
+  width: {$EASYCAPTCHA.drag.size}px;
+  height: {$EASYCAPTCHA.drag.size}px;
+  border-radius: 5px;
+  border: 1px solid {$EASYCAPTCHA.drag.bd1};
+  background: {$EASYCAPTCHA.drag.obj};
+  z-index: 10;
+  cursor: move;
+}
+#easycaptcha .drag_item.active {
+  z-index: 100;
+  opacity: 0.75;
+}
+#easycaptcha .drag_item img {
+  width: {$EASYCAPTCHA.drag.size}px;
+  height: {$EASYCAPTCHA.drag.size}px;
+  border-radius: 5px;
+}
+#easycaptcha .drop_zone {
+  padding: 5px;
+  width: {$EASYCAPTCHA.drag.size}px;
+  height: {$EASYCAPTCHA.drag.size}px;
+  margin-left: {math equation='15+(x+5)*y' x=$EASYCAPTCHA.drag.size y=$EASYCAPTCHA.drag.nb}px;
+  line-height: {$EASYCAPTCHA.drag.size}px;
+  background: {$EASYCAPTCHA.drag.bg1};
+  background: -webkit-linear-gradient(bottom, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: -moz-linear-gradient(bottom, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: -ms-linear-gradient(bottom, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: -o-linear-gradient(bottom, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  background: linear-gradient(to top, {$EASYCAPTCHA.drag.bg1} 0%, {$EASYCAPTCHA.drag.bg2} 100%);
+  border: 1px dotted {$EASYCAPTCHA.drag.bd2};
+  border-radius: 5px;
+  text-align: center;
+  text-transform: uppercase;
+  color: {$EASYCAPTCHA.drag.txt};
+}
+#easycaptcha .drop_zone.active {
+  background: {$EASYCAPTCHA.drag.sel};
+}
+#easycaptcha .drop_zone.valid {
+  background: {$EASYCAPTCHA.drag.sel};
+  box-shadow: 0 0 0 2px {$EASYCAPTCHA.drag.sel};
+}
Index: /extensions/EasyCaptcha/template/drag.js
===================================================================
--- /extensions/EasyCaptcha/template/drag.js	(revision 26024)
+++ /extensions/EasyCaptcha/template/drag.js	(revision 26025)
@@ -39,10 +39,10 @@
       });
   })
-  .drag('end', function(e, dd) {
+  .drag('end', function() {
       $(this).removeClass('active');
   });
 
 $easycaptcha.find('.drop_zone')
-  .drop('start', function(e, dd) {
+  .drop('start', function() {
       $(this).addClass('active');
   })
Index: /extensions/EasyCaptcha/template/guestbook.tpl
===================================================================
--- /extensions/EasyCaptcha/template/guestbook.tpl	(revision 26024)
+++ /extensions/EasyCaptcha/template/guestbook.tpl	(revision 26025)
@@ -3,6 +3,6 @@
 
   {* <!-- DRAG & DROP --> *}
-  {if $EASYCAPTCHA_CHALLENGE == 'drag'}
-  <td colspan=2><label>{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate|sprintf:$EASYCAPTCHA_CONF.text}</label></td>
+  {if $EASYCAPTCHA.challenge == 'drag'}
+  <td colspan=2><label>{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate:$EASYCAPTCHA.drag.text}</label></td>
 
   {footer_script}
@@ -12,5 +12,5 @@
 
   {* <!-- TIC TAC TOE --> *}
-  {else if $EASYCAPTCHA_CHALLENGE == 'tictac'}
+  {else if $EASYCAPTCHA.challenge == 'tictac'}
   <td colspan=2><label>{'You are player X, click on the right case to complete the line.'|translate}</label></td>
 
Index: /extensions/EasyCaptcha/template/register.tpl
===================================================================
--- /extensions/EasyCaptcha/template/register.tpl	(revision 26024)
+++ /extensions/EasyCaptcha/template/register.tpl	(revision 26025)
@@ -4,9 +4,9 @@
 
   {* <!-- DRAG & DROP --> *}
-  {if $EASYCAPTCHA_CHALLENGE == 'drag'}
-  <span class="property"><label>{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate|sprintf:$EASYCAPTCHA_CONF.text}</label></span>
+  {if $EASYCAPTCHA.challenge == 'drag'}
+  <span class="property"><label>{'To verify you are a human, please place the <b>%s</b> in the most right box bellow.'|translate:$EASYCAPTCHA.drag.text}</label></span>
 
   {* <!-- TIC TAC TOE --> *}
-  {else if $EASYCAPTCHA_CHALLENGE == 'tictac'}
+  {else if $EASYCAPTCHA.challenge == 'tictac'}
   <span class="property"><label>{'You are player X, click on the right case to complete the line.'|translate}</label></span>
 
Index: /extensions/EasyCaptcha/template/style.css
===================================================================
--- /extensions/EasyCaptcha/template/style.css	(revision 26024)
+++ /extensions/EasyCaptcha/template/style.css	(revision 26025)
@@ -40,6 +40,7 @@
 .my-warnings {
   background-image:none;
+  display:inline-block;
   min-height:0;
-  padding:0 0 0 5px;
+  padding:5px 5px 0 5px;
   margin:0 5px 15px 5px;
   font-weight:normal;
Index: /extensions/EasyCaptcha/template/tictac.css
===================================================================
--- /extensions/EasyCaptcha/template/tictac.css	(revision 26025)
+++ /extensions/EasyCaptcha/template/tictac.css	(revision 26025)
@@ -0,0 +1,24 @@
+#easycaptcha table {
+  width: {$EASYCAPTCHA.tictac.size}px;
+  height: {$EASYCAPTCHA.tictac.size}px;
+  border-collapse: collapse;
+  display: inline-block;
+  margin: 0;
+  background: url('../tictac/gen.php?t={$smarty.now}') no-repeat;
+}
+#easycaptcha td {
+  border: none;
+  padding: 0;
+}
+#easycaptcha label {
+  display: block;
+  width: {math equation="floor(x/3)" x=$EASYCAPTCHA.tictac.size}px;
+  height: {math equation="floor(x/3)" x=$EASYCAPTCHA.tictac.size}px;
+  cursor: url('../tictac/gen.php?cross=96') 16 16, pointer;
+}
+#easycaptcha input {
+  display: none;
+}
+#easycaptcha label.selected {
+  background: url('../tictac/gen.php?cross={$EASYCAPTCHA.tictac.size}') no-repeat;
+}
