Index: .doxygen.conf
===================================================================
--- .doxygen.conf	(revision 3732)
+++ .doxygen.conf	(revision 3793)
@@ -6,5 +6,5 @@
 DOXYFILE_ENCODING      = UTF-8
 PROJECT_NAME           = Dotclear
-PROJECT_NUMBER         = 2.14
+PROJECT_NUMBER         = 2.15
 PROJECT_BRIEF          =
 PROJECT_LOGO           =
Index: .hgsigs
===================================================================
--- .hgsigs	(revision 3682)
+++ .hgsigs	(revision 3857)
@@ -1,2 +1,3 @@
 266ba234e2a5115e47379030e9439b6abcb11e80 0 iQEcBAABCgAGBQJV1WIcAAoJELwJObfmz3HnHHEH/1+ohmFEzHx5M90oAtQN4pQLsPCZ/fCVG5w6OoD56DOPP3IMaTSxlEzoG3mjWv0gzAb4zJjPErBwRy7keq3rjT5SyDs17aHRmCE91+YuGNBDnQHAD68gVZaQQ+L2d5+EHYdGtxcwiFUyRWEv+U/4NW0UexuJDVqzS6ztUC45D1a2Qt9Q4bbEsywmE5Bl7IP7hjxKlICJNo3fclpCgdryPeB7gatOJz4uw/T6tbJVzvD2ETA/9kp+hg2yFNWBhS0zgK/BKcinqlh2AW4fPDsrOvr7LnIQUt5KwdJmbNA3A8moF2EU9/PiF76tWF5IHtnk9x/bQjCgukZSZ383eUzlY58=
 ee065bfd6458b8fab13c8adf7649f8f988deb8e1 0 iQEzBAABCgAdFiEEl+7zWgi24VqTXSmqvAk5t+bPcecFAlprnkcACgkQvAk5t+bPcefsjQf/XYGUwwbDjOlWLdBRpGrnANElA1I8It6vlFJhMCBxlKm2USHMcQ0soOD4qFBUNioFBffPFLaD9wYHgU9oDfRzyKO09ntu0zO8jxetGrKItJJJqY9RUCKi5lYxvFICVwk3F7u8dU2Z5QxNI4g6rqlidxjzzBh9SprwcHi5kV33yLaShcvGjpU/23CstGRbfDy/rIBlC+xWEb8F8P+xQpPlzv7Ex7PBEAU3l3cdlwZic7gZM8c9rEf4fenH7WmWTAybeaga2RK5N2D6r4NB3+4zfr/AkwB7LCiLvNC+10RwoRHPwIZTe0pIf7AQG6YCXbWboEsbDD5bzJxpuTDjFJTTcA==
+1dc51dbf8899b36afeadf4433d8df2c06198822d 0 iQEzBAABCgAdFiEEl+7zWgi24VqTXSmqvAk5t+bPcecFAluOSrkACgkQvAk5t+bPcecItAf+OAikzkRFaOQ+OD3B73F2Ob8G3x/f6ujyQ2jhMzTiQ98cOcrvaejzsxxxuA3nRXIMWpaoFOnn+pLo0bWCeumGP0G6mG3XiZ+lEWsoxwIYGGKCns2/3xwSEjxT+EOz+qV0NfPvkHDdWNme9EUA1ljAZ/qR9UgumQK30t7LxT5C+JfzXm8jVWQYhJVYtAdNgUJdn2HQE+2xu0zTJIvaHS2LVGi+Qa+exL2/RjLl88YJLyDgIoPFP8/ncYSnTFcKY4SNP8AFAwH/b7DUcYpuBEiN0xM7TbOdDihtiS/PUpbECH7aei/N6ajWil7X8nFXWXLkPCSg48p7PtHYTEVhH6ZqmQ==
Index: .hgtags
===================================================================
--- .hgtags	(revision 3809)
+++ .hgtags	(revision 3856)
@@ -38,2 +38,3 @@
 57c79fd7f152a9d954c85f0b58cfdccd8b1ed8eb 2.13.1
 076e9950a9dc2bce7fd6d9ee7147ca60f26b2233 2.14.1
+08b090767191a6566ca4c8e559eb0cb0ebcc90df 2.14.2
Index: admin/auth.php
===================================================================
--- admin/auth.php	(revision 3731)
+++ admin/auth.php	(revision 3874)
@@ -122,9 +122,9 @@
             throw new Exception();
         }
-        $data = array(
+        $data = [
             'user_id'       => base64_decode($tmp_data[0]),
             'cookie_admin'  => $tmp_data[1],
             'user_remember' => $tmp_data[2] == '1'
-        );
+        ];
         if ($data['user_id'] === false) {
             throw new Exception();
@@ -190,9 +190,9 @@
 
     if ($check_perms && $core->auth->mustChangePassword()) {
-        $login_data = join('/', array(
+        $login_data = join('/', [
             base64_encode($user_id),
             $cookie_admin,
             empty($_POST['user_remember']) ? '0' : '1'
-        ));
+        ]);
 
         if (!$core->auth->allowPassChange()) {
@@ -294,8 +294,8 @@
     '<p><label for="user_id">' . __('Username:') . '</label> ' .
     form::field('user_id', 20, 32,
-        array(
+        [
             'default'      => html::escapeHTML($user_id),
             'autocomplete' => 'username'
-        )
+        ]
     ) .
     '</p>' .
@@ -303,8 +303,8 @@
     '<p><label for="user_email">' . __('Email:') . '</label> ' .
     form::email('user_email',
-        array(
+        [
             'default'      => html::escapeHTML($user_email),
             'autocomplete' => 'email'
-        )
+        ]
     ) .
     '</p>' .
@@ -322,14 +322,14 @@
     '<p><label for="new_pwd">' . __('New password:') . '</label> ' .
     form::password('new_pwd', 20, 255,
-        array(
+        [
             'autocomplete' => 'new-password'
-        )
+        ]
     ) . '</p>' .
 
     '<p><label for="new_pwd_c">' . __('Confirm password:') . '</label> ' .
     form::password('new_pwd_c', 20, 255,
-        array(
+        [
             'autocomplete' => 'new-password'
-        )
+        ]
     ) . '</p>' .
     '</div>' .
@@ -338,5 +338,5 @@
     form::hidden('login_data', $login_data) . '</p>';
 } else {
-    if (is_callable(array($core->auth, 'authForm'))) {
+    if (is_callable([$core->auth, 'authForm'])) {
         echo $core->auth->authForm($user_id);
     } else {
@@ -356,15 +356,15 @@
         '<p><label for="user_id">' . __('Username:') . '</label> ' .
         form::field('user_id', 20, 32,
-            array(
+            [
                 'default'      => html::escapeHTML($user_id),
                 'autocomplete' => 'username'
-            )
+            ]
         ) . '</p>' .
 
         '<p><label for="user_pwd">' . __('Password:') . '</label> ' .
         form::password('user_pwd', 20, 255,
-            array(
+            [
                 'autocomplete' => 'current-password'
-            )
+            ]
         ) . '</p>' .
 
@@ -397,7 +397,7 @@
             echo '<p id="more"><strong>' . __('Connection issue?') . '</strong></p>';
             if ($core->auth->allowPassChange()) {
-                echo '<p><a href="' . $core->adminurl->get('admin.auth', array('recover' => 1)) . '">' . __('I forgot my password') . '</a></p>';
+                echo '<p><a href="' . $core->adminurl->get('admin.auth', ['recover' => 1]) . '">' . __('I forgot my password') . '</a></p>';
             }
-            echo '<p><a href="' . $core->adminurl->get('admin.auth', array('safe_mode' => 1)) . '" id="safe_mode_link">' . __('I want to log in in safe mode') . '</a></p>';
+            echo '<p><a href="' . $core->adminurl->get('admin.auth', ['safe_mode' => 1]) . '" id="safe_mode_link">' . __('I want to log in in safe mode') . '</a></p>';
         }
 
Index: admin/blog.php
===================================================================
--- admin/blog.php	(revision 3731)
+++ admin/blog.php	(revision 3874)
@@ -48,5 +48,5 @@
         $core->callBehavior('adminAfterBlogCreate', $cur, $blog_id, $blog_settings);
         dcPage::addSuccessNotice(sprintf(__('Blog "%s" successfully created'), html::escapeHTML($cur->blog_name)));
-        $core->adminurl->redirect("admin.blog", array('id' => $cur->blog_id));
+        $core->adminurl->redirect("admin.blog", ['id' => $cur->blog_id]);
     } catch (Exception $e) {
         $core->error->add($e->getMessage());
@@ -60,9 +60,9 @@
     dcPage::open(__('New blog'), dcPage::jsConfirmClose('blog-form'),
         dcPage::breadcrumb(
-            array(
+            [
                 __('System')   => '',
                 __('Blogs')    => $core->adminurl->get("admin.blogs"),
                 __('New blog') => ''
-            ))
+            ])
     );
 
@@ -73,8 +73,8 @@
     '<p><label class="required" for="blog_id"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog ID:') . '</label> ' .
     form::field('blog_id', 30, 32,
-        array(
+        [
             'default'    => html::escapeHTML($blog_id),
             'extra_html' => 'required placeholder="' . __('Blog ID') . '"'
-        )
+        ]
     ) . '</p>' .
     '<p class="form-note">' . __('At least 2 characters using letters, numbers or symbols.') . '</p> ';
@@ -83,17 +83,17 @@
     '<p><label class="required" for="blog_name"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog name:') . '</label> ' .
     form::field('blog_name', 30, 255,
-        array(
+        [
             'default'    => html::escapeHTML($blog_name),
             'extra_html' => 'required placeholder="' . __('Blog name') . '"'
-        )
+        ]
     ) . '</p>' .
 
     '<p><label class="required" for="blog_url"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog URL:') . '</label> ' .
     form::url('blog_url',
-        array(
+        [
             'size'       => 30,
             'default'    => html::escapeHTML($blog_url),
             'extra_html' => 'required placeholder="' . __('Blog URL') . '"'
-        )
+        ]
     ) . '</p>' .
 
Index: admin/blog_del.php
===================================================================
--- admin/blog_del.php	(revision 3731)
+++ admin/blog_del.php	(revision 3874)
@@ -48,9 +48,9 @@
 dcPage::open(__('Delete a blog'), '',
     dcPage::breadcrumb(
-        array(
+        [
             __('System')        => '',
             __('Blogs')         => $core->adminurl->get("admin.blogs"),
             __('Delete a blog') => ''
-        ))
+        ])
 );
 
@@ -66,5 +66,5 @@
     '<div>' . $core->formNonce() . '</div>' .
     '<p><label for="pwd">' . __('Your password:') . '</label> ' .
-    form::password('pwd', 20, 255, array('autocomplete' => 'current-password')) . '</p>' .
+    form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '</p>' .
     '<p><input type="submit" class="delete" name="del" value="' . __('Delete this blog') . '" />' .
     form::hidden('blog_id', $blog_id) . '</p>' .
Index: admin/blog_pref.php
===================================================================
--- admin/blog_pref.php	(revision 3731)
+++ admin/blog_pref.php	(revision 3874)
@@ -48,5 +48,5 @@
 
     $action = $core->adminurl->get("admin.blog");
-    $redir  = $core->adminurl->get("admin.blog", array('id' => "%s"), '&', true);
+    $redir  = $core->adminurl->get("admin.blog", ['id' => "%s"], '&', true);
 }
 
@@ -61,9 +61,9 @@
 $date_formats       = $blog_settings->system->date_formats;
 $time_formats       = $blog_settings->system->time_formats;
-$date_formats_combo = array('' => '');
+$date_formats_combo = ['' => ''];
 foreach ($date_formats as $format) {
     $date_formats_combo[dt::str($format, $now)] = $format;
 }
-$time_formats_combo = array('' => '');
+$time_formats_combo = ['' => ''];
 foreach ($time_formats as $format) {
     $time_formats_combo[dt::str($format, $now)] = $format;
@@ -71,11 +71,11 @@
 
 # URL scan modes
-$url_scan_combo = array(
+$url_scan_combo = [
     'PATH_INFO'    => 'path_info',
     'QUERY_STRING' => 'query_string'
-);
+];
 
 # Post URL combo
-$post_url_combo = array(
+$post_url_combo = [
     __('year/month/day/title') => '{y}/{m}/{d}/{t}',
     __('year/month/title')     => '{y}/{m}/{t}',
@@ -84,5 +84,5 @@
     __('post id/title')        => '{id}/{t}',
     __('post id')              => '{id}'
-);
+];
 if (!in_array($blog_settings->system->post_url_format, $post_url_combo)) {
     $post_url_combo[html::escapeHTML($blog_settings->system->post_url_format)] = html::escapeHTML($blog_settings->system->post_url_format);
@@ -90,12 +90,12 @@
 
 # Note title tag combo
-$note_title_tag_combo = array(
+$note_title_tag_combo = [
     __('H4') => 0,
     __('H3') => 1,
     __('P')  => 2
-);
+];
 
 # Image title combo
-$img_title_combo = array(
+$img_title_combo = [
     __('(none)')                     => '',
     __('Title')                      => 'Title ;; separator(, )',
@@ -103,5 +103,5 @@
     __('Title, Country, Date')       => 'Title ;; Country ;; Date(%b %Y) ;; separator(, )',
     __('Title, City, Country, Date') => 'Title ;; City ;; Country ;; Date(%b %Y) ;; separator(, )'
-);
+];
 if (!in_array($blog_settings->system->media_img_title_pattern, $img_title_combo)) {
     $img_title_combo[html::escapeHTML($blog_settings->system->media_img_title_pattern)] = html::escapeHTML($blog_settings->system->media_img_title_pattern);
@@ -109,5 +109,5 @@
 
 # Image default size combo
-$img_default_size_combo = array();
+$img_default_size_combo = [];
 try {
     $media                                  = new dcMedia($core);
@@ -121,28 +121,28 @@
 
 # Image default alignment combo
-$img_default_alignment_combo = array(
+$img_default_alignment_combo = [
     __('None')   => 'none',
     __('Left')   => 'left',
     __('Right')  => 'right',
     __('Center') => 'center'
-);
+];
 
 # Image default legend and title combo
-$img_default_legend_combo = array(
+$img_default_legend_combo = [
     __('Legend and title') => 'legend',
     __('Title')            => 'title',
     __('None')             => 'none'
-);
+];
 
 # Robots policy options
-$robots_policy_options = array(
+$robots_policy_options = [
     'INDEX,FOLLOW'               => __("I would like search engines and archivers to index and archive my blog's content."),
     'INDEX,FOLLOW,NOARCHIVE'     => __("I would like search engines and archivers to index but not archive my blog's content."),
     'NOINDEX,NOFOLLOW,NOARCHIVE' => __("I would like to prevent search engines and archivers from indexing or archiving my blog's content.")
-);
+];
 
 # jQuery available versions
 $jquery_root           = dirname(__FILE__) . '/../inc/js/jquery';
-$jquery_versions_combo = array(__('Default') . ' (' . DC_DEFAULT_JQUERY . ')' => DC_DEFAULT_JQUERY);
+$jquery_versions_combo = [__('Default') . ' (' . DC_DEFAULT_JQUERY . ')' => DC_DEFAULT_JQUERY];
 if (is_dir($jquery_root) && is_readable($jquery_root)) {
     if (($d = @dir($jquery_root)) !== false) {
@@ -295,16 +295,16 @@
 if ($standalone) {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($blog_name) => '',
             __('Blog settings')          => ''
-        )
+        ]
     );
 } else {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             __('System')                                               => '',
             __('Blogs')                                                => $core->adminurl->get("admin.blogs"),
             __('Blog settings') . ' : ' . html::escapeHTML($blog_name) => ''
-        ));
+        ]);
 }
 
@@ -324,5 +324,5 @@
     "</script>" .
     dcPage::jsConfirmClose('blog-form') .
-    ($rte_flag ? $core->callBehavior('adminPostEditor', $desc_editor['xhtml'], 'blog_desc', array('#blog_desc'), 'xhtml') : '') .
+    ($rte_flag ? $core->callBehavior('adminPostEditor', $desc_editor['xhtml'], 'blog_desc', ['#blog_desc'], 'xhtml') : '') .
     dcPage::jsLoad('js/_blog_pref.js') .
 
@@ -345,5 +345,5 @@
     echo
     '<div class="multi-part" id="params" title="' . __('Parameters') . '">' .
-    '<h3 class="out-of-screen-if-js">' . __('Parameters') . '</h3>' .
+    '<div id="standard-pref"><h3>' . __('Blog parameters') . '</h3>' .
         '<form action="' . $action . '" method="post" id="blog-form">';
 
@@ -355,8 +355,8 @@
     '<p><label for="blog_name" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog name:') . '</label>' .
     form::field('blog_name', 30, 255,
-        array(
+        [
             'default'    => html::escapeHTML($blog_name),
             'extra_html' => 'required placeholder="' . __('Blog name') . '"'
-        )
+        ]
     ) . '</p>';
 
@@ -418,8 +418,8 @@
     __('Moderate comments') . '</label></p>' .
     '<p><label for="comments_ttl" class="classic">' . sprintf(__('Leave comments open for %s days') . '.',
-        form::number('comments_ttl', array(
+        form::number('comments_ttl', [
             'min'     => 0,
             'max'     => 999,
-            'default' => $blog_settings->system->comments_ttl)
+            'default' => $blog_settings->system->comments_ttl]
         )) .
     '</label></p>' .
@@ -441,8 +441,8 @@
     __('Moderate trackbacks') . '</label></p>' .
     '<p><label for="trackbacks_ttl" class="classic">' . sprintf(__('Leave trackbacks open for %s days') . '.',
-        form::number('trackbacks_ttl', array(
+        form::number('trackbacks_ttl', [
             'min'     => 0,
             'max'     => 999,
-            'default' => $blog_settings->system->trackbacks_ttl)
+            'default' => $blog_settings->system->trackbacks_ttl]
         )) .
     '</label></p>' .
@@ -464,5 +464,5 @@
     '<p><label for="date_format">' . __('Date format:') . '</label> ' .
     form::field('date_format', 30, 255, html::escapeHTML($blog_settings->system->date_format)) .
-    form::combo('date_format_select', $date_formats_combo, array('extra_html' => 'title="' . __('Pattern of date') . '"')) .
+    form::combo('date_format_select', $date_formats_combo, ['extra_html' => 'title="' . __('Pattern of date') . '"']) .
     '</p>' .
     '<p class="chosen form-note">' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->date_format)) . '</p>' .
@@ -470,5 +470,5 @@
     '<p><label for="time_format">' . __('Time format:') . '</label>' .
     form::field('time_format', 30, 255, html::escapeHTML($blog_settings->system->time_format)) .
-    form::combo('time_format_select', $time_formats_combo, array('extra_html' => 'title="' . __('Pattern of time') . '"')) .
+    form::combo('time_format_select', $time_formats_combo, ['extra_html' => 'title="' . __('Pattern of time') . '"']) .
     '</p>' .
     '<p class="chosen form-note">' . __('Sample:') . ' ' . dt::str(html::escapeHTML($blog_settings->system->time_format)) . '</p>' .
@@ -485,32 +485,32 @@
     '<div class="col">' .
     '<p><label for="nb_post_for_home" class="classic">' . sprintf(__('Display %s entries on home page'),
-        form::number('nb_post_for_home', array(
+        form::number('nb_post_for_home', [
             'min'     => 1,
             'max'     => 999,
-            'default' => $blog_settings->system->nb_post_for_home)
+            'default' => $blog_settings->system->nb_post_for_home]
         )) .
     '</label></p>' .
 
     '<p><label for="nb_post_per_page" class="classic">' . sprintf(__('Display %s entries per page'),
-        form::number('nb_post_per_page', array(
+        form::number('nb_post_per_page', [
             'min'     => 1,
             'max'     => 999,
-            'default' => $blog_settings->system->nb_post_per_page)
+            'default' => $blog_settings->system->nb_post_per_page]
         )) .
     '</label></p>' .
 
     '<p><label for="nb_post_per_feed" class="classic">' . sprintf(__('Display %s entries per feed'),
-        form::number('nb_post_per_feed', array(
+        form::number('nb_post_per_feed', [
             'min'     => 1,
             'max'     => 999,
-            'default' => $blog_settings->system->nb_post_per_feed)
+            'default' => $blog_settings->system->nb_post_per_feed]
         )) .
     '</label></p>' .
 
     '<p><label for="nb_comment_per_feed" class="classic">' . sprintf(__('Display %s comments per feed'),
-        form::number('nb_comment_per_feed', array(
+        form::number('nb_comment_per_feed', [
             'min'     => 1,
             'max'     => 999,
-            'default' => $blog_settings->system->nb_comment_per_feed)
+            'default' => $blog_settings->system->nb_comment_per_feed]
         )) .
     '</label></p>' .
@@ -539,42 +539,42 @@
     '<h5>' . __('Generated image sizes (max dimension in pixels)') . '</h5>' .
     '<p class="field"><label for="media_img_t_size">' . __('Thumbnail') . '</label> ' .
-    form::number('media_img_t_size', array(
+    form::number('media_img_t_size', [
         'min'     => -1,
         'max'     => 999,
         'default' => $blog_settings->system->media_img_t_size
-    )) .
+    ]) .
     '</p>' .
 
     '<p class="field"><label for="media_img_s_size">' . __('Small') . '</label> ' .
-    form::number('media_img_s_size', array(
+    form::number('media_img_s_size', [
         'min'     => -1,
         'max'     => 999,
         'default' => $blog_settings->system->media_img_s_size
-    )) .
+    ]) .
     '</p>' .
 
     '<p class="field"><label for="media_img_m_size">' . __('Medium') . '</label> ' .
-    form::number('media_img_m_size', array(
+    form::number('media_img_m_size', [
         'min'     => -1,
         'max'     => 999,
         'default' => $blog_settings->system->media_img_m_size
-    )) .
+    ]) .
     '</p>' .
 
     '<h5>' . __('Default size of the inserted video (in pixels)') . '</h5>' .
     '<p class="field"><label for="media_video_width">' . __('Width') . '</label> ' .
-    form::number('media_video_width', array(
+    form::number('media_video_width', [
         'min'     => -1,
         'max'     => 999,
         'default' => $blog_settings->system->media_video_width
-    )) .
+    ]) .
     '</p>' .
 
     '<p class="field"><label for="media_video_height">' . __('Height') . '</label> ' .
-    form::number('media_video_height', array(
+    form::number('media_video_height', [
         'min'     => -1,
         'max'     => 999,
         'default' => $blog_settings->system->media_video_height
-    )) .
+    ]) .
     '</p>' .
 
@@ -615,4 +615,5 @@
     '<br class="clear" />' . //Opera sucks
 
+    '</div>' .
     '</div>';
 
@@ -629,10 +630,10 @@
         echo
         '<p><label for="blog_url" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Blog URL:') . '</label>' .
-        form::url('blog_url', array(
+        form::url('blog_url', [
             'size'       => 50,
             'max'        => 255,
             'default'    => html::escapeHTML($blog_url),
             'extra_html' => 'required placeholder="' . __('Blog URL') . '"'
-        )) .
+        ]) .
         '</p>' .
 
@@ -720,5 +721,5 @@
     foreach ($robots_policy_options as $k => $v) {
         echo '<p><label for="robots_policy-' . $i . '" class="classic">' .
-        form::radio(array('robots_policy', 'robots_policy-' . $i), $k, $blog_settings->system->robots_policy == $k) . ' ' . $v . '</label></p>';
+        form::radio(['robots_policy', 'robots_policy-' . $i], $k, $blog_settings->system->robots_policy == $k) . ' ' . $v . '</label></p>';
         $i++;
     }
@@ -763,5 +764,5 @@
         '<form action="' . $core->adminurl->get("admin.blog.del") . '" method="post">' .
         '<p><input type="submit" class="delete" value="' . __('Delete this blog') . '" />' .
-        form::hidden(array('blog_id'), $blog_id) .
+        form::hidden(['blog_id'], $blog_id) .
         $core->formNonce() . '</p>' .
             '</form>';
@@ -790,5 +791,5 @@
     } else {
         if ($core->auth->isSuperAdmin()) {
-            $user_url_p = '<a href="' . $core->adminurl->get("admin.user", array('id' => '%1$s'), '&amp;', true) . '">%1$s</a>';
+            $user_url_p = '<a href="' . $core->adminurl->get("admin.user", ['id' => '%1$s'], '&amp;', true) . '">%1$s</a>';
         } else {
             $user_url_p = '%1$s';
@@ -825,8 +826,8 @@
                     '<ul>';
                 foreach ($post_type as $type => $pt_info) {
-                    $params = array(
+                    $params = [
                         'post_type' => $type,
                         'user_id'   => $k
-                    );
+                    ];
                     echo '<li>' . sprintf(__('%1$s: %2$s'), __($pt_info['label']), $core->blog->getPosts($params, true)->f(0)) . '</li>';
                 }
@@ -861,8 +862,8 @@
                     '<form action="' . $core->adminurl->get('admin.user.actions') . '" method="post">' .
                     '<p class="change-user-perm"><input type="submit" class="reset" value="' . __('Change permissions') . '" />' .
-                    form::hidden(array('redir'), $core->adminurl->get("admin.blog.pref", array('id' => $k), '&')) .
-                    form::hidden(array('action'), 'perms') .
-                    form::hidden(array('users[]'), $k) .
-                    form::hidden(array('blogs[]'), $blog_id) .
+                    form::hidden(['redir'], $core->adminurl->get("admin.blog.pref", ['id' => $k], '&')) .
+                    form::hidden(['action'], 'perms') .
+                    form::hidden(['users[]'], $k) .
+                    form::hidden(['blogs[]'], $blog_id) .
                     $core->formNonce() .
                         '</p>' .
Index: admin/blog_theme.php
===================================================================
--- admin/blog_theme.php	(revision 3731)
+++ admin/blog_theme.php	(revision 3874)
@@ -20,5 +20,6 @@
     $core->themes,
     $core->blog->themes_path,
-    $core->blog->settings->system->store_theme_url
+    $core->blog->settings->system->store_theme_url,
+    !empty($_GET['nocache'])
 );
 adminThemesList::$distributed_modules = explode(',', DC_DISTRIB_THEMES);
@@ -36,5 +37,5 @@
     }
 
-    http::cache(array_merge(array($f), get_included_files()));
+    http::cache(array_merge([$f], get_included_files()));
 
     header('Content-Type: ' . files::getMimeType($f));
@@ -63,9 +64,9 @@
 
         dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($core->blog->name)                                 => '',
                 __('Blog appearance')                                               => $list->getURL('', false),
                 '<span class="page-title">' . __('Theme configuration') . '</span>' => ''
-            ))
+            ])
     );
 
@@ -97,12 +98,18 @@
 
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name)                             => '',
             '<span class="page-title">' . __('Blog appearance') . '</span>' => ''
-        ))
+        ])
 );
 
 # -- Display modules lists --
 if ($core->auth->isSuperAdmin()) {
+
+    if (!$core->error->flag()) {
+        if (!empty($_GET['nocache'])) {
+            dcPage::success(__('Manual checking of themes update done successfully.'));
+        }
+    }
 
     # Updated modules from repo
@@ -122,6 +129,6 @@
             ->setModules($modules)
             ->displayModules(
-                /*cols */array('checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'),
-                /* actions */array('update', 'delete')
+                /*cols */['checkbox', 'name', 'sshot', 'desc', 'author', 'version', 'current_version', 'parent'],
+                /* actions */['update', 'delete']
             );
 
@@ -134,4 +141,10 @@
 
             '</div>';
+    } else {
+        echo
+        '<form action="' . $list->getURL('', false) . '" method="get">' .
+        '<p><input type="hidden" name="nocache" value="1" />' .
+        '<input type="submit" value="' . __('Force checking update of themes') . '" /></p>' .
+            '</form>';
     }
 }
@@ -151,6 +164,6 @@
         ->setModules($modules)
         ->displayModules(
-            /* cols */array('sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'),
-            /* actions */array('select', 'behavior', 'deactivate', 'delete')
+            /* cols */['sshot', 'distrib', 'name', 'config', 'desc', 'author', 'version', 'parent'],
+            /* actions */['select', 'behavior', 'deactivate', 'delete']
         );
 
@@ -173,6 +186,6 @@
         ->setModules($modules)
         ->displayModules(
-            /* cols */array('name', 'distrib'),
-            /* actions */array('activate', 'delete')
+            /* cols */['name', 'distrib'],
+            /* actions */['activate', 'delete']
         );
 
@@ -200,6 +213,6 @@
             ->displayIndex()
             ->displayModules(
-                /* cols */array('expander', 'sshot', 'name', 'score', 'config', 'desc', 'author', 'version', 'parent', 'details', 'support'),
-                /* actions */array('install'),
+                /* cols */['expander', 'sshot', 'name', 'score', 'config', 'desc', 'author', 'version', 'parent', 'details', 'support'],
+                /* actions */['install'],
                 /* nav limit */true
             );
Index: admin/blogs.php
===================================================================
--- admin/blogs.php	(revision 3746)
+++ admin/blogs.php	(revision 3874)
@@ -14,19 +14,19 @@
 # Filters
 $status_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     dcAdminCombos::getBlogStatusesCombo()
 );
 
-$sortby_combo = array(
+$sortby_combo = [
     __('Last update') => 'blog_upddt',
     __('Blog name')   => 'UPPER(blog_name)',
     __('Blog ID')     => 'B.blog_id',
     __('Status')      => 'blog_status'
-);
+];
 
-$order_combo = array(
+$order_combo = [
     __('Descending') => 'desc',
     __('Ascending')  => 'asc'
-);
+];
 
 # Actions
@@ -86,5 +86,5 @@
 }
 
-$params['limit'] = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params['limit'] = [(($page - 1) * $nb_per_page), $nb_per_page];
 
 try {
@@ -110,8 +110,8 @@
     dcPage::jsLoad('js/_blogs.js') . dcPage::jsFilterControl($show_filters),
     dcPage::breadcrumb(
-        array(
+        [
             __('System')        => '',
             __('List of blogs') => ''
-        ))
+        ])
 );
 
@@ -163,5 +163,5 @@
             '<p class="col right"><label for="action" class="classic">' . __('Selected blogs action:') . '</label> ' .
             form::combo('action', $blogs_actions_page->getCombo(),
-                array('class' => 'online', 'extra_html' => 'title="' . __('Actions') . '"')) .
+                ['class' => 'online', 'extra_html' => 'title="' . __('Actions') . '"']) .
             $core->formNonce() .
             '<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
@@ -169,11 +169,11 @@
 
             '<p><label for="pwd" class="classic">' . __('Please give your password to confirm blog(s) deletion:') . '</label> ' .
-            form::password('pwd', 20, 255, array('autocomplete' => 'current-password')) . '</p>' .
+            form::password('pwd', 20, 255, ['autocomplete' => 'current-password']) . '</p>' .
 
-            form::hidden(array('sortby'), $sortby) .
-            form::hidden(array('order'), $order) .
-            form::hidden(array('status'), $status) .
-            form::hidden(array('page'), $page) .
-            form::hidden(array('nb'), $nb_per_page) .
+            form::hidden(['sortby'], $sortby) .
+            form::hidden(['order'], $order) .
+            form::hidden(['status'], $status) .
+            form::hidden(['page'], $page) .
+            form::hidden(['nb'], $nb_per_page) .
 
             '</form>' : ''),
Index: admin/categories.php
===================================================================
--- admin/categories.php	(revision 3731)
+++ admin/categories.php	(revision 3874)
@@ -110,8 +110,8 @@
 dcPage::open(__('Categories'), $starting_script,
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Categories')                    => ''
-        ))
+        ])
 );
 
@@ -156,7 +156,7 @@
         echo
         '<p class="cat-title"><label class="classic" for="cat_' . $rs->cat_id . '"><a href="' .
-        $core->adminurl->get("admin.category", array('id' => $rs->cat_id)) . '">' . html::escapeHTML($rs->cat_title) .
+        $core->adminurl->get("admin.category", ['id' => $rs->cat_id]) . '">' . html::escapeHTML($rs->cat_title) .
         '</a></label> </p>' .
-        '<p class="cat-nb-posts">(<a href="' . $core->adminurl->get("admin.posts", array('cat_id' => $rs->cat_id)) . '">' .
+        '<p class="cat-nb-posts">(<a href="' . $core->adminurl->get("admin.posts", ['cat_id' => $rs->cat_id]) . '">' .
         sprintf(($rs->nb_post > 1 ? __('%d entries') : __('%d entry')), $rs->nb_post) . '</a>' .
         ', ' . __('total:') . ' ' . $rs->nb_total . ')</p>' .
@@ -169,5 +169,5 @@
             echo
             '<label for="mov_cat_' . $rs->cat_id . '">' . __('Move entries to') . '</label> ' .
-            form::combo(array('mov_cat[' . $rs->cat_id . ']', 'mov_cat_' . $rs->cat_id), array_filter($categories_combo,
+            form::combo(['mov_cat[' . $rs->cat_id . ']', 'mov_cat_' . $rs->cat_id], array_filter($categories_combo,
                 function ($cat) {return $cat->value != $GLOBALS['rs']->cat_id;}
             ), '', '') .
Index: admin/category.php
===================================================================
--- admin/category.php	(revision 3731)
+++ admin/category.php	(revision 3874)
@@ -41,8 +41,8 @@
 
     # Allowed parents list
-    $children        = $core->blog->getCategories(array('start' => $cat_id));
-    $allowed_parents = array(__('Top level') => 0);
-
-    $p = array();
+    $children        = $core->blog->getCategories(['start' => $cat_id]);
+    $allowed_parents = [__('Top level') => 0];
+
+    $p = [];
     while ($children->fetch()) {
         $p[$children->cat_id] = 1;
@@ -61,5 +61,5 @@
 
     # Allowed siblings list
-    $siblings = array();
+    $siblings = [];
     $rs       = $core->blog->getCategoryFirstChildren($cat_parent);
     while ($rs->fetch()) {
@@ -126,5 +126,5 @@
             dcPage::addSuccessNotice(__('The category has been successfully updated.'));
 
-            $core->adminurl->redirect("admin.category", array('id' => $_POST['id']));
+            $core->adminurl->redirect("admin.category", ['id' => $_POST['id']]);
         }
         # Create category
@@ -149,11 +149,11 @@
 $title = $cat_id ? html::escapeHTML($cat_title) : __('New category');
 
-$elements = array(
+$elements = [
     html::escapeHTML($core->blog->name) => '',
     __('Categories')                    => $core->adminurl->get("admin.categories")
-);
+];
 if ($cat_id) {
     while ($parents->fetch()) {
-        $elements[html::escapeHTML($parents->cat_title)] = $core->adminurl->get("admin.category", array('id' => $parents->cat_id));
+        $elements[html::escapeHTML($parents->cat_title)] = $core->adminurl->get("admin.category", ['id' => $parents->cat_id]);
     }
 }
@@ -170,5 +170,5 @@
     dcPage::jsConfirmClose('category-form') .
     dcPage::jsLoad('js/_category.js') .
-    ($rte_flag ? $core->callBehavior('adminPostEditor', $category_editor['xhtml'], 'category', array('#cat_desc'), 'xhtml') : ''),
+    ($rte_flag ? $core->callBehavior('adminPostEditor', $category_editor['xhtml'], 'category', ['#cat_desc'], 'xhtml') : ''),
     dcPage::breadcrumb($elements)
 );
@@ -182,8 +182,8 @@
 '<h3>' . __('Category information') . '</h3>' .
 '<p><label class="required" for="cat_title"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Name:') . '</label> ' .
-form::field('cat_title', 40, 255, array(
+form::field('cat_title', 40, 255, [
     'default'    => html::escapeHTML($cat_title),
     'extra_html' => 'required placeholder="' . __('Name') . '"'
-)) .
+]) .
     '</p>';
 if (!$cat_id) {
@@ -231,5 +231,5 @@
     form::combo('cat_parent', $allowed_parents, $cat_parent) . '</p>' .
     '<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
-    form::hidden(array('id'), $cat_id) . $core->formNonce() . '</p>' .
+    form::hidden(['id'], $cat_id) . $core->formNonce() . '</p>' .
         '</form>' .
         '</div>';
@@ -241,9 +241,9 @@
         '<h4>' . __('Category sibling') . '</h4>' .
         '<p><label class="classic" for="cat_sibling">' . __('Move current category') . '</label> ' .
-        form::combo('cat_move', array(__('before') => 'before', __('after') => 'after'),
-            array('extra_html' => 'title="' . __('position: ') . '"')) . ' ' .
+        form::combo('cat_move', [__('before') => 'before', __('after') => 'after'],
+            ['extra_html' => 'title="' . __('position: ') . '"']) . ' ' .
         form::combo('cat_sibling', $siblings) . '</p>' .
         '<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
-        form::hidden(array('id'), $cat_id) . $core->formNonce() . '</p>' .
+        form::hidden(['id'], $cat_id) . $core->formNonce() . '</p>' .
             '</form>' .
             '</div>';
Index: admin/comment.php
===================================================================
--- admin/comment.php	(revision 3731)
+++ admin/comment.php	(revision 3874)
@@ -32,5 +32,5 @@
     try
     {
-        $rs = $core->blog->getPosts(array('post_id' => $_POST['post_id'], 'post_type' => ''));
+        $rs = $core->blog->getPosts(['post_id' => $_POST['post_id'], 'post_type' => '']);
 
         if ($rs->isEmpty()) {
@@ -127,5 +127,5 @@
 
             dcPage::addSuccessNotice(__('Comment has been successfully updated.'));
-            $core->adminurl->redirect("admin.comment", array('id' => $comment_id));
+            $core->adminurl->redirect("admin.comment", ['id' => $comment_id]);
         } catch (Exception $e) {
             $core->error->add($e->getMessage());
@@ -156,16 +156,16 @@
 if ($comment_id) {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             html::escapeHTML($post_title)       => $core->getPostAdminURL($post_type, $post_id) . '&amp;co=1#c' . $comment_id,
             __('Edit comment')                  => ''
-        ));
+        ]);
 } else {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             html::escapeHTML($post_title)       => $core->getPostAdminURL($post_type, $post_id),
             __('Edit comment')                  => ''
-        ));
+        ]);
 }
 
@@ -173,5 +173,5 @@
     dcPage::jsConfirmClose('comment-form') .
     dcPage::jsLoad('js/_comment.js') .
-    $core->callBehavior('adminPostEditor', $comment_editor['xhtml'], 'comment', array('#comment_content'), 'xhtml') .
+    $core->callBehavior('adminPostEditor', $comment_editor['xhtml'], 'comment', ['#comment_content'], 'xhtml') .
     # --BEHAVIOR-- adminCommentHeaders
     $core->callBehavior('adminCommentHeaders'),
@@ -198,5 +198,5 @@
     '<h3>' . __('Information collected') . '</h3>' .
     '<p>' . __('IP address:') . ' ' .
-    '<a href="' . $core->adminurl->get("admin.comments", array('ip' => $comment_ip)) . '">' . $comment_ip . '</a></p>' .
+    '<a href="' . $core->adminurl->get("admin.comments", ['ip' => $comment_ip]) . '">' . $comment_ip . '</a></p>' .
 
     '<p>' . __('Date:') . ' ' .
@@ -206,8 +206,8 @@
     '<h3>' . __('Comment submitted') . '</h3>' .
     '<p><label for="comment_author" class="required"><abbr title="' . __('Required field') . '">*</abbr>' . __('Author:') . '</label>' .
-    form::field('comment_author', 30, 255, array(
+    form::field('comment_author', 30, 255, [
         'default'    => html::escapeHTML($comment_author),
         'extra_html' => 'required placeholder="' . __('Author') . '"'
-    )) .
+    ]) .
     '</p>' .
 
@@ -223,5 +223,5 @@
     '<p><label for="comment_status">' . __('Status:') . '</label>' .
     form::combo('comment_status', $status_combo,
-        array('default' => $comment_status, 'disabled' => !$can_publish)) .
+        ['default' => $comment_status, 'disabled' => !$can_publish]) .
     '</p>' .
 
Index: admin/comments.php
===================================================================
--- admin/comments.php	(revision 3731)
+++ admin/comments.php	(revision 3874)
@@ -25,15 +25,15 @@
 # Filter form we'll put in html_block
 $status_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     dcAdminCombos::getCommentStatusescombo()
 );
 
-$type_combo = array(
+$type_combo = [
     '-'             => '',
     __('Comment')   => 'co',
     __('Trackback') => 'tb'
-);
-
-$sortby_combo = array(
+];
+
+$sortby_combo = [
     __('Date')        => 'comment_dt',
     __('Entry title') => 'post_title',
@@ -41,16 +41,16 @@
     __('Author')      => 'comment_author',
     __('Status')      => 'comment_status'
-);
-
-$sortby_lex = array(
+];
+
+$sortby_lex = [
     // key in sorty_combo (see above) => field in SQL request
     'post_title'          => 'post_title',
     'comment_author'      => 'comment_author',
-    'comment_spam_filter' => 'comment_spam_filter');
-
-$order_combo = array(
+    'comment_spam_filter' => 'comment_spam_filter'];
+
+$order_combo = [
     __('Descending') => 'desc',
     __('Ascending')  => 'asc'
-);
+];
 
 /* Get comments
@@ -79,5 +79,5 @@
 }
 
-$params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
 $params['no_content'] = true;
 
@@ -155,5 +155,5 @@
 
 # Actions combo box
-$combo_action = array();
+$combo_action = [];
 $default      = '';
 if ($core->auth->check('delete,contentadmin', $core->blog->id) && $status == -2) {
@@ -183,8 +183,8 @@
     dcPage::jsLoad('js/_comments.js') . dcPage::jsFilterControl($show_filters),
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Comments and trackbacks')       => ''
-        ))
+        ])
 );
 if (!empty($_GET['upd'])) {
@@ -200,5 +200,5 @@
     }
 
-    $spam_count = $core->blog->getComments(array('comment_status' => -2), true)->f(0);
+    $spam_count = $core->blog->getComments(['comment_status' => -2], true)->f(0);
     if ($spam_count > 0) {
 
@@ -209,8 +209,8 @@
             if ($spam_count == 1) {
                 echo '<p>' . sprintf(__('You have one spam comment.'), '<strong>' . $spam_count . '</strong>') . ' ' .
-                '<a href="' . $core->adminurl->get("admin.comments", array('status' => -2)) . '">' . __('Show it.') . '</a></p>';
+                '<a href="' . $core->adminurl->get("admin.comments", ['status' => -2]) . '">' . __('Show it.') . '</a></p>';
             } elseif ($spam_count > 1) {
                 echo '<p>' . sprintf(__('You have %s spam comments.'), '<strong>' . $spam_count . '</strong>') . ' ' .
-                '<a href="' . $core->adminurl->get("admin.comments", array('status' => -2)) . '">' . __('Show them.') . '</a></p>';
+                '<a href="' . $core->adminurl->get("admin.comments", ['status' => -2]) . '">' . __('Show them.') . '</a></p>';
             }
         }
@@ -278,17 +278,17 @@
         '<p class="col right"><label for="action" class="classic">' . __('Selected comments action:') . '</label> ' .
         form::combo('action', $comments_actions_page->getCombo(),
-            array('default' => $default, 'extra_html' => 'title="' . __('Actions') . '"')) .
+            ['default' => $default, 'extra_html' => 'title="' . __('Actions') . '"']) .
         $core->formNonce() .
         '<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
-        form::hidden(array('type'), $type) .
-        form::hidden(array('sortby'), $sortby) .
-        form::hidden(array('order'), $order) .
-        form::hidden(array('author'), html::escapeHTML(preg_replace('/%/', '%%', $author))) .
-        form::hidden(array('status'), $status) .
-        form::hidden(array('ip'), preg_replace('/%/', '%%', $ip)) .
-        form::hidden(array('page'), $page) .
-        form::hidden(array('nb'), $nb_per_page) .
-        form::hidden(array('email'), html::escapeHTML(preg_replace('/%/', '%%', $email))) .
-        form::hidden(array('site'), html::escapeHTML(preg_replace('/%/', '%%', $site))) .
+        form::hidden(['type'], $type) .
+        form::hidden(['sortby'], $sortby) .
+        form::hidden(['order'], $order) .
+        form::hidden(['author'], html::escapeHTML(preg_replace('/%/', '%%', $author))) .
+        form::hidden(['status'], $status) .
+        form::hidden(['ip'], preg_replace('/%/', '%%', $ip)) .
+        form::hidden(['page'], $page) .
+        form::hidden(['nb'], $nb_per_page) .
+        form::hidden(['email'], html::escapeHTML(preg_replace('/%/', '%%', $email))) .
+        form::hidden(['site'], html::escapeHTML(preg_replace('/%/', '%%', $site))) .
         '</div>' .
 
Index: admin/comments_actions.php
===================================================================
--- admin/comments_actions.php	(revision 3731)
+++ admin/comments_actions.php	(revision 3874)
@@ -23,5 +23,5 @@
 } else {
     $uri  = $core->adminurl->get("admin.comments");
-    $args = array();
+    $args = [];
 }
 
Index: admin/csp_report.php
===================================================================
--- admin/csp_report.php	(revision 3731)
+++ admin/csp_report.php	(revision 3874)
@@ -93,5 +93,5 @@
 
             // Prettify the JSON-formatted data
-            $violation = array_merge(array('hash' => $hash), $data['csp-report']);
+            $violation = array_merge(['hash' => $hash], $data['csp-report']);
             $output    = json_encode($violation, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
 
Index: admin/help.php
===================================================================
--- admin/help.php	(revision 3731)
+++ admin/help.php	(revision 3874)
@@ -12,8 +12,7 @@
 dcPage::check('usage,contentadmin');
 
-$helpPage = function () {
-    $ret = array('content' => '', 'title' => '');
+$helpPage = function (...$args) {
+    $ret = ['content' => '', 'title' => ''];
 
-    $args = func_get_args();
     if (empty($args)) {
         return $ret;
@@ -71,13 +70,13 @@
 if ($content_array['title'] != '') {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             __('Global help')       => $core->adminurl->get("admin.help"),
             $content_array['title'] => ''
-        ));
+        ]);
 } else {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             __('Global help') => ''
-        ));
+        ]);
 }
 
Index: admin/index.php
===================================================================
--- admin/index.php	(revision 3781)
+++ admin/index.php	(revision 3874)
@@ -31,5 +31,5 @@
 dcPage::check('usage,contentadmin');
 
-if ($core->plugins->disableDepModules($core->adminurl->get('admin.home', array()))) {
+if ($core->plugins->disableDepModules($core->adminurl->get('admin.home', []))) {
     exit;
 }
@@ -108,5 +108,5 @@
 
 # Latest news for dashboard
-$__dashboard_items = new ArrayObject(array(new ArrayObject(), new ArrayObject()));
+$__dashboard_items = new ArrayObject([new ArrayObject(), new ArrayObject()]);
 
 $dashboardItem = 0;
@@ -115,5 +115,5 @@
 if ($core->auth->user_prefs->dashboard->doclinks) {
     if (!empty($__resources['doc'])) {
-        $doc_links = '<div class="box small dc-box"><h3>' . __('Documentation and support') . '</h3><ul>';
+        $doc_links = '<div class="box small dc-box" id="doc-and-support"><h3>' . __('Documentation and support') . '</h3><ul>';
 
         foreach ($__resources['doc'] as $k => $v) {
@@ -131,5 +131,5 @@
 
 # Dashboard content
-$__dashboard_contents = new ArrayObject(array(new ArrayObject, new ArrayObject));
+$__dashboard_contents = new ArrayObject([new ArrayObject, new ArrayObject]);
 $core->callBehavior('adminDashboardContents', $core, $__dashboard_contents);
 
@@ -142,5 +142,5 @@
         if ($post_editor && !empty($post_editor[$post_format])) {
             // context is not post because of tags not available
-            $admin_post_behavior = $core->callBehavior('adminPostEditor', $post_editor[$post_format], 'quickentry', array('#post_content'), $post_format);
+            $admin_post_behavior = $core->callBehavior('adminPostEditor', $post_editor[$post_format], 'quickentry', ['#post_content'], $post_format);
         }
     }
@@ -150,4 +150,6 @@
 -------------------------------------------------------- */
 dcPage::open(__('Dashboard'),
+    dcPage::jsLoad('js/jquery/jquery-ui.custom.js') .
+    dcPage::jsLoad('js/jquery/jquery.ui.touch-punch.js') .
     dcPage::jsLoad('js/_index.js') .
     $admin_post_behavior .
@@ -155,8 +157,8 @@
     $core->callBehavior('adminDashboardHeaders'),
     dcPage::breadcrumb(
-        array(
+        [
             __('Dashboard') . ' : ' . html::escapeHTML($core->blog->name) => ''
-        ),
-        array('home_link' => false)
+        ],
+        ['home_link' => false]
     )
 );
@@ -164,5 +166,5 @@
 if ($core->auth->getInfo('user_default_blog') != $core->blog->id && $core->auth->getBlogCount() > 1) {
     echo
-    '<p><a href="' . $core->adminurl->get("admin.home", array('default_blog' => 1)) . '" class="button">' . __('Make this blog my default blog') . '</a></p>';
+    '<p><a href="' . $core->adminurl->get("admin.home", ['default_blog' => 1]) . '" class="button">' . __('Make this blog my default blog') . '</a></p>';
 }
 
@@ -189,5 +191,5 @@
 }
 
-$err = array();
+$err = [];
 
 # Check cache directory
@@ -244,40 +246,108 @@
 }
 
-# Dashboard items and contents (processed first, as we need to know the result before displaying the icons.)
-$dashboardItems = '';
-foreach ($__dashboard_items as $i) {
-    foreach ($i as $v) {
-        $dashboardItems .= $v;
-    }
-}
-$dashboardContents = '';
-foreach ($__dashboard_contents as $i) {
-    foreach ($i as $v) {
-        $dashboardContents .= $v;
-    }
-}
-
-# Dashboard elements: icons then boxes (items then contents)
-echo '<div id="dashboard-main">';
-
+# Get current main orders
+$main_order = $core->auth->user_prefs->dashboard->main_order;
+$main_order = ($main_order != '' ? explode(',', $main_order) : []);
+
+# Get current boxes orders
+$boxes_order = $core->auth->user_prefs->dashboard->boxes_order;
+$boxes_order = ($boxes_order != '' ? explode(',', $boxes_order) : []);
+
+# Get current boxes items orders
+$boxes_items_order = $core->auth->user_prefs->dashboard->boxes_items_order;
+$boxes_items_order = ($boxes_items_order != '' ? explode(',', $boxes_items_order) : []);
+
+# Get current boxes contents orders
+$boxes_contents_order = $core->auth->user_prefs->dashboard->boxes_contents_order;
+$boxes_contents_order = ($boxes_contents_order != '' ? explode(',', $boxes_contents_order) : []);
+
+$composeItems = function ($list, $blocks, $flat = false) {
+
+    $ret   = [];
+    $items = [];
+
+    if ($flat) {
+        $items = $blocks;
+    } else {
+        foreach ($blocks as $i) {
+            foreach ($i as $v) {
+                $items[] = $v;
+            }
+        }
+    }
+
+    # First loop to find ordered indexes
+    $order = [];
+    $index = 0;
+    foreach ($items as $v) {
+        if (preg_match('/<div.*?id="([^"].*?)".*?>/ms', $v, $match)) {
+            $id       = $match[1];
+            $position = array_search($id, $list, true);
+            if ($position !== false) {
+                $order[$position] = $index;
+            }
+        }
+        $index++;
+    }
+
+    # Second loop to combine ordered items
+    $index = 0;
+    foreach ($items as $v) {
+        $position = array_search($index, $order, true);
+        if ($position !== false) {
+            $ret[$position] = $v;
+        }
+        $index++;
+    }
+    # Reorder items on their position (key)
+    ksort($ret);
+
+    # Third loop to combine unordered items
+    $index = 0;
+    foreach ($items as $v) {
+        $position = array_search($index, $order, true);
+        if ($position === false) {
+            $ret[count($ret)] = $v;
+        }
+        $index++;
+    }
+
+    return join('', $ret);
+};
+
+# Compose dashboard items (doc, …)
+$dashboardItems = $composeItems($boxes_items_order, $__dashboard_items);
+# Compose dashboard contents (plugin's modules)
+$dashboardContents = $composeItems($boxes_contents_order, $__dashboard_contents);
+
+$__dashboard_boxes = [];
+if ($dashboardItems != '') {
+    $__dashboard_boxes[] = '<div class="db-items" id="db-items">' . $dashboardItems . '</div>';
+}
+if ($dashboardContents != '') {
+    $__dashboard_boxes[] = '<div class="db-contents" id="db-contents">' . $dashboardContents . '</div>';
+}
+$dashboardBoxes = $composeItems($boxes_order, $__dashboard_boxes, true);
+
+# Compose main area
+$__dashboard_main = [];
 if (!$core->auth->user_prefs->dashboard->nofavicons) {
     # Dashboard icons
-    echo '<div id="icons">';
+    $dashboardIcons = '<div id="icons">';
     foreach ($__dashboard_icons as $i) {
-        echo
-        '<p><a href="' . $i[1] . '"><img src="' . dc_admin_icon_url($i[2]) . '" alt="" />' .
+        $dashboardIcons .= '<p><a href="' . $i[1] . '"><img src="' . dc_admin_icon_url($i[2]) . '" alt="" />' .
             '<br /><span class="db-icon-title">' . $i[0] . '</span></a></p>';
     }
-    echo '</div>';
-}
-
+    $dashboardIcons .= '</div>';
+    $__dashboard_main[] = $dashboardIcons;
+}
 if ($core->auth->user_prefs->dashboard->quickentry) {
     if ($core->auth->check('usage,contentadmin', $core->blog->id)) {
         # Getting categories
         $categories_combo = dcAdminCombos::getCategoriesCombo(
-            $core->blog->getCategories(array())
+            $core->blog->getCategories([])
         );
 
-        echo
+        $dashboardQuickEntry =
         '<div id="quick">' .
         '<h3>' . __('Quick entry') . sprintf(' &rsaquo; %s', $core->auth->getOption('post_format')) . '</h3>' .
@@ -285,12 +355,12 @@
         '<h4>' . __('New entry') . '</h4>' .
         '<p class="col"><label for="post_title" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label>' .
-        form::field('post_title', 20, 255, array(
+        form::field('post_title', 20, 255, [
             'class'      => 'maximal',
             'extra_html' => 'required placeholder="' . __('Title') . '"'
-        )) .
+        ]) .
         '</p>' .
         '<p class="area"><label class="required" ' .
         'for="post_content"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Content:') . '</label> ' .
-        form::textarea('post_content', 50, 10, array('extra_html' => 'required placeholder="' . __('Content') . '"')) .
+        form::textarea('post_content', 50, 10, ['extra_html' => 'required placeholder="' . __('Content') . '"']) .
         '</p>' .
         '<p><label for="cat_id" class="classic">' . __('Category:') . '</label> ' .
@@ -320,16 +390,15 @@
             '</form>' .
             '</div>';
-    }
-}
-
-if ($dashboardContents != '' || $dashboardItems != '') {
-    echo
-        '<div id="dashboard-boxes">' .
-        ($dashboardItems != '' ? '<div class="db-items">' . $dashboardItems . '</div>' : '') .
-        ($dashboardContents != '' ? '<div class="db-contents">' . $dashboardContents . '</div>' : '') .
-        '</div>';
-}
-
-echo '</div>'; #end dashboard-main
+        $__dashboard_main[] = $dashboardQuickEntry;
+    }
+}
+if ($dashboardBoxes != '') {
+    $__dashboard_main[] = '<div id="dashboard-boxes">' . $dashboardBoxes . '</div>';
+}
+$dashboardMain = $composeItems($main_order, $__dashboard_main, true);
+
+# Dashboard elements
+echo '<div id="dashboard-main">' . $dashboardMain . '</div>';
+
 dcPage::helpBlock('core_dashboard');
 dcPage::close();
Index: admin/install/check.php
===================================================================
--- admin/install/check.php	(revision 3795)
+++ admin/install/check.php	(revision 3874)
@@ -12,5 +12,5 @@
 function dcSystemCheck($con, &$err)
 {
-    $err = array();
+    $err = [];
 
     if (version_compare(phpversion(), '5.6', '<')) {
Index: admin/install/index.php
===================================================================
--- admin/install/index.php	(revision 3731)
+++ admin/install/index.php	(revision 3874)
@@ -146,8 +146,8 @@
         # date and time formats
         $formatDate   = __('%A, %B %e %Y');
-        $date_formats = array('%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%Y/%m/%d', '%d.%m.%Y', '%b %e %Y', '%e %b %Y', '%Y %b %e',
+        $date_formats = ['%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%Y/%m/%d', '%d.%m.%Y', '%b %e %Y', '%e %b %Y', '%Y %b %e',
             '%a, %Y-%m-%d', '%a, %m/%d/%Y', '%a, %d/%m/%Y', '%a, %Y/%m/%d', '%B %e, %Y', '%e %B, %Y', '%Y, %B %e', '%e. %B %Y',
-            '%A, %B %e, %Y', '%A, %e %B, %Y', '%A, %Y, %B %e', '%A, %Y, %B %e', '%A, %e. %B %Y');
-        $time_formats = array('%H:%M', '%I:%M', '%l:%M', '%Hh%M', '%Ih%M', '%lh%M');
+            '%A, %B %e, %Y', '%A, %e %B, %Y', '%A, %Y, %B %e', '%A, %Y, %B %e', '%A, %e. %B %Y'];
+        $time_formats = ['%H:%M', '%I:%M', '%l:%M', '%Hh%M', '%Ih%M', '%lh%M'];
         if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
             $formatDate   = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $formatDate);
@@ -240,5 +240,5 @@
         # Add default favorites
         $core->favs = new dcFavorites($core);
-        $init_favs  = array('posts', 'new_post', 'newpage', 'comments', 'categories', 'media', 'blog_theme', 'widgets', 'simpleMenu', 'prefs', 'help');
+        $init_favs  = ['posts', 'new_post', 'newpage', 'comments', 'categories', 'media', 'blog_theme', 'widgets', 'simpleMenu', 'prefs', 'help'];
         $core->favs->setFavoriteIDs($init_favs, true);
 
@@ -331,21 +331,21 @@
     '<fieldset><legend>' . __('User information') . '</legend>' .
     '<p><label for="u_firstname">' . __('First Name:') . '</label> ' .
-    form::field('u_firstname', 30, 255, array(
+    form::field('u_firstname', 30, 255, [
         'default'      => html::escapeHTML($u_firstname),
         'autocomplete' => 'given-name'
-    )) .
+    ]) .
     '</p>' .
     '<p><label for="u_name">' . __('Last Name:') . '</label> ' .
-    form::field('u_name', 30, 255, array(
+    form::field('u_name', 30, 255, [
         'default'      => html::escapeHTML($u_name),
         'autocomplete' => 'family-name'
-    )) .
+    ]) .
     '</p>' .
     '<p><label for="u_email">' . __('Email:') . '</label> ' .
-    form::email('u_email', array(
+    form::email('u_email', [
         'size'         => 30,
         'default'      => html::escapeHTML($u_email),
         'autocomplete' => 'email'
-    )) .
+    ]) .
     '</p>' .
     '</fieldset>' .
@@ -353,17 +353,17 @@
     '<fieldset><legend>' . __('Username and password') . '</legend>' .
     '<p><label for="u_login" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Username:') . ' ' .
-    form::field('u_login', 30, 32, array(
+    form::field('u_login', 30, 32, [
         'default'      => html::escapeHTML($u_login),
         'extra_html'   => 'required placeholder="' . __('Username') . '"',
         'autocomplete' => 'username'
-    )) .
+    ]) .
     '</label></p>' .
     '<div class="pw-table">' .
     '<p class="pw-cell">' .
     '<label for="u_pwd" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('New password:') . '</label>' .
-    form::password('u_pwd', 30, 255, array(
+    form::password('u_pwd', 30, 255, [
         'extra_html'   => 'data-indicator="pwindicator" required placeholder="' . __('Password') . '"',
         'autocomplete' => 'new-password'
-    )) .
+    ]) .
     '</p>' .
     '<div id="pwindicator">' .
@@ -373,8 +373,8 @@
     '</div>' .
     '<p><label for="u_pwd2" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Confirm password:') . ' ' .
-    form::password('u_pwd2', 30, 255, array(
+    form::password('u_pwd2', 30, 255, [
         'extra_html'   => 'required placeholder="' . __('Password') . '"',
         'autocomplete' => 'new-password'
-    )) .
+    ]) .
     '</label></p>' .
     '</fieldset>' .
@@ -421,6 +421,6 @@
     '<form action="../auth.php" method="post">' .
     '<p><input type="submit" value="' . __('Manage your blog now') . '" />' .
-    form::hidden(array('user_id'), html::escapeHTML($u_login)) .
-    form::hidden(array('user_pwd'), html::escapeHTML($u_pwd)) .
+    form::hidden(['user_id'], html::escapeHTML($u_login)) .
+    form::hidden(['user_pwd'], html::escapeHTML($u_pwd)) .
         '</p>' .
         '</form>';
Index: admin/install/wizard.php
===================================================================
--- admin/install/wizard.php	(revision 3806)
+++ admin/install/wizard.php	(revision 3874)
@@ -194,11 +194,11 @@
 '<form action="wizard.php" method="post">' .
 '<p><label class="required" for="DBDRIVER"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Database type:') . '</label> ' .
-form::combo('DBDRIVER', array(
+form::combo('DBDRIVER', [
     __('MySQL (deprecated)')  => 'mysql',
     __('MySQLi')              => 'mysqli',
     __('MySQLi (full UTF-8)') => 'mysqlimb4',
     __('PostgreSQL')          => 'pgsql',
-    __('SQLite')              => 'sqlite'),
-    array('default' => $DBDRIVER, 'extra_html' => 'required placeholder="' . __('Driver') . '"')) . '</p>' .
+    __('SQLite')              => 'sqlite'],
+    ['default' => $DBDRIVER, 'extra_html' => 'required placeholder="' . __('Driver') . '"']) . '</p>' .
 '<p><label for="DBHOST">' . __('Database Host Name:') . '</label> ' .
 form::field('DBHOST', 30, 255, html::escapeHTML($DBHOST)) . '</p>' .
@@ -210,15 +210,15 @@
 form::password('DBPASSWORD', 30, 255) . '</p>' .
 '<p><label for="DBPREFIX" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Database Tables Prefix:') . '</label> ' .
-form::field('DBPREFIX', 30, 255, array(
+form::field('DBPREFIX', 30, 255, [
     'default'    => html::escapeHTML($DBPREFIX),
     'extra_html' => 'required placeholder="' . __('Prefix') . '"'
-)) .
+]) .
 '</p>' .
 '<p><label for="ADMINMAILFROM">' . __('Master Email: (used as sender for password recovery)') . '</label> ' .
-form::email('ADMINMAILFROM', array(
+form::email('ADMINMAILFROM', [
     'size'         => 30,
     'default'      => html::escapeHTML($ADMINMAILFROM),
     'autocomplete' => 'email'
-)) .
+]) .
 '</p>' .
 
Index: admin/js/_auth.js
===================================================================
--- admin/js/_auth.js	(revision 3725)
+++ admin/js/_auth.js	(revision 3851)
@@ -3,6 +3,6 @@
 
 $(window).load(function() {
-  var uid = $('input[name=user_id]');
-  var upw = $('input[name=user_pwd]');
+  let uid = $('input[name=user_id]');
+  let upw = $('input[name=user_pwd]');
   uid.focus();
 
@@ -10,8 +10,5 @@
     return;
   }
-
-  uid.keypress(processKey);
-
-  function processKey(evt) {
+  uid.keypress(evt => {
     if (evt.which == 13 && upw.val() == '') {
       upw.focus();
@@ -19,5 +16,6 @@
     }
     return true;
-  }
+  });
+
   $.cookie('dc_admin_test_cookie', true);
   if ($.cookie('dc_admin_test_cookie')) {
Index: admin/js/_blog_pref.js
===================================================================
--- admin/js/_blog_pref.js	(revision 3706)
+++ admin/js/_blog_pref.js	(revision 3880)
@@ -1,53 +1,56 @@
 /*global $, dotclear, jsToolBar */
 'use strict';
-function checkQueryString() {
-	var blogUrl = $('#blog_url')[0].value;
-	var urlScan = $('#url_scan')[0].value;
-	var errorMsg = '';
-	if (/.*[^\/]$/.exec(blogUrl) && urlScan=='path_info') {
-		errorMsg = dotclear.msg.warning_path_info;
-	} else if (/.*[^\?]$/.exec(blogUrl) && urlScan=='query_string') {
-		errorMsg = dotclear.msg.warning_query_string;
-	}
-	$('p#urlwarning').remove();
-	if (errorMsg != '') {
-		$('#blog_url').parents('p').after('<p id="urlwarning" class="warning">'+errorMsg+'</p>');
-	}
-}
-
 
 $(function() {
-	var blog_url = $('#blog_url');
-	if (blog_url.length > 0 && !blog_url.is(':hidden')) {
-		checkQueryString();
-		$('#blog_url').focusout(checkQueryString);
-		$('body').on('change','#url_scan',checkQueryString);
-	}
+  const blog_url = $('#blog_url');
+  if (blog_url.length > 0 && !blog_url.is(':hidden')) {
+    const checkQueryString = function() {
+      const url = blog_url[0].value;
+      const scan = $('#url_scan')[0].value;
+      let msg = '';
+      if (/.*[^\/]$/.exec(url) && scan == 'path_info') {
+        msg = dotclear.msg.warning_path_info;
+      } else if (/.*[^\?]$/.exec(url) && scan == 'query_string') {
+        msg = dotclear.msg.warning_query_string;
+      }
+      $('p#urlwarning').remove();
+      if (msg != '') {
+        blog_url.parents('p').after(`<p id="urlwarning" class="warning">${msg}</p>`);
+      }
+    };
+    checkQueryString();
+    blog_url.focusout(checkQueryString);
+    $('body').on('change', '#url_scan', checkQueryString);
+  }
 
-	$('#date_format_select,#time_format_select').change(function() {
-		if ($(this).prop('value') == '') {
-			return;
-		}
-		$('#'+$(this).attr('id').replace('_select','')).prop('value', $(this).prop('value'));
-		$(this).parent().next('.chosen').html($(this).find(':selected').prop('label'));
-	});
+  $('#date_format_select,#time_format_select').change(function() {
+    if ($(this).prop('value') == '') {
+      return;
+    }
+    $('#' + $(this).attr('id').replace('_select', '')).prop('value', $(this).prop('value'));
+    $(this).parent().next('.chosen').html($(this).find(':selected').prop('label'));
+  });
 
-	// HTML text editor
-	if ($.isFunction(jsToolBar)) {
-		$('#blog_desc').each(function() {
-			var tbWidgetText = new jsToolBar(this);
-			tbWidgetText.context = 'blog_desc';
-			tbWidgetText.draw('xhtml');
-		});
-	}
+  // HTML text editor
+  if ($.isFunction(jsToolBar)) {
+    $('#blog_desc').each(function() {
+      let tbWidgetText = new jsToolBar(this);
+      tbWidgetText.context = 'blog_desc';
+      tbWidgetText.draw('xhtml');
+    });
+  }
 
-	// Hide advanced and plugins prefs sections
-	$('#advanced-pref h3').toggleWithLegend($('#advanced-pref').children().not('h3'),{
-		legend_click: true,
-		user_pref: 'dcx_blog_pref_adv'
-	});
-	$('#plugins-pref h3').toggleWithLegend($('#plugins-pref').children().not('h3'),{
-		legend_click: true,
-		user_pref: 'dcx_blog_pref_plg'
-	});
+  // Hide advanced and plugins prefs sections
+  $('#standard-pref h3').toggleWithLegend($('#standard-pref').children().not('h3'), {
+    legend_click: true,
+    hide: false
+  });
+  $('#advanced-pref h3').toggleWithLegend($('#advanced-pref').children().not('h3'), {
+    legend_click: true,
+    user_pref: 'dcx_blog_pref_adv',
+  });
+  $('#plugins-pref h3').toggleWithLegend($('#plugins-pref').children().not('h3'), {
+    legend_click: true,
+    user_pref: 'dcx_blog_pref_plg',
+  });
 });
Index: admin/js/_blog_theme.js
===================================================================
--- admin/js/_blog_theme.js	(revision 3768)
+++ admin/js/_blog_theme.js	(revision 3880)
@@ -5,5 +5,5 @@
   // expend theme info
   $('.module-sshot').not('.current-theme .module-sshot').each(function() {
-    var bar = $('<div>').addClass('bloc-toggler');
+    const bar = $('<div>').addClass('bloc-toggler');
     $(this).after(
       $(bar).toggleWithLegend($(this).parent().children('.toggle-bloc'), {
@@ -22,5 +22,5 @@
   // dirty short search blocker
   $('div.modules-search form input[type=submit]').click(function() {
-    var mlen = $('input[name=m_search]', $(this).parent()).val();
+    const mlen = $('input[name=m_search]', $(this).parent()).val();
     if (mlen.length > 2) {
       return true;
@@ -37,21 +37,21 @@
   // actions tests
   $('.modules-form-actions').each(function() {
-    var rxActionType = /^[^\[]+/;
-    var rxActionValue = /([^\[]+)\]$/;
-    var checkboxes = $(this).find('input[type=checkbox]');
+    const rxActionType = /^[^\[]+/;
+    const rxActionValue = /([^\[]+)\]$/;
+    const checkboxes = $(this).find('input[type=checkbox]');
 
     // check if submit is a global action or one line action
     $('input[type=submit]', this).click(function() {
-      var keyword = $(this).attr('name');
+      const keyword = $(this).attr('name');
       if (!keyword) {
         return true;
       }
-      var maction = keyword.match(rxActionType);
-      var action = maction[0];
-      var mvalues = keyword.match(rxActionValue);
+      const maction = keyword.match(rxActionType);
+      const action = maction[0];
+      const mvalues = keyword.match(rxActionValue);
 
       // action on multiple modules
       if (!mvalues) {
-        var checked = false;
+        let checked = false;
 
         // check if there is checkboxes in form
@@ -76,5 +76,5 @@
         // action on one module
       } else {
-        var module = mvalues[1];
+        const module = mvalues[1];
 
         // confirm delete
Index: admin/js/_blogs.js
===================================================================
--- admin/js/_blogs.js	(revision 3706)
+++ admin/js/_blogs.js	(revision 3880)
@@ -9,5 +9,5 @@
   dotclear.condSubmit('#form-blogs td input[type=checkbox]', '#form-blogs #do-action');
   $('#form-blogs').submit(function() {
-    var action = $(this).find('select[name="action"]').val();
+    const action = $(this).find('select[name="action"]').val();
     if (action == 'delete') {
       return window.confirm(dotclear.msg.confirm_delete_blog.replace('%s', $('input[name="blogs[]"]:checked').size()));
Index: admin/js/_category.js
===================================================================
--- admin/js/_category.js	(revision 3706)
+++ admin/js/_category.js	(revision 3880)
@@ -6,5 +6,5 @@
 
   if ($.isFunction(jsToolBar)) {
-    var tbCategory = new jsToolBar(document.getElementById('cat_desc'));
+    const tbCategory = new jsToolBar(document.getElementById('cat_desc'));
     tbCategory.draw('xhtml');
   }
Index: admin/js/_comment.js
===================================================================
--- admin/js/_comment.js	(revision 3706)
+++ admin/js/_comment.js	(revision 3880)
@@ -4,5 +4,5 @@
 $(function() {
 	if ($.isFunction(jsToolBar)) {
-		var tbComment = new jsToolBar(document.getElementById('comment_content'));
+		const tbComment = new jsToolBar(document.getElementById('comment_content'));
 		tbComment.draw('xhtml');
 	}
Index: admin/js/_comments.js
===================================================================
--- admin/js/_comments.js	(revision 3706)
+++ admin/js/_comments.js	(revision 3880)
@@ -2,54 +2,41 @@
 'use strict';
 
-dotclear.viewCommentContent = function(line, action) {
+dotclear.viewCommentContent = function(line, action, e) {
   action = action || 'toggle';
-  var commentId = $(line).attr('id').substr(1);
-  var tr = document.getElementById('ce' + commentId);
+  if ($(line).attr('id') == undefined) {
+    return;
+  }
 
-  if (!tr && (action == 'toggle' || action == 'open')) {
-    tr = document.createElement('tr');
-    tr.id = 'ce' + commentId;
-    var td = document.createElement('td');
-    td.colSpan = 6;
-    td.className = 'expand';
-    tr.appendChild(td);
+  const commentId = $(line).attr('id').substr(1);
+  const lineId = `ce${commentId}`;
+  let tr = document.getElementById(lineId);
 
-    // Get comment content
-    $.get('services.php', {
-      f: 'getCommentById',
-      id: commentId
-    }, function(data) {
-      var rsp = $(data).children('rsp')[0];
+  // If meta key down or it's a spam then display content HTML code
+  const clean = (e.metaKey || $(line).hasClass('sts-junk'));
 
-      if (rsp.attributes[0].value == 'ok') {
-        var comment = $(rsp).find('comment_display_content').text();
-
-        if (comment) {
-          $(td).append(comment);
-          var comment_email = $(rsp).find('comment_email').text();
-          var comment_site = $(rsp).find('comment_site').text();
-          var comment_ip = $(rsp).find('comment_ip').text();
-          var comment_spam_disp = $(rsp).find('comment_spam_disp').text();
-
-          $(td).append('<p><strong>' + dotclear.msg.website +
-            '</strong> ' + comment_site + '<br />' +
-            '<strong>' + dotclear.msg.email + '</strong> ' + comment_email + '<br />' +
-            '<strong>' + dotclear.msg.ip_address +
-            '</strong> <a href="comments.php?ip=' + comment_ip + '">' + comment_ip + '</a>' +
-            '<br />' + comment_spam_disp + '</p>');
-        }
+  if (!tr) {
+    // Get comment content if possible
+    dotclear.getCommentContent(commentId, function(content) {
+      if (content) {
+        // Content found
+        tr = document.createElement('tr');
+        tr.id = lineId;
+        const td = document.createElement('td');
+        td.colSpan = $(line).children('td').length;
+        td.className = 'expand';
+        tr.appendChild(td);
+        $(td).append(content);
+        $(line).addClass('expand');
+        line.parentNode.insertBefore(tr, line.nextSibling);
       } else {
-        window.alert($(rsp).find('message').text());
+        // No content, content not found or server error
+        $(line).removeClass('expand');
       }
+    }, {
+      clean: clean
     });
-
+  } else {
+    $(tr).toggle();
     $(line).toggleClass('expand');
-    line.parentNode.insertBefore(tr, line.nextSibling);
-  } else if (tr && tr.style.display == 'none' && (action == 'toggle' || action == 'open')) {
-    $(tr).css('display', 'table-row');
-    $(line).addClass('expand');
-  } else if (tr && tr.style.display != 'none' && (action == 'toggle' || action == 'close')) {
-    $(tr).css('display', 'none');
-    $(line).removeClass('expand');
   }
 };
Index: admin/js/_index.js
===================================================================
--- admin/js/_index.js	(revision 3781)
+++ admin/js/_index.js	(revision 3880)
@@ -3,5 +3,5 @@
 
 dotclear.dbCommentsCount = function() {
-  var params = {
+  const params = {
     f: 'getCommentsCount',
     xd_check: dotclear.nonce,
@@ -13,11 +13,11 @@
       window.console.log('Dotclear REST server error');
     } else {
-      var nb = $('rsp>count', data).attr('ret');
+      const nb = $('rsp>count', data).attr('ret');
       if (nb != dotclear.dbCommentsCount_Counter) {
         // First pass or counter changed
-        var icon = $('#dashboard-main #icons p a[href="comments.php"]');
+        const icon = $('#dashboard-main #icons p a[href="comments.php"]');
         if (icon.length) {
           // Update count if exists
-          var nb_label = icon.children('span.db-icon-title');
+          const nb_label = icon.children('span.db-icon-title');
           if (nb_label.length) {
             nb_label.text(nb);
@@ -31,5 +31,5 @@
 };
 dotclear.dbPostsCount = function() {
-  var params = {
+  const params = {
     f: 'getPostsCount',
     xd_check: dotclear.nonce,
@@ -41,11 +41,11 @@
       window.console.log('Dotclear REST server error');
     } else {
-      var nb = $('rsp>count', data).attr('ret');
+      const nb = $('rsp>count', data).attr('ret');
       if (nb != dotclear.dbPostsCount_Counter) {
         // First pass or counter changed
-        var icon = $('#dashboard-main #icons p a[href="posts.php"]');
+        const icon = $('#dashboard-main #icons p a[href="posts.php"]');
         if (icon.length) {
           // Update count if exists
-          var nb_label = icon.children('span.db-icon-title');
+          const nb_label = icon.children('span.db-icon-title');
           if (nb_label.length) {
             nb_label.text(nb);
@@ -64,5 +64,5 @@
     }
 
-    var params = {
+    const params = {
       f: 'quickPost',
       xd_check: dotclear.nonce,
@@ -80,5 +80,5 @@
 
     $.post('services.php', params, function(data) {
-      var msg;
+      let msg;
       if ($('rsp[status=failed]', data).length > 0) {
         msg = '<p class="qinfo"><strong>' + dotclear.msg.error +
@@ -108,5 +108,5 @@
   }
 
-  var f = $('#quick-entry');
+  const f = $('#quick-entry');
   if (f.length > 0) {
     if ($.isFunction(jsToolBar)) {
@@ -143,5 +143,5 @@
 
   // check if core update available
-  var params = {
+  let params = {
     f: 'checkCoreUpdate',
     xd_check: dotclear.nonce
@@ -153,6 +153,8 @@
       if ($('rsp>update', data).attr('check') == 1) {
         // Something has to be displayed
-        var xml = $('rsp>update', data).attr('ret');
+        const xml = $('rsp>update', data).attr('ret');
         $('#content h2').after(xml);
+        // manage outgoing links
+        dotclear.outgoingLinks('#ajax-update a');
       }
     }
@@ -170,5 +172,5 @@
       if ($('rsp>news', data).attr('check') == 1) {
         // Something has to be displayed
-        var xml = $('rsp>news', data).attr('ret');
+        const xml = $('rsp>news', data).attr('ret');
         if ($('#dashboard-boxes').length == 0) {
           // Create the #dashboard-boxes container
@@ -180,4 +182,6 @@
         }
         $('#dashboard-boxes div.db-items').prepend(xml);
+        // manage outgoing links
+        dotclear.outgoingLinks('#ajax-news a');
       }
     }
@@ -186,6 +190,5 @@
   // run counters' update on some dashboard icons
   // Comments (including everything)
-  var icon_com = $('#dashboard-main #icons p a[href="comments.php"]');
-  if (icon_com.length) {
+  if ($('#dashboard-main #icons p a[href="comments.php"]').length) {
     // Icon exists on dashboard
     // First pass
@@ -195,6 +198,5 @@
   }
   // Posts
-  var icon_com = $('#dashboard-main #icons p a[href="posts.php"]');
-  if (icon_com.length) {
+  if ($('#dashboard-main #icons p a[href="posts.php"]').length) {
     // Icon exists on dashboard
     // First pass
@@ -203,3 +205,40 @@
     dotclear.dbPostsCount_Timer = setInterval(dotclear.dbCommentsPost, 600 * 1000);
   }
+
+  // Dashboard boxes and their children are sortable
+  const set_positions = function(sel, id) {
+    const list = $(sel).sortable("toArray").join();
+    // Save positions (via services) for id
+    const params = {
+      f: 'setDashboardPositions',
+      xd_check: dotclear.nonce,
+      id: id,
+      list: list
+    };
+    $.post('services.php', params, function() {});
+  };
+  const init_positions = function(sel, id) {
+    $(sel).sortable({
+      cursor: 'move',
+      opacity: 0.5,
+      tolerance: "pointer",
+      update: function() {
+        set_positions(sel, id);
+      },
+      start: function() {
+        $(sel).addClass('sortable-area');
+      },
+      stop: function() {
+        $(sel).removeClass('sortable-area');
+      }
+    });
+  };
+  // Wait 5 seconds before activating ordering capabilities on dashboard
+  setTimeout(function() {
+    init_positions('#dashboard-main', 'main_order');
+    init_positions('#dashboard-boxes', 'boxes_order');
+    init_positions('#db-items', 'boxes_items_order');
+    init_positions('#db-contents', 'boxes_contents_order');
+  }, 5000);
+
 });
Index: admin/js/_langs.js
===================================================================
--- admin/js/_langs.js	(revision 3706)
+++ admin/js/_langs.js	(revision 3880)
@@ -4,5 +4,5 @@
 $(function() {
 	$('table.plugins form input[type=submit][name=delete]').click(function() {
-		var l_name = $(this).parents('tr.line').find('td:first').text();
+		const l_name = $(this).parents('tr.line').find('td:first').text();
 		return window.confirm(dotclear.msg.confirm_delete_lang.replace('%s',l_name));
 	});
Index: admin/js/_media.js
===================================================================
--- admin/js/_media.js	(revision 3706)
+++ admin/js/_media.js	(revision 3880)
@@ -5,6 +5,6 @@
   $.fn.enhancedUploader = function() {
     return this.each(function() {
-      var me = $(this);
-      var $container = $(me).parent();
+      const me = $(this);
+      const $container = $(me).parent();
 
       function enableButton(button) {
@@ -17,5 +17,5 @@
 
       function displayMessageInQueue(n) {
-        var msg = '';
+        let msg = '';
         if (n == 1) {
           msg = dotclear.jsUpload.msg.file_in_queue;
@@ -88,5 +88,6 @@
       });
 
-      var $msg, label;
+      let $msg;
+      let label;
 
       if ($container.hasClass('enhanced_uploader')) {
@@ -103,5 +104,5 @@
       }
 
-      $('<p class="clear"><button type="button" class="enhanced-toggle">' + $msg + '</button></p>').click(function(e) {
+      $(`<p class="clear"><button type="button" class="enhanced-toggle">${$msg}</button></p>`).click(function(e) {
         if ($container.hasClass('enhanced_uploader')) {
           $msg = dotclear.msg.enhanced_uploader_activate;
@@ -122,6 +123,6 @@
           label = dotclear.jsUpload.msg.choose_files;
           $('#upfile').attr('multiple', true);
-          var startButton = $('.button.start');
-          var buttonBar = $('#fileupload .fileupload-buttonbar');
+          const startButton = $('.button.start');
+          const buttonBar = $('#fileupload .fileupload-buttonbar');
           disableButton(startButton);
           disableButton(buttonBar);
@@ -153,5 +154,5 @@
 
   $('#form-medias #delete_medias').click(function(e) {
-    var count_checked = $('input[name="medias[]"]:checked', $('#form-medias')).length;
+    const count_checked = $('input[name="medias[]"]:checked', $('#form-medias')).length;
     if (count_checked == 0) {
       e.preventDefault();
@@ -168,10 +169,10 @@
   // attach media
   $('#form-medias').on('click', '.media-item .attach-media', function(e) {
-    var parts = $(this).prop('href').split('?');
-    var str_params = parts[1].split('&');
-    var postData = {};
-
-    for (var n = 0; n < str_params.length; n++) {
-      var kv = str_params[n].split('=');
+    const parts = $(this).prop('href').split('?');
+    const str_params = parts[1].split('&');
+    let postData = {};
+
+    for (let n = 0; n < str_params.length; n++) {
+      const kv = str_params[n].split('=');
       postData[kv[0]] = kv[1];
     }
@@ -192,6 +193,6 @@
   function fileRemoveAct() {
     $('body').on('click', 'a.media-remove', function() {
-      var m_name = $(this).parents('.media-item').find('a.media-link').text();
-      var m_text = '';
+      const m_name = $(this).parents('.media-item').find('a.media-link').text();
+      let m_text = '';
       if ($(this).parents('div.media-folder').length == 0) {
         m_text = dotclear.msg.confirm_delete_media.replace('%s', m_name);
@@ -200,5 +201,5 @@
       }
       if (window.confirm(m_text)) {
-        var f = $('#media-remove-hide').get(0);
+        const f = $('#media-remove-hide').get(0);
         f.elements.remove.value = this.href.replace(/^(.*)&remove=(.*?)(&|$)/, '$2');
         this.href = '';
Index: admin/js/_media_item.js
===================================================================
--- admin/js/_media_item.js	(revision 3706)
+++ admin/js/_media_item.js	(revision 3880)
@@ -4,7 +4,7 @@
 $(function() {
   // Add datePicker if possible
-  var media_dt = document.getElementById('media_dt');
+  const media_dt = document.getElementById('media_dt');
   if (media_dt != undefined) {
-    var post_dtPick = new datePicker(media_dt);
+    const post_dtPick = new datePicker(media_dt);
     post_dtPick.img_top = '1.5em';
     post_dtPick.draw();
@@ -18,11 +18,11 @@
   // Display zip file content
   $('#file-unzip').each(function() {
-    var a = document.createElement('a');
-    var mediaId = $(this).find('input[name=id]').val();
-    var self = $(this);
+    const a = document.createElement('a');
+    const mediaId = $(this).find('input[name=id]').val();
+    const This = $(this);
 
     a.href = '#';
     $(a).text(dotclear.msg.zip_file_content);
-    self.before(a);
+    This.before(a);
     $(a).wrap('<p></p>');
 
@@ -32,10 +32,10 @@
         id: mediaId
       }, function(data) {
-        var rsp = $(data).children('rsp')[0];
+        const rsp = $(data).children('rsp')[0];
 
         if (rsp.attributes[0].value == 'ok') {
-          var div = document.createElement('div');
-          var list = document.createElement('ul');
-          var expanded = false;
+          const div = document.createElement('div');
+          const list = document.createElement('ul');
+          let expanded = false;
 
           $(div).css({
@@ -46,5 +46,5 @@
           $(div).addClass('color-div');
           $(div).append(list);
-          self.before(div);
+          This.before(div);
           $(a).hide();
           $(div).before('<h3>' + dotclear.msg.zip_file_content + '</h3>');
Index: admin/js/_plugins.js
===================================================================
--- admin/js/_plugins.js	(revision 3768)
+++ admin/js/_plugins.js	(revision 3880)
@@ -21,21 +21,21 @@
   // actions tests
   $('.modules-form-actions').each(function() {
-    var rxActionType = /^[^\[]+/;
-    var rxActionValue = /([^\[]+)\]$/;
-    var checkboxes = $(this).find('input[type=checkbox]');
+    const rxActionType = /^[^\[]+/;
+    const rxActionValue = /([^\[]+)\]$/;
+    const checkboxes = $(this).find('input[type=checkbox]');
 
     // check if submit is a global action or one line action
     $('input[type=submit]', this).click(function() {
-      var keyword = $(this).attr('name');
+      const keyword = $(this).attr('name');
       if (!keyword) {
         return true;
       }
-      var maction = keyword.match(rxActionType);
-      var action = maction[0];
-      var mvalues = keyword.match(rxActionValue);
+      const maction = keyword.match(rxActionType);
+      const action = maction[0];
+      const mvalues = keyword.match(rxActionValue);
 
       // action on multiple modules
       if (!mvalues) {
-        var checked = false;
+        let checked = false;
 
         // check if there is checkboxes in form
@@ -60,5 +60,5 @@
         // action on one module
       } else {
-        var module = mvalues[1];
+        const module = mvalues[1];
 
         // confirm delete
Index: admin/js/_post.js
===================================================================
--- admin/js/_post.js	(revision 3706)
+++ admin/js/_post.js	(revision 3880)
@@ -2,48 +2,39 @@
 'use strict';
 
-dotclear.viewCommentContent = function(line) {
-  var commentId = $(line).attr('id').substr(1);
-  var tr = document.getElementById('ce' + commentId);
+dotclear.viewCommentContent = function(line, action, e) {
+  action = action || 'toggle';
+  if ($(line).attr('id') == undefined) {
+    return;
+  }
+
+  const commentId = $(line).attr('id').substr(1);
+  const lineId = `ce${commentId}`;
+  let tr = document.getElementById(lineId);
+
+  // If meta key down or it's a spam then display content HTML code
+  const clean = (e.metaKey || $(line).hasClass('sts-junk'));
 
   if (!tr) {
-    tr = document.createElement('tr');
-    tr.id = 'ce' + commentId;
-    var td = document.createElement('td');
-    td.colSpan = 6;
-    td.className = 'expand';
-    tr.appendChild(td);
-
     // Get comment content
-    $.get('services.php', {
-      f: 'getCommentById',
-      id: commentId
-    }, function(data) {
-      var rsp = $(data).children('rsp')[0];
-
-      if (rsp.attributes[0].value == 'ok') {
-        var comment = $(rsp).find('comment_display_content').text();
-
-        if (comment) {
-          $(td).append(comment);
-          var comment_email = $(rsp).find('comment_email').text();
-          var comment_site = $(rsp).find('comment_site').text();
-          //          var comment_ip = $(rsp).find('comment_ip').text();
-          var comment_spam_disp = $(rsp).find('comment_spam_disp').text();
-
-          $(td).append('<p><strong>' + dotclear.msg.website +
-            '</strong> ' + comment_site + '<br />' +
-            '<strong>' + dotclear.msg.email + '</strong> ' +
-            comment_email + '<br />' + comment_spam_disp + '</p>');
-        }
+    dotclear.getCommentContent(commentId, function(content) {
+      if (content) {
+        // Content found
+        tr = document.createElement('tr');
+        tr.id = lineId;
+        const td = document.createElement('td');
+        td.colSpan = $(line).children('td').length;
+        td.className = 'expand';
+        tr.appendChild(td);
+        $(td).append(content);
+        $(line).addClass('expand');
+        line.parentNode.insertBefore(tr, line.nextSibling);
       } else {
-        window.alert($(rsp).find('message').text());
+        // No content, content not found or server error
+        $(line).removeClass('expand');
       }
+    }, {
+      ip: false,
+      clean: clean
     });
-
-    $(line).toggleClass('expand');
-    line.parentNode.insertBefore(tr, line.nextSibling);
-  } else if (tr.style.display == 'none') {
-    $(tr).toggle();
-    $(line).toggleClass('expand');
   } else {
     $(tr).toggle();
@@ -54,9 +45,9 @@
 $(function() {
   // Post preview
-  var $preview_url = $('#post-preview').attr('href');
+  let $preview_url = $('#post-preview').attr('href');
   if ($preview_url) {
 
     // Make $preview_url absolute
-    var $a = document.createElement('a');
+    let $a = document.createElement('a');
     $a.href = $('#post-preview').attr('href');
     $preview_url = $a.href;
@@ -90,5 +81,5 @@
 
     // Add date picker
-    var post_dtPick = new datePicker($('#post_dt').get(0));
+    const post_dtPick = new datePicker($('#post_dt').get(0));
     post_dtPick.img_top = '1.5em';
     post_dtPick.draw();
@@ -152,5 +143,5 @@
     $('a.attachment-remove').click(function() {
       this.href = '';
-      var m_name = $(this).parents('ul').find('li:first>a').attr('title');
+      const m_name = $(this).parents('ul').find('li:first>a').attr('title');
       if (window.confirm(dotclear.msg.confirm_remove_attachment.replace('%s', m_name))) {
         var f = $('#attachment-remove-hide').get(0);
@@ -164,4 +155,5 @@
   $('#comments').onetabload(function() {
     $.expandContent({
+      line: $('#form-comments .comments-list tr:not(.line)'),
       lines: $('#form-comments .comments-list tr.line'),
       callback: dotclear.viewCommentContent
@@ -176,4 +168,5 @@
   $('#trackbacks').onetabload(function() {
     $.expandContent({
+      line: $('#form-trackbacks .comments-list tr:not(.line)'),
       lines: $('#form-trackbacks .comments-list tr.line'),
       callback: dotclear.viewCommentContent
Index: admin/js/_posts_actions.js
===================================================================
--- admin/js/_posts_actions.js	(revision 3706)
+++ admin/js/_posts_actions.js	(revision 3880)
@@ -3,5 +3,5 @@
 
 $(function() {
-  var new_auth_id = $('#new_auth_id');
+  const new_auth_id = $('#new_auth_id');
   if (new_auth_id.length) {
     new_auth_id.autocomplete(usersList, {
Index: admin/js/_posts_list.js
===================================================================
--- admin/js/_posts_list.js	(revision 3706)
+++ admin/js/_posts_list.js	(revision 3880)
@@ -2,50 +2,37 @@
 'use strict';
 
-dotclear.viewPostContent = function(line, action) {
+dotclear.viewPostContent = function(line, action, e) {
   action = action || 'toggle';
-  var postId = $(line).attr('id').substr(1);
-  var tr = document.getElementById('pe' + postId);
+  if ($(line).attr('id') == undefined) {
+    return;
+  }
 
-  if (!tr && (action == 'toggle' || action == 'open')) {
-    tr = document.createElement('tr');
-    tr.id = 'pe' + postId;
-    var td = document.createElement('td');
-    td.colSpan = 8;
-    td.className = 'expand';
-    tr.appendChild(td);
+  const postId = $(line).attr('id').substr(1);
+  const lineId = `pe${postId}`;
+  let tr = document.getElementById(lineId);
 
-    // Get post content
-    $.get('services.php', {
-      f: 'getPostById',
-      id: postId,
-      post_type: ''
-    }, function(data) {
-      var rsp = $(data).children('rsp')[0];
-
-      if (rsp.attributes[0].value == 'ok') {
-        var post = $(rsp).find('post_display_content').text();
-        var post_excerpt = $(rsp).find('post_display_excerpt').text();
-        var res = '';
-
-        if (post) {
-          if (post_excerpt) {
-            res += post_excerpt + '<hr />';
-          }
-          res += post;
-          $(td).append(res);
-        }
+  if (!tr) {
+    // Get post content if possible
+    dotclear.getEntryContent(postId, function(content) {
+      if (content) {
+        // Content found
+        tr = document.createElement('tr');
+        tr.id = lineId;
+        const td = document.createElement('td');
+        td.colSpan = $(line).children('td').length;
+        td.className = 'expand';
+        tr.appendChild(td);
+        $(td).append(content);
+        $(line).addClass('expand');
+        line.parentNode.insertBefore(tr, line.nextSibling);
       } else {
-        window.alert($(rsp).find('message').text());
+        $(line).toggleClass('expand');
       }
+    }, {
+      clean: (e.metaKey)
     });
-
-    $(line).addClass('expand');
-    line.parentNode.insertBefore(tr, line.nextSibling);
-  } else if (tr && tr.style.display == 'none' && (action == 'toggle' || action == 'open')) {
-    $(tr).css('display', 'table-row');
-    $(line).addClass('expand');
-  } else if (tr && tr.style.display != 'none' && (action == 'toggle' || action == 'close')) {
-    $(tr).css('display', 'none');
-    $(line).removeClass('expand');
+  } else {
+    $(tr).toggle();
+    $(line).toggleClass('expand');
   }
 };
Index: admin/js/_preferences-dragdrop.js
===================================================================
--- admin/js/_preferences-dragdrop.js	(revision 3706)
+++ admin/js/_preferences-dragdrop.js	(revision 3880)
@@ -13,5 +13,5 @@
   });
   $('#favs-form').submit(function() {
-    var order = [];
+    let order = [];
     $('#my-favs ul li input.position').each(function() {
       order.push(this.name.replace(/^order\[([^\]]+)\]$/, '$1'));
Index: admin/js/_preferences.js
===================================================================
--- admin/js/_preferences.js	(revision 3706)
+++ admin/js/_preferences.js	(revision 3880)
@@ -6,5 +6,5 @@
     return;
   }
-  var user_email = $('#user_email').val();
+  const user_email = $('#user_email').val();
   $('#user-form').submit(function() {
     var e = this.elements.cur_pwd;
Index: admin/js/_users.js
===================================================================
--- admin/js/_users.js	(revision 3706)
+++ admin/js/_users.js	(revision 3880)
@@ -8,9 +8,9 @@
   dotclear.condSubmit('#form-users input[type="checkbox"]', '#form-users #do-action');
   $('#form-users').submit(function() {
-    var action = $(this).find('select[name="action"]').val();
-    var user_ids = [];
-    var nb_posts = [];
-    var i;
-    var msg_cannot_delete = false;
+    const action = $(this).find('select[name="action"]').val();
+    let user_ids = [];
+    let nb_posts = [];
+    let i;
+    let msg_cannot_delete = false;
 
     $(this).find('input[name="users[]"]').each(function() {
@@ -35,5 +35,5 @@
     }
 
-    var selectfields = 0;
+    let selectfields = 0;
     for (i = 0; i < user_ids.length; i++) {
       selectfields += user_ids[i].checked;
Index: admin/js/_users_actions.js
===================================================================
--- admin/js/_users_actions.js	(revision 3706)
+++ admin/js/_users_actions.js	(revision 3880)
@@ -5,10 +5,10 @@
   return this.each(function() {
 
-    var perms = {};
-    var re = /^perm\[(.+?)\]\[(.+?)\]$/;
-    var e, prop;
+    let perms = {};
+    const re = /^perm\[(.+?)\]\[(.+?)\]$/;
+    let e, prop;
 
-    var admin = function(E, perms, re) {
-      var P = E.name.match(re);
+    const admin = function(E, perms, re) {
+      const P = E.name.match(re);
 
       perms[P[1]].usage.checked = E.checked;
@@ -29,6 +29,6 @@
     };
 
-    var contentadmin = function(E, perms, re) {
-      var P = E.name.match(re);
+    const contentadmin = function(E, perms, re) {
+      const P = E.name.match(re);
 
       perms[P[1]].usage.checked = E.checked;
@@ -41,6 +41,6 @@
     };
 
-    var mediaadmin = function(E, perms, re) {
-      var P = E.name.match(re);
+    const mediaadmin = function(E, perms, re) {
+      const P = E.name.match(re);
 
       perms[P[1]].media.checked = E.checked;
@@ -50,5 +50,5 @@
 
     // Building a nice object of form elements
-    for (var i = 0; i < this.elements.length; i++) {
+    for (let i = 0; i < this.elements.length; i++) {
       e = this.elements[i];
       if (e.name == undefined) {
@@ -65,7 +65,7 @@
     }
     // Populate states
-    for (var blog in perms) {
+    for (let blog in perms) {
       // Loop on blog
-      for (var element in perms[blog]) {
+      for (let element in perms[blog]) {
         // Loop on permission
         e = perms[blog][element];
Index: admin/js/color-picker.js
===================================================================
--- admin/js/color-picker.js	(revision 3706)
+++ admin/js/color-picker.js	(revision 3880)
@@ -8,7 +8,5 @@
 jQuery.fn.colorPicker = function() {
   $(this).each(function() {
-    var colbox, f;
-    colbox = $('#jquery-colorpicker')[0];
-
+    let colbox = $('#jquery-colorpicker')[0];
     if (colbox == undefined) {
       colbox = document.createElement('div');
@@ -23,12 +21,12 @@
       $('body').append(colbox);
     }
-    f = $.farbtastic(colbox);
+    const f = $.farbtastic(colbox);
     f.linkTo(this);
 
-    var handler = $(document.createElement('img'));
+    const handler = $(document.createElement('img'));
     handler.attr('src', 'images/picker.png');
     handler.attr('alt', '');
 
-    var span = $(document.createElement('span'));
+    const span = $(document.createElement('span'));
 
     if ($(this).css('position') == 'absolute') {
@@ -54,10 +52,10 @@
     });
 
-    var This = this;
+    const This = this;
     handler.click(function() {
       if ($(colbox).css('display') == 'none' || this != colbox.linkedto) {
         f.linkTo(This);
         This.focus();
-        var offset = $(This).offset();
+        const offset = $(This).offset();
         $(colbox).css({
           zIndex: 1000,
Index: admin/js/common.js
===================================================================
--- admin/js/common.js	(revision 3843)
+++ admin/js/common.js	(revision 3882)
@@ -53,8 +53,12 @@
     if (event.shiftKey) {
       if (dotclear.lastclicked != '') {
-        var range;
-        var trparent = $(this).parents('tr');
-        if (trparent.nextAll('#' + dotclear.lastclicked).length != 0) range = trparent.nextUntil('#' + dotclear.lastclicked);
-        else range = trparent.prevUntil('#' + dotclear.lastclicked);
+        let range;
+        const trparent = $(this).parents('tr');
+        const id = `#${dotclear.lastclicked}`;
+        if (trparent.nextAll(id).length != 0) {
+          range = trparent.nextUntil(id);
+        } else {
+          range = trparent.prevUntil(id);
+        }
         range.find('input[type=checkbox]').setChecked(dotclear.lastclickedstatus);
         this.checked = dotclear.lastclickedstatus;
@@ -68,5 +72,5 @@
 };
 jQuery.fn.toggleWithLegend = function(target, s) {
-  var defaults = {
+  const defaults = {
     img_on_txt: dotclear.img_plus_txt,
     img_on_alt: dotclear.img_plus_alt,
@@ -81,19 +85,19 @@
     reverse_user_pref: false // Reverse cookie behavior
   };
-  var p = jQuery.extend(defaults, s);
+  const p = jQuery.extend(defaults, s);
   if (!target) {
     return this;
   }
-  var set_cookie = p.hide ^ p.reverse_cookie;
+  const set_cookie = p.hide ^ p.reverse_cookie;
   if (p.cookie && jQuery.cookie(p.cookie)) {
     p.hide = p.reverse_cookie;
   }
-  var set_user_pref = p.hide ^ p.reverse_user_pref;
+  let set_user_pref = p.hide ^ p.reverse_user_pref;
   if (p.user_pref && p.unfolded_sections !== undefined && (p.user_pref in p.unfolded_sections)) {
     p.hide = p.reverse_user_pref;
   }
-  var toggle = function(i, speed) {
+  const toggle = function(i, speed) {
     speed = speed || 0;
-    var b = $(i).get(0);
+    const b = $(i).get(0);
     if (p.hide) {
       b.firstChild.data = p.img_on_txt;
@@ -125,13 +129,13 @@
   };
   return this.each(function() {
-    var b = document.createElement('button');
+    const b = document.createElement('button');
     b.setAttribute('type', 'button');
     b.className = 'details-cmd';
     b.value = p.img_on_txt;
     b.setAttribute('aria-label', p.img_on_alt);
-    var t = document.createTextNode(p.img_on_txt);
+    const t = document.createTextNode(p.img_on_txt);
     b.appendChild(t);
 
-    var ctarget = p.legend_click ? this : b;
+    const ctarget = p.legend_click ? this : b;
     $(ctarget).css('cursor', 'pointer');
     if (p.legend_click) {
@@ -140,19 +144,10 @@
     $(ctarget).click(function(e) {
       if (p.user_pref && set_user_pref) {
-        if (p.hide ^ p.reverse_user_pref) {
-          jQuery.post('services.php', {
-            'f': 'setSectionFold',
-            'section': p.user_pref,
-            'value': 1,
-            xd_check: dotclear.nonce
-          }, function() {});
-        } else {
-          jQuery.post('services.php', {
-            'f': 'setSectionFold',
-            'section': p.user_pref,
-            'value': 0,
-            xd_check: dotclear.nonce
-          }, function() {});
-        }
+        jQuery.post('services.php', {
+          f: 'setSectionFold',
+          section: p.user_pref,
+          value: (p.hide ^ p.reverse_user_pref ? 1 : 0),
+          xd_check: dotclear.nonce
+        }, function() {});
         jQuery.cookie(p.user_pref, '', {
           expires: -1
@@ -167,37 +162,35 @@
   });
 };
+
 (function($) {
   $.expandContent = function(opts) {
-    var defaults = {};
-    $.expandContent.options = $.extend({}, defaults, opts);
     if (opts == undefined || opts.callback == undefined || !$.isFunction(opts.callback)) {
       return;
     }
     if (opts.line != undefined) {
-      multipleExpander(opts.line, opts.lines);
+      multipleExpander(opts.line, opts.lines, opts.callback);
     }
     opts.lines.each(function() {
-      singleExpander(this);
-    });
-  };
-  var singleExpander = function singleExpander(line) {
-    $('<button type="button" class="details-cmd" aria-label="' + dotclear.img_plus_alt + '">' + dotclear.img_plus_txt + '</button>').click(function (e) {
+      singleExpander(this, opts.callback);
+    });
+  };
+  const singleExpander = function(line, callback) {
+    $(`<button type="button" class="details-cmd" aria-label="${dotclear.img_plus_alt}">${dotclear.img_plus_txt}</button>`).click(function(e) {
       toggleArrow(this);
-      $.expandContent.options.callback.call(this, line);
+      callback(line, '', e);
       e.preventDefault();
     }).prependTo($(line).children().get(0)); // first td
   };
-  var multipleExpander = function multipleExpander(line, lines) {
-    $('<button type="button" class="details-cmd" aria-label="' + dotclear.img_plus_alt + '">' + dotclear.img_plus_txt + '</button>').click(function (e) {
-      var that = this;
+  const multipleExpander = function(line, lines, callback) {
+    $(`<button type="button" class="details-cmd" aria-label="${dotclear.img_plus_alt}">${dotclear.img_plus_txt}</button>`).click(function(e) {
       var action = toggleArrow(this);
       lines.each(function() {
         toggleArrow(this.firstChild.firstChild, action);
-        $.expandContent.options.callback.call(that, this, action);
+        callback(this, action, e);
       });
       e.preventDefault();
     }).prependTo($(line).children().get(0)); // first td
   };
-  var toggleArrow = function toggleArrow(button, action) {
+  const toggleArrow = function(button, action) {
     action = action || '';
     if (action == '') {
@@ -224,5 +217,6 @@
     return this;
   }
-  var p = {
+  let select = $();
+  const p = {
     img_on_txt: dotclear.img_plus_txt,
     img_on_alt: dotclear.img_plus_alt,
@@ -230,6 +224,6 @@
     img_off_alt: dotclear.img_minus_alt
   };
-  var This = this;
-  var toggle = function() {
+  const This = this;
+  const toggle = function() {
     $('#content').toggleClass('with-help');
     if (document.all) {
@@ -244,5 +238,5 @@
     return false;
   };
-  var sizeBox = function() {
+  const sizeBox = function() {
     This.css('height', 'auto');
     if ($('#wrapper').height() > This.height()) {
@@ -250,8 +244,8 @@
     }
   };
-  var textToggler = function(o) {
-    var b = $('<button type="button" class="details-cmd" aria-label="' + p.img_on_alt + '">' + p.img_on_txt + '</button>');
+  const textToggler = function(o) {
+    const b = $(`<button type="button" class="details-cmd" aria-label="${p.img_on_alt}">${p.img_on_txt}</button>`);
     o.css('cursor', 'pointer');
-    var hide = true;
+    let hide = true;
     o.prepend(' ').prepend(b);
     o.click(function() {
@@ -265,5 +259,5 @@
       });
       hide = !hide;
-      var img = $(this).find('button.details-cmd');
+      const img = $(this).find('button.details-cmd');
       if (!hide) {
         img.html(p.img_off_txt);
@@ -284,6 +278,5 @@
   this.find('h4:first').nextAll('*:not(h4)').hide();
   sizeBox();
-  var img = $('<p id="help-button"><span><a href="">' + dotclear.msg.help + '</a></span></p>');
-  var select = $();
+  const img = $(`<p id="help-button"><span><a href="">${dotclear.msg.help}</a></span></p>`);
   img.click(function(e) {
     e.preventDefault();
@@ -292,7 +285,7 @@
   $('#content').append(img);
   // listen for scroll
-  var peInPage = $('#help-button').offset().top;
+  const peInPage = $('#help-button').offset().top;
   $('#help-button').addClass('floatable');
-  var peInFloat = $('#help-button').offset().top - $(window).scrollTop();
+  const peInFloat = $('#help-button').offset().top - $(window).scrollTop();
   $('#help-button').removeClass('floatable');
   $(window).scroll(function() {
@@ -305,11 +298,13 @@
   return this;
 };
+
 /* Dotclear common object
 -------------------------------------------------------- */
-var dotclear = {
+const dotclear = {
   msg: {},
+
   enterKeyInForm: function(frm_id, ok_id, cancel_id) {
     $(frm_id + ':not(' + cancel_id + ')').keyup(function(e) {
-      if (e.key == 'Enter') {
+      if ((e.key == 'Enter') && ($(ok_id).prop('disabled') !== true)) {
         e.preventDefault();
         e.stopPropagation();
@@ -318,6 +313,7 @@
     });
   },
+
   condSubmit: function(chkboxes, target) {
-    var checkboxes = $(chkboxes),
+    const checkboxes = $(chkboxes),
       submitButt = $(target);
     if (checkboxes === undefined || submitButt === undefined) {
@@ -341,16 +337,17 @@
     });
   },
+
   hideLockable: function() {
     $('div.lockable').each(function() {
-      var current_lockable_div = this;
+      const current_lockable_div = this;
       $(this).find('p.form-note').hide();
       $(this).find('input').each(function() {
         this.disabled = true;
-        $(this).width(($(this).width() - 14) + 'px');
-        var imgE = document.createElement('img');
+        $(this).width(`${$(this).width() - 14}px`);
+        const imgE = document.createElement('img');
         imgE.src = 'images/locker.png';
         imgE.style.position = 'absolute';
         imgE.style.top = '1.8em';
-        imgE.style.left = ($(this).width() + 14) + 'px';
+        imgE.style.left = `${$(this).width() + 14}px`;
         imgE.alt = dotclear.msg.click_to_unlock;
         $(imgE).css('cursor', 'pointer');
@@ -368,8 +365,9 @@
     });
   },
+
   checkboxesHelpers: function(e, target, c, s) {
     $(e).append(document.createTextNode(dotclear.msg.to_select));
     $(e).append(document.createTextNode(' '));
-    $('<button type="button" class="checkbox-helper select-all">' + dotclear.msg.select_all + '</button>').click(function() {
+    $(`<button type="button" class="checkbox-helper select-all">${dotclear.msg.select_all}</button>`).click(function() {
       if (target !== undefined) {
         target.check();
@@ -383,5 +381,5 @@
     }).appendTo($(e));
     $(e).append(document.createTextNode(' '));
-    $('<button type="button" class="checkbox-helper select-none">' + dotclear.msg.no_selection + '</button>').click(function() {
+    $(`<button type="button" class="checkbox-helper select-none">${dotclear.msg.no_selection}</button>`).click(function() {
       if (target !== undefined) {
         target.unCheck();
@@ -395,5 +393,5 @@
     }).appendTo($(e));
     $(e).append(document.createTextNode(' '));
-    $('<button type="button" class="checkbox-helper select-reverse">' + dotclear.msg.invert_sel + '</button>').click(function() {
+    $(`<button type="button" class="checkbox-helper select-reverse">${dotclear.msg.invert_sel}</button>`).click(function() {
       if (target !== undefined) {
         target.toggleCheck();
@@ -407,11 +405,12 @@
     }).appendTo($(e));
   },
+
   postsActionsHelper: function() {
     $('#form-entries').submit(function() {
-      var action = $(this).find('select[name="action"]').val();
+      const action = $(this).find('select[name="action"]').val();
       if (action === undefined) {
         return;
       }
-      var checked = false;
+      let checked = false;
       $(this).find('input[name="entries[]"]').each(function() {
         if (this.checked) {
@@ -428,8 +427,9 @@
     });
   },
+
   commentsActionsHelper: function() {
     $('#form-comments').submit(function() {
-      var action = $(this).find('select[name="action"]').val();
-      var checked = false;
+      const action = $(this).find('select[name="action"]').val();
+      let checked = false;
       $(this).find('input[name="comments[]"]').each(function() {
         if (this.checked) {
@@ -445,6 +445,105 @@
       return true;
     });
-  }
-};
+  },
+
+  outgoingLinks: function(target) {
+    $(target).filter(function() {
+      return ((this.hostname && this.hostname != location.hostname && !$(this).hasClass('modal') && !$(this).hasClass('modal-image')) || $(this).hasClass('outgoing'));
+    }).each(function() {
+      $(this).prop('title', `${$(this).prop('title')} (${dotclear.msg.new_window})`);
+      if (!$(this).hasClass('outgoing')) {
+        $(this).append('&nbsp;<img class="outgoing-js" src="images/outgoing-link.svg" alt=""/>');
+      }
+    }).click(function(e) {
+      e.preventDefault();
+      window.open($(this).attr('href'));
+    });
+  },
+
+  badge: function($elt, options = null) {
+    // Cope with selector given as string or DOM element rather than a jQuery object
+    if (typeof $elt === 'string' || $elt instanceof Element) {
+      $elt = $($elt);
+    }
+
+    // Return if elt does not exist
+    if (!$elt.length) return;
+
+    // Cope with options
+    const opt = $.extend({
+      /* sibling: define if the given element is a sibling of the badge or it's parent
+       *  true: use $elt.after() to add badge
+       *  false: use $elt.parent().append() to add badge (default)
+       */
+      sibling: false,
+      /* id: badge unique class
+       *  this class will be used to delete all corresponding badge (used for removing and updating)
+       */
+      id: 'default',
+      /* remove: will remove the badge if set to true */
+      remove: false,
+      /* value: badge value */
+      value: null,
+      /* inline: if set to true, the badge is an inline element (useful for menu item) rather than a block */
+      inline: false,
+      /* icon: if set to true, the badge is attached to a dashboard icon (needed for correct positionning) */
+      icon: false,
+      /* type: Override default background (which may vary)
+       *  by default badge background are soft grey for dashboard icons (see opt.icon) and bright red for all other elements
+       *  possible values:
+       *    'std':  bright red
+       *    'info': blue
+       *    'soft': soft grey
+       */
+      type: '',
+      /* left: display badge on the left rather than on the right (unused for inline badge) */
+      left: false,
+      /* noborder: do not display the badge border */
+      noborder: false,
+      /* small: use a smaller font-size */
+      small: false,
+      /* classes: additionnal badge classes */
+      classes: ''
+    }, options);
+
+    // Set some constants
+    const classid = `span.badge.badge-${opt.id}`; // Pseudo unique class
+
+    // Set badgeable class to elt parent's (if sibling) or elt itself, if it is necessary
+    const $parent = (opt.sibling ? $elt.parent() : $elt);
+    if (!opt.inline && !opt.remove && !$parent.hasClass('badgeable')) {
+      $parent.addClass('badgeable');
+    }
+
+    // Remove existing badge if exists
+    const $badge = (opt.sibling ? $parent.children(classid) : $elt.children(classid));
+    if ($badge.length) {
+      $badge.remove();
+    }
+
+    // Add the new badge if any
+    if (!opt.remove && opt.value !== null) {
+      // Compose badge classes
+      const cls = `badge badge-${opt.id} \
+${opt.inline ? 'badge-inline' : 'badge-block'}\
+${opt.icon ? ' badge-icon' : ''}\
+${opt.type !== '' ? ` badge-${opt.type}` : ''}\
+${opt.left ? ' badge-left' : ''}\
+${opt.noborder ? ' badge-noborder' : ''}\
+${opt.small ? ' badge-small' : ''}\
+${opt.classes !== '' ? ` ${opt.classes}` : ''}`;
+      // Compose badge
+      const xml = `<span class="${cls}" aria-hidden="true">${opt.value}</span>`;
+      if (opt.sibling) {
+        // Add badge after it's sibling
+        $elt.after(xml);
+      } else {
+        // Append badge to the elt
+        $elt.append(xml);
+      }
+    }
+  }
+};
+
 /* On document ready
 -------------------------------------------------------- */
@@ -454,21 +553,11 @@
   $('body').contents().each(function() {
     if (this.nodeType == 8) {
-      var data = this.data;
+      let data = this.data;
       data = data.replace(/ /g, '&nbsp;').replace(/\n/g, '<br/>');
-      $('<span class="tooltip" aria-hidden="true">' + $('#footer a').prop('title') + data + '</span>').appendTo('#footer a');
+      $(`<span class="tooltip" aria-hidden="true">${$('#footer a').prop('title')}${data}</span>`).appendTo('#footer a');
     }
   });
   // manage outgoing links
-  $('a').filter(function() {
-    return ((this.hostname && this.hostname != location.hostname && !$(this).hasClass('modal') && !$(this).hasClass('modal-image')) || $(this).hasClass('outgoing'));
-  }).each(function() {
-    $(this).prop('title', $(this).prop('title') + ' (' + dotclear.msg.new_window + ')');
-    if (!$(this).hasClass('outgoing')) {
-      $(this).append('&nbsp;<img class="outgoing-js" src="images/outgoing-link.svg" alt=""/>');
-    }
-  }).click(function(e) {
-    e.preventDefault();
-    window.open($(this).attr('href'));
-  });
+  dotclear.outgoingLinks('a');
   // Popups: dealing with Escape key fired
   $('#dotclear-admin.popup').keyup(function(e) {
@@ -483,5 +572,5 @@
     this.form.submit();
   });
-  var menu_settings = {
+  const menu_settings = {
     img_on_src: dotclear.img_menu_off,
     img_off_src: dotclear.img_menu_on,
@@ -507,5 +596,5 @@
   $('p.success,p.warning,p.error,div.error').each(function() {
     $(this).addClass('close-notice-parent');
-    $(this).append('<button class="close-notice" type="button"><img src="images/close.png" alt="' + dotclear.msg.close_notice + '" /></button>');
+    $(this).append(`<button class="close-notice" type="button"><img src="images/close.png" alt="${dotclear.msg.close_notice}" /></button>`);
   });
   $('button.close-notice').click(function(e) {
@@ -515,5 +604,5 @@
   // Password
   $('form:has(input[type=password][name=your_pwd])').submit(function() {
-    var e = this.elements.your_pwd;
+    const e = this.elements.your_pwd;
     if (e.value == '') {
       $(e).addClass('missing').focusout(function() {
@@ -555,5 +644,5 @@
   }
   // Main menu collapser
-  var objMain = $('#wrapper');
+  const objMain = $('#wrapper');
 
   function showSidebar() {
@@ -573,6 +662,5 @@
   }
   // Sidebar separator
-  var objSeparator = $('#collapser');
-  objSeparator.click(function(e) {
+  $('#collapser').click(function(e) {
     e.preventDefault();
     if (objMain.hasClass('hide-mm')) {
Index: admin/js/confirm-close.js
===================================================================
--- admin/js/confirm-close.js	(revision 3706)
+++ admin/js/confirm-close.js	(revision 3880)
@@ -4,5 +4,5 @@
 function confirmClose() {
   if (arguments.length > 0) {
-    for (var i = 0; i < arguments.length; i++) {
+    for (let i = 0; i < arguments.length; i++) {
       this.forms_id.push(arguments[i]);
     }
@@ -19,13 +19,12 @@
     // Store current form's element's values
 
-    var formsInPage = this.getForms();
-    var f, e;
-    var This = this;
+    const formsInPage = this.getForms();
+    const This = this;
     this.forms = [];
-    for (var i = 0; i < formsInPage.length; i++) {
-      f = formsInPage[i];
-      var tmpForm = [];
-      for (var j = 0; j < f.elements.length; j++) {
-        e = this.getFormElementValue(f[j]);
+    for (let i = 0; i < formsInPage.length; i++) {
+      const f = formsInPage[i];
+      let tmpForm = [];
+      for (let j = 0; j < f.elements.length; j++) {
+        const e = this.getFormElementValue(f[j]);
         if (e != undefined) {
           tmpForm.push(e);
@@ -48,16 +47,15 @@
     }
 
-    var formsInPage = this.getForms();
-    var f, e, i, j;
-    for (i = 0; i < formsInPage.length; i++) {
-      f = formsInPage[i];
+    const formsInPage = this.getForms();
+    for (let i = 0; i < formsInPage.length; i++) {
+      const f = formsInPage[i];
       var tmpForm = [];
-      for (j = 0; j < f.elements.length; j++) {
-        e = this.getFormElementValue(f[j]);
+      for (let j = 0; j < f.elements.length; j++) {
+        const e = this.getFormElementValue(f[j]);
         if (e != undefined) {
           tmpForm.push(e);
         }
       }
-      for (j = 0; j < this.forms[i].length; j++) {
+      for (let j = 0; j < this.forms[i].length; j++) {
         if (this.forms[i][j] != tmpForm[j]) {
           return false;
@@ -77,8 +75,7 @@
 
     if (this.forms_id.length > 0) {
-      var res = [];
-      var f;
-      for (var i = 0; i < this.forms_id.length; i++) {
-        f = document.getElementById(this.forms_id[i]);
+      let res = [];
+      for (let i = 0; i < this.forms_id.length; i++) {
+        const f = document.getElementById(this.forms_id[i]);
         if (f != undefined) {
           res.push(f);
@@ -134,5 +131,5 @@
 
   getFormRadioValue: function(e) {
-    for (var i = 0; i < e.length; i++) {
+    for (let i = 0; i < e.length; i++) {
       if (e[i].checked) {
         return e[i].value;
@@ -145,5 +142,5 @@
 };
 
-var confirmClosePage = new confirmClose();
+let confirmClosePage = new confirmClose();
 
 chainHandler(window, 'onload', function() {
Index: admin/js/date-picker.js
===================================================================
--- admin/js/date-picker.js	(revision 3706)
+++ admin/js/date-picker.js	(revision 3880)
@@ -21,6 +21,8 @@
   this.oTable.className = 'date-picker';
 
-  var cur = 1;
-  var oRow, oHeading, oSpan;
+  let cur = 1;
+  let oRow;
+  let oHeading;
+  let oSpan;
 
   // Set title
@@ -32,5 +34,5 @@
   oHeading.className = 'date-picker-month';
 
-  var nav = document.createElement('span');
+  let nav = document.createElement('span');
   nav.appendChild(document.createTextNode(String.fromCharCode(171)));
   nav.fn = this.changeMonth;
@@ -97,7 +99,6 @@
   // Create legend
   oRow = document.createElement('tr');
-  var cday;
-  for (i = 0; i < this.days.length; i++) {
-    cday = this.days[i].substring(0, 1).toUpperCase();
+  for (let i = 0; i < this.days.length; i++) {
+    const cday = this.days[i].substring(0, 1).toUpperCase();
     oHeading = document.createElement('th');
     oHeading.appendChild(document.createTextNode(cday));
@@ -108,8 +109,8 @@
 
   // Create 6 rows of 7 cols for days
-  for (var i = 0; i < 6; i++) {
+  for (let i = 0; i < 6; i++) {
     oRow = document.createElement('tr');
 
-    for (var j = 0; j < 7; j++) {
+    for (let j = 0; j < 7; j++) {
       this.oDates[cur] = document.createElement('td');
       this.oDates[cur].appendChild(document.createTextNode(
@@ -243,9 +244,9 @@
       this.months[this.month - 1]));
 
-    var firstDay = this.firstDay();
-    var nbDays = this.numberOfDays();
+    const firstDay = this.firstDay();
+    const nbDays = this.numberOfDays();
 
     // Empty days
-    for (var i = 1; i <= 42; i++) {
+    for (let i = 1; i <= 42; i++) {
       while (this.oDates[i].hasChildNodes()) {
         this.oDates[i].removeChild(this.oDates[i].firstChild);
@@ -259,6 +260,6 @@
 
     // Insert days from the first day to the last
-    for (i = 1; i <= nbDays; i++) {
-      var j = firstDay + i - 1;
+    for (let i = 1; i <= nbDays; i++) {
+      const j = firstDay + i - 1;
 
       while (this.oDates[j].hasChildNodes()) {
@@ -316,6 +317,5 @@
 
   changeMonth: function(dir) {
-    var m = this.month;
-    m = m + dir;
+    const m = this.month + dir;
 
     if (m > 12) {
@@ -346,7 +346,7 @@
 
   sendDate: function(d) {
-    var m = this.month;
-    var hour = this.oHour.value * 1;
-    var minute = this.oMinute.value * 1;
+    let m = this.month;
+    let hour = this.oHour.value * 1;
+    let minute = this.oMinute.value * 1;
 
     if (hour < 0 || hour > 23 || isNaN(hour)) {
@@ -370,15 +370,15 @@
     }
 
-    this.target.value = this.year + '-' + m + '-' + d + ' ' + hour + ':' + minute;
+    this.target.value = `${this.year}-${m}-${d} ${hour}:${minute}`;
     this.close();
   },
 
   sendNow: function() {
-    var dt = new Date();
-    var y = dt.getFullYear();
-    var m = dt.getMonth() + 1;
-    var d = dt.getDate();
-    var h = dt.getHours();
-    var i = dt.getMinutes();
+    let dt = new Date();
+    const y = dt.getFullYear();
+    let m = dt.getMonth() + 1;
+    let d = dt.getDate();
+    let h = dt.getHours();
+    let i = dt.getMinutes();
 
     if (m < 10) {
@@ -395,5 +395,5 @@
     }
 
-    this.target.value = y + '-' + m + '-' + d + ' ' + h + ':' + i;
+    this.target.value = `${y}-${m}-${d} ${h}:${i}`;
     this.close();
   },
@@ -404,5 +404,5 @@
 
   numberOfDays: function() {
-    var res = 31;
+    let res = 31;
     if (this.month == 4 || this.month == 6 || this.month == 9 ||
       this.month == 11) {
@@ -420,6 +420,6 @@
 
   firstDay: function() {
-    var dt = new Date(this.year, this.month - 1, 1);
-    var res = dt.getDay();
+    let dt = new Date(this.year, this.month - 1, 1);
+    let res = dt.getDay();
 
     if (res == 0) {
@@ -432,6 +432,6 @@
   show: function() {
     // Parsing target value
-    var re = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;
-    var match = re.exec(this.target.value);
+    const re = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;
+    const match = re.exec(this.target.value);
     if (match) {
       this.year = match[1] * 1;
@@ -441,5 +441,5 @@
       this.minute = match[5] * 1;
     } else {
-      var dt = new Date();
+      let dt = new Date();
       this.year = dt.getFullYear();
       this.month = dt.getMonth() + 1;
@@ -457,6 +457,6 @@
 
   setPosition: function() {
-    var t_x = this.findPosX(this.target);
-    var t_y = this.findPosY(this.target);
+    const t_x = this.findPosX(this.target);
+    const t_y = this.findPosY(this.target);
 
     this.oTable.style.position = 'absolute';
@@ -467,5 +467,5 @@
 
   findPosX: function(obj) {
-    var curleft = 0;
+    let curleft = 0;
     if (obj.offsetParent) {
       while (1) {
@@ -483,5 +483,5 @@
 
   findPosY: function(obj) {
-    var curtop = 0;
+    let curtop = 0;
     if (obj.offsetParent) {
       while (1) {
@@ -499,5 +499,5 @@
 
   draw: function() {
-    var imgE = document.createElement('img');
+    const imgE = document.createElement('img');
     imgE.src = this.img_src;
     imgE.alt = this.img_alt;
Index: admin/js/filter-controls.js
===================================================================
--- admin/js/filter-controls.js	(revision 3706)
+++ admin/js/filter-controls.js	(revision 3880)
@@ -3,11 +3,11 @@
 
 $(function() {
-  var reset_url = '?';
+  let reset_url = '?';
   if (dotclear.filter_reset_url != undefined) {
     reset_url = dotclear.filter_reset_url;
   }
 
-  var $filtersform = $('#filters-form');
-  $filtersform.before('<p><a id="filter-control" class="form-control" href="' + reset_url + '" style="display:inline">' + dotclear.msg.filter_posts_list + '</a></p>');
+  const $filtersform = $('#filters-form');
+  $filtersform.before(`<p><a id="filter-control" class="form-control" href="${reset_url}" style="display:inline">${dotclear.msg.filter_posts_list}</a></p>`);
 
   if (dotclear.msg.show_filters == 'false') {
Index: admin/js/jquery/jquery.pageTabs.js
===================================================================
--- admin/js/jquery/jquery.pageTabs.js	(revision 3690)
+++ admin/js/jquery/jquery.pageTabs.js	(revision 3884)
@@ -1,7 +1,9 @@
+/*global jQuery, chainHandler */
+'use strict';
+
 (function($) {
-  'use strict';
 
   $.pageTabs = function(start_tab, opts) {
-    var defaults = {
+    const defaults = {
       containerClass: 'part-tabs',
       partPrefix: 'part-',
@@ -12,7 +14,7 @@
 
     $.pageTabs.options = $.extend({}, defaults, opts);
-    var active_tab = start_tab || '';
-    var hash = $.pageTabs.getLocationHash();
-    var subhash = $.pageTabs.getLocationSubhash();
+    let active_tab = start_tab || '';
+    const hash = $.pageTabs.getLocationHash();
+    const subhash = $.pageTabs.getLocationSubhash();
 
     if (hash !== undefined && hash) {
@@ -25,5 +27,5 @@
     createTabs();
 
-    $('ul li', '.' + $.pageTabs.options.containerClass).click(function(e) {
+    $('ul li', '.' + $.pageTabs.options.containerClass).click(function() {
       if ($(this).hasClass($.pageTabs.options.activeClass)) {
         return;
@@ -34,5 +36,5 @@
       $('.' + $.pageTabs.options.contentClass + '.active').removeClass('active').hide();
 
-      var part_to_activate = $('#' + $.pageTabs.options.partPrefix + getHash($(this).find('a').attr('href')));
+      const part_to_activate = $('#' + $.pageTabs.options.partPrefix + getHash($(this).find('a').attr('href')));
 
       part_to_activate.addClass('active').show();
@@ -45,5 +47,5 @@
     });
 
-    $(window).bind('hashchange onhashchange', function(e) {
+    $(window).bind('hashchange onhashchange', function() {
       $.pageTabs.clickTab($.pageTabs.getLocationHash());
     });
@@ -52,7 +54,7 @@
 
     if (subhash !== undefined) {
-      var elt = document.getElementById(subhash);
+      const elt = document.getElementById(subhash);
       // Tab displayed, now scroll to the sub-part if defined in original document.location (#tab.sub-part)
-      elt.scrollIntoView()
+      elt.scrollIntoView();
       // Give focus to the sub-part if possible
       $('#' + subhash).addClass('focus').focusout(function() {
@@ -65,7 +67,6 @@
   };
 
-  var createTabs = function createTabs() {
-    var lis = [],
-      li_class = '';
+  const createTabs = function createTabs() {
+    let lis = [];
 
     $('.' + $.pageTabs.options.contentClass).each(function() {
@@ -80,6 +81,6 @@
   };
 
-  var getHash = function getHash(href) {
-    var href = href || '';
+  const getHash = function getHash(href) {
+    href = href || '';
 
     return href.replace(/.*#/, '');
@@ -92,5 +93,5 @@
       // try to find anchor in a .multi-part div
       if ($('#' + tab).length == 1) {
-        var div_content = $('#' + tab).parents('.' + $.pageTabs.options.contentClass);
+        const div_content = $('#' + tab).parents('.' + $.pageTabs.options.contentClass);
         if (div_content.length == 1) {
           tab = div_content.attr('id').replace($.pageTabs.options.partPrefix, '');
@@ -110,10 +111,10 @@
   $.pageTabs.getLocationHash = function() {
     // Return the URL hash (without subhash — #hash[.subhash])
-    var h = getHash(document.location.hash).split('.');
+    const h = getHash(document.location.hash).split('.');
     return h[0];
   };
   $.pageTabs.getLocationSubhash = function() {
     // Return the URL subhash if present (without hash — #hash[.subhash])
-    var sh = getHash(document.location.hash).split('.');
+    const sh = getHash(document.location.hash).split('.');
     return sh[1];
   };
@@ -123,7 +124,7 @@
   this.each(function() {
     if (f) {
-      chainHandler(this, 'tabload', f)
+      chainHandler(this, 'tabload', f);
     } else {
-      var h = this.tabload;
+      const h = this.tabload;
       if (h) {
         h.apply(this);
@@ -139,5 +140,5 @@
       chainHandler(this, 'onetabload', f);
     } else {
-      var h = this.onetabload;
+      const h = this.onetabload;
       if (h != null) {
         h.apply(this);
Index: admin/js/meta-editor.js
===================================================================
--- admin/js/meta-editor.js	(revision 3706)
+++ admin/js/meta-editor.js	(revision 3880)
@@ -54,9 +54,9 @@
     });
 
-    var This = this;
+    const This = this;
 
     this.submit_button = $('<input type="button" value="ok" class="ib meta-helper" />');
     this.submit_button.click(function() {
-      var v = This.meta_dialog.val();
+      const v = This.meta_dialog.val();
       This.addMeta(v);
       return false;
@@ -72,5 +72,5 @@
 
   displayMetaList: function() {
-    var li;
+    let li;
     if (this.meta_list == undefined) {
       this.meta_list = $('<ul class="metaList"></ul>');
@@ -79,10 +79,10 @@
 
     if (this.post_id == false) {
-      var meta = this.splitMetaValues(this.meta_field.val());
+      const meta = this.splitMetaValues(this.meta_field.val());
 
       this.meta_list.empty();
-      for (var i = 0; i < meta.length; i++) {
+      for (let i = 0; i < meta.length; i++) {
         li = $('<li>' + meta[i] + '</li>');
-        var a_remove = $('<button type="button" class="metaRemove meta-helper"><img src="images/trash.png" alt="remove" /></button>');
+        const a_remove = $('<button type="button" class="metaRemove meta-helper"><img src="images/trash.png" alt="remove" /></button>');
         a_remove.get(0).caller = this;
         a_remove.get(0).meta_id = meta[i];
@@ -95,6 +95,6 @@
       }
     } else {
-      var This = this;
-      var params = {
+      const This = this;
+      const params = {
         f: 'getMeta',
         metaType: this.meta_type,
@@ -112,7 +112,7 @@
         This.meta_list.empty();
         data.find('meta').each(function() {
-          var meta_id = $(this).text();
+          const meta_id = $(this).text();
           li = $('<li><a href="' + This.meta_url + $(this).attr('uri') + '">' + meta_id + '</a></li>');
-          a_remove = $('<button type="button" class="metaRemove meta-helper"><img src="images/trash.png" alt="remove" /></button>');
+          const a_remove = $('<button type="button" class="metaRemove meta-helper"><img src="images/trash.png" alt="remove" /></button>');
           a_remove.get(0).caller = This;
           a_remove.get(0).meta_id = meta_id;
@@ -145,5 +145,5 @@
 
   showMetaList: function(list_type, target) {
-    var params = {
+    const params = {
       f: 'getMeta',
       metaType: this.meta_type,
@@ -155,9 +155,9 @@
     }
 
-    var This = this;
+    const This = this;
 
     $.get(this.service_uri, params, function(data) {
 
-      var pl = $('<p class="addMeta"></p>');
+      const pl = $('<p class="addMeta"></p>');
 
       $(target).find('.addMeta').remove();
@@ -165,11 +165,10 @@
       if ($(data).find('meta').length > 0) {
         pl.empty();
-        var meta_link;
 
         $(data).find('meta').each(function(i) {
-          meta_link = $('<button type="button" class="metaItem meta-helper">' + $(this).text() + '</button>');
+          const meta_link = $('<button type="button" class="metaItem meta-helper">' + $(this).text() + '</button>');
           meta_link.get(0).meta_id = $(this).text();
           meta_link.click(function() {
-            var v = This.splitMetaValues(This.meta_dialog.val() + ',' + this.meta_id);
+            const v = This.splitMetaValues(This.meta_dialog.val() + ',' + this.meta_id);
             This.meta_dialog.val(v.join(','));
             return false;
@@ -183,5 +182,5 @@
 
         if (list_type == 'more') {
-          var a_more = $('<button type="button" class="button metaGetMore meta-helper"></button>');
+          const a_more = $('<button type="button" class="button metaGetMore meta-helper"></button>');
           a_more.append(This.text_all + String.fromCharCode(160) + String.fromCharCode(187));
           a_more.click(function() {
@@ -195,8 +194,8 @@
           pl.addClass('hide');
 
-          var pa = $('<p></p>');
+          const pa = $('<p></p>');
           target.append(pa);
 
-          var a = $('<button type="button" class="button metaGetList meta-helper">' + This.text_choose + '</button>');
+          const a = $(`<button type="button" class="button metaGetList meta-helper">${This.text_choose}</button>`);
           a.click(function() {
             $(this).parent().next().removeClass('hide');
@@ -225,5 +224,5 @@
       this.displayMetaList();
     } else {
-      var params = {
+      const params = {
         xd_check: dotclear.nonce,
         f: 'setPostMeta',
@@ -233,5 +232,5 @@
       };
 
-      var This = this;
+      const This = this;
       $.post(this.service_uri, params, function(data) {
         if ($(data).find('rsp').attr('status') == 'ok') {
@@ -247,6 +246,6 @@
   removeMeta: function(meta_id) {
     if (this.post_id == false) {
-      var meta = this.splitMetaValues(this.meta_field.val());
-      for (var i = 0; i < meta.length; i++) {
+      let meta = this.splitMetaValues(this.meta_field.val());
+      for (let i = 0; i < meta.length; i++) {
         if (meta[i] == meta_id) {
           meta.splice(i, 1);
@@ -257,9 +256,9 @@
       this.displayMetaList();
     } else {
-      var text_confirm_msg = this.text_confirm_remove.replace(/%s/, this.meta_type);
+      const text_confirm_msg = this.text_confirm_remove.replace(/%s/, this.meta_type);
 
       if (window.confirm(text_confirm_msg)) {
-        var This = this;
-        var params = {
+        const This = this;
+        const params = {
           xd_check: dotclear.nonce,
           f: 'delMeta',
@@ -290,8 +289,8 @@
     }
 
-    var res = [];
-    var v = str.split(',');
+    let res = [];
+    let v = str.split(',');
     v.sort();
-    for (var i = 0; i < v.length; i++) {
+    for (let i = 0; i < v.length; i++) {
       v[i] = v[i].replace(/^\s*/, '').replace(/\s*$/, '');
       if (v[i] != '' && !inArray(v[i], res)) {
Index: admin/js/services.js
===================================================================
--- admin/js/services.js	(revision 3880)
+++ admin/js/services.js	(revision 3880)
@@ -0,0 +1,174 @@
+/*global $, dotclear */
+'use strict';
+
+/**
+ * Gets the entry (post, page, …) content.
+ *
+ * @param      numeric     postId    The post identifier
+ * @param      function    callback  The callback
+ * @param      object      options   The options
+ */
+dotclear.getEntryContent = function(postId, callback, options) {
+  let res = '';
+  const opt = $.extend({
+    // Entry type (default: post)
+    type: '',
+    // Alert on error
+    alert: true,
+    // Clean content (useful for potential XSS in spam)
+    clean: false,
+    // Cut content after length chars (-1 to not cut)
+    length: -1,
+  }, options);
+
+  // Check callback fn()
+  if (!$.isFunction(callback)) {
+    return;
+  }
+
+  // Get entry content
+  $.get('services.php', {
+      f: 'getPostById',
+      id: postId,
+      post_type: opt.type,
+      xd_check: dotclear.nonce
+    })
+    .done(function(data) {
+      // Response received
+      const rsp = $(data).children('rsp')[0];
+      if (rsp.attributes[0].value == 'ok') {
+        let excerpt = $(rsp).find('post_display_excerpt').text();
+        let content = $(rsp).find('post_display_content').text();
+        if (excerpt || content) {
+          // Clean content if requested
+          if (opt.clean) {
+            const text = document.createElement('textarea');
+            if (excerpt) {
+              text.textContent = excerpt;
+              excerpt = text.innerHTML;
+            }
+            if (content) {
+              text.textContent = content;
+              content = text.innerHTML;
+            }
+          }
+          // Compose full content
+          if (!opt.clean) {
+            content = (excerpt ? `${excerpt}<hr />` : '') + content;
+          }
+          // Cut content if requested
+          if (opt.length > -1) {
+            content = content.substr(0, opt.length);
+          }
+          if (opt.clean && content) {
+            content = `<pre>${content}</pre>`;
+          }
+          res = content;
+        }
+      } else {
+        if (opt.alert) {
+          window.alert($(rsp).find('message').text());
+        }
+      }
+    })
+    .fail(function(jqXHR, textStatus, errorThrown) {
+      // No response
+      window.console.log(`AJAX ${textStatus} (status: ${jqXHR.status} ${errorThrown})`);
+      if (opt.alert) {
+        window.alert('Server error');
+      }
+    })
+    .always(function() {
+      // Finally
+      callback(res);
+    });
+};
+
+/**
+ * Gets the comment content.
+ *
+ * @param      numeric     commentId  The comment identifier
+ * @param      function    callback   The callback
+ * @param      object      options    The options
+ */
+dotclear.getCommentContent = function(commentId, callback, options) {
+  let res = '';
+  const opt = $.extend({
+    // Get comment metadata (email, site, …)
+    metadata: true,
+    // Show IP in metadata
+    ip: true,
+    // Alert on error
+    alert: true,
+    // Clean content (useful for potential XSS in spam)
+    clean: false,
+    // Cut content after length chars (-1 to not cut)
+    length: -1,
+  }, options);
+
+  // Check callback fn()
+  if (!$.isFunction(callback)) {
+    return;
+  }
+
+  // Get comment content
+  $.get('services.php', {
+      f: 'getCommentById',
+      id: commentId,
+      xd_check: dotclear.nonce
+    })
+    .done(function(data) {
+      // Response received
+      const rsp = $(data).children('rsp')[0];
+      if (rsp.attributes[0].value == 'ok') {
+        let content = $(rsp).find('comment_display_content').text();
+        if (content) {
+          // Clean content if requested
+          if (opt.clean) {
+            const text = document.createElement('textarea');
+            text.textContent = content;
+            content = text.innerHTML;
+          }
+          // Cut content if requested
+          if (opt.length > -1) {
+            content = content.substr(0, opt.length);
+          }
+          if (opt.clean && content) {
+            content = `<pre>${content}</pre>`;
+          }
+          // Get metadata (if requested)
+          if (opt.metadata) {
+            const comment_email = $(rsp).find('comment_email').text();
+            const comment_site = $(rsp).find('comment_site').text();
+            const comment_ip = $(rsp).find('comment_ip').text();
+            const comment_spam_disp = $(rsp).find('comment_spam_disp').text();
+
+            content += `<p>
+              <strong>${dotclear.msg.website}</strong> ${comment_site}<br />
+              <strong>${dotclear.msg.email}</strong> ${comment_email}`;
+            if (opt.ip) {
+              content += `<br />
+                <strong>${dotclear.msg.ip_address}</strong> <a href="comments.php?ip=${comment_ip}">${comment_ip}</a>`;
+            }
+            content += `</p>${comment_spam_disp}`;
+          }
+          res = content;
+        }
+      } else {
+        if (opt.alert) {
+          window.alert($(rsp).find('message').text());
+        }
+      }
+    })
+    .fail(function(jqXHR, textStatus, errorThrown) {
+      // No response
+      window.console.log(`AJAX ${textStatus} (status: ${jqXHR.status} ${errorThrown})`);
+      if (opt.alert) {
+        window.alert('Server error');
+      }
+    })
+    .always(function() {
+      // Finally
+      callback(res);
+    });
+};
Index: admin/langs.php
===================================================================
--- admin/langs.php	(revision 3731)
+++ admin/langs.php	(revision 3874)
@@ -158,8 +158,8 @@
     dcPage::jsLoad('js/_langs.js'),
     dcPage::breadcrumb(
-        array(
+        [
             __('System')               => '',
             __('Languages management') => ''
-        ))
+        ])
 );
 
@@ -183,5 +183,5 @@
 
 $locales_content = scandir(DC_L10N_ROOT);
-$tmp             = array();
+$tmp             = [];
 foreach ($locales_content as $v) {
     $c = ($v == '.' || $v == '..' || $v == 'en' || !is_dir(DC_L10N_ROOT . '/' . $v) || !isset($iso_codes[$v]));
@@ -217,5 +217,5 @@
             '<div>' .
             $core->formNonce() .
-            form::hidden(array('locale_id'), html::escapeHTML($k)) .
+            form::hidden(['locale_id'], html::escapeHTML($k)) .
             '<input type="submit" class="delete" name="delete" value="' . __('Delete') . '" /> ' .
                 '</div>' .
@@ -236,5 +236,5 @@
 
 if (!empty($dc_langs) && $is_writable) {
-    $dc_langs_combo = array();
+    $dc_langs_combo = [];
     foreach ($dc_langs as $k => $v) {
         if ($v->link && isset($iso_codes[$v->title])) {
@@ -249,10 +249,10 @@
         'Proposed languages are based on your version: %s.'), '<strong>' . DC_VERSION . '</strong>') . '</p>' .
     '<p class="field"><label for="pkg_url" class="classic">' . __('Language:') . '</label> ' .
-    form::combo(array('pkg_url'), $dc_langs_combo) . '</p>' .
+    form::combo(['pkg_url'], $dc_langs_combo) . '</p>' .
     '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label> ' .
-    form::password(array('your_pwd', 'your_pwd1'), 20, 255,
-        array(
+    form::password(['your_pwd', 'your_pwd1'], 20, 255,
+        [
             'extra_html'   => 'required placeholder="' . __('Password') . '"',
-            'autocomplete' => 'current-password')
+            'autocomplete' => 'current-password']
     ) . '</p>' .
     '<p><input type="submit" value="' . __('Install language') . '" />' .
@@ -271,8 +271,8 @@
     '<input type="file" id="pkg_file" name="pkg_file" required /></p>' .
     '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label> ' .
-    form::password(array('your_pwd', 'your_pwd2'), 20, 255,
-        array(
+    form::password(['your_pwd', 'your_pwd2'], 20, 255,
+        [
             'extra_html'   => 'required placeholder="' . __('Password') . '"',
-            'autocomplete' => 'current-password')
+            'autocomplete' => 'current-password']
     ) . '</p>' .
     '<p><input type="submit" name="upload_pkg" value="' . __('Upload language') . '" />' .
Index: admin/media.php
===================================================================
--- admin/media.php	(revision 3731)
+++ admin/media.php	(revision 3874)
@@ -14,5 +14,5 @@
 $post_id = !empty($_REQUEST['post_id']) ? (integer) $_REQUEST['post_id'] : null;
 if ($post_id) {
-    $post = $core->blog->getPosts(array('post_id' => $post_id, 'post_type' => ''));
+    $post = $core->blog->getPosts(['post_id' => $post_id, 'post_type' => '']);
     if ($post->isEmpty()) {
         $post_id = null;
@@ -58,10 +58,10 @@
 
 # Sort combo
-$sort_combo = array(
+$sort_combo = [
     __('By names, in ascending order')  => 'name-asc',
     __('By names, in descending order') => 'name-desc',
     __('By dates, in ascending order')  => 'date-asc',
     __('By dates, in descending order') => 'date-desc'
-);
+];
 
 if (!empty($_GET['file_mode'])) {
@@ -90,5 +90,5 @@
 $select = !empty($_REQUEST['select']) ? (integer) $_REQUEST['select'] : 0; // 0 : none, 1 : single media, >1 : multiple medias
 
-$page_url_params = new ArrayObject(array('popup' => $popup, 'select' => $select, 'post_id' => $post_id, 'link_type' => $link_type));
+$page_url_params = new ArrayObject(['popup' => $popup, 'select' => $select, 'post_id' => $post_id, 'link_type' => $link_type]);
 if ($d) {
     $page_url_params['d'] = $d;
@@ -105,8 +105,8 @@
 
 if ($popup) {
-    $open_f  = array('dcPage', 'openPopup');
-    $close_f = array('dcPage', 'closePopup');
+    $open_f  = ['dcPage', 'openPopup'];
+    $close_f = ['dcPage', 'closePopup'];
 } else {
-    $open_f  = array('dcPage', 'open');
+    $open_f  = ['dcPage', 'open'];
     $close_f = function () {
         dcPage::helpBlock('core_media');
@@ -159,5 +159,5 @@
     if ($f->d) {
         // Folder
-        $link = $core->adminurl->get('admin.media', array_merge($page_url_params, array('d' => html::sanitizeURL($f->relname))));
+        $link = $core->adminurl->get('admin.media', array_merge($page_url_params, ['d' => html::sanitizeURL($f->relname)]));
         if ($f->parent) {
             $fname = '..';
@@ -169,5 +169,5 @@
         // Item
         $params = new ArrayObject(
-            array(
+            [
                 'id'        => $f->media_id,
                 'plugin_id' => $plugin_id,
@@ -176,5 +176,5 @@
                 'post_id'   => $post_id,
                 'link_type' => $link_type
-            )
+            ]
         );
         $core->callBehavior('adminMediaURLParams', $params);
@@ -199,5 +199,5 @@
             } else {
                 // Multiple media selection checkbox
-                $act .= form::checkbox(array('medias[]', 'media_' . rawurlencode($file)), $file);
+                $act .= form::checkbox(['medias[]', 'media_' . rawurlencode($file)], $file);
             }
         } else {
@@ -208,5 +208,5 @@
                 '<a class="attach-media" title="' . __('Attach this file to entry') . '" href="' .
                 $core->adminurl->get("admin.post.media",
-                    array('media_id' => $f->media_id, 'post_id' => $post_id, 'attach' => 1, 'link_type' => $link_type)) .
+                    ['media_id' => $f->media_id, 'post_id' => $post_id, 'attach' => 1, 'link_type' => $link_type]) .
                 '">' .
                 '<img src="images/plus.png" alt="' . __('Attach this file to entry') . '"/>' .
@@ -225,5 +225,5 @@
             if ($select < 2) {
                 // Already set for multiple media selection
-                $act .= form::checkbox(array('medias[]', 'media_' . rawurlencode($file)), $file);
+                $act .= form::checkbox(['medias[]', 'media_' . rawurlencode($file)], $file);
             }
         } else {
@@ -261,5 +261,5 @@
         // Show player if relevant
         if ($file_type[0] == 'audio') {
-            $lst .= '<li>' . dcMedia::audioPlayer($f->type, $f->file_url, $core->adminurl->get("admin.home", array('pf' => 'player_mp3.swf')), null, $core->blog->settings->system->media_flash_fallback, false) . '</li>';
+            $lst .= '<li>' . dcMedia::audioPlayer($f->type, $f->file_url, $core->adminurl->get("admin.home", ['pf' => 'player_mp3.swf']), null, $core->blog->settings->system->media_flash_fallback, false) . '</li>';
         }
 
@@ -321,5 +321,5 @@
             $fav_dirs = $core->auth->user_prefs->interface->media_fav_dirs;
             if (!is_array($fav_dirs)) {
-                $fav_dirs = array();
+                $fav_dirs = [];
             }
             if (!in_array($fav_dir, $fav_dirs) && $_GET['fav'] == 'y') {
@@ -347,5 +347,5 @@
         $last_dirs = $core->auth->user_prefs->interface->media_last_dirs;
         if (!is_array($last_dirs)) {
-            $last_dirs = array();
+            $last_dirs = [];
         }
         if (!in_array($recent_dir, $last_dirs)) {
@@ -383,5 +383,5 @@
 if ($dir && !empty($_FILES['upfile'])) {
     // only one file per request : @see option singleFileUploads in admin/js/jsUpload/jquery.fileupload
-    $upfile = array('name' => $_FILES['upfile']['name'][0],
+    $upfile = ['name' => $_FILES['upfile']['name'][0],
         'type'                 => $_FILES['upfile']['type'][0],
         'tmp_name'             => $_FILES['upfile']['tmp_name'][0],
@@ -389,9 +389,9 @@
         'size'                 => $_FILES['upfile']['size'][0],
         'title'                => html::escapeHTML($_FILES['upfile']['name'][0])
-    );
+    ];
 
     if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
         header('Content-type: application/json');
-        $message = array();
+        $message = [];
 
         try {
@@ -399,14 +399,14 @@
             $new_file_id = $core->media->uploadFile($upfile['tmp_name'], $upfile['name'], $upfile['title']);
 
-            $message['files'][] = array(
+            $message['files'][] = [
                 'name' => $upfile['name'],
                 'size' => $upfile['size'],
                 'html' => $mediaItemLine($core->media->getFile($new_file_id), 1, $query)
-            );
+            ];
         } catch (Exception $e) {
-            $message['files'][] = array('name' => $upfile['name'],
+            $message['files'][] = ['name' => $upfile['name'],
                 'size'                             => $upfile['size'],
                 'error'                            => $e->getMessage()
-            );
+            ];
         }
         echo json_encode($message);
@@ -486,10 +486,10 @@
     call_user_func($open_f, __('Media manager'), '',
         dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($core->blog->name) => '',
                 __('Media manager')                 => '',
                 __('confirm removal')               => ''
-            ),
-            array('home_link' => !$popup)
+            ],
+            ['home_link' => !$popup]
         )
     );
@@ -519,9 +519,9 @@
 if (!isset($core->media)) {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Media manager')                 => ''
-        ),
-        array('home_link' => !$popup)
+        ],
+        ['home_link' => !$popup]
     );
 } else {
@@ -532,10 +532,10 @@
         $count      = $query ? count($dir['files']) : 0;
         $breadcrumb = dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($core->blog->name)                                                                    => '',
                 __('Media manager')                                                                                    => $core->adminurl->get('admin.media', $home_params),
                 __('Search:') . ' ' . $q . ' (' . sprintf(__('%s file found', '%s files found', $count), $count) . ')' => ''
-            ),
-            array('home_link' => !$popup)
+            ],
+            ['home_link' => !$popup]
         );
     } else {
@@ -546,9 +546,9 @@
         if ($breadcrumb_media == '') {
             $breadcrumb = dcPage::breadcrumb(
-                array(
+                [
                     html::escapeHTML($core->blog->name) => '',
                     __('Media manager')                 => $core->adminurl->get('admin.media', $home_params)
-                ),
-                array('home_link' => !$popup)
+                ],
+                ['home_link' => !$popup]
             );
         } else {
@@ -557,13 +557,13 @@
 
             $breadcrumb = dcPage::breadcrumb(
-                array(
+                [
                     html::escapeHTML($core->blog->name) => '',
                     __('Media manager')                 => $core->adminurl->get('admin.media', $home_params),
                     $breadcrumb_media                   => ''
-                ),
-                array(
+                ],
+                [
                     'home_link' => !$popup,
                     'hl'        => false
-                )
+                ]
             );
         }
@@ -582,5 +582,5 @@
     $fav_dirs = $core->auth->user_prefs->interface->media_fav_dirs;
     if (!is_array($fav_dirs)) {
-        $fav_dirs = array();
+        $fav_dirs = [];
     }
     foreach ($fav_dirs as $ld) {
@@ -649,5 +649,5 @@
     dcPage::jsModal() .
     dcPage::jsLoad('js/_media.js') .
-    ($core_media_writable ? dcPage::jsUpload(array('d=' . $d)) : ''),
+    ($core_media_writable ? dcPage::jsUpload(['d=' . $d]) : ''),
     $breadcrumb
 );
@@ -738,11 +738,11 @@
 '<div class="files-group">%s</div>' .
 '<p class="hidden">' . $core->formNonce() .
-form::hidden(array('d'), $d) .
-form::hidden(array('q'), $q) .
-form::hidden(array('popup'), $popup) .
-form::hidden(array('select'), $select) .
-form::hidden(array('plugin_id'), $plugin_id) .
-form::hidden(array('post_id'), $post_id) .
-form::hidden(array('link_type'), $link_type) .
+form::hidden(['d'], $d) .
+form::hidden(['q'], $q) .
+form::hidden(['popup'], $popup) .
+form::hidden(['select'], $select) .
+form::hidden(['plugin_id'], $plugin_id) .
+form::hidden(['post_id'], $post_id) .
+form::hidden(['link_type'], $link_type) .
     '</p>';
 
@@ -776,9 +776,9 @@
 '<input type="submit" value="' . __('OK') . '" />' . ' ' .
 '<span class="form-note">' . __('Will search into media filename (including path), title and description') . '</span>' .
-form::hidden(array('popup'), $popup) .
-form::hidden(array('select'), $select) .
-form::hidden(array('plugin_id'), $plugin_id) .
-form::hidden(array('post_id'), $post_id) .
-form::hidden(array('link_type'), $link_type) .
+form::hidden(['popup'], $popup) .
+form::hidden(['select'], $select) .
+form::hidden(['plugin_id'], $plugin_id) .
+form::hidden(['post_id'], $post_id) .
+form::hidden(['link_type'], $link_type) .
     '</p>' .
     '</form>';
@@ -797,8 +797,8 @@
     '<form action="' . $core->adminurl->get("admin.media") . '" method="get" id="filters-form">' .
     '<span class="media-file-mode">' .
-    '<a href="' . $core->adminurl->get("admin.media", array_merge($page_url_params, array('file_mode' => 'grid'))) . '" title="' . __('Grid display mode') . '">' .
+    '<a href="' . $core->adminurl->get("admin.media", array_merge($page_url_params, ['file_mode' => 'grid'])) . '" title="' . __('Grid display mode') . '">' .
     '<img src="images/grid-' . ($file_mode == 'grid' ? 'on' : 'off') . '.png" alt="' . __('Grid display mode') . '" />' .
     '</a>' .
-    '<a href="' . $core->adminurl->get("admin.media", array_merge($page_url_params, array('file_mode' => 'list'))) . '" title="' . __('List display mode') . '">' .
+    '<a href="' . $core->adminurl->get("admin.media", array_merge($page_url_params, ['file_mode' => 'list'])) . '" title="' . __('List display mode') . '">' .
     '<img src="images/list-' . ($file_mode == 'list' ? 'on' : 'off') . '.png" alt="' . __('List display mode') . '" />' .
     '</a>' .
@@ -809,10 +809,10 @@
     form::number('nb_per_page', 0, 999, $nb_per_page) . ' ' .
     '<input type="submit" value="' . __('OK') . '" />' .
-    form::hidden(array('popup'), $popup) .
-    form::hidden(array('select'), $select) .
-    form::hidden(array('plugin_id'), $plugin_id) .
-    form::hidden(array('post_id'), $post_id) .
-    form::hidden(array('link_type'), $link_type) .
-    form::hidden(array('q'), $q) .
+    form::hidden(['popup'], $popup) .
+    form::hidden(['select'], $select) .
+    form::hidden(['plugin_id'], $plugin_id) .
+    form::hidden(['post_id'], $post_id) .
+    form::hidden(['link_type'], $link_type) .
+    form::hidden(['q'], $q) .
     '</p>' .
     '</form>' .
@@ -910,5 +910,5 @@
         '<h4 class="pretty-title">' . sprintf(__('Backup content of %s'), ($d == '' ? '“' . __('Media manager') . '”' : '“' . $d . '”')) . '</h4>' .
         '<p><a class="button submit" href="' . $core->adminurl->get('admin.media',
-            array_merge($page_url_params, array('zipdl' => 1))) . '">' . __('Download zip file') . '</a></p>' .
+            array_merge($page_url_params, ['zipdl' => 1])) . '">' . __('Download zip file') . '</a></p>' .
             '</div>';
     }
@@ -933,5 +933,5 @@
     '<p class="more-info">' . __('Please take care to publish media that you own and that are not protected by copyright.') . '</p>' .
     '<form id="fileupload" action="' . html::escapeURL($core->adminurl->get('admin.media', $page_url_params)) . '" method="post" enctype="multipart/form-data" aria-disabled="false">' .
-    '<p>' . form::hidden(array('MAX_FILE_SIZE'), DC_MAX_UPLOAD_SIZE) .
+    '<p>' . form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) .
     $core->formNonce() . '</p>' .
         '<div class="fileupload-ctrl"><p class="queue-message"></p><ul class="files"></ul></div>';
@@ -956,5 +956,5 @@
         echo
         '<p class="one-file form-help info">' . __('To send several files at the same time, you can activate the enhanced uploader in') .
-        ' <a href="' . $core->adminurl->get("admin.user.preferences", array('tab' => 'user-options')) . '">' . __('My preferences') . '</a></p>';
+        ' <a href="' . $core->adminurl->get("admin.user.preferences", ['tab' => 'user-options']) . '">' . __('My preferences') . '</a></p>';
     }
 
@@ -967,11 +967,11 @@
     echo
     '<p style="clear:both;">' .
-    form::hidden(array('d'), $d) .
-    form::hidden(array('q'), $q) .
-    form::hidden(array('popup'), $popup) .
-    form::hidden(array('select'), $select) .
-    form::hidden(array('plugin_id'), $plugin_id) .
-    form::hidden(array('post_id'), $post_id) .
-    form::hidden(array('link_type'), $link_type) .
+    form::hidden(['d'], $d) .
+    form::hidden(['q'], $q) .
+    form::hidden(['popup'], $popup) .
+    form::hidden(['select'], $select) .
+    form::hidden(['plugin_id'], $plugin_id) .
+    form::hidden(['post_id'], $post_id) .
+    form::hidden(['link_type'], $link_type) .
         '</p>' .
         '</form>' .
@@ -986,10 +986,10 @@
 form::hidden('rmyes', 1) .
 form::hidden('d', html::escapeHTML($d)) .
-form::hidden(array('q'), $q) .
-form::hidden(array('popup'), $popup) .
-form::hidden(array('select'), $select) .
-form::hidden(array('plugin_id'), $plugin_id) .
-form::hidden(array('post_id'), $post_id) .
-form::hidden(array('link_type'), $link_type) .
+form::hidden(['q'], $q) .
+form::hidden(['popup'], $popup) .
+form::hidden(['select'], $select) .
+form::hidden(['plugin_id'], $plugin_id) .
+form::hidden(['post_id'], $post_id) .
+form::hidden(['link_type'], $link_type) .
 form::hidden('remove', '') .
 $core->formNonce() .
Index: admin/media_item.php
===================================================================
--- admin/media_item.php	(revision 3731)
+++ admin/media_item.php	(revision 3874)
@@ -16,5 +16,5 @@
 $post_id = !empty($_REQUEST['post_id']) ? (integer) $_REQUEST['post_id'] : null;
 if ($post_id) {
-    $post = $core->blog->getPosts(array('post_id' => $post_id));
+    $post = $core->blog->getPosts(['post_id' => $post_id]);
     if ($post->isEmpty()) {
         $post_id = null;
@@ -31,6 +31,6 @@
 $select                = !empty($_REQUEST['select']) ? (integer) $_REQUEST['select'] : 0; // 0 : none, 1 : single media, >1 : multiple medias
 $plugin_id             = isset($_REQUEST['plugin_id']) ? html::sanitizeURL($_REQUEST['plugin_id']) : '';
-$page_url_params       = array('popup' => $popup, 'select' => $select, 'post_id' => $post_id);
-$media_page_url_params = array('popup' => $popup, 'select' => $select, 'post_id' => $post_id, 'link_type' => $link_type);
+$page_url_params       = ['popup' => $popup, 'select' => $select, 'post_id' => $post_id];
+$media_page_url_params = ['popup' => $popup, 'select' => $select, 'post_id' => $post_id, 'link_type' => $link_type];
 
 if ($plugin_id != '') {
@@ -46,8 +46,8 @@
 
 if ($popup) {
-    $open_f  = array('dcPage', 'openPopup');
-    $close_f = array('dcPage', 'closePopup');
+    $open_f  = ['dcPage', 'openPopup'];
+    $close_f = ['dcPage', 'closePopup'];
 } else {
-    $open_f  = array('dcPage', 'open');
+    $open_f  = ['dcPage', 'open'];
     $close_f = function () {
         dcPage::helpBlock('core_media');
@@ -73,5 +73,5 @@
 
     # Prepare directories combo box
-    $dirs_combo = array();
+    $dirs_combo = [];
     foreach ($core->media->getDBDirs() as $v) {
         $dirs_combo['/' . $v] = $v;
@@ -182,5 +182,5 @@
 # Function to get image title based on meta
 $get_img_title = function ($file, $pattern, $dto_first = false, $no_date_alone = false) {
-    $res     = array();
+    $res     = [];
     $pattern = preg_split('/\s*;;\s*/', $pattern);
     $sep     = ', ';
@@ -244,13 +244,13 @@
     ($popup ? dcPage::jsPageTabs($tab) : ''),
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Media manager')                 => $home_url,
             $breadcrumb                         => ''
-        ),
-        array(
+        ],
+        [
             'home_link' => !$popup,
             'hl'        => false
-        )
+        ]
     )
 );
@@ -321,10 +321,10 @@
             $s_checked = ($s == $media_img_default_size);
             echo '<label class="classic">' .
-            form::radio(array('src'), html::escapeHTML($v), $s_checked) . ' ' .
+            form::radio(['src'], html::escapeHTML($v), $s_checked) . ' ' .
             $core->media->thumb_sizes[$s][2] . '</label><br /> ';
         }
         $s_checked = (!isset($file->media_thumb[$media_img_default_size]));
         echo '<label class="classic">' .
-        form::radio(array('src'), $file->file_url, $s_checked) . ' ' . __('original') . '</label><br /> ';
+        form::radio(['src'], $file->file_url, $s_checked) . ' ' . __('original') . '</label><br /> ';
         echo '</p>';
 
@@ -341,8 +341,8 @@
     '<button type="button" id="media-select-ok" class="submit">' . __('Select') . '</button> ' .
     '<button type="button" id="media-select-cancel">' . __('Cancel') . '</button>' .
-    form::hidden(array('type'), html::escapeHTML($media_type)) .
-    form::hidden(array('title'), html::escapeHTML($file->media_title)) .
-    form::hidden(array('description'), html::escapeHTML($media_desc)) .
-    form::hidden(array('url'), $file->file_url) .
+    form::hidden(['type'], html::escapeHTML($media_type)) .
+    form::hidden(['title'], html::escapeHTML($file->media_title)) .
+    form::hidden(['description'], html::escapeHTML($media_desc)) .
+    form::hidden(['url'], $file->file_url) .
         '</p>';
 
@@ -392,10 +392,10 @@
             $s_checked = ($s == $media_img_default_size);
             echo '<label class="classic">' .
-            form::radio(array('src'), html::escapeHTML($v), $s_checked) . ' ' .
+            form::radio(['src'], html::escapeHTML($v), $s_checked) . ' ' .
             $core->media->thumb_sizes[$s][2] . '</label><br /> ';
         }
         $s_checked = (!isset($file->media_thumb[$media_img_default_size]));
         echo '<label class="classic">' .
-        form::radio(array('src'), $file->file_url, $s_checked) . ' ' . __('original') . '</label><br /> ';
+        form::radio(['src'], $file->file_url, $s_checked) . ' ' . __('original') . '</label><br /> ';
         echo '</p>';
         echo '</div>';
@@ -405,11 +405,11 @@
         '<h3>' . __('Image legend and title') . '</h3>' .
         '<p>' .
-        '<label for="legend1" class="classic">' . form::radio(array('legend', 'legend1'), 'legend',
+        '<label for="legend1" class="classic">' . form::radio(['legend', 'legend1'], 'legend',
             ($media_img_default_legend == 'legend')) .
         __('Legend and title') . '</label><br />' .
-        '<label for="legend2" class="classic">' . form::radio(array('legend', 'legend2'), 'title',
+        '<label for="legend2" class="classic">' . form::radio(['legend', 'legend2'], 'title',
             ($media_img_default_legend == 'title')) .
         __('Title') . '</label><br />' .
-        '<label for="legend3" class="classic">' . form::radio(array('legend', 'legend3'), 'none',
+        '<label for="legend3" class="classic">' . form::radio(['legend', 'legend3'], 'none',
             ($media_img_default_legend == 'none')) .
         __('None') . '</label>' .
@@ -420,15 +420,15 @@
         '<div class="two-boxes">' .
         '<h3>' . __('Image alignment') . '</h3>';
-        $i_align = array(
-            'none'   => array(__('None'), ($media_img_default_alignment == 'none' ? 1 : 0)),
-            'left'   => array(__('Left'), ($media_img_default_alignment == 'left' ? 1 : 0)),
-            'right'  => array(__('Right'), ($media_img_default_alignment == 'right' ? 1 : 0)),
-            'center' => array(__('Center'), ($media_img_default_alignment == 'center' ? 1 : 0))
-        );
+        $i_align = [
+            'none'   => [__('None'), ($media_img_default_alignment == 'none' ? 1 : 0)],
+            'left'   => [__('Left'), ($media_img_default_alignment == 'left' ? 1 : 0)],
+            'right'  => [__('Right'), ($media_img_default_alignment == 'right' ? 1 : 0)],
+            'center' => [__('Center'), ($media_img_default_alignment == 'center' ? 1 : 0)]
+        ];
 
         echo '<p>';
         foreach ($i_align as $k => $v) {
             echo '<label class="classic">' .
-            form::radio(array('alignment'), $k, $v[1]) . ' ' . $v[0] . '</label><br /> ';
+            form::radio(['alignment'], $k, $v[1]) . ' ' . $v[0] . '</label><br /> ';
         }
         echo '</p>';
@@ -439,7 +439,7 @@
         '<h3>' . __('Image insertion') . '</h3>' .
         '<p>' .
-        '<label for="insert1" class="classic">' . form::radio(array('insertion', 'insert1'), 'simple', !$media_img_default_link) .
+        '<label for="insert1" class="classic">' . form::radio(['insertion', 'insert1'], 'simple', !$media_img_default_link) .
         __('As a single image') . '</label><br />' .
-        '<label for="insert2" class="classic">' . form::radio(array('insertion', 'insert2'), 'link', $media_img_default_link) .
+        '<label for="insert2" class="classic">' . form::radio(['insertion', 'insert2'], 'link', $media_img_default_link) .
         __('As a link to the original image') . '</label>' .
             '</p>' .
@@ -453,15 +453,15 @@
         dcPage::message(__("Please note that you cannot insert mp3 files with visual editor."), false);
 
-        $i_align = array(
-            'none'   => array(__('None'), ($media_img_default_alignment == 'none' ? 1 : 0)),
-            'left'   => array(__('Left'), ($media_img_default_alignment == 'left' ? 1 : 0)),
-            'right'  => array(__('Right'), ($media_img_default_alignment == 'right' ? 1 : 0)),
-            'center' => array(__('Center'), ($media_img_default_alignment == 'center' ? 1 : 0))
-        );
+        $i_align = [
+            'none'   => [__('None'), ($media_img_default_alignment == 'none' ? 1 : 0)],
+            'left'   => [__('Left'), ($media_img_default_alignment == 'left' ? 1 : 0)],
+            'right'  => [__('Right'), ($media_img_default_alignment == 'right' ? 1 : 0)],
+            'center' => [__('Center'), ($media_img_default_alignment == 'center' ? 1 : 0)]
+        ];
 
         echo '<p>';
         foreach ($i_align as $k => $v) {
             echo '<label class="classic">' .
-            form::radio(array('alignment'), $k, $v[1]) . ' ' . $v[0] . '</label><br /> ';
+            form::radio(['alignment'], $k, $v[1]) . ' ' . $v[0] . '</label><br /> ';
         }
 
@@ -490,15 +490,15 @@
         '<h3>' . __('Video disposition') . '</h3>';
 
-        $i_align = array(
-            'none'   => array(__('None'), ($media_img_default_alignment == 'none' ? 1 : 0)),
-            'left'   => array(__('Left'), ($media_img_default_alignment == 'left' ? 1 : 0)),
-            'right'  => array(__('Right'), ($media_img_default_alignment == 'right' ? 1 : 0)),
-            'center' => array(__('Center'), ($media_img_default_alignment == 'center' ? 1 : 0))
-        );
+        $i_align = [
+            'none'   => [__('None'), ($media_img_default_alignment == 'none' ? 1 : 0)],
+            'left'   => [__('Left'), ($media_img_default_alignment == 'left' ? 1 : 0)],
+            'right'  => [__('Right'), ($media_img_default_alignment == 'right' ? 1 : 0)],
+            'center' => [__('Center'), ($media_img_default_alignment == 'center' ? 1 : 0)]
+        ];
 
         echo '<p>';
         foreach ($i_align as $k => $v) {
             echo '<label class="classic">' .
-            form::radio(array('alignment'), $k, $v[1]) . ' ' . $v[0] . '</label><br /> ';
+            form::radio(['alignment'], $k, $v[1]) . ' ' . $v[0] . '</label><br /> ';
         }
 
@@ -517,8 +517,8 @@
     '<button type="button" id="media-insert-ok" class="submit">' . __('Insert') . '</button> ' .
     '<button type="button" id="media-insert-cancel">' . __('Cancel') . '</button>' .
-    form::hidden(array('type'), html::escapeHTML($media_type)) .
-    form::hidden(array('title'), html::escapeHTML($file->media_title)) .
-    form::hidden(array('description'), html::escapeHTML($media_desc)) .
-    form::hidden(array('url'), $file->file_url) .
+    form::hidden(['type'], html::escapeHTML($media_type)) .
+    form::hidden(['title'], html::escapeHTML($file->media_title)) .
+    form::hidden(['description'], html::escapeHTML($media_desc)) .
+    form::hidden(['url'], $file->file_url) .
         '</p>';
 
@@ -531,8 +531,8 @@
         '<p>' . __('Make current settings as default') . ' ' .
         '<input class="reset" type="submit" name="save_blog_prefs" value="' . __('OK') . '" />' .
-        form::hidden(array('pref_src'), '') .
-        form::hidden(array('pref_alignment'), '') .
-        form::hidden(array('pref_insertion'), '') .
-        form::hidden(array('pref_legend'), '') .
+        form::hidden(['pref_src'], '') .
+        form::hidden(['pref_alignment'], '') .
+        form::hidden(['pref_insertion'], '') .
+        form::hidden(['pref_legend'], '') .
         $core->adminurl->getHiddenFormFields('admin.media.item', $page_url_params) .
         $core->formNonce() . '</p>' .
@@ -580,7 +580,7 @@
         $strong_link = ($s == $thumb_size) ? '<strong>%s</strong>' : '%s';
         printf($strong_link, '<a href="' . $core->adminurl->get('admin.media.item', array_merge($page_url_params,
-            array("size" => $s, 'tab' => 'media-details-tab'))) . '">' . $core->media->thumb_sizes[$s][2] . '</a> | ');
-    }
-    echo '<a href="' . $core->adminurl->get('admin.media.item', array_merge($page_url_params, array("size" => "o", "tab" => "media-details-tab"))) . '">' . __('original') . '</a>';
+            ["size" => $s, 'tab' => 'media-details-tab'])) . '">' . $core->media->thumb_sizes[$s][2] . '</a> | ');
+    }
+    echo '<a href="' . $core->adminurl->get('admin.media.item', array_merge($page_url_params, ["size" => "o", "tab" => "media-details-tab"])) . '">' . __('original') . '</a>';
     echo '</p>';
 
@@ -606,9 +606,9 @@
 // Show player if relevant
 if ($file_type[0] == 'audio') {
-    echo dcMedia::audioPlayer($file->type, $file->file_url, $core->adminurl->get("admin.home", array('pf' => 'player_mp3.swf')),
+    echo dcMedia::audioPlayer($file->type, $file->file_url, $core->adminurl->get("admin.home", ['pf' => 'player_mp3.swf']),
         null, $core->blog->settings->system->media_flash_fallback);
 }
 if ($file_type[0] == 'video') {
-    echo dcMedia::videoPlayer($file->type, $file->file_url, $core->adminurl->get("admin.home", array('pf' => 'player_flv.swf')),
+    echo dcMedia::videoPlayer($file->type, $file->file_url, $core->adminurl->get("admin.home", ['pf' => 'player_flv.swf']),
         null, $core->blog->settings->system->media_flash_fallback);
 }
@@ -633,9 +633,9 @@
 if (empty($_GET['find_posts'])) {
     echo
-    '<p><a class="button" href="' . $core->adminurl->get('admin.media.item', array_merge($page_url_params, array("find_posts" => 1, "tab" => "media-details-tab"))) . '">' .
+    '<p><a class="button" href="' . $core->adminurl->get('admin.media.item', array_merge($page_url_params, ["find_posts" => 1, "tab" => "media-details-tab"])) . '">' .
     __('Show entries containing this media') . '</a></p>';
 } else {
     echo '<h3>' . __('Entries containing this media') . '</h3>';
-    $params = array(
+    $params = [
         'post_type' => '',
         'from'      => 'LEFT OUTER JOIN ' . $core->prefix . 'post_media PM ON P.post_id = PM.post_id ',
@@ -644,5 +644,5 @@
         "OR post_content_xhtml LIKE '%" . $core->con->escape($file->relname) . "%' " .
         "OR post_excerpt_xhtml LIKE '%" . $core->con->escape($file->relname) . "%' "
-    );
+    ];
 
     if ($file->media_image) {
@@ -728,8 +728,8 @@
 
     if ($file->type == 'application/zip') {
-        $inflate_combo = array(
+        $inflate_combo = [
             __('Extract in a new directory')   => 'new',
             __('Extract in current directory') => 'current'
-        );
+        ];
 
         echo
@@ -763,5 +763,5 @@
     Dont forget to remove call to datepicker in media_item.js
 
-    form::datetime('media_dt', array('default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', $file->media_dt)))) .
+    form::datetime('media_dt', ['default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', $file->media_dt))]) .
      */
     '</p>' .
@@ -778,5 +778,5 @@
     '<form class="clear fieldset" action="' . $core->adminurl->get("admin.media.item") . '" method="post" enctype="multipart/form-data">' .
     '<h4>' . __('Change file') . '</h4>' .
-    '<div>' . form::hidden(array('MAX_FILE_SIZE'), DC_MAX_UPLOAD_SIZE) . '</div>' .
+    '<div>' . form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) . '</div>' .
     '<p><label for="upfile">' . __('Choose a file:') .
     ' (' . sprintf(__('Maximum size %s'), files::size(DC_MAX_UPLOAD_SIZE)) . ') ' .
Index: admin/plugin.php
===================================================================
--- admin/plugin.php	(revision 3731)
+++ admin/plugin.php	(revision 3874)
@@ -17,9 +17,9 @@
 
 if ($popup) {
-    $open_f  = array('dcPage', 'openPopup');
-    $close_f = array('dcPage', 'closePopup');
+    $open_f  = ['dcPage', 'openPopup'];
+    $close_f = ['dcPage', 'closePopup'];
 } else {
-    $open_f  = array('dcPage', 'open');
-    $close_f = array('dcPage', 'close');
+    $open_f  = ['dcPage', 'open'];
+    $close_f = ['dcPage', 'close'];
 }
 
@@ -85,8 +85,8 @@
     call_user_func($open_f, __('Plugin not found'), '',
         dcPage::breadcrumb(
-            array(
+            [
                 __('System')           => '',
                 __('Plugin not found') => ''
-            ))
+            ])
     );
 
Index: admin/plugins.php
===================================================================
--- admin/plugins.php	(revision 3731)
+++ admin/plugins.php	(revision 3874)
@@ -10,5 +10,5 @@
 require dirname(__FILE__) . '/../inc/admin/prepend.php';
 
-dcPage::check('admin');
+dcPage::checkSuper();
 
 # -- Page helper --
@@ -16,5 +16,6 @@
     $core->plugins,
     DC_PLUGINS_ROOT,
-    $core->blog->settings->system->store_plugin_url
+    $core->blog->settings->system->store_plugin_url,
+    !empty($_GET['nocache'])
 );
 
@@ -22,5 +23,5 @@
 adminModulesList::$distributed_modules = explode(',', DC_DISTRIB_PLUGINS);
 
-if ($core->plugins->disableDepModules($core->adminurl->get('admin.plugins', array()))) {
+if ($core->plugins->disableDepModules($core->adminurl->get('admin.plugins', []))) {
     exit;
 }
@@ -42,9 +43,9 @@
 
         dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($core->blog->name)                                  => '',
                 __('Plugins management')                                             => $list->getURL('', false),
                 '<span class="page-title">' . __('Plugin configuration') . '</span>' => ''
-            ))
+            ])
     );
 
@@ -81,8 +82,8 @@
 
     dcPage::breadcrumb(
-        array(
+        [
             __('System')             => '',
             __('Plugins management') => ''
-        ))
+        ])
 );
 
@@ -115,4 +116,10 @@
 # -- Display modules lists --
 if ($core->auth->isSuperAdmin()) {
+
+    if (!$core->error->flag()) {
+        if (!empty($_GET['nocache'])) {
+            dcPage::success(__('Manual checking of plugins update done successfully.'));
+        }
+    }
 
     # Updated modules from repo
@@ -132,6 +139,6 @@
             ->setModules($modules)
             ->displayModules(
-                /*cols */array('checkbox', 'icon', 'name', 'version', 'current_version', 'desc'),
-                /* actions */array('update')
+                /*cols */['checkbox', 'icon', 'name', 'version', 'current_version', 'desc'],
+                /* actions */['update']
             );
 
@@ -144,4 +151,10 @@
 
             '</div>';
+    } else {
+        echo
+        '<form action="' . $list->getURL('', false) . '" method="get">' .
+        '<p><input type="hidden" name="nocache" value="1" />' .
+        '<input type="submit" value="' . __('Force checking update of plugins') . '" /></p>' .
+            '</form>';
     }
 }
@@ -163,6 +176,6 @@
         ->setModules($modules)
         ->displayModules(
-            /* cols */array('expander', 'icon', 'name', 'version', 'desc', 'distrib', 'deps'),
-            /* actions */array('deactivate', 'delete', 'behavior')
+            /* cols */['expander', 'icon', 'name', 'version', 'desc', 'distrib', 'deps'],
+            /* actions */['deactivate', 'delete', 'behavior']
         );
 }
@@ -181,6 +194,6 @@
             ->setModules($modules)
             ->displayModules(
-                /* cols */array('expander', 'icon', 'name', 'version', 'desc', 'distrib'),
-                /* actions */array('activate', 'delete')
+                /* cols */['expander', 'icon', 'name', 'version', 'desc', 'distrib'],
+                /* actions */['activate', 'delete']
             );
     }
@@ -208,6 +221,6 @@
             ->displayIndex()
             ->displayModules(
-                /* cols */array('expander', 'name', 'score', 'version', 'desc', 'deps'),
-                /* actions */array('install'),
+                /* cols */['expander', 'name', 'score', 'version', 'desc', 'deps'],
+                /* actions */['install'],
                 /* nav limit */true
             );
Index: admin/popup_link.php
===================================================================
--- admin/popup_link.php	(revision 3731)
+++ admin/popup_link.php	(revision 3874)
@@ -22,5 +22,5 @@
 
 # Languages combo
-$rs         = $core->blog->getLangs(array('order' => 'asc'));
+$rs         = $core->blog->getLangs(['order' => 'asc']);
 $lang_combo = dcAdminCombos::getLangsCombo($rs, true);
 
@@ -28,8 +28,8 @@
 '<form id="link-insert-form" action="#" method="get">' .
 '<p><label class="required" for="href"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Link URL:') . '</label> ' .
-form::field('href', 35, 512, array(
+form::field('href', 35, 512, [
     'default'    => html::escapeHTML($href),
     'extra_html' => 'required placeholder="' . __('URL') . '"'
-)) .
+]) .
 '</p>' .
 '<p><label for="title">' . __('Link title:') . '</label> ' .
Index: admin/popup_posts.php
===================================================================
--- admin/popup_posts.php	(revision 3731)
+++ admin/popup_posts.php	(revision 3874)
@@ -28,6 +28,6 @@
 }
 
-$params               = array();
-$params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params               = [];
+$params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
 $params['no_content'] = true;
 $params['order']      = 'post_dt DESC';
Index: admin/post.php
===================================================================
--- admin/post.php	(revision 3771)
+++ admin/post.php	(revision 3878)
@@ -38,6 +38,6 @@
 $can_delete    = false;
 
-$post_headlink = '<link rel="%s" title="%s" href="' . $core->adminurl->get('admin.post', array('id' => "%s"), '&amp;', true) . '" />';
-$post_link     = '<a href="' . $core->adminurl->get('admin.post', array('id' => "%s"), '&amp;', true) . '" title="%s">%s</a>';
+$post_headlink = '<link rel="%s" title="%s" href="' . $core->adminurl->get('admin.post', ['id' => "%s"], '&amp;', true) . '" />';
+$post_link     = '<a href="' . $core->adminurl->get('admin.post', ['id' => "%s"], '&amp;', true) . '" title="%s">%s</a>';
 $next_link     = $prev_link     = $next_headlink     = $prev_headlink     = null;
 
@@ -58,5 +58,5 @@
 # Formats combo
 $core_formaters    = $core->getFormaters();
-$available_formats = array('' => '');
+$available_formats = ['' => ''];
 foreach ($core_formaters as $editor => $formats) {
     foreach ($formats as $format) {
@@ -66,5 +66,5 @@
 
 # Languages combo
-$rs         = $core->blog->getLangs(array('order' => 'asc'));
+$rs         = $core->blog->getLangs(['order' => 'asc']);
 $lang_combo = dcAdminCombos::getLangsCombo($rs, true);
 
@@ -147,5 +147,5 @@
 }
 
-$comments_actions_page = new dcCommentsActionsPage($core, $core->adminurl->get('admin.post'), array('id' => $post_id, '_ANCHOR' => $anchor, 'section' => $anchor));
+$comments_actions_page = new dcCommentsActionsPage($core, $core->adminurl->get('admin.post'), ['id' => $post_id, '_ANCHOR' => $anchor, 'section' => $anchor]);
 
 if ($comments_actions_page->process()) {
@@ -176,5 +176,5 @@
             $core->adminurl->redirect(
                 'admin.post',
-                array('id' => $post_id, 'tb' => '1')
+                ['id' => $post_id, 'tb' => '1']
             );
         }
@@ -298,5 +298,5 @@
             $core->adminurl->redirect(
                 'admin.post',
-                array('id' => $post_id)
+                ['id' => $post_id]
             );
         } catch (Exception $e) {
@@ -318,5 +318,5 @@
             $core->adminurl->redirect(
                 'admin.post',
-                array('id' => $return_id)
+                ['id' => $return_id]
             );
         } catch (Exception $e) {
@@ -376,10 +376,10 @@
     if ($p_edit == $c_edit) {
         $admin_post_behavior .= $core->callBehavior('adminPostEditor',
-            $p_edit, 'post', array('#post_excerpt', '#post_content', '#comment_content'), $post_format);
+            $p_edit, 'post', ['#post_excerpt', '#post_content', '#comment_content'], $post_format);
     } else {
         $admin_post_behavior .= $core->callBehavior('adminPostEditor',
-            $p_edit, 'post', array('#post_excerpt', '#post_content'), $post_format);
+            $p_edit, 'post', ['#post_excerpt', '#post_content'], $post_format);
         $admin_post_behavior .= $core->callBehavior('adminPostEditor',
-            $c_edit, 'comment', array('#comment_content'), 'xhtml');
+            $c_edit, 'comment', ['#comment_content'], 'xhtml');
     }
 }
@@ -397,12 +397,12 @@
     $next_headlink . "\n" . $prev_headlink,
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name)         => '',
             __('Entries')                               => $core->adminurl->get("admin.posts"),
             ($post_id ? $page_title_edit : $page_title) => ''
-        ))
-    , array(
+        ])
+    , [
         'x-frame-allow' => $core->blog->url
-    )
+    ]
 );
 
@@ -488,5 +488,5 @@
     '<th>' . __('Edit') . '</th>' .
         '</tr>';
-    $comments = array();
+    $comments = [];
     if (isset($_REQUEST['comments'])) {
         foreach ($_REQUEST['comments'] as $v) {
@@ -496,36 +496,41 @@
 
     while ($rs->fetch()) {
-        $comment_url = $core->adminurl->get("admin.comment", array('id' => $rs->comment_id));
-
-        $img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
+        $comment_url = $core->adminurl->get("admin.comment", ['id' => $rs->comment_id]);
+
+        $img       = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
+        $sts_class = '';
         switch ($rs->comment_status) {
             case 1:
                 $img_status = sprintf($img, __('Published'), 'check-on.png');
+                $sts_class  = 'sts-online';
                 break;
             case 0:
                 $img_status = sprintf($img, __('Unpublished'), 'check-off.png');
+                $sts_class  = 'sts-offline';
                 break;
             case -1:
                 $img_status = sprintf($img, __('Pending'), 'check-wrn.png');
+                $sts_class  = 'sts-pending';
                 break;
             case -2:
                 $img_status = sprintf($img, __('Junk'), 'junk.png');
+                $sts_class  = 'sts-junk';
                 break;
         }
 
         echo
-        '<tr class="line' . ($rs->comment_status != 1 ? ' offline' : '') . '"' .
+        '<tr class="line ' . ($rs->comment_status != 1 ? ' offline ' : '') . $sts_class . '"' .
         ' id="c' . $rs->comment_id . '">' .
 
         '<td class="nowrap">' .
-        ($has_action ? form::checkbox(array('comments[]'), $rs->comment_id,
-            array(
+        ($has_action ? form::checkbox(['comments[]'], $rs->comment_id,
+            [
                 'checked'    => isset($comments[$rs->comment_id]),
                 'extra_html' => 'title="' . ($tb ? __('select this trackback') : __('select this comment') . '"')
-            )
+            ]
         ) : '') . '</td>' .
         '<td class="maximal">' . html::escapeHTML($rs->comment_author) . '</td>' .
         '<td class="nowrap">' . dt::dt2str(__('%Y-%m-%d %H:%M'), $rs->comment_dt) . '</td>' .
-        '<td class="nowrap"><a href="' . $core->adminurl->get("admin.comments", array('ip' => $rs->comment_ip)) . '">' . $rs->comment_ip . '</a></td>' .
+        '<td class="nowrap"><a href="' . $core->adminurl->get("admin.comments", ['ip' => $rs->comment_ip]) . '">' . $rs->comment_ip . '</a></td>' .
         '<td class="nowrap status">' . $img_status . '</td>' .
         '<td class="nowrap status"><a href="' . $comment_url . '">' .
@@ -541,12 +546,12 @@
 -------------------------------------------------------- */
 if ($can_edit_post) {
-    $sidebar_items = new ArrayObject(array(
-        'status-box'  => array(
+    $sidebar_items = new ArrayObject([
+        'status-box'  => [
             'title' => __('Status'),
-            'items' => array(
+            'items' => [
                 'post_status' =>
                 '<p class="entry-status"><label for="post_status">' . __('Entry status') . ' ' . $img_status . '</label>' .
                 form::combo('post_status', $status_combo,
-                    array('default' => $post_status, 'class' => 'maximal', 'disabled' => !$can_publish)) .
+                    ['default' => $post_status, 'class' => 'maximal', 'disabled' => !$can_publish]) .
                 '</p>',
                 'post_dt'     =>
@@ -557,8 +562,8 @@
                 Dont forget to remove call to datepicker in post.js
 
-                form::datetime('post_dt', array(
+                form::datetime('post_dt', [
                 'default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', strtotime($post_dt))),
                 'class' => ($bad_dt ? 'invalid' : '')
-                )) .
+                ]) .
                  */
                 '</p>',
@@ -573,10 +578,10 @@
                 '<p class="format_control control_no_xhtml">' .
                 '<a id="convert-xhtml" class="button' . ($post_id && $post_format != 'wiki' ? ' hide' : '') . '" href="' .
-                $core->adminurl->get('admin.post', array('id' => $post_id, 'xconv' => '1')) .
+                $core->adminurl->get('admin.post', ['id' => $post_id, 'xconv' => '1']) .
                 '">' .
-                __('Convert to XHTML') . '</a></p></div>')),
-        'metas-box'   => array(
+                __('Convert to XHTML') . '</a></p></div>']],
+        'metas-box'   => [
             'title' => __('Filing'),
-            'items' => array(
+            'items' => [
                 'post_selected' =>
                 '<p><label for="post_selected" class="classic">' .
@@ -593,5 +598,5 @@
                     '<h5 id="create_cat">' . __('Add a new category') . '</h5>' .
                     '<p><label for="new_cat_title">' . __('Title:') . ' ' .
-                    form::field('new_cat_title', 30, 255, array('class' => 'maximal')) . '</label></p>' .
+                    form::field('new_cat_title', 30, 255, ['class' => 'maximal']) . '</label></p>' .
                     '<p><label for="new_cat_parent">' . __('Parent:') . ' ' .
                     form::combo('new_cat_parent', $categories_combo, '', 'maximal') .
@@ -599,8 +604,8 @@
                     '</div>'
                     : '') .
-                '</div>')),
-        'options-box' => array(
+                '</div>']],
+        'options-box' => [
             'title' => __('Options'),
-            'items' => array(
+            'items' => [
                 'post_open_comment_tb' =>
                 '<div>' .
@@ -638,15 +643,15 @@
                 __('Warning: If you set the URL manually, it may conflict with another entry.') .
                 '</p></div>'
-            ))));
-
-    $main_items = new ArrayObject(array(
+            ]]]);
+
+    $main_items = new ArrayObject([
         "post_title"   =>
         '<p class="col">' .
         '<label class="required no-margin bold" for="post_title"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label>' .
-        form::field('post_title', 20, 255, array(
+        form::field('post_title', 20, 255, [
             'default'    => html::escapeHTML($post_title),
             'class'      => 'maximal',
             'extra_html' => 'required placeholder="' . __('Title') . '"'
-        )) .
+        ]) .
         '</p>',
 
@@ -661,8 +666,8 @@
         'for="post_content"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Content:') . '</label> ' .
         form::textarea('post_content', 50, $core->auth->getOption('edit_size'),
-            array(
+            [
                 'default'    => html::escapeHTML($post_content),
                 'extra_html' => 'required placeholder="' . __('Content') . '"'
-            )) .
+            ]) .
         '</p>',
 
@@ -672,5 +677,5 @@
         form::textarea('post_notes', 50, 5, html::escapeHTML($post_notes)) .
         '</p>'
-    )
+    ]
     );
 
@@ -744,7 +749,7 @@
     -------------------------------------------------------- */
 
-    $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC');
-
-    $comments = $core->blog->getComments(array_merge($params, array('comment_trackback' => 0)));
+    $params = ['post_id' => $post_id, 'order' => 'comment_dt ASC'];
+
+    $comments = $core->blog->getComments(array_merge($params, ['comment_trackback' => 0]));
 
     echo
@@ -773,6 +778,6 @@
         '<p class="col right"><label for="action" class="classic">' . __('Selected comments action:') . '</label> ' .
         form::combo('action', $combo_action) .
-        form::hidden(array('section'), 'comments') .
-        form::hidden(array('id'), $post_id) .
+        form::hidden(['section'], 'comments') .
+        form::hidden(['id'], $post_id) .
         $core->formNonce() .
         '<input type="submit" value="' . __('ok') . '" /></p>' .
@@ -790,8 +795,8 @@
     '<div class="constrained">' .
     '<p><label for="comment_author" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Name:') . '</label>' .
-    form::field('comment_author', 30, 255, array(
+    form::field('comment_author', 30, 255, [
         'default'    => html::escapeHTML($core->auth->getInfo('user_cn')),
         'extra_html' => 'required placeholder="' . __('Author') . '"'
-    )) .
+    ]) .
     '</p>' .
 
@@ -806,5 +811,5 @@
     '<p class="area"><label for="comment_content" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' .
     __('Comment:') . '</label> ' .
-    form::textarea('comment_content', 50, 8, array('extra_html' => 'required placeholder="' . __('Comment') . '"')) .
+    form::textarea('comment_content', 50, 8, ['extra_html' => 'required placeholder="' . __('Comment') . '"']) .
     '</p>' .
 
@@ -824,6 +829,6 @@
     -------------------------------------------------------- */
 
-    $params     = array('post_id' => $post_id, 'order' => 'comment_dt ASC');
-    $trackbacks = $core->blog->getComments(array_merge($params, array('comment_trackback' => 1)));
+    $params     = ['post_id' => $post_id, 'order' => 'comment_dt ASC'];
+    $trackbacks = $core->blog->getComments(array_merge($params, ['comment_trackback' => 1]));
 
     # Actions combo box
@@ -860,5 +865,5 @@
         form::combo('action', $combo_action) .
         form::hidden('id', $post_id) .
-        form::hidden(array('section'), 'trackbacks') .
+        form::hidden(['section'], 'trackbacks') .
         $core->formNonce() .
         '<input type="submit" value="' . __('ok') . '" /></p>' .
@@ -875,5 +880,5 @@
         echo
         '<h3>' . __('Ping blogs') . '</h3>' .
-        '<form action="' . $core->adminurl->get("admin.post", array('id' => $post_id)) . '" id="trackback-form" method="post">' .
+        '<form action="' . $core->adminurl->get("admin.post", ['id' => $post_id]) . '" id="trackback-form" method="post">' .
         '<p><label for="tb_urls" class="area">' . __('URLs to ping:') . '</label>' .
         form::textarea('tb_urls', 60, 5, $tb_urls) .
@@ -888,5 +893,5 @@
             (empty($_GET['tb_auto']) ?
             '&nbsp;&nbsp;<a class="button" href="' .
-            $core->adminurl->get("admin.post", array('id' => $post_id, 'tb_auto' => 1, 'tb' => 1)) .
+            $core->adminurl->get("admin.post", ['id' => $post_id, 'tb_auto' => 1, 'tb' => 1]) .
             '">' . __('Auto discover ping URLs') . '</a>'
             : '') .
Index: admin/post_media.php
===================================================================
--- admin/post_media.php	(revision 3731)
+++ admin/post_media.php	(revision 3874)
@@ -19,5 +19,5 @@
     exit;
 }
-$rs = $core->blog->getPosts(array('post_id' => $post_id, 'post_type' => ''));
+$rs = $core->blog->getPosts(['post_id' => $post_id, 'post_type' => '']);
 if ($rs->isEmpty()) {
     exit;
@@ -30,5 +30,5 @@
         if (!empty($_SERVER['HTTP_X_REQUESTED_WITH'])) {
             header('Content-type: application/json');
-            echo json_encode(array('url' => $core->getPostAdminURL($rs->post_type, $post_id, false)));
+            echo json_encode(['url' => $core->getPostAdminURL($rs->post_type, $post_id, false)]);
             exit();
         } else {
Index: admin/posts.php
===================================================================
--- admin/posts.php	(revision 3745)
+++ admin/posts.php	(revision 3874)
@@ -28,5 +28,5 @@
 # Getting dates
 try {
-    $dates = $core->blog->getDates(array('type' => 'month'));
+    $dates = $core->blog->getDates(['type' => 'month']);
 } catch (Exception $e) {
     $core->error->add($e->getMessage());
@@ -44,15 +44,15 @@
 dcUtils::lexicalKeySort($users_combo);
 $users_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     $users_combo
 );
 
 $categories_combo = array_merge(
-    array(
+    [
         new formSelectOption('-', ''),
-        new formSelectOption(__('(No cat)'), 'NULL')),
+        new formSelectOption(__('(No cat)'), 'NULL')],
     dcAdminCombos::getCategoriesCombo($categories, false)
 );
-$categories_values = array();
+$categories_values = [];
 foreach ($categories_combo as $cat) {
     if (isset($cat->value)) {
@@ -62,46 +62,46 @@
 
 $status_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     dcAdminCombos::getPostStatusesCombo()
 );
 
-$selected_combo = array(
+$selected_combo = [
     '-'                => '',
     __('Selected')     => '1',
     __('Not selected') => '0'
-);
-
-$comment_combo = array(
+];
+
+$comment_combo = [
     '-'          => '',
     __('Opened') => '1',
     __('Closed') => '0'
-);
-
-$trackback_combo = array(
+];
+
+$trackback_combo = [
     '-'          => '',
     __('Opened') => '1',
     __('Closed') => '0'
-);
-
-$attachment_combo = array(
+];
+
+$attachment_combo = [
     '-'                       => '',
     __('With attachments')    => '1',
     __('Without attachments') => '0'
-);
-
-$password_combo = array(
+];
+
+$password_combo = [
     '-'                    => '',
     __('With password')    => '1',
     __('Without password') => '0'
-);
+];
 
 # Months array
 $dt_m_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     dcAdminCombos::getDatesCombo($dates)
 );
 
 $lang_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     dcAdminCombos::getLangsCombo($langs, false)
 );
@@ -109,5 +109,5 @@
 # Post formats
 $core_formaters    = $core->getFormaters();
-$available_formats = array();
+$available_formats = [];
 foreach ($core_formaters as $editor => $formats) {
     foreach ($formats as $format) {
@@ -116,9 +116,9 @@
 }
 $format_combo = array_merge(
-    array('-' => ''),
+    ['-' => ''],
     $available_formats
 );
 
-$sortby_combo = array(
+$sortby_combo = [
     __('Date')                 => 'post_dt',
     __('Title')                => 'post_title',
@@ -129,16 +129,16 @@
     __('Number of comments')   => 'nb_comment',
     __('Number of trackbacks') => 'nb_trackback'
-);
-
-$sortby_lex = array(
+];
+
+$sortby_lex = [
     // key in sorty_combo (see above) => field in SQL request
     'post_title' => 'post_title',
     'cat_title'  => 'cat_title',
-    'user_id'    => 'P.user_id');
-
-$order_combo = array(
+    'user_id'    => 'P.user_id'];
+
+$order_combo = [
     __('Descending') => 'desc',
     __('Ascending')  => 'asc'
-);
+];
 
 # Actions combo box
@@ -178,5 +178,5 @@
 }
 
-$params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
 $params['no_content'] = true;
 $params['where']      = '';
@@ -308,8 +308,8 @@
     dcPage::jsLoad('js/_posts_list.js') . dcPage::jsFilterControl($show_filters),
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Entries')                       => ''
-        ))
+        ])
 );
 if (!empty($_GET['upd'])) {
@@ -382,18 +382,18 @@
         form::combo('action', $posts_actions_page->getCombo()) .
         '<input id="do-action" type="submit" value="' . __('ok') . '" disabled /></p>' .
-        form::hidden(array('user_id'), $user_id) .
-        form::hidden(array('cat_id'), $cat_id) .
-        form::hidden(array('status'), $status) .
-        form::hidden(array('password'), $password) .
-        form::hidden(array('selected'), $selected) .
-        form::hidden(array('comment'), $comment) .
-        form::hidden(array('trackback'), $trackback) .
-        form::hidden(array('attachment'), $attachment) .
-        form::hidden(array('month'), $month) .
-        form::hidden(array('lang'), $lang) .
-        form::hidden(array('sortby'), $sortby) .
-        form::hidden(array('order'), $order) .
-        form::hidden(array('page'), $page) .
-        form::hidden(array('nb'), $nb_per_page) .
+        form::hidden(['user_id'], $user_id) .
+        form::hidden(['cat_id'], $cat_id) .
+        form::hidden(['status'], $status) .
+        form::hidden(['password'], $password) .
+        form::hidden(['selected'], $selected) .
+        form::hidden(['comment'], $comment) .
+        form::hidden(['trackback'], $trackback) .
+        form::hidden(['attachment'], $attachment) .
+        form::hidden(['month'], $month) .
+        form::hidden(['lang'], $lang) .
+        form::hidden(['sortby'], $sortby) .
+        form::hidden(['order'], $order) .
+        form::hidden(['page'], $page) .
+        form::hidden(['nb'], $nb_per_page) .
         $core->formNonce() .
         '</div>' .
Index: admin/posts_actions.php
===================================================================
--- admin/posts_actions.php	(revision 3731)
+++ admin/posts_actions.php	(revision 3874)
@@ -26,5 +26,5 @@
 } else {
     $uri  = $core->adminurl->get("admin.posts");
-    $args = array();
+    $args = [];
 }
 
Index: admin/preferences.php
===================================================================
--- admin/preferences.php	(revision 3800)
+++ admin/preferences.php	(revision 3874)
@@ -25,5 +25,5 @@
 $user_options = $core->auth->getOptions();
 if (empty($user_options['editor']) || !is_array($user_options['editor'])) {
-    $user_options['editor'] = array();
+    $user_options['editor'] = [];
 }
 
@@ -60,5 +60,5 @@
 if (!empty($_GET['append']) || !empty($_GET['removed']) || !empty($_GET['neworder']) ||
     !empty($_GET['replaced']) || !empty($_POST['appendaction']) || !empty($_POST['removeaction']) ||
-    !empty($_GET['db-updated'])) {
+    !empty($_GET['db-updated']) || !empty($_POST['resetorder'])) {
     $default_tab = 'user-favorites';
 } elseif (!empty($_GET['updated'])) {
@@ -75,5 +75,5 @@
 # Format by editors
 $formaters         = $core->getFormaters();
-$format_by_editors = array();
+$format_by_editors = [];
 foreach ($formaters as $editor => $formats) {
     foreach ($formats as $format) {
@@ -81,5 +81,5 @@
     }
 }
-$available_formats = array('' => '');
+$available_formats = ['' => ''];
 foreach (array_keys($format_by_editors) as $format) {
     $available_formats[$format] = $format;
@@ -90,5 +90,5 @@
 $status_combo = dcAdminCombos::getPostStatusescombo();
 
-$iconsets_combo = array(__('Default') => '');
+$iconsets_combo = [__('Default') => ''];
 $iconsets_root  = dirname(__FILE__) . '/images/iconset/';
 if (is_dir($iconsets_root) && is_readable($iconsets_root)) {
@@ -103,5 +103,5 @@
 
 # Body base font size (37.5% = 6px, 50% = 8px, 62.5% = 10px, 75% = 12px, 87.5% = 14px)
-$htmlfontsize_combo = array(
+$htmlfontsize_combo = [
     __('Smallest') => '37.5%',
     __('Smaller')  => '50%',
@@ -109,5 +109,5 @@
     __('Larger')   => '75%',
     __('Largest')  => '87,5%'
-);
+];
 # Ensure Font size is set to default is empty
 if ($user_ui_htmlfontsize == '') {
@@ -119,8 +119,8 @@
 
 # Get 3rd parts xhtml editor flags
-$rte = array(
-    'blog_descr' => array(true, __('Blog description (in blog parameters)')),
-    'cat_descr'  => array(true, __('Category description'))
-);
+$rte = [
+    'blog_descr' => [true, __('Blog description (in blog parameters)')],
+    'cat_descr'  => [true, __('Category description')]
+];
 $rte = new ArrayObject($rte);
 $core->callBehavior('adminRteFlags', $core, $rte);
@@ -136,13 +136,13 @@
 
 # Get default colums (admin lists)
-$cols = array(
-    'posts' => array(__('Posts'), array(
-        'date'       => array(true, __('Date')),
-        'category'   => array(true, __('Category')),
-        'author'     => array(true, __('Author')),
-        'comments'   => array(true, __('Comments')),
-        'trackbacks' => array(true, __('Trackbacks'))
-    ))
-);
+$cols = [
+    'posts' => [__('Posts'), [
+        'date'       => [true, __('Date')],
+        'category'   => [true, __('Category')],
+        'author'     => [true, __('Author')],
+        'comments'   => [true, __('Comments')],
+        'trackbacks' => [true, __('Trackbacks')]
+    ]]
+];
 $cols = new arrayObject($cols);
 $core->callBehavior('adminColumnsLists', $core, $cols);
@@ -255,11 +255,11 @@
         $core->auth->user_prefs->interface->put('media_by_page', (integer) $_POST['user_ui_media_by_page'], 'integer');
         $core->auth->user_prefs->interface->put('media_nb_last_dirs', (integer) $_POST['user_ui_media_nb_last_dirs'], 'integer');
-        $core->auth->user_prefs->interface->put('media_last_dirs', array(), 'array', null, false);
-        $core->auth->user_prefs->interface->put('media_fav_dirs', array(), 'array', null, false);
+        $core->auth->user_prefs->interface->put('media_last_dirs', [], 'array', null, false);
+        $core->auth->user_prefs->interface->put('media_fav_dirs', [], 'array', null, false);
 
         # Update user columns (lists)
-        $cu = array();
+        $cu = [];
         foreach ($cols as $col_type => $cols_list) {
-            $ct = array();
+            $ct = [];
             foreach ($cols_list[1] as $col_name => $col_data) {
                 $ct[$col_name] = isset($_POST['cols_' . $col_type]) && in_array($col_name, $_POST['cols_' . $col_type], true) ? true : false;
@@ -272,5 +272,5 @@
 
         # Update user xhtml editor flags
-        $rf = array();
+        $rf = [];
         foreach ($rte as $rk => $rv) {
             $rf[$rk] = isset($_POST['rte_flags']) && in_array($rk, $_POST['rte_flags'], true) ? true : false;
@@ -285,5 +285,5 @@
 
         dcPage::addSuccessNotice(__('Personal options has been successfully updated.'));
-        $core->adminurl->redirect("admin.user.preferences", array(), '#user-options');
+        $core->adminurl->redirect("admin.user.preferences", [], '#user-options');
     } catch (Exception $e) {
         $core->error->add($e->getMessage());
@@ -313,5 +313,5 @@
 
         dcPage::addSuccessNotice(__('Dashboard options has been successfully updated.'));
-        $core->adminurl->redirect("admin.user.preferences", array(), '#user-favorites');
+        $core->adminurl->redirect("admin.user.preferences", [], '#user-favorites');
     } catch (Exception $e) {
         $core->error->add($e->getMessage());
@@ -335,5 +335,5 @@
         if (!$core->error->flag()) {
             dcPage::addSuccessNotice(__('Favorites have been successfully added.'));
-            $core->adminurl->redirect("admin.user.preferences", array(), '#user-favorites');
+            $core->adminurl->redirect("admin.user.preferences", [], '#user-favorites');
         }
     } catch (Exception $e) {
@@ -348,5 +348,5 @@
             throw new Exception(__('No favorite selected'));
         }
-        $user_fav_ids = array();
+        $user_fav_ids = [];
         foreach ($core->favs->getFavoriteIDs(false) as $v) {
             $user_fav_ids[$v] = true;
@@ -360,5 +360,5 @@
         if (!$core->error->flag()) {
             dcPage::addSuccessNotice(__('Favorites have been successfully removed.'));
-            $core->adminurl->redirect("admin.user.preferences", array(), '#user-favorites');
+            $core->adminurl->redirect("admin.user.preferences", [], '#user-favorites');
         }
     } catch (Exception $e) {
@@ -368,5 +368,5 @@
 
 # Order favs
-$order = array();
+$order = [];
 if (empty($_POST['favs_order']) && !empty($_POST['order'])) {
     $order = $_POST['order'];
@@ -386,5 +386,5 @@
     if (!$core->error->flag()) {
         dcPage::addSuccessNotice(__('Favorites have been successfully updated.'));
-        $core->adminurl->redirect("admin.user.preferences", array(), '#user-favorites');
+        $core->adminurl->redirect("admin.user.preferences", [], '#user-favorites');
     }
 }
@@ -397,5 +397,18 @@
     if (!$core->error->flag()) {
         dcPage::addSuccessNotice(__('Default favorites have been successfully updated.'));
-        $core->adminurl->redirect("admin.user.preferences", array(), '#user-favorites');
+        $core->adminurl->redirect("admin.user.preferences", [], '#user-favorites');
+    }
+}
+
+# Reset dashboard items order
+if (!empty($_POST['resetorder'])) {
+    $core->auth->user_prefs->dashboard->drop('main_order');
+    $core->auth->user_prefs->dashboard->drop('boxes_order');
+    $core->auth->user_prefs->dashboard->drop('boxes_items_order');
+    $core->auth->user_prefs->dashboard->drop('boxes_contents_order');
+
+    if (!$core->error->flag()) {
+        dcPage::addSuccessNotice(__('Dashboard items order have been successfully reset.'));
+        $core->adminurl->redirect("admin.user.preferences", [], '#user-favorites');
     }
 }
@@ -426,8 +439,8 @@
 
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->auth->userID()) => '',
             $page_title                             => ''
-        ))
+        ])
 );
 
@@ -440,37 +453,37 @@
 
 '<p><label for="user_name">' . __('Last Name:') . '</label>' .
-form::field('user_name', 20, 255, array(
+form::field('user_name', 20, 255, [
     'default'      => html::escapeHTML($user_name),
     'autocomplete' => 'family-name'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_firstname">' . __('First Name:') . '</label>' .
-form::field('user_firstname', 20, 255, array(
+form::field('user_firstname', 20, 255, [
     'default'      => html::escapeHTML($user_firstname),
     'autocomplete' => 'given-name'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_displayname">' . __('Display name:') . '</label>' .
-form::field('user_displayname', 20, 255, array(
+form::field('user_displayname', 20, 255, [
     'default'      => html::escapeHTML($user_displayname),
     'autocomplete' => 'nickname'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_email">' . __('Email:') . '</label>' .
-form::email('user_email', array(
+form::email('user_email', [
     'default'      => html::escapeHTML($user_email),
     'autocomplete' => 'email'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_url">' . __('URL:') . '</label>' .
-form::url('user_url', array(
+form::url('user_url', [
     'size'         => 30,
     'default'      => html::escapeHTML($user_url),
     'autocomplete' => 'url'
-)) .
+]) .
 '</p>' .
 
@@ -488,7 +501,7 @@
     '<p class="pw-cell"><label for="new_pwd">' . __('New password:') . '</label>' .
     form::password('new_pwd', 20, 255,
-        array(
+        [
             'extra_html'   => 'data-indicator="pwindicator"',
-            'autocomplete' => 'new-password')
+            'autocomplete' => 'new-password']
     ) . '</p>' .
     '<div id="pwindicator">' .
@@ -500,12 +513,12 @@
     '<p><label for="new_pwd_c">' . __('Confirm new password:') . '</label>' .
     form::password('new_pwd_c', 20, 255,
-        array(
-            'autocomplete' => 'new-password')
+        [
+            'autocomplete' => 'new-password']
     ) . '</p>' .
 
     '<p><label for="cur_pwd">' . __('Your current password:') . '</label>' .
     form::password('cur_pwd', 20, 255,
-        array(
-            'autocomplete' => 'current-password')
+        [
+            'autocomplete' => 'current-password']
     ) . '</p>' .
     '<p class="form-note warn">' .
@@ -597,5 +610,5 @@
         echo
         '<p><label for="cols_' . $col_type . '-' . $col_name . '" class="classic">' .
-        form::checkbox(array('cols_' . $col_type . '[]', 'cols_' . $col_type . '-' . $col_name), $col_name, $col_data[0]) . $col_data[1] . '</label>';
+        form::checkbox(['cols_' . $col_type . '[]', 'cols_' . $col_type . '-' . $col_name], $col_name, $col_data[0]) . $col_data[1] . '</label>';
     }
     echo '</div>';
@@ -613,6 +626,6 @@
     '<p class="field"><label for="user_editor_' . $format . '">' . sprintf(__('Preferred editor for %s:'), $format) . '</label>' .
     form::combo(
-        array('user_editor[' . $format . ']', 'user_editor_' . $format),
-        array_merge(array(__('Choose an editor') => ''), $editors),
+        ['user_editor[' . $format . ']', 'user_editor_' . $format],
+        array_merge([__('Choose an editor') => ''], $editors),
         $user_options['editor'][$format]
     ) . '</p>';
@@ -644,5 +657,5 @@
     echo
     '<p><label for="rte_' . $rk . '" class="classic">' .
-    form::checkbox(array('rte_flags[]', 'rte_' . $rk), $rk, $rv[0]) . $rv[1] . '</label>';
+    form::checkbox(['rte_flags[]', 'rte_' . $rk], $rk, $rv[0]) . $rv[1] . '</label>';
 }
 echo '</div>';
@@ -669,4 +682,5 @@
 echo '<h3>' . __('My dashboard') . '</h3>';
 
+# Favorites
 echo '<form action="' . $core->adminurl->get("admin.user.preferences") . '" method="post" id="favs-form" class="two-boxes odd">';
 
@@ -686,11 +700,11 @@
         echo '<li id="fu-' . $id . '">' . '<label for="fuk-' . $id . '">' .
         '<img src="' . dc_admin_icon_url($fav['small-icon']) . '" alt="" /> ' . '<span class="zoom"><img src="' . dc_admin_icon_url($fav['large-icon']) . '" alt="" /></span>' .
-        form::field(array('order[' . $id . ']'), 2, 3, array(
+        form::field(['order[' . $id . ']'], 2, 3, [
             'default'    => $count,
             'class'      => 'position',
             'extra_html' => 'title="' . sprintf(__('position of %s'), $fav['title']) . '"'
-        )) .
-        form::hidden(array('dynorder[]', 'dynorder-' . $id . ''), $id) .
-        form::checkbox(array('remove[]', 'fuk-' . $id), $id) . __($fav['title']) . '</label>' .
+        ]) .
+        form::hidden(['dynorder[]', 'dynorder-' . $id . ''], $id) .
+        form::checkbox(['remove[]', 'fuk-' . $id], $id) . __($fav['title']) . '</label>' .
             '</li>';
     }
@@ -727,5 +741,5 @@
 
 $avail_fav       = $core->favs->getFavorites($core->favs->getAvailableFavoritesIDs());
-$default_fav_ids = array();
+$default_fav_ids = [];
 foreach ($core->favs->getFavoriteIDs(true) as $v) {
     $default_fav_ids[$v] = true;
@@ -757,5 +771,5 @@
     '<img src="' . dc_admin_icon_url($fav['small-icon']) . '" alt="" /> ' .
     '<span class="zoom"><img src="' . dc_admin_icon_url($fav['large-icon']) . '" alt="" /></span>' .
-    form::checkbox(array('append[]', 'fak-' . $k), $k) .
+    form::checkbox(['append[]', 'fak-' . $k], $k) .
         $fav['title'] . '</label>' .
         (isset($default_fav_ids[$k]) ? ' <span class="default-fav"><img src="images/selected.png" alt="' . __('(default favorite)') . '" /></span>' : '') .
@@ -774,4 +788,5 @@
 echo '</form>';
 
+# Dashboard items
 echo
 '<form action="' . $core->adminurl->get("admin.user.preferences") . '" method="post" id="db-forms" class="two-boxes even">' .
@@ -835,4 +850,14 @@
     '</form>';
 
+# Dashboard items order (reset)
+echo '<form action="' . $core->adminurl->get("admin.user.preferences") . '" method="post" id="order-reset" class="two-boxes even">';
+echo '<div class="fieldset"><h4>' . __('Dashboard items order') . '</h4>';
+echo
+'<p>' .
+$core->formNonce() .
+'<input type="submit" name="resetorder" value="' . __('Reset dashboard items order') . '" /></p>';
+echo '</div>';
+echo '</form>';
+
 echo '</div>'; # /multipart-user-favorites
 
Index: admin/search.php
===================================================================
--- admin/search.php	(revision 3731)
+++ admin/search.php	(revision 3874)
@@ -26,5 +26,5 @@
     $q = html::escapeHTML($q);
 
-    $params = array();
+    $params = [];
 
     # Get posts
@@ -33,5 +33,5 @@
 
         $params['search']     = $q;
-        $params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+        $params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
         $params['no_content'] = true;
         $params['order']      = 'post_dt DESC';
@@ -50,5 +50,5 @@
 
         $params['search']     = $q;
-        $params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+        $params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
         $params['no_content'] = true;
         $params['order']      = 'comment_dt DESC';
@@ -65,5 +65,5 @@
 
 if ($qtype == 'p') {
-    $posts_actions_page = new dcPostsActionsPage($core, $core->adminurl->get("admin.search"), array('q' => $q, 'qtype' => $qtype));
+    $posts_actions_page = new dcPostsActionsPage($core, $core->adminurl->get("admin.search"), ['q' => $q, 'qtype' => $qtype]);
 
     if ($posts_actions_page->process()) {
@@ -71,5 +71,5 @@
     }
 } else {
-    $comments_actions_page = new dcCommentsActionsPage($core, $core->adminurl->get("admin.search"), array('q' => $q, 'qtype' => $qtype));
+    $comments_actions_page = new dcCommentsActionsPage($core, $core->adminurl->get("admin.search"), ['q' => $q, 'qtype' => $qtype]);
 
     if ($comments_actions_page->process()) {
@@ -80,8 +80,8 @@
 dcPage::open(__('Search'), $starting_scripts,
     dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Search')                        => ''
-        ))
+        ])
 );
 
@@ -90,6 +90,6 @@
 '<div class="fieldset"><h3>' . __('Search options') . '</h3>' .
 '<p><label for="q">' . __('Query:') . ' </label>' . form::field('q', 30, 255, $q) . '</p>' .
-'<p><label for="qtype1" class="classic">' . form::radio(array('qtype', 'qtype1'), 'p', $qtype == 'p') . ' ' . __('Search in entries') . '</label> ' .
-'<label for="qtype2" class="classic">' . form::radio(array('qtype', 'qtype2'), 'c', $qtype == 'c') . ' ' . __('Search in comments') . '</label></p>' .
+'<p><label for="qtype1" class="classic">' . form::radio(['qtype', 'qtype1'], 'p', $qtype == 'p') . ' ' . __('Search in entries') . '</label> ' .
+'<label for="qtype2" class="classic">' . form::radio(['qtype', 'qtype2'], 'c', $qtype == 'c') . ' ' . __('Search in comments') . '</label></p>' .
 '<p><input type="submit" value="' . __('Search') . '" /></p>' .
     '</div>' .
@@ -117,5 +117,5 @@
 
             '<p class="col right"><label for="action1" class="classic">' . __('Selected entries action:') . '</label> ' .
-            form::combo(array('action', 'action1'), $posts_actions_page->getCombo()) .
+            form::combo(['action', 'action1'], $posts_actions_page->getCombo()) .
             '<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
             $core->formNonce() .
@@ -144,5 +144,5 @@
 
             '<p class="col right"><label for="action2" class="classic">' . __('Selected comments action:') . '</label> ' .
-            form::combo(array('action', 'action2'), $comments_actions_page->getCombo()) .
+            form::combo(['action', 'action2'], $comments_actions_page->getCombo()) .
             '<input id="do-action" type="submit" value="' . __('ok') . '" /></p>' .
             $core->formNonce() .
Index: admin/services.php
===================================================================
--- admin/services.php	(revision 3781)
+++ admin/services.php	(revision 3874)
@@ -10,19 +10,20 @@
 require dirname(__FILE__) . '/../inc/admin/prepend.php';
 
-$core->rest->addFunction('getPostsCount', array('dcRestMethods', 'getPostsCount'));
-$core->rest->addFunction('getCommentsCount', array('dcRestMethods', 'getCommentsCount'));
-$core->rest->addFunction('checkNewsUpdate', array('dcRestMethods', 'checkNewsUpdate'));
-$core->rest->addFunction('checkCoreUpdate', array('dcRestMethods', 'checkCoreUpdate'));
-$core->rest->addFunction('getPostById', array('dcRestMethods', 'getPostById'));
-$core->rest->addFunction('getCommentById', array('dcRestMethods', 'getCommentById'));
-$core->rest->addFunction('quickPost', array('dcRestMethods', 'quickPost'));
-$core->rest->addFunction('validatePostMarkup', array('dcRestMethods', 'validatePostMarkup'));
-$core->rest->addFunction('getZipMediaContent', array('dcRestMethods', 'getZipMediaContent'));
-$core->rest->addFunction('getMeta', array('dcRestMethods', 'getMeta'));
-$core->rest->addFunction('delMeta', array('dcRestMethods', 'delMeta'));
-$core->rest->addFunction('setPostMeta', array('dcRestMethods', 'setPostMeta'));
-$core->rest->addFunction('searchMeta', array('dcRestMethods', 'searchMeta'));
-$core->rest->addFunction('setSectionFold', array('dcRestMethods', 'setSectionFold'));
-$core->rest->addFunction('getModuleById', array('dcRestMethods', 'getModuleById'));
+$core->rest->addFunction('getPostsCount', ['dcRestMethods', 'getPostsCount']);
+$core->rest->addFunction('getCommentsCount', ['dcRestMethods', 'getCommentsCount']);
+$core->rest->addFunction('checkNewsUpdate', ['dcRestMethods', 'checkNewsUpdate']);
+$core->rest->addFunction('checkCoreUpdate', ['dcRestMethods', 'checkCoreUpdate']);
+$core->rest->addFunction('getPostById', ['dcRestMethods', 'getPostById']);
+$core->rest->addFunction('getCommentById', ['dcRestMethods', 'getCommentById']);
+$core->rest->addFunction('quickPost', ['dcRestMethods', 'quickPost']);
+$core->rest->addFunction('validatePostMarkup', ['dcRestMethods', 'validatePostMarkup']);
+$core->rest->addFunction('getZipMediaContent', ['dcRestMethods', 'getZipMediaContent']);
+$core->rest->addFunction('getMeta', ['dcRestMethods', 'getMeta']);
+$core->rest->addFunction('delMeta', ['dcRestMethods', 'delMeta']);
+$core->rest->addFunction('setPostMeta', ['dcRestMethods', 'setPostMeta']);
+$core->rest->addFunction('searchMeta', ['dcRestMethods', 'searchMeta']);
+$core->rest->addFunction('setSectionFold', ['dcRestMethods', 'setSectionFold']);
+$core->rest->addFunction('getModuleById', ['dcRestMethods', 'getModuleById']);
+$core->rest->addFunction('setDashboardPositions', ['dcRestMethods', 'setDashboardPositions']);
 
 $core->rest->serve();
@@ -39,5 +40,5 @@
     public static function getPostsCount($core, $get)
     {
-        $count = $core->blog->getPosts(array(), true)->f(0);
+        $count = $core->blog->getPosts([], true)->f(0);
         $str   = sprintf(__('%d post', '%d posts', $count), $count);
 
@@ -56,5 +57,5 @@
     public static function getCommentsCount($core, $get)
     {
-        $count = $core->blog->getComments(array(), true)->f(0);
+        $count = $core->blog->getComments([], true)->f(0);
         $str   = sprintf(__('%d comment', '%d comments', $count), $count);
 
@@ -86,5 +87,5 @@
                 $feed = $feed_reader->parse($GLOBALS['__resources']['rss_news']);
                 if ($feed) {
-                    $ret = '<div class="box medium dc-box"><h3>' . __('Dotclear news') . '</h3><dl id="news">';
+                    $ret = '<div class="box medium dc-box" id="ajax-news"><h3>' . __('Dotclear news') . '</h3><dl id="news">';
                     $i   = 1;
                     foreach ($feed->items as $item) {
@@ -132,7 +133,7 @@
                 if (version_compare(phpversion(), $updater->getPHPVersion()) >= 0) {
                     $ret =
-                    '<div class="dc-update"><h3>' . sprintf(__('Dotclear %s is available!'), $new_v) . '</h3> ' .
+                    '<div class="dc-update" id="ajax-update"><h3>' . sprintf(__('Dotclear %s is available!'), $new_v) . '</h3> ' .
                     '<p><a class="button submit" href="' . $core->adminurl->get("admin.update") . '">' . sprintf(__('Upgrade now'), $new_v) . '</a> ' .
-                    '<a class="button" href="' . $core->adminurl->get("admin.update", array('hide_msg' => 1)) . '">' . __('Remind me later') . '</a>' .
+                    '<a class="button" href="' . $core->adminurl->get("admin.update", ['hide_msg' => 1]) . '">' . __('Remind me later') . '</a>' .
                         ($version_info ? ' </p>' .
                         '<p class="updt-info"><a href="' . $version_info . '">' . __('Information about this version') . '</a>' : '') . '</p>' .
@@ -165,5 +166,5 @@
         }
 
-        $params = array('post_id' => (integer) $get['id']);
+        $params = ['post_id' => (integer) $get['id']];
 
         if (isset($get['post_type'])) {
@@ -231,5 +232,5 @@
         }
 
-        $rs = $core->blog->getComments(array('comment_id' => (integer) $get['id']));
+        $rs = $core->blog->getComments(['comment_id' => (integer) $get['id']]);
 
         if ($rs->isEmpty()) {
@@ -307,5 +308,5 @@
         $rsp->id = $return_id;
 
-        $post = $core->blog->getPosts(array('post_id' => $return_id));
+        $post = $core->blog->getPosts(['post_id' => $return_id]);
 
         $rsp->post_status = $post->post_status;
@@ -391,9 +392,9 @@
         $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc';
 
-        $rs = $core->meta->getMetadata(array(
+        $rs = $core->meta->getMetadata([
             'meta_type' => $metaType,
             'limit'     => $limit,
             'meta_id'   => $metaId,
-            'post_id'   => $postid));
+            'post_id'   => $postid]);
         $rs = $core->meta->computeMetaStats($rs);
 
@@ -450,8 +451,8 @@
 
         # Get previous meta for post
-        $post_meta = $core->meta->getMetadata(array(
+        $post_meta = $core->meta->getMetadata([
             'meta_type' => $post['metaType'],
-            'post_id'   => $post['postId']));
-        $pm = array();
+            'post_id'   => $post['postId']]);
+        $pm = [];
         while ($post_meta->fetch()) {
             $pm[] = $post_meta->meta_id;
@@ -493,5 +494,5 @@
         $sortby = !empty($get['sortby']) ? $get['sortby'] : 'meta_type,asc';
 
-        $rs = $core->meta->getMetadata(array('meta_type' => $metaType));
+        $rs = $core->meta->getMetadata(['meta_type' => $metaType]);
         $rs = $core->meta->computeMetaStats($rs);
 
@@ -548,5 +549,5 @@
             $toggles = explode(',', trim($core->auth->user_prefs->toggles->unfolded_sections));
         } else {
-            $toggles = array();
+            $toggles = [];
         }
         $k = array_search($section, $toggles);
@@ -566,4 +567,24 @@
     }
 
+    public static function setDashboardPositions($core, $get, $post)
+    {
+        if (empty($post['id'])) {
+            throw new Exception('No zone name');
+        }
+        if (empty($post['list'])) {
+            throw new Exception('No sorted list of id');
+        }
+
+        if ($core->auth->user_prefs->dashboard === null) {
+            $core->auth->user_prefs->addWorkspace('dashboard');
+        }
+
+        $zone  = $post['id'];
+        $order = $post['list'];
+
+        $core->auth->user_prefs->dashboard->put($zone, $order);
+        return true;
+    }
+
     public static function getModuleById($core, $get, $post)
     {
@@ -577,5 +598,5 @@
         $id     = $get['id'];
         $list   = $get['list'];
-        $module = array();
+        $module = [];
 
         if ($list == 'plugin-activate') {
Index: admin/style/default-dark.css
===================================================================
--- admin/style/default-dark.css	(revision 3853)
+++ admin/style/default-dark.css	(revision 3877)
@@ -21,5 +21,6 @@
 
 a {
-  background: transparent; }
+  background: transparent;
+  }
   a:focus {
     outline: thin dotted; }
@@ -224,4 +225,7 @@
   Colors
 --------------------------------------------------- */
+/* bright red */
+/* slategray */
+/* soft dark blue */
 /** --------------------------------------------------
     Common rules
@@ -229,5 +233,7 @@
 /* Typographie */
 :root {
-  --html-font-size: 62.5%; }
+  --html-font-size: 62.5%;
+  --body-color: #dcdee0;
+  --body-background: #272b30; }
 
 html {
@@ -745,5 +751,6 @@
   margin: 0 -1em 1em -1em;
   background: #272b30;
-  border-bottom: 1px solid #86888c; }
+  border-bottom: 1px solid #86888c;
+  }
 
 /* page courante dans le fil d'ariane */
@@ -962,4 +969,8 @@
   border-color: #cbced1;
   background: #272b30; }
+  fieldset hr {
+    background-color: #cbced1;
+    border-width: 0;
+    margin: 1em 0; }
   fieldset:focus-within {
     background-color: #363a3e; }
@@ -1080,4 +1091,8 @@
   margin-top: .3em;
   margin-bottom: .3em; }
+
+input[type=color] {
+  width: 4em;
+  height: 3em; }
 
 optgroup {
@@ -1583,10 +1598,6 @@
   padding: 0;
   overflow: hidden;
-  position: absolute;
-  top: 3em;
-  left: 0;
   background: #a2cbe9;
-  width: 100%;
-  z-index: 100; }
+  width: 100%; }
   #prelude li {
     list-style-type: none;
@@ -2111,7 +2122,10 @@
 #dashboard-main {
   text-align: center; }
+  #dashboard-main > *:last-child {
+    margin-bottom: 1em; }
 
 /* raccourcis */
 #icons {
+  margin: 1em auto 2em;
   display: flex;
   flex-wrap: wrap;
@@ -2150,7 +2164,7 @@
 /* billet rapide */
 #quick {
+  max-width: 72em;
+  margin: 1em auto 2em;
   padding: 1em;
-  max-width: 72em;
-  margin: 0 auto;
   background: #323334;
   border: 1px solid #dbdcdd;
@@ -2165,7 +2179,5 @@
     padding: .2em 1em .1em 24px;
     color: #323334; }
-  #quick #new_cat,
-  #quick .q-cat,
-  #quick .q-cat label {
+  #quick #new_cat, #quick .q-cat, #quick .q-cat label {
     display: inline-block;
     vertical-align: top;
@@ -2179,6 +2191,5 @@
 /* modules additionnels */
 #dashboard-boxes {
-  margin: 1em auto 1em;
-  padding-top: 2em;
+  margin: 1em auto 2em;
   display: flex;
   flex-wrap: wrap;
@@ -2192,20 +2203,16 @@
     text-align: left; }
 
-.db-items,
-.db-contents {
+.db-items, .db-contents {
   display: flex;
   flex-wrap: wrap;
   justify-content: center;
   flex: 1 1 auto; }
-  .db-items img,
-  .db-contents img {
+  .db-items img, .db-contents img {
     vertical-align: middle; }
-  .db-items ul,
-  .db-contents ul {
+  .db-items ul, .db-contents ul {
     display: block;
     padding-left: 1.5em;
     list-style: square; }
-  .db-items li,
-  .db-contents li {
+  .db-items li, .db-contents li {
     margin: 0.25em 0 0 0; }
 
@@ -3113,4 +3120,8 @@
   .fieldset h3 {
     margin-top: 0; }
+  .fieldset hr {
+    background-color: #cbced1;
+    border-width: 0;
+    margin: 1em 0; }
   .fieldset:focus-within {
     background-color: #363a3e; }
@@ -3164,5 +3175,6 @@
 
 .offline {
-  color: #86888c; }
+  color: #86888c;
+  background: #323334; }
 
 /* caché pour tout le monde */
@@ -3193,4 +3205,10 @@
 
 /* ---------------------------------------------- Couleurs ajoutées via javascript
+
+/* Sortable (jQuery UI) */
+.sortable-area {
+  border: 1px dashed currentColor;
+  background-color: #4c4d4f; }
+
 /* color-picker.js */
 .color-color-picker {
@@ -3202,4 +3220,67 @@
 .color-div {
   border: 1px solid #c9cbcf; }
+
+/* Badges (common.js) */
+.badgeable {
+  /* class to set to badge parent's, not mandatory for menu items */
+  position: relative; }
+
+/* Badge design */
+.badge {
+  color: #fff;
+  background-color: #d54e21;
+  border: 1px solid #dcdee0;
+  vertical-align: top;
+  border-radius: 10px;
+  padding: 0 .6em; }
+
+.badge-icon {
+  background-color: #607d8b; }
+
+/* Badge background override */
+.badge-std {
+  background-color: #d54e21; }
+
+.badge-info {
+  background-color: #3f51b5; }
+
+.badge-soft {
+  background-color: #607d8b; }
+
+/* Badge position */
+.badge-block {
+  /* Dashboard module → badge on top right */
+  position: absolute;
+  top: -10px;
+  right: -10px; }
+
+.badge-icon {
+  /* Dashboard icon → badge on top right */
+  right: 20px; }
+
+.badge-inline {
+  /* Menu item */
+  margin-left: .5em; }
+
+.badge-left {
+  right: auto;
+  left: -10px; }
+  .badge-left.badge-icon {
+    left: 20px; }
+
+/* Badge design option */
+.badge-noborder {
+  border: none; }
+
+.badge-small {
+  font-size: smaller; }
+  .badge-small.badge-icon {
+    right: 25px; }
+    .badge-small.badge-icon.badge-left {
+      right: auto;
+      left: 25px; }
+
+.badge-square {
+  border-radius: 0; }
 
 /* ------------------------------------------------------------------------------------
Index: admin/style/default.css
===================================================================
--- admin/style/default.css	(revision 3853)
+++ admin/style/default.css	(revision 3876)
@@ -224,4 +224,7 @@
   Colors
 --------------------------------------------------- */
+/* bright red */
+/* slategray */
+/* soft dark blue */
 /** --------------------------------------------------
     Common rules
@@ -229,5 +232,7 @@
 /* Typographie */
 :root {
-  --html-font-size: 62.5%; }
+  --html-font-size: 62.5%;
+  --body-color: #323232;
+  --body-background: #fff; }
 
 html {
@@ -962,4 +967,8 @@
   border-color: #cbced1;
   background: #fff; }
+  fieldset hr {
+    background-color: #cbced1;
+    border-width: 0;
+    margin: 1em 0; }
   fieldset:focus-within {
     background-color: #ededed; }
@@ -1080,4 +1089,8 @@
   margin-top: .3em;
   margin-bottom: .3em; }
+
+input[type=color] {
+  width: 4em;
+  height: 3em; }
 
 optgroup {
@@ -1583,10 +1596,6 @@
   padding: 0;
   overflow: hidden;
-  position: absolute;
-  top: 3em;
-  left: 0;
   background: #a2cbe9;
-  width: 100%;
-  z-index: 100; }
+  width: 100%; }
   #prelude li {
     list-style-type: none;
@@ -2111,7 +2120,10 @@
 #dashboard-main {
   text-align: center; }
+  #dashboard-main > *:last-child {
+    margin-bottom: 1em; }
 
 /* raccourcis */
 #icons {
+  margin: 1em auto 2em;
   display: flex;
   flex-wrap: wrap;
@@ -2150,7 +2162,7 @@
 /* billet rapide */
 #quick {
+  max-width: 72em;
+  margin: 1em auto 2em;
   padding: 1em;
-  max-width: 72em;
-  margin: 0 auto;
   background: #f3f3f3;
   border: 1px solid #dbdbdb;
@@ -2165,7 +2177,5 @@
     padding: .2em 1em .1em 24px;
     color: #323232; }
-  #quick #new_cat,
-  #quick .q-cat,
-  #quick .q-cat label {
+  #quick #new_cat, #quick .q-cat, #quick .q-cat label {
     display: inline-block;
     vertical-align: top;
@@ -2179,6 +2189,5 @@
 /* modules additionnels */
 #dashboard-boxes {
-  margin: 1em auto 1em;
-  padding-top: 2em;
+  margin: 1em auto 2em;
   display: flex;
   flex-wrap: wrap;
@@ -2192,20 +2201,16 @@
     text-align: left; }
 
-.db-items,
-.db-contents {
+.db-items, .db-contents {
   display: flex;
   flex-wrap: wrap;
   justify-content: center;
   flex: 1 1 auto; }
-  .db-items img,
-  .db-contents img {
+  .db-items img, .db-contents img {
     vertical-align: middle; }
-  .db-items ul,
-  .db-contents ul {
+  .db-items ul, .db-contents ul {
     display: block;
     padding-left: 1.5em;
     list-style: square; }
-  .db-items li,
-  .db-contents li {
+  .db-items li, .db-contents li {
     margin: 0.25em 0 0 0; }
 
@@ -3113,4 +3118,8 @@
   .fieldset h3 {
     margin-top: 0; }
+  .fieldset hr {
+    background-color: #cbced1;
+    border-width: 0;
+    margin: 1em 0; }
   .fieldset:focus-within {
     background-color: #ededed; }
@@ -3164,5 +3173,6 @@
 
 .offline {
-  color: #676e78; }
+  color: #676e78;
+  background: #f3f3f3; }
 
 /* caché pour tout le monde */
@@ -3193,4 +3203,10 @@
 
 /* ---------------------------------------------- Couleurs ajoutées via javascript
+
+/* Sortable (jQuery UI) */
+.sortable-area {
+  border: 1px dashed currentColor;
+  background-color: #f3f3f3; }
+
 /* color-picker.js */
 .color-color-picker {
@@ -3202,4 +3218,67 @@
 .color-div {
   border: 1px solid #c9c9c9; }
+
+/* Badges (common.js) */
+.badgeable {
+  /* class to set to badge parent's, not mandatory for menu items */
+  position: relative; }
+
+/* Badge design */
+.badge {
+  color: #fff;
+  background-color: #d54e21;
+  border: 1px solid transparent;
+  vertical-align: top;
+  border-radius: 10px;
+  padding: 0 .6em; }
+
+.badge-icon {
+  background-color: #607d8b; }
+
+/* Badge background override */
+.badge-std {
+  background-color: #d54e21; }
+
+.badge-info {
+  background-color: #3f51b5; }
+
+.badge-soft {
+  background-color: #607d8b; }
+
+/* Badge position */
+.badge-block {
+  /* Dashboard module → badge on top right */
+  position: absolute;
+  top: -10px;
+  right: -10px; }
+
+.badge-icon {
+  /* Dashboard icon → badge on top right */
+  right: 20px; }
+
+.badge-inline {
+  /* Menu item */
+  margin-left: .5em; }
+
+.badge-left {
+  right: auto;
+  left: -10px; }
+  .badge-left.badge-icon {
+    left: 20px; }
+
+/* Badge design option */
+.badge-noborder {
+  border: none; }
+
+.badge-small {
+  font-size: smaller; }
+  .badge-small.badge-icon {
+    right: 25px; }
+    .badge-small.badge-icon.badge-left {
+      right: auto;
+      left: 25px; }
+
+.badge-square {
+  border-radius: 0; }
 
 /* ------------------------------------------------------------------------------------
Index: admin/style/scss/partials/_classes.scss
===================================================================
--- admin/style/scss/partials/_classes.scss	(revision 3774)
+++ admin/style/scss/partials/_classes.scss	(revision 3876)
@@ -266,4 +266,9 @@
 		margin-top: 0;
 	}
+  hr {
+    background-color: $fieldset-border;
+    border-width: 0;
+    margin: 1em 0;
+  }
 	&:focus-within {
 		background-color: $fieldset-focus-background;
@@ -333,4 +338,5 @@
 .offline {
 	color: $offline;
+  background: $offline-background;
 }
 
Index: admin/style/scss/partials/_common.scss
===================================================================
--- admin/style/scss/partials/_common.scss	(revision 3763)
+++ admin/style/scss/partials/_common.scss	(revision 3828)
@@ -4,4 +4,7 @@
 	// May be superseed by user pref (typically from 50% to 75%, default 62.5%)
 	--html-font-size: #{$html-font-size};
+  // Main colors
+  --body-color: #{$body-color};
+  --body-background: #{$body-background};
 }
 
Index: admin/style/scss/partials/_forms.scss
===================================================================
--- admin/style/scss/partials/_forms.scss	(revision 3780)
+++ admin/style/scss/partials/_forms.scss	(revision 3876)
@@ -44,4 +44,9 @@
   border-color: $fieldset-border;
   background: $fieldset-background;
+  hr {
+    background-color: $fieldset-border;
+    border-width: 0;
+    margin: 1em 0;
+  }
   &:focus-within {
     background-color: $fieldset-focus-background;
@@ -180,4 +185,8 @@
   margin-bottom: .3em;
 }
+input[type=color] {
+  width: 4em;
+  height: 3em;
+}
 optgroup {
   font-weight: bold;
Index: admin/style/scss/partials/_header.scss
===================================================================
--- admin/style/scss/partials/_header.scss	(revision 3763)
+++ admin/style/scss/partials/_header.scss	(revision 3822)
@@ -6,10 +6,6 @@
 	padding: 0;
 	overflow: hidden;
-	position: absolute;
-	top: 3em;
-	left: 0;
 	background: $prelude-background;
 	width: 100%;
-	z-index: 100;
 	li {
 		list-style-type: none;
Index: admin/style/scss/partials/_index.scss
===================================================================
--- admin/style/scss/partials/_index.scss	(revision 3787)
+++ admin/style/scss/partials/_index.scss	(revision 3839)
@@ -1,157 +1,142 @@
 #dashboard-main {
-	text-align: center;
+  text-align: center;
+  & > *:last-child {
+    margin-bottom: 1em;
+  }
 }
-
-
 /* raccourcis */
 
 #icons {
-	display: flex;
-	flex-wrap: wrap;
-	justify-content: center;
-	p {
-		width: 13em;
-		margin: 1em 0 2em;
+  margin: 1em auto 2em;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+  p {
+    width: 13em;
+    margin: 1em 0 2em;
     display: flex;
     flex-direction: column;
     justify-content: flex-start;
     align-items: center;
-	}
-	a {
-		&,
-		&:link,
-		&:visited,
-		&:hover,
-		&:focus {
-			border-bottom-width: 0;
-			text-decoration: none;
-		}
-		span {
+  }
+  a {
+    &, &:link, &:visited, &:hover, &:focus {
+      border-bottom-width: 0;
+      text-decoration: none;
+    }
+    span {
       color: $index-link-color;
-			border-bottom: 1px dotted $index-link-border;
-		}
-		img {
-			padding: 1.5em;
-			background-color: $index-icon-background;
-			border-radius: 8px;
-			border: 1px solid $index-icon-border;
-			display: inline-block;
+      border-bottom: 1px dotted $index-link-border;
+    }
+    img {
+      padding: 1.5em;
+      background-color: $index-icon-background;
+      border-radius: 8px;
+      border: 1px solid $index-icon-border;
+      display: inline-block;
       filter: contrast($index-icon-contrast);
-		}
-		&:focus {
-			outline: 0;
-			span {
-				border: 2px solid $index-icon-outline;
-			}
-		}
-		&:focus,
-		&:hover {
-			img {
-				background: $index-icon-outline;
-				outline: 0;
-				border-color: $index-icon-border;
-			}
-			span {
-				border-bottom-style: solid;
-			}
-		}
-	}
+    }
+    &:focus {
+      outline: 0;
+      span {
+        border: 2px solid $index-icon-outline;
+      }
+    }
+    &:focus, &:hover {
+      img {
+        background: $index-icon-outline;
+        outline: 0;
+        border-color: $index-icon-border;
+      }
+      span {
+        border-bottom-style: solid;
+      }
+    }
+  }
 }
-
-
 /* billet rapide */
 
 #quick {
-	padding: 1em;
-	max-width: 72em;
-	margin: 0 auto;
-	background: $quick-background;
+  max-width: 72em;
+  margin: 1em auto 2em;
+  padding: 1em;
+  background: $quick-background;
   border: 1px solid $quick-border;
-	text-align: left;
-	h3 {
-		margin-bottom: 0.2em;
-		font-size: 1.2em;
-	}
-	p.qinfo {
-		margin: -.7em -1em 1em;
-		background: $quick-info-background url(msg-info.png) no-repeat .2em .2em;
-		border: 1px solid $quick-info-border;
-		padding: .2em 1em .1em 24px;
-		color: $quick-info-color;
-	}
-	#new_cat,
-	.q-cat,
-	.q-cat label {
-		display: inline-block;
-		vertical-align: top;
-		margin-right: 1em;
-		margin-top: 0;
-	}
-	.q-cat label {
-		margin-right: .3em;
-	}
-	#new_cat {
-		margin-bottom: 2em;
-	}
+  text-align: left;
+  h3 {
+    margin-bottom: 0.2em;
+    font-size: 1.2em;
+  }
+  p.qinfo {
+    margin: -.7em -1em 1em;
+    background: $quick-info-background url(msg-info.png) no-repeat .2em .2em;
+    border: 1px solid $quick-info-border;
+    padding: .2em 1em .1em 24px;
+    color: $quick-info-color;
+  }
+  #new_cat, .q-cat, .q-cat label {
+    display: inline-block;
+    vertical-align: top;
+    margin-right: 1em;
+    margin-top: 0;
+  }
+  .q-cat label {
+    margin-right: .3em;
+  }
+  #new_cat {
+    margin-bottom: 2em;
+  }
 }
-
-
 /* modules additionnels */
 
 #dashboard-boxes {
-	margin: 1em auto 1em;
-	padding-top: 2em;
-	display: flex;
-	flex-wrap: wrap;
-	justify-content: center;
-	.box {
-		padding: 10px;
-		border: 1px solid $index-box-border;
-		border-radius: 3px;
-		min-height: 200px;
-		margin: 10px;
-		text-align: left;
-	}
+  margin: 1em auto 2em;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+  .box {
+    padding: 10px;
+    border: 1px solid $index-box-border;
+    border-radius: 3px;
+    min-height: 200px;
+    margin: 10px;
+    text-align: left;
+  }
 }
-
-.db-items,
-.db-contents {
-	//	display: inline-block;
-	//	text-align: center;
-	display: flex;
-	flex-wrap: wrap;
-	justify-content: center;
-	flex: 1 1 auto;
-	img {
-		vertical-align: middle;
-	}
-	ul {
-		display: block;
-		padding-left: 1.5em;
-		list-style: square;
-	}
-	li {
-		margin: 0.25em 0 0 0;
-	}
+.db-items, .db-contents {
+  //  display: inline-block;
+  //  text-align: center;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+  flex: 1 1 auto;
+  img {
+    vertical-align: middle;
+  }
+  ul {
+    display: block;
+    padding-left: 1.5em;
+    list-style: square;
+  }
+  li {
+    margin: 0.25em 0 0 0;
+  }
 }
-
 .no-js .outgoing img {
-	display: none;
+  display: none;
 }
-
 .dc-box {
-	background: transparent url(dc_logos/sq-logo-32.png) no-repeat top right;
+  background: transparent url(dc_logos/sq-logo-32.png) no-repeat top right;
 }
-
 #news {
-	dt {
-		font-weight: bold;
-		margin: 0 0 0.4em 0;
-	}
-	dd {
-		margin: 0 0 1em 0;
-		p {
-			margin: 0.2em 0 0 0;
-		}
-	}
+  dt {
+    font-weight: bold;
+    margin: 0 0 0.4em 0;
+  }
+  dd {
+    margin: 0 0 1em 0;
+    p {
+      margin: 0.2em 0 0 0;
+    }
+  }
 }
Index: admin/style/scss/partials/_utils.scss
===================================================================
--- admin/style/scss/partials/_utils.scss	(revision 3763)
+++ admin/style/scss/partials/_utils.scss	(revision 3871)
@@ -1,3 +1,11 @@
 /* ---------------------------------------------- Couleurs ajoutées via javascript
+
+/* Sortable (jQuery UI) */
+
+.sortable-area {
+  border: 1px dashed currentColor;
+  background-color: $main-menu-background;
+}
+
 /* color-picker.js */
 
@@ -13,2 +21,75 @@
 	border: 1px solid $color-div-border;
 }
+
+/* Badges (common.js) */
+
+.badgeable {
+  /* class to set to badge parent's, not mandatory for menu items */
+  position: relative;
+}
+
+/* Badge design */
+.badge {
+  color: $badge-color;
+  background-color: $badge-std-background;
+  border: 1px solid $badge-border;
+  vertical-align: top;
+  border-radius: 10px;
+  padding: 0 .6em;
+}
+.badge-icon {
+  background-color: $badge-soft-background;
+}
+
+/* Badge background override */
+.badge-std {
+  background-color: $badge-std-background;
+}
+.badge-info {
+  background-color: $badge-info-background;
+}
+.badge-soft {
+  background-color: $badge-soft-background;
+}
+
+/* Badge position */
+.badge-block {
+  /* Dashboard module → badge on top right */
+  position: absolute;
+  top: -10px;
+  right: -10px;
+}
+.badge-icon {
+  /* Dashboard icon → badge on top right */
+  right: 20px;
+}
+.badge-inline {
+  /* Menu item */
+  margin-left: .5em;
+}
+.badge-left {
+  right: auto;
+  left: -10px;
+  &.badge-icon {
+    left: 20px;
+  }
+}
+
+/* Badge design option */
+.badge-noborder {
+  border: none;
+}
+.badge-small {
+  font-size: smaller;
+  &.badge-icon {
+    right: 25px;
+    &.badge-left {
+      right: auto;
+      left: 25px;
+    }
+  }
+}
+.badge-square {
+  border-radius: 0;
+}
+
Index: admin/style/scss/themes/_dark.scss
===================================================================
--- admin/style/scss/themes/_dark.scss	(revision 3780)
+++ admin/style/scss/themes/_dark.scss	(revision 3871)
@@ -68,4 +68,8 @@
 $add:             #bee74b;
 $add-alt:         #9bca1c;
+
+$badge:           #d54e21;  /* bright red */
+$badge-soft:      #607d8b;  /* slategray */
+$badge-info:      #3f51b5;  /* soft dark blue */
 
 // Common
@@ -420,4 +424,5 @@
 
 $offline:                         $gray-semi-dark;
+$offline-background:              $gray-very-dark;
 
 $mark-attach-img:                 url('../images/attach.svg');
@@ -430,4 +435,10 @@
 
 $color-div-border:                $gray-light;
+
+$badge-color:                     $white;                             // #ffffff
+$badge-border:                    $body-color;
+$badge-std-background:            $badge;                             // #d54e21
+$badge-soft-background:           $badge-soft;
+$badge-info-background:           $badge-info;
 
 // Debug
Index: admin/style/scss/themes/_light.scss
===================================================================
--- admin/style/scss/themes/_light.scss	(revision 3780)
+++ admin/style/scss/themes/_light.scss	(revision 3871)
@@ -15,4 +15,5 @@
 
 $gray-very-dark:    shade($gray, 72%);  // #323232 (near to #333 used before)
+$gray-darker:       shade($gray, 50%);  // #595b5d
 $gray-semi-dark:    shade($gray, 25%);  // #868686 (near to #999 used before)
 $gray-light:        tint($gray, 30%);   // #c9c9c9 (near to #ccc used before)
@@ -67,4 +68,8 @@
 $add:             #bee74b;
 $add-alt:         #9bca1c;
+
+$badge:           #d54e21;  /* bright red */
+$badge-soft:      #607d8b;  /* slategray */
+$badge-info:      #3f51b5;  /* soft dark blue */
 
 // Common
@@ -419,4 +424,5 @@
 
 $offline:                         $gray-dark;                         // #676e78
+$offline-background:              $gray-very-light;                   // #f3f3f3
 
 $mark-attach-img:                 url('../images/attach.svg');
@@ -429,4 +435,10 @@
 
 $color-div-border:                $gray-light;                        // #c9c9c9
+
+$badge-color:                     $white;                             // #ffffff
+$badge-border:                    transparent;
+$badge-std-background:            $badge;                             // #d54e21
+$badge-soft-background:           $badge-soft;
+$badge-info-background:           $badge-info;
 
 // Debug
Index: admin/update.php
===================================================================
--- admin/update.php	(revision 3771)
+++ admin/update.php	(revision 3874)
@@ -37,5 +37,5 @@
 
 $step = isset($_GET['step']) ? $_GET['step'] : '';
-$step = in_array($step, array('check', 'download', 'backup', 'unzip')) ? $step : '';
+$step = in_array($step, ['check', 'download', 'backup', 'unzip']) ? $step : '';
 
 $default_tab = !empty($_GET['tab']) ? html::escapeHTML($_GET['tab']) : 'update';
@@ -44,5 +44,5 @@
 }
 
-$archives = array();
+$archives = [];
 foreach (files::scanDir(DC_BACKUP_PATH) as $v) {
     if (preg_match('/backup-([0-9A-Za-z\.-]+).zip/', $v)) {
@@ -159,8 +159,8 @@
         : ''),
     dcPage::breadcrumb(
-        array(
+        [
             __('System')          => '',
             __('Dotclear update') => ''
-        ))
+        ])
 );
 
@@ -211,5 +211,5 @@
         foreach ($archives as $v) {
             echo
-            '<p><label class="classic">' . form::radio(array('backup_file'), html::escapeHTML($v)) . ' ' .
+            '<p><label class="classic">' . form::radio(['backup_file'], html::escapeHTML($v)) . ' ' .
             html::escapeHTML($v) . '</label></p>';
         }
Index: admin/user.php
===================================================================
--- admin/user.php	(revision 3731)
+++ admin/user.php	(revision 3874)
@@ -125,9 +125,9 @@
 
             dcPage::addSuccessNotice(__('User has been successfully updated.'));
-            $core->adminurl->redirect("admin.user", array('id' => $new_id));
+            $core->adminurl->redirect("admin.user", ['id' => $new_id]);
         }
         # Add user
         else {
-            if ($core->getUsers(array('user_id' => $cur->user_id), true)->f(0) > 0) {
+            if ($core->getUsers(['user_id' => $cur->user_id], true)->f(0) > 0) {
                 throw new Exception(sprintf(__('User "%s" already exists.'), html::escapeHTML($cur->user_id)));
             }
@@ -145,5 +145,5 @@
                 $core->adminurl->redirect("admin.user");
             } else {
-                $core->adminurl->redirect("admin.user", array('id' => $new_id));
+                $core->adminurl->redirect("admin.user", ['id' => $new_id]);
             }
         }
@@ -173,9 +173,9 @@
 
     dcPage::breadcrumb(
-        array(
+        [
             __('System') => '',
             __('Users')  => $core->adminurl->get("admin.users"),
             $page_title  => ''
-        ))
+        ])
 );
 
@@ -196,9 +196,9 @@
 
 '<p><label for="user_id" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('User ID:') . '</label> ' .
-form::field('user_id', 20, 255, array(
+form::field('user_id', 20, 255, [
     'default'      => html::escapeHTML($user_id),
     'extra_html'   => 'required placeholder="' . __('Login') . '"',
     'autocomplete' => 'username'
-)) .
+]) .
 '</p>' .
 '<p class="form-note info">' . __('At least 2 characters using letters, numbers or symbols.') . '</p>';
@@ -217,8 +217,8 @@
 ($user_id != '' ? __('New password:') : __('Password:')) . '</label>' .
 form::password('new_pwd', 20, 255,
-    array(
+    [
         'extra_html'   => 'data-indicator="pwindicator"' .
         ($user_id != '' ? '' : ' required placeholder="' . __('Password') . '"'),
-        'autocomplete' => 'new-password')
+        'autocomplete' => 'new-password']
 ) .
 '</p>' .
@@ -233,7 +233,7 @@
 ($user_id != '' ? '' : '<abbr title="' . __('Required field') . '">*</abbr> ') . __('Confirm password:') . '</label> ' .
 form::password('new_pwd_c', 20, 255,
-    array(
+    [
         'extra_html'   => ($user_id != '' ? '' : 'required placeholder="' . __('Password') . '"'),
-        'autocomplete' => 'new-password')) .
+        'autocomplete' => 'new-password']) .
     '</p>';
 
@@ -250,46 +250,46 @@
 '<p><label for="user_super" class="classic">' .
 form::checkbox(($super_disabled ? 'user_super_off' : 'user_super'), '1',
-    array(
+    [
         'checked'  => $user_super,
         'disabled' => $super_disabled
-    )) .
+    ]) .
 ' ' . __('Super administrator') . '</label></p>' .
-($super_disabled ? form::hidden(array('user_super'), $user_super) : '') .
+($super_disabled ? form::hidden(['user_super'], $user_super) : '') .
 
 '<p><label for="user_name">' . __('Last Name:') . '</label> ' .
-form::field('user_name', 20, 255, array(
+form::field('user_name', 20, 255, [
     'default'      => html::escapeHTML($user_name),
     'autocomplete' => 'family-name'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_firstname">' . __('First Name:') . '</label> ' .
-form::field('user_firstname', 20, 255, array(
+form::field('user_firstname', 20, 255, [
     'default'      => html::escapeHTML($user_firstname),
     'autocomplete' => 'given-name'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_displayname">' . __('Display name:') . '</label> ' .
-form::field('user_displayname', 20, 255, array(
+form::field('user_displayname', 20, 255, [
     'default'      => html::escapeHTML($user_displayname),
     'autocomplete' => 'nickname'
-)) .
+]) .
 '</p>' .
 
 '<p><label for="user_email">' . __('Email:') . '</label> ' .
-form::email('user_email', array(
+form::email('user_email', [
     'default'      => html::escapeHTML($user_email),
     'autocomplete' => 'email'
-)) .
+]) .
 '</p>' .
 '<p class="form-note">' . __('Mandatory for password recovering procedure.') . '</p>' .
 
 '<p><label for="user_url">' . __('URL:') . '</label> ' .
-form::url('user_url', array(
+form::url('user_url', [
     'size'         => 30,
     'default'      => html::escapeHTML($user_url),
     'autocomplete' => 'url'
-)) .
+]) .
 '</p>' .
 '</div>' .
@@ -330,8 +330,8 @@
 '<abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label>' .
 form::password('your_pwd', 20, 255,
-    array(
+    [
         'extra_html'   => 'required placeholder="' . __('Password') . '"',
         'autocomplete' => 'current-password'
-    )
+    ]
 ) . '</p>' .
 '<p class="clear"><input type="submit" name="save" accesskey="s" value="' . __('Save') . '" />' .
@@ -351,7 +351,7 @@
         '<form action="' . $core->adminurl->get("admin.user.actions") . '" method="post">' .
         '<p><input type="submit" value="' . __('Add new permissions') . '" />' .
-        form::hidden(array('redir'), $core->adminurl->get("admin.user", array('id' => $user_id))) .
-        form::hidden(array('action'), 'blogs') .
-        form::hidden(array('users[]'), $user_id) .
+        form::hidden(['redir'], $core->adminurl->get("admin.user", ['id' => $user_id])) .
+        form::hidden(['action'], 'blogs') .
+        form::hidden(['users[]'], $user_id) .
         $core->formNonce() .
             '</p>' .
@@ -369,5 +369,5 @@
                     '<form action="' . $core->adminurl->get("admin.user.actions") . '" method="post" class="perm-block">' .
                     '<p class="blog-perm">' . __('Blog:') . ' <a href="' .
-                    $core->adminurl->get("admin.blog", array('id' => html::escapeHTML($k))) . '">' .
+                    $core->adminurl->get("admin.blog", ['id' => html::escapeHTML($k)]) . '">' .
                     html::escapeHTML($v['name']) . '</a> (' . html::escapeHTML($k) . ')</p>';
 
@@ -381,8 +381,8 @@
                     '</ul>' .
                     '<p class="add-perm"><input type="submit" class="reset" value="' . __('Change permissions') . '" />' .
-                    form::hidden(array('redir'), $core->adminurl->get("admin.user", array('id' => $user_id))) .
-                    form::hidden(array('action'), 'perms') .
-                    form::hidden(array('users[]'), $user_id) .
-                    form::hidden(array('blogs[]'), $k) .
+                    form::hidden(['redir'], $core->adminurl->get("admin.user", ['id' => $user_id])) .
+                    form::hidden(['action'], 'perms') .
+                    form::hidden(['users[]'], $user_id) .
+                    form::hidden(['blogs[]'], $k) .
                     $core->formNonce() .
                         '</p>' .
Index: admin/users.php
===================================================================
--- admin/users.php	(revision 3731)
+++ admin/users.php	(revision 3874)
@@ -13,5 +13,5 @@
 
 # Creating filter combo boxes
-$sortby_combo = array(
+$sortby_combo = [
     __('Username')          => 'user_id',
     __('Last Name')         => 'user_name',
@@ -19,26 +19,26 @@
     __('Display name')      => 'user_displayname',
     __('Number of entries') => 'nb_post'
-);
+];
 
-$sortby_lex = array(
+$sortby_lex = [
     // key in sorty_combo (see above) => field in SQL request
     'user_id'          => 'U.user_id',
     'user_name'        => 'user_name',
     'user_firstname'   => 'user_firstname',
-    'user_displayname' => 'user_displayname');
+    'user_displayname' => 'user_displayname'];
 
-$order_combo = array(
+$order_combo = [
     __('Descending') => 'desc',
     __('Ascending')  => 'asc'
-);
+];
 
 # Actions combo box
-$combo_action = array(
+$combo_action = [
     __('Set permissions') => 'blogs',
     __('Delete')          => 'deleteuser'
-);
+];
 
 # --BEHAVIOR-- adminUsersActionsCombo
-$core->callBehavior('adminUsersActionsCombo', array(&$combo_action));
+$core->callBehavior('adminUsersActionsCombo', [&$combo_action]);
 
 $show_filters = false;
@@ -59,5 +59,5 @@
 $order  = !empty($_GET['order']) ? $_GET['order'] : 'asc';
 
-$params['limit'] = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params['limit'] = [(($page - 1) * $nb_per_page), $nb_per_page];
 
 # - Search filter
@@ -109,8 +109,8 @@
     dcPage::jsLoad('js/_users.js') . dcPage::jsFilterControl($show_filters),
     dcPage::breadcrumb(
-        array(
+        [
             __('System') => '',
             __('Users')  => ''
-        ))
+        ])
 );
 
@@ -164,9 +164,9 @@
         '</label> ' .
         '<input id="do-action" type="submit" value="' . __('ok') . '" />' .
-        form::hidden(array('q'), html::escapeHTML($q)) .
-        form::hidden(array('sortby'), $sortby) .
-        form::hidden(array('order'), $order) .
-        form::hidden(array('page'), $page) .
-        form::hidden(array('nb'), $nb_per_page) .
+        form::hidden(['q'], html::escapeHTML($q)) .
+        form::hidden(['sortby'], $sortby) .
+        form::hidden(['order'], $order) .
+        form::hidden(['page'], $page) .
+        form::hidden(['nb'], $nb_per_page) .
         $core->formNonce() .
         '</p>' .
Index: admin/users_actions.php
===================================================================
--- admin/users_actions.php	(revision 3771)
+++ admin/users_actions.php	(revision 3874)
@@ -12,5 +12,5 @@
 dcPage::checkSuper();
 
-$users = array();
+$users = [];
 if (!empty($_POST['users']) && is_array($_POST['users'])) {
     foreach ($_POST['users'] as $u) {
@@ -21,5 +21,5 @@
 }
 
-$blogs = array();
+$blogs = [];
 if (!empty($_POST['blogs']) && is_array($_POST['blogs'])) {
     foreach ($_POST['blogs'] as $b) {
@@ -38,5 +38,5 @@
         $redir = $_POST['redir'];
     } else {
-        $redir = $core->adminurl->get("admin.users", array(
+        $redir = $core->adminurl->get("admin.users", [
             'q'      => $_POST['q'],
             'sortby' => $_POST['sortby'],
@@ -44,5 +44,5 @@
             'page'   => $_POST['page'],
             'nb'     => $_POST['nb']
-        ));
+        ]);
     }
 
@@ -87,5 +87,5 @@
             foreach ($users as $u) {
                 foreach ($blogs as $b) {
-                    $set_perms = array();
+                    $set_perms = [];
 
                     if (!empty($_POST['perm'][$b])) {
@@ -114,16 +114,16 @@
 if (!empty($users) && empty($blogs) && $action == 'blogs') {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             __('System')      => '',
             __('Users')       => $core->adminurl->get("admin.users"),
             __('Permissions') => ''
-        ));
+        ]);
 } else {
     $breadcrumb = dcPage::breadcrumb(
-        array(
+        [
             __('System')  => '',
             __('Users')   => $core->adminurl->get("admin.users"),
             __('Actions') => ''
-        ));
+        ]);
 }
 
@@ -143,16 +143,16 @@
 $hidden_fields = '';
 foreach ($users as $u) {
-    $hidden_fields .= form::hidden(array('users[]'), $u);
+    $hidden_fields .= form::hidden(['users[]'], $u);
 }
 
 if (isset($_POST['redir']) && strpos($_POST['redir'], '://') === false) {
-    $hidden_fields .= form::hidden(array('redir'), html::escapeURL($_POST['redir']));
+    $hidden_fields .= form::hidden(['redir'], html::escapeURL($_POST['redir']));
 } else {
     $hidden_fields .=
-    form::hidden(array('q'), html::escapeHTML($_POST['q'])) .
-    form::hidden(array('sortby'), $_POST['sortby']) .
-    form::hidden(array('order'), $_POST['order']) .
-    form::hidden(array('page'), $_POST['page']) .
-    form::hidden(array('nb'), $_POST['nb']);
+    form::hidden(['q'], html::escapeHTML($_POST['q'])) .
+    form::hidden(['sortby'], $_POST['sortby']) .
+    form::hidden(['order'], $_POST['order']) .
+    form::hidden(['page'], $_POST['page']) .
+    form::hidden(['nb'], $_POST['nb']);
 }
 
@@ -170,5 +170,5 @@
 
     foreach ($users as $u) {
-        $user_list[] = '<a href="' . $core->adminurl->get("admin.user", array('id' => $u)) . '">' . $u . '</a>';
+        $user_list[] = '<a href="' . $core->adminurl->get("admin.user", ['id' => $u]) . '">' . $u . '</a>';
     }
 
@@ -201,8 +201,8 @@
             '<tr class="line">' .
             '<td class="nowrap">' .
-            form::checkbox(array('blogs[]'), $rs->blog_id,
-                array(
+            form::checkbox(['blogs[]'], $rs->blog_id,
+                [
                     'extra_html' => 'title="' . __('select') . ' ' . $rs->blog_id . '"'
-                )) .
+                ]) .
             '</td>' .
             '<td class="nowrap">' . $rs->blog_id . '</td>' .
@@ -220,5 +220,5 @@
         '<p><input id="do-action" type="submit" value="' . __('Set permissions') . '" />' .
         $hidden_fields .
-        form::hidden(array('action'), 'perms') .
+        form::hidden(['action'], 'perms') .
         $core->formNonce() . '</p>' .
             '</form>';
@@ -227,5 +227,5 @@
 # Permissions list for each selected blogs
 elseif (!empty($blogs) && !empty($users) && $action == 'perms') {
-    $user_perm = array();
+    $user_perm = [];
     if (count($users) == 1) {
         $user_perm = $core->getUserPermissions($users[0]);
@@ -233,5 +233,5 @@
 
     foreach ($users as $u) {
-        $user_list[] = '<a href="' . $core->adminurl->get("admin.user", array('id' => $u)) . '">' . $u . '</a>';
+        $user_list[] = '<a href="' . $core->adminurl->get("admin.user", ['id' => $u]) . '">' . $u . '</a>';
     }
 
@@ -244,6 +244,6 @@
 
     foreach ($blogs as $b) {
-        echo '<h3>' . ('Blog:') . ' <a href="' . $core->adminurl->get("admin.blog", array('id' => html::escapeHTML($b))) . '">' . html::escapeHTML($b) . '</a>' .
-        form::hidden(array('blogs[]'), $b) . '</h3>';
+        echo '<h3>' . ('Blog:') . ' <a href="' . $core->adminurl->get("admin.blog", ['id' => html::escapeHTML($b)]) . '">' . html::escapeHTML($b) . '</a>' .
+        form::hidden(['blogs[]'], $b) . '</h3>';
         $unknown_perms = $user_perm;
         foreach ($core->auth->getPermissionsTypes() as $perm_id => $perm) {
@@ -259,5 +259,5 @@
             echo
             '<p><label for="perm' . html::escapeHTML($b) . html::escapeHTML($perm_id) . '" class="classic">' .
-            form::checkbox(array('perm[' . html::escapeHTML($b) . '][' . html::escapeHTML($perm_id) . ']', 'perm' . html::escapeHTML($b) . html::escapeHTML($perm_id)),
+            form::checkbox(['perm[' . html::escapeHTML($b) . '][' . html::escapeHTML($perm_id) . ']', 'perm' . html::escapeHTML($b) . html::escapeHTML($perm_id)],
                 1, $checked) . ' ' .
             __($perm) . '</label></p>';
@@ -270,6 +270,6 @@
                 '<p><label for="perm' . html::escapeHTML($b) . html::escapeHTML($perm_id) . '" class="classic">' .
                 form::checkbox(
-                    array('perm[' . html::escapeHTML($b) . '][' . html::escapeHTML($perm_id) . ']',
-                        'perm' . html::escapeHTML($b) . html::escapeHTML($perm_id)),
+                    ['perm[' . html::escapeHTML($b) . '][' . html::escapeHTML($perm_id) . ']',
+                        'perm' . html::escapeHTML($b) . html::escapeHTML($perm_id)],
                     1, $checked) . ' ' .
                 sprintf(__('[%s] (unreferenced permission)'), $perm_id) . '</label></p>';
@@ -284,12 +284,12 @@
     '<p><label for="your_pwd" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label>' .
     form::password('your_pwd', 20, 255,
-        array(
+        [
             'extra_html'   => 'required placeholder="' . __('Password') . '"',
             'autocomplete' => 'current-password'
-        )
+        ]
     ) . '</p>' .
     '<p><input type="submit" accesskey="s" value="' . __('Save') . '" />' .
     $hidden_fields .
-    form::hidden(array('action'), 'updateperm') .
+    form::hidden(['action'], 'updateperm') .
     $core->formNonce() . '</p>' .
         '</div>' .
Index: build-tools/Minifier.php
===================================================================
--- build-tools/Minifier.php	(revision 3798)
+++ build-tools/Minifier.php	(revision 3883)
@@ -107,5 +107,5 @@
 
             $jshrink = new Minifier();
-            $js = $jshrink->lock($js);
+            $js      = $jshrink->lock($js);
             $jshrink->minifyDirectToOutput($js, $options);
 
@@ -155,7 +155,7 @@
     {
         $this->options = array_merge(static::$defaultOptions, $options);
-        $js = str_replace("\r\n", "\n", $js);
-        $js = str_replace('/**/', '', $js);
-        $this->input = str_replace("\r", "\n", $js);
+        $js            = str_replace("\r\n", "\n", $js);
+        $js            = str_replace('/**/', '', $js);
+        $this->input   = str_replace("\r", "\n", $js);
 
         // We add a newline to the end of the script to make it easier to deal
@@ -190,12 +190,14 @@
                     // if B is a space we skip the rest of the switch block and go down to the
                     // string/regex check below, resetting $this->b with getReal
-                    if($this->b === ' ')
+                    if ($this->b === ' ') {
                         break;
+                    }
 
                 // otherwise we treat the newline like a space
 
                 case ' ':
-                    if(static::isAlphaNumeric($this->b))
+                    if (static::isAlphaNumeric($this->b)) {
                         echo $this->a;
+                    }
 
                     $this->saveString();
@@ -205,5 +207,5 @@
                     switch ($this->b) {
                         case "\n":
-                            if (strpos('}])+-"\'', $this->a) !== false) {
+                            if (strpos('}])+-"\'`', $this->a) !== false) {
                                 echo $this->a;
                                 $this->saveString();
@@ -218,10 +220,11 @@
 
                         case ' ':
-                            if(!static::isAlphaNumeric($this->a))
+                            if (!static::isAlphaNumeric($this->a)) {
                                 break;
+                            }
 
                         default:
                             // check for some regex that breaks stuff
-                            if ($this->a === '/' && ($this->b === '\'' || $this->b === '"')) {
+                            if ($this->a === '/' && ($this->b === '\'' || $this->b === '"' || $this->b === '`')) {
                                 $this->saveRegex();
                                 continue;
@@ -237,6 +240,8 @@
             $this->b = $this->getReal();
 
-            if(($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false))
+            if (($this->b == '/' && strpos('(,=:[!&|?', $this->a) !== false)) {
                 $this->saveRegex();
+            }
+
         }
     }
@@ -251,5 +256,5 @@
         unset($this->input);
         $this->index = 0;
-        $this->a = $this->b = '';
+        $this->a     = $this->b     = '';
         unset($this->c);
         unset($this->options);
@@ -268,5 +273,5 @@
             unset($this->c);
 
-        // Otherwise we start pulling from the input.
+            // Otherwise we start pulling from the input.
         } else {
             $char = substr($this->input, $this->index, 1);
@@ -283,7 +288,7 @@
         // Normalize all whitespace except for the newline character into a
         // standard space.
-        if($char !== "\n" && ord($char) < 32)
-
+        if ($char !== "\n" && ord($char) < 32) {
             return ' ';
+        }
 
         return $char;
@@ -303,5 +308,5 @@
     {
         $startIndex = $this->index;
-        $char = $this->getChar();
+        $char       = $this->getChar();
 
         // Check to see if we're potentially in a comment
@@ -365,11 +370,11 @@
         if ($this->getNext('*/')) {
 
-            $this->getChar(); // get *
-            $this->getChar(); // get /
+            $this->getChar();         // get *
+            $this->getChar();         // get /
             $char = $this->getChar(); // get next real character
 
             // Now we reinsert conditional comments and YUI-style licensing comments
             if (($this->options['flaggedComments'] && $thirdCommentString === '!')
-                || ($thirdCommentString === '@') ) {
+                || ($thirdCommentString === '@')) {
 
                 // If conditional comments or flagged comments are not the first thing in the script
@@ -395,10 +400,12 @@
         }
 
-        if($char === false)
+        if ($char === false) {
             throw new \RuntimeException('Unclosed multiline comment at position: ' . ($this->index - 2));
+        }
 
         // if we're here c is part of the comment and therefore tossed
-        if(isset($this->c))
+        if (isset($this->c)) {
             unset($this->c);
+        }
 
         return $char;
@@ -419,7 +426,7 @@
 
         // If it's not there return false.
-        if($pos === false)
-
+        if ($pos === false) {
             return false;
+        }
 
         // Adjust position of index to jump ahead to the asked for string
@@ -445,9 +452,9 @@
 
         // If this isn't a string we don't need to do anything.
-        if ($this->a !== "'" && $this->a !== '"') {
+        if ($this->a !== "'" && $this->a !== '"' && $this->a !== '`') {
             return;
         }
 
-        // String type is the quote used, " or '
+        // String type is the quote used, " or ' or `
         $stringType = $this->a;
 
@@ -474,5 +481,9 @@
                 // block below.
                 case "\n":
-                    throw new \RuntimeException('Unclosed string at position: ' . $startpos );
+                    if ($stringType !== '`') {
+                        throw new \RuntimeException('Unclosed string at position: ' . $startpos);
+                    } else {
+                        echo $this->a;
+                    }
                     break;
 
@@ -494,5 +505,4 @@
                     break;
 
-
                 // Since we're not dealing with any special cases we simply
                 // output the character and continue our loop.
@@ -514,6 +524,7 @@
 
         while (($this->a = $this->getChar()) !== false) {
-            if($this->a === '/')
+            if ($this->a === '/') {
                 break;
+            }
 
             if ($this->a === '\\') {
@@ -522,6 +533,7 @@
             }
 
-            if($this->a === "\n")
+            if ($this->a === "\n") {
                 throw new \RuntimeException('Unclosed regex pattern at position: ' . $this->index);
+            }
 
             echo $this->a;
Index: build-tools/min-js.php
===================================================================
--- build-tools/min-js.php	(revision 3801)
+++ build-tools/min-js.php	(revision 3883)
@@ -28,5 +28,5 @@
     fclose($fp);
 } catch (Exception $e) {
-    fwrite(STDERR, $e->getMessage() . "\n");
+    fwrite(STDERR, $e->getMessage() . ($js ? "($js)" : '') . "\n");
     exit(1);
 }
Index: debian/mkdcl.php
===================================================================
--- debian/mkdcl.php	(revision 2566)
+++ debian/mkdcl.php	(revision 3874)
@@ -16,5 +16,5 @@
 	{
 		$f = file($this->f);
-		$res = array();
+		$res = [];
 		$done = false;
 
@@ -96,5 +96,5 @@
 	private function getPackageInfo($l)
 	{
-		$res = array(
+		$res = [
 			'package' => '',
 			'version' => '',
@@ -102,6 +102,6 @@
 			'keywords' => '',
 			'changelog' => '',
-			'maintainer' => array()
-		);
+			'maintainer' => []
+		];
 
 		$l = explode(';',$l);
@@ -126,9 +126,9 @@
 	private function getMaintainerInfo($l)
 	{
-		$res = array(
+		$res = [
 			'name' => '',
 			'email' => '',
 			'date' => ''
-		);
+		];
 
 		if (preg_match('/^ -- (.+?) <(.+?)>  (.+?)$/',$l,$m)) {
@@ -171,12 +171,12 @@
 		}
 
-		$res = array();
+		$res = [];
 		foreach ($x->logentry as $change)
 		{
-			$res[(integer) $change['revision']] = array(
+			$res[(integer) $change['revision']] = [
 				'author' => (string) $change->author,
 				'date' => (string) $change->date,
 				'msg' => trim((string) $change->msg)
-			);
+			];
 		}
 
Index: features/bootstrap/autoload.php
===================================================================
--- features/bootstrap/autoload.php	(revision 2995)
+++ features/bootstrap/autoload.php	(revision 3874)
@@ -15,5 +15,5 @@
 require_once __DIR__.'/../../vendor/autoload.php';
 
-$__autoload = array();
+$__autoload = [];
 $__autoload['dbStruct'] = CLEARBRICKS_PATH.'/dbschema/class.dbstruct.php';
 $__autoload['dbSchema'] = CLEARBRICKS_PATH.'/dbschema/class.dbschema.php';
Index: inc/admin/actions/class.dcaction.php
===================================================================
--- inc/admin/actions/class.dcaction.php	(revision 3731)
+++ inc/admin/actions/class.dcaction.php	(revision 3874)
@@ -64,15 +64,15 @@
      * @return mixed Value.
      */
-    public function __construct($core, $uri, $redirect_args = array())
+    public function __construct($core, $uri, $redirect_args = [])
     {
         $this->core            = $core;
         $this->actions         = new ArrayObject();
-        $this->combo           = array();
+        $this->combo           = [];
         $this->uri             = $uri;
         $this->redir_args      = $redirect_args;
-        $this->redirect_fields = array();
+        $this->redirect_fields = [];
         $this->action          = '';
         $this->cb_title        = __('Title');
-        $this->entries         = array();
+        $this->entries         = [];
         $this->from            = new ArrayObject($_POST);
         $this->field_entries   = 'entries';
@@ -122,12 +122,12 @@
                 $values = array_values($a);
                 if (!isset($this->combo[$k])) {
-                    $this->combo[$k] = array();
+                    $this->combo[$k] = [];
                 }
                 $this->combo[$k] = array_merge($this->combo[$k], $a);
             } elseif ($a instanceof formSelectOption) {
-                $values          = array($a->value);
+                $values          = [$a->value];
                 $this->combo[$k] = $a->value;
             } else {
-                $values          = array($a);
+                $values          = [$a];
                 $this->combo[$k] = $a;
             }
@@ -193,5 +193,5 @@
         $ret = '';
         foreach ($this->redir_args as $k => $v) {
-            $ret .= form::hidden(array($k), $v);
+            $ret .= form::hidden([$k], $v);
         }
         if ($with_ids) {
@@ -245,5 +245,5 @@
      * @return string the redirection url
      */
-    public function getRedirection($with_selected_entries = false, $params = array())
+    public function getRedirection($with_selected_entries = false, $params = [])
     {
         $redir_args = array_merge($params, $this->redir_args);
@@ -265,5 +265,5 @@
      * @access public
      */
-    public function redirect($with_selected_entries = false, $params = array())
+    public function redirect($with_selected_entries = false, $params = [])
     {
         http::redirect($this->getRedirection($with_selected_entries, $params));
@@ -357,7 +357,7 @@
             $ret .=
             '<tr><td class="minimal">' .
-            form::checkbox(array($this->field_entries . '[]'), $id, array(
+            form::checkbox([$this->field_entries . '[]'], $id, [
                 'checked' => true
-            )) .
+            ]) .
                 '</td>' .
                 '<td>' . $title . '</td></tr>';
Index: inc/admin/actions/class.dcactionblogs.php
===================================================================
--- inc/admin/actions/class.dcactionblogs.php	(revision 3731)
+++ inc/admin/actions/class.dcactionblogs.php	(revision 3874)
@@ -12,8 +12,8 @@
 class dcBlogsActionsPage extends dcActionsPage
 {
-    public function __construct($core, $uri, $redirect_args = array())
+    public function __construct($core, $uri, $redirect_args = [])
     {
         parent::__construct($core, $uri, $redirect_args);
-        $this->redirect_fields = array('status', 'sortby', 'order', 'page', 'nb');
+        $this->redirect_fields = ['status', 'sortby', 'order', 'page', 'nb'];
         $this->field_entries   = 'blogs';
         $this->title_cb        = __('Blogs');
@@ -57,9 +57,9 @@
         $this->core->error->add($e->getMessage());
         $this->beginPage(dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($this->core->blog->name) => '',
                 __('Blogs')                               => $this->core->adminurl->get('admin.blogs'),
                 __('Blogs actions')                       => ''
-            ))
+            ])
         );
         $this->endPage();
@@ -72,8 +72,8 @@
             $ret .=
             '<tr>' .
-            '<td class="minimal">' . form::checkbox(array($this->field_entries . '[]'), $id,
-                array(
+            '<td class="minimal">' . form::checkbox([$this->field_entries . '[]'], $id,
+                [
                     'checked' => true
-                )) .
+                ]) .
                 '</td>' .
                 '<td>' . $res['blog'] . '</td>' .
@@ -90,5 +90,5 @@
     protected function fetchEntries($from)
     {
-        $params = array();
+        $params = [];
         if (!empty($from['blogs'])) {
             $params['blog_id'] = $from['blogs'];
@@ -97,8 +97,8 @@
         $bl = $this->core->getBlogs($params);
         while ($bl->fetch()) {
-            $this->entries[$bl->blog_id] = array(
+            $this->entries[$bl->blog_id] = [
                 'blog' => $bl->blog_id,
                 'name' => $bl->blog_name
-            );
+            ];
         }
         $this->rs = $bl;
@@ -115,15 +115,15 @@
 
         $ap->addAction(
-            array(__('Status') => array(
+            [__('Status') => [
                 __('Set online')     => 'online',
                 __('Set offline')    => 'offline',
                 __('Set as removed') => 'remove'
-            )),
-            array('dcDefaultBlogActions', 'doChangeBlogStatus')
+            ]],
+            ['dcDefaultBlogActions', 'doChangeBlogStatus']
         );
         $ap->addAction(
-            array(__('Delete') => array(
-                __('Delete') => 'delete')),
-            array('dcDefaultBlogActions', 'doDeleteBlog')
+            [__('Delete') => [
+                __('Delete') => 'delete']],
+            ['dcDefaultBlogActions', 'doDeleteBlog']
         );
     }
@@ -175,5 +175,5 @@
         }
 
-        $ids = array();
+        $ids = [];
         foreach ($ap_ids as $id) {
             if ($id == $core->blog->id) {
Index: inc/admin/actions/class.dcactioncomments.php
===================================================================
--- inc/admin/actions/class.dcactioncomments.php	(revision 3731)
+++ inc/admin/actions/class.dcactioncomments.php	(revision 3874)
@@ -12,9 +12,9 @@
 class dcCommentsActionsPage extends dcActionsPage
 {
-    public function __construct($core, $uri, $redirect_args = array())
+    public function __construct($core, $uri, $redirect_args = [])
     {
         parent::__construct($core, $uri, $redirect_args);
-        $this->redirect_fields = array('type', 'author', 'status',
-            'sortby', 'ip', 'order', 'page', 'nb', 'section');
+        $this->redirect_fields = ['type', 'author', 'status',
+            'sortby', 'ip', 'order', 'page', 'nb', 'section'];
         $this->field_entries = 'comments';
         $this->title_cb      = __('Comments');
@@ -59,9 +59,9 @@
         $this->core->error->add($e->getMessage());
         $this->beginPage(dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($this->core->blog->name) => '',
                 __('Comments')                            => $this->core->adminurl->get('admin.comments'),
                 __('Comments actions')                    => ''
-            ))
+            ])
         );
         $this->endPage();
@@ -85,8 +85,8 @@
             $ret .=
             '<tr><td class="minimal">' .
-            form::checkbox(array($this->field_entries . '[]'), $id,
-                array(
+            form::checkbox([$this->field_entries . '[]'], $id,
+                [
                     'checked' => true
-                )) .
+                ]) .
                 '</td>' .
                 '<td>' . $title['author'] . '</td><td>' . $title['title'] . '</td></tr>';
@@ -98,5 +98,5 @@
     protected function fetchEntries($from)
     {
-        $params = array();
+        $params = [];
         if (!empty($from['comments'])) {
             $comments = $from['comments'];
@@ -116,8 +116,8 @@
         $co = $this->core->blog->getComments($params);
         while ($co->fetch()) {
-            $this->entries[$co->comment_id] = array(
+            $this->entries[$co->comment_id] = [
                 'title'  => $co->post_title,
                 'author' => $co->comment_author
-            );
+            ];
         }
         $this->rs = $co;
@@ -131,11 +131,11 @@
         if ($core->auth->check('publish,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Status') => array(
+                [__('Status') => [
                     __('Publish')         => 'publish',
                     __('Unpublish')       => 'unpublish',
                     __('Mark as pending') => 'pending',
                     __('Mark as junk')    => 'junk'
-                )),
-                array('dcDefaultCommentActions', 'doChangeCommentStatus')
+                ]],
+                ['dcDefaultCommentActions', 'doChangeCommentStatus']
             );
         }
@@ -143,7 +143,7 @@
         if ($core->auth->check('delete,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Delete') => array(
-                    __('Delete') => 'delete')),
-                array('dcDefaultCommentActions', 'doDeleteComment')
+                [__('Delete') => [
+                    __('Delete') => 'delete']],
+                ['dcDefaultCommentActions', 'doDeleteComment']
             );
         }
@@ -158,5 +158,5 @@
 
         if ($ip_filter_active) {
-            $blacklist_actions = array(__('Blacklist IP') => 'blacklist');
+            $blacklist_actions = [__('Blacklist IP') => 'blacklist'];
             if ($core->auth->isSuperAdmin()) {
                 $blacklist_actions[__('Blacklist IP (global)')] = 'blacklist_global';
@@ -164,6 +164,6 @@
 
             $ap->addAction(
-                array(__('IP address') => $blacklist_actions),
-                array('dcDefaultCommentActions', 'doBlacklistIP')
+                [__('IP address') => $blacklist_actions],
+                ['dcDefaultCommentActions', 'doBlacklistIP']
             );
         }
Index: inc/admin/actions/class.dcactionposts.php
===================================================================
--- inc/admin/actions/class.dcactionposts.php	(revision 3731)
+++ inc/admin/actions/class.dcactionposts.php	(revision 3874)
@@ -12,9 +12,9 @@
 class dcPostsActionsPage extends dcActionsPage
 {
-    public function __construct($core, $uri, $redirect_args = array())
+    public function __construct($core, $uri, $redirect_args = [])
     {
         parent::__construct($core, $uri, $redirect_args);
-        $this->redirect_fields = array('user_id', 'cat_id', 'status',
-            'selected', 'attachment', 'month', 'lang', 'sortby', 'order', 'page', 'nb');
+        $this->redirect_fields = ['user_id', 'cat_id', 'status',
+            'selected', 'attachment', 'month', 'lang', 'sortby', 'order', 'page', 'nb'];
         $this->loadDefaults();
     }
@@ -61,9 +61,9 @@
         $this->core->error->add($e->getMessage());
         $this->beginPage(dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($this->core->blog->name) => '',
                 $this->getCallerTitle()                   => $this->getRedirection(true),
                 __('Entries actions')                     => ''
-            ))
+            ])
         );
         $this->endPage();
@@ -72,5 +72,5 @@
     protected function fetchEntries($from)
     {
-        $params = array();
+        $params = [];
         if (!empty($from['entries'])) {
             $entries = $from['entries'];
@@ -107,44 +107,44 @@
         if ($core->auth->check('publish,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Status') => array(
+                [__('Status') => [
                     __('Publish')         => 'publish',
                     __('Unpublish')       => 'unpublish',
                     __('Schedule')        => 'schedule',
                     __('Mark as pending') => 'pending'
-                )),
-                array('dcDefaultPostActions', 'doChangePostStatus')
+                ]],
+                ['dcDefaultPostActions', 'doChangePostStatus']
             );
         }
         $ap->addAction(
-            array(__('Mark') => array(
+            [__('Mark') => [
                 __('Mark as selected')   => 'selected',
                 __('Mark as unselected') => 'unselected'
-            )),
-            array('dcDefaultPostActions', 'doUpdateSelectedPost')
+            ]],
+            ['dcDefaultPostActions', 'doUpdateSelectedPost']
         );
         $ap->addAction(
-            array(__('Change') => array(
+            [__('Change') => [
                 __('Change category') => 'category'
-            )),
-            array('dcDefaultPostActions', 'doChangePostCategory')
+            ]],
+            ['dcDefaultPostActions', 'doChangePostCategory']
         );
         $ap->addAction(
-            array(__('Change') => array(
+            [__('Change') => [
                 __('Change language') => 'lang'
-            )),
-            array('dcDefaultPostActions', 'doChangePostLang')
+            ]],
+            ['dcDefaultPostActions', 'doChangePostLang']
         );
         if ($core->auth->check('admin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Change') => array(
-                    __('Change author') => 'author')),
-                array('dcDefaultPostActions', 'doChangePostAuthor')
+                [__('Change') => [
+                    __('Change author') => 'author']],
+                ['dcDefaultPostActions', 'doChangePostAuthor']
             );
         }
         if ($core->auth->check('delete,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Delete') => array(
-                    __('Delete') => 'delete')),
-                array('dcDefaultPostActions', 'doDeletePost')
+                [__('Delete') => [
+                    __('Delete') => 'delete']],
+                ['dcDefaultPostActions', 'doDeletePost']
             );
         }
@@ -281,9 +281,9 @@
             $ap->beginPage(
                 dcPage::breadcrumb(
-                    array(
+                    [
                         html::escapeHTML($core->blog->name)      => '',
                         $ap->getCallerTitle()                    => $ap->getRedirection(true),
                         __('Change category for this selection') => ''
-                    )));
+                    ]));
             # categories list
             # Getting categories
@@ -295,5 +295,5 @@
             $ap->getCheckboxes() .
             '<p><label for="new_cat_id" class="classic">' . __('Category:') . '</label> ' .
-            form::combo(array('new_cat_id'), $categories_combo);
+            form::combo(['new_cat_id'], $categories_combo);
 
             if ($core->auth->check('categories', $core->blog->id)) {
@@ -312,5 +312,5 @@
             $core->formNonce() .
             $ap->getHiddenFields() .
-            form::hidden(array('action'), 'category') .
+            form::hidden(['action'], 'category') .
             '<input type="submit" value="' . __('Save') . '" /></p>' .
                 '</form>';
@@ -349,8 +349,8 @@
             $usersList = '';
             if ($core->auth->check('admin', $core->blog->id)) {
-                $params = array(
+                $params = [
                     'limit' => 100,
                     'order' => 'nb_post DESC'
-                );
+                ];
                 $rs       = $core->getUsers($params);
                 $rsStatic = $rs->toStatic();
@@ -364,8 +364,8 @@
             $ap->beginPage(
                 dcPage::breadcrumb(
-                    array(
+                    [
                         html::escapeHTML($core->blog->name)    => '',
                         $ap->getCallerTitle()                  => $ap->getRedirection(true),
-                        __('Change author for this selection') => '')),
+                        __('Change author for this selection') => '']),
                 dcPage::jsLoad('js/jquery/jquery.autocomplete.js') .
                 '<script type="text/javascript">' . "\n" .
@@ -382,5 +382,5 @@
             echo
             $core->formNonce() . $ap->getHiddenFields() .
-            form::hidden(array('action'), 'author') .
+            form::hidden(['action'], 'author') .
             '<input type="submit" value="' . __('Save') . '" /></p>' .
                 '</form>';
@@ -412,14 +412,14 @@
             $ap->beginPage(
                 dcPage::breadcrumb(
-                    array(
+                    [
                         html::escapeHTML($core->blog->name)      => '',
                         $ap->getCallerTitle()                    => $ap->getRedirection(true),
                         __('Change language for this selection') => ''
-                    )));
+                    ]));
             # lang list
             # Languages combo
-            $rs         = $core->blog->getLangs(array('order' => 'asc'));
+            $rs         = $core->blog->getLangs(['order' => 'asc']);
             $all_langs  = l10n::getISOcodes(0, 1);
-            $lang_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1, 1));
+            $lang_combo = ['' => '', __('Most used') => [], __('Available') => l10n::getISOcodes(1, 1)];
             while ($rs->fetch()) {
                 if (isset($all_langs[$rs->post_lang])) {
@@ -442,5 +442,5 @@
             echo
             $core->formNonce() . $ap->getHiddenFields() .
-            form::hidden(array('action'), 'lang') .
+            form::hidden(['action'], 'lang') .
             '<input type="submit" value="' . __('Save') . '" /></p>' .
                 '</form>';
Index: inc/admin/class.dc.favorites.php
===================================================================
--- inc/admin/class.dc.favorites.php	(revision 3731)
+++ inc/admin/class.dc.favorites.php	(revision 3874)
@@ -48,5 +48,5 @@
         $this->fav_defs   = new ArrayObject();
         $this->ws         = $core->auth->user_prefs->addWorkspace('dashboard');
-        $this->user_prefs = array();
+        $this->user_prefs = [];
 
         if ($this->ws->prefExists('favorites')) {
@@ -55,8 +55,8 @@
             // Since we never know what user puts through user:preferences ...
             if (!is_array($this->local_prefs)) {
-                $this->local_prefs = array();
+                $this->local_prefs = [];
             }
             if (!is_array($this->global_prefs)) {
-                $this->global_prefs = array();
+                $this->global_prefs = [];
             }
         } else {
@@ -106,5 +106,5 @@
             $fattr = $this->fav_defs[$p];
         }
-        $fattr = array_merge(array('id' => null, 'class' => null), $fattr);
+        $fattr = array_merge(['id' => null, 'class' => null], $fattr);
         if (isset($fattr['permissions'])) {
             if (is_bool($fattr['permissions']) && !$fattr['permissions']) {
@@ -114,4 +114,6 @@
                 return false;
             }
+        } elseif (!$this->core->auth->isSuperAdmin()) {
+            return false;
         }
         return $fattr;
@@ -129,5 +131,5 @@
     public function getFavorites($ids)
     {
-        $prefs = array();
+        $prefs = [];
         foreach ($ids as $id) {
             $f = $this->getFavorite($id);
@@ -156,5 +158,5 @@
         }
         if (!count($this->user_prefs)) {
-            $this->user_prefs = $this->getFavorites(array('new_post'));
+            $this->user_prefs = $this->getFavorites(['new_post']);
         }
         $u = explode('?', $_SERVER['REQUEST_URI']);
@@ -182,5 +184,4 @@
             }
         }
-
     }
 
@@ -194,6 +195,6 @@
     {
         $fav_ws             = $this->core->auth->user_prefs->addWorkspace('favorites');
-        $this->local_prefs  = array();
-        $this->global_prefs = array();
+        $this->local_prefs  = [];
+        $this->global_prefs = [];
         foreach ($fav_ws->dumpPrefs() as $k => $v) {
             $fav = @unserialize($v['value']);
@@ -222,5 +223,5 @@
         $this->core->callBehavior('adminDashboardFavs', $this->core, $f);
         foreach ($f as $k => $v) {
-            $fav = array(
+            $fav = [
                 'title'       => __($v[1]),
                 'url'         => $v[2],
@@ -230,5 +231,5 @@
                 'id'          => $v[6],
                 'class'       => $v[7]
-            );
+            ];
             $this->register($v[0], $fav);
         }
@@ -343,5 +344,5 @@
                 call_user_func($v['dashboard_cb'], $this->core, $v);
             }
-            $icons[$k] = new ArrayObject(array($v['title'], $v['url'], $v['large-icon']));
+            $icons[$k] = new ArrayObject([$v['title'], $v['url'], $v['large-icon']]);
             $this->core->callBehavior('adminDashboardFavsIcon', $this->core, $k, $icons[$k]);
         }
@@ -409,17 +410,17 @@
     {
         $core = &$GLOBALS['core'];
-        $favs->registerMultiple(array(
-            'prefs'      => array(
+        $favs->registerMultiple([
+            'prefs'      => [
                 'title'      => __('My preferences'),
                 'url'        => $core->adminurl->get("admin.user.preferences"),
                 'small-icon' => 'images/menu/user-pref.png',
-                'large-icon' => 'images/menu/user-pref-b.png'),
-            'new_post'   => array(
+                'large-icon' => 'images/menu/user-pref-b.png'],
+            'new_post'   => [
                 'title'       => __('New entry'),
                 'url'         => $core->adminurl->get("admin.post"),
                 'small-icon'  => 'images/menu/edit.png',
                 'large-icon'  => 'images/menu/edit-b.png',
-                'permissions' => 'usage,contentadmin'),
-            'posts'      => array(
+                'permissions' => 'usage,contentadmin'],
+            'posts'      => [
                 'title'        => __('Posts'),
                 'url'          => $core->adminurl->get("admin.posts"),
@@ -427,6 +428,6 @@
                 'large-icon'   => 'images/menu/entries-b.png',
                 'permissions'  => 'usage,contentadmin',
-                'dashboard_cb' => array('defaultFavorites', 'postsDashboard')),
-            'comments'   => array(
+                'dashboard_cb' => ['defaultFavorites', 'postsDashboard']],
+            'comments'   => [
                 'title'        => __('Comments'),
                 'url'          => $core->adminurl->get("admin.comments"),
@@ -434,67 +435,67 @@
                 'large-icon'   => 'images/menu/comments-b.png',
                 'permissions'  => 'usage,contentadmin',
-                'dashboard_cb' => array('defaultFavorites', 'commentsDashboard')),
-            'search'     => array(
+                'dashboard_cb' => ['defaultFavorites', 'commentsDashboard']],
+            'search'     => [
                 'title'       => __('Search'),
                 'url'         => $core->adminurl->get("admin.search"),
                 'small-icon'  => 'images/menu/search.png',
                 'large-icon'  => 'images/menu/search-b.png',
-                'permissions' => 'usage,contentadmin'),
-            'categories' => array(
+                'permissions' => 'usage,contentadmin'],
+            'categories' => [
                 'title'       => __('Categories'),
                 'url'         => $core->adminurl->get("admin.categories"),
                 'small-icon'  => 'images/menu/categories.png',
                 'large-icon'  => 'images/menu/categories-b.png',
-                'permissions' => 'categories'),
-            'media'      => array(
+                'permissions' => 'categories'],
+            'media'      => [
                 'title'       => __('Media manager'),
                 'url'         => $core->adminurl->get("admin.media"),
                 'small-icon'  => 'images/menu/media.png',
                 'large-icon'  => 'images/menu/media-b.png',
-                'permissions' => 'media,media_admin'),
-            'blog_pref'  => array(
+                'permissions' => 'media,media_admin'],
+            'blog_pref'  => [
                 'title'       => __('Blog settings'),
                 'url'         => $core->adminurl->get("admin.blog.pref"),
                 'small-icon'  => 'images/menu/blog-pref.png',
                 'large-icon'  => 'images/menu/blog-pref-b.png',
-                'permissions' => 'admin'),
-            'blog_theme' => array(
+                'permissions' => 'admin'],
+            'blog_theme' => [
                 'title'       => __('Blog appearance'),
                 'url'         => $core->adminurl->get("admin.blog.theme"),
                 'small-icon'  => 'images/menu/themes.png',
                 'large-icon'  => 'images/menu/blog-theme-b.png',
-                'permissions' => 'admin'),
-            'blogs'      => array(
+                'permissions' => 'admin'],
+            'blogs'      => [
                 'title'       => __('Blogs'),
                 'url'         => $core->adminurl->get("admin.blogs"),
                 'small-icon'  => 'images/menu/blogs.png',
                 'large-icon'  => 'images/menu/blogs-b.png',
-                'permissions' => 'usage,contentadmin'),
-            'users'      => array(
+                'permissions' => 'usage,contentadmin'],
+            'users'      => [
                 'title'      => __('Users'),
                 'url'        => $core->adminurl->get("admin.users"),
                 'small-icon' => 'images/menu/users.png',
-                'large-icon' => 'images/menu/users-b.png'),
-            'plugins'    => array(
+                'large-icon' => 'images/menu/users-b.png'],
+            'plugins'    => [
                 'title'      => __('Plugins management'),
                 'url'        => $core->adminurl->get("admin.plugins"),
                 'small-icon' => 'images/menu/plugins.png',
-                'large-icon' => 'images/menu/plugins-b.png'),
-            'langs'      => array(
+                'large-icon' => 'images/menu/plugins-b.png'],
+            'langs'      => [
                 'title'      => __('Languages'),
                 'url'        => $core->adminurl->get("admin.langs"),
                 'small-icon' => 'images/menu/langs.png',
-                'large-icon' => 'images/menu/langs-b.png'),
-            'help'       => array(
+                'large-icon' => 'images/menu/langs-b.png'],
+            'help'       => [
                 'title'      => __('Global help'),
                 'url'        => $core->adminurl->get("admin.help"),
                 'small-icon' => 'images/menu/help.png',
-                'large-icon' => 'images/menu/help-b.png')
-        ));
+                'large-icon' => 'images/menu/help-b.png']
+        ]);
     }
 
     public static function postsDashboard($core, $v)
     {
-        $post_count  = $core->blog->getPosts(array(), true)->f(0);
+        $post_count  = $core->blog->getPosts([], true)->f(0);
         $str_entries = __('%d post', '%d posts', $post_count);
         $v['title']  = sprintf($str_entries, $post_count);
@@ -503,5 +504,5 @@
     public static function commentsDashboard($core, $v)
     {
-        $comment_count = $core->blog->getComments(array(), true)->f(0);
+        $comment_count = $core->blog->getComments([], true)->f(0);
         $str_comments  = __('%d comment', '%d comments', $comment_count);
         $v['title']    = sprintf($str_comments, $comment_count);
Index: inc/admin/class.dc.menu.php
===================================================================
--- inc/admin/class.dc.menu.php	(revision 3731)
+++ inc/admin/class.dc.menu.php	(revision 3874)
@@ -20,6 +20,6 @@
         $this->title     = $title;
         $this->itemSpace = $itemSpace;
-        $this->pinned    = array();
-        $this->items     = array();
+        $this->pinned    = [];
+        $this->items     = [];
     }
 
Index: inc/admin/lib.admincombos.php
===================================================================
--- inc/admin/lib.admincombos.php	(revision 3731)
+++ inc/admin/lib.admincombos.php	(revision 3874)
@@ -29,7 +29,7 @@
     public static function getCategoriesCombo($categories, $include_empty = true, $use_url = false)
     {
-        $categories_combo = array();
+        $categories_combo = [];
         if ($include_empty) {
-            $categories_combo = array(new formSelectOption(__('(No cat)'), ''));
+            $categories_combo = [new formSelectOption(__('(No cat)'), '')];
         }
         while ($categories->fetch()) {
@@ -51,5 +51,5 @@
     public static function getPostStatusesCombo()
     {
-        $status_combo = array();
+        $status_combo = [];
         foreach (self::$core->blog->getAllPostStatus() as $k => $v) {
             $status_combo[$v] = (string) $k;
@@ -66,5 +66,5 @@
     public static function getUsersCombo($users)
     {
-        $users_combo = array();
+        $users_combo = [];
         while ($users->fetch()) {
             $user_cn = dcUtils::getUserCN($users->user_id, $users->user_name,
@@ -88,5 +88,5 @@
     public static function getDatesCombo($dates)
     {
-        $dt_m_combo = array();
+        $dt_m_combo = [];
         while ($dates->fetch()) {
             $dt_m_combo[dt::str('%B %Y', $dates->ts())] = $dates->year() . $dates->month();
@@ -107,5 +107,5 @@
         $all_langs = l10n::getISOcodes(0, 1);
         if ($with_available) {
-            $langs_combo = array('' => '', __('Most used') => array(), __('Available') => l10n::getISOcodes(1, 1));
+            $langs_combo = ['' => '', __('Most used') => [], __('Available') => l10n::getISOcodes(1, 1)];
             while ($langs->fetch()) {
                 if (isset($all_langs[$langs->post_lang])) {
@@ -117,5 +117,5 @@
             }
         } else {
-            $langs_combo = array();
+            $langs_combo = [];
             while ($langs->fetch()) {
                 $lang_name               = isset($all_langs[$langs->post_lang]) ? $all_langs[$langs->post_lang] : $langs->post_lang;
@@ -134,5 +134,5 @@
     public static function getAdminLangsCombo()
     {
-        $lang_combo = array();
+        $lang_combo = [];
         $langs      = l10n::getISOcodes(1, 1);
         foreach ($langs as $k => $v) {
@@ -150,5 +150,5 @@
     public static function getEditorsCombo()
     {
-        $editors_combo = array();
+        $editors_combo = [];
 
         foreach (self::$core->getEditors() as $v) {
@@ -167,5 +167,5 @@
     public static function getFormatersCombo($editor_id = '')
     {
-        $formaters_combo = array();
+        $formaters_combo = [];
 
         if (!empty($editor_id)) {
@@ -191,5 +191,5 @@
     public static function getBlogStatusesCombo()
     {
-        $status_combo = array();
+        $status_combo = [];
         foreach (self::$core->getAllBlogStatus() as $k => $v) {
             $status_combo[$v] = (string) $k;
@@ -205,5 +205,5 @@
     public static function getCommentStatusescombo()
     {
-        $status_combo = array();
+        $status_combo = [];
         foreach (self::$core->blog->getAllCommentStatus() as $k => $v) {
             $status_combo[$v] = (string) $k;
Index: inc/admin/lib.dc.adminurl.php
===================================================================
--- inc/admin/lib.dc.adminurl.php	(revision 3731)
+++ inc/admin/lib.dc.adminurl.php	(revision 3874)
@@ -37,7 +37,7 @@
      * @param  array  $params query string params (optional)
      */
-    public function register($name, $url, $params = array())
+    public function register($name, $url, $params = [])
     {
-        $this->urls[$name] = array('url' => $url, 'qs' => $params);
+        $this->urls[$name] = ['url' => $url, 'qs' => $params];
     }
 
@@ -49,5 +49,5 @@
      * @param  string $newurl new url if different from the original
      */
-    public function registercopy($name, $orig, $params = array(), $newurl = '')
+    public function registercopy($name, $orig, $params = [], $newurl = '')
     {
         if (!isset($this->urls[$orig])) {
@@ -72,5 +72,5 @@
      * @return string            the forged url
      */
-    public function get($name, $params = array(), $separator = '&amp;', $parametric = false)
+    public function get($name, $params = [], $separator = '&amp;', $parametric = false)
     {
         if (!isset($this->urls[$name])) {
@@ -99,5 +99,5 @@
      * @return string            the forged url
      */
-    public function redirect($name, $params = array(), $suffix = "")
+    public function redirect($name, $params = [], $suffix = "")
     {
         if (!isset($this->urls[$name])) {
@@ -130,5 +130,5 @@
      * @return string            the forged form data
      */
-    public function getHiddenFormFields($name, $params = array())
+    public function getHiddenFormFields($name, $params = [])
     {
         if (!isset($this->urls[$name])) {
@@ -139,5 +139,5 @@
         $str = '';
         foreach ((array) $p as $k => $v) {
-            $str .= form::hidden(array($k), $v);
+            $str .= form::hidden([$k], $v);
         }
         return $str;
@@ -154,5 +154,5 @@
      * @return string            the forged decoded url
      */
-    public function decode($name, $params = array(), $separator = '&')
+    public function decode($name, $params = [], $separator = '&')
     {
         return urldecode($this->get($name, $params, false, $separator));
Index: inc/admin/lib.dc.page.php
===================================================================
--- inc/admin/lib.dc.page.php	(revision 3791)
+++ inc/admin/lib.dc.page.php	(revision 3878)
@@ -14,13 +14,13 @@
 class dcPage
 {
-    private static $loaded_js     = array();
-    private static $loaded_css    = array();
+    private static $loaded_js     = [];
+    private static $loaded_css    = [];
     private static $xframe_loaded = false;
-    private static $N_TYPES       = array(
+    private static $N_TYPES       = [
         "success" => "success",
         "warning" => "warning-msg",
         "error"   => "error",
         "message" => "message",
-        "static"  => "static-msg");
+        "static"  => "static-msg"];
 
     # Auth check
@@ -53,5 +53,5 @@
 
     # Top of admin page
-    public static function open($title = '', $head = '', $breadcrumb = '', $options = array())
+    public static function open($title = '', $head = '', $breadcrumb = '', $options = [])
     {
         global $core;
@@ -68,6 +68,6 @@
             $blog_box .= '</p>';
         } else {
-            $rs_blogs = $core->getBlogs(array('order' => 'LOWER(blog_name)', 'limit' => 20));
-            $blogs    = array();
+            $rs_blogs = $core->getBlogs(['order' => 'LOWER(blog_name)', 'limit' => 20]);
+            $blogs    = [];
             while ($rs_blogs->fetch()) {
                 $blogs[html::escapeHTML($rs_blogs->blog_name . ' - ' . $rs_blogs->blog_url)] = $rs_blogs->blog_id;
@@ -84,5 +84,5 @@
 
         # Display
-        $headers = new ArrayObject(array());
+        $headers = new ArrayObject([]);
 
         # Content-Type
@@ -102,5 +102,5 @@
         if (!$safe_mode && $core->blog->settings->system->csp_admin_on) {
             // Get directives from settings if exist, else set defaults
-            $csp = new ArrayObject(array());
+            $csp = new ArrayObject([]);
 
                                                                                 // SQlite Clearbricks driver does not allow using single quote at beginning or end of a field value
@@ -135,5 +135,5 @@
 
             // Construct CSP header
-            $directives = array();
+            $directives = [];
             foreach ($csp as $key => $value) {
                 if ($value) {
@@ -168,6 +168,8 @@
 
         if ($core->auth->user_prefs->interface->darkmode) {
+            echo self::jsVars(['dotclear_darkMode' => 1]);
             echo self::cssLoad('style/default-dark.css');
         } else {
+            echo self::jsVars(['dotclear_darkMode' => 0]);
             echo self::cssLoad('style/default.css');
         }
@@ -220,8 +222,7 @@
         '<li><a href="#content">' . __('Go to the content') . '</a></li>' .
         '<li><a href="#main-menu">' . __('Go to the menu') . '</a></li>' .
-        '<li><a href="#qx">' . __('Go to search') . '</a></li>' .
         '<li><a href="#help">' . __('Go to help') . '</a></li>' .
         '</ul>' . "\n" .
-        '<div id="header" role="banner">' .
+        '<header id="header" role="banner">' .
         '<h1><a href="' . $core->adminurl->get("admin.home") . '"><span class="hidden">' . DC_VENDOR_NAME . '</span></a></h1>' . "\n";
 
@@ -236,8 +237,8 @@
         '<li><a class="smallscreen' . (preg_match('/' . preg_quote($core->adminurl->get('admin.user.preferences')) . '(\?.*)?$/', $_SERVER['REQUEST_URI']) ? ' active' : '') .
         '" href="' . $core->adminurl->get("admin.user.preferences") . '">' . __('My preferences') . '</a></li>' .
-        '<li><a href="' . $core->adminurl->get("admin.home", array('logout' => 1)) . '" class="logout"><span class="nomobile">' . sprintf(__('Logout %s'), $core->auth->userID()) .
+        '<li><a href="' . $core->adminurl->get("admin.home", ['logout' => 1]) . '" class="logout"><span class="nomobile">' . sprintf(__('Logout %s'), $core->auth->userID()) .
             '</span><img src="images/logout.png" alt="" /></a></li>' .
             '</ul>' .
-            '</div>'; // end header
+            '</header>'; // end header
 
         echo
@@ -247,5 +248,5 @@
         '<img class="expand-mm visually-hidden" src="images/collapser-show.png" alt="' . __('Show main menu') . '" />' .
             '</button></div>' .
-            '<div id="main" role="main">' . "\n" .
+            '<main id="main" role="main">' . "\n" .
             '<div id="content" class="clearfix">' . "\n";
 
@@ -302,5 +303,5 @@
     }
 
-    public static function addNotice($type, $message, $options = array())
+    public static function addNotice($type, $message, $options = [])
     {
         if (isset(self::$N_TYPES[$type])) {
@@ -312,8 +313,8 @@
             $notifications = $_SESSION['notifications'];
         } else {
-            $notifications = array();
-        }
-
-        $n = array_merge($options, array('class' => $class, 'ts' => time(), 'text' => $message));
+            $notifications = [];
+        }
+
+        $n = array_merge($options, ['class' => $class, 'ts' => time(), 'text' => $message]);
         if ($type != "static") {
             $notifications[] = $n;
@@ -324,15 +325,15 @@
     }
 
-    public static function addSuccessNotice($message, $options = array())
+    public static function addSuccessNotice($message, $options = [])
     {
         self::addNotice("success", $message, $options);
     }
 
-    public static function addWarningNotice($message, $options = array())
+    public static function addWarningNotice($message, $options = [])
     {
         self::addNotice("warning", $message, $options);
     }
 
-    public static function addErrorNotice($message, $options = array())
+    public static function addErrorNotice($message, $options = [])
     {
         self::addNotice("error", $message, $options);
@@ -367,7 +368,7 @@
         echo
         "</div>\n" . // End of #content
-        "</div>\n" . // End of #main
-
-        '<div id="main-menu" role="navigation">' . "\n" .
+        "</main>\n" . // End of #main
+
+        '<nav id="main-menu" role="navigation">' . "\n" .
 
         '<form id="search-menu" action="' . $core->adminurl->get("admin.search") . '" method="get" role="search">' .
@@ -390,5 +391,5 @@
 
         echo
-        '</div>' . "\n" . // End of #main-menu
+        '</nav>' . "\n" . // End of #main-menu
         "</div>\n";       // End of #wrapper
 
@@ -409,7 +410,7 @@
 
         echo
-            '<div id="footer" role="contentinfo">' .
+            '<footer id="footer" role="contentinfo">' .
             '<a href="http://dotclear.org/" title="' . $text . '">' .
-            '<img src="style/dc_logos/w-dotclear90.png" alt="' . $text . '" /></a></div>' . "\n" .
+            '<img src="style/dc_logos/w-dotclear90.png" alt="' . $text . '" /></a></footer>' . "\n" .
             "<!-- " . "\n" .
             $figure .
@@ -448,6 +449,8 @@
 
         if ($core->auth->user_prefs->interface->darkmode) {
+            echo self::jsVars(['dotclear_darkMode' => 1]);
             echo self::cssLoad('style/default-dark.css');
         } else {
+            echo self::jsVars(['dotclear_darkMode' => 0]);
             echo self::cssLoad('style/default.css');
         }
@@ -494,5 +497,5 @@
         echo
             '<div id="wrapper">' . "\n" .
-            '<div id="main" role="main">' . "\n" .
+            '<main id="main" role="main">' . "\n" .
             '<div id="content">' . "\n";
 
@@ -508,14 +511,14 @@
         echo
         "</div>\n" . // End of #content
-        "</div>\n" . // End of #main
+        "</main>\n" . // End of #main
         "</div>\n" . // End of #wrapper
 
         '<p id="gototop"><a href="#wrapper">' . __('Page top') . '</a></p>' . "\n" .
 
-            '<div id="footer" role="contentinfo"><p>&nbsp;</p></div>' . "\n" .
+            '<footer id="footer" role="contentinfo"><p>&nbsp;</p></footer>' . "\n" .
             '</body></html>';
     }
 
-    public static function breadcrumb($elements = null, $options = array())
+    public static function breadcrumb($elements = null, $options = [])
     {
         global $core;
@@ -616,5 +619,5 @@
     }
 
-    public static function helpBlock()
+    public static function helpBlock(...$params)
     {
         global $core;
@@ -624,6 +627,5 @@
         }
 
-        $args = func_get_args();
-        $args = new ArrayObject($args);
+        $args = new ArrayObject($params);
 
         # --BEHAVIOR-- adminPageHelpBlock
@@ -740,5 +742,5 @@
             }
         } else {
-            $unfolded_sections = array();
+            $unfolded_sections = [];
         }
         return '<script type="text/javascript">' . "\n" .
@@ -763,4 +765,5 @@
         self::jsLoad('js/jquery/jquery.biscuit.js') .
         self::jsLoad('js/common.js') .
+        self::jsLoad('js/services.js') .
         self::jsLoad('js/prelude.js') .
 
@@ -911,14 +914,13 @@
     }
 
-    public static function jsConfirmClose()
-    {
-        $args = func_get_args();
+    public static function jsConfirmClose(...$args)
+    {
         if (count($args) > 0) {
             foreach ($args as $k => $v) {
                 $args[$k] = "'" . html::escapeJS($v) . "'";
             }
-            $args = implode(',', $args);
+            $params = implode(',', $args);
         } else {
-            $args = '';
+            $params = '';
         }
 
@@ -926,5 +928,5 @@
         self::jsLoad('js/confirm-close.js') .
         '<script type="text/javascript">' . "\n" .
-        "confirmClosePage = new confirmClose(" . $args . "); " .
+        "confirmClosePage = new confirmClose(" . $params . "); " .
         "confirmClose.prototype.prompt = '" . html::escapeJS(__('You have unsaved changes.')) . "'; " .
             "</script>\n";
@@ -1002,5 +1004,5 @@
     }
 
-    public static function jsUpload($params = array(), $base_url = null)
+    public static function jsUpload($params = [], $base_url = null)
     {
         if (!$base_url) {
@@ -1008,9 +1010,9 @@
         }
 
-        $params = array_merge($params, array(
+        $params = array_merge($params, [
             'sess_id=' . session_id(),
             'sess_uid=' . $_SESSION['sess_browser_uid'],
             'xd_check=' . $GLOBALS['core']->getNonce()
-        ));
+        ]);
 
         return
@@ -1067,5 +1069,5 @@
     }
 
-    public static function jsLoadCodeMirror($theme = '', $multi = true, $modes = array('css', 'htmlmixed', 'javascript', 'php', 'xml'))
+    public static function jsLoadCodeMirror($theme = '', $multi = true, $modes = ['css', 'htmlmixed', 'javascript', 'php', 'xml'])
     {
         $ret =
@@ -1114,5 +1116,5 @@
     public static function getCodeMirrorThemes()
     {
-        $themes      = array();
+        $themes      = [];
         $themes_root = dirname(__FILE__) . '/../../admin' . '/js/codemirror/theme/';
         if (is_dir($themes_root) && is_readable($themes_root)) {
@@ -1131,10 +1133,10 @@
     public static function getPF($file)
     {
-        return $GLOBALS['core']->adminurl->get('load.plugin.file', array('pf' => $file));
+        return $GLOBALS['core']->adminurl->get('load.plugin.file', ['pf' => $file]);
     }
 
     public static function getVF($file)
     {
-        return $GLOBALS['core']->adminurl->get('load.var.file', array('vf' => $file));
+        return $GLOBALS['core']->adminurl->get('load.var.file', ['vf' => $file]);
     }
 
Index: inc/admin/lib.moduleslist.php
===================================================================
--- inc/admin/lib.moduleslist.php	(revision 3775)
+++ inc/admin/lib.moduleslist.php	(revision 3874)
@@ -23,8 +23,8 @@
 
     public static $allow_multi_install = false; /**< @var    boolean    Work with multiple root directories */
-    public static $distributed_modules = array(); /**< @var    array    List of modules distributed with Dotclear */
+    public static $distributed_modules = []; /**< @var    array    List of modules distributed with Dotclear */
 
     protected $list_id = 'unknow'; /**< @var    string    Current list ID */
-    protected $data    = array(); /**< @var    array    Current modules */
+    protected $data    = []; /**< @var    array    Current modules */
 
     protected $config_module  = ''; /**< @var    string    Module ID to configure */
@@ -42,5 +42,5 @@
 
     public static $nav_indexes = 'abcdefghijklmnopqrstuvwxyz0123456789'; /**< @var    string    Index list */
-    protected $nav_list        = array(); /**< @var    array    Index list with special index */
+    protected $nav_list        = []; /**< @var    array    Index list with special index */
     protected $nav_special     = 'other'; /**< @var    string    Text for other special index */
 
@@ -54,12 +54,13 @@
      *
      * @param    object    $modules        dcModules instance
-     * @param    string    $modules_root    Modules root directories
+     * @param    string    $modules_root   Modules root directories
      * @param    string    $xml_url        URL of modules feed from repository
-     */
-    public function __construct(dcModules $modules, $modules_root, $xml_url)
+     * @param    boolean   $force          Force query repository
+     */
+    public function __construct(dcModules $modules, $modules_root, $xml_url, $force = false)
     {
         $this->core    = $modules->core;
         $this->modules = $modules;
-        $this->store   = new dcStore($modules, $xml_url);
+        $this->store   = new dcStore($modules, $xml_url, $force);
 
         $this->page_url = $this->core->adminurl->get('admin.plugins');
@@ -77,5 +78,5 @@
     public function setList($id)
     {
-        $this->data     = array();
+        $this->data     = [];
         $this->page_tab = '';
         $this->list_id  = $id;
@@ -298,5 +299,5 @@
     {
         $this->nav_special = (string) $str;
-        $this->nav_list    = array_merge(str_split(self::$nav_indexes), array($this->nav_special));
+        $this->nav_list    = array_merge(str_split(self::$nav_indexes), [$this->nav_special]);
 
         return $this;
@@ -325,5 +326,5 @@
 
         # Fetch modules required field
-        $indexes = array();
+        $indexes = [];
         foreach ($this->data as $id => $module) {
             if (!isset($module[$this->sort_field])) {
@@ -340,5 +341,5 @@
         }
 
-        $buttons = array();
+        $buttons = [];
         foreach ($this->nav_list as $char) {
             # Selected letter
@@ -411,5 +412,5 @@
     public function setModules($modules)
     {
-        $this->data = array();
+        $this->data = [];
         if (!empty($modules) && is_array($modules)) {
             foreach ($modules as $id => $module) {
@@ -446,5 +447,5 @@
         return array_merge(
             # Default values
-            array(
+            [
                 'desc'              => '',
                 'author'            => '',
@@ -464,11 +465,11 @@
                 'score'             => 0,
                 'type'              => null,
-                'require'           => array(),
-                'settings'          => array()
-            ),
+                'require'           => [],
+                'settings'          => []
+            ],
             # Module's values
             $module,
             # Clean up values
-            array(
+            [
                 'id'    => $id,
                 'sid'   => self::sanitizeString($id),
@@ -476,5 +477,5 @@
                 'name'  => $name,
                 'sname' => self::sanitizeString($name)
-            )
+            ]
         );
     }
@@ -503,5 +504,5 @@
     public static function sortModules($modules, $field, $asc = true)
     {
-        $origin = $sorter = array();
+        $origin = $sorter = [];
 
         foreach ($modules as $id => $module) {
@@ -527,5 +528,5 @@
      * @return    adminModulesList self instance
      */
-    public function displayModules($cols = array('name', 'version', 'desc'), $actions = array(), $nav_limit = false)
+    public function displayModules($cols = ['name', 'version', 'desc'], $actions = [], $nav_limit = false)
     {
         echo
@@ -611,5 +612,5 @@
                 echo
                 '<td class="module-icon nowrap">' .
-                form::checkbox(array('modules[' . $count . ']', html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id)), html::escapeHTML($id)) .
+                form::checkbox(['modules[' . $count . ']', html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id)], html::escapeHTML($id)) .
                     '</td>';
             }
@@ -641,5 +642,5 @@
                 echo
                 html::escapeHTML($module['name']) . ($id != $module['name'] ? sprintf(__(' (%s)'), $id) : '') .
-                form::hidden(array('modules[' . $count . ']'), html::escapeHTML($id));
+                form::hidden(['modules[' . $count . ']'], html::escapeHTML($id));
             }
             echo
@@ -731,5 +732,5 @@
                     }
 
-                    $more = array();
+                    $more = [];
                     if (!empty($module['details'])) {
                         $more[] = '<a class="module-details" href="' . $module['details'] . '">' . __('Details') . '</a>';
@@ -820,5 +821,5 @@
     public static function getSettingsUrls($core, $id, $check = false, $self = true)
     {
-        $st = array();
+        $st = [];
 
         $mr       = $core->plugins->moduleRoot($id);
@@ -830,5 +831,5 @@
                     $core->auth->isSuperAdmin() ||
                     $core->auth->check($core->plugins->moduleInfo($id, 'permissions'), $core->blog->id)) {
-                    $params = array('module' => $id, 'conf' => '1');
+                    $params = ['module' => $id, 'conf' => '1'];
                     if (!$core->plugins->moduleInfo($id, 'standalone_config') && !$self) {
                         $params['redir'] = $core->adminurl->get('admin.plugin.' . $id);
@@ -889,5 +890,5 @@
     protected function getActions($id, $module, $actions)
     {
-        $submits = array();
+        $submits = [];
 
         # Use loop to keep requested order
@@ -951,5 +952,5 @@
     protected function getGlobalActions($actions, $with_selection = false)
     {
-        $submits = array();
+        $submits = [];
 
         # Use loop to keep requested order
@@ -1014,5 +1015,5 @@
         }
 
-        $modules = !empty($_POST['modules']) && is_array($_POST['modules']) ? array_values($_POST['modules']) : array();
+        $modules = !empty($_POST['modules']) && is_array($_POST['modules']) ? array_values($_POST['modules']) : [];
 
         if ($this->core->auth->isSuperAdmin() && !empty($_POST['delete'])) {
@@ -1286,9 +1287,9 @@
         '<input type="file" name="pkg_file" id="pkg_file" required /></p>' .
         '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label> ' .
-        form::password(array('your_pwd', 'your_pwd1'), 20, 255,
-            array(
+        form::password(['your_pwd', 'your_pwd1'], 20, 255,
+            [
                 'extra_html'   => 'required placeholder="' . __('Password') . '"',
                 'autocomplete' => 'current-password'
-            )
+            ]
         ) . '</p>' .
         '<p><input type="submit" name="upload_pkg" value="' . __('Upload') . '" />' .
@@ -1301,14 +1302,14 @@
         '<h4>' . __('Download a zip file') . '</h4>' .
         '<p class="field"><label for="pkg_url" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Zip file URL:') . '</label> ' .
-        form::field('pkg_url', 40, 255, array(
+        form::field('pkg_url', 40, 255, [
             'extra_html' => 'required placeholder="' . __('URL') . '"'
-        )) .
+        ]) .
         '</p>' .
         '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label> ' .
-        form::password(array('your_pwd', 'your_pwd2'), 20, 255,
-            array(
+        form::password(['your_pwd', 'your_pwd2'], 20, 255,
+            [
                 'extra_html'   => 'required placeholder="' . __('Password') . '"',
                 'autocomplete' => 'current-password'
-            )
+            ]
         ) . '</p>' .
         '<p><input type="submit" name="fetch_pkg" value="' . __('Download') . '" />' .
@@ -1468,14 +1469,15 @@
      *
      * @param    object    $modules        dcModules instance
-     * @param    string    $modules_root    Modules root directories
+     * @param    string    $modules_root   Modules root directories
      * @param    string    $xml_url        URL of modules feed from repository
-     */
-    public function __construct(dcModules $modules, $modules_root, $xml_url)
-    {
-        parent::__construct($modules, $modules_root, $xml_url);
+     * @param    boolean   $force          Force query repository
+     */
+    public function __construct(dcModules $modules, $modules_root, $xml_url, $force = false)
+    {
+        parent::__construct($modules, $modules_root, $xml_url, $force);
         $this->page_url = $this->core->adminurl->get('admin.blog.theme');
     }
 
-    public function displayModules($cols = array('name', 'config', 'version', 'desc'), $actions = array(), $nav_limit = false)
+    public function displayModules($cols = ['name', 'config', 'version', 'desc'], $actions = [], $nav_limit = false)
     {
         echo
@@ -1517,5 +1519,5 @@
                     $line .=
                     '<label for="' . html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id) . '">' .
-                    form::checkbox(array('modules[' . $count . ']', html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id)), html::escapeHTML($id)) .
+                    form::checkbox(['modules[' . $count . ']', html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id)], html::escapeHTML($id)) .
                     html::escapeHTML($module['name']) .
                         '</label>';
@@ -1523,5 +1525,5 @@
                 } else {
                     $line .=
-                    form::hidden(array('modules[' . $count . ']'), html::escapeHTML($id)) .
+                    form::hidden(['modules[' . $count . ']'], html::escapeHTML($id)) .
                     html::escapeHTML($module['name']);
                 }
@@ -1567,10 +1569,10 @@
                     $line .=
                     '<label for="' . html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id) . '">' .
-                    form::checkbox(array('modules[' . $count . ']', html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id)), html::escapeHTML($id)) .
+                    form::checkbox(['modules[' . $count . ']', html::escapeHTML($this->list_id) . '_modules_' . html::escapeHTML($id)], html::escapeHTML($id)) .
                     html::escapeHTML($module['name']) .
                         '</label>';
                 } else {
                     $line .=
-                    form::hidden(array('modules[' . $count . ']'), html::escapeHTML($id)) .
+                    form::hidden(['modules[' . $count . ']'], html::escapeHTML($id)) .
                     html::escapeHTML($module['name']);
                 }
@@ -1710,5 +1712,5 @@
     protected function getActions($id, $module, $actions)
     {
-        $submits = array();
+        $submits = [];
 
         $this->core->blog->settings->addNamespace('system');
@@ -1730,5 +1732,5 @@
     protected function getGlobalActions($actions, $with_selection = false)
     {
-        $submits = array();
+        $submits = [];
 
         foreach ($actions as $action) {
@@ -1766,5 +1768,5 @@
         }
 
-        $modules = !empty($_POST['modules']) && is_array($_POST['modules']) ? array_values($_POST['modules']) : array();
+        $modules = !empty($_POST['modules']) && is_array($_POST['modules']) ? array_values($_POST['modules']) : [];
 
         if (!empty($_POST['select'])) {
Index: inc/admin/lib.pager.php
===================================================================
--- inc/admin/lib.pager.php	(revision 3774)
+++ inc/admin/lib.pager.php	(revision 3874)
@@ -34,5 +34,5 @@
             parse_str($url['query'], $args);
         } else {
-            $args = array();
+            $args = [];
         }
         # Removing session information
@@ -56,8 +56,8 @@
                 if (is_array($v)) {
                     foreach ($v as $k2 => $v2) {
-                        $this->form_hidden .= form::hidden(array($k . '[]'), html::escapeHTML($v2));
+                        $this->form_hidden .= form::hidden([$k . '[]'], html::escapeHTML($v2));
                     }
                 } else {
-                    $this->form_hidden .= form::hidden(array($k), html::escapeHTML($v));
+                    $this->form_hidden .= form::hidden([$k], html::escapeHTML($v));
                 }
             }
@@ -116,5 +116,5 @@
             ($this->nb_pages > 1 ?
             sprintf('<li class="direct-access">' . __('Direct access page %s'),
-                form::number(array($this->var_page), 1, $this->nb_pages)) .
+                form::number([$this->var_page], 1, $this->nb_pages)) .
             '<input type="submit" value="' . __('ok') . '" class="reset" ' .
             'name="ok" />' . $this->form_hidden . '</li>' : '');
@@ -180,5 +180,5 @@
         } else {
             $pager   = new dcPager($page, $this->rs_count, $nb_per_page, 10);
-            $entries = array();
+            $entries = [];
             if (isset($_REQUEST['entries'])) {
                 foreach ($_REQUEST['entries'] as $v) {
@@ -193,8 +193,8 @@
                 $html_block .= '<caption>' . sprintf(__('List of %s entries matching the filter.'), $this->rs_count) . '</caption>';
             } else {
-                $nb_published   = $this->core->blog->getPosts(array('post_status' => 1), true)->f(0);
-                $nb_pending     = $this->core->blog->getPosts(array('post_status' => -2), true)->f(0);
-                $nb_programmed  = $this->core->blog->getPosts(array('post_status' => -1), true)->f(0);
-                $nb_unpublished = $this->core->blog->getPosts(array('post_status' => 0), true)->f(0);
+                $nb_published   = $this->core->blog->getPosts(['post_status' => 1], true)->f(0);
+                $nb_pending     = $this->core->blog->getPosts(['post_status' => -2], true)->f(0);
+                $nb_programmed  = $this->core->blog->getPosts(['post_status' => -1], true)->f(0);
+                $nb_unpublished = $this->core->blog->getPosts(['post_status' => 0], true)->f(0);
                 $html_block .= '<caption>' .
                 sprintf(__('List of entries (%s)'), $this->rs_count) .
@@ -202,23 +202,23 @@
                     sprintf(
                         __(', <a href="%s">published</a> (1)', ', <a href="%s">published</a> (%s)', $nb_published),
-                        $this->core->adminurl->get('admin.posts', array('status' => 1)),
+                        $this->core->adminurl->get('admin.posts', ['status' => 1]),
                         $nb_published) : '') .
                     ($nb_pending ?
                     sprintf(
                         __(', <a href="%s">pending</a> (1)', ', <a href="%s">pending</a> (%s)', $nb_pending),
-                        $this->core->adminurl->get('admin.posts', array('status' => -2)),
+                        $this->core->adminurl->get('admin.posts', ['status' => -2]),
                         $nb_pending) : '') .
                     ($nb_programmed ?
                     sprintf(__(', <a href="%s">programmed</a> (1)', ', <a href="%s">programmed</a> (%s)', $nb_programmed),
-                        $this->core->adminurl->get('admin.posts', array('status' => -1)),
+                        $this->core->adminurl->get('admin.posts', ['status' => -1]),
                         $nb_programmed) : '') .
                     ($nb_unpublished ?
                     sprintf(__(', <a href="%s">unpublished</a> (1)', ', <a href="%s">unpublished</a> (%s)', $nb_unpublished),
-                        $this->core->adminurl->get('admin.posts', array('status' => 0)),
+                        $this->core->adminurl->get('admin.posts', ['status' => 0]),
                         $nb_unpublished) : '') .
                     '</caption>';
             }
 
-            $cols = array(
+            $cols = [
                 'title'      => '<th colspan="2" class="first">' . __('Title') . '</th>',
                 'date'       => '<th scope="col">' . __('Date') . '</th>',
@@ -230,5 +230,5 @@
                 '" /><span class="hidden">' . __('Trackbacks') . '</span></th>',
                 'status'     => '<th scope="col">' . __('Status') . '</th>'
-            );
+            ];
             $cols = new ArrayObject($cols);
             $this->core->callBehavior('adminPostListHeader', $this->core, $this->rs, $cols);
@@ -261,5 +261,5 @@
     {
         if ($this->core->auth->check('categories', $this->core->blog->id)) {
-            $cat_link = '<a href="' . $this->core->adminurl->get('admin.category', array('id' => '%s'), '&amp;', true) . '">%s</a>';
+            $cat_link = '<a href="' . $this->core->adminurl->get('admin.category', ['id' => '%s'], '&amp;', true) . '">%s</a>';
         } else {
             $cat_link = '%2$s';
@@ -314,11 +314,11 @@
         ' id="p' . $this->rs->post_id . '">';
 
-        $cols = array(
+        $cols = [
             'check'      => '<td class="nowrap">' .
-            form::checkbox(array('entries[]'), $this->rs->post_id,
-                array(
+            form::checkbox(['entries[]'], $this->rs->post_id,
+                [
                     'checked'  => $checked,
                     'disabled' => !$this->rs->isEditable()
-                )) .
+                ]) .
             '</td>',
             'title'      => '<td class="maximal" scope="row"><a href="' .
@@ -331,5 +331,5 @@
             'trackbacks' => '<td class="nowrap count">' . $this->rs->nb_trackback . '</td>',
             'status'     => '<td class="nowrap status">' . $img_status . ' ' . $selected . ' ' . $protected . ' ' . $attach . '</td>'
-        );
+        ];
         $cols = new ArrayObject($cols);
         $this->core->callBehavior('adminPostListValue', $this->core, $this->rs, $cols);
@@ -358,10 +358,10 @@
             '<table><caption class="hidden">' . __('Entries list') . '</caption><tr>';
 
-            $cols = array(
+            $cols = [
                 'title'  => '<th scope="col">' . __('Title') . '</th>',
                 'date'   => '<th scope="col">' . __('Date') . '</th>',
                 'author' => '<th scope="col">' . __('Author') . '</th>',
                 'status' => '<th scope="col">' . __('Status') . '</th>'
-            );
+            ];
 
             $cols = new ArrayObject($cols);
@@ -435,5 +435,5 @@
         ' id="p' . $this->rs->post_id . '">';
 
-        $cols = array(
+        $cols = [
             'title'  => '<td scope="row" class="maximal"><a href="' .
             $this->core->getPostAdminURL($this->rs->post_type, $this->rs->post_id) . '" ' .
@@ -443,5 +443,5 @@
             'author' => '<td class="nowrap">' . html::escapeHTML($this->rs->user_id) . '</td>',
             'status' => '<td class="nowrap status">' . $img_status . ' ' . $selected . ' ' . $protected . ' ' . $attach . '</td>'
-        );
+        ];
 
         $cols = new ArrayObject($cols);
@@ -470,5 +470,5 @@
         } else {
             // Get antispam filters' name
-            $filters = array();
+            $filters = [];
             if ($spam) {
                 if (class_exists('dcAntispam')) {
@@ -483,5 +483,5 @@
             $pager = new dcPager($page, $this->rs_count, $nb_per_page, 10);
 
-            $comments = array();
+            $comments = [];
             if (isset($_REQUEST['comments'])) {
                 foreach ($_REQUEST['comments'] as $v) {
@@ -501,8 +501,8 @@
                     '</caption>';
             } else {
-                $nb_published   = $this->core->blog->getComments(array('comment_status' => 1), true)->f(0);
-                $nb_spam        = $this->core->blog->getComments(array('comment_status' => -2), true)->f(0);
-                $nb_pending     = $this->core->blog->getComments(array('comment_status' => -1), true)->f(0);
-                $nb_unpublished = $this->core->blog->getComments(array('comment_status' => 0), true)->f(0);
+                $nb_published   = $this->core->blog->getComments(['comment_status' => 1], true)->f(0);
+                $nb_spam        = $this->core->blog->getComments(['comment_status' => -2], true)->f(0);
+                $nb_pending     = $this->core->blog->getComments(['comment_status' => -1], true)->f(0);
+                $nb_unpublished = $this->core->blog->getComments(['comment_status' => 0], true)->f(0);
                 $html_block .= '<caption>' .
                 sprintf(__('List of comments and trackbacks (%s)'), $this->rs_count) .
@@ -510,28 +510,28 @@
                     sprintf(
                         __(', <a href="%s">published</a> (1)', ', <a href="%s">published</a> (%s)', $nb_published),
-                        $this->core->adminurl->get('admin.comments', array('status' => 1)),
+                        $this->core->adminurl->get('admin.comments', ['status' => 1]),
                         $nb_published) : '') .
                     ($nb_spam ?
                     sprintf(
                         __(', <a href="%s">spam</a> (1)', ', <a href="%s">spam</a> (%s)', $nb_spam),
-                        $this->core->adminurl->get('admin.comments', array('status' => -2)),
+                        $this->core->adminurl->get('admin.comments', ['status' => -2]),
                         $nb_spam) : '') .
                     ($nb_pending ?
                     sprintf(__(', <a href="%s">pending</a> (1)', ', <a href="%s">pending</a> (%s)', $nb_pending),
-                        $this->core->adminurl->get('admin.comments', array('status' => -1)),
+                        $this->core->adminurl->get('admin.comments', ['status' => -1]),
                         $nb_pending) : '') .
                     ($nb_unpublished ?
                     sprintf(__(', <a href="%s">unpublished</a> (1)', ', <a href="%s">unpublished</a> (%s)', $nb_unpublished),
-                        $this->core->adminurl->get('admin.comments', array('status' => 0)),
+                        $this->core->adminurl->get('admin.comments', ['status' => 0]),
                         $nb_unpublished) : '') .
                     '</caption>';
             }
 
-            $cols = array(
+            $cols = [
                 'type'   => '<th colspan="2" scope="col" abbr="comm" class="first">' . __('Type') . '</th>',
                 'author' => '<th scope="col">' . __('Author') . '</th>',
                 'date'   => '<th scope="col">' . __('Date') . '</th>',
                 'status' => '<th scope="col" class="txt-center">' . __('Status') . '</th>'
-            );
+            ];
             if ($spam) {
                 $cols['ip']          = '<th scope="col">' . __('IP') . '</th>';
@@ -565,10 +565,10 @@
     }
 
-    private function commentLine($checked = false, $spam = false, $filters = array())
+    private function commentLine($checked = false, $spam = false, $filters = [])
     {
         global $core, $author, $status, $sortby, $order, $nb_per_page;
 
         $author_url =
-        $this->core->adminurl->get('admin.comments', array(
+        $this->core->adminurl->get('admin.comments', [
             'n'      => $nb_per_page,
             'status' => $status,
@@ -576,9 +576,9 @@
             'order'  => $order,
             'author' => $this->rs->comment_author
-        ));
+        ]);
 
         $post_url = $this->core->getPostAdminURL($this->rs->post_type, $this->rs->post_id);
 
-        $comment_url = $this->core->adminurl->get('admin.comment', array('id' => $this->rs->comment_id));
+        $comment_url = $this->core->adminurl->get('admin.comment', ['id' => $this->rs->comment_id]);
 
         $comment_dt =
@@ -618,7 +618,7 @@
         ' id="c' . $this->rs->comment_id . '">';
 
-        $cols = array(
+        $cols = [
             'check'  => '<td class="nowrap">' .
-            form::checkbox(array('comments[]'), $this->rs->comment_id, $checked) .
+            form::checkbox(['comments[]'], $this->rs->comment_id, $checked) .
             '</td>',
             'type'   => '<td class="nowrap" abbr="' . __('Type and author') . '" scope="row">' .
@@ -630,5 +630,5 @@
             'date'   => '<td class="nowrap count">' . dt::dt2str(__('%Y-%m-%d %H:%M'), $this->rs->comment_dt) . '</td>',
             'status' => '<td class="nowrap status txt-center">' . $img_status . '</td>'
-        );
+        ];
 
         if ($spam) {
@@ -642,5 +642,5 @@
             }
             $cols['ip'] = '<td class="nowrap"><a href="' .
-            $core->adminurl->get("admin.comments", array('ip' => $this->rs->comment_ip)) . '">' .
+            $core->adminurl->get("admin.comments", ['ip' => $this->rs->comment_ip]) . '">' .
             $this->rs->comment_ip . '</a></td>';
             $cols['spam_filter'] = '<td class="nowrap">' . $filter_name . '</td>';
@@ -670,5 +670,5 @@
             }
         } else {
-            $blogs = array();
+            $blogs = [];
             if (isset($_REQUEST['blogs'])) {
                 foreach ($_REQUEST['blogs'] as $v) {
@@ -679,5 +679,5 @@
             $pager = new dcPager($page, $this->rs_count, $nb_per_page, 10);
 
-            $cols = array(
+            $cols = [
                 'blog'   => '<th' .
                 ($this->core->auth->isSuperAdmin() ? ' colspan="2"' : '') .
@@ -688,5 +688,5 @@
                 'upddt'  => '<th scope="col" class="nowrap">' . __('Last update') . '</th>',
                 'status' => '<th scope="col" class="txt-center">' . __('Status') . '</th>'
-            );
+            ];
 
             $cols = new ArrayObject($cols);
@@ -728,14 +728,14 @@
         $blog_id = html::escapeHTML($this->rs->blog_id);
 
-        $cols = array(
+        $cols = [
             'check'  =>
             ($this->core->auth->isSuperAdmin() ?
                 '<td class="nowrap">' .
-                form::checkbox(array('blogs[]'), $this->rs->blog_id, $checked) .
+                form::checkbox(['blogs[]'], $this->rs->blog_id, $checked) .
                 '</td>' : ''),
             'blog'   =>
             '<td class="nowrap">' .
             ($this->core->auth->isSuperAdmin() ?
-                '<a href="' . $this->core->adminurl->get("admin.blog", array('id' => $blog_id)) . '"  ' .
+                '<a href="' . $this->core->adminurl->get("admin.blog", ['id' => $blog_id]) . '"  ' .
                 'title="' . sprintf(__('Edit blog settings for %s'), $blog_id) . '">' .
                 '<img src="images/edit-mini.png" alt="' . __('Edit blog settings') . '" /> ' . $blog_id . '</a> ' :
@@ -744,5 +744,5 @@
             'name'   =>
             '<td class="maximal">' .
-            '<a href="' . $this->core->adminurl->get("admin.home", array('switchblog' => $this->rs->blog_id)) . '" ' .
+            '<a href="' . $this->core->adminurl->get("admin.home", ['switchblog' => $this->rs->blog_id]) . '" ' .
             'title="' . sprintf(__('Switch to blog %s'), $this->rs->blog_id) . '">' .
             html::escapeHTML($this->rs->blog_name) . '</a>' .
@@ -769,5 +769,5 @@
             ) .
             '</td>'
-        );
+        ];
 
         $cols = new ArrayObject($cols);
@@ -804,5 +804,5 @@
             }
 
-            $cols = array(
+            $cols = [
                 'username'     => '<th colspan="2" scope="col" class="first">' . __('Username') . '</th>',
                 'first_name'   => '<th scope="col">' . __('First Name') . '</th>',
@@ -810,5 +810,5 @@
                 'display_name' => '<th scope="col">' . __('Display name') . '</th>',
                 'entries'      => '<th scope="col" class="nowrap">' . __('Entries (all types)') . '</th>'
-            );
+            ];
 
             $cols = new ArrayObject($cols);
@@ -852,9 +852,9 @@
         $res = '<tr class="line">';
 
-        $cols = array(
-            'check'        => '<td class="nowrap">' . form::hidden(array('nb_post[]'), (integer) $this->rs->nb_post) .
-            form::checkbox(array('users[]'), $this->rs->user_id) . '</td>',
+        $cols = [
+            'check'        => '<td class="nowrap">' . form::hidden(['nb_post[]'], (integer) $this->rs->nb_post) .
+            form::checkbox(['users[]'], $this->rs->user_id) . '</td>',
             'username'     => '<td class="maximal" scope="row"><a href="' .
-            $this->core->adminurl->get('admin.user', array('id' => $this->rs->user_id)) . '">' .
+            $this->core->adminurl->get('admin.user', ['id' => $this->rs->user_id]) . '">' .
             $this->rs->user_id . '</a>&nbsp;' . $img_status . '</td>',
             'first_name'   => '<td class="nowrap">' . html::escapeHTML($this->rs->user_firstname) . '</td>',
@@ -862,7 +862,7 @@
             'display_name' => '<td class="nowrap">' . html::escapeHTML($this->rs->user_displayname) . '</td>',
             'entries'      => '<td class="nowrap count"><a href="' .
-            $this->core->adminurl->get('admin.posts', array('user_id' => $this->rs->user_id)) . '">' .
+            $this->core->adminurl->get('admin.posts', ['user_id' => $this->rs->user_id]) . '">' .
             $this->rs->nb_post . '</a></td>'
-        );
+        ];
 
         $cols = new ArrayObject($cols);
Index: inc/admin/prepend.php
===================================================================
--- inc/admin/prepend.php	(revision 3731)
+++ inc/admin/prepend.php	(revision 3874)
@@ -51,5 +51,5 @@
                 $icon = path::real(dirname(__FILE__) . '/../../admin/images/iconset/' . $user_ui_iconset . '/' . $m[1], false);
                 if ($icon !== false) {
-                    $allow_types = array('png', 'jpg', 'jpeg', 'gif');
+                    $allow_types = ['png', 'jpg', 'jpeg', 'gif'];
                     if (is_file($icon) && is_readable($icon) && in_array(files::getExtension($icon), $allow_types)) {
                         return DC_ADMIN_URL . 'images/iconset/' . $user_ui_iconset . '/' . $m[1];
@@ -196,6 +196,6 @@
 $core->adminurl->register('admin.update', 'update.php');
 
-$core->adminurl->registercopy('load.plugin.file', 'admin.home', array('pf' => 'dummy.css'));
-$core->adminurl->registercopy('load.var.file', 'admin.home', array('vf' => 'dummy.json'));
+$core->adminurl->registercopy('load.plugin.file', 'admin.home', ['pf' => 'dummy.css']);
+$core->adminurl->registercopy('load.var.file', 'admin.home', ['vf' => 'dummy.json']);
 
 if ($core->auth->userID() && $core->blog !== null) {
Index: inc/core/class.dc.auth.php
===================================================================
--- inc/core/class.dc.auth.php	(revision 3731)
+++ inc/core/class.dc.auth.php	(revision 3874)
@@ -30,7 +30,7 @@
     protected $user_id;
     /** @var array Array with user information */
-    protected $user_info = array();
+    protected $user_info = [];
     /** @var array Array with user options */
-    protected $user_options = array();
+    protected $user_options = [];
     /** @var boolean User must change his password after login */
     protected $user_change_pwd;
@@ -38,9 +38,9 @@
     protected $user_admin;
     /** @var array Permissions for each blog */
-    protected $permissions = array();
+    protected $permissions = [];
     /** @var boolean User can change its password */
     protected $allow_pass_change = true;
     /** @var array List of blogs on which the user has permissions */
-    protected $blogs = array();
+    protected $blogs = [];
     /** @var integer Count of user blogs */
     public $blog_count = null;
@@ -65,5 +65,5 @@
         $this->perm_table = $core->prefix . 'permissions';
 
-        $this->perm_types = array(
+        $this->perm_types = [
             'admin'        => __('administrator'),
             'usage'        => __('manage their own entries and comments'),
@@ -74,5 +74,5 @@
             'media'        => __('manage their own media items'),
             'media_admin'  => __('manage all media items')
-        );
+        ];
     }
 
@@ -375,12 +375,9 @@
      * @return mixed
      */
-    public function sudo($f)
+    public function sudo($f, ...$args)
     {
         if (!is_callable($f)) {
             throw new Exception($f . ' function doest not exist');
         }
-
-        $args = func_get_args();
-        array_shift($args);
 
         if ($this->user_admin) {
@@ -425,5 +422,5 @@
             $rs = $this->con->select($strReq);
 
-            $this->blogs[$blog_id] = $rs->isEmpty() ? false : array('admin' => true);
+            $this->blogs[$blog_id] = $rs->isEmpty() ? false : ['admin' => true];
 
             return $this->blogs[$blog_id];
@@ -445,5 +442,5 @@
     {
         if ($this->blog_count === null) {
-            $this->blog_count = $this->core->getBlogs(array(), true)->f(0);
+            $this->blog_count = $this->core->getBlogs([], true)->f(0);
         }
 
@@ -544,5 +541,5 @@
         $level = preg_replace('/\|$/', '', $level);
 
-        $res = array();
+        $res = [];
         foreach (explode('|', $level) as $v) {
             $res[$v] = true;
@@ -637,5 +634,5 @@
         $cur->update("WHERE user_recover_key = '" . $this->con->escape($recover_key) . "'");
 
-        return array('user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass);
+        return ['user_email' => $rs->user_email, 'user_id' => $rs->user_id, 'new_pass' => $new_pass];
     }
     //@}
Index: inc/core/class.dc.blog.php
===================================================================
--- inc/core/class.dc.blog.php	(revision 3731)
+++ inc/core/class.dc.blog.php	(revision 3874)
@@ -49,6 +49,6 @@
     public $public_path;
 
-    private $post_status    = array();
-    private $comment_status = array();
+    private $post_status    = [];
+    private $comment_status = [];
 
     private $categories;
@@ -249,5 +249,5 @@
             $rs = $this->con->select($strReq);
 
-            $affected_posts = array();
+            $affected_posts = [];
             while ($rs->fetch()) {
                 $affected_posts[] = (integer) $rs->post_id;
@@ -269,5 +269,5 @@
         $rs = $this->con->select($strReq);
 
-        $posts = array();
+        $posts = [];
         while ($rs->fetch()) {
             if ($rs->comment_trackback) {
@@ -320,7 +320,7 @@
     @return    <b>record</b>
      */
-    public function getCategories($params = array())
-    {
-        $c_params = array();
+    public function getCategories($params = [])
+    {
+        $c_params = [];
         if (isset($params['post_type'])) {
             $c_params['post_type'] = $params['post_type'];
@@ -341,6 +341,6 @@
 
         # Get each categories total posts count
-        $data  = array();
-        $stack = array();
+        $data  = [];
+        $stack = [];
         $level = 0;
         $cols  = $rs->columns();
@@ -370,5 +370,5 @@
             $level = $rs->level;
 
-            $t = array();
+            $t = [];
             foreach ($cols as $c) {
                 $t[$c] = $rs->f($c);
@@ -388,10 +388,10 @@
                 if ($v['cat_id'] == $params['cat_id']) {
                     $found = true;
-                    $data  = array($v);
+                    $data  = [$v];
                     break;
                 }
             }
             if (!$found) {
-                $data = array();
+                $data = [];
             }
         }
@@ -403,10 +403,10 @@
                 if ($v['cat_url'] == $params['cat_url']) {
                     $found = true;
-                    $data  = array($v);
+                    $data  = [$v];
                     break;
                 }
             }
             if (!$found) {
-                $data = array();
+                $data = [];
             }
         }
@@ -423,5 +423,5 @@
     public function getCategory($id)
     {
-        return $this->getCategories(array('cat_id' => $id));
+        return $this->getCategories(['cat_id' => $id]);
     }
 
@@ -456,8 +456,8 @@
     public function getCategoryFirstChildren($id)
     {
-        return $this->getCategories(array('start' => $id, 'level' => $id == 0 ? 1 : 2));
-    }
-
-    private function getCategoriesCounter($params = array())
+        return $this->getCategories(['start' => $id, 'level' => $id == 0 ? 1 : 2]);
+    }
+
+    private function getCategoriesCounter($params = [])
     {
         $strReq =
@@ -478,5 +478,5 @@
 
         $rs       = $this->con->select($strReq);
-        $counters = array();
+        $counters = [];
         while ($rs->fetch()) {
             $counters[$rs->cat_id] = $rs->nb_post;
@@ -499,9 +499,9 @@
         }
 
-        $url = array();
+        $url = [];
         if ($parent != 0) {
             $rs = $this->getCategory($parent);
             if ($rs->isEmpty()) {
-                $url = array();
+                $url = [];
             } else {
                 $url[] = $rs->cat_url;
@@ -551,5 +551,5 @@
 
         if ($cur->cat_url == '') {
-            $url = array();
+            $url = [];
             $rs  = $this->categories()->getParents($id);
             while ($rs->fetch()) {
@@ -695,5 +695,5 @@
 
             $rs = $this->con->select($strReq);
-            $a  = array();
+            $a  = [];
             while ($rs->fetch()) {
                 $a[] = $rs->cat_url;
@@ -785,5 +785,5 @@
     @return    <b>record</b>    A record with some more capabilities or the SQL request
      */
-    public function getPosts($params = array(), $count_only = false)
+    public function getPosts($params = [], $count_only = false)
     {
         # --BEHAVIOR-- coreBlogBeforeGetPosts
@@ -860,5 +860,5 @@
                 array_walk($params['post_id'], function (&$v, $k) {if ($v !== null) {$v = (integer) $v;}});
             } else {
-                $params['post_id'] = array((integer) $params['post_id']);
+                $params['post_id'] = [(integer) $params['post_id']];
             }
             $strReq .= 'AND P.post_id ' . $this->con->in($params['post_id']);
@@ -869,5 +869,5 @@
                 array_walk($params['exclude_post_id'], function (&$v, $k) {if ($v !== null) {$v = (integer) $v;}});
             } else {
-                $params['exclude_post_id'] = array((integer) $params['exclude_post_id']);
+                $params['exclude_post_id'] = [(integer) $params['exclude_post_id']];
             }
             $strReq .= 'AND P.post_id NOT ' . $this->con->in($params['exclude_post_id']);
@@ -884,5 +884,5 @@
         if (isset($params['cat_id']) && $params['cat_id'] !== '') {
             if (!is_array($params['cat_id'])) {
-                $params['cat_id'] = array($params['cat_id']);
+                $params['cat_id'] = [$params['cat_id']];
             }
             if (!empty($params['cat_id_not'])) {
@@ -892,5 +892,5 @@
         } elseif (isset($params['cat_url']) && $params['cat_url'] !== '') {
             if (!is_array($params['cat_url'])) {
-                $params['cat_url'] = array($params['cat_url']);
+                $params['cat_url'] = [$params['cat_url']];
             }
             if (!empty($params['cat_url_not'])) {
@@ -938,5 +938,5 @@
                 # --BEHAVIOR-- corePostSearch
                 if ($this->core->hasBehavior('corePostSearch')) {
-                    $this->core->callBehavior('corePostSearch', $this->core, array(&$words, &$strReq, &$params));
+                    $this->core->callBehavior('corePostSearch', $this->core, [&$words, &$strReq, &$params]);
                 }
 
@@ -990,5 +990,5 @@
         $rs            = $this->con->select($strReq);
         $rs->core      = $this->core;
-        $rs->_nb_media = array();
+        $rs->_nb_media = [];
         $rs->extend('rsExtPost');
 
@@ -997,5 +997,5 @@
 
         # --BEHAVIOR-- coreBlogAfterGetPosts
-        $alt = new arrayObject(array('rs' => null, 'params' => $params, 'count_only' => $count_only));
+        $alt = new arrayObject(['rs' => null, 'params' => $params, 'count_only' => $count_only]);
         $this->core->callBehavior('coreBlogAfterGetPosts', $rs, $alt);
         if ($alt['rs'] instanceof record) {
@@ -1068,5 +1068,5 @@
     @return    record
      */
-    public function getLangs($params = array())
+    public function getLangs($params = [])
     {
         $strReq = 'SELECT COUNT(post_id) as nb_post, post_lang ' .
@@ -1132,5 +1132,5 @@
     @return    record
      */
-    public function getDates($params = array())
+    public function getDates($params = [])
     {
         $dt_f  = '%Y-%m-%d';
@@ -1610,11 +1610,11 @@
     public function firstPublicationEntries($ids)
     {
-        $posts = $this->getPosts(array(
+        $posts = $this->getPosts([
             'post_id'       => dcUtils::cleanIds($ids),
             'post_status'   => 1,
             'post_firstpub' => 0
-        ));
-
-        $to_change = array();
+        ]);
+
+        $to_change = [];
         while ($posts->fetch()) {
 
@@ -1663,7 +1663,7 @@
         $field = $field == 'cat_id' ? 'cat_id' : 'cat_url';
 
-        $sub     = array();
-        $not     = array();
-        $queries = array();
+        $sub     = [];
+        $not     = [];
+        $queries = [];
 
         foreach ($arr as $v) {
@@ -1699,8 +1699,8 @@
 
         # Create queries
-        $sql = array(
-            0 => array(), # wanted categories
-            1 => array() # excluded categories
-        );
+        $sql = [
+            0 => [], # wanted categories
+            1 => [] # excluded categories
+        ];
 
         foreach ($queries as $id => $q) {
@@ -1838,10 +1838,10 @@
 
         # --BEHAVIOR-- coreAfterPostContentFormat
-        $this->core->callBehavior('coreAfterPostContentFormat', array(
+        $this->core->callBehavior('coreAfterPostContentFormat', [
             'excerpt'       => &$excerpt,
             'content'       => &$content,
             'excerpt_xhtml' => &$excerpt_xhtml,
             'content_xhtml' => &$content_xhtml
-        ));
+        ]);
     }
 
@@ -1860,5 +1860,5 @@
         $url = trim($url);
 
-        $url_patterns = array(
+        $url_patterns = [
             '{y}'  => date('Y', strtotime($post_dt)),
             '{m}'  => date('m', strtotime($post_dt)),
@@ -1866,5 +1866,5 @@
             '{t}'  => text::tidyURL($post_title),
             '{id}' => (integer) $post_id
-        );
+        ];
 
         # If URL is empty, we create a new one
@@ -1896,5 +1896,5 @@
             } else {
                 $clause = "LIKE '" .
-                $this->con->escape(preg_replace(array('%', '_', '!'), array('!%', '!_', '!!'), $url)) .
+                $this->con->escape(preg_replace(['%', '_', '!'], ['!%', '!_', '!!'], $url)) .
                     "%' ESCAPE '!'";
             }
@@ -1906,5 +1906,5 @@
 
             $rs = $this->con->select($strReq);
-            $a  = array();
+            $a  = [];
             while ($rs->fetch()) {
                 $a[] = $rs->post_url;
@@ -1961,5 +1961,5 @@
     @return    <b>record</b>    A record with some more capabilities
      */
-    public function getComments($params = array(), $count_only = false)
+    public function getComments($params = [], $count_only = false)
     {
         if ($count_only) {
@@ -2030,5 +2030,5 @@
                 array_walk($params['comment_id'], function (&$v, $k) {if ($v !== null) {$v = (integer) $v;}});
             } else {
-                $params['comment_id'] = array((integer) $params['comment_id']);
+                $params['comment_id'] = [(integer) $params['comment_id']];
             }
             $strReq .= 'AND comment_id ' . $this->con->in($params['comment_id']);
@@ -2073,5 +2073,5 @@
                 # --BEHAVIOR coreCommentSearch
                 if ($this->core->hasBehavior('coreCommentSearch')) {
-                    $this->core->callBehavior('coreCommentSearch', $this->core, array(&$words, &$strReq, &$params));
+                    $this->core->callBehavior('coreCommentSearch', $this->core, [&$words, &$strReq, &$params]);
                 }
 
@@ -2184,5 +2184,5 @@
         }
 
-        $rs = $this->getComments(array('comment_id' => $id));
+        $rs = $this->getComments(['comment_id' => $id]);
 
         if ($rs->isEmpty()) {
@@ -2289,5 +2289,5 @@
 
         # Retrieve posts affected by comments edition
-        $affected_posts = array();
+        $affected_posts = [];
         $strReq         =
         'SELECT post_id ' .
Index: inc/core/class.dc.categories.php
===================================================================
--- inc/core/class.dc.categories.php	(revision 3731)
+++ inc/core/class.dc.categories.php	(revision 3874)
@@ -31,22 +31,22 @@
         $this->blog_id       = $core->blog->id;
         $this->table         = $core->prefix . 'category';
-        $this->add_condition = array('blog_id' => "'" . $this->con->escape($this->blog_id) . "'");
-    }
-
-    public function getChildren($start = 0, $id = null, $sort = 'asc', $fields = array())
-    {
-        $fields = array_merge(array('cat_title', 'cat_url', 'cat_desc'), $fields);
+        $this->add_condition = ['blog_id' => "'" . $this->con->escape($this->blog_id) . "'"];
+    }
+
+    public function getChildren($start = 0, $id = null, $sort = 'asc', $fields = [])
+    {
+        $fields = array_merge(['cat_title', 'cat_url', 'cat_desc'], $fields);
         return parent::getChildren($start, $id, $sort, $fields);
     }
 
-    public function getParents($id, $fields = array())
-    {
-        $fields = array_merge(array('cat_title', 'cat_url', 'cat_desc'), $fields);
+    public function getParents($id, $fields = [])
+    {
+        $fields = array_merge(['cat_title', 'cat_url', 'cat_desc'], $fields);
         return parent::getParents($id, $fields);
     }
 
-    public function getParent($id, $fields = array())
-    {
-        $fields = array_merge(array('cat_title', 'cat_url', 'cat_desc'), $fields);
+    public function getParent($id, $fields = [])
+    {
+        $fields = array_merge(['cat_title', 'cat_url', 'cat_desc'], $fields);
         return parent::getParent($id, $fields);
     }
@@ -62,5 +62,5 @@
     protected $f_id;
 
-    protected $add_condition = array();
+    protected $add_condition = [];
 
     protected $parents;
@@ -71,5 +71,5 @@
     }
 
-    public function getChildren($start = 0, $id = null, $sort = 'asc', $fields = array())
+    public function getChildren($start = 0, $id = null, $sort = 'asc', $fields = [])
     {
         $fields = count($fields) > 0 ? ', C2.' . implode(', C2.', $fields) : '';
@@ -103,5 +103,5 @@
     }
 
-    public function getParents($id, $fields = array())
+    public function getParents($id, $fields = [])
     {
         $fields = count($fields) > 0 ? ', C1.' . implode(', C1.', $fields) : '';
@@ -119,5 +119,5 @@
     }
 
-    public function getParent($id, $fields = array())
+    public function getParent($id, $fields = [])
     {
         $fields = count($fields) > 0 ? ', C1.' . implode(', C1.', $fields) : '';
@@ -472,5 +472,5 @@
         }
 
-        $w = array();
+        $w = [];
         foreach ($this->add_condition as $c => $n) {
             $w[] = $prefix . $c . ' = ' . $n;
Index: inc/core/class.dc.core.php
===================================================================
--- inc/core/class.dc.core.php	(revision 3866)
+++ inc/core/class.dc.core.php	(revision 3874)
@@ -31,7 +31,7 @@
 
     private $versions   = null;
-    private $formaters  = array();
-    private $behaviors  = array();
-    private $post_types = array();
+    private $formaters  = [];
+    private $behaviors  = [];
+    private $post_types = [];
 
     /**
@@ -151,9 +151,9 @@
     public function getAllBlogStatus()
     {
-        return array(
+        return [
             1  => __('online'),
             0  => __('offline'),
             -1 => __('removed')
-        );
+        ];
     }
 
@@ -200,5 +200,5 @@
         }
 
-        return form::hidden(array('xd_check'), $this->getNonce());
+        return form::hidden(['xd_check'], $this->getNonce());
     }
     //@}
@@ -244,5 +244,5 @@
     public function getEditors()
     {
-        $editors = array();
+        $editors = [];
 
         foreach (array_keys($this->formaters) as $editor_id) {
@@ -270,5 +270,5 @@
     public function getFormaters($editor_id = '')
     {
-        $formaters_list = array();
+        $formaters_list = [];
 
         if (!empty($editor_id)) {
@@ -363,5 +363,5 @@
         }
 
-        return array();
+        return [];
     }
 
@@ -376,10 +376,7 @@
     @return    <b>string</b> Behavior concatened result
      */
-    public function callBehavior($behavior)
+    public function callBehavior($behavior, ...$args)
     {
         if (isset($this->behaviors[$behavior])) {
-            $args = func_get_args();
-            array_shift($args);
-
             $res = '';
 
@@ -417,9 +414,9 @@
     public function setPostType($type, $admin_url, $public_url, $label = '')
     {
-        $this->post_types[$type] = array(
+        $this->post_types[$type] = [
             'admin_url'  => $admin_url,
             'public_url' => $public_url,
             'label'      => ($label != '' ? $label : $type)
-        );
+        ];
     }
 
@@ -528,5 +525,5 @@
     @return    <b>record</b>
      */
-    public function getUsers($params = array(), $count_only = false)
+    public function getUsers($params = [], $count_only = false)
     {
         if ($count_only) {
@@ -566,5 +563,5 @@
             if (!empty($params['order']) && !$count_only) {
                 if (preg_match('`^([^. ]+) (?:asc|desc)`i', $params['order'], $matches)) {
-                    if (in_array($matches[1], array('user_id', 'user_name', 'user_firstname', 'user_displayname'))) {
+                    if (in_array($matches[1], ['user_id', 'user_name', 'user_firstname', 'user_displayname'])) {
                         $table_prefix = 'U.';
                     } else {
@@ -728,12 +725,12 @@
         $rs = $this->con->select($strReq);
 
-        $res = array();
+        $res = [];
 
         while ($rs->fetch()) {
-            $res[$rs->blog_id] = array(
+            $res[$rs->blog_id] = [
                 'name' => $rs->blog_name,
                 'url'  => $rs->blog_url,
                 'p'    => $this->auth->parsePermissions($rs->permissions)
-            );
+            ];
         }
 
@@ -860,11 +857,11 @@
     public function userDefaults()
     {
-        return array(
+        return [
             'edit_size'      => 24,
             'enable_wysiwyg' => true,
             'toolbar_bottom' => false,
-            'editor'         => array('xhtml' => 'dcCKEditor', 'wiki' => 'dcLegacyEditor'),
+            'editor'         => ['xhtml' => 'dcCKEditor', 'wiki' => 'dcLegacyEditor'],
             'post_format'    => 'wiki'
-        );
+        ];
     }
     //@}
@@ -908,8 +905,8 @@
         $rs = $this->con->select($strReq);
 
-        $res = array();
+        $res = [];
 
         while ($rs->fetch()) {
-            $res[$rs->user_id] = array(
+            $res[$rs->user_id] = [
                 'name'        => $rs->user_name,
                 'firstname'   => $rs->user_firstname,
@@ -918,5 +915,5 @@
                 'super'       => (boolean) $rs->user_super,
                 'p'           => $this->auth->parsePermissions($rs->permissions)
-            );
+            ];
         }
 
@@ -932,5 +929,5 @@
     public function getBlog($id)
     {
-        $blog = $this->getBlogs(array('blog_id' => $id));
+        $blog = $this->getBlogs(['blog_id' => $id]);
 
         if ($blog->isEmpty()) {
@@ -953,5 +950,5 @@
     @return    <b>record</b>
      */
-    public function getBlogs($params = array(), $count_only = false)
+    public function getBlogs($params = [], $count_only = false)
     {
         $join  = ''; // %1$s
@@ -1000,5 +997,5 @@
         if (isset($params['blog_id']) && $params['blog_id'] !== '') {
             if (!is_array($params['blog_id'])) {
-                $params['blog_id'] = array($params['blog_id']);
+                $params['blog_id'] = [$params['blog_id']];
             }
             $where .= 'AND B.blog_id ' . $this->con->in($params['blog_id']);
@@ -1184,5 +1181,5 @@
         $this->initWiki();
 
-        $this->wiki2xhtml->setOpts(array(
+        $this->wiki2xhtml->setOpts([
             'active_title'        => 1,
             'active_setext_title' => 0,
@@ -1217,7 +1214,7 @@
             'note_str'            => '<div class="footnotes"><h4>Notes</h4>%s</div>',
             'img_style_center'    => 'display:table; margin:0 auto;'
-        ));
-
-        $this->wiki2xhtml->registerFunction('url:post', array($this, 'wikiPostLink'));
+        ]);
+
+        $this->wiki2xhtml->registerFunction('url:post', [$this, 'wikiPostLink']);
 
         # --BEHAVIOR-- coreWikiPostInit
@@ -1232,5 +1229,5 @@
         $this->initWiki();
 
-        $this->wiki2xhtml->setOpts(array(
+        $this->wiki2xhtml->setOpts([
             'active_title'        => 0,
             'active_setext_title' => 0,
@@ -1261,5 +1258,5 @@
             'parse_pre'           => 0,
             'active_fr_syntax'    => 0
-        ));
+        ]);
 
         # --BEHAVIOR-- coreInitWikiSimpleComment
@@ -1274,5 +1271,5 @@
         $this->initWiki();
 
-        $this->wiki2xhtml->setOpts(array(
+        $this->wiki2xhtml->setOpts([
             'active_title'        => 0,
             'active_setext_title' => 0,
@@ -1303,5 +1300,5 @@
             'parse_pre'           => 0,
             'active_fr_syntax'    => 0
-        ));
+        ]);
 
         # --BEHAVIOR-- coreInitWikiComment
@@ -1312,18 +1309,18 @@
     {
         if (!($this->blog instanceof dcBlog)) {
-            return array();
+            return [];
         }
 
         $post_id = abs((integer) substr($url, 5));
         if (!$post_id) {
-            return array();
-        }
-
-        $post = $this->blog->getPosts(array('post_id' => $post_id));
+            return [];
+        }
+
+        $post = $this->blog->getPosts(['post_id' => $post_id]);
         if ($post->isEmpty()) {
-            return array();
-        }
-
-        $res        = array('url' => $post->getURL());
+            return [];
+        }
+
+        $res        = ['url' => $post->getURL()];
         $post_title = $post->post_title;
 
@@ -1355,97 +1352,97 @@
     {
         if (!is_array($defaults)) {
-            $defaults = array(
-                array('allow_comments', 'boolean', true,
-                    'Allow comments on blog'),
-                array('allow_trackbacks', 'boolean', true,
-                    'Allow trackbacks on blog'),
-                array('blog_timezone', 'string', 'Europe/London',
-                    'Blog timezone'),
-                array('comments_nofollow', 'boolean', true,
-                    'Add rel="nofollow" to comments URLs'),
-                array('comments_pub', 'boolean', true,
-                    'Publish comments immediately'),
-                array('comments_ttl', 'integer', 0,
-                    'Number of days to keep comments open (0 means no ttl)'),
-                array('copyright_notice', 'string', '', 'Copyright notice (simple text)'),
-                array('date_format', 'string', '%A, %B %e %Y',
-                    'Date format. See PHP strftime function for patterns'),
-                array('editor', 'string', '',
-                    'Person responsible of the content'),
-                array('enable_html_filter', 'boolean', 0,
-                    'Enable HTML filter'),
-                array('enable_xmlrpc', 'boolean', 0,
-                    'Enable XML/RPC interface'),
-                array('lang', 'string', 'en',
-                    'Default blog language'),
-                array('media_exclusion', 'string', '/\.(phps?|pht(ml)?|phl|.?html?|xml|js|htaccess)[0-9]*$/i',
-                    'File name exclusion pattern in media manager. (PCRE value)'),
-                array('media_img_m_size', 'integer', 448,
-                    'Image medium size in media manager'),
-                array('media_img_s_size', 'integer', 240,
-                    'Image small size in media manager'),
-                array('media_img_t_size', 'integer', 100,
-                    'Image thumbnail size in media manager'),
-                array('media_img_title_pattern', 'string', 'Title ;; Date(%b %Y) ;; separator(, )',
-                    'Pattern to set image title when you insert it in a post'),
-                array('media_video_width', 'integer', 400,
-                    'Video width in media manager'),
-                array('media_video_height', 'integer', 300,
-                    'Video height in media manager'),
-                array('media_flash_fallback', 'boolean', true,
-                    'Flash player fallback for audio and video media'),
-                array('nb_post_for_home', 'integer', 20,
-                    'Number of entries on first home page'),
-                array('nb_post_per_page', 'integer', 20,
-                    'Number of entries on home pages and category pages'),
-                array('nb_post_per_feed', 'integer', 20,
-                    'Number of entries on feeds'),
-                array('nb_comment_per_feed', 'integer', 20,
-                    'Number of comments on feeds'),
-                array('post_url_format', 'string', '{y}/{m}/{d}/{t}',
-                    'Post URL format. {y}: year, {m}: month, {d}: day, {id}: post id, {t}: entry title'),
-                array('public_path', 'string', 'public',
-                    'Path to public directory, begins with a / for a full system path'),
-                array('public_url', 'string', '/public',
-                    'URL to public directory'),
-                array('robots_policy', 'string', 'INDEX,FOLLOW',
-                    'Search engines robots policy'),
-                array('short_feed_items', 'boolean', false,
-                    'Display short feed items'),
-                array('theme', 'string', 'berlin',
-                    'Blog theme'),
-                array('themes_path', 'string', 'themes',
-                    'Themes root path'),
-                array('themes_url', 'string', '/themes',
-                    'Themes root URL'),
-                array('time_format', 'string', '%H:%M',
-                    'Time format. See PHP strftime function for patterns'),
-                array('tpl_allow_php', 'boolean', false,
-                    'Allow PHP code in templates'),
-                array('tpl_use_cache', 'boolean', true,
-                    'Use template caching'),
-                array('trackbacks_pub', 'boolean', true,
-                    'Publish trackbacks immediately'),
-                array('trackbacks_ttl', 'integer', 0,
-                    'Number of days to keep trackbacks open (0 means no ttl)'),
-                array('url_scan', 'string', 'query_string',
-                    'URL handle mode (path_info or query_string)'),
-                array('use_smilies', 'boolean', false,
-                    'Show smilies on entries and comments'),
-                array('no_search', 'boolean', false,
-                    'Disable search'),
-                array('inc_subcats', 'boolean', false,
-                    'Include sub-categories in category page and category posts feed'),
-                array('wiki_comments', 'boolean', false,
-                    'Allow commenters to use a subset of wiki syntax'),
-                array('import_feed_url_control', 'boolean', true,
-                    'Control feed URL before import'),
-                array('import_feed_no_private_ip', 'boolean', true,
-                    'Prevent import feed from private IP'),
-                array('import_feed_ip_regexp', 'string', '',
-                    'Authorize import feed only from this IP regexp'),
-                array('import_feed_port_regexp', 'string', '/^(80|443)$/',
-                    'Authorize import feed only from this port regexp')
-            );
+            $defaults = [
+                ['allow_comments', 'boolean', true,
+                    'Allow comments on blog'],
+                ['allow_trackbacks', 'boolean', true,
+                    'Allow trackbacks on blog'],
+                ['blog_timezone', 'string', 'Europe/London',
+                    'Blog timezone'],
+                ['comments_nofollow', 'boolean', true,
+                    'Add rel="nofollow" to comments URLs'],
+                ['comments_pub', 'boolean', true,
+                    'Publish comments immediately'],
+                ['comments_ttl', 'integer', 0,
+                    'Number of days to keep comments open (0 means no ttl)'],
+                ['copyright_notice', 'string', '', 'Copyright notice (simple text)'],
+                ['date_format', 'string', '%A, %B %e %Y',
+                    'Date format. See PHP strftime function for patterns'],
+                ['editor', 'string', '',
+                    'Person responsible of the content'],
+                ['enable_html_filter', 'boolean', 0,
+                    'Enable HTML filter'],
+                ['enable_xmlrpc', 'boolean', 0,
+                    'Enable XML/RPC interface'],
+                ['lang', 'string', 'en',
+                    'Default blog language'],
+                ['media_exclusion', 'string', '/\.(phps?|pht(ml)?|phl|.?html?|xml|js|htaccess)[0-9]*$/i',
+                    'File name exclusion pattern in media manager. (PCRE value)'],
+                ['media_img_m_size', 'integer', 448,
+                    'Image medium size in media manager'],
+                ['media_img_s_size', 'integer', 240,
+                    'Image small size in media manager'],
+                ['media_img_t_size', 'integer', 100,
+                    'Image thumbnail size in media manager'],
+                ['media_img_title_pattern', 'string', 'Title ;; Date(%b %Y) ;; separator(, )',
+                    'Pattern to set image title when you insert it in a post'],
+                ['media_video_width', 'integer', 400,
+                    'Video width in media manager'],
+                ['media_video_height', 'integer', 300,
+                    'Video height in media manager'],
+                ['media_flash_fallback', 'boolean', true,
+                    'Flash player fallback for audio and video media'],
+                ['nb_post_for_home', 'integer', 20,
+                    'Number of entries on first home page'],
+                ['nb_post_per_page', 'integer', 20,
+                    'Number of entries on home pages and category pages'],
+                ['nb_post_per_feed', 'integer', 20,
+                    'Number of entries on feeds'],
+                ['nb_comment_per_feed', 'integer', 20,
+                    'Number of comments on feeds'],
+                ['post_url_format', 'string', '{y}/{m}/{d}/{t}',
+                    'Post URL format. {y}: year, {m}: month, {d}: day, {id}: post id, {t}: entry title'],
+                ['public_path', 'string', 'public',
+                    'Path to public directory, begins with a / for a full system path'],
+                ['public_url', 'string', '/public',
+                    'URL to public directory'],
+                ['robots_policy', 'string', 'INDEX,FOLLOW',
+                    'Search engines robots policy'],
+                ['short_feed_items', 'boolean', false,
+                    'Display short feed items'],
+                ['theme', 'string', 'berlin',
+                    'Blog theme'],
+                ['themes_path', 'string', 'themes',
+                    'Themes root path'],
+                ['themes_url', 'string', '/themes',
+                    'Themes root URL'],
+                ['time_format', 'string', '%H:%M',
+                    'Time format. See PHP strftime function for patterns'],
+                ['tpl_allow_php', 'boolean', false,
+                    'Allow PHP code in templates'],
+                ['tpl_use_cache', 'boolean', true,
+                    'Use template caching'],
+                ['trackbacks_pub', 'boolean', true,
+                    'Publish trackbacks immediately'],
+                ['trackbacks_ttl', 'integer', 0,
+                    'Number of days to keep trackbacks open (0 means no ttl)'],
+                ['url_scan', 'string', 'query_string',
+                    'URL handle mode (path_info or query_string)'],
+                ['use_smilies', 'boolean', false,
+                    'Show smilies on entries and comments'],
+                ['no_search', 'boolean', false,
+                    'Disable search'],
+                ['inc_subcats', 'boolean', false,
+                    'Include sub-categories in category page and category posts feed'],
+                ['wiki_comments', 'boolean', false,
+                    'Allow commenters to use a subset of wiki syntax'],
+                ['import_feed_url_control', 'boolean', true,
+                    'Control feed URL before import'],
+                ['import_feed_no_private_ip', 'boolean', true,
+                    'Prevent import feed from private IP'],
+                ['import_feed_ip_regexp', 'string', '',
+                    'Authorize import feed only from this IP regexp'],
+                ['import_feed_port_regexp', 'string', '/^(80|443)$/',
+                    'Authorize import feed only from this port regexp']
+            ];
         }
 
Index: inc/core/class.dc.error.php
===================================================================
--- inc/core/class.dc.error.php	(revision 3750)
+++ inc/core/class.dc.error.php	(revision 3874)
@@ -19,5 +19,5 @@
 {
     /** @var array Errors stack */
-    protected $errors = array();
+    protected $errors = [];
     /** @var boolean True if stack is not empty */
     protected $flag = false;
@@ -72,5 +72,5 @@
     {
         $this->flag   = false;
-        $this->errors = array();
+        $this->errors = [];
     }
 
Index: inc/core/class.dc.log.php
===================================================================
--- inc/core/class.dc.log.php	(revision 3731)
+++ inc/core/class.dc.log.php	(revision 3874)
@@ -41,5 +41,5 @@
     @return    <b>record</b>    A record with some more capabilities
      */
-    public function getLogs($params = array(), $count_only = false)
+    public function getLogs($params = [], $count_only = false)
     {
         if ($count_only) {
Index: inc/core/class.dc.media.php
===================================================================
--- inc/core/class.dc.media.php	(revision 3731)
+++ inc/core/class.dc.media.php	(revision 3874)
@@ -23,5 +23,5 @@
     protected $file_sort = 'name-asc';
 
-    protected $file_handler = array(); ///< <b>array</b> Array of callbacks
+    protected $file_handler = []; ///< <b>array</b> Array of callbacks
 
     public $thumb_tp       = '%s/.%s_%s.jpg'; ///< <b>string</b> Thumbnail file pattern
@@ -35,10 +35,10 @@
     - sq: square image
      */
-    public $thumb_sizes = array(
-        'm'  => array(448, 'ratio', 'medium'),
-        's'  => array(240, 'ratio', 'small'),
-        't'  => array(100, 'ratio', 'thumbnail'),
-        'sq' => array(48, 'crop', 'square')
-    );
+    public $thumb_sizes = [
+        'm'  => [448, 'ratio', 'medium'],
+        's'  => [240, 'ratio', 'small'],
+        't'  => [100, 'ratio', 'thumbnail'],
+        'sq' => [48, 'crop', 'square']
+    ];
 
     public $icon_img = 'images/media/%s.png'; ///< <b>string</b> Icon file pattern
@@ -91,25 +91,25 @@
 
         # Event handlers
-        $this->addFileHandler('image/jpeg', 'create', array($this, 'imageThumbCreate'));
-        $this->addFileHandler('image/png', 'create', array($this, 'imageThumbCreate'));
-        $this->addFileHandler('image/gif', 'create', array($this, 'imageThumbCreate'));
-
-        $this->addFileHandler('image/png', 'update', array($this, 'imageThumbUpdate'));
-        $this->addFileHandler('image/jpeg', 'update', array($this, 'imageThumbUpdate'));
-        $this->addFileHandler('image/gif', 'update', array($this, 'imageThumbUpdate'));
-
-        $this->addFileHandler('image/png', 'remove', array($this, 'imageThumbRemove'));
-        $this->addFileHandler('image/jpeg', 'remove', array($this, 'imageThumbRemove'));
-        $this->addFileHandler('image/gif', 'remove', array($this, 'imageThumbRemove'));
-
-        $this->addFileHandler('image/jpeg', 'create', array($this, 'imageMetaCreate'));
-
-        $this->addFileHandler('image/jpeg', 'recreate', array($this, 'imageThumbCreate'));
-        $this->addFileHandler('image/png', 'recreate', array($this, 'imageThumbCreate'));
-        $this->addFileHandler('image/gif', 'recreate', array($this, 'imageThumbCreate'));
-
-        $this->addFileHandler('image/jpeg', 'recreate', array($this, 'imageThumbCreate'));
-        $this->addFileHandler('image/png', 'recreate', array($this, 'imageThumbCreate'));
-        $this->addFileHandler('image/gif', 'recreate', array($this, 'imageThumbCreate'));
+        $this->addFileHandler('image/jpeg', 'create', [$this, 'imageThumbCreate']);
+        $this->addFileHandler('image/png', 'create', [$this, 'imageThumbCreate']);
+        $this->addFileHandler('image/gif', 'create', [$this, 'imageThumbCreate']);
+
+        $this->addFileHandler('image/png', 'update', [$this, 'imageThumbUpdate']);
+        $this->addFileHandler('image/jpeg', 'update', [$this, 'imageThumbUpdate']);
+        $this->addFileHandler('image/gif', 'update', [$this, 'imageThumbUpdate']);
+
+        $this->addFileHandler('image/png', 'remove', [$this, 'imageThumbRemove']);
+        $this->addFileHandler('image/jpeg', 'remove', [$this, 'imageThumbRemove']);
+        $this->addFileHandler('image/gif', 'remove', [$this, 'imageThumbRemove']);
+
+        $this->addFileHandler('image/jpeg', 'create', [$this, 'imageMetaCreate']);
+
+        $this->addFileHandler('image/jpeg', 'recreate', [$this, 'imageThumbCreate']);
+        $this->addFileHandler('image/png', 'recreate', [$this, 'imageThumbCreate']);
+        $this->addFileHandler('image/gif', 'recreate', [$this, 'imageThumbCreate']);
+
+        $this->addFileHandler('image/jpeg', 'recreate', [$this, 'imageThumbCreate']);
+        $this->addFileHandler('image/png', 'recreate', [$this, 'imageThumbCreate']);
+        $this->addFileHandler('image/gif', 'recreate', [$this, 'imageThumbCreate']);
 
         # Thumbnails sizes
@@ -158,11 +158,7 @@
     }
 
-    protected function callFileHandler($type, $event)
+    protected function callFileHandler($type, $event, ...$args)
     {
         if (!empty($this->file_handler[$type][$event])) {
-            $args = func_get_args();
-            array_shift($args);
-            array_shift($args);
-
             foreach ($this->file_handler[$type][$event] as $f) {
                 call_user_func_array($f, $args);
@@ -295,5 +291,5 @@
 
             # Thumbnails
-            $f->media_thumb = array();
+            $f->media_thumb = [];
             $p              = path::info($f->relname);
 
@@ -335,5 +331,5 @@
     public function setFileSort($type = 'name')
     {
-        if (in_array($type, array('name-asc', 'name-desc', 'date-asc', 'date-desc'))) {
+        if (in_array($type, ['name-asc', 'name-desc', 'date-asc', 'date-desc'])) {
             $this->file_sort = $type;
         }
@@ -406,5 +402,5 @@
         parent::getDir();
 
-        $f_res = array();
+        $f_res = [];
         $p_dir = $this->dir;
 
@@ -418,5 +414,5 @@
         }
 
-        $f_reg = array();
+        $f_reg = [];
 
         while ($rs->fetch()) {
@@ -471,5 +467,5 @@
         }
         try {
-            usort($this->dir['files'], array($this, 'sortFileHandler'));
+            usort($this->dir['files'], [$this, 'sortFileHandler']);
         } catch (Exception $e) {}
     }
@@ -536,6 +532,6 @@
         $rs = $this->con->select($strReq);
 
-        $this->dir = array('dirs' => array(), 'files' => array());
-        $f_res     = array();
+        $this->dir = ['dirs' => [], 'files' => []];
+        $f_res     = [];
         while ($rs->fetch()) {
             $fr = $this->fileRecord($rs);
@@ -547,5 +543,5 @@
 
         try {
-            usort($this->dir['files'], array($this, 'sortFileHandler'));
+            usort($this->dir['files'], [$this, 'sortFileHandler']);
         } catch (Exception $e) {}
 
@@ -564,8 +560,8 @@
     public function getPostMedia($post_id, $media_id = null, $link_type = null)
     {
-        $params = array(
+        $params = [
             'post_id'    => $post_id,
             'media_path' => $this->path
-        );
+        ];
         if ($media_id) {
             $params['media_id'] = (integer) $media_id;
@@ -576,5 +572,5 @@
         $rs = $this->postmedia->getPostMedia($params);
 
-        $res = array();
+        $res = [];
 
         while ($rs->fetch()) {
@@ -651,5 +647,5 @@
         $delReq = 'DELETE FROM ' . $this->table . ' ' .
             'WHERE media_id IN (%s) ';
-        $del_ids = array();
+        $del_ids = [];
 
         while ($rs->fetch()) {
@@ -1119,5 +1115,5 @@
 
             if (!is_array($args)) {
-                $args = array(
+                $args = [
                     'showvolume'      => 1,
                     'loadingcolor'    => 'ff9900',
@@ -1129,5 +1125,5 @@
                     'slidercolor2'    => '999999',
                     'sliderovercolor' => '0066cc'
-                );
+                ];
             }
 
@@ -1141,5 +1137,5 @@
             }
 
-            $vars = array();
+            $vars = [];
             foreach ($args as $k => $v) {
                 $vars[] = $k . '=' . $v;
@@ -1205,5 +1201,5 @@
 
             if (!is_array($args)) {
-                $args = array(
+                $args = [
                     'margin'          => 1,
                     'showvolume'      => 1,
@@ -1214,5 +1210,5 @@
                     'slidercolor2'    => '999999',
                     'sliderovercolor' => '0066cc'
-                );
+                ];
             }
 
@@ -1226,5 +1222,5 @@
             }
 
-            $vars = array();
+            $vars = [];
             foreach ($args as $k => $v) {
                 $vars[] = $k . '=' . $v;
@@ -1268,5 +1264,5 @@
 
         if (!is_array($args)) {
-            $args = array(
+            $args = [
                 'showvolume'      => 1,
                 'loadingcolor'    => 'ff9900',
@@ -1278,5 +1274,5 @@
                 'slidercolor2'    => '999999',
                 'sliderovercolor' => '0066cc'
-            );
+            ];
         }
 
@@ -1290,5 +1286,5 @@
         }
 
-        $vars = array();
+        $vars = [];
         foreach ($args as $k => $v) {
             $vars[] = $k . '=' . $v;
@@ -1325,5 +1321,5 @@
 
         if (!is_array($args)) {
-            $args = array(
+            $args = [
                 'margin'          => 1,
                 'showvolume'      => 1,
@@ -1334,5 +1330,5 @@
                 'slidercolor2'    => '999999',
                 'sliderovercolor' => '0066cc'
-            );
+            ];
         }
 
@@ -1346,5 +1342,5 @@
         }
 
-        $vars = array();
+        $vars = [];
         foreach ($args as $k => $v) {
             $vars[] = $k . '=' . $v;
Index: inc/core/class.dc.meta.php
===================================================================
--- inc/core/class.dc.meta.php	(revision 3733)
+++ inc/core/class.dc.meta.php	(revision 3874)
@@ -42,5 +42,5 @@
     public function splitMetaValues($str)
     {
-        $res = array();
+        $res = [];
         foreach (explode(',', $str) as $i => $tag) {
             $tag = trim($tag);
@@ -80,5 +80,5 @@
 
         if (!is_array($meta)) {
-            return array();
+            return [];
         }
 
@@ -118,9 +118,9 @@
     {
         $meta = $this->getMetaArray($str);
-        $data = array();
+        $data = [];
 
         if (isset($meta[$type])) {
             foreach ($meta[$type] as $v) {
-                $data[] = array(
+                $data[] = [
                     'meta_id'       => $v,
                     'meta_type'     => $type,
@@ -129,5 +129,5 @@
                     'percent'       => 0,
                     'roundpercent'  => 0
-                );
+                ];
             }
         }
@@ -191,5 +191,5 @@
         $rs = $this->con->select($strReq);
 
-        $meta = array();
+        $meta = [];
         while ($rs->fetch()) {
             $meta[$rs->meta_type][] = $rs->meta_id;
@@ -216,5 +216,5 @@
     @return    <b>record</b>    the resulting posts record
      */
-    public function getPostsByMeta($params = array(), $count_only = false)
+    public function getPostsByMeta($params = [], $count_only = false)
     {
         if (!isset($params['meta_id'])) {
@@ -248,5 +248,5 @@
     @return    <b>record</b>    the resulting comments record
      */
-    public function getCommentsByMeta($params = array(), $count_only = false)
+    public function getCommentsByMeta($params = [], $count_only = false)
     {
         if (!isset($params['meta_id'])) {
@@ -282,5 +282,5 @@
     public function getMeta($type = null, $limit = null, $meta_id = null, $post_id = null)
     {
-        $params = array();
+        $params = [];
 
         if ($type != null) {
@@ -320,5 +320,5 @@
     @return    <b>record</b>    the resulting comments record
      */
-    public function getMetadata($params = array(), $count_only = false)
+    public function getMetadata($params = [], $count_only = false)
     {
         if ($count_only) {
@@ -390,5 +390,5 @@
         $rs_static = $rs->toStatic();
 
-        $max = array();
+        $max = [];
         while ($rs_static->fetch()) {
             $type = $rs_static->meta_type;
@@ -513,5 +513,5 @@
         }
 
-        $to_update = $to_remove = array();
+        $to_update = $to_remove = [];
 
         $rs = $this->con->select(sprintf($getReq, $this->con->escape($meta_id),
@@ -587,8 +587,8 @@
 
         if ($rs->isEmpty()) {
-            return array();
-        }
-
-        $ids = array();
+            return [];
+        }
+
+        $ids = [];
         while ($rs->fetch()) {
             $ids[] = $rs->post_id;
Index: inc/core/class.dc.modules.php
===================================================================
--- inc/core/class.dc.modules.php	(revision 3731)
+++ inc/core/class.dc.modules.php	(revision 3874)
@@ -18,12 +18,12 @@
     protected $path;
     protected $ns;
-    protected $modules       = array();
-    protected $disabled      = array();
-    protected $errors        = array();
-    protected $modules_names = array();
-    protected $all_modules   = array();
+    protected $modules       = [];
+    protected $disabled      = [];
+    protected $errors        = [];
+    protected $modules_names = [];
+    protected $all_modules   = [];
     protected $disabled_mode = false;
-    protected $disabled_meta = array();
-    protected $to_disable    = array();
+    protected $disabled_meta = [];
+    protected $to_disable    = [];
 
     protected $id;
@@ -31,5 +31,5 @@
 
     # Inclusion variables
-    protected static $superglobals = array('GLOBALS', '_SERVER', '_GET', '_POST', '_COOKIE', '_FILES', '_ENV', '_REQUEST', '_SESSION');
+    protected static $superglobals = ['GLOBALS', '_SERVER', '_GET', '_POST', '_COOKIE', '_FILES', '_ENV', '_REQUEST', '_SESSION'];
     protected static $_k;
     protected static $_n;
@@ -60,11 +60,11 @@
     {
         $dc_version       = preg_replace('/\-dev$/', '', DC_VERSION);
-        $this->to_disable = array();
+        $this->to_disable = [];
         foreach ($this->all_modules as $k => &$m) {
             if (isset($m['requires'])) {
-                $missing = array();
+                $missing = [];
                 foreach ($m['requires'] as &$dep) {
                     if (!is_array($dep)) {
-                        $dep = array($dep);
+                        $dep = [$dep];
                     }
                     // grab missing dependencies
@@ -91,5 +91,5 @@
                     $m['cannot_enable'] = $missing;
                     if ($m['enabled']) {
-                        $this->to_disable[] = array('name' => $k, 'reason' => $missing);
+                        $this->to_disable[] = ['name' => $k, 'reason' => $missing];
                     }
                 }
@@ -119,5 +119,5 @@
             return false;
         }
-        $reason = array();
+        $reason = [];
         foreach ($this->to_disable as $module) {
             try {
@@ -132,5 +132,5 @@
                 join('', $reason)
             );
-            dcPage::addWarningNotice($message, array('divtag' => true, 'with_ts' => false));
+            dcPage::addWarningNotice($message, ['divtag' => true, 'with_ts' => false]);
             $url = $redir_url . (strpos($redir_url, "?") ? '&' : '?') . 'dep=1';
             http::redirect($url);
@@ -161,5 +161,5 @@
         $disabled = $disabled && !get_parent_class($this) ? true : false;
 
-        $ignored = array();
+        $ignored = [];
 
         foreach ($this->path as $root) {
@@ -211,5 +211,5 @@
         $this->checkDependencies();
         # Sort plugins
-        uasort($this->modules, array($this, 'sortModules'));
+        uasort($this->modules, [$this, 'sortModules']);
 
         foreach ($this->modules as $id => $m) {
@@ -229,5 +229,5 @@
             if ($ns == 'admin') {
                 $this->loadModuleL10Nresources($id, $lang);
-                $this->core->adminurl->register('admin.plugin.' . $id, 'plugin.php', array('p' => $id));
+                $this->core->adminurl->register('admin.plugin.' . $id, 'plugin.php', ['p' => $id]);
             }
         }
@@ -275,10 +275,10 @@
     (currently available keys : permissions, priority, type)
      */
-    public function registerModule($name, $desc, $author, $version, $properties = array())
+    public function registerModule($name, $desc, $author, $version, $properties = [])
     {
         if ($this->disabled_mode) {
             $this->disabled_meta = array_merge(
                 $properties,
-                array(
+                [
                     'root'          => $this->mroot,
                     'name'          => $name,
@@ -288,5 +288,5 @@
                     'enabled'       => false,
                     'root_writable' => is_writable($this->mroot)
-                )
+                ]
             );
             return;
@@ -295,5 +295,5 @@
         if (!is_array($properties)) {
             $args       = func_get_args();
-            $properties = array();
+            $properties = [];
             if (isset($args[4])) {
                 $properties['permissions'] = $args[4];
@@ -306,5 +306,5 @@
         # Default module properties
         $properties = array_merge(
-            array(
+            [
                 'permissions'       => null,
                 'priority'          => 1000,
@@ -312,7 +312,7 @@
                 'type'              => null,
                 'enabled'           => true,
-                'requires'          => array(),
-                'settings'          => array()
-            ), $properties
+                'requires'          => [],
+                'settings'          => []
+            ], $properties
         );
 
@@ -346,5 +346,5 @@
                 $this->modules[$this->id]   = array_merge(
                     $properties,
-                    array(
+                    [
                         'root'          => $this->mroot,
                         'name'          => $name,
@@ -353,5 +353,5 @@
                         'version'       => $version,
                         'root_writable' => is_writable($this->mroot)
-                    )
+                    ]
                 );
             } else {
@@ -370,7 +370,7 @@
     public function resetModulesList()
     {
-        $this->modules       = array();
-        $this->modules_names = array();
-        $this->errors        = array();
+        $this->modules       = [];
+        $this->modules_names = [];
+        $this->errors        = [];
     }
 
@@ -476,5 +476,5 @@
     public function installModules()
     {
-        $res = array('success' => array(), 'failure' => array());
+        $res = ['success' => [], 'failure' => []];
         foreach ($this->modules as $id => &$m) {
             $i = $this->installModule($id, $msg);
Index: inc/core/class.dc.namespace.php
===================================================================
--- inc/core/class.dc.namespace.php	(revision 3773)
+++ inc/core/class.dc.namespace.php	(revision 3874)
@@ -18,8 +18,8 @@
     protected $blog_id; ///< <b>string</b> Blog ID
 
-    protected $global_settings = array(); ///< <b>array</b> Global settings array
-    protected $local_settings  = array(); ///< <b>array</b> Local settings array
-    protected $settings        = array(); ///< <b>array</b> Associative settings array
-    protected $ns;                        ///< <b>string</b> Current namespace
+    protected $global_settings = []; ///< <b>array</b> Global settings array
+    protected $local_settings  = []; ///< <b>array</b> Local settings array
+    protected $settings        = []; ///< <b>array</b> Associative settings array
+    protected $ns;                   ///< <b>string</b> Current namespace
 
     /**
@@ -83,5 +83,5 @@
             $array = $rs->blog_id ? 'local' : 'global';
 
-            $this->{$array . '_settings'}[$id] = array(
+            $this->{$array . '_settings'}[$id] = [
                 'ns'     => $this->ns,
                 'value'  => $value,
@@ -89,5 +89,5 @@
                 'label'  => (string) $rs->f('setting_label'),
                 'global' => $rs->blog_id == ''
-            );
+            ];
         }
 
@@ -375,5 +375,5 @@
         $array = $global ? 'global' : 'local';
         unset($this->{$array . '_settings'});
-        $this->{$array . '_settings'} = array();
+        $this->{$array . '_settings'} = [];
 
         $array          = $global ? 'local' : 'global';
Index: inc/core/class.dc.plugins.php
===================================================================
--- inc/core/class.dc.plugins.php	(revision 3731)
+++ inc/core/class.dc.plugins.php	(revision 3874)
@@ -39,10 +39,10 @@
     @param    properties    <b>array</b>        extra properties (currently available keys : permissions, priority, standalone_config, type)
      */
-    public function registerModule($name, $desc, $author, $version, $properties = array())
+    public function registerModule($name, $desc, $author, $version, $properties = [])
     {
         # Fallback to legacy registerModule parameters
         if (!is_array($properties)) {
             $args       = func_get_args();
-            $properties = array();
+            $properties = [];
             if (isset($args[4])) {
                 $properties['permissions'] = $args[4];
Index: inc/core/class.dc.postmedia.php
===================================================================
--- inc/core/class.dc.postmedia.php	(revision 3731)
+++ inc/core/class.dc.postmedia.php	(revision 3874)
@@ -37,5 +37,5 @@
     @return    <b>array</b> Array of fileItems
      */
-    public function getPostMedia($params = array())
+    public function getPostMedia($params = [])
     {
         $strReq =
@@ -55,5 +55,5 @@
         }
 
-        $where = array();
+        $where = [];
         if (isset($params['post_id'])) {
             $where[] = "PM.post_id " . $this->con->in($params['post_id']);
@@ -94,5 +94,5 @@
         $media_id = (integer) $media_id;
 
-        $f = $this->getPostMedia(array('post_id' => $post_id, 'media_id' => $media_id, 'link_type' => $link_type));
+        $f = $this->getPostMedia(['post_id' => $post_id, 'media_id' => $media_id, 'link_type' => $link_type]);
 
         if (!$f->isEmpty()) {
@@ -157,5 +157,5 @@
         $rs = $this->con->select($strReq);
 
-        $res = array();
+        $res = [];
 
         while ($rs->fetch()) {
Index: inc/core/class.dc.prefs.php
===================================================================
--- inc/core/class.dc.prefs.php	(revision 3731)
+++ inc/core/class.dc.prefs.php	(revision 3874)
@@ -22,5 +22,5 @@
     protected $user_id; ///< <b>string</b> User ID
 
-    protected $workspaces = array(); ///< <b>array</b> Associative workspaces array
+    protected $workspaces = []; ///< <b>array</b> Associative workspaces array
 
     protected $ws; ///< <b>string</b> Current workspace
Index: inc/core/class.dc.rs.extensions.php
===================================================================
--- inc/core/class.dc.rs.extensions.php	(revision 3731)
+++ inc/core/class.dc.rs.extensions.php	(revision 3874)
@@ -348,5 +348,5 @@
     {
         if ($encoded) {
-            return strtr($rs->user_email, array('@' => '%40', '.' => '%2e'));
+            return strtr($rs->user_email, ['@' => '%40', '.' => '%2e']);
         }
         return $rs->user_email;
@@ -577,5 +577,5 @@
 
         if ($rs->core->blog->settings->system->comments_nofollow) {
-            $res = preg_replace_callback('#<a(.*?href=".*?".*?)>#ms', array('self', 'noFollowURL'), $res);
+            $res = preg_replace_callback('#<a(.*?href=".*?".*?)>#ms', ['self', 'noFollowURL'], $res);
         }
 
@@ -655,5 +655,5 @@
     {
         if ($encoded) {
-            return strtr($rs->comment_email, array('@' => '%40', '.' => '%2e'));
+            return strtr($rs->comment_email, ['@' => '%40', '.' => '%2e']);
         }
         return $rs->comment_email;
@@ -864,5 +864,5 @@
             return $options;
         }
-        return array();
+        return [];
     }
 
@@ -920,5 +920,5 @@
         $this->sortsign  = strtolower($order) == 'asc' ? 1 : -1;
 
-        usort($this->__data, array($this, 'lexicalSortCallback'));
+        usort($this->__data, [$this, 'lexicalSortCallback']);
 
         $this->sortfield = null;
Index: inc/core/class.dc.settings.php
===================================================================
--- inc/core/class.dc.settings.php	(revision 3731)
+++ inc/core/class.dc.settings.php	(revision 3874)
@@ -23,5 +23,5 @@
     protected $blog_id; ///< <b>string</b> Blog ID
 
-    protected $namespaces = array(); ///< <b>array</b> Associative namespaces array
+    protected $namespaces = []; ///< <b>array</b> Associative namespaces array
 
     protected $ns; ///< <b>string</b> Current namespace
@@ -222,5 +222,5 @@
             $this->namespaces[$this->ns]->$n['value'] = $v;
         } else {
-            $this->namespaces[$this->ns]->$n = array(
+            $this->namespaces[$this->ns]->$n = [
                 'ns'     => $this->ns,
                 'value'  => $v,
@@ -228,5 +228,5 @@
                 'label'  => '',
                 'global' => false
-            );
+            ];
         }
     }
@@ -321,5 +321,5 @@
         $this->raiseDeprecated('dumpSettings');
 
-        $settings = array();
+        $settings = [];
         // Parse all the namespaces
         foreach (array_keys($this->namespaces) as $id => $ns) {
@@ -343,5 +343,5 @@
         $this->raiseDeprecated('dumpGlobalSettings');
 
-        $settings = array();
+        $settings = [];
         // Parse all the namespaces
         foreach (array_keys($this->namespaces) as $id => $ns) {
@@ -363,8 +363,8 @@
     @return    <b>record</b>    A record
      */
-    public function getGlobalSettings($params = array())
+    public function getGlobalSettings($params = [])
     {
         $strReq = "SELECT * from " . $this->table . " ";
-        $where  = array();
+        $where  = [];
         if (!empty($params['ns'])) {
             $where[] = "setting_ns = '" . $this->con->escape($params['ns']) . "'";
Index: inc/core/class.dc.sql.statement.php
===================================================================
--- inc/core/class.dc.sql.statement.php	(revision 3754)
+++ inc/core/class.dc.sql.statement.php	(revision 3874)
@@ -45,5 +45,5 @@
         $this->cond    =
         $this->sql     =
-        array();
+        [];
     }
 
@@ -106,5 +106,5 @@
     {
         if ($reset) {
-            $this->columns = array();
+            $this->columns = [];
         }
         if (is_array($c)) {
@@ -140,5 +140,5 @@
     {
         if ($reset) {
-            $this->from = array();
+            $this->from = [];
         }
         // Remove comma on beginning of clause(s) (legacy code)
@@ -167,5 +167,5 @@
     {
         if ($reset) {
-            $this->where = array();
+            $this->where = [];
         }
         if (is_array($c)) {
@@ -188,5 +188,5 @@
     {
         if ($reset) {
-            $this->cond = array();
+            $this->cond = [];
         }
         if (is_array($c)) {
@@ -209,5 +209,5 @@
     {
         if ($reset) {
-            $this->sql = array();
+            $this->sql = [];
         }
         if (is_array($c)) {
@@ -289,5 +289,5 @@
         } else {
             $clause = "LIKE '" .
-            $this->escape(preg_replace(array('%', '_', '!'), array('!%', '!_', '!!'), $value)) .
+            $this->escape(preg_replace(['%', '_', '!'], ['!%', '!_', '!!'], $value)) .
                 "%' ESCAPE '!'";
         }
@@ -313,10 +313,10 @@
         $filter = function ($s) {
             $s        = strtoupper($s);
-            $patterns = array(
+            $patterns = [
                 '\s+' => ' ', // Multiple spaces/tabs -> one space
                 ' \)' => ')', // <space>) -> )
                 ' ,'  => ',', // <space>, -> ,
                 '\( ' => '(' // (<space> -> (
-            );
+            ];
             foreach ($patterns as $pattern => $replace) {
                 $s = preg_replace('!' . $pattern . '!', $replace, $s);
@@ -353,5 +353,5 @@
         $this->order  =
         $this->group  =
-        array();
+        [];
 
         $this->limit    = null;
@@ -373,5 +373,5 @@
     {
         if ($reset) {
-            $this->join = array();
+            $this->join = [];
         }
         if (is_array($c)) {
@@ -394,5 +394,5 @@
     {
         if ($reset) {
-            $this->having = array();
+            $this->having = [];
         }
         if (is_array($c)) {
@@ -415,5 +415,5 @@
     {
         if ($reset) {
-            $this->order = array();
+            $this->order = [];
         }
         if (is_array($c)) {
@@ -436,5 +436,5 @@
     {
         if ($reset) {
-            $this->group = array();
+            $this->group = [];
         }
         if (is_array($c)) {
@@ -653,5 +653,5 @@
     public function __construct(&$core, $ctx = null)
     {
-        $this->set = array();
+        $this->set = [];
 
         parent::__construct($core, $ctx);
@@ -695,5 +695,5 @@
     {
         if ($reset) {
-            $this->set = array();
+            $this->set = [];
         }
         if (is_array($c)) {
@@ -825,5 +825,5 @@
     public function __construct(&$core, $ctx = null)
     {
-        $this->lines = array();
+        $this->lines = [];
 
         parent::__construct($core, $ctx);
@@ -854,5 +854,5 @@
     {
         if ($reset) {
-            $this->lines = array();
+            $this->lines = [];
         }
         if (is_array($c)) {
@@ -907,5 +907,5 @@
         $query .= 'VALUES ';
         if (count($this->lines)) {
-            $raws = array();
+            $raws = [];
             foreach ($this->lines as $line) {
                 $raws[] = '(' . join(', ', $line) . ')';
Index: inc/core/class.dc.store.parser.php
===================================================================
--- inc/core/class.dc.store.parser.php	(revision 3731)
+++ inc/core/class.dc.store.parser.php	(revision 3874)
@@ -37,5 +37,5 @@
 
         $this->xml   = simplexml_load_string($data);
-        $this->items = array();
+        $this->items = [];
 
         if ($this->xml === false) {
@@ -61,5 +61,5 @@
             $attrs = $i->attributes();
 
-            $item = array();
+            $item = [];
 
             # DC/DA shared markers
@@ -79,5 +79,5 @@
             $item['sshot']   = (string) $i->children(self::$bloc)->sshot;
 
-            $tags = array();
+            $tags = [];
             foreach ($i->children(self::$bloc)->tags as $t) {
                 $tags[] = (string) $t->tag;
Index: inc/core/class.dc.store.php
===================================================================
--- inc/core/class.dc.store.php	(revision 3731)
+++ inc/core/class.dc.store.php	(revision 3874)
@@ -24,5 +24,5 @@
 
     /** @var    array    Modules fields to search on and their weighting */
-    public static $weighting = array('id' => 10, 'name' => 8, 'author' => 6, 'tags' => 4, 'desc' => 2);
+    public static $weighting = ['id' => 10, 'name' => 8, 'author' => 6, 'tags' => 4, 'desc' => 2];
 
     /** @var    string    User agent used to query repository */
@@ -38,6 +38,7 @@
      * @param    object    $modules        dcModules instance
      * @param    string    $xml_url        XML feed URL
-     */
-    public function __construct(dcModules $modules, $xml_url)
+     * @param    boolean   $force          Force query repository
+     */
+    public function __construct(dcModules $modules, $xml_url, $force = false)
     {
         $this->core       = $modules->core;
@@ -46,5 +47,5 @@
         $this->user_agent = sprintf('Dotclear/%s)', DC_VERSION);
 
-        $this->check();
+        $this->check($force);
     }
 
@@ -66,5 +67,5 @@
         $raw_datas = $parser->getModules();
 
-        uasort($raw_datas, array('self', 'sort'));
+        uasort($raw_datas, ['self', 'sort']);
 
         $skipped = array_keys($this->modules->getDisabledModules());
@@ -75,5 +76,5 @@
         }
 
-        $updates = array();
+        $updates = [];
         $current = $this->modules->getModules();
         foreach ($current as $p_id => $p_infos) {
@@ -89,8 +90,8 @@
         }
 
-        $this->data = array(
+        $this->data = [
             'new'    => $raw_datas,
             'update' => $updates
-        );
+        ];
 
         return true;
@@ -124,5 +125,5 @@
     public function search($pattern)
     {
-        $result = array();
+        $result = [];
 
         # Split query into small clean words
@@ -244,5 +245,5 @@
     public static function patternize($str)
     {
-        $arr = array();
+        $arr = [];
 
         foreach (explode(' ', $str) as $_) {
Index: inc/core/class.dc.store.reader.php
===================================================================
--- inc/core/class.dc.store.reader.php	(revision 3731)
+++ inc/core/class.dc.store.reader.php	(revision 3874)
@@ -54,5 +54,5 @@
     public function parse($url)
     {
-        $this->validators = array();
+        $this->validators = [];
 
         if ($this->cache_dir) {
Index: inc/core/class.dc.themes.php
===================================================================
--- inc/core/class.dc.themes.php	(revision 3731)
+++ inc/core/class.dc.themes.php	(revision 3874)
@@ -38,10 +38,10 @@
     (currently available keys : parent, priority, standalone_config, type, tplset)
      */
-    public function registerModule($name, $desc, $author, $version, $properties = array())
+    public function registerModule($name, $desc, $author, $version, $properties = [])
     {
         # Fallback to legacy registerModule parameters
         if (!is_array($properties)) {
             $args       = func_get_args();
-            $properties = array();
+            $properties = [];
             if (isset($args[4])) {
                 $properties['parent'] = $args[4];
@@ -53,7 +53,7 @@
         # Themes specifics properties
         $properties = array_merge(
-            array('parent' => null, 'tplset' => DC_DEFAULT_TPLSET),
+            ['parent' => null, 'tplset' => DC_DEFAULT_TPLSET],
             $properties,
-            array('permissions' => 'admin') // force themes perms
+            ['permissions' => 'admin'] // force themes perms
         );
 
Index: inc/core/class.dc.trackback.php
===================================================================
--- inc/core/class.dc.trackback.php	(revision 3731)
+++ inc/core/class.dc.trackback.php	(revision 3874)
@@ -80,8 +80,8 @@
         # Maybe a webmention
         if (count($ping_parts) == 3) {
-            $payload = http_build_query(array(
+            $payload = http_build_query([
                 'source' => $post_url,
                 'target' => $ping_parts[1]
-            ));
+            ]);
 
             try {
@@ -97,5 +97,5 @@
             }
 
-            if (!in_array($status, array('200', '201', '202'))) {
+            if (!in_array($status, ['200', '201', '202'])) {
                 $ping_error = $http->getStatus();
                 $ping_msg   = __('Bad server response code');
@@ -104,5 +104,5 @@
         # No, let's walk by the trackback way
         elseif (count($ping_parts) < 2) {
-            $data = array(
+            $data = [
                 'title'     => $post_title,
                 'excerpt'   => $post_excerpt,
@@ -110,5 +110,5 @@
                 'blog_name' => trim(html::escapeHTML(html::clean($this->core->blog->name)))
                 //,'__debug' => false
-            );
+            ];
 
             # Ping
@@ -206,5 +206,5 @@
 
         if (!$err) {
-            $post = $this->core->blog->getPosts(array('post_id' => $post_id, 'post_type' => ''));
+            $post = $this->core->blog->getPosts(['post_id' => $post_id, 'post_type' => '']);
 
             if ($post->isEmpty()) {
@@ -430,9 +430,9 @@
     private function pingAlreadyDone($post_id, $from_url)
     {
-        $params = array(
+        $params = [
             'post_id'           => $post_id,
             'comment_site'      => $from_url,
             'comment_trackback' => 1
-        );
+        ];
 
         $rs = $this->core->blog->getComments($params, true);
@@ -570,8 +570,8 @@
 
         # Time to see if we've got a winner...
-        $params = array(
+        $params = [
             'post_type' => $p_type,
             'post_url'  => $post_url
-        );
+        ];
         $posts = $this->core->blog->getPosts($params);
 
@@ -605,5 +605,5 @@
 
         # Bad luck. Bye, bye...
-        if (!in_array($c_type[0], array('text/html', 'application/xhtml+xml'))) {
+        if (!in_array($c_type[0], ['text/html', 'application/xhtml+xml'])) {
             throw new Exception(__('Your source URL does not look like a supported content type. Sorry. Bye, bye!'), 0);
         }
@@ -638,5 +638,5 @@
     public function discover($text)
     {
-        $res = array();
+        $res = [];
 
         foreach ($this->getTextLinks($text) as $link) {
@@ -657,5 +657,5 @@
     private function getTextLinks($text)
     {
-        $res = array();
+        $res = [];
 
         # href attribute on "a" tags
@@ -743,5 +743,5 @@
         if ($wm_url) {
             $type = explode(';', $http->getHeader('content-type'));
-            if (!in_array($type[0], array('text/html', 'application/xhtml+xml'))) {
+            if (!in_array($type[0], ['text/html', 'application/xhtml+xml'])) {
                 $wm_url = false;
             }
Index: inc/core/class.dc.update.php
===================================================================
--- inc/core/class.dc.update.php	(revision 3795)
+++ inc/core/class.dc.update.php	(revision 3874)
@@ -21,5 +21,5 @@
     protected $cache_file;
 
-    protected $version_info = array(
+    protected $version_info = [
         'version'  => null,
         'href'     => null,
@@ -28,8 +28,8 @@
         'php'      => '5.6',
         'notify'   => true
-    );
+    ];
 
     protected $cache_ttl    = '-6 hours';
-    protected $forced_files = array();
+    protected $forced_files = [];
 
     /**
@@ -172,7 +172,7 @@
     }
 
-    public function setForcedFiles()
-    {
-        $this->forced_files = func_get_args();
+    public function setForcedFiles(...$args)
+    {
+        $this->forced_files = $args;
     }
 
@@ -314,5 +314,5 @@
         unset($opts, $cur_digests, $new_digests, $zip);
 
-        $not_readable = array();
+        $not_readable = [];
 
         if (!empty($this->forced_files)) {
@@ -376,6 +376,6 @@
         }
 
-        $zip_files    = array();
-        $not_writable = array();
+        $zip_files    = [];
+        $not_writable = [];
 
         foreach ($new_files as $file) {
@@ -424,8 +424,8 @@
         $new_md5 = $new_path = $new_digests;
 
-        array_walk($cur_md5, array($this, 'parseLine'), 1);
-        array_walk($cur_path, array($this, 'parseLine'), 2);
-        array_walk($new_md5, array($this, 'parseLine'), 1);
-        array_walk($new_path, array($this, 'parseLine'), 2);
+        array_walk($cur_md5, [$this, 'parseLine'], 1);
+        array_walk($cur_path, [$this, 'parseLine'], 2);
+        array_walk($new_md5, [$this, 'parseLine'], 1);
+        array_walk($new_path, [$this, 'parseLine'], 2);
 
         $cur = array_combine($cur_md5, $cur_path);
@@ -464,5 +464,5 @@
         $contents = file($digests_file, $opts);
 
-        $changes = array();
+        $changes = [];
 
         foreach ($contents as $digest) {
Index: inc/core/class.dc.utils.php
===================================================================
--- inc/core/class.dc.utils.php	(revision 3731)
+++ inc/core/class.dc.utils.php	(revision 3874)
@@ -52,8 +52,8 @@
     public static function cleanIds($ids)
     {
-        $clean_ids = array();
+        $clean_ids = [];
 
         if (!is_array($ids)) {
-            $ids = array($ids);
+            $ids = [$ids];
         }
 
@@ -132,5 +132,5 @@
     public static function jsVar($n, $v)
     {
-        return dcUtils::jsVars(array($n => $v));
+        return dcUtils::jsVars([$n => $v]);
     }
 
@@ -147,5 +147,5 @@
             dcUtils::setLexicalLang($ns, $lang);
         }
-        return usort($arr, array('dcUtils', 'lexicalSortHelper'));
+        return usort($arr, ['dcUtils', 'lexicalSortHelper']);
     }
 
@@ -162,5 +162,5 @@
             dcUtils::setLexicalLang($ns, $lang);
         }
-        return uasort($arr, array('dcUtils', 'lexicalSortHelper'));
+        return uasort($arr, ['dcUtils', 'lexicalSortHelper']);
     }
 
@@ -177,5 +177,5 @@
             dcUtils::setLexicalLang($ns, $lang);
         }
-        return uksort($arr, array('dcUtils', 'lexicalSortHelper'));
+        return uksort($arr, ['dcUtils', 'lexicalSortHelper']);
     }
 
@@ -210,366 +210,366 @@
     // removeDiacritics function (see https://github.com/infralabs/DiacriticsRemovePHP)
 
-    protected static $defaultDiacriticsRemovalMap = array(
-        array(
+    protected static $defaultDiacriticsRemovalMap = [
+        [
             'base'    => "A",
             'letters' => '/(&#65;|&#9398;|&#65313;|&#192;|&#193;|&#194;|&#7846;|&#7844;|&#7850;|&#7848;|&#195;|&#256;|&#258;|&#7856;|&#7854;|&#7860;|&#7858;|&#550;|&#480;|&#196;|&#478;|&#7842;|&#197;|&#506;|&#461;|&#512;|&#514;|&#7840;|&#7852;|&#7862;|&#7680;|&#260;|&#570;|&#11375;|[\x{0041}\x{24B6}\x{FF21}\x{00C0}\x{00C1}\x{00C2}\x{1EA6}\x{1EA4}\x{1EAA}\x{1EA8}\x{00C3}\x{0100}\x{0102}\x{1EB0}\x{1EAE}\x{1EB4}\x{1EB2}\x{0226}\x{01E0}\x{00C4}\x{01DE}\x{1EA2}\x{00C5}\x{01FA}\x{01CD}\x{0200}\x{0202}\x{1EA0}\x{1EAC}\x{1EB6}\x{1E00}\x{0104}\x{023A}\x{2C6F}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "AA",
             'letters' => '/(&#42802;|[\x{A732}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "AE",
             'letters' => '/(&#198;|&#508;|&#482;|[\x{00C6}\x{01FC}\x{01E2}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "AO",
             'letters' => '/(&#42804;|[\x{A734}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "AU",
             'letters' => '/(&#42806;|[\x{A736}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "AV",
             'letters' => '/(&#42808;|&#42810;|[\x{A738}\x{A73A}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "AY",
             'letters' => '/(&#42812;|[\x{A73C}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "B",
             'letters' => '/(&#66;|&#9399;|&#65314;|&#7682;|&#7684;|&#7686;|&#579;|&#386;|&#385;|[\x{0042}\x{24B7}\x{FF22}\x{1E02}\x{1E04}\x{1E06}\x{0243}\x{0182}\x{0181}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "C",
             'letters' => '/(&#67;|&#9400;|&#65315;|&#262;|&#264;|&#266;|&#268;|&#199;|&#7688;|&#391;|&#571;|&#42814;|[\x{0043}\x{24B8}\x{FF23}\x{0106}\x{0108}\x{010A}\x{010C}\x{00C7}\x{1E08}\x{0187}\x{023B}\x{A73E}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "D",
             'letters' => '/(&#68;|&#9401;|&#65316;|&#7690;|&#270;|&#7692;|&#7696;|&#7698;|&#7694;|&#272;|&#395;|&#394;|&#393;|&#42873;|&#208;|[\x{0044}\x{24B9}\x{FF24}\x{1E0A}\x{010E}\x{1E0C}\x{1E10}\x{1E12}\x{1E0E}\x{0110}\x{018B}\x{018A}\x{0189}\x{A779}\x{00D0}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "DZ",
             'letters' => '/(&#497;|&#452;|[\x{01F1}\x{01C4}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "Dz",
             'letters' => '/(&#498;|&#453;|[\x{01F2}\x{01C5}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "E",
             'letters' => '/(&#69;|&#9402;|&#65317;|&#200;|&#201;|&#202;|&#7872;|&#7870;|&#7876;|&#7874;|&#7868;|&#274;|&#7700;|&#7702;|&#276;|&#278;|&#203;|&#7866;|&#282;|&#516;|&#518;|&#7864;|&#7878;|&#552;|&#7708;|&#280;|&#7704;|&#7706;|&#400;|&#398;|[\x{0045}\x{24BA}\x{FF25}\x{00C8}\x{00C9}\x{00CA}\x{1EC0}\x{1EBE}\x{1EC4}\x{1EC2}\x{1EBC}\x{0112}\x{1E14}\x{1E16}\x{0114}\x{0116}\x{00CB}\x{1EBA}\x{011A}\x{0204}\x{0206}\x{1EB8}\x{1EC6}\x{0228}\x{1E1C}\x{0118}\x{1E18}\x{1E1A}\x{0190}\x{018E}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "F",
             'letters' => '/(&#70;|&#9403;|&#65318;|&#7710;|&#401;|&#42875;|[\x{0046}\x{24BB}\x{FF26}\x{1E1E}\x{0191}\x{A77B}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "G",
             'letters' => '/(&#71;|&#9404;|&#65319;|&#500;|&#284;|&#7712;|&#286;|&#288;|&#486;|&#290;|&#484;|&#403;|&#42912;|&#42877;|&#42878;|[\x{0047}\x{24BC}\x{FF27}\x{01F4}\x{011C}\x{1E20}\x{011E}\x{0120}\x{01E6}\x{0122}\x{01E4}\x{0193}\x{A7A0}\x{A77D}\x{A77E}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "H",
             'letters' => '/(&#72;|&#9405;|&#65320;|&#292;|&#7714;|&#7718;|&#542;|&#7716;|&#7720;|&#7722;|&#294;|&#11367;|&#11381;|&#42893;|[\x{0048}\x{24BD}\x{FF28}\x{0124}\x{1E22}\x{1E26}\x{021E}\x{1E24}\x{1E28}\x{1E2A}\x{0126}\x{2C67}\x{2C75}\x{A78D}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "I",
             'letters' => '/(&#73;|&#9406;|&#65321;|&#204;|&#205;|&#206;|&#296;|&#298;|&#300;|&#304;|&#207;|&#7726;|&#7880;|&#463;|&#520;|&#522;|&#7882;|&#302;|&#7724;|&#407;|[\x{0049}\x{24BE}\x{FF29}\x{00CC}\x{00CD}\x{00CE}\x{0128}\x{012A}\x{012C}\x{0130}\x{00CF}\x{1E2E}\x{1EC8}\x{01CF}\x{0208}\x{020A}\x{1ECA}\x{012E}\x{1E2C}\x{0197}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "J",
             'letters' => '/(&#74;|&#9407;|&#65322;|&#308;|&#584;|[\x{004A}\x{24BF}\x{FF2A}\x{0134}\x{0248}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "K",
             'letters' => '/(&#75;|&#9408;|&#65323;|&#7728;|&#488;|&#7730;|&#310;|&#7732;|&#408;|&#11369;|&#42816;|&#42818;|&#42820;|&#42914;|[\x{004B}\x{24C0}\x{FF2B}\x{1E30}\x{01E8}\x{1E32}\x{0136}\x{1E34}\x{0198}\x{2C69}\x{A740}\x{A742}\x{A744}\x{A7A2}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "L",
             'letters' => '/(&#76;|&#9409;|&#65324;|&#319;|&#313;|&#317;|&#7734;|&#7736;|&#315;|&#7740;|&#7738;|&#321;|&#573;|&#11362;|&#11360;|&#42824;|&#42822;|&#42880;|[\x{004C}\x{24C1}\x{FF2C}\x{013F}\x{0139}\x{013D}\x{1E36}\x{1E38}\x{013B}\x{1E3C}\x{1E3A}\x{0141}\x{023D}\x{2C62}\x{2C60}\x{A748}\x{A746}\x{A780}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "LJ",
             'letters' => '/(&#455;|[\x{01C7}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "Lj",
             'letters' => '/(&#456;|[\x{01C8}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "M",
             'letters' => '/(&#77;|&#9410;|&#65325;|&#7742;|&#7744;|&#7746;|&#11374;|&#412;|[\x{004D}\x{24C2}\x{FF2D}\x{1E3E}\x{1E40}\x{1E42}\x{2C6E}\x{019C}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "N",
             'letters' => '/(&#78;|&#9411;|&#65326;|&#504;|&#323;|&#209;|&#7748;|&#327;|&#7750;|&#325;|&#7754;|&#7752;|&#544;|&#413;|&#42896;|&#42916;|&#330;|[\x{004E}\x{24C3}\x{FF2E}\x{01F8}\x{0143}\x{00D1}\x{1E44}\x{0147}\x{1E46}\x{0145}\x{1E4A}\x{1E48}\x{0220}\x{019D}\x{A790}\x{A7A4}\x{014A}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "NJ",
             'letters' => '/(&#458;|[\x{01CA}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "Nj",
             'letters' => '/(&#459;|[\x{01CB}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "O",
             'letters' => '/(&#79;|&#9412;|&#65327;|&#210;|&#211;|&#212;|&#7890;|&#7888;|&#7894;|&#7892;|&#213;|&#7756;|&#556;|&#7758;|&#332;|&#7760;|&#7762;|&#334;|&#558;|&#560;|&#214;|&#554;|&#7886;|&#336;|&#465;|&#524;|&#526;|&#416;|&#7900;|&#7898;|&#7904;|&#7902;|&#7906;|&#7884;|&#7896;|&#490;|&#492;|&#216;|&#510;|&#390;|&#415;|&#42826;|&#42828;|[\x{004F}\x{24C4}\x{FF2F}\x{00D2}\x{00D3}\x{00D4}\x{1ED2}\x{1ED0}\x{1ED6}\x{1ED4}\x{00D5}\x{1E4C}\x{022C}\x{1E4E}\x{014C}\x{1E50}\x{1E52}\x{014E}\x{022E}\x{0230}\x{00D6}\x{022A}\x{1ECE}\x{0150}\x{01D1}\x{020C}\x{020E}\x{01A0}\x{1EDC}\x{1EDA}\x{1EE0}\x{1EDE}\x{1EE2}\x{1ECC}\x{1ED8}\x{01EA}\x{01EC}\x{00D8}\x{01FE}\x{0186}\x{019F}\x{A74A}\x{A74C}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "OE",
             'letters' => '/(&#338;|[\x{0152}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "OI",
             'letters' => '/(&#418;|[\x{01A2}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "OO",
             'letters' => '/(&#42830;|[\x{A74E}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "OU",
             'letters' => '/(&#546;|[\x{0222}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "P",
             'letters' => '/(&#80;|&#9413;|&#65328;|&#7764;|&#7766;|&#420;|&#11363;|&#42832;|&#42834;|&#42836;|[\x{0050}\x{24C5}\x{FF30}\x{1E54}\x{1E56}\x{01A4}\x{2C63}\x{A750}\x{A752}\x{A754}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "Q",
             'letters' => '/(&#81;|&#9414;|&#65329;|&#42838;|&#42840;|&#586;|[\x{0051}\x{24C6}\x{FF31}\x{A756}\x{A758}\x{024A}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "R",
             'letters' => '/(&#82;|&#9415;|&#65330;|&#340;|&#7768;|&#344;|&#528;|&#530;|&#7770;|&#7772;|&#342;|&#7774;|&#588;|&#11364;|&#42842;|&#42918;|&#42882;|[\x{0052}\x{24C7}\x{FF32}\x{0154}\x{1E58}\x{0158}\x{0210}\x{0212}\x{1E5A}\x{1E5C}\x{0156}\x{1E5E}\x{024C}\x{2C64}\x{A75A}\x{A7A6}\x{A782}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "S",
             'letters' => '/(&#83;|&#9416;|&#65331;|&#7838;|&#346;|&#7780;|&#348;|&#7776;|&#352;|&#7782;|&#7778;|&#7784;|&#536;|&#350;|&#11390;|&#42920;|&#42884;|[\x{0053}\x{24C8}\x{FF33}\x{1E9E}\x{015A}\x{1E64}\x{015C}\x{1E60}\x{0160}\x{1E66}\x{1E62}\x{1E68}\x{0218}\x{015E}\x{2C7E}\x{A7A8}\x{A784}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "T",
             'letters' => '/(&#84;|&#9417;|&#65332;|&#7786;|&#356;|&#7788;|&#538;|&#354;|&#7792;|&#7790;|&#358;|&#428;|&#430;|&#574;|&#42886;|[\x{0054}\x{24C9}\x{FF34}\x{1E6A}\x{0164}\x{1E6C}\x{021A}\x{0162}\x{1E70}\x{1E6E}\x{0166}\x{01AC}\x{01AE}\x{023E}\x{A786}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "TH",
             'letters' => '/(&#222;|[\x{00DE}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "TZ",
             'letters' => '/(&#42792;|[\x{A728}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "U",
             'letters' => '/(&#85;|&#9418;|&#65333;|&#217;|&#218;|&#219;|&#360;|&#7800;|&#362;|&#7802;|&#364;|&#220;|&#475;|&#471;|&#469;|&#473;|&#7910;|&#366;|&#368;|&#467;|&#532;|&#534;|&#431;|&#7914;|&#7912;|&#7918;|&#7916;|&#7920;|&#7908;|&#7794;|&#370;|&#7798;|&#7796;|&#580;|[\x{0055}\x{24CA}\x{FF35}\x{00D9}\x{00DA}\x{00DB}\x{0168}\x{1E78}\x{016A}\x{1E7A}\x{016C}\x{00DC}\x{01DB}\x{01D7}\x{01D5}\x{01D9}\x{1EE6}\x{016E}\x{0170}\x{01D3}\x{0214}\x{0216}\x{01AF}\x{1EEA}\x{1EE8}\x{1EEE}\x{1EEC}\x{1EF0}\x{1EE4}\x{1E72}\x{0172}\x{1E76}\x{1E74}\x{0244}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "V",
             'letters' => '/(&#86;|&#9419;|&#65334;|&#7804;|&#7806;|&#434;|&#42846;|&#581;|[\x{0056}\x{24CB}\x{FF36}\x{1E7C}\x{1E7E}\x{01B2}\x{A75E}\x{0245}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "VY",
             'letters' => '/(&#42848;|[\x{A760}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "W",
             'letters' => '/(&#87;|&#9420;|&#65335;|&#7808;|&#7810;|&#372;|&#7814;|&#7812;|&#7816;|&#11378;|[\x{0057}\x{24CC}\x{FF37}\x{1E80}\x{1E82}\x{0174}\x{1E86}\x{1E84}\x{1E88}\x{2C72}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "X",
             'letters' => '/(&#88;|&#9421;|&#65336;|&#7818;|&#7820;|[\x{0058}\x{24CD}\x{FF38}\x{1E8A}\x{1E8C}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "Y",
             'letters' => '/(&#89;|&#9422;|&#65337;|&#7922;|&#221;|&#374;|&#7928;|&#562;|&#7822;|&#376;|&#7926;|&#7924;|&#435;|&#590;|&#7934;|[\x{0059}\x{24CE}\x{FF39}\x{1EF2}\x{00DD}\x{0176}\x{1EF8}\x{0232}\x{1E8E}\x{0178}\x{1EF6}\x{1EF4}\x{01B3}\x{024E}\x{1EFE}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "Z",
             'letters' => '/(&#90;|&#9423;|&#65338;|&#377;|&#7824;|&#379;|&#381;|&#7826;|&#7828;|&#437;|&#548;|&#11391;|&#11371;|&#42850;|[\x{005A}\x{24CF}\x{FF3A}\x{0179}\x{1E90}\x{017B}\x{017D}\x{1E92}\x{1E94}\x{01B5}\x{0224}\x{2C7F}\x{2C6B}\x{A762}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "a",
             'letters' => '/(&#97;|&#9424;|&#65345;|&#7834;|&#224;|&#225;|&#226;|&#7847;|&#7845;|&#7851;|&#7849;|&#227;|&#257;|&#259;|&#7857;|&#7855;|&#7861;|&#7859;|&#551;|&#481;|&#228;|&#479;|&#7843;|&#229;|&#507;|&#462;|&#513;|&#515;|&#7841;|&#7853;|&#7863;|&#7681;|&#261;|&#11365;|&#592;|[\x{0061}\x{24D0}\x{FF41}\x{1E9A}\x{00E0}\x{00E1}\x{00E2}\x{1EA7}\x{1EA5}\x{1EAB}\x{1EA9}\x{00E3}\x{0101}\x{0103}\x{1EB1}\x{1EAF}\x{1EB5}\x{1EB3}\x{0227}\x{01E1}\x{00E4}\x{01DF}\x{1EA3}\x{00E5}\x{01FB}\x{01CE}\x{0201}\x{0203}\x{1EA1}\x{1EAD}\x{1EB7}\x{1E01}\x{0105}\x{2C65}\x{0250}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "aa",
             'letters' => '/(&#42803;|[\x{A733}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "ae",
             'letters' => '/(&#230;|&#509;|&#483;|[\x{00E6}\x{01FD}\x{01E3}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "ao",
             'letters' => '/(&#42805;|[\x{A735}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "au",
             'letters' => '/(&#42807;|[\x{A737}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "av",
             'letters' => '/(&#42809;|&#42811;|[\x{A739}\x{A73B}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "ay",
             'letters' => '/(&#42813;|[\x{A73D}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "b",
             'letters' => '/(&#98;|&#9425;|&#65346;|&#7683;|&#7685;|&#7687;|&#384;|&#387;|&#595;|[\x{0062}\x{24D1}\x{FF42}\x{1E03}\x{1E05}\x{1E07}\x{0180}\x{0183}\x{0253}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "c",
             'letters' => '/(&#99;|&#9426;|&#65347;|&#263;|&#265;|&#267;|&#269;|&#231;|&#7689;|&#392;|&#572;|&#42815;|&#8580;|[\x{0063}\x{24D2}\x{FF43}\x{0107}\x{0109}\x{010B}\x{010D}\x{00E7}\x{1E09}\x{0188}\x{023C}\x{A73F}\x{2184}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "d",
             'letters' => '/(&#100;|&#9427;|&#65348;|&#7691;|&#271;|&#7693;|&#7697;|&#7699;|&#7695;|&#273;|&#396;|&#598;|&#599;|&#42874;|&#240;|[\x{0064}\x{24D3}\x{FF44}\x{1E0B}\x{010F}\x{1E0D}\x{1E11}\x{1E13}\x{1E0F}\x{0111}\x{018C}\x{0256}\x{0257}\x{A77A}\x{00F0}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "dz",
             'letters' => '/(&#499;|&#454;|[\x{01F3}\x{01C6}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "e",
             'letters' => '/(&#101;|&#9428;|&#65349;|&#232;|&#233;|&#234;|&#7873;|&#7871;|&#7877;|&#7875;|&#7869;|&#275;|&#7701;|&#7703;|&#277;|&#279;|&#235;|&#7867;|&#283;|&#517;|&#519;|&#7865;|&#7879;|&#553;|&#7709;|&#281;|&#7705;|&#7707;|&#583;|&#603;|&#477;|[\x{0065}\x{24D4}\x{FF45}\x{00E8}\x{00E9}\x{00EA}\x{1EC1}\x{1EBF}\x{1EC5}\x{1EC3}\x{1EBD}\x{0113}\x{1E15}\x{1E17}\x{0115}\x{0117}\x{00EB}\x{1EBB}\x{011B}\x{0205}\x{0207}\x{1EB9}\x{1EC7}\x{0229}\x{1E1D}\x{0119}\x{1E19}\x{1E1B}\x{0247}\x{025B}\x{01DD}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "f",
             'letters' => '/(&#102;|&#9429;|&#65350;|&#7711;|&#402;|&#42876;|[\x{0066}\x{24D5}\x{FF46}\x{1E1F}\x{0192}\x{A77C}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "g",
             'letters' => '/(&#103;|&#9430;|&#65351;|&#501;|&#285;|&#7713;|&#287;|&#289;|&#487;|&#291;|&#485;|&#608;|&#42913;|&#7545;|&#42879;|[\x{0067}\x{24D6}\x{FF47}\x{01F5}\x{011D}\x{1E21}\x{011F}\x{0121}\x{01E7}\x{0123}\x{01E5}\x{0260}\x{A7A1}\x{1D79}\x{A77F}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "h",
             'letters' => '/(&#104;|&#9431;|&#65352;|&#293;|&#7715;|&#7719;|&#543;|&#7717;|&#7721;|&#7723;|&#7830;|&#295;|&#11368;|&#11382;|&#613;|[\x{0068}\x{24D7}\x{FF48}\x{0125}\x{1E23}\x{1E27}\x{021F}\x{1E25}\x{1E29}\x{1E2B}\x{1E96}\x{0127}\x{2C68}\x{2C76}\x{0265}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "hv",
             'letters' => '/(&#405;|[\x{0195}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "i",
             'letters' => '/(&#105;|&#9432;|&#65353;|&#236;|&#237;|&#238;|&#297;|&#299;|&#301;|&#239;|&#7727;|&#7881;|&#464;|&#521;|&#523;|&#7883;|&#303;|&#7725;|&#616;|&#305;|[\x{0069}\x{24D8}\x{FF49}\x{00EC}\x{00ED}\x{00EE}\x{0129}\x{012B}\x{012D}\x{00EF}\x{1E2F}\x{1EC9}\x{01D0}\x{0209}\x{020B}\x{1ECB}\x{012F}\x{1E2D}\x{0268}\x{0131}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "ij",
             'letters' => '/(&#307;|[\x{0133}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "j",
             'letters' => '/(&#106;|&#9433;|&#65354;|&#309;|&#496;|&#585;|[\x{006A}\x{24D9}\x{FF4A}\x{0135}\x{01F0}\x{0249}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "k",
             'letters' => '/(&#107;|&#9434;|&#65355;|&#7729;|&#489;|&#7731;|&#311;|&#7733;|&#409;|&#11370;|&#42817;|&#42819;|&#42821;|&#42915;|[\x{006B}\x{24DA}\x{FF4B}\x{1E31}\x{01E9}\x{1E33}\x{0137}\x{1E35}\x{0199}\x{2C6A}\x{A741}\x{A743}\x{A745}\x{A7A3}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "l",
             'letters' => '/(&#108;|&#9435;|&#65356;|&#320;|&#314;|&#318;|&#7735;|&#7737;|&#316;|&#7741;|&#7739;|&#322;|&#410;|&#619;|&#11361;|&#42825;|&#42881;|&#42823;|[\x{006C}\x{24DB}\x{FF4C}\x{0140}\x{013A}\x{013E}\x{1E37}\x{1E39}\x{013C}\x{1E3D}\x{1E3B}\x{0142}\x{019A}\x{026B}\x{2C61}\x{A749}\x{A781}\x{A747}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "lj",
             'letters' => '/(&#457;|[\x{01C9}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "m",
             'letters' => '/(&#109;|&#9436;|&#65357;|&#7743;|&#7745;|&#7747;|&#625;|&#623;|[\x{006D}\x{24DC}\x{FF4D}\x{1E3F}\x{1E41}\x{1E43}\x{0271}\x{026F}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "n",
             'letters' => '/(&#110;|&#9437;|&#65358;|&#505;|&#324;|&#241;|&#7749;|&#328;|&#7751;|&#326;|&#7755;|&#7753;|&#414;|&#626;|&#329;|&#42897;|&#42917;|&#331;|[\x{006E}\x{24DD}\x{FF4E}\x{01F9}\x{0144}\x{00F1}\x{1E45}\x{0148}\x{1E47}\x{0146}\x{1E4B}\x{1E49}\x{019E}\x{0272}\x{0149}\x{A791}\x{A7A5}\x{014B}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "nj",
             'letters' => '/(&#460;|[\x{01CC}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "o",
             'letters' => '/(&#111;|&#9438;|&#65359;|&#242;|&#243;|&#244;|&#7891;|&#7889;|&#7895;|&#7893;|&#245;|&#7757;|&#557;|&#7759;|&#333;|&#7761;|&#7763;|&#335;|&#559;|&#561;|&#246;|&#555;|&#7887;|&#337;|&#466;|&#525;|&#527;|&#417;|&#7901;|&#7899;|&#7905;|&#7903;|&#7907;|&#7885;|&#7897;|&#491;|&#493;|&#248;|&#511;|&#596;|&#42827;|&#42829;|&#629;|[\x{006F}\x{24DE}\x{FF4F}\x{00F2}\x{00F3}\x{00F4}\x{1ED3}\x{1ED1}\x{1ED7}\x{1ED5}\x{00F5}\x{1E4D}\x{022D}\x{1E4F}\x{014D}\x{1E51}\x{1E53}\x{014F}\x{022F}\x{0231}\x{00F6}\x{022B}\x{1ECF}\x{0151}\x{01D2}\x{020D}\x{020F}\x{01A1}\x{1EDD}\x{1EDB}\x{1EE1}\x{1EDF}\x{1EE3}\x{1ECD}\x{1ED9}\x{01EB}\x{01ED}\x{00F8}\x{01FF}\x{0254}\x{A74B}\x{A74D}\x{0275}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "oe",
             'letters' => '/(&#339;|[\x{0153}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "oi",
             'letters' => '/(&#419;|[\x{01A3}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "ou",
             'letters' => '/(&#547;|[\x{0223}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "oo",
             'letters' => '/(&#42831;|[\x{A74F}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "p",
             'letters' => '/(&#112;|&#9439;|&#65360;|&#7765;|&#7767;|&#421;|&#7549;|&#42833;|&#42835;|&#42837;|[\x{0070}\x{24DF}\x{FF50}\x{1E55}\x{1E57}\x{01A5}\x{1D7D}\x{A751}\x{A753}\x{A755}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "q",
             'letters' => '/(&#113;|&#9440;|&#65361;|&#587;|&#42839;|&#42841;|[\x{0071}\x{24E0}\x{FF51}\x{024B}\x{A757}\x{A759}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "r",
             'letters' => '/(&#114;|&#9441;|&#65362;|&#341;|&#7769;|&#345;|&#529;|&#531;|&#7771;|&#7773;|&#343;|&#7775;|&#589;|&#637;|&#42843;|&#42919;|&#42883;|[\x{0072}\x{24E1}\x{FF52}\x{0155}\x{1E59}\x{0159}\x{0211}\x{0213}\x{1E5B}\x{1E5D}\x{0157}\x{1E5F}\x{024D}\x{027D}\x{A75B}\x{A7A7}\x{A783}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "s",
             'letters' => '/(&#115;|&#9442;|&#65363;|&#347;|&#7781;|&#349;|&#7777;|&#353;|&#7783;|&#7779;|&#7785;|&#537;|&#351;|&#575;|&#42921;|&#42885;|&#7835;|&#383;|[\x{0073}\x{24E2}\x{FF53}\x{015B}\x{1E65}\x{015D}\x{1E61}\x{0161}\x{1E67}\x{1E63}\x{1E69}\x{0219}\x{015F}\x{023F}\x{A7A9}\x{A785}\x{1E9B}\x{017F}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "ss",
             'letters' => '/(&#223;|[\x{00DF}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "t",
             'letters' => '/(&#116;|&#9443;|&#65364;|&#7787;|&#7831;|&#357;|&#7789;|&#539;|&#355;|&#7793;|&#7791;|&#359;|&#429;|&#648;|&#11366;|&#42887;|[\x{0074}\x{24E3}\x{FF54}\x{1E6B}\x{1E97}\x{0165}\x{1E6D}\x{021B}\x{0163}\x{1E71}\x{1E6F}\x{0167}\x{01AD}\x{0288}\x{2C66}\x{A787}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "th",
             'letters' => '/(&#254;|[\x{00FE}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "tz",
             'letters' => '/(&#42793;|[\x{A729}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "u",
             'letters' => '/(&#117;|&#9444;|&#65365;|&#249;|&#250;|&#251;|&#361;|&#7801;|&#363;|&#7803;|&#365;|&#252;|&#476;|&#472;|&#470;|&#474;|&#7911;|&#367;|&#369;|&#468;|&#533;|&#535;|&#432;|&#7915;|&#7913;|&#7919;|&#7917;|&#7921;|&#7909;|&#7795;|&#371;|&#7799;|&#7797;|&#649;|[\x{0075}\x{24E4}\x{FF55}\x{00F9}\x{00FA}\x{00FB}\x{0169}\x{1E79}\x{016B}\x{1E7B}\x{016D}\x{00FC}\x{01DC}\x{01D8}\x{01D6}\x{01DA}\x{1EE7}\x{016F}\x{0171}\x{01D4}\x{0215}\x{0217}\x{01B0}\x{1EEB}\x{1EE9}\x{1EEF}\x{1EED}\x{1EF1}\x{1EE5}\x{1E73}\x{0173}\x{1E77}\x{1E75}\x{0289}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "v",
             'letters' => '/(&#118;|&#9445;|&#65366;|&#7805;|&#7807;|&#651;|&#42847;|&#652;|[\x{0076}\x{24E5}\x{FF56}\x{1E7D}\x{1E7F}\x{028B}\x{A75F}\x{028C}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "vy",
             'letters' => '/(&#42849;|[\x{A761}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "w",
             'letters' => '/(&#119;|&#9446;|&#65367;|&#7809;|&#7811;|&#373;|&#7815;|&#7813;|&#7832;|&#7817;|&#11379;|[\x{0077}\x{24E6}\x{FF57}\x{1E81}\x{1E83}\x{0175}\x{1E87}\x{1E85}\x{1E98}\x{1E89}\x{2C73}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "x",
             'letters' => '/(&#120;|&#9447;|&#65368;|&#7819;|&#7821;|[\x{0078}\x{24E7}\x{FF58}\x{1E8B}\x{1E8D}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "y",
             'letters' => '/(&#121;|&#9448;|&#65369;|&#7923;|&#253;|&#375;|&#7929;|&#563;|&#7823;|&#255;|&#7927;|&#7833;|&#7925;|&#436;|&#591;|&#7935;|[\x{0079}\x{24E8}\x{FF59}\x{1EF3}\x{00FD}\x{0177}\x{1EF9}\x{0233}\x{1E8F}\x{00FF}\x{1EF7}\x{1E99}\x{1EF5}\x{01B4}\x{024F}\x{1EFF}])/'
-        ),
-        array(
+        ],
+        [
             'base'    => "z",
             'letters' => '/(&#122;|&#9449;|&#65370;|&#378;|&#7825;|&#380;|&#382;|&#7827;|&#7829;|&#438;|&#549;|&#576;|&#11372;|&#42851;|[\x{007A}\x{24E9}\x{FF5A}\x{017A}\x{1E91}\x{017C}\x{017E}\x{1E93}\x{1E95}\x{01B6}\x{0225}\x{0240}\x{2C6C}\x{A763}])/'
-        )
-    );
+        ]
+    ];
 
     public static function removeDiacritics($str)
Index: inc/core/class.dc.workspace.php
===================================================================
--- inc/core/class.dc.workspace.php	(revision 3773)
+++ inc/core/class.dc.workspace.php	(revision 3874)
@@ -18,8 +18,8 @@
     protected $user_id; ///< <b>string</b> User ID
 
-    protected $global_prefs = array(); ///< <b>array</b> Global prefs array
-    protected $local_prefs  = array(); ///< <b>array</b> Local prefs array
-    protected $prefs        = array(); ///< <b>array</b> Associative prefs array
-    protected $ws;                     ///< <b>string</b> Current workspace
+    protected $global_prefs = []; ///< <b>array</b> Global prefs array
+    protected $local_prefs  = []; ///< <b>array</b> Local prefs array
+    protected $prefs        = []; ///< <b>array</b> Associative prefs array
+    protected $ws;                ///< <b>string</b> Current workspace
 
     /**
@@ -87,5 +87,5 @@
             $array = $rs->user_id ? 'local' : 'global';
 
-            $this->{$array . '_prefs'}[$id] = array(
+            $this->{$array . '_prefs'}[$id] = [
                 'ws'     => $this->ws,
                 'value'  => $value,
@@ -93,5 +93,5 @@
                 'label'  => (string) $rs->f('pref_label'),
                 'global' => $rs->user_id == ''
-            );
+            ];
         }
 
@@ -391,5 +391,5 @@
         $array = $global ? 'global' : 'local';
         unset($this->{$array . '_prefs'});
-        $this->{$array . '_prefs'} = array();
+        $this->{$array . '_prefs'} = [];
 
         $array       = $global ? 'local' : 'global';
Index: inc/core/class.dc.xmlrpc.php
===================================================================
--- inc/core/class.dc.xmlrpc.php	(revision 3731)
+++ inc/core/class.dc.xmlrpc.php	(revision 3874)
@@ -28,192 +28,192 @@
 
         # Blogger methods
-        $this->addCallback('blogger.newPost', array($this, 'blogger_newPost'),
-            array('string', 'string', 'string', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('blogger.newPost', [$this, 'blogger_newPost'],
+            ['string', 'string', 'string', 'string', 'string', 'string', 'integer'],
             'New post');
 
-        $this->addCallback('blogger.editPost', array($this, 'blogger_editPost'),
-            array('boolean', 'string', 'string', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('blogger.editPost', [$this, 'blogger_editPost'],
+            ['boolean', 'string', 'string', 'string', 'string', 'string', 'integer'],
             'Edit a post');
 
-        $this->addCallback('blogger.getPost', array($this, 'blogger_getPost'),
-            array('struct', 'string', 'integer', 'string', 'string'),
+        $this->addCallback('blogger.getPost', [$this, 'blogger_getPost'],
+            ['struct', 'string', 'integer', 'string', 'string'],
             'Return a posts by ID');
 
-        $this->addCallback('blogger.deletePost', array($this, 'blogger_deletePost'),
-            array('string', 'string', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('blogger.deletePost', [$this, 'blogger_deletePost'],
+            ['string', 'string', 'string', 'string', 'string', 'integer'],
             'Delete a post');
 
-        $this->addCallback('blogger.getRecentPosts', array($this, 'blogger_getRecentPosts'),
-            array('array', 'string', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('blogger.getRecentPosts', [$this, 'blogger_getRecentPosts'],
+            ['array', 'string', 'string', 'string', 'string', 'integer'],
             'Return a list of recent posts');
 
-        $this->addCallback('blogger.getUsersBlogs', array($this, 'blogger_getUserBlogs'),
-            array('struct', 'string', 'string', 'string'),
+        $this->addCallback('blogger.getUsersBlogs', [$this, 'blogger_getUserBlogs'],
+            ['struct', 'string', 'string', 'string'],
             "Return user's blog");
 
-        $this->addCallback('blogger.getUserInfo', array($this, 'blogger_getUserInfo'),
-            array('struct', 'string', 'string', 'string'),
+        $this->addCallback('blogger.getUserInfo', [$this, 'blogger_getUserInfo'],
+            ['struct', 'string', 'string', 'string'],
             'Return User Info');
 
         # Metaweblog methods
-        $this->addCallback('metaWeblog.newPost', array($this, 'mw_newPost'),
-            array('string', 'string', 'string', 'string', 'struct', 'boolean'),
+        $this->addCallback('metaWeblog.newPost', [$this, 'mw_newPost'],
+            ['string', 'string', 'string', 'string', 'struct', 'boolean'],
             'Creates a new post, and optionnaly publishes it.');
 
-        $this->addCallback('metaWeblog.editPost', array($this, 'mw_editPost'),
-            array('boolean', 'string', 'string', 'string', 'struct', 'boolean'),
+        $this->addCallback('metaWeblog.editPost', [$this, 'mw_editPost'],
+            ['boolean', 'string', 'string', 'string', 'struct', 'boolean'],
             'Updates information about an existing entry');
 
-        $this->addCallback('metaWeblog.getPost', array($this, 'mw_getPost'),
-            array('struct', 'string', 'string', 'string'),
+        $this->addCallback('metaWeblog.getPost', [$this, 'mw_getPost'],
+            ['struct', 'string', 'string', 'string'],
             'Returns information about a specific post');
 
-        $this->addCallback('metaWeblog.getRecentPosts', array($this, 'mw_getRecentPosts'),
-            array('array', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('metaWeblog.getRecentPosts', [$this, 'mw_getRecentPosts'],
+            ['array', 'string', 'string', 'string', 'integer'],
             'List of most recent posts in the system');
 
-        $this->addCallback('metaWeblog.getCategories', array($this, 'mw_getCategories'),
-            array('array', 'string', 'string', 'string'),
+        $this->addCallback('metaWeblog.getCategories', [$this, 'mw_getCategories'],
+            ['array', 'string', 'string', 'string'],
             'List of all categories defined in the weblog');
 
-        $this->addCallback('metaWeblog.newMediaObject', array($this, 'mw_newMediaObject'),
-            array('struct', 'string', 'string', 'string', 'struct'),
+        $this->addCallback('metaWeblog.newMediaObject', [$this, 'mw_newMediaObject'],
+            ['struct', 'string', 'string', 'string', 'struct'],
             'Upload a file on the web server');
 
         # MovableType methods
-        $this->addCallback('mt.getRecentPostTitles', array($this, 'mt_getRecentPostTitles'),
-            array('array', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('mt.getRecentPostTitles', [$this, 'mt_getRecentPostTitles'],
+            ['array', 'string', 'string', 'string', 'integer'],
             'List of most recent posts in the system');
 
-        $this->addCallback('mt.getCategoryList', array($this, 'mt_getCategoryList'),
-            array('array', 'string', 'string', 'string'),
+        $this->addCallback('mt.getCategoryList', [$this, 'mt_getCategoryList'],
+            ['array', 'string', 'string', 'string'],
             'List of all categories defined in the weblog');
 
-        $this->addCallback('mt.getPostCategories', array($this, 'mt_getPostCategories'),
-            array('array', 'string', 'string', 'string'),
+        $this->addCallback('mt.getPostCategories', [$this, 'mt_getPostCategories'],
+            ['array', 'string', 'string', 'string'],
             'List of all categories to which the post is assigned');
 
-        $this->addCallback('mt.setPostCategories', array($this, 'mt_setPostCategories'),
-            array('boolean', 'string', 'string', 'string', 'array'),
+        $this->addCallback('mt.setPostCategories', [$this, 'mt_setPostCategories'],
+            ['boolean', 'string', 'string', 'string', 'array'],
             'Sets the categories for a post');
 
-        $this->addCallback('mt.publishPost', array($this, 'mt_publishPost'),
-            array('boolean', 'string', 'string', 'string'),
+        $this->addCallback('mt.publishPost', [$this, 'mt_publishPost'],
+            ['boolean', 'string', 'string', 'string'],
             'Retrieve pings list for a post');
 
-        $this->addCallback('mt.supportedMethods', array($this, 'listMethods'),
-            array(), 'Retrieve information about the XML-RPC methods supported by the server.');
-
-        $this->addCallback('mt.supportedTextFilters', array($this, 'mt_supportedTextFilters'),
-            array(), 'Retrieve information about supported text filters.');
+        $this->addCallback('mt.supportedMethods', [$this, 'listMethods'],
+            [], 'Retrieve information about the XML-RPC methods supported by the server.');
+
+        $this->addCallback('mt.supportedTextFilters', [$this, 'mt_supportedTextFilters'],
+            [], 'Retrieve information about supported text filters.');
 
         # WordPress methods
-        $this->addCallback('wp.getUsersBlogs', array($this, 'wp_getUsersBlogs'),
-            array('array', 'string', 'string'),
+        $this->addCallback('wp.getUsersBlogs', [$this, 'wp_getUsersBlogs'],
+            ['array', 'string', 'string'],
             'Retrieve the blogs of the user.');
 
-        $this->addCallback('wp.getPage', array($this, 'wp_getPage'),
-            array('struct', 'integer', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getPage', [$this, 'wp_getPage'],
+            ['struct', 'integer', 'integer', 'string', 'string'],
             'Get the page identified by the page ID.');
 
-        $this->addCallback('wp.getPages', array($this, 'wp_getPages'),
-            array('array', 'integer', 'string', 'string', 'integer'),
+        $this->addCallback('wp.getPages', [$this, 'wp_getPages'],
+            ['array', 'integer', 'string', 'string', 'integer'],
             'Get an array of all the pages on a blog.');
 
-        $this->addCallback('wp.newPage', array($this, 'wp_newPage'),
-            array('integer', 'integer', 'string', 'string', 'struct', 'boolean'),
+        $this->addCallback('wp.newPage', [$this, 'wp_newPage'],
+            ['integer', 'integer', 'string', 'string', 'struct', 'boolean'],
             'Create a new page.');
 
-        $this->addCallback('wp.deletePage', array($this, 'wp_deletePage'),
-            array('boolean', 'integer', 'string', 'string', 'integer'),
+        $this->addCallback('wp.deletePage', [$this, 'wp_deletePage'],
+            ['boolean', 'integer', 'string', 'string', 'integer'],
             'Removes a page from the blog.');
 
-        $this->addCallback('wp.editPage', array($this, 'wp_editPage'),
-            array('boolean', 'integer', 'integer', 'string', 'string', 'struct', 'boolean'),
+        $this->addCallback('wp.editPage', [$this, 'wp_editPage'],
+            ['boolean', 'integer', 'integer', 'string', 'string', 'struct', 'boolean'],
             'Make changes to a blog page.');
 
-        $this->addCallback('wp.getPageList', array($this, 'wp_getPageList'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getPageList', [$this, 'wp_getPageList'],
+            ['array', 'integer', 'string', 'string'],
             'Get an array of all the pages on a blog. Just the minimum details, lighter than wp.getPages.');
 
-        $this->addCallback('wp.getAuthors', array($this, 'wp_getAuthors'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getAuthors', [$this, 'wp_getAuthors'],
+            ['array', 'integer', 'string', 'string'],
             'Get an array of users for the blog.');
 
-        $this->addCallback('wp.getCategories', array($this, 'wp_getCategories'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getCategories', [$this, 'wp_getCategories'],
+            ['array', 'integer', 'string', 'string'],
             'Get an array of available categories on a blog.');
 
-        $this->addCallback('wp.getTags', array($this, 'wp_getTags'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getTags', [$this, 'wp_getTags'],
+            ['array', 'integer', 'string', 'string'],
             'Get list of all tags for the blog.');
 
-        $this->addCallback('wp.newCategory', array($this, 'wp_newCategory'),
-            array('integer', 'integer', 'string', 'string', 'struct'),
+        $this->addCallback('wp.newCategory', [$this, 'wp_newCategory'],
+            ['integer', 'integer', 'string', 'string', 'struct'],
             'Create a new category.');
 
-        $this->addCallback('wp.deleteCategory', array($this, 'wp_deleteCategory'),
-            array('boolean', 'integer', 'string', 'string', 'integer'),
+        $this->addCallback('wp.deleteCategory', [$this, 'wp_deleteCategory'],
+            ['boolean', 'integer', 'string', 'string', 'integer'],
             'Delete a category with a given ID.');
 
-        $this->addCallback('wp.suggestCategories', array($this, 'wp_suggestCategories'),
-            array('array', 'integer', 'string', 'string', 'string', 'integer'),
+        $this->addCallback('wp.suggestCategories', [$this, 'wp_suggestCategories'],
+            ['array', 'integer', 'string', 'string', 'string', 'integer'],
             'Get an array of categories that start with a given string.');
 
-        $this->addCallback('wp.uploadFile', array($this, 'wp_uploadFile'),
-            array('struct', 'integer', 'string', 'string', 'struct'),
+        $this->addCallback('wp.uploadFile', [$this, 'wp_uploadFile'],
+            ['struct', 'integer', 'string', 'string', 'struct'],
             'Upload a file');
 
-        $this->addCallback('wp.getPostStatusList', array($this, 'wp_getPostStatusList'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getPostStatusList', [$this, 'wp_getPostStatusList'],
+            ['array', 'integer', 'string', 'string'],
             'Retrieve all of the post statuses.');
 
-        $this->addCallback('wp.getPageStatusList', array($this, 'wp_getPageStatusList'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getPageStatusList', [$this, 'wp_getPageStatusList'],
+            ['array', 'integer', 'string', 'string'],
             'Retrieve all of the pages statuses.');
 
-        $this->addCallback('wp.getPageTemplates', array($this, 'wp_getPageTemplates'),
-            array('struct', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getPageTemplates', [$this, 'wp_getPageTemplates'],
+            ['struct', 'integer', 'string', 'string'],
             'Retrieve page templates.');
 
-        $this->addCallback('wp.getOptions', array($this, 'wp_getOptions'),
-            array('struct', 'integer', 'string', 'string', 'array'),
+        $this->addCallback('wp.getOptions', [$this, 'wp_getOptions'],
+            ['struct', 'integer', 'string', 'string', 'array'],
             'Retrieve blog options');
 
-        $this->addCallback('wp.setOptions', array($this, 'wp_setOptions'),
-            array('struct', 'integer', 'string', 'string', 'struct'),
+        $this->addCallback('wp.setOptions', [$this, 'wp_setOptions'],
+            ['struct', 'integer', 'string', 'string', 'struct'],
             'Update blog options');
 
-        $this->addCallback('wp.getComment', array($this, 'wp_getComment'),
-            array('struct', 'integer', 'string', 'string', 'integer'),
+        $this->addCallback('wp.getComment', [$this, 'wp_getComment'],
+            ['struct', 'integer', 'string', 'string', 'integer'],
             "Gets a comment, given it's comment ID.");
 
-        $this->addCallback('wp.getCommentCount', array($this, 'wp_getCommentCount'),
-            array('array', 'integer', 'string', 'string', 'integer'),
+        $this->addCallback('wp.getCommentCount', [$this, 'wp_getCommentCount'],
+            ['array', 'integer', 'string', 'string', 'integer'],
             'Retrieve comment count.');
 
-        $this->addCallback('wp.getComments', array($this, 'wp_getComments'),
-            array('array', 'integer', 'string', 'string', 'struct'),
+        $this->addCallback('wp.getComments', [$this, 'wp_getComments'],
+            ['array', 'integer', 'string', 'string', 'struct'],
             'Gets a set of comments for a given post.');
 
-        $this->addCallback('wp.deleteComment', array($this, 'wp_deleteComment'),
-            array('boolean', 'integer', 'string', 'string', 'integer'),
+        $this->addCallback('wp.deleteComment', [$this, 'wp_deleteComment'],
+            ['boolean', 'integer', 'string', 'string', 'integer'],
             'Delete a comment with given ID.');
 
-        $this->addCallback('wp.editComment', array($this, 'wp_editComment'),
-            array('boolean', 'integer', 'string', 'string', 'integer', 'struct'),
+        $this->addCallback('wp.editComment', [$this, 'wp_editComment'],
+            ['boolean', 'integer', 'string', 'string', 'integer', 'struct'],
             'Edit a comment with given ID.');
 
-        $this->addCallback('wp.newComment', array($this, 'wp_newComment'),
-            array('integer', 'integer', 'string', 'string', 'integer', 'struct'),
+        $this->addCallback('wp.newComment', [$this, 'wp_newComment'],
+            ['integer', 'integer', 'string', 'string', 'integer', 'struct'],
             'Create a new comment for a given post ID.');
 
-        $this->addCallback('wp.getCommentStatusList', array($this, 'wp_getCommentStatusList'),
-            array('array', 'integer', 'string', 'string'),
+        $this->addCallback('wp.getCommentStatusList', [$this, 'wp_getCommentStatusList'],
+            ['array', 'integer', 'string', 'string'],
             'Retrieve all of the comment statuses.');
 
         # Pingback support
-        $this->addCallback('pingback.ping', array($this, 'pingback_ping'),
-            array('string', 'string', 'string'),
+        $this->addCallback('pingback.ping', [$this, 'pingback_ping'],
+            ['string', 'string', 'string'],
             'Notify a link to a post.');
     }
@@ -231,5 +231,5 @@
             return $rsp;
         } catch (Exception $e) {
-            $this->debugTrace($methodname, $args, array($e->getMessage(), $e->getCode()));
+            $this->debugTrace($methodname, $args, [$e->getMessage(), $e->getCode()]);
             throw $e;
         }
@@ -304,8 +304,8 @@
         $this->setUser($user, $pwd);
         $this->setBlog();
-        $rs = $this->core->blog->getPosts(array(
+        $rs = $this->core->blog->getPosts([
             'post_id'   => (integer) $post_id,
             'post_type' => $post_type
-        ));
+        ]);
 
         if ($rs->isEmpty()) {
@@ -318,5 +318,5 @@
     private function getCatID($cat_url)
     {
-        $rs = $this->core->blog->getCategories(array('cat_url' => $cat_url));
+        $rs = $this->core->blog->getCategories(['cat_url' => $cat_url]);
 
         return $rs->isEmpty() ? null : $rs->cat_id;
@@ -325,5 +325,5 @@
     /* Generic methods
     --------------------------------------------------- */
-    private function newPost($blog_id, $user, $pwd, $content, $struct = array(), $publish = true)
+    private function newPost($blog_id, $user, $pwd, $content, $struct = [], $publish = true)
     {
         $this->setUser($user, $pwd);
@@ -418,5 +418,5 @@
     }
 
-    private function editPost($post_id, $user, $pwd, $content, $struct = array(), $publish = true)
+    private function editPost($post_id, $user, $pwd, $content, $struct = [], $publish = true)
     {
         $post_id = (integer) $post_id;
@@ -527,5 +527,5 @@
 
         if ($post->cat_id) {
-            $res['categories'] = array($post->cat_url);
+            $res['categories'] = [$post->cat_url];
         }
 
@@ -550,5 +550,5 @@
 
         # --BEHAVIOR-- xmlrpcGetPostInfo
-        $this->core->callBehavior('xmlrpcGetPostInfo', $this, $type, array(&$res));
+        $this->core->callBehavior('xmlrpcGetPostInfo', $this, $type, [&$res]);
 
         return $res;
@@ -576,12 +576,12 @@
         }
 
-        $params          = array();
+        $params          = [];
         $params['limit'] = $nb_post;
 
         $posts = $this->core->blog->getPosts($params);
 
-        $res = array();
+        $res = [];
         while ($posts->fetch()) {
-            $tres = array();
+            $tres = [];
 
             $tres['dateCreated'] = new xmlrpcDate($posts->getTS());
@@ -590,5 +590,5 @@
 
             if ($posts->cat_id) {
-                $tres['categories'] = array($posts->cat_url);
+                $tres['categories'] = [$posts->cat_url];
             }
 
@@ -613,5 +613,5 @@
 
             # --BEHAVIOR-- xmlrpcGetPostInfo
-            $this->core->callBehavior('xmlrpcGetPostInfo', $this, $type, array(&$tres));
+            $this->core->callBehavior('xmlrpcGetPostInfo', $this, $type, [&$tres]);
 
             $res[] = $tres;
@@ -626,9 +626,9 @@
         $this->setBlog();
 
-        return array(array(
+        return [[
             'url'      => $this->core->blog->url,
             'blogid'   => '1',
             'blogName' => $this->core->blog->name
-        ));
+        ]];
     }
 
@@ -637,5 +637,5 @@
         $this->setUser($user, $pwd);
 
-        return array(
+        return [
             'userid'    => $this->core->auth->userID(),
             'firstname' => $this->core->auth->getInfo('user_firstname'),
@@ -644,5 +644,5 @@
             'email'     => $this->core->auth->getInfo('user_email'),
             'url'       => $this->core->auth->getInfo('user_url')
-        );
+        ];
     }
 
@@ -653,8 +653,8 @@
         $rs = $this->core->blog->getCategories();
 
-        $res = array();
+        $res = [];
 
         $l     = $rs->level;
-        $stack = array('', $rs->cat_url);
+        $stack = ['', $rs->cat_url];
 
         while ($rs->fetch()) {
@@ -673,5 +673,5 @@
             }
 
-            $res[] = array(
+            $res[] = [
                 'categoryId'   => $rs->cat_url,
                 'parentId'     => $parent,
@@ -682,5 +682,5 @@
                 'rssUrl'       => $this->core->blog->url .
                 $this->core->url->getURLFor('feed', 'category/' . $rs->cat_url . '/rss2')
-            );
+            ];
 
             $stack[] = $rs->cat_url;
@@ -697,11 +697,11 @@
         $post = $this->getPostRS($post_id, $user, $pwd);
 
-        return array(
-            array(
+        return [
+            [
                 'categoryName' => $post->cat_url,
                 'categoryId'   => (string) $post->cat_url,
                 'isPrimary'    => true
-            )
-        );
+            ]
+        ];
     }
 
@@ -788,14 +788,14 @@
 
         $f = $media->getFile($media_id);
-        return array(
+        return [
             'file' => $file_name,
             'url'  => $f->file_url,
             'type' => files::getMimeType($file_name)
-        );
+        ];
     }
 
     private function translateWpStatus($s)
     {
-        $status = array(
+        $status = [
             'draft'     => -2,
             'pending'   => -2,
@@ -803,5 +803,5 @@
             'publish'   => 1,
             'scheduled' => -1
-        );
+        ];
 
         if (is_int($s)) {
@@ -815,9 +815,9 @@
     private function translateWpCommentstatus($s)
     {
-        $status = array(
+        $status = [
             'hold'    => -1,
             'approve' => 0,
             'spam'    => -2
-        );
+        ];
 
         if (is_int($s)) {
@@ -829,5 +829,5 @@
     }
 
-    private function translateWpOptions($options = array())
+    private function translateWpOptions($options = [])
     {
         $timezone = 0;
@@ -836,49 +836,49 @@
         }
 
-        $res = array(
-            'software_name'    => array(
+        $res = [
+            'software_name'    => [
                 'desc'     => 'Software Name',
                 'readonly' => true,
                 'value'    => 'Dotclear'
-            ),
-            'software_version' => array(
+            ],
+            'software_version' => [
                 'desc'     => 'Software Version',
                 'readonly' => true,
                 'value'    => DC_VERSION
-            ),
-            'blog_url'         => array(
+            ],
+            'blog_url'         => [
                 'desc'     => 'Blog URL',
                 'readonly' => true,
                 'value'    => $this->core->blog->url
-            ),
-            'time_zone'        => array(
+            ],
+            'time_zone'        => [
                 'desc'     => 'Time Zone',
                 'readonly' => true,
                 'value'    => (string) $timezone
-            ),
-            'blog_title'       => array(
+            ],
+            'blog_title'       => [
                 'desc'     => 'Blog Title',
                 'readonly' => false,
                 'value'    => $this->core->blog->name
-            ),
-            'blog_tagline'     => array(
+            ],
+            'blog_tagline'     => [
                 'desc'     => 'Blog Tagline',
                 'readonly' => false,
                 'value'    => $this->core->blog->desc
-            ),
-            'date_format'      => array(
+            ],
+            'date_format'      => [
                 'desc'     => 'Date Format',
                 'readonly' => false,
                 'value'    => $this->core->blog->settings->system->date_format
-            ),
-            'time_format'      => array(
+            ],
+            'time_format'      => [
                 'desc'     => 'Time Format',
                 'readonly' => false,
                 'value'    => $this->core->blog->settings->system->time_format
-            )
-        );
+            ]
+        ];
 
         if (!empty($options)) {
-            $r = array();
+            $r = [];
             foreach ($options as $v) {
                 if (isset($res[$v])) {
@@ -897,5 +897,5 @@
         $this->setBlog();
 
-        return array(
+        return [
             'draft'     => 'Draft',
             'pending'   => 'Pending Review',
@@ -903,5 +903,5 @@
             'publish'   => 'Published',
             'scheduled' => 'Scheduled'
-        );
+        ];
     }
 
@@ -912,10 +912,10 @@
         $this->checkPagesPermission();
 
-        return array(
+        return [
             'draft'     => 'Draft',
             'private'   => 'Private',
             'published' => 'Published',
             'scheduled' => 'Scheduled'
-        );
+        ];
     }
 
@@ -937,8 +937,8 @@
         $this->checkPagesPermission();
 
-        $params = array(
+        $params = [
             'post_type' => 'page',
             'order'     => 'post_position ASC, post_title ASC'
-        );
+        ];
 
         if ($id) {
@@ -951,7 +951,7 @@
         $posts = $this->core->blog->getPosts($params);
 
-        $res = array();
+        $res = [];
         while ($posts->fetch()) {
-            $tres = array(
+            $tres = [
                 "dateCreated"            => new xmlrpcDate($posts->getTS()),
                 "userid"                 => $posts->user_id,
@@ -962,5 +962,5 @@
                 "link"                   => $posts->getURL(),
                 "permaLink"              => $posts->getURL(),
-                "categories"             => array(),
+                "categories"             => [],
                 "excerpt"                => $posts->post_excerpt_xhtml,
                 "text_more"              => '',
@@ -976,10 +976,10 @@
                 "wp_author_display_name" => $posts->getAuthorCN(),
                 "date_created_gmt"       => new xmlrpcDate(dt::iso8601($posts->getTS(), $posts->post_tz)),
-                "custom_fields"          => array(),
+                "custom_fields"          => [],
                 "wp_page_template"       => 'default'
-            );
+            ];
 
             # --BEHAVIOR-- xmlrpcGetPageInfo
-            $this->core->callBehavior('xmlrpcGetPageInfo', $this, array(&$tres));
+            $this->core->callBehavior('xmlrpcGetPageInfo', $this, [&$tres]);
 
             $res[] = $tres;
@@ -1031,12 +1031,12 @@
 
         $rs  = $this->core->getBlogPermissions($this->core->blog->id);
-        $res = array();
+        $res = [];
 
         foreach ($rs as $k => $v) {
-            $res[] = array(
+            $res[] = [
                 'user_id'      => $k,
                 'user_login'   => $k,
                 'display_name' => dcUtils::getUserCN($k, $v['name'], $v['firstname'], $v['displayname'])
-            );
+            ];
         }
         return $res;
@@ -1051,5 +1051,5 @@
         $tags->sort('meta_id_lower', 'asc');
 
-        $res = array();
+        $res = [];
         $url = $this->core->blog->url .
         $this->core->url->getURLFor('tag', '%s');
@@ -1057,5 +1057,5 @@
         $this->core->url->getURLFor('tag_feed', '%s');
         while ($tags->fetch()) {
-            $res[] = array(
+            $res[] = [
                 'tag_id'   => $tags->meta_id,
                 'name'     => $tags->meta_id,
@@ -1064,5 +1064,5 @@
                 'html_url' => sprintf($url, $tags->meta_id),
                 'rss_url'  => sprintf($f_url, $tags->meta_id)
-            );
+            ];
         }
         return $res;
@@ -1103,5 +1103,5 @@
         $this->setBlog();
 
-        $c = $this->core->blog->getCategories(array('cat_url' => $cat_id));
+        $c = $this->core->blog->getCategories(['cat_url' => $cat_id]);
         if ($c->isEmpty()) {
             throw new Exception(__('This category does not exist.'));
@@ -1127,10 +1127,10 @@
         $rs = $this->core->con->select($strReq);
 
-        $res = array();
+        $res = [];
         while ($rs->fetch()) {
-            $res[] = array(
+            $res[] = [
                 'category_id'   => $rs->cat_url,
                 'category_name' => $rs->cat_url
-            );
+            ];
         }
         return $res;
@@ -1142,11 +1142,11 @@
         $this->setBlog();
 
-        $res = array(
+        $res = [
             'approved'            => 0,
             'awaiting_moderation' => 0,
             'spam'                => 0,
             'total'               => 0
-        );
-        $rs = $this->core->blog->getComments(array('post_id' => $post_id));
+        ];
+        $rs = $this->core->blog->getComments(['post_id' => $post_id]);
 
         while ($rs->fetch()) {
@@ -1168,5 +1168,5 @@
         $this->setBlog();
 
-        $params = array();
+        $params = [];
 
         if (!empty($struct['status'])) {
@@ -1184,10 +1184,10 @@
         $offset          = !empty($struct['offset']) ? (integer) $struct['offset'] : 0;
         $limit           = !empty($struct['number']) ? (integer) $struct['number'] : 10;
-        $params['limit'] = array($offset, $limit);
+        $params['limit'] = [$offset, $limit];
 
         $rs  = $this->core->blog->getComments($params);
-        $res = array();
+        $res = [];
         while ($rs->fetch()) {
-            $res[] = array(
+            $res[] = [
                 'date_created_gmt' => new xmlrpcDate($rs->getTS()),
                 'user_id'          => $rs->user_id,
@@ -1203,5 +1203,5 @@
                 'author_email'     => $rs->comment_email,
                 'author_ip'        => $rs->comment_ip
-            );
+            ];
         }
         return $res;
@@ -1293,10 +1293,10 @@
     public function blogger_newPost($appkey, $blogid, $username, $password, $content, $publish)
     {
-        return $this->newPost($blogid, $username, $password, $content, array(), $publish);
+        return $this->newPost($blogid, $username, $password, $content, [], $publish);
     }
 
     public function blogger_editPost($appkey, $postid, $username, $password, $content, $publish)
     {
-        return $this->editPost($postid, $username, $password, $content, array(), $publish);
+        return $this->editPost($postid, $username, $password, $content, [], $publish);
     }
 
@@ -1387,5 +1387,5 @@
     public function mt_supportedTextFilters()
     {
-        return array();
+        return [];
     }
 
@@ -1431,7 +1431,7 @@
     {
         $A   = $this->getPages($blogid, $username, $password);
-        $res = array();
+        $res = [];
         foreach ($A as $v) {
-            $res[] = array(
+            $res[] = [
                 'page_id'          => $v['page_id'],
                 'page_title'       => $v['title'],
@@ -1439,5 +1439,5 @@
                 'dateCreated'      => $v['dateCreated'],
                 'date_created_gmt' => $v['date_created_gmt']
-            );
+            ];
         }
         return $res;
@@ -1491,8 +1491,8 @@
     public function wp_getPageTemplates($blogid, $username, $password)
     {
-        return array('Default' => 'default');
-    }
-
-    public function wp_getOptions($blogid, $username, $password, $options = array())
+        return ['Default' => 'default'];
+    }
+
+    public function wp_getOptions($blogid, $username, $password, $options = [])
     {
         $this->setUser($username, $password);
@@ -1513,5 +1513,5 @@
         $opt = $this->translateWpOptions();
 
-        $done         = array();
+        $done         = [];
         $blog_changes = false;
         $cur          = $this->core->con->openCursor($this->core->prefix . 'blog');
@@ -1556,5 +1556,5 @@
     public function wp_getComment($blogid, $username, $password, $commentid)
     {
-        $res = $this->getComments($username, $password, array(), $commentid);
+        $res = $this->getComments($username, $password, [], $commentid);
 
         if (empty($res)) {
@@ -1595,9 +1595,9 @@
         $this->setBlog();
 
-        return array(
+        return [
             'hold'    => 'Unapproved',
             'approve' => 'Approved',
             'spam'    => 'Spam'
-        );
+        ];
     }
 
@@ -1608,5 +1608,5 @@
         dcTrackback::checkURLs($from_url, $to_url);
 
-        $args = array('type' => 'pingback', 'from_url' => $from_url, 'to_url' => $to_url);
+        $args = ['type' => 'pingback', 'from_url' => $from_url, 'to_url' => $to_url];
 
         # Time to get things done...
Index: inc/dbschema/upgrade.php
===================================================================
--- inc/dbschema/upgrade.php	(revision 3867)
+++ inc/dbschema/upgrade.php	(revision 3875)
@@ -118,5 +118,5 @@
         if (version_compare($version, '2.1.6', '<=')) {
             # ie7js has been upgraded
-            $ie7files = array(
+            $ie7files = [
                 'ie7-base64.php ',
                 'ie7-content.htc',
@@ -139,5 +139,5 @@
                 'ie7-standard-p.js',
                 'ie7-xml-extras.js'
-            );
+            ];
             foreach ($ie7files as $f) {
                 @unlink(DC_ROOT . '/admin/js/ie7/' . $f);
@@ -173,26 +173,26 @@
         if (version_compare($version, '2.3', '<')) {
             # Add global favorites
-            $init_fav = array();
-
-            $init_fav['new_post'] = array('new_post', 'New entry', 'post.php',
+            $init_fav = [];
+
+            $init_fav['new_post'] = ['new_post', 'New entry', 'post.php',
                 'images/menu/edit.png', 'images/menu/edit-b.png',
-                'usage,contentadmin', null, null);
-            $init_fav['newpage'] = array('newpage', 'New page', 'plugin.php?p=pages&amp;act=page',
+                'usage,contentadmin', null, null];
+            $init_fav['newpage'] = ['newpage', 'New page', 'plugin.php?p=pages&amp;act=page',
                 'index.php?pf=pages/icon-np.png', 'index.php?pf=pages/icon-np-big.png',
-                'contentadmin,pages', null, null);
-            $init_fav['media'] = array('media', 'Media manager', 'media.php',
+                'contentadmin,pages', null, null];
+            $init_fav['media'] = ['media', 'Media manager', 'media.php',
                 'images/menu/media.png', 'images/menu/media-b.png',
-                'media,media_admin', null, null);
-            $init_fav['widgets'] = array('widgets', 'Presentation widgets', 'plugin.php?p=widgets',
+                'media,media_admin', null, null];
+            $init_fav['widgets'] = ['widgets', 'Presentation widgets', 'plugin.php?p=widgets',
                 'index.php?pf=widgets/icon.png', 'index.php?pf=widgets/icon-big.png',
-                'admin', null, null);
-            $init_fav['blog_theme'] = array('blog_theme', 'Blog appearance', 'blog_theme.php',
+                'admin', null, null];
+            $init_fav['blog_theme'] = ['blog_theme', 'Blog appearance', 'blog_theme.php',
                 'images/menu/themes.png', 'images/menu/blog-theme-b.png',
-                'admin', null, null);
+                'admin', null, null];
 
             $count = 0;
             foreach ($init_fav as $k => $f) {
-                $t = array('name' => $f[0], 'title'       => $f[1], 'url' => $f[2], 'small-icon' => $f[3],
-                    'large-icon'      => $f[4], 'permissions' => $f[5], 'id'  => $f[6], 'class'      => $f[7]);
+                $t = ['name' => $f[0], 'title'       => $f[1], 'url' => $f[2], 'small-icon' => $f[3],
+                    'large-icon'      => $f[4], 'permissions' => $f[5], 'id'  => $f[6], 'class'      => $f[7]];
                 $sqlstr = 'INSERT INTO ' . $core->prefix . 'pref (pref_id, user_id, pref_ws, pref_value, pref_type, pref_label) VALUES (' .
                 '\'' . sprintf("g%03s", $count) . '\',NULL,\'favorites\',\'' . serialize($t) . '\',\'string\',NULL);';
@@ -202,5 +202,5 @@
 
             # A bit of housecleaning for no longer needed files
-            $remfiles = array(
+            $remfiles = [
                 'admin/style/cat-bg.png',
                 'admin/style/footer-bg.png',
@@ -272,6 +272,6 @@
                 'themes/default/tpl/_mp3_player.html',
                 'themes/default/tpl/_top.html'
-            );
-            $remfolders = array(
+            ];
+            $remfolders = [
                 'inc/clearbricks/common',
                 'inc/clearbricks/dblayer',
@@ -296,5 +296,5 @@
                 'inc/clearbricks',
                 'themes/default/tpl'
-            );
+            ];
 
             foreach ($remfiles as $f) {
@@ -380,8 +380,8 @@
 
             # Add date and time formats
-            $date_formats = array('%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%Y/%m/%d', '%d.%m.%Y', '%b %e %Y', '%e %b %Y', '%Y %b %e',
+            $date_formats = ['%Y-%m-%d', '%m/%d/%Y', '%d/%m/%Y', '%Y/%m/%d', '%d.%m.%Y', '%b %e %Y', '%e %b %Y', '%Y %b %e',
                 '%a, %Y-%m-%d', '%a, %m/%d/%Y', '%a, %d/%m/%Y', '%a, %Y/%m/%d', '%B %e, %Y', '%e %B, %Y', '%Y, %B %e', '%e. %B %Y',
-                '%A, %B %e, %Y', '%A, %e %B, %Y', '%A, %Y, %B %e', '%A, %Y, %B %e', '%A, %e. %B %Y');
-            $time_formats = array('%H:%M', '%I:%M', '%l:%M', '%Hh%M', '%Ih%M', '%lh%M');
+                '%A, %B %e, %Y', '%A, %e %B, %Y', '%A, %Y, %B %e', '%A, %Y, %B %e', '%A, %e. %B %Y'];
+            $time_formats = ['%H:%M', '%I:%M', '%l:%M', '%Hh%M', '%Ih%M', '%lh%M'];
             if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
                 $date_formats = array_map(function ($f) {return str_replace('%e', '%#d', $f);}, $date_formats);
@@ -573,5 +573,5 @@
 
             # A bit of housecleaning for no longer needed files
-            $remfiles = array(
+            $remfiles = [
                 'admin/js/jquery/jquery.modal.js',
                 'admin/style/modal/close.png',
@@ -596,10 +596,10 @@
                 'plugins/tags/js/jquery.autocomplete.js',
                 'theme/ductile/ie.css'
-            );
-            $remfolders = array(
+            ];
+            $remfolders = [
                 'admin/style/modal',
                 'admin/js/tool-man',
                 'admin/js/ie7'
-            );
+            ];
 
             foreach ($remfiles as $f) {
@@ -652,4 +652,23 @@
                 "   OR setting_value = '/\\.(phps?|pht(ml)?|phl|s?html?|js|htaccess)[0-9]*$/i'";
             $core->con->execute($strReq);
+        }
+
+        if (version_compare($version, '2.15', '<')) {
+            # switch from jQuery 1.11.3 to 1.12.4
+            $strReq = 'UPDATE ' . $core->prefix . 'setting ' .
+                " SET setting_value = '1.12.4' " .
+                " WHERE setting_id = 'jquery_version' " .
+                " AND setting_ns = 'system' " .
+                " AND setting_value = '1.11.3' ";
+            $core->con->execute($strReq);
+
+            # A bit of housecleaning for no longer needed files
+            $remfiles = [
+                'plugins/dcLegacyEditor/tpl/index.tpl',
+                'plugins/dcCKEditor/tpl/index.tpl'
+            ];
+            foreach ($remfiles as $f) {
+                @unlink(DC_ROOT . '/' . $f);
+            }
         }
 
@@ -678,5 +697,5 @@
             $value = @unserialize($rs->setting_value);
             if (!$value) {
-                $value = array();
+                $value = [];
             }
             settype($value, 'array');
@@ -713,5 +732,5 @@
             $value = @unserialize($rs->pref_value);
             if (!$value) {
-                $value = array();
+                $value = [];
             }
             settype($value, 'array');
Index: nc/js/jquery/1.11.3/jquery.cookie.js
===================================================================
--- inc/js/jquery/1.11.3/jquery.cookie.js	(revision 3027)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*!
- * jQuery Cookie Plugin v1.4.1
- * https://github.com/carhartl/jquery-cookie
- *
- * Copyright 2006, 2014 Klaus Hartl
- * Released under the MIT license
- */
-(function (factory) {
-	if (typeof define === 'function' && define.amd) {
-		// AMD
-		define(['jquery'], factory);
-	} else if (typeof exports === 'object') {
-		// CommonJS
-		factory(require('jquery'));
-	} else {
-		// Browser globals
-		factory(jQuery);
-	}
-}(function ($) {
-
-	var pluses = /\+/g;
-
-	function encode(s) {
-		return config.raw ? s : encodeURIComponent(s);
-	}
-
-	function decode(s) {
-		return config.raw ? s : decodeURIComponent(s);
-	}
-
-	function stringifyCookieValue(value) {
-		return encode(config.json ? JSON.stringify(value) : String(value));
-	}
-
-	function parseCookieValue(s) {
-		if (s.indexOf('"') === 0) {
-			// This is a quoted cookie as according to RFC2068, unescape...
-			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
-		}
-
-		try {
-			// Replace server-side written pluses with spaces.
-			// If we can't decode the cookie, ignore it, it's unusable.
-			// If we can't parse the cookie, ignore it, it's unusable.
-			s = decodeURIComponent(s.replace(pluses, ' '));
-			return config.json ? JSON.parse(s) : s;
-		} catch(e) {}
-	}
-
-	function read(s, converter) {
-		var value = config.raw ? s : parseCookieValue(s);
-		return $.isFunction(converter) ? converter(value) : value;
-	}
-
-	var config = $.cookie = function (key, value, options) {
-
-		// Write
-
-		if (arguments.length > 1 && !$.isFunction(value)) {
-			options = $.extend({}, config.defaults, options);
-
-			if (typeof options.expires === 'number') {
-				var days = options.expires, t = options.expires = new Date();
-				t.setTime(+t + days * 864e+5);
-			}
-
-			return (document.cookie = [
-				encode(key), '=', stringifyCookieValue(value),
-				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
-				options.path    ? '; path=' + options.path : '',
-				options.domain  ? '; domain=' + options.domain : '',
-				options.secure  ? '; secure' : ''
-			].join(''));
-		}
-
-		// Read
-
-		var result = key ? undefined : {};
-
-		// To prevent the for loop in the first place assign an empty array
-		// in case there are no cookies at all. Also prevents odd result when
-		// calling $.cookie().
-		var cookies = document.cookie ? document.cookie.split('; ') : [];
-
-		for (var i = 0, l = cookies.length; i < l; i++) {
-			var parts = cookies[i].split('=');
-			var name = decode(parts.shift());
-			var cookie = parts.join('=');
-
-			if (key && key === name) {
-				// If second argument (value) is a function it's a converter...
-				result = read(cookie, value);
-				break;
-			}
-
-			// Prevent storing a cookie that we couldn't decode.
-			if (!key && (cookie = read(cookie)) !== undefined) {
-				result[name] = cookie;
-			}
-		}
-
-		return result;
-	};
-
-	config.defaults = {};
-
-	$.removeCookie = function (key, options) {
-		if ($.cookie(key) === undefined) {
-			return false;
-		}
-
-		// Must not alter options, thus extending a fresh object...
-		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
-		return !$.cookie(key);
-	};
-
-}));
Index: nc/js/jquery/1.11.3/jquery.js
===================================================================
--- inc/js/jquery/1.11.3/jquery.js	(revision 3027)
+++ 	(revision )
@@ -1,10351 +1,0 @@
-/*!
- * jQuery JavaScript Library v1.11.3
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-04-28T16:19Z
- */
-
-(function( global, factory ) {
-
-	if ( typeof module === "object" && typeof module.exports === "object" ) {
-		// For CommonJS and CommonJS-like environments where a proper window is present,
-		// execute the factory and get jQuery
-		// For environments that do not inherently posses a window with a document
-		// (such as Node.js), expose a jQuery-making factory as module.exports
-		// This accentuates the need for the creation of a real window
-		// e.g. var jQuery = require("jquery")(window);
-		// See ticket #14549 for more info
-		module.exports = global.document ?
-			factory( global, true ) :
-			function( w ) {
-				if ( !w.document ) {
-					throw new Error( "jQuery requires a window with a document" );
-				}
-				return factory( w );
-			};
-	} else {
-		factory( global );
-	}
-
-// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Can't do this because several apps including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-// Support: Firefox 18+
-//
-
-var deletedIds = [];
-
-var slice = deletedIds.slice;
-
-var concat = deletedIds.concat;
-
-var push = deletedIds.push;
-
-var indexOf = deletedIds.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var support = {};
-
-
-
-var
-	version = "1.11.3",
-
-	// Define a local copy of jQuery
-	jQuery = function( selector, context ) {
-		// The jQuery object is actually just the init constructor 'enhanced'
-		// Need init if jQuery is called (just allow error to be thrown if not included)
-		return new jQuery.fn.init( selector, context );
-	},
-
-	// Support: Android<4.1, IE<9
-	// Make sure we trim BOM and NBSP
-	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
-	// Matches dashed string for camelizing
-	rmsPrefix = /^-ms-/,
-	rdashAlpha = /-([\da-z])/gi,
-
-	// Used by jQuery.camelCase as callback to replace()
-	fcamelCase = function( all, letter ) {
-		return letter.toUpperCase();
-	};
-
-jQuery.fn = jQuery.prototype = {
-	// The current version of jQuery being used
-	jquery: version,
-
-	constructor: jQuery,
-
-	// Start with an empty selector
-	selector: "",
-
-	// The default length of a jQuery object is 0
-	length: 0,
-
-	toArray: function() {
-		return slice.call( this );
-	},
-
-	// Get the Nth element in the matched element set OR
-	// Get the whole matched element set as a clean array
-	get: function( num ) {
-		return num != null ?
-
-			// Return just the one element from the set
-			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
-			// Return all the elements in a clean array
-			slice.call( this );
-	},
-
-	// Take an array of elements and push it onto the stack
-	// (returning the new matched element set)
-	pushStack: function( elems ) {
-
-		// Build a new jQuery matched element set
-		var ret = jQuery.merge( this.constructor(), elems );
-
-		// Add the old object onto the stack (as a reference)
-		ret.prevObject = this;
-		ret.context = this.context;
-
-		// Return the newly-formed element set
-		return ret;
-	},
-
-	// Execute a callback for every element in the matched set.
-	// (You can seed the arguments with an array of args, but this is
-	// only used internally.)
-	each: function( callback, args ) {
-		return jQuery.each( this, callback, args );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map(this, function( elem, i ) {
-			return callback.call( elem, i, elem );
-		}));
-	},
-
-	slice: function() {
-		return this.pushStack( slice.apply( this, arguments ) );
-	},
-
-	first: function() {
-		return this.eq( 0 );
-	},
-
-	last: function() {
-		return this.eq( -1 );
-	},
-
-	eq: function( i ) {
-		var len = this.length,
-			j = +i + ( i < 0 ? len : 0 );
-		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
-	},
-
-	end: function() {
-		return this.prevObject || this.constructor(null);
-	},
-
-	// For internal use only.
-	// Behaves like an Array's method, not like a jQuery method.
-	push: push,
-	sort: deletedIds.sort,
-	splice: deletedIds.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
-	var src, copyIsArray, copy, name, options, clone,
-		target = arguments[0] || {},
-		i = 1,
-		length = arguments.length,
-		deep = false;
-
-	// Handle a deep copy situation
-	if ( typeof target === "boolean" ) {
-		deep = target;
-
-		// skip the boolean and the target
-		target = arguments[ i ] || {};
-		i++;
-	}
-
-	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
-		target = {};
-	}
-
-	// extend jQuery itself if only one argument is passed
-	if ( i === length ) {
-		target = this;
-		i--;
-	}
-
-	for ( ; i < length; i++ ) {
-		// Only deal with non-null/undefined values
-		if ( (options = arguments[ i ]) != null ) {
-			// Extend the base object
-			for ( name in options ) {
-				src = target[ name ];
-				copy = options[ name ];
-
-				// Prevent never-ending loop
-				if ( target === copy ) {
-					continue;
-				}
-
-				// Recurse if we're merging plain objects or arrays
-				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
-					if ( copyIsArray ) {
-						copyIsArray = false;
-						clone = src && jQuery.isArray(src) ? src : [];
-
-					} else {
-						clone = src && jQuery.isPlainObject(src) ? src : {};
-					}
-
-					// Never move original objects, clone them
-					target[ name ] = jQuery.extend( deep, clone, copy );
-
-				// Don't bring in undefined values
-				} else if ( copy !== undefined ) {
-					target[ name ] = copy;
-				}
-			}
-		}
-	}
-
-	// Return the modified object
-	return target;
-};
-
-jQuery.extend({
-	// Unique for each copy of jQuery on the page
-	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
-	// Assume jQuery is ready without the ready module
-	isReady: true,
-
-	error: function( msg ) {
-		throw new Error( msg );
-	},
-
-	noop: function() {},
-
-	// See test/unit/core.js for details concerning isFunction.
-	// Since version 1.3, DOM methods and functions like alert
-	// aren't supported. They return false on IE (#2968).
-	isFunction: function( obj ) {
-		return jQuery.type(obj) === "function";
-	},
-
-	isArray: Array.isArray || function( obj ) {
-		return jQuery.type(obj) === "array";
-	},
-
-	isWindow: function( obj ) {
-		/* jshint eqeqeq: false */
-		return obj != null && obj == obj.window;
-	},
-
-	isNumeric: function( obj ) {
-		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
-		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
-		// subtraction forces infinities to NaN
-		// adding 1 corrects loss of precision from parseFloat (#15100)
-		return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
-	},
-
-	isEmptyObject: function( obj ) {
-		var name;
-		for ( name in obj ) {
-			return false;
-		}
-		return true;
-	},
-
-	isPlainObject: function( obj ) {
-		var key;
-
-		// Must be an Object.
-		// Because of IE, we also have to check the presence of the constructor property.
-		// Make sure that DOM nodes and window objects don't pass through, as well
-		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
-			return false;
-		}
-
-		try {
-			// Not own constructor property must be Object
-			if ( obj.constructor &&
-				!hasOwn.call(obj, "constructor") &&
-				!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
-				return false;
-			}
-		} catch ( e ) {
-			// IE8,9 Will throw exceptions on certain host objects #9897
-			return false;
-		}
-
-		// Support: IE<9
-		// Handle iteration over inherited properties before own properties.
-		if ( support.ownLast ) {
-			for ( key in obj ) {
-				return hasOwn.call( obj, key );
-			}
-		}
-
-		// Own properties are enumerated firstly, so to speed up,
-		// if last one is own, then all properties are own.
-		for ( key in obj ) {}
-
-		return key === undefined || hasOwn.call( obj, key );
-	},
-
-	type: function( obj ) {
-		if ( obj == null ) {
-			return obj + "";
-		}
-		return typeof obj === "object" || typeof obj === "function" ?
-			class2type[ toString.call(obj) ] || "object" :
-			typeof obj;
-	},
-
-	// Evaluates a script in a global context
-	// Workarounds based on findings by Jim Driscoll
-	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
-	globalEval: function( data ) {
-		if ( data && jQuery.trim( data ) ) {
-			// We use execScript on Internet Explorer
-			// We use an anonymous function so that context is window
-			// rather than jQuery in Firefox
-			( window.execScript || function( data ) {
-				window[ "eval" ].call( window, data );
-			} )( data );
-		}
-	},
-
-	// Convert dashed to camelCase; used by the css and data modules
-	// Microsoft forgot to hump their vendor prefix (#9572)
-	camelCase: function( string ) {
-		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
-	},
-
-	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-	},
-
-	// args is for internal usage only
-	each: function( obj, callback, args ) {
-		var value,
-			i = 0,
-			length = obj.length,
-			isArray = isArraylike( obj );
-
-		if ( args ) {
-			if ( isArray ) {
-				for ( ; i < length; i++ ) {
-					value = callback.apply( obj[ i ], args );
-
-					if ( value === false ) {
-						break;
-					}
-				}
-			} else {
-				for ( i in obj ) {
-					value = callback.apply( obj[ i ], args );
-
-					if ( value === false ) {
-						break;
-					}
-				}
-			}
-
-		// A special, fast, case for the most common use of each
-		} else {
-			if ( isArray ) {
-				for ( ; i < length; i++ ) {
-					value = callback.call( obj[ i ], i, obj[ i ] );
-
-					if ( value === false ) {
-						break;
-					}
-				}
-			} else {
-				for ( i in obj ) {
-					value = callback.call( obj[ i ], i, obj[ i ] );
-
-					if ( value === false ) {
-						break;
-					}
-				}
-			}
-		}
-
-		return obj;
-	},
-
-	// Support: Android<4.1, IE<9
-	trim: function( text ) {
-		return text == null ?
-			"" :
-			( text + "" ).replace( rtrim, "" );
-	},
-
-	// results is for internal usage only
-	makeArray: function( arr, results ) {
-		var ret = results || [];
-
-		if ( arr != null ) {
-			if ( isArraylike( Object(arr) ) ) {
-				jQuery.merge( ret,
-					typeof arr === "string" ?
-					[ arr ] : arr
-				);
-			} else {
-				push.call( ret, arr );
-			}
-		}
-
-		return ret;
-	},
-
-	inArray: function( elem, arr, i ) {
-		var len;
-
-		if ( arr ) {
-			if ( indexOf ) {
-				return indexOf.call( arr, elem, i );
-			}
-
-			len = arr.length;
-			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
-
-			for ( ; i < len; i++ ) {
-				// Skip accessing in sparse arrays
-				if ( i in arr && arr[ i ] === elem ) {
-					return i;
-				}
-			}
-		}
-
-		return -1;
-	},
-
-	merge: function( first, second ) {
-		var len = +second.length,
-			j = 0,
-			i = first.length;
-
-		while ( j < len ) {
-			first[ i++ ] = second[ j++ ];
-		}
-
-		// Support: IE<9
-		// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
-		if ( len !== len ) {
-			while ( second[j] !== undefined ) {
-				first[ i++ ] = second[ j++ ];
-			}
-		}
-
-		first.length = i;
-
-		return first;
-	},
-
-	grep: function( elems, callback, invert ) {
-		var callbackInverse,
-			matches = [],
-			i = 0,
-			length = elems.length,
-			callbackExpect = !invert;
-
-		// Go through the array, only saving the items
-		// that pass the validator function
-		for ( ; i < length; i++ ) {
-			callbackInverse = !callback( elems[ i ], i );
-			if ( callbackInverse !== callbackExpect ) {
-				matches.push( elems[ i ] );
-			}
-		}
-
-		return matches;
-	},
-
-	// arg is for internal usage only
-	map: function( elems, callback, arg ) {
-		var value,
-			i = 0,
-			length = elems.length,
-			isArray = isArraylike( elems ),
-			ret = [];
-
-		// Go through the array, translating each of the items to their new values
-		if ( isArray ) {
-			for ( ; i < length; i++ ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-
-		// Go through every key on the object,
-		} else {
-			for ( i in elems ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-		}
-
-		// Flatten any nested arrays
-		return concat.apply( [], ret );
-	},
-
-	// A global GUID counter for objects
-	guid: 1,
-
-	// Bind a function to a context, optionally partially applying any
-	// arguments.
-	proxy: function( fn, context ) {
-		var args, proxy, tmp;
-
-		if ( typeof context === "string" ) {
-			tmp = fn[ context ];
-			context = fn;
-			fn = tmp;
-		}
-
-		// Quick check to determine if target is callable, in the spec
-		// this throws a TypeError, but we will just return undefined.
-		if ( !jQuery.isFunction( fn ) ) {
-			return undefined;
-		}
-
-		// Simulated bind
-		args = slice.call( arguments, 2 );
-		proxy = function() {
-			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
-		};
-
-		// Set the guid of unique handler to the same of original handler, so it can be removed
-		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
-		return proxy;
-	},
-
-	now: function() {
-		return +( new Date() );
-	},
-
-	// jQuery.support is not used in Core but other projects attach their
-	// properties to it so it needs to exist.
-	support: support
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
-	class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-function isArraylike( obj ) {
-
-	// Support: iOS 8.2 (not reproducible in simulator)
-	// `in` check used to prevent JIT error (gh-2145)
-	// hasOwn isn't used here due to false negatives
-	// regarding Nodelist length in IE
-	var length = "length" in obj && obj.length,
-		type = jQuery.type( obj );
-
-	if ( type === "function" || jQuery.isWindow( obj ) ) {
-		return false;
-	}
-
-	if ( obj.nodeType === 1 && length ) {
-		return true;
-	}
-
-	return type === "array" || length === 0 ||
-		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v2.2.0-pre
- * http://sizzlejs.com/
- *
- * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-12-16
- */
-(function( window ) {
-
-var i,
-	support,
-	Expr,
-	getText,
-	isXML,
-	tokenize,
-	compile,
-	select,
-	outermostContext,
-	sortInput,
-	hasDuplicate,
-
-	// Local document vars
-	setDocument,
-	document,
-	docElem,
-	documentIsHTML,
-	rbuggyQSA,
-	rbuggyMatches,
-	matches,
-	contains,
-
-	// Instance-specific data
-	expando = "sizzle" + 1 * new Date(),
-	preferredDoc = window.document,
-	dirruns = 0,
-	done = 0,
-	classCache = createCache(),
-	tokenCache = createCache(),
-	compilerCache = createCache(),
-	sortOrder = function( a, b ) {
-		if ( a === b ) {
-			hasDuplicate = true;
-		}
-		return 0;
-	},
-
-	// General-purpose constants
-	MAX_NEGATIVE = 1 << 31,
-
-	// Instance methods
-	hasOwn = ({}).hasOwnProperty,
-	arr = [],
-	pop = arr.pop,
-	push_native = arr.push,
-	push = arr.push,
-	slice = arr.slice,
-	// Use a stripped-down indexOf as it's faster than native
-	// http://jsperf.com/thor-indexof-vs-for/5
-	indexOf = function( list, elem ) {
-		var i = 0,
-			len = list.length;
-		for ( ; i < len; i++ ) {
-			if ( list[i] === elem ) {
-				return i;
-			}
-		}
-		return -1;
-	},
-
-	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
-	// Regular expressions
-
-	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
-	whitespace = "[\\x20\\t\\r\\n\\f]",
-	// http://www.w3.org/TR/css3-syntax/#characters
-	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
-	// Loosely modeled on CSS identifier characters
-	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
-	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
-	identifier = characterEncoding.replace( "w", "w#" ),
-
-	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
-	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
-		// Operator (capture 2)
-		"*([*^$|!~]?=)" + whitespace +
-		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
-		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
-		"*\\]",
-
-	pseudos = ":(" + characterEncoding + ")(?:\\((" +
-		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
-		// 1. quoted (capture 3; capture 4 or capture 5)
-		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
-		// 2. simple (capture 6)
-		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
-		// 3. anything else (capture 2)
-		".*" +
-		")\\)|)",
-
-	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
-	rwhitespace = new RegExp( whitespace + "+", "g" ),
-	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
-	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
-	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
-	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
-	rpseudo = new RegExp( pseudos ),
-	ridentifier = new RegExp( "^" + identifier + "$" ),
-
-	matchExpr = {
-		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
-		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
-		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
-		"ATTR": new RegExp( "^" + attributes ),
-		"PSEUDO": new RegExp( "^" + pseudos ),
-		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
-			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
-			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
-		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
-		// For use in libraries implementing .is()
-		// We use this for POS matching in `select`
-		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
-			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
-	},
-
-	rinputs = /^(?:input|select|textarea|button)$/i,
-	rheader = /^h\d$/i,
-
-	rnative = /^[^{]+\{\s*\[native \w/,
-
-	// Easily-parseable/retrievable ID or TAG or CLASS selectors
-	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
-	rsibling = /[+~]/,
-	rescape = /'|\\/g,
-
-	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
-	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
-	funescape = function( _, escaped, escapedWhitespace ) {
-		var high = "0x" + escaped - 0x10000;
-		// NaN means non-codepoint
-		// Support: Firefox<24
-		// Workaround erroneous numeric interpretation of +"0x"
-		return high !== high || escapedWhitespace ?
-			escaped :
-			high < 0 ?
-				// BMP codepoint
-				String.fromCharCode( high + 0x10000 ) :
-				// Supplemental Plane codepoint (surrogate pair)
-				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
-	},
-
-	// Used for iframes
-	// See setDocument()
-	// Removing the function wrapper causes a "Permission Denied"
-	// error in IE
-	unloadHandler = function() {
-		setDocument();
-	};
-
-// Optimize for push.apply( _, NodeList )
-try {
-	push.apply(
-		(arr = slice.call( preferredDoc.childNodes )),
-		preferredDoc.childNodes
-	);
-	// Support: Android<4.0
-	// Detect silently failing push.apply
-	arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
-	push = { apply: arr.length ?
-
-		// Leverage slice if possible
-		function( target, els ) {
-			push_native.apply( target, slice.call(els) );
-		} :
-
-		// Support: IE<9
-		// Otherwise append directly
-		function( target, els ) {
-			var j = target.length,
-				i = 0;
-			// Can't trust NodeList.length
-			while ( (target[j++] = els[i++]) ) {}
-			target.length = j - 1;
-		}
-	};
-}
-
-function Sizzle( selector, context, results, seed ) {
-	var match, elem, m, nodeType,
-		// QSA vars
-		i, groups, old, nid, newContext, newSelector;
-
-	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
-		setDocument( context );
-	}
-
-	context = context || document;
-	results = results || [];
-	nodeType = context.nodeType;
-
-	if ( typeof selector !== "string" || !selector ||
-		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
-		return results;
-	}
-
-	if ( !seed && documentIsHTML ) {
-
-		// Try to shortcut find operations when possible (e.g., not under DocumentFragment)
-		if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
-			// Speed-up: Sizzle("#ID")
-			if ( (m = match[1]) ) {
-				if ( nodeType === 9 ) {
-					elem = context.getElementById( m );
-					// Check parentNode to catch when Blackberry 4.6 returns
-					// nodes that are no longer in the document (jQuery #6963)
-					if ( elem && elem.parentNode ) {
-						// Handle the case where IE, Opera, and Webkit return items
-						// by name instead of ID
-						if ( elem.id === m ) {
-							results.push( elem );
-							return results;
-						}
-					} else {
-						return results;
-					}
-				} else {
-					// Context is not a document
-					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
-						contains( context, elem ) && elem.id === m ) {
-						results.push( elem );
-						return results;
-					}
-				}
-
-			// Speed-up: Sizzle("TAG")
-			} else if ( match[2] ) {
-				push.apply( results, context.getElementsByTagName( selector ) );
-				return results;
-
-			// Speed-up: Sizzle(".CLASS")
-			} else if ( (m = match[3]) && support.getElementsByClassName ) {
-				push.apply( results, context.getElementsByClassName( m ) );
-				return results;
-			}
-		}
-
-		// QSA path
-		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
-			nid = old = expando;
-			newContext = context;
-			newSelector = nodeType !== 1 && selector;
-
-			// qSA works strangely on Element-rooted queries
-			// We can work around this by specifying an extra ID on the root
-			// and working up from there (Thanks to Andrew Dupont for the technique)
-			// IE 8 doesn't work on object elements
-			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
-				groups = tokenize( selector );
-
-				if ( (old = context.getAttribute("id")) ) {
-					nid = old.replace( rescape, "\\$&" );
-				} else {
-					context.setAttribute( "id", nid );
-				}
-				nid = "[id='" + nid + "'] ";
-
-				i = groups.length;
-				while ( i-- ) {
-					groups[i] = nid + toSelector( groups[i] );
-				}
-				newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
-				newSelector = groups.join(",");
-			}
-
-			if ( newSelector ) {
-				try {
-					push.apply( results,
-						newContext.querySelectorAll( newSelector )
-					);
-					return results;
-				} catch(qsaError) {
-				} finally {
-					if ( !old ) {
-						context.removeAttribute("id");
-					}
-				}
-			}
-		}
-	}
-
-	// All others
-	return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
- *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- *	deleting the oldest entry
- */
-function createCache() {
-	var keys = [];
-
-	function cache( key, value ) {
-		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
-		if ( keys.push( key + " " ) > Expr.cacheLength ) {
-			// Only keep the most recent entries
-			delete cache[ keys.shift() ];
-		}
-		return (cache[ key + " " ] = value);
-	}
-	return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
-	fn[ expando ] = true;
-	return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
-	var div = document.createElement("div");
-
-	try {
-		return !!fn( div );
-	} catch (e) {
-		return false;
-	} finally {
-		// Remove from its parent by default
-		if ( div.parentNode ) {
-			div.parentNode.removeChild( div );
-		}
-		// release memory in IE
-		div = null;
-	}
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
-	var arr = attrs.split("|"),
-		i = attrs.length;
-
-	while ( i-- ) {
-		Expr.attrHandle[ arr[i] ] = handler;
-	}
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
-	var cur = b && a,
-		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
-			( ~b.sourceIndex || MAX_NEGATIVE ) -
-			( ~a.sourceIndex || MAX_NEGATIVE );
-
-	// Use IE sourceIndex if available on both nodes
-	if ( diff ) {
-		return diff;
-	}
-
-	// Check if b follows a
-	if ( cur ) {
-		while ( (cur = cur.nextSibling) ) {
-			if ( cur === b ) {
-				return -1;
-			}
-		}
-	}
-
-	return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return name === "input" && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return (name === "input" || name === "button") && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
-	return markFunction(function( argument ) {
-		argument = +argument;
-		return markFunction(function( seed, matches ) {
-			var j,
-				matchIndexes = fn( [], seed.length, argument ),
-				i = matchIndexes.length;
-
-			// Match elements found at the specified indexes
-			while ( i-- ) {
-				if ( seed[ (j = matchIndexes[i]) ] ) {
-					seed[j] = !(matches[j] = seed[j]);
-				}
-			}
-		});
-	});
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
-	return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
-	// documentElement is verified for cases where it doesn't yet exist
-	// (such as loading iframes in IE - #4833)
-	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
-	return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
-	var hasCompare, parent,
-		doc = node ? node.ownerDocument || node : preferredDoc;
-
-	// If no document and documentElement is available, return
-	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
-		return document;
-	}
-
-	// Set our document
-	document = doc;
-	docElem = doc.documentElement;
-	parent = doc.defaultView;
-
-	// Support: IE>8
-	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
-	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
-	// IE6-8 do not support the defaultView property so parent will be undefined
-	if ( parent && parent !== parent.top ) {
-		// IE11 does not have attachEvent, so all must suffer
-		if ( parent.addEventListener ) {
-			parent.addEventListener( "unload", unloadHandler, false );
-		} else if ( parent.attachEvent ) {
-			parent.attachEvent( "onunload", unloadHandler );
-		}
-	}
-
-	/* Support tests
-	---------------------------------------------------------------------- */
-	documentIsHTML = !isXML( doc );
-
-	/* Attributes
-	---------------------------------------------------------------------- */
-
-	// Support: IE<8
-	// Verify that getAttribute really returns attributes and not properties
-	// (excepting IE8 booleans)
-	support.attributes = assert(function( div ) {
-		div.className = "i";
-		return !div.getAttribute("className");
-	});
-
-	/* getElement(s)By*
-	---------------------------------------------------------------------- */
-
-	// Check if getElementsByTagName("*") returns only elements
-	support.getElementsByTagName = assert(function( div ) {
-		div.appendChild( doc.createComment("") );
-		return !div.getElementsByTagName("*").length;
-	});
-
-	// Support: IE<9
-	support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
-
-	// Support: IE<10
-	// Check if getElementById returns elements by name
-	// The broken getElementById methods don't pick up programatically-set names,
-	// so use a roundabout getElementsByName test
-	support.getById = assert(function( div ) {
-		docElem.appendChild( div ).id = expando;
-		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
-	});
-
-	// ID find and filter
-	if ( support.getById ) {
-		Expr.find["ID"] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var m = context.getElementById( id );
-				// Check parentNode to catch when Blackberry 4.6 returns
-				// nodes that are no longer in the document #6963
-				return m && m.parentNode ? [ m ] : [];
-			}
-		};
-		Expr.filter["ID"] = function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				return elem.getAttribute("id") === attrId;
-			};
-		};
-	} else {
-		// Support: IE6/7
-		// getElementById is not reliable as a find shortcut
-		delete Expr.find["ID"];
-
-		Expr.filter["ID"] =  function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-				return node && node.value === attrId;
-			};
-		};
-	}
-
-	// Tag
-	Expr.find["TAG"] = support.getElementsByTagName ?
-		function( tag, context ) {
-			if ( typeof context.getElementsByTagName !== "undefined" ) {
-				return context.getElementsByTagName( tag );
-
-			// DocumentFragment nodes don't have gEBTN
-			} else if ( support.qsa ) {
-				return context.querySelectorAll( tag );
-			}
-		} :
-
-		function( tag, context ) {
-			var elem,
-				tmp = [],
-				i = 0,
-				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
-				results = context.getElementsByTagName( tag );
-
-			// Filter out possible comments
-			if ( tag === "*" ) {
-				while ( (elem = results[i++]) ) {
-					if ( elem.nodeType === 1 ) {
-						tmp.push( elem );
-					}
-				}
-
-				return tmp;
-			}
-			return results;
-		};
-
-	// Class
-	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
-		if ( documentIsHTML ) {
-			return context.getElementsByClassName( className );
-		}
-	};
-
-	/* QSA/matchesSelector
-	---------------------------------------------------------------------- */
-
-	// QSA and matchesSelector support
-
-	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
-	rbuggyMatches = [];
-
-	// qSa(:focus) reports false when true (Chrome 21)
-	// We allow this because of a bug in IE8/9 that throws an error
-	// whenever `document.activeElement` is accessed on an iframe
-	// So, we allow :focus to pass through QSA all the time to avoid the IE error
-	// See http://bugs.jquery.com/ticket/13378
-	rbuggyQSA = [];
-
-	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
-		// Build QSA regex
-		// Regex strategy adopted from Diego Perini
-		assert(function( div ) {
-			// Select is set to empty string on purpose
-			// This is to test IE's treatment of not explicitly
-			// setting a boolean content attribute,
-			// since its presence should be enough
-			// http://bugs.jquery.com/ticket/12359
-			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
-				"<select id='" + expando + "-\f]' msallowcapture=''>" +
-				"<option selected=''></option></select>";
-
-			// Support: IE8, Opera 11-12.16
-			// Nothing should be selected when empty strings follow ^= or $= or *=
-			// The test attribute must be unknown in Opera but "safe" for WinRT
-			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
-			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
-				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
-			}
-
-			// Support: IE8
-			// Boolean attributes and "value" are not treated correctly
-			if ( !div.querySelectorAll("[selected]").length ) {
-				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
-			}
-
-			// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
-			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
-				rbuggyQSA.push("~=");
-			}
-
-			// Webkit/Opera - :checked should return selected option elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			// IE8 throws error here and will not see later tests
-			if ( !div.querySelectorAll(":checked").length ) {
-				rbuggyQSA.push(":checked");
-			}
-
-			// Support: Safari 8+, iOS 8+
-			// https://bugs.webkit.org/show_bug.cgi?id=136851
-			// In-page `selector#id sibing-combinator selector` fails
-			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
-				rbuggyQSA.push(".#.+[+~]");
-			}
-		});
-
-		assert(function( div ) {
-			// Support: Windows 8 Native Apps
-			// The type and name attributes are restricted during .innerHTML assignment
-			var input = doc.createElement("input");
-			input.setAttribute( "type", "hidden" );
-			div.appendChild( input ).setAttribute( "name", "D" );
-
-			// Support: IE8
-			// Enforce case-sensitivity of name attribute
-			if ( div.querySelectorAll("[name=d]").length ) {
-				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
-			}
-
-			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
-			// IE8 throws error here and will not see later tests
-			if ( !div.querySelectorAll(":enabled").length ) {
-				rbuggyQSA.push( ":enabled", ":disabled" );
-			}
-
-			// Opera 10-11 does not throw on post-comma invalid pseudos
-			div.querySelectorAll("*,:x");
-			rbuggyQSA.push(",.*:");
-		});
-	}
-
-	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
-		docElem.webkitMatchesSelector ||
-		docElem.mozMatchesSelector ||
-		docElem.oMatchesSelector ||
-		docElem.msMatchesSelector) )) ) {
-
-		assert(function( div ) {
-			// Check to see if it's possible to do matchesSelector
-			// on a disconnected node (IE 9)
-			support.disconnectedMatch = matches.call( div, "div" );
-
-			// This should fail with an exception
-			// Gecko does not error, returns false instead
-			matches.call( div, "[s!='']:x" );
-			rbuggyMatches.push( "!=", pseudos );
-		});
-	}
-
-	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
-	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
-	/* Contains
-	---------------------------------------------------------------------- */
-	hasCompare = rnative.test( docElem.compareDocumentPosition );
-
-	// Element contains another
-	// Purposefully does not implement inclusive descendent
-	// As in, an element does not contain itself
-	contains = hasCompare || rnative.test( docElem.contains ) ?
-		function( a, b ) {
-			var adown = a.nodeType === 9 ? a.documentElement : a,
-				bup = b && b.parentNode;
-			return a === bup || !!( bup && bup.nodeType === 1 && (
-				adown.contains ?
-					adown.contains( bup ) :
-					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
-			));
-		} :
-		function( a, b ) {
-			if ( b ) {
-				while ( (b = b.parentNode) ) {
-					if ( b === a ) {
-						return true;
-					}
-				}
-			}
-			return false;
-		};
-
-	/* Sorting
-	---------------------------------------------------------------------- */
-
-	// Document order sorting
-	sortOrder = hasCompare ?
-	function( a, b ) {
-
-		// Flag for duplicate removal
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		// Sort on method existence if only one input has compareDocumentPosition
-		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
-		if ( compare ) {
-			return compare;
-		}
-
-		// Calculate position if both inputs belong to the same document
-		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
-			a.compareDocumentPosition( b ) :
-
-			// Otherwise we know they are disconnected
-			1;
-
-		// Disconnected nodes
-		if ( compare & 1 ||
-			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
-			// Choose the first element that is related to our preferred document
-			if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
-				return -1;
-			}
-			if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
-				return 1;
-			}
-
-			// Maintain original order
-			return sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-		}
-
-		return compare & 4 ? -1 : 1;
-	} :
-	function( a, b ) {
-		// Exit early if the nodes are identical
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		var cur,
-			i = 0,
-			aup = a.parentNode,
-			bup = b.parentNode,
-			ap = [ a ],
-			bp = [ b ];
-
-		// Parentless nodes are either documents or disconnected
-		if ( !aup || !bup ) {
-			return a === doc ? -1 :
-				b === doc ? 1 :
-				aup ? -1 :
-				bup ? 1 :
-				sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-
-		// If the nodes are siblings, we can do a quick check
-		} else if ( aup === bup ) {
-			return siblingCheck( a, b );
-		}
-
-		// Otherwise we need full lists of their ancestors for comparison
-		cur = a;
-		while ( (cur = cur.parentNode) ) {
-			ap.unshift( cur );
-		}
-		cur = b;
-		while ( (cur = cur.parentNode) ) {
-			bp.unshift( cur );
-		}
-
-		// Walk down the tree looking for a discrepancy
-		while ( ap[i] === bp[i] ) {
-			i++;
-		}
-
-		return i ?
-			// Do a sibling check if the nodes have a common ancestor
-			siblingCheck( ap[i], bp[i] ) :
-
-			// Otherwise nodes in our document sort first
-			ap[i] === preferredDoc ? -1 :
-			bp[i] === preferredDoc ? 1 :
-			0;
-	};
-
-	return doc;
-};
-
-Sizzle.matches = function( expr, elements ) {
-	return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
-	// Set document vars if needed
-	if ( ( elem.ownerDocument || elem ) !== document ) {
-		setDocument( elem );
-	}
-
-	// Make sure that attribute selectors are quoted
-	expr = expr.replace( rattributeQuotes, "='$1']" );
-
-	if ( support.matchesSelector && documentIsHTML &&
-		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
-		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
-
-		try {
-			var ret = matches.call( elem, expr );
-
-			// IE 9's matchesSelector returns false on disconnected nodes
-			if ( ret || support.disconnectedMatch ||
-					// As well, disconnected nodes are said to be in a document
-					// fragment in IE 9
-					elem.document && elem.document.nodeType !== 11 ) {
-				return ret;
-			}
-		} catch (e) {}
-	}
-
-	return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
-	// Set document vars if needed
-	if ( ( context.ownerDocument || context ) !== document ) {
-		setDocument( context );
-	}
-	return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
-	// Set document vars if needed
-	if ( ( elem.ownerDocument || elem ) !== document ) {
-		setDocument( elem );
-	}
-
-	var fn = Expr.attrHandle[ name.toLowerCase() ],
-		// Don't get fooled by Object.prototype properties (jQuery #13807)
-		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
-			fn( elem, name, !documentIsHTML ) :
-			undefined;
-
-	return val !== undefined ?
-		val :
-		support.attributes || !documentIsHTML ?
-			elem.getAttribute( name ) :
-			(val = elem.getAttributeNode(name)) && val.specified ?
-				val.value :
-				null;
-};
-
-Sizzle.error = function( msg ) {
-	throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
-	var elem,
-		duplicates = [],
-		j = 0,
-		i = 0;
-
-	// Unless we *know* we can detect duplicates, assume their presence
-	hasDuplicate = !support.detectDuplicates;
-	sortInput = !support.sortStable && results.slice( 0 );
-	results.sort( sortOrder );
-
-	if ( hasDuplicate ) {
-		while ( (elem = results[i++]) ) {
-			if ( elem === results[ i ] ) {
-				j = duplicates.push( i );
-			}
-		}
-		while ( j-- ) {
-			results.splice( duplicates[ j ], 1 );
-		}
-	}
-
-	// Clear input after sorting to release objects
-	// See https://github.com/jquery/sizzle/pull/225
-	sortInput = null;
-
-	return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
-	var node,
-		ret = "",
-		i = 0,
-		nodeType = elem.nodeType;
-
-	if ( !nodeType ) {
-		// If no nodeType, this is expected to be an array
-		while ( (node = elem[i++]) ) {
-			// Do not traverse comment nodes
-			ret += getText( node );
-		}
-	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
-		// Use textContent for elements
-		// innerText usage removed for consistency of new lines (jQuery #11153)
-		if ( typeof elem.textContent === "string" ) {
-			return elem.textContent;
-		} else {
-			// Traverse its children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				ret += getText( elem );
-			}
-		}
-	} else if ( nodeType === 3 || nodeType === 4 ) {
-		return elem.nodeValue;
-	}
-	// Do not include comment or processing instruction nodes
-
-	return ret;
-};
-
-Expr = Sizzle.selectors = {
-
-	// Can be adjusted by the user
-	cacheLength: 50,
-
-	createPseudo: markFunction,
-
-	match: matchExpr,
-
-	attrHandle: {},
-
-	find: {},
-
-	relative: {
-		">": { dir: "parentNode", first: true },
-		" ": { dir: "parentNode" },
-		"+": { dir: "previousSibling", first: true },
-		"~": { dir: "previousSibling" }
-	},
-
-	preFilter: {
-		"ATTR": function( match ) {
-			match[1] = match[1].replace( runescape, funescape );
-
-			// Move the given value to match[3] whether quoted or unquoted
-			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
-
-			if ( match[2] === "~=" ) {
-				match[3] = " " + match[3] + " ";
-			}
-
-			return match.slice( 0, 4 );
-		},
-
-		"CHILD": function( match ) {
-			/* matches from matchExpr["CHILD"]
-				1 type (only|nth|...)
-				2 what (child|of-type)
-				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
-				4 xn-component of xn+y argument ([+-]?\d*n|)
-				5 sign of xn-component
-				6 x of xn-component
-				7 sign of y-component
-				8 y of y-component
-			*/
-			match[1] = match[1].toLowerCase();
-
-			if ( match[1].slice( 0, 3 ) === "nth" ) {
-				// nth-* requires argument
-				if ( !match[3] ) {
-					Sizzle.error( match[0] );
-				}
-
-				// numeric x and y parameters for Expr.filter.CHILD
-				// remember that false/true cast respectively to 0/1
-				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
-				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
-			// other types prohibit arguments
-			} else if ( match[3] ) {
-				Sizzle.error( match[0] );
-			}
-
-			return match;
-		},
-
-		"PSEUDO": function( match ) {
-			var excess,
-				unquoted = !match[6] && match[2];
-
-			if ( matchExpr["CHILD"].test( match[0] ) ) {
-				return null;
-			}
-
-			// Accept quoted arguments as-is
-			if ( match[3] ) {
-				match[2] = match[4] || match[5] || "";
-
-			// Strip excess characters from unquoted arguments
-			} else if ( unquoted && rpseudo.test( unquoted ) &&
-				// Get excess from tokenize (recursively)
-				(excess = tokenize( unquoted, true )) &&
-				// advance to the next closing parenthesis
-				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
-				// excess is a negative index
-				match[0] = match[0].slice( 0, excess );
-				match[2] = unquoted.slice( 0, excess );
-			}
-
-			// Return only captures needed by the pseudo filter method (type and argument)
-			return match.slice( 0, 3 );
-		}
-	},
-
-	filter: {
-
-		"TAG": function( nodeNameSelector ) {
-			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
-			return nodeNameSelector === "*" ?
-				function() { return true; } :
-				function( elem ) {
-					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
-				};
-		},
-
-		"CLASS": function( className ) {
-			var pattern = classCache[ className + " " ];
-
-			return pattern ||
-				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
-				classCache( className, function( elem ) {
-					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
-				});
-		},
-
-		"ATTR": function( name, operator, check ) {
-			return function( elem ) {
-				var result = Sizzle.attr( elem, name );
-
-				if ( result == null ) {
-					return operator === "!=";
-				}
-				if ( !operator ) {
-					return true;
-				}
-
-				result += "";
-
-				return operator === "=" ? result === check :
-					operator === "!=" ? result !== check :
-					operator === "^=" ? check && result.indexOf( check ) === 0 :
-					operator === "*=" ? check && result.indexOf( check ) > -1 :
-					operator === "$=" ? check && result.slice( -check.length ) === check :
-					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
-					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
-					false;
-			};
-		},
-
-		"CHILD": function( type, what, argument, first, last ) {
-			var simple = type.slice( 0, 3 ) !== "nth",
-				forward = type.slice( -4 ) !== "last",
-				ofType = what === "of-type";
-
-			return first === 1 && last === 0 ?
-
-				// Shortcut for :nth-*(n)
-				function( elem ) {
-					return !!elem.parentNode;
-				} :
-
-				function( elem, context, xml ) {
-					var cache, outerCache, node, diff, nodeIndex, start,
-						dir = simple !== forward ? "nextSibling" : "previousSibling",
-						parent = elem.parentNode,
-						name = ofType && elem.nodeName.toLowerCase(),
-						useCache = !xml && !ofType;
-
-					if ( parent ) {
-
-						// :(first|last|only)-(child|of-type)
-						if ( simple ) {
-							while ( dir ) {
-								node = elem;
-								while ( (node = node[ dir ]) ) {
-									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
-										return false;
-									}
-								}
-								// Reverse direction for :only-* (if we haven't yet done so)
-								start = dir = type === "only" && !start && "nextSibling";
-							}
-							return true;
-						}
-
-						start = [ forward ? parent.firstChild : parent.lastChild ];
-
-						// non-xml :nth-child(...) stores cache data on `parent`
-						if ( forward && useCache ) {
-							// Seek `elem` from a previously-cached index
-							outerCache = parent[ expando ] || (parent[ expando ] = {});
-							cache = outerCache[ type ] || [];
-							nodeIndex = cache[0] === dirruns && cache[1];
-							diff = cache[0] === dirruns && cache[2];
-							node = nodeIndex && parent.childNodes[ nodeIndex ];
-
-							while ( (node = ++nodeIndex && node && node[ dir ] ||
-
-								// Fallback to seeking `elem` from the start
-								(diff = nodeIndex = 0) || start.pop()) ) {
-
-								// When found, cache indexes on `parent` and break
-								if ( node.nodeType === 1 && ++diff && node === elem ) {
-									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
-									break;
-								}
-							}
-
-						// Use previously-cached element index if available
-						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
-							diff = cache[1];
-
-						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
-						} else {
-							// Use the same loop as above to seek `elem` from the start
-							while ( (node = ++nodeIndex && node && node[ dir ] ||
-								(diff = nodeIndex = 0) || start.pop()) ) {
-
-								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
-									// Cache the index of each encountered element
-									if ( useCache ) {
-										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
-									}
-
-									if ( node === elem ) {
-										break;
-									}
-								}
-							}
-						}
-
-						// Incorporate the offset, then check against cycle size
-						diff -= last;
-						return diff === first || ( diff % first === 0 && diff / first >= 0 );
-					}
-				};
-		},
-
-		"PSEUDO": function( pseudo, argument ) {
-			// pseudo-class names are case-insensitive
-			// http://www.w3.org/TR/selectors/#pseudo-classes
-			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
-			// Remember that setFilters inherits from pseudos
-			var args,
-				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
-					Sizzle.error( "unsupported pseudo: " + pseudo );
-
-			// The user may use createPseudo to indicate that
-			// arguments are needed to create the filter function
-			// just as Sizzle does
-			if ( fn[ expando ] ) {
-				return fn( argument );
-			}
-
-			// But maintain support for old signatures
-			if ( fn.length > 1 ) {
-				args = [ pseudo, pseudo, "", argument ];
-				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
-					markFunction(function( seed, matches ) {
-						var idx,
-							matched = fn( seed, argument ),
-							i = matched.length;
-						while ( i-- ) {
-							idx = indexOf( seed, matched[i] );
-							seed[ idx ] = !( matches[ idx ] = matched[i] );
-						}
-					}) :
-					function( elem ) {
-						return fn( elem, 0, args );
-					};
-			}
-
-			return fn;
-		}
-	},
-
-	pseudos: {
-		// Potentially complex pseudos
-		"not": markFunction(function( selector ) {
-			// Trim the selector passed to compile
-			// to avoid treating leading and trailing
-			// spaces as combinators
-			var input = [],
-				results = [],
-				matcher = compile( selector.replace( rtrim, "$1" ) );
-
-			return matcher[ expando ] ?
-				markFunction(function( seed, matches, context, xml ) {
-					var elem,
-						unmatched = matcher( seed, null, xml, [] ),
-						i = seed.length;
-
-					// Match elements unmatched by `matcher`
-					while ( i-- ) {
-						if ( (elem = unmatched[i]) ) {
-							seed[i] = !(matches[i] = elem);
-						}
-					}
-				}) :
-				function( elem, context, xml ) {
-					input[0] = elem;
-					matcher( input, null, xml, results );
-					// Don't keep the element (issue #299)
-					input[0] = null;
-					return !results.pop();
-				};
-		}),
-
-		"has": markFunction(function( selector ) {
-			return function( elem ) {
-				return Sizzle( selector, elem ).length > 0;
-			};
-		}),
-
-		"contains": markFunction(function( text ) {
-			text = text.replace( runescape, funescape );
-			return function( elem ) {
-				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
-			};
-		}),
-
-		// "Whether an element is represented by a :lang() selector
-		// is based solely on the element's language value
-		// being equal to the identifier C,
-		// or beginning with the identifier C immediately followed by "-".
-		// The matching of C against the element's language value is performed case-insensitively.
-		// The identifier C does not have to be a valid language name."
-		// http://www.w3.org/TR/selectors/#lang-pseudo
-		"lang": markFunction( function( lang ) {
-			// lang value must be a valid identifier
-			if ( !ridentifier.test(lang || "") ) {
-				Sizzle.error( "unsupported lang: " + lang );
-			}
-			lang = lang.replace( runescape, funescape ).toLowerCase();
-			return function( elem ) {
-				var elemLang;
-				do {
-					if ( (elemLang = documentIsHTML ?
-						elem.lang :
-						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
-						elemLang = elemLang.toLowerCase();
-						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
-					}
-				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
-				return false;
-			};
-		}),
-
-		// Miscellaneous
-		"target": function( elem ) {
-			var hash = window.location && window.location.hash;
-			return hash && hash.slice( 1 ) === elem.id;
-		},
-
-		"root": function( elem ) {
-			return elem === docElem;
-		},
-
-		"focus": function( elem ) {
-			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
-		},
-
-		// Boolean properties
-		"enabled": function( elem ) {
-			return elem.disabled === false;
-		},
-
-		"disabled": function( elem ) {
-			return elem.disabled === true;
-		},
-
-		"checked": function( elem ) {
-			// In CSS3, :checked should return both checked and selected elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			var nodeName = elem.nodeName.toLowerCase();
-			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
-		},
-
-		"selected": function( elem ) {
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			if ( elem.parentNode ) {
-				elem.parentNode.selectedIndex;
-			}
-
-			return elem.selected === true;
-		},
-
-		// Contents
-		"empty": function( elem ) {
-			// http://www.w3.org/TR/selectors/#empty-pseudo
-			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
-			//   but not by others (comment: 8; processing instruction: 7; etc.)
-			// nodeType < 6 works because attributes (2) do not appear as children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				if ( elem.nodeType < 6 ) {
-					return false;
-				}
-			}
-			return true;
-		},
-
-		"parent": function( elem ) {
-			return !Expr.pseudos["empty"]( elem );
-		},
-
-		// Element/input types
-		"header": function( elem ) {
-			return rheader.test( elem.nodeName );
-		},
-
-		"input": function( elem ) {
-			return rinputs.test( elem.nodeName );
-		},
-
-		"button": function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return name === "input" && elem.type === "button" || name === "button";
-		},
-
-		"text": function( elem ) {
-			var attr;
-			return elem.nodeName.toLowerCase() === "input" &&
-				elem.type === "text" &&
-
-				// Support: IE<8
-				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
-				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
-		},
-
-		// Position-in-collection
-		"first": createPositionalPseudo(function() {
-			return [ 0 ];
-		}),
-
-		"last": createPositionalPseudo(function( matchIndexes, length ) {
-			return [ length - 1 ];
-		}),
-
-		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			return [ argument < 0 ? argument + length : argument ];
-		}),
-
-		"even": createPositionalPseudo(function( matchIndexes, length ) {
-			var i = 0;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"odd": createPositionalPseudo(function( matchIndexes, length ) {
-			var i = 1;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; --i >= 0; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; ++i < length; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		})
-	}
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
-	Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
-	Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
-	var matched, match, tokens, type,
-		soFar, groups, preFilters,
-		cached = tokenCache[ selector + " " ];
-
-	if ( cached ) {
-		return parseOnly ? 0 : cached.slice( 0 );
-	}
-
-	soFar = selector;
-	groups = [];
-	preFilters = Expr.preFilter;
-
-	while ( soFar ) {
-
-		// Comma and first run
-		if ( !matched || (match = rcomma.exec( soFar )) ) {
-			if ( match ) {
-				// Don't consume trailing commas as valid
-				soFar = soFar.slice( match[0].length ) || soFar;
-			}
-			groups.push( (tokens = []) );
-		}
-
-		matched = false;
-
-		// Combinators
-		if ( (match = rcombinators.exec( soFar )) ) {
-			matched = match.shift();
-			tokens.push({
-				value: matched,
-				// Cast descendant combinators to space
-				type: match[0].replace( rtrim, " " )
-			});
-			soFar = soFar.slice( matched.length );
-		}
-
-		// Filters
-		for ( type in Expr.filter ) {
-			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
-				(match = preFilters[ type ]( match ))) ) {
-				matched = match.shift();
-				tokens.push({
-					value: matched,
-					type: type,
-					matches: match
-				});
-				soFar = soFar.slice( matched.length );
-			}
-		}
-
-		if ( !matched ) {
-			break;
-		}
-	}
-
-	// Return the length of the invalid excess
-	// if we're just parsing
-	// Otherwise, throw an error or return tokens
-	return parseOnly ?
-		soFar.length :
-		soFar ?
-			Sizzle.error( selector ) :
-			// Cache the tokens
-			tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
-	var i = 0,
-		len = tokens.length,
-		selector = "";
-	for ( ; i < len; i++ ) {
-		selector += tokens[i].value;
-	}
-	return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
-	var dir = combinator.dir,
-		checkNonElements = base && dir === "parentNode",
-		doneName = done++;
-
-	return combinator.first ?
-		// Check against closest ancestor/preceding element
-		function( elem, context, xml ) {
-			while ( (elem = elem[ dir ]) ) {
-				if ( elem.nodeType === 1 || checkNonElements ) {
-					return matcher( elem, context, xml );
-				}
-			}
-		} :
-
-		// Check against all ancestor/preceding elements
-		function( elem, context, xml ) {
-			var oldCache, outerCache,
-				newCache = [ dirruns, doneName ];
-
-			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
-			if ( xml ) {
-				while ( (elem = elem[ dir ]) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						if ( matcher( elem, context, xml ) ) {
-							return true;
-						}
-					}
-				}
-			} else {
-				while ( (elem = elem[ dir ]) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						outerCache = elem[ expando ] || (elem[ expando ] = {});
-						if ( (oldCache = outerCache[ dir ]) &&
-							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
-							// Assign to newCache so results back-propagate to previous elements
-							return (newCache[ 2 ] = oldCache[ 2 ]);
-						} else {
-							// Reuse newcache so results back-propagate to previous elements
-							outerCache[ dir ] = newCache;
-
-							// A match means we're done; a fail means we have to keep checking
-							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
-								return true;
-							}
-						}
-					}
-				}
-			}
-		};
-}
-
-function elementMatcher( matchers ) {
-	return matchers.length > 1 ?
-		function( elem, context, xml ) {
-			var i = matchers.length;
-			while ( i-- ) {
-				if ( !matchers[i]( elem, context, xml ) ) {
-					return false;
-				}
-			}
-			return true;
-		} :
-		matchers[0];
-}
-
-function multipleContexts( selector, contexts, results ) {
-	var i = 0,
-		len = contexts.length;
-	for ( ; i < len; i++ ) {
-		Sizzle( selector, contexts[i], results );
-	}
-	return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
-	var elem,
-		newUnmatched = [],
-		i = 0,
-		len = unmatched.length,
-		mapped = map != null;
-
-	for ( ; i < len; i++ ) {
-		if ( (elem = unmatched[i]) ) {
-			if ( !filter || filter( elem, context, xml ) ) {
-				newUnmatched.push( elem );
-				if ( mapped ) {
-					map.push( i );
-				}
-			}
-		}
-	}
-
-	return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
-	if ( postFilter && !postFilter[ expando ] ) {
-		postFilter = setMatcher( postFilter );
-	}
-	if ( postFinder && !postFinder[ expando ] ) {
-		postFinder = setMatcher( postFinder, postSelector );
-	}
-	return markFunction(function( seed, results, context, xml ) {
-		var temp, i, elem,
-			preMap = [],
-			postMap = [],
-			preexisting = results.length,
-
-			// Get initial elements from seed or context
-			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
-			// Prefilter to get matcher input, preserving a map for seed-results synchronization
-			matcherIn = preFilter && ( seed || !selector ) ?
-				condense( elems, preMap, preFilter, context, xml ) :
-				elems,
-
-			matcherOut = matcher ?
-				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
-				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
-					// ...intermediate processing is necessary
-					[] :
-
-					// ...otherwise use results directly
-					results :
-				matcherIn;
-
-		// Find primary matches
-		if ( matcher ) {
-			matcher( matcherIn, matcherOut, context, xml );
-		}
-
-		// Apply postFilter
-		if ( postFilter ) {
-			temp = condense( matcherOut, postMap );
-			postFilter( temp, [], context, xml );
-
-			// Un-match failing elements by moving them back to matcherIn
-			i = temp.length;
-			while ( i-- ) {
-				if ( (elem = temp[i]) ) {
-					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
-				}
-			}
-		}
-
-		if ( seed ) {
-			if ( postFinder || preFilter ) {
-				if ( postFinder ) {
-					// Get the final matcherOut by condensing this intermediate into postFinder contexts
-					temp = [];
-					i = matcherOut.length;
-					while ( i-- ) {
-						if ( (elem = matcherOut[i]) ) {
-							// Restore matcherIn since elem is not yet a final match
-							temp.push( (matcherIn[i] = elem) );
-						}
-					}
-					postFinder( null, (matcherOut = []), temp, xml );
-				}
-
-				// Move matched elements from seed to results to keep them synchronized
-				i = matcherOut.length;
-				while ( i-- ) {
-					if ( (elem = matcherOut[i]) &&
-						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
-
-						seed[temp] = !(results[temp] = elem);
-					}
-				}
-			}
-
-		// Add elements to results, through postFinder if defined
-		} else {
-			matcherOut = condense(
-				matcherOut === results ?
-					matcherOut.splice( preexisting, matcherOut.length ) :
-					matcherOut
-			);
-			if ( postFinder ) {
-				postFinder( null, results, matcherOut, xml );
-			} else {
-				push.apply( results, matcherOut );
-			}
-		}
-	});
-}
-
-function matcherFromTokens( tokens ) {
-	var checkContext, matcher, j,
-		len = tokens.length,
-		leadingRelative = Expr.relative[ tokens[0].type ],
-		implicitRelative = leadingRelative || Expr.relative[" "],
-		i = leadingRelative ? 1 : 0,
-
-		// The foundational matcher ensures that elements are reachable from top-level context(s)
-		matchContext = addCombinator( function( elem ) {
-			return elem === checkContext;
-		}, implicitRelative, true ),
-		matchAnyContext = addCombinator( function( elem ) {
-			return indexOf( checkContext, elem ) > -1;
-		}, implicitRelative, true ),
-		matchers = [ function( elem, context, xml ) {
-			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
-				(checkContext = context).nodeType ?
-					matchContext( elem, context, xml ) :
-					matchAnyContext( elem, context, xml ) );
-			// Avoid hanging onto element (issue #299)
-			checkContext = null;
-			return ret;
-		} ];
-
-	for ( ; i < len; i++ ) {
-		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
-			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
-		} else {
-			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
-			// Return special upon seeing a positional matcher
-			if ( matcher[ expando ] ) {
-				// Find the next relative operator (if any) for proper handling
-				j = ++i;
-				for ( ; j < len; j++ ) {
-					if ( Expr.relative[ tokens[j].type ] ) {
-						break;
-					}
-				}
-				return setMatcher(
-					i > 1 && elementMatcher( matchers ),
-					i > 1 && toSelector(
-						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
-						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
-					).replace( rtrim, "$1" ),
-					matcher,
-					i < j && matcherFromTokens( tokens.slice( i, j ) ),
-					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
-					j < len && toSelector( tokens )
-				);
-			}
-			matchers.push( matcher );
-		}
-	}
-
-	return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
-	var bySet = setMatchers.length > 0,
-		byElement = elementMatchers.length > 0,
-		superMatcher = function( seed, context, xml, results, outermost ) {
-			var elem, j, matcher,
-				matchedCount = 0,
-				i = "0",
-				unmatched = seed && [],
-				setMatched = [],
-				contextBackup = outermostContext,
-				// We must always have either seed elements or outermost context
-				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
-				// Use integer dirruns iff this is the outermost matcher
-				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
-				len = elems.length;
-
-			if ( outermost ) {
-				outermostContext = context !== document && context;
-			}
-
-			// Add elements passing elementMatchers directly to results
-			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
-			// Support: IE<9, Safari
-			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
-			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
-				if ( byElement && elem ) {
-					j = 0;
-					while ( (matcher = elementMatchers[j++]) ) {
-						if ( matcher( elem, context, xml ) ) {
-							results.push( elem );
-							break;
-						}
-					}
-					if ( outermost ) {
-						dirruns = dirrunsUnique;
-					}
-				}
-
-				// Track unmatched elements for set filters
-				if ( bySet ) {
-					// They will have gone through all possible matchers
-					if ( (elem = !matcher && elem) ) {
-						matchedCount--;
-					}
-
-					// Lengthen the array for every element, matched or not
-					if ( seed ) {
-						unmatched.push( elem );
-					}
-				}
-			}
-
-			// Apply set filters to unmatched elements
-			matchedCount += i;
-			if ( bySet && i !== matchedCount ) {
-				j = 0;
-				while ( (matcher = setMatchers[j++]) ) {
-					matcher( unmatched, setMatched, context, xml );
-				}
-
-				if ( seed ) {
-					// Reintegrate element matches to eliminate the need for sorting
-					if ( matchedCount > 0 ) {
-						while ( i-- ) {
-							if ( !(unmatched[i] || setMatched[i]) ) {
-								setMatched[i] = pop.call( results );
-							}
-						}
-					}
-
-					// Discard index placeholder values to get only actual matches
-					setMatched = condense( setMatched );
-				}
-
-				// Add matches to results
-				push.apply( results, setMatched );
-
-				// Seedless set matches succeeding multiple successful matchers stipulate sorting
-				if ( outermost && !seed && setMatched.length > 0 &&
-					( matchedCount + setMatchers.length ) > 1 ) {
-
-					Sizzle.uniqueSort( results );
-				}
-			}
-
-			// Override manipulation of globals by nested matchers
-			if ( outermost ) {
-				dirruns = dirrunsUnique;
-				outermostContext = contextBackup;
-			}
-
-			return unmatched;
-		};
-
-	return bySet ?
-		markFunction( superMatcher ) :
-		superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
-	var i,
-		setMatchers = [],
-		elementMatchers = [],
-		cached = compilerCache[ selector + " " ];
-
-	if ( !cached ) {
-		// Generate a function of recursive functions that can be used to check each element
-		if ( !match ) {
-			match = tokenize( selector );
-		}
-		i = match.length;
-		while ( i-- ) {
-			cached = matcherFromTokens( match[i] );
-			if ( cached[ expando ] ) {
-				setMatchers.push( cached );
-			} else {
-				elementMatchers.push( cached );
-			}
-		}
-
-		// Cache the compiled function
-		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
-		// Save selector and tokenization
-		cached.selector = selector;
-	}
-	return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- *  selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- *  selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
-	var i, tokens, token, type, find,
-		compiled = typeof selector === "function" && selector,
-		match = !seed && tokenize( (selector = compiled.selector || selector) );
-
-	results = results || [];
-
-	// Try to minimize operations if there is no seed and only one group
-	if ( match.length === 1 ) {
-
-		// Take a shortcut and set the context if the root selector is an ID
-		tokens = match[0] = match[0].slice( 0 );
-		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
-				support.getById && context.nodeType === 9 && documentIsHTML &&
-				Expr.relative[ tokens[1].type ] ) {
-
-			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
-			if ( !context ) {
-				return results;
-
-			// Precompiled matchers will still verify ancestry, so step up a level
-			} else if ( compiled ) {
-				context = context.parentNode;
-			}
-
-			selector = selector.slice( tokens.shift().value.length );
-		}
-
-		// Fetch a seed set for right-to-left matching
-		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
-		while ( i-- ) {
-			token = tokens[i];
-
-			// Abort if we hit a combinator
-			if ( Expr.relative[ (type = token.type) ] ) {
-				break;
-			}
-			if ( (find = Expr.find[ type ]) ) {
-				// Search, expanding context for leading sibling combinators
-				if ( (seed = find(
-					token.matches[0].replace( runescape, funescape ),
-					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
-				)) ) {
-
-					// If seed is empty or no tokens remain, we can return early
-					tokens.splice( i, 1 );
-					selector = seed.length && toSelector( tokens );
-					if ( !selector ) {
-						push.apply( results, seed );
-						return results;
-					}
-
-					break;
-				}
-			}
-		}
-	}
-
-	// Compile and execute a filtering function if one is not provided
-	// Provide `match` to avoid retokenization if we modified the selector above
-	( compiled || compile( selector, match ) )(
-		seed,
-		context,
-		!documentIsHTML,
-		results,
-		rsibling.test( selector ) && testContext( context.parentNode ) || context
-	);
-	return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome 14-35+
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
-	// Should return 1, but returns 4 (following)
-	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
-	div.innerHTML = "<a href='#'></a>";
-	return div.firstChild.getAttribute("href") === "#" ;
-}) ) {
-	addHandle( "type|href|height|width", function( elem, name, isXML ) {
-		if ( !isXML ) {
-			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
-		}
-	});
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
-	div.innerHTML = "<input/>";
-	div.firstChild.setAttribute( "value", "" );
-	return div.firstChild.getAttribute( "value" ) === "";
-}) ) {
-	addHandle( "value", function( elem, name, isXML ) {
-		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
-			return elem.defaultValue;
-		}
-	});
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
-	return div.getAttribute("disabled") == null;
-}) ) {
-	addHandle( booleans, function( elem, name, isXML ) {
-		var val;
-		if ( !isXML ) {
-			return elem[ name ] === true ? name.toLowerCase() :
-					(val = elem.getAttributeNode( name )) && val.specified ?
-					val.value :
-				null;
-		}
-	});
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
-	if ( jQuery.isFunction( qualifier ) ) {
-		return jQuery.grep( elements, function( elem, i ) {
-			/* jshint -W018 */
-			return !!qualifier.call( elem, i, elem ) !== not;
-		});
-
-	}
-
-	if ( qualifier.nodeType ) {
-		return jQuery.grep( elements, function( elem ) {
-			return ( elem === qualifier ) !== not;
-		});
-
-	}
-
-	if ( typeof qualifier === "string" ) {
-		if ( risSimple.test( qualifier ) ) {
-			return jQuery.filter( qualifier, elements, not );
-		}
-
-		qualifier = jQuery.filter( qualifier, elements );
-	}
-
-	return jQuery.grep( elements, function( elem ) {
-		return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
-	});
-}
-
-jQuery.filter = function( expr, elems, not ) {
-	var elem = elems[ 0 ];
-
-	if ( not ) {
-		expr = ":not(" + expr + ")";
-	}
-
-	return elems.length === 1 && elem.nodeType === 1 ?
-		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
-		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
-			return elem.nodeType === 1;
-		}));
-};
-
-jQuery.fn.extend({
-	find: function( selector ) {
-		var i,
-			ret = [],
-			self = this,
-			len = self.length;
-
-		if ( typeof selector !== "string" ) {
-			return this.pushStack( jQuery( selector ).filter(function() {
-				for ( i = 0; i < len; i++ ) {
-					if ( jQuery.contains( self[ i ], this ) ) {
-						return true;
-					}
-				}
-			}) );
-		}
-
-		for ( i = 0; i < len; i++ ) {
-			jQuery.find( selector, self[ i ], ret );
-		}
-
-		// Needed because $( selector, context ) becomes $( context ).find( selector )
-		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
-		ret.selector = this.selector ? this.selector + " " + selector : selector;
-		return ret;
-	},
-	filter: function( selector ) {
-		return this.pushStack( winnow(this, selector || [], false) );
-	},
-	not: function( selector ) {
-		return this.pushStack( winnow(this, selector || [], true) );
-	},
-	is: function( selector ) {
-		return !!winnow(
-			this,
-
-			// If this is a positional/relative selector, check membership in the returned set
-			// so $("p:first").is("p:last") won't return true for a doc with two "p".
-			typeof selector === "string" && rneedsContext.test( selector ) ?
-				jQuery( selector ) :
-				selector || [],
-			false
-		).length;
-	}
-});
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
-	// Use the correct document accordingly with window argument (sandbox)
-	document = window.document,
-
-	// A simple way to check for HTML strings
-	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
-	// Strict HTML recognition (#11290: must start with <)
-	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
-	init = jQuery.fn.init = function( selector, context ) {
-		var match, elem;
-
-		// HANDLE: $(""), $(null), $(undefined), $(false)
-		if ( !selector ) {
-			return this;
-		}
-
-		// Handle HTML strings
-		if ( typeof selector === "string" ) {
-			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
-				// Assume that strings that start and end with <> are HTML and skip the regex check
-				match = [ null, selector, null ];
-
-			} else {
-				match = rquickExpr.exec( selector );
-			}
-
-			// Match html or make sure no context is specified for #id
-			if ( match && (match[1] || !context) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[1] ) {
-					context = context instanceof jQuery ? context[0] : context;
-
-					// scripts is true for back-compat
-					// Intentionally let the error be thrown if parseHTML is not present
-					jQuery.merge( this, jQuery.parseHTML(
-						match[1],
-						context && context.nodeType ? context.ownerDocument || context : document,
-						true
-					) );
-
-					// HANDLE: $(html, props)
-					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
-						for ( match in context ) {
-							// Properties of context are called as methods if possible
-							if ( jQuery.isFunction( this[ match ] ) ) {
-								this[ match ]( context[ match ] );
-
-							// ...and otherwise set as attributes
-							} else {
-								this.attr( match, context[ match ] );
-							}
-						}
-					}
-
-					return this;
-
-				// HANDLE: $(#id)
-				} else {
-					elem = document.getElementById( match[2] );
-
-					// Check parentNode to catch when Blackberry 4.6 returns
-					// nodes that are no longer in the document #6963
-					if ( elem && elem.parentNode ) {
-						// Handle the case where IE and Opera return items
-						// by name instead of ID
-						if ( elem.id !== match[2] ) {
-							return rootjQuery.find( selector );
-						}
-
-						// Otherwise, we inject the element directly into the jQuery object
-						this.length = 1;
-						this[0] = elem;
-					}
-
-					this.context = document;
-					this.selector = selector;
-					return this;
-				}
-
-			// HANDLE: $(expr, $(...))
-			} else if ( !context || context.jquery ) {
-				return ( context || rootjQuery ).find( selector );
-
-			// HANDLE: $(expr, context)
-			// (which is just equivalent to: $(context).find(expr)
-			} else {
-				return this.constructor( context ).find( selector );
-			}
-
-		// HANDLE: $(DOMElement)
-		} else if ( selector.nodeType ) {
-			this.context = this[0] = selector;
-			this.length = 1;
-			return this;
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( jQuery.isFunction( selector ) ) {
-			return typeof rootjQuery.ready !== "undefined" ?
-				rootjQuery.ready( selector ) :
-				// Execute immediately if ready is not present
-				selector( jQuery );
-		}
-
-		if ( selector.selector !== undefined ) {
-			this.selector = selector.selector;
-			this.context = selector.context;
-		}
-
-		return jQuery.makeArray( selector, this );
-	};
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
-	// methods guaranteed to produce a unique set when starting from a unique set
-	guaranteedUnique = {
-		children: true,
-		contents: true,
-		next: true,
-		prev: true
-	};
-
-jQuery.extend({
-	dir: function( elem, dir, until ) {
-		var matched = [],
-			cur = elem[ dir ];
-
-		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
-			if ( cur.nodeType === 1 ) {
-				matched.push( cur );
-			}
-			cur = cur[dir];
-		}
-		return matched;
-	},
-
-	sibling: function( n, elem ) {
-		var r = [];
-
-		for ( ; n; n = n.nextSibling ) {
-			if ( n.nodeType === 1 && n !== elem ) {
-				r.push( n );
-			}
-		}
-
-		return r;
-	}
-});
-
-jQuery.fn.extend({
-	has: function( target ) {
-		var i,
-			targets = jQuery( target, this ),
-			len = targets.length;
-
-		return this.filter(function() {
-			for ( i = 0; i < len; i++ ) {
-				if ( jQuery.contains( this, targets[i] ) ) {
-					return true;
-				}
-			}
-		});
-	},
-
-	closest: function( selectors, context ) {
-		var cur,
-			i = 0,
-			l = this.length,
-			matched = [],
-			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
-				jQuery( selectors, context || this.context ) :
-				0;
-
-		for ( ; i < l; i++ ) {
-			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
-				// Always skip document fragments
-				if ( cur.nodeType < 11 && (pos ?
-					pos.index(cur) > -1 :
-
-					// Don't pass non-elements to Sizzle
-					cur.nodeType === 1 &&
-						jQuery.find.matchesSelector(cur, selectors)) ) {
-
-					matched.push( cur );
-					break;
-				}
-			}
-		}
-
-		return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
-	},
-
-	// Determine the position of an element within
-	// the matched set of elements
-	index: function( elem ) {
-
-		// No argument, return index in parent
-		if ( !elem ) {
-			return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
-		}
-
-		// index in selector
-		if ( typeof elem === "string" ) {
-			return jQuery.inArray( this[0], jQuery( elem ) );
-		}
-
-		// Locate the position of the desired element
-		return jQuery.inArray(
-			// If it receives a jQuery object, the first element is used
-			elem.jquery ? elem[0] : elem, this );
-	},
-
-	add: function( selector, context ) {
-		return this.pushStack(
-			jQuery.unique(
-				jQuery.merge( this.get(), jQuery( selector, context ) )
-			)
-		);
-	},
-
-	addBack: function( selector ) {
-		return this.add( selector == null ?
-			this.prevObject : this.prevObject.filter(selector)
-		);
-	}
-});
-
-function sibling( cur, dir ) {
-	do {
-		cur = cur[ dir ];
-	} while ( cur && cur.nodeType !== 1 );
-
-	return cur;
-}
-
-jQuery.each({
-	parent: function( elem ) {
-		var parent = elem.parentNode;
-		return parent && parent.nodeType !== 11 ? parent : null;
-	},
-	parents: function( elem ) {
-		return jQuery.dir( elem, "parentNode" );
-	},
-	parentsUntil: function( elem, i, until ) {
-		return jQuery.dir( elem, "parentNode", until );
-	},
-	next: function( elem ) {
-		return sibling( elem, "nextSibling" );
-	},
-	prev: function( elem ) {
-		return sibling( elem, "previousSibling" );
-	},
-	nextAll: function( elem ) {
-		return jQuery.dir( elem, "nextSibling" );
-	},
-	prevAll: function( elem ) {
-		return jQuery.dir( elem, "previousSibling" );
-	},
-	nextUntil: function( elem, i, until ) {
-		return jQuery.dir( elem, "nextSibling", until );
-	},
-	prevUntil: function( elem, i, until ) {
-		return jQuery.dir( elem, "previousSibling", until );
-	},
-	siblings: function( elem ) {
-		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
-	},
-	children: function( elem ) {
-		return jQuery.sibling( elem.firstChild );
-	},
-	contents: function( elem ) {
-		return jQuery.nodeName( elem, "iframe" ) ?
-			elem.contentDocument || elem.contentWindow.document :
-			jQuery.merge( [], elem.childNodes );
-	}
-}, function( name, fn ) {
-	jQuery.fn[ name ] = function( until, selector ) {
-		var ret = jQuery.map( this, fn, until );
-
-		if ( name.slice( -5 ) !== "Until" ) {
-			selector = until;
-		}
-
-		if ( selector && typeof selector === "string" ) {
-			ret = jQuery.filter( selector, ret );
-		}
-
-		if ( this.length > 1 ) {
-			// Remove duplicates
-			if ( !guaranteedUnique[ name ] ) {
-				ret = jQuery.unique( ret );
-			}
-
-			// Reverse order for parents* and prev-derivatives
-			if ( rparentsprev.test( name ) ) {
-				ret = ret.reverse();
-			}
-		}
-
-		return this.pushStack( ret );
-	};
-});
-var rnotwhite = (/\S+/g);
-
-
-
-// String to Object options format cache
-var optionsCache = {};
-
-// Convert String-formatted options into Object-formatted ones and store in cache
-function createOptions( options ) {
-	var object = optionsCache[ options ] = {};
-	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
-		object[ flag ] = true;
-	});
-	return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- *	options: an optional list of space-separated options that will change how
- *			the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- *	once:			will ensure the callback list can only be fired once (like a Deferred)
- *
- *	memory:			will keep track of previous values and will call any callback added
- *					after the list has been fired right away with the latest "memorized"
- *					values (like a Deferred)
- *
- *	unique:			will ensure a callback can only be added once (no duplicate in the list)
- *
- *	stopOnFalse:	interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
-	// Convert options from String-formatted to Object-formatted if needed
-	// (we check in cache first)
-	options = typeof options === "string" ?
-		( optionsCache[ options ] || createOptions( options ) ) :
-		jQuery.extend( {}, options );
-
-	var // Flag to know if list is currently firing
-		firing,
-		// Last fire value (for non-forgettable lists)
-		memory,
-		// Flag to know if list was already fired
-		fired,
-		// End of the loop when firing
-		firingLength,
-		// Index of currently firing callback (modified by remove if needed)
-		firingIndex,
-		// First callback to fire (used internally by add and fireWith)
-		firingStart,
-		// Actual callback list
-		list = [],
-		// Stack of fire calls for repeatable lists
-		stack = !options.once && [],
-		// Fire callbacks
-		fire = function( data ) {
-			memory = options.memory && data;
-			fired = true;
-			firingIndex = firingStart || 0;
-			firingStart = 0;
-			firingLength = list.length;
-			firing = true;
-			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
-				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
-					memory = false; // To prevent further calls using add
-					break;
-				}
-			}
-			firing = false;
-			if ( list ) {
-				if ( stack ) {
-					if ( stack.length ) {
-						fire( stack.shift() );
-					}
-				} else if ( memory ) {
-					list = [];
-				} else {
-					self.disable();
-				}
-			}
-		},
-		// Actual Callbacks object
-		self = {
-			// Add a callback or a collection of callbacks to the list
-			add: function() {
-				if ( list ) {
-					// First, we save the current length
-					var start = list.length;
-					(function add( args ) {
-						jQuery.each( args, function( _, arg ) {
-							var type = jQuery.type( arg );
-							if ( type === "function" ) {
-								if ( !options.unique || !self.has( arg ) ) {
-									list.push( arg );
-								}
-							} else if ( arg && arg.length && type !== "string" ) {
-								// Inspect recursively
-								add( arg );
-							}
-						});
-					})( arguments );
-					// Do we need to add the callbacks to the
-					// current firing batch?
-					if ( firing ) {
-						firingLength = list.length;
-					// With memory, if we're not firing then
-					// we should call right away
-					} else if ( memory ) {
-						firingStart = start;
-						fire( memory );
-					}
-				}
-				return this;
-			},
-			// Remove a callback from the list
-			remove: function() {
-				if ( list ) {
-					jQuery.each( arguments, function( _, arg ) {
-						var index;
-						while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
-							list.splice( index, 1 );
-							// Handle firing indexes
-							if ( firing ) {
-								if ( index <= firingLength ) {
-									firingLength--;
-								}
-								if ( index <= firingIndex ) {
-									firingIndex--;
-								}
-							}
-						}
-					});
-				}
-				return this;
-			},
-			// Check if a given callback is in the list.
-			// If no argument is given, return whether or not list has callbacks attached.
-			has: function( fn ) {
-				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
-			},
-			// Remove all callbacks from the list
-			empty: function() {
-				list = [];
-				firingLength = 0;
-				return this;
-			},
-			// Have the list do nothing anymore
-			disable: function() {
-				list = stack = memory = undefined;
-				return this;
-			},
-			// Is it disabled?
-			disabled: function() {
-				return !list;
-			},
-			// Lock the list in its current state
-			lock: function() {
-				stack = undefined;
-				if ( !memory ) {
-					self.disable();
-				}
-				return this;
-			},
-			// Is it locked?
-			locked: function() {
-				return !stack;
-			},
-			// Call all callbacks with the given context and arguments
-			fireWith: function( context, args ) {
-				if ( list && ( !fired || stack ) ) {
-					args = args || [];
-					args = [ context, args.slice ? args.slice() : args ];
-					if ( firing ) {
-						stack.push( args );
-					} else {
-						fire( args );
-					}
-				}
-				return this;
-			},
-			// Call all the callbacks with the given arguments
-			fire: function() {
-				self.fireWith( this, arguments );
-				return this;
-			},
-			// To know if the callbacks have already been called at least once
-			fired: function() {
-				return !!fired;
-			}
-		};
-
-	return self;
-};
-
-
-jQuery.extend({
-
-	Deferred: function( func ) {
-		var tuples = [
-				// action, add listener, listener list, final state
-				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
-				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
-				[ "notify", "progress", jQuery.Callbacks("memory") ]
-			],
-			state = "pending",
-			promise = {
-				state: function() {
-					return state;
-				},
-				always: function() {
-					deferred.done( arguments ).fail( arguments );
-					return this;
-				},
-				then: function( /* fnDone, fnFail, fnProgress */ ) {
-					var fns = arguments;
-					return jQuery.Deferred(function( newDefer ) {
-						jQuery.each( tuples, function( i, tuple ) {
-							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
-							// deferred[ done | fail | progress ] for forwarding actions to newDefer
-							deferred[ tuple[1] ](function() {
-								var returned = fn && fn.apply( this, arguments );
-								if ( returned && jQuery.isFunction( returned.promise ) ) {
-									returned.promise()
-										.done( newDefer.resolve )
-										.fail( newDefer.reject )
-										.progress( newDefer.notify );
-								} else {
-									newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
-								}
-							});
-						});
-						fns = null;
-					}).promise();
-				},
-				// Get a promise for this deferred
-				// If obj is provided, the promise aspect is added to the object
-				promise: function( obj ) {
-					return obj != null ? jQuery.extend( obj, promise ) : promise;
-				}
-			},
-			deferred = {};
-
-		// Keep pipe for back-compat
-		promise.pipe = promise.then;
-
-		// Add list-specific methods
-		jQuery.each( tuples, function( i, tuple ) {
-			var list = tuple[ 2 ],
-				stateString = tuple[ 3 ];
-
-			// promise[ done | fail | progress ] = list.add
-			promise[ tuple[1] ] = list.add;
-
-			// Handle state
-			if ( stateString ) {
-				list.add(function() {
-					// state = [ resolved | rejected ]
-					state = stateString;
-
-				// [ reject_list | resolve_list ].disable; progress_list.lock
-				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
-			}
-
-			// deferred[ resolve | reject | notify ]
-			deferred[ tuple[0] ] = function() {
-				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
-				return this;
-			};
-			deferred[ tuple[0] + "With" ] = list.fireWith;
-		});
-
-		// Make the deferred a promise
-		promise.promise( deferred );
-
-		// Call given func if any
-		if ( func ) {
-			func.call( deferred, deferred );
-		}
-
-		// All done!
-		return deferred;
-	},
-
-	// Deferred helper
-	when: function( subordinate /* , ..., subordinateN */ ) {
-		var i = 0,
-			resolveValues = slice.call( arguments ),
-			length = resolveValues.length,
-
-			// the count of uncompleted subordinates
-			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
-			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
-			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
-
-			// Update function for both resolve and progress values
-			updateFunc = function( i, contexts, values ) {
-				return function( value ) {
-					contexts[ i ] = this;
-					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
-					if ( values === progressValues ) {
-						deferred.notifyWith( contexts, values );
-
-					} else if ( !(--remaining) ) {
-						deferred.resolveWith( contexts, values );
-					}
-				};
-			},
-
-			progressValues, progressContexts, resolveContexts;
-
-		// add listeners to Deferred subordinates; treat others as resolved
-		if ( length > 1 ) {
-			progressValues = new Array( length );
-			progressContexts = new Array( length );
-			resolveContexts = new Array( length );
-			for ( ; i < length; i++ ) {
-				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
-					resolveValues[ i ].promise()
-						.done( updateFunc( i, resolveContexts, resolveValues ) )
-						.fail( deferred.reject )
-						.progress( updateFunc( i, progressContexts, progressValues ) );
-				} else {
-					--remaining;
-				}
-			}
-		}
-
-		// if we're not waiting on anything, resolve the master
-		if ( !remaining ) {
-			deferred.resolveWith( resolveContexts, resolveValues );
-		}
-
-		return deferred.promise();
-	}
-});
-
-
-// The deferred used on DOM ready
-var readyList;
-
-jQuery.fn.ready = function( fn ) {
-	// Add the callback
-	jQuery.ready.promise().done( fn );
-
-	return this;
-};
-
-jQuery.extend({
-	// Is the DOM ready to be used? Set to true once it occurs.
-	isReady: false,
-
-	// A counter to track how many items to wait for before
-	// the ready event fires. See #6781
-	readyWait: 1,
-
-	// Hold (or release) the ready event
-	holdReady: function( hold ) {
-		if ( hold ) {
-			jQuery.readyWait++;
-		} else {
-			jQuery.ready( true );
-		}
-	},
-
-	// Handle when the DOM is ready
-	ready: function( wait ) {
-
-		// Abort if there are pending holds or we're already ready
-		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
-			return;
-		}
-
-		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
-		if ( !document.body ) {
-			return setTimeout( jQuery.ready );
-		}
-
-		// Remember that the DOM is ready
-		jQuery.isReady = true;
-
-		// If a normal DOM Ready event fired, decrement, and wait if need be
-		if ( wait !== true && --jQuery.readyWait > 0 ) {
-			return;
-		}
-
-		// If there are functions bound, to execute
-		readyList.resolveWith( document, [ jQuery ] );
-
-		// Trigger any bound ready events
-		if ( jQuery.fn.triggerHandler ) {
-			jQuery( document ).triggerHandler( "ready" );
-			jQuery( document ).off( "ready" );
-		}
-	}
-});
-
-/**
- * Clean-up method for dom ready events
- */
-function detach() {
-	if ( document.addEventListener ) {
-		document.removeEventListener( "DOMContentLoaded", completed, false );
-		window.removeEventListener( "load", completed, false );
-
-	} else {
-		document.detachEvent( "onreadystatechange", completed );
-		window.detachEvent( "onload", completed );
-	}
-}
-
-/**
- * The ready event handler and self cleanup method
- */
-function completed() {
-	// readyState === "complete" is good enough for us to call the dom ready in oldIE
-	if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
-		detach();
-		jQuery.ready();
-	}
-}
-
-jQuery.ready.promise = function( obj ) {
-	if ( !readyList ) {
-
-		readyList = jQuery.Deferred();
-
-		// Catch cases where $(document).ready() is called after the browser event has already occurred.
-		// we once tried to use readyState "interactive" here, but it caused issues like the one
-		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
-		if ( document.readyState === "complete" ) {
-			// Handle it asynchronously to allow scripts the opportunity to delay ready
-			setTimeout( jQuery.ready );
-
-		// Standards-based browsers support DOMContentLoaded
-		} else if ( document.addEventListener ) {
-			// Use the handy event callback
-			document.addEventListener( "DOMContentLoaded", completed, false );
-
-			// A fallback to window.onload, that will always work
-			window.addEventListener( "load", completed, false );
-
-		// If IE event model is used
-		} else {
-			// Ensure firing before onload, maybe late but safe also for iframes
-			document.attachEvent( "onreadystatechange", completed );
-
-			// A fallback to window.onload, that will always work
-			window.attachEvent( "onload", completed );
-
-			// If IE and not a frame
-			// continually check to see if the document is ready
-			var top = false;
-
-			try {
-				top = window.frameElement == null && document.documentElement;
-			} catch(e) {}
-
-			if ( top && top.doScroll ) {
-				(function doScrollCheck() {
-					if ( !jQuery.isReady ) {
-
-						try {
-							// Use the trick by Diego Perini
-							// http://javascript.nwbox.com/IEContentLoaded/
-							top.doScroll("left");
-						} catch(e) {
-							return setTimeout( doScrollCheck, 50 );
-						}
-
-						// detach all dom ready events
-						detach();
-
-						// and execute any waiting functions
-						jQuery.ready();
-					}
-				})();
-			}
-		}
-	}
-	return readyList.promise( obj );
-};
-
-
-var strundefined = typeof undefined;
-
-
-
-// Support: IE<9
-// Iteration over object's inherited properties before its own
-var i;
-for ( i in jQuery( support ) ) {
-	break;
-}
-support.ownLast = i !== "0";
-
-// Note: most support tests are defined in their respective modules.
-// false until the test is run
-support.inlineBlockNeedsLayout = false;
-
-// Execute ASAP in case we need to set body.style.zoom
-jQuery(function() {
-	// Minified: var a,b,c,d
-	var val, div, body, container;
-
-	body = document.getElementsByTagName( "body" )[ 0 ];
-	if ( !body || !body.style ) {
-		// Return for frameset docs that don't have a body
-		return;
-	}
-
-	// Setup
-	div = document.createElement( "div" );
-	container = document.createElement( "div" );
-	container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
-	body.appendChild( container ).appendChild( div );
-
-	if ( typeof div.style.zoom !== strundefined ) {
-		// Support: IE<8
-		// Check if natively block-level elements act like inline-block
-		// elements when setting their display to 'inline' and giving
-		// them layout
-		div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
-
-		support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
-		if ( val ) {
-			// Prevent IE 6 from affecting layout for positioned elements #11048
-			// Prevent IE from shrinking the body in IE 7 mode #12869
-			// Support: IE<8
-			body.style.zoom = 1;
-		}
-	}
-
-	body.removeChild( container );
-});
-
-
-
-
-(function() {
-	var div = document.createElement( "div" );
-
-	// Execute the test only if not already executed in another module.
-	if (support.deleteExpando == null) {
-		// Support: IE<9
-		support.deleteExpando = true;
-		try {
-			delete div.test;
-		} catch( e ) {
-			support.deleteExpando = false;
-		}
-	}
-
-	// Null elements to avoid leaks in IE.
-	div = null;
-})();
-
-
-/**
- * Determines whether an object can have data
- */
-jQuery.acceptData = function( elem ) {
-	var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
-		nodeType = +elem.nodeType || 1;
-
-	// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
-	return nodeType !== 1 && nodeType !== 9 ?
-		false :
-
-		// Nodes accept data unless otherwise specified; rejection can be conditional
-		!noData || noData !== true && elem.getAttribute("classid") === noData;
-};
-
-
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
-	rmultiDash = /([A-Z])/g;
-
-function dataAttr( elem, key, data ) {
-	// If nothing was found internally, try to fetch any
-	// data from the HTML5 data-* attribute
-	if ( data === undefined && elem.nodeType === 1 ) {
-
-		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
-
-		data = elem.getAttribute( name );
-
-		if ( typeof data === "string" ) {
-			try {
-				data = data === "true" ? true :
-					data === "false" ? false :
-					data === "null" ? null :
-					// Only convert to a number if it doesn't change the string
-					+data + "" === data ? +data :
-					rbrace.test( data ) ? jQuery.parseJSON( data ) :
-					data;
-			} catch( e ) {}
-
-			// Make sure we set the data so it isn't changed later
-			jQuery.data( elem, key, data );
-
-		} else {
-			data = undefined;
-		}
-	}
-
-	return data;
-}
-
-// checks a cache object for emptiness
-function isEmptyDataObject( obj ) {
-	var name;
-	for ( name in obj ) {
-
-		// if the public data object is empty, the private is still empty
-		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
-			continue;
-		}
-		if ( name !== "toJSON" ) {
-			return false;
-		}
-	}
-
-	return true;
-}
-
-function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
-	if ( !jQuery.acceptData( elem ) ) {
-		return;
-	}
-
-	var ret, thisCache,
-		internalKey = jQuery.expando,
-
-		// We have to handle DOM nodes and JS objects differently because IE6-7
-		// can't GC object references properly across the DOM-JS boundary
-		isNode = elem.nodeType,
-
-		// Only DOM nodes need the global jQuery cache; JS object data is
-		// attached directly to the object so GC can occur automatically
-		cache = isNode ? jQuery.cache : elem,
-
-		// Only defining an ID for JS objects if its cache already exists allows
-		// the code to shortcut on the same path as a DOM node with no cache
-		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
-
-	// Avoid doing any more work than we need to when trying to get data on an
-	// object that has no data at all
-	if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
-		return;
-	}
-
-	if ( !id ) {
-		// Only DOM nodes need a new unique ID for each element since their data
-		// ends up in the global cache
-		if ( isNode ) {
-			id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
-		} else {
-			id = internalKey;
-		}
-	}
-
-	if ( !cache[ id ] ) {
-		// Avoid exposing jQuery metadata on plain JS objects when the object
-		// is serialized using JSON.stringify
-		cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
-	}
-
-	// An object can be passed to jQuery.data instead of a key/value pair; this gets
-	// shallow copied over onto the existing cache
-	if ( typeof name === "object" || typeof name === "function" ) {
-		if ( pvt ) {
-			cache[ id ] = jQuery.extend( cache[ id ], name );
-		} else {
-			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
-		}
-	}
-
-	thisCache = cache[ id ];
-
-	// jQuery data() is stored in a separate object inside the object's internal data
-	// cache in order to avoid key collisions between internal data and user-defined
-	// data.
-	if ( !pvt ) {
-		if ( !thisCache.data ) {
-			thisCache.data = {};
-		}
-
-		thisCache = thisCache.data;
-	}
-
-	if ( data !== undefined ) {
-		thisCache[ jQuery.camelCase( name ) ] = data;
-	}
-
-	// Check for both converted-to-camel and non-converted data property names
-	// If a data property was specified
-	if ( typeof name === "string" ) {
-
-		// First Try to find as-is property data
-		ret = thisCache[ name ];
-
-		// Test for null|undefined property data
-		if ( ret == null ) {
-
-			// Try to find the camelCased property
-			ret = thisCache[ jQuery.camelCase( name ) ];
-		}
-	} else {
-		ret = thisCache;
-	}
-
-	return ret;
-}
-
-function internalRemoveData( elem, name, pvt ) {
-	if ( !jQuery.acceptData( elem ) ) {
-		return;
-	}
-
-	var thisCache, i,
-		isNode = elem.nodeType,
-
-		// See jQuery.data for more information
-		cache = isNode ? jQuery.cache : elem,
-		id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
-
-	// If there is already no cache entry for this object, there is no
-	// purpose in continuing
-	if ( !cache[ id ] ) {
-		return;
-	}
-
-	if ( name ) {
-
-		thisCache = pvt ? cache[ id ] : cache[ id ].data;
-
-		if ( thisCache ) {
-
-			// Support array or space separated string names for data keys
-			if ( !jQuery.isArray( name ) ) {
-
-				// try the string as a key before any manipulation
-				if ( name in thisCache ) {
-					name = [ name ];
-				} else {
-
-					// split the camel cased version by spaces unless a key with the spaces exists
-					name = jQuery.camelCase( name );
-					if ( name in thisCache ) {
-						name = [ name ];
-					} else {
-						name = name.split(" ");
-					}
-				}
-			} else {
-				// If "name" is an array of keys...
-				// When data is initially created, via ("key", "val") signature,
-				// keys will be converted to camelCase.
-				// Since there is no way to tell _how_ a key was added, remove
-				// both plain key and camelCase key. #12786
-				// This will only penalize the array argument path.
-				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
-			}
-
-			i = name.length;
-			while ( i-- ) {
-				delete thisCache[ name[i] ];
-			}
-
-			// If there is no data left in the cache, we want to continue
-			// and let the cache object itself get destroyed
-			if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
-				return;
-			}
-		}
-	}
-
-	// See jQuery.data for more information
-	if ( !pvt ) {
-		delete cache[ id ].data;
-
-		// Don't destroy the parent cache unless the internal data object
-		// had been the only thing left in it
-		if ( !isEmptyDataObject( cache[ id ] ) ) {
-			return;
-		}
-	}
-
-	// Destroy the cache
-	if ( isNode ) {
-		jQuery.cleanData( [ elem ], true );
-
-	// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
-	/* jshint eqeqeq: false */
-	} else if ( support.deleteExpando || cache != cache.window ) {
-		/* jshint eqeqeq: true */
-		delete cache[ id ];
-
-	// When all else fails, null
-	} else {
-		cache[ id ] = null;
-	}
-}
-
-jQuery.extend({
-	cache: {},
-
-	// The following elements (space-suffixed to avoid Object.prototype collisions)
-	// throw uncatchable exceptions if you attempt to set expando properties
-	noData: {
-		"applet ": true,
-		"embed ": true,
-		// ...but Flash objects (which have this classid) *can* handle expandos
-		"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
-	},
-
-	hasData: function( elem ) {
-		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
-		return !!elem && !isEmptyDataObject( elem );
-	},
-
-	data: function( elem, name, data ) {
-		return internalData( elem, name, data );
-	},
-
-	removeData: function( elem, name ) {
-		return internalRemoveData( elem, name );
-	},
-
-	// For internal use only.
-	_data: function( elem, name, data ) {
-		return internalData( elem, name, data, true );
-	},
-
-	_removeData: function( elem, name ) {
-		return internalRemoveData( elem, name, true );
-	}
-});
-
-jQuery.fn.extend({
-	data: function( key, value ) {
-		var i, name, data,
-			elem = this[0],
-			attrs = elem && elem.attributes;
-
-		// Special expections of .data basically thwart jQuery.access,
-		// so implement the relevant behavior ourselves
-
-		// Gets all values
-		if ( key === undefined ) {
-			if ( this.length ) {
-				data = jQuery.data( elem );
-
-				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
-					i = attrs.length;
-					while ( i-- ) {
-
-						// Support: IE11+
-						// The attrs elements can be null (#14894)
-						if ( attrs[ i ] ) {
-							name = attrs[ i ].name;
-							if ( name.indexOf( "data-" ) === 0 ) {
-								name = jQuery.camelCase( name.slice(5) );
-								dataAttr( elem, name, data[ name ] );
-							}
-						}
-					}
-					jQuery._data( elem, "parsedAttrs", true );
-				}
-			}
-
-			return data;
-		}
-
-		// Sets multiple values
-		if ( typeof key === "object" ) {
-			return this.each(function() {
-				jQuery.data( this, key );
-			});
-		}
-
-		return arguments.length > 1 ?
-
-			// Sets one value
-			this.each(function() {
-				jQuery.data( this, key, value );
-			}) :
-
-			// Gets one value
-			// Try to fetch any internally stored data first
-			elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
-	},
-
-	removeData: function( key ) {
-		return this.each(function() {
-			jQuery.removeData( this, key );
-		});
-	}
-});
-
-
-jQuery.extend({
-	queue: function( elem, type, data ) {
-		var queue;
-
-		if ( elem ) {
-			type = ( type || "fx" ) + "queue";
-			queue = jQuery._data( elem, type );
-
-			// Speed up dequeue by getting out quickly if this is just a lookup
-			if ( data ) {
-				if ( !queue || jQuery.isArray(data) ) {
-					queue = jQuery._data( elem, type, jQuery.makeArray(data) );
-				} else {
-					queue.push( data );
-				}
-			}
-			return queue || [];
-		}
-	},
-
-	dequeue: function( elem, type ) {
-		type = type || "fx";
-
-		var queue = jQuery.queue( elem, type ),
-			startLength = queue.length,
-			fn = queue.shift(),
-			hooks = jQuery._queueHooks( elem, type ),
-			next = function() {
-				jQuery.dequeue( elem, type );
-			};
-
-		// If the fx queue is dequeued, always remove the progress sentinel
-		if ( fn === "inprogress" ) {
-			fn = queue.shift();
-			startLength--;
-		}
-
-		if ( fn ) {
-
-			// Add a progress sentinel to prevent the fx queue from being
-			// automatically dequeued
-			if ( type === "fx" ) {
-				queue.unshift( "inprogress" );
-			}
-
-			// clear up the last queue stop function
-			delete hooks.stop;
-			fn.call( elem, next, hooks );
-		}
-
-		if ( !startLength && hooks ) {
-			hooks.empty.fire();
-		}
-	},
-
-	// not intended for public consumption - generates a queueHooks object, or returns the current one
-	_queueHooks: function( elem, type ) {
-		var key = type + "queueHooks";
-		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
-			empty: jQuery.Callbacks("once memory").add(function() {
-				jQuery._removeData( elem, type + "queue" );
-				jQuery._removeData( elem, key );
-			})
-		});
-	}
-});
-
-jQuery.fn.extend({
-	queue: function( type, data ) {
-		var setter = 2;
-
-		if ( typeof type !== "string" ) {
-			data = type;
-			type = "fx";
-			setter--;
-		}
-
-		if ( arguments.length < setter ) {
-			return jQuery.queue( this[0], type );
-		}
-
-		return data === undefined ?
-			this :
-			this.each(function() {
-				var queue = jQuery.queue( this, type, data );
-
-				// ensure a hooks for this queue
-				jQuery._queueHooks( this, type );
-
-				if ( type === "fx" && queue[0] !== "inprogress" ) {
-					jQuery.dequeue( this, type );
-				}
-			});
-	},
-	dequeue: function( type ) {
-		return this.each(function() {
-			jQuery.dequeue( this, type );
-		});
-	},
-	clearQueue: function( type ) {
-		return this.queue( type || "fx", [] );
-	},
-	// Get a promise resolved when queues of a certain type
-	// are emptied (fx is the type by default)
-	promise: function( type, obj ) {
-		var tmp,
-			count = 1,
-			defer = jQuery.Deferred(),
-			elements = this,
-			i = this.length,
-			resolve = function() {
-				if ( !( --count ) ) {
-					defer.resolveWith( elements, [ elements ] );
-				}
-			};
-
-		if ( typeof type !== "string" ) {
-			obj = type;
-			type = undefined;
-		}
-		type = type || "fx";
-
-		while ( i-- ) {
-			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
-			if ( tmp && tmp.empty ) {
-				count++;
-				tmp.empty.add( resolve );
-			}
-		}
-		resolve();
-		return defer.promise( obj );
-	}
-});
-var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHidden = function( elem, el ) {
-		// isHidden might be called from jQuery#filter function;
-		// in that case, element will be second argument
-		elem = el || elem;
-		return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
-	};
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
-	var i = 0,
-		length = elems.length,
-		bulk = key == null;
-
-	// Sets many values
-	if ( jQuery.type( key ) === "object" ) {
-		chainable = true;
-		for ( i in key ) {
-			jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
-		}
-
-	// Sets one value
-	} else if ( value !== undefined ) {
-		chainable = true;
-
-		if ( !jQuery.isFunction( value ) ) {
-			raw = true;
-		}
-
-		if ( bulk ) {
-			// Bulk operations run against the entire set
-			if ( raw ) {
-				fn.call( elems, value );
-				fn = null;
-
-			// ...except when executing function values
-			} else {
-				bulk = fn;
-				fn = function( elem, key, value ) {
-					return bulk.call( jQuery( elem ), value );
-				};
-			}
-		}
-
-		if ( fn ) {
-			for ( ; i < length; i++ ) {
-				fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
-			}
-		}
-	}
-
-	return chainable ?
-		elems :
-
-		// Gets
-		bulk ?
-			fn.call( elems ) :
-			length ? fn( elems[0], key ) : emptyGet;
-};
-var rcheckableType = (/^(?:checkbox|radio)$/i);
-
-
-
-(function() {
-	// Minified: var a,b,c
-	var input = document.createElement( "input" ),
-		div = document.createElement( "div" ),
-		fragment = document.createDocumentFragment();
-
-	// Setup
-	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
-
-	// IE strips leading whitespace when .innerHTML is used
-	support.leadingWhitespace = div.firstChild.nodeType === 3;
-
-	// Make sure that tbody elements aren't automatically inserted
-	// IE will insert them into empty tables
-	support.tbody = !div.getElementsByTagName( "tbody" ).length;
-
-	// Make sure that link elements get serialized correctly by innerHTML
-	// This requires a wrapper element in IE
-	support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
-
-	// Makes sure cloning an html5 element does not cause problems
-	// Where outerHTML is undefined, this still works
-	support.html5Clone =
-		document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
-
-	// Check if a disconnected checkbox will retain its checked
-	// value of true after appended to the DOM (IE6/7)
-	input.type = "checkbox";
-	input.checked = true;
-	fragment.appendChild( input );
-	support.appendChecked = input.checked;
-
-	// Make sure textarea (and checkbox) defaultValue is properly cloned
-	// Support: IE6-IE11+
-	div.innerHTML = "<textarea>x</textarea>";
-	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-
-	// #11217 - WebKit loses check when the name is after the checked attribute
-	fragment.appendChild( div );
-	div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
-
-	// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
-	// old WebKit doesn't clone checked state correctly in fragments
-	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
-	// Support: IE<9
-	// Opera does not clone events (and typeof div.attachEvent === undefined).
-	// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
-	support.noCloneEvent = true;
-	if ( div.attachEvent ) {
-		div.attachEvent( "onclick", function() {
-			support.noCloneEvent = false;
-		});
-
-		div.cloneNode( true ).click();
-	}
-
-	// Execute the test only if not already executed in another module.
-	if (support.deleteExpando == null) {
-		// Support: IE<9
-		support.deleteExpando = true;
-		try {
-			delete div.test;
-		} catch( e ) {
-			support.deleteExpando = false;
-		}
-	}
-})();
-
-
-(function() {
-	var i, eventName,
-		div = document.createElement( "div" );
-
-	// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
-	for ( i in { submit: true, change: true, focusin: true }) {
-		eventName = "on" + i;
-
-		if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
-			// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
-			div.setAttribute( eventName, "t" );
-			support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
-		}
-	}
-
-	// Null elements to avoid leaks in IE.
-	div = null;
-})();
-
-
-var rformElems = /^(?:input|select|textarea)$/i,
-	rkeyEvent = /^key/,
-	rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
-	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
-	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
-
-function returnTrue() {
-	return true;
-}
-
-function returnFalse() {
-	return false;
-}
-
-function safeActiveElement() {
-	try {
-		return document.activeElement;
-	} catch ( err ) { }
-}
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
-	global: {},
-
-	add: function( elem, types, handler, data, selector ) {
-		var tmp, events, t, handleObjIn,
-			special, eventHandle, handleObj,
-			handlers, type, namespaces, origType,
-			elemData = jQuery._data( elem );
-
-		// Don't attach events to noData or text/comment nodes (but allow plain objects)
-		if ( !elemData ) {
-			return;
-		}
-
-		// Caller can pass in an object of custom data in lieu of the handler
-		if ( handler.handler ) {
-			handleObjIn = handler;
-			handler = handleObjIn.handler;
-			selector = handleObjIn.selector;
-		}
-
-		// Make sure that the handler has a unique ID, used to find/remove it later
-		if ( !handler.guid ) {
-			handler.guid = jQuery.guid++;
-		}
-
-		// Init the element's event structure and main handler, if this is the first
-		if ( !(events = elemData.events) ) {
-			events = elemData.events = {};
-		}
-		if ( !(eventHandle = elemData.handle) ) {
-			eventHandle = elemData.handle = function( e ) {
-				// Discard the second event of a jQuery.event.trigger() and
-				// when an event is called after a page has unloaded
-				return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
-					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
-					undefined;
-			};
-			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
-			eventHandle.elem = elem;
-		}
-
-		// Handle multiple events separated by a space
-		types = ( types || "" ).match( rnotwhite ) || [ "" ];
-		t = types.length;
-		while ( t-- ) {
-			tmp = rtypenamespace.exec( types[t] ) || [];
-			type = origType = tmp[1];
-			namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
-			// There *must* be a type, no attaching namespace-only handlers
-			if ( !type ) {
-				continue;
-			}
-
-			// If event changes its type, use the special event handlers for the changed type
-			special = jQuery.event.special[ type ] || {};
-
-			// If selector defined, determine special event api type, otherwise given type
-			type = ( selector ? special.delegateType : special.bindType ) || type;
-
-			// Update special based on newly reset type
-			special = jQuery.event.special[ type ] || {};
-
-			// handleObj is passed to all event handlers
-			handleObj = jQuery.extend({
-				type: type,
-				origType: origType,
-				data: data,
-				handler: handler,
-				guid: handler.guid,
-				selector: selector,
-				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
-				namespace: namespaces.join(".")
-			}, handleObjIn );
-
-			// Init the event handler queue if we're the first
-			if ( !(handlers = events[ type ]) ) {
-				handlers = events[ type ] = [];
-				handlers.delegateCount = 0;
-
-				// Only use addEventListener/attachEvent if the special events handler returns false
-				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
-					// Bind the global event handler to the element
-					if ( elem.addEventListener ) {
-						elem.addEventListener( type, eventHandle, false );
-
-					} else if ( elem.attachEvent ) {
-						elem.attachEvent( "on" + type, eventHandle );
-					}
-				}
-			}
-
-			if ( special.add ) {
-				special.add.call( elem, handleObj );
-
-				if ( !handleObj.handler.guid ) {
-					handleObj.handler.guid = handler.guid;
-				}
-			}
-
-			// Add to the element's handler list, delegates in front
-			if ( selector ) {
-				handlers.splice( handlers.delegateCount++, 0, handleObj );
-			} else {
-				handlers.push( handleObj );
-			}
-
-			// Keep track of which events have ever been used, for event optimization
-			jQuery.event.global[ type ] = true;
-		}
-
-		// Nullify elem to prevent memory leaks in IE
-		elem = null;
-	},
-
-	// Detach an event or set of events from an element
-	remove: function( elem, types, handler, selector, mappedTypes ) {
-		var j, handleObj, tmp,
-			origCount, t, events,
-			special, handlers, type,
-			namespaces, origType,
-			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
-
-		if ( !elemData || !(events = elemData.events) ) {
-			return;
-		}
-
-		// Once for each type.namespace in types; type may be omitted
-		types = ( types || "" ).match( rnotwhite ) || [ "" ];
-		t = types.length;
-		while ( t-- ) {
-			tmp = rtypenamespace.exec( types[t] ) || [];
-			type = origType = tmp[1];
-			namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
-			// Unbind all events (on this namespace, if provided) for the element
-			if ( !type ) {
-				for ( type in events ) {
-					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
-				}
-				continue;
-			}
-
-			special = jQuery.event.special[ type ] || {};
-			type = ( selector ? special.delegateType : special.bindType ) || type;
-			handlers = events[ type ] || [];
-			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
-
-			// Remove matching events
-			origCount = j = handlers.length;
-			while ( j-- ) {
-				handleObj = handlers[ j ];
-
-				if ( ( mappedTypes || origType === handleObj.origType ) &&
-					( !handler || handler.guid === handleObj.guid ) &&
-					( !tmp || tmp.test( handleObj.namespace ) ) &&
-					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
-					handlers.splice( j, 1 );
-
-					if ( handleObj.selector ) {
-						handlers.delegateCount--;
-					}
-					if ( special.remove ) {
-						special.remove.call( elem, handleObj );
-					}
-				}
-			}
-
-			// Remove generic event handler if we removed something and no more handlers exist
-			// (avoids potential for endless recursion during removal of special event handlers)
-			if ( origCount && !handlers.length ) {
-				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
-					jQuery.removeEvent( elem, type, elemData.handle );
-				}
-
-				delete events[ type ];
-			}
-		}
-
-		// Remove the expando if it's no longer used
-		if ( jQuery.isEmptyObject( events ) ) {
-			delete elemData.handle;
-
-			// removeData also checks for emptiness and clears the expando if empty
-			// so use it instead of delete
-			jQuery._removeData( elem, "events" );
-		}
-	},
-
-	trigger: function( event, data, elem, onlyHandlers ) {
-		var handle, ontype, cur,
-			bubbleType, special, tmp, i,
-			eventPath = [ elem || document ],
-			type = hasOwn.call( event, "type" ) ? event.type : event,
-			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
-
-		cur = tmp = elem = elem || document;
-
-		// Don't do events on text and comment nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-			return;
-		}
-
-		// focus/blur morphs to focusin/out; ensure we're not firing them right now
-		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
-			return;
-		}
-
-		if ( type.indexOf(".") >= 0 ) {
-			// Namespaced trigger; create a regexp to match event type in handle()
-			namespaces = type.split(".");
-			type = namespaces.shift();
-			namespaces.sort();
-		}
-		ontype = type.indexOf(":") < 0 && "on" + type;
-
-		// Caller can pass in a jQuery.Event object, Object, or just an event type string
-		event = event[ jQuery.expando ] ?
-			event :
-			new jQuery.Event( type, typeof event === "object" && event );
-
-		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
-		event.isTrigger = onlyHandlers ? 2 : 3;
-		event.namespace = namespaces.join(".");
-		event.namespace_re = event.namespace ?
-			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
-			null;
-
-		// Clean up the event in case it is being reused
-		event.result = undefined;
-		if ( !event.target ) {
-			event.target = elem;
-		}
-
-		// Clone any incoming data and prepend the event, creating the handler arg list
-		data = data == null ?
-			[ event ] :
-			jQuery.makeArray( data, [ event ] );
-
-		// Allow special events to draw outside the lines
-		special = jQuery.event.special[ type ] || {};
-		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
-			return;
-		}
-
-		// Determine event propagation path in advance, per W3C events spec (#9951)
-		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
-		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
-			bubbleType = special.delegateType || type;
-			if ( !rfocusMorph.test( bubbleType + type ) ) {
-				cur = cur.parentNode;
-			}
-			for ( ; cur; cur = cur.parentNode ) {
-				eventPath.push( cur );
-				tmp = cur;
-			}
-
-			// Only add window if we got to document (e.g., not plain obj or detached DOM)
-			if ( tmp === (elem.ownerDocument || document) ) {
-				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
-			}
-		}
-
-		// Fire handlers on the event path
-		i = 0;
-		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
-
-			event.type = i > 1 ?
-				bubbleType :
-				special.bindType || type;
-
-			// jQuery handler
-			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
-			if ( handle ) {
-				handle.apply( cur, data );
-			}
-
-			// Native handler
-			handle = ontype && cur[ ontype ];
-			if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
-				event.result = handle.apply( cur, data );
-				if ( event.result === false ) {
-					event.preventDefault();
-				}
-			}
-		}
-		event.type = type;
-
-		// If nobody prevented the default action, do it now
-		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
-			if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
-				jQuery.acceptData( elem ) ) {
-
-				// Call a native DOM method on the target with the same name name as the event.
-				// Can't use an .isFunction() check here because IE6/7 fails that test.
-				// Don't do default actions on window, that's where global variables be (#6170)
-				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
-
-					// Don't re-trigger an onFOO event when we call its FOO() method
-					tmp = elem[ ontype ];
-
-					if ( tmp ) {
-						elem[ ontype ] = null;
-					}
-
-					// Prevent re-triggering of the same event, since we already bubbled it above
-					jQuery.event.triggered = type;
-					try {
-						elem[ type ]();
-					} catch ( e ) {
-						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
-						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
-					}
-					jQuery.event.triggered = undefined;
-
-					if ( tmp ) {
-						elem[ ontype ] = tmp;
-					}
-				}
-			}
-		}
-
-		return event.result;
-	},
-
-	dispatch: function( event ) {
-
-		// Make a writable jQuery.Event from the native event object
-		event = jQuery.event.fix( event );
-
-		var i, ret, handleObj, matched, j,
-			handlerQueue = [],
-			args = slice.call( arguments ),
-			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
-			special = jQuery.event.special[ event.type ] || {};
-
-		// Use the fix-ed jQuery.Event rather than the (read-only) native event
-		args[0] = event;
-		event.delegateTarget = this;
-
-		// Call the preDispatch hook for the mapped type, and let it bail if desired
-		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
-			return;
-		}
-
-		// Determine handlers
-		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
-		// Run delegates first; they may want to stop propagation beneath us
-		i = 0;
-		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
-			event.currentTarget = matched.elem;
-
-			j = 0;
-			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
-
-				// Triggered event must either 1) have no namespace, or
-				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
-				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
-
-					event.handleObj = handleObj;
-					event.data = handleObj.data;
-
-					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
-							.apply( matched.elem, args );
-
-					if ( ret !== undefined ) {
-						if ( (event.result = ret) === false ) {
-							event.preventDefault();
-							event.stopPropagation();
-						}
-					}
-				}
-			}
-		}
-
-		// Call the postDispatch hook for the mapped type
-		if ( special.postDispatch ) {
-			special.postDispatch.call( this, event );
-		}
-
-		return event.result;
-	},
-
-	handlers: function( event, handlers ) {
-		var sel, handleObj, matches, i,
-			handlerQueue = [],
-			delegateCount = handlers.delegateCount,
-			cur = event.target;
-
-		// Find delegate handlers
-		// Black-hole SVG <use> instance trees (#13180)
-		// Avoid non-left-click bubbling in Firefox (#3861)
-		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
-
-			/* jshint eqeqeq: false */
-			for ( ; cur != this; cur = cur.parentNode || this ) {
-				/* jshint eqeqeq: true */
-
-				// Don't check non-elements (#13208)
-				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
-				if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
-					matches = [];
-					for ( i = 0; i < delegateCount; i++ ) {
-						handleObj = handlers[ i ];
-
-						// Don't conflict with Object.prototype properties (#13203)
-						sel = handleObj.selector + " ";
-
-						if ( matches[ sel ] === undefined ) {
-							matches[ sel ] = handleObj.needsContext ?
-								jQuery( sel, this ).index( cur ) >= 0 :
-								jQuery.find( sel, this, null, [ cur ] ).length;
-						}
-						if ( matches[ sel ] ) {
-							matches.push( handleObj );
-						}
-					}
-					if ( matches.length ) {
-						handlerQueue.push({ elem: cur, handlers: matches });
-					}
-				}
-			}
-		}
-
-		// Add the remaining (directly-bound) handlers
-		if ( delegateCount < handlers.length ) {
-			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
-		}
-
-		return handlerQueue;
-	},
-
-	fix: function( event ) {
-		if ( event[ jQuery.expando ] ) {
-			return event;
-		}
-
-		// Create a writable copy of the event object and normalize some properties
-		var i, prop, copy,
-			type = event.type,
-			originalEvent = event,
-			fixHook = this.fixHooks[ type ];
-
-		if ( !fixHook ) {
-			this.fixHooks[ type ] = fixHook =
-				rmouseEvent.test( type ) ? this.mouseHooks :
-				rkeyEvent.test( type ) ? this.keyHooks :
-				{};
-		}
-		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
-		event = new jQuery.Event( originalEvent );
-
-		i = copy.length;
-		while ( i-- ) {
-			prop = copy[ i ];
-			event[ prop ] = originalEvent[ prop ];
-		}
-
-		// Support: IE<9
-		// Fix target property (#1925)
-		if ( !event.target ) {
-			event.target = originalEvent.srcElement || document;
-		}
-
-		// Support: Chrome 23+, Safari?
-		// Target should not be a text node (#504, #13143)
-		if ( event.target.nodeType === 3 ) {
-			event.target = event.target.parentNode;
-		}
-
-		// Support: IE<9
-		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
-		event.metaKey = !!event.metaKey;
-
-		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
-	},
-
-	// Includes some event props shared by KeyEvent and MouseEvent
-	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
-
-	fixHooks: {},
-
-	keyHooks: {
-		props: "char charCode key keyCode".split(" "),
-		filter: function( event, original ) {
-
-			// Add which for key events
-			if ( event.which == null ) {
-				event.which = original.charCode != null ? original.charCode : original.keyCode;
-			}
-
-			return event;
-		}
-	},
-
-	mouseHooks: {
-		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
-		filter: function( event, original ) {
-			var body, eventDoc, doc,
-				button = original.button,
-				fromElement = original.fromElement;
-
-			// Calculate pageX/Y if missing and clientX/Y available
-			if ( event.pageX == null && original.clientX != null ) {
-				eventDoc = event.target.ownerDocument || document;
-				doc = eventDoc.documentElement;
-				body = eventDoc.body;
-
-				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
-				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
-			}
-
-			// Add relatedTarget, if necessary
-			if ( !event.relatedTarget && fromElement ) {
-				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
-			}
-
-			// Add which for click: 1 === left; 2 === middle; 3 === right
-			// Note: button is not normalized, so don't use it
-			if ( !event.which && button !== undefined ) {
-				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
-			}
-
-			return event;
-		}
-	},
-
-	special: {
-		load: {
-			// Prevent triggered image.load events from bubbling to window.load
-			noBubble: true
-		},
-		focus: {
-			// Fire native event if possible so blur/focus sequence is correct
-			trigger: function() {
-				if ( this !== safeActiveElement() && this.focus ) {
-					try {
-						this.focus();
-						return false;
-					} catch ( e ) {
-						// Support: IE<9
-						// If we error on focus to hidden element (#1486, #12518),
-						// let .trigger() run the handlers
-					}
-				}
-			},
-			delegateType: "focusin"
-		},
-		blur: {
-			trigger: function() {
-				if ( this === safeActiveElement() && this.blur ) {
-					this.blur();
-					return false;
-				}
-			},
-			delegateType: "focusout"
-		},
-		click: {
-			// For checkbox, fire native event so checked state will be right
-			trigger: function() {
-				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
-					this.click();
-					return false;
-				}
-			},
-
-			// For cross-browser consistency, don't fire native .click() on links
-			_default: function( event ) {
-				return jQuery.nodeName( event.target, "a" );
-			}
-		},
-
-		beforeunload: {
-			postDispatch: function( event ) {
-
-				// Support: Firefox 20+
-				// Firefox doesn't alert if the returnValue field is not set.
-				if ( event.result !== undefined && event.originalEvent ) {
-					event.originalEvent.returnValue = event.result;
-				}
-			}
-		}
-	},
-
-	simulate: function( type, elem, event, bubble ) {
-		// Piggyback on a donor event to simulate a different one.
-		// Fake originalEvent to avoid donor's stopPropagation, but if the
-		// simulated event prevents default then we do the same on the donor.
-		var e = jQuery.extend(
-			new jQuery.Event(),
-			event,
-			{
-				type: type,
-				isSimulated: true,
-				originalEvent: {}
-			}
-		);
-		if ( bubble ) {
-			jQuery.event.trigger( e, null, elem );
-		} else {
-			jQuery.event.dispatch.call( elem, e );
-		}
-		if ( e.isDefaultPrevented() ) {
-			event.preventDefault();
-		}
-	}
-};
-
-jQuery.removeEvent = document.removeEventListener ?
-	function( elem, type, handle ) {
-		if ( elem.removeEventListener ) {
-			elem.removeEventListener( type, handle, false );
-		}
-	} :
-	function( elem, type, handle ) {
-		var name = "on" + type;
-
-		if ( elem.detachEvent ) {
-
-			// #8545, #7054, preventing memory leaks for custom events in IE6-8
-			// detachEvent needed property on element, by name of that event, to properly expose it to GC
-			if ( typeof elem[ name ] === strundefined ) {
-				elem[ name ] = null;
-			}
-
-			elem.detachEvent( name, handle );
-		}
-	};
-
-jQuery.Event = function( src, props ) {
-	// Allow instantiation without the 'new' keyword
-	if ( !(this instanceof jQuery.Event) ) {
-		return new jQuery.Event( src, props );
-	}
-
-	// Event object
-	if ( src && src.type ) {
-		this.originalEvent = src;
-		this.type = src.type;
-
-		// Events bubbling up the document may have been marked as prevented
-		// by a handler lower down the tree; reflect the correct value.
-		this.isDefaultPrevented = src.defaultPrevented ||
-				src.defaultPrevented === undefined &&
-				// Support: IE < 9, Android < 4.0
-				src.returnValue === false ?
-			returnTrue :
-			returnFalse;
-
-	// Event type
-	} else {
-		this.type = src;
-	}
-
-	// Put explicitly provided properties onto the event object
-	if ( props ) {
-		jQuery.extend( this, props );
-	}
-
-	// Create a timestamp if incoming event doesn't have one
-	this.timeStamp = src && src.timeStamp || jQuery.now();
-
-	// Mark it as fixed
-	this[ jQuery.expando ] = true;
-};
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
-	isDefaultPrevented: returnFalse,
-	isPropagationStopped: returnFalse,
-	isImmediatePropagationStopped: returnFalse,
-
-	preventDefault: function() {
-		var e = this.originalEvent;
-
-		this.isDefaultPrevented = returnTrue;
-		if ( !e ) {
-			return;
-		}
-
-		// If preventDefault exists, run it on the original event
-		if ( e.preventDefault ) {
-			e.preventDefault();
-
-		// Support: IE
-		// Otherwise set the returnValue property of the original event to false
-		} else {
-			e.returnValue = false;
-		}
-	},
-	stopPropagation: function() {
-		var e = this.originalEvent;
-
-		this.isPropagationStopped = returnTrue;
-		if ( !e ) {
-			return;
-		}
-		// If stopPropagation exists, run it on the original event
-		if ( e.stopPropagation ) {
-			e.stopPropagation();
-		}
-
-		// Support: IE
-		// Set the cancelBubble property of the original event to true
-		e.cancelBubble = true;
-	},
-	stopImmediatePropagation: function() {
-		var e = this.originalEvent;
-
-		this.isImmediatePropagationStopped = returnTrue;
-
-		if ( e && e.stopImmediatePropagation ) {
-			e.stopImmediatePropagation();
-		}
-
-		this.stopPropagation();
-	}
-};
-
-// Create mouseenter/leave events using mouseover/out and event-time checks
-jQuery.each({
-	mouseenter: "mouseover",
-	mouseleave: "mouseout",
-	pointerenter: "pointerover",
-	pointerleave: "pointerout"
-}, function( orig, fix ) {
-	jQuery.event.special[ orig ] = {
-		delegateType: fix,
-		bindType: fix,
-
-		handle: function( event ) {
-			var ret,
-				target = this,
-				related = event.relatedTarget,
-				handleObj = event.handleObj;
-
-			// For mousenter/leave call the handler if related is outside the target.
-			// NB: No relatedTarget if the mouse left/entered the browser window
-			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
-				event.type = handleObj.origType;
-				ret = handleObj.handler.apply( this, arguments );
-				event.type = fix;
-			}
-			return ret;
-		}
-	};
-});
-
-// IE submit delegation
-if ( !support.submitBubbles ) {
-
-	jQuery.event.special.submit = {
-		setup: function() {
-			// Only need this for delegated form submit events
-			if ( jQuery.nodeName( this, "form" ) ) {
-				return false;
-			}
-
-			// Lazy-add a submit handler when a descendant form may potentially be submitted
-			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
-				// Node name check avoids a VML-related crash in IE (#9807)
-				var elem = e.target,
-					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
-				if ( form && !jQuery._data( form, "submitBubbles" ) ) {
-					jQuery.event.add( form, "submit._submit", function( event ) {
-						event._submit_bubble = true;
-					});
-					jQuery._data( form, "submitBubbles", true );
-				}
-			});
-			// return undefined since we don't need an event listener
-		},
-
-		postDispatch: function( event ) {
-			// If form was submitted by the user, bubble the event up the tree
-			if ( event._submit_bubble ) {
-				delete event._submit_bubble;
-				if ( this.parentNode && !event.isTrigger ) {
-					jQuery.event.simulate( "submit", this.parentNode, event, true );
-				}
-			}
-		},
-
-		teardown: function() {
-			// Only need this for delegated form submit events
-			if ( jQuery.nodeName( this, "form" ) ) {
-				return false;
-			}
-
-			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
-			jQuery.event.remove( this, "._submit" );
-		}
-	};
-}
-
-// IE change delegation and checkbox/radio fix
-if ( !support.changeBubbles ) {
-
-	jQuery.event.special.change = {
-
-		setup: function() {
-
-			if ( rformElems.test( this.nodeName ) ) {
-				// IE doesn't fire change on a check/radio until blur; trigger it on click
-				// after a propertychange. Eat the blur-change in special.change.handle.
-				// This still fires onchange a second time for check/radio after blur.
-				if ( this.type === "checkbox" || this.type === "radio" ) {
-					jQuery.event.add( this, "propertychange._change", function( event ) {
-						if ( event.originalEvent.propertyName === "checked" ) {
-							this._just_changed = true;
-						}
-					});
-					jQuery.event.add( this, "click._change", function( event ) {
-						if ( this._just_changed && !event.isTrigger ) {
-							this._just_changed = false;
-						}
-						// Allow triggered, simulated change events (#11500)
-						jQuery.event.simulate( "change", this, event, true );
-					});
-				}
-				return false;
-			}
-			// Delegated event; lazy-add a change handler on descendant inputs
-			jQuery.event.add( this, "beforeactivate._change", function( e ) {
-				var elem = e.target;
-
-				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
-					jQuery.event.add( elem, "change._change", function( event ) {
-						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
-							jQuery.event.simulate( "change", this.parentNode, event, true );
-						}
-					});
-					jQuery._data( elem, "changeBubbles", true );
-				}
-			});
-		},
-
-		handle: function( event ) {
-			var elem = event.target;
-
-			// Swallow native change events from checkbox/radio, we already triggered them above
-			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
-				return event.handleObj.handler.apply( this, arguments );
-			}
-		},
-
-		teardown: function() {
-			jQuery.event.remove( this, "._change" );
-
-			return !rformElems.test( this.nodeName );
-		}
-	};
-}
-
-// Create "bubbling" focus and blur events
-if ( !support.focusinBubbles ) {
-	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
-		// Attach a single capturing handler on the document while someone wants focusin/focusout
-		var handler = function( event ) {
-				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
-			};
-
-		jQuery.event.special[ fix ] = {
-			setup: function() {
-				var doc = this.ownerDocument || this,
-					attaches = jQuery._data( doc, fix );
-
-				if ( !attaches ) {
-					doc.addEventListener( orig, handler, true );
-				}
-				jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
-			},
-			teardown: function() {
-				var doc = this.ownerDocument || this,
-					attaches = jQuery._data( doc, fix ) - 1;
-
-				if ( !attaches ) {
-					doc.removeEventListener( orig, handler, true );
-					jQuery._removeData( doc, fix );
-				} else {
-					jQuery._data( doc, fix, attaches );
-				}
-			}
-		};
-	});
-}
-
-jQuery.fn.extend({
-
-	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
-		var type, origFn;
-
-		// Types can be a map of types/handlers
-		if ( typeof types === "object" ) {
-			// ( types-Object, selector, data )
-			if ( typeof selector !== "string" ) {
-				// ( types-Object, data )
-				data = data || selector;
-				selector = undefined;
-			}
-			for ( type in types ) {
-				this.on( type, selector, data, types[ type ], one );
-			}
-			return this;
-		}
-
-		if ( data == null && fn == null ) {
-			// ( types, fn )
-			fn = selector;
-			data = selector = undefined;
-		} else if ( fn == null ) {
-			if ( typeof selector === "string" ) {
-				// ( types, selector, fn )
-				fn = data;
-				data = undefined;
-			} else {
-				// ( types, data, fn )
-				fn = data;
-				data = selector;
-				selector = undefined;
-			}
-		}
-		if ( fn === false ) {
-			fn = returnFalse;
-		} else if ( !fn ) {
-			return this;
-		}
-
-		if ( one === 1 ) {
-			origFn = fn;
-			fn = function( event ) {
-				// Can use an empty set, since event contains the info
-				jQuery().off( event );
-				return origFn.apply( this, arguments );
-			};
-			// Use same guid so caller can remove using origFn
-			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
-		}
-		return this.each( function() {
-			jQuery.event.add( this, types, fn, data, selector );
-		});
-	},
-	one: function( types, selector, data, fn ) {
-		return this.on( types, selector, data, fn, 1 );
-	},
-	off: function( types, selector, fn ) {
-		var handleObj, type;
-		if ( types && types.preventDefault && types.handleObj ) {
-			// ( event )  dispatched jQuery.Event
-			handleObj = types.handleObj;
-			jQuery( types.delegateTarget ).off(
-				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
-				handleObj.selector,
-				handleObj.handler
-			);
-			return this;
-		}
-		if ( typeof types === "object" ) {
-			// ( types-object [, selector] )
-			for ( type in types ) {
-				this.off( type, selector, types[ type ] );
-			}
-			return this;
-		}
-		if ( selector === false || typeof selector === "function" ) {
-			// ( types [, fn] )
-			fn = selector;
-			selector = undefined;
-		}
-		if ( fn === false ) {
-			fn = returnFalse;
-		}
-		return this.each(function() {
-			jQuery.event.remove( this, types, fn, selector );
-		});
-	},
-
-	trigger: function( type, data ) {
-		return this.each(function() {
-			jQuery.event.trigger( type, data, this );
-		});
-	},
-	triggerHandler: function( type, data ) {
-		var elem = this[0];
-		if ( elem ) {
-			return jQuery.event.trigger( type, data, elem, true );
-		}
-	}
-});
-
-
-function createSafeFragment( document ) {
-	var list = nodeNames.split( "|" ),
-		safeFrag = document.createDocumentFragment();
-
-	if ( safeFrag.createElement ) {
-		while ( list.length ) {
-			safeFrag.createElement(
-				list.pop()
-			);
-		}
-	}
-	return safeFrag;
-}
-
-var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
-		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
-	rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
-	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
-	rleadingWhitespace = /^\s+/,
-	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
-	rtagName = /<([\w:]+)/,
-	rtbody = /<tbody/i,
-	rhtml = /<|&#?\w+;/,
-	rnoInnerhtml = /<(?:script|style|link)/i,
-	// checked="checked" or checked
-	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
-	rscriptType = /^$|\/(?:java|ecma)script/i,
-	rscriptTypeMasked = /^true\/(.*)/,
-	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
-
-	// We have to close these tags to support XHTML (#13200)
-	wrapMap = {
-		option: [ 1, "<select multiple='multiple'>", "</select>" ],
-		legend: [ 1, "<fieldset>", "</fieldset>" ],
-		area: [ 1, "<map>", "</map>" ],
-		param: [ 1, "<object>", "</object>" ],
-		thead: [ 1, "<table>", "</table>" ],
-		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
-		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
-		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-
-		// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
-		// unless wrapped in a div with non-breaking characters in front of it.
-		_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
-	},
-	safeFragment = createSafeFragment( document ),
-	fragmentDiv = safeFragment.appendChild( document.createElement("div") );
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-function getAll( context, tag ) {
-	var elems, elem,
-		i = 0,
-		found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
-			typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
-			undefined;
-
-	if ( !found ) {
-		for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
-			if ( !tag || jQuery.nodeName( elem, tag ) ) {
-				found.push( elem );
-			} else {
-				jQuery.merge( found, getAll( elem, tag ) );
-			}
-		}
-	}
-
-	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
-		jQuery.merge( [ context ], found ) :
-		found;
-}
-
-// Used in buildFragment, fixes the defaultChecked property
-function fixDefaultChecked( elem ) {
-	if ( rcheckableType.test( elem.type ) ) {
-		elem.defaultChecked = elem.checked;
-	}
-}
-
-// Support: IE<8
-// Manipulating tables requires a tbody
-function manipulationTarget( elem, content ) {
-	return jQuery.nodeName( elem, "table" ) &&
-		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
-
-		elem.getElementsByTagName("tbody")[0] ||
-			elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
-		elem;
-}
-
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
-	elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
-	return elem;
-}
-function restoreScript( elem ) {
-	var match = rscriptTypeMasked.exec( elem.type );
-	if ( match ) {
-		elem.type = match[1];
-	} else {
-		elem.removeAttribute("type");
-	}
-	return elem;
-}
-
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
-	var elem,
-		i = 0;
-	for ( ; (elem = elems[i]) != null; i++ ) {
-		jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
-	}
-}
-
-function cloneCopyEvent( src, dest ) {
-
-	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
-		return;
-	}
-
-	var type, i, l,
-		oldData = jQuery._data( src ),
-		curData = jQuery._data( dest, oldData ),
-		events = oldData.events;
-
-	if ( events ) {
-		delete curData.handle;
-		curData.events = {};
-
-		for ( type in events ) {
-			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
-				jQuery.event.add( dest, type, events[ type ][ i ] );
-			}
-		}
-	}
-
-	// make the cloned public data object a copy from the original
-	if ( curData.data ) {
-		curData.data = jQuery.extend( {}, curData.data );
-	}
-}
-
-function fixCloneNodeIssues( src, dest ) {
-	var nodeName, e, data;
-
-	// We do not need to do anything for non-Elements
-	if ( dest.nodeType !== 1 ) {
-		return;
-	}
-
-	nodeName = dest.nodeName.toLowerCase();
-
-	// IE6-8 copies events bound via attachEvent when using cloneNode.
-	if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
-		data = jQuery._data( dest );
-
-		for ( e in data.events ) {
-			jQuery.removeEvent( dest, e, data.handle );
-		}
-
-		// Event data gets referenced instead of copied if the expando gets copied too
-		dest.removeAttribute( jQuery.expando );
-	}
-
-	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
-	if ( nodeName === "script" && dest.text !== src.text ) {
-		disableScript( dest ).text = src.text;
-		restoreScript( dest );
-
-	// IE6-10 improperly clones children of object elements using classid.
-	// IE10 throws NoModificationAllowedError if parent is null, #12132.
-	} else if ( nodeName === "object" ) {
-		if ( dest.parentNode ) {
-			dest.outerHTML = src.outerHTML;
-		}
-
-		// This path appears unavoidable for IE9. When cloning an object
-		// element in IE9, the outerHTML strategy above is not sufficient.
-		// If the src has innerHTML and the destination does not,
-		// copy the src.innerHTML into the dest.innerHTML. #10324
-		if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
-			dest.innerHTML = src.innerHTML;
-		}
-
-	} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
-		// IE6-8 fails to persist the checked state of a cloned checkbox
-		// or radio button. Worse, IE6-7 fail to give the cloned element
-		// a checked appearance if the defaultChecked value isn't also set
-
-		dest.defaultChecked = dest.checked = src.checked;
-
-		// IE6-7 get confused and end up setting the value of a cloned
-		// checkbox/radio button to an empty string instead of "on"
-		if ( dest.value !== src.value ) {
-			dest.value = src.value;
-		}
-
-	// IE6-8 fails to return the selected option to the default selected
-	// state when cloning options
-	} else if ( nodeName === "option" ) {
-		dest.defaultSelected = dest.selected = src.defaultSelected;
-
-	// IE6-8 fails to set the defaultValue to the correct value when
-	// cloning other types of input fields
-	} else if ( nodeName === "input" || nodeName === "textarea" ) {
-		dest.defaultValue = src.defaultValue;
-	}
-}
-
-jQuery.extend({
-	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
-		var destElements, node, clone, i, srcElements,
-			inPage = jQuery.contains( elem.ownerDocument, elem );
-
-		if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
-			clone = elem.cloneNode( true );
-
-		// IE<=8 does not properly clone detached, unknown element nodes
-		} else {
-			fragmentDiv.innerHTML = elem.outerHTML;
-			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
-		}
-
-		if ( (!support.noCloneEvent || !support.noCloneChecked) &&
-				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
-
-			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
-			destElements = getAll( clone );
-			srcElements = getAll( elem );
-
-			// Fix all IE cloning issues
-			for ( i = 0; (node = srcElements[i]) != null; ++i ) {
-				// Ensure that the destination node is not null; Fixes #9587
-				if ( destElements[i] ) {
-					fixCloneNodeIssues( node, destElements[i] );
-				}
-			}
-		}
-
-		// Copy the events from the original to the clone
-		if ( dataAndEvents ) {
-			if ( deepDataAndEvents ) {
-				srcElements = srcElements || getAll( elem );
-				destElements = destElements || getAll( clone );
-
-				for ( i = 0; (node = srcElements[i]) != null; i++ ) {
-					cloneCopyEvent( node, destElements[i] );
-				}
-			} else {
-				cloneCopyEvent( elem, clone );
-			}
-		}
-
-		// Preserve script evaluation history
-		destElements = getAll( clone, "script" );
-		if ( destElements.length > 0 ) {
-			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
-		}
-
-		destElements = srcElements = node = null;
-
-		// Return the cloned set
-		return clone;
-	},
-
-	buildFragment: function( elems, context, scripts, selection ) {
-		var j, elem, contains,
-			tmp, tag, tbody, wrap,
-			l = elems.length,
-
-			// Ensure a safe fragment
-			safe = createSafeFragment( context ),
-
-			nodes = [],
-			i = 0;
-
-		for ( ; i < l; i++ ) {
-			elem = elems[ i ];
-
-			if ( elem || elem === 0 ) {
-
-				// Add nodes directly
-				if ( jQuery.type( elem ) === "object" ) {
-					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
-
-				// Convert non-html into a text node
-				} else if ( !rhtml.test( elem ) ) {
-					nodes.push( context.createTextNode( elem ) );
-
-				// Convert html into DOM nodes
-				} else {
-					tmp = tmp || safe.appendChild( context.createElement("div") );
-
-					// Deserialize a standard representation
-					tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
-					wrap = wrapMap[ tag ] || wrapMap._default;
-
-					tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
-
-					// Descend through wrappers to the right content
-					j = wrap[0];
-					while ( j-- ) {
-						tmp = tmp.lastChild;
-					}
-
-					// Manually add leading whitespace removed by IE
-					if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
-						nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
-					}
-
-					// Remove IE's autoinserted <tbody> from table fragments
-					if ( !support.tbody ) {
-
-						// String was a <table>, *may* have spurious <tbody>
-						elem = tag === "table" && !rtbody.test( elem ) ?
-							tmp.firstChild :
-
-							// String was a bare <thead> or <tfoot>
-							wrap[1] === "<table>" && !rtbody.test( elem ) ?
-								tmp :
-								0;
-
-						j = elem && elem.childNodes.length;
-						while ( j-- ) {
-							if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
-								elem.removeChild( tbody );
-							}
-						}
-					}
-
-					jQuery.merge( nodes, tmp.childNodes );
-
-					// Fix #12392 for WebKit and IE > 9
-					tmp.textContent = "";
-
-					// Fix #12392 for oldIE
-					while ( tmp.firstChild ) {
-						tmp.removeChild( tmp.firstChild );
-					}
-
-					// Remember the top-level container for proper cleanup
-					tmp = safe.lastChild;
-				}
-			}
-		}
-
-		// Fix #11356: Clear elements from fragment
-		if ( tmp ) {
-			safe.removeChild( tmp );
-		}
-
-		// Reset defaultChecked for any radios and checkboxes
-		// about to be appended to the DOM in IE 6/7 (#8060)
-		if ( !support.appendChecked ) {
-			jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
-		}
-
-		i = 0;
-		while ( (elem = nodes[ i++ ]) ) {
-
-			// #4087 - If origin and destination elements are the same, and this is
-			// that element, do not do anything
-			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
-				continue;
-			}
-
-			contains = jQuery.contains( elem.ownerDocument, elem );
-
-			// Append to fragment
-			tmp = getAll( safe.appendChild( elem ), "script" );
-
-			// Preserve script evaluation history
-			if ( contains ) {
-				setGlobalEval( tmp );
-			}
-
-			// Capture executables
-			if ( scripts ) {
-				j = 0;
-				while ( (elem = tmp[ j++ ]) ) {
-					if ( rscriptType.test( elem.type || "" ) ) {
-						scripts.push( elem );
-					}
-				}
-			}
-		}
-
-		tmp = null;
-
-		return safe;
-	},
-
-	cleanData: function( elems, /* internal */ acceptData ) {
-		var elem, type, id, data,
-			i = 0,
-			internalKey = jQuery.expando,
-			cache = jQuery.cache,
-			deleteExpando = support.deleteExpando,
-			special = jQuery.event.special;
-
-		for ( ; (elem = elems[i]) != null; i++ ) {
-			if ( acceptData || jQuery.acceptData( elem ) ) {
-
-				id = elem[ internalKey ];
-				data = id && cache[ id ];
-
-				if ( data ) {
-					if ( data.events ) {
-						for ( type in data.events ) {
-							if ( special[ type ] ) {
-								jQuery.event.remove( elem, type );
-
-							// This is a shortcut to avoid jQuery.event.remove's overhead
-							} else {
-								jQuery.removeEvent( elem, type, data.handle );
-							}
-						}
-					}
-
-					// Remove cache only if it was not already removed by jQuery.event.remove
-					if ( cache[ id ] ) {
-
-						delete cache[ id ];
-
-						// IE does not allow us to delete expando properties from nodes,
-						// nor does it have a removeAttribute function on Document nodes;
-						// we must handle all of these cases
-						if ( deleteExpando ) {
-							delete elem[ internalKey ];
-
-						} else if ( typeof elem.removeAttribute !== strundefined ) {
-							elem.removeAttribute( internalKey );
-
-						} else {
-							elem[ internalKey ] = null;
-						}
-
-						deletedIds.push( id );
-					}
-				}
-			}
-		}
-	}
-});
-
-jQuery.fn.extend({
-	text: function( value ) {
-		return access( this, function( value ) {
-			return value === undefined ?
-				jQuery.text( this ) :
-				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
-		}, null, value, arguments.length );
-	},
-
-	append: function() {
-		return this.domManip( arguments, function( elem ) {
-			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-				var target = manipulationTarget( this, elem );
-				target.appendChild( elem );
-			}
-		});
-	},
-
-	prepend: function() {
-		return this.domManip( arguments, function( elem ) {
-			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-				var target = manipulationTarget( this, elem );
-				target.insertBefore( elem, target.firstChild );
-			}
-		});
-	},
-
-	before: function() {
-		return this.domManip( arguments, function( elem ) {
-			if ( this.parentNode ) {
-				this.parentNode.insertBefore( elem, this );
-			}
-		});
-	},
-
-	after: function() {
-		return this.domManip( arguments, function( elem ) {
-			if ( this.parentNode ) {
-				this.parentNode.insertBefore( elem, this.nextSibling );
-			}
-		});
-	},
-
-	remove: function( selector, keepData /* Internal Use Only */ ) {
-		var elem,
-			elems = selector ? jQuery.filter( selector, this ) : this,
-			i = 0;
-
-		for ( ; (elem = elems[i]) != null; i++ ) {
-
-			if ( !keepData && elem.nodeType === 1 ) {
-				jQuery.cleanData( getAll( elem ) );
-			}
-
-			if ( elem.parentNode ) {
-				if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
-					setGlobalEval( getAll( elem, "script" ) );
-				}
-				elem.parentNode.removeChild( elem );
-			}
-		}
-
-		return this;
-	},
-
-	empty: function() {
-		var elem,
-			i = 0;
-
-		for ( ; (elem = this[i]) != null; i++ ) {
-			// Remove element nodes and prevent memory leaks
-			if ( elem.nodeType === 1 ) {
-				jQuery.cleanData( getAll( elem, false ) );
-			}
-
-			// Remove any remaining nodes
-			while ( elem.firstChild ) {
-				elem.removeChild( elem.firstChild );
-			}
-
-			// If this is a select, ensure that it displays empty (#12336)
-			// Support: IE<9
-			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
-				elem.options.length = 0;
-			}
-		}
-
-		return this;
-	},
-
-	clone: function( dataAndEvents, deepDataAndEvents ) {
-		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
-		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
-		return this.map(function() {
-			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
-		});
-	},
-
-	html: function( value ) {
-		return access( this, function( value ) {
-			var elem = this[ 0 ] || {},
-				i = 0,
-				l = this.length;
-
-			if ( value === undefined ) {
-				return elem.nodeType === 1 ?
-					elem.innerHTML.replace( rinlinejQuery, "" ) :
-					undefined;
-			}
-
-			// See if we can take a shortcut and just use innerHTML
-			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
-				( support.htmlSerialize || !rnoshimcache.test( value )  ) &&
-				( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
-				!wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
-
-				value = value.replace( rxhtmlTag, "<$1></$2>" );
-
-				try {
-					for (; i < l; i++ ) {
-						// Remove element nodes and prevent memory leaks
-						elem = this[i] || {};
-						if ( elem.nodeType === 1 ) {
-							jQuery.cleanData( getAll( elem, false ) );
-							elem.innerHTML = value;
-						}
-					}
-
-					elem = 0;
-
-				// If using innerHTML throws an exception, use the fallback method
-				} catch(e) {}
-			}
-
-			if ( elem ) {
-				this.empty().append( value );
-			}
-		}, null, value, arguments.length );
-	},
-
-	replaceWith: function() {
-		var arg = arguments[ 0 ];
-
-		// Make the changes, replacing each context element with the new content
-		this.domManip( arguments, function( elem ) {
-			arg = this.parentNode;
-
-			jQuery.cleanData( getAll( this ) );
-
-			if ( arg ) {
-				arg.replaceChild( elem, this );
-			}
-		});
-
-		// Force removal if there was no new content (e.g., from empty arguments)
-		return arg && (arg.length || arg.nodeType) ? this : this.remove();
-	},
-
-	detach: function( selector ) {
-		return this.remove( selector, true );
-	},
-
-	domManip: function( args, callback ) {
-
-		// Flatten any nested arrays
-		args = concat.apply( [], args );
-
-		var first, node, hasScripts,
-			scripts, doc, fragment,
-			i = 0,
-			l = this.length,
-			set = this,
-			iNoClone = l - 1,
-			value = args[0],
-			isFunction = jQuery.isFunction( value );
-
-		// We can't cloneNode fragments that contain checked, in WebKit
-		if ( isFunction ||
-				( l > 1 && typeof value === "string" &&
-					!support.checkClone && rchecked.test( value ) ) ) {
-			return this.each(function( index ) {
-				var self = set.eq( index );
-				if ( isFunction ) {
-					args[0] = value.call( this, index, self.html() );
-				}
-				self.domManip( args, callback );
-			});
-		}
-
-		if ( l ) {
-			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
-			first = fragment.firstChild;
-
-			if ( fragment.childNodes.length === 1 ) {
-				fragment = first;
-			}
-
-			if ( first ) {
-				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
-				hasScripts = scripts.length;
-
-				// Use the original fragment for the last item instead of the first because it can end up
-				// being emptied incorrectly in certain situations (#8070).
-				for ( ; i < l; i++ ) {
-					node = fragment;
-
-					if ( i !== iNoClone ) {
-						node = jQuery.clone( node, true, true );
-
-						// Keep references to cloned scripts for later restoration
-						if ( hasScripts ) {
-							jQuery.merge( scripts, getAll( node, "script" ) );
-						}
-					}
-
-					callback.call( this[i], node, i );
-				}
-
-				if ( hasScripts ) {
-					doc = scripts[ scripts.length - 1 ].ownerDocument;
-
-					// Reenable scripts
-					jQuery.map( scripts, restoreScript );
-
-					// Evaluate executable scripts on first document insertion
-					for ( i = 0; i < hasScripts; i++ ) {
-						node = scripts[ i ];
-						if ( rscriptType.test( node.type || "" ) &&
-							!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
-
-							if ( node.src ) {
-								// Optional AJAX dependency, but won't run scripts if not present
-								if ( jQuery._evalUrl ) {
-									jQuery._evalUrl( node.src );
-								}
-							} else {
-								jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
-							}
-						}
-					}
-				}
-
-				// Fix #11809: Avoid leaking memory
-				fragment = first = null;
-			}
-		}
-
-		return this;
-	}
-});
-
-jQuery.each({
-	appendTo: "append",
-	prependTo: "prepend",
-	insertBefore: "before",
-	insertAfter: "after",
-	replaceAll: "replaceWith"
-}, function( name, original ) {
-	jQuery.fn[ name ] = function( selector ) {
-		var elems,
-			i = 0,
-			ret = [],
-			insert = jQuery( selector ),
-			last = insert.length - 1;
-
-		for ( ; i <= last; i++ ) {
-			elems = i === last ? this : this.clone(true);
-			jQuery( insert[i] )[ original ]( elems );
-
-			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
-			push.apply( ret, elems.get() );
-		}
-
-		return this.pushStack( ret );
-	};
-});
-
-
-var iframe,
-	elemdisplay = {};
-
-/**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-// Called only from within defaultDisplay
-function actualDisplay( name, doc ) {
-	var style,
-		elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
-		// getDefaultComputedStyle might be reliably used only on attached element
-		display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
-
-			// Use of this method is a temporary fix (more like optmization) until something better comes along,
-			// since it was removed from specification and supported only in FF
-			style.display : jQuery.css( elem[ 0 ], "display" );
-
-	// We don't have any data stored on the element,
-	// so use "detach" method as fast way to get rid of the element
-	elem.detach();
-
-	return display;
-}
-
-/**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
-function defaultDisplay( nodeName ) {
-	var doc = document,
-		display = elemdisplay[ nodeName ];
-
-	if ( !display ) {
-		display = actualDisplay( nodeName, doc );
-
-		// If the simple way fails, read from inside an iframe
-		if ( display === "none" || !display ) {
-
-			// Use the already-created iframe if possible
-			iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
-
-			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
-			doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
-
-			// Support: IE
-			doc.write();
-			doc.close();
-
-			display = actualDisplay( nodeName, doc );
-			iframe.detach();
-		}
-
-		// Store the correct default display
-		elemdisplay[ nodeName ] = display;
-	}
-
-	return display;
-}
-
-
-(function() {
-	var shrinkWrapBlocksVal;
-
-	support.shrinkWrapBlocks = function() {
-		if ( shrinkWrapBlocksVal != null ) {
-			return shrinkWrapBlocksVal;
-		}
-
-		// Will be changed later if needed.
-		shrinkWrapBlocksVal = false;
-
-		// Minified: var b,c,d
-		var div, body, container;
-
-		body = document.getElementsByTagName( "body" )[ 0 ];
-		if ( !body || !body.style ) {
-			// Test fired too early or in an unsupported environment, exit.
-			return;
-		}
-
-		// Setup
-		div = document.createElement( "div" );
-		container = document.createElement( "div" );
-		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
-		body.appendChild( container ).appendChild( div );
-
-		// Support: IE6
-		// Check if elements with layout shrink-wrap their children
-		if ( typeof div.style.zoom !== strundefined ) {
-			// Reset CSS: box-sizing; display; margin; border
-			div.style.cssText =
-				// Support: Firefox<29, Android 2.3
-				// Vendor-prefix box-sizing
-				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
-				"box-sizing:content-box;display:block;margin:0;border:0;" +
-				"padding:1px;width:1px;zoom:1";
-			div.appendChild( document.createElement( "div" ) ).style.width = "5px";
-			shrinkWrapBlocksVal = div.offsetWidth !== 3;
-		}
-
-		body.removeChild( container );
-
-		return shrinkWrapBlocksVal;
-	};
-
-})();
-var rmargin = (/^margin/);
-
-var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
-
-
-var getStyles, curCSS,
-	rposition = /^(top|right|bottom|left)$/;
-
-if ( window.getComputedStyle ) {
-	getStyles = function( elem ) {
-		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
-		// IE throws on elements created in popups
-		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
-		if ( elem.ownerDocument.defaultView.opener ) {
-			return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
-		}
-
-		return window.getComputedStyle( elem, null );
-	};
-
-	curCSS = function( elem, name, computed ) {
-		var width, minWidth, maxWidth, ret,
-			style = elem.style;
-
-		computed = computed || getStyles( elem );
-
-		// getPropertyValue is only needed for .css('filter') in IE9, see #12537
-		ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
-
-		if ( computed ) {
-
-			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
-				ret = jQuery.style( elem, name );
-			}
-
-			// A tribute to the "awesome hack by Dean Edwards"
-			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
-			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
-			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
-			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
-
-				// Remember the original values
-				width = style.width;
-				minWidth = style.minWidth;
-				maxWidth = style.maxWidth;
-
-				// Put in the new values to get a computed value out
-				style.minWidth = style.maxWidth = style.width = ret;
-				ret = computed.width;
-
-				// Revert the changed values
-				style.width = width;
-				style.minWidth = minWidth;
-				style.maxWidth = maxWidth;
-			}
-		}
-
-		// Support: IE
-		// IE returns zIndex value as an integer.
-		return ret === undefined ?
-			ret :
-			ret + "";
-	};
-} else if ( document.documentElement.currentStyle ) {
-	getStyles = function( elem ) {
-		return elem.currentStyle;
-	};
-
-	curCSS = function( elem, name, computed ) {
-		var left, rs, rsLeft, ret,
-			style = elem.style;
-
-		computed = computed || getStyles( elem );
-		ret = computed ? computed[ name ] : undefined;
-
-		// Avoid setting ret to empty string here
-		// so we don't default to auto
-		if ( ret == null && style && style[ name ] ) {
-			ret = style[ name ];
-		}
-
-		// From the awesome hack by Dean Edwards
-		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
-		// If we're not dealing with a regular pixel number
-		// but a number that has a weird ending, we need to convert it to pixels
-		// but not position css attributes, as those are proportional to the parent element instead
-		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
-		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
-
-			// Remember the original values
-			left = style.left;
-			rs = elem.runtimeStyle;
-			rsLeft = rs && rs.left;
-
-			// Put in the new values to get a computed value out
-			if ( rsLeft ) {
-				rs.left = elem.currentStyle.left;
-			}
-			style.left = name === "fontSize" ? "1em" : ret;
-			ret = style.pixelLeft + "px";
-
-			// Revert the changed values
-			style.left = left;
-			if ( rsLeft ) {
-				rs.left = rsLeft;
-			}
-		}
-
-		// Support: IE
-		// IE returns zIndex value as an integer.
-		return ret === undefined ?
-			ret :
-			ret + "" || "auto";
-	};
-}
-
-
-
-
-function addGetHookIf( conditionFn, hookFn ) {
-	// Define the hook, we'll check on the first run if it's really needed.
-	return {
-		get: function() {
-			var condition = conditionFn();
-
-			if ( condition == null ) {
-				// The test was not ready at this point; screw the hook this time
-				// but check again when needed next time.
-				return;
-			}
-
-			if ( condition ) {
-				// Hook not needed (or it's not possible to use it due to missing dependency),
-				// remove it.
-				// Since there are no other hooks for marginRight, remove the whole object.
-				delete this.get;
-				return;
-			}
-
-			// Hook needed; redefine it so that the support test is not executed again.
-
-			return (this.get = hookFn).apply( this, arguments );
-		}
-	};
-}
-
-
-(function() {
-	// Minified: var b,c,d,e,f,g, h,i
-	var div, style, a, pixelPositionVal, boxSizingReliableVal,
-		reliableHiddenOffsetsVal, reliableMarginRightVal;
-
-	// Setup
-	div = document.createElement( "div" );
-	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
-	a = div.getElementsByTagName( "a" )[ 0 ];
-	style = a && a.style;
-
-	// Finish early in limited (non-browser) environments
-	if ( !style ) {
-		return;
-	}
-
-	style.cssText = "float:left;opacity:.5";
-
-	// Support: IE<9
-	// Make sure that element opacity exists (as opposed to filter)
-	support.opacity = style.opacity === "0.5";
-
-	// Verify style float existence
-	// (IE uses styleFloat instead of cssFloat)
-	support.cssFloat = !!style.cssFloat;
-
-	div.style.backgroundClip = "content-box";
-	div.cloneNode( true ).style.backgroundClip = "";
-	support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
-	// Support: Firefox<29, Android 2.3
-	// Vendor-prefix box-sizing
-	support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
-		style.WebkitBoxSizing === "";
-
-	jQuery.extend(support, {
-		reliableHiddenOffsets: function() {
-			if ( reliableHiddenOffsetsVal == null ) {
-				computeStyleTests();
-			}
-			return reliableHiddenOffsetsVal;
-		},
-
-		boxSizingReliable: function() {
-			if ( boxSizingReliableVal == null ) {
-				computeStyleTests();
-			}
-			return boxSizingReliableVal;
-		},
-
-		pixelPosition: function() {
-			if ( pixelPositionVal == null ) {
-				computeStyleTests();
-			}
-			return pixelPositionVal;
-		},
-
-		// Support: Android 2.3
-		reliableMarginRight: function() {
-			if ( reliableMarginRightVal == null ) {
-				computeStyleTests();
-			}
-			return reliableMarginRightVal;
-		}
-	});
-
-	function computeStyleTests() {
-		// Minified: var b,c,d,j
-		var div, body, container, contents;
-
-		body = document.getElementsByTagName( "body" )[ 0 ];
-		if ( !body || !body.style ) {
-			// Test fired too early or in an unsupported environment, exit.
-			return;
-		}
-
-		// Setup
-		div = document.createElement( "div" );
-		container = document.createElement( "div" );
-		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
-		body.appendChild( container ).appendChild( div );
-
-		div.style.cssText =
-			// Support: Firefox<29, Android 2.3
-			// Vendor-prefix box-sizing
-			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
-			"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
-			"border:1px;padding:1px;width:4px;position:absolute";
-
-		// Support: IE<9
-		// Assume reasonable values in the absence of getComputedStyle
-		pixelPositionVal = boxSizingReliableVal = false;
-		reliableMarginRightVal = true;
-
-		// Check for getComputedStyle so that this code is not run in IE<9.
-		if ( window.getComputedStyle ) {
-			pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
-			boxSizingReliableVal =
-				( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
-
-			// Support: Android 2.3
-			// Div with explicit width and no margin-right incorrectly
-			// gets computed margin-right based on width of container (#3333)
-			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-			contents = div.appendChild( document.createElement( "div" ) );
-
-			// Reset CSS: box-sizing; display; margin; border; padding
-			contents.style.cssText = div.style.cssText =
-				// Support: Firefox<29, Android 2.3
-				// Vendor-prefix box-sizing
-				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
-				"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
-			contents.style.marginRight = contents.style.width = "0";
-			div.style.width = "1px";
-
-			reliableMarginRightVal =
-				!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
-
-			div.removeChild( contents );
-		}
-
-		// Support: IE8
-		// Check if table cells still have offsetWidth/Height when they are set
-		// to display:none and there are still other visible table cells in a
-		// table row; if so, offsetWidth/Height are not reliable for use when
-		// determining if an element has been hidden directly using
-		// display:none (it is still safe to use offsets if a parent element is
-		// hidden; don safety goggles and see bug #4512 for more information).
-		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
-		contents = div.getElementsByTagName( "td" );
-		contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
-		reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
-		if ( reliableHiddenOffsetsVal ) {
-			contents[ 0 ].style.display = "";
-			contents[ 1 ].style.display = "none";
-			reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
-		}
-
-		body.removeChild( container );
-	}
-
-})();
-
-
-// A method for quickly swapping in/out CSS properties to get correct calculations.
-jQuery.swap = function( elem, options, callback, args ) {
-	var ret, name,
-		old = {};
-
-	// Remember the old values, and insert the new ones
-	for ( name in options ) {
-		old[ name ] = elem.style[ name ];
-		elem.style[ name ] = options[ name ];
-	}
-
-	ret = callback.apply( elem, args || [] );
-
-	// Revert the old values
-	for ( name in options ) {
-		elem.style[ name ] = old[ name ];
-	}
-
-	return ret;
-};
-
-
-var
-		ralpha = /alpha\([^)]*\)/i,
-	ropacity = /opacity\s*=\s*([^)]*)/,
-
-	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
-	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
-	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
-	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
-	rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
-
-	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
-	cssNormalTransform = {
-		letterSpacing: "0",
-		fontWeight: "400"
-	},
-
-	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
-
-
-// return a css property mapped to a potentially vendor prefixed property
-function vendorPropName( style, name ) {
-
-	// shortcut for names that are not vendor prefixed
-	if ( name in style ) {
-		return name;
-	}
-
-	// check for vendor prefixed names
-	var capName = name.charAt(0).toUpperCase() + name.slice(1),
-		origName = name,
-		i = cssPrefixes.length;
-
-	while ( i-- ) {
-		name = cssPrefixes[ i ] + capName;
-		if ( name in style ) {
-			return name;
-		}
-	}
-
-	return origName;
-}
-
-function showHide( elements, show ) {
-	var display, elem, hidden,
-		values = [],
-		index = 0,
-		length = elements.length;
-
-	for ( ; index < length; index++ ) {
-		elem = elements[ index ];
-		if ( !elem.style ) {
-			continue;
-		}
-
-		values[ index ] = jQuery._data( elem, "olddisplay" );
-		display = elem.style.display;
-		if ( show ) {
-			// Reset the inline display of this element to learn if it is
-			// being hidden by cascaded rules or not
-			if ( !values[ index ] && display === "none" ) {
-				elem.style.display = "";
-			}
-
-			// Set elements which have been overridden with display: none
-			// in a stylesheet to whatever the default browser style is
-			// for such an element
-			if ( elem.style.display === "" && isHidden( elem ) ) {
-				values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
-			}
-		} else {
-			hidden = isHidden( elem );
-
-			if ( display && display !== "none" || !hidden ) {
-				jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
-			}
-		}
-	}
-
-	// Set the display of most of the elements in a second loop
-	// to avoid the constant reflow
-	for ( index = 0; index < length; index++ ) {
-		elem = elements[ index ];
-		if ( !elem.style ) {
-			continue;
-		}
-		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
-			elem.style.display = show ? values[ index ] || "" : "none";
-		}
-	}
-
-	return elements;
-}
-
-function setPositiveNumber( elem, value, subtract ) {
-	var matches = rnumsplit.exec( value );
-	return matches ?
-		// Guard against undefined "subtract", e.g., when used as in cssHooks
-		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
-		value;
-}
-
-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
-	var i = extra === ( isBorderBox ? "border" : "content" ) ?
-		// If we already have the right measurement, avoid augmentation
-		4 :
-		// Otherwise initialize for horizontal or vertical properties
-		name === "width" ? 1 : 0,
-
-		val = 0;
-
-	for ( ; i < 4; i += 2 ) {
-		// both box models exclude margin, so add it if we want it
-		if ( extra === "margin" ) {
-			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
-		}
-
-		if ( isBorderBox ) {
-			// border-box includes padding, so remove it if we want content
-			if ( extra === "content" ) {
-				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-			}
-
-			// at this point, extra isn't border nor margin, so remove border
-			if ( extra !== "margin" ) {
-				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-			}
-		} else {
-			// at this point, extra isn't content, so add padding
-			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-
-			// at this point, extra isn't content nor padding, so add border
-			if ( extra !== "padding" ) {
-				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-			}
-		}
-	}
-
-	return val;
-}
-
-function getWidthOrHeight( elem, name, extra ) {
-
-	// Start with offset property, which is equivalent to the border-box value
-	var valueIsBorderBox = true,
-		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
-		styles = getStyles( elem ),
-		isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
-
-	// some non-html elements return undefined for offsetWidth, so check for null/undefined
-	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
-	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
-	if ( val <= 0 || val == null ) {
-		// Fall back to computed then uncomputed css if necessary
-		val = curCSS( elem, name, styles );
-		if ( val < 0 || val == null ) {
-			val = elem.style[ name ];
-		}
-
-		// Computed unit is not pixels. Stop here and return.
-		if ( rnumnonpx.test(val) ) {
-			return val;
-		}
-
-		// we need the check for style in case a browser which returns unreliable values
-		// for getComputedStyle silently falls back to the reliable elem.style
-		valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
-
-		// Normalize "", auto, and prepare for extra
-		val = parseFloat( val ) || 0;
-	}
-
-	// use the active box-sizing model to add/subtract irrelevant styles
-	return ( val +
-		augmentWidthOrHeight(
-			elem,
-			name,
-			extra || ( isBorderBox ? "border" : "content" ),
-			valueIsBorderBox,
-			styles
-		)
-	) + "px";
-}
-
-jQuery.extend({
-	// Add in style property hooks for overriding the default
-	// behavior of getting and setting a style property
-	cssHooks: {
-		opacity: {
-			get: function( elem, computed ) {
-				if ( computed ) {
-					// We should always get a number back from opacity
-					var ret = curCSS( elem, "opacity" );
-					return ret === "" ? "1" : ret;
-				}
-			}
-		}
-	},
-
-	// Don't automatically add "px" to these possibly-unitless properties
-	cssNumber: {
-		"columnCount": true,
-		"fillOpacity": true,
-		"flexGrow": true,
-		"flexShrink": true,
-		"fontWeight": true,
-		"lineHeight": true,
-		"opacity": true,
-		"order": true,
-		"orphans": true,
-		"widows": true,
-		"zIndex": true,
-		"zoom": true
-	},
-
-	// Add in properties whose names you wish to fix before
-	// setting or getting the value
-	cssProps: {
-		// normalize float css property
-		"float": support.cssFloat ? "cssFloat" : "styleFloat"
-	},
-
-	// Get and set the style property on a DOM Node
-	style: function( elem, name, value, extra ) {
-		// Don't set styles on text and comment nodes
-		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
-			return;
-		}
-
-		// Make sure that we're working with the right name
-		var ret, type, hooks,
-			origName = jQuery.camelCase( name ),
-			style = elem.style;
-
-		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
-
-		// gets hook for the prefixed version
-		// followed by the unprefixed version
-		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
-		// Check if we're setting a value
-		if ( value !== undefined ) {
-			type = typeof value;
-
-			// convert relative number strings (+= or -=) to relative numbers. #7345
-			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
-				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
-				// Fixes bug #9237
-				type = "number";
-			}
-
-			// Make sure that null and NaN values aren't set. See: #7116
-			if ( value == null || value !== value ) {
-				return;
-			}
-
-			// If a number was passed in, add 'px' to the (except for certain CSS properties)
-			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
-				value += "px";
-			}
-
-			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
-			// but it would mean to define eight (for every problematic property) identical functions
-			if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
-				style[ name ] = "inherit";
-			}
-
-			// If a hook was provided, use that value, otherwise just set the specified value
-			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
-
-				// Support: IE
-				// Swallow errors from 'invalid' CSS values (#5509)
-				try {
-					style[ name ] = value;
-				} catch(e) {}
-			}
-
-		} else {
-			// If a hook was provided get the non-computed value from there
-			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
-				return ret;
-			}
-
-			// Otherwise just get the value from the style object
-			return style[ name ];
-		}
-	},
-
-	css: function( elem, name, extra, styles ) {
-		var num, val, hooks,
-			origName = jQuery.camelCase( name );
-
-		// Make sure that we're working with the right name
-		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
-
-		// gets hook for the prefixed version
-		// followed by the unprefixed version
-		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
-		// If a hook was provided get the computed value from there
-		if ( hooks && "get" in hooks ) {
-			val = hooks.get( elem, true, extra );
-		}
-
-		// Otherwise, if a way to get the computed value exists, use that
-		if ( val === undefined ) {
-			val = curCSS( elem, name, styles );
-		}
-
-		//convert "normal" to computed value
-		if ( val === "normal" && name in cssNormalTransform ) {
-			val = cssNormalTransform[ name ];
-		}
-
-		// Return, converting to number if forced or a qualifier was provided and val looks numeric
-		if ( extra === "" || extra ) {
-			num = parseFloat( val );
-			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
-		}
-		return val;
-	}
-});
-
-jQuery.each([ "height", "width" ], function( i, name ) {
-	jQuery.cssHooks[ name ] = {
-		get: function( elem, computed, extra ) {
-			if ( computed ) {
-				// certain elements can have dimension info if we invisibly show them
-				// however, it must have a current display style that would benefit from this
-				return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
-					jQuery.swap( elem, cssShow, function() {
-						return getWidthOrHeight( elem, name, extra );
-					}) :
-					getWidthOrHeight( elem, name, extra );
-			}
-		},
-
-		set: function( elem, value, extra ) {
-			var styles = extra && getStyles( elem );
-			return setPositiveNumber( elem, value, extra ?
-				augmentWidthOrHeight(
-					elem,
-					name,
-					extra,
-					support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
-					styles
-				) : 0
-			);
-		}
-	};
-});
-
-if ( !support.opacity ) {
-	jQuery.cssHooks.opacity = {
-		get: function( elem, computed ) {
-			// IE uses filters for opacity
-			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
-				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
-				computed ? "1" : "";
-		},
-
-		set: function( elem, value ) {
-			var style = elem.style,
-				currentStyle = elem.currentStyle,
-				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
-				filter = currentStyle && currentStyle.filter || style.filter || "";
-
-			// IE has trouble with opacity if it does not have layout
-			// Force it by setting the zoom level
-			style.zoom = 1;
-
-			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
-			// if value === "", then remove inline opacity #12685
-			if ( ( value >= 1 || value === "" ) &&
-					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
-					style.removeAttribute ) {
-
-				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
-				// if "filter:" is present at all, clearType is disabled, we want to avoid this
-				// style.removeAttribute is IE Only, but so apparently is this code path...
-				style.removeAttribute( "filter" );
-
-				// if there is no filter style applied in a css rule or unset inline opacity, we are done
-				if ( value === "" || currentStyle && !currentStyle.filter ) {
-					return;
-				}
-			}
-
-			// otherwise, set new filter values
-			style.filter = ralpha.test( filter ) ?
-				filter.replace( ralpha, opacity ) :
-				filter + " " + opacity;
-		}
-	};
-}
-
-jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
-	function( elem, computed ) {
-		if ( computed ) {
-			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-			// Work around by temporarily setting element display to inline-block
-			return jQuery.swap( elem, { "display": "inline-block" },
-				curCSS, [ elem, "marginRight" ] );
-		}
-	}
-);
-
-// These hooks are used by animate to expand properties
-jQuery.each({
-	margin: "",
-	padding: "",
-	border: "Width"
-}, function( prefix, suffix ) {
-	jQuery.cssHooks[ prefix + suffix ] = {
-		expand: function( value ) {
-			var i = 0,
-				expanded = {},
-
-				// assumes a single number if not a string
-				parts = typeof value === "string" ? value.split(" ") : [ value ];
-
-			for ( ; i < 4; i++ ) {
-				expanded[ prefix + cssExpand[ i ] + suffix ] =
-					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
-			}
-
-			return expanded;
-		}
-	};
-
-	if ( !rmargin.test( prefix ) ) {
-		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
-	}
-});
-
-jQuery.fn.extend({
-	css: function( name, value ) {
-		return access( this, function( elem, name, value ) {
-			var styles, len,
-				map = {},
-				i = 0;
-
-			if ( jQuery.isArray( name ) ) {
-				styles = getStyles( elem );
-				len = name.length;
-
-				for ( ; i < len; i++ ) {
-					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
-				}
-
-				return map;
-			}
-
-			return value !== undefined ?
-				jQuery.style( elem, name, value ) :
-				jQuery.css( elem, name );
-		}, name, value, arguments.length > 1 );
-	},
-	show: function() {
-		return showHide( this, true );
-	},
-	hide: function() {
-		return showHide( this );
-	},
-	toggle: function( state ) {
-		if ( typeof state === "boolean" ) {
-			return state ? this.show() : this.hide();
-		}
-
-		return this.each(function() {
-			if ( isHidden( this ) ) {
-				jQuery( this ).show();
-			} else {
-				jQuery( this ).hide();
-			}
-		});
-	}
-});
-
-
-function Tween( elem, options, prop, end, easing ) {
-	return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
-	constructor: Tween,
-	init: function( elem, options, prop, end, easing, unit ) {
-		this.elem = elem;
-		this.prop = prop;
-		this.easing = easing || "swing";
-		this.options = options;
-		this.start = this.now = this.cur();
-		this.end = end;
-		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
-	},
-	cur: function() {
-		var hooks = Tween.propHooks[ this.prop ];
-
-		return hooks && hooks.get ?
-			hooks.get( this ) :
-			Tween.propHooks._default.get( this );
-	},
-	run: function( percent ) {
-		var eased,
-			hooks = Tween.propHooks[ this.prop ];
-
-		if ( this.options.duration ) {
-			this.pos = eased = jQuery.easing[ this.easing ](
-				percent, this.options.duration * percent, 0, 1, this.options.duration
-			);
-		} else {
-			this.pos = eased = percent;
-		}
-		this.now = ( this.end - this.start ) * eased + this.start;
-
-		if ( this.options.step ) {
-			this.options.step.call( this.elem, this.now, this );
-		}
-
-		if ( hooks && hooks.set ) {
-			hooks.set( this );
-		} else {
-			Tween.propHooks._default.set( this );
-		}
-		return this;
-	}
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
-	_default: {
-		get: function( tween ) {
-			var result;
-
-			if ( tween.elem[ tween.prop ] != null &&
-				(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
-				return tween.elem[ tween.prop ];
-			}
-
-			// passing an empty string as a 3rd parameter to .css will automatically
-			// attempt a parseFloat and fallback to a string if the parse fails
-			// so, simple values such as "10px" are parsed to Float.
-			// complex values such as "rotate(1rad)" are returned as is.
-			result = jQuery.css( tween.elem, tween.prop, "" );
-			// Empty strings, null, undefined and "auto" are converted to 0.
-			return !result || result === "auto" ? 0 : result;
-		},
-		set: function( tween ) {
-			// use step hook for back compat - use cssHook if its there - use .style if its
-			// available and use plain properties where available
-			if ( jQuery.fx.step[ tween.prop ] ) {
-				jQuery.fx.step[ tween.prop ]( tween );
-			} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
-				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
-			} else {
-				tween.elem[ tween.prop ] = tween.now;
-			}
-		}
-	}
-};
-
-// Support: IE <=9
-// Panic based approach to setting things on disconnected nodes
-
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
-	set: function( tween ) {
-		if ( tween.elem.nodeType && tween.elem.parentNode ) {
-			tween.elem[ tween.prop ] = tween.now;
-		}
-	}
-};
-
-jQuery.easing = {
-	linear: function( p ) {
-		return p;
-	},
-	swing: function( p ) {
-		return 0.5 - Math.cos( p * Math.PI ) / 2;
-	}
-};
-
-jQuery.fx = Tween.prototype.init;
-
-// Back Compat <1.8 extension point
-jQuery.fx.step = {};
-
-
-
-
-var
-	fxNow, timerId,
-	rfxtypes = /^(?:toggle|show|hide)$/,
-	rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
-	rrun = /queueHooks$/,
-	animationPrefilters = [ defaultPrefilter ],
-	tweeners = {
-		"*": [ function( prop, value ) {
-			var tween = this.createTween( prop, value ),
-				target = tween.cur(),
-				parts = rfxnum.exec( value ),
-				unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
-				// Starting value computation is required for potential unit mismatches
-				start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
-					rfxnum.exec( jQuery.css( tween.elem, prop ) ),
-				scale = 1,
-				maxIterations = 20;
-
-			if ( start && start[ 3 ] !== unit ) {
-				// Trust units reported by jQuery.css
-				unit = unit || start[ 3 ];
-
-				// Make sure we update the tween properties later on
-				parts = parts || [];
-
-				// Iteratively approximate from a nonzero starting point
-				start = +target || 1;
-
-				do {
-					// If previous iteration zeroed out, double until we get *something*
-					// Use a string for doubling factor so we don't accidentally see scale as unchanged below
-					scale = scale || ".5";
-
-					// Adjust and apply
-					start = start / scale;
-					jQuery.style( tween.elem, prop, start + unit );
-
-				// Update scale, tolerating zero or NaN from tween.cur()
-				// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
-				} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
-			}
-
-			// Update tween properties
-			if ( parts ) {
-				start = tween.start = +start || +target || 0;
-				tween.unit = unit;
-				// If a +=/-= token was provided, we're doing a relative animation
-				tween.end = parts[ 1 ] ?
-					start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
-					+parts[ 2 ];
-			}
-
-			return tween;
-		} ]
-	};
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
-	setTimeout(function() {
-		fxNow = undefined;
-	});
-	return ( fxNow = jQuery.now() );
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
-	var which,
-		attrs = { height: type },
-		i = 0;
-
-	// if we include width, step value is 1 to do all cssExpand values,
-	// if we don't include width, step value is 2 to skip over Left and Right
-	includeWidth = includeWidth ? 1 : 0;
-	for ( ; i < 4 ; i += 2 - includeWidth ) {
-		which = cssExpand[ i ];
-		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
-	}
-
-	if ( includeWidth ) {
-		attrs.opacity = attrs.width = type;
-	}
-
-	return attrs;
-}
-
-function createTween( value, prop, animation ) {
-	var tween,
-		collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
-		index = 0,
-		length = collection.length;
-	for ( ; index < length; index++ ) {
-		if ( (tween = collection[ index ].call( animation, prop, value )) ) {
-
-			// we're done with this property
-			return tween;
-		}
-	}
-}
-
-function defaultPrefilter( elem, props, opts ) {
-	/* jshint validthis: true */
-	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
-		anim = this,
-		orig = {},
-		style = elem.style,
-		hidden = elem.nodeType && isHidden( elem ),
-		dataShow = jQuery._data( elem, "fxshow" );
-
-	// handle queue: false promises
-	if ( !opts.queue ) {
-		hooks = jQuery._queueHooks( elem, "fx" );
-		if ( hooks.unqueued == null ) {
-			hooks.unqueued = 0;
-			oldfire = hooks.empty.fire;
-			hooks.empty.fire = function() {
-				if ( !hooks.unqueued ) {
-					oldfire();
-				}
-			};
-		}
-		hooks.unqueued++;
-
-		anim.always(function() {
-			// doing this makes sure that the complete handler will be called
-			// before this completes
-			anim.always(function() {
-				hooks.unqueued--;
-				if ( !jQuery.queue( elem, "fx" ).length ) {
-					hooks.empty.fire();
-				}
-			});
-		});
-	}
-
-	// height/width overflow pass
-	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
-		// Make sure that nothing sneaks out
-		// Record all 3 overflow attributes because IE does not
-		// change the overflow attribute when overflowX and
-		// overflowY are set to the same value
-		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
-		// Set display property to inline-block for height/width
-		// animations on inline elements that are having width/height animated
-		display = jQuery.css( elem, "display" );
-
-		// Test default display if display is currently "none"
-		checkDisplay = display === "none" ?
-			jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
-
-		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
-
-			// inline-level elements accept inline-block;
-			// block-level elements need to be inline with layout
-			if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
-				style.display = "inline-block";
-			} else {
-				style.zoom = 1;
-			}
-		}
-	}
-
-	if ( opts.overflow ) {
-		style.overflow = "hidden";
-		if ( !support.shrinkWrapBlocks() ) {
-			anim.always(function() {
-				style.overflow = opts.overflow[ 0 ];
-				style.overflowX = opts.overflow[ 1 ];
-				style.overflowY = opts.overflow[ 2 ];
-			});
-		}
-	}
-
-	// show/hide pass
-	for ( prop in props ) {
-		value = props[ prop ];
-		if ( rfxtypes.exec( value ) ) {
-			delete props[ prop ];
-			toggle = toggle || value === "toggle";
-			if ( value === ( hidden ? "hide" : "show" ) ) {
-
-				// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
-				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
-					hidden = true;
-				} else {
-					continue;
-				}
-			}
-			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
-
-		// Any non-fx value stops us from restoring the original display value
-		} else {
-			display = undefined;
-		}
-	}
-
-	if ( !jQuery.isEmptyObject( orig ) ) {
-		if ( dataShow ) {
-			if ( "hidden" in dataShow ) {
-				hidden = dataShow.hidden;
-			}
-		} else {
-			dataShow = jQuery._data( elem, "fxshow", {} );
-		}
-
-		// store state if its toggle - enables .stop().toggle() to "reverse"
-		if ( toggle ) {
-			dataShow.hidden = !hidden;
-		}
-		if ( hidden ) {
-			jQuery( elem ).show();
-		} else {
-			anim.done(function() {
-				jQuery( elem ).hide();
-			});
-		}
-		anim.done(function() {
-			var prop;
-			jQuery._removeData( elem, "fxshow" );
-			for ( prop in orig ) {
-				jQuery.style( elem, prop, orig[ prop ] );
-			}
-		});
-		for ( prop in orig ) {
-			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
-
-			if ( !( prop in dataShow ) ) {
-				dataShow[ prop ] = tween.start;
-				if ( hidden ) {
-					tween.end = tween.start;
-					tween.start = prop === "width" || prop === "height" ? 1 : 0;
-				}
-			}
-		}
-
-	// If this is a noop like .hide().hide(), restore an overwritten display value
-	} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
-		style.display = display;
-	}
-}
-
-function propFilter( props, specialEasing ) {
-	var index, name, easing, value, hooks;
-
-	// camelCase, specialEasing and expand cssHook pass
-	for ( index in props ) {
-		name = jQuery.camelCase( index );
-		easing = specialEasing[ name ];
-		value = props[ index ];
-		if ( jQuery.isArray( value ) ) {
-			easing = value[ 1 ];
-			value = props[ index ] = value[ 0 ];
-		}
-
-		if ( index !== name ) {
-			props[ name ] = value;
-			delete props[ index ];
-		}
-
-		hooks = jQuery.cssHooks[ name ];
-		if ( hooks && "expand" in hooks ) {
-			value = hooks.expand( value );
-			delete props[ name ];
-
-			// not quite $.extend, this wont overwrite keys already present.
-			// also - reusing 'index' from above because we have the correct "name"
-			for ( index in value ) {
-				if ( !( index in props ) ) {
-					props[ index ] = value[ index ];
-					specialEasing[ index ] = easing;
-				}
-			}
-		} else {
-			specialEasing[ name ] = easing;
-		}
-	}
-}
-
-function Animation( elem, properties, options ) {
-	var result,
-		stopped,
-		index = 0,
-		length = animationPrefilters.length,
-		deferred = jQuery.Deferred().always( function() {
-			// don't match elem in the :animated selector
-			delete tick.elem;
-		}),
-		tick = function() {
-			if ( stopped ) {
-				return false;
-			}
-			var currentTime = fxNow || createFxNow(),
-				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
-				// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
-				temp = remaining / animation.duration || 0,
-				percent = 1 - temp,
-				index = 0,
-				length = animation.tweens.length;
-
-			for ( ; index < length ; index++ ) {
-				animation.tweens[ index ].run( percent );
-			}
-
-			deferred.notifyWith( elem, [ animation, percent, remaining ]);
-
-			if ( percent < 1 && length ) {
-				return remaining;
-			} else {
-				deferred.resolveWith( elem, [ animation ] );
-				return false;
-			}
-		},
-		animation = deferred.promise({
-			elem: elem,
-			props: jQuery.extend( {}, properties ),
-			opts: jQuery.extend( true, { specialEasing: {} }, options ),
-			originalProperties: properties,
-			originalOptions: options,
-			startTime: fxNow || createFxNow(),
-			duration: options.duration,
-			tweens: [],
-			createTween: function( prop, end ) {
-				var tween = jQuery.Tween( elem, animation.opts, prop, end,
-						animation.opts.specialEasing[ prop ] || animation.opts.easing );
-				animation.tweens.push( tween );
-				return tween;
-			},
-			stop: function( gotoEnd ) {
-				var index = 0,
-					// if we are going to the end, we want to run all the tweens
-					// otherwise we skip this part
-					length = gotoEnd ? animation.tweens.length : 0;
-				if ( stopped ) {
-					return this;
-				}
-				stopped = true;
-				for ( ; index < length ; index++ ) {
-					animation.tweens[ index ].run( 1 );
-				}
-
-				// resolve when we played the last frame
-				// otherwise, reject
-				if ( gotoEnd ) {
-					deferred.resolveWith( elem, [ animation, gotoEnd ] );
-				} else {
-					deferred.rejectWith( elem, [ animation, gotoEnd ] );
-				}
-				return this;
-			}
-		}),
-		props = animation.props;
-
-	propFilter( props, animation.opts.specialEasing );
-
-	for ( ; index < length ; index++ ) {
-		result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
-		if ( result ) {
-			return result;
-		}
-	}
-
-	jQuery.map( props, createTween, animation );
-
-	if ( jQuery.isFunction( animation.opts.start ) ) {
-		animation.opts.start.call( elem, animation );
-	}
-
-	jQuery.fx.timer(
-		jQuery.extend( tick, {
-			elem: elem,
-			anim: animation,
-			queue: animation.opts.queue
-		})
-	);
-
-	// attach callbacks from options
-	return animation.progress( animation.opts.progress )
-		.done( animation.opts.done, animation.opts.complete )
-		.fail( animation.opts.fail )
-		.always( animation.opts.always );
-}
-
-jQuery.Animation = jQuery.extend( Animation, {
-	tweener: function( props, callback ) {
-		if ( jQuery.isFunction( props ) ) {
-			callback = props;
-			props = [ "*" ];
-		} else {
-			props = props.split(" ");
-		}
-
-		var prop,
-			index = 0,
-			length = props.length;
-
-		for ( ; index < length ; index++ ) {
-			prop = props[ index ];
-			tweeners[ prop ] = tweeners[ prop ] || [];
-			tweeners[ prop ].unshift( callback );
-		}
-	},
-
-	prefilter: function( callback, prepend ) {
-		if ( prepend ) {
-			animationPrefilters.unshift( callback );
-		} else {
-			animationPrefilters.push( callback );
-		}
-	}
-});
-
-jQuery.speed = function( speed, easing, fn ) {
-	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
-		complete: fn || !fn && easing ||
-			jQuery.isFunction( speed ) && speed,
-		duration: speed,
-		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
-	};
-
-	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
-		opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
-	// normalize opt.queue - true/undefined/null -> "fx"
-	if ( opt.queue == null || opt.queue === true ) {
-		opt.queue = "fx";
-	}
-
-	// Queueing
-	opt.old = opt.complete;
-
-	opt.complete = function() {
-		if ( jQuery.isFunction( opt.old ) ) {
-			opt.old.call( this );
-		}
-
-		if ( opt.queue ) {
-			jQuery.dequeue( this, opt.queue );
-		}
-	};
-
-	return opt;
-};
-
-jQuery.fn.extend({
-	fadeTo: function( speed, to, easing, callback ) {
-
-		// show any hidden elements after setting opacity to 0
-		return this.filter( isHidden ).css( "opacity", 0 ).show()
-
-			// animate to the value specified
-			.end().animate({ opacity: to }, speed, easing, callback );
-	},
-	animate: function( prop, speed, easing, callback ) {
-		var empty = jQuery.isEmptyObject( prop ),
-			optall = jQuery.speed( speed, easing, callback ),
-			doAnimation = function() {
-				// Operate on a copy of prop so per-property easing won't be lost
-				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
-				// Empty animations, or finishing resolves immediately
-				if ( empty || jQuery._data( this, "finish" ) ) {
-					anim.stop( true );
-				}
-			};
-			doAnimation.finish = doAnimation;
-
-		return empty || optall.queue === false ?
-			this.each( doAnimation ) :
-			this.queue( optall.queue, doAnimation );
-	},
-	stop: function( type, clearQueue, gotoEnd ) {
-		var stopQueue = function( hooks ) {
-			var stop = hooks.stop;
-			delete hooks.stop;
-			stop( gotoEnd );
-		};
-
-		if ( typeof type !== "string" ) {
-			gotoEnd = clearQueue;
-			clearQueue = type;
-			type = undefined;
-		}
-		if ( clearQueue && type !== false ) {
-			this.queue( type || "fx", [] );
-		}
-
-		return this.each(function() {
-			var dequeue = true,
-				index = type != null && type + "queueHooks",
-				timers = jQuery.timers,
-				data = jQuery._data( this );
-
-			if ( index ) {
-				if ( data[ index ] && data[ index ].stop ) {
-					stopQueue( data[ index ] );
-				}
-			} else {
-				for ( index in data ) {
-					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
-						stopQueue( data[ index ] );
-					}
-				}
-			}
-
-			for ( index = timers.length; index--; ) {
-				if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
-					timers[ index ].anim.stop( gotoEnd );
-					dequeue = false;
-					timers.splice( index, 1 );
-				}
-			}
-
-			// start the next in the queue if the last step wasn't forced
-			// timers currently will call their complete callbacks, which will dequeue
-			// but only if they were gotoEnd
-			if ( dequeue || !gotoEnd ) {
-				jQuery.dequeue( this, type );
-			}
-		});
-	},
-	finish: function( type ) {
-		if ( type !== false ) {
-			type = type || "fx";
-		}
-		return this.each(function() {
-			var index,
-				data = jQuery._data( this ),
-				queue = data[ type + "queue" ],
-				hooks = data[ type + "queueHooks" ],
-				timers = jQuery.timers,
-				length = queue ? queue.length : 0;
-
-			// enable finishing flag on private data
-			data.finish = true;
-
-			// empty the queue first
-			jQuery.queue( this, type, [] );
-
-			if ( hooks && hooks.stop ) {
-				hooks.stop.call( this, true );
-			}
-
-			// look for any active animations, and finish them
-			for ( index = timers.length; index--; ) {
-				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
-					timers[ index ].anim.stop( true );
-					timers.splice( index, 1 );
-				}
-			}
-
-			// look for any animations in the old queue and finish them
-			for ( index = 0; index < length; index++ ) {
-				if ( queue[ index ] && queue[ index ].finish ) {
-					queue[ index ].finish.call( this );
-				}
-			}
-
-			// turn off finishing flag
-			delete data.finish;
-		});
-	}
-});
-
-jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
-	var cssFn = jQuery.fn[ name ];
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return speed == null || typeof speed === "boolean" ?
-			cssFn.apply( this, arguments ) :
-			this.animate( genFx( name, true ), speed, easing, callback );
-	};
-});
-
-// Generate shortcuts for custom animations
-jQuery.each({
-	slideDown: genFx("show"),
-	slideUp: genFx("hide"),
-	slideToggle: genFx("toggle"),
-	fadeIn: { opacity: "show" },
-	fadeOut: { opacity: "hide" },
-	fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return this.animate( props, speed, easing, callback );
-	};
-});
-
-jQuery.timers = [];
-jQuery.fx.tick = function() {
-	var timer,
-		timers = jQuery.timers,
-		i = 0;
-
-	fxNow = jQuery.now();
-
-	for ( ; i < timers.length; i++ ) {
-		timer = timers[ i ];
-		// Checks the timer has not already been removed
-		if ( !timer() && timers[ i ] === timer ) {
-			timers.splice( i--, 1 );
-		}
-	}
-
-	if ( !timers.length ) {
-		jQuery.fx.stop();
-	}
-	fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
-	jQuery.timers.push( timer );
-	if ( timer() ) {
-		jQuery.fx.start();
-	} else {
-		jQuery.timers.pop();
-	}
-};
-
-jQuery.fx.interval = 13;
-
-jQuery.fx.start = function() {
-	if ( !timerId ) {
-		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
-	}
-};
-
-jQuery.fx.stop = function() {
-	clearInterval( timerId );
-	timerId = null;
-};
-
-jQuery.fx.speeds = {
-	slow: 600,
-	fast: 200,
-	// Default speed
-	_default: 400
-};
-
-
-// Based off of the plugin by Clint Helfers, with permission.
-// http://blindsignals.com/index.php/2009/07/jquery-delay/
-jQuery.fn.delay = function( time, type ) {
-	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
-	type = type || "fx";
-
-	return this.queue( type, function( next, hooks ) {
-		var timeout = setTimeout( next, time );
-		hooks.stop = function() {
-			clearTimeout( timeout );
-		};
-	});
-};
-
-
-(function() {
-	// Minified: var a,b,c,d,e
-	var input, div, select, a, opt;
-
-	// Setup
-	div = document.createElement( "div" );
-	div.setAttribute( "className", "t" );
-	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
-	a = div.getElementsByTagName("a")[ 0 ];
-
-	// First batch of tests.
-	select = document.createElement("select");
-	opt = select.appendChild( document.createElement("option") );
-	input = div.getElementsByTagName("input")[ 0 ];
-
-	a.style.cssText = "top:1px";
-
-	// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
-	support.getSetAttribute = div.className !== "t";
-
-	// Get the style information from getAttribute
-	// (IE uses .cssText instead)
-	support.style = /top/.test( a.getAttribute("style") );
-
-	// Make sure that URLs aren't manipulated
-	// (IE normalizes it by default)
-	support.hrefNormalized = a.getAttribute("href") === "/a";
-
-	// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
-	support.checkOn = !!input.value;
-
-	// Make sure that a selected-by-default option has a working selected property.
-	// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
-	support.optSelected = opt.selected;
-
-	// Tests for enctype support on a form (#6743)
-	support.enctype = !!document.createElement("form").enctype;
-
-	// Make sure that the options inside disabled selects aren't marked as disabled
-	// (WebKit marks them as disabled)
-	select.disabled = true;
-	support.optDisabled = !opt.disabled;
-
-	// Support: IE8 only
-	// Check if we can trust getAttribute("value")
-	input = document.createElement( "input" );
-	input.setAttribute( "value", "" );
-	support.input = input.getAttribute( "value" ) === "";
-
-	// Check if an input maintains its value after becoming a radio
-	input.value = "t";
-	input.setAttribute( "type", "radio" );
-	support.radioValue = input.value === "t";
-})();
-
-
-var rreturn = /\r/g;
-
-jQuery.fn.extend({
-	val: function( value ) {
-		var hooks, ret, isFunction,
-			elem = this[0];
-
-		if ( !arguments.length ) {
-			if ( elem ) {
-				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
-				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
-					return ret;
-				}
-
-				ret = elem.value;
-
-				return typeof ret === "string" ?
-					// handle most common string cases
-					ret.replace(rreturn, "") :
-					// handle cases where value is null/undef or number
-					ret == null ? "" : ret;
-			}
-
-			return;
-		}
-
-		isFunction = jQuery.isFunction( value );
-
-		return this.each(function( i ) {
-			var val;
-
-			if ( this.nodeType !== 1 ) {
-				return;
-			}
-
-			if ( isFunction ) {
-				val = value.call( this, i, jQuery( this ).val() );
-			} else {
-				val = value;
-			}
-
-			// Treat null/undefined as ""; convert numbers to string
-			if ( val == null ) {
-				val = "";
-			} else if ( typeof val === "number" ) {
-				val += "";
-			} else if ( jQuery.isArray( val ) ) {
-				val = jQuery.map( val, function( value ) {
-					return value == null ? "" : value + "";
-				});
-			}
-
-			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
-			// If set returns undefined, fall back to normal setting
-			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
-				this.value = val;
-			}
-		});
-	}
-});
-
-jQuery.extend({
-	valHooks: {
-		option: {
-			get: function( elem ) {
-				var val = jQuery.find.attr( elem, "value" );
-				return val != null ?
-					val :
-					// Support: IE10-11+
-					// option.text throws exceptions (#14686, #14858)
-					jQuery.trim( jQuery.text( elem ) );
-			}
-		},
-		select: {
-			get: function( elem ) {
-				var value, option,
-					options = elem.options,
-					index = elem.selectedIndex,
-					one = elem.type === "select-one" || index < 0,
-					values = one ? null : [],
-					max = one ? index + 1 : options.length,
-					i = index < 0 ?
-						max :
-						one ? index : 0;
-
-				// Loop through all the selected options
-				for ( ; i < max; i++ ) {
-					option = options[ i ];
-
-					// oldIE doesn't update selected after form reset (#2551)
-					if ( ( option.selected || i === index ) &&
-							// Don't return options that are disabled or in a disabled optgroup
-							( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
-							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
-
-						// Get the specific value for the option
-						value = jQuery( option ).val();
-
-						// We don't need an array for one selects
-						if ( one ) {
-							return value;
-						}
-
-						// Multi-Selects return an array
-						values.push( value );
-					}
-				}
-
-				return values;
-			},
-
-			set: function( elem, value ) {
-				var optionSet, option,
-					options = elem.options,
-					values = jQuery.makeArray( value ),
-					i = options.length;
-
-				while ( i-- ) {
-					option = options[ i ];
-
-					if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
-
-						// Support: IE6
-						// When new option element is added to select box we need to
-						// force reflow of newly added node in order to workaround delay
-						// of initialization properties
-						try {
-							option.selected = optionSet = true;
-
-						} catch ( _ ) {
-
-							// Will be executed only in IE6
-							option.scrollHeight;
-						}
-
-					} else {
-						option.selected = false;
-					}
-				}
-
-				// Force browsers to behave consistently when non-matching value is set
-				if ( !optionSet ) {
-					elem.selectedIndex = -1;
-				}
-
-				return options;
-			}
-		}
-	}
-});
-
-// Radios and checkboxes getter/setter
-jQuery.each([ "radio", "checkbox" ], function() {
-	jQuery.valHooks[ this ] = {
-		set: function( elem, value ) {
-			if ( jQuery.isArray( value ) ) {
-				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
-			}
-		}
-	};
-	if ( !support.checkOn ) {
-		jQuery.valHooks[ this ].get = function( elem ) {
-			// Support: Webkit
-			// "" is returned instead of "on" if a value isn't specified
-			return elem.getAttribute("value") === null ? "on" : elem.value;
-		};
-	}
-});
-
-
-
-
-var nodeHook, boolHook,
-	attrHandle = jQuery.expr.attrHandle,
-	ruseDefault = /^(?:checked|selected)$/i,
-	getSetAttribute = support.getSetAttribute,
-	getSetInput = support.input;
-
-jQuery.fn.extend({
-	attr: function( name, value ) {
-		return access( this, jQuery.attr, name, value, arguments.length > 1 );
-	},
-
-	removeAttr: function( name ) {
-		return this.each(function() {
-			jQuery.removeAttr( this, name );
-		});
-	}
-});
-
-jQuery.extend({
-	attr: function( elem, name, value ) {
-		var hooks, ret,
-			nType = elem.nodeType;
-
-		// don't get/set attributes on text, comment and attribute nodes
-		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
-			return;
-		}
-
-		// Fallback to prop when attributes are not supported
-		if ( typeof elem.getAttribute === strundefined ) {
-			return jQuery.prop( elem, name, value );
-		}
-
-		// All attributes are lowercase
-		// Grab necessary hook if one is defined
-		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-			name = name.toLowerCase();
-			hooks = jQuery.attrHooks[ name ] ||
-				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
-		}
-
-		if ( value !== undefined ) {
-
-			if ( value === null ) {
-				jQuery.removeAttr( elem, name );
-
-			} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
-				return ret;
-
-			} else {
-				elem.setAttribute( name, value + "" );
-				return value;
-			}
-
-		} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
-			return ret;
-
-		} else {
-			ret = jQuery.find.attr( elem, name );
-
-			// Non-existent attributes return null, we normalize to undefined
-			return ret == null ?
-				undefined :
-				ret;
-		}
-	},
-
-	removeAttr: function( elem, value ) {
-		var name, propName,
-			i = 0,
-			attrNames = value && value.match( rnotwhite );
-
-		if ( attrNames && elem.nodeType === 1 ) {
-			while ( (name = attrNames[i++]) ) {
-				propName = jQuery.propFix[ name ] || name;
-
-				// Boolean attributes get special treatment (#10870)
-				if ( jQuery.expr.match.bool.test( name ) ) {
-					// Set corresponding property to false
-					if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
-						elem[ propName ] = false;
-					// Support: IE<9
-					// Also clear defaultChecked/defaultSelected (if appropriate)
-					} else {
-						elem[ jQuery.camelCase( "default-" + name ) ] =
-							elem[ propName ] = false;
-					}
-
-				// See #9699 for explanation of this approach (setting first, then removal)
-				} else {
-					jQuery.attr( elem, name, "" );
-				}
-
-				elem.removeAttribute( getSetAttribute ? name : propName );
-			}
-		}
-	},
-
-	attrHooks: {
-		type: {
-			set: function( elem, value ) {
-				if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
-					// Setting the type on a radio button after the value resets the value in IE6-9
-					// Reset value to default in case type is set after value during creation
-					var val = elem.value;
-					elem.setAttribute( "type", value );
-					if ( val ) {
-						elem.value = val;
-					}
-					return value;
-				}
-			}
-		}
-	}
-});
-
-// Hook for boolean attributes
-boolHook = {
-	set: function( elem, value, name ) {
-		if ( value === false ) {
-			// Remove boolean attributes when set to false
-			jQuery.removeAttr( elem, name );
-		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
-			// IE<8 needs the *property* name
-			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
-
-		// Use defaultChecked and defaultSelected for oldIE
-		} else {
-			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
-		}
-
-		return name;
-	}
-};
-
-// Retrieve booleans specially
-jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
-
-	var getter = attrHandle[ name ] || jQuery.find.attr;
-
-	attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
-		function( elem, name, isXML ) {
-			var ret, handle;
-			if ( !isXML ) {
-				// Avoid an infinite loop by temporarily removing this function from the getter
-				handle = attrHandle[ name ];
-				attrHandle[ name ] = ret;
-				ret = getter( elem, name, isXML ) != null ?
-					name.toLowerCase() :
-					null;
-				attrHandle[ name ] = handle;
-			}
-			return ret;
-		} :
-		function( elem, name, isXML ) {
-			if ( !isXML ) {
-				return elem[ jQuery.camelCase( "default-" + name ) ] ?
-					name.toLowerCase() :
-					null;
-			}
-		};
-});
-
-// fix oldIE attroperties
-if ( !getSetInput || !getSetAttribute ) {
-	jQuery.attrHooks.value = {
-		set: function( elem, value, name ) {
-			if ( jQuery.nodeName( elem, "input" ) ) {
-				// Does not return so that setAttribute is also used
-				elem.defaultValue = value;
-			} else {
-				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
-				return nodeHook && nodeHook.set( elem, value, name );
-			}
-		}
-	};
-}
-
-// IE6/7 do not support getting/setting some attributes with get/setAttribute
-if ( !getSetAttribute ) {
-
-	// Use this for any attribute in IE6/7
-	// This fixes almost every IE6/7 issue
-	nodeHook = {
-		set: function( elem, value, name ) {
-			// Set the existing or create a new attribute node
-			var ret = elem.getAttributeNode( name );
-			if ( !ret ) {
-				elem.setAttributeNode(
-					(ret = elem.ownerDocument.createAttribute( name ))
-				);
-			}
-
-			ret.value = value += "";
-
-			// Break association with cloned elements by also using setAttribute (#9646)
-			if ( name === "value" || value === elem.getAttribute( name ) ) {
-				return value;
-			}
-		}
-	};
-
-	// Some attributes are constructed with empty-string values when not defined
-	attrHandle.id = attrHandle.name = attrHandle.coords =
-		function( elem, name, isXML ) {
-			var ret;
-			if ( !isXML ) {
-				return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
-					ret.value :
-					null;
-			}
-		};
-
-	// Fixing value retrieval on a button requires this module
-	jQuery.valHooks.button = {
-		get: function( elem, name ) {
-			var ret = elem.getAttributeNode( name );
-			if ( ret && ret.specified ) {
-				return ret.value;
-			}
-		},
-		set: nodeHook.set
-	};
-
-	// Set contenteditable to false on removals(#10429)
-	// Setting to empty string throws an error as an invalid value
-	jQuery.attrHooks.contenteditable = {
-		set: function( elem, value, name ) {
-			nodeHook.set( elem, value === "" ? false : value, name );
-		}
-	};
-
-	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
-	// This is for removals
-	jQuery.each([ "width", "height" ], function( i, name ) {
-		jQuery.attrHooks[ name ] = {
-			set: function( elem, value ) {
-				if ( value === "" ) {
-					elem.setAttribute( name, "auto" );
-					return value;
-				}
-			}
-		};
-	});
-}
-
-if ( !support.style ) {
-	jQuery.attrHooks.style = {
-		get: function( elem ) {
-			// Return undefined in the case of empty string
-			// Note: IE uppercases css property names, but if we were to .toLowerCase()
-			// .cssText, that would destroy case senstitivity in URL's, like in "background"
-			return elem.style.cssText || undefined;
-		},
-		set: function( elem, value ) {
-			return ( elem.style.cssText = value + "" );
-		}
-	};
-}
-
-
-
-
-var rfocusable = /^(?:input|select|textarea|button|object)$/i,
-	rclickable = /^(?:a|area)$/i;
-
-jQuery.fn.extend({
-	prop: function( name, value ) {
-		return access( this, jQuery.prop, name, value, arguments.length > 1 );
-	},
-
-	removeProp: function( name ) {
-		name = jQuery.propFix[ name ] || name;
-		return this.each(function() {
-			// try/catch handles cases where IE balks (such as removing a property on window)
-			try {
-				this[ name ] = undefined;
-				delete this[ name ];
-			} catch( e ) {}
-		});
-	}
-});
-
-jQuery.extend({
-	propFix: {
-		"for": "htmlFor",
-		"class": "className"
-	},
-
-	prop: function( elem, name, value ) {
-		var ret, hooks, notxml,
-			nType = elem.nodeType;
-
-		// don't get/set properties on text, comment and attribute nodes
-		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
-			return;
-		}
-
-		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
-		if ( notxml ) {
-			// Fix name and attach hooks
-			name = jQuery.propFix[ name ] || name;
-			hooks = jQuery.propHooks[ name ];
-		}
-
-		if ( value !== undefined ) {
-			return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
-				ret :
-				( elem[ name ] = value );
-
-		} else {
-			return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
-				ret :
-				elem[ name ];
-		}
-	},
-
-	propHooks: {
-		tabIndex: {
-			get: function( elem ) {
-				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
-				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-				// Use proper attribute retrieval(#12072)
-				var tabindex = jQuery.find.attr( elem, "tabindex" );
-
-				return tabindex ?
-					parseInt( tabindex, 10 ) :
-					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
-						0 :
-						-1;
-			}
-		}
-	}
-});
-
-// Some attributes require a special call on IE
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !support.hrefNormalized ) {
-	// href/src property should get the full normalized URL (#10299/#12915)
-	jQuery.each([ "href", "src" ], function( i, name ) {
-		jQuery.propHooks[ name ] = {
-			get: function( elem ) {
-				return elem.getAttribute( name, 4 );
-			}
-		};
-	});
-}
-
-// Support: Safari, IE9+
-// mis-reports the default selected property of an option
-// Accessing the parent's selectedIndex property fixes it
-if ( !support.optSelected ) {
-	jQuery.propHooks.selected = {
-		get: function( elem ) {
-			var parent = elem.parentNode;
-
-			if ( parent ) {
-				parent.selectedIndex;
-
-				// Make sure that it also works with optgroups, see #5701
-				if ( parent.parentNode ) {
-					parent.parentNode.selectedIndex;
-				}
-			}
-			return null;
-		}
-	};
-}
-
-jQuery.each([
-	"tabIndex",
-	"readOnly",
-	"maxLength",
-	"cellSpacing",
-	"cellPadding",
-	"rowSpan",
-	"colSpan",
-	"useMap",
-	"frameBorder",
-	"contentEditable"
-], function() {
-	jQuery.propFix[ this.toLowerCase() ] = this;
-});
-
-// IE6/7 call enctype encoding
-if ( !support.enctype ) {
-	jQuery.propFix.enctype = "encoding";
-}
-
-
-
-
-var rclass = /[\t\r\n\f]/g;
-
-jQuery.fn.extend({
-	addClass: function( value ) {
-		var classes, elem, cur, clazz, j, finalValue,
-			i = 0,
-			len = this.length,
-			proceed = typeof value === "string" && value;
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each(function( j ) {
-				jQuery( this ).addClass( value.call( this, j, this.className ) );
-			});
-		}
-
-		if ( proceed ) {
-			// The disjunction here is for better compressibility (see removeClass)
-			classes = ( value || "" ).match( rnotwhite ) || [];
-
-			for ( ; i < len; i++ ) {
-				elem = this[ i ];
-				cur = elem.nodeType === 1 && ( elem.className ?
-					( " " + elem.className + " " ).replace( rclass, " " ) :
-					" "
-				);
-
-				if ( cur ) {
-					j = 0;
-					while ( (clazz = classes[j++]) ) {
-						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
-							cur += clazz + " ";
-						}
-					}
-
-					// only assign if different to avoid unneeded rendering.
-					finalValue = jQuery.trim( cur );
-					if ( elem.className !== finalValue ) {
-						elem.className = finalValue;
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	removeClass: function( value ) {
-		var classes, elem, cur, clazz, j, finalValue,
-			i = 0,
-			len = this.length,
-			proceed = arguments.length === 0 || typeof value === "string" && value;
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each(function( j ) {
-				jQuery( this ).removeClass( value.call( this, j, this.className ) );
-			});
-		}
-		if ( proceed ) {
-			classes = ( value || "" ).match( rnotwhite ) || [];
-
-			for ( ; i < len; i++ ) {
-				elem = this[ i ];
-				// This expression is here for better compressibility (see addClass)
-				cur = elem.nodeType === 1 && ( elem.className ?
-					( " " + elem.className + " " ).replace( rclass, " " ) :
-					""
-				);
-
-				if ( cur ) {
-					j = 0;
-					while ( (clazz = classes[j++]) ) {
-						// Remove *all* instances
-						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
-							cur = cur.replace( " " + clazz + " ", " " );
-						}
-					}
-
-					// only assign if different to avoid unneeded rendering.
-					finalValue = value ? jQuery.trim( cur ) : "";
-					if ( elem.className !== finalValue ) {
-						elem.className = finalValue;
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	toggleClass: function( value, stateVal ) {
-		var type = typeof value;
-
-		if ( typeof stateVal === "boolean" && type === "string" ) {
-			return stateVal ? this.addClass( value ) : this.removeClass( value );
-		}
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each(function( i ) {
-				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
-			});
-		}
-
-		return this.each(function() {
-			if ( type === "string" ) {
-				// toggle individual class names
-				var className,
-					i = 0,
-					self = jQuery( this ),
-					classNames = value.match( rnotwhite ) || [];
-
-				while ( (className = classNames[ i++ ]) ) {
-					// check each className given, space separated list
-					if ( self.hasClass( className ) ) {
-						self.removeClass( className );
-					} else {
-						self.addClass( className );
-					}
-				}
-
-			// Toggle whole class name
-			} else if ( type === strundefined || type === "boolean" ) {
-				if ( this.className ) {
-					// store className if set
-					jQuery._data( this, "__className__", this.className );
-				}
-
-				// If the element has a class name or if we're passed "false",
-				// then remove the whole classname (if there was one, the above saved it).
-				// Otherwise bring back whatever was previously saved (if anything),
-				// falling back to the empty string if nothing was stored.
-				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
-			}
-		});
-	},
-
-	hasClass: function( selector ) {
-		var className = " " + selector + " ",
-			i = 0,
-			l = this.length;
-		for ( ; i < l; i++ ) {
-			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
-				return true;
-			}
-		}
-
-		return false;
-	}
-});
-
-
-
-
-// Return jQuery for attributes-only inclusion
-
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
-	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
-	"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
-
-	// Handle event binding
-	jQuery.fn[ name ] = function( data, fn ) {
-		return arguments.length > 0 ?
-			this.on( name, null, data, fn ) :
-			this.trigger( name );
-	};
-});
-
-jQuery.fn.extend({
-	hover: function( fnOver, fnOut ) {
-		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
-	},
-
-	bind: function( types, data, fn ) {
-		return this.on( types, null, data, fn );
-	},
-	unbind: function( types, fn ) {
-		return this.off( types, null, fn );
-	},
-
-	delegate: function( selector, types, data, fn ) {
-		return this.on( types, selector, data, fn );
-	},
-	undelegate: function( selector, types, fn ) {
-		// ( namespace ) or ( selector, types [, fn] )
-		return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
-	}
-});
-
-
-var nonce = jQuery.now();
-
-var rquery = (/\?/);
-
-
-
-var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
-
-jQuery.parseJSON = function( data ) {
-	// Attempt to parse using the native JSON parser first
-	if ( window.JSON && window.JSON.parse ) {
-		// Support: Android 2.3
-		// Workaround failure to string-cast null input
-		return window.JSON.parse( data + "" );
-	}
-
-	var requireNonComma,
-		depth = null,
-		str = jQuery.trim( data + "" );
-
-	// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
-	// after removing valid tokens
-	return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
-
-		// Force termination if we see a misplaced comma
-		if ( requireNonComma && comma ) {
-			depth = 0;
-		}
-
-		// Perform no more replacements after returning to outermost depth
-		if ( depth === 0 ) {
-			return token;
-		}
-
-		// Commas must not follow "[", "{", or ","
-		requireNonComma = open || comma;
-
-		// Determine new depth
-		// array/object open ("[" or "{"): depth += true - false (increment)
-		// array/object close ("]" or "}"): depth += false - true (decrement)
-		// other cases ("," or primitive): depth += true - true (numeric cast)
-		depth += !close - !open;
-
-		// Remove this token
-		return "";
-	}) ) ?
-		( Function( "return " + str ) )() :
-		jQuery.error( "Invalid JSON: " + data );
-};
-
-
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
-	var xml, tmp;
-	if ( !data || typeof data !== "string" ) {
-		return null;
-	}
-	try {
-		if ( window.DOMParser ) { // Standard
-			tmp = new DOMParser();
-			xml = tmp.parseFromString( data, "text/xml" );
-		} else { // IE
-			xml = new ActiveXObject( "Microsoft.XMLDOM" );
-			xml.async = "false";
-			xml.loadXML( data );
-		}
-	} catch( e ) {
-		xml = undefined;
-	}
-	if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
-		jQuery.error( "Invalid XML: " + data );
-	}
-	return xml;
-};
-
-
-var
-	// Document location
-	ajaxLocParts,
-	ajaxLocation,
-
-	rhash = /#.*$/,
-	rts = /([?&])_=[^&]*/,
-	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
-	// #7653, #8125, #8152: local protocol detection
-	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
-	rnoContent = /^(?:GET|HEAD)$/,
-	rprotocol = /^\/\//,
-	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
-
-	/* Prefilters
-	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
-	 * 2) These are called:
-	 *    - BEFORE asking for a transport
-	 *    - AFTER param serialization (s.data is a string if s.processData is true)
-	 * 3) key is the dataType
-	 * 4) the catchall symbol "*" can be used
-	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
-	 */
-	prefilters = {},
-
-	/* Transports bindings
-	 * 1) key is the dataType
-	 * 2) the catchall symbol "*" can be used
-	 * 3) selection will start with transport dataType and THEN go to "*" if needed
-	 */
-	transports = {},
-
-	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
-	allTypes = "*/".concat("*");
-
-// #8138, IE may throw an exception when accessing
-// a field from window.location if document.domain has been set
-try {
-	ajaxLocation = location.href;
-} catch( e ) {
-	// Use the href attribute of an A element
-	// since IE will modify it given document.location
-	ajaxLocation = document.createElement( "a" );
-	ajaxLocation.href = "";
-	ajaxLocation = ajaxLocation.href;
-}
-
-// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
-	// dataTypeExpression is optional and defaults to "*"
-	return function( dataTypeExpression, func ) {
-
-		if ( typeof dataTypeExpression !== "string" ) {
-			func = dataTypeExpression;
-			dataTypeExpression = "*";
-		}
-
-		var dataType,
-			i = 0,
-			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
-
-		if ( jQuery.isFunction( func ) ) {
-			// For each dataType in the dataTypeExpression
-			while ( (dataType = dataTypes[i++]) ) {
-				// Prepend if requested
-				if ( dataType.charAt( 0 ) === "+" ) {
-					dataType = dataType.slice( 1 ) || "*";
-					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
-
-				// Otherwise append
-				} else {
-					(structure[ dataType ] = structure[ dataType ] || []).push( func );
-				}
-			}
-		}
-	};
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
-
-	var inspected = {},
-		seekingTransport = ( structure === transports );
-
-	function inspect( dataType ) {
-		var selected;
-		inspected[ dataType ] = true;
-		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
-			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
-			if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
-				options.dataTypes.unshift( dataTypeOrTransport );
-				inspect( dataTypeOrTransport );
-				return false;
-			} else if ( seekingTransport ) {
-				return !( selected = dataTypeOrTransport );
-			}
-		});
-		return selected;
-	}
-
-	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
-	var deep, key,
-		flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
-	for ( key in src ) {
-		if ( src[ key ] !== undefined ) {
-			( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
-		}
-	}
-	if ( deep ) {
-		jQuery.extend( true, target, deep );
-	}
-
-	return target;
-}
-
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
-	var firstDataType, ct, finalDataType, type,
-		contents = s.contents,
-		dataTypes = s.dataTypes;
-
-	// Remove auto dataType and get content-type in the process
-	while ( dataTypes[ 0 ] === "*" ) {
-		dataTypes.shift();
-		if ( ct === undefined ) {
-			ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
-		}
-	}
-
-	// Check if we're dealing with a known content-type
-	if ( ct ) {
-		for ( type in contents ) {
-			if ( contents[ type ] && contents[ type ].test( ct ) ) {
-				dataTypes.unshift( type );
-				break;
-			}
-		}
-	}
-
-	// Check to see if we have a response for the expected dataType
-	if ( dataTypes[ 0 ] in responses ) {
-		finalDataType = dataTypes[ 0 ];
-	} else {
-		// Try convertible dataTypes
-		for ( type in responses ) {
-			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
-				finalDataType = type;
-				break;
-			}
-			if ( !firstDataType ) {
-				firstDataType = type;
-			}
-		}
-		// Or just use first one
-		finalDataType = finalDataType || firstDataType;
-	}
-
-	// If we found a dataType
-	// We add the dataType to the list if needed
-	// and return the corresponding response
-	if ( finalDataType ) {
-		if ( finalDataType !== dataTypes[ 0 ] ) {
-			dataTypes.unshift( finalDataType );
-		}
-		return responses[ finalDataType ];
-	}
-}
-
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
-	var conv2, current, conv, tmp, prev,
-		converters = {},
-		// Work with a copy of dataTypes in case we need to modify it for conversion
-		dataTypes = s.dataTypes.slice();
-
-	// Create converters map with lowercased keys
-	if ( dataTypes[ 1 ] ) {
-		for ( conv in s.converters ) {
-			converters[ conv.toLowerCase() ] = s.converters[ conv ];
-		}
-	}
-
-	current = dataTypes.shift();
-
-	// Convert to each sequential dataType
-	while ( current ) {
-
-		if ( s.responseFields[ current ] ) {
-			jqXHR[ s.responseFields[ current ] ] = response;
-		}
-
-		// Apply the dataFilter if provided
-		if ( !prev && isSuccess && s.dataFilter ) {
-			response = s.dataFilter( response, s.dataType );
-		}
-
-		prev = current;
-		current = dataTypes.shift();
-
-		if ( current ) {
-
-			// There's only work to do if current dataType is non-auto
-			if ( current === "*" ) {
-
-				current = prev;
-
-			// Convert response if prev dataType is non-auto and differs from current
-			} else if ( prev !== "*" && prev !== current ) {
-
-				// Seek a direct converter
-				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
-
-				// If none found, seek a pair
-				if ( !conv ) {
-					for ( conv2 in converters ) {
-
-						// If conv2 outputs current
-						tmp = conv2.split( " " );
-						if ( tmp[ 1 ] === current ) {
-
-							// If prev can be converted to accepted input
-							conv = converters[ prev + " " + tmp[ 0 ] ] ||
-								converters[ "* " + tmp[ 0 ] ];
-							if ( conv ) {
-								// Condense equivalence converters
-								if ( conv === true ) {
-									conv = converters[ conv2 ];
-
-								// Otherwise, insert the intermediate dataType
-								} else if ( converters[ conv2 ] !== true ) {
-									current = tmp[ 0 ];
-									dataTypes.unshift( tmp[ 1 ] );
-								}
-								break;
-							}
-						}
-					}
-				}
-
-				// Apply converter (if not an equivalence)
-				if ( conv !== true ) {
-
-					// Unless errors are allowed to bubble, catch and return them
-					if ( conv && s[ "throws" ] ) {
-						response = conv( response );
-					} else {
-						try {
-							response = conv( response );
-						} catch ( e ) {
-							return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return { state: "success", data: response };
-}
-
-jQuery.extend({
-
-	// Counter for holding the number of active queries
-	active: 0,
-
-	// Last-Modified header cache for next request
-	lastModified: {},
-	etag: {},
-
-	ajaxSettings: {
-		url: ajaxLocation,
-		type: "GET",
-		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
-		global: true,
-		processData: true,
-		async: true,
-		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
-		/*
-		timeout: 0,
-		data: null,
-		dataType: null,
-		username: null,
-		password: null,
-		cache: null,
-		throws: false,
-		traditional: false,
-		headers: {},
-		*/
-
-		accepts: {
-			"*": allTypes,
-			text: "text/plain",
-			html: "text/html",
-			xml: "application/xml, text/xml",
-			json: "application/json, text/javascript"
-		},
-
-		contents: {
-			xml: /xml/,
-			html: /html/,
-			json: /json/
-		},
-
-		responseFields: {
-			xml: "responseXML",
-			text: "responseText",
-			json: "responseJSON"
-		},
-
-		// Data converters
-		// Keys separate source (or catchall "*") and destination types with a single space
-		converters: {
-
-			// Convert anything to text
-			"* text": String,
-
-			// Text to html (true = no transformation)
-			"text html": true,
-
-			// Evaluate text as a json expression
-			"text json": jQuery.parseJSON,
-
-			// Parse text as xml
-			"text xml": jQuery.parseXML
-		},
-
-		// For options that shouldn't be deep extended:
-		// you can add your own custom options here if
-		// and when you create one that shouldn't be
-		// deep extended (see ajaxExtend)
-		flatOptions: {
-			url: true,
-			context: true
-		}
-	},
-
-	// Creates a full fledged settings object into target
-	// with both ajaxSettings and settings fields.
-	// If target is omitted, writes into ajaxSettings.
-	ajaxSetup: function( target, settings ) {
-		return settings ?
-
-			// Building a settings object
-			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
-
-			// Extending ajaxSettings
-			ajaxExtend( jQuery.ajaxSettings, target );
-	},
-
-	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
-	ajaxTransport: addToPrefiltersOrTransports( transports ),
-
-	// Main method
-	ajax: function( url, options ) {
-
-		// If url is an object, simulate pre-1.5 signature
-		if ( typeof url === "object" ) {
-			options = url;
-			url = undefined;
-		}
-
-		// Force options to be an object
-		options = options || {};
-
-		var // Cross-domain detection vars
-			parts,
-			// Loop variable
-			i,
-			// URL without anti-cache param
-			cacheURL,
-			// Response headers as string
-			responseHeadersString,
-			// timeout handle
-			timeoutTimer,
-
-			// To know if global events are to be dispatched
-			fireGlobals,
-
-			transport,
-			// Response headers
-			responseHeaders,
-			// Create the final options object
-			s = jQuery.ajaxSetup( {}, options ),
-			// Callbacks context
-			callbackContext = s.context || s,
-			// Context for global events is callbackContext if it is a DOM node or jQuery collection
-			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
-				jQuery( callbackContext ) :
-				jQuery.event,
-			// Deferreds
-			deferred = jQuery.Deferred(),
-			completeDeferred = jQuery.Callbacks("once memory"),
-			// Status-dependent callbacks
-			statusCode = s.statusCode || {},
-			// Headers (they are sent all at once)
-			requestHeaders = {},
-			requestHeadersNames = {},
-			// The jqXHR state
-			state = 0,
-			// Default abort message
-			strAbort = "canceled",
-			// Fake xhr
-			jqXHR = {
-				readyState: 0,
-
-				// Builds headers hashtable if needed
-				getResponseHeader: function( key ) {
-					var match;
-					if ( state === 2 ) {
-						if ( !responseHeaders ) {
-							responseHeaders = {};
-							while ( (match = rheaders.exec( responseHeadersString )) ) {
-								responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
-							}
-						}
-						match = responseHeaders[ key.toLowerCase() ];
-					}
-					return match == null ? null : match;
-				},
-
-				// Raw string
-				getAllResponseHeaders: function() {
-					return state === 2 ? responseHeadersString : null;
-				},
-
-				// Caches the header
-				setRequestHeader: function( name, value ) {
-					var lname = name.toLowerCase();
-					if ( !state ) {
-						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
-						requestHeaders[ name ] = value;
-					}
-					return this;
-				},
-
-				// Overrides response content-type header
-				overrideMimeType: function( type ) {
-					if ( !state ) {
-						s.mimeType = type;
-					}
-					return this;
-				},
-
-				// Status-dependent callbacks
-				statusCode: function( map ) {
-					var code;
-					if ( map ) {
-						if ( state < 2 ) {
-							for ( code in map ) {
-								// Lazy-add the new callback in a way that preserves old ones
-								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
-							}
-						} else {
-							// Execute the appropriate callbacks
-							jqXHR.always( map[ jqXHR.status ] );
-						}
-					}
-					return this;
-				},
-
-				// Cancel the request
-				abort: function( statusText ) {
-					var finalText = statusText || strAbort;
-					if ( transport ) {
-						transport.abort( finalText );
-					}
-					done( 0, finalText );
-					return this;
-				}
-			};
-
-		// Attach deferreds
-		deferred.promise( jqXHR ).complete = completeDeferred.add;
-		jqXHR.success = jqXHR.done;
-		jqXHR.error = jqXHR.fail;
-
-		// Remove hash character (#7531: and string promotion)
-		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
-		// Handle falsy url in the settings object (#10093: consistency with old signature)
-		// We also use the url parameter if available
-		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
-
-		// Alias method option to type as per ticket #12004
-		s.type = options.method || options.type || s.method || s.type;
-
-		// Extract dataTypes list
-		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
-
-		// A cross-domain request is in order when we have a protocol:host:port mismatch
-		if ( s.crossDomain == null ) {
-			parts = rurl.exec( s.url.toLowerCase() );
-			s.crossDomain = !!( parts &&
-				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
-					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
-						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
-			);
-		}
-
-		// Convert data if not already a string
-		if ( s.data && s.processData && typeof s.data !== "string" ) {
-			s.data = jQuery.param( s.data, s.traditional );
-		}
-
-		// Apply prefilters
-		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
-		// If request was aborted inside a prefilter, stop there
-		if ( state === 2 ) {
-			return jqXHR;
-		}
-
-		// We can fire global events as of now if asked to
-		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
-		fireGlobals = jQuery.event && s.global;
-
-		// Watch for a new set of requests
-		if ( fireGlobals && jQuery.active++ === 0 ) {
-			jQuery.event.trigger("ajaxStart");
-		}
-
-		// Uppercase the type
-		s.type = s.type.toUpperCase();
-
-		// Determine if request has content
-		s.hasContent = !rnoContent.test( s.type );
-
-		// Save the URL in case we're toying with the If-Modified-Since
-		// and/or If-None-Match header later on
-		cacheURL = s.url;
-
-		// More options handling for requests with no content
-		if ( !s.hasContent ) {
-
-			// If data is available, append data to url
-			if ( s.data ) {
-				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
-				// #9682: remove data so that it's not used in an eventual retry
-				delete s.data;
-			}
-
-			// Add anti-cache in url if needed
-			if ( s.cache === false ) {
-				s.url = rts.test( cacheURL ) ?
-
-					// If there is already a '_' parameter, set its value
-					cacheURL.replace( rts, "$1_=" + nonce++ ) :
-
-					// Otherwise add one to the end
-					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
-			}
-		}
-
-		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-		if ( s.ifModified ) {
-			if ( jQuery.lastModified[ cacheURL ] ) {
-				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
-			}
-			if ( jQuery.etag[ cacheURL ] ) {
-				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
-			}
-		}
-
-		// Set the correct header, if data is being sent
-		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
-			jqXHR.setRequestHeader( "Content-Type", s.contentType );
-		}
-
-		// Set the Accepts header for the server, depending on the dataType
-		jqXHR.setRequestHeader(
-			"Accept",
-			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
-				s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
-				s.accepts[ "*" ]
-		);
-
-		// Check for headers option
-		for ( i in s.headers ) {
-			jqXHR.setRequestHeader( i, s.headers[ i ] );
-		}
-
-		// Allow custom headers/mimetypes and early abort
-		if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
-			// Abort if not done already and return
-			return jqXHR.abort();
-		}
-
-		// aborting is no longer a cancellation
-		strAbort = "abort";
-
-		// Install callbacks on deferreds
-		for ( i in { success: 1, error: 1, complete: 1 } ) {
-			jqXHR[ i ]( s[ i ] );
-		}
-
-		// Get transport
-		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
-		// If no transport, we auto-abort
-		if ( !transport ) {
-			done( -1, "No Transport" );
-		} else {
-			jqXHR.readyState = 1;
-
-			// Send global event
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
-			}
-			// Timeout
-			if ( s.async && s.timeout > 0 ) {
-				timeoutTimer = setTimeout(function() {
-					jqXHR.abort("timeout");
-				}, s.timeout );
-			}
-
-			try {
-				state = 1;
-				transport.send( requestHeaders, done );
-			} catch ( e ) {
-				// Propagate exception as error if not done
-				if ( state < 2 ) {
-					done( -1, e );
-				// Simply rethrow otherwise
-				} else {
-					throw e;
-				}
-			}
-		}
-
-		// Callback for when everything is done
-		function done( status, nativeStatusText, responses, headers ) {
-			var isSuccess, success, error, response, modified,
-				statusText = nativeStatusText;
-
-			// Called once
-			if ( state === 2 ) {
-				return;
-			}
-
-			// State is "done" now
-			state = 2;
-
-			// Clear timeout if it exists
-			if ( timeoutTimer ) {
-				clearTimeout( timeoutTimer );
-			}
-
-			// Dereference transport for early garbage collection
-			// (no matter how long the jqXHR object will be used)
-			transport = undefined;
-
-			// Cache response headers
-			responseHeadersString = headers || "";
-
-			// Set readyState
-			jqXHR.readyState = status > 0 ? 4 : 0;
-
-			// Determine if successful
-			isSuccess = status >= 200 && status < 300 || status === 304;
-
-			// Get response data
-			if ( responses ) {
-				response = ajaxHandleResponses( s, jqXHR, responses );
-			}
-
-			// Convert no matter what (that way responseXXX fields are always set)
-			response = ajaxConvert( s, response, jqXHR, isSuccess );
-
-			// If successful, handle type chaining
-			if ( isSuccess ) {
-
-				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-				if ( s.ifModified ) {
-					modified = jqXHR.getResponseHeader("Last-Modified");
-					if ( modified ) {
-						jQuery.lastModified[ cacheURL ] = modified;
-					}
-					modified = jqXHR.getResponseHeader("etag");
-					if ( modified ) {
-						jQuery.etag[ cacheURL ] = modified;
-					}
-				}
-
-				// if no content
-				if ( status === 204 || s.type === "HEAD" ) {
-					statusText = "nocontent";
-
-				// if not modified
-				} else if ( status === 304 ) {
-					statusText = "notmodified";
-
-				// If we have data, let's convert it
-				} else {
-					statusText = response.state;
-					success = response.data;
-					error = response.error;
-					isSuccess = !error;
-				}
-			} else {
-				// We extract error from statusText
-				// then normalize statusText and status for non-aborts
-				error = statusText;
-				if ( status || !statusText ) {
-					statusText = "error";
-					if ( status < 0 ) {
-						status = 0;
-					}
-				}
-			}
-
-			// Set data for the fake xhr object
-			jqXHR.status = status;
-			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
-
-			// Success/Error
-			if ( isSuccess ) {
-				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
-			} else {
-				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
-			}
-
-			// Status-dependent callbacks
-			jqXHR.statusCode( statusCode );
-			statusCode = undefined;
-
-			if ( fireGlobals ) {
-				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
-					[ jqXHR, s, isSuccess ? success : error ] );
-			}
-
-			// Complete
-			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
-				// Handle the global AJAX counter
-				if ( !( --jQuery.active ) ) {
-					jQuery.event.trigger("ajaxStop");
-				}
-			}
-		}
-
-		return jqXHR;
-	},
-
-	getJSON: function( url, data, callback ) {
-		return jQuery.get( url, data, callback, "json" );
-	},
-
-	getScript: function( url, callback ) {
-		return jQuery.get( url, undefined, callback, "script" );
-	}
-});
-
-jQuery.each( [ "get", "post" ], function( i, method ) {
-	jQuery[ method ] = function( url, data, callback, type ) {
-		// shift arguments if data argument was omitted
-		if ( jQuery.isFunction( data ) ) {
-			type = type || callback;
-			callback = data;
-			data = undefined;
-		}
-
-		return jQuery.ajax({
-			url: url,
-			type: method,
-			dataType: type,
-			data: data,
-			success: callback
-		});
-	};
-});
-
-
-jQuery._evalUrl = function( url ) {
-	return jQuery.ajax({
-		url: url,
-		type: "GET",
-		dataType: "script",
-		async: false,
-		global: false,
-		"throws": true
-	});
-};
-
-
-jQuery.fn.extend({
-	wrapAll: function( html ) {
-		if ( jQuery.isFunction( html ) ) {
-			return this.each(function(i) {
-				jQuery(this).wrapAll( html.call(this, i) );
-			});
-		}
-
-		if ( this[0] ) {
-			// The elements to wrap the target around
-			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
-
-			if ( this[0].parentNode ) {
-				wrap.insertBefore( this[0] );
-			}
-
-			wrap.map(function() {
-				var elem = this;
-
-				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
-					elem = elem.firstChild;
-				}
-
-				return elem;
-			}).append( this );
-		}
-
-		return this;
-	},
-
-	wrapInner: function( html ) {
-		if ( jQuery.isFunction( html ) ) {
-			return this.each(function(i) {
-				jQuery(this).wrapInner( html.call(this, i) );
-			});
-		}
-
-		return this.each(function() {
-			var self = jQuery( this ),
-				contents = self.contents();
-
-			if ( contents.length ) {
-				contents.wrapAll( html );
-
-			} else {
-				self.append( html );
-			}
-		});
-	},
-
-	wrap: function( html ) {
-		var isFunction = jQuery.isFunction( html );
-
-		return this.each(function(i) {
-			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
-		});
-	},
-
-	unwrap: function() {
-		return this.parent().each(function() {
-			if ( !jQuery.nodeName( this, "body" ) ) {
-				jQuery( this ).replaceWith( this.childNodes );
-			}
-		}).end();
-	}
-});
-
-
-jQuery.expr.filters.hidden = function( elem ) {
-	// Support: Opera <= 12.12
-	// Opera reports offsetWidths and offsetHeights less than zero on some elements
-	return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
-		(!support.reliableHiddenOffsets() &&
-			((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
-};
-
-jQuery.expr.filters.visible = function( elem ) {
-	return !jQuery.expr.filters.hidden( elem );
-};
-
-
-
-
-var r20 = /%20/g,
-	rbracket = /\[\]$/,
-	rCRLF = /\r?\n/g,
-	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
-	rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
-	var name;
-
-	if ( jQuery.isArray( obj ) ) {
-		// Serialize array item.
-		jQuery.each( obj, function( i, v ) {
-			if ( traditional || rbracket.test( prefix ) ) {
-				// Treat each array item as a scalar.
-				add( prefix, v );
-
-			} else {
-				// Item is non-scalar (array or object), encode its numeric index.
-				buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
-			}
-		});
-
-	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
-		// Serialize object item.
-		for ( name in obj ) {
-			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
-		}
-
-	} else {
-		// Serialize scalar item.
-		add( prefix, obj );
-	}
-}
-
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
-	var prefix,
-		s = [],
-		add = function( key, value ) {
-			// If value is a function, invoke it and return its value
-			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
-			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
-		};
-
-	// Set traditional to true for jQuery <= 1.3.2 behavior.
-	if ( traditional === undefined ) {
-		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
-	}
-
-	// If an array was passed in, assume that it is an array of form elements.
-	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-		// Serialize the form elements
-		jQuery.each( a, function() {
-			add( this.name, this.value );
-		});
-
-	} else {
-		// If traditional, encode the "old" way (the way 1.3.2 or older
-		// did it), otherwise encode params recursively.
-		for ( prefix in a ) {
-			buildParams( prefix, a[ prefix ], traditional, add );
-		}
-	}
-
-	// Return the resulting serialization
-	return s.join( "&" ).replace( r20, "+" );
-};
-
-jQuery.fn.extend({
-	serialize: function() {
-		return jQuery.param( this.serializeArray() );
-	},
-	serializeArray: function() {
-		return this.map(function() {
-			// Can add propHook for "elements" to filter or add form elements
-			var elements = jQuery.prop( this, "elements" );
-			return elements ? jQuery.makeArray( elements ) : this;
-		})
-		.filter(function() {
-			var type = this.type;
-			// Use .is(":disabled") so that fieldset[disabled] works
-			return this.name && !jQuery( this ).is( ":disabled" ) &&
-				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
-				( this.checked || !rcheckableType.test( type ) );
-		})
-		.map(function( i, elem ) {
-			var val = jQuery( this ).val();
-
-			return val == null ?
-				null :
-				jQuery.isArray( val ) ?
-					jQuery.map( val, function( val ) {
-						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-					}) :
-					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-		}).get();
-	}
-});
-
-
-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
-	// Support: IE6+
-	function() {
-
-		// XHR cannot access local files, always use ActiveX for that case
-		return !this.isLocal &&
-
-			// Support: IE7-8
-			// oldIE XHR does not support non-RFC2616 methods (#13240)
-			// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
-			// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
-			// Although this check for six methods instead of eight
-			// since IE also does not support "trace" and "connect"
-			/^(get|post|head|put|delete|options)$/i.test( this.type ) &&
-
-			createStandardXHR() || createActiveXHR();
-	} :
-	// For all other browsers, use the standard XMLHttpRequest object
-	createStandardXHR;
-
-var xhrId = 0,
-	xhrCallbacks = {},
-	xhrSupported = jQuery.ajaxSettings.xhr();
-
-// Support: IE<10
-// Open requests must be manually aborted on unload (#5280)
-// See https://support.microsoft.com/kb/2856746 for more info
-if ( window.attachEvent ) {
-	window.attachEvent( "onunload", function() {
-		for ( var key in xhrCallbacks ) {
-			xhrCallbacks[ key ]( undefined, true );
-		}
-	});
-}
-
-// Determine support properties
-support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-xhrSupported = support.ajax = !!xhrSupported;
-
-// Create transport if the browser can provide an xhr
-if ( xhrSupported ) {
-
-	jQuery.ajaxTransport(function( options ) {
-		// Cross domain only allowed if supported through XMLHttpRequest
-		if ( !options.crossDomain || support.cors ) {
-
-			var callback;
-
-			return {
-				send: function( headers, complete ) {
-					var i,
-						xhr = options.xhr(),
-						id = ++xhrId;
-
-					// Open the socket
-					xhr.open( options.type, options.url, options.async, options.username, options.password );
-
-					// Apply custom fields if provided
-					if ( options.xhrFields ) {
-						for ( i in options.xhrFields ) {
-							xhr[ i ] = options.xhrFields[ i ];
-						}
-					}
-
-					// Override mime type if needed
-					if ( options.mimeType && xhr.overrideMimeType ) {
-						xhr.overrideMimeType( options.mimeType );
-					}
-
-					// X-Requested-With header
-					// For cross-domain requests, seeing as conditions for a preflight are
-					// akin to a jigsaw puzzle, we simply never set it to be sure.
-					// (it can always be set on a per-request basis or even using ajaxSetup)
-					// For same-domain requests, won't change header if already provided.
-					if ( !options.crossDomain && !headers["X-Requested-With"] ) {
-						headers["X-Requested-With"] = "XMLHttpRequest";
-					}
-
-					// Set headers
-					for ( i in headers ) {
-						// Support: IE<9
-						// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
-						// request header to a null-value.
-						//
-						// To keep consistent with other XHR implementations, cast the value
-						// to string and ignore `undefined`.
-						if ( headers[ i ] !== undefined ) {
-							xhr.setRequestHeader( i, headers[ i ] + "" );
-						}
-					}
-
-					// Do send the request
-					// This may raise an exception which is actually
-					// handled in jQuery.ajax (so no try/catch here)
-					xhr.send( ( options.hasContent && options.data ) || null );
-
-					// Listener
-					callback = function( _, isAbort ) {
-						var status, statusText, responses;
-
-						// Was never called and is aborted or complete
-						if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
-							// Clean up
-							delete xhrCallbacks[ id ];
-							callback = undefined;
-							xhr.onreadystatechange = jQuery.noop;
-
-							// Abort manually if needed
-							if ( isAbort ) {
-								if ( xhr.readyState !== 4 ) {
-									xhr.abort();
-								}
-							} else {
-								responses = {};
-								status = xhr.status;
-
-								// Support: IE<10
-								// Accessing binary-data responseText throws an exception
-								// (#11426)
-								if ( typeof xhr.responseText === "string" ) {
-									responses.text = xhr.responseText;
-								}
-
-								// Firefox throws an exception when accessing
-								// statusText for faulty cross-domain requests
-								try {
-									statusText = xhr.statusText;
-								} catch( e ) {
-									// We normalize with Webkit giving an empty statusText
-									statusText = "";
-								}
-
-								// Filter status for non standard behaviors
-
-								// If the request is local and we have data: assume a success
-								// (success with no data won't get notified, that's the best we
-								// can do given current implementations)
-								if ( !status && options.isLocal && !options.crossDomain ) {
-									status = responses.text ? 200 : 404;
-								// IE - #1450: sometimes returns 1223 when it should be 204
-								} else if ( status === 1223 ) {
-									status = 204;
-								}
-							}
-						}
-
-						// Call complete if needed
-						if ( responses ) {
-							complete( status, statusText, responses, xhr.getAllResponseHeaders() );
-						}
-					};
-
-					if ( !options.async ) {
-						// if we're in sync mode we fire the callback
-						callback();
-					} else if ( xhr.readyState === 4 ) {
-						// (IE6 & IE7) if it's in cache and has been
-						// retrieved directly we need to fire the callback
-						setTimeout( callback );
-					} else {
-						// Add to the list of active xhr callbacks
-						xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
-					}
-				},
-
-				abort: function() {
-					if ( callback ) {
-						callback( undefined, true );
-					}
-				}
-			};
-		}
-	});
-}
-
-// Functions to create xhrs
-function createStandardXHR() {
-	try {
-		return new window.XMLHttpRequest();
-	} catch( e ) {}
-}
-
-function createActiveXHR() {
-	try {
-		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
-	} catch( e ) {}
-}
-
-
-
-
-// Install script dataType
-jQuery.ajaxSetup({
-	accepts: {
-		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
-	},
-	contents: {
-		script: /(?:java|ecma)script/
-	},
-	converters: {
-		"text script": function( text ) {
-			jQuery.globalEval( text );
-			return text;
-		}
-	}
-});
-
-// Handle cache's special case and global
-jQuery.ajaxPrefilter( "script", function( s ) {
-	if ( s.cache === undefined ) {
-		s.cache = false;
-	}
-	if ( s.crossDomain ) {
-		s.type = "GET";
-		s.global = false;
-	}
-});
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function(s) {
-
-	// This transport only deals with cross domain requests
-	if ( s.crossDomain ) {
-
-		var script,
-			head = document.head || jQuery("head")[0] || document.documentElement;
-
-		return {
-
-			send: function( _, callback ) {
-
-				script = document.createElement("script");
-
-				script.async = true;
-
-				if ( s.scriptCharset ) {
-					script.charset = s.scriptCharset;
-				}
-
-				script.src = s.url;
-
-				// Attach handlers for all browsers
-				script.onload = script.onreadystatechange = function( _, isAbort ) {
-
-					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
-
-						// Handle memory leak in IE
-						script.onload = script.onreadystatechange = null;
-
-						// Remove the script
-						if ( script.parentNode ) {
-							script.parentNode.removeChild( script );
-						}
-
-						// Dereference the script
-						script = null;
-
-						// Callback if not abort
-						if ( !isAbort ) {
-							callback( 200, "success" );
-						}
-					}
-				};
-
-				// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
-				// Use native DOM manipulation to avoid our domManip AJAX trickery
-				head.insertBefore( script, head.firstChild );
-			},
-
-			abort: function() {
-				if ( script ) {
-					script.onload( undefined, true );
-				}
-			}
-		};
-	}
-});
-
-
-
-
-var oldCallbacks = [],
-	rjsonp = /(=)\?(?=&|$)|\?\?/;
-
-// Default jsonp settings
-jQuery.ajaxSetup({
-	jsonp: "callback",
-	jsonpCallback: function() {
-		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
-		this[ callback ] = true;
-		return callback;
-	}
-});
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
-	var callbackName, overwritten, responseContainer,
-		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
-			"url" :
-			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
-		);
-
-	// Handle iff the expected data type is "jsonp" or we have a parameter to set
-	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
-		// Get callback name, remembering preexisting value associated with it
-		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
-			s.jsonpCallback() :
-			s.jsonpCallback;
-
-		// Insert callback into url or form data
-		if ( jsonProp ) {
-			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
-		} else if ( s.jsonp !== false ) {
-			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
-		}
-
-		// Use data converter to retrieve json after script execution
-		s.converters["script json"] = function() {
-			if ( !responseContainer ) {
-				jQuery.error( callbackName + " was not called" );
-			}
-			return responseContainer[ 0 ];
-		};
-
-		// force json dataType
-		s.dataTypes[ 0 ] = "json";
-
-		// Install callback
-		overwritten = window[ callbackName ];
-		window[ callbackName ] = function() {
-			responseContainer = arguments;
-		};
-
-		// Clean-up function (fires after converters)
-		jqXHR.always(function() {
-			// Restore preexisting value
-			window[ callbackName ] = overwritten;
-
-			// Save back as free
-			if ( s[ callbackName ] ) {
-				// make sure that re-using the options doesn't screw things around
-				s.jsonpCallback = originalSettings.jsonpCallback;
-
-				// save the callback name for future use
-				oldCallbacks.push( callbackName );
-			}
-
-			// Call if it was a function and we have a response
-			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
-				overwritten( responseContainer[ 0 ] );
-			}
-
-			responseContainer = overwritten = undefined;
-		});
-
-		// Delegate to script
-		return "script";
-	}
-});
-
-
-
-
-// data: string of html
-// context (optional): If specified, the fragment will be created in this context, defaults to document
-// keepScripts (optional): If true, will include scripts passed in the html string
-jQuery.parseHTML = function( data, context, keepScripts ) {
-	if ( !data || typeof data !== "string" ) {
-		return null;
-	}
-	if ( typeof context === "boolean" ) {
-		keepScripts = context;
-		context = false;
-	}
-	context = context || document;
-
-	var parsed = rsingleTag.exec( data ),
-		scripts = !keepScripts && [];
-
-	// Single tag
-	if ( parsed ) {
-		return [ context.createElement( parsed[1] ) ];
-	}
-
-	parsed = jQuery.buildFragment( [ data ], context, scripts );
-
-	if ( scripts && scripts.length ) {
-		jQuery( scripts ).remove();
-	}
-
-	return jQuery.merge( [], parsed.childNodes );
-};
-
-
-// Keep a copy of the old load method
-var _load = jQuery.fn.load;
-
-/**
- * Load a url into a page
- */
-jQuery.fn.load = function( url, params, callback ) {
-	if ( typeof url !== "string" && _load ) {
-		return _load.apply( this, arguments );
-	}
-
-	var selector, response, type,
-		self = this,
-		off = url.indexOf(" ");
-
-	if ( off >= 0 ) {
-		selector = jQuery.trim( url.slice( off, url.length ) );
-		url = url.slice( 0, off );
-	}
-
-	// If it's a function
-	if ( jQuery.isFunction( params ) ) {
-
-		// We assume that it's the callback
-		callback = params;
-		params = undefined;
-
-	// Otherwise, build a param string
-	} else if ( params && typeof params === "object" ) {
-		type = "POST";
-	}
-
-	// If we have elements to modify, make the request
-	if ( self.length > 0 ) {
-		jQuery.ajax({
-			url: url,
-
-			// if "type" variable is undefined, then "GET" method will be used
-			type: type,
-			dataType: "html",
-			data: params
-		}).done(function( responseText ) {
-
-			// Save response for use in complete callback
-			response = arguments;
-
-			self.html( selector ?
-
-				// If a selector was specified, locate the right elements in a dummy div
-				// Exclude scripts to avoid IE 'Permission Denied' errors
-				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
-				// Otherwise use the full result
-				responseText );
-
-		}).complete( callback && function( jqXHR, status ) {
-			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
-		});
-	}
-
-	return this;
-};
-
-
-
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
-	jQuery.fn[ type ] = function( fn ) {
-		return this.on( type, fn );
-	};
-});
-
-
-
-
-jQuery.expr.filters.animated = function( elem ) {
-	return jQuery.grep(jQuery.timers, function( fn ) {
-		return elem === fn.elem;
-	}).length;
-};
-
-
-
-
-
-var docElem = window.document.documentElement;
-
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
-	return jQuery.isWindow( elem ) ?
-		elem :
-		elem.nodeType === 9 ?
-			elem.defaultView || elem.parentWindow :
-			false;
-}
-
-jQuery.offset = {
-	setOffset: function( elem, options, i ) {
-		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
-			position = jQuery.css( elem, "position" ),
-			curElem = jQuery( elem ),
-			props = {};
-
-		// set position first, in-case top/left are set even on static elem
-		if ( position === "static" ) {
-			elem.style.position = "relative";
-		}
-
-		curOffset = curElem.offset();
-		curCSSTop = jQuery.css( elem, "top" );
-		curCSSLeft = jQuery.css( elem, "left" );
-		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
-			jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
-
-		// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
-		if ( calculatePosition ) {
-			curPosition = curElem.position();
-			curTop = curPosition.top;
-			curLeft = curPosition.left;
-		} else {
-			curTop = parseFloat( curCSSTop ) || 0;
-			curLeft = parseFloat( curCSSLeft ) || 0;
-		}
-
-		if ( jQuery.isFunction( options ) ) {
-			options = options.call( elem, i, curOffset );
-		}
-
-		if ( options.top != null ) {
-			props.top = ( options.top - curOffset.top ) + curTop;
-		}
-		if ( options.left != null ) {
-			props.left = ( options.left - curOffset.left ) + curLeft;
-		}
-
-		if ( "using" in options ) {
-			options.using.call( elem, props );
-		} else {
-			curElem.css( props );
-		}
-	}
-};
-
-jQuery.fn.extend({
-	offset: function( options ) {
-		if ( arguments.length ) {
-			return options === undefined ?
-				this :
-				this.each(function( i ) {
-					jQuery.offset.setOffset( this, options, i );
-				});
-		}
-
-		var docElem, win,
-			box = { top: 0, left: 0 },
-			elem = this[ 0 ],
-			doc = elem && elem.ownerDocument;
-
-		if ( !doc ) {
-			return;
-		}
-
-		docElem = doc.documentElement;
-
-		// Make sure it's not a disconnected DOM node
-		if ( !jQuery.contains( docElem, elem ) ) {
-			return box;
-		}
-
-		// If we don't have gBCR, just use 0,0 rather than error
-		// BlackBerry 5, iOS 3 (original iPhone)
-		if ( typeof elem.getBoundingClientRect !== strundefined ) {
-			box = elem.getBoundingClientRect();
-		}
-		win = getWindow( doc );
-		return {
-			top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
-			left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
-		};
-	},
-
-	position: function() {
-		if ( !this[ 0 ] ) {
-			return;
-		}
-
-		var offsetParent, offset,
-			parentOffset = { top: 0, left: 0 },
-			elem = this[ 0 ];
-
-		// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
-		if ( jQuery.css( elem, "position" ) === "fixed" ) {
-			// we assume that getBoundingClientRect is available when computed position is fixed
-			offset = elem.getBoundingClientRect();
-		} else {
-			// Get *real* offsetParent
-			offsetParent = this.offsetParent();
-
-			// Get correct offsets
-			offset = this.offset();
-			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
-				parentOffset = offsetParent.offset();
-			}
-
-			// Add offsetParent borders
-			parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
-			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
-		}
-
-		// Subtract parent offsets and element margins
-		// note: when an element has margin: auto the offsetLeft and marginLeft
-		// are the same in Safari causing offset.left to incorrectly be 0
-		return {
-			top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
-			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
-		};
-	},
-
-	offsetParent: function() {
-		return this.map(function() {
-			var offsetParent = this.offsetParent || docElem;
-
-			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
-				offsetParent = offsetParent.offsetParent;
-			}
-			return offsetParent || docElem;
-		});
-	}
-});
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
-	var top = /Y/.test( prop );
-
-	jQuery.fn[ method ] = function( val ) {
-		return access( this, function( elem, method, val ) {
-			var win = getWindow( elem );
-
-			if ( val === undefined ) {
-				return win ? (prop in win) ? win[ prop ] :
-					win.document.documentElement[ method ] :
-					elem[ method ];
-			}
-
-			if ( win ) {
-				win.scrollTo(
-					!top ? val : jQuery( win ).scrollLeft(),
-					top ? val : jQuery( win ).scrollTop()
-				);
-
-			} else {
-				elem[ method ] = val;
-			}
-		}, method, val, arguments.length, null );
-	};
-});
-
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// getComputedStyle returns percent when specified for top/left/bottom/right
-// rather than make the css module depend on the offset module, we just check for it here
-jQuery.each( [ "top", "left" ], function( i, prop ) {
-	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
-		function( elem, computed ) {
-			if ( computed ) {
-				computed = curCSS( elem, prop );
-				// if curCSS returns percentage, fallback to offset
-				return rnumnonpx.test( computed ) ?
-					jQuery( elem ).position()[ prop ] + "px" :
-					computed;
-			}
-		}
-	);
-});
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
-	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
-		// margin is only for outerHeight, outerWidth
-		jQuery.fn[ funcName ] = function( margin, value ) {
-			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
-				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
-			return access( this, function( elem, type, value ) {
-				var doc;
-
-				if ( jQuery.isWindow( elem ) ) {
-					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
-					// isn't a whole lot we can do. See pull request at this URL for discussion:
-					// https://github.com/jquery/jquery/pull/764
-					return elem.document.documentElement[ "client" + name ];
-				}
-
-				// Get document width or height
-				if ( elem.nodeType === 9 ) {
-					doc = elem.documentElement;
-
-					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
-					// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
-					return Math.max(
-						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
-						elem.body[ "offset" + name ], doc[ "offset" + name ],
-						doc[ "client" + name ]
-					);
-				}
-
-				return value === undefined ?
-					// Get width or height on the element, requesting but not forcing parseFloat
-					jQuery.css( elem, type, extra ) :
-
-					// Set width or height on the element
-					jQuery.style( elem, type, value, extra );
-			}, type, chainable ? margin : undefined, chainable, null );
-		};
-	});
-});
-
-
-// The number of elements contained in the matched element set
-jQuery.fn.size = function() {
-	return this.length;
-};
-
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
-	define( "jquery", [], function() {
-		return jQuery;
-	});
-}
-
-
-
-
-var
-	// Map over jQuery in case of overwrite
-	_jQuery = window.jQuery,
-
-	// Map over the $ in case of overwrite
-	_$ = window.$;
-
-jQuery.noConflict = function( deep ) {
-	if ( window.$ === jQuery ) {
-		window.$ = _$;
-	}
-
-	if ( deep && window.jQuery === jQuery ) {
-		window.jQuery = _jQuery;
-	}
-
-	return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in
-// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( typeof noGlobal === strundefined ) {
-	window.jQuery = window.$ = jQuery;
-}
-
-
-
-
-return jQuery;
-
-}));
Index: inc/js/jquery/1.12.4/jquery.cookie.js
===================================================================
--- inc/js/jquery/1.12.4/jquery.cookie.js	(revision 3829)
+++ inc/js/jquery/1.12.4/jquery.cookie.js	(revision 3829)
@@ -0,0 +1,117 @@
+/*!
+ * jQuery Cookie Plugin v1.4.1
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2006, 2014 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+	if (typeof define === 'function' && define.amd) {
+		// AMD
+		define(['jquery'], factory);
+	} else if (typeof exports === 'object') {
+		// CommonJS
+		factory(require('jquery'));
+	} else {
+		// Browser globals
+		factory(jQuery);
+	}
+}(function ($) {
+
+	var pluses = /\+/g;
+
+	function encode(s) {
+		return config.raw ? s : encodeURIComponent(s);
+	}
+
+	function decode(s) {
+		return config.raw ? s : decodeURIComponent(s);
+	}
+
+	function stringifyCookieValue(value) {
+		return encode(config.json ? JSON.stringify(value) : String(value));
+	}
+
+	function parseCookieValue(s) {
+		if (s.indexOf('"') === 0) {
+			// This is a quoted cookie as according to RFC2068, unescape...
+			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+		}
+
+		try {
+			// Replace server-side written pluses with spaces.
+			// If we can't decode the cookie, ignore it, it's unusable.
+			// If we can't parse the cookie, ignore it, it's unusable.
+			s = decodeURIComponent(s.replace(pluses, ' '));
+			return config.json ? JSON.parse(s) : s;
+		} catch(e) {}
+	}
+
+	function read(s, converter) {
+		var value = config.raw ? s : parseCookieValue(s);
+		return $.isFunction(converter) ? converter(value) : value;
+	}
+
+	var config = $.cookie = function (key, value, options) {
+
+		// Write
+
+		if (arguments.length > 1 && !$.isFunction(value)) {
+			options = $.extend({}, config.defaults, options);
+
+			if (typeof options.expires === 'number') {
+				var days = options.expires, t = options.expires = new Date();
+				t.setTime(+t + days * 864e+5);
+			}
+
+			return (document.cookie = [
+				encode(key), '=', stringifyCookieValue(value),
+				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+				options.path    ? '; path=' + options.path : '',
+				options.domain  ? '; domain=' + options.domain : '',
+				options.secure  ? '; secure' : ''
+			].join(''));
+		}
+
+		// Read
+
+		var result = key ? undefined : {};
+
+		// To prevent the for loop in the first place assign an empty array
+		// in case there are no cookies at all. Also prevents odd result when
+		// calling $.cookie().
+		var cookies = document.cookie ? document.cookie.split('; ') : [];
+
+		for (var i = 0, l = cookies.length; i < l; i++) {
+			var parts = cookies[i].split('=');
+			var name = decode(parts.shift());
+			var cookie = parts.join('=');
+
+			if (key && key === name) {
+				// If second argument (value) is a function it's a converter...
+				result = read(cookie, value);
+				break;
+			}
+
+			// Prevent storing a cookie that we couldn't decode.
+			if (!key && (cookie = read(cookie)) !== undefined) {
+				result[name] = cookie;
+			}
+		}
+
+		return result;
+	};
+
+	config.defaults = {};
+
+	$.removeCookie = function (key, options) {
+		if ($.cookie(key) === undefined) {
+			return false;
+		}
+
+		// Must not alter options, thus extending a fresh object...
+		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
+		return !$.cookie(key);
+	};
+
+}));
Index: inc/js/jquery/1.12.4/jquery.js
===================================================================
--- inc/js/jquery/1.12.4/jquery.js	(revision 3829)
+++ inc/js/jquery/1.12.4/jquery.js	(revision 3829)
@@ -0,0 +1,5 @@
+/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
+}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
+marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
+padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
Index: inc/js/jquery/3.3.1/jquery.cookie.js
===================================================================
--- inc/js/jquery/3.3.1/jquery.cookie.js	(revision 3829)
+++ inc/js/jquery/3.3.1/jquery.cookie.js	(revision 3829)
@@ -0,0 +1,117 @@
+/*!
+ * jQuery Cookie Plugin v1.4.1
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2006, 2014 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+	if (typeof define === 'function' && define.amd) {
+		// AMD
+		define(['jquery'], factory);
+	} else if (typeof exports === 'object') {
+		// CommonJS
+		factory(require('jquery'));
+	} else {
+		// Browser globals
+		factory(jQuery);
+	}
+}(function ($) {
+
+	var pluses = /\+/g;
+
+	function encode(s) {
+		return config.raw ? s : encodeURIComponent(s);
+	}
+
+	function decode(s) {
+		return config.raw ? s : decodeURIComponent(s);
+	}
+
+	function stringifyCookieValue(value) {
+		return encode(config.json ? JSON.stringify(value) : String(value));
+	}
+
+	function parseCookieValue(s) {
+		if (s.indexOf('"') === 0) {
+			// This is a quoted cookie as according to RFC2068, unescape...
+			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+		}
+
+		try {
+			// Replace server-side written pluses with spaces.
+			// If we can't decode the cookie, ignore it, it's unusable.
+			// If we can't parse the cookie, ignore it, it's unusable.
+			s = decodeURIComponent(s.replace(pluses, ' '));
+			return config.json ? JSON.parse(s) : s;
+		} catch(e) {}
+	}
+
+	function read(s, converter) {
+		var value = config.raw ? s : parseCookieValue(s);
+		return $.isFunction(converter) ? converter(value) : value;
+	}
+
+	var config = $.cookie = function (key, value, options) {
+
+		// Write
+
+		if (arguments.length > 1 && !$.isFunction(value)) {
+			options = $.extend({}, config.defaults, options);
+
+			if (typeof options.expires === 'number') {
+				var days = options.expires, t = options.expires = new Date();
+				t.setTime(+t + days * 864e+5);
+			}
+
+			return (document.cookie = [
+				encode(key), '=', stringifyCookieValue(value),
+				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+				options.path    ? '; path=' + options.path : '',
+				options.domain  ? '; domain=' + options.domain : '',
+				options.secure  ? '; secure' : ''
+			].join(''));
+		}
+
+		// Read
+
+		var result = key ? undefined : {};
+
+		// To prevent the for loop in the first place assign an empty array
+		// in case there are no cookies at all. Also prevents odd result when
+		// calling $.cookie().
+		var cookies = document.cookie ? document.cookie.split('; ') : [];
+
+		for (var i = 0, l = cookies.length; i < l; i++) {
+			var parts = cookies[i].split('=');
+			var name = decode(parts.shift());
+			var cookie = parts.join('=');
+
+			if (key && key === name) {
+				// If second argument (value) is a function it's a converter...
+				result = read(cookie, value);
+				break;
+			}
+
+			// Prevent storing a cookie that we couldn't decode.
+			if (!key && (cookie = read(cookie)) !== undefined) {
+				result[name] = cookie;
+			}
+		}
+
+		return result;
+	};
+
+	config.defaults = {};
+
+	$.removeCookie = function (key, options) {
+		if ($.cookie(key) === undefined) {
+			return false;
+		}
+
+		// Must not alter options, thus extending a fresh object...
+		$.cookie(key, '', $.extend({}, options, { expires: -1 }));
+		return !$.cookie(key);
+	};
+
+}));
Index: inc/js/jquery/3.3.1/jquery.js
===================================================================
--- inc/js/jquery/3.3.1/jquery.js	(revision 3829)
+++ inc/js/jquery/3.3.1/jquery.js	(revision 3829)
@@ -0,0 +1,10364 @@
+/*!
+ * jQuery JavaScript Library v3.3.1
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2018-01-20T17:24Z
+ */
+( function( global, factory ) {
+
+	"use strict";
+
+	if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+		// For CommonJS and CommonJS-like environments where a proper `window`
+		// is present, execute the factory and get jQuery.
+		// For environments that do not have a `window` with a `document`
+		// (such as Node.js), expose a factory as module.exports.
+		// This accentuates the need for the creation of a real `window`.
+		// e.g. var jQuery = require("jquery")(window);
+		// See ticket #14549 for more info.
+		module.exports = global.document ?
+			factory( global, true ) :
+			function( w ) {
+				if ( !w.document ) {
+					throw new Error( "jQuery requires a window with a document" );
+				}
+				return factory( w );
+			};
+	} else {
+		factory( global );
+	}
+
+// Pass this if window is not defined yet
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
+
+var arr = [];
+
+var document = window.document;
+
+var getProto = Object.getPrototypeOf;
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
+var support = {};
+
+var isFunction = function isFunction( obj ) {
+
+      // Support: Chrome <=57, Firefox <=52
+      // In some browsers, typeof returns "function" for HTML <object> elements
+      // (i.e., `typeof document.createElement( "object" ) === "function"`).
+      // We don't want to classify *any* DOM node as a function.
+      return typeof obj === "function" && typeof obj.nodeType !== "number";
+  };
+
+
+var isWindow = function isWindow( obj ) {
+		return obj != null && obj === obj.window;
+	};
+
+
+
+
+	var preservedScriptAttributes = {
+		type: true,
+		src: true,
+		noModule: true
+	};
+
+	function DOMEval( code, doc, node ) {
+		doc = doc || document;
+
+		var i,
+			script = doc.createElement( "script" );
+
+		script.text = code;
+		if ( node ) {
+			for ( i in preservedScriptAttributes ) {
+				if ( node[ i ] ) {
+					script[ i ] = node[ i ];
+				}
+			}
+		}
+		doc.head.appendChild( script ).parentNode.removeChild( script );
+	}
+
+
+function toType( obj ) {
+	if ( obj == null ) {
+		return obj + "";
+	}
+
+	// Support: Android <=2.3 only (functionish RegExp)
+	return typeof obj === "object" || typeof obj === "function" ?
+		class2type[ toString.call( obj ) ] || "object" :
+		typeof obj;
+}
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
+var
+	version = "3.3.1",
+
+	// Define a local copy of jQuery
+	jQuery = function( selector, context ) {
+
+		// The jQuery object is actually just the init constructor 'enhanced'
+		// Need init if jQuery is called (just allow error to be thrown if not included)
+		return new jQuery.fn.init( selector, context );
+	},
+
+	// Support: Android <=4.0 only
+	// Make sure we trim BOM and NBSP
+	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
+
+jQuery.fn = jQuery.prototype = {
+
+	// The current version of jQuery being used
+	jquery: version,
+
+	constructor: jQuery,
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	toArray: function() {
+		return slice.call( this );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+
+		// Return all the elements in a clean array
+		if ( num == null ) {
+			return slice.call( this );
+		}
+
+		// Return just the one element from the set
+		return num < 0 ? this[ num + this.length ] : this[ num ];
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems ) {
+
+		// Build a new jQuery matched element set
+		var ret = jQuery.merge( this.constructor(), elems );
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	each: function( callback ) {
+		return jQuery.each( this, callback );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map( this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		} ) );
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ) );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	eq: function( i ) {
+		var len = this.length,
+			j = +i + ( i < 0 ? len : 0 );
+		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor();
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: arr.sort,
+	splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var options, name, src, copy, copyIsArray, clone,
+		target = arguments[ 0 ] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+
+		// Skip the boolean and the target
+		target = arguments[ i ] || {};
+		i++;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !isFunction( target ) ) {
+		target = {};
+	}
+
+	// Extend jQuery itself if only one argument is passed
+	if ( i === length ) {
+		target = this;
+		i--;
+	}
+
+	for ( ; i < length; i++ ) {
+
+		// Only deal with non-null/undefined values
+		if ( ( options = arguments[ i ] ) != null ) {
+
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+					( copyIsArray = Array.isArray( copy ) ) ) ) {
+
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && Array.isArray( src ) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject( src ) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend( {
+
+	// Unique for each copy of jQuery on the page
+	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+	// Assume jQuery is ready without the ready module
+	isReady: true,
+
+	error: function( msg ) {
+		throw new Error( msg );
+	},
+
+	noop: function() {},
+
+	isPlainObject: function( obj ) {
+		var proto, Ctor;
+
+		// Detect obvious negatives
+		// Use toString instead of jQuery.type to catch host objects
+		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+			return false;
+		}
+
+		proto = getProto( obj );
+
+		// Objects with no prototype (e.g., `Object.create( null )`) are plain
+		if ( !proto ) {
+			return true;
+		}
+
+		// Objects with prototype are plain iff they were constructed by a global Object function
+		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+	},
+
+	isEmptyObject: function( obj ) {
+
+		/* eslint-disable no-unused-vars */
+		// See https://github.com/eslint/eslint/issues/6125
+		var name;
+
+		for ( name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	// Evaluates a script in a global context
+	globalEval: function( code ) {
+		DOMEval( code );
+	},
+
+	each: function( obj, callback ) {
+		var length, i = 0;
+
+		if ( isArrayLike( obj ) ) {
+			length = obj.length;
+			for ( ; i < length; i++ ) {
+				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+					break;
+				}
+			}
+		} else {
+			for ( i in obj ) {
+				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+					break;
+				}
+			}
+		}
+
+		return obj;
+	},
+
+	// Support: Android <=4.0 only
+	trim: function( text ) {
+		return text == null ?
+			"" :
+			( text + "" ).replace( rtrim, "" );
+	},
+
+	// results is for internal usage only
+	makeArray: function( arr, results ) {
+		var ret = results || [];
+
+		if ( arr != null ) {
+			if ( isArrayLike( Object( arr ) ) ) {
+				jQuery.merge( ret,
+					typeof arr === "string" ?
+					[ arr ] : arr
+				);
+			} else {
+				push.call( ret, arr );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, arr, i ) {
+		return arr == null ? -1 : indexOf.call( arr, elem, i );
+	},
+
+	// Support: Android <=4.0 only, PhantomJS 1 only
+	// push.apply(_, arraylike) throws on ancient WebKit
+	merge: function( first, second ) {
+		var len = +second.length,
+			j = 0,
+			i = first.length;
+
+		for ( ; j < len; j++ ) {
+			first[ i++ ] = second[ j ];
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, invert ) {
+		var callbackInverse,
+			matches = [],
+			i = 0,
+			length = elems.length,
+			callbackExpect = !invert;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( ; i < length; i++ ) {
+			callbackInverse = !callback( elems[ i ], i );
+			if ( callbackInverse !== callbackExpect ) {
+				matches.push( elems[ i ] );
+			}
+		}
+
+		return matches;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var length, value,
+			i = 0,
+			ret = [];
+
+		// Go through the array, translating each of the items to their new values
+		if ( isArrayLike( elems ) ) {
+			length = elems.length;
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret.push( value );
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( i in elems ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret.push( value );
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// jQuery.support is not used in Core but other projects attach their
+	// properties to it so it needs to exist.
+	support: support
+} );
+
+if ( typeof Symbol === "function" ) {
+	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+	// Support: real iOS 8.2 only (not reproducible in simulator)
+	// `in` check used to prevent JIT error (gh-2145)
+	// hasOwn isn't used here due to false negatives
+	// regarding Nodelist length in IE
+	var length = !!obj && "length" in obj && obj.length,
+		type = toType( obj );
+
+	if ( isFunction( obj ) || isWindow( obj ) ) {
+		return false;
+	}
+
+	return type === "array" || length === 0 ||
+		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-08-08
+ */
+(function( window ) {
+
+var i,
+	support,
+	Expr,
+	getText,
+	isXML,
+	tokenize,
+	compile,
+	select,
+	outermostContext,
+	sortInput,
+	hasDuplicate,
+
+	// Local document vars
+	setDocument,
+	document,
+	docElem,
+	documentIsHTML,
+	rbuggyQSA,
+	rbuggyMatches,
+	matches,
+	contains,
+
+	// Instance-specific data
+	expando = "sizzle" + 1 * new Date(),
+	preferredDoc = window.document,
+	dirruns = 0,
+	done = 0,
+	classCache = createCache(),
+	tokenCache = createCache(),
+	compilerCache = createCache(),
+	sortOrder = function( a, b ) {
+		if ( a === b ) {
+			hasDuplicate = true;
+		}
+		return 0;
+	},
+
+	// Instance methods
+	hasOwn = ({}).hasOwnProperty,
+	arr = [],
+	pop = arr.pop,
+	push_native = arr.push,
+	push = arr.push,
+	slice = arr.slice,
+	// Use a stripped-down indexOf as it's faster than native
+	// https://jsperf.com/thor-indexof-vs-for/5
+	indexOf = function( list, elem ) {
+		var i = 0,
+			len = list.length;
+		for ( ; i < len; i++ ) {
+			if ( list[i] === elem ) {
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+	// Regular expressions
+
+	// http://www.w3.org/TR/css3-selectors/#whitespace
+	whitespace = "[\\x20\\t\\r\\n\\f]",
+
+	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+
+	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+		// Operator (capture 2)
+		"*([*^$|!~]?=)" + whitespace +
+		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+		"*\\]",
+
+	pseudos = ":(" + identifier + ")(?:\\((" +
+		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+		// 1. quoted (capture 3; capture 4 or capture 5)
+		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+		// 2. simple (capture 6)
+		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+		// 3. anything else (capture 2)
+		".*" +
+		")\\)|)",
+
+	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+	rwhitespace = new RegExp( whitespace + "+", "g" ),
+	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+	rpseudo = new RegExp( pseudos ),
+	ridentifier = new RegExp( "^" + identifier + "$" ),
+
+	matchExpr = {
+		"ID": new RegExp( "^#(" + identifier + ")" ),
+		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
+		"ATTR": new RegExp( "^" + attributes ),
+		"PSEUDO": new RegExp( "^" + pseudos ),
+		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+		// For use in libraries implementing .is()
+		// We use this for POS matching in `select`
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+	},
+
+	rinputs = /^(?:input|select|textarea|button)$/i,
+	rheader = /^h\d$/i,
+
+	rnative = /^[^{]+\{\s*\[native \w/,
+
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
+	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+	rsibling = /[+~]/,
+
+	// CSS escapes
+	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+	funescape = function( _, escaped, escapedWhitespace ) {
+		var high = "0x" + escaped - 0x10000;
+		// NaN means non-codepoint
+		// Support: Firefox<24
+		// Workaround erroneous numeric interpretation of +"0x"
+		return high !== high || escapedWhitespace ?
+			escaped :
+			high < 0 ?
+				// BMP codepoint
+				String.fromCharCode( high + 0x10000 ) :
+				// Supplemental Plane codepoint (surrogate pair)
+				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+	},
+
+	// CSS string/identifier serialization
+	// https://drafts.csswg.org/cssom/#common-serializing-idioms
+	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+	fcssescape = function( ch, asCodePoint ) {
+		if ( asCodePoint ) {
+
+			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+			if ( ch === "\0" ) {
+				return "\uFFFD";
+			}
+
+			// Control characters and (dependent upon position) numbers get escaped as code points
+			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+		}
+
+		// Other potentially-special ASCII characters get backslash-escaped
+		return "\\" + ch;
+	},
+
+	// Used for iframes
+	// See setDocument()
+	// Removing the function wrapper causes a "Permission Denied"
+	// error in IE
+	unloadHandler = function() {
+		setDocument();
+	},
+
+	disabledAncestor = addCombinator(
+		function( elem ) {
+			return elem.disabled === true && ("form" in elem || "label" in elem);
+		},
+		{ dir: "parentNode", next: "legend" }
+	);
+
+// Optimize for push.apply( _, NodeList )
+try {
+	push.apply(
+		(arr = slice.call( preferredDoc.childNodes )),
+		preferredDoc.childNodes
+	);
+	// Support: Android<4.0
+	// Detect silently failing push.apply
+	arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+	push = { apply: arr.length ?
+
+		// Leverage slice if possible
+		function( target, els ) {
+			push_native.apply( target, slice.call(els) );
+		} :
+
+		// Support: IE<9
+		// Otherwise append directly
+		function( target, els ) {
+			var j = target.length,
+				i = 0;
+			// Can't trust NodeList.length
+			while ( (target[j++] = els[i++]) ) {}
+			target.length = j - 1;
+		}
+	};
+}
+
+function Sizzle( selector, context, results, seed ) {
+	var m, i, elem, nid, match, groups, newSelector,
+		newContext = context && context.ownerDocument,
+
+		// nodeType defaults to 9, since context defaults to document
+		nodeType = context ? context.nodeType : 9;
+
+	results = results || [];
+
+	// Return early from calls with invalid selector or context
+	if ( typeof selector !== "string" || !selector ||
+		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+		return results;
+	}
+
+	// Try to shortcut find operations (as opposed to filters) in HTML documents
+	if ( !seed ) {
+
+		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+			setDocument( context );
+		}
+		context = context || document;
+
+		if ( documentIsHTML ) {
+
+			// If the selector is sufficiently simple, try using a "get*By*" DOM method
+			// (excepting DocumentFragment context, where the methods don't exist)
+			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+				// ID selector
+				if ( (m = match[1]) ) {
+
+					// Document context
+					if ( nodeType === 9 ) {
+						if ( (elem = context.getElementById( m )) ) {
+
+							// Support: IE, Opera, Webkit
+							// TODO: identify versions
+							// getElementById can match elements by name instead of ID
+							if ( elem.id === m ) {
+								results.push( elem );
+								return results;
+							}
+						} else {
+							return results;
+						}
+
+					// Element context
+					} else {
+
+						// Support: IE, Opera, Webkit
+						// TODO: identify versions
+						// getElementById can match elements by name instead of ID
+						if ( newContext && (elem = newContext.getElementById( m )) &&
+							contains( context, elem ) &&
+							elem.id === m ) {
+
+							results.push( elem );
+							return results;
+						}
+					}
+
+				// Type selector
+				} else if ( match[2] ) {
+					push.apply( results, context.getElementsByTagName( selector ) );
+					return results;
+
+				// Class selector
+				} else if ( (m = match[3]) && support.getElementsByClassName &&
+					context.getElementsByClassName ) {
+
+					push.apply( results, context.getElementsByClassName( m ) );
+					return results;
+				}
+			}
+
+			// Take advantage of querySelectorAll
+			if ( support.qsa &&
+				!compilerCache[ selector + " " ] &&
+				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+				if ( nodeType !== 1 ) {
+					newContext = context;
+					newSelector = selector;
+
+				// qSA looks outside Element context, which is not what we want
+				// Thanks to Andrew Dupont for this workaround technique
+				// Support: IE <=8
+				// Exclude object elements
+				} else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+					// Capture the context ID, setting it first if necessary
+					if ( (nid = context.getAttribute( "id" )) ) {
+						nid = nid.replace( rcssescape, fcssescape );
+					} else {
+						context.setAttribute( "id", (nid = expando) );
+					}
+
+					// Prefix every selector in the list
+					groups = tokenize( selector );
+					i = groups.length;
+					while ( i-- ) {
+						groups[i] = "#" + nid + " " + toSelector( groups[i] );
+					}
+					newSelector = groups.join( "," );
+
+					// Expand context for sibling selectors
+					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+						context;
+				}
+
+				if ( newSelector ) {
+					try {
+						push.apply( results,
+							newContext.querySelectorAll( newSelector )
+						);
+						return results;
+					} catch ( qsaError ) {
+					} finally {
+						if ( nid === expando ) {
+							context.removeAttribute( "id" );
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// All others
+	return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *	deleting the oldest entry
+ */
+function createCache() {
+	var keys = [];
+
+	function cache( key, value ) {
+		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+		if ( keys.push( key + " " ) > Expr.cacheLength ) {
+			// Only keep the most recent entries
+			delete cache[ keys.shift() ];
+		}
+		return (cache[ key + " " ] = value);
+	}
+	return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+	fn[ expando ] = true;
+	return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created element and returns a boolean result
+ */
+function assert( fn ) {
+	var el = document.createElement("fieldset");
+
+	try {
+		return !!fn( el );
+	} catch (e) {
+		return false;
+	} finally {
+		// Remove from its parent by default
+		if ( el.parentNode ) {
+			el.parentNode.removeChild( el );
+		}
+		// release memory in IE
+		el = null;
+	}
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+	var arr = attrs.split("|"),
+		i = arr.length;
+
+	while ( i-- ) {
+		Expr.attrHandle[ arr[i] ] = handler;
+	}
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+	var cur = b && a,
+		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+			a.sourceIndex - b.sourceIndex;
+
+	// Use IE sourceIndex if available on both nodes
+	if ( diff ) {
+		return diff;
+	}
+
+	// Check if b follows a
+	if ( cur ) {
+		while ( (cur = cur.nextSibling) ) {
+			if ( cur === b ) {
+				return -1;
+			}
+		}
+	}
+
+	return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return name === "input" && elem.type === type;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return (name === "input" || name === "button") && elem.type === type;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
+
+	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+	return function( elem ) {
+
+		// Only certain elements can match :enabled or :disabled
+		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+		if ( "form" in elem ) {
+
+			// Check for inherited disabledness on relevant non-disabled elements:
+			// * listed form-associated elements in a disabled fieldset
+			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
+			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+			// * option elements in a disabled optgroup
+			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+			// All such elements have a "form" property.
+			if ( elem.parentNode && elem.disabled === false ) {
+
+				// Option elements defer to a parent optgroup if present
+				if ( "label" in elem ) {
+					if ( "label" in elem.parentNode ) {
+						return elem.parentNode.disabled === disabled;
+					} else {
+						return elem.disabled === disabled;
+					}
+				}
+
+				// Support: IE 6 - 11
+				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
+				return elem.isDisabled === disabled ||
+
+					// Where there is no isDisabled, check manually
+					/* jshint -W018 */
+					elem.isDisabled !== !disabled &&
+						disabledAncestor( elem ) === disabled;
+			}
+
+			return elem.disabled === disabled;
+
+		// Try to winnow out elements that can't be disabled before trusting the disabled property.
+		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+		// even exist on them, let alone have a boolean value.
+		} else if ( "label" in elem ) {
+			return elem.disabled === disabled;
+		}
+
+		// Remaining elements are neither :enabled nor :disabled
+		return false;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+	return markFunction(function( argument ) {
+		argument = +argument;
+		return markFunction(function( seed, matches ) {
+			var j,
+				matchIndexes = fn( [], seed.length, argument ),
+				i = matchIndexes.length;
+
+			// Match elements found at the specified indexes
+			while ( i-- ) {
+				if ( seed[ (j = matchIndexes[i]) ] ) {
+					seed[j] = !(matches[j] = seed[j]);
+				}
+			}
+		});
+	});
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+	return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833)
+	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+	var hasCompare, subWindow,
+		doc = node ? node.ownerDocument || node : preferredDoc;
+
+	// Return early if doc is invalid or already selected
+	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+		return document;
+	}
+
+	// Update global variables
+	document = doc;
+	docElem = document.documentElement;
+	documentIsHTML = !isXML( document );
+
+	// Support: IE 9-11, Edge
+	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+	if ( preferredDoc !== document &&
+		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+		// Support: IE 11, Edge
+		if ( subWindow.addEventListener ) {
+			subWindow.addEventListener( "unload", unloadHandler, false );
+
+		// Support: IE 9 - 10 only
+		} else if ( subWindow.attachEvent ) {
+			subWindow.attachEvent( "onunload", unloadHandler );
+		}
+	}
+
+	/* Attributes
+	---------------------------------------------------------------------- */
+
+	// Support: IE<8
+	// Verify that getAttribute really returns attributes and not properties
+	// (excepting IE8 booleans)
+	support.attributes = assert(function( el ) {
+		el.className = "i";
+		return !el.getAttribute("className");
+	});
+
+	/* getElement(s)By*
+	---------------------------------------------------------------------- */
+
+	// Check if getElementsByTagName("*") returns only elements
+	support.getElementsByTagName = assert(function( el ) {
+		el.appendChild( document.createComment("") );
+		return !el.getElementsByTagName("*").length;
+	});
+
+	// Support: IE<9
+	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+	// Support: IE<10
+	// Check if getElementById returns elements by name
+	// The broken getElementById methods don't pick up programmatically-set names,
+	// so use a roundabout getElementsByName test
+	support.getById = assert(function( el ) {
+		docElem.appendChild( el ).id = expando;
+		return !document.getElementsByName || !document.getElementsByName( expando ).length;
+	});
+
+	// ID filter and find
+	if ( support.getById ) {
+		Expr.filter["ID"] = function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				return elem.getAttribute("id") === attrId;
+			};
+		};
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+				var elem = context.getElementById( id );
+				return elem ? [ elem ] : [];
+			}
+		};
+	} else {
+		Expr.filter["ID"] =  function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				var node = typeof elem.getAttributeNode !== "undefined" &&
+					elem.getAttributeNode("id");
+				return node && node.value === attrId;
+			};
+		};
+
+		// Support: IE 6 - 7 only
+		// getElementById is not reliable as a find shortcut
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+				var node, i, elems,
+					elem = context.getElementById( id );
+
+				if ( elem ) {
+
+					// Verify the id attribute
+					node = elem.getAttributeNode("id");
+					if ( node && node.value === id ) {
+						return [ elem ];
+					}
+
+					// Fall back on getElementsByName
+					elems = context.getElementsByName( id );
+					i = 0;
+					while ( (elem = elems[i++]) ) {
+						node = elem.getAttributeNode("id");
+						if ( node && node.value === id ) {
+							return [ elem ];
+						}
+					}
+				}
+
+				return [];
+			}
+		};
+	}
+
+	// Tag
+	Expr.find["TAG"] = support.getElementsByTagName ?
+		function( tag, context ) {
+			if ( typeof context.getElementsByTagName !== "undefined" ) {
+				return context.getElementsByTagName( tag );
+
+			// DocumentFragment nodes don't have gEBTN
+			} else if ( support.qsa ) {
+				return context.querySelectorAll( tag );
+			}
+		} :
+
+		function( tag, context ) {
+			var elem,
+				tmp = [],
+				i = 0,
+				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+				results = context.getElementsByTagName( tag );
+
+			// Filter out possible comments
+			if ( tag === "*" ) {
+				while ( (elem = results[i++]) ) {
+					if ( elem.nodeType === 1 ) {
+						tmp.push( elem );
+					}
+				}
+
+				return tmp;
+			}
+			return results;
+		};
+
+	// Class
+	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+			return context.getElementsByClassName( className );
+		}
+	};
+
+	/* QSA/matchesSelector
+	---------------------------------------------------------------------- */
+
+	// QSA and matchesSelector support
+
+	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+	rbuggyMatches = [];
+
+	// qSa(:focus) reports false when true (Chrome 21)
+	// We allow this because of a bug in IE8/9 that throws an error
+	// whenever `document.activeElement` is accessed on an iframe
+	// So, we allow :focus to pass through QSA all the time to avoid the IE error
+	// See https://bugs.jquery.com/ticket/13378
+	rbuggyQSA = [];
+
+	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+		// Build QSA regex
+		// Regex strategy adopted from Diego Perini
+		assert(function( el ) {
+			// Select is set to empty string on purpose
+			// This is to test IE's treatment of not explicitly
+			// setting a boolean content attribute,
+			// since its presence should be enough
+			// https://bugs.jquery.com/ticket/12359
+			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
+				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
+				"<option selected=''></option></select>";
+
+			// Support: IE8, Opera 11-12.16
+			// Nothing should be selected when empty strings follow ^= or $= or *=
+			// The test attribute must be unknown in Opera but "safe" for WinRT
+			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+			}
+
+			// Support: IE8
+			// Boolean attributes and "value" are not treated correctly
+			if ( !el.querySelectorAll("[selected]").length ) {
+				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+			}
+
+			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+				rbuggyQSA.push("~=");
+			}
+
+			// Webkit/Opera - :checked should return selected option elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			// IE8 throws error here and will not see later tests
+			if ( !el.querySelectorAll(":checked").length ) {
+				rbuggyQSA.push(":checked");
+			}
+
+			// Support: Safari 8+, iOS 8+
+			// https://bugs.webkit.org/show_bug.cgi?id=136851
+			// In-page `selector#id sibling-combinator selector` fails
+			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+				rbuggyQSA.push(".#.+[+~]");
+			}
+		});
+
+		assert(function( el ) {
+			el.innerHTML = "<a href='' disabled='disabled'></a>" +
+				"<select disabled='disabled'><option/></select>";
+
+			// Support: Windows 8 Native Apps
+			// The type and name attributes are restricted during .innerHTML assignment
+			var input = document.createElement("input");
+			input.setAttribute( "type", "hidden" );
+			el.appendChild( input ).setAttribute( "name", "D" );
+
+			// Support: IE8
+			// Enforce case-sensitivity of name attribute
+			if ( el.querySelectorAll("[name=d]").length ) {
+				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+			}
+
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+			// IE8 throws error here and will not see later tests
+			if ( el.querySelectorAll(":enabled").length !== 2 ) {
+				rbuggyQSA.push( ":enabled", ":disabled" );
+			}
+
+			// Support: IE9-11+
+			// IE's :disabled selector does not pick up the children of disabled fieldsets
+			docElem.appendChild( el ).disabled = true;
+			if ( el.querySelectorAll(":disabled").length !== 2 ) {
+				rbuggyQSA.push( ":enabled", ":disabled" );
+			}
+
+			// Opera 10-11 does not throw on post-comma invalid pseudos
+			el.querySelectorAll("*,:x");
+			rbuggyQSA.push(",.*:");
+		});
+	}
+
+	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+		docElem.webkitMatchesSelector ||
+		docElem.mozMatchesSelector ||
+		docElem.oMatchesSelector ||
+		docElem.msMatchesSelector) )) ) {
+
+		assert(function( el ) {
+			// Check to see if it's possible to do matchesSelector
+			// on a disconnected node (IE 9)
+			support.disconnectedMatch = matches.call( el, "*" );
+
+			// This should fail with an exception
+			// Gecko does not error, returns false instead
+			matches.call( el, "[s!='']:x" );
+			rbuggyMatches.push( "!=", pseudos );
+		});
+	}
+
+	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+	/* Contains
+	---------------------------------------------------------------------- */
+	hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+	// Element contains another
+	// Purposefully self-exclusive
+	// As in, an element does not contain itself
+	contains = hasCompare || rnative.test( docElem.contains ) ?
+		function( a, b ) {
+			var adown = a.nodeType === 9 ? a.documentElement : a,
+				bup = b && b.parentNode;
+			return a === bup || !!( bup && bup.nodeType === 1 && (
+				adown.contains ?
+					adown.contains( bup ) :
+					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+			));
+		} :
+		function( a, b ) {
+			if ( b ) {
+				while ( (b = b.parentNode) ) {
+					if ( b === a ) {
+						return true;
+					}
+				}
+			}
+			return false;
+		};
+
+	/* Sorting
+	---------------------------------------------------------------------- */
+
+	// Document order sorting
+	sortOrder = hasCompare ?
+	function( a, b ) {
+
+		// Flag for duplicate removal
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		// Sort on method existence if only one input has compareDocumentPosition
+		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+		if ( compare ) {
+			return compare;
+		}
+
+		// Calculate position if both inputs belong to the same document
+		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+			a.compareDocumentPosition( b ) :
+
+			// Otherwise we know they are disconnected
+			1;
+
+		// Disconnected nodes
+		if ( compare & 1 ||
+			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+			// Choose the first element that is related to our preferred document
+			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+				return -1;
+			}
+			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+				return 1;
+			}
+
+			// Maintain original order
+			return sortInput ?
+				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+				0;
+		}
+
+		return compare & 4 ? -1 : 1;
+	} :
+	function( a, b ) {
+		// Exit early if the nodes are identical
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		var cur,
+			i = 0,
+			aup = a.parentNode,
+			bup = b.parentNode,
+			ap = [ a ],
+			bp = [ b ];
+
+		// Parentless nodes are either documents or disconnected
+		if ( !aup || !bup ) {
+			return a === document ? -1 :
+				b === document ? 1 :
+				aup ? -1 :
+				bup ? 1 :
+				sortInput ?
+				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+				0;
+
+		// If the nodes are siblings, we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+		}
+
+		// Otherwise we need full lists of their ancestors for comparison
+		cur = a;
+		while ( (cur = cur.parentNode) ) {
+			ap.unshift( cur );
+		}
+		cur = b;
+		while ( (cur = cur.parentNode) ) {
+			bp.unshift( cur );
+		}
+
+		// Walk down the tree looking for a discrepancy
+		while ( ap[i] === bp[i] ) {
+			i++;
+		}
+
+		return i ?
+			// Do a sibling check if the nodes have a common ancestor
+			siblingCheck( ap[i], bp[i] ) :
+
+			// Otherwise nodes in our document sort first
+			ap[i] === preferredDoc ? -1 :
+			bp[i] === preferredDoc ? 1 :
+			0;
+	};
+
+	return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+	return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	// Make sure that attribute selectors are quoted
+	expr = expr.replace( rattributeQuotes, "='$1']" );
+
+	if ( support.matchesSelector && documentIsHTML &&
+		!compilerCache[ expr + " " ] &&
+		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+		try {
+			var ret = matches.call( elem, expr );
+
+			// IE 9's matchesSelector returns false on disconnected nodes
+			if ( ret || support.disconnectedMatch ||
+					// As well, disconnected nodes are said to be in a document
+					// fragment in IE 9
+					elem.document && elem.document.nodeType !== 11 ) {
+				return ret;
+			}
+		} catch (e) {}
+	}
+
+	return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+	// Set document vars if needed
+	if ( ( context.ownerDocument || context ) !== document ) {
+		setDocument( context );
+	}
+	return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	var fn = Expr.attrHandle[ name.toLowerCase() ],
+		// Don't get fooled by Object.prototype properties (jQuery #13807)
+		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+			fn( elem, name, !documentIsHTML ) :
+			undefined;
+
+	return val !== undefined ?
+		val :
+		support.attributes || !documentIsHTML ?
+			elem.getAttribute( name ) :
+			(val = elem.getAttributeNode(name)) && val.specified ?
+				val.value :
+				null;
+};
+
+Sizzle.escape = function( sel ) {
+	return (sel + "").replace( rcssescape, fcssescape );
+};
+
+Sizzle.error = function( msg ) {
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+	var elem,
+		duplicates = [],
+		j = 0,
+		i = 0;
+
+	// Unless we *know* we can detect duplicates, assume their presence
+	hasDuplicate = !support.detectDuplicates;
+	sortInput = !support.sortStable && results.slice( 0 );
+	results.sort( sortOrder );
+
+	if ( hasDuplicate ) {
+		while ( (elem = results[i++]) ) {
+			if ( elem === results[ i ] ) {
+				j = duplicates.push( i );
+			}
+		}
+		while ( j-- ) {
+			results.splice( duplicates[ j ], 1 );
+		}
+	}
+
+	// Clear input after sorting to release objects
+	// See https://github.com/jquery/sizzle/pull/225
+	sortInput = null;
+
+	return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+	var node,
+		ret = "",
+		i = 0,
+		nodeType = elem.nodeType;
+
+	if ( !nodeType ) {
+		// If no nodeType, this is expected to be an array
+		while ( (node = elem[i++]) ) {
+			// Do not traverse comment nodes
+			ret += getText( node );
+		}
+	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+		// Use textContent for elements
+		// innerText usage removed for consistency of new lines (jQuery #11153)
+		if ( typeof elem.textContent === "string" ) {
+			return elem.textContent;
+		} else {
+			// Traverse its children
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				ret += getText( elem );
+			}
+		}
+	} else if ( nodeType === 3 || nodeType === 4 ) {
+		return elem.nodeValue;
+	}
+	// Do not include comment or processing instruction nodes
+
+	return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+	// Can be adjusted by the user
+	cacheLength: 50,
+
+	createPseudo: markFunction,
+
+	match: matchExpr,
+
+	attrHandle: {},
+
+	find: {},
+
+	relative: {
+		">": { dir: "parentNode", first: true },
+		" ": { dir: "parentNode" },
+		"+": { dir: "previousSibling", first: true },
+		"~": { dir: "previousSibling" }
+	},
+
+	preFilter: {
+		"ATTR": function( match ) {
+			match[1] = match[1].replace( runescape, funescape );
+
+			// Move the given value to match[3] whether quoted or unquoted
+			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+			if ( match[2] === "~=" ) {
+				match[3] = " " + match[3] + " ";
+			}
+
+			return match.slice( 0, 4 );
+		},
+
+		"CHILD": function( match ) {
+			/* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 what (child|of-type)
+				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				4 xn-component of xn+y argument ([+-]?\d*n|)
+				5 sign of xn-component
+				6 x of xn-component
+				7 sign of y-component
+				8 y of y-component
+			*/
+			match[1] = match[1].toLowerCase();
+
+			if ( match[1].slice( 0, 3 ) === "nth" ) {
+				// nth-* requires argument
+				if ( !match[3] ) {
+					Sizzle.error( match[0] );
+				}
+
+				// numeric x and y parameters for Expr.filter.CHILD
+				// remember that false/true cast respectively to 0/1
+				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+			// other types prohibit arguments
+			} else if ( match[3] ) {
+				Sizzle.error( match[0] );
+			}
+
+			return match;
+		},
+
+		"PSEUDO": function( match ) {
+			var excess,
+				unquoted = !match[6] && match[2];
+
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
+				return null;
+			}
+
+			// Accept quoted arguments as-is
+			if ( match[3] ) {
+				match[2] = match[4] || match[5] || "";
+
+			// Strip excess characters from unquoted arguments
+			} else if ( unquoted && rpseudo.test( unquoted ) &&
+				// Get excess from tokenize (recursively)
+				(excess = tokenize( unquoted, true )) &&
+				// advance to the next closing parenthesis
+				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+				// excess is a negative index
+				match[0] = match[0].slice( 0, excess );
+				match[2] = unquoted.slice( 0, excess );
+			}
+
+			// Return only captures needed by the pseudo filter method (type and argument)
+			return match.slice( 0, 3 );
+		}
+	},
+
+	filter: {
+
+		"TAG": function( nodeNameSelector ) {
+			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+			return nodeNameSelector === "*" ?
+				function() { return true; } :
+				function( elem ) {
+					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+				};
+		},
+
+		"CLASS": function( className ) {
+			var pattern = classCache[ className + " " ];
+
+			return pattern ||
+				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+				classCache( className, function( elem ) {
+					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+				});
+		},
+
+		"ATTR": function( name, operator, check ) {
+			return function( elem ) {
+				var result = Sizzle.attr( elem, name );
+
+				if ( result == null ) {
+					return operator === "!=";
+				}
+				if ( !operator ) {
+					return true;
+				}
+
+				result += "";
+
+				return operator === "=" ? result === check :
+					operator === "!=" ? result !== check :
+					operator === "^=" ? check && result.indexOf( check ) === 0 :
+					operator === "*=" ? check && result.indexOf( check ) > -1 :
+					operator === "$=" ? check && result.slice( -check.length ) === check :
+					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+					false;
+			};
+		},
+
+		"CHILD": function( type, what, argument, first, last ) {
+			var simple = type.slice( 0, 3 ) !== "nth",
+				forward = type.slice( -4 ) !== "last",
+				ofType = what === "of-type";
+
+			return first === 1 && last === 0 ?
+
+				// Shortcut for :nth-*(n)
+				function( elem ) {
+					return !!elem.parentNode;
+				} :
+
+				function( elem, context, xml ) {
+					var cache, uniqueCache, outerCache, node, nodeIndex, start,
+						dir = simple !== forward ? "nextSibling" : "previousSibling",
+						parent = elem.parentNode,
+						name = ofType && elem.nodeName.toLowerCase(),
+						useCache = !xml && !ofType,
+						diff = false;
+
+					if ( parent ) {
+
+						// :(first|last|only)-(child|of-type)
+						if ( simple ) {
+							while ( dir ) {
+								node = elem;
+								while ( (node = node[ dir ]) ) {
+									if ( ofType ?
+										node.nodeName.toLowerCase() === name :
+										node.nodeType === 1 ) {
+
+										return false;
+									}
+								}
+								// Reverse direction for :only-* (if we haven't yet done so)
+								start = dir = type === "only" && !start && "nextSibling";
+							}
+							return true;
+						}
+
+						start = [ forward ? parent.firstChild : parent.lastChild ];
+
+						// non-xml :nth-child(...) stores cache data on `parent`
+						if ( forward && useCache ) {
+
+							// Seek `elem` from a previously-cached index
+
+							// ...in a gzip-friendly way
+							node = parent;
+							outerCache = node[ expando ] || (node[ expando ] = {});
+
+							// Support: IE <9 only
+							// Defend against cloned attroperties (jQuery gh-1709)
+							uniqueCache = outerCache[ node.uniqueID ] ||
+								(outerCache[ node.uniqueID ] = {});
+
+							cache = uniqueCache[ type ] || [];
+							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+							diff = nodeIndex && cache[ 2 ];
+							node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+								// Fallback to seeking `elem` from the start
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								// When found, cache indexes on `parent` and break
+								if ( node.nodeType === 1 && ++diff && node === elem ) {
+									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+									break;
+								}
+							}
+
+						} else {
+							// Use previously-cached element index if available
+							if ( useCache ) {
+								// ...in a gzip-friendly way
+								node = elem;
+								outerCache = node[ expando ] || (node[ expando ] = {});
+
+								// Support: IE <9 only
+								// Defend against cloned attroperties (jQuery gh-1709)
+								uniqueCache = outerCache[ node.uniqueID ] ||
+									(outerCache[ node.uniqueID ] = {});
+
+								cache = uniqueCache[ type ] || [];
+								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+								diff = nodeIndex;
+							}
+
+							// xml :nth-child(...)
+							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
+							if ( diff === false ) {
+								// Use the same loop as above to seek `elem` from the start
+								while ( (node = ++nodeIndex && node && node[ dir ] ||
+									(diff = nodeIndex = 0) || start.pop()) ) {
+
+									if ( ( ofType ?
+										node.nodeName.toLowerCase() === name :
+										node.nodeType === 1 ) &&
+										++diff ) {
+
+										// Cache the index of each encountered element
+										if ( useCache ) {
+											outerCache = node[ expando ] || (node[ expando ] = {});
+
+											// Support: IE <9 only
+											// Defend against cloned attroperties (jQuery gh-1709)
+											uniqueCache = outerCache[ node.uniqueID ] ||
+												(outerCache[ node.uniqueID ] = {});
+
+											uniqueCache[ type ] = [ dirruns, diff ];
+										}
+
+										if ( node === elem ) {
+											break;
+										}
+									}
+								}
+							}
+						}
+
+						// Incorporate the offset, then check against cycle size
+						diff -= last;
+						return diff === first || ( diff % first === 0 && diff / first >= 0 );
+					}
+				};
+		},
+
+		"PSEUDO": function( pseudo, argument ) {
+			// pseudo-class names are case-insensitive
+			// http://www.w3.org/TR/selectors/#pseudo-classes
+			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+			// Remember that setFilters inherits from pseudos
+			var args,
+				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+					Sizzle.error( "unsupported pseudo: " + pseudo );
+
+			// The user may use createPseudo to indicate that
+			// arguments are needed to create the filter function
+			// just as Sizzle does
+			if ( fn[ expando ] ) {
+				return fn( argument );
+			}
+
+			// But maintain support for old signatures
+			if ( fn.length > 1 ) {
+				args = [ pseudo, pseudo, "", argument ];
+				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+					markFunction(function( seed, matches ) {
+						var idx,
+							matched = fn( seed, argument ),
+							i = matched.length;
+						while ( i-- ) {
+							idx = indexOf( seed, matched[i] );
+							seed[ idx ] = !( matches[ idx ] = matched[i] );
+						}
+					}) :
+					function( elem ) {
+						return fn( elem, 0, args );
+					};
+			}
+
+			return fn;
+		}
+	},
+
+	pseudos: {
+		// Potentially complex pseudos
+		"not": markFunction(function( selector ) {
+			// Trim the selector passed to compile
+			// to avoid treating leading and trailing
+			// spaces as combinators
+			var input = [],
+				results = [],
+				matcher = compile( selector.replace( rtrim, "$1" ) );
+
+			return matcher[ expando ] ?
+				markFunction(function( seed, matches, context, xml ) {
+					var elem,
+						unmatched = matcher( seed, null, xml, [] ),
+						i = seed.length;
+
+					// Match elements unmatched by `matcher`
+					while ( i-- ) {
+						if ( (elem = unmatched[i]) ) {
+							seed[i] = !(matches[i] = elem);
+						}
+					}
+				}) :
+				function( elem, context, xml ) {
+					input[0] = elem;
+					matcher( input, null, xml, results );
+					// Don't keep the element (issue #299)
+					input[0] = null;
+					return !results.pop();
+				};
+		}),
+
+		"has": markFunction(function( selector ) {
+			return function( elem ) {
+				return Sizzle( selector, elem ).length > 0;
+			};
+		}),
+
+		"contains": markFunction(function( text ) {
+			text = text.replace( runescape, funescape );
+			return function( elem ) {
+				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+			};
+		}),
+
+		// "Whether an element is represented by a :lang() selector
+		// is based solely on the element's language value
+		// being equal to the identifier C,
+		// or beginning with the identifier C immediately followed by "-".
+		// The matching of C against the element's language value is performed case-insensitively.
+		// The identifier C does not have to be a valid language name."
+		// http://www.w3.org/TR/selectors/#lang-pseudo
+		"lang": markFunction( function( lang ) {
+			// lang value must be a valid identifier
+			if ( !ridentifier.test(lang || "") ) {
+				Sizzle.error( "unsupported lang: " + lang );
+			}
+			lang = lang.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				var elemLang;
+				do {
+					if ( (elemLang = documentIsHTML ?
+						elem.lang :
+						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+						elemLang = elemLang.toLowerCase();
+						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+					}
+				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+				return false;
+			};
+		}),
+
+		// Miscellaneous
+		"target": function( elem ) {
+			var hash = window.location && window.location.hash;
+			return hash && hash.slice( 1 ) === elem.id;
+		},
+
+		"root": function( elem ) {
+			return elem === docElem;
+		},
+
+		"focus": function( elem ) {
+			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+		},
+
+		// Boolean properties
+		"enabled": createDisabledPseudo( false ),
+		"disabled": createDisabledPseudo( true ),
+
+		"checked": function( elem ) {
+			// In CSS3, :checked should return both checked and selected elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			var nodeName = elem.nodeName.toLowerCase();
+			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+		},
+
+		"selected": function( elem ) {
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			if ( elem.parentNode ) {
+				elem.parentNode.selectedIndex;
+			}
+
+			return elem.selected === true;
+		},
+
+		// Contents
+		"empty": function( elem ) {
+			// http://www.w3.org/TR/selectors/#empty-pseudo
+			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+			//   but not by others (comment: 8; processing instruction: 7; etc.)
+			// nodeType < 6 works because attributes (2) do not appear as children
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				if ( elem.nodeType < 6 ) {
+					return false;
+				}
+			}
+			return true;
+		},
+
+		"parent": function( elem ) {
+			return !Expr.pseudos["empty"]( elem );
+		},
+
+		// Element/input types
+		"header": function( elem ) {
+			return rheader.test( elem.nodeName );
+		},
+
+		"input": function( elem ) {
+			return rinputs.test( elem.nodeName );
+		},
+
+		"button": function( elem ) {
+			var name = elem.nodeName.toLowerCase();
+			return name === "input" && elem.type === "button" || name === "button";
+		},
+
+		"text": function( elem ) {
+			var attr;
+			return elem.nodeName.toLowerCase() === "input" &&
+				elem.type === "text" &&
+
+				// Support: IE<8
+				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+		},
+
+		// Position-in-collection
+		"first": createPositionalPseudo(function() {
+			return [ 0 ];
+		}),
+
+		"last": createPositionalPseudo(function( matchIndexes, length ) {
+			return [ length - 1 ];
+		}),
+
+		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			return [ argument < 0 ? argument + length : argument ];
+		}),
+
+		"even": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 0;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 1;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; --i >= 0; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; ++i < length; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		})
+	}
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+	Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+	Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+	var matched, match, tokens, type,
+		soFar, groups, preFilters,
+		cached = tokenCache[ selector + " " ];
+
+	if ( cached ) {
+		return parseOnly ? 0 : cached.slice( 0 );
+	}
+
+	soFar = selector;
+	groups = [];
+	preFilters = Expr.preFilter;
+
+	while ( soFar ) {
+
+		// Comma and first run
+		if ( !matched || (match = rcomma.exec( soFar )) ) {
+			if ( match ) {
+				// Don't consume trailing commas as valid
+				soFar = soFar.slice( match[0].length ) || soFar;
+			}
+			groups.push( (tokens = []) );
+		}
+
+		matched = false;
+
+		// Combinators
+		if ( (match = rcombinators.exec( soFar )) ) {
+			matched = match.shift();
+			tokens.push({
+				value: matched,
+				// Cast descendant combinators to space
+				type: match[0].replace( rtrim, " " )
+			});
+			soFar = soFar.slice( matched.length );
+		}
+
+		// Filters
+		for ( type in Expr.filter ) {
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+				(match = preFilters[ type ]( match ))) ) {
+				matched = match.shift();
+				tokens.push({
+					value: matched,
+					type: type,
+					matches: match
+				});
+				soFar = soFar.slice( matched.length );
+			}
+		}
+
+		if ( !matched ) {
+			break;
+		}
+	}
+
+	// Return the length of the invalid excess
+	// if we're just parsing
+	// Otherwise, throw an error or return tokens
+	return parseOnly ?
+		soFar.length :
+		soFar ?
+			Sizzle.error( selector ) :
+			// Cache the tokens
+			tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+	var i = 0,
+		len = tokens.length,
+		selector = "";
+	for ( ; i < len; i++ ) {
+		selector += tokens[i].value;
+	}
+	return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+	var dir = combinator.dir,
+		skip = combinator.next,
+		key = skip || dir,
+		checkNonElements = base && key === "parentNode",
+		doneName = done++;
+
+	return combinator.first ?
+		// Check against closest ancestor/preceding element
+		function( elem, context, xml ) {
+			while ( (elem = elem[ dir ]) ) {
+				if ( elem.nodeType === 1 || checkNonElements ) {
+					return matcher( elem, context, xml );
+				}
+			}
+			return false;
+		} :
+
+		// Check against all ancestor/preceding elements
+		function( elem, context, xml ) {
+			var oldCache, uniqueCache, outerCache,
+				newCache = [ dirruns, doneName ];
+
+			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+			if ( xml ) {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						if ( matcher( elem, context, xml ) ) {
+							return true;
+						}
+					}
+				}
+			} else {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+						// Support: IE <9 only
+						// Defend against cloned attroperties (jQuery gh-1709)
+						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+						if ( skip && skip === elem.nodeName.toLowerCase() ) {
+							elem = elem[ dir ] || elem;
+						} else if ( (oldCache = uniqueCache[ key ]) &&
+							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+							// Assign to newCache so results back-propagate to previous elements
+							return (newCache[ 2 ] = oldCache[ 2 ]);
+						} else {
+							// Reuse newcache so results back-propagate to previous elements
+							uniqueCache[ key ] = newCache;
+
+							// A match means we're done; a fail means we have to keep checking
+							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+								return true;
+							}
+						}
+					}
+				}
+			}
+			return false;
+		};
+}
+
+function elementMatcher( matchers ) {
+	return matchers.length > 1 ?
+		function( elem, context, xml ) {
+			var i = matchers.length;
+			while ( i-- ) {
+				if ( !matchers[i]( elem, context, xml ) ) {
+					return false;
+				}
+			}
+			return true;
+		} :
+		matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+	var i = 0,
+		len = contexts.length;
+	for ( ; i < len; i++ ) {
+		Sizzle( selector, contexts[i], results );
+	}
+	return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+	var elem,
+		newUnmatched = [],
+		i = 0,
+		len = unmatched.length,
+		mapped = map != null;
+
+	for ( ; i < len; i++ ) {
+		if ( (elem = unmatched[i]) ) {
+			if ( !filter || filter( elem, context, xml ) ) {
+				newUnmatched.push( elem );
+				if ( mapped ) {
+					map.push( i );
+				}
+			}
+		}
+	}
+
+	return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+	if ( postFilter && !postFilter[ expando ] ) {
+		postFilter = setMatcher( postFilter );
+	}
+	if ( postFinder && !postFinder[ expando ] ) {
+		postFinder = setMatcher( postFinder, postSelector );
+	}
+	return markFunction(function( seed, results, context, xml ) {
+		var temp, i, elem,
+			preMap = [],
+			postMap = [],
+			preexisting = results.length,
+
+			// Get initial elements from seed or context
+			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+			// Prefilter to get matcher input, preserving a map for seed-results synchronization
+			matcherIn = preFilter && ( seed || !selector ) ?
+				condense( elems, preMap, preFilter, context, xml ) :
+				elems,
+
+			matcherOut = matcher ?
+				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+					// ...intermediate processing is necessary
+					[] :
+
+					// ...otherwise use results directly
+					results :
+				matcherIn;
+
+		// Find primary matches
+		if ( matcher ) {
+			matcher( matcherIn, matcherOut, context, xml );
+		}
+
+		// Apply postFilter
+		if ( postFilter ) {
+			temp = condense( matcherOut, postMap );
+			postFilter( temp, [], context, xml );
+
+			// Un-match failing elements by moving them back to matcherIn
+			i = temp.length;
+			while ( i-- ) {
+				if ( (elem = temp[i]) ) {
+					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+				}
+			}
+		}
+
+		if ( seed ) {
+			if ( postFinder || preFilter ) {
+				if ( postFinder ) {
+					// Get the final matcherOut by condensing this intermediate into postFinder contexts
+					temp = [];
+					i = matcherOut.length;
+					while ( i-- ) {
+						if ( (elem = matcherOut[i]) ) {
+							// Restore matcherIn since elem is not yet a final match
+							temp.push( (matcherIn[i] = elem) );
+						}
+					}
+					postFinder( null, (matcherOut = []), temp, xml );
+				}
+
+				// Move matched elements from seed to results to keep them synchronized
+				i = matcherOut.length;
+				while ( i-- ) {
+					if ( (elem = matcherOut[i]) &&
+						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+						seed[temp] = !(results[temp] = elem);
+					}
+				}
+			}
+
+		// Add elements to results, through postFinder if defined
+		} else {
+			matcherOut = condense(
+				matcherOut === results ?
+					matcherOut.splice( preexisting, matcherOut.length ) :
+					matcherOut
+			);
+			if ( postFinder ) {
+				postFinder( null, results, matcherOut, xml );
+			} else {
+				push.apply( results, matcherOut );
+			}
+		}
+	});
+}
+
+function matcherFromTokens( tokens ) {
+	var checkContext, matcher, j,
+		len = tokens.length,
+		leadingRelative = Expr.relative[ tokens[0].type ],
+		implicitRelative = leadingRelative || Expr.relative[" "],
+		i = leadingRelative ? 1 : 0,
+
+		// The foundational matcher ensures that elements are reachable from top-level context(s)
+		matchContext = addCombinator( function( elem ) {
+			return elem === checkContext;
+		}, implicitRelative, true ),
+		matchAnyContext = addCombinator( function( elem ) {
+			return indexOf( checkContext, elem ) > -1;
+		}, implicitRelative, true ),
+		matchers = [ function( elem, context, xml ) {
+			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+				(checkContext = context).nodeType ?
+					matchContext( elem, context, xml ) :
+					matchAnyContext( elem, context, xml ) );
+			// Avoid hanging onto element (issue #299)
+			checkContext = null;
+			return ret;
+		} ];
+
+	for ( ; i < len; i++ ) {
+		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+		} else {
+			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+			// Return special upon seeing a positional matcher
+			if ( matcher[ expando ] ) {
+				// Find the next relative operator (if any) for proper handling
+				j = ++i;
+				for ( ; j < len; j++ ) {
+					if ( Expr.relative[ tokens[j].type ] ) {
+						break;
+					}
+				}
+				return setMatcher(
+					i > 1 && elementMatcher( matchers ),
+					i > 1 && toSelector(
+						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
+						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+					).replace( rtrim, "$1" ),
+					matcher,
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+					j < len && toSelector( tokens )
+				);
+			}
+			matchers.push( matcher );
+		}
+	}
+
+	return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+	var bySet = setMatchers.length > 0,
+		byElement = elementMatchers.length > 0,
+		superMatcher = function( seed, context, xml, results, outermost ) {
+			var elem, j, matcher,
+				matchedCount = 0,
+				i = "0",
+				unmatched = seed && [],
+				setMatched = [],
+				contextBackup = outermostContext,
+				// We must always have either seed elements or outermost context
+				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+				// Use integer dirruns iff this is the outermost matcher
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+				len = elems.length;
+
+			if ( outermost ) {
+				outermostContext = context === document || context || outermost;
+			}
+
+			// Add elements passing elementMatchers directly to results
+			// Support: IE<9, Safari
+			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
+			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+				if ( byElement && elem ) {
+					j = 0;
+					if ( !context && elem.ownerDocument !== document ) {
+						setDocument( elem );
+						xml = !documentIsHTML;
+					}
+					while ( (matcher = elementMatchers[j++]) ) {
+						if ( matcher( elem, context || document, xml) ) {
+							results.push( elem );
+							break;
+						}
+					}
+					if ( outermost ) {
+						dirruns = dirrunsUnique;
+					}
+				}
+
+				// Track unmatched elements for set filters
+				if ( bySet ) {
+					// They will have gone through all possible matchers
+					if ( (elem = !matcher && elem) ) {
+						matchedCount--;
+					}
+
+					// Lengthen the array for every element, matched or not
+					if ( seed ) {
+						unmatched.push( elem );
+					}
+				}
+			}
+
+			// `i` is now the count of elements visited above, and adding it to `matchedCount`
+			// makes the latter nonnegative.
+			matchedCount += i;
+
+			// Apply set filters to unmatched elements
+			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+			// no element matchers and no seed.
+			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
+			// numerically zero.
+			if ( bySet && i !== matchedCount ) {
+				j = 0;
+				while ( (matcher = setMatchers[j++]) ) {
+					matcher( unmatched, setMatched, context, xml );
+				}
+
+				if ( seed ) {
+					// Reintegrate element matches to eliminate the need for sorting
+					if ( matchedCount > 0 ) {
+						while ( i-- ) {
+							if ( !(unmatched[i] || setMatched[i]) ) {
+								setMatched[i] = pop.call( results );
+							}
+						}
+					}
+
+					// Discard index placeholder values to get only actual matches
+					setMatched = condense( setMatched );
+				}
+
+				// Add matches to results
+				push.apply( results, setMatched );
+
+				// Seedless set matches succeeding multiple successful matchers stipulate sorting
+				if ( outermost && !seed && setMatched.length > 0 &&
+					( matchedCount + setMatchers.length ) > 1 ) {
+
+					Sizzle.uniqueSort( results );
+				}
+			}
+
+			// Override manipulation of globals by nested matchers
+			if ( outermost ) {
+				dirruns = dirrunsUnique;
+				outermostContext = contextBackup;
+			}
+
+			return unmatched;
+		};
+
+	return bySet ?
+		markFunction( superMatcher ) :
+		superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+	var i,
+		setMatchers = [],
+		elementMatchers = [],
+		cached = compilerCache[ selector + " " ];
+
+	if ( !cached ) {
+		// Generate a function of recursive functions that can be used to check each element
+		if ( !match ) {
+			match = tokenize( selector );
+		}
+		i = match.length;
+		while ( i-- ) {
+			cached = matcherFromTokens( match[i] );
+			if ( cached[ expando ] ) {
+				setMatchers.push( cached );
+			} else {
+				elementMatchers.push( cached );
+			}
+		}
+
+		// Cache the compiled function
+		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+		// Save selector and tokenization
+		cached.selector = selector;
+	}
+	return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ *  selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ *  selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+	var i, tokens, token, type, find,
+		compiled = typeof selector === "function" && selector,
+		match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+	results = results || [];
+
+	// Try to minimize operations if there is only one selector in the list and no seed
+	// (the latter of which guarantees us context)
+	if ( match.length === 1 ) {
+
+		// Reduce context if the leading compound selector is an ID
+		tokens = match[0] = match[0].slice( 0 );
+		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
+
+			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+			if ( !context ) {
+				return results;
+
+			// Precompiled matchers will still verify ancestry, so step up a level
+			} else if ( compiled ) {
+				context = context.parentNode;
+			}
+
+			selector = selector.slice( tokens.shift().value.length );
+		}
+
+		// Fetch a seed set for right-to-left matching
+		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+		while ( i-- ) {
+			token = tokens[i];
+
+			// Abort if we hit a combinator
+			if ( Expr.relative[ (type = token.type) ] ) {
+				break;
+			}
+			if ( (find = Expr.find[ type ]) ) {
+				// Search, expanding context for leading sibling combinators
+				if ( (seed = find(
+					token.matches[0].replace( runescape, funescape ),
+					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+				)) ) {
+
+					// If seed is empty or no tokens remain, we can return early
+					tokens.splice( i, 1 );
+					selector = seed.length && toSelector( tokens );
+					if ( !selector ) {
+						push.apply( results, seed );
+						return results;
+					}
+
+					break;
+				}
+			}
+		}
+	}
+
+	// Compile and execute a filtering function if one is not provided
+	// Provide `match` to avoid retokenization if we modified the selector above
+	( compiled || compile( selector, match ) )(
+		seed,
+		context,
+		!documentIsHTML,
+		results,
+		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+	);
+	return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( el ) {
+	// Should return 1, but returns 4 (following)
+	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( el ) {
+	el.innerHTML = "<a href='#'></a>";
+	return el.firstChild.getAttribute("href") === "#" ;
+}) ) {
+	addHandle( "type|href|height|width", function( elem, name, isXML ) {
+		if ( !isXML ) {
+			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+		}
+	});
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( el ) {
+	el.innerHTML = "<input/>";
+	el.firstChild.setAttribute( "value", "" );
+	return el.firstChild.getAttribute( "value" ) === "";
+}) ) {
+	addHandle( "value", function( elem, name, isXML ) {
+		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+			return elem.defaultValue;
+		}
+	});
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( el ) {
+	return el.getAttribute("disabled") == null;
+}) ) {
+	addHandle( booleans, function( elem, name, isXML ) {
+		var val;
+		if ( !isXML ) {
+			return elem[ name ] === true ? name.toLowerCase() :
+					(val = elem.getAttributeNode( name )) && val.specified ?
+					val.value :
+				null;
+		}
+	});
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+
+// Deprecated
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+var dir = function( elem, dir, until ) {
+	var matched = [],
+		truncate = until !== undefined;
+
+	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+		if ( elem.nodeType === 1 ) {
+			if ( truncate && jQuery( elem ).is( until ) ) {
+				break;
+			}
+			matched.push( elem );
+		}
+	}
+	return matched;
+};
+
+
+var siblings = function( n, elem ) {
+	var matched = [];
+
+	for ( ; n; n = n.nextSibling ) {
+		if ( n.nodeType === 1 && n !== elem ) {
+			matched.push( n );
+		}
+	}
+
+	return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+function nodeName( elem, name ) {
+
+  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+};
+var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+	if ( isFunction( qualifier ) ) {
+		return jQuery.grep( elements, function( elem, i ) {
+			return !!qualifier.call( elem, i, elem ) !== not;
+		} );
+	}
+
+	// Single element
+	if ( qualifier.nodeType ) {
+		return jQuery.grep( elements, function( elem ) {
+			return ( elem === qualifier ) !== not;
+		} );
+	}
+
+	// Arraylike of elements (jQuery, arguments, Array)
+	if ( typeof qualifier !== "string" ) {
+		return jQuery.grep( elements, function( elem ) {
+			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+		} );
+	}
+
+	// Filtered directly for both simple and complex selectors
+	return jQuery.filter( qualifier, elements, not );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+	var elem = elems[ 0 ];
+
+	if ( not ) {
+		expr = ":not(" + expr + ")";
+	}
+
+	if ( elems.length === 1 && elem.nodeType === 1 ) {
+		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+	}
+
+	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+		return elem.nodeType === 1;
+	} ) );
+};
+
+jQuery.fn.extend( {
+	find: function( selector ) {
+		var i, ret,
+			len = this.length,
+			self = this;
+
+		if ( typeof selector !== "string" ) {
+			return this.pushStack( jQuery( selector ).filter( function() {
+				for ( i = 0; i < len; i++ ) {
+					if ( jQuery.contains( self[ i ], this ) ) {
+						return true;
+					}
+				}
+			} ) );
+		}
+
+		ret = this.pushStack( [] );
+
+		for ( i = 0; i < len; i++ ) {
+			jQuery.find( selector, self[ i ], ret );
+		}
+
+		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+	},
+	filter: function( selector ) {
+		return this.pushStack( winnow( this, selector || [], false ) );
+	},
+	not: function( selector ) {
+		return this.pushStack( winnow( this, selector || [], true ) );
+	},
+	is: function( selector ) {
+		return !!winnow(
+			this,
+
+			// If this is a positional/relative selector, check membership in the returned set
+			// so $("p:first").is("p:last") won't return true for a doc with two "p".
+			typeof selector === "string" && rneedsContext.test( selector ) ?
+				jQuery( selector ) :
+				selector || [],
+			false
+		).length;
+	}
+} );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+	// A simple way to check for HTML strings
+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+	// Strict HTML recognition (#11290: must start with <)
+	// Shortcut simple #id case for speed
+	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+	init = jQuery.fn.init = function( selector, context, root ) {
+		var match, elem;
+
+		// HANDLE: $(""), $(null), $(undefined), $(false)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Method init() accepts an alternate rootjQuery
+		// so migrate can support jQuery.sub (gh-2101)
+		root = root || rootjQuery;
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			if ( selector[ 0 ] === "<" &&
+				selector[ selector.length - 1 ] === ">" &&
+				selector.length >= 3 ) {
+
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = rquickExpr.exec( selector );
+			}
+
+			// Match html or make sure no context is specified for #id
+			if ( match && ( match[ 1 ] || !context ) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[ 1 ] ) {
+					context = context instanceof jQuery ? context[ 0 ] : context;
+
+					// Option to run scripts is true for back-compat
+					// Intentionally let the error be thrown if parseHTML is not present
+					jQuery.merge( this, jQuery.parseHTML(
+						match[ 1 ],
+						context && context.nodeType ? context.ownerDocument || context : document,
+						true
+					) );
+
+					// HANDLE: $(html, props)
+					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+						for ( match in context ) {
+
+							// Properties of context are called as methods if possible
+							if ( isFunction( this[ match ] ) ) {
+								this[ match ]( context[ match ] );
+
+							// ...and otherwise set as attributes
+							} else {
+								this.attr( match, context[ match ] );
+							}
+						}
+					}
+
+					return this;
+
+				// HANDLE: $(#id)
+				} else {
+					elem = document.getElementById( match[ 2 ] );
+
+					if ( elem ) {
+
+						// Inject the element directly into the jQuery object
+						this[ 0 ] = elem;
+						this.length = 1;
+					}
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return ( context || root ).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(DOMElement)
+		} else if ( selector.nodeType ) {
+			this[ 0 ] = selector;
+			this.length = 1;
+			return this;
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( isFunction( selector ) ) {
+			return root.ready !== undefined ?
+				root.ready( selector ) :
+
+				// Execute immediately if ready is not present
+				selector( jQuery );
+		}
+
+		return jQuery.makeArray( selector, this );
+	};
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+	// Methods guaranteed to produce a unique set when starting from a unique set
+	guaranteedUnique = {
+		children: true,
+		contents: true,
+		next: true,
+		prev: true
+	};
+
+jQuery.fn.extend( {
+	has: function( target ) {
+		var targets = jQuery( target, this ),
+			l = targets.length;
+
+		return this.filter( function() {
+			var i = 0;
+			for ( ; i < l; i++ ) {
+				if ( jQuery.contains( this, targets[ i ] ) ) {
+					return true;
+				}
+			}
+		} );
+	},
+
+	closest: function( selectors, context ) {
+		var cur,
+			i = 0,
+			l = this.length,
+			matched = [],
+			targets = typeof selectors !== "string" && jQuery( selectors );
+
+		// Positional selectors never match, since there's no _selection_ context
+		if ( !rneedsContext.test( selectors ) ) {
+			for ( ; i < l; i++ ) {
+				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+					// Always skip document fragments
+					if ( cur.nodeType < 11 && ( targets ?
+						targets.index( cur ) > -1 :
+
+						// Don't pass non-elements to Sizzle
+						cur.nodeType === 1 &&
+							jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+						matched.push( cur );
+						break;
+					}
+				}
+			}
+		}
+
+		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+	},
+
+	// Determine the position of an element within the set
+	index: function( elem ) {
+
+		// No argument, return index in parent
+		if ( !elem ) {
+			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+		}
+
+		// Index in selector
+		if ( typeof elem === "string" ) {
+			return indexOf.call( jQuery( elem ), this[ 0 ] );
+		}
+
+		// Locate the position of the desired element
+		return indexOf.call( this,
+
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[ 0 ] : elem
+		);
+	},
+
+	add: function( selector, context ) {
+		return this.pushStack(
+			jQuery.uniqueSort(
+				jQuery.merge( this.get(), jQuery( selector, context ) )
+			)
+		);
+	},
+
+	addBack: function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter( selector )
+		);
+	}
+} );
+
+function sibling( cur, dir ) {
+	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+	return cur;
+}
+
+jQuery.each( {
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return sibling( elem, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return sibling( elem, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return siblings( ( elem.parentNode || {} ).firstChild, elem );
+	},
+	children: function( elem ) {
+		return siblings( elem.firstChild );
+	},
+	contents: function( elem ) {
+        if ( nodeName( elem, "iframe" ) ) {
+            return elem.contentDocument;
+        }
+
+        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+        // Treat the template element as a regular one in browsers that
+        // don't support it.
+        if ( nodeName( elem, "template" ) ) {
+            elem = elem.content || elem;
+        }
+
+        return jQuery.merge( [], elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var matched = jQuery.map( this, fn, until );
+
+		if ( name.slice( -5 ) !== "Until" ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			matched = jQuery.filter( selector, matched );
+		}
+
+		if ( this.length > 1 ) {
+
+			// Remove duplicates
+			if ( !guaranteedUnique[ name ] ) {
+				jQuery.uniqueSort( matched );
+			}
+
+			// Reverse order for parents* and prev-derivatives
+			if ( rparentsprev.test( name ) ) {
+				matched.reverse();
+			}
+		}
+
+		return this.pushStack( matched );
+	};
+} );
+var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+	var object = {};
+	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
+		object[ flag ] = true;
+	} );
+	return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *	options: an optional list of space-separated options that will change how
+ *			the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *	memory:			will keep track of previous values and will call any callback added
+ *					after the list has been fired right away with the latest "memorized"
+ *					values (like a Deferred)
+ *
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *	stopOnFalse:	interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+	// Convert options from String-formatted to Object-formatted if needed
+	// (we check in cache first)
+	options = typeof options === "string" ?
+		createOptions( options ) :
+		jQuery.extend( {}, options );
+
+	var // Flag to know if list is currently firing
+		firing,
+
+		// Last fire value for non-forgettable lists
+		memory,
+
+		// Flag to know if list was already fired
+		fired,
+
+		// Flag to prevent firing
+		locked,
+
+		// Actual callback list
+		list = [],
+
+		// Queue of execution data for repeatable lists
+		queue = [],
+
+		// Index of currently firing callback (modified by add/remove as needed)
+		firingIndex = -1,
+
+		// Fire callbacks
+		fire = function() {
+
+			// Enforce single-firing
+			locked = locked || options.once;
+
+			// Execute callbacks for all pending executions,
+			// respecting firingIndex overrides and runtime changes
+			fired = firing = true;
+			for ( ; queue.length; firingIndex = -1 ) {
+				memory = queue.shift();
+				while ( ++firingIndex < list.length ) {
+
+					// Run callback and check for early termination
+					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+						options.stopOnFalse ) {
+
+						// Jump to end and forget the data so .add doesn't re-fire
+						firingIndex = list.length;
+						memory = false;
+					}
+				}
+			}
+
+			// Forget the data if we're done with it
+			if ( !options.memory ) {
+				memory = false;
+			}
+
+			firing = false;
+
+			// Clean up if we're done firing for good
+			if ( locked ) {
+
+				// Keep an empty list if we have data for future add calls
+				if ( memory ) {
+					list = [];
+
+				// Otherwise, this object is spent
+				} else {
+					list = "";
+				}
+			}
+		},
+
+		// Actual Callbacks object
+		self = {
+
+			// Add a callback or a collection of callbacks to the list
+			add: function() {
+				if ( list ) {
+
+					// If we have memory from a past run, we should fire after adding
+					if ( memory && !firing ) {
+						firingIndex = list.length - 1;
+						queue.push( memory );
+					}
+
+					( function add( args ) {
+						jQuery.each( args, function( _, arg ) {
+							if ( isFunction( arg ) ) {
+								if ( !options.unique || !self.has( arg ) ) {
+									list.push( arg );
+								}
+							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
+
+								// Inspect recursively
+								add( arg );
+							}
+						} );
+					} )( arguments );
+
+					if ( memory && !firing ) {
+						fire();
+					}
+				}
+				return this;
+			},
+
+			// Remove a callback from the list
+			remove: function() {
+				jQuery.each( arguments, function( _, arg ) {
+					var index;
+					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+						list.splice( index, 1 );
+
+						// Handle firing indexes
+						if ( index <= firingIndex ) {
+							firingIndex--;
+						}
+					}
+				} );
+				return this;
+			},
+
+			// Check if a given callback is in the list.
+			// If no argument is given, return whether or not list has callbacks attached.
+			has: function( fn ) {
+				return fn ?
+					jQuery.inArray( fn, list ) > -1 :
+					list.length > 0;
+			},
+
+			// Remove all callbacks from the list
+			empty: function() {
+				if ( list ) {
+					list = [];
+				}
+				return this;
+			},
+
+			// Disable .fire and .add
+			// Abort any current/pending executions
+			// Clear all callbacks and values
+			disable: function() {
+				locked = queue = [];
+				list = memory = "";
+				return this;
+			},
+			disabled: function() {
+				return !list;
+			},
+
+			// Disable .fire
+			// Also disable .add unless we have memory (since it would have no effect)
+			// Abort any pending executions
+			lock: function() {
+				locked = queue = [];
+				if ( !memory && !firing ) {
+					list = memory = "";
+				}
+				return this;
+			},
+			locked: function() {
+				return !!locked;
+			},
+
+			// Call all callbacks with the given context and arguments
+			fireWith: function( context, args ) {
+				if ( !locked ) {
+					args = args || [];
+					args = [ context, args.slice ? args.slice() : args ];
+					queue.push( args );
+					if ( !firing ) {
+						fire();
+					}
+				}
+				return this;
+			},
+
+			// Call all the callbacks with the given arguments
+			fire: function() {
+				self.fireWith( this, arguments );
+				return this;
+			},
+
+			// To know if the callbacks have already been called at least once
+			fired: function() {
+				return !!fired;
+			}
+		};
+
+	return self;
+};
+
+
+function Identity( v ) {
+	return v;
+}
+function Thrower( ex ) {
+	throw ex;
+}
+
+function adoptValue( value, resolve, reject, noValue ) {
+	var method;
+
+	try {
+
+		// Check for promise aspect first to privilege synchronous behavior
+		if ( value && isFunction( ( method = value.promise ) ) ) {
+			method.call( value ).done( resolve ).fail( reject );
+
+		// Other thenables
+		} else if ( value && isFunction( ( method = value.then ) ) ) {
+			method.call( value, resolve, reject );
+
+		// Other non-thenables
+		} else {
+
+			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+			// * false: [ value ].slice( 0 ) => resolve( value )
+			// * true: [ value ].slice( 1 ) => resolve()
+			resolve.apply( undefined, [ value ].slice( noValue ) );
+		}
+
+	// For Promises/A+, convert exceptions into rejections
+	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+	// Deferred#then to conditionally suppress rejection.
+	} catch ( value ) {
+
+		// Support: Android 4.0 only
+		// Strict mode functions invoked without .call/.apply get global-object context
+		reject.apply( undefined, [ value ] );
+	}
+}
+
+jQuery.extend( {
+
+	Deferred: function( func ) {
+		var tuples = [
+
+				// action, add listener, callbacks,
+				// ... .then handlers, argument index, [final state]
+				[ "notify", "progress", jQuery.Callbacks( "memory" ),
+					jQuery.Callbacks( "memory" ), 2 ],
+				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
+					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
+					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
+			],
+			state = "pending",
+			promise = {
+				state: function() {
+					return state;
+				},
+				always: function() {
+					deferred.done( arguments ).fail( arguments );
+					return this;
+				},
+				"catch": function( fn ) {
+					return promise.then( null, fn );
+				},
+
+				// Keep pipe for back-compat
+				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
+					var fns = arguments;
+
+					return jQuery.Deferred( function( newDefer ) {
+						jQuery.each( tuples, function( i, tuple ) {
+
+							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
+							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
+
+							// deferred.progress(function() { bind to newDefer or newDefer.notify })
+							// deferred.done(function() { bind to newDefer or newDefer.resolve })
+							// deferred.fail(function() { bind to newDefer or newDefer.reject })
+							deferred[ tuple[ 1 ] ]( function() {
+								var returned = fn && fn.apply( this, arguments );
+								if ( returned && isFunction( returned.promise ) ) {
+									returned.promise()
+										.progress( newDefer.notify )
+										.done( newDefer.resolve )
+										.fail( newDefer.reject );
+								} else {
+									newDefer[ tuple[ 0 ] + "With" ](
+										this,
+										fn ? [ returned ] : arguments
+									);
+								}
+							} );
+						} );
+						fns = null;
+					} ).promise();
+				},
+				then: function( onFulfilled, onRejected, onProgress ) {
+					var maxDepth = 0;
+					function resolve( depth, deferred, handler, special ) {
+						return function() {
+							var that = this,
+								args = arguments,
+								mightThrow = function() {
+									var returned, then;
+
+									// Support: Promises/A+ section 2.3.3.3.3
+									// https://promisesaplus.com/#point-59
+									// Ignore double-resolution attempts
+									if ( depth < maxDepth ) {
+										return;
+									}
+
+									returned = handler.apply( that, args );
+
+									// Support: Promises/A+ section 2.3.1
+									// https://promisesaplus.com/#point-48
+									if ( returned === deferred.promise() ) {
+										throw new TypeError( "Thenable self-resolution" );
+									}
+
+									// Support: Promises/A+ sections 2.3.3.1, 3.5
+									// https://promisesaplus.com/#point-54
+									// https://promisesaplus.com/#point-75
+									// Retrieve `then` only once
+									then = returned &&
+
+										// Support: Promises/A+ section 2.3.4
+										// https://promisesaplus.com/#point-64
+										// Only check objects and functions for thenability
+										( typeof returned === "object" ||
+											typeof returned === "function" ) &&
+										returned.then;
+
+									// Handle a returned thenable
+									if ( isFunction( then ) ) {
+
+										// Special processors (notify) just wait for resolution
+										if ( special ) {
+											then.call(
+												returned,
+												resolve( maxDepth, deferred, Identity, special ),
+												resolve( maxDepth, deferred, Thrower, special )
+											);
+
+										// Normal processors (resolve) also hook into progress
+										} else {
+
+											// ...and disregard older resolution values
+											maxDepth++;
+
+											then.call(
+												returned,
+												resolve( maxDepth, deferred, Identity, special ),
+												resolve( maxDepth, deferred, Thrower, special ),
+												resolve( maxDepth, deferred, Identity,
+													deferred.notifyWith )
+											);
+										}
+
+									// Handle all other returned values
+									} else {
+
+										// Only substitute handlers pass on context
+										// and multiple values (non-spec behavior)
+										if ( handler !== Identity ) {
+											that = undefined;
+											args = [ returned ];
+										}
+
+										// Process the value(s)
+										// Default process is resolve
+										( special || deferred.resolveWith )( that, args );
+									}
+								},
+
+								// Only normal processors (resolve) catch and reject exceptions
+								process = special ?
+									mightThrow :
+									function() {
+										try {
+											mightThrow();
+										} catch ( e ) {
+
+											if ( jQuery.Deferred.exceptionHook ) {
+												jQuery.Deferred.exceptionHook( e,
+													process.stackTrace );
+											}
+
+											// Support: Promises/A+ section 2.3.3.3.4.1
+											// https://promisesaplus.com/#point-61
+											// Ignore post-resolution exceptions
+											if ( depth + 1 >= maxDepth ) {
+
+												// Only substitute handlers pass on context
+												// and multiple values (non-spec behavior)
+												if ( handler !== Thrower ) {
+													that = undefined;
+													args = [ e ];
+												}
+
+												deferred.rejectWith( that, args );
+											}
+										}
+									};
+
+							// Support: Promises/A+ section 2.3.3.3.1
+							// https://promisesaplus.com/#point-57
+							// Re-resolve promises immediately to dodge false rejection from
+							// subsequent errors
+							if ( depth ) {
+								process();
+							} else {
+
+								// Call an optional hook to record the stack, in case of exception
+								// since it's otherwise lost when execution goes async
+								if ( jQuery.Deferred.getStackHook ) {
+									process.stackTrace = jQuery.Deferred.getStackHook();
+								}
+								window.setTimeout( process );
+							}
+						};
+					}
+
+					return jQuery.Deferred( function( newDefer ) {
+
+						// progress_handlers.add( ... )
+						tuples[ 0 ][ 3 ].add(
+							resolve(
+								0,
+								newDefer,
+								isFunction( onProgress ) ?
+									onProgress :
+									Identity,
+								newDefer.notifyWith
+							)
+						);
+
+						// fulfilled_handlers.add( ... )
+						tuples[ 1 ][ 3 ].add(
+							resolve(
+								0,
+								newDefer,
+								isFunction( onFulfilled ) ?
+									onFulfilled :
+									Identity
+							)
+						);
+
+						// rejected_handlers.add( ... )
+						tuples[ 2 ][ 3 ].add(
+							resolve(
+								0,
+								newDefer,
+								isFunction( onRejected ) ?
+									onRejected :
+									Thrower
+							)
+						);
+					} ).promise();
+				},
+
+				// Get a promise for this deferred
+				// If obj is provided, the promise aspect is added to the object
+				promise: function( obj ) {
+					return obj != null ? jQuery.extend( obj, promise ) : promise;
+				}
+			},
+			deferred = {};
+
+		// Add list-specific methods
+		jQuery.each( tuples, function( i, tuple ) {
+			var list = tuple[ 2 ],
+				stateString = tuple[ 5 ];
+
+			// promise.progress = list.add
+			// promise.done = list.add
+			// promise.fail = list.add
+			promise[ tuple[ 1 ] ] = list.add;
+
+			// Handle state
+			if ( stateString ) {
+				list.add(
+					function() {
+
+						// state = "resolved" (i.e., fulfilled)
+						// state = "rejected"
+						state = stateString;
+					},
+
+					// rejected_callbacks.disable
+					// fulfilled_callbacks.disable
+					tuples[ 3 - i ][ 2 ].disable,
+
+					// rejected_handlers.disable
+					// fulfilled_handlers.disable
+					tuples[ 3 - i ][ 3 ].disable,
+
+					// progress_callbacks.lock
+					tuples[ 0 ][ 2 ].lock,
+
+					// progress_handlers.lock
+					tuples[ 0 ][ 3 ].lock
+				);
+			}
+
+			// progress_handlers.fire
+			// fulfilled_handlers.fire
+			// rejected_handlers.fire
+			list.add( tuple[ 3 ].fire );
+
+			// deferred.notify = function() { deferred.notifyWith(...) }
+			// deferred.resolve = function() { deferred.resolveWith(...) }
+			// deferred.reject = function() { deferred.rejectWith(...) }
+			deferred[ tuple[ 0 ] ] = function() {
+				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
+				return this;
+			};
+
+			// deferred.notifyWith = list.fireWith
+			// deferred.resolveWith = list.fireWith
+			// deferred.rejectWith = list.fireWith
+			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+		} );
+
+		// Make the deferred a promise
+		promise.promise( deferred );
+
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+
+		// All done!
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( singleValue ) {
+		var
+
+			// count of uncompleted subordinates
+			remaining = arguments.length,
+
+			// count of unprocessed arguments
+			i = remaining,
+
+			// subordinate fulfillment data
+			resolveContexts = Array( i ),
+			resolveValues = slice.call( arguments ),
+
+			// the master Deferred
+			master = jQuery.Deferred(),
+
+			// subordinate callback factory
+			updateFunc = function( i ) {
+				return function( value ) {
+					resolveContexts[ i ] = this;
+					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+					if ( !( --remaining ) ) {
+						master.resolveWith( resolveContexts, resolveValues );
+					}
+				};
+			};
+
+		// Single- and empty arguments are adopted like Promise.resolve
+		if ( remaining <= 1 ) {
+			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+				!remaining );
+
+			// Use .then() to unwrap secondary thenables (cf. gh-3000)
+			if ( master.state() === "pending" ||
+				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+				return master.then();
+			}
+		}
+
+		// Multiple arguments are aggregated like Promise.all array elements
+		while ( i-- ) {
+			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+		}
+
+		return master.promise();
+	}
+} );
+
+
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+	// Support: IE 8 - 9 only
+	// Console exists when dev tools are open, which can happen at any time
+	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+	}
+};
+
+
+
+
+jQuery.readyException = function( error ) {
+	window.setTimeout( function() {
+		throw error;
+	} );
+};
+
+
+
+
+// The deferred used on DOM ready
+var readyList = jQuery.Deferred();
+
+jQuery.fn.ready = function( fn ) {
+
+	readyList
+		.then( fn )
+
+		// Wrap jQuery.readyException in a function so that the lookup
+		// happens at the time of error handling instead of callback
+		// registration.
+		.catch( function( error ) {
+			jQuery.readyException( error );
+		} );
+
+	return this;
+};
+
+jQuery.extend( {
+
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+
+		// Abort if there are pending holds or we're already ready
+		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+			return;
+		}
+
+		// Remember that the DOM is ready
+		jQuery.isReady = true;
+
+		// If a normal DOM Ready event fired, decrement, and wait if need be
+		if ( wait !== true && --jQuery.readyWait > 0 ) {
+			return;
+		}
+
+		// If there are functions bound, to execute
+		readyList.resolveWith( document, [ jQuery ] );
+	}
+} );
+
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
+function completed() {
+	document.removeEventListener( "DOMContentLoaded", completed );
+	window.removeEventListener( "load", completed );
+	jQuery.ready();
+}
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+	// Handle it asynchronously to allow scripts the opportunity to delay ready
+	window.setTimeout( jQuery.ready );
+
+} else {
+
+	// Use the handy event callback
+	document.addEventListener( "DOMContentLoaded", completed );
+
+	// A fallback to window.onload, that will always work
+	window.addEventListener( "load", completed );
+}
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+	var i = 0,
+		len = elems.length,
+		bulk = key == null;
+
+	// Sets many values
+	if ( toType( key ) === "object" ) {
+		chainable = true;
+		for ( i in key ) {
+			access( elems, fn, i, key[ i ], true, emptyGet, raw );
+		}
+
+	// Sets one value
+	} else if ( value !== undefined ) {
+		chainable = true;
+
+		if ( !isFunction( value ) ) {
+			raw = true;
+		}
+
+		if ( bulk ) {
+
+			// Bulk operations run against the entire set
+			if ( raw ) {
+				fn.call( elems, value );
+				fn = null;
+
+			// ...except when executing function values
+			} else {
+				bulk = fn;
+				fn = function( elem, key, value ) {
+					return bulk.call( jQuery( elem ), value );
+				};
+			}
+		}
+
+		if ( fn ) {
+			for ( ; i < len; i++ ) {
+				fn(
+					elems[ i ], key, raw ?
+					value :
+					value.call( elems[ i ], i, fn( elems[ i ], key ) )
+				);
+			}
+		}
+	}
+
+	if ( chainable ) {
+		return elems;
+	}
+
+	// Gets
+	if ( bulk ) {
+		return fn.call( elems );
+	}
+
+	return len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+
+
+// Matches dashed string for camelizing
+var rmsPrefix = /^-ms-/,
+	rdashAlpha = /-([a-z])/g;
+
+// Used by camelCase as callback to replace()
+function fcamelCase( all, letter ) {
+	return letter.toUpperCase();
+}
+
+// Convert dashed to camelCase; used by the css and data modules
+// Support: IE <=9 - 11, Edge 12 - 15
+// Microsoft forgot to hump their vendor prefix (#9572)
+function camelCase( string ) {
+	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+}
+var acceptData = function( owner ) {
+
+	// Accepts only:
+	//  - Node
+	//    - Node.ELEMENT_NODE
+	//    - Node.DOCUMENT_NODE
+	//  - Object
+	//    - Any
+	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+	this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+	cache: function( owner ) {
+
+		// Check if the owner object already has a cache
+		var value = owner[ this.expando ];
+
+		// If not, create one
+		if ( !value ) {
+			value = {};
+
+			// We can accept data for non-element nodes in modern browsers,
+			// but we should not, see #8335.
+			// Always return an empty object.
+			if ( acceptData( owner ) ) {
+
+				// If it is a node unlikely to be stringify-ed or looped over
+				// use plain assignment
+				if ( owner.nodeType ) {
+					owner[ this.expando ] = value;
+
+				// Otherwise secure it in a non-enumerable property
+				// configurable must be true to allow the property to be
+				// deleted when data is removed
+				} else {
+					Object.defineProperty( owner, this.expando, {
+						value: value,
+						configurable: true
+					} );
+				}
+			}
+		}
+
+		return value;
+	},
+	set: function( owner, data, value ) {
+		var prop,
+			cache = this.cache( owner );
+
+		// Handle: [ owner, key, value ] args
+		// Always use camelCase key (gh-2257)
+		if ( typeof data === "string" ) {
+			cache[ camelCase( data ) ] = value;
+
+		// Handle: [ owner, { properties } ] args
+		} else {
+
+			// Copy the properties one-by-one to the cache object
+			for ( prop in data ) {
+				cache[ camelCase( prop ) ] = data[ prop ];
+			}
+		}
+		return cache;
+	},
+	get: function( owner, key ) {
+		return key === undefined ?
+			this.cache( owner ) :
+
+			// Always use camelCase key (gh-2257)
+			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
+	},
+	access: function( owner, key, value ) {
+
+		// In cases where either:
+		//
+		//   1. No key was specified
+		//   2. A string key was specified, but no value provided
+		//
+		// Take the "read" path and allow the get method to determine
+		// which value to return, respectively either:
+		//
+		//   1. The entire cache object
+		//   2. The data stored at the key
+		//
+		if ( key === undefined ||
+				( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+			return this.get( owner, key );
+		}
+
+		// When the key is not a string, or both a key and value
+		// are specified, set or extend (existing objects) with either:
+		//
+		//   1. An object of properties
+		//   2. A key and value
+		//
+		this.set( owner, key, value );
+
+		// Since the "set" path can have two possible entry points
+		// return the expected data based on which path was taken[*]
+		return value !== undefined ? value : key;
+	},
+	remove: function( owner, key ) {
+		var i,
+			cache = owner[ this.expando ];
+
+		if ( cache === undefined ) {
+			return;
+		}
+
+		if ( key !== undefined ) {
+
+			// Support array or space separated string of keys
+			if ( Array.isArray( key ) ) {
+
+				// If key is an array of keys...
+				// We always set camelCase keys, so remove that.
+				key = key.map( camelCase );
+			} else {
+				key = camelCase( key );
+
+				// If a key with the spaces exists, use it.
+				// Otherwise, create an array by matching non-whitespace
+				key = key in cache ?
+					[ key ] :
+					( key.match( rnothtmlwhite ) || [] );
+			}
+
+			i = key.length;
+
+			while ( i-- ) {
+				delete cache[ key[ i ] ];
+			}
+		}
+
+		// Remove the expando if there's no more data
+		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+			// Support: Chrome <=35 - 45
+			// Webkit & Blink performance suffers when deleting properties
+			// from DOM nodes, so set to undefined instead
+			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+			if ( owner.nodeType ) {
+				owner[ this.expando ] = undefined;
+			} else {
+				delete owner[ this.expando ];
+			}
+		}
+	},
+	hasData: function( owner ) {
+		var cache = owner[ this.expando ];
+		return cache !== undefined && !jQuery.isEmptyObject( cache );
+	}
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+//	Implementation Summary
+//
+//	1. Enforce API surface and semantic compatibility with 1.9.x branch
+//	2. Improve the module's maintainability by reducing the storage
+//		paths to a single mechanism.
+//	3. Use the same single mechanism to support "private" and "user" data.
+//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+//	5. Avoid exposing implementation details on user objects (eg. expando properties)
+//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+	rmultiDash = /[A-Z]/g;
+
+function getData( data ) {
+	if ( data === "true" ) {
+		return true;
+	}
+
+	if ( data === "false" ) {
+		return false;
+	}
+
+	if ( data === "null" ) {
+		return null;
+	}
+
+	// Only convert to a number if it doesn't change the string
+	if ( data === +data + "" ) {
+		return +data;
+	}
+
+	if ( rbrace.test( data ) ) {
+		return JSON.parse( data );
+	}
+
+	return data;
+}
+
+function dataAttr( elem, key, data ) {
+	var name;
+
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+		data = elem.getAttribute( name );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = getData( data );
+			} catch ( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			dataUser.set( elem, key, data );
+		} else {
+			data = undefined;
+		}
+	}
+	return data;
+}
+
+jQuery.extend( {
+	hasData: function( elem ) {
+		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+	},
+
+	data: function( elem, name, data ) {
+		return dataUser.access( elem, name, data );
+	},
+
+	removeData: function( elem, name ) {
+		dataUser.remove( elem, name );
+	},
+
+	// TODO: Now that all calls to _data and _removeData have been replaced
+	// with direct calls to dataPriv methods, these can be deprecated.
+	_data: function( elem, name, data ) {
+		return dataPriv.access( elem, name, data );
+	},
+
+	_removeData: function( elem, name ) {
+		dataPriv.remove( elem, name );
+	}
+} );
+
+jQuery.fn.extend( {
+	data: function( key, value ) {
+		var i, name, data,
+			elem = this[ 0 ],
+			attrs = elem && elem.attributes;
+
+		// Gets all values
+		if ( key === undefined ) {
+			if ( this.length ) {
+				data = dataUser.get( elem );
+
+				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+					i = attrs.length;
+					while ( i-- ) {
+
+						// Support: IE 11 only
+						// The attrs elements can be null (#14894)
+						if ( attrs[ i ] ) {
+							name = attrs[ i ].name;
+							if ( name.indexOf( "data-" ) === 0 ) {
+								name = camelCase( name.slice( 5 ) );
+								dataAttr( elem, name, data[ name ] );
+							}
+						}
+					}
+					dataPriv.set( elem, "hasDataAttrs", true );
+				}
+			}
+
+			return data;
+		}
+
+		// Sets multiple values
+		if ( typeof key === "object" ) {
+			return this.each( function() {
+				dataUser.set( this, key );
+			} );
+		}
+
+		return access( this, function( value ) {
+			var data;
+
+			// The calling jQuery object (element matches) is not empty
+			// (and therefore has an element appears at this[ 0 ]) and the
+			// `value` parameter was not undefined. An empty jQuery object
+			// will result in `undefined` for elem = this[ 0 ] which will
+			// throw an exception if an attempt to read a data cache is made.
+			if ( elem && value === undefined ) {
+
+				// Attempt to get data from the cache
+				// The key will always be camelCased in Data
+				data = dataUser.get( elem, key );
+				if ( data !== undefined ) {
+					return data;
+				}
+
+				// Attempt to "discover" the data in
+				// HTML5 custom data-* attrs
+				data = dataAttr( elem, key );
+				if ( data !== undefined ) {
+					return data;
+				}
+
+				// We tried really hard, but the data doesn't exist.
+				return;
+			}
+
+			// Set the data...
+			this.each( function() {
+
+				// We always store the camelCased key
+				dataUser.set( this, key, value );
+			} );
+		}, null, value, arguments.length > 1, null, true );
+	},
+
+	removeData: function( key ) {
+		return this.each( function() {
+			dataUser.remove( this, key );
+		} );
+	}
+} );
+
+
+jQuery.extend( {
+	queue: function( elem, type, data ) {
+		var queue;
+
+		if ( elem ) {
+			type = ( type || "fx" ) + "queue";
+			queue = dataPriv.get( elem, type );
+
+			// Speed up dequeue by getting out quickly if this is just a lookup
+			if ( data ) {
+				if ( !queue || Array.isArray( data ) ) {
+					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+				} else {
+					queue.push( data );
+				}
+			}
+			return queue || [];
+		}
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			startLength = queue.length,
+			fn = queue.shift(),
+			hooks = jQuery._queueHooks( elem, type ),
+			next = function() {
+				jQuery.dequeue( elem, type );
+			};
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+			startLength--;
+		}
+
+		if ( fn ) {
+
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift( "inprogress" );
+			}
+
+			// Clear up the last queue stop function
+			delete hooks.stop;
+			fn.call( elem, next, hooks );
+		}
+
+		if ( !startLength && hooks ) {
+			hooks.empty.fire();
+		}
+	},
+
+	// Not public - generate a queueHooks object, or return the current one
+	_queueHooks: function( elem, type ) {
+		var key = type + "queueHooks";
+		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+			empty: jQuery.Callbacks( "once memory" ).add( function() {
+				dataPriv.remove( elem, [ type + "queue", key ] );
+			} )
+		} );
+	}
+} );
+
+jQuery.fn.extend( {
+	queue: function( type, data ) {
+		var setter = 2;
+
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+			setter--;
+		}
+
+		if ( arguments.length < setter ) {
+			return jQuery.queue( this[ 0 ], type );
+		}
+
+		return data === undefined ?
+			this :
+			this.each( function() {
+				var queue = jQuery.queue( this, type, data );
+
+				// Ensure a hooks for this queue
+				jQuery._queueHooks( this, type );
+
+				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+					jQuery.dequeue( this, type );
+				}
+			} );
+	},
+	dequeue: function( type ) {
+		return this.each( function() {
+			jQuery.dequeue( this, type );
+		} );
+	},
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	},
+
+	// Get a promise resolved when queues of a certain type
+	// are emptied (fx is the type by default)
+	promise: function( type, obj ) {
+		var tmp,
+			count = 1,
+			defer = jQuery.Deferred(),
+			elements = this,
+			i = this.length,
+			resolve = function() {
+				if ( !( --count ) ) {
+					defer.resolveWith( elements, [ elements ] );
+				}
+			};
+
+		if ( typeof type !== "string" ) {
+			obj = type;
+			type = undefined;
+		}
+		type = type || "fx";
+
+		while ( i-- ) {
+			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+			if ( tmp && tmp.empty ) {
+				count++;
+				tmp.empty.add( resolve );
+			}
+		}
+		resolve();
+		return defer.promise( obj );
+	}
+} );
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHiddenWithinTree = function( elem, el ) {
+
+		// isHiddenWithinTree might be called from jQuery#filter function;
+		// in that case, element will be second argument
+		elem = el || elem;
+
+		// Inline style trumps all
+		return elem.style.display === "none" ||
+			elem.style.display === "" &&
+
+			// Otherwise, check computed style
+			// Support: Firefox <=43 - 45
+			// Disconnected elements can have computed display: none, so first confirm that elem is
+			// in the document.
+			jQuery.contains( elem.ownerDocument, elem ) &&
+
+			jQuery.css( elem, "display" ) === "none";
+	};
+
+var swap = function( elem, options, callback, args ) {
+	var ret, name,
+		old = {};
+
+	// Remember the old values, and insert the new ones
+	for ( name in options ) {
+		old[ name ] = elem.style[ name ];
+		elem.style[ name ] = options[ name ];
+	}
+
+	ret = callback.apply( elem, args || [] );
+
+	// Revert the old values
+	for ( name in options ) {
+		elem.style[ name ] = old[ name ];
+	}
+
+	return ret;
+};
+
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+	var adjusted, scale,
+		maxIterations = 20,
+		currentValue = tween ?
+			function() {
+				return tween.cur();
+			} :
+			function() {
+				return jQuery.css( elem, prop, "" );
+			},
+		initial = currentValue(),
+		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+		// Starting value computation is required for potential unit mismatches
+		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+			rcssNum.exec( jQuery.css( elem, prop ) );
+
+	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+		// Support: Firefox <=54
+		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
+		initial = initial / 2;
+
+		// Trust units reported by jQuery.css
+		unit = unit || initialInUnit[ 3 ];
+
+		// Iteratively approximate from a nonzero starting point
+		initialInUnit = +initial || 1;
+
+		while ( maxIterations-- ) {
+
+			// Evaluate and update our best guess (doubling guesses that zero out).
+			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
+			jQuery.style( elem, prop, initialInUnit + unit );
+			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
+				maxIterations = 0;
+			}
+			initialInUnit = initialInUnit / scale;
+
+		}
+
+		initialInUnit = initialInUnit * 2;
+		jQuery.style( elem, prop, initialInUnit + unit );
+
+		// Make sure we update the tween properties later on
+		valueParts = valueParts || [];
+	}
+
+	if ( valueParts ) {
+		initialInUnit = +initialInUnit || +initial || 0;
+
+		// Apply relative offset (+=/-=) if specified
+		adjusted = valueParts[ 1 ] ?
+			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+			+valueParts[ 2 ];
+		if ( tween ) {
+			tween.unit = unit;
+			tween.start = initialInUnit;
+			tween.end = adjusted;
+		}
+	}
+	return adjusted;
+}
+
+
+var defaultDisplayMap = {};
+
+function getDefaultDisplay( elem ) {
+	var temp,
+		doc = elem.ownerDocument,
+		nodeName = elem.nodeName,
+		display = defaultDisplayMap[ nodeName ];
+
+	if ( display ) {
+		return display;
+	}
+
+	temp = doc.body.appendChild( doc.createElement( nodeName ) );
+	display = jQuery.css( temp, "display" );
+
+	temp.parentNode.removeChild( temp );
+
+	if ( display === "none" ) {
+		display = "block";
+	}
+	defaultDisplayMap[ nodeName ] = display;
+
+	return display;
+}
+
+function showHide( elements, show ) {
+	var display, elem,
+		values = [],
+		index = 0,
+		length = elements.length;
+
+	// Determine new display value for elements that need to change
+	for ( ; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+
+		display = elem.style.display;
+		if ( show ) {
+
+			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+			// check is required in this first loop unless we have a nonempty display value (either
+			// inline or about-to-be-restored)
+			if ( display === "none" ) {
+				values[ index ] = dataPriv.get( elem, "display" ) || null;
+				if ( !values[ index ] ) {
+					elem.style.display = "";
+				}
+			}
+			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+				values[ index ] = getDefaultDisplay( elem );
+			}
+		} else {
+			if ( display !== "none" ) {
+				values[ index ] = "none";
+
+				// Remember what we're overwriting
+				dataPriv.set( elem, "display", display );
+			}
+		}
+	}
+
+	// Set the display of the elements in a second loop to avoid constant reflow
+	for ( index = 0; index < length; index++ ) {
+		if ( values[ index ] != null ) {
+			elements[ index ].style.display = values[ index ];
+		}
+	}
+
+	return elements;
+}
+
+jQuery.fn.extend( {
+	show: function() {
+		return showHide( this, true );
+	},
+	hide: function() {
+		return showHide( this );
+	},
+	toggle: function( state ) {
+		if ( typeof state === "boolean" ) {
+			return state ? this.show() : this.hide();
+		}
+
+		return this.each( function() {
+			if ( isHiddenWithinTree( this ) ) {
+				jQuery( this ).show();
+			} else {
+				jQuery( this ).hide();
+			}
+		} );
+	}
+} );
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+
+var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+	// Support: IE <=9 only
+	option: [ 1, "<select multiple='multiple'>", "</select>" ],
+
+	// XHTML parsers do not magically insert elements in the
+	// same way that tag soup parsers do. So we cannot shorten
+	// this by omitting <tbody> or other required elements.
+	thead: [ 1, "<table>", "</table>" ],
+	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
+	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+	_default: [ 0, "", "" ]
+};
+
+// Support: IE <=9 only
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+	// Support: IE <=9 - 11 only
+	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
+	var ret;
+
+	if ( typeof context.getElementsByTagName !== "undefined" ) {
+		ret = context.getElementsByTagName( tag || "*" );
+
+	} else if ( typeof context.querySelectorAll !== "undefined" ) {
+		ret = context.querySelectorAll( tag || "*" );
+
+	} else {
+		ret = [];
+	}
+
+	if ( tag === undefined || tag && nodeName( context, tag ) ) {
+		return jQuery.merge( [ context ], ret );
+	}
+
+	return ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+	var i = 0,
+		l = elems.length;
+
+	for ( ; i < l; i++ ) {
+		dataPriv.set(
+			elems[ i ],
+			"globalEval",
+			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
+		);
+	}
+}
+
+
+var rhtml = /<|&#?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+	var elem, tmp, tag, wrap, contains, j,
+		fragment = context.createDocumentFragment(),
+		nodes = [],
+		i = 0,
+		l = elems.length;
+
+	for ( ; i < l; i++ ) {
+		elem = elems[ i ];
+
+		if ( elem || elem === 0 ) {
+
+			// Add nodes directly
+			if ( toType( elem ) === "object" ) {
+
+				// Support: Android <=4.0 only, PhantomJS 1 only
+				// push.apply(_, arraylike) throws on ancient WebKit
+				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+			// Convert non-html into a text node
+			} else if ( !rhtml.test( elem ) ) {
+				nodes.push( context.createTextNode( elem ) );
+
+			// Convert html into DOM nodes
+			} else {
+				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+				// Deserialize a standard representation
+				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+				wrap = wrapMap[ tag ] || wrapMap._default;
+				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+				// Descend through wrappers to the right content
+				j = wrap[ 0 ];
+				while ( j-- ) {
+					tmp = tmp.lastChild;
+				}
+
+				// Support: Android <=4.0 only, PhantomJS 1 only
+				// push.apply(_, arraylike) throws on ancient WebKit
+				jQuery.merge( nodes, tmp.childNodes );
+
+				// Remember the top-level container
+				tmp = fragment.firstChild;
+
+				// Ensure the created nodes are orphaned (#12392)
+				tmp.textContent = "";
+			}
+		}
+	}
+
+	// Remove wrapper from fragment
+	fragment.textContent = "";
+
+	i = 0;
+	while ( ( elem = nodes[ i++ ] ) ) {
+
+		// Skip elements already in the context collection (trac-4087)
+		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+			if ( ignored ) {
+				ignored.push( elem );
+			}
+			continue;
+		}
+
+		contains = jQuery.contains( elem.ownerDocument, elem );
+
+		// Append to fragment
+		tmp = getAll( fragment.appendChild( elem ), "script" );
+
+		// Preserve script evaluation history
+		if ( contains ) {
+			setGlobalEval( tmp );
+		}
+
+		// Capture executables
+		if ( scripts ) {
+			j = 0;
+			while ( ( elem = tmp[ j++ ] ) ) {
+				if ( rscriptType.test( elem.type || "" ) ) {
+					scripts.push( elem );
+				}
+			}
+		}
+	}
+
+	return fragment;
+}
+
+
+( function() {
+	var fragment = document.createDocumentFragment(),
+		div = fragment.appendChild( document.createElement( "div" ) ),
+		input = document.createElement( "input" );
+
+	// Support: Android 4.0 - 4.3 only
+	// Check state lost if the name is set (#11217)
+	// Support: Windows Web Apps (WWA)
+	// `name` and `type` must use .setAttribute for WWA (#14901)
+	input.setAttribute( "type", "radio" );
+	input.setAttribute( "checked", "checked" );
+	input.setAttribute( "name", "t" );
+
+	div.appendChild( input );
+
+	// Support: Android <=4.1 only
+	// Older WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	// Support: IE <=11 only
+	// Make sure textarea (and checkbox) defaultValue is properly cloned
+	div.innerHTML = "<textarea>x</textarea>";
+	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+var documentElement = document.documentElement;
+
+
+
+var
+	rkeyEvent = /^key/,
+	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+	return true;
+}
+
+function returnFalse() {
+	return false;
+}
+
+// Support: IE <=9 only
+// See #13393 for more info
+function safeActiveElement() {
+	try {
+		return document.activeElement;
+	} catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+	var origFn, type;
+
+	// Types can be a map of types/handlers
+	if ( typeof types === "object" ) {
+
+		// ( types-Object, selector, data )
+		if ( typeof selector !== "string" ) {
+
+			// ( types-Object, data )
+			data = data || selector;
+			selector = undefined;
+		}
+		for ( type in types ) {
+			on( elem, type, selector, data, types[ type ], one );
+		}
+		return elem;
+	}
+
+	if ( data == null && fn == null ) {
+
+		// ( types, fn )
+		fn = selector;
+		data = selector = undefined;
+	} else if ( fn == null ) {
+		if ( typeof selector === "string" ) {
+
+			// ( types, selector, fn )
+			fn = data;
+			data = undefined;
+		} else {
+
+			// ( types, data, fn )
+			fn = data;
+			data = selector;
+			selector = undefined;
+		}
+	}
+	if ( fn === false ) {
+		fn = returnFalse;
+	} else if ( !fn ) {
+		return elem;
+	}
+
+	if ( one === 1 ) {
+		origFn = fn;
+		fn = function( event ) {
+
+			// Can use an empty set, since event contains the info
+			jQuery().off( event );
+			return origFn.apply( this, arguments );
+		};
+
+		// Use same guid so caller can remove using origFn
+		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+	}
+	return elem.each( function() {
+		jQuery.event.add( this, types, fn, data, selector );
+	} );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+	global: {},
+
+	add: function( elem, types, handler, data, selector ) {
+
+		var handleObjIn, eventHandle, tmp,
+			events, t, handleObj,
+			special, handlers, type, namespaces, origType,
+			elemData = dataPriv.get( elem );
+
+		// Don't attach events to noData or text/comment nodes (but allow plain objects)
+		if ( !elemData ) {
+			return;
+		}
+
+		// Caller can pass in an object of custom data in lieu of the handler
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+			selector = handleObjIn.selector;
+		}
+
+		// Ensure that invalid selectors throw exceptions at attach time
+		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
+		if ( selector ) {
+			jQuery.find.matchesSelector( documentElement, selector );
+		}
+
+		// Make sure that the handler has a unique ID, used to find/remove it later
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure and main handler, if this is the first
+		if ( !( events = elemData.events ) ) {
+			events = elemData.events = {};
+		}
+		if ( !( eventHandle = elemData.handle ) ) {
+			eventHandle = elemData.handle = function( e ) {
+
+				// Discard the second event of a jQuery.event.trigger() and
+				// when an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+			};
+		}
+
+		// Handle multiple events separated by a space
+		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[ t ] ) || [];
+			type = origType = tmp[ 1 ];
+			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+			// There *must* be a type, no attaching namespace-only handlers
+			if ( !type ) {
+				continue;
+			}
+
+			// If event changes its type, use the special event handlers for the changed type
+			special = jQuery.event.special[ type ] || {};
+
+			// If selector defined, determine special event api type, otherwise given type
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+
+			// Update special based on newly reset type
+			special = jQuery.event.special[ type ] || {};
+
+			// handleObj is passed to all event handlers
+			handleObj = jQuery.extend( {
+				type: type,
+				origType: origType,
+				data: data,
+				handler: handler,
+				guid: handler.guid,
+				selector: selector,
+				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+				namespace: namespaces.join( "." )
+			}, handleObjIn );
+
+			// Init the event handler queue if we're the first
+			if ( !( handlers = events[ type ] ) ) {
+				handlers = events[ type ] = [];
+				handlers.delegateCount = 0;
+
+				// Only use addEventListener if the special events handler returns false
+				if ( !special.setup ||
+					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle );
+					}
+				}
+			}
+
+			if ( special.add ) {
+				special.add.call( elem, handleObj );
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add to the element's handler list, delegates in front
+			if ( selector ) {
+				handlers.splice( handlers.delegateCount++, 0, handleObj );
+			} else {
+				handlers.push( handleObj );
+			}
+
+			// Keep track of which events have ever been used, for event optimization
+			jQuery.event.global[ type ] = true;
+		}
+
+	},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, selector, mappedTypes ) {
+
+		var j, origCount, tmp,
+			events, t, handleObj,
+			special, handlers, type, namespaces, origType,
+			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+		if ( !elemData || !( events = elemData.events ) ) {
+			return;
+		}
+
+		// Once for each type.namespace in types; type may be omitted
+		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[ t ] ) || [];
+			type = origType = tmp[ 1 ];
+			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+			// Unbind all events (on this namespace, if provided) for the element
+			if ( !type ) {
+				for ( type in events ) {
+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+				}
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+			handlers = events[ type ] || [];
+			tmp = tmp[ 2 ] &&
+				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+			// Remove matching events
+			origCount = j = handlers.length;
+			while ( j-- ) {
+				handleObj = handlers[ j ];
+
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
+					( !handler || handler.guid === handleObj.guid ) &&
+					( !tmp || tmp.test( handleObj.namespace ) ) &&
+					( !selector || selector === handleObj.selector ||
+						selector === "**" && handleObj.selector ) ) {
+					handlers.splice( j, 1 );
+
+					if ( handleObj.selector ) {
+						handlers.delegateCount--;
+					}
+					if ( special.remove ) {
+						special.remove.call( elem, handleObj );
+					}
+				}
+			}
+
+			// Remove generic event handler if we removed something and no more handlers exist
+			// (avoids potential for endless recursion during removal of special event handlers)
+			if ( origCount && !handlers.length ) {
+				if ( !special.teardown ||
+					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				delete events[ type ];
+			}
+		}
+
+		// Remove data and the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			dataPriv.remove( elem, "handle events" );
+		}
+	},
+
+	dispatch: function( nativeEvent ) {
+
+		// Make a writable jQuery.Event from the native event object
+		var event = jQuery.event.fix( nativeEvent );
+
+		var i, j, ret, matched, handleObj, handlerQueue,
+			args = new Array( arguments.length ),
+			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+			special = jQuery.event.special[ event.type ] || {};
+
+		// Use the fix-ed jQuery.Event rather than the (read-only) native event
+		args[ 0 ] = event;
+
+		for ( i = 1; i < arguments.length; i++ ) {
+			args[ i ] = arguments[ i ];
+		}
+
+		event.delegateTarget = this;
+
+		// Call the preDispatch hook for the mapped type, and let it bail if desired
+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+			return;
+		}
+
+		// Determine handlers
+		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+		// Run delegates first; they may want to stop propagation beneath us
+		i = 0;
+		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+			event.currentTarget = matched.elem;
+
+			j = 0;
+			while ( ( handleObj = matched.handlers[ j++ ] ) &&
+				!event.isImmediatePropagationStopped() ) {
+
+				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
+				// a subset or equal to those in the bound event (both can have no namespace).
+				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+					event.handleObj = handleObj;
+					event.data = handleObj.data;
+
+					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+						handleObj.handler ).apply( matched.elem, args );
+
+					if ( ret !== undefined ) {
+						if ( ( event.result = ret ) === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+				}
+			}
+		}
+
+		// Call the postDispatch hook for the mapped type
+		if ( special.postDispatch ) {
+			special.postDispatch.call( this, event );
+		}
+
+		return event.result;
+	},
+
+	handlers: function( event, handlers ) {
+		var i, handleObj, sel, matchedHandlers, matchedSelectors,
+			handlerQueue = [],
+			delegateCount = handlers.delegateCount,
+			cur = event.target;
+
+		// Find delegate handlers
+		if ( delegateCount &&
+
+			// Support: IE <=9
+			// Black-hole SVG <use> instance trees (trac-13180)
+			cur.nodeType &&
+
+			// Support: Firefox <=42
+			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+			// Support: IE 11 only
+			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+			!( event.type === "click" && event.button >= 1 ) ) {
+
+			for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+				// Don't check non-elements (#13208)
+				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
+					matchedHandlers = [];
+					matchedSelectors = {};
+					for ( i = 0; i < delegateCount; i++ ) {
+						handleObj = handlers[ i ];
+
+						// Don't conflict with Object.prototype properties (#13203)
+						sel = handleObj.selector + " ";
+
+						if ( matchedSelectors[ sel ] === undefined ) {
+							matchedSelectors[ sel ] = handleObj.needsContext ?
+								jQuery( sel, this ).index( cur ) > -1 :
+								jQuery.find( sel, this, null, [ cur ] ).length;
+						}
+						if ( matchedSelectors[ sel ] ) {
+							matchedHandlers.push( handleObj );
+						}
+					}
+					if ( matchedHandlers.length ) {
+						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
+					}
+				}
+			}
+		}
+
+		// Add the remaining (directly-bound) handlers
+		cur = this;
+		if ( delegateCount < handlers.length ) {
+			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+		}
+
+		return handlerQueue;
+	},
+
+	addProp: function( name, hook ) {
+		Object.defineProperty( jQuery.Event.prototype, name, {
+			enumerable: true,
+			configurable: true,
+
+			get: isFunction( hook ) ?
+				function() {
+					if ( this.originalEvent ) {
+							return hook( this.originalEvent );
+					}
+				} :
+				function() {
+					if ( this.originalEvent ) {
+							return this.originalEvent[ name ];
+					}
+				},
+
+			set: function( value ) {
+				Object.defineProperty( this, name, {
+					enumerable: true,
+					configurable: true,
+					writable: true,
+					value: value
+				} );
+			}
+		} );
+	},
+
+	fix: function( originalEvent ) {
+		return originalEvent[ jQuery.expando ] ?
+			originalEvent :
+			new jQuery.Event( originalEvent );
+	},
+
+	special: {
+		load: {
+
+			// Prevent triggered image.load events from bubbling to window.load
+			noBubble: true
+		},
+		focus: {
+
+			// Fire native event if possible so blur/focus sequence is correct
+			trigger: function() {
+				if ( this !== safeActiveElement() && this.focus ) {
+					this.focus();
+					return false;
+				}
+			},
+			delegateType: "focusin"
+		},
+		blur: {
+			trigger: function() {
+				if ( this === safeActiveElement() && this.blur ) {
+					this.blur();
+					return false;
+				}
+			},
+			delegateType: "focusout"
+		},
+		click: {
+
+			// For checkbox, fire native event so checked state will be right
+			trigger: function() {
+				if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
+					this.click();
+					return false;
+				}
+			},
+
+			// For cross-browser consistency, don't fire native .click() on links
+			_default: function( event ) {
+				return nodeName( event.target, "a" );
+			}
+		},
+
+		beforeunload: {
+			postDispatch: function( event ) {
+
+				// Support: Firefox 20+
+				// Firefox doesn't alert if the returnValue field is not set.
+				if ( event.result !== undefined && event.originalEvent ) {
+					event.originalEvent.returnValue = event.result;
+				}
+			}
+		}
+	}
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+
+	// This "if" is needed for plain objects
+	if ( elem.removeEventListener ) {
+		elem.removeEventListener( type, handle );
+	}
+};
+
+jQuery.Event = function( src, props ) {
+
+	// Allow instantiation without the 'new' keyword
+	if ( !( this instanceof jQuery.Event ) ) {
+		return new jQuery.Event( src, props );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+
+		// Events bubbling up the document may have been marked as prevented
+		// by a handler lower down the tree; reflect the correct value.
+		this.isDefaultPrevented = src.defaultPrevented ||
+				src.defaultPrevented === undefined &&
+
+				// Support: Android <=2.3 only
+				src.returnValue === false ?
+			returnTrue :
+			returnFalse;
+
+		// Create target properties
+		// Support: Safari <=6 - 7 only
+		// Target should not be a text node (#504, #13143)
+		this.target = ( src.target && src.target.nodeType === 3 ) ?
+			src.target.parentNode :
+			src.target;
+
+		this.currentTarget = src.currentTarget;
+		this.relatedTarget = src.relatedTarget;
+
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// Put explicitly provided properties onto the event object
+	if ( props ) {
+		jQuery.extend( this, props );
+	}
+
+	// Create a timestamp if incoming event doesn't have one
+	this.timeStamp = src && src.timeStamp || Date.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	constructor: jQuery.Event,
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse,
+	isSimulated: false,
+
+	preventDefault: function() {
+		var e = this.originalEvent;
+
+		this.isDefaultPrevented = returnTrue;
+
+		if ( e && !this.isSimulated ) {
+			e.preventDefault();
+		}
+	},
+	stopPropagation: function() {
+		var e = this.originalEvent;
+
+		this.isPropagationStopped = returnTrue;
+
+		if ( e && !this.isSimulated ) {
+			e.stopPropagation();
+		}
+	},
+	stopImmediatePropagation: function() {
+		var e = this.originalEvent;
+
+		this.isImmediatePropagationStopped = returnTrue;
+
+		if ( e && !this.isSimulated ) {
+			e.stopImmediatePropagation();
+		}
+
+		this.stopPropagation();
+	}
+};
+
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+	altKey: true,
+	bubbles: true,
+	cancelable: true,
+	changedTouches: true,
+	ctrlKey: true,
+	detail: true,
+	eventPhase: true,
+	metaKey: true,
+	pageX: true,
+	pageY: true,
+	shiftKey: true,
+	view: true,
+	"char": true,
+	charCode: true,
+	key: true,
+	keyCode: true,
+	button: true,
+	buttons: true,
+	clientX: true,
+	clientY: true,
+	offsetX: true,
+	offsetY: true,
+	pointerId: true,
+	pointerType: true,
+	screenX: true,
+	screenY: true,
+	targetTouches: true,
+	toElement: true,
+	touches: true,
+
+	which: function( event ) {
+		var button = event.button;
+
+		// Add which for key events
+		if ( event.which == null && rkeyEvent.test( event.type ) ) {
+			return event.charCode != null ? event.charCode : event.keyCode;
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+			if ( button & 1 ) {
+				return 1;
+			}
+
+			if ( button & 2 ) {
+				return 3;
+			}
+
+			if ( button & 4 ) {
+				return 2;
+			}
+
+			return 0;
+		}
+
+		return event.which;
+	}
+}, jQuery.event.addProp );
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+jQuery.each( {
+	mouseenter: "mouseover",
+	mouseleave: "mouseout",
+	pointerenter: "pointerover",
+	pointerleave: "pointerout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		delegateType: fix,
+		bindType: fix,
+
+		handle: function( event ) {
+			var ret,
+				target = this,
+				related = event.relatedTarget,
+				handleObj = event.handleObj;
+
+			// For mouseenter/leave call the handler if related is outside the target.
+			// NB: No relatedTarget if the mouse left/entered the browser window
+			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
+				event.type = handleObj.origType;
+				ret = handleObj.handler.apply( this, arguments );
+				event.type = fix;
+			}
+			return ret;
+		}
+	};
+} );
+
+jQuery.fn.extend( {
+
+	on: function( types, selector, data, fn ) {
+		return on( this, types, selector, data, fn );
+	},
+	one: function( types, selector, data, fn ) {
+		return on( this, types, selector, data, fn, 1 );
+	},
+	off: function( types, selector, fn ) {
+		var handleObj, type;
+		if ( types && types.preventDefault && types.handleObj ) {
+
+			// ( event )  dispatched jQuery.Event
+			handleObj = types.handleObj;
+			jQuery( types.delegateTarget ).off(
+				handleObj.namespace ?
+					handleObj.origType + "." + handleObj.namespace :
+					handleObj.origType,
+				handleObj.selector,
+				handleObj.handler
+			);
+			return this;
+		}
+		if ( typeof types === "object" ) {
+
+			// ( types-object [, selector] )
+			for ( type in types ) {
+				this.off( type, selector, types[ type ] );
+			}
+			return this;
+		}
+		if ( selector === false || typeof selector === "function" ) {
+
+			// ( types [, fn] )
+			fn = selector;
+			selector = undefined;
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		}
+		return this.each( function() {
+			jQuery.event.remove( this, types, fn, selector );
+		} );
+	}
+} );
+
+
+var
+
+	/* eslint-disable max-len */
+
+	// See https://github.com/eslint/eslint/issues/3229
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+	/* eslint-enable */
+
+	// Support: IE <=10 - 11, Edge 12 - 13 only
+	// In IE/Edge using regex groups here causes severe slowdowns.
+	// See https://connect.microsoft.com/IE/feedback/details/1736512/
+	rnoInnerhtml = /<script|<style|<link/i,
+
+	// checked="checked" or checked
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
+
+// Prefer a tbody over its parent table for containing new rows
+function manipulationTarget( elem, content ) {
+	if ( nodeName( elem, "table" ) &&
+		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
+
+		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
+	}
+
+	return elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
+	return elem;
+}
+function restoreScript( elem ) {
+	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
+		elem.type = elem.type.slice( 5 );
+	} else {
+		elem.removeAttribute( "type" );
+	}
+
+	return elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+
+	if ( dest.nodeType !== 1 ) {
+		return;
+	}
+
+	// 1. Copy private data: events, handlers, etc.
+	if ( dataPriv.hasData( src ) ) {
+		pdataOld = dataPriv.access( src );
+		pdataCur = dataPriv.set( dest, pdataOld );
+		events = pdataOld.events;
+
+		if ( events ) {
+			delete pdataCur.handle;
+			pdataCur.events = {};
+
+			for ( type in events ) {
+				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+					jQuery.event.add( dest, type, events[ type ][ i ] );
+				}
+			}
+		}
+	}
+
+	// 2. Copy user data
+	if ( dataUser.hasData( src ) ) {
+		udataOld = dataUser.access( src );
+		udataCur = jQuery.extend( {}, udataOld );
+
+		dataUser.set( dest, udataCur );
+	}
+}
+
+// Fix IE bugs, see support tests
+function fixInput( src, dest ) {
+	var nodeName = dest.nodeName.toLowerCase();
+
+	// Fails to persist the checked state of a cloned checkbox or radio button.
+	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+		dest.checked = src.checked;
+
+	// Fails to return the selected option to the default selected state when cloning options
+	} else if ( nodeName === "input" || nodeName === "textarea" ) {
+		dest.defaultValue = src.defaultValue;
+	}
+}
+
+function domManip( collection, args, callback, ignored ) {
+
+	// Flatten any nested arrays
+	args = concat.apply( [], args );
+
+	var fragment, first, scripts, hasScripts, node, doc,
+		i = 0,
+		l = collection.length,
+		iNoClone = l - 1,
+		value = args[ 0 ],
+		valueIsFunction = isFunction( value );
+
+	// We can't cloneNode fragments that contain checked, in WebKit
+	if ( valueIsFunction ||
+			( l > 1 && typeof value === "string" &&
+				!support.checkClone && rchecked.test( value ) ) ) {
+		return collection.each( function( index ) {
+			var self = collection.eq( index );
+			if ( valueIsFunction ) {
+				args[ 0 ] = value.call( this, index, self.html() );
+			}
+			domManip( self, args, callback, ignored );
+		} );
+	}
+
+	if ( l ) {
+		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
+		first = fragment.firstChild;
+
+		if ( fragment.childNodes.length === 1 ) {
+			fragment = first;
+		}
+
+		// Require either new content or an interest in ignored elements to invoke the callback
+		if ( first || ignored ) {
+			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+			hasScripts = scripts.length;
+
+			// Use the original fragment for the last item
+			// instead of the first because it can end up
+			// being emptied incorrectly in certain situations (#8070).
+			for ( ; i < l; i++ ) {
+				node = fragment;
+
+				if ( i !== iNoClone ) {
+					node = jQuery.clone( node, true, true );
+
+					// Keep references to cloned scripts for later restoration
+					if ( hasScripts ) {
+
+						// Support: Android <=4.0 only, PhantomJS 1 only
+						// push.apply(_, arraylike) throws on ancient WebKit
+						jQuery.merge( scripts, getAll( node, "script" ) );
+					}
+				}
+
+				callback.call( collection[ i ], node, i );
+			}
+
+			if ( hasScripts ) {
+				doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+				// Reenable scripts
+				jQuery.map( scripts, restoreScript );
+
+				// Evaluate executable scripts on first document insertion
+				for ( i = 0; i < hasScripts; i++ ) {
+					node = scripts[ i ];
+					if ( rscriptType.test( node.type || "" ) &&
+						!dataPriv.access( node, "globalEval" ) &&
+						jQuery.contains( doc, node ) ) {
+
+						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
+
+							// Optional AJAX dependency, but won't run scripts if not present
+							if ( jQuery._evalUrl ) {
+								jQuery._evalUrl( node.src );
+							}
+						} else {
+							DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node );
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return collection;
+}
+
+function remove( elem, selector, keepData ) {
+	var node,
+		nodes = selector ? jQuery.filter( selector, elem ) : elem,
+		i = 0;
+
+	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
+		if ( !keepData && node.nodeType === 1 ) {
+			jQuery.cleanData( getAll( node ) );
+		}
+
+		if ( node.parentNode ) {
+			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
+				setGlobalEval( getAll( node, "script" ) );
+			}
+			node.parentNode.removeChild( node );
+		}
+	}
+
+	return elem;
+}
+
+jQuery.extend( {
+	htmlPrefilter: function( html ) {
+		return html.replace( rxhtmlTag, "<$1></$2>" );
+	},
+
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+		var i, l, srcElements, destElements,
+			clone = elem.cloneNode( true ),
+			inPage = jQuery.contains( elem.ownerDocument, elem );
+
+		// Fix IE cloning issues
+		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
+				!jQuery.isXMLDoc( elem ) ) {
+
+			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
+			destElements = getAll( clone );
+			srcElements = getAll( elem );
+
+			for ( i = 0, l = srcElements.length; i < l; i++ ) {
+				fixInput( srcElements[ i ], destElements[ i ] );
+			}
+		}
+
+		// Copy the events from the original to the clone
+		if ( dataAndEvents ) {
+			if ( deepDataAndEvents ) {
+				srcElements = srcElements || getAll( elem );
+				destElements = destElements || getAll( clone );
+
+				for ( i = 0, l = srcElements.length; i < l; i++ ) {
+					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+				}
+			} else {
+				cloneCopyEvent( elem, clone );
+			}
+		}
+
+		// Preserve script evaluation history
+		destElements = getAll( clone, "script" );
+		if ( destElements.length > 0 ) {
+			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+		}
+
+		// Return the cloned set
+		return clone;
+	},
+
+	cleanData: function( elems ) {
+		var data, elem, type,
+			special = jQuery.event.special,
+			i = 0;
+
+		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
+			if ( acceptData( elem ) ) {
+				if ( ( data = elem[ dataPriv.expando ] ) ) {
+					if ( data.events ) {
+						for ( type in data.events ) {
+							if ( special[ type ] ) {
+								jQuery.event.remove( elem, type );
+
+							// This is a shortcut to avoid jQuery.event.remove's overhead
+							} else {
+								jQuery.removeEvent( elem, type, data.handle );
+							}
+						}
+					}
+
+					// Support: Chrome <=35 - 45+
+					// Assign undefined instead of using delete, see Data#remove
+					elem[ dataPriv.expando ] = undefined;
+				}
+				if ( elem[ dataUser.expando ] ) {
+
+					// Support: Chrome <=35 - 45+
+					// Assign undefined instead of using delete, see Data#remove
+					elem[ dataUser.expando ] = undefined;
+				}
+			}
+		}
+	}
+} );
+
+jQuery.fn.extend( {
+	detach: function( selector ) {
+		return remove( this, selector, true );
+	},
+
+	remove: function( selector ) {
+		return remove( this, selector );
+	},
+
+	text: function( value ) {
+		return access( this, function( value ) {
+			return value === undefined ?
+				jQuery.text( this ) :
+				this.empty().each( function() {
+					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+						this.textContent = value;
+					}
+				} );
+		}, null, value, arguments.length );
+	},
+
+	append: function() {
+		return domManip( this, arguments, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				var target = manipulationTarget( this, elem );
+				target.appendChild( elem );
+			}
+		} );
+	},
+
+	prepend: function() {
+		return domManip( this, arguments, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				var target = manipulationTarget( this, elem );
+				target.insertBefore( elem, target.firstChild );
+			}
+		} );
+	},
+
+	before: function() {
+		return domManip( this, arguments, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this );
+			}
+		} );
+	},
+
+	after: function() {
+		return domManip( this, arguments, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			}
+		} );
+	},
+
+	empty: function() {
+		var elem,
+			i = 0;
+
+		for ( ; ( elem = this[ i ] ) != null; i++ ) {
+			if ( elem.nodeType === 1 ) {
+
+				// Prevent memory leaks
+				jQuery.cleanData( getAll( elem, false ) );
+
+				// Remove any remaining nodes
+				elem.textContent = "";
+			}
+		}
+
+		return this;
+	},
+
+	clone: function( dataAndEvents, deepDataAndEvents ) {
+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+		return this.map( function() {
+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+		} );
+	},
+
+	html: function( value ) {
+		return access( this, function( value ) {
+			var elem = this[ 0 ] || {},
+				i = 0,
+				l = this.length;
+
+			if ( value === undefined && elem.nodeType === 1 ) {
+				return elem.innerHTML;
+			}
+
+			// See if we can take a shortcut and just use innerHTML
+			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
+
+				value = jQuery.htmlPrefilter( value );
+
+				try {
+					for ( ; i < l; i++ ) {
+						elem = this[ i ] || {};
+
+						// Remove element nodes and prevent memory leaks
+						if ( elem.nodeType === 1 ) {
+							jQuery.cleanData( getAll( elem, false ) );
+							elem.innerHTML = value;
+						}
+					}
+
+					elem = 0;
+
+				// If using innerHTML throws an exception, use the fallback method
+				} catch ( e ) {}
+			}
+
+			if ( elem ) {
+				this.empty().append( value );
+			}
+		}, null, value, arguments.length );
+	},
+
+	replaceWith: function() {
+		var ignored = [];
+
+		// Make the changes, replacing each non-ignored context element with the new content
+		return domManip( this, arguments, function( elem ) {
+			var parent = this.parentNode;
+
+			if ( jQuery.inArray( this, ignored ) < 0 ) {
+				jQuery.cleanData( getAll( this ) );
+				if ( parent ) {
+					parent.replaceChild( elem, this );
+				}
+			}
+
+		// Force callback invocation
+		}, ignored );
+	}
+} );
+
+jQuery.each( {
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var elems,
+			ret = [],
+			insert = jQuery( selector ),
+			last = insert.length - 1,
+			i = 0;
+
+		for ( ; i <= last; i++ ) {
+			elems = i === last ? this : this.clone( true );
+			jQuery( insert[ i ] )[ original ]( elems );
+
+			// Support: Android <=4.0 only, PhantomJS 1 only
+			// .get() because push.apply(_, arraylike) throws on ancient WebKit
+			push.apply( ret, elems.get() );
+		}
+
+		return this.pushStack( ret );
+	};
+} );
+var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
+
+var getStyles = function( elem ) {
+
+		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
+		// IE throws on elements created in popups
+		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
+		var view = elem.ownerDocument.defaultView;
+
+		if ( !view || !view.opener ) {
+			view = window;
+		}
+
+		return view.getComputedStyle( elem );
+	};
+
+var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
+
+
+
+( function() {
+
+	// Executing both pixelPosition & boxSizingReliable tests require only one layout
+	// so they're executed at the same time to save the second computation.
+	function computeStyleTests() {
+
+		// This is a singleton, we need to execute it only once
+		if ( !div ) {
+			return;
+		}
+
+		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
+			"margin-top:1px;padding:0;border:0";
+		div.style.cssText =
+			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
+			"margin:auto;border:1px;padding:1px;" +
+			"width:60%;top:1%";
+		documentElement.appendChild( container ).appendChild( div );
+
+		var divStyle = window.getComputedStyle( div );
+		pixelPositionVal = divStyle.top !== "1%";
+
+		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
+		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
+
+		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
+		// Some styles come back with percentage values, even though they shouldn't
+		div.style.right = "60%";
+		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
+
+		// Support: IE 9 - 11 only
+		// Detect misreporting of content dimensions for box-sizing:border-box elements
+		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
+
+		// Support: IE 9 only
+		// Detect overflow:scroll screwiness (gh-3699)
+		div.style.position = "absolute";
+		scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
+
+		documentElement.removeChild( container );
+
+		// Nullify the div so it wouldn't be stored in the memory and
+		// it will also be a sign that checks already performed
+		div = null;
+	}
+
+	function roundPixelMeasures( measure ) {
+		return Math.round( parseFloat( measure ) );
+	}
+
+	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
+		reliableMarginLeftVal,
+		container = document.createElement( "div" ),
+		div = document.createElement( "div" );
+
+	// Finish early in limited (non-browser) environments
+	if ( !div.style ) {
+		return;
+	}
+
+	// Support: IE <=9 - 11 only
+	// Style of cloned element affects source element cloned (#8908)
+	div.style.backgroundClip = "content-box";
+	div.cloneNode( true ).style.backgroundClip = "";
+	support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+	jQuery.extend( support, {
+		boxSizingReliable: function() {
+			computeStyleTests();
+			return boxSizingReliableVal;
+		},
+		pixelBoxStyles: function() {
+			computeStyleTests();
+			return pixelBoxStylesVal;
+		},
+		pixelPosition: function() {
+			computeStyleTests();
+			return pixelPositionVal;
+		},
+		reliableMarginLeft: function() {
+			computeStyleTests();
+			return reliableMarginLeftVal;
+		},
+		scrollboxSize: function() {
+			computeStyleTests();
+			return scrollboxSizeVal;
+		}
+	} );
+} )();
+
+
+function curCSS( elem, name, computed ) {
+	var width, minWidth, maxWidth, ret,
+
+		// Support: Firefox 51+
+		// Retrieving style before computed somehow
+		// fixes an issue with getting wrong values
+		// on detached elements
+		style = elem.style;
+
+	computed = computed || getStyles( elem );
+
+	// getPropertyValue is needed for:
+	//   .css('filter') (IE 9 only, #12537)
+	//   .css('--customProperty) (#3144)
+	if ( computed ) {
+		ret = computed.getPropertyValue( name ) || computed[ name ];
+
+		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+			ret = jQuery.style( elem, name );
+		}
+
+		// A tribute to the "awesome hack by Dean Edwards"
+		// Android Browser returns percentage for some values,
+		// but width seems to be reliably pixels.
+		// This is against the CSSOM draft spec:
+		// https://drafts.csswg.org/cssom/#resolved-values
+		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
+
+			// Remember the original values
+			width = style.width;
+			minWidth = style.minWidth;
+			maxWidth = style.maxWidth;
+
+			// Put in the new values to get a computed value out
+			style.minWidth = style.maxWidth = style.width = ret;
+			ret = computed.width;
+
+			// Revert the changed values
+			style.width = width;
+			style.minWidth = minWidth;
+			style.maxWidth = maxWidth;
+		}
+	}
+
+	return ret !== undefined ?
+
+		// Support: IE <=9 - 11 only
+		// IE returns zIndex value as an integer.
+		ret + "" :
+		ret;
+}
+
+
+function addGetHookIf( conditionFn, hookFn ) {
+
+	// Define the hook, we'll check on the first run if it's really needed.
+	return {
+		get: function() {
+			if ( conditionFn() ) {
+
+				// Hook not needed (or it's not possible to use it due
+				// to missing dependency), remove it.
+				delete this.get;
+				return;
+			}
+
+			// Hook needed; redefine it so that the support test is not executed again.
+			return ( this.get = hookFn ).apply( this, arguments );
+		}
+	};
+}
+
+
+var
+
+	// Swappable if display is none or starts with table
+	// except "table", "table-cell", or "table-caption"
+	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+	rcustomProp = /^--/,
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssNormalTransform = {
+		letterSpacing: "0",
+		fontWeight: "400"
+	},
+
+	cssPrefixes = [ "Webkit", "Moz", "ms" ],
+	emptyStyle = document.createElement( "div" ).style;
+
+// Return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( name ) {
+
+	// Shortcut for names that are not vendor prefixed
+	if ( name in emptyStyle ) {
+		return name;
+	}
+
+	// Check for vendor prefixed names
+	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
+		i = cssPrefixes.length;
+
+	while ( i-- ) {
+		name = cssPrefixes[ i ] + capName;
+		if ( name in emptyStyle ) {
+			return name;
+		}
+	}
+}
+
+// Return a property mapped along what jQuery.cssProps suggests or to
+// a vendor prefixed property.
+function finalPropName( name ) {
+	var ret = jQuery.cssProps[ name ];
+	if ( !ret ) {
+		ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
+	}
+	return ret;
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+
+	// Any relative (+/-) values have already been
+	// normalized at this point
+	var matches = rcssNum.exec( value );
+	return matches ?
+
+		// Guard against undefined "subtract", e.g., when used as in cssHooks
+		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
+		value;
+}
+
+function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
+	var i = dimension === "width" ? 1 : 0,
+		extra = 0,
+		delta = 0;
+
+	// Adjustment may not be necessary
+	if ( box === ( isBorderBox ? "border" : "content" ) ) {
+		return 0;
+	}
+
+	for ( ; i < 4; i += 2 ) {
+
+		// Both box models exclude margin
+		if ( box === "margin" ) {
+			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
+		}
+
+		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
+		if ( !isBorderBox ) {
+
+			// Add padding
+			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+			// For "border" or "margin", add border
+			if ( box !== "padding" ) {
+				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+
+			// But still keep track of it otherwise
+			} else {
+				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+
+		// If we get here with a border-box (content + padding + border), we're seeking "content" or
+		// "padding" or "margin"
+		} else {
+
+			// For "content", subtract padding
+			if ( box === "content" ) {
+				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+			}
+
+			// For "content" or "padding", subtract border
+			if ( box !== "margin" ) {
+				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		}
+	}
+
+	// Account for positive content-box scroll gutter when requested by providing computedVal
+	if ( !isBorderBox && computedVal >= 0 ) {
+
+		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
+		// Assuming integer scroll gutter, subtract the rest and round down
+		delta += Math.max( 0, Math.ceil(
+			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
+			computedVal -
+			delta -
+			extra -
+			0.5
+		) );
+	}
+
+	return delta;
+}
+
+function getWidthOrHeight( elem, dimension, extra ) {
+
+	// Start with computed style
+	var styles = getStyles( elem ),
+		val = curCSS( elem, dimension, styles ),
+		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+		valueIsBorderBox = isBorderBox;
+
+	// Support: Firefox <=54
+	// Return a confounding non-pixel value or feign ignorance, as appropriate.
+	if ( rnumnonpx.test( val ) ) {
+		if ( !extra ) {
+			return val;
+		}
+		val = "auto";
+	}
+
+	// Check for style in case a browser which returns unreliable values
+	// for getComputedStyle silently falls back to the reliable elem.style
+	valueIsBorderBox = valueIsBorderBox &&
+		( support.boxSizingReliable() || val === elem.style[ dimension ] );
+
+	// Fall back to offsetWidth/offsetHeight when value is "auto"
+	// This happens for inline elements with no explicit setting (gh-3571)
+	// Support: Android <=4.1 - 4.3 only
+	// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
+	if ( val === "auto" ||
+		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) {
+
+		val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];
+
+		// offsetWidth/offsetHeight provide border-box values
+		valueIsBorderBox = true;
+	}
+
+	// Normalize "" and auto
+	val = parseFloat( val ) || 0;
+
+	// Adjust for the element's box model
+	return ( val +
+		boxModelAdjustment(
+			elem,
+			dimension,
+			extra || ( isBorderBox ? "border" : "content" ),
+			valueIsBorderBox,
+			styles,
+
+			// Provide the current computed size to request scroll gutter calculation (gh-3589)
+			val
+		)
+	) + "px";
+}
+
+jQuery.extend( {
+
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity" );
+					return ret === "" ? "1" : ret;
+				}
+			}
+		}
+	},
+
+	// Don't automatically add "px" to these possibly-unitless properties
+	cssNumber: {
+		"animationIterationCount": true,
+		"columnCount": true,
+		"fillOpacity": true,
+		"flexGrow": true,
+		"flexShrink": true,
+		"fontWeight": true,
+		"lineHeight": true,
+		"opacity": true,
+		"order": true,
+		"orphans": true,
+		"widows": true,
+		"zIndex": true,
+		"zoom": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, type, hooks,
+			origName = camelCase( name ),
+			isCustomProp = rcustomProp.test( name ),
+			style = elem.style;
+
+		// Make sure that we're working with the right name. We don't
+		// want to query the value if it is a CSS custom property
+		// since they are user-defined.
+		if ( !isCustomProp ) {
+			name = finalPropName( origName );
+		}
+
+		// Gets hook for the prefixed version, then unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			type = typeof value;
+
+			// Convert "+=" or "-=" to relative numbers (#7345)
+			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
+				value = adjustCSS( elem, name, ret );
+
+				// Fixes bug #9237
+				type = "number";
+			}
+
+			// Make sure that null and NaN values aren't set (#7116)
+			if ( value == null || value !== value ) {
+				return;
+			}
+
+			// If a number was passed in, add the unit (except for certain CSS properties)
+			if ( type === "number" ) {
+				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
+			}
+
+			// background-* props affect original clone's values
+			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
+				style[ name ] = "inherit";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !( "set" in hooks ) ||
+				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
+
+				if ( isCustomProp ) {
+					style.setProperty( name, value );
+				} else {
+					style[ name ] = value;
+				}
+			}
+
+		} else {
+
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks &&
+				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
+
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, extra, styles ) {
+		var val, num, hooks,
+			origName = camelCase( name ),
+			isCustomProp = rcustomProp.test( name );
+
+		// Make sure that we're working with the right name. We don't
+		// want to modify the value if it is a CSS custom property
+		// since they are user-defined.
+		if ( !isCustomProp ) {
+			name = finalPropName( origName );
+		}
+
+		// Try prefixed name followed by the unprefixed name
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks ) {
+			val = hooks.get( elem, true, extra );
+		}
+
+		// Otherwise, if a way to get the computed value exists, use that
+		if ( val === undefined ) {
+			val = curCSS( elem, name, styles );
+		}
+
+		// Convert "normal" to computed value
+		if ( val === "normal" && name in cssNormalTransform ) {
+			val = cssNormalTransform[ name ];
+		}
+
+		// Make numeric if forced or a qualifier was provided and val looks numeric
+		if ( extra === "" || extra ) {
+			num = parseFloat( val );
+			return extra === true || isFinite( num ) ? num || 0 : val;
+		}
+
+		return val;
+	}
+} );
+
+jQuery.each( [ "height", "width" ], function( i, dimension ) {
+	jQuery.cssHooks[ dimension ] = {
+		get: function( elem, computed, extra ) {
+			if ( computed ) {
+
+				// Certain elements can have dimension info if we invisibly show them
+				// but it must have a current display style that would benefit
+				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
+
+					// Support: Safari 8+
+					// Table columns in Safari have non-zero offsetWidth & zero
+					// getBoundingClientRect().width unless display is changed.
+					// Support: IE <=11 only
+					// Running getBoundingClientRect on a disconnected node
+					// in IE throws an error.
+					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
+						swap( elem, cssShow, function() {
+							return getWidthOrHeight( elem, dimension, extra );
+						} ) :
+						getWidthOrHeight( elem, dimension, extra );
+			}
+		},
+
+		set: function( elem, value, extra ) {
+			var matches,
+				styles = getStyles( elem ),
+				isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+				subtract = extra && boxModelAdjustment(
+					elem,
+					dimension,
+					extra,
+					isBorderBox,
+					styles
+				);
+
+			// Account for unreliable border-box dimensions by comparing offset* to computed and
+			// faking a content-box to get border and padding (gh-3699)
+			if ( isBorderBox && support.scrollboxSize() === styles.position ) {
+				subtract -= Math.ceil(
+					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
+					parseFloat( styles[ dimension ] ) -
+					boxModelAdjustment( elem, dimension, "border", false, styles ) -
+					0.5
+				);
+			}
+
+			// Convert to pixels if value adjustment is needed
+			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
+				( matches[ 3 ] || "px" ) !== "px" ) {
+
+				elem.style[ dimension ] = value;
+				value = jQuery.css( elem, dimension );
+			}
+
+			return setPositiveNumber( elem, value, subtract );
+		}
+	};
+} );
+
+jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
+	function( elem, computed ) {
+		if ( computed ) {
+			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
+				elem.getBoundingClientRect().left -
+					swap( elem, { marginLeft: 0 }, function() {
+						return elem.getBoundingClientRect().left;
+					} )
+				) + "px";
+		}
+	}
+);
+
+// These hooks are used by animate to expand properties
+jQuery.each( {
+	margin: "",
+	padding: "",
+	border: "Width"
+}, function( prefix, suffix ) {
+	jQuery.cssHooks[ prefix + suffix ] = {
+		expand: function( value ) {
+			var i = 0,
+				expanded = {},
+
+				// Assumes a single number if not a string
+				parts = typeof value === "string" ? value.split( " " ) : [ value ];
+
+			for ( ; i < 4; i++ ) {
+				expanded[ prefix + cssExpand[ i ] + suffix ] =
+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+			}
+
+			return expanded;
+		}
+	};
+
+	if ( prefix !== "margin" ) {
+		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+	}
+} );
+
+jQuery.fn.extend( {
+	css: function( name, value ) {
+		return access( this, function( elem, name, value ) {
+			var styles, len,
+				map = {},
+				i = 0;
+
+			if ( Array.isArray( name ) ) {
+				styles = getStyles( elem );
+				len = name.length;
+
+				for ( ; i < len; i++ ) {
+					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+				}
+
+				return map;
+			}
+
+			return value !== undefined ?
+				jQuery.style( elem, name, value ) :
+				jQuery.css( elem, name );
+		}, name, value, arguments.length > 1 );
+	}
+} );
+
+
+function Tween( elem, options, prop, end, easing ) {
+	return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+	constructor: Tween,
+	init: function( elem, options, prop, end, easing, unit ) {
+		this.elem = elem;
+		this.prop = prop;
+		this.easing = easing || jQuery.easing._default;
+		this.options = options;
+		this.start = this.now = this.cur();
+		this.end = end;
+		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+	},
+	cur: function() {
+		var hooks = Tween.propHooks[ this.prop ];
+
+		return hooks && hooks.get ?
+			hooks.get( this ) :
+			Tween.propHooks._default.get( this );
+	},
+	run: function( percent ) {
+		var eased,
+			hooks = Tween.propHooks[ this.prop ];
+
+		if ( this.options.duration ) {
+			this.pos = eased = jQuery.easing[ this.easing ](
+				percent, this.options.duration * percent, 0, 1, this.options.duration
+			);
+		} else {
+			this.pos = eased = percent;
+		}
+		this.now = ( this.end - this.start ) * eased + this.start;
+
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		if ( hooks && hooks.set ) {
+			hooks.set( this );
+		} else {
+			Tween.propHooks._default.set( this );
+		}
+		return this;
+	}
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+	_default: {
+		get: function( tween ) {
+			var result;
+
+			// Use a property on the element directly when it is not a DOM element,
+			// or when there is no matching style property that exists.
+			if ( tween.elem.nodeType !== 1 ||
+				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
+				return tween.elem[ tween.prop ];
+			}
+
+			// Passing an empty string as a 3rd parameter to .css will automatically
+			// attempt a parseFloat and fallback to a string if the parse fails.
+			// Simple values such as "10px" are parsed to Float;
+			// complex values such as "rotate(1rad)" are returned as-is.
+			result = jQuery.css( tween.elem, tween.prop, "" );
+
+			// Empty strings, null, undefined and "auto" are converted to 0.
+			return !result || result === "auto" ? 0 : result;
+		},
+		set: function( tween ) {
+
+			// Use step hook for back compat.
+			// Use cssHook if its there.
+			// Use .style if available and use plain properties where available.
+			if ( jQuery.fx.step[ tween.prop ] ) {
+				jQuery.fx.step[ tween.prop ]( tween );
+			} else if ( tween.elem.nodeType === 1 &&
+				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
+					jQuery.cssHooks[ tween.prop ] ) ) {
+				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+			} else {
+				tween.elem[ tween.prop ] = tween.now;
+			}
+		}
+	}
+};
+
+// Support: IE <=9 only
+// Panic based approach to setting things on disconnected nodes
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+	set: function( tween ) {
+		if ( tween.elem.nodeType && tween.elem.parentNode ) {
+			tween.elem[ tween.prop ] = tween.now;
+		}
+	}
+};
+
+jQuery.easing = {
+	linear: function( p ) {
+		return p;
+	},
+	swing: function( p ) {
+		return 0.5 - Math.cos( p * Math.PI ) / 2;
+	},
+	_default: "swing"
+};
+
+jQuery.fx = Tween.prototype.init;
+
+// Back compat <1.8 extension point
+jQuery.fx.step = {};
+
+
+
+
+var
+	fxNow, inProgress,
+	rfxtypes = /^(?:toggle|show|hide)$/,
+	rrun = /queueHooks$/;
+
+function schedule() {
+	if ( inProgress ) {
+		if ( document.hidden === false && window.requestAnimationFrame ) {
+			window.requestAnimationFrame( schedule );
+		} else {
+			window.setTimeout( schedule, jQuery.fx.interval );
+		}
+
+		jQuery.fx.tick();
+	}
+}
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+	window.setTimeout( function() {
+		fxNow = undefined;
+	} );
+	return ( fxNow = Date.now() );
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+	var which,
+		i = 0,
+		attrs = { height: type };
+
+	// If we include width, step value is 1 to do all cssExpand values,
+	// otherwise step value is 2 to skip over Left and Right
+	includeWidth = includeWidth ? 1 : 0;
+	for ( ; i < 4; i += 2 - includeWidth ) {
+		which = cssExpand[ i ];
+		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+	}
+
+	if ( includeWidth ) {
+		attrs.opacity = attrs.width = type;
+	}
+
+	return attrs;
+}
+
+function createTween( value, prop, animation ) {
+	var tween,
+		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
+		index = 0,
+		length = collection.length;
+	for ( ; index < length; index++ ) {
+		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
+
+			// We're done with this property
+			return tween;
+		}
+	}
+}
+
+function defaultPrefilter( elem, props, opts ) {
+	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
+		isBox = "width" in props || "height" in props,
+		anim = this,
+		orig = {},
+		style = elem.style,
+		hidden = elem.nodeType && isHiddenWithinTree( elem ),
+		dataShow = dataPriv.get( elem, "fxshow" );
+
+	// Queue-skipping animations hijack the fx hooks
+	if ( !opts.queue ) {
+		hooks = jQuery._queueHooks( elem, "fx" );
+		if ( hooks.unqueued == null ) {
+			hooks.unqueued = 0;
+			oldfire = hooks.empty.fire;
+			hooks.empty.fire = function() {
+				if ( !hooks.unqueued ) {
+					oldfire();
+				}
+			};
+		}
+		hooks.unqueued++;
+
+		anim.always( function() {
+
+			// Ensure the complete handler is called before this completes
+			anim.always( function() {
+				hooks.unqueued--;
+				if ( !jQuery.queue( elem, "fx" ).length ) {
+					hooks.empty.fire();
+				}
+			} );
+		} );
+	}
+
+	// Detect show/hide animations
+	for ( prop in props ) {
+		value = props[ prop ];
+		if ( rfxtypes.test( value ) ) {
+			delete props[ prop ];
+			toggle = toggle || value === "toggle";
+			if ( value === ( hidden ? "hide" : "show" ) ) {
+
+				// Pretend to be hidden if this is a "show" and
+				// there is still data from a stopped show/hide
+				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+					hidden = true;
+
+				// Ignore all other no-op show/hide data
+				} else {
+					continue;
+				}
+			}
+			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+		}
+	}
+
+	// Bail out if this is a no-op like .hide().hide()
+	propTween = !jQuery.isEmptyObject( props );
+	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
+		return;
+	}
+
+	// Restrict "overflow" and "display" styles during box animations
+	if ( isBox && elem.nodeType === 1 ) {
+
+		// Support: IE <=9 - 11, Edge 12 - 15
+		// Record all 3 overflow attributes because IE does not infer the shorthand
+		// from identically-valued overflowX and overflowY and Edge just mirrors
+		// the overflowX value there.
+		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+		// Identify a display type, preferring old show/hide data over the CSS cascade
+		restoreDisplay = dataShow && dataShow.display;
+		if ( restoreDisplay == null ) {
+			restoreDisplay = dataPriv.get( elem, "display" );
+		}
+		display = jQuery.css( elem, "display" );
+		if ( display === "none" ) {
+			if ( restoreDisplay ) {
+				display = restoreDisplay;
+			} else {
+
+				// Get nonempty value(s) by temporarily forcing visibility
+				showHide( [ elem ], true );
+				restoreDisplay = elem.style.display || restoreDisplay;
+				display = jQuery.css( elem, "display" );
+				showHide( [ elem ] );
+			}
+		}
+
+		// Animate inline elements as inline-block
+		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
+			if ( jQuery.css( elem, "float" ) === "none" ) {
+
+				// Restore the original display value at the end of pure show/hide animations
+				if ( !propTween ) {
+					anim.done( function() {
+						style.display = restoreDisplay;
+					} );
+					if ( restoreDisplay == null ) {
+						display = style.display;
+						restoreDisplay = display === "none" ? "" : display;
+					}
+				}
+				style.display = "inline-block";
+			}
+		}
+	}
+
+	if ( opts.overflow ) {
+		style.overflow = "hidden";
+		anim.always( function() {
+			style.overflow = opts.overflow[ 0 ];
+			style.overflowX = opts.overflow[ 1 ];
+			style.overflowY = opts.overflow[ 2 ];
+		} );
+	}
+
+	// Implement show/hide animations
+	propTween = false;
+	for ( prop in orig ) {
+
+		// General show/hide setup for this element animation
+		if ( !propTween ) {
+			if ( dataShow ) {
+				if ( "hidden" in dataShow ) {
+					hidden = dataShow.hidden;
+				}
+			} else {
+				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
+			}
+
+			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
+			if ( toggle ) {
+				dataShow.hidden = !hidden;
+			}
+
+			// Show elements before animating them
+			if ( hidden ) {
+				showHide( [ elem ], true );
+			}
+
+			/* eslint-disable no-loop-func */
+
+			anim.done( function() {
+
+			/* eslint-enable no-loop-func */
+
+				// The final step of a "hide" animation is actually hiding the element
+				if ( !hidden ) {
+					showHide( [ elem ] );
+				}
+				dataPriv.remove( elem, "fxshow" );
+				for ( prop in orig ) {
+					jQuery.style( elem, prop, orig[ prop ] );
+				}
+			} );
+		}
+
+		// Per-property setup
+		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+		if ( !( prop in dataShow ) ) {
+			dataShow[ prop ] = propTween.start;
+			if ( hidden ) {
+				propTween.end = propTween.start;
+				propTween.start = 0;
+			}
+		}
+	}
+}
+
+function propFilter( props, specialEasing ) {
+	var index, name, easing, value, hooks;
+
+	// camelCase, specialEasing and expand cssHook pass
+	for ( index in props ) {
+		name = camelCase( index );
+		easing = specialEasing[ name ];
+		value = props[ index ];
+		if ( Array.isArray( value ) ) {
+			easing = value[ 1 ];
+			value = props[ index ] = value[ 0 ];
+		}
+
+		if ( index !== name ) {
+			props[ name ] = value;
+			delete props[ index ];
+		}
+
+		hooks = jQuery.cssHooks[ name ];
+		if ( hooks && "expand" in hooks ) {
+			value = hooks.expand( value );
+			delete props[ name ];
+
+			// Not quite $.extend, this won't overwrite existing keys.
+			// Reusing 'index' because we have the correct "name"
+			for ( index in value ) {
+				if ( !( index in props ) ) {
+					props[ index ] = value[ index ];
+					specialEasing[ index ] = easing;
+				}
+			}
+		} else {
+			specialEasing[ name ] = easing;
+		}
+	}
+}
+
+function Animation( elem, properties, options ) {
+	var result,
+		stopped,
+		index = 0,
+		length = Animation.prefilters.length,
+		deferred = jQuery.Deferred().always( function() {
+
+			// Don't match elem in the :animated selector
+			delete tick.elem;
+		} ),
+		tick = function() {
+			if ( stopped ) {
+				return false;
+			}
+			var currentTime = fxNow || createFxNow(),
+				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+
+				// Support: Android 2.3 only
+				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
+				temp = remaining / animation.duration || 0,
+				percent = 1 - temp,
+				index = 0,
+				length = animation.tweens.length;
+
+			for ( ; index < length; index++ ) {
+				animation.tweens[ index ].run( percent );
+			}
+
+			deferred.notifyWith( elem, [ animation, percent, remaining ] );
+
+			// If there's more to do, yield
+			if ( percent < 1 && length ) {
+				return remaining;
+			}
+
+			// If this was an empty animation, synthesize a final progress notification
+			if ( !length ) {
+				deferred.notifyWith( elem, [ animation, 1, 0 ] );
+			}
+
+			// Resolve the animation and report its conclusion
+			deferred.resolveWith( elem, [ animation ] );
+			return false;
+		},
+		animation = deferred.promise( {
+			elem: elem,
+			props: jQuery.extend( {}, properties ),
+			opts: jQuery.extend( true, {
+				specialEasing: {},
+				easing: jQuery.easing._default
+			}, options ),
+			originalProperties: properties,
+			originalOptions: options,
+			startTime: fxNow || createFxNow(),
+			duration: options.duration,
+			tweens: [],
+			createTween: function( prop, end ) {
+				var tween = jQuery.Tween( elem, animation.opts, prop, end,
+						animation.opts.specialEasing[ prop ] || animation.opts.easing );
+				animation.tweens.push( tween );
+				return tween;
+			},
+			stop: function( gotoEnd ) {
+				var index = 0,
+
+					// If we are going to the end, we want to run all the tweens
+					// otherwise we skip this part
+					length = gotoEnd ? animation.tweens.length : 0;
+				if ( stopped ) {
+					return this;
+				}
+				stopped = true;
+				for ( ; index < length; index++ ) {
+					animation.tweens[ index ].run( 1 );
+				}
+
+				// Resolve when we played the last frame; otherwise, reject
+				if ( gotoEnd ) {
+					deferred.notifyWith( elem, [ animation, 1, 0 ] );
+					deferred.resolveWith( elem, [ animation, gotoEnd ] );
+				} else {
+					deferred.rejectWith( elem, [ animation, gotoEnd ] );
+				}
+				return this;
+			}
+		} ),
+		props = animation.props;
+
+	propFilter( props, animation.opts.specialEasing );
+
+	for ( ; index < length; index++ ) {
+		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
+		if ( result ) {
+			if ( isFunction( result.stop ) ) {
+				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
+					result.stop.bind( result );
+			}
+			return result;
+		}
+	}
+
+	jQuery.map( props, createTween, animation );
+
+	if ( isFunction( animation.opts.start ) ) {
+		animation.opts.start.call( elem, animation );
+	}
+
+	// Attach callbacks from options
+	animation
+		.progress( animation.opts.progress )
+		.done( animation.opts.done, animation.opts.complete )
+		.fail( animation.opts.fail )
+		.always( animation.opts.always );
+
+	jQuery.fx.timer(
+		jQuery.extend( tick, {
+			elem: elem,
+			anim: animation,
+			queue: animation.opts.queue
+		} )
+	);
+
+	return animation;
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+	tweeners: {
+		"*": [ function( prop, value ) {
+			var tween = this.createTween( prop, value );
+			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
+			return tween;
+		} ]
+	},
+
+	tweener: function( props, callback ) {
+		if ( isFunction( props ) ) {
+			callback = props;
+			props = [ "*" ];
+		} else {
+			props = props.match( rnothtmlwhite );
+		}
+
+		var prop,
+			index = 0,
+			length = props.length;
+
+		for ( ; index < length; index++ ) {
+			prop = props[ index ];
+			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
+			Animation.tweeners[ prop ].unshift( callback );
+		}
+	},
+
+	prefilters: [ defaultPrefilter ],
+
+	prefilter: function( callback, prepend ) {
+		if ( prepend ) {
+			Animation.prefilters.unshift( callback );
+		} else {
+			Animation.prefilters.push( callback );
+		}
+	}
+} );
+
+jQuery.speed = function( speed, easing, fn ) {
+	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+		complete: fn || !fn && easing ||
+			isFunction( speed ) && speed,
+		duration: speed,
+		easing: fn && easing || easing && !isFunction( easing ) && easing
+	};
+
+	// Go to the end state if fx are off
+	if ( jQuery.fx.off ) {
+		opt.duration = 0;
+
+	} else {
+		if ( typeof opt.duration !== "number" ) {
+			if ( opt.duration in jQuery.fx.speeds ) {
+				opt.duration = jQuery.fx.speeds[ opt.duration ];
+
+			} else {
+				opt.duration = jQuery.fx.speeds._default;
+			}
+		}
+	}
+
+	// Normalize opt.queue - true/undefined/null -> "fx"
+	if ( opt.queue == null || opt.queue === true ) {
+		opt.queue = "fx";
+	}
+
+	// Queueing
+	opt.old = opt.complete;
+
+	opt.complete = function() {
+		if ( isFunction( opt.old ) ) {
+			opt.old.call( this );
+		}
+
+		if ( opt.queue ) {
+			jQuery.dequeue( this, opt.queue );
+		}
+	};
+
+	return opt;
+};
+
+jQuery.fn.extend( {
+	fadeTo: function( speed, to, easing, callback ) {
+
+		// Show any hidden elements after setting opacity to 0
+		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
+
+			// Animate to the value specified
+			.end().animate( { opacity: to }, speed, easing, callback );
+	},
+	animate: function( prop, speed, easing, callback ) {
+		var empty = jQuery.isEmptyObject( prop ),
+			optall = jQuery.speed( speed, easing, callback ),
+			doAnimation = function() {
+
+				// Operate on a copy of prop so per-property easing won't be lost
+				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+				// Empty animations, or finishing resolves immediately
+				if ( empty || dataPriv.get( this, "finish" ) ) {
+					anim.stop( true );
+				}
+			};
+			doAnimation.finish = doAnimation;
+
+		return empty || optall.queue === false ?
+			this.each( doAnimation ) :
+			this.queue( optall.queue, doAnimation );
+	},
+	stop: function( type, clearQueue, gotoEnd ) {
+		var stopQueue = function( hooks ) {
+			var stop = hooks.stop;
+			delete hooks.stop;
+			stop( gotoEnd );
+		};
+
+		if ( typeof type !== "string" ) {
+			gotoEnd = clearQueue;
+			clearQueue = type;
+			type = undefined;
+		}
+		if ( clearQueue && type !== false ) {
+			this.queue( type || "fx", [] );
+		}
+
+		return this.each( function() {
+			var dequeue = true,
+				index = type != null && type + "queueHooks",
+				timers = jQuery.timers,
+				data = dataPriv.get( this );
+
+			if ( index ) {
+				if ( data[ index ] && data[ index ].stop ) {
+					stopQueue( data[ index ] );
+				}
+			} else {
+				for ( index in data ) {
+					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+						stopQueue( data[ index ] );
+					}
+				}
+			}
+
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this &&
+					( type == null || timers[ index ].queue === type ) ) {
+
+					timers[ index ].anim.stop( gotoEnd );
+					dequeue = false;
+					timers.splice( index, 1 );
+				}
+			}
+
+			// Start the next in the queue if the last step wasn't forced.
+			// Timers currently will call their complete callbacks, which
+			// will dequeue but only if they were gotoEnd.
+			if ( dequeue || !gotoEnd ) {
+				jQuery.dequeue( this, type );
+			}
+		} );
+	},
+	finish: function( type ) {
+		if ( type !== false ) {
+			type = type || "fx";
+		}
+		return this.each( function() {
+			var index,
+				data = dataPriv.get( this ),
+				queue = data[ type + "queue" ],
+				hooks = data[ type + "queueHooks" ],
+				timers = jQuery.timers,
+				length = queue ? queue.length : 0;
+
+			// Enable finishing flag on private data
+			data.finish = true;
+
+			// Empty the queue first
+			jQuery.queue( this, type, [] );
+
+			if ( hooks && hooks.stop ) {
+				hooks.stop.call( this, true );
+			}
+
+			// Look for any active animations, and finish them
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+					timers[ index ].anim.stop( true );
+					timers.splice( index, 1 );
+				}
+			}
+
+			// Look for any animations in the old queue and finish them
+			for ( index = 0; index < length; index++ ) {
+				if ( queue[ index ] && queue[ index ].finish ) {
+					queue[ index ].finish.call( this );
+				}
+			}
+
+			// Turn off finishing flag
+			delete data.finish;
+		} );
+	}
+} );
+
+jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
+	var cssFn = jQuery.fn[ name ];
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return speed == null || typeof speed === "boolean" ?
+			cssFn.apply( this, arguments ) :
+			this.animate( genFx( name, true ), speed, easing, callback );
+	};
+} );
+
+// Generate shortcuts for custom animations
+jQuery.each( {
+	slideDown: genFx( "show" ),
+	slideUp: genFx( "hide" ),
+	slideToggle: genFx( "toggle" ),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" },
+	fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, easing, callback ) {
+		return this.animate( props, speed, easing, callback );
+	};
+} );
+
+jQuery.timers = [];
+jQuery.fx.tick = function() {
+	var timer,
+		i = 0,
+		timers = jQuery.timers;
+
+	fxNow = Date.now();
+
+	for ( ; i < timers.length; i++ ) {
+		timer = timers[ i ];
+
+		// Run the timer and safely remove it when done (allowing for external removal)
+		if ( !timer() && timers[ i ] === timer ) {
+			timers.splice( i--, 1 );
+		}
+	}
+
+	if ( !timers.length ) {
+		jQuery.fx.stop();
+	}
+	fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+	jQuery.timers.push( timer );
+	jQuery.fx.start();
+};
+
+jQuery.fx.interval = 13;
+jQuery.fx.start = function() {
+	if ( inProgress ) {
+		return;
+	}
+
+	inProgress = true;
+	schedule();
+};
+
+jQuery.fx.stop = function() {
+	inProgress = null;
+};
+
+jQuery.fx.speeds = {
+	slow: 600,
+	fast: 200,
+
+	// Default speed
+	_default: 400
+};
+
+
+// Based off of the plugin by Clint Helfers, with permission.
+// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
+jQuery.fn.delay = function( time, type ) {
+	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+	type = type || "fx";
+
+	return this.queue( type, function( next, hooks ) {
+		var timeout = window.setTimeout( next, time );
+		hooks.stop = function() {
+			window.clearTimeout( timeout );
+		};
+	} );
+};
+
+
+( function() {
+	var input = document.createElement( "input" ),
+		select = document.createElement( "select" ),
+		opt = select.appendChild( document.createElement( "option" ) );
+
+	input.type = "checkbox";
+
+	// Support: Android <=4.3 only
+	// Default value for a checkbox should be "on"
+	support.checkOn = input.value !== "";
+
+	// Support: IE <=11 only
+	// Must access selectedIndex to make default options select
+	support.optSelected = opt.selected;
+
+	// Support: IE <=11 only
+	// An input loses its value after becoming a radio
+	input = document.createElement( "input" );
+	input.value = "t";
+	input.type = "radio";
+	support.radioValue = input.value === "t";
+} )();
+
+
+var boolHook,
+	attrHandle = jQuery.expr.attrHandle;
+
+jQuery.fn.extend( {
+	attr: function( name, value ) {
+		return access( this, jQuery.attr, name, value, arguments.length > 1 );
+	},
+
+	removeAttr: function( name ) {
+		return this.each( function() {
+			jQuery.removeAttr( this, name );
+		} );
+	}
+} );
+
+jQuery.extend( {
+	attr: function( elem, name, value ) {
+		var ret, hooks,
+			nType = elem.nodeType;
+
+		// Don't get/set attributes on text, comment and attribute nodes
+		if ( nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( typeof elem.getAttribute === "undefined" ) {
+			return jQuery.prop( elem, name, value );
+		}
+
+		// Attribute hooks are determined by the lowercase version
+		// Grab necessary hook if one is defined
+		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
+				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
+		}
+
+		if ( value !== undefined ) {
+			if ( value === null ) {
+				jQuery.removeAttr( elem, name );
+				return;
+			}
+
+			if ( hooks && "set" in hooks &&
+				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+				return ret;
+			}
+
+			elem.setAttribute( name, value + "" );
+			return value;
+		}
+
+		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+			return ret;
+		}
+
+		ret = jQuery.find.attr( elem, name );
+
+		// Non-existent attributes return null, we normalize to undefined
+		return ret == null ? undefined : ret;
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				if ( !support.radioValue && value === "radio" &&
+					nodeName( elem, "input" ) ) {
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return value;
+				}
+			}
+		}
+	},
+
+	removeAttr: function( elem, value ) {
+		var name,
+			i = 0,
+
+			// Attribute names can contain non-HTML whitespace characters
+			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+			attrNames = value && value.match( rnothtmlwhite );
+
+		if ( attrNames && elem.nodeType === 1 ) {
+			while ( ( name = attrNames[ i++ ] ) ) {
+				elem.removeAttribute( name );
+			}
+		}
+	}
+} );
+
+// Hooks for boolean attributes
+boolHook = {
+	set: function( elem, value, name ) {
+		if ( value === false ) {
+
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else {
+			elem.setAttribute( name, name );
+		}
+		return name;
+	}
+};
+
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+	var getter = attrHandle[ name ] || jQuery.find.attr;
+
+	attrHandle[ name ] = function( elem, name, isXML ) {
+		var ret, handle,
+			lowercaseName = name.toLowerCase();
+
+		if ( !isXML ) {
+
+			// Avoid an infinite loop by temporarily removing this function from the getter
+			handle = attrHandle[ lowercaseName ];
+			attrHandle[ lowercaseName ] = ret;
+			ret = getter( elem, name, isXML ) != null ?
+				lowercaseName :
+				null;
+			attrHandle[ lowercaseName ] = handle;
+		}
+		return ret;
+	};
+} );
+
+
+
+
+var rfocusable = /^(?:input|select|textarea|button)$/i,
+	rclickable = /^(?:a|area)$/i;
+
+jQuery.fn.extend( {
+	prop: function( name, value ) {
+		return access( this, jQuery.prop, name, value, arguments.length > 1 );
+	},
+
+	removeProp: function( name ) {
+		return this.each( function() {
+			delete this[ jQuery.propFix[ name ] || name ];
+		} );
+	}
+} );
+
+jQuery.extend( {
+	prop: function( elem, name, value ) {
+		var ret, hooks,
+			nType = elem.nodeType;
+
+		// Don't get/set properties on text, comment and attribute nodes
+		if ( nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+
+			// Fix name and attach hooks
+			name = jQuery.propFix[ name ] || name;
+			hooks = jQuery.propHooks[ name ];
+		}
+
+		if ( value !== undefined ) {
+			if ( hooks && "set" in hooks &&
+				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+				return ret;
+			}
+
+			return ( elem[ name ] = value );
+		}
+
+		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+			return ret;
+		}
+
+		return elem[ name ];
+	},
+
+	propHooks: {
+		tabIndex: {
+			get: function( elem ) {
+
+				// Support: IE <=9 - 11 only
+				// elem.tabIndex doesn't always return the
+				// correct value when it hasn't been explicitly set
+				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				// Use proper attribute retrieval(#12072)
+				var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+				if ( tabindex ) {
+					return parseInt( tabindex, 10 );
+				}
+
+				if (
+					rfocusable.test( elem.nodeName ) ||
+					rclickable.test( elem.nodeName ) &&
+					elem.href
+				) {
+					return 0;
+				}
+
+				return -1;
+			}
+		}
+	},
+
+	propFix: {
+		"for": "htmlFor",
+		"class": "className"
+	}
+} );
+
+// Support: IE <=11 only
+// Accessing the selectedIndex property
+// forces the browser to respect setting selected
+// on the option
+// The getter ensures a default option is selected
+// when in an optgroup
+// eslint rule "no-unused-expressions" is disabled for this code
+// since it considers such accessions noop
+if ( !support.optSelected ) {
+	jQuery.propHooks.selected = {
+		get: function( elem ) {
+
+			/* eslint no-unused-expressions: "off" */
+
+			var parent = elem.parentNode;
+			if ( parent && parent.parentNode ) {
+				parent.parentNode.selectedIndex;
+			}
+			return null;
+		},
+		set: function( elem ) {
+
+			/* eslint no-unused-expressions: "off" */
+
+			var parent = elem.parentNode;
+			if ( parent ) {
+				parent.selectedIndex;
+
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+		}
+	};
+}
+
+jQuery.each( [
+	"tabIndex",
+	"readOnly",
+	"maxLength",
+	"cellSpacing",
+	"cellPadding",
+	"rowSpan",
+	"colSpan",
+	"useMap",
+	"frameBorder",
+	"contentEditable"
+], function() {
+	jQuery.propFix[ this.toLowerCase() ] = this;
+} );
+
+
+
+
+	// Strip and collapse whitespace according to HTML spec
+	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
+	function stripAndCollapse( value ) {
+		var tokens = value.match( rnothtmlwhite ) || [];
+		return tokens.join( " " );
+	}
+
+
+function getClass( elem ) {
+	return elem.getAttribute && elem.getAttribute( "class" ) || "";
+}
+
+function classesToArray( value ) {
+	if ( Array.isArray( value ) ) {
+		return value;
+	}
+	if ( typeof value === "string" ) {
+		return value.match( rnothtmlwhite ) || [];
+	}
+	return [];
+}
+
+jQuery.fn.extend( {
+	addClass: function( value ) {
+		var classes, elem, cur, curValue, clazz, j, finalValue,
+			i = 0;
+
+		if ( isFunction( value ) ) {
+			return this.each( function( j ) {
+				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
+			} );
+		}
+
+		classes = classesToArray( value );
+
+		if ( classes.length ) {
+			while ( ( elem = this[ i++ ] ) ) {
+				curValue = getClass( elem );
+				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+				if ( cur ) {
+					j = 0;
+					while ( ( clazz = classes[ j++ ] ) ) {
+						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+							cur += clazz + " ";
+						}
+					}
+
+					// Only assign if different to avoid unneeded rendering.
+					finalValue = stripAndCollapse( cur );
+					if ( curValue !== finalValue ) {
+						elem.setAttribute( "class", finalValue );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		var classes, elem, cur, curValue, clazz, j, finalValue,
+			i = 0;
+
+		if ( isFunction( value ) ) {
+			return this.each( function( j ) {
+				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
+			} );
+		}
+
+		if ( !arguments.length ) {
+			return this.attr( "class", "" );
+		}
+
+		classes = classesToArray( value );
+
+		if ( classes.length ) {
+			while ( ( elem = this[ i++ ] ) ) {
+				curValue = getClass( elem );
+
+				// This expression is here for better compressibility (see addClass)
+				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+				if ( cur ) {
+					j = 0;
+					while ( ( clazz = classes[ j++ ] ) ) {
+
+						// Remove *all* instances
+						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
+							cur = cur.replace( " " + clazz + " ", " " );
+						}
+					}
+
+					// Only assign if different to avoid unneeded rendering.
+					finalValue = stripAndCollapse( cur );
+					if ( curValue !== finalValue ) {
+						elem.setAttribute( "class", finalValue );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value,
+			isValidValue = type === "string" || Array.isArray( value );
+
+		if ( typeof stateVal === "boolean" && isValidValue ) {
+			return stateVal ? this.addClass( value ) : this.removeClass( value );
+		}
+
+		if ( isFunction( value ) ) {
+			return this.each( function( i ) {
+				jQuery( this ).toggleClass(
+					value.call( this, i, getClass( this ), stateVal ),
+					stateVal
+				);
+			} );
+		}
+
+		return this.each( function() {
+			var className, i, self, classNames;
+
+			if ( isValidValue ) {
+
+				// Toggle individual class names
+				i = 0;
+				self = jQuery( this );
+				classNames = classesToArray( value );
+
+				while ( ( className = classNames[ i++ ] ) ) {
+
+					// Check each className given, space separated list
+					if ( self.hasClass( className ) ) {
+						self.removeClass( className );
+					} else {
+						self.addClass( className );
+					}
+				}
+
+			// Toggle whole class name
+			} else if ( value === undefined || type === "boolean" ) {
+				className = getClass( this );
+				if ( className ) {
+
+					// Store className if set
+					dataPriv.set( this, "__className__", className );
+				}
+
+				// If the element has a class name or if we're passed `false`,
+				// then remove the whole classname (if there was one, the above saved it).
+				// Otherwise bring back whatever was previously saved (if anything),
+				// falling back to the empty string if nothing was stored.
+				if ( this.setAttribute ) {
+					this.setAttribute( "class",
+						className || value === false ?
+						"" :
+						dataPriv.get( this, "__className__" ) || ""
+					);
+				}
+			}
+		} );
+	},
+
+	hasClass: function( selector ) {
+		var className, elem,
+			i = 0;
+
+		className = " " + selector + " ";
+		while ( ( elem = this[ i++ ] ) ) {
+			if ( elem.nodeType === 1 &&
+				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
+					return true;
+			}
+		}
+
+		return false;
+	}
+} );
+
+
+
+
+var rreturn = /\r/g;
+
+jQuery.fn.extend( {
+	val: function( value ) {
+		var hooks, ret, valueIsFunction,
+			elem = this[ 0 ];
+
+		if ( !arguments.length ) {
+			if ( elem ) {
+				hooks = jQuery.valHooks[ elem.type ] ||
+					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+				if ( hooks &&
+					"get" in hooks &&
+					( ret = hooks.get( elem, "value" ) ) !== undefined
+				) {
+					return ret;
+				}
+
+				ret = elem.value;
+
+				// Handle most common string cases
+				if ( typeof ret === "string" ) {
+					return ret.replace( rreturn, "" );
+				}
+
+				// Handle cases where value is null/undef or number
+				return ret == null ? "" : ret;
+			}
+
+			return;
+		}
+
+		valueIsFunction = isFunction( value );
+
+		return this.each( function( i ) {
+			var val;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( valueIsFunction ) {
+				val = value.call( this, i, jQuery( this ).val() );
+			} else {
+				val = value;
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+
+			} else if ( typeof val === "number" ) {
+				val += "";
+
+			} else if ( Array.isArray( val ) ) {
+				val = jQuery.map( val, function( value ) {
+					return value == null ? "" : value + "";
+				} );
+			}
+
+			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+			// If set returns undefined, fall back to normal setting
+			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
+				this.value = val;
+			}
+		} );
+	}
+} );
+
+jQuery.extend( {
+	valHooks: {
+		option: {
+			get: function( elem ) {
+
+				var val = jQuery.find.attr( elem, "value" );
+				return val != null ?
+					val :
+
+					// Support: IE <=10 - 11 only
+					// option.text throws exceptions (#14686, #14858)
+					// Strip and collapse whitespace
+					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+					stripAndCollapse( jQuery.text( elem ) );
+			}
+		},
+		select: {
+			get: function( elem ) {
+				var value, option, i,
+					options = elem.options,
+					index = elem.selectedIndex,
+					one = elem.type === "select-one",
+					values = one ? null : [],
+					max = one ? index + 1 : options.length;
+
+				if ( index < 0 ) {
+					i = max;
+
+				} else {
+					i = one ? index : 0;
+				}
+
+				// Loop through all the selected options
+				for ( ; i < max; i++ ) {
+					option = options[ i ];
+
+					// Support: IE <=9 only
+					// IE8-9 doesn't update selected after form reset (#2551)
+					if ( ( option.selected || i === index ) &&
+
+							// Don't return options that are disabled or in a disabled optgroup
+							!option.disabled &&
+							( !option.parentNode.disabled ||
+								!nodeName( option.parentNode, "optgroup" ) ) ) {
+
+						// Get the specific value for the option
+						value = jQuery( option ).val();
+
+						// We don't need an array for one selects
+						if ( one ) {
+							return value;
+						}
+
+						// Multi-Selects return an array
+						values.push( value );
+					}
+				}
+
+				return values;
+			},
+
+			set: function( elem, value ) {
+				var optionSet, option,
+					options = elem.options,
+					values = jQuery.makeArray( value ),
+					i = options.length;
+
+				while ( i-- ) {
+					option = options[ i ];
+
+					/* eslint-disable no-cond-assign */
+
+					if ( option.selected =
+						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
+					) {
+						optionSet = true;
+					}
+
+					/* eslint-enable no-cond-assign */
+				}
+
+				// Force browsers to behave consistently when non-matching value is set
+				if ( !optionSet ) {
+					elem.selectedIndex = -1;
+				}
+				return values;
+			}
+		}
+	}
+} );
+
+// Radios and checkboxes getter/setter
+jQuery.each( [ "radio", "checkbox" ], function() {
+	jQuery.valHooks[ this ] = {
+		set: function( elem, value ) {
+			if ( Array.isArray( value ) ) {
+				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
+			}
+		}
+	};
+	if ( !support.checkOn ) {
+		jQuery.valHooks[ this ].get = function( elem ) {
+			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
+		};
+	}
+} );
+
+
+
+
+// Return jQuery for attributes-only inclusion
+
+
+support.focusin = "onfocusin" in window;
+
+
+var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+	stopPropagationCallback = function( e ) {
+		e.stopPropagation();
+	};
+
+jQuery.extend( jQuery.event, {
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+
+		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
+			eventPath = [ elem || document ],
+			type = hasOwn.call( event, "type" ) ? event.type : event,
+			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
+
+		cur = lastElement = tmp = elem = elem || document;
+
+		// Don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// focus/blur morphs to focusin/out; ensure we're not firing them right now
+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+			return;
+		}
+
+		if ( type.indexOf( "." ) > -1 ) {
+
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split( "." );
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+		ontype = type.indexOf( ":" ) < 0 && "on" + type;
+
+		// Caller can pass in a jQuery.Event object, Object, or just an event type string
+		event = event[ jQuery.expando ] ?
+			event :
+			new jQuery.Event( type, typeof event === "object" && event );
+
+		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+		event.isTrigger = onlyHandlers ? 2 : 3;
+		event.namespace = namespaces.join( "." );
+		event.rnamespace = event.namespace ?
+			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
+			null;
+
+		// Clean up the event in case it is being reused
+		event.result = undefined;
+		if ( !event.target ) {
+			event.target = elem;
+		}
+
+		// Clone any incoming data and prepend the event, creating the handler arg list
+		data = data == null ?
+			[ event ] :
+			jQuery.makeArray( data, [ event ] );
+
+		// Allow special events to draw outside the lines
+		special = jQuery.event.special[ type ] || {};
+		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+			return;
+		}
+
+		// Determine event propagation path in advance, per W3C events spec (#9951)
+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
+
+			bubbleType = special.delegateType || type;
+			if ( !rfocusMorph.test( bubbleType + type ) ) {
+				cur = cur.parentNode;
+			}
+			for ( ; cur; cur = cur.parentNode ) {
+				eventPath.push( cur );
+				tmp = cur;
+			}
+
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
+			if ( tmp === ( elem.ownerDocument || document ) ) {
+				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+			}
+		}
+
+		// Fire handlers on the event path
+		i = 0;
+		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
+			lastElement = cur;
+			event.type = i > 1 ?
+				bubbleType :
+				special.bindType || type;
+
+			// jQuery handler
+			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
+				dataPriv.get( cur, "handle" );
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+
+			// Native handler
+			handle = ontype && cur[ ontype ];
+			if ( handle && handle.apply && acceptData( cur ) ) {
+				event.result = handle.apply( cur, data );
+				if ( event.result === false ) {
+					event.preventDefault();
+				}
+			}
+		}
+		event.type = type;
+
+		// If nobody prevented the default action, do it now
+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+			if ( ( !special._default ||
+				special._default.apply( eventPath.pop(), data ) === false ) &&
+				acceptData( elem ) ) {
+
+				// Call a native DOM method on the target with the same name as the event.
+				// Don't do default actions on window, that's where global variables be (#6170)
+				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
+
+					// Don't re-trigger an onFOO event when we call its FOO() method
+					tmp = elem[ ontype ];
+
+					if ( tmp ) {
+						elem[ ontype ] = null;
+					}
+
+					// Prevent re-triggering of the same event, since we already bubbled it above
+					jQuery.event.triggered = type;
+
+					if ( event.isPropagationStopped() ) {
+						lastElement.addEventListener( type, stopPropagationCallback );
+					}
+
+					elem[ type ]();
+
+					if ( event.isPropagationStopped() ) {
+						lastElement.removeEventListener( type, stopPropagationCallback );
+					}
+
+					jQuery.event.triggered = undefined;
+
+					if ( tmp ) {
+						elem[ ontype ] = tmp;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	// Piggyback on a donor event to simulate a different one
+	// Used only for `focus(in | out)` events
+	simulate: function( type, elem, event ) {
+		var e = jQuery.extend(
+			new jQuery.Event(),
+			event,
+			{
+				type: type,
+				isSimulated: true
+			}
+		);
+
+		jQuery.event.trigger( e, null, elem );
+	}
+
+} );
+
+jQuery.fn.extend( {
+
+	trigger: function( type, data ) {
+		return this.each( function() {
+			jQuery.event.trigger( type, data, this );
+		} );
+	},
+	triggerHandler: function( type, data ) {
+		var elem = this[ 0 ];
+		if ( elem ) {
+			return jQuery.event.trigger( type, data, elem, true );
+		}
+	}
+} );
+
+
+// Support: Firefox <=44
+// Firefox doesn't have focus(in | out) events
+// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+//
+// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
+// focus(in | out) events fire after focus & blur events,
+// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
+// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
+if ( !support.focusin ) {
+	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+		// Attach a single capturing handler on the document while someone wants focusin/focusout
+		var handler = function( event ) {
+			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
+		};
+
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				var doc = this.ownerDocument || this,
+					attaches = dataPriv.access( doc, fix );
+
+				if ( !attaches ) {
+					doc.addEventListener( orig, handler, true );
+				}
+				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
+			},
+			teardown: function() {
+				var doc = this.ownerDocument || this,
+					attaches = dataPriv.access( doc, fix ) - 1;
+
+				if ( !attaches ) {
+					doc.removeEventListener( orig, handler, true );
+					dataPriv.remove( doc, fix );
+
+				} else {
+					dataPriv.access( doc, fix, attaches );
+				}
+			}
+		};
+	} );
+}
+var location = window.location;
+
+var nonce = Date.now();
+
+var rquery = ( /\?/ );
+
+
+
+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+	var xml;
+	if ( !data || typeof data !== "string" ) {
+		return null;
+	}
+
+	// Support: IE 9 - 11 only
+	// IE throws on parseFromString with invalid input.
+	try {
+		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
+	} catch ( e ) {
+		xml = undefined;
+	}
+
+	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+		jQuery.error( "Invalid XML: " + data );
+	}
+	return xml;
+};
+
+
+var
+	rbracket = /\[\]$/,
+	rCRLF = /\r?\n/g,
+	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+	rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+	var name;
+
+	if ( Array.isArray( obj ) ) {
+
+		// Serialize array item.
+		jQuery.each( obj, function( i, v ) {
+			if ( traditional || rbracket.test( prefix ) ) {
+
+				// Treat each array item as a scalar.
+				add( prefix, v );
+
+			} else {
+
+				// Item is non-scalar (array or object), encode its numeric index.
+				buildParams(
+					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
+					v,
+					traditional,
+					add
+				);
+			}
+		} );
+
+	} else if ( !traditional && toType( obj ) === "object" ) {
+
+		// Serialize object item.
+		for ( name in obj ) {
+			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+		}
+
+	} else {
+
+		// Serialize scalar item.
+		add( prefix, obj );
+	}
+}
+
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+	var prefix,
+		s = [],
+		add = function( key, valueOrFunction ) {
+
+			// If value is a function, invoke it and use its return value
+			var value = isFunction( valueOrFunction ) ?
+				valueOrFunction() :
+				valueOrFunction;
+
+			s[ s.length ] = encodeURIComponent( key ) + "=" +
+				encodeURIComponent( value == null ? "" : value );
+		};
+
+	// If an array was passed in, assume that it is an array of form elements.
+	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+
+		// Serialize the form elements
+		jQuery.each( a, function() {
+			add( this.name, this.value );
+		} );
+
+	} else {
+
+		// If traditional, encode the "old" way (the way 1.3.2 or older
+		// did it), otherwise encode params recursively.
+		for ( prefix in a ) {
+			buildParams( prefix, a[ prefix ], traditional, add );
+		}
+	}
+
+	// Return the resulting serialization
+	return s.join( "&" );
+};
+
+jQuery.fn.extend( {
+	serialize: function() {
+		return jQuery.param( this.serializeArray() );
+	},
+	serializeArray: function() {
+		return this.map( function() {
+
+			// Can add propHook for "elements" to filter or add form elements
+			var elements = jQuery.prop( this, "elements" );
+			return elements ? jQuery.makeArray( elements ) : this;
+		} )
+		.filter( function() {
+			var type = this.type;
+
+			// Use .is( ":disabled" ) so that fieldset[disabled] works
+			return this.name && !jQuery( this ).is( ":disabled" ) &&
+				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+				( this.checked || !rcheckableType.test( type ) );
+		} )
+		.map( function( i, elem ) {
+			var val = jQuery( this ).val();
+
+			if ( val == null ) {
+				return null;
+			}
+
+			if ( Array.isArray( val ) ) {
+				return jQuery.map( val, function( val ) {
+					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+				} );
+			}
+
+			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+		} ).get();
+	}
+} );
+
+
+var
+	r20 = /%20/g,
+	rhash = /#.*$/,
+	rantiCache = /([?&])_=[^&]*/,
+	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
+
+	// #7653, #8125, #8152: local protocol detection
+	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+	rnoContent = /^(?:GET|HEAD)$/,
+	rprotocol = /^\/\//,
+
+	/* Prefilters
+	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+	 * 2) These are called:
+	 *    - BEFORE asking for a transport
+	 *    - AFTER param serialization (s.data is a string if s.processData is true)
+	 * 3) key is the dataType
+	 * 4) the catchall symbol "*" can be used
+	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+	 */
+	prefilters = {},
+
+	/* Transports bindings
+	 * 1) key is the dataType
+	 * 2) the catchall symbol "*" can be used
+	 * 3) selection will start with transport dataType and THEN go to "*" if needed
+	 */
+	transports = {},
+
+	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+	allTypes = "*/".concat( "*" ),
+
+	// Anchor tag for parsing the document origin
+	originAnchor = document.createElement( "a" );
+	originAnchor.href = location.href;
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+	// dataTypeExpression is optional and defaults to "*"
+	return function( dataTypeExpression, func ) {
+
+		if ( typeof dataTypeExpression !== "string" ) {
+			func = dataTypeExpression;
+			dataTypeExpression = "*";
+		}
+
+		var dataType,
+			i = 0,
+			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
+
+		if ( isFunction( func ) ) {
+
+			// For each dataType in the dataTypeExpression
+			while ( ( dataType = dataTypes[ i++ ] ) ) {
+
+				// Prepend if requested
+				if ( dataType[ 0 ] === "+" ) {
+					dataType = dataType.slice( 1 ) || "*";
+					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
+
+				// Otherwise append
+				} else {
+					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
+				}
+			}
+		}
+	};
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+	var inspected = {},
+		seekingTransport = ( structure === transports );
+
+	function inspect( dataType ) {
+		var selected;
+		inspected[ dataType ] = true;
+		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+			if ( typeof dataTypeOrTransport === "string" &&
+				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+
+				options.dataTypes.unshift( dataTypeOrTransport );
+				inspect( dataTypeOrTransport );
+				return false;
+			} else if ( seekingTransport ) {
+				return !( selected = dataTypeOrTransport );
+			}
+		} );
+		return selected;
+	}
+
+	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+	var key, deep,
+		flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+	for ( key in src ) {
+		if ( src[ key ] !== undefined ) {
+			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+		}
+	}
+	if ( deep ) {
+		jQuery.extend( true, target, deep );
+	}
+
+	return target;
+}
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+	var ct, type, finalDataType, firstDataType,
+		contents = s.contents,
+		dataTypes = s.dataTypes;
+
+	// Remove auto dataType and get content-type in the process
+	while ( dataTypes[ 0 ] === "*" ) {
+		dataTypes.shift();
+		if ( ct === undefined ) {
+			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
+		}
+	}
+
+	// Check if we're dealing with a known content-type
+	if ( ct ) {
+		for ( type in contents ) {
+			if ( contents[ type ] && contents[ type ].test( ct ) ) {
+				dataTypes.unshift( type );
+				break;
+			}
+		}
+	}
+
+	// Check to see if we have a response for the expected dataType
+	if ( dataTypes[ 0 ] in responses ) {
+		finalDataType = dataTypes[ 0 ];
+	} else {
+
+		// Try convertible dataTypes
+		for ( type in responses ) {
+			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
+				finalDataType = type;
+				break;
+			}
+			if ( !firstDataType ) {
+				firstDataType = type;
+			}
+		}
+
+		// Or just use first one
+		finalDataType = finalDataType || firstDataType;
+	}
+
+	// If we found a dataType
+	// We add the dataType to the list if needed
+	// and return the corresponding response
+	if ( finalDataType ) {
+		if ( finalDataType !== dataTypes[ 0 ] ) {
+			dataTypes.unshift( finalDataType );
+		}
+		return responses[ finalDataType ];
+	}
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+	var conv2, current, conv, tmp, prev,
+		converters = {},
+
+		// Work with a copy of dataTypes in case we need to modify it for conversion
+		dataTypes = s.dataTypes.slice();
+
+	// Create converters map with lowercased keys
+	if ( dataTypes[ 1 ] ) {
+		for ( conv in s.converters ) {
+			converters[ conv.toLowerCase() ] = s.converters[ conv ];
+		}
+	}
+
+	current = dataTypes.shift();
+
+	// Convert to each sequential dataType
+	while ( current ) {
+
+		if ( s.responseFields[ current ] ) {
+			jqXHR[ s.responseFields[ current ] ] = response;
+		}
+
+		// Apply the dataFilter if provided
+		if ( !prev && isSuccess && s.dataFilter ) {
+			response = s.dataFilter( response, s.dataType );
+		}
+
+		prev = current;
+		current = dataTypes.shift();
+
+		if ( current ) {
+
+			// There's only work to do if current dataType is non-auto
+			if ( current === "*" ) {
+
+				current = prev;
+
+			// Convert response if prev dataType is non-auto and differs from current
+			} else if ( prev !== "*" && prev !== current ) {
+
+				// Seek a direct converter
+				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+				// If none found, seek a pair
+				if ( !conv ) {
+					for ( conv2 in converters ) {
+
+						// If conv2 outputs current
+						tmp = conv2.split( " " );
+						if ( tmp[ 1 ] === current ) {
+
+							// If prev can be converted to accepted input
+							conv = converters[ prev + " " + tmp[ 0 ] ] ||
+								converters[ "* " + tmp[ 0 ] ];
+							if ( conv ) {
+
+								// Condense equivalence converters
+								if ( conv === true ) {
+									conv = converters[ conv2 ];
+
+								// Otherwise, insert the intermediate dataType
+								} else if ( converters[ conv2 ] !== true ) {
+									current = tmp[ 0 ];
+									dataTypes.unshift( tmp[ 1 ] );
+								}
+								break;
+							}
+						}
+					}
+				}
+
+				// Apply converter (if not an equivalence)
+				if ( conv !== true ) {
+
+					// Unless errors are allowed to bubble, catch and return them
+					if ( conv && s.throws ) {
+						response = conv( response );
+					} else {
+						try {
+							response = conv( response );
+						} catch ( e ) {
+							return {
+								state: "parsererror",
+								error: conv ? e : "No conversion from " + prev + " to " + current
+							};
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return { state: "success", data: response };
+}
+
+jQuery.extend( {
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	ajaxSettings: {
+		url: location.href,
+		type: "GET",
+		isLocal: rlocalProtocol.test( location.protocol ),
+		global: true,
+		processData: true,
+		async: true,
+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+
+		/*
+		timeout: 0,
+		data: null,
+		dataType: null,
+		username: null,
+		password: null,
+		cache: null,
+		throws: false,
+		traditional: false,
+		headers: {},
+		*/
+
+		accepts: {
+			"*": allTypes,
+			text: "text/plain",
+			html: "text/html",
+			xml: "application/xml, text/xml",
+			json: "application/json, text/javascript"
+		},
+
+		contents: {
+			xml: /\bxml\b/,
+			html: /\bhtml/,
+			json: /\bjson\b/
+		},
+
+		responseFields: {
+			xml: "responseXML",
+			text: "responseText",
+			json: "responseJSON"
+		},
+
+		// Data converters
+		// Keys separate source (or catchall "*") and destination types with a single space
+		converters: {
+
+			// Convert anything to text
+			"* text": String,
+
+			// Text to html (true = no transformation)
+			"text html": true,
+
+			// Evaluate text as a json expression
+			"text json": JSON.parse,
+
+			// Parse text as xml
+			"text xml": jQuery.parseXML
+		},
+
+		// For options that shouldn't be deep extended:
+		// you can add your own custom options here if
+		// and when you create one that shouldn't be
+		// deep extended (see ajaxExtend)
+		flatOptions: {
+			url: true,
+			context: true
+		}
+	},
+
+	// Creates a full fledged settings object into target
+	// with both ajaxSettings and settings fields.
+	// If target is omitted, writes into ajaxSettings.
+	ajaxSetup: function( target, settings ) {
+		return settings ?
+
+			// Building a settings object
+			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+			// Extending ajaxSettings
+			ajaxExtend( jQuery.ajaxSettings, target );
+	},
+
+	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+	ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+	// Main method
+	ajax: function( url, options ) {
+
+		// If url is an object, simulate pre-1.5 signature
+		if ( typeof url === "object" ) {
+			options = url;
+			url = undefined;
+		}
+
+		// Force options to be an object
+		options = options || {};
+
+		var transport,
+
+			// URL without anti-cache param
+			cacheURL,
+
+			// Response headers
+			responseHeadersString,
+			responseHeaders,
+
+			// timeout handle
+			timeoutTimer,
+
+			// Url cleanup var
+			urlAnchor,
+
+			// Request state (becomes false upon send and true upon completion)
+			completed,
+
+			// To know if global events are to be dispatched
+			fireGlobals,
+
+			// Loop variable
+			i,
+
+			// uncached part of the url
+			uncached,
+
+			// Create the final options object
+			s = jQuery.ajaxSetup( {}, options ),
+
+			// Callbacks context
+			callbackContext = s.context || s,
+
+			// Context for global events is callbackContext if it is a DOM node or jQuery collection
+			globalEventContext = s.context &&
+				( callbackContext.nodeType || callbackContext.jquery ) ?
+					jQuery( callbackContext ) :
+					jQuery.event,
+
+			// Deferreds
+			deferred = jQuery.Deferred(),
+			completeDeferred = jQuery.Callbacks( "once memory" ),
+
+			// Status-dependent callbacks
+			statusCode = s.statusCode || {},
+
+			// Headers (they are sent all at once)
+			requestHeaders = {},
+			requestHeadersNames = {},
+
+			// Default abort message
+			strAbort = "canceled",
+
+			// Fake xhr
+			jqXHR = {
+				readyState: 0,
+
+				// Builds headers hashtable if needed
+				getResponseHeader: function( key ) {
+					var match;
+					if ( completed ) {
+						if ( !responseHeaders ) {
+							responseHeaders = {};
+							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
+								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+							}
+						}
+						match = responseHeaders[ key.toLowerCase() ];
+					}
+					return match == null ? null : match;
+				},
+
+				// Raw string
+				getAllResponseHeaders: function() {
+					return completed ? responseHeadersString : null;
+				},
+
+				// Caches the header
+				setRequestHeader: function( name, value ) {
+					if ( completed == null ) {
+						name = requestHeadersNames[ name.toLowerCase() ] =
+							requestHeadersNames[ name.toLowerCase() ] || name;
+						requestHeaders[ name ] = value;
+					}
+					return this;
+				},
+
+				// Overrides response content-type header
+				overrideMimeType: function( type ) {
+					if ( completed == null ) {
+						s.mimeType = type;
+					}
+					return this;
+				},
+
+				// Status-dependent callbacks
+				statusCode: function( map ) {
+					var code;
+					if ( map ) {
+						if ( completed ) {
+
+							// Execute the appropriate callbacks
+							jqXHR.always( map[ jqXHR.status ] );
+						} else {
+
+							// Lazy-add the new callbacks in a way that preserves old ones
+							for ( code in map ) {
+								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+							}
+						}
+					}
+					return this;
+				},
+
+				// Cancel the request
+				abort: function( statusText ) {
+					var finalText = statusText || strAbort;
+					if ( transport ) {
+						transport.abort( finalText );
+					}
+					done( 0, finalText );
+					return this;
+				}
+			};
+
+		// Attach deferreds
+		deferred.promise( jqXHR );
+
+		// Add protocol if not provided (prefilters might expect it)
+		// Handle falsy url in the settings object (#10093: consistency with old signature)
+		// We also use the url parameter if available
+		s.url = ( ( url || s.url || location.href ) + "" )
+			.replace( rprotocol, location.protocol + "//" );
+
+		// Alias method option to type as per ticket #12004
+		s.type = options.method || options.type || s.method || s.type;
+
+		// Extract dataTypes list
+		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
+
+		// A cross-domain request is in order when the origin doesn't match the current origin.
+		if ( s.crossDomain == null ) {
+			urlAnchor = document.createElement( "a" );
+
+			// Support: IE <=8 - 11, Edge 12 - 15
+			// IE throws exception on accessing the href property if url is malformed,
+			// e.g. http://example.com:80x/
+			try {
+				urlAnchor.href = s.url;
+
+				// Support: IE <=8 - 11 only
+				// Anchor's host property isn't correctly set when s.url is relative
+				urlAnchor.href = urlAnchor.href;
+				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
+					urlAnchor.protocol + "//" + urlAnchor.host;
+			} catch ( e ) {
+
+				// If there is an error parsing the URL, assume it is crossDomain,
+				// it can be rejected by the transport if it is invalid
+				s.crossDomain = true;
+			}
+		}
+
+		// Convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Apply prefilters
+		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+		// If request was aborted inside a prefilter, stop there
+		if ( completed ) {
+			return jqXHR;
+		}
+
+		// We can fire global events as of now if asked to
+		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
+		fireGlobals = jQuery.event && s.global;
+
+		// Watch for a new set of requests
+		if ( fireGlobals && jQuery.active++ === 0 ) {
+			jQuery.event.trigger( "ajaxStart" );
+		}
+
+		// Uppercase the type
+		s.type = s.type.toUpperCase();
+
+		// Determine if request has content
+		s.hasContent = !rnoContent.test( s.type );
+
+		// Save the URL in case we're toying with the If-Modified-Since
+		// and/or If-None-Match header later on
+		// Remove hash to simplify url manipulation
+		cacheURL = s.url.replace( rhash, "" );
+
+		// More options handling for requests with no content
+		if ( !s.hasContent ) {
+
+			// Remember the hash so we can put it back
+			uncached = s.url.slice( cacheURL.length );
+
+			// If data is available and should be processed, append data to url
+			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
+				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
+
+				// #9682: remove data so that it's not used in an eventual retry
+				delete s.data;
+			}
+
+			// Add or update anti-cache param if needed
+			if ( s.cache === false ) {
+				cacheURL = cacheURL.replace( rantiCache, "$1" );
+				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
+			}
+
+			// Put hash and anti-cache on the URL that will be requested (gh-1732)
+			s.url = cacheURL + uncached;
+
+		// Change '%20' to '+' if this is encoded form body content (gh-2658)
+		} else if ( s.data && s.processData &&
+			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
+			s.data = s.data.replace( r20, "+" );
+		}
+
+		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+		if ( s.ifModified ) {
+			if ( jQuery.lastModified[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+			}
+			if ( jQuery.etag[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+			}
+		}
+
+		// Set the correct header, if data is being sent
+		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+			jqXHR.setRequestHeader( "Content-Type", s.contentType );
+		}
+
+		// Set the Accepts header for the server, depending on the dataType
+		jqXHR.setRequestHeader(
+			"Accept",
+			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
+				s.accepts[ s.dataTypes[ 0 ] ] +
+					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+				s.accepts[ "*" ]
+		);
+
+		// Check for headers option
+		for ( i in s.headers ) {
+			jqXHR.setRequestHeader( i, s.headers[ i ] );
+		}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend &&
+			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
+
+			// Abort if not done already and return
+			return jqXHR.abort();
+		}
+
+		// Aborting is no longer a cancellation
+		strAbort = "abort";
+
+		// Install callbacks on deferreds
+		completeDeferred.add( s.complete );
+		jqXHR.done( s.success );
+		jqXHR.fail( s.error );
+
+		// Get transport
+		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+		// If no transport, we auto-abort
+		if ( !transport ) {
+			done( -1, "No Transport" );
+		} else {
+			jqXHR.readyState = 1;
+
+			// Send global event
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+			}
+
+			// If request was aborted inside ajaxSend, stop there
+			if ( completed ) {
+				return jqXHR;
+			}
+
+			// Timeout
+			if ( s.async && s.timeout > 0 ) {
+				timeoutTimer = window.setTimeout( function() {
+					jqXHR.abort( "timeout" );
+				}, s.timeout );
+			}
+
+			try {
+				completed = false;
+				transport.send( requestHeaders, done );
+			} catch ( e ) {
+
+				// Rethrow post-completion exceptions
+				if ( completed ) {
+					throw e;
+				}
+
+				// Propagate others as results
+				done( -1, e );
+			}
+		}
+
+		// Callback for when everything is done
+		function done( status, nativeStatusText, responses, headers ) {
+			var isSuccess, success, error, response, modified,
+				statusText = nativeStatusText;
+
+			// Ignore repeat invocations
+			if ( completed ) {
+				return;
+			}
+
+			completed = true;
+
+			// Clear timeout if it exists
+			if ( timeoutTimer ) {
+				window.clearTimeout( timeoutTimer );
+			}
+
+			// Dereference transport for early garbage collection
+			// (no matter how long the jqXHR object will be used)
+			transport = undefined;
+
+			// Cache response headers
+			responseHeadersString = headers || "";
+
+			// Set readyState
+			jqXHR.readyState = status > 0 ? 4 : 0;
+
+			// Determine if successful
+			isSuccess = status >= 200 && status < 300 || status === 304;
+
+			// Get response data
+			if ( responses ) {
+				response = ajaxHandleResponses( s, jqXHR, responses );
+			}
+
+			// Convert no matter what (that way responseXXX fields are always set)
+			response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+			// If successful, handle type chaining
+			if ( isSuccess ) {
+
+				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+				if ( s.ifModified ) {
+					modified = jqXHR.getResponseHeader( "Last-Modified" );
+					if ( modified ) {
+						jQuery.lastModified[ cacheURL ] = modified;
+					}
+					modified = jqXHR.getResponseHeader( "etag" );
+					if ( modified ) {
+						jQuery.etag[ cacheURL ] = modified;
+					}
+				}
+
+				// if no content
+				if ( status === 204 || s.type === "HEAD" ) {
+					statusText = "nocontent";
+
+				// if not modified
+				} else if ( status === 304 ) {
+					statusText = "notmodified";
+
+				// If we have data, let's convert it
+				} else {
+					statusText = response.state;
+					success = response.data;
+					error = response.error;
+					isSuccess = !error;
+				}
+			} else {
+
+				// Extract error from statusText and normalize for non-aborts
+				error = statusText;
+				if ( status || !statusText ) {
+					statusText = "error";
+					if ( status < 0 ) {
+						status = 0;
+					}
+				}
+			}
+
+			// Set data for the fake xhr object
+			jqXHR.status = status;
+			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+			// Success/Error
+			if ( isSuccess ) {
+				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+			} else {
+				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+			}
+
+			// Status-dependent callbacks
+			jqXHR.statusCode( statusCode );
+			statusCode = undefined;
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+					[ jqXHR, s, isSuccess ? success : error ] );
+			}
+
+			// Complete
+			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+			if ( fireGlobals ) {
+				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+
+				// Handle the global AJAX counter
+				if ( !( --jQuery.active ) ) {
+					jQuery.event.trigger( "ajaxStop" );
+				}
+			}
+		}
+
+		return jqXHR;
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get( url, data, callback, "json" );
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get( url, undefined, callback, "script" );
+	}
+} );
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+	jQuery[ method ] = function( url, data, callback, type ) {
+
+		// Shift arguments if data argument was omitted
+		if ( isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = undefined;
+		}
+
+		// The url can be an options object (which then must have .url)
+		return jQuery.ajax( jQuery.extend( {
+			url: url,
+			type: method,
+			dataType: type,
+			data: data,
+			success: callback
+		}, jQuery.isPlainObject( url ) && url ) );
+	};
+} );
+
+
+jQuery._evalUrl = function( url ) {
+	return jQuery.ajax( {
+		url: url,
+
+		// Make this explicit, since user can override this through ajaxSetup (#11264)
+		type: "GET",
+		dataType: "script",
+		cache: true,
+		async: false,
+		global: false,
+		"throws": true
+	} );
+};
+
+
+jQuery.fn.extend( {
+	wrapAll: function( html ) {
+		var wrap;
+
+		if ( this[ 0 ] ) {
+			if ( isFunction( html ) ) {
+				html = html.call( this[ 0 ] );
+			}
+
+			// The elements to wrap the target around
+			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
+
+			if ( this[ 0 ].parentNode ) {
+				wrap.insertBefore( this[ 0 ] );
+			}
+
+			wrap.map( function() {
+				var elem = this;
+
+				while ( elem.firstElementChild ) {
+					elem = elem.firstElementChild;
+				}
+
+				return elem;
+			} ).append( this );
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( isFunction( html ) ) {
+			return this.each( function( i ) {
+				jQuery( this ).wrapInner( html.call( this, i ) );
+			} );
+		}
+
+		return this.each( function() {
+			var self = jQuery( this ),
+				contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		} );
+	},
+
+	wrap: function( html ) {
+		var htmlIsFunction = isFunction( html );
+
+		return this.each( function( i ) {
+			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
+		} );
+	},
+
+	unwrap: function( selector ) {
+		this.parent( selector ).not( "body" ).each( function() {
+			jQuery( this ).replaceWith( this.childNodes );
+		} );
+		return this;
+	}
+} );
+
+
+jQuery.expr.pseudos.hidden = function( elem ) {
+	return !jQuery.expr.pseudos.visible( elem );
+};
+jQuery.expr.pseudos.visible = function( elem ) {
+	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
+};
+
+
+
+
+jQuery.ajaxSettings.xhr = function() {
+	try {
+		return new window.XMLHttpRequest();
+	} catch ( e ) {}
+};
+
+var xhrSuccessStatus = {
+
+		// File protocol always yields status code 0, assume 200
+		0: 200,
+
+		// Support: IE <=9 only
+		// #1450: sometimes IE returns 1223 when it should be 204
+		1223: 204
+	},
+	xhrSupported = jQuery.ajaxSettings.xhr();
+
+support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+support.ajax = xhrSupported = !!xhrSupported;
+
+jQuery.ajaxTransport( function( options ) {
+	var callback, errorCallback;
+
+	// Cross domain only allowed if supported through XMLHttpRequest
+	if ( support.cors || xhrSupported && !options.crossDomain ) {
+		return {
+			send: function( headers, complete ) {
+				var i,
+					xhr = options.xhr();
+
+				xhr.open(
+					options.type,
+					options.url,
+					options.async,
+					options.username,
+					options.password
+				);
+
+				// Apply custom fields if provided
+				if ( options.xhrFields ) {
+					for ( i in options.xhrFields ) {
+						xhr[ i ] = options.xhrFields[ i ];
+					}
+				}
+
+				// Override mime type if needed
+				if ( options.mimeType && xhr.overrideMimeType ) {
+					xhr.overrideMimeType( options.mimeType );
+				}
+
+				// X-Requested-With header
+				// For cross-domain requests, seeing as conditions for a preflight are
+				// akin to a jigsaw puzzle, we simply never set it to be sure.
+				// (it can always be set on a per-request basis or even using ajaxSetup)
+				// For same-domain requests, won't change header if already provided.
+				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
+					headers[ "X-Requested-With" ] = "XMLHttpRequest";
+				}
+
+				// Set headers
+				for ( i in headers ) {
+					xhr.setRequestHeader( i, headers[ i ] );
+				}
+
+				// Callback
+				callback = function( type ) {
+					return function() {
+						if ( callback ) {
+							callback = errorCallback = xhr.onload =
+								xhr.onerror = xhr.onabort = xhr.ontimeout =
+									xhr.onreadystatechange = null;
+
+							if ( type === "abort" ) {
+								xhr.abort();
+							} else if ( type === "error" ) {
+
+								// Support: IE <=9 only
+								// On a manual native abort, IE9 throws
+								// errors on any property access that is not readyState
+								if ( typeof xhr.status !== "number" ) {
+									complete( 0, "error" );
+								} else {
+									complete(
+
+										// File: protocol always yields status 0; see #8605, #14207
+										xhr.status,
+										xhr.statusText
+									);
+								}
+							} else {
+								complete(
+									xhrSuccessStatus[ xhr.status ] || xhr.status,
+									xhr.statusText,
+
+									// Support: IE <=9 only
+									// IE9 has no XHR2 but throws on binary (trac-11426)
+									// For XHR2 non-text, let the caller handle it (gh-2498)
+									( xhr.responseType || "text" ) !== "text"  ||
+									typeof xhr.responseText !== "string" ?
+										{ binary: xhr.response } :
+										{ text: xhr.responseText },
+									xhr.getAllResponseHeaders()
+								);
+							}
+						}
+					};
+				};
+
+				// Listen to events
+				xhr.onload = callback();
+				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
+
+				// Support: IE 9 only
+				// Use onreadystatechange to replace onabort
+				// to handle uncaught aborts
+				if ( xhr.onabort !== undefined ) {
+					xhr.onabort = errorCallback;
+				} else {
+					xhr.onreadystatechange = function() {
+
+						// Check readyState before timeout as it changes
+						if ( xhr.readyState === 4 ) {
+
+							// Allow onerror to be called first,
+							// but that will not handle a native abort
+							// Also, save errorCallback to a variable
+							// as xhr.onerror cannot be accessed
+							window.setTimeout( function() {
+								if ( callback ) {
+									errorCallback();
+								}
+							} );
+						}
+					};
+				}
+
+				// Create the abort callback
+				callback = callback( "abort" );
+
+				try {
+
+					// Do send the request (this may raise an exception)
+					xhr.send( options.hasContent && options.data || null );
+				} catch ( e ) {
+
+					// #14683: Only rethrow if this hasn't been notified as an error yet
+					if ( callback ) {
+						throw e;
+					}
+				}
+			},
+
+			abort: function() {
+				if ( callback ) {
+					callback();
+				}
+			}
+		};
+	}
+} );
+
+
+
+
+// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
+jQuery.ajaxPrefilter( function( s ) {
+	if ( s.crossDomain ) {
+		s.contents.script = false;
+	}
+} );
+
+// Install script dataType
+jQuery.ajaxSetup( {
+	accepts: {
+		script: "text/javascript, application/javascript, " +
+			"application/ecmascript, application/x-ecmascript"
+	},
+	contents: {
+		script: /\b(?:java|ecma)script\b/
+	},
+	converters: {
+		"text script": function( text ) {
+			jQuery.globalEval( text );
+			return text;
+		}
+	}
+} );
+
+// Handle cache's special case and crossDomain
+jQuery.ajaxPrefilter( "script", function( s ) {
+	if ( s.cache === undefined ) {
+		s.cache = false;
+	}
+	if ( s.crossDomain ) {
+		s.type = "GET";
+	}
+} );
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function( s ) {
+
+	// This transport only deals with cross domain requests
+	if ( s.crossDomain ) {
+		var script, callback;
+		return {
+			send: function( _, complete ) {
+				script = jQuery( "<script>" ).prop( {
+					charset: s.scriptCharset,
+					src: s.url
+				} ).on(
+					"load error",
+					callback = function( evt ) {
+						script.remove();
+						callback = null;
+						if ( evt ) {
+							complete( evt.type === "error" ? 404 : 200, evt.type );
+						}
+					}
+				);
+
+				// Use native DOM manipulation to avoid our domManip AJAX trickery
+				document.head.appendChild( script[ 0 ] );
+			},
+			abort: function() {
+				if ( callback ) {
+					callback();
+				}
+			}
+		};
+	}
+} );
+
+
+
+
+var oldCallbacks = [],
+	rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup( {
+	jsonp: "callback",
+	jsonpCallback: function() {
+		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+		this[ callback ] = true;
+		return callback;
+	}
+} );
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+	var callbackName, overwritten, responseContainer,
+		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+			"url" :
+			typeof s.data === "string" &&
+				( s.contentType || "" )
+					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
+				rjsonp.test( s.data ) && "data"
+		);
+
+	// Handle iff the expected data type is "jsonp" or we have a parameter to set
+	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+		// Get callback name, remembering preexisting value associated with it
+		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
+			s.jsonpCallback() :
+			s.jsonpCallback;
+
+		// Insert callback into url or form data
+		if ( jsonProp ) {
+			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+		} else if ( s.jsonp !== false ) {
+			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+		}
+
+		// Use data converter to retrieve json after script execution
+		s.converters[ "script json" ] = function() {
+			if ( !responseContainer ) {
+				jQuery.error( callbackName + " was not called" );
+			}
+			return responseContainer[ 0 ];
+		};
+
+		// Force json dataType
+		s.dataTypes[ 0 ] = "json";
+
+		// Install callback
+		overwritten = window[ callbackName ];
+		window[ callbackName ] = function() {
+			responseContainer = arguments;
+		};
+
+		// Clean-up function (fires after converters)
+		jqXHR.always( function() {
+
+			// If previous value didn't exist - remove it
+			if ( overwritten === undefined ) {
+				jQuery( window ).removeProp( callbackName );
+
+			// Otherwise restore preexisting value
+			} else {
+				window[ callbackName ] = overwritten;
+			}
+
+			// Save back as free
+			if ( s[ callbackName ] ) {
+
+				// Make sure that re-using the options doesn't screw things around
+				s.jsonpCallback = originalSettings.jsonpCallback;
+
+				// Save the callback name for future use
+				oldCallbacks.push( callbackName );
+			}
+
+			// Call if it was a function and we have a response
+			if ( responseContainer && isFunction( overwritten ) ) {
+				overwritten( responseContainer[ 0 ] );
+			}
+
+			responseContainer = overwritten = undefined;
+		} );
+
+		// Delegate to script
+		return "script";
+	}
+} );
+
+
+
+
+// Support: Safari 8 only
+// In Safari 8 documents created via document.implementation.createHTMLDocument
+// collapse sibling forms: the second one becomes a child of the first one.
+// Because of that, this security measure has to be disabled in Safari 8.
+// https://bugs.webkit.org/show_bug.cgi?id=137337
+support.createHTMLDocument = ( function() {
+	var body = document.implementation.createHTMLDocument( "" ).body;
+	body.innerHTML = "<form></form><form></form>";
+	return body.childNodes.length === 2;
+} )();
+
+
+// Argument "data" should be string of html
+// context (optional): If specified, the fragment will be created in this context,
+// defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+	if ( typeof data !== "string" ) {
+		return [];
+	}
+	if ( typeof context === "boolean" ) {
+		keepScripts = context;
+		context = false;
+	}
+
+	var base, parsed, scripts;
+
+	if ( !context ) {
+
+		// Stop scripts or inline event handlers from being executed immediately
+		// by using document.implementation
+		if ( support.createHTMLDocument ) {
+			context = document.implementation.createHTMLDocument( "" );
+
+			// Set the base href for the created document
+			// so any parsed elements with URLs
+			// are based on the document's URL (gh-2965)
+			base = context.createElement( "base" );
+			base.href = document.location.href;
+			context.head.appendChild( base );
+		} else {
+			context = document;
+		}
+	}
+
+	parsed = rsingleTag.exec( data );
+	scripts = !keepScripts && [];
+
+	// Single tag
+	if ( parsed ) {
+		return [ context.createElement( parsed[ 1 ] ) ];
+	}
+
+	parsed = buildFragment( [ data ], context, scripts );
+
+	if ( scripts && scripts.length ) {
+		jQuery( scripts ).remove();
+	}
+
+	return jQuery.merge( [], parsed.childNodes );
+};
+
+
+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+	var selector, type, response,
+		self = this,
+		off = url.indexOf( " " );
+
+	if ( off > -1 ) {
+		selector = stripAndCollapse( url.slice( off ) );
+		url = url.slice( 0, off );
+	}
+
+	// If it's a function
+	if ( isFunction( params ) ) {
+
+		// We assume that it's the callback
+		callback = params;
+		params = undefined;
+
+	// Otherwise, build a param string
+	} else if ( params && typeof params === "object" ) {
+		type = "POST";
+	}
+
+	// If we have elements to modify, make the request
+	if ( self.length > 0 ) {
+		jQuery.ajax( {
+			url: url,
+
+			// If "type" variable is undefined, then "GET" method will be used.
+			// Make value of this field explicit since
+			// user can override it through ajaxSetup method
+			type: type || "GET",
+			dataType: "html",
+			data: params
+		} ).done( function( responseText ) {
+
+			// Save response for use in complete callback
+			response = arguments;
+
+			self.html( selector ?
+
+				// If a selector was specified, locate the right elements in a dummy div
+				// Exclude scripts to avoid IE 'Permission Denied' errors
+				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+				// Otherwise use the full result
+				responseText );
+
+		// If the request succeeds, this function gets "data", "status", "jqXHR"
+		// but they are ignored because response was set above.
+		// If it fails, this function gets "jqXHR", "status", "error"
+		} ).always( callback && function( jqXHR, status ) {
+			self.each( function() {
+				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
+			} );
+		} );
+	}
+
+	return this;
+};
+
+
+
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [
+	"ajaxStart",
+	"ajaxStop",
+	"ajaxComplete",
+	"ajaxError",
+	"ajaxSuccess",
+	"ajaxSend"
+], function( i, type ) {
+	jQuery.fn[ type ] = function( fn ) {
+		return this.on( type, fn );
+	};
+} );
+
+
+
+
+jQuery.expr.pseudos.animated = function( elem ) {
+	return jQuery.grep( jQuery.timers, function( fn ) {
+		return elem === fn.elem;
+	} ).length;
+};
+
+
+
+
+jQuery.offset = {
+	setOffset: function( elem, options, i ) {
+		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+			position = jQuery.css( elem, "position" ),
+			curElem = jQuery( elem ),
+			props = {};
+
+		// Set position first, in-case top/left are set even on static elem
+		if ( position === "static" ) {
+			elem.style.position = "relative";
+		}
+
+		curOffset = curElem.offset();
+		curCSSTop = jQuery.css( elem, "top" );
+		curCSSLeft = jQuery.css( elem, "left" );
+		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
+
+		// Need to be able to calculate position if either
+		// top or left is auto and position is either absolute or fixed
+		if ( calculatePosition ) {
+			curPosition = curElem.position();
+			curTop = curPosition.top;
+			curLeft = curPosition.left;
+
+		} else {
+			curTop = parseFloat( curCSSTop ) || 0;
+			curLeft = parseFloat( curCSSLeft ) || 0;
+		}
+
+		if ( isFunction( options ) ) {
+
+			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
+			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
+		}
+
+		if ( options.top != null ) {
+			props.top = ( options.top - curOffset.top ) + curTop;
+		}
+		if ( options.left != null ) {
+			props.left = ( options.left - curOffset.left ) + curLeft;
+		}
+
+		if ( "using" in options ) {
+			options.using.call( elem, props );
+
+		} else {
+			curElem.css( props );
+		}
+	}
+};
+
+jQuery.fn.extend( {
+
+	// offset() relates an element's border box to the document origin
+	offset: function( options ) {
+
+		// Preserve chaining for setter
+		if ( arguments.length ) {
+			return options === undefined ?
+				this :
+				this.each( function( i ) {
+					jQuery.offset.setOffset( this, options, i );
+				} );
+		}
+
+		var rect, win,
+			elem = this[ 0 ];
+
+		if ( !elem ) {
+			return;
+		}
+
+		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
+		// Support: IE <=11 only
+		// Running getBoundingClientRect on a
+		// disconnected node in IE throws an error
+		if ( !elem.getClientRects().length ) {
+			return { top: 0, left: 0 };
+		}
+
+		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
+		rect = elem.getBoundingClientRect();
+		win = elem.ownerDocument.defaultView;
+		return {
+			top: rect.top + win.pageYOffset,
+			left: rect.left + win.pageXOffset
+		};
+	},
+
+	// position() relates an element's margin box to its offset parent's padding box
+	// This corresponds to the behavior of CSS absolute positioning
+	position: function() {
+		if ( !this[ 0 ] ) {
+			return;
+		}
+
+		var offsetParent, offset, doc,
+			elem = this[ 0 ],
+			parentOffset = { top: 0, left: 0 };
+
+		// position:fixed elements are offset from the viewport, which itself always has zero offset
+		if ( jQuery.css( elem, "position" ) === "fixed" ) {
+
+			// Assume position:fixed implies availability of getBoundingClientRect
+			offset = elem.getBoundingClientRect();
+
+		} else {
+			offset = this.offset();
+
+			// Account for the *real* offset parent, which can be the document or its root element
+			// when a statically positioned element is identified
+			doc = elem.ownerDocument;
+			offsetParent = elem.offsetParent || doc.documentElement;
+			while ( offsetParent &&
+				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
+				jQuery.css( offsetParent, "position" ) === "static" ) {
+
+				offsetParent = offsetParent.parentNode;
+			}
+			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
+
+				// Incorporate borders into its offset, since they are outside its content origin
+				parentOffset = jQuery( offsetParent ).offset();
+				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
+				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
+			}
+		}
+
+		// Subtract parent offsets and element margins
+		return {
+			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
+		};
+	},
+
+	// This method will return documentElement in the following cases:
+	// 1) For the element inside the iframe without offsetParent, this method will return
+	//    documentElement of the parent window
+	// 2) For the hidden or detached element
+	// 3) For body or html element, i.e. in case of the html node - it will return itself
+	//
+	// but those exceptions were never presented as a real life use-cases
+	// and might be considered as more preferable results.
+	//
+	// This logic, however, is not guaranteed and can change at any point in the future
+	offsetParent: function() {
+		return this.map( function() {
+			var offsetParent = this.offsetParent;
+
+			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+
+			return offsetParent || documentElement;
+		} );
+	}
+} );
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+	var top = "pageYOffset" === prop;
+
+	jQuery.fn[ method ] = function( val ) {
+		return access( this, function( elem, method, val ) {
+
+			// Coalesce documents and windows
+			var win;
+			if ( isWindow( elem ) ) {
+				win = elem;
+			} else if ( elem.nodeType === 9 ) {
+				win = elem.defaultView;
+			}
+
+			if ( val === undefined ) {
+				return win ? win[ prop ] : elem[ method ];
+			}
+
+			if ( win ) {
+				win.scrollTo(
+					!top ? val : win.pageXOffset,
+					top ? val : win.pageYOffset
+				);
+
+			} else {
+				elem[ method ] = val;
+			}
+		}, method, val, arguments.length );
+	};
+} );
+
+// Support: Safari <=7 - 9.1, Chrome <=37 - 49
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
+// getComputedStyle returns percent when specified for top/left/bottom/right;
+// rather than make the css module depend on the offset module, just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+		function( elem, computed ) {
+			if ( computed ) {
+				computed = curCSS( elem, prop );
+
+				// If curCSS returns percentage, fallback to offset
+				return rnumnonpx.test( computed ) ?
+					jQuery( elem ).position()[ prop ] + "px" :
+					computed;
+			}
+		}
+	);
+} );
+
+
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
+		function( defaultExtra, funcName ) {
+
+		// Margin is only for outerHeight, outerWidth
+		jQuery.fn[ funcName ] = function( margin, value ) {
+			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+			return access( this, function( elem, type, value ) {
+				var doc;
+
+				if ( isWindow( elem ) ) {
+
+					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
+					return funcName.indexOf( "outer" ) === 0 ?
+						elem[ "inner" + name ] :
+						elem.document.documentElement[ "client" + name ];
+				}
+
+				// Get document width or height
+				if ( elem.nodeType === 9 ) {
+					doc = elem.documentElement;
+
+					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
+					// whichever is greatest
+					return Math.max(
+						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+						elem.body[ "offset" + name ], doc[ "offset" + name ],
+						doc[ "client" + name ]
+					);
+				}
+
+				return value === undefined ?
+
+					// Get width or height on the element, requesting but not forcing parseFloat
+					jQuery.css( elem, type, extra ) :
+
+					// Set width or height on the element
+					jQuery.style( elem, type, value, extra );
+			}, type, chainable ? margin : undefined, chainable );
+		};
+	} );
+} );
+
+
+jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
+	function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( data, fn ) {
+		return arguments.length > 0 ?
+			this.on( name, null, data, fn ) :
+			this.trigger( name );
+	};
+} );
+
+jQuery.fn.extend( {
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	}
+} );
+
+
+
+
+jQuery.fn.extend( {
+
+	bind: function( types, data, fn ) {
+		return this.on( types, null, data, fn );
+	},
+	unbind: function( types, fn ) {
+		return this.off( types, null, fn );
+	},
+
+	delegate: function( selector, types, data, fn ) {
+		return this.on( types, selector, data, fn );
+	},
+	undelegate: function( selector, types, fn ) {
+
+		// ( namespace ) or ( selector, types [, fn] )
+		return arguments.length === 1 ?
+			this.off( selector, "**" ) :
+			this.off( types, selector || "**", fn );
+	}
+} );
+
+// Bind a function to a context, optionally partially applying any
+// arguments.
+// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
+// However, it is not slated for removal any time soon
+jQuery.proxy = function( fn, context ) {
+	var tmp, args, proxy;
+
+	if ( typeof context === "string" ) {
+		tmp = fn[ context ];
+		context = fn;
+		fn = tmp;
+	}
+
+	// Quick check to determine if target is callable, in the spec
+	// this throws a TypeError, but we will just return undefined.
+	if ( !isFunction( fn ) ) {
+		return undefined;
+	}
+
+	// Simulated bind
+	args = slice.call( arguments, 2 );
+	proxy = function() {
+		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+	};
+
+	// Set the guid of unique handler to the same of original handler, so it can be removed
+	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+	return proxy;
+};
+
+jQuery.holdReady = function( hold ) {
+	if ( hold ) {
+		jQuery.readyWait++;
+	} else {
+		jQuery.ready( true );
+	}
+};
+jQuery.isArray = Array.isArray;
+jQuery.parseJSON = JSON.parse;
+jQuery.nodeName = nodeName;
+jQuery.isFunction = isFunction;
+jQuery.isWindow = isWindow;
+jQuery.camelCase = camelCase;
+jQuery.type = toType;
+
+jQuery.now = Date.now;
+
+jQuery.isNumeric = function( obj ) {
+
+	// As of jQuery 3.0, isNumeric is limited to
+	// strings and numbers (primitives or objects)
+	// that can be coerced to finite numbers (gh-2662)
+	var type = jQuery.type( obj );
+	return ( type === "number" || type === "string" ) &&
+
+		// parseFloat NaNs numeric-cast false positives ("")
+		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+		// subtraction forces infinities to NaN
+		!isNaN( obj - parseFloat( obj ) );
+};
+
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+	define( "jquery", [], function() {
+		return jQuery;
+	} );
+}
+
+
+
+
+var
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+	if ( window.$ === jQuery ) {
+		window.$ = _$;
+	}
+
+	if ( deep && window.jQuery === jQuery ) {
+		window.jQuery = _jQuery;
+	}
+
+	return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in AMD
+// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( !noGlobal ) {
+	window.jQuery = window.$ = jQuery;
+}
+
+
+
+
+return jQuery;
+} );
Index: inc/load_plugin_file.php
===================================================================
--- inc/load_plugin_file.php	(revision 3731)
+++ inc/load_plugin_file.php	(revision 3874)
@@ -56,5 +56,5 @@
 }
 
-$allow_types = array('png', 'jpg', 'jpeg', 'gif', 'css', 'js', 'swf', 'svg');
+$allow_types = ['png', 'jpg', 'jpeg', 'gif', 'css', 'js', 'swf', 'svg'];
 
 $pf = path::clean($_GET['pf']);
@@ -89,5 +89,5 @@
 
 http::$cache_max_age = 7 * 24 * 60 * 60; // One week cache for plugin's files served by ?pf=… is better than old 2 hours
-http::cache(array_merge(array($PF), get_included_files()));
+http::cache(array_merge([$PF], get_included_files()));
 
 header('Content-Type: ' . files::getMimeType($PF));
Index: inc/load_var_file.php
===================================================================
--- inc/load_var_file.php	(revision 3731)
+++ inc/load_var_file.php	(revision 3874)
@@ -56,5 +56,5 @@
 }
 
-$allow_types = array('png', 'jpg', 'jpeg', 'gif', 'css', 'js', 'swf', 'svg', 'html', 'xml', 'json', 'txt');
+$allow_types = ['png', 'jpg', 'jpeg', 'gif', 'css', 'js', 'swf', 'svg', 'html', 'xml', 'json', 'txt'];
 
 $vf = path::clean($_GET['vf']);
@@ -74,5 +74,5 @@
 
 http::$cache_max_age = 7 * 24 * 60 * 60; // One week cache for var files served by ?vf=…
-http::cache(array_merge(array($VF), get_included_files()));
+http::cache(array_merge([$VF], get_included_files()));
 
 header('Content-Type: ' . files::getMimeType($VF));
Index: inc/prepend.php
===================================================================
--- inc/prepend.php	(revision 3855)
+++ inc/prepend.php	(revision 3874)
@@ -102,6 +102,6 @@
 # Disallow every special wrapper
 if (function_exists('stream_wrapper_unregister')) {
-    $special_wrappers = array_intersect(array('http', 'https', 'ftp', 'ftps', 'ssh2.shell', 'ssh2.exec',
-        'ssh2.tunnel', 'ssh2.sftp', 'ssh2.scp', 'ogg', 'expect', 'phar'), stream_get_wrappers());
+    $special_wrappers = array_intersect(['http', 'https', 'ftp', 'ftps', 'ssh2.shell', 'ssh2.exec',
+        'ssh2.tunnel', 'ssh2.sftp', 'ssh2.scp', 'ogg', 'expect', 'phar'], stream_get_wrappers());
     foreach ($special_wrappers as $p) {
         @stream_wrapper_unregister($p);
@@ -144,5 +144,5 @@
 # Constants
 define('DC_ROOT', path::real(dirname(__FILE__) . '/..'));
-define('DC_VERSION', '2.14.2');
+define('DC_VERSION', '2.15-dev');
 define('DC_DIGESTS', dirname(__FILE__) . '/digests');
 define('DC_L10N_ROOT', dirname(__FILE__) . '/../locales');
@@ -279,17 +279,17 @@
 }
 
-$core->url->registerDefault(array('dcUrlHandlers', 'home'));
-$core->url->registerError(array('dcUrlHandlers', 'default404'));
-$core->url->register('lang', '', '^([a-zA-Z]{2}(?:-[a-z]{2})?(?:/page/[0-9]+)?)$', array('dcUrlHandlers', 'lang'));
-$core->url->register('post', 'post', '^post/(.+)$', array('dcUrlHandlers', 'post'));
-$core->url->register('preview', 'preview', '^preview/(.+)$', array('dcUrlHandlers', 'preview'));
-$core->url->register('category', 'category', '^category/(.+)$', array('dcUrlHandlers', 'category'));
-$core->url->register('archive', 'archive', '^archive(/.+)?$', array('dcUrlHandlers', 'archive'));
-
-$core->url->register('feed', 'feed', '^feed/(.+)$', array('dcUrlHandlers', 'feed'));
-$core->url->register('trackback', 'trackback', '^trackback/(.+)$', array('dcUrlHandlers', 'trackback'));
-$core->url->register('webmention', 'webmention', '^webmention(/.+)?$', array('dcUrlHandlers', 'webmention'));
-$core->url->register('rsd', 'rsd', '^rsd$', array('dcUrlHandlers', 'rsd'));
-$core->url->register('xmlrpc', 'xmlrpc', '^xmlrpc/(.+)$', array('dcUrlHandlers', 'xmlrpc'));
+$core->url->registerDefault(['dcUrlHandlers', 'home']);
+$core->url->registerError(['dcUrlHandlers', 'default404']);
+$core->url->register('lang', '', '^([a-zA-Z]{2}(?:-[a-z]{2})?(?:/page/[0-9]+)?)$', ['dcUrlHandlers', 'lang']);
+$core->url->register('post', 'post', '^post/(.+)$', ['dcUrlHandlers', 'post']);
+$core->url->register('preview', 'preview', '^preview/(.+)$', ['dcUrlHandlers', 'preview']);
+$core->url->register('category', 'category', '^category/(.+)$', ['dcUrlHandlers', 'category']);
+$core->url->register('archive', 'archive', '^archive(/.+)?$', ['dcUrlHandlers', 'archive']);
+
+$core->url->register('feed', 'feed', '^feed/(.+)$', ['dcUrlHandlers', 'feed']);
+$core->url->register('trackback', 'trackback', '^trackback/(.+)$', ['dcUrlHandlers', 'trackback']);
+$core->url->register('webmention', 'webmention', '^webmention(/.+)?$', ['dcUrlHandlers', 'webmention']);
+$core->url->register('rsd', 'rsd', '^rsd$', ['dcUrlHandlers', 'rsd']);
+$core->url->register('xmlrpc', 'xmlrpc', '^xmlrpc/(.+)$', ['dcUrlHandlers', 'xmlrpc']);
 
 // Should use dcAdminURL class, but only in admin -> to be moved to public/prepend.php and admin/prepend.php ?
@@ -306,5 +306,5 @@
 
 # Register supplemental mime types
-files::registerMimeTypes(array(
+files::registerMimeTypes([
     // Audio
     'aac'  => 'audio/aac',
@@ -316,5 +316,5 @@
     'm4p'  => 'video/mp4',
     'webm' => 'video/webm'
-));
+]);
 
 # Shutdown
Index: inc/public/class.dc.template.php
===================================================================
--- inc/public/class.dc.template.php	(revision 3731)
+++ inc/public/class.dc.template.php	(revision 3874)
@@ -29,188 +29,188 @@
 
         # Transitional tags
-        $this->addValue('EntryTrackbackCount', array($this, 'EntryPingCount'));
-        $this->addValue('EntryTrackbackData', array($this, 'EntryPingData'));
-        $this->addValue('EntryTrackbackLink', array($this, 'EntryPingLink'));
+        $this->addValue('EntryTrackbackCount', [$this, 'EntryPingCount']);
+        $this->addValue('EntryTrackbackData', [$this, 'EntryPingData']);
+        $this->addValue('EntryTrackbackLink', [$this, 'EntryPingLink']);
 
         # l10n
-        $this->addValue('lang', array($this, 'l10n'));
+        $this->addValue('lang', [$this, 'l10n']);
 
         # Loops test tags
-        $this->addBlock('LoopPosition', array($this, 'LoopPosition'));
-        $this->addValue('LoopIndex', array($this, 'LoopIndex'));
+        $this->addBlock('LoopPosition', [$this, 'LoopPosition']);
+        $this->addValue('LoopIndex', [$this, 'LoopIndex']);
 
         # Archives
-        $this->addBlock('Archives', array($this, 'Archives'));
-        $this->addBlock('ArchivesHeader', array($this, 'ArchivesHeader'));
-        $this->addBlock('ArchivesFooter', array($this, 'ArchivesFooter'));
-        $this->addBlock('ArchivesYearHeader', array($this, 'ArchivesYearHeader'));
-        $this->addBlock('ArchivesYearFooter', array($this, 'ArchivesYearFooter'));
-        $this->addValue('ArchiveDate', array($this, 'ArchiveDate'));
-        $this->addBlock('ArchiveNext', array($this, 'ArchiveNext'));
-        $this->addBlock('ArchivePrevious', array($this, 'ArchivePrevious'));
-        $this->addValue('ArchiveEntriesCount', array($this, 'ArchiveEntriesCount'));
-        $this->addValue('ArchiveURL', array($this, 'ArchiveURL'));
+        $this->addBlock('Archives', [$this, 'Archives']);
+        $this->addBlock('ArchivesHeader', [$this, 'ArchivesHeader']);
+        $this->addBlock('ArchivesFooter', [$this, 'ArchivesFooter']);
+        $this->addBlock('ArchivesYearHeader', [$this, 'ArchivesYearHeader']);
+        $this->addBlock('ArchivesYearFooter', [$this, 'ArchivesYearFooter']);
+        $this->addValue('ArchiveDate', [$this, 'ArchiveDate']);
+        $this->addBlock('ArchiveNext', [$this, 'ArchiveNext']);
+        $this->addBlock('ArchivePrevious', [$this, 'ArchivePrevious']);
+        $this->addValue('ArchiveEntriesCount', [$this, 'ArchiveEntriesCount']);
+        $this->addValue('ArchiveURL', [$this, 'ArchiveURL']);
 
         # Blog
-        $this->addValue('BlogArchiveURL', array($this, 'BlogArchiveURL'));
-        $this->addValue('BlogCopyrightNotice', array($this, 'BlogCopyrightNotice'));
-        $this->addValue('BlogDescription', array($this, 'BlogDescription'));
-        $this->addValue('BlogEditor', array($this, 'BlogEditor'));
-        $this->addValue('BlogFeedID', array($this, 'BlogFeedID'));
-        $this->addValue('BlogFeedURL', array($this, 'BlogFeedURL'));
-        $this->addValue('BlogRSDURL', array($this, 'BlogRSDURL'));
-        $this->addValue('BlogName', array($this, 'BlogName'));
-        $this->addValue('BlogLanguage', array($this, 'BlogLanguage'));
-        $this->addValue('BlogThemeURL', array($this, 'BlogThemeURL'));
-        $this->addValue('BlogParentThemeURL', array($this, 'BlogParentThemeURL'));
-        $this->addValue('BlogUpdateDate', array($this, 'BlogUpdateDate'));
-        $this->addValue('BlogID', array($this, 'BlogID'));
-        $this->addValue('BlogURL', array($this, 'BlogURL'));
-        $this->addValue('BlogXMLRPCURL', array($this, 'BlogXMLRPCURL'));
-        $this->addValue('BlogPublicURL', array($this, 'BlogPublicURL'));
-        $this->addValue('BlogQmarkURL', array($this, 'BlogQmarkURL'));
-        $this->addValue('BlogMetaRobots', array($this, 'BlogMetaRobots'));
-        $this->addValue('BlogJsJQuery', array($this, 'BlogJsJQuery'));
+        $this->addValue('BlogArchiveURL', [$this, 'BlogArchiveURL']);
+        $this->addValue('BlogCopyrightNotice', [$this, 'BlogCopyrightNotice']);
+        $this->addValue('BlogDescription', [$this, 'BlogDescription']);
+        $this->addValue('BlogEditor', [$this, 'BlogEditor']);
+        $this->addValue('BlogFeedID', [$this, 'BlogFeedID']);
+        $this->addValue('BlogFeedURL', [$this, 'BlogFeedURL']);
+        $this->addValue('BlogRSDURL', [$this, 'BlogRSDURL']);
+        $this->addValue('BlogName', [$this, 'BlogName']);
+        $this->addValue('BlogLanguage', [$this, 'BlogLanguage']);
+        $this->addValue('BlogThemeURL', [$this, 'BlogThemeURL']);
+        $this->addValue('BlogParentThemeURL', [$this, 'BlogParentThemeURL']);
+        $this->addValue('BlogUpdateDate', [$this, 'BlogUpdateDate']);
+        $this->addValue('BlogID', [$this, 'BlogID']);
+        $this->addValue('BlogURL', [$this, 'BlogURL']);
+        $this->addValue('BlogXMLRPCURL', [$this, 'BlogXMLRPCURL']);
+        $this->addValue('BlogPublicURL', [$this, 'BlogPublicURL']);
+        $this->addValue('BlogQmarkURL', [$this, 'BlogQmarkURL']);
+        $this->addValue('BlogMetaRobots', [$this, 'BlogMetaRobots']);
+        $this->addValue('BlogJsJQuery', [$this, 'BlogJsJQuery']);
 
         # Categories
-        $this->addBlock('Categories', array($this, 'Categories'));
-        $this->addBlock('CategoriesHeader', array($this, 'CategoriesHeader'));
-        $this->addBlock('CategoriesFooter', array($this, 'CategoriesFooter'));
-        $this->addBlock('CategoryIf', array($this, 'CategoryIf'));
-        $this->addBlock('CategoryFirstChildren', array($this, 'CategoryFirstChildren'));
-        $this->addBlock('CategoryParents', array($this, 'CategoryParents'));
-        $this->addValue('CategoryFeedURL', array($this, 'CategoryFeedURL'));
-        $this->addValue('CategoryURL', array($this, 'CategoryURL'));
-        $this->addValue('CategoryShortURL', array($this, 'CategoryShortURL'));
-        $this->addValue('CategoryDescription', array($this, 'CategoryDescription'));
-        $this->addValue('CategoryTitle', array($this, 'CategoryTitle'));
-        $this->addValue('CategoryEntriesCount', array($this, 'CategoryEntriesCount'));
+        $this->addBlock('Categories', [$this, 'Categories']);
+        $this->addBlock('CategoriesHeader', [$this, 'CategoriesHeader']);
+        $this->addBlock('CategoriesFooter', [$this, 'CategoriesFooter']);
+        $this->addBlock('CategoryIf', [$this, 'CategoryIf']);
+        $this->addBlock('CategoryFirstChildren', [$this, 'CategoryFirstChildren']);
+        $this->addBlock('CategoryParents', [$this, 'CategoryParents']);
+        $this->addValue('CategoryFeedURL', [$this, 'CategoryFeedURL']);
+        $this->addValue('CategoryURL', [$this, 'CategoryURL']);
+        $this->addValue('CategoryShortURL', [$this, 'CategoryShortURL']);
+        $this->addValue('CategoryDescription', [$this, 'CategoryDescription']);
+        $this->addValue('CategoryTitle', [$this, 'CategoryTitle']);
+        $this->addValue('CategoryEntriesCount', [$this, 'CategoryEntriesCount']);
 
         # Comments
-        $this->addBlock('Comments', array($this, 'Comments'));
-        $this->addValue('CommentAuthor', array($this, 'CommentAuthor'));
-        $this->addValue('CommentAuthorDomain', array($this, 'CommentAuthorDomain'));
-        $this->addValue('CommentAuthorLink', array($this, 'CommentAuthorLink'));
-        $this->addValue('CommentAuthorMailMD5', array($this, 'CommentAuthorMailMD5'));
-        $this->addValue('CommentAuthorURL', array($this, 'CommentAuthorURL'));
-        $this->addValue('CommentContent', array($this, 'CommentContent'));
-        $this->addValue('CommentDate', array($this, 'CommentDate'));
-        $this->addValue('CommentTime', array($this, 'CommentTime'));
-        $this->addValue('CommentEmail', array($this, 'CommentEmail'));
-        $this->addValue('CommentEntryTitle', array($this, 'CommentEntryTitle'));
-        $this->addValue('CommentFeedID', array($this, 'CommentFeedID'));
-        $this->addValue('CommentID', array($this, 'CommentID'));
-        $this->addBlock('CommentIf', array($this, 'CommentIf'));
-        $this->addValue('CommentIfFirst', array($this, 'CommentIfFirst'));
-        $this->addValue('CommentIfMe', array($this, 'CommentIfMe'));
-        $this->addValue('CommentIfOdd', array($this, 'CommentIfOdd'));
-        $this->addValue('CommentIP', array($this, 'CommentIP'));
-        $this->addValue('CommentOrderNumber', array($this, 'CommentOrderNumber'));
-        $this->addBlock('CommentsFooter', array($this, 'CommentsFooter'));
-        $this->addBlock('CommentsHeader', array($this, 'CommentsHeader'));
-        $this->addValue('CommentPostURL', array($this, 'CommentPostURL'));
-        $this->addBlock('IfCommentAuthorEmail', array($this, 'IfCommentAuthorEmail'));
-        $this->addValue('CommentHelp', array($this, 'CommentHelp'));
+        $this->addBlock('Comments', [$this, 'Comments']);
+        $this->addValue('CommentAuthor', [$this, 'CommentAuthor']);
+        $this->addValue('CommentAuthorDomain', [$this, 'CommentAuthorDomain']);
+        $this->addValue('CommentAuthorLink', [$this, 'CommentAuthorLink']);
+        $this->addValue('CommentAuthorMailMD5', [$this, 'CommentAuthorMailMD5']);
+        $this->addValue('CommentAuthorURL', [$this, 'CommentAuthorURL']);
+        $this->addValue('CommentContent', [$this, 'CommentContent']);
+        $this->addValue('CommentDate', [$this, 'CommentDate']);
+        $this->addValue('CommentTime', [$this, 'CommentTime']);
+        $this->addValue('CommentEmail', [$this, 'CommentEmail']);
+        $this->addValue('CommentEntryTitle', [$this, 'CommentEntryTitle']);
+        $this->addValue('CommentFeedID', [$this, 'CommentFeedID']);
+        $this->addValue('CommentID', [$this, 'CommentID']);
+        $this->addBlock('CommentIf', [$this, 'CommentIf']);
+        $this->addValue('CommentIfFirst', [$this, 'CommentIfFirst']);
+        $this->addValue('CommentIfMe', [$this, 'CommentIfMe']);
+        $this->addValue('CommentIfOdd', [$this, 'CommentIfOdd']);
+        $this->addValue('CommentIP', [$this, 'CommentIP']);
+        $this->addValue('CommentOrderNumber', [$this, 'CommentOrderNumber']);
+        $this->addBlock('CommentsFooter', [$this, 'CommentsFooter']);
+        $this->addBlock('CommentsHeader', [$this, 'CommentsHeader']);
+        $this->addValue('CommentPostURL', [$this, 'CommentPostURL']);
+        $this->addBlock('IfCommentAuthorEmail', [$this, 'IfCommentAuthorEmail']);
+        $this->addValue('CommentHelp', [$this, 'CommentHelp']);
 
         # Comment preview
-        $this->addBlock('IfCommentPreview', array($this, 'IfCommentPreview'));
-        $this->addBlock('IfCommentPreviewOptional', array($this, 'IfCommentPreviewOptional'));
-        $this->addValue('CommentPreviewName', array($this, 'CommentPreviewName'));
-        $this->addValue('CommentPreviewEmail', array($this, 'CommentPreviewEmail'));
-        $this->addValue('CommentPreviewSite', array($this, 'CommentPreviewSite'));
-        $this->addValue('CommentPreviewContent', array($this, 'CommentPreviewContent'));
-        $this->addValue('CommentPreviewCheckRemember', array($this, 'CommentPreviewCheckRemember'));
+        $this->addBlock('IfCommentPreview', [$this, 'IfCommentPreview']);
+        $this->addBlock('IfCommentPreviewOptional', [$this, 'IfCommentPreviewOptional']);
+        $this->addValue('CommentPreviewName', [$this, 'CommentPreviewName']);
+        $this->addValue('CommentPreviewEmail', [$this, 'CommentPreviewEmail']);
+        $this->addValue('CommentPreviewSite', [$this, 'CommentPreviewSite']);
+        $this->addValue('CommentPreviewContent', [$this, 'CommentPreviewContent']);
+        $this->addValue('CommentPreviewCheckRemember', [$this, 'CommentPreviewCheckRemember']);
 
         # Entries
-        $this->addBlock('DateFooter', array($this, 'DateFooter'));
-        $this->addBlock('DateHeader', array($this, 'DateHeader'));
-        $this->addBlock('Entries', array($this, 'Entries'));
-        $this->addBlock('EntriesFooter', array($this, 'EntriesFooter'));
-        $this->addBlock('EntriesHeader', array($this, 'EntriesHeader'));
-        $this->addValue('EntryAuthorCommonName', array($this, 'EntryAuthorCommonName'));
-        $this->addValue('EntryAuthorDisplayName', array($this, 'EntryAuthorDisplayName'));
-        $this->addValue('EntryAuthorEmail', array($this, 'EntryAuthorEmail'));
-        $this->addValue('EntryAuthorEmailMD5', array($this, 'EntryAuthorEmailMD5'));
-        $this->addValue('EntryAuthorID', array($this, 'EntryAuthorID'));
-        $this->addValue('EntryAuthorLink', array($this, 'EntryAuthorLink'));
-        $this->addValue('EntryAuthorURL', array($this, 'EntryAuthorURL'));
-        $this->addValue('EntryBasename', array($this, 'EntryBasename'));
-        $this->addValue('EntryCategory', array($this, 'EntryCategory'));
-        $this->addValue('EntryCategoryDescription', array($this, 'EntryCategoryDescription'));
-        $this->addBlock('EntryCategoriesBreadcrumb', array($this, 'EntryCategoriesBreadcrumb'));
-        $this->addValue('EntryCategoryID', array($this, 'EntryCategoryID'));
-        $this->addValue('EntryCategoryURL', array($this, 'EntryCategoryURL'));
-        $this->addValue('EntryCategoryShortURL', array($this, 'EntryCategoryShortURL'));
-        $this->addValue('EntryCommentCount', array($this, 'EntryCommentCount'));
-        $this->addValue('EntryContent', array($this, 'EntryContent'));
-        $this->addValue('EntryDate', array($this, 'EntryDate'));
-        $this->addValue('EntryExcerpt', array($this, 'EntryExcerpt'));
-        $this->addValue('EntryFeedID', array($this, 'EntryFeedID'));
-        $this->addValue('EntryFirstImage', array($this, 'EntryFirstImage'));
-        $this->addValue('EntryID', array($this, 'EntryID'));
-        $this->addBlock('EntryIf', array($this, 'EntryIf'));
-        $this->addBlock('EntryIfContentCut', array($this, 'EntryIfContentCut'));
-        $this->addValue('EntryIfFirst', array($this, 'EntryIfFirst'));
-        $this->addValue('EntryIfOdd', array($this, 'EntryIfOdd'));
-        $this->addValue('EntryIfSelected', array($this, 'EntryIfSelected'));
-        $this->addValue('EntryLang', array($this, 'EntryLang'));
-        $this->addBlock('EntryNext', array($this, 'EntryNext'));
-        $this->addValue('EntryPingCount', array($this, 'EntryPingCount'));
-        $this->addValue('EntryPingData', array($this, 'EntryPingData'));
-        $this->addValue('EntryPingLink', array($this, 'EntryPingLink'));
-        $this->addBlock('EntryPrevious', array($this, 'EntryPrevious'));
-        $this->addValue('EntryTitle', array($this, 'EntryTitle'));
-        $this->addValue('EntryTime', array($this, 'EntryTime'));
-        $this->addValue('EntryURL', array($this, 'EntryURL'));
+        $this->addBlock('DateFooter', [$this, 'DateFooter']);
+        $this->addBlock('DateHeader', [$this, 'DateHeader']);
+        $this->addBlock('Entries', [$this, 'Entries']);
+        $this->addBlock('EntriesFooter', [$this, 'EntriesFooter']);
+        $this->addBlock('EntriesHeader', [$this, 'EntriesHeader']);
+        $this->addValue('EntryAuthorCommonName', [$this, 'EntryAuthorCommonName']);
+        $this->addValue('EntryAuthorDisplayName', [$this, 'EntryAuthorDisplayName']);
+        $this->addValue('EntryAuthorEmail', [$this, 'EntryAuthorEmail']);
+        $this->addValue('EntryAuthorEmailMD5', [$this, 'EntryAuthorEmailMD5']);
+        $this->addValue('EntryAuthorID', [$this, 'EntryAuthorID']);
+        $this->addValue('EntryAuthorLink', [$this, 'EntryAuthorLink']);
+        $this->addValue('EntryAuthorURL', [$this, 'EntryAuthorURL']);
+        $this->addValue('EntryBasename', [$this, 'EntryBasename']);
+        $this->addValue('EntryCategory', [$this, 'EntryCategory']);
+        $this->addValue('EntryCategoryDescription', [$this, 'EntryCategoryDescription']);
+        $this->addBlock('EntryCategoriesBreadcrumb', [$this, 'EntryCategoriesBreadcrumb']);
+        $this->addValue('EntryCategoryID', [$this, 'EntryCategoryID']);
+        $this->addValue('EntryCategoryURL', [$this, 'EntryCategoryURL']);
+        $this->addValue('EntryCategoryShortURL', [$this, 'EntryCategoryShortURL']);
+        $this->addValue('EntryCommentCount', [$this, 'EntryCommentCount']);
+        $this->addValue('EntryContent', [$this, 'EntryContent']);
+        $this->addValue('EntryDate', [$this, 'EntryDate']);
+        $this->addValue('EntryExcerpt', [$this, 'EntryExcerpt']);
+        $this->addValue('EntryFeedID', [$this, 'EntryFeedID']);
+        $this->addValue('EntryFirstImage', [$this, 'EntryFirstImage']);
+        $this->addValue('EntryID', [$this, 'EntryID']);
+        $this->addBlock('EntryIf', [$this, 'EntryIf']);
+        $this->addBlock('EntryIfContentCut', [$this, 'EntryIfContentCut']);
+        $this->addValue('EntryIfFirst', [$this, 'EntryIfFirst']);
+        $this->addValue('EntryIfOdd', [$this, 'EntryIfOdd']);
+        $this->addValue('EntryIfSelected', [$this, 'EntryIfSelected']);
+        $this->addValue('EntryLang', [$this, 'EntryLang']);
+        $this->addBlock('EntryNext', [$this, 'EntryNext']);
+        $this->addValue('EntryPingCount', [$this, 'EntryPingCount']);
+        $this->addValue('EntryPingData', [$this, 'EntryPingData']);
+        $this->addValue('EntryPingLink', [$this, 'EntryPingLink']);
+        $this->addBlock('EntryPrevious', [$this, 'EntryPrevious']);
+        $this->addValue('EntryTitle', [$this, 'EntryTitle']);
+        $this->addValue('EntryTime', [$this, 'EntryTime']);
+        $this->addValue('EntryURL', [$this, 'EntryURL']);
 
         # Languages
-        $this->addBlock('Languages', array($this, 'Languages'));
-        $this->addBlock('LanguagesHeader', array($this, 'LanguagesHeader'));
-        $this->addBlock('LanguagesFooter', array($this, 'LanguagesFooter'));
-        $this->addValue('LanguageCode', array($this, 'LanguageCode'));
-        $this->addBlock('LanguageIfCurrent', array($this, 'LanguageIfCurrent'));
-        $this->addValue('LanguageURL', array($this, 'LanguageURL'));
+        $this->addBlock('Languages', [$this, 'Languages']);
+        $this->addBlock('LanguagesHeader', [$this, 'LanguagesHeader']);
+        $this->addBlock('LanguagesFooter', [$this, 'LanguagesFooter']);
+        $this->addValue('LanguageCode', [$this, 'LanguageCode']);
+        $this->addBlock('LanguageIfCurrent', [$this, 'LanguageIfCurrent']);
+        $this->addValue('LanguageURL', [$this, 'LanguageURL']);
 
         # Pagination
-        $this->addBlock('Pagination', array($this, 'Pagination'));
-        $this->addValue('PaginationCounter', array($this, 'PaginationCounter'));
-        $this->addValue('PaginationCurrent', array($this, 'PaginationCurrent'));
-        $this->addBlock('PaginationIf', array($this, 'PaginationIf'));
-        $this->addValue('PaginationURL', array($this, 'PaginationURL'));
+        $this->addBlock('Pagination', [$this, 'Pagination']);
+        $this->addValue('PaginationCounter', [$this, 'PaginationCounter']);
+        $this->addValue('PaginationCurrent', [$this, 'PaginationCurrent']);
+        $this->addBlock('PaginationIf', [$this, 'PaginationIf']);
+        $this->addValue('PaginationURL', [$this, 'PaginationURL']);
 
         # Trackbacks
-        $this->addValue('PingBlogName', array($this, 'PingBlogName'));
-        $this->addValue('PingContent', array($this, 'PingContent'));
-        $this->addValue('PingDate', array($this, 'PingDate'));
-        $this->addValue('PingEntryTitle', array($this, 'PingEntryTitle'));
-        $this->addValue('PingFeedID', array($this, 'PingFeedID'));
-        $this->addValue('PingID', array($this, 'PingID'));
-        $this->addValue('PingIfFirst', array($this, 'PingIfFirst'));
-        $this->addValue('PingIfOdd', array($this, 'PingIfOdd'));
-        $this->addValue('PingIP', array($this, 'PingIP'));
-        $this->addValue('PingNoFollow', array($this, 'PingNoFollow'));
-        $this->addValue('PingOrderNumber', array($this, 'PingOrderNumber'));
-        $this->addValue('PingPostURL', array($this, 'PingPostURL'));
-        $this->addBlock('Pings', array($this, 'Pings'));
-        $this->addBlock('PingsFooter', array($this, 'PingsFooter'));
-        $this->addBlock('PingsHeader', array($this, 'PingsHeader'));
-        $this->addValue('PingTime', array($this, 'PingTime'));
-        $this->addValue('PingTitle', array($this, 'PingTitle'));
-        $this->addValue('PingAuthorURL', array($this, 'PingAuthorURL'));
+        $this->addValue('PingBlogName', [$this, 'PingBlogName']);
+        $this->addValue('PingContent', [$this, 'PingContent']);
+        $this->addValue('PingDate', [$this, 'PingDate']);
+        $this->addValue('PingEntryTitle', [$this, 'PingEntryTitle']);
+        $this->addValue('PingFeedID', [$this, 'PingFeedID']);
+        $this->addValue('PingID', [$this, 'PingID']);
+        $this->addValue('PingIfFirst', [$this, 'PingIfFirst']);
+        $this->addValue('PingIfOdd', [$this, 'PingIfOdd']);
+        $this->addValue('PingIP', [$this, 'PingIP']);
+        $this->addValue('PingNoFollow', [$this, 'PingNoFollow']);
+        $this->addValue('PingOrderNumber', [$this, 'PingOrderNumber']);
+        $this->addValue('PingPostURL', [$this, 'PingPostURL']);
+        $this->addBlock('Pings', [$this, 'Pings']);
+        $this->addBlock('PingsFooter', [$this, 'PingsFooter']);
+        $this->addBlock('PingsHeader', [$this, 'PingsHeader']);
+        $this->addValue('PingTime', [$this, 'PingTime']);
+        $this->addValue('PingTitle', [$this, 'PingTitle']);
+        $this->addValue('PingAuthorURL', [$this, 'PingAuthorURL']);
 
         # System
-        $this->addValue('SysBehavior', array($this, 'SysBehavior'));
-        $this->addBlock('SysIf', array($this, 'SysIf'));
-        $this->addBlock('SysIfCommentPublished', array($this, 'SysIfCommentPublished'));
-        $this->addBlock('SysIfCommentPending', array($this, 'SysIfCommentPending'));
-        $this->addBlock('SysIfFormError', array($this, 'SysIfFormError'));
-        $this->addValue('SysFeedSubtitle', array($this, 'SysFeedSubtitle'));
-        $this->addValue('SysFormError', array($this, 'SysFormError'));
-        $this->addValue('SysPoweredBy', array($this, 'SysPoweredBy'));
-        $this->addValue('SysSearchString', array($this, 'SysSearchString'));
-        $this->addValue('SysSelfURI', array($this, 'SysSelfURI'));
+        $this->addValue('SysBehavior', [$this, 'SysBehavior']);
+        $this->addBlock('SysIf', [$this, 'SysIf']);
+        $this->addBlock('SysIfCommentPublished', [$this, 'SysIfCommentPublished']);
+        $this->addBlock('SysIfCommentPending', [$this, 'SysIfCommentPending']);
+        $this->addBlock('SysIfFormError', [$this, 'SysIfFormError']);
+        $this->addValue('SysFeedSubtitle', [$this, 'SysFeedSubtitle']);
+        $this->addValue('SysFormError', [$this, 'SysFormError']);
+        $this->addValue('SysPoweredBy', [$this, 'SysPoweredBy']);
+        $this->addValue('SysSearchString', [$this, 'SysSearchString']);
+        $this->addValue('SysSelfURI', [$this, 'SysSelfURI']);
 
         # Generic
-        $this->addValue('else', array($this, 'GenericElse'));
+        $this->addValue('else', [$this, 'GenericElse']);
     }
 
@@ -243,5 +243,5 @@
 
         # --BEHAVIOR-- templateInsideBlock
-        $this->core->callBehavior('templateInsideBlock', $this->core, $this->current_tag, $attr, array(&$content));
+        $this->core->callBehavior('templateInsideBlock', $this->core, $this->current_tag, $attr, [&$content]);
 
         $res .= parent::compileBlockNode($this->current_tag, $attr, $content);
@@ -269,12 +269,12 @@
     }
 
-    public function getFilters($attr, $default = array())
+    public function getFilters($attr, $default = [])
     {
         if (!is_array($attr) && !($attr instanceof arrayObject)) {
-            $attr = array();
+            $attr = [];
         }
 
         $p = array_merge(
-            array(
+            [
                 0             => null,
                 'encode_xml'  => 0,
@@ -287,5 +287,5 @@
                 'capitalize'  => 0,
                 'strip_tags'  => 0
-            ),
+            ],
             $default
         );
@@ -318,10 +318,10 @@
     public function getSortByStr($attr, $table = null)
     {
-        $res = array();
+        $res = [];
 
         $default_order = 'desc';
 
-        $default_alias = array(
-            'post'    => array(
+        $default_alias = [
+            'post'    => [
                 'title'     => 'post_title',
                 'selected'  => 'post_selected',
@@ -331,11 +331,11 @@
                 'comment'   => 'nb_comment',
                 'trackback' => 'nb_trackback'
-            ),
-            'comment' => array(
+            ],
+            'comment' => [
                 'author' => 'comment_author',
                 'date'   => 'comment_dt',
                 'id'     => 'comment_id'
-            )
-        );
+            ]
+        ];
 
         $alias = new ArrayObject();
@@ -349,8 +349,8 @@
             foreach ($alias as $k => $v) {
                 if (!is_array($v)) {
-                    $alias[$k] = array();
+                    $alias[$k] = [];
                 }
                 if (!isset($default_alias[$k]) || !is_array($default_alias[$k])) {
-                    $default_alias[$k] = array();
+                    $default_alias[$k] = [];
                 }
                 $default_alias[$k] = array_merge($default_alias[$k], $alias[$k]);
@@ -474,5 +474,5 @@
     public function Archives($attr, $content)
     {
-        $p = "if (!isset(\$params)) \$params = array();\n";
+        $p = "if (!isset(\$params)) \$params = [];\n";
         $p .= "\$params['type'] = 'month';\n";
         if (isset($attr['type'])) {
@@ -507,5 +507,5 @@
         $res .= $p;
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Archives", "method" => "blog::getDates"),
+            ["tag" => "Archives", "method" => "blog::getDates"],
             $attr, $content);
         $res .= '$_ctx->archives = $core->blog->getDates($params); unset($params);' . "\n";
@@ -587,9 +587,9 @@
         return $this->displayCounter(
             sprintf($f, '$_ctx->archives->nb_post'),
-            array(
+            [
                 'none' => 'no archive',
                 'one'  => 'one archive',
                 'more' => '%d archives'
-            ),
+            ],
             $attr,
             true
@@ -607,5 +607,5 @@
     public function ArchiveNext($attr, $content)
     {
-        $p = "if (!isset(\$params)) \$params = array();\n";
+        $p = "if (!isset(\$params)) \$params = [];\n";
         $p .= "\$params['type'] = 'month';\n";
         if (isset($attr['type'])) {
@@ -626,5 +626,5 @@
         $res .= $p;
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "ArchiveNext", "method" => "blog::getDates"),
+            ["tag" => "ArchiveNext", "method" => "blog::getDates"],
             $attr, $content);
         $res .= '$_ctx->archives = $core->blog->getDates($params); unset($params);' . "\n";
@@ -647,5 +647,5 @@
     public function ArchivePrevious($attr, $content)
     {
-        $p = 'if (!isset($params)) $params = array();';
+        $p = 'if (!isset($params)) $params = [];';
         $p .= "\$params['type'] = 'month';\n";
         if (isset($attr['type'])) {
@@ -665,5 +665,5 @@
         $res = "<?php\n";
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "ArchivePrevious", "method" => "blog::getDates"),
+            ["tag" => "ArchivePrevious", "method" => "blog::getDates"],
             $attr, $content);
         $res .= $p;
@@ -900,5 +900,5 @@
     public function Categories($attr, $content)
     {
-        $p = "if (!isset(\$params)) \$params = array();\n";
+        $p = "if (!isset(\$params)) \$params = [];\n";
 
         if (isset($attr['url'])) {
@@ -921,5 +921,5 @@
         $res .= $p;
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Categories", "method" => "blog::getCategories"),
+            ["tag" => "Categories", "method" => "blog::getCategories"],
             $attr, $content);
         $res .= '$_ctx->categories = $core->blog->getCategories($params);' . "\n";
@@ -1095,9 +1095,9 @@
         return $this->displayCounter(
             sprintf($f, '$_ctx->categories->nb_post'),
-            array(
+            [
                 'none' => 'No post',
                 'one'  => 'One post',
                 'more' => '%d posts'
-            ),
+            ],
             $attr,
             true
@@ -1153,11 +1153,11 @@
                 // standard pagination, set offset
                 $p .= "if ((\$core->url->type == 'default') || (\$core->url->type == 'default-page')) {\n";
-                $p .= "    \$params['limit'] = array((\$_page_number == 1 ? 0 : (\$_page_number - 2) * \$nb_entry_per_page + \$nb_entry_first_page),\$params['limit']);\n";
+                $p .= "    \$params['limit'] = [(\$_page_number == 1 ? 0 : (\$_page_number - 2) * \$nb_entry_per_page + \$nb_entry_first_page),\$params['limit']];\n";
                 $p .= "} else {\n";
-                $p .= "    \$params['limit'] = array((\$_page_number - 1) * \$nb_entry_per_page,\$params['limit']);\n";
+                $p .= "    \$params['limit'] = [(\$_page_number - 1) * \$nb_entry_per_page,\$params['limit']];\n";
                 $p .= "}\n";
             } else {
                 // no pagination, get all posts from 0 to limit
-                $p .= "\$params['limit'] = array(0, \$params['limit']);\n";
+                $p .= "\$params['limit'] = [0, \$params['limit']];\n";
             }
         }
@@ -1243,5 +1243,5 @@
         $res .= $p;
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Entries", "method" => "blog::getPosts"),
+            ["tag" => "Entries", "method" => "blog::getPosts"],
             $attr, $content);
         $res .= '$_ctx->post_params = $params;' . "\n";
@@ -1894,9 +1894,9 @@
         return $this->displayCounter(
             $operation,
-            array(
+            [
                 'none' => 'no comments',
                 'one'  => 'one comment',
                 'more' => '%d comments'
-            ),
+            ],
             $attr,
             false
@@ -1916,9 +1916,9 @@
         return $this->displayCounter(
             '$_ctx->posts->nb_trackback',
-            array(
+            [
                 'none' => 'no trackbacks',
                 'one'  => 'one trackback',
                 'more' => '%d trackbacks'
-            ),
+            ],
             $attr,
             false
@@ -1953,5 +1953,5 @@
     public function Languages($attr, $content)
     {
-        $p = "if (!isset(\$params)) \$params = array();\n";
+        $p = "if (!isset(\$params)) \$params = [];\n";
 
         if (isset($attr['lang'])) {
@@ -1967,5 +1967,5 @@
         $res .= $p;
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Languages", "method" => "blog::getLangs"),
+            ["tag" => "Languages", "method" => "blog::getLangs"],
             $attr, $content);
         $res .= '$_ctx->langs = $core->blog->getLangs($params); unset($params);' . "\n";
@@ -2044,5 +2044,5 @@
         $p .= '$params = $_ctx->post_params;' . "\n";
         $p .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Pagination", "method" => "blog::getPosts"),
+            ["tag" => "Pagination", "method" => "blog::getPosts"],
             $attr, $content);
         $p .= '$_ctx->pagination = $core->blog->getPosts($params,true); unset($params);' . "\n";
@@ -2092,5 +2092,5 @@
     public function PaginationIf($attr, $content)
     {
-        $if = array();
+        $if = [];
 
         if (isset($attr['start'])) {
@@ -2194,5 +2194,5 @@
         $res = "<?php\n";
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Comments", "method" => "blog::getComments"),
+            ["tag" => "Comments", "method" => "blog::getComments"],
             $attr, $content);
         $res .= $p;
@@ -2373,5 +2373,5 @@
     public function CommentIf($attr, $content)
     {
-        $if      = array();
+        $if      = [];
         $is_ping = null;
 
@@ -2806,5 +2806,5 @@
         $res .= $p;
         $res .= $this->core->callBehavior("templatePrepareParams",
-            array("tag" => "Pings", "method" => "blog::getComments"),
+            ["tag" => "Pings", "method" => "blog::getComments"],
             $attr, $content);
         $res .= '$_ctx->pings = $core->blog->getComments($params); unset($params);' . "\n";
Index: inc/public/default-templates/dotty/404.html
===================================================================
--- inc/public/default-templates/dotty/404.html	(revision 3455)
+++ inc/public/default-templates/dotty/404.html	(revision 3849)
@@ -22,5 +22,5 @@
 	</header>
 
-	<nav class="content-inner">
+	<div class="content-inner">
 		<h3>{{tpl:lang Suggestions:}}</h3>
 		<ul>
@@ -29,4 +29,4 @@
 			<li><a href="{{tpl:BlogURL}}archive">{{tpl:lang Explore archives}}</a></li>
 		</ul>
-	</nav> <!-- # End #content-inner -->
+	</div> <!-- # End #content-inner -->
 </tpl:Block>
Index: inc/public/default-templates/dotty/_footer.html
===================================================================
--- inc/public/default-templates/dotty/_footer.html	(revision 3455)
+++ inc/public/default-templates/dotty/_footer.html	(revision 3846)
@@ -1,3 +1,3 @@
-<p id="gotop"><a href="#top">{{tpl:lang Page top}}</a></p>
+<p id="gotop"><a href="#prelude">{{tpl:lang Page top}}</a></p>
 
 <footer class="footer" id="footer" role="contentinfo">
Index: inc/public/default-templates/dotty/_video_player.html
===================================================================
--- inc/public/default-templates/dotty/_video_player.html	(revision 3246)
+++ inc/public/default-templates/dotty/_video_player.html	(revision 3848)
@@ -1,3 +1,3 @@
-<video controls preload="auto" width="400" height="300">
+<video controls preload="auto" style="width:400px; height:300px;">
 	<source src="{{tpl:MediaURL}}">
 </video>
Index: inc/public/default-templates/dotty/password-form.html
===================================================================
--- inc/public/default-templates/dotty/password-form.html	(revision 3455)
+++ inc/public/default-templates/dotty/password-form.html	(revision 3847)
@@ -42,5 +42,5 @@
 				<input type="password" name="password" value="" />
 			</label>
-			<input type="submit" value="ok" />
+			<input type="submit" value="ok" title="{{tpl:lang Access to content}}" />
 		</p>
 	</form>
Index: inc/public/default-templates/dotty/post.html
===================================================================
--- inc/public/default-templates/dotty/post.html	(revision 3422)
+++ inc/public/default-templates/dotty/post.html	(revision 3847)
@@ -36,22 +36,16 @@
 
 <tpl:Block name="main-content">
-	<nav class="navlinks topnl">
-		<tpl:EntryPrevious><a href="{{tpl:EntryURL}}"
-		 title="{{tpl:EntryTitle encode_html="1"}}" class="prev">&#171; {{tpl:EntryTitle encode_html="1"
+	<nav class="navlinks topnl" role="navigation" aria-label="{{tpl:lang Entries}}">
+		<tpl:EntryPrevious><a href="{{tpl:EntryURL}}" class="prev"><span aria-hidden="true">&#171; </span><span class="sr">{{tpl:lang Previous entry:}} </span>{{tpl:EntryTitle encode_html="1"
 		 cut_string="50"}}</a></tpl:EntryPrevious>
-		<tpl:EntryNext> <span>-</span> <a href="{{tpl:EntryURL}}"
-		 title="{{tpl:EntryTitle encode_html="1"}}" class="next">{{tpl:EntryTitle encode_html="1"
-		 cut_string="50"}} &#187;</a></tpl:EntryNext>
+		<tpl:EntryNext> <span>-</span> <a href="{{tpl:EntryURL}}" class="next"><span class="sr">{{tpl:lang Next entry:}} </span>{{tpl:EntryTitle encode_html="1" cut_string="50"}}<span aria-hidden="true"> &#187;</span></a></tpl:EntryNext>
 	</nav>
 
 	{{tpl:include src="_simple-entry.html"}}
 
-	<nav class="navlinks">
-		<tpl:EntryPrevious><a href="{{tpl:EntryURL}}"
-		 title="{{tpl:EntryTitle encode_html="1"}}" class="prev">&#171; {{tpl:EntryTitle encode_html="1"
+	<nav class="navlinks" role="navigation" aria-label="{{tpl:lang Entries}}">
+		<tpl:EntryPrevious><a href="{{tpl:EntryURL}}" class="prev"><span aria-hidden="true">&#171; </span><span class="sr">{{tpl:lang Previous entry:}} </span>{{tpl:EntryTitle encode_html="1"
 		 cut_string="50"}}</a></tpl:EntryPrevious>
-		<tpl:EntryNext> <span>-</span> <a href="{{tpl:EntryURL}}"
-		 title="{{tpl:EntryTitle encode_html="1"}}" class="next">{{tpl:EntryTitle encode_html="1"
-		 cut_string="50"}} &#187;</a></tpl:EntryNext>
+		<tpl:EntryNext> <span>-</span> <a href="{{tpl:EntryURL}}" class="next"><span class="sr">{{tpl:lang Next entry:}} </span>{{tpl:EntryTitle encode_html="1" cut_string="50"}}<span aria-hidden="true"> &#187;</span></a></tpl:EntryNext>
 	</nav>
 </tpl:Block>
Index: inc/public/lib.tpl.context.php
===================================================================
--- inc/public/lib.tpl.context.php	(revision 3830)
+++ inc/public/lib.tpl.context.php	(revision 3874)
@@ -12,5 +12,5 @@
 class context
 {
-    public $stack = array();
+    public $stack = [];
 
     public function __set($name, $var)
@@ -105,5 +105,5 @@
         return self::global_filters(
             $str,
-            array(0       => null,
+            [0       => null,
                 'encode_xml'  => $encode_xml,
                 'remove_html' => $remove_html,
@@ -112,10 +112,50 @@
                 'upper_case'  => ($upper_case == 1 ? 1 : 0),
                 'capitalize'  => ($upper_case == 2 ? 1 : 0),
-                'encode_url'  => $encode_url),
+                'encode_url'  => $encode_url],
             $tag);
     }
 
+    private static function default_filters($filter, $str, $arg)
+    {
+        switch ($filter) {
+            case 'strip_tags':
+                return self::strip_tags($str);
+
+            case 'remove_html':
+                return preg_replace('/\s+/', ' ', self::remove_html($str));
+
+            case 'encode_xml':
+            case 'encode_html':
+                return self::encode_xml($str);
+
+            case 'cut_string':
+                return self::cut_string($str, (integer) $arg);
+
+            case 'lower_case':
+                return self::lower_case($str);
+
+            case 'capitalize':
+                return self::capitalize($str);
+
+            case 'upper_case':
+                return self::upper_case($str);
+
+            case 'encode_url':
+                return self::encode_url($str);
+        }
+        return $str;
+    }
+
     public static function global_filters($str, $args, $tag = '')
     {
+        $filters = [
+            'strip_tags',                             // Removes HTML tags (mono line)
+            'remove_html',                            // Removes HTML tags
+            'encode_xml', 'encode_html',              // Encode HTML entities
+            'cut_string',                             // Cut string (length in $args['cut_string'])
+            'lower_case', 'capitalize', 'upper_case', // Case transformations
+            'encode_url'                             // URL encode (as for insert in query string)
+        ];
+
         $args[0] = &$str;
 
@@ -124,29 +164,18 @@
         $str = $args[0];
 
-        if ($args['strip_tags']) {
-            $str = self::strip_tags($str);
-        }
-        if ($args['remove_html']) {
-            $str = self::remove_html($str);
-            $str = preg_replace('/\s+/', ' ', $str);
-        }
-        if ($args['encode_xml'] || $args['encode_html']) {
-            $str = self::encode_xml($str);
-        }
-
-        if ($args['cut_string'] > 0) {
-            $str = self::cut_string($str, (integer) $args['cut_string']);
-        }
-
-        if ($args['lower_case']) {
-            $str = self::lower_case($str);
-        } elseif ($args['capitalize']) {
-            $str = self::capitalize($str);
-        } elseif ($args['upper_case']) {
-            $str = self::upper_case($str);
-        }
-
-        if ($args['encode_url']) {
-            $str = self::encode_url($str);
+        foreach ($filters as $filter) {
+            # --BEHAVIOR-- publicContentFilter
+            switch ($GLOBALS['core']->callBehavior('publicContentFilter', $GLOBALS['core'], $tag, $args, $filter)) {
+                case '1':
+                    // 3rd party filter applied and must stop
+                    break;
+                case '0':
+                default:
+                    // 3rd party filter applied and should continue
+                    // Apply default filter
+                    if ($args[$filter]) {
+                        $str = self::default_filters($filter, $str, $args[$filter]);
+                    }
+            }
         }
 
@@ -180,5 +209,5 @@
     public static function strip_tags($str)
     {
-        return trim(preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t"), ' ', html::clean($str))));
+        return trim(preg_replace('/ {2,}/', ' ', str_replace(["\r", "\n", "\t"], ' ', html::clean($str))));
     }
 
@@ -307,5 +336,5 @@
     public static function robotsPolicy($base, $over)
     {
-        $pol  = array('INDEX' => 'INDEX', 'FOLLOW' => 'FOLLOW', 'ARCHIVE' => 'ARCHIVE');
+        $pol  = ['INDEX' => 'INDEX', 'FOLLOW' => 'FOLLOW', 'ARCHIVE' => 'ARCHIVE'];
         $base = array_flip(preg_split('/\s*,\s*/', $base));
         $over = array_flip(preg_split('/\s*,\s*/', $over));
@@ -330,5 +359,5 @@
     public static function getSmilies($blog)
     {
-        $path = array();
+        $path = [];
         if (isset($GLOBALS['__theme'])) {
             $path[] = $GLOBALS['__theme'];
@@ -341,5 +370,5 @@
         $base_url   = $blog->settings->system->themes_url . '/%s/smilies/';
 
-        $res = array();
+        $res = [];
 
         foreach ($path as $t) {
@@ -356,5 +385,5 @@
         $def = file($f);
 
-        $res = array();
+        $res = [];
         foreach ($def as $v) {
             $v = trim($v);
@@ -419,5 +448,5 @@
         #
         $index  = 0;
-        $tokens = array();
+        $tokens = [];
 
         $match = '(?s:<!(?:--.*?--\s*)+>)|' . # comment
@@ -430,7 +459,7 @@
         foreach ($parts as $part) {
             if (++$index % 2 && $part != '') {
-                $tokens[] = array('text', $part);
+                $tokens[] = ['text', $part];
             } else {
-                $tokens[] = array('tag', $part);
+                $tokens[] = ['tag', $part];
             }
 
Index: inc/public/lib.urlhandlers.php
===================================================================
--- inc/public/lib.urlhandlers.php	(revision 3731)
+++ inc/public/lib.urlhandlers.php	(revision 3874)
@@ -33,5 +33,5 @@
     {
         $core = &$GLOBALS['core'];
-        $t    = new ArrayObject(array($type, $url, $representation, $handler));
+        $t    = new ArrayObject([$type, $url, $representation, $handler]);
         $core->callBehavior("publicRegisterURL", $t);
         parent::register($t[0], $t[1], $t[2], $t[3]);
@@ -241,5 +241,5 @@
             $GLOBALS['_search'] = !empty($_GET['q']) ? rawurldecode($_GET['q']) : '';
             if ($GLOBALS['_search']) {
-                $params = new ArrayObject(array('search' => $GLOBALS['_search']));
+                $params = new ArrayObject(['search' => $GLOBALS['_search']]);
                 $core->callBehavior('publicBeforeSearchCount', $params);
                 $GLOBALS['_search_count'] = $core->blog->getPosts($params, true)->f(0);
@@ -256,6 +256,6 @@
 
         $n      = self::getPageNumber($args);
-        $params = new ArrayObject(array(
-            'lang' => $args));
+        $params = new ArrayObject([
+            'lang' => $args]);
 
         $core->callBehavior('publicLangBeforeGetLangs', $params, $args);
@@ -286,8 +286,8 @@
             self::p404();
         } else {
-            $params = new ArrayObject(array(
+            $params = new ArrayObject([
                 'cat_url'       => $args,
                 'post_type'     => 'post',
-                'without_empty' => false));
+                'without_empty' => false]);
 
             $core->callBehavior('publicCategoryBeforeGetCategories', $params, $args);
@@ -317,8 +317,8 @@
             self::serveDocument('archive.html');
         } elseif (preg_match('|^/([0-9]{4})/([0-9]{2})$|', $args, $m)) {
-            $params = new ArrayObject(array(
+            $params = new ArrayObject([
                 'year'  => $m[1],
                 'month' => $m[2],
-                'type'  => 'month'));
+                'type'  => 'month']);
 
             $core->callBehavior('publicArchiveBeforeGetDates', $params, $args);
@@ -349,6 +349,6 @@
             $core->blog->withoutPassword(false);
 
-            $params = new ArrayObject(array(
-                'post_url' => $args));
+            $params = new ArrayObject([
+                'post_url' => $args]);
 
             $core->callBehavior('publicPostBeforeGetPosts', $params, $args);
@@ -380,10 +380,10 @@
                         $pwd_cookie = json_decode($_COOKIE['dc_passwd']);
                         if ($pwd_cookie === null) {
-                            $pwd_cookie = array();
+                            $pwd_cookie = [];
                         } else {
                             $pwd_cookie = (array) $pwd_cookie;
                         }
                     } else {
-                        $pwd_cookie = array();
+                        $pwd_cookie = [];
                     }
 
@@ -542,5 +542,5 @@
 
         if (preg_match('!^([a-z]{2}(-[a-z]{2})?)/(.*)$!', $args, $m)) {
-            $params = new ArrayObject(array('lang' => $m[1]));
+            $params = new ArrayObject(['lang' => $m[1]]);
 
             $args = $m[3];
@@ -582,7 +582,7 @@
 
         if ($cat_url) {
-            $params = new ArrayObject(array(
+            $params = new ArrayObject([
                 'cat_url'   => $cat_url,
-                'post_type' => 'post'));
+                'post_type' => 'post']);
 
             $core->callBehavior('publicFeedBeforeGetCategories', $params, $args);
@@ -598,7 +598,7 @@
             $subtitle = ' - ' . $_ctx->categories->cat_title;
         } elseif ($post_id) {
-            $params = new ArrayObject(array(
+            $params = new ArrayObject([
                 'post_id'   => $post_id,
-                'post_type' => ''));
+                'post_type' => '']);
 
             $core->callBehavior('publicFeedBeforeGetPosts', $params, $args);
@@ -650,5 +650,5 @@
 
             if (!is_array($args)) {
-                $args = array();
+                $args = [];
             }
 
@@ -668,5 +668,5 @@
         $core = &$GLOBALS['core'];
         if (!is_array($args)) {
-            $args = array();
+            $args = [];
         }
 
Index: inc/public/prepend.php
===================================================================
--- inc/public/prepend.php	(revision 3731)
+++ inc/public/prepend.php	(revision 3874)
@@ -130,10 +130,10 @@
 # Prepare the HTTP cache thing
 $mod_files = get_included_files();
-$mod_ts    = array();
+$mod_ts    = [];
 $mod_ts[]  = $core->blog->upddt;
 
-$__theme_tpl_path = array(
+$__theme_tpl_path = [
     $core->blog->themes_path . '/' . $__theme . '/tpl'
-);
+];
 if ($__parent_theme) {
     $__theme_tpl_path[] = $core->blog->themes_path . '/' . $__parent_theme . '/tpl';
Index: inc/public/rs.extension.php
===================================================================
--- inc/public/rs.extension.php	(revision 3731)
+++ inc/public/rs.extension.php	(revision 3874)
@@ -10,6 +10,6 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('coreBlogGetPosts', array('rsExtendPublic', 'coreBlogGetPosts'));
-$core->addBehavior('coreBlogGetComments', array('rsExtendPublic', 'coreBlogGetComments'));
+$core->addBehavior('coreBlogGetPosts', ['rsExtendPublic', 'coreBlogGetPosts']);
+$core->addBehavior('coreBlogGetComments', ['rsExtendPublic', 'coreBlogGetComments']);
 
 class rsExtendPublic
Index: locales/en/help/core_wiki.html
===================================================================
--- locales/en/help/core_wiki.html	(revision 2534)
+++ locales/en/help/core_wiki.html	(revision 3859)
@@ -26,14 +26,21 @@
   <code>*</code> or <code>#</code> for unnumbered or numbered lists respectively.
   List imbrication is done by mixing list markers this way:
-<pre>
-* item 1
-** item 1.1
-* item 2
-*# item 2.1
-...
-</pre>
+  <pre>
+    <code>*</code> item 1
+    <code>**</code> item 1.1
+    <code>*</code> item 2
+    <code>*#</code> item 2.1
+  ...
+  </pre>
+  </li>
+  <li><strong>Definition lists:</strong> Start each line with <code>=</code> for the term to define and with <code>:</code> for the definition of the term.
+  <pre>
+  <code>=</code> term
+  <code>:</code> description of the term
+  </pre>
   </li>
   <li><strong>Preformatted text:</strong> Each line must start with a space.</li>
   <li><strong>Block quote:</strong> Each line must start with a <code>&gt;</code>.</li>
+  <li><strong>Side block:</strong> Each line must start with a <code>)</code>.</li>
 </ul>
 </dd>
@@ -61,4 +68,5 @@
   <li><strong>Code:</strong> <code>@@code@@</code></li>
   <li><strong>Footnotes:</strong> <code>$$footnote$$</code></li>
+  <li><strong>Superscript</strong>&nbsp;: <code>^superscript^</code></li>
 </ul>
 </dd>
Index: locales/en/plugins.po
===================================================================
--- locales/en/plugins.po	(revision 3784)
+++ locales/en/plugins.po	(revision 3817)
@@ -469,4 +469,7 @@
 msgstr ""
 
+msgid "More information on <a href="https://en.wikipedia.org/wiki/XHTML_Friends_Network">Wikipedia</a> website"
+msgstr ""
+
 msgid "_xfn_Me"
 msgstr "Me"
Index: locales/fr/help/core_wiki.html
===================================================================
--- locales/fr/help/core_wiki.html	(revision 2798)
+++ locales/fr/help/core_wiki.html	(revision 3859)
@@ -33,7 +33,14 @@
 </pre>
   </li>
+  <li><strong>Listes de définition</strong>&nbsp;: ligne débutant par <code>=</code> pour le terme à définir et par <code>:</code> pour la définition du terme.
+  <pre>
+  <code>=</code> terme
+  <code>:</code> définition du terme
+  </pre>
+  </li>
   <li><strong>Texte préformaté</strong>&nbsp;: espace avant chaque ligne de texte.</li>
   <li><strong>Bloc de citation</strong>&nbsp;: <code>&gt;</code> devant chaque
   ligne de texte.</li>
+  <li><strong>Bloc de côté</strong>&nbsp;: <code>)</code> devant chaque ligne de texte</li>
 </ul>
 </dd>
@@ -60,4 +67,5 @@
   <li><strong>Code</strong>&nbsp;: <code>@@code ici@@</code></li>
   <li><strong>Note de bas de page</strong>&nbsp;: <code>$$Corps de la note$$</code></li>
+  <li><strong>Exposant</strong>&nbsp;: <code>^exposant^</code></li>
 </ul>
 </dd>
Index: locales/fr/main.po
===================================================================
--- locales/fr/main.po	(revision 3795)
+++ locales/fr/main.po	(revision 3836)
@@ -591,4 +591,10 @@
 msgstr "Mettre à jour les thèmes"
 
+msgid "Manual checking of themes update done successfully."
+msgstr "La vérification manuelle de mise à jour des thèmes a été effectuée."
+
+msgid "Force checking update of themes"
+msgstr "Forcer la vérification de mise à jour des thèmes"
+
 #, php-format
 msgid "There is one theme to update available from repository."
@@ -1782,4 +1788,10 @@
 msgstr "Mise à jour des plugins"
 
+msgid "Manual checking of plugins update done successfully."
+msgstr "La vérification manuelle de mise à jour des plugins a été effectuée."
+
+msgid "Force checking update of plugins"
+msgstr "Forcer la vérification de mise à jour des plugins"
+
 #, php-format
 msgid "There is one plugin to update available from repository."
@@ -2153,4 +2165,7 @@
 msgstr "Les favoris par défaut ont été enregistrés."
 
+msgid "Dashboard items order have been successfully reset."
+msgstr "Le positionnement des éléments du tableau de bord a été réinitialisé."
+
 msgid "My profile"
 msgstr "Mon profil"
@@ -2337,4 +2352,10 @@
 msgid "Save my dashboard options"
 msgstr "Enregistrer les options de mon tableau de bord"
+
+msgid "Dashboard items order"
+msgstr "Positionnement des éléments du tableau de bord"
+
+msgid "Reset dashboard items order"
+msgstr "Réinitialiser le positionnement des éléments du tableau de bord"
 
 msgid "Search options"
Index: locales/fr/plugins.po
===================================================================
--- locales/fr/plugins.po	(revision 3790)
+++ locales/fr/plugins.po	(revision 3817)
@@ -476,78 +476,81 @@
 msgstr "Informations XFN"
 
+msgid "More information on <a href="https://en.wikipedia.org/wiki/XHTML_Friends_Network">Wikipedia</a> website"
+msgstr "Plus d'information sur le site <a href="https://fr.wikipedia.org/wiki/XHTML_Friends_Network">Wikipedia</a>"
+
 msgid "_xfn_Me"
-msgstr "_xfn_Me"
+msgstr "Identité"
 
 msgid "_xfn_Another link for myself"
-msgstr "_xfn_Another link for myself"
+msgstr "Une autre de mes adresses Web"
 
 msgid "_xfn_Friendship"
-msgstr "_xfn_Friendship"
+msgstr "Amitié"
 
 msgid "_xfn_Contact"
-msgstr "_xfn_Contact"
+msgstr "Contact"
 
 msgid "_xfn_Acquaintance"
-msgstr "_xfn_Acquaintance"
+msgstr "Connaissance"
 
 msgid "_xfn_Friend"
-msgstr "_xfn_Friend"
+msgstr "Ami·e"
 
 msgid "_xfn_Physical"
-msgstr "_xfn_Physical"
+msgstr "Physique"
 
 msgid "_xfn_Met"
-msgstr "_xfn_Met"
+msgstr "Rencontré·e"
 
 msgid "_xfn_Professional"
-msgstr "_xfn_Professional"
+msgstr "Professionnel"
 
 msgid "_xfn_Co-worker"
-msgstr "_xfn_Co-worker"
+msgstr "Collègue de travail"
 
 msgid "_xfn_Colleague"
-msgstr "_xfn_Colleague"
+msgstr "Consœur ou Confrère"
 
 msgid "_xfn_Geographical"
-msgstr "_xfn_Geographical"
+msgstr "Géographique"
 
 msgid "_xfn_Co-resident"
-msgstr "_xfn_Co-resident"
+msgstr "Colocataire"
 
 msgid "_xfn_Neighbor"
-msgstr "_xfn_Neighbor"
+msgstr "Voisin"
 
 msgid "_xfn_Family"
-msgstr "_xfn_Family"
+msgstr "Famille"
 
 msgid "_xfn_Child"
-msgstr "_xfn_Child"
+msgstr "Enfant"
 
 msgid "_xfn_Parent"
-msgstr "_xfn_Parent"
+msgstr "Parent"
 
 msgid "_xfn_Sibling"
-msgstr "_xfn_Sibling"
+msgstr "Sœur/frère"
 
 msgid "_xfn_Spouse"
-msgstr "_xfn_Spouse"
+msgstr "Conjoint·e"
 
 msgid "_xfn_Kin"
-msgstr "_xfn_Kin"
+msgstr "Famille"
 
 msgid "_xfn_Romantic"
-msgstr "_xfn_Romantic"
+msgstr "Romantique"
 
 msgid "_xfn_Muse"
-msgstr "_xfn_Muse"
+msgstr "Muse"
 
 msgid "_xfn_Crush"
-msgstr "_xfn_Crush"
+msgstr "Coup de foudre"
 
 msgid "_xfn_Date"
-msgstr "_xfn_Date"
+msgstr "Petit·e ami·e"
 
 msgid "_xfn_Sweetheart"
-msgstr "_xfn_Sweetheart"
+msgstr "Être aimé"
 
 msgid "Nothing to import"
Index: locales/fr/public.po
===================================================================
--- locales/fr/public.po	(revision 3686)
+++ locales/fr/public.po	(revision 3847)
@@ -68,4 +68,7 @@
 msgstr "%d annexes"
 
+msgid "Previous entry:"
+msgstr "Billet précédent :"
+
 msgid "previous entries"
 msgstr "billets précédents"
@@ -77,4 +80,10 @@
 msgstr "de"
 
+msgid "Entries"
+msgstr "Billets"
+
+msgid "Next entry:"
+msgstr "Billet suivant :"
+
 msgid "next entries"
 msgstr "billets suivants"
@@ -251,4 +260,7 @@
 msgstr "Mot de passe :"
 
+msgid "Access to content"
+msgstr "Accéder au contenu"
+
 msgid "You must provide a valid email address."
 msgstr "Vous devez indiquer une adresse e-mail valide."
Index: locales/lb/date.po
===================================================================
--- locales/lb/date.po	(revision 3818)
+++ locales/lb/date.po	(revision 3818)
@@ -0,0 +1,135 @@
+# SOME DESCRIPTIVE TITLE.
+# This file is put in the public domain.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Dotclear 2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-04-15 16:27+0200\n"
+"PO-Revision-Date: 2017-01-15 19:05+0100\n"
+"Last-Translator: Alain Vagner<alain.vagner@sous-anneau.org>\n"
+"Language-Team: \n"
+"Language: lb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.11\n"
+
+msgid "%Y-%m-%d %H:%M"
+msgstr ""
+
+msgid "_Jan"
+msgstr "Jan"
+
+msgid "_Feb"
+msgstr "Feb"
+
+msgid "_Mar"
+msgstr "Mäe"
+
+msgid "_Apr"
+msgstr "Abr"
+
+msgid "_May"
+msgstr "Mee"
+
+msgid "_Jun"
+msgstr "Jun"
+
+msgid "_Jul"
+msgstr "Jul"
+
+msgid "_Aug"
+msgstr "Aug"
+
+msgid "_Sep"
+msgstr "Sep"
+
+msgid "_Oct"
+msgstr "Okt"
+
+msgid "_Nov"
+msgstr "Nov"
+
+msgid "_Dec"
+msgstr "Dez"
+
+msgid "January"
+msgstr "Januar"
+
+msgid "February"
+msgstr "Februar"
+
+msgid "March"
+msgstr "Mäerz"
+
+msgid "April"
+msgstr "Abrëll"
+
+msgid "May"
+msgstr "Mee"
+
+msgid "June"
+msgstr "Juni"
+
+msgid "July"
+msgstr "Juli"
+
+msgid "August"
+msgstr "August"
+
+msgid "September"
+msgstr "September"
+
+msgid "October"
+msgstr "Oktober"
+
+msgid "November"
+msgstr "November"
+
+msgid "December"
+msgstr "Dezember"
+
+msgid "_Mon"
+msgstr "Méi"
+
+msgid "_Tue"
+msgstr "Dën"
+
+msgid "_Wed"
+msgstr "Mët"
+
+msgid "_Thu"
+msgstr "Don"
+
+msgid "_Fri"
+msgstr "Fre"
+
+msgid "_Sat"
+msgstr "Sam"
+
+msgid "_Sun"
+msgstr "Son"
+
+msgid "Monday"
+msgstr "Méindeg"
+
+msgid "Tuesday"
+msgstr "Dënschdeg"
+
+msgid "Wednesday"
+msgstr "Mëttwoch"
+
+msgid "Thursday"
+msgstr "Donneschdeg"
+
+msgid "Friday"
+msgstr "Freideg"
+
+msgid "Saturday"
+msgstr "Samschdeg"
+
+msgid "Sunday"
+msgstr "Sonndeg"
Index: locales/lb/help/core_blog_new.html
===================================================================
--- locales/lb/help/core_blog_new.html	(revision 3818)
+++ locales/lb/help/core_blog_new.html	(revision 3818)
@@ -0,0 +1,24 @@
+<html>
+<head>
+  <title>New blog</title>
+</head>
+
+<body>
+
+<h4>Create a new blog</h4>
+<dl>
+  <dt>Blog ID</dt>
+  <dd>Unique identifier of the blog. Mandatory, can only be modified by a super administrator.</dd>
+
+  <dt>Blog name</dt>
+  <dd>Blog name. Mandatory, can be modified at any time without any impact on the blog operation.</dd>
+
+  <dt>Blog URL</dt>
+  <dd>Full URL of the blog. Mandatory, can only be modified by a super administrator.</dd>
+
+  <dt>Blog description</dt>
+  <dd>Free text to describe the blog. It is a simple text without any specific formatting.</dd>
+</dl>
+
+</body>
+</html>
Index: locales/lb/help/core_blog_pref.html
===================================================================
--- locales/lb/help/core_blog_pref.html	(revision 3818)
+++ locales/lb/help/core_blog_pref.html	(revision 3818)
@@ -0,0 +1,202 @@
+<html>
+<head>
+  <title>Blog settings</title>
+</head>
+
+<body>
+<h4>Blog details</h4>
+<dl>
+  <dt>Blog ID</dt>
+  <dd>Unique ID of the blog. Mandatory, can only be modified by a super administrator.</dd>
+
+  <dt>Blog name</dt>
+  <dd>Name of the blog, mandatory. It can be modified at any time without any impact on the blog operation.</dd>
+
+  <dt>Blog URL</dt>
+  <dd>Full blog URL. Mandatory, can only be modified by a super administrator.</dd>
+
+  <dt>URL scan method</dt>
+  <dd>Defines the way the URL is read. PATH_INFO is recommended, QUERY_STRING has to be used if PATH_INFO does not work. Using PATH_INFO mode, the blog URL must end with a "/" and using QUERY_STRING, it must end with an "?".</dd>
+
+  <dt>Blog status</dt>
+  <dd>
+    <ul>
+      <li><strong>Online:</strong> Blog open to visitors.</li>
+      <li><strong>Offline:</strong> Blog closed to visitors but open to writers.</li>
+      <li><strong>Removed:</strong> Blog closed to both visitors and writers, open only to super administrators.</li>
+    </ul>
+  </dd>
+
+  <dt>Blog description</dt>
+  <dd>Here you can put any description you want for your blog. This is a simple text, without any formatting.</dd>
+</dl>
+
+<h4>Blog configuration</h4>
+<dl>
+  <dt>Blog editor's name</dt>
+  <dd>Name of the person responsible for the blog. It may be the owner or the publisher if there is one. This information will be displayed in the blog feed.</dd>
+
+  <dt>Default language</dt>
+  <dd>Language of the blog interface. Either this language is amongst the avalaible ones, and the interface will be translated, or it is not, and the interface will be in English by default.</dd>
+
+  <dt>Blog timezone</dt>
+  <dd>Defines the timezone that will be used for comments and trackbacks.</dd>
+
+  <dt>Copyright notice</dt>
+  <dd>Note about the reproduction rights for the blog.</dd>
+
+  <dt>New post URL format</dt>
+  <dd>Dropdown list to select the URL format.</dd>
+
+  <dt>HTML tag for the title of the notes on the blog</dt>
+  <dd>Dropdown list to select an HTML tag.</dd>
+
+  <dt>XML/RPC interface</dt>
+  <dd>Allows external clients to interact with your blog via the XML/RPC protocol. After activation the required parameters to be set in your external clients are displayed.</dd>
+</dl>
+
+<h4>Comments and trackbacks</h4>
+<dl>
+  <dt>Accept comments</dt>
+  <dd>Globally accepts comments on the blog. Takes precedence over the per post setting.</dd>
+
+  <dt>Moderate comments</dt>
+  <dd>With this option, comments will be published only after editor's agreement.</dd>
+
+  <dt>Leave comments open for X days</dt>
+  <dd>The number of days during wich comments will be open after the post publication. When empty, the comments will be kept open indefinitly.</dd>
+
+  <dt>Wiki syntax for comments</dt>
+  <dd>Allows a subset of the wiki syntax to be used in comments.</dd>
+
+  <dt>Accept trackbacks</dt>
+  <dd>Globally accepts trackbacks on the blog. Takes precedence over the per post setting.</dd>
+
+  <dt>Moderate trackbacks</dt>
+  <dd>With this option, trackbacks will be published only after editor's agreement.</dd>
+
+  <dt>Leave trackbacks open for X days</dt>
+  <dd>The number of days during wich trackbacks will be open after the post publication. When empty, the trackbacks will be kept open indefinitly.</dd>
+
+  <dt>Add "nofollow" relation on comments and trackbacks links</dt>
+  <dd>Adds an attribute on links in comments and trackbacks, instructing the search bots not to follow them. This antispam features has yet to prove its value.</dd>
+</dl>
+
+<h4>Blog presentation</h4>
+<dl>
+  <dt>Date format</dt>
+  <dd>Defines the date format for the blog posts. See the "Format reference" section below for more information. You can use the dropdown list to quickly select a pre-existing pattern.</dd>
+
+  <dt>Time format</dt>
+  <dd>Defines the time format for the blog posts. See the "Format reference" section below for more information. You can use the dropdown list to quickly select a pre-existing pattern.</dd>
+
+  <dt>Display smilies on entries and comments</dt>
+  <dd>Turns some strings like :-) or ;-) into pictures.</dd>
+
+  <dt>Display X entries per page</dt>
+  <dd>Will display X entries on the blog main page as well as in the different categories.</dd>
+
+  <dt>Display X entries per feed</dt>
+  <dd>Will display X entries in the blog feeds.</dd>
+
+  <dt>Display X comments per feed</dt>
+  <dd>Will display X comments in the blog comments feeds.</dd>
+
+  <dt>Truncate feeds</dt>
+  <dd>This option will only provide an abstract from the blog posts in the feeds.</dd>
+
+  <dt>Include sub-categories in category page and category posts feed</dt>
+  <dd>When this option is activated, posts in sub-categories will be displayed in the parent categories pages as well as in their feeds.</dd>
+</dl>
+
+<h4>Media and images</h4>
+<dl>
+  <dt>Generated image sizes (in pixels)</dt>
+  <dd>When you add an image in the media manager, other sizes are automatically generated. Here you can define the dimension of the longest size (width or heigth) of each type of generated images. If you leave one field empty, the media manager will not create the corresponding miniature.</dd>
+
+  <dt>Default image insertion attributes</dt>
+  <dd>The selected settings will apply on all the new images added to the media manager.</dd>
+
+  <dt>Inserted image title</dt>
+  <dd>Select the format of the "title" tags applied to your images, based on information retrieved from the images metadata.</dd>
+
+  <dt>Use original media date if possible</dt>
+  <dd>When this option is activated, if the image metadata contains a date, it will be used. If not, the upload date will be used.</dd>
+
+  <dt>Size of inserted image</dt>
+  <dd>Defines the default size used when inserting an image in a blog post.</dd>
+
+  <dt>Image alignment</dt>
+  <dd>Defines the default alignment used when inserting an image in a blog post.</dd>
+
+  <dt>Insert a link to the original image</dt>
+  <dd>When this option is activated, the pictures inserted in a blog post will be clickable and point to the original-sized picture.</dd>
+
+</dl>
+
+<h4>Search engines robots policy</h4>
+<p>Here you can indicate if you want Web search engines to index and/or archive your pages or not. Select the last option if you do not want people to be able to find your blog using a Web search engine.</p>
+
+<h4>Antispam</h4>
+<p>You can set the number of days after which you want the junk comments to be automatically deleted. Leave that field blank (or put 0) to deactivate this feature.</p>
+
+<h4>Users</h4>
+<p>Lists this blog's users as well as their permissions.</p>
+
+<h3>Format reference</h3>
+<p>Some fields can be configured to format the date and time to your needs.
+Here is a reference:</p>
+
+<ul>
+  <li><strong>%a:</strong> Abreviated week day (local).</li>
+  <li><strong>%A:</strong> Complete week day (local).</li>
+  <li><strong>%b:</strong> Abbreviated month name (local).</li>
+  <li><strong>%B:</strong> Complete month name (local).</li>
+  <li><strong>%c:</strong> Default local date and time display.</li>
+  <li><strong>%C:</strong> Century (the year, divided by 100 and
+  round up beetween 00 and 99)</li>
+  <li><strong>%d:</strong> Numeric month day (from 01 to 31)</li>
+  <li><strong>%D:</strong> Identical to %m/%d/%y</li>
+  <li><strong>%e:</strong> Numeric month day (from 1 to 31)</li>
+  <li><strong>%g:</strong> Identical to %G, 2 digits.</li>
+  <li><strong>%G:</strong> The year on 4 digits, according to the week number
+  (cf. %V). Format and value identical to %Y, except that if the number of the
+  week belongs to the preceding or following year, the current year
+  will be used instead.</li>
+  <li><strong>%h:</strong> Identical to %b</li>
+  <li><strong>%H:</strong> Digital hour of the day, 24H mode
+  (from 00 to 23)</li>
+  <li><strong>%I:</strong> Digital hour of the day, 12H mode
+  (from 01 to 12)</li>
+  <li><strong>%j:</strong> Day of the year, digital (from 001 to 366)</li>
+  <li><strong>%m:</strong> Month, digital (from 1 à 12)</li>
+  <li><strong>%M:</strong> Minute, digital</li>
+  <li><strong>%n:</strong> Newline character</li>
+  <li><strong>%p:</strong> Either `am' or `pm', according to the absolute time,
+  or depending of the local settings.</li>
+  <li><strong>%r:</strong> The hour, a.m. and p.m. format</li>
+  <li><strong>%R:</strong> The hour, 24h format</li>
+  <li><strong>%S:</strong> Seconds, digital</li>
+  <li><strong>%t:</strong> Tab character</li>
+  <li><strong>%T:</strong> The current time (identical to %H:%M:%S)</li>
+  <li><strong>%u:</strong> Day week, digit, from 1 to 7. (1 stands for monday)</li>
+  <li><strong>%U:</strong> Week number, the first Sunday of the year being the
+  first day of the first week.</li>
+  <li><strong>%V:</strong> The week number as defined in ISO
+  8601:1988, digital, from 01 to 53. The week 1 is the first week
+  with more than 4 days in the current year, whose Monday is the first day.
+  (Use %G or %g for the year elements corresponding to the number of the
+  week for the considered timestamp.)</li>
+  <li><strong>%W:</strong> Number of the week in the year, the first Monday of
+  the year being the start of the first week</li>
+  <li><strong>%w:</strong> Day of the week, digital, 0 stands for sunday</li>
+  <li><strong>%x:</strong> Prefered format for the date without the time</li>
+  <li><strong>%X:</strong> Prefered format for the time without the date</li>
+  <li><strong>%y:</strong> The year, two digits (from 00 to 99)</li>
+  <li><strong>%Y:</strong> The year, four digits</li>
+  <li><strong>%Z or %z:</strong> Timezone, name or abbreviation</li>
+  <li><strong>%%:</strong> A litteral `%' character</li>
+</ul>
+
+</body>
+</html>
Index: locales/lb/help/core_blog_theme.html
===================================================================
--- locales/lb/help/core_blog_theme.html	(revision 3818)
+++ locales/lb/help/core_blog_theme.html	(revision 3818)
@@ -0,0 +1,20 @@
+<html>
+<head>
+  <title>Blog aspect</title>
+</head>
+
+<body>
+
+<h4>Installed themes</h4>
+<p>The list of installed themes appears in this tab. You can select a theme by clicking on it and pressing <strong>Use this one</strong>.</p>
+<p>The currently selected theme can be modified using the <strong>Edit theme files</strong> button. If the selected theme includes a theme editor, it can be easily personalized using the <strong>Configure theme</strong> button.</p>
+<p>You can also deactivate a theme (for instance if you have compatibilities issues with it). A <strong>Deactivated themes</strong> tab will appear containing the list of these.</p>
+
+<h4>Add themes</h4>
+<p>This tab allows you to browse the DotAddict themes repository either by alphabetical order, either by searching using the dedicated field. The themes that are already installed do not appear in the list.</p>
+
+<h4>Install or upgrade manually</h4>
+<p>If the theme you want to install (or upgrade) is not in the DotAddict repository, you can install it either by uploading it from your hard drive, either by entering its installation URL. A theme is always packaged as a zip file.</p>
+
+</body>
+</html>
Index: locales/lb/help/core_blogs.html
===================================================================
--- locales/lb/help/core_blogs.html	(revision 3818)
+++ locales/lb/help/core_blogs.html	(revision 3818)
@@ -0,0 +1,24 @@
+<html>
+<head>
+  <title>List of blogs</title>
+</head>
+
+<body>
+
+<h4>Filter the list of blogs</h4>
+<dl>
+  <dt>Search</dt>
+  <dd>The search is based on the blog identifier. You can use the <strong>*</strong> wildcard to specify only a part of the name.</dd>
+
+  <dt>Order by</dt>
+  <dd>Last update of the blog, blog name, blog ID.</dd>
+
+  <dt>Sort</dt>
+  <dd>Indicate the sorting you want to use to filter the results (descending or ascending).</dd>
+
+  <dt>Blogs per page</dt>
+  <dd>Selects the number of blogs displayed per page in this list.</dd>
+</dl>
+
+</body>
+</html>
Index: locales/lb/help/core_categories.html
===================================================================
--- locales/lb/help/core_categories.html	(revision 3818)
+++ locales/lb/help/core_categories.html	(revision 3818)
@@ -0,0 +1,29 @@
+<html>
+  <head>
+    <title>Categories</title>
+  </head>
+  <body>
+    <h4>Categories list</h4>
+    <dl>
+      <dt>Delete a category</dt>
+      <dd>Choose the category you want to delete by clicking on <strong>Delete the category</strong>. A pop-up will ask you to confirm this action.<br />
+	A category can only be deleted if it contains no article in it.<br />
+  To empty a category, you can move the entries by selecting (in the dropdown list) the new category they will be moved to. Click <strong>OK</strong> to confirm this choice.
+      </dd>
+
+      <dt>Reorder categories</dt>
+      <dd>You can modify the categories order using drag and drop. You can also move a category to a parent category.<br />
+        When you're satisfied with the order, click <strong>Save categories order</strong>.</dd>
+      
+      <dt>Reorder all categories on the top level</dt>
+      <dd>Use this option to move back all the categories to the top level.<br />
+        If you want to modify the categories order more precisely, you can :
+	<ul>
+	  <li>either move them using drag and drop,</li>
+	  <li>either click on each category name and select its parent category or its position to its siblings.</li>
+	</ul>
+      </dd>
+    </dl>
+
+  </body>
+</html>
Index: locales/lb/help/core_category.html
===================================================================
--- locales/lb/help/core_category.html	(revision 3818)
+++ locales/lb/help/core_category.html	(revision 3818)
@@ -0,0 +1,32 @@
+<html>
+<head>
+  <title>Category</title>
+</head>
+
+<body>
+<h4>Create a new category</h4>
+<dl>
+  <dt>Name</dt>
+  <dd>Choose the name you want to give to your new category. This field is mandatory.</dd>
+
+  <dt>Parent</dt>
+  <dd>It is possible to create sub-categories. In that case, you have to select its parent category in the <strong>Parent</strong> field.</dd>
+
+  <dt>URL</dt>
+  <dd>Dotclear creates a default URL for the category, making it reachable with a path such as <strong>http://myblog.tld/category/My-category</strong>. By clicking the little lock on the right, you can modify it the way you like.</dd>
+
+  <dt>Description</dt>
+  <dd>This description field content will be displayed when entering a category in the blog. You can fill it with any kind of content (paragraphs, lists, etc.). The format used for this field is XHTML.</dd>
+</dl>
+
+<h4>Move this category</h4>
+<dl>
+  <dt>Parent category</dt>
+  <dd>It is possible to create sub-categories. In that case, you have to select its parent category in the <strong>Parent</strong> field.</dd>
+
+  <dt>Sibling category</dt>
+  <dd>You can move the category into any other one, which will become its parent. You can also specify its position to its other siblings by moving it before or after one of them.</dd>
+</dl>
+
+</body>
+</html>
Index: locales/lb/help/core_comments.html
===================================================================
--- locales/lb/help/core_comments.html	(revision 3818)
+++ locales/lb/help/core_comments.html	(revision 3818)
@@ -0,0 +1,58 @@
+<html>
+<head>
+  <title>Comments</title>
+</head>
+
+<body>
+<h3>Filters for comment list</h3>
+<dl>
+  <dt>Type:</dt>
+  <dd>None, comments or trackbacks.</dd>
+  
+  <dt>Status:</dt>
+  <dd><ul>
+    <li><strong>junk</strong>: <!-- Pour spampl' ? --></li>
+    <li><strong>pending</strong>: <!-- Modération ? --></li>
+    <li><strong>unpublished</strong>: offline ;</li>
+    <li><strong>published</strong>: online.</li>
+  </ul></dd>
+  
+  <dt>Order by:</dt>
+  <dd>Choose: date, entry title, author or status, then
+  choose the sort order.</dd>
+  
+  <dt>Sort</dt>
+  <dd>Choose whether the list will be sorted in ascending or descending order.</dd>
+  
+  <dt>Comment author.</dt>
+  <dd>The search is not case sensitive. If you want to search only a part of
+  the name, you can use the <strong>*</strong> generic character.</dd>
+  
+  <dt>Comments per page :</dt>
+  <dd>Allows you to choose the number of comments on each page of this list.</dd>
+</dl>
+
+<h3>Modify or add a comment</h3>
+<dl>
+  <dt>Author:</dt>
+  <dd>Author name. This field is mandatory.</dd>
+  
+  <dt>Email:</dt>
+  <dd>Author's email address.</dd>
+  
+  <dt>Web site:</dt>
+  <dd>URL of the comment author's blog or website.</dd>
+  
+  <dt>Status:</dt>
+  <dd><ul>
+    <li><strong>junk</strong>: <!-- Pour spampl' ? --></li>
+    <li><strong>pending</strong>: <!-- Modération ? --></li>
+    <li><strong>unpublished</strong>: offline</li>
+    <li><strong>published</strong>: online</li>
+  </ul></dd>
+  
+  <dt>Comment:</dt>
+  <dd>Comment's content. This field is html formated.</dd>
+</dl>
+</body>
+</html>
Index: locales/lb/help/core_dashboard.html
===================================================================
--- locales/lb/help/core_dashboard.html	(revision 3818)
+++ locales/lb/help/core_dashboard.html	(revision 3818)
@@ -0,0 +1,29 @@
+<html>
+<head>
+  <title>Dashboard</title>
+</head>
+
+<body>
+<h4>Header</h4>
+	<p>If there are several blogs you can access on this instance, a dropdown list allows you to pick the one you want to work on. If there is only one blog, it simply displays its name.</p>
+	<p>The following link allows to go on the current blog (opens in a new tab).</p>
+	<p>The other links allow you to go back to this dashboard, to access your preferences and to logout.</p>
+<h4>Personalisation of the dashboard</h4>
+	<dl>
+		<dt>Favorites</dt>
+		<dd>The big icons in the middle of the page allow you to quickly access your favorite admin pages.</dd>
+		<dt>Dashboard modules</dt>
+		<dd>The modules displayed under the favorites are installed by default or added by plugins.</dd>
+	</dl>
+	<p>You can personalize the display of favorites and modules by going in the <a href="preferences.php#user-favorites">My dashboard</a> tab in the <strong>My preferences</strong> page.</p>
+<h4>The main menu</h4>
+	<p>You can display or hide this menu at any time by clicking on its right side<span class="hidden"> (or by activating the <strong>Hide the main menu</strong> link)</span>.</p>
+	<p>The first part of the menu lists all the favorite pages of the user. You can select to display this list or not in the <a href="preferences.php#user-favorites">My dashboard</a> tab in the <strong>My preferences</strong> page.</p>
+	<p>The rest of the menu lists the administration pages. It is divided in three sections:</p>
+	<ul>
+		<li><strong>Blog</strong> for everything relative to the current blog content and parameters.</li>
+		<li><strong>System settings</strong> to manage the global installation.</li>
+		<li><strong>Plugins</strong> for extensions affecting the whole system.</li>
+	</ul>
+</body>
+</html>
Index: locales/lb/help/core_langs.html
===================================================================
--- locales/lb/help/core_langs.html	(revision 3818)
+++ locales/lb/help/core_langs.html	(revision 3818)
@@ -0,0 +1,22 @@
+<html>
+<head>
+  <title>Languages</title>
+</head>
+
+<body>
+
+<h4>Installed languages</h4>
+<p>You will find here the list of installed languages available for your administration profile and for your blog. Each of these languages can be removed.</p>
+<p>In the case where no language would be present, English would be used by default for the administration part as well as for the blog.</p>
+
+<h4>Install or upgrade languages</h4>
+
+<h5>Available languages</h5>
+<p>You will find here a list of languages available on Dotclear website. To install one of these languages, select it in the dropdown list, enter your password and press <strong>Install language</strong>.</p>
+<p>The selected language will then be downloaded and installed on your system.</p>
+
+<h5>Upload a zip file</h5>
+<p>You can also use a compressed archive (zip format) to install a language. Select the corresponding file on your computer, enter your password and press <strong>Upload language</strong>.</p>
+
+</body>
+</html>
Index: locales/lb/help/core_media.html
===================================================================
--- locales/lb/help/core_media.html	(revision 3818)
+++ locales/lb/help/core_media.html	(revision 3818)
@@ -0,0 +1,92 @@
+<html>
+  <head>
+    <title>Media manager</title>
+  </head>
+  <body>
+    <h4>Media list</h4>
+    <p>The main page of the media manager displays a list of available files (media) for the currently selected blog.</p>
+
+    <p>You can click the icons or names of the media in the folder or any subfolder to display them.</p>
+
+    <p>Selecting a MP3 sound file displays a player to immediately play the file. The Flash plugin must be installed on your browser for this player to operate.</p>
+
+    <p>The images are displayed with a thumbnail when possible.</p>
+
+    <h4>Add files</h4>
+    <dl>
+      <dt>Choose a file</dt>
+      <dd>Here you can select one of your local files to send it on your 
+      blog. Should the file be bigger than the maximum size, it will not be sent.</dd>
+      
+      <dt>Title</dt>
+      <dd>Optional title for the file you want to send.</dd>
+      
+      <dt>Private</dt>
+      <dd>Check this if you want the file to be private, i.e. accessible only by
+      its owner and not accessible from the blog (until published).</dd>
+    </dl>
+
+    <dl>
+      <dt>Enhanced uploader</dt>
+      <dd>Allows to select one or several of your local files to send them on your 
+  blog. Should any file be bigger than the maximum size, it will not be sent.<br />
+	When you select several local files, they are added to the queue. You can add more files by clicking again on <strong>Choose files</strong>. You can also remove files from the queue by clicking on the corresponding red cross-shaped icon.<br />
+  When you are ready, click on <strong>Upload</strong>.</dd>
+    </dl>
+
+    <h4>Delete files</h4>
+    <p>To delete a file, check its checkbox and click on <strong>Remove selected media</strong>. You can delete several files at once.</p>
+
+    <h4>New folder</h4>
+    <p>This form allows you to create a new subfolder in the currently displayed
+folder. Just choose a name for it as you would do on your own computer.</p>
+
+    <h4>Media details</h4>
+    <p>This page displays a set of information about the currently selected file and allows you to perform a several operations on it.</p>
+
+    <dl>
+      <dt>File name</dt>
+      <dd>Change the file name of the current file.</dd>
+      
+      <dt>File title</dt>
+      <dd>Give a title to the file or change the current one.</dd>
+      
+      <dt>File date</dt>
+      <dd>Change the file date.</dd>
+      
+      <dt>Private</dt>
+      <dd>Specify that the file will be hidden to anyone but its owner in the media manager.</dd>
+      
+      <dt>New directory</dt>
+      <dd>Allows you to move the file in another folder.</dd>
+      
+      <dt>Change file</dt>
+      <dd>With this form, you can replace the file while keeping all the attributes
+      (name, title...). As always, you have to respect the maximum file size.</dd>
+    </dl>
+
+    <h4>Specific case: images</h4>
+    <p>When you add an image, depending of its size, up to four versions will be made available (depending on the original image size):</p>
+    <ul>
+      <li><strong>Square:</strong> A 48x48 pixels square thumbnail.</li>
+      <li><strong>Thumbnail:</strong> The image reduced to 100 pixels on its longest side.</li>
+      <li><strong>Small:</strong> The longest side is reduced to 240 pixels.</li>
+      <li><strong>Medium:</strong> The longest side is reduced to 500 pixels.</li>
+      <li><strong>Original:</strong> The original, unchanged image.</li>
+    </ul>
+    <p>Default sizes for the thumbnail, small and medium versions can be modified in your blog settings.</p>
+
+    <h4>Attach a file to an entry</h4>
+    <p>You can easily attach a file to one of your posts. First, create a new post and save it. Then click on "Add files to this entry" to open the media manager.</p>
+
+    <p>Just click on the [+] icon (Attach this file to entry). The file will then
+be attached to the post.</p>
+
+    <p>The attached files will be shown on the post page, as a list after the post content. The MP3 files will be made available through a Flash player, so that they can be easily played by your visitors.</p>
+
+    <h4>Podcast and broadcasting of music files</h4>
+    <p>All attached files will be included in your blog feeds, allowing an easy
+podcasting of any type of file.</p>
+
+  </body>
+</html>
Index: locales/lb/help/core_plugins.html
===================================================================
--- locales/lb/help/core_plugins.html	(revision 3818)
+++ locales/lb/help/core_plugins.html	(revision 3818)
@@ -0,0 +1,42 @@
+<html>
+<head>
+  <title>Plugins management</title>
+</head>
+
+<body>
+
+<h4>Installed plugins</h4>
+
+<p>Each line starts with the plugin logo you will find in the menu (on the left of your screen).</p>
+
+<p>A Dotclear logo next to the action buttons indicates that the plugin comes directly with Dotclear and is one of its components.</p>
+
+<h3>Activated plugins</h3>
+<p>This list displays information about activated plugins: Name, version, short description. Two actions are possible: <strong>Deactivate</strong> (temporary operation) or <strong>Delete</strong> (permanent operation).</p>
+
+
+<h3>Deactivated plugins</h3>
+<p>This list shows the plugins that have been deactivated by the user. For each one, two actions are possible: <strong>Activate</strong> or <strong>Delete</strong> (permanent operation).</p> 
+
+
+<h4>Add plugins</h4>
+<p>This page allows you to browse the DotAddict repository and to install a plugin directly from it.</p>
+
+<p>Two search methods are available:</p>
+<ul>
+	<li>By typing the plugin name in the <em>Search in repository</em> field,
+	<li>By browsing the index</li>
+</ul>
+<p>In the index, unfolding a plugin by clicking on the arrow next to its name will allow you to access its DotAddict page or to go to a support website if the plugin author picked one.</p>
+
+
+<h4>Install or upgrade manually</h4>
+<p>You can install your own plugins or plugins that are not available on DotAddict using this page.</p>
+<p>There are two ways to install them:</p>
+<ul>
+	<li><strong>Upload a zip file</strong> from your computer. Click on <strong>Browse</strong> to select the file, enter your password, and press <strong>Upload</strong>.
+	<li><strong>Download a zip file</strong> directly from the Web by entering its URL, then enter your password and press <strong>Download</strong>.</li>
+</ul>
+
+</body>
+</html>
Index: locales/lb/help/core_post.html
===================================================================
--- locales/lb/help/core_post.html	(revision 3818)
+++ locales/lb/help/core_post.html	(revision 3818)
@@ -0,0 +1,114 @@
+<html>
+<head>
+  <title>Editing an entry</title>
+</head>
+
+<body>
+<h4>Editing an entry</h4>
+
+<dl>
+  <dt>Entry title</dt>
+  <dd>Type in the entry title. This field is mandatory.</dd>
+  
+  <dt>Excerpt</dt>
+  <dd>The content of this field will be shown in pages showing entries as
+  a list, such as the homepage or categories pages, followed by a "continue reading"
+  link. It will also be visible at the beginning of the page showing the
+  whole post. Should you leave it blank, the <em>content</em> field will be shown entirely on the homepage and other entry list pages.</dd>
+  
+  <dt>Content</dt>
+  <dd>The content of your entry. This field is mandatory.</dd>
+  
+  <dt>Personal notes</dt>
+  <dd>This text area is for personal use, for notes or memos. What you enter here
+  will never be displayed on the blog.</dd>
+  
+  <dt>Entry status</dt>
+  <dd>Allows you to choose your entry's status:
+    <ul>
+      <li><strong>Pending:</strong> The publication status has not yet been decided.</li>
+      <li><strong>Scheduled:</strong> The post will be set online at the time and date set in the <strong>Published on</strong> field.</li>
+      <li><strong>Unpublished:</strong> The post is offline.</li>
+      <li><strong>Published:</strong> The post is online.</li>
+    </ul>
+  </dd>
+  
+  <dt>Publication date and hour</dt>
+  <dd>Here you can change the entry's publication date and time. If the entry's
+  status is <strong>Scheduled</strong>, it will be online at the given date and time.</dd>
+
+  <dt>Entry language</dt>
+  <dd>Select the language code of your entry. It defaults to your (as a
+  user) language but you can change it to whatever language code you want, e.g.
+  "en" or "es-ar". This code is used for the entry's display.</dd>
+
+  <dt>Text formatting</dt>
+  <dd>Choose the entry's syntax. Wiki is a simplified syntax
+  and will be converted to valid XHTML. Unless you have a perfect
+  understanding of XHTML, we advise you to choose the Wiki syntax.
+  See the Wiki syntax reference for more information.</dd>
+
+  <dt>Selected entry</dt>
+  <dd>The selected entries will be listed on your blog menu, under the title "Best of me".</dd>
+
+  <dt>Category</dt>
+  <dd>Your entry's category. To create a new category, please see the
+  <strong>Categories</strong> section. You can choose to leave
+  you entry without a category by selecting the <em>(none)</em> item.</dd>
+
+  <dt>Add a new category</dt>
+  <dd>You can create a new category by entering its title and selecting its parent category (or select <em>(none)</em> to create a top level category).</dd>
+  
+  <dt>Tags</dt>
+  <dd>Add tags separated by commas, and press <strong>ok</strong> when done. You can also select existing tags by clicking on <strong>Choose from list</strong>.</dd>
+
+  <dt>Attachments</dt>
+  <dd>Attachments are media files added to the entry. You can use the <strong>Add files to this entry</strong> button to select media files to add to the entry.<br />
+    This option will appear after you save your entry.<br />
+    Please check the Media manager help for more information.</dd>
+
+  <dt>Accept comments</dt>
+  <dd>Check this box to allow your visitors to comment on this entry. The corresponding global setting can be found in the blog settings.</dd>
+
+  <dt>Accept trackbacks</dt>
+  <dd>A trackback is a way to let a portion of your entry as a comment on
+  another blog. Check this box to allow others to trackback your entry. The
+  corresponding global setting is to be found in the blog settings.</dd>
+  
+  <dt>Password</dt>
+  <dd>You can enter a password for your entry. A password protected entry will
+  not be displayed on your blog, it will only be accessible to those you will
+  give the entry URL to (see the <strong>view entry</strong> link) and password.</dd>
+
+  <dt>Basename</dt>
+  <dd>You can unprotect this field by clicking on the little lock on its right and choose another URL for your entry. If the URL you're trying to use is already used by another entry, a number will be added to it.</dd>  
+  
+</dl>
+
+<h4>Comments</h4>
+<dl>
+  <dt>Comment list</dt>
+  <dd>On the <strong>Comments</strong> tab, you can read and change the status of
+  your entry's comments (and trackbacks). If you're allowed to by the blog administrator, you will be able to set your comments (and trackbacks) online or offline, to delete them or to mark them as junk.</dd>
+  
+  <dt>Add a comment</dt>
+  <dd>On the <strong>Add a comment</strong> tab, you can reply to one of your entry's comments without leaving your blog's backend. The syntax to be used here is plain, unlimited XHTML. Use the fields as if you were modifying a comment.</dd>
+</dl>
+  
+<h4>Add a comment</h4>
+<dl>
+  <dt>Name</dt>
+  <dd>Comment author's name. This field is mandatory.</dd>
+
+  <dt>Email</dt>
+  <dd>Comment author's e-mail address.</dd>
+
+  <dt>Website</dt>
+  <dd>Comment author's Website URL.</dd>
+
+  <dt>Comment</dt>
+  <dd>Comment content. This field uses XHTML syntax.</dd>
+</dl>
+
+</body>
+</html>
Index: locales/lb/help/core_posts.html
===================================================================
--- locales/lb/help/core_posts.html	(revision 3818)
+++ locales/lb/help/core_posts.html	(revision 3818)
@@ -0,0 +1,63 @@
+<html>
+<head>
+  <title>Entries management</title>
+</head>
+
+<body>
+
+<h4>Entries list filter</h4>
+
+<dl>
+  <dt>Author</dt>
+  <dd>Filters entries by author.</dd>
+  
+  <dt>Category</dt>
+  <dd>Filters entries by category.</dd>
+  
+  <dt>Status</dt>
+  <dd>Filters entries by status:<ul>
+      <li><strong>Pending:</strong> Pending entries.</li>
+      <li><strong>Scheduled:</strong> Scheduled entries.</li>
+      <li><strong>Unpublished:</strong> Offline entries.</li>
+      <li><strong>Published:</strong> Online entries.</li>
+    </ul></dd>
+  
+  <dt>Selected</dt>
+  <dd>Filters entries that have the <strong>Selected</strong> status or not.</dd>
+
+  <dt>Attachments</dt>
+  <dd>Filters entries based on if they have attachments or not.</dd>
+  
+  <dt>Month</dt>
+  <dd>Filters entries from the given month of a given year.</dd>
+  
+  <dt>Language</dt>
+  <dd>Filters entries based on the language set in the <strong>Language</strong> field of an entry.</dd>
+  
+  <dt>Order by</dt>
+  <dd>Allows you to order the result by date, title, category, author, publication status, selected status, number of comments or number of trackbacks.</dd>
+  
+  <dt>Sort</dt>
+  <dd>Allows you to sort the results ascending or descending.</dd>
+  
+  <dt>Entries per page</dt>
+  <dd>Number of entries to display per page.</dd>
+</dl>
+
+<h4>Batch actions</h4>
+<p>It is possible to make a batch of actions on several articles. The possible actions depend on the user's permissions:</p>
+<ul>
+  <li><strong>Publish:</strong> Publish the selected entries online.</li>
+  <li><strong>Unpublish:</strong> Pull the selected entries offline.</li>
+  <li><strong>Schedule:</strong> Schedule the selected entries to be set online at publication date.</li>
+  <li><strong>Mark as pending:</strong> Mark selected entries as pending.</li>
+  <li><strong>Mark as selected/unselected:</strong> Set the selected entries as Selected/Unselected./li>
+  <li><strong>Change category:</strong> Modify the category of the selected entries.</li>
+  <li><strong>Change language:</strong> Modify the language of the selected entries.</li>
+  <li><strong>Change author:</strong> Modify the selected entries' author by entering the new author's ID.</li>
+  <li><strong>Delete:</strong> Delete the selected entries (this operation cannot be cancelled).</li>
+  <li><strong>Add/Remove tags:</strong> Add or remove tags on the selected entries.</li>
+</ul>
+<p><em>The above list might contain other items if additional actions have been added by plugins active on your system.</em></p>
+</body>
+</html>
Index: locales/lb/help/core_search.html
===================================================================
--- locales/lb/help/core_search.html	(revision 3818)
+++ locales/lb/help/core_search.html	(revision 3818)
@@ -0,0 +1,36 @@
+<html>
+<head>
+  <title>Search</title>
+</head>
+
+<body>
+<h4>Search options</h4>
+	<p>Specify the words or terms you're looking for in the text field and select the search scope:</p>
+	<dl>
+	<dt>Search in entries</dt>
+	<dd>Search will only be done on <strong>Article title</strong>, <strong>Summary</strong> and <strong>Content</strong> fields of an entry.</dd>
+	<dt>Search in comments</dt>
+	<dd>Search will only be done on comments.</dd>
+	</dl>
+
+<h4>Search results</h4>
+	<h5>Result</h5>
+		<p>A search result allows you to click on one of the article's link to edit it.</p>
+	<h5>Batch actions</h5>
+		<p>It is possible to make a batch of actions on several articles in one time. The possible actions depend on the user's permissions:</p>
+		<ul>
+			<li><strong>Publish:</strong> Publish the article.</li>
+			<li><strong>Unpublish:</strong> Put the article offline.</li>
+			<li><strong>Schedule:</strong> Schedule the entries to be put online at the publication date.</li>
+			<li><strong>Mark as pending:</strong> Pending to be published.</li>
+			<li><strong>Mark as selected:</strong> Highlight the selected entries.</li>
+			<li><strong>Mark as unselected:</strong> Remove the highlight (if any) on selected entries.</li>
+			<li><strong>Change category:</strong> Redirect on the categories list to change the category of the selected articles.</li>
+			<li><strong>Change language:</strong> Redirect on the languages list to modify the entries languages.</li>
+			<li><strong>Change author:</strong> Allows to modify the entries author by specifying the user ID of the new author.</li>
+			<li><strong>Delete:</strong> Delete the entries. A pop-up window will be displayed to confirm your choice.</li>
+			<li><strong>Add tags:</strong> Add tags to the selected entries.</li>
+			<li><strong>Remove tags:</strong> Remove one or more tags from the selected entries.</li>
+		<ul>
+</body>
+</html>
Index: locales/lb/help/core_trackbacks.html
===================================================================
--- locales/lb/help/core_trackbacks.html	(revision 3818)
+++ locales/lb/help/core_trackbacks.html	(revision 3818)
@@ -0,0 +1,25 @@
+<html>
+<head>
+  <title>Editing an entry</title>
+</head>
+
+<body>
+
+<h4>Trackbacks</h4>
+<p>To make a trackback, click on the <em>Ping blogs</em> link. If you don't see this link, make sure your entry status is set to <em>published</em>.</p>
+
+<dl>
+  <dt>URLs to ping</dt>
+  <dd>Paste here the trackback URLs you found in the posts you want to ping.</dd>
+  
+  
+  <dt>Excerpt to send</dt>
+  <dd>By default, this field contains the beginning of your entry. This is what will be sent to the blog you're pinging, along with a link to your post. You can modify the excerpt by editing this field.</dd>
+  
+  <dt>Auto discover ping URLs</dt>
+  <dd>If your entry links to specific posts and if the blog hosting those posts
+  is set to allow it, this tool will find the URLs to ping for you.</dd>
+</dl>
+
+</body>
+</html>
Index: locales/lb/help/core_update.html
===================================================================
--- locales/lb/help/core_update.html	(revision 3818)
+++ locales/lb/help/core_update.html	(revision 3818)
@@ -0,0 +1,25 @@
+<html>
+  <head>
+    <title>Update</title>
+  </head>
+  <body>
+    <h4>Update</h4>
+    <p>This page allows you to update Dotclear automatically. If a new version is available, you will be asked if you want to update. Before doing so, you can check what changes do this update bring by clicking on <strong>Information about this version</strong>.</p>
+
+    <p>You can force the new version check by clicking on <strong>Force Dotclear update checking</strong>.</p>
+
+    <p>If everything is OK, i.e. if you didn't manually modified any installation files, the update procedure will:</p>
+    <ul>
+      <li>Create a backup of your current installation in the current working directory named backup-x.y.z.zip (where x.y.z are the version numbers, e.g. 2.5.3).</li>
+      <li>Download the new version.</li>
+    </ul>
+    <p>Once this is done, a message such as the following will be displayed: "Congratulations, you're one click away from the end of the update."<br />
+      Click on <strong>Finish the update</strong>. You will be logged out. The database will be updated, if needed, when you will log back in.</p>
+
+    <p>If you manually modified some files, they will be listed and you will be advised to manually update them.</p>
+
+    <h4>Manage backup files</h4>
+    <p>From this tab, you can remove old backup files.</p>
+    <p>You can also rollback to a previous version. Only consider rolling back if you have serious troubles with the new version.</p>
+  </body>
+</html>
Index: locales/lb/help/core_user.html
===================================================================
--- locales/lb/help/core_user.html	(revision 3818)
+++ locales/lb/help/core_user.html	(revision 3818)
@@ -0,0 +1,70 @@
+<html>
+<head>
+  <title>User</title>
+</head>
+
+<body>
+
+<h4>User profile</h4>
+<dl>
+  <dt>User ID</dt>
+  <dd>At least 2 characters using letters, numbers or symbols (no space). This field is mandatory.</dd>
+
+  <dt>New password</dt>
+  <dd>If you want to change your password, enter the new password twice in <strong>New password</strong> and <strong>Confirm password</strong> fields. Passwords must contain at least 6 characters. Both fields are mandatory.</dd>
+
+  <dt>Password change required to connect</dt>
+  <dd>Check this box so that a new user will have to choose his own password when he will connect.</dd>
+
+  <dt>Super administrator</dt>
+  <dd>This will give the current user all the permissions on all the blogs hosted on the system.</dd>
+  
+  <dt>Last name, First name</dt>
+  <dd>If no display name is provided, the displayed author's name will contain the last name and first name entered in these two fields.</dd>
+
+  <dt>Display name</dt>
+  <dd>You can select the nickname you want to use to sign your articles. If not empty, this field will be used instead of the last name and first name fields.</dd>
+
+  <dt>Email</dt>
+  <dd>This e-mail address will be used if you need to recover your password from Dotclear's authentication screen.</dd>
+
+  <dt>URL</dt>
+  <dd>Indicates the user's website. If this field is not empty, the author's name will become a clickable link to this website.</dd>
+</dl>
+
+<h4>Options</h4>
+<h5>Interface</h5>
+<dl>
+  <dt>Language</dt>
+  <dd>Set the default language for new entries. If a translation is available for this language, the blog interface will be translated in this language as well.</dd>
+
+  <dt>Timezone</dt>
+  <dd>This option impacts the way the entries' publication time is displayed.</dd>
+</dl>
+
+<h5>Edition</h5>
+<dl>  
+  <dt>Preferred format</dt>
+  <dd>Choose the entry's syntax. Wiki is a simplified syntax
+  and will be converted to valid XHTML. Unless you have a perfect
+  understanding of XHTML, we advise you to choose the Wiki syntax.
+  See the Wiki syntax reference for more information.</dd>
+  
+  <dt>Default entry status</dt>
+  <dd>The default status for new entries can be set to:
+    <ul>
+      <li><strong>Pending:</strong> The publication status has not been yet decided.</li>
+      <li><strong>Scheduled:</strong> The entry will be set online at the time and date provided in the <strong>Published on</strong> field.</li>
+      <li><strong>Unpublished:</strong> Offline entry.</li>
+      <li><strong>Published:</strong> Online entry.</li>
+    </ul>
+  </dd>
+
+  <dt>Entry edit field height</dt>
+  <dd>Sets the height of the edition field of an entry. By default, this parameter is set to 24.</dd>
+
+  <dt>Tags list format</dt>
+  <dd>You can select if you want to see, while editing an entry, all the tags used (<strong>Extended</strong>) or only the most used ones (<strong>Short</strong>).</dd>
+</dl>
+</body>
+</html>
Index: locales/lb/help/core_user_pref.html
===================================================================
--- locales/lb/help/core_user_pref.html	(revision 3818)
+++ locales/lb/help/core_user_pref.html	(revision 3818)
@@ -0,0 +1,139 @@
+<html>
+<head>
+  <title>My preferences</title>
+</head>
+
+<body>
+
+<h4>My profile</h4>
+<dl>
+  <dt>Last name, First name</dt>
+  <dd>If the display name is empty, the author's name will be displayed
+  as his first name and last name as set here.</dd>
+  
+  <dt>Display name</dt>
+  <dd>Here you can choose a nickname that will be displayed in your posts instead 
+  of your last name and first name.</dd>
+  
+  <dt>Email</dt>
+  <dd>E-mail address used when you request a new password.<br />
+    New comment notifications will be sent to this address as well.<em>(If you update
+  this field, you must enter your current password in the appropriate field at the 
+  bottom of the form)</em></dd>
+  
+  <dt>URL</dt>
+  <dd>The user's website. If set, the author name will be displayed as
+  a link to the said website.</dd>
+  
+  <dt>Language for my interface</dt>
+  <dd>The language used when publishing entries. If the translation is available,
+  the interface will also be displayed in that language.</dd>
+  
+  <dt>My timezone</dt>
+  <dd>That choice will define the time displayed on post publication.</dd>
+  
+  <dt>Change your password</dt>
+  <dd>To change your password, write down twice your password in the fields 
+  <em>New password</em> and <em>Confirm password</em>. The minimal password 
+  length is 6 characters. If no new password is provided, the current one is kept.
+  <em>(If you update this field, you must enter your current password in
+  the appropriate field at the bottom of the form)</em></dd>
+</dl>
+
+
+<h4>My options</h4>
+<h5>Interface</h5>
+<dl>  
+  <dt>Activate enhanced uploader in media manager</dt>
+  <dd>Allows to activate the advanced interface in media manager that enables to 
+  upload multiple files at a time (Note: Your Web browser must support Javascript 
+  to be able to use this feature).</dd>
+
+  <dt>Disable Javascript powered drag and drop for ordering items</dt>
+  <dd>Allows to disable "drag and drop" for item ordering. Drag and drop will be 
+  replaced by numeric fields that will let you enter fields position instead.</dd>
+
+  <dt>Number of elements displayed per page in media manager</dt>
+  <dd>Defines the number of media that will be displayed in media manager (folders
+  are not taken into account when counting items).</dd>
+  
+  <dt>Do not use standard favicon</dt>
+  <dd>Allows to disable default favicon in the Web browser address bar.</dd>
+</dl>
+
+<h5>Edition</h5>
+<dl>    
+  <dt>Preferred format</dt>
+  <dd>Choose the entry's syntax. Wiki is a simplified syntax
+  and will be converted to valid XHTML. Unless you have a perfect
+  understanding of XHTML, we advise you to choose the Wiki syntax.
+  See the Wiki syntax reference for more information.</dd>
+  
+  <dt>Default entry status</dt>
+  <dd>The default status for new entries can be set to:
+    <ul>
+      <li><strong>Pending:</strong> The publication status has not been yet decided.</li>
+      <li><strong>Scheduled:</strong> The entry will be set online at the time and date provided in the <strong>Published on</strong> field.</li>
+      <li><strong>Unpublished:</strong> Offline entry.</li>
+      <li><strong>Published:</strong> Online entry.</li>
+    </ul>
+  </dd>
+  
+  <dt>Entry edit field height</dt>
+  <dd>Sets the height of the edition field of an entry. By default, this parameter is set to 24.</dd>
+  
+  <dt>Enable WYSIWYG mode</dt>
+  <dd>Allows the use of the visual editor (WYSIWYG: What You See Is What You Get) for the entries, pages and categories description fields.</dd>
+</dl>
+
+<h5>Other options</h5>
+<dl>
+  <dt>Tags list format</dt>
+  <dd>You can select if you want to see, while editing an entry, all the tags used (<strong>Extended</strong>) or only the most used ones (<strong>Short</strong>).</dd>
+
+  <dt>Syntax highlighting in theme editor</dt>
+  <dd>Enables syntax highlighting when using the theme editor (HTML and CSS files)</dd>     
+</dl>
+
+
+<h4>My dashboard</h4>
+<dl>
+  <dt>My favorites</dt>
+  <dd>This zone displays the chosen favorites on the blog's dashboard. 
+  They can be reordered with your mouse if Javascript is activated in your browser. 
+  Otherwise, a field allows to give them an ordering number. When you are done, do not forget to save your changes by pressing <strong>Save order</strong>.<br />
+  You may also delete favorites by selecting them and pressing <strong>Delete selected favorites</strong>.</dd>
+  
+  <dt>Define as default favorites (super administrator)</dt> 
+  <dd>Enable to set currently defined favorites list as default favorites list for all users. This list will be proposed to users if they don't have defined their own favorites yet.</dd>
+
+  <dt>Other available favorites</dt>
+  <dd>All plugins allowing to be put as favorites are diplayed here. Check the corresponding boxes and add them to the dashboard by pressing <strong>Add tp my favorites</strong>.</dd>
+
+  <dt>Display favorites at the top of the menu</dt>
+  <dd>If enabled, displays favorites at the top of the menu.</dd>
+
+  <dt>Icon set</dt>
+  <dd>If several iconsets are installed, enables to choose which icon set to
+  use for admin.</dd>
+  
+  <dt>Dashboard modules</dt>
+  <dd>Choices made in this zone will be reflected on your blog's dashboard.</dd>
+  
+  <dt>Display documentation links</dt>
+  <dd>Enable to display documentation links on dashboard landing page.</dd>
+  
+  <dt>Display Dotclear news</dt>
+  <dd>Enable to display Dotclear news on dashboard landing page.</dd>
+
+  <dt>Display quick entry form</dt>
+  <dd>Enable to display "quick entry" form on dashboard landing page.</dd>
+
+  <dt>Display overdue tasks counter on maintenance dashboard icon</dt>
+  <dd>Enables to display the number of overdue tasks (i.e. that should be processed) under the <strong>Maintenance</strong> icon. <strong>Maintenance</strong> icon has to be set in your favorites to use this feature.</dd>
+
+  <dt>Display overdue tasks list on dashboard items</dt>
+  <dd>Enable to display the list of overdue tasks (i.e. that should be processed) in a dedicated section on the Dashboard landing page.</dd>
+</dl>
+</body>
+</html>
Index: locales/lb/help/core_users.html
===================================================================
--- locales/lb/help/core_users.html	(revision 3818)
+++ locales/lb/help/core_users.html	(revision 3818)
@@ -0,0 +1,48 @@
+<html>
+  <head>
+    <title>Users</title>
+  </head>
+  <body>
+    <p>This page lists all the users on the system.</p>
+    <p>To add (or modify) users' permissions, your password will be required in the <strong>Your password</strong> field.</p>
+
+    <h4>Users list filter</h4>
+    <dl>
+      <dt>Search</dt>
+      <dd>Search is based on the user ID. The <strong>*</strong> wildcard can be used to look only for a part of the user ID.</dd>
+
+      <dt>Order by</dt>
+      <dd>The users list can be ordered by their <em>ID</em>, their <em>Last Name</em>, their <em>First Name</em>, their <em>Display Name</em> (nickname) or the <em>Number of Entries</em> they created.</dd>
+
+      <dt>Sort</dt>
+      <dd>Indicates the sorting method that will be applied to the result list (<em>Ascending</em> or <em>Descending</em>).</dd>
+
+      <dt>Users per page</dt>
+      <dd>Sets the number of users displayed in each page of the result list.</dd>
+    </dl>
+
+    <h4>Users batch actions</h4>
+    <p>It is possible to make a batch of actions on several users at one time.</p>
+    <ul>
+      <li><strong>Set permissions:</strong> Set permissions for one or more blog(s).</li>
+      <li><strong>Delete:</strong> Remove the selected user(s) from the system. A user who created entries cannot be deleted.</li>
+    </ul>
+    <p>If you decide to set users' permissions, you will be redirected to a new page listing the blogs available on your system. Check the blogs you want to set the permissions on, and press <strong>Set permissions</strong>.</p>
+
+    <h4>Users permissions</h4>
+    <p>For each blog, you can set the following permissions:</p>
+    <ul>
+      <li><strong>Administrator:</strong> Can administrate the blog entirely.</li>
+      <li><strong>Manage their own entries and comments:</strong> The user can create entries and manage the comments on entries he created.</li>
+      <li><strong>Publish entries and comments:</strong> The user can modify the publication status of his own entries and of his entries' comments.</li>
+      <li><strong>Delete entries and comments:</strong> The user can delete his own entries as well as his entries' comments.</li>
+      <li><strong>Manage all entries and comments:</strong> The user can manage all the entries of this blog, no matter if he's the author or not.</li>
+      <li><strong>Manage categories:</strong> The user can create, modify and delete categories.</li>
+      <li><strong>Manage their own media items:</strong> The user can add media items and modifye or delete his own media.</li>
+      <li><strong>Manage all media items:</strong> The user can manage the media items from any user.</li>
+      <li><strong>Manage pages:</strong> The user can add and modify pages.</li>
+      <li><strong>Manage blogroll:</strong> The user can manage the blogroll of the current blog.</li>
+    </ul>
+    <p>The <strong>Super administrator</strong> status is set in the user profile.</p>
+  </body>
+</html>
Index: locales/lb/help/core_wiki.html
===================================================================
--- locales/lb/help/core_wiki.html	(revision 3818)
+++ locales/lb/help/core_wiki.html	(revision 3818)
@@ -0,0 +1,84 @@
+<html>
+<head>
+  <title>Wiki syntax reference</title>
+</head>
+
+<body>
+
+<h4>Wiki syntax reference</h4>
+
+<p>The Wiki syntax is a way to enhance your text with a minimal set
+of tags studied to cover the basic needs (titles, paragraphs, quotes,
+lists...).</p>
+
+<dl>
+<dt>Block elements</dt>
+<dd>
+<ul>
+  <li>Leave an empty line between two similar blocks.</li>
+  <li><strong>Paragraph:</strong> Free text, ended by an empty line if
+  another paragraph is to follow.</li>
+  <li><strong>Title:</strong> <code>!!! title</code>, <code>!! title</code>
+  or <code>! title</code>, allowing you to use three  different levels of
+  heading.</li>
+  <li><strong>Horizontal line:</strong> <code>----</code></li>
+  <li><strong>Lists:</strong> Start each line with
+  <code>*</code> or <code>#</code> for unnumbered or numbered lists respectively.
+  List imbrication is done by mixing list markers this way:
+<pre>
+* item 1
+** item 1.1
+* item 2
+*# item 2.1
+...
+</pre>
+  </li>
+  <li><strong>Preformatted text:</strong> Each line must start with a space.</li>
+  <li><strong>Block quote:</strong> Each line must start with a <code>&gt;</code>.</li>
+</ul>
+</dd>
+
+<dt>Formatting tags</dt>
+<dd>
+<ul>
+  <li><strong>Emphasis:</strong> Two quotes <code>''text''</code></li>
+  <li><strong>Strong emphasis:</strong> Two underscores <code>__text__</code></li>
+  <li><strong>New line:</strong> <code>%%%</code></li>
+  <li><strong>Insertion:</strong> Two plusses <code>++text++</code></li>
+  <li><strong>Deletion:</strong> Two minuses <code>--text--</code></li>
+  <li><strong>Link:</strong> <code>[url]</code>, <code>[name|url]</code>,
+    <code>[name|url|language]</code> or <code>[name|url|language|title]</code></li>
+  <li><strong>Image:</strong>
+    <code>((url|alternative text))</code>,
+    <code>((url|alternative text|position))</code> or
+    <code>((url|alternative text|position|long description))</code>.
+    <br />The position can be either L (left), R (right) or C (centered).</li>
+  <li><strong>Anchor:</strong> <code>~anchor~</code></li>
+  <li><strong>Acronym:</strong> <code>??acronym|title??</code></li>
+  <li><strong>Inline HTML:</strong> Two backquotes <code>``html code``</code></li>
+  <li><strong>Inline quote:</strong> <code>{{quote}}</code>,
+    <code>{{quote|language}}</code> or <code>{{quote|language|url}}</code></li>
+  <li><strong>Code:</strong> <code>@@code@@</code></li>
+  <li><strong>Footnotes:</strong> <code>$$footnote$$</code></li>
+</ul>
+</dd>
+
+<dt>Unformatted text</dt>
+<dd>If you don't want one formatting character to be interpreted as such, add a
+<code>\</code> just before it. For instance:
+<code>\[Text in brackets without being a link\]</code>
+</dd>
+
+<dt>HTML code</dt>
+<dd>Even if you chose the Wiki syntax, you may sometimes need a more
+powerful formatting, i.e. HTML syntax. Do it the following way:
+<pre>
+///html
+&lt;p style="color:red"&gt;my text in red&lt;/p&gt;
+///
+</pre>
+</dd>
+</dl>
+
+</body>
+</html>
Index: locales/lb/help/index.html
===================================================================
--- locales/lb/help/index.html	(revision 3818)
+++ locales/lb/help/index.html	(revision 3818)
@@ -0,0 +1,398 @@
+<html>
+<head>
+  <title></title> <!-- Leave the title empty -->
+</head>
+
+<body>
+
+<div class="multi-part legible" id="first-step" title="First steps">
+	<h3>Interface discovery</h3>
+	<div class="fieldset">
+		<h4>First steps</h4>
+		<p>In addition to the global help pages, several administration pages have an online help. If javascript is enabled
+		on your browser, you can see online help at the upper-right position of the page, by clicking on the <img src="images/menu/help.png" alt="" /> <strong>Need Help?</strong> link. If Javascript is disabled, the help is displayed at the bottom of the page.</p>
+	</div>
+
+	<p>Each administration page will display the same top heading, main menu and footer. <em>(The order given here is what is shown on a computer screen. For mobile devices or tablets, it may vary according to the space available.)</em></p>
+
+	<h4 class="pretty-title">Top heading</h4>
+	<p>The top heading is composed of three elements:</p>
+	<h5 class="as_h4">Logo</h5>
+	<p>By default, this logo is the Dotclear logo and links to the administration landing page. However, a platform
+	manager can choose another logo and redirect towards something else (generally, the service landing page).</p>
+
+	<h5 class="as_h4">Blog(s)</h5>
+	<p>The first element located after the logo shows the <em>active</em> blog, i.e. the blog on which you are acting. If your
+	installation is composed of several blogs, these informations are available in a combo menu, which lets you switch to another blog.</p>
+	<p>The link following the blog name opens your current blog in another window or another tab.</p>
+
+	<h5 class="as_h4">User</h5>
+	<p>The link <em>My dashboard</em> gets you back to the blog administration landing page.</p>
+	<p>The link <em>My preferences</em> leads to the page where you can modify your personal informations, setup the dashboard and choose your interface and editing options.</p>
+	<p>Surprisingly, the link <em>Disconnect [your login]</em> disconnects you from the administration of your blog (at Dotclear's, we are ergonomy champions!).</p>
+
+	<h4 class="pretty-title">Main menu</h4>
+	<p>The main menu is located on the left side of the screen. It can be collapsed by clicking on its right border (and then uncollapsed by clicking again on it).</p>
+	<p>It leads to the different administration pages, according to your permissions on the current blog. It is composed of four blocks:</p>
+	<ul>
+		<li><strong>My favorites</strong> lists the pages that you have selected as favorites in the <em>My preferences</em>/<em>My Dashboard</em> tab. If you have not selected any favorite yet, this list will contain the default Dotclear set, or the set that has been defined by the platform manager. If you do not want to display this block, you can uncheck the matching checkbox in your dashboard options.</li>
+		<li><strong>Blog</strong> lists all the pages that enable to feed and setup the current blog, from editing an entry, managing media, choosing the blog appearance or other parameters.<br />
+		<em>If you do not have administrator rights on the current blog, there will be no other block below that one in the main menu.</em></li>
+		<li><strong>System settings</strong> links to the pages that allow you to manage the Dotclear installation: blogs management, users and available languages, plugins installation, system settings. If you have rights on several blogs, but no superadministrator rights, you will only see the <em>Blogs</em> entry.</li>
+		<li><strong>Plugins</strong> enables you to setup the installed plugins. If the plugin settings only impact one blog at a time, its administration page is available from the <em>Blog</em> block, but if they impact the whole installation, they are located here, and only available for super-admin users.</li>
+	</ul>
+
+	<h4 class="pretty-title">Footer</h4>
+	<p>A free version of Dotclear will be offered to any user who will discover the secret hidden in the footer.</p>
+
+	<h3>Help for great beginners</h3>
+	<p>If you are not familiar with blogs, we recommend that you have a look at our documentation (the whole table of contents is available in the <strong>Documentation</strong> tab of this page) as well as tutorials such as:
+	<ul>
+		<li><a href="http://dotclear.org/documentation/2.0/usage/beginners">My first entry, step by step.</a></li>
+	</ul>
+
+	<p>The <a href="http://dotclear.org/forum/">Dotclear forum</a> is a welcoming place where there is no such thing as <em>a stupid question</em>. Don't hesitate to participate if you need help and, why not, to help people in return.</p>
+
+	<p class="info">We try our best to use a vocabulary that is easy to understand without specific knowledge. However, if we end up using a technical term, you will probably find its definition in the <a href="http://dotclear.org/documentation/glossary">glossary</a> of our online documentation.</p>
+</div>
+
+<div class="multi-part" id="users-doc" title="User manual">
+	<h3>User manual</h3>
+	<div class="three-boxes">
+		<h4 class="pretty-title">Managing the content</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/usage/entries">Entries</a>
+					<ul>
+						<li>Creating and editing</li>
+						<li>Entry details</li>
+						<li>Entry-related actions</li>
+						<li>Comments and trackbacks</li>
+						<li>Batch management of entries</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/comments-trackbacks">Comments and trackbacks</a>
+					<ul>
+						<li>Follow-up</li>
+						<li>Management</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/categories">Categories</a>
+					<ul>
+						<li>Creating a category</li>
+						<li>Editing a category</li>
+						<li>Deleting a category</li>
+						<li>Sotring the category list</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/tags">Tags (keywords)</a>
+					<ul>
+						<li>Adding tags</li>
+						<li>Tag management</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/media">Media and attachments</a>
+					<ul>
+						<li>Creating a sub-directory</li>
+						<li>Adding files</li>
+						<li>Downloading a zip archive of the current directory</li>
+						<li>Change of fill in file details</li>
+						<li>Adding files directly</li>
+						<li>Special file types</li>
+						<li>Attachments</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/widgets">Blog menu content (widgets)</a>
+					<ul>
+						<li>Navigation sidebar, Extra sidebar</li>
+						<li>Default widgets</li>
+						<li>Adding/removing a widget</li>
+						<li>Widgets options</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/blogroll">Blogroll</a>
+					<ul>
+						<li>Blogroll</li>
+						<li>Adding a link</li>
+						<li>Adding a category</li>
+						<li>XFN</li>
+						<li>Importing links from an OPML or XBEL file</li>
+					</ul>
+				</li>
+			</ul>
+	</div>
+	<div class="three-boxes">
+		<h4 class="pretty-title">Settings and customization</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/usage/blog-parameters">Blog settings</a>
+					<ul>
+						<li>Blog details</li>
+						<li>Blog configuration</li>
+						<li>Comments and trackbacks</li>
+						<li>Blog presentation</li>
+						<li>Media and images</li>
+						<li>Search engine robot policy</li>
+						<li>Antispam</li>
+						<li>LightBox</li>
+						<li>Save</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/usage/user-preferences">User preferences</a>
+					<ul>
+						<li>My profile</li>
+						<li>My options</li>
+						<li>My dashboard</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/themes">Blog appearance</a>
+					<ul>
+						<li>Choose a theme</li>
+						<li>Install a theme</li>
+						<li>Personnalize a theme</li>
+						<li>Theme editor</li>
+					</ul>
+				</li>
+			</ul>
+	</div>
+	<div class="three-boxes fieldset">
+			<h4 class="smart-title">Additional readings</h4>
+				<h5>Glossary</h5>
+				<ul><li><a href="http://dotclear.org/documentation/glossary">All these mysterious words used on the Web and in Dotclear</a></li></ul>
+				<h5>Input syntaxes</h5>
+					<ul>
+						<li><a href="http://dotclear.org/documentation/2.0/usage/syntaxes">Wiki syntax and XHTML equivalent</a></li>
+						<li><a href="http://dotclear.org/documentation/2.0/usage/syntaxes#to-go-further">To go further</a></li>
+					</ul>
+				<h5>Subscription (RSS, Atom...)</h5>
+					<ul>
+						<li><a href="http://dotclear.org/documentation/2.0/usage/feeds">What's that?</a></li>
+						<li><a href="http://dotclear.org/documentation/2.0/usage/feeds#how-do-i-make-it-available-on-my-blog">How do I make it available on my blog?</a></li>
+						<li><a href="http://dotclear.org/documentation/2.0/usage/feeds#how-do-i-suscribe-to-a-feed">How do I subscribe to a feed?</a></li>
+						<li><a href="http://dotclear.org/documentation/2.0/usage/feeds#to-go-further">To go further</a></li>
+					</ul>
+			<h4 class="smart-title">Help</h4>
+				<ul>
+					<li><a href="http://dotclear.org/forum">The Dotclear forum</a></li>
+					<li><a href="http://dotclear.org/documentation/2.0/faq">Frequently Asked Questions</a></li>
+				</ul>
+	</div>
+</div>
+
+	<div class="multi-part" id="admin-doc" title="Documentation for administrators">
+	<h3>Documentation for administrators</h3>
+		<div class="three-boxes">
+		<h4 class="pretty-title">Installation and update</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/admin/install">Installation</a>
+					<ul>
+						<li>Prerequisites</li>
+						<li>Automatic installation</li>
+						<li>Standard installation</li>
+						<li>Installing using the wizard</li>
+						<li>Installing from the config.php file</li>
+						<li>Completing the installation process</li>
+						<li>Next steps</li>
+					</ul>
+					</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/upgrade">Updating</a>
+					<ul>
+						<li>Preparing for the update</li>
+						<li>Automatic upgrade</li>
+						<li>Updating the program</li>
+						<li>Updating the database</li>
+						<li>Appendix: updating a mercurial copy</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/config">Configuration File (config.php) Parameters</a>
+					<ul>
+						<li>Introduction</li>
+						<li>Parameters</li>
+						<li>Adding information to the file</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/1-to-2">Upgrading from Dotclear 1.2 to Dotclear 2</a>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/migrate">Migrating from another blogging software to Dotclear</a></li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/local-install">Local installation</a>
+					<ul>
+						<li>Windows</li>
+						<li>Mac OS X</li>
+						<li>Linux</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/install/iis">Installing Dotclear with IIS7</a></li>
+			</ul>
+
+			<h5>Hosting Annex</h5>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/hosting">Hosting</a>
+				</li>
+			</ul>
+		</div>
+		<div class="three-boxes">
+			<h4 class="pretty-title">Administration</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/admin/users">Managing users</a>
+					<ul>
+						<li>Existing user list</li>
+						<li>Creating a user</li>
+						<li>Modifying a user</li>
+						<li>User permissions</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/clean-install">Clean installation</a>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/multiblog">Multiblog Installation</a></li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/plugins">Managing plugins</a>
+					<ul>
+						<li>Installing a plugin</li>
+						<li>Configuring plugins</li>
+						<li>Removing a plugin</li>
+						<li>Updating a plugin</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/themes/blowup">The default theme Blowup</a>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/themes">Blog Themes</a>
+					<ul>
+						<li>Choosing a theme</li>
+						<li>Installing a theme</li>
+						<li>Customizing a theme</li>
+						<li>Theme editor</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/aboutconfig">Advanced configuration</a></li>
+			</ul>
+		</div>
+		<div class="three-boxes">
+			<h4 class="pretty-title">Maintenance</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/admin/backup">Backup and restore</a>
+					<ul>
+						<li>Import/Export</li>
+						<li>Files</li>
+						<li>Database</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/admin/antispam">Spam comment filters</a>
+					<ul>
+						<li>Filter organization</li>
+						<li>Filter configuration</li>
+					</ul>
+				</li>
+			</ul>
+			<div class="fieldset vertical-separator">
+				<h4 class="smart-title">Help</h4>
+				<ul>
+					<li><a href="http://dotclear.org/forum">The Dotclear forum</a></li>
+					<li><a href="http://dotclear.org/documentation/2.0/faq#administration">Frequently Asked Questions (Administrators)</a></li>
+				</ul>
+			</div>
+		</div>
+
+	</div>
+
+	<div class="multi-part" id="guide-dev" title="Developers documentation">
+	<h3>Developer and Designer resources</h3>
+
+		<div class="three-boxes first-child">
+			<h4 class="pretty-title">Design &amp; Themes</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/resources/themes">Themes</a>
+					<ul>
+						<li>User guide for themes</li>
+						<li>The template tags</li>
+						<li>Appendix</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/resources/themes/inheritance">Themes inheritance</a>
+					<ul>
+						<li>Principle</li>
+						<li>Limitations</li>
+						<li>Set up</li>
+					</ul>
+					</li>
+				<li><a href="http://dotclear.org/documentation/2.0/resources/themes/tags">Template tags</a>
+					<ul>
+						<li>Generalities / utilities</li>
+						<li>Blog</li>
+						<li>Entries</li>
+						<li>Entries pagination</li>
+						<li>Comments</li>
+						<li>Comment preview</li>
+						<li>Pings</li>
+						<li>Attachments</li>
+						<li>Categories</li>
+						<li>Tags</li>
+						<li>Archives</li>
+						<li>Languages</li>
+						<li>System</li>
+						<li>Widgets</li>
+					</ul>
+				</li>
+			</ul>
+		</div>
+
+		<div class="three-boxes first-child">
+			<h4 class="pretty-title">Code &amp; Plugins</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/resources/tpl">Creation of a tpl tag for a plugin or a theme</a>
+					<ul>
+						<li>Introduction</li>
+						<li>Values</li>
+						<li>Instructions blocks</li>
+						<li>Demonstration of the template cache influence</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/resources/plugins">Plugins</a>
+					<ul>
+						<li>Writing a plugin</li>
+						<li>Appendix</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/resources/plugins/help">Building the plugin contextual help</a></li>
+				<li><a href="http://dotclear.org/documentation/2.0/resources/authentication">External authentication</a>
+					<ul>
+						<li>Preamble</li>
+						<li>A new authentication class</li>
+						<li>Scenario</li>
+						<li>Application</li>
+					</ul>
+				</li>
+				<li><a href="http://dotclear.org/documentation/2.0/resources/xml-rpc">XML/RPC interface</a></li>
+				<li><a href="http://dev.dotclear.org/code/2/">API documentation</a></li>
+			</ul>
+		</div>
+
+		<div class="three-boxes">
+			<h4 class="pretty-title">Contribution &amp; Support</h4>
+			<ul class="from-left">
+				<li><a href="http://dotclear.org/documentation/2.0/resources/contribute">Contribute</a>
+					<ul>
+						<li>Edit this documentation</li>
+						<li>Share your creations</li>
+						<li>Report bugs or suggest new features</li>
+						<li>Localization</li>
+				</ul>
+			</li>
+				<li><a href="http://hg.dotclear.org/">Dotclear source code repository</a></li>
+				<li><a href="http://dotclear.org/forum">Dotclear forum</a></li>
+			</ul>
+
+			<div class="fieldset">
+				<h4 class="smart-title">Conventions</h4>
+				<ul>
+					<li><a href="http://dotclear.org/documentation/2.0/resources/coding-standards">Coding standards</a></li>
+					<li><a href="_charte.php">Administration pages chart</a></li>
+				</ul>
+			</div>
+		</div>
+	</div>
+	<div class="multi-part legible" id="a11y-ergo" title="Accessibility and ergonomy">
+	<h3>Accessibility and ergonomy</h3>
+	<p>The Dotclear interface fulfills almost all the <a href="http://www.w3.org/TR/WCAG20/">WCAG 2.0</a> criterion. We are working towards making Dotclear compatible with <a href="http://www.w3.org/TR/ATAG20/">ATAG 2.0</a> guidelines.</p>
+	<p>Accessibility and ergonomy are one of our main concern. We regularly run analysis with the help of experts and continuously provide fixes and enhancements.</p>
+	<p>You can help us by opening <a href="http://dev.dotclear.org/2.0/report">tickets</a> or by participating on the <a href="http://dotclear.org/forum/">forum</a>. You can also participate in user testing or join our team!</p>
+	</div>
+
+</body>
+</html>
Index: locales/lb/main.po
===================================================================
--- locales/lb/main.po	(revision 3818)
+++ locales/lb/main.po	(revision 3818)
@@ -0,0 +1,3941 @@
+# SOME DESCRIPTIVE TITLE.
+# This file is put in the public domain.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Dotclear 2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 10:18+0100\n"
+"PO-Revision-Date: 2016-07-18 15:46+0200\n"
+"Last-Translator: Franck Paul <carnet.franck.paul@gmail.com>\n"
+"Language-Team: \n"
+"Language: en\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.8\n"
+
+msgid "Dotclear has been upgraded."
+msgstr ""
+
+msgid "Password reset"
+msgstr ""
+
+msgid "Someone has requested to reset the password for the following site and username."
+msgstr ""
+
+msgid "Username:"
+msgstr ""
+
+msgid "To reset your password visit the following address, otherwise just ignore this email and nothing will happen."
+msgstr ""
+
+#, php-format
+msgid "The e-mail was sent successfully to %s."
+msgstr ""
+
+msgid "Your new password"
+msgstr ""
+
+msgid "Password:"
+msgstr ""
+
+msgid "Your new password is in your mailbox."
+msgstr ""
+
+msgid "Passwords don't match"
+msgstr ""
+
+msgid "You didn't change your password."
+msgstr ""
+
+msgid "You have to change your password before you can login."
+msgstr ""
+
+msgid "In order to login, you have to change your password now."
+msgstr ""
+
+msgid "Safe Mode can only be used for super administrators."
+msgstr ""
+
+msgid "Insufficient permissions"
+msgstr ""
+
+msgid "Wrong username or password"
+msgstr ""
+
+msgid "Back to login screen"
+msgstr ""
+
+msgid "Request a new password"
+msgstr ""
+
+msgid "Email:"
+msgstr ""
+
+msgid "recover"
+msgstr ""
+
+msgid "Change your password"
+msgstr ""
+
+msgid "New password:"
+msgstr ""
+
+msgid "Confirm password:"
+msgstr ""
+
+msgid "change"
+msgstr ""
+
+msgid "Safe mode login"
+msgstr ""
+
+msgid "This mode allows you to login without activating any of your plugins. This may be useful to solve compatibility problems"
+msgstr ""
+
+msgid "Disable or delete any plugin suspected to cause trouble, then log out and log back in normally."
+msgstr ""
+
+msgid "Remember my ID on this device"
+msgstr ""
+
+msgid "log in"
+msgstr ""
+
+msgid "You must accept cookies in order to use the private area."
+msgstr ""
+
+msgid "Get back to normal authentication"
+msgstr ""
+
+msgid "Connection issue?"
+msgstr ""
+
+msgid "I forgot my password"
+msgstr ""
+
+msgid "I want to log in in safe mode"
+msgstr ""
+
+#, php-format
+msgid "Blog \"%s\" successfully created"
+msgstr ""
+
+msgid "New blog"
+msgstr ""
+
+msgid "System"
+msgstr ""
+
+msgid "Blogs"
+msgstr ""
+
+msgid "Blog ID:"
+msgstr ""
+
+msgid "Required field"
+msgstr ""
+
+msgid "At least 2 characters using letters, numbers or symbols."
+msgstr ""
+
+msgid "Blog name:"
+msgstr ""
+
+msgid "Blog URL:"
+msgstr ""
+
+msgid "Blog description:"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "No such blog ID"
+msgstr ""
+
+msgid "Password verification failed"
+msgstr ""
+
+#, php-format
+msgid "Blog \"%s\" successfully deleted"
+msgstr ""
+
+msgid "Delete a blog"
+msgstr ""
+
+msgid "Warning"
+msgstr ""
+
+#, php-format
+msgid "You are about to delete the blog %s. Every entry, comment and category will be deleted."
+msgstr ""
+
+msgid "Please give your password to confirm the blog deletion."
+msgstr ""
+
+msgid "Your password:"
+msgstr ""
+
+msgid "Delete this blog"
+msgstr ""
+
+msgid "No given blog id."
+msgstr ""
+
+msgid "No such blog."
+msgstr ""
+
+msgid "year/month/day/title"
+msgstr ""
+
+msgid "year/month/title"
+msgstr ""
+
+msgid "year/title"
+msgstr ""
+
+msgid "title"
+msgstr ""
+
+msgid "post id/title"
+msgstr ""
+
+msgid "post id"
+msgstr ""
+
+msgid "H4"
+msgstr ""
+
+msgid "H3"
+msgstr ""
+
+msgid "P"
+msgstr ""
+
+msgid "(none)"
+msgstr ""
+
+msgid "Title"
+msgstr ""
+
+msgid "Title, Date"
+msgstr ""
+
+msgid "Title, Country, Date"
+msgstr ""
+
+msgid "Title, City, Country, Date"
+msgstr ""
+
+msgid "original"
+msgstr ""
+
+msgid "None"
+msgstr ""
+
+msgid "Left"
+msgstr ""
+
+msgid "Right"
+msgstr ""
+
+msgid "Center"
+msgstr ""
+
+msgid "I would like search engines and archivers to index and archive my blog's content."
+msgstr ""
+
+msgid "I would like search engines and archivers to index but not archive my blog's content."
+msgstr ""
+
+msgid "I would like to prevent search engines and archivers from indexing or archiving my blog's content."
+msgstr ""
+
+msgid "Default"
+msgstr ""
+
+msgid "This blog ID is already used."
+msgstr ""
+
+msgid "Invalid language code"
+msgstr ""
+
+msgid "Blog has been successfully updated."
+msgstr ""
+
+msgid "Blog settings"
+msgstr ""
+
+msgid "Warning: except for special configurations, it is generally advised to have a trailing \"/\" in your blog URL in PATH_INFO mode."
+msgstr ""
+
+msgid "Warning: except for special configurations, it is generally advised to have a trailing \"?\" in your blog URL in QUERY_STRING mode."
+msgstr ""
+
+msgid "Blog has been successfully created."
+msgstr ""
+
+msgid "Parameters"
+msgstr ""
+
+msgid "Blog details"
+msgstr ""
+
+msgid "Please note that changing your blog ID may require changes in your public index.php file."
+msgstr ""
+
+msgid "URL scan method:"
+msgstr ""
+
+#, php-format
+msgid "The URL of blog or the URL scan method might not be well set (<code>%s</code> return a <strong>%s</strong> status)."
+msgstr ""
+
+#, php-format
+msgid "The URL of blog or the URL scan method might not be well set (<code>%s</code> does not return an ATOM feed)."
+msgstr ""
+
+msgid "Blog status:"
+msgstr ""
+
+msgid "Blog configuration"
+msgstr ""
+
+msgid "Blog editor name:"
+msgstr ""
+
+msgid "Default language:"
+msgstr ""
+
+msgid "Blog timezone:"
+msgstr ""
+
+msgid "Copyright notice:"
+msgstr ""
+
+msgid "New post URL format:"
+msgstr ""
+
+msgid "Dotclear"
+msgstr ""
+
+msgid "Sample:"
+msgstr ""
+
+msgid "HTML tag for the title of the notes on the blog:"
+msgstr ""
+
+msgid "Enable XML/RPC interface"
+msgstr ""
+
+msgid "XML/RPC interface allows you to edit your blog with an external client."
+msgstr ""
+
+msgid "XML/RPC interface is active. You should set the following parameters on your XML/RPC client:"
+msgstr ""
+
+msgid "Server URL:"
+msgstr ""
+
+msgid "Blogging system:"
+msgstr ""
+
+msgid "User name:"
+msgstr ""
+
+msgid "your password"
+msgstr ""
+
+msgid "Comments and trackbacks"
+msgstr ""
+
+msgid "Accept comments"
+msgstr ""
+
+msgid "Moderate comments"
+msgstr ""
+
+#, php-format
+msgid "Leave comments open for %s days"
+msgstr ""
+
+msgid "No limit: leave blank."
+msgstr ""
+
+msgid "Wiki syntax for comments"
+msgstr ""
+
+msgid "Preview of comment before submit is not mandatory"
+msgstr ""
+
+msgid "Accept trackbacks"
+msgstr ""
+
+msgid "Moderate trackbacks"
+msgstr ""
+
+#, php-format
+msgid "Leave trackbacks open for %s days"
+msgstr ""
+
+msgid "Add \"nofollow\" relation on comments and trackbacks links"
+msgstr ""
+
+msgid "Blog presentation"
+msgstr ""
+
+msgid "Date format:"
+msgstr ""
+
+msgid "Pattern of date"
+msgstr ""
+
+msgid "Time format:"
+msgstr ""
+
+msgid "Pattern of time"
+msgstr ""
+
+msgid "Display smilies on entries and comments"
+msgstr ""
+
+msgid "Disable internal search system"
+msgstr ""
+
+#, php-format
+msgid "Display %s entries on home page"
+msgstr ""
+
+#, php-format
+msgid "Display %s entries per page"
+msgstr ""
+
+#, php-format
+msgid "Display %s entries per feed"
+msgstr ""
+
+#, php-format
+msgid "Display %s comments per feed"
+msgstr ""
+
+msgid "Truncate feeds"
+msgstr ""
+
+msgid "Include sub-categories in category page and category posts feed"
+msgstr ""
+
+msgid "Media and images"
+msgstr ""
+
+msgid "Please note that if you change current settings bellow, they will now apply to all new images in the media manager."
+msgstr ""
+
+msgid "Be carefull if you share it with other blogs in your installation."
+msgstr ""
+
+msgid "Generated image sizes (max dimension in pixels)"
+msgstr ""
+
+msgid "Thumbnail"
+msgstr ""
+
+msgid "Small"
+msgstr ""
+
+msgid "Medium"
+msgstr ""
+
+msgid "Default size of the inserted video (in pixels)"
+msgstr ""
+
+msgid "Width"
+msgstr ""
+
+msgid "Height"
+msgstr ""
+
+msgid "Flash player"
+msgstr ""
+
+msgid "Insert Flash player fallback for video (mp4 or m4v) and audio (mp3) media"
+msgstr ""
+
+msgid "For flv video, the Flash player will be anyway inserted."
+msgstr ""
+
+msgid "Default image insertion attributes"
+msgstr ""
+
+msgid "Inserted image title"
+msgstr ""
+
+msgid "Use original media date if possible"
+msgstr ""
+
+msgid "Do not display date if alone in title"
+msgstr ""
+
+msgid "It is retrieved from the picture's metadata."
+msgstr ""
+
+msgid "Size of inserted image:"
+msgstr ""
+
+msgid "Image alignment:"
+msgstr ""
+
+msgid "Insert a link to the original image"
+msgstr ""
+
+msgid "Search engines robots policy"
+msgstr ""
+
+msgid "jQuery javascript library"
+msgstr ""
+
+msgid "jQuery version to be loaded for this blog:"
+msgstr ""
+
+msgid "Blog security"
+msgstr ""
+
+msgid "Protect the blog from Clickjacking (see <a href=\"https://en.wikipedia.org/wiki/Clickjacking\">Wikipedia</a>)"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "The current blog cannot be deleted."
+msgstr ""
+
+msgid "Only superadmin can delete a blog."
+msgstr ""
+
+msgid "Users"
+msgstr ""
+
+msgid "Users on this blog"
+msgstr ""
+
+msgid "No users"
+msgstr ""
+
+msgid "Publications on this blog:"
+msgstr ""
+
+#, php-format
+msgid "%1$s: %2$s"
+msgstr ""
+
+msgid "Permissions:"
+msgstr ""
+
+msgid "Super administrator"
+msgstr ""
+
+msgid "All rights on all blogs."
+msgstr ""
+
+#, php-format
+msgid "[%s] (unreferenced permission)"
+msgstr ""
+
+msgid "All rights on this blog."
+msgstr ""
+
+msgid "Change permissions"
+msgstr ""
+
+msgid "Blog appearance"
+msgstr ""
+
+msgid "Theme configuration"
+msgstr ""
+
+msgid "Themes management"
+msgstr ""
+
+msgid "Update themes"
+msgstr ""
+
+#, php-format
+msgid "There is one theme to update available from repository."
+msgid_plural "There are %s themes to update available from repository."
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "Visit %s repository, the resources center for Dotclear."
+msgstr ""
+
+msgid "Installed themes"
+msgstr ""
+
+msgid "You can configure and manage installed themes from this list."
+msgstr ""
+
+msgid "Deactivated themes"
+msgstr ""
+
+msgid "Deactivated themes are installed but not usable. You can activate them from here."
+msgstr ""
+
+msgid "Add themes"
+msgstr ""
+
+msgid "Add themes from repository"
+msgstr ""
+
+msgid "Install or upgrade manually"
+msgstr ""
+
+msgid "Add themes from a package"
+msgstr ""
+
+msgid "You can install themes by uploading or downloading zip files."
+msgstr ""
+
+msgid "Some functions are disabled, please give write access to your themes directory to enable them."
+msgstr ""
+
+msgid "Last update"
+msgstr ""
+
+msgid "Blog name"
+msgstr ""
+
+msgid "Blog ID"
+msgstr ""
+
+msgid "Status"
+msgstr ""
+
+msgid "Descending"
+msgstr ""
+
+msgid "Ascending"
+msgstr ""
+
+msgid "List of blogs"
+msgstr ""
+
+msgid "Create a new blog"
+msgstr ""
+
+msgid "Show filters and display options"
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Search:"
+msgstr ""
+
+msgid "Status:"
+msgstr ""
+
+msgid "Display options"
+msgstr ""
+
+msgid "Order by:"
+msgstr ""
+
+msgid "Sort:"
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "blogs per page"
+msgstr ""
+
+msgid "Apply filters and display options"
+msgstr ""
+
+msgid "Selected blogs action:"
+msgstr ""
+
+msgid "Actions"
+msgstr ""
+
+msgid "ok"
+msgstr ""
+
+msgid "Please give your password to confirm blog(s) deletion:"
+msgstr ""
+
+msgid "This category does not exist."
+msgstr ""
+
+#, php-format
+msgid "The category \"%s\" has been successfully deleted."
+msgstr ""
+
+msgid "Category where to move entries does not exist"
+msgstr ""
+
+#, php-format
+msgid "The entries have been successfully moved to category \"%s\""
+msgstr ""
+
+msgid "Categories have been successfully reordered."
+msgstr ""
+
+msgid "Categories order has been successfully reset."
+msgstr ""
+
+msgid "Categories"
+msgstr ""
+
+msgid "The category has been successfully removed."
+msgid_plural "The categories have been successfully removed."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Entries have been successfully moved to the category you choose."
+msgstr ""
+
+msgid "New category"
+msgstr ""
+
+msgid "No category so far."
+msgstr ""
+
+#, php-format
+msgid "%d entries"
+msgstr ""
+
+#, php-format
+msgid "%d entry"
+msgstr ""
+
+msgid "total:"
+msgstr ""
+
+msgid "URL:"
+msgstr ""
+
+msgid "Move entries to"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Delete category"
+msgstr ""
+
+msgid "To rearrange categories order, move items by drag and drop, then click on “Save categories order” button."
+msgstr ""
+
+msgid "Save categories order"
+msgstr ""
+
+msgid "Reorder all categories on the top level"
+msgstr ""
+
+msgid "Top level"
+msgstr ""
+
+msgid "The category has been successfully moved"
+msgstr ""
+
+msgid "The category has been successfully updated."
+msgstr ""
+
+#, php-format
+msgid "The category \"%s\" has been successfully created."
+msgstr ""
+
+msgid "Category has been successfully updated."
+msgstr ""
+
+msgid "Category information"
+msgstr ""
+
+msgid "Name:"
+msgstr ""
+
+msgid "Parent:"
+msgstr ""
+
+msgid "Warning: If you set the URL manually, it may conflict with another category."
+msgstr ""
+
+msgid "Description:"
+msgstr ""
+
+msgid "Move this category"
+msgstr ""
+
+msgid "Category parent"
+msgstr ""
+
+msgid "Category sibling"
+msgstr ""
+
+msgid "Move current category"
+msgstr ""
+
+msgid "after"
+msgstr ""
+
+msgid "before"
+msgstr ""
+
+msgid "position: "
+msgstr ""
+
+msgid "Entry does not exist."
+msgstr ""
+
+msgid "Comment has been successfully created."
+msgstr ""
+
+msgid "No comments"
+msgstr ""
+
+msgid "Comment has been successfully updated."
+msgstr ""
+
+msgid "Comment has been successfully deleted."
+msgstr ""
+
+msgid "You can't edit this comment."
+msgstr ""
+
+msgid "Edit comment"
+msgstr ""
+
+#, php-format
+msgid "Your comment on my blog %s"
+msgstr ""
+
+#, php-format
+msgid ""
+"Hi!\n"
+"\n"
+"You wrote a comment on:\n"
+"%s\n"
+"\n"
+"\n"
+msgstr ""
+
+msgid "Send an e-mail"
+msgstr ""
+
+msgid "Information collected"
+msgstr ""
+
+msgid "IP address:"
+msgstr ""
+
+msgid "Date:"
+msgstr ""
+
+msgid "Comment submitted"
+msgstr ""
+
+msgid "Author:"
+msgstr ""
+
+msgid "Web site:"
+msgstr ""
+
+msgid "Comment:"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Comment"
+msgstr ""
+
+msgid "Trackback"
+msgstr ""
+
+msgid "Date"
+msgstr ""
+
+msgid "Entry title"
+msgstr ""
+
+msgid "Entry date"
+msgstr ""
+
+msgid "Author"
+msgstr ""
+
+msgid "IP"
+msgstr ""
+
+msgid "Spam filter"
+msgstr ""
+
+msgid "Selected comments have been successfully updated."
+msgstr ""
+
+msgid "Selected comments have been successfully deleted."
+msgstr ""
+
+msgid "Spam comments have been successfully deleted."
+msgstr ""
+
+msgid "You have one spam comment."
+msgstr ""
+
+msgid "Show it."
+msgstr ""
+
+#, php-format
+msgid "You have %s spam comments."
+msgstr ""
+
+msgid "Show them."
+msgstr ""
+
+msgid "Delete all spams"
+msgstr ""
+
+msgid "Type:"
+msgstr ""
+
+msgid "comments per page"
+msgstr ""
+
+msgid "Selected comments action:"
+msgstr ""
+
+msgid "Global help"
+msgstr ""
+
+#, php-format
+msgid "An update is available"
+msgid_plural "%s updates are available."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Dotclear news"
+msgstr ""
+
+msgid "%d %B %Y:"
+msgstr ""
+
+msgid "Documentation and support"
+msgstr ""
+
+msgid "Dashboard"
+msgstr ""
+
+#, php-format
+msgid "Dotclear %s is available!"
+msgstr ""
+
+msgid "Upgrade now"
+msgstr ""
+
+msgid "Remind me later"
+msgstr ""
+
+msgid "Information about this version"
+msgstr ""
+
+msgid "Make this blog my default blog"
+msgstr ""
+
+msgid "This blog is offline"
+msgstr ""
+
+msgid "This blog is removed"
+msgstr ""
+
+#, php-format
+msgid "%s is not defined, you should edit your configuration file."
+msgstr ""
+
+msgid "See <a href=\"http://dotclear.org/documentation/2.0/admin/config\">documentation</a> for more information."
+msgstr ""
+
+msgid "The cache directory does not exist or is not writable. You must create this directory with sufficient rights and affect this location to \"DC_TPL_CACHE\" in inc/config.php file."
+msgstr ""
+
+msgid "The cache directory does not exist or is not writable. You should contact your administrator."
+msgstr ""
+
+msgid "There is no writable directory /public/ at the location set in about:config \"public_path\". You must create this directory with sufficient rights (or change this setting)."
+msgstr ""
+
+msgid "There is no writable root directory for the media manager. You should contact your administrator."
+msgstr ""
+
+msgid "Error:"
+msgstr ""
+
+msgid "Following plugins have been installed:"
+msgstr ""
+
+msgid "Following plugins have not been installed:"
+msgstr ""
+
+msgid "Errors have occured with following plugins:"
+msgstr ""
+
+msgid "Quick entry"
+msgstr ""
+
+msgid "New entry"
+msgstr ""
+
+msgid "Title:"
+msgstr ""
+
+msgid "Content:"
+msgstr ""
+
+msgid "Category:"
+msgstr ""
+
+msgid "Add a new category"
+msgstr ""
+
+msgid "This category will be created when you will save your post."
+msgstr ""
+
+msgid "Save and publish"
+msgstr ""
+
+#, php-format
+msgid "PHP version is %s (5.3 or earlier needed)."
+msgstr ""
+
+msgid "Multibyte string module (mbstring) is not available."
+msgstr ""
+
+msgid "Iconv module is not available."
+msgstr ""
+
+msgid "Output control functions are not available."
+msgstr ""
+
+msgid "SimpleXML module is not available."
+msgstr ""
+
+msgid "DOM XML module is not available."
+msgstr ""
+
+msgid "PCRE engine does not support UTF-8 strings."
+msgstr ""
+
+msgid "SPL module is not available."
+msgstr ""
+
+#, php-format
+msgid "MySQL version is %s (4.1 or earlier needed)."
+msgstr ""
+
+msgid "MySQL InnoDB engine is not available."
+msgstr ""
+
+#, php-format
+msgid "PostgreSQL version is %s (8.0 or earlier needed)."
+msgstr ""
+
+msgid "Please set a master key (DC_MASTER_KEY) in configuration file."
+msgstr ""
+
+msgid "Dotclear is already installed."
+msgstr ""
+
+msgid "Dotclear cannot be installed."
+msgstr ""
+
+msgid "No user ID given"
+msgstr ""
+
+msgid "User ID must contain at least 2 characters using letters, numbers or symbols."
+msgstr ""
+
+msgid "Invalid email address"
+msgstr ""
+
+msgid "No password given"
+msgstr ""
+
+msgid "Password must contain at least 6 characters."
+msgstr ""
+
+msgid "My first blog"
+msgstr ""
+
+msgid "%A, %B %e %Y"
+msgstr ""
+
+msgid "Welcome to Dotclear!"
+msgstr ""
+
+msgid "This is your first entry. When you're ready to blog, log in to edit or delete it."
+msgstr ""
+
+msgid "Dotclear Team"
+msgstr ""
+
+msgid ""
+"<p>This is a comment.</p>\n"
+"<p>To delete it, log in and view your blog's comments. Then you might remove or edit it.</p>"
+msgstr ""
+
+msgid "Dotclear Install"
+msgstr ""
+
+#, php-format
+msgid "Password strength: %s"
+msgstr ""
+
+msgid "very weak"
+msgstr ""
+
+msgid "weak"
+msgstr ""
+
+msgid "mediocre"
+msgstr ""
+
+msgid "strong"
+msgstr ""
+
+msgid "very strong"
+msgstr ""
+
+msgid "show"
+msgstr ""
+
+msgid "Dotclear installation"
+msgstr ""
+
+#, php-format
+msgid "Cache directory %s is not writable."
+msgstr ""
+
+msgid "Errors:"
+msgstr ""
+
+msgid "Configuration file has been successfully created."
+msgstr ""
+
+msgid "User information"
+msgstr ""
+
+msgid "Please provide the following information needed to create the first user."
+msgstr ""
+
+msgid "First Name:"
+msgstr ""
+
+msgid "Last Name:"
+msgstr ""
+
+msgid "Username and password"
+msgstr ""
+
+msgid "All done!"
+msgstr ""
+
+msgid "Dotclear has been successfully installed. Here is some useful information you should keep."
+msgstr ""
+
+msgid "Your account"
+msgstr ""
+
+msgid "Your blog"
+msgstr ""
+
+msgid "Blog address:"
+msgstr ""
+
+msgid "Administration interface:"
+msgstr ""
+
+msgid "Manage your blog now"
+msgstr ""
+
+msgid "Installation can not be completed"
+msgstr ""
+
+msgid "For the said reasons, Dotclear can not be installed. Please refer to <a href=\"http://dotclear.org/documentation/2.0/admin/install\">the documentation</a> to learn how to correct the problem."
+msgstr ""
+
+#, php-format
+msgid "Path <strong>%s</strong> is not writable."
+msgstr ""
+
+msgid "Dotclear installation wizard could not create configuration file for you. You must change folder right or create the <strong>config.php</strong> file manually, please refer to <a href=\"http://dotclear.org/documentation/2.0/admin/install\">the documentation</a> to learn how to do this."
+msgstr ""
+
+#, php-format
+msgid "Cannot write \"%s\" directory."
+msgstr ""
+
+msgid "Master email is not valid."
+msgstr ""
+
+#, php-format
+msgid "File %s does not exist."
+msgstr ""
+
+#, php-format
+msgid "Cannot write %s file."
+msgstr ""
+
+msgid "Dotclear installation wizard"
+msgstr ""
+
+msgid "Welcome"
+msgstr ""
+
+msgid "To complete your Dotclear installation and start writing on your blog, we just need to know how to access your database and who you are. Just fill this two steps wizard with this information and we will be done."
+msgstr ""
+
+msgid "Attention:"
+msgstr ""
+
+msgid "this wizard may not function on every host. If it does not work for you, please refer to <a href=\"http://dotclear.org/documentation/2.0/admin/install\">the documentation</a> to learn how to create the <strong>config.php</strong> file manually."
+msgstr ""
+
+msgid "System information"
+msgstr ""
+
+msgid "Please provide the following information needed to create your configuration file."
+msgstr ""
+
+msgid "Database type:"
+msgstr ""
+
+msgid "MySQL (deprecated)"
+msgstr ""
+
+msgid "MySQLi"
+msgstr ""
+
+msgid "PostgreSQL"
+msgstr ""
+
+msgid "SQLite"
+msgstr ""
+
+msgid "Database Host Name:"
+msgstr ""
+
+msgid "Database Name:"
+msgstr ""
+
+msgid "Database User Name:"
+msgstr ""
+
+msgid "Database Password:"
+msgstr ""
+
+msgid "Database Tables Prefix:"
+msgstr ""
+
+msgid "Master Email: (used as sender for password recovery)"
+msgstr ""
+
+msgid "Continue"
+msgstr ""
+
+msgid "No such installed language"
+msgstr ""
+
+msgid "You can't remove English language."
+msgstr ""
+
+msgid "Permissions to delete language denied."
+msgstr ""
+
+msgid "Language has been successfully deleted."
+msgstr ""
+
+msgid "Invalid language file URL."
+msgstr ""
+
+msgid "Language has been successfully upgraded"
+msgstr ""
+
+msgid "Language has been successfully installed."
+msgstr ""
+
+msgid "Unable to move uploaded file."
+msgstr ""
+
+msgid "Languages management"
+msgstr ""
+
+msgid "Here you can install, upgrade or remove languages for your Dotclear installation."
+msgstr ""
+
+#, php-format
+msgid "You can change your user language in your <a href=\"%1$s\">preferences</a> or change your blog's main language in your <a href=\"%2$s\">blog settings</a>."
+msgstr ""
+
+msgid "Installed languages"
+msgstr ""
+
+msgid "No additional language is installed."
+msgstr ""
+
+msgid "Language"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "Install or upgrade languages"
+msgstr ""
+
+#, php-format
+msgid "You can install or remove a language by adding or removing the relevant directory in your %s folder."
+msgstr ""
+
+msgid "Available languages"
+msgstr ""
+
+#, php-format
+msgid "You can download and install a additional language directly from Dotclear.net. Proposed languages are based on your version: %s."
+msgstr ""
+
+msgid "Language:"
+msgstr ""
+
+msgid "Install language"
+msgstr ""
+
+msgid "Upload a zip file"
+msgstr ""
+
+msgid "You can install languages by uploading zip files."
+msgstr ""
+
+msgid "Language zip file:"
+msgstr ""
+
+msgid "Upload language"
+msgstr ""
+
+msgid "Invalid language zip file."
+msgstr ""
+
+msgid "The zip file does not appear to be a valid Dotclear language pack."
+msgstr ""
+
+msgid "An error occurred during language upgrade."
+msgstr ""
+
+msgid "By names, in ascending order"
+msgstr ""
+
+msgid "By names, in descending order"
+msgstr ""
+
+msgid "By dates, in ascending order"
+msgstr ""
+
+msgid "By dates, in descending order"
+msgstr ""
+
+msgid "Not a valid directory"
+msgstr ""
+
+#, php-format
+msgid "Directory \"%s\" has been successfully created."
+msgstr ""
+
+msgid "Files have been successfully uploaded."
+msgstr ""
+
+#, php-format
+msgid "Successfully delete one media."
+msgid_plural "Successfully delete %d medias."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Directory has been successfully removed."
+msgstr ""
+
+msgid "File has been successfully removed."
+msgstr ""
+
+#, php-format
+msgid "Directory \"%s\" has been successfully rebuilt."
+msgstr ""
+
+msgid "Media manager"
+msgstr ""
+
+msgid "confirm removal"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to remove %s?"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+#, php-format
+msgid "%s file found"
+msgid_plural "%s files found"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Remove this folder from your favorites"
+msgstr ""
+
+msgid "Add this folder to your favorites"
+msgstr ""
+
+msgid "Goto recent folder:"
+msgstr ""
+
+msgid "You do not have sufficient permissions to write to this folder."
+msgstr ""
+
+msgid "Directory has been successfully created."
+msgstr ""
+
+msgid "Directory has been successfully rebuilt."
+msgstr ""
+
+msgid "Zip file has been successfully extracted."
+msgstr ""
+
+#, php-format
+msgid "Select a file by clicking on %s"
+msgstr ""
+
+msgid "Select this file"
+msgstr ""
+
+msgid "Choose selected medias"
+msgstr ""
+
+#, php-format
+msgid "Select files and click on <strong>%s</strong> button"
+msgstr ""
+
+msgid "or"
+msgstr ""
+
+msgid "upload a new file"
+msgstr ""
+
+#, php-format
+msgid "Choose a file to attach to entry %s by clicking on %s"
+msgstr ""
+
+msgid "Attach this file to entry"
+msgstr ""
+
+#, php-format
+msgid "Choose a file to insert into entry by clicking on %s"
+msgstr ""
+
+msgid "Remove selected medias"
+msgstr ""
+
+msgid "Will search into media filename (including path), title and description"
+msgstr ""
+
+msgid "No file."
+msgstr ""
+
+msgid "Grid display mode"
+msgstr ""
+
+msgid "List display mode"
+msgstr ""
+
+msgid "Sort files:"
+msgstr ""
+
+msgid "Number of elements displayed per page:"
+msgstr ""
+
+msgid "Media list"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+#, php-format
+msgid "In %s:"
+msgstr ""
+
+msgid "Create new directory"
+msgstr ""
+
+msgid "Directory Name:"
+msgstr ""
+
+#, php-format
+msgid "Backup content of %s"
+msgstr ""
+
+msgid "Download zip file"
+msgstr ""
+
+msgid "Add files"
+msgstr ""
+
+msgid "Please take care to publish media that you own and that are not protected by copyright."
+msgstr ""
+
+msgid "Choose file"
+msgstr ""
+
+msgid "Choose files"
+msgstr ""
+
+msgid "Maximum file size allowed:"
+msgstr ""
+
+msgid "Private"
+msgstr ""
+
+msgid "To send several files at the same time, you can activate the enhanced uploader in"
+msgstr ""
+
+msgid "My preferences"
+msgstr ""
+
+msgid "Refresh"
+msgstr ""
+
+msgid "Clear all"
+msgstr ""
+
+msgid "Upload"
+msgstr ""
+
+#, php-format
+msgid "Current settings for medias and images are defined in %s"
+msgstr ""
+
+msgid "Blog parameters"
+msgstr ""
+
+msgid "Insert this file into entry"
+msgstr ""
+
+msgid "delete"
+msgstr ""
+
+msgid "open"
+msgstr ""
+
+msgid "Not a valid file"
+msgstr ""
+
+msgid "File has been successfully updated."
+msgstr ""
+
+msgid "Thumbnails have been successfully updated."
+msgstr ""
+
+msgid "Default media insertion settings have been successfully updated."
+msgstr ""
+
+msgid "Are you sure to delete this media?"
+msgstr ""
+
+msgid "Select media item"
+msgstr ""
+
+msgid "Image size:"
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Insert media item"
+msgstr ""
+
+msgid "Image alignment"
+msgstr ""
+
+msgid "Image insertion"
+msgstr ""
+
+msgid "As a single image"
+msgstr ""
+
+msgid "As a link to the original image"
+msgstr ""
+
+msgid "MP3 disposition"
+msgstr ""
+
+msgid "Please note that you cannot insert mp3 files with visual editor."
+msgstr ""
+
+msgid "Please note that you cannot insert video files with visual editor."
+msgstr ""
+
+msgid "Video size"
+msgstr ""
+
+msgid "Width:"
+msgstr ""
+
+msgid "Height:"
+msgstr ""
+
+msgid "Video disposition"
+msgstr ""
+
+msgid "Media item will be inserted as a link."
+msgstr ""
+
+msgid "Insert"
+msgstr ""
+
+msgid "Make current settings as default"
+msgstr ""
+
+msgid "Media details"
+msgstr ""
+
+msgid "Available sizes:"
+msgstr ""
+
+msgid "Thumbnail details"
+msgstr ""
+
+msgid "Image width:"
+msgstr ""
+
+msgid "Image height:"
+msgstr ""
+
+msgid "File size:"
+msgstr ""
+
+msgid "File URL:"
+msgstr ""
+
+msgid "File owner:"
+msgstr ""
+
+msgid "File type:"
+msgstr ""
+
+msgid "Show entries containing this media"
+msgstr ""
+
+msgid "Entries containing this media"
+msgstr ""
+
+msgid "No entry seems contain this media."
+msgstr ""
+
+msgid "published"
+msgstr ""
+
+msgid "unpublished"
+msgstr ""
+
+msgid "scheduled"
+msgstr ""
+
+msgid "pending"
+msgstr ""
+
+msgid "Image details"
+msgstr ""
+
+msgid "No detail"
+msgstr ""
+
+msgid "Updates and modifications"
+msgstr ""
+
+msgid "Update thumbnails"
+msgstr ""
+
+msgid "This will create or update thumbnails for this image."
+msgstr ""
+
+msgid "Extract in a new directory"
+msgstr ""
+
+msgid "Extract in current directory"
+msgstr ""
+
+msgid "Extract archive"
+msgstr ""
+
+msgid "This will extract archive in a new directory that should not exist yet."
+msgstr ""
+
+msgid "This will extract archive in current directory and will overwrite existing files or directory."
+msgstr ""
+
+msgid "Extract mode:"
+msgstr ""
+
+msgid "Extract"
+msgstr ""
+
+msgid "Change media properties"
+msgstr ""
+
+msgid "File name:"
+msgstr ""
+
+msgid "File title:"
+msgstr ""
+
+msgid "File date:"
+msgstr ""
+
+msgid "New directory:"
+msgstr ""
+
+msgid "Change file"
+msgstr ""
+
+msgid "Choose a file:"
+msgstr ""
+
+#, php-format
+msgid "Maximum size %s"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Delete this media"
+msgstr ""
+
+msgid "No content found on this plugin."
+msgstr ""
+
+msgid "Plugin not found"
+msgstr ""
+
+msgid "The plugin you reached does not exist or does not have an admin page."
+msgstr ""
+
+msgid "Plugins management"
+msgstr ""
+
+msgid "Plugin configuration"
+msgstr ""
+
+msgid "Update plugins"
+msgstr ""
+
+#, php-format
+msgid "There is one plugin to update available from repository."
+msgid_plural "There are %s plugins to update available from repository."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Installed plugins"
+msgstr ""
+
+msgid "Activated plugins"
+msgstr ""
+
+msgid "You can configure and manage installed plugins from this list."
+msgstr ""
+
+msgid "Deactivated plugins"
+msgstr ""
+
+msgid "Deactivated plugins are installed but not usable. You can activate them from here."
+msgstr ""
+
+msgid "Add plugins"
+msgstr ""
+
+msgid "Add plugins from repository"
+msgstr ""
+
+msgid "Add plugins from a package"
+msgstr ""
+
+msgid "You can install plugins by uploading or downloading zip files."
+msgstr ""
+
+msgid "Some functions are disabled, please give write access to your plugins directory to enable them."
+msgstr ""
+
+msgid "Add a link"
+msgstr ""
+
+msgid "Link URL:"
+msgstr ""
+
+msgid "Link title:"
+msgstr ""
+
+msgid "Link language:"
+msgstr ""
+
+msgid "Add a link to an entry"
+msgstr ""
+
+msgid "Entry type:"
+msgstr ""
+
+msgid "Ok"
+msgstr ""
+
+msgid "Search entry:"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "cancel"
+msgstr ""
+
+msgid "Edit entry"
+msgstr ""
+
+msgid "This entry does not exist."
+msgstr ""
+
+msgid "Next entry"
+msgstr ""
+
+msgid "Previous entry"
+msgstr ""
+
+msgid "All pings sent."
+msgstr ""
+
+msgid "Invalid publication date"
+msgstr ""
+
+#, php-format
+msgid "The post \"%s\" has been successfully updated"
+msgstr ""
+
+msgid "Entry has been successfully created."
+msgstr ""
+
+msgid "Published"
+msgstr ""
+
+msgid "Unpublished"
+msgstr ""
+
+msgid "Scheduled"
+msgstr ""
+
+msgid "Pending"
+msgstr ""
+
+#, php-format
+msgid "&ldquo;%s&rdquo;"
+msgstr ""
+
+msgid "Entries"
+msgstr ""
+
+msgid "Entry has been successfully updated."
+msgstr ""
+
+msgid "File has been successfully attached."
+msgstr ""
+
+msgid "Attachment has been successfully removed."
+msgstr ""
+
+msgid "Don't forget to validate your XHTML conversion by saving your post."
+msgstr ""
+
+msgid "Go to this entry on the site"
+msgstr ""
+
+msgid "Entry status"
+msgstr ""
+
+msgid "Publication date and hour"
+msgstr ""
+
+msgid "Entry language"
+msgstr ""
+
+msgid "Text formatting"
+msgstr ""
+
+msgid "Convert to XHTML"
+msgstr ""
+
+msgid "Filing"
+msgstr ""
+
+msgid "Selected entry"
+msgstr ""
+
+msgid "Category"
+msgstr ""
+
+msgid "Options"
+msgstr ""
+
+msgid "Comments and trackbacks list"
+msgstr ""
+
+msgid "Warning: Comments are not more accepted for this entry."
+msgstr ""
+
+msgid "Comments are not accepted on this blog so far."
+msgstr ""
+
+msgid "Warning: Trackbacks are not more accepted for this entry."
+msgstr ""
+
+msgid "Trackbacks are not accepted on this blog so far."
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "Edit basename"
+msgstr ""
+
+msgid "Warning: If you set the URL manually, it may conflict with another entry."
+msgstr ""
+
+msgid "Excerpt:"
+msgstr ""
+
+msgid "Introduction to the post."
+msgstr ""
+
+msgid "Personal notes:"
+msgstr ""
+
+msgid "Unpublished notes."
+msgstr ""
+
+msgid "Edit post"
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Comments"
+msgstr ""
+
+msgid "Add a comment"
+msgstr ""
+
+msgid "Trackbacks"
+msgstr ""
+
+msgid "Trackbacks received"
+msgstr ""
+
+msgid "No trackback"
+msgstr ""
+
+msgid "Selected trackbacks action:"
+msgstr ""
+
+msgid "Ping blogs"
+msgstr ""
+
+msgid "URLs to ping:"
+msgstr ""
+
+msgid "Excerpt to send:"
+msgstr ""
+
+msgid "Auto discover ping URLs"
+msgstr ""
+
+msgid "Previously sent pings"
+msgstr ""
+
+msgid "IP address"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Junk"
+msgstr ""
+
+msgid "select this comment"
+msgstr ""
+
+msgid "select this trackback"
+msgstr ""
+
+msgid "Edit this comment"
+msgstr ""
+
+msgid "This attachment does not exist"
+msgstr ""
+
+msgid "Remove attachment"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Are you sure you want to remove this attachment?"
+msgstr ""
+
+msgid "(No cat)"
+msgstr "(none)"
+
+msgid "Selected"
+msgstr ""
+
+msgid "Not selected"
+msgstr ""
+
+msgid "Opened"
+msgstr ""
+
+msgid "Closed"
+msgstr ""
+
+msgid "With attachments"
+msgstr ""
+
+msgid "Without attachments"
+msgstr ""
+
+msgid "With password"
+msgstr ""
+
+msgid "Without password"
+msgstr ""
+
+msgid "Number of comments"
+msgstr ""
+
+msgid "Number of trackbacks"
+msgstr ""
+
+msgid "Selected entries have been successfully updated."
+msgstr ""
+
+msgid "Selected entries have been successfully deleted."
+msgstr ""
+
+msgid "Format:"
+msgstr ""
+
+msgid "Selected:"
+msgstr ""
+
+msgid "Attachments:"
+msgstr ""
+
+msgid "Month:"
+msgstr ""
+
+msgid "Lang:"
+msgstr ""
+
+msgid "Comments:"
+msgstr ""
+
+msgid "Trackbacks:"
+msgstr ""
+
+msgid "entries per page"
+msgstr ""
+
+msgid "Selected entries action:"
+msgstr ""
+
+msgid "Smaller"
+msgstr ""
+
+msgid "Larger"
+msgstr ""
+
+msgid "Blog description (in blog parameters)"
+msgstr ""
+
+msgid "Category description"
+msgstr ""
+
+msgid "Posts"
+msgstr ""
+
+msgid "If you want to change your email or password you must provide your current password."
+msgstr ""
+
+msgid "Personal information has been successfully updated."
+msgstr ""
+
+msgid "Personal options has been successfully updated."
+msgstr ""
+
+msgid "Dashboard options has been successfully updated."
+msgstr ""
+
+msgid "No favorite selected"
+msgstr ""
+
+msgid "Favorites have been successfully added."
+msgstr ""
+
+msgid "Favorites have been successfully removed."
+msgstr ""
+
+msgid "Favorites have been successfully updated."
+msgstr ""
+
+msgid "Default favorites have been successfully updated."
+msgstr ""
+
+msgid "My profile"
+msgstr ""
+
+msgid "Display name:"
+msgstr ""
+
+msgid "Language for my interface:"
+msgstr ""
+
+msgid "My timezone:"
+msgstr ""
+
+msgid "Change my password"
+msgstr ""
+
+msgid "Confirm new password:"
+msgstr ""
+
+msgid "Your current password:"
+msgstr ""
+
+msgid "If you have changed your email or password you must provide your current password to save these modifications."
+msgstr ""
+
+msgid "Update my profile"
+msgstr ""
+
+msgid "My options"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Activate enhanced uploader in media manager"
+msgstr ""
+
+msgid "Disable javascript powered drag and drop for ordering items"
+msgstr ""
+
+msgid "If checked, numeric fields will allow to type the elements' ordering number."
+msgstr ""
+
+msgid "Hide all secondary information and notes"
+msgstr ""
+
+msgid "Font size:"
+msgstr ""
+
+msgid "Number of elements displayed per page in media manager:"
+msgstr ""
+
+msgid "Number of recent folders proposed in media manager:"
+msgstr ""
+
+msgid "Leave empty to ignore, displayed only if Javascript is enabled in your browser."
+msgstr ""
+
+msgid "Do not use standard favicon"
+msgstr ""
+
+msgid "This will be applied for all users"
+msgstr ""
+
+msgid "Optional columns displayed in lists"
+msgstr ""
+
+msgid "Edition"
+msgstr ""
+
+#, php-format
+msgid "Preferred editor for %s:"
+msgstr ""
+
+msgid "Choose an editor"
+msgstr ""
+
+msgid "Preferred format:"
+msgstr ""
+
+msgid "Default entry status:"
+msgstr ""
+
+msgid "Entry edit field height:"
+msgstr ""
+
+msgid "Enable WYSIWYG mode"
+msgstr ""
+
+msgid "Display editor's toolbar at bottom of textarea (if possible)"
+msgstr ""
+
+msgid "Use xhtml editor for:"
+msgstr ""
+
+msgid "Other options"
+msgstr ""
+
+msgid "Save my options"
+msgstr ""
+
+msgid "My dashboard"
+msgstr ""
+
+msgid "My favorites"
+msgstr ""
+
+#, php-format
+msgid "position of %s"
+msgstr ""
+
+msgid "Save order"
+msgstr ""
+
+msgid "Delete selected favorites"
+msgstr ""
+
+msgid "Are you sure you want to remove selected favorites?"
+msgstr ""
+
+msgid "If you are a super administrator, you may define this set of favorites to be used by default on all blogs of this installation."
+msgstr ""
+
+msgid "Define as default favorites"
+msgstr ""
+
+msgid "Currently no personal favorites."
+msgstr ""
+
+msgid "Other available favorites"
+msgstr ""
+
+msgid "(default favorite)"
+msgstr ""
+
+msgid "Add to my favorites"
+msgstr ""
+
+msgid "Menu"
+msgstr ""
+
+msgid "Display favorites at the top of the menu"
+msgstr ""
+
+msgid "Dashboard icons"
+msgstr ""
+
+msgid "Display dashboard icons"
+msgstr ""
+
+msgid "Iconset:"
+msgstr ""
+
+msgid "Dashboard modules"
+msgstr ""
+
+msgid "Display documentation links"
+msgstr ""
+
+msgid "Display Dotclear news"
+msgstr ""
+
+msgid "Display quick entry form"
+msgstr ""
+
+msgid "Save my dashboard options"
+msgstr ""
+
+msgid "Search options"
+msgstr ""
+
+msgid "Query:"
+msgstr ""
+
+msgid "Search in entries"
+msgstr ""
+
+msgid "Search in comments"
+msgstr ""
+
+#, php-format
+msgid "%d entries found"
+msgstr ""
+
+#, php-format
+msgid "%d entry found"
+msgstr ""
+
+#, php-format
+msgid "%d comment found"
+msgstr ""
+
+#, php-format
+msgid "%d comments found"
+msgstr ""
+
+msgid "Dotclear update"
+msgstr ""
+
+#, php-format
+msgid "Unable to delete file %s"
+msgstr ""
+
+#, php-format
+msgid "Downloaded Dotclear archive seems to be corrupted. Try <a %s>download it</a> again."
+msgstr ""
+
+msgid "If this problem persists try to <a href=\"http://dotclear.org/download\">update manually</a>."
+msgstr ""
+
+msgid "The following files of your Dotclear installation have been modified so we won't try to update your installation. Please try to <a href=\"http://dotclear.org/download\">update manually</a>."
+msgstr ""
+
+#, php-format
+msgid "The following files of your Dotclear installation are not readable. Please fix this or try to make a backup file named %s manually."
+msgstr ""
+
+msgid "The following files of your Dotclear installation cannot be written. Please fix this or try to <a href=\"http://dotclear.org/download\">update manually</a>."
+msgstr ""
+
+msgid "Manual checking of update done successfully."
+msgstr ""
+
+msgid "No newer Dotclear version available."
+msgstr ""
+
+msgid "Force checking update Dotclear"
+msgstr ""
+
+#, php-format
+msgid "Dotclear %s is available."
+msgstr ""
+
+#, php-format
+msgid "PHP version is %s (%s or earlier needed)."
+msgstr ""
+
+msgid "To upgrade your Dotclear installation simply click on the following button. A backup file of your current installation will be created in your root directory."
+msgstr ""
+
+msgid "Update Dotclear"
+msgstr ""
+
+msgid "Manage backup files"
+msgstr ""
+
+msgid "Update backup files"
+msgstr ""
+
+msgid "The following files are backups of previously updates. You can revert your previous installation or delete theses files."
+msgstr ""
+
+msgid "Please note that reverting your Dotclear version may have some unwanted side-effects. Consider reverting only if you experience strong issues with this new version."
+msgstr ""
+
+#, php-format
+msgid "You should not revert to version prior to last one (%s)."
+msgstr ""
+
+msgid "Delete selected file"
+msgstr ""
+
+msgid "Revert to selected file"
+msgstr ""
+
+msgid "Congratulations, you're one click away from the end of the update."
+msgstr ""
+
+msgid "Finish the update."
+msgstr ""
+
+msgid "New user"
+msgstr ""
+
+msgid "User has been successfully updated."
+msgstr ""
+
+#, php-format
+msgid "User \"%s\" already exists."
+msgstr ""
+
+msgid "User has been successfully created."
+msgstr ""
+
+msgid "User profile"
+msgstr ""
+
+msgid "User ID:"
+msgstr ""
+
+msgid "Warning:"
+msgstr ""
+
+msgid "If you change your username, you will have to log in again."
+msgstr ""
+
+msgid "Password change required to connect"
+msgstr ""
+
+msgid "Mandatory for password recovering procedure."
+msgstr ""
+
+msgid "Timezone:"
+msgstr ""
+
+msgid "Save and create another"
+msgstr ""
+
+msgid "Permissions"
+msgstr ""
+
+msgid "Add new permissions"
+msgstr ""
+
+msgid "No permissions so far."
+msgstr ""
+
+msgid "Blog:"
+msgstr ""
+
+#, php-format
+msgid "%s is super admin (all rights on all blogs)."
+msgstr ""
+
+msgid "Username"
+msgstr ""
+
+msgid "Last Name"
+msgstr ""
+
+msgid "First Name"
+msgstr ""
+
+msgid "Display name"
+msgstr ""
+
+msgid "Number of entries"
+msgstr ""
+
+msgid "Set permissions"
+msgstr ""
+
+msgid "User has been successfully removed."
+msgstr ""
+
+msgid "The permissions have been successfully updated."
+msgstr ""
+
+msgid "users per page"
+msgstr ""
+
+msgid "Selected users action:"
+msgstr ""
+
+msgid "No blog or user given."
+msgstr ""
+
+msgid "You cannot delete yourself."
+msgstr ""
+
+msgid "User has been successfully deleted."
+msgstr ""
+
+msgid "Back to user profile"
+msgstr ""
+
+#, php-format
+msgid "Choose one or more blogs to which you want to give permissions to users %s."
+msgstr ""
+
+msgid "No blog"
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "select"
+msgstr ""
+
+#, php-format
+msgid "You are about to change permissions on the following blogs for users %s."
+msgstr ""
+
+msgid "Validate permissions"
+msgstr ""
+
+msgid "Back to blogs list"
+msgstr ""
+
+msgid "Blogs actions"
+msgstr ""
+
+msgid "Blog id"
+msgstr ""
+
+msgid "Set online"
+msgstr ""
+
+msgid "Set offline"
+msgstr ""
+
+msgid "Set as removed"
+msgstr ""
+
+msgid "No blog selected"
+msgstr ""
+
+msgid "Selected blogs have been successfully updated."
+msgstr ""
+
+#, php-format
+msgid "%d blog has been successfully deleted"
+msgid_plural "%d blogs have been successfully deleted"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Back to comments list"
+msgstr ""
+
+msgid "Comments actions"
+msgstr ""
+
+msgid "Publish"
+msgstr ""
+
+msgid "Unpublish"
+msgstr ""
+
+msgid "Mark as pending"
+msgstr ""
+
+msgid "Mark as junk"
+msgstr ""
+
+msgid "Blacklist IP"
+msgstr ""
+
+msgid "Blacklist IP (global)"
+msgstr ""
+
+msgid "No comment selected"
+msgstr ""
+
+msgid "IP addresses for selected comments have been blacklisted."
+msgstr ""
+
+msgid "Back to entries list"
+msgstr ""
+
+msgid "Entries actions"
+msgstr ""
+
+msgid "Schedule"
+msgstr ""
+
+msgid "Mark"
+msgstr ""
+
+msgid "Mark as selected"
+msgstr ""
+
+msgid "Mark as unselected"
+msgstr ""
+
+msgid "Change"
+msgstr ""
+
+msgid "Change category"
+msgstr ""
+
+msgid "Change language"
+msgstr ""
+
+msgid "Change author"
+msgstr ""
+
+msgid "No entry selected"
+msgstr ""
+
+#, php-format
+msgid "%d entry has been successfully updated to status : \"%s\""
+msgid_plural "%d entries have been successfully updated to status : \"%s\""
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "%d entry has been successfully marked as selected"
+msgid_plural "%d entries have been successfully marked as selected"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "%d entry has been successfully marked as unselected"
+msgid_plural "%d entries have been successfully marked as unselected"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "%d entry has been successfully deleted"
+msgid_plural "%d entries have been successfully deleted"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "%d entry has been successfully moved to category \"%s\""
+msgid_plural "%d entries have been successfully moved to category \"%s\""
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Change category for this selection"
+msgstr ""
+
+msgid "Create a new category for the post(s)"
+msgstr ""
+
+msgid "This user does not exist"
+msgstr ""
+
+#, php-format
+msgid "%d entry has been successfully set to user \"%s\""
+msgid_plural "%d entries have been successfully set to user \"%s\""
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Change author for this selection"
+msgstr ""
+
+msgid "New author (author ID):"
+msgstr ""
+
+#, php-format
+msgid "%d entry has been successfully set to language \"%s\""
+msgid_plural "%d entries have been successfully set to language \"%s\""
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Change language for this selection"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Most used"
+msgstr ""
+
+msgid "Entry language:"
+msgstr ""
+
+msgid "Languages"
+msgstr ""
+
+#, php-format
+msgid "%d post"
+msgid_plural "%d posts"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "%d comment"
+msgid_plural "%d comments"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Change blog"
+msgstr ""
+
+msgid "Blogs:"
+msgstr ""
+
+msgid "Go to the content"
+msgstr ""
+
+msgid "Go to the menu"
+msgstr ""
+
+msgid "Go to search"
+msgstr ""
+
+msgid "Go to help"
+msgstr ""
+
+msgid "Go to site"
+msgstr ""
+
+#, php-format
+msgid "Logout %s"
+msgstr ""
+
+msgid "Hide main menu"
+msgstr ""
+
+msgid "Show main menu"
+msgstr ""
+
+msgid "Safe mode"
+msgstr ""
+
+msgid "You are in safe mode. All plugins have been temporarily disabled. Remind to log out then log in again normally to get back all functionalities"
+msgstr ""
+
+msgid "[%H:%M:%S]"
+msgstr ""
+
+#, php-format
+msgid "Thank you for using %s."
+msgstr ""
+
+msgid "Page top"
+msgstr ""
+
+msgid "Go to dashboard"
+msgstr ""
+
+msgid "Help about this page"
+msgstr ""
+
+#, php-format
+msgid "See also %s"
+msgstr ""
+
+msgid "the global help"
+msgstr ""
+
+msgid "uncover"
+msgstr ""
+
+msgid "hide"
+msgstr ""
+
+msgid "Need help?"
+msgstr ""
+
+msgid "new window"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Select:"
+msgstr ""
+
+msgid "no selection"
+msgstr ""
+
+msgid "select all"
+msgstr ""
+
+msgid "Invert selection"
+msgstr ""
+
+msgid "view entry"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete selected entries (%s)?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete selected medias (%d)?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete selected categories (%s)?"
+msgstr ""
+
+msgid "Are you sure you want to delete this entry?"
+msgstr ""
+
+msgid "Click here to unlock the field"
+msgstr ""
+
+msgid "Are you sure you want to delete all spams?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete selected comments (%s)?"
+msgstr ""
+
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
+msgid "Users with posts cannot be deleted."
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete selected users (%s)?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete selected blogs (%s)?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete category \"%s\"?"
+msgstr ""
+
+msgid "Are you sure you want to reorder all categories?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to remove media \"%s\"?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to remove directory \"%s\"?"
+msgstr ""
+
+msgid "Are you sure you want to extract archive in current directory?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to remove attachment \"%s\"?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete \"%s\" language?"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete \"%s\" plugin?"
+msgstr ""
+
+msgid "Are you sure you want to delete selected plugins?"
+msgstr ""
+
+msgid "Use this theme"
+msgstr ""
+
+msgid "Remove this theme"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to delete \"%s\" theme?"
+msgstr ""
+
+msgid "Are you sure you want to delete selected themes?"
+msgstr ""
+
+msgid "Are you sure you want to delete this backup?"
+msgstr ""
+
+msgid "Are you sure you want to revert to this backup?"
+msgstr ""
+
+msgid "Zip file content"
+msgstr ""
+
+msgid "XHTML markup validator"
+msgstr ""
+
+msgid "XHTML content is valid."
+msgstr ""
+
+msgid "There are XHTML markup errors."
+msgstr ""
+
+msgid "Attention: an audit of a content not yet registered."
+msgstr ""
+
+msgid "You have unsaved changes. Switch post format will loose these changes. Proceed anyway?"
+msgstr ""
+
+msgid "Warning: post format change will not convert existing content. You will need to apply new format by yourself. Proceed anyway?"
+msgstr ""
+
+msgid "Loading enhanced uploader, please wait."
+msgstr ""
+
+msgid "Details"
+msgstr ""
+
+msgid "Support"
+msgstr ""
+
+msgid "Help:"
+msgstr ""
+
+msgid "Section:"
+msgstr ""
+
+msgid "Tags:"
+msgstr ""
+
+msgid "You have unsaved changes."
+msgstr ""
+
+msgid "Choose date"
+msgstr ""
+
+msgid "close"
+msgstr ""
+
+msgid "now"
+msgstr ""
+
+msgid "Temporarily activate enhanced uploader"
+msgstr ""
+
+msgid "Temporarily disable enhanced uploader"
+msgstr ""
+
+msgid "Limit exceeded."
+msgstr ""
+
+msgid "File size exceeds allowed limit."
+msgstr ""
+
+msgid "Canceled."
+msgstr ""
+
+msgid "HTTP Error:"
+msgstr ""
+
+msgid "Clean"
+msgstr ""
+
+msgid "File successfully uploaded."
+msgstr ""
+
+msgid "No file in queue."
+msgstr ""
+
+msgid "1 file in queue."
+msgstr ""
+
+#, php-format
+msgid "%d files in queue."
+msgstr ""
+
+msgid "Queue error:"
+msgstr ""
+
+msgid "Cancel filters and display options"
+msgstr ""
+
+msgid "other"
+msgstr ""
+
+msgid "Search in repository:"
+msgstr ""
+
+msgid "Reset search"
+msgstr ""
+
+msgid "Search is allowed on multiple terms longer than 2 chars, terms must be separated by space."
+msgstr ""
+
+#, php-format
+msgid "Found %d result for search \"%s\":"
+msgid_plural "Found %d results for search \"%s\":"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "current selection"
+msgstr ""
+
+#, php-format
+msgid "%d result"
+msgid_plural "%d results"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "no results"
+msgstr ""
+
+msgid "Browse index:"
+msgstr ""
+
+msgid "Plugins list"
+msgstr ""
+
+msgid "Score"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Current version"
+msgstr ""
+
+#, php-format
+msgid "This module cannot be disabled nor deleted, since the following modules are also enabled : %s"
+msgstr ""
+
+msgid "This module cannot be enabled, because of the following reasons :"
+msgstr ""
+
+msgid "Plugin from official distribution"
+msgstr ""
+
+msgid "Manage plugin"
+msgstr ""
+
+msgid "No plugins matched your search."
+msgstr ""
+
+msgid "Configure plugin"
+msgstr ""
+
+msgid "Plugin settings (in blog parameters)"
+msgstr ""
+
+msgid "Plugin settings (in user preferences)"
+msgstr ""
+
+msgid "Plugin settings"
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Deactivate"
+msgstr ""
+
+msgid "Install"
+msgstr ""
+
+msgid "Update"
+msgstr ""
+
+msgid "Activate selected plugins"
+msgstr ""
+
+msgid "Activate all plugins from this list"
+msgstr ""
+
+msgid "Deactivate selected plugins"
+msgstr ""
+
+msgid "Deactivate all plugins from this list"
+msgstr ""
+
+msgid "Update selected plugins"
+msgstr ""
+
+msgid "Update all plugins from this list"
+msgstr ""
+
+msgid "No such plugin."
+msgstr ""
+
+msgid "You don't have permissions to delete this plugin."
+msgstr ""
+
+msgid "Some plugins have not been delete."
+msgstr ""
+
+msgid "Plugin has been successfully deleted."
+msgid_plural "Plugins have been successuflly deleted."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Plugin has been successfully installed."
+msgid_plural "Plugins have been successuflly installed."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Plugin has been successfully activated."
+msgid_plural "Plugins have been successuflly activated."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Some plugins have not been deactivated."
+msgstr ""
+
+msgid "Plugin has been successfully deactivated."
+msgid_plural "Plugins have been successuflly deactivated."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Plugin has been successfully updated."
+msgid_plural "Plugins have been successuflly updated."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Zip file path:"
+msgstr ""
+
+msgid "Download a zip file"
+msgstr ""
+
+msgid "Zip file URL:"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "Unknow plugin ID"
+msgstr ""
+
+msgid "This plugin has no configuration file."
+msgstr ""
+
+#, php-format
+msgid "Configure \"%s\""
+msgstr ""
+
+msgid "Back"
+msgstr ""
+
+#, php-format
+msgid "Score: %s"
+msgstr ""
+
+#, php-format
+msgid "%s screenshot."
+msgstr ""
+
+#, php-format
+msgid "by %s"
+msgstr ""
+
+#, php-format
+msgid "version %s"
+msgstr ""
+
+#, php-format
+msgid "(current version %s)"
+msgstr ""
+
+#, php-format
+msgid "(built on \"%s\")"
+msgstr ""
+
+#, php-format
+msgid "(requires \"%s\")"
+msgstr ""
+
+msgid "View stylesheet"
+msgstr ""
+
+msgid "Configure theme"
+msgstr ""
+
+msgid "No themes matched your search."
+msgstr ""
+
+msgid "Use this one"
+msgstr ""
+
+msgid "Update selected themes"
+msgstr ""
+
+msgid "Update all themes from this list"
+msgstr ""
+
+msgid "No such theme."
+msgstr ""
+
+msgid "Theme has been successfully selected."
+msgstr ""
+
+msgid "Theme has been successfully activated."
+msgid_plural "Themes have been successuflly activated."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Some themes have not been deactivated."
+msgstr ""
+
+msgid "Theme has been successfully deactivated."
+msgid_plural "Themes have been successuflly deactivated."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "You don't have permissions to delete this theme."
+msgstr ""
+
+msgid "Some themes have not been delete."
+msgstr ""
+
+msgid "Theme has been successfully deleted."
+msgid_plural "Themes have been successuflly deleted."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Theme has been successfully installed."
+msgid_plural "Themes have been successuflly installed."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Theme has been successfully updated."
+msgid_plural "Themes have been successuflly updated."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "First page"
+msgstr ""
+
+msgid "Previous page"
+msgstr ""
+
+msgid "Next page"
+msgstr ""
+
+msgid "Last page"
+msgstr ""
+
+#, php-format
+msgid "Page %s / %s"
+msgstr ""
+
+#, php-format
+msgid "Direct access page %s"
+msgstr ""
+
+msgid "&#171; prev."
+msgstr ""
+
+msgid "next &#187;"
+msgstr ""
+
+msgid "No entry matches the filter"
+msgstr ""
+
+msgid "No entry"
+msgstr ""
+
+#, php-format
+msgid "List of %s entries matching the filter."
+msgstr ""
+
+#, php-format
+msgid "List of entries (%s)"
+msgstr ""
+
+#, php-format
+msgid ", <a href=\"%s\">published</a> (1)"
+msgid_plural ", <a href=\"%s\">published</a> (%s)"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid ", <a href=\"%s\">pending</a> (1)"
+msgid_plural ", <a href=\"%s\">pending</a> (%s)"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid ", <a href=\"%s\">programmed</a> (1)"
+msgid_plural ", <a href=\"%s\">programmed</a> (%s)"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid ", <a href=\"%s\">unpublished</a> (1)"
+msgid_plural ", <a href=\"%s\">unpublished</a> (%s)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Protected"
+msgstr ""
+
+#, php-format
+msgid "%d attachment"
+msgstr ""
+
+#, php-format
+msgid "%d attachments"
+msgstr ""
+
+msgid "Entries list"
+msgstr ""
+
+msgid "No comments or trackbacks matches the filter"
+msgstr ""
+
+#, php-format
+msgid "Comment or trackback matching the filter."
+msgid_plural "List of %s comments or trackbacks matching the filter."
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "List of comments and trackbacks (%s)"
+msgstr ""
+
+#, php-format
+msgid ", <a href=\"%s\">spam</a> (1)"
+msgid_plural ", <a href=\"%s\">spam</a> (%s)"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Type"
+msgstr ""
+
+msgid "Entry"
+msgstr ""
+
+#, php-format
+msgid "Edit the %1$s from %2$s"
+msgstr ""
+
+msgid "comment"
+msgstr ""
+
+msgid "trackback"
+msgstr ""
+
+msgid "Type and author"
+msgstr ""
+
+msgid "No blog matches the filter"
+msgstr ""
+
+msgid "Entries (all types)"
+msgstr "Entries"
+
+#, php-format
+msgid "%d blog matches the filter."
+msgid_plural "%d blogs match the filter."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Blogs list"
+msgstr ""
+
+#, php-format
+msgid "Edit blog settings for %s"
+msgstr ""
+
+msgid "Edit blog settings"
+msgstr ""
+
+#, php-format
+msgid "Switch to blog %s"
+msgstr ""
+
+msgid "No user matches the filter"
+msgstr ""
+
+msgid "No user"
+msgstr ""
+
+#, php-format
+msgid "List of %s users match the filter."
+msgstr ""
+
+msgid "Users list"
+msgstr ""
+
+msgid "admin"
+msgstr ""
+
+msgid "superadmin"
+msgstr ""
+
+#, php-format
+msgid "ratio %.1f"
+msgstr ""
+
+#, php-format
+msgid "(%s)"
+msgstr ""
+
+msgid "The 'public' directory does not exist."
+msgstr ""
+
+#, php-format
+msgid "The '%s' directory cannot be modified."
+msgstr ""
+
+msgid "At least one of the following functions is not available: imagecreatetruecolor, imagepng & imagecreatefrompng."
+msgstr ""
+
+msgid "Unable to create images."
+msgstr ""
+
+msgid "Invalid file type."
+msgstr ""
+
+msgid "An error occurred while writing the file."
+msgstr ""
+
+#, php-format
+msgid "Uploaded image is not %s pixels wide."
+msgstr ""
+
+msgid "Database error"
+msgstr ""
+
+msgid "There seems to be no Session table in your database. Is Dotclear completly installed?"
+msgstr ""
+
+msgid "System settings"
+msgstr ""
+
+msgid "Blog"
+msgstr ""
+
+msgid "Plugins"
+msgstr ""
+
+msgid "medium"
+msgstr ""
+
+msgid "small"
+msgstr ""
+
+msgid "thumbnail"
+msgstr ""
+
+msgid "square"
+msgstr ""
+
+msgid "Pages"
+msgstr ""
+
+msgid "administrator"
+msgstr ""
+
+msgid "manage their own entries and comments"
+msgstr ""
+
+msgid "publish entries and comments"
+msgstr ""
+
+msgid "delete entries and comments"
+msgstr ""
+
+msgid "manage all entries and comments"
+msgstr ""
+
+msgid "manage categories"
+msgstr ""
+
+msgid "manage their own media items"
+msgstr ""
+
+msgid "manage all media items"
+msgstr ""
+
+msgid "That user does not exist in the database."
+msgstr ""
+
+msgid "That key does not exist in the database."
+msgstr ""
+
+msgid "You are not allowed to add categories"
+msgstr ""
+
+msgid "You are not allowed to update categories"
+msgstr ""
+
+msgid "You are not allowed to delete categories"
+msgstr ""
+
+msgid "This category is not empty."
+msgstr ""
+
+msgid "You are not allowed to reset categories order"
+msgstr ""
+
+msgid "Empty category URL"
+msgstr ""
+
+msgid "You must provide a category title"
+msgstr ""
+
+msgid "You must provide a category URL"
+msgstr ""
+
+msgid "You are not allowed to create an entry"
+msgstr ""
+
+msgid "You are not allowed to update entries"
+msgstr ""
+
+msgid "No such entry ID"
+msgstr ""
+
+msgid "You are not allowed to edit this entry"
+msgstr ""
+
+msgid "You are not allowed to change this entry status"
+msgstr ""
+
+msgid "You are not allowed to change this entry category"
+msgstr ""
+
+msgid "You are not allowed to change entries category"
+msgstr ""
+
+msgid "You are not allowed to delete entries"
+msgstr ""
+
+msgid "No entry title"
+msgstr ""
+
+msgid "No entry content"
+msgstr ""
+
+msgid "Notes"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Empty entry URL"
+msgstr ""
+
+msgid "You are not allowed to update comments"
+msgstr ""
+
+msgid "No such comment ID"
+msgstr ""
+
+msgid "You are not allowed to update this comment"
+msgstr ""
+
+msgid "You are not allowed to change this comment's status"
+msgstr ""
+
+msgid "You are not allowed to delete comments"
+msgstr ""
+
+msgid "You must provide a comment"
+msgstr ""
+
+msgid "You must provide an author name"
+msgstr ""
+
+msgid "Email address is not valid."
+msgstr ""
+
+msgid "online"
+msgstr ""
+
+msgid "offline"
+msgstr ""
+
+msgid "removed"
+msgstr ""
+
+msgid "You are not an administrator"
+msgstr ""
+
+msgid "Invalid user language code"
+msgstr ""
+
+msgid "Blog ID must contain at least 2 characters using letters, numbers or symbols."
+msgstr ""
+
+msgid "No blog name"
+msgstr ""
+
+msgid "No blog URL"
+msgstr ""
+
+msgid "No log message"
+msgstr ""
+
+msgid "unknown"
+msgstr ""
+
+msgid "No blog defined."
+msgstr ""
+
+msgid "You are not a super administrator."
+msgstr ""
+
+msgid "Permission denied."
+msgstr ""
+
+msgid "You are not the file owner."
+msgstr ""
+
+msgid "This file is not allowed."
+msgstr ""
+
+msgid "New file already exists."
+msgstr ""
+
+msgid "File does not exist in the database."
+msgstr ""
+
+#, php-format
+msgid "Extract destination directory %s already exists."
+msgstr ""
+
+msgid "Embedded Audio Player"
+msgstr ""
+
+msgid "Embedded Video Player"
+msgstr ""
+
+#, php-format
+msgid "Requires %s module which is not installed"
+msgstr ""
+
+#, php-format
+msgid "Requires Dotclear version %s, but version %s is installed"
+msgstr ""
+
+#, php-format
+msgid "Requires %s module version %s, but version %s is installed"
+msgstr ""
+
+#, php-format
+msgid "Requires %s module which is disabled"
+msgstr ""
+
+msgid "The following extensions have been disabled :"
+msgstr ""
+
+#, php-format
+msgid "Module \"%s\" has type \"%s\" that mismatch required module type \"%s\"."
+msgstr ""
+
+#, php-format
+msgid "Module \"%s\" is installed twice in \"%s\" and \"%s\"."
+msgstr ""
+
+msgid "Empty module zip file."
+msgstr ""
+
+msgid "The zip file does not appear to be a valid Dotclear module."
+msgstr ""
+
+msgid "An error occurred during module deletion."
+msgstr ""
+
+#, php-format
+msgid "Unable to upgrade \"%s\". (older or same version)"
+msgstr ""
+
+msgid "Unable to read new _define.php file"
+msgstr ""
+
+msgid "No such module."
+msgstr ""
+
+msgid "Cannot remove module files"
+msgstr ""
+
+msgid "Cannot deactivate plugin."
+msgstr ""
+
+msgid "Cannot activate plugin."
+msgstr ""
+
+#, php-format
+msgid "Invalid setting dcNamespace: %s"
+msgstr ""
+
+msgid "Unable to retrieve settings:"
+msgstr ""
+
+#, php-format
+msgid "%s is not a valid setting id"
+msgstr ""
+
+msgid "No namespace specified"
+msgstr ""
+
+msgid "Unable to retrieve workspaces:"
+msgstr ""
+
+msgid "Unable to retrieve namespaces:"
+msgstr ""
+
+#, php-format
+msgid "Invalid setting namespace: %s"
+msgstr ""
+
+msgid "Failed to read data feed"
+msgstr ""
+
+msgid "Wrong data feed"
+msgstr ""
+
+msgid "An error occurred while downloading the file."
+msgstr ""
+
+#, php-format
+msgid "%s has still been pinged"
+msgstr ""
+
+msgid "Unable to ping URL"
+msgstr ""
+
+msgid "Bad server response code"
+msgstr ""
+
+#, php-format
+msgid "%s is not a ping URL"
+msgstr ""
+
+#, php-format
+msgid "%s, ping error:"
+msgstr ""
+
+msgid "Don't repeat yourself, please."
+msgstr ""
+
+msgid "Where's your title?"
+msgstr ""
+
+msgid "Sorry, an internal problem has occured."
+msgstr ""
+
+msgid "Thanks, mate. It was a pleasure."
+msgstr ""
+
+msgid "A website mention this entry."
+msgstr ""
+
+msgid "Any chance you ping one of my contents? No? Really?"
+msgstr ""
+
+msgid "Sorry but you can not ping this type of content."
+msgstr ""
+
+msgid "Oops. Kinda \"not found\" stuff. Please check the target URL twice."
+msgstr ""
+
+msgid "Sorry, dude. This entry does not accept pingback at the moment."
+msgstr ""
+
+msgid "Your source URL does not look like a supported content type. Sorry. Bye, bye!"
+msgstr ""
+
+msgid "No valid source URL provided? Try again!"
+msgstr ""
+
+msgid "No valid target URL provided? Try again!"
+msgstr ""
+
+msgid "LOL!"
+msgstr ""
+
+msgid "Digests file not found."
+msgstr ""
+
+msgid "No file to download"
+msgstr ""
+
+msgid "Root directory is not writable."
+msgstr ""
+
+msgid "An error occurred while downloading archive."
+msgstr ""
+
+msgid "Archive not found."
+msgstr ""
+
+msgid "Unable to read current digests file."
+msgstr ""
+
+msgid "Downloaded file does not seem to be a valid archive."
+msgstr ""
+
+msgid "Incomplete archive."
+msgstr ""
+
+msgid "Unable to read digests file."
+msgstr ""
+
+msgid "Invalid digests file."
+msgstr ""
+
+#, php-format
+msgid "Invalid dcWorkspace: %s"
+msgstr ""
+
+msgid "Unable to retrieve prefs:"
+msgstr ""
+
+#, php-format
+msgid "%s is not a valid pref id"
+msgstr ""
+
+msgid "No workspace specified"
+msgstr ""
+
+msgid "Something went wrong with auto upgrade:"
+msgstr ""
+
+msgid "Unable to open directory."
+msgstr ""
+
+msgid "Unable to create directory."
+msgstr ""
+
+msgid "File is not writable."
+msgstr ""
+
+msgid "Unable to open file."
+msgstr ""
+
+msgid "Not an uploaded file."
+msgstr ""
+
+msgid "The uploaded file exceeds the maximum file size allowed."
+msgstr ""
+
+msgid "The uploaded file was only partially uploaded."
+msgstr ""
+
+msgid "No file was uploaded."
+msgstr ""
+
+msgid "Missing a temporary folder."
+msgstr ""
+
+msgid "Failed to write file to disk."
+msgstr ""
+
+msgid "A PHP extension stopped the file upload."
+msgstr ""
+
+#, php-format
+msgid "%s is not a directory."
+msgstr ""
+
+msgid "Bad range"
+msgstr ""
+
+msgid "Invalid range"
+msgstr ""
+
+msgid "Invalid line number"
+msgstr ""
+
+msgid "Chunk is out of range"
+msgstr ""
+
+msgid "Bad context"
+msgstr ""
+
+msgid "Bad context (in deletion)"
+msgstr ""
+
+msgid "Invalid diff format"
+msgstr ""
+
+msgid "Uploading this file is not allowed."
+msgstr ""
+
+msgid "Destination directory is not in jail."
+msgstr ""
+
+msgid "File already exists."
+msgstr ""
+
+msgid "Cannot write in this directory."
+msgstr ""
+
+msgid "Source file does not exist."
+msgstr ""
+
+msgid "File is not in jail."
+msgstr ""
+
+msgid "Destination directory is not writable."
+msgstr ""
+
+msgid "Unable to rename file."
+msgstr ""
+
+msgid "File cannot be removed."
+msgstr ""
+
+msgid "Directory is not in jail."
+msgstr ""
+
+msgid "Directory cannot be removed."
+msgstr ""
+
+msgid "Not enough memory to open image."
+msgstr ""
+
+#, php-format
+msgid "Did not find closing tag for block <tpl:%s>. Content has been ignored."
+msgstr ""
+
+#, php-format
+msgid "Unexpected closing tag </tpl:%s> found."
+msgstr ""
+
+msgid "WARNING: the following errors have been found while parsing template file :"
+msgstr ""
+
+msgid "singular"
+msgid_plural "plural"
+msgstr[0] ""
+msgstr[1] ""
+
+#, php-format
+msgid "File %s is not compressed in the zip."
+msgstr ""
+
+#, php-format
+msgid "Trying to unzip a folder name %s"
+msgstr ""
+
+msgid "Unable to write destination file."
+msgstr ""
+
+msgid "Unable to write in target directory, permission denied."
+msgstr ""
+
+msgid "Not enough memory to open file."
+msgstr ""
+
+msgid "File does not exist"
+msgstr ""
+
+msgid "Cannot read file"
+msgstr ""
+
+msgid "Directory does not exist"
+msgstr ""
+
+msgid "Cannot read directory"
+msgstr ""
+
+msgid "Site temporarily unavailable"
+msgstr ""
+
+msgid "<p>We apologize for this temporary unavailability.<br />Thank you for your understanding.</p>"
+msgstr ""
+
+msgid "Unable to connect to database"
+msgstr ""
+
+#, php-format
+msgid "<p>This either means that the username and password information in your <strong>config.php</strong> file is incorrect or we can't contact the database server at \"<em>%s</em>\". This could mean your host's database server is down.</p> <ul><li>Are you sure you have the correct username and password?</li><li>Are you sure that you have typed the correct hostname?</li><li>Are you sure that the database server is running?</li></ul><p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href=\"http://forum.dotclear.net/\">Dotclear Support Forums</a>.</p>"
+msgstr ""
+
+msgid "The following error was encountered while trying to read the database:"
+msgstr ""
Index: locales/lb/plugins.po
===================================================================
--- locales/lb/plugins.po	(revision 3818)
+++ locales/lb/plugins.po	(revision 3818)
@@ -0,0 +1,2155 @@
+# SOME DESCRIPTIVE TITLE.
+# This file is put in the public domain.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Dotclear 2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-11-23 10:18+0100\n"
+"PO-Revision-Date: 2017-01-15 21:29+0100\n"
+"Last-Translator: Alain Vagner <alain.vagner@sous-anneau.org>\n"
+"Language-Team: \n"
+"Language: lb\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 1.8.11\n"
+
+msgid "Manage every blog configuration directive"
+msgstr ""
+
+msgid "Akismet interface for Dotclear"
+msgstr ""
+
+msgid "Generic antispam plugin for Dotclear"
+msgstr ""
+
+msgid "Manage post attachments"
+msgstr ""
+
+msgid "Manage your blogroll"
+msgstr ""
+
+msgid "Configure your Blowup Theme"
+msgstr ""
+
+msgid "Legacy modules for dotclear"
+msgstr ""
+
+msgid "Trackback validity check"
+msgstr ""
+
+msgid "Import and Export your blog"
+msgstr ""
+
+msgid "Maintain your installation"
+msgstr ""
+
+msgid "Serve entries as simple web pages"
+msgstr ""
+
+msgid "Ping services"
+msgstr ""
+
+msgid "Simple menu for Dotclear"
+msgstr ""
+
+msgid "Tags for posts"
+msgstr ""
+
+msgid "Theme Editor"
+msgstr ""
+
+msgid "Manage every user preference directive"
+msgstr ""
+
+msgid "Widgets for your blog sidebars"
+msgstr ""
+
+msgid "dotclear legacy editor"
+msgstr ""
+
+msgid "dotclear CKEditor integration"
+msgstr ""
+
+msgid "Breadcrumb for Dotclear"
+msgstr ""
+
+msgid "Search engine form"
+msgstr ""
+
+msgid "List of navigation links"
+msgstr ""
+
+msgid "List of selected entries"
+msgstr ""
+
+msgid "List of available languages"
+msgstr ""
+
+msgid "List of categories"
+msgstr ""
+
+msgid "Feed subscription links (RSS or Atom)"
+msgstr ""
+
+msgid "List of last entries from feed (RSS or Atom)"
+msgstr ""
+
+msgid "Simple text"
+msgstr ""
+
+msgid "List of last entries published"
+msgstr ""
+
+msgid "List of last comments published"
+msgstr ""
+
+msgid "List of published pages"
+msgstr ""
+
+msgid "Blogroll list"
+msgstr ""
+
+msgid "List of simple menu items"
+msgstr ""
+
+msgid "Tags cloud"
+msgstr ""
+
+msgid "Configuration successfully updated"
+msgstr ""
+
+msgid "no"
+msgstr ""
+
+msgid "yes"
+msgstr ""
+
+msgid "about:config"
+msgstr ""
+
+#, php-format
+msgid "Settings for %s"
+msgstr ""
+
+msgid "Setting ID"
+msgstr ""
+
+msgid "Value"
+msgstr ""
+
+msgid "Description"
+msgstr ""
+
+msgid "Goto:"
+msgstr ""
+
+msgid "Global settings"
+msgstr ""
+
+msgid "Akismet spam filter"
+msgstr ""
+
+#, php-format
+msgid "Filtered by %s."
+msgstr ""
+
+msgid "Filter configuration have been successfully saved."
+msgstr ""
+
+msgid "Akismet API key:"
+msgstr ""
+
+msgid "API key verified"
+msgstr ""
+
+msgid "API key not verified"
+msgstr ""
+
+msgid "Get your own API key"
+msgstr ""
+
+msgid "Antispam"
+msgstr ""
+
+#, php-format
+msgid "All spam comments older than %s day(s) will be automatically deleted."
+msgstr ""
+
+#, php-format
+msgid "You can modify this duration in the %s"
+msgstr ""
+
+msgid "Delete junk comments older than"
+msgstr ""
+
+msgid "days"
+msgstr ""
+
+msgid "Set spam filters."
+msgstr ""
+
+msgid "IP Blacklist / Whitelist Filter"
+msgstr ""
+
+#, php-format
+msgid "Filtered by %1$s with rule %2$s."
+msgstr ""
+
+msgid "IP address has been successfully added."
+msgstr ""
+
+msgid "IP addresses have been successfully removed."
+msgstr ""
+
+msgid "Blacklist"
+msgstr ""
+
+msgid "Whitelist"
+msgstr ""
+
+msgid "Add an IP address: "
+msgstr ""
+
+msgid "Global IP (used for all blogs)"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "No IP address in list."
+msgstr ""
+
+msgid "IP list"
+msgstr ""
+
+msgid "Local IPs (used only for this blog)"
+msgstr ""
+
+msgid "Global IPs (used for all blogs)"
+msgstr ""
+
+msgid "Checks sender IP address against DNSBL servers"
+msgstr ""
+
+#, php-format
+msgid "Filtered by %1$s with server %2$s."
+msgstr ""
+
+msgid "The list of DNSBL servers has been succesfully updated."
+msgstr ""
+
+msgid "IP Lookup servers"
+msgstr ""
+
+msgid "Add here a coma separated list of servers."
+msgstr ""
+
+msgid "Checks links in comments against surbl.org"
+msgstr ""
+
+msgid "Words Blacklist"
+msgstr ""
+
+#, php-format
+msgid "Filtered by %1$s with word %2$s."
+msgstr ""
+
+msgid "Words have been successfully added."
+msgstr ""
+
+msgid "Word has been successfully added."
+msgstr ""
+
+msgid "Words have been successfully removed."
+msgstr ""
+
+msgid "Add a word "
+msgstr ""
+
+msgid "Global word (used for all blogs)"
+msgstr ""
+
+msgid "No word in list."
+msgstr ""
+
+msgid "List of bad words"
+msgstr ""
+
+msgid "Local words (used only for this blog)"
+msgstr ""
+
+msgid "Global words (used for all blogs)"
+msgstr ""
+
+msgid "Delete selected words"
+msgstr ""
+
+msgid "Create default wordlist"
+msgstr ""
+
+msgid "This word exists"
+msgstr ""
+
+msgid "No description"
+msgstr ""
+
+#, php-format
+msgid "Filtered by %1$s (%2$s)"
+msgstr ""
+
+msgid "Unknown filter."
+msgstr ""
+
+msgid "This comment is a spam:"
+msgstr ""
+
+#, php-format
+msgid "(including %d spam comment)"
+msgstr ""
+
+#, php-format
+msgid "(including %d spam comments)"
+msgstr ""
+
+msgid "Spam moderation"
+msgstr ""
+
+msgid "Spam"
+msgstr ""
+
+msgid "Ham"
+msgstr ""
+
+msgid "Filter does not exist."
+msgstr ""
+
+msgid "Filter has no user interface."
+msgstr ""
+
+msgid "Filters configuration has been successfully saved."
+msgstr ""
+
+#, php-format
+msgid "%s configuration"
+msgstr ""
+
+#, php-format
+msgid "%s filter configuration"
+msgstr ""
+
+msgid "Back to filters list"
+msgstr ""
+
+msgid "Information"
+msgstr ""
+
+msgid "Junk comments:"
+msgstr ""
+
+msgid "Published comments:"
+msgstr ""
+
+msgid "Available spam filters"
+msgstr ""
+
+msgid "Order"
+msgstr ""
+
+msgid "Active"
+msgstr ""
+
+msgid "Auto Del."
+msgstr ""
+
+msgid "Filter name"
+msgstr ""
+
+msgid "Filter configuration"
+msgstr ""
+
+msgid "position"
+msgstr ""
+
+msgid "Syndication"
+msgstr ""
+
+msgid "Junk comments RSS feed"
+msgstr ""
+
+msgid "Published comments RSS feed"
+msgstr ""
+
+msgid "Attachments"
+msgstr ""
+
+#, php-format
+msgid "Attachments (%d)"
+msgstr ""
+
+msgid "remove"
+msgstr ""
+
+msgid "No attachment."
+msgstr ""
+
+msgid "Add files to this entry"
+msgstr ""
+
+msgid "Blogroll"
+msgstr ""
+
+msgid "manage blogroll"
+msgstr ""
+
+msgid "Links"
+msgstr ""
+
+msgid "Title (optional)"
+msgstr ""
+
+msgid "All categories"
+msgstr ""
+
+msgid "Display on:"
+msgstr ""
+
+msgid "All pages"
+msgstr ""
+
+msgid "Home page only"
+msgstr ""
+
+msgid "Except on home page"
+msgstr ""
+
+msgid "Content only"
+msgstr ""
+
+msgid "CSS class:"
+msgstr ""
+
+msgid "Offline"
+msgstr ""
+
+msgid "You must provide a link title"
+msgstr ""
+
+msgid "You must provide a link URL"
+msgstr ""
+
+msgid "You need to provide a XBEL or OPML file."
+msgstr ""
+
+msgid "File is not in XML format."
+msgstr ""
+
+msgid "No such link or title"
+msgstr ""
+
+msgid "Link has been successfully updated"
+msgstr ""
+
+msgid "Category has been successfully updated"
+msgstr ""
+
+msgid "Return to blogroll"
+msgstr ""
+
+msgid "Edit category"
+msgstr ""
+
+msgid "Edit link"
+msgstr ""
+
+msgid "XFN information"
+msgstr ""
+
+msgid "_xfn_Me"
+msgstr "Me"
+
+msgid "_xfn_Another link for myself"
+msgstr "Another link for myself"
+
+msgid "_xfn_Friendship"
+msgstr "Friendship"
+
+msgid "_xfn_Contact"
+msgstr "Contact"
+
+msgid "_xfn_Acquaintance"
+msgstr "Acquaintance"
+
+msgid "_xfn_Friend"
+msgstr "Friend"
+
+msgid "_xfn_Physical"
+msgstr "Physical"
+
+msgid "_xfn_Met"
+msgstr "Met"
+
+msgid "_xfn_Professional"
+msgstr "Professional"
+
+msgid "_xfn_Co-worker"
+msgstr "Co-worker"
+
+msgid "_xfn_Colleague"
+msgstr "Colleague"
+
+msgid "_xfn_Geographical"
+msgstr "Geographical"
+
+msgid "_xfn_Co-resident"
+msgstr "Co-resident"
+
+msgid "_xfn_Neighbor"
+msgstr "Neighbor"
+
+msgid "_xfn_Family"
+msgstr "Family"
+
+msgid "_xfn_Child"
+msgstr "Child"
+
+msgid "_xfn_Parent"
+msgstr "Parent"
+
+msgid "_xfn_Sibling"
+msgstr "Sibling"
+
+msgid "_xfn_Spouse"
+msgstr "Spouse"
+
+msgid "_xfn_Kin"
+msgstr "Kin"
+
+msgid "_xfn_Romantic"
+msgstr "Romantic"
+
+msgid "_xfn_Muse"
+msgstr "Muse"
+
+msgid "_xfn_Crush"
+msgstr "Crush"
+
+msgid "_xfn_Date"
+msgstr "Date"
+
+msgid "_xfn_Sweetheart"
+msgstr "Sweetheart"
+
+msgid "Nothing to import"
+msgstr ""
+
+msgid "links have been successfully imported."
+msgstr ""
+
+msgid "Import operation cancelled."
+msgstr ""
+
+msgid "Link has been successfully created."
+msgstr ""
+
+msgid "category has been successfully created."
+msgstr ""
+
+msgid "Items have been successfully removed."
+msgstr ""
+
+msgid "Items order has been successfully updated"
+msgstr ""
+
+msgid "Lang"
+msgstr ""
+
+msgid "select this link"
+msgstr ""
+
+msgid "Delete selected links"
+msgstr ""
+
+msgid "Are you sure you want to delete selected links?"
+msgstr ""
+
+msgid "The link list is empty."
+msgstr ""
+
+msgid "Add a new link"
+msgstr ""
+
+msgid "Add a category"
+msgstr ""
+
+msgid "Import links"
+msgstr ""
+
+msgid "OPML or XBEL File:"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid "Light linear gradient"
+msgstr ""
+
+msgid "Medium linear gradient"
+msgstr ""
+
+msgid "Dark linear gradient"
+msgstr ""
+
+msgid "Solid color"
+msgstr ""
+
+msgid "Custom..."
+msgstr ""
+
+msgid "Theme configuration has been successfully updated."
+msgstr ""
+
+msgid "Blowup configuration"
+msgstr ""
+
+msgid "Predefined styles"
+msgstr ""
+
+msgid "Apply code"
+msgstr ""
+
+msgid "Choose a predefined style"
+msgstr ""
+
+msgid "Back to Blog appearance"
+msgstr ""
+
+msgid "For the following reasons, images cannot be created. You won't be able to change some background properties."
+msgstr ""
+
+msgid "Customization"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "Background color:"
+msgstr ""
+
+msgid "Background color fill:"
+msgstr ""
+
+msgid "Main text font:"
+msgstr ""
+
+msgid "Main text font size:"
+msgstr ""
+
+msgid "Main text color:"
+msgstr ""
+
+msgid "Text line height:"
+msgstr ""
+
+msgid "Links color:"
+msgstr ""
+
+msgid "Visited links color:"
+msgstr ""
+
+msgid "Focus links color:"
+msgstr ""
+
+msgid "Prelude color:"
+msgstr ""
+
+msgid "Hide main title"
+msgstr ""
+
+msgid "Main title font:"
+msgstr ""
+
+msgid "Main title font size:"
+msgstr ""
+
+msgid "Main title color:"
+msgstr ""
+
+msgid "Main title alignment:"
+msgstr ""
+
+msgid "center"
+msgstr ""
+
+msgid "left"
+msgstr ""
+
+msgid "right"
+msgstr ""
+
+msgid "Main title position (x:y)"
+msgstr ""
+
+msgid "Top image"
+msgstr ""
+
+msgid "Choose \"Custom...\" to upload your own image."
+msgstr ""
+
+msgid "Add your image:"
+msgstr ""
+
+#, php-format
+msgid "JPEG or PNG file, 800 pixels wide, maximum size %s"
+msgstr ""
+
+msgid "Sidebar"
+msgstr ""
+
+msgid "Sidebar position:"
+msgstr ""
+
+msgid "Sidebar text font:"
+msgstr ""
+
+msgid "Sidebar text font size:"
+msgstr ""
+
+msgid "Sidebar text color:"
+msgstr ""
+
+msgid "Sidebar titles font:"
+msgstr ""
+
+msgid "Sidebar titles font size:"
+msgstr ""
+
+msgid "Sidebar titles color:"
+msgstr ""
+
+msgid "Sidebar 2nd level titles font:"
+msgstr ""
+
+msgid "Sidebar 2nd level titles font size:"
+msgstr ""
+
+msgid "Sidebar 2nd level titles color:"
+msgstr ""
+
+msgid "Sidebar lines color:"
+msgstr ""
+
+msgid "Sidebar links color:"
+msgstr ""
+
+msgid "Sidebar visited links color:"
+msgstr ""
+
+msgid "Sidebar focus links color:"
+msgstr ""
+
+msgid "Date title font:"
+msgstr ""
+
+msgid "Date title font size:"
+msgstr ""
+
+msgid "Date title color:"
+msgstr ""
+
+msgid "Entry title font:"
+msgstr ""
+
+msgid "Entry title font size:"
+msgstr ""
+
+msgid "Entry title color:"
+msgstr ""
+
+msgid "Comment background color:"
+msgstr ""
+
+msgid "Comment text color:"
+msgstr ""
+
+msgid "My comment background color:"
+msgstr ""
+
+msgid "My comment text color:"
+msgstr ""
+
+msgid "Footer"
+msgstr ""
+
+msgid "Footer font:"
+msgstr ""
+
+msgid "Footer font size:"
+msgstr ""
+
+msgid "Footer color:"
+msgstr ""
+
+msgid "Footer links color:"
+msgstr ""
+
+msgid "Footer background color:"
+msgstr ""
+
+msgid "Additional CSS"
+msgstr ""
+
+msgid "Any additional CSS styles (must be written using the CSS syntax):"
+msgstr ""
+
+msgid "Configuration import / export"
+msgstr ""
+
+msgid "You can share your configuration using the following code. To apply a configuration, paste the code, click on \"Apply code\" and save."
+msgstr ""
+
+msgid "Copy this code:"
+msgstr ""
+
+msgid "default"
+msgstr ""
+
+msgid "Unable to create css file."
+msgstr ""
+
+msgid "Unable to open image."
+msgstr ""
+
+msgid "Breadcrumb"
+msgstr ""
+
+msgid "Enable breadcrumb for this blog"
+msgstr ""
+
+msgid "The {{tpl:Breadcrumb [separator=\" &amp;rsaquo; \"]}} tag should be present (or inserted if not) in the template."
+msgstr ""
+
+msgid "Do not encapsulate breadcrumb in a &lt;p id=\"breadcrumb\"&gt;...&lt;/p&gt; tag."
+msgstr ""
+
+msgid "Home"
+msgstr "Haaptsäit"
+
+#, php-format
+msgid "page %d"
+msgstr ""
+
+msgid "Archives"
+msgstr "Archive"
+
+msgid "All tags"
+msgstr ""
+
+msgid "404"
+msgstr ""
+
+msgid "The configuration has been updated."
+msgstr ""
+
+msgid "Media chooser"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "Link to an entry"
+msgstr ""
+
+msgid "Link"
+msgstr ""
+
+msgid "l"
+msgstr ""
+
+msgid "External image"
+msgstr ""
+
+msgid "URL field cannot be empty."
+msgstr ""
+
+msgid "visual"
+msgstr ""
+
+msgid "source"
+msgstr ""
+
+msgid "You can use the following shortcuts to format your text."
+msgstr ""
+
+msgid "-- none --"
+msgstr ""
+
+msgid "-- block format --"
+msgstr ""
+
+msgid "Paragraph"
+msgstr ""
+
+msgid "Level 1 header"
+msgstr ""
+
+msgid "Level 2 header"
+msgstr ""
+
+msgid "Level 3 header"
+msgstr ""
+
+msgid "Level 4 header"
+msgstr ""
+
+msgid "Level 5 header"
+msgstr ""
+
+msgid "Level 6 header"
+msgstr ""
+
+msgid "Strong emphasis"
+msgstr ""
+
+msgid "Emphasis"
+msgstr ""
+
+msgid "Inserted"
+msgstr ""
+
+msgid "Deleted"
+msgstr ""
+
+msgid "Inline quote"
+msgstr ""
+
+msgid "Code"
+msgstr ""
+
+msgid "Line break"
+msgstr ""
+
+msgid "Blockquote"
+msgstr ""
+
+msgid "Preformated text"
+msgstr ""
+
+msgid "Unordered list"
+msgstr ""
+
+msgid "Ordered list"
+msgstr ""
+
+msgid "URL?"
+msgstr ""
+
+msgid "Language?"
+msgstr ""
+
+msgid "Remove text formating"
+msgstr ""
+
+msgid "Checks trackback source for a link to the post"
+msgstr ""
+
+msgid "Import/Export"
+msgstr ""
+
+msgid "Flat file export"
+msgstr ""
+
+msgid "Exports a blog or a full Dotclear installation to flat file."
+msgstr ""
+
+msgid "Export file not found."
+msgstr ""
+
+msgid "Failed to compress export file."
+msgstr ""
+
+msgid "Single blog"
+msgstr ""
+
+#, php-format
+msgid "This will create an export of your current blog: %s"
+msgstr ""
+
+msgid "Compress file"
+msgstr ""
+
+msgid "You may also want to download your media directory as a zip file"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Multiple blogs"
+msgstr ""
+
+msgid "This will create an export of all the content of your database."
+msgstr ""
+
+msgid "Congratulation!"
+msgstr ""
+
+msgid "Your blog has been successfully imported. Welcome on Dotclear 2!"
+msgstr ""
+
+msgid "Why don't you blog this now?"
+msgstr ""
+
+msgid "visit your dashboard"
+msgstr ""
+
+msgid "Dotclear 1.2 import"
+msgstr ""
+
+msgid "Import a Dotclear 1.2 installation into your current blog."
+msgstr ""
+
+#, php-format
+msgid "Import the content of a Dotclear 1.2's blog in the current blog: %s."
+msgstr ""
+
+msgid "Please note that this process will empty your categories, blogroll, entries and comments on the current blog."
+msgstr ""
+
+msgid "General information"
+msgstr ""
+
+msgid "Import my blog now"
+msgstr ""
+
+msgid "We first need some information about your old Dotclear 1.2 installation."
+msgstr ""
+
+msgid "Entries import options"
+msgstr ""
+
+msgid "Number of entries to import at once:"
+msgstr ""
+
+msgid "Importing users"
+msgstr ""
+
+msgid "Importing categories"
+msgstr ""
+
+msgid "Importing blogroll"
+msgstr ""
+
+#, php-format
+msgid "Importing entries from %d to %d / %d"
+msgstr ""
+
+msgid "Please read carefully"
+msgstr ""
+
+msgid "Every newly imported user has received a random password and will need to ask for a new one by following the \"I forgot my password\" link on the login page (Their registered email address has to be valid.)"
+msgstr ""
+
+#, php-format
+msgid "Please note that Dotclear 2 has a new URL layout. You can avoid broken links by installing <a href=\"%s\">DC1 redirect</a> plugin and activate it in your blog configuration."
+msgstr ""
+
+msgid "next step"
+msgstr ""
+
+msgid "Depending on the size of your blog, it could take a few minutes."
+msgstr ""
+
+msgid "Dotclear tables not found"
+msgstr ""
+
+msgid "RSS or Atom feed import"
+msgstr ""
+
+msgid "Add a feed content to the blog."
+msgstr ""
+
+msgid "Cannot retrieve feed URL."
+msgstr ""
+
+msgid "No items in feed."
+msgstr ""
+
+msgid "Content successfully imported."
+msgstr ""
+
+#, php-format
+msgid "Add a feed content to the current blog: <strong>%s</strong>."
+msgstr ""
+
+msgid "Feed URL:"
+msgstr ""
+
+msgid "Flat file import"
+msgstr ""
+
+msgid "Imports a blog or a full Dotclear installation from flat file."
+msgstr ""
+
+msgid "Single blog successfully imported."
+msgstr ""
+
+msgid "Are you sure you want to import a full backup file?"
+msgstr ""
+
+#, php-format
+msgid "This will import a single blog backup as new content in the current blog: <strong>%s</strong>."
+msgstr ""
+
+msgid "Upload a backup file"
+msgstr ""
+
+#, php-format
+msgid "maximum size %s"
+msgstr ""
+
+msgid "or pick up a local file in your public directory"
+msgstr ""
+
+msgid "This will reset all the content of your database, except users."
+msgstr ""
+
+msgid "Another file with same name exists."
+msgstr ""
+
+msgid "Failed to extract backup file."
+msgstr ""
+
+msgid "No backup in compressed file."
+msgstr ""
+
+msgid "WordPress import"
+msgstr ""
+
+msgid "Import a WordPress installation into your current blog."
+msgstr ""
+
+#, php-format
+msgid "This will import your WordPress content as new content in the current blog: %s."
+msgstr ""
+
+msgid "We first need some information about your old WordPress installation."
+msgstr ""
+
+msgid "WordPress and Dotclear's handling of categories are quite different. You can assign several categories to a single post in WordPress. In the Dotclear world, we see it more like \"One category, several tags.\" Therefore Dotclear can only import one category per post and will chose the lowest numbered one. If you want to keep a trace of every category, you can import them as tags, with an optional prefix."
+msgstr ""
+
+msgid "On the other hand, in WordPress, a post can not be uncategorized, and a default installation has a first category labelised <i>\"Uncategorized\"</i>.If you did not change that category, you can just ignore it while importing your blog, as Dotclear allows you to actually keep your posts uncategorized."
+msgstr ""
+
+msgid "Ignore the first category:"
+msgstr ""
+
+msgid "Import lowest numbered category on posts:"
+msgstr ""
+
+msgid "Import all categories as tags:"
+msgstr ""
+
+msgid "Prefix such tags with:"
+msgstr ""
+
+msgid "Content filters"
+msgstr ""
+
+msgid "You may want to process your post and/or comment content with the following filters."
+msgstr ""
+
+msgid "Post content formatter:"
+msgstr ""
+
+msgid "Comment content formatter:"
+msgstr ""
+
+msgid "WordPress tables not found"
+msgstr ""
+
+msgid "No file to read."
+msgstr ""
+
+msgid "File is not a DotClear backup."
+msgstr ""
+
+msgid "File is not a single blog export."
+msgstr ""
+
+#, php-format
+msgid "Error raised at line %s"
+msgstr ""
+
+msgid "File is not a full export."
+msgstr ""
+
+#, php-format
+msgid "ID of \"%3$s\" does not match on record \"%1$s\" at line %2$s of backup file."
+msgstr ""
+
+msgid "Database export"
+msgstr ""
+
+msgid "Download database of current blog"
+msgstr ""
+
+msgid "Download database of all blogs"
+msgstr ""
+
+msgid "Please wait..."
+msgstr ""
+
+#, php-format
+msgid "Export functions are in the page %s."
+msgstr ""
+
+msgid "Maintenance"
+msgstr ""
+
+msgid "Servicing"
+msgstr ""
+
+msgid "Tools to maintain the performance of your blogs."
+msgstr ""
+
+msgid "Backup"
+msgstr ""
+
+msgid "Tools to back up your content."
+msgstr ""
+
+msgid "Development"
+msgstr ""
+
+msgid "Tools to assist in development of plugins, themes and core."
+msgstr ""
+
+msgid "Optimize"
+msgstr ""
+
+msgid "Count and index"
+msgstr ""
+
+msgid "Purge"
+msgstr ""
+
+msgid "Other"
+msgstr ""
+
+msgid "Current blog"
+msgstr ""
+
+msgid "All blogs"
+msgstr ""
+
+msgid "Maintain translations"
+msgstr ""
+
+msgid "Translations"
+msgstr ""
+
+#, php-format
+msgid "One task to execute"
+msgid_plural "%s tasks to execute"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "This task has never been executed."
+msgstr ""
+
+#, php-format
+msgid "Last execution of this task was on %s."
+msgstr ""
+
+#, php-format
+msgid "There is a task to execute."
+msgid_plural "There are %s tasks to execute."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Manage tasks"
+msgstr ""
+
+msgid "Display overdue tasks counter on maintenance dashboard icon"
+msgstr ""
+
+msgid "Display overdue tasks list on dashboard items"
+msgstr ""
+
+msgid "Failed to execute task."
+msgstr ""
+
+msgid "Task successfully executed."
+msgstr ""
+
+msgid "Empty templates cache directory"
+msgstr ""
+
+msgid "Templates cache directory emptied."
+msgstr ""
+
+msgid "Failed to empty templates cache directory."
+msgstr ""
+
+msgid "It may be useful to empty this cache when modifying a theme's .html or .css files (or when updating a theme or plugin). Notice : with some hosters, the templates cache cannot be emptied with this plugin. You may then have to delete the directory <strong>/cbtpl/</strong> directly on the server with your FTP software."
+msgstr ""
+
+msgid "Count again comments and trackbacks"
+msgstr ""
+
+msgid "Comments and trackback counted."
+msgstr ""
+
+msgid "Failed to count comments and trackbacks."
+msgstr ""
+
+msgid "Count again comments and trackbacks allows to check their exact numbers. This operation can be useful when importing from another blog platform (or when migrating from dotclear 1 to dotclear 2)."
+msgstr ""
+
+msgid "Delete the Content-Security-Policy report file"
+msgstr ""
+
+msgid "Content-Security-Policy report file has been deleted."
+msgstr ""
+
+msgid "Failed to delete the Content-Security-Policy report file."
+msgstr ""
+
+msgid "Remove the Content-Security-Policy report file."
+msgstr ""
+
+msgid "Search engine index"
+msgstr ""
+
+msgid "Index all comments for search engine"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+#, php-format
+msgid "Indexing comment %d to %d."
+msgstr ""
+
+msgid "Comments index done."
+msgstr ""
+
+msgid "Failed to index comments."
+msgstr ""
+
+msgid "Index all comments and trackbacks in search engine index. This operation is necessary, after importing content in your blog, to use internal search engine, on public and private pages."
+msgstr ""
+
+msgid "Index all entries for search engine"
+msgstr ""
+
+#, php-format
+msgid "Indexing entry %d to %d."
+msgstr ""
+
+msgid "Entries index done."
+msgstr ""
+
+msgid "Failed to index entries."
+msgstr ""
+
+msgid "Index all entries in search engine index. This operation is necessary, after importing content in your blog, to use internal search engine, on public and private pages."
+msgstr ""
+
+msgid "Delete all logs"
+msgstr ""
+
+msgid "Logs deleted."
+msgstr ""
+
+msgid "Failed to delete logs."
+msgstr ""
+
+msgid "Logs record all activity and connection to your blog history. Unless you need to keep this history, consider deleting these logs from time to time."
+msgstr ""
+
+msgid "Entries metadata"
+msgstr ""
+
+msgid "Synchronize entries metadata"
+msgstr ""
+
+#, php-format
+msgid "Synchronize entry %d to %d."
+msgstr ""
+
+msgid "Entries metadata synchronize done."
+msgstr ""
+
+msgid "Failed to synchronize entries metadata."
+msgstr ""
+
+msgid "Synchronize all entries metadata could be useful after importing content in your blog or do bad operation on database tables."
+msgstr ""
+
+msgid "Optimise database"
+msgstr ""
+
+msgid "optimize tables"
+msgstr ""
+
+msgid "Optimization successful."
+msgstr ""
+
+msgid "Failed to optimize tables."
+msgstr ""
+
+msgid "After numerous delete or update operations on Dotclear's database, it gets fragmented. Optimizing will allow to defragment it. It has no incidence on your data's integrity. It is recommended to optimize before any blog export."
+msgstr ""
+
+msgid "Download media folder of current blog"
+msgstr ""
+
+msgid "It may be useful to backup your media folder. This compress all content of media folder into a single zip file. Notice : with some hosters, the media folder cannot be compressed with this plugin if it is too big."
+msgstr ""
+
+msgid "Download active theme of current blog"
+msgstr ""
+
+msgid "It may be useful to backup the active theme before any change or update. This compress theme folder into a single zip file."
+msgstr ""
+
+msgid "Maintenance plugin has been successfully configured."
+msgstr ""
+
+msgid "Never"
+msgstr ""
+
+msgid "Every week"
+msgstr ""
+
+msgid "Every two weeks"
+msgstr ""
+
+msgid "Every month"
+msgstr ""
+
+msgid "Every two months"
+msgstr ""
+
+msgid "You have not sufficient permissions to view this page."
+msgstr ""
+
+msgid "You should execute it now."
+msgstr ""
+
+msgid "Execute task"
+msgstr ""
+
+msgid "This may take a very long time."
+msgstr ""
+
+msgid "Alert settings"
+msgstr ""
+
+msgid "Activation"
+msgstr ""
+
+msgid "Display alert messages on late tasks"
+msgstr ""
+
+#, php-format
+msgid "You can place list of late tasks on your %s."
+msgstr ""
+
+msgid "Frequency"
+msgstr ""
+
+msgid "Use one recall time for all tasks"
+msgstr ""
+
+msgid "Recall time for all tasks:"
+msgstr ""
+
+msgid "Use one recall time per task"
+msgstr ""
+
+msgid "New page"
+msgstr ""
+
+#, php-format
+msgid "%d page"
+msgstr ""
+
+#, php-format
+msgid "%d pages"
+msgstr ""
+
+msgid "manage pages"
+msgstr ""
+
+msgid "My first page"
+msgstr ""
+
+msgid "This is your first page. When you're ready to blog, log in to edit or delete it."
+msgstr ""
+
+msgid "Published on"
+msgstr ""
+
+msgid "This page's comments feed"
+msgstr ""
+
+msgid "You must provide a valid email address."
+msgstr ""
+
+msgid "Page title"
+msgstr ""
+
+msgid "Page position"
+msgstr ""
+
+msgid "Publication date"
+msgstr ""
+
+msgid "Pages actions"
+msgstr ""
+
+msgid "Back to pages list"
+msgstr ""
+
+msgid "Selected pages have been successfully reordered."
+msgstr ""
+
+msgid "No page"
+msgstr ""
+
+msgid "Hidden"
+msgstr ""
+
+msgid "Select this page"
+msgstr ""
+
+msgid "Are you sure you want to delete selected pages?"
+msgstr ""
+
+msgid "Selected pages have been successfully updated."
+msgstr ""
+
+msgid "Selected pages have been successfully deleted."
+msgstr ""
+
+msgid "Selected pages action:"
+msgstr ""
+
+msgid "To rearrange pages order, change number at the begining of the line, then click on “Save pages order” button."
+msgstr ""
+
+msgid "To rearrange pages order, move items by drag and drop, then click on “Save pages order” button."
+msgstr ""
+
+msgid "Save pages order"
+msgstr ""
+
+msgid "This page does not exist."
+msgstr ""
+
+msgid "Edit page"
+msgstr ""
+
+msgid "Are you sure you want to delete this page?"
+msgstr ""
+
+msgid "Page has been successfully updated."
+msgstr ""
+
+msgid "Page has been successfully created."
+msgstr ""
+
+msgid "Go to this page on the site"
+msgstr ""
+
+msgid "Page status"
+msgstr ""
+
+msgid "Page language"
+msgstr ""
+
+msgid "Hide in widget Pages"
+msgstr ""
+
+msgid "Warning: If you set the URL manually, it may conflict with another page."
+msgstr ""
+
+msgid "Introduction to the page."
+msgstr ""
+
+msgid "Select this comment"
+msgstr ""
+
+msgid "Pings"
+msgstr ""
+
+msgid "Settings have been successfully updated."
+msgstr ""
+
+msgid "Pings configuration"
+msgstr ""
+
+msgid "Activate pings extension"
+msgstr ""
+
+msgid "Service name:"
+msgstr ""
+
+msgid "Service URI:"
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Test ping services"
+msgstr ""
+
+msgid "Check all"
+msgstr ""
+
+msgid "Simple menu"
+msgstr ""
+
+msgid "Item description"
+msgstr ""
+
+msgid "Displayed in link"
+msgstr ""
+
+msgid "Used as link title"
+msgstr ""
+
+msgid "Displayed in link and used as title"
+msgstr ""
+
+msgid "Not displayed nor used"
+msgstr ""
+
+msgid "All months"
+msgstr ""
+
+msgid "Archive"
+msgstr ""
+
+msgid "Page"
+msgstr ""
+
+msgid "Tags"
+msgstr ""
+
+msgid "User defined"
+msgstr ""
+
+msgid "Configuration successfully updated."
+msgstr ""
+
+msgid "Label"
+msgstr ""
+
+msgid "Recent posts"
+msgstr ""
+
+#, php-format
+msgid "Switch to %s language"
+msgstr ""
+
+msgid "Recent Posts from this category"
+msgstr ""
+
+#, php-format
+msgid "Posts from %s"
+msgstr ""
+
+#, php-format
+msgid "Recent posts for %s tag"
+msgstr ""
+
+msgid "Menu item has been successfully added."
+msgstr ""
+
+msgid "Label and URL of menu item are mandatory."
+msgstr ""
+
+msgid "Menu items have been successfully removed."
+msgstr ""
+
+msgid "No menu items selected."
+msgstr ""
+
+msgid "Label is mandatory."
+msgstr ""
+
+msgid "URL is mandatory."
+msgstr ""
+
+msgid "Menu items have been successfully updated."
+msgstr ""
+
+msgid "Step #1"
+msgstr ""
+
+msgid "Step #2"
+msgstr ""
+
+msgid "Step #3"
+msgstr ""
+
+msgid "Add item"
+msgstr ""
+
+msgid "Select type"
+msgstr ""
+
+msgid "Type of item menu:"
+msgstr ""
+
+msgid "Continue..."
+msgstr "Continue…"
+
+msgid "Select language:"
+msgstr ""
+
+msgid "Select category:"
+msgstr ""
+
+msgid "Select month (if necessary):"
+msgstr ""
+
+msgid "Select page:"
+msgstr ""
+
+msgid "Select tag (if necessary):"
+msgstr ""
+
+msgid "Label of item menu:"
+msgstr ""
+
+msgid "Description of item menu:"
+msgstr ""
+
+msgid "URL of item menu:"
+msgstr ""
+
+msgid "Add this item"
+msgstr ""
+
+msgid "Enable simple menu for this blog"
+msgstr ""
+
+msgid "Save configuration"
+msgstr ""
+
+msgid "Add an item"
+msgstr ""
+
+msgid "Menu items list"
+msgstr ""
+
+msgid "Update menu"
+msgstr ""
+
+msgid "Delete selected menu items"
+msgstr ""
+
+msgid "Are you sure you want to remove selected menu items?"
+msgstr ""
+
+msgid "No menu items so far."
+msgstr ""
+
+msgid "This tag's comments Atom feed"
+msgstr ""
+
+msgid "This tag's entries Atom feed"
+msgstr ""
+
+msgid "Tag"
+msgstr ""
+
+msgid "Limit (empty means no limit):"
+msgstr ""
+
+msgid "Entries count"
+msgstr ""
+
+msgid "Tag name"
+msgstr ""
+
+msgid "Link to all tags:"
+msgstr ""
+
+msgid "Add tags"
+msgstr ""
+
+msgid "Remove tags"
+msgstr ""
+
+msgid "Tag has been successfully added to selected entries"
+msgid_plural "Tags have been successfully added to selected entries"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Add tags to this selection"
+msgstr ""
+
+msgid "Are you sure you want to remove this tag?"
+msgstr ""
+
+msgid "Add a tag to this entry"
+msgstr ""
+
+msgid "Choose from list"
+msgstr ""
+
+msgid "all"
+msgstr ""
+
+msgid "Enter tags separated by coma"
+msgstr ""
+
+msgid "used in %e - frequency %p%"
+msgstr ""
+
+msgid "entry"
+msgstr ""
+
+msgid "entries"
+msgstr ""
+
+msgid "Tags to add:"
+msgstr ""
+
+msgid "Tag has been successfully removed from selected entries"
+msgid_plural "Tags have been successfully removed from selected entries"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "No tags for selected entries"
+msgstr ""
+
+msgid "Remove selected tags from this selection"
+msgstr ""
+
+msgid "Following tags have been found in selected entries:"
+msgstr ""
+
+msgid "Short"
+msgstr ""
+
+msgid "Extended"
+msgstr ""
+
+msgid "Tags list format:"
+msgstr ""
+
+msgid "Tag has been successfully renamed"
+msgstr ""
+
+msgid "Tag has been successfully removed"
+msgstr ""
+
+#, php-format
+msgid "Are you sure you want to remove tag: “%s”?"
+msgstr ""
+
+msgid "Back to tags list"
+msgstr ""
+
+msgid "Rename"
+msgstr ""
+
+msgid "Delete this tag"
+msgstr ""
+
+#, php-format
+msgid "List of entries with the tag “%s”"
+msgstr ""
+
+msgid "No tags on this blog."
+msgstr ""
+
+msgid "Edit theme files"
+msgstr ""
+
+msgid "Syntax highlighting"
+msgstr ""
+
+msgid "Syntax highlighting in theme editor"
+msgstr ""
+
+msgid "Theme:"
+msgstr ""
+
+msgid "No file"
+msgstr ""
+
+msgid "From theme:"
+msgstr ""
+
+msgid "From parent:"
+msgstr ""
+
+msgid "From template set:"
+msgstr ""
+
+msgid "File does not exist."
+msgstr ""
+
+#, php-format
+msgid "File %s is not readable"
+msgstr ""
+
+#, php-format
+msgid "Unable to write file %s. Please check your theme files and folders permissions."
+msgstr ""
+
+#, php-format
+msgid "Unable to delete file %s. Please check your theme files and folders permissions."
+msgstr ""
+
+msgid "The file has been reset."
+msgstr ""
+
+msgid "Saving document..."
+msgstr ""
+
+msgid "Document saved"
+msgstr ""
+
+msgid "An error occurred:"
+msgstr ""
+
+msgid "Are you sure you want to reset this file?"
+msgstr ""
+
+#, php-format
+msgid "Your current theme on this blog is \"%s\"."
+msgstr ""
+
+msgid "You can't edit default theme."
+msgstr ""
+
+msgid "Please select a file to edit."
+msgstr ""
+
+msgid "File editor"
+msgstr ""
+
+#, php-format
+msgid "Editing file %s"
+msgstr ""
+
+msgid "Reset"
+msgstr ""
+
+msgid "This file is not writable. Please check your theme files permissions."
+msgstr ""
+
+msgid "Templates files"
+msgstr ""
+
+msgid "CSS files"
+msgstr ""
+
+msgid "JavaScript files"
+msgstr ""
+
+msgid "Locales files"
+msgstr ""
+
+msgid "Preferences successfully updated"
+msgstr ""
+
+msgid "user:preferences"
+msgstr ""
+
+msgid "User preferences"
+msgstr ""
+
+msgid "Global preferences"
+msgstr ""
+
+msgid "Presentation widgets"
+msgstr ""
+
+msgid "Widget's textareas"
+msgstr ""
+
+msgid "Search engine"
+msgstr ""
+
+msgid "Placeholder (HTML5 only, optional):"
+msgstr ""
+
+msgid "Navigation links"
+msgstr ""
+
+msgid "Selected entries"
+msgstr ""
+
+msgid "Best of me"
+msgstr "Wichteg Bäiträg"
+
+msgid "Blog languages"
+msgstr ""
+
+msgid "With entries counts"
+msgstr ""
+
+msgid "Include sub cats in count"
+msgstr ""
+
+msgid "Include empty categories"
+msgstr ""
+
+msgid "Subscribe links"
+msgstr ""
+
+msgid "Subscribe"
+msgstr "Sech Abonnéieren"
+
+msgid "Feeds type:"
+msgstr ""
+
+msgid "Feed reader"
+msgstr ""
+
+msgid "Somewhere else"
+msgstr ""
+
+msgid "Entries limit:"
+msgstr ""
+
+msgid "Text"
+msgstr ""
+
+msgid "Text:"
+msgstr ""
+
+msgid "Last entries"
+msgstr "Lëscht Artikelen"
+
+msgid "Uncategorized"
+msgstr ""
+
+msgid "Tag:"
+msgstr ""
+
+msgid "Last comments"
+msgstr "Lëscht Commentairen"
+
+msgid "Comments limit:"
+msgstr ""
+
+#, php-format
+msgid "This blog's entries %s feed"
+msgstr ""
+
+#, php-format
+msgid "This blog's comments %s feed"
+msgstr ""
+
+msgid "Entries feed"
+msgstr "Bäiträg Feed"
+
+msgid "Comments feed"
+msgstr "Commentairen Feed"
+
+msgid "navigation"
+msgstr ""
+
+msgid "extra"
+msgstr ""
+
+msgid "custom"
+msgstr ""
+
+msgid "empty string"
+msgstr ""
+
+msgid "Sidebars and their widgets have been saved."
+msgstr ""
+
+msgid "Sidebars have been resetting."
+msgstr ""
+
+msgid "Widgets"
+msgstr ""
+
+msgid "Are you sure you want to reset sidebars?"
+msgstr ""
+
+msgid "Available widgets"
+msgstr ""
+
+msgid "Drag widgets from this list to one of the sidebars, for add."
+msgstr ""
+
+msgid "order"
+msgstr ""
+
+msgid "Append to:"
+msgstr ""
+
+msgid "Add widgets to sidebars"
+msgstr ""
+
+msgid "Navigation sidebar"
+msgstr ""
+
+msgid "Extra sidebar"
+msgstr ""
+
+msgid "Custom sidebar"
+msgstr ""
+
+msgid "Update sidebars"
+msgstr ""
+
+msgid "Reset sidebars"
+msgstr ""
+
+msgid "Widget ID:"
+msgstr ""
+
+msgid "No setting for this widget"
+msgstr ""
+
+msgid "boolean"
+msgstr ""
+
+msgid "possible values:"
+msgstr ""
+
+msgid "listitem"
+msgstr ""
+
+msgid "string"
+msgstr ""
+
+msgid "Setting name:"
+msgstr ""
+
+msgid "No widget as far."
+msgstr ""
+
+msgid "Up the widget"
+msgstr ""
+
+msgid "Down the widget"
+msgstr ""
+
+msgid "Remove the widget"
+msgstr ""
+
+msgid "Remove widget"
+msgstr ""
+
+msgid "Drag widgets here to remove."
+msgstr ""
Index: plugins/aboutConfig/_define.php
===================================================================
--- plugins/aboutConfig/_define.php	(revision 3731)
+++ plugins/aboutConfig/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "Olivier Meunier",                           // Author
     '0.5',                                       // Version
-    array(
+    [
         'type' => 'plugin'
-    )
+    ]
 
 );
Index: plugins/aboutConfig/index.php
===================================================================
--- plugins/aboutConfig/index.php	(revision 3731)
+++ plugins/aboutConfig/index.php	(revision 3874)
@@ -71,16 +71,16 @@
 {
     if ($s['type'] == 'boolean') {
-        $field = form::combo(array($field_name . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id),
-            array(__('yes') => 1, __('no') => 0), $s['value'] ? 1 : 0);
+        $field = form::combo([$field_name . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id],
+            [__('yes') => 1, __('no') => 0], $s['value'] ? 1 : 0);
     } else {
         if ($s['type'] == 'array') {
-            $field = form::field(array($field_name . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id), 40, null,
+            $field = form::field([$field_name . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id], 40, null,
                 html::escapeHTML(json_encode($s['value'])));
         } else {
-            $field = form::field(array($field_name . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id), 40, null,
+            $field = form::field([$field_name . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id], 40, null,
                 html::escapeHTML($s['value']));
         }
     }
-    $type = form::hidden(array($field_name . '_type' . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id . '_type'),
+    $type = form::hidden([$field_name . '_type' . '[' . $ns . '][' . $id . ']', $field_name . '_' . $ns . '_' . $id . '_type'],
         html::escapeHTML($s['type']));
 
@@ -105,9 +105,9 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         __('System')                        => '',
         html::escapeHTML($core->blog->name) => '',
         __('about:config')                  => ''
-    )) .
+    ]) .
 dcPage::notices();
 ?>
@@ -123,5 +123,5 @@
 '  <th>' . __('Value') . '</th>' . "\n" .
 '  <th>' . __('Type') . '</th>' . "\n" .
-'  <th class="maximalx">' . __('Description') . '</th>' . "\n" .
+'  <th>' . __('Description') . '</th>' . "\n" .
     '</tr>' . "\n" .
     '</thead>' . "\n" .
@@ -129,5 +129,5 @@
 $table_footer = '</tbody></table></div>';
 
-$settings = array();
+$settings = [];
 foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) {
     foreach ($namespace->dumpSettings() as $k => $v) {
@@ -137,5 +137,5 @@
 ksort($settings);
 if (count($settings) > 0) {
-    $ns_combo = array();
+    $ns_combo = [];
     foreach ($settings as $ns => $s) {
         $ns_combo[$ns] = '#l_' . $ns;
@@ -174,5 +174,5 @@
 
 <?php
-$settings = array();
+$settings = [];
 
 foreach ($core->blog->settings->dumpNamespaces() as $ns => $namespace) {
@@ -185,5 +185,5 @@
 
 if (count($settings) > 0) {
-    $ns_combo = array();
+    $ns_combo = [];
     foreach ($settings as $ns => $s) {
         $ns_combo[$ns] = '#g_' . $ns;
Index: plugins/akismet/_define.php
===================================================================
--- plugins/akismet/_define.php	(revision 3731)
+++ plugins/akismet/_define.php	(revision 3874)
@@ -17,8 +17,8 @@
     "Olivier Meunier",                // Author
     '1.1',                            // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'priority'    => 200,
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/akismet/class.dc.filter.akismet.php
===================================================================
--- plugins/akismet/class.dc.filter.akismet.php	(revision 3731)
+++ plugins/akismet/class.dc.filter.akismet.php	(revision 3874)
@@ -60,5 +60,5 @@
         {
             if ($ak->verify()) {
-                $post = $blog->getPosts(array('post_id' => $post_id));
+                $post = $blog->getPosts(['post_id' => $post_id]);
 
                 $c = $ak->comment_check(
@@ -186,8 +186,8 @@
         $path       = sprintf($this->ak_path, 'verify-key');
 
-        $data = array(
+        $data = [
             'key'  => $this->ak_key,
             'blog' => $this->blog_url
-        );
+        ];
 
         if ($this->post($path, $data, 'UTF-8')) {
@@ -200,6 +200,6 @@
     public function comment_check($permalink, $type, $author, $email, $url, $content)
     {
-        $info_ignore = array('HTTP_COOKIE');
-        $info        = array();
+        $info_ignore = ['HTTP_COOKIE'];
+        $info        = [];
 
         foreach ($_SERVER as $k => $v) {
@@ -224,5 +224,5 @@
     }
 
-    protected function callFunc($function, $permalink, $type, $author, $email, $url, $content, $info = array())
+    protected function callFunc($function, $permalink, $type, $author, $email, $url, $content, $info = [])
     {
         $ua      = isset($info['HTTP_USER_AGENT']) ? $info['HTTP_USER_AGENT'] : '';
@@ -230,5 +230,5 @@
 
         # Prepare comment data
-        $data = array(
+        $data = [
             'blog'                 => $this->blog_url,
             'user_ip'              => http::realIP(),
@@ -241,5 +241,5 @@
             'comment_author_url'   => $url,
             'comment_content'      => $content
-        );
+        ];
 
         $data = array_merge($data, $info);
Index: plugins/antispam/_admin.php
===================================================================
--- plugins/antispam/_admin.php	(revision 3790)
+++ plugins/antispam/_admin.php	(revision 3874)
@@ -22,8 +22,8 @@
     $core->auth->check('admin', $core->blog->id));
 
-$core->addBehavior('coreAfterCommentUpdate', array('dcAntispam', 'trainFilters'));
-$core->addBehavior('adminAfterCommentDesc', array('dcAntispam', 'statusMessage'));
-$core->addBehavior('adminDashboardIcons', array('dcAntispam', 'dashboardIcon'));
-$core->addBehavior('adminDashboardHeaders', array('dcAntispam', 'dashboardHeaders'));
+$core->addBehavior('coreAfterCommentUpdate', ['dcAntispam', 'trainFilters']);
+$core->addBehavior('adminAfterCommentDesc', ['dcAntispam', 'statusMessage']);
+$core->addBehavior('adminDashboardIcons', ['dcAntispam', 'dashboardIcon']);
+$core->addBehavior('adminDashboardHeaders', ['dcAntispam', 'dashboardHeaders']);
 
 $core->addBehavior('adminDashboardFavorites', 'antispamDashboardFavorites');
@@ -32,10 +32,10 @@
 function antispamDashboardFavorites($core, $favs)
 {
-    $favs->register('antispam', array(
+    $favs->register('antispam', [
         'title'       => __('Antispam'),
         'url'         => $core->adminurl->get('admin.plugin.antispam'),
         'small-icon'  => dcPage::getPF('antispam/icon.png'),
         'large-icon'  => dcPage::getPF('antispam/icon-big.png'),
-        'permissions' => 'admin')
+        'permissions' => 'admin']
     );
 }
@@ -54,8 +54,8 @@
 
 if (!DC_ANTISPAM_CONF_SUPER || $core->auth->isSuperAdmin()) {
-    $core->addBehavior('adminBlogPreferencesForm', array('antispamBehaviors', 'adminBlogPreferencesForm'));
-    $core->addBehavior('adminBeforeBlogSettingsUpdate', array('antispamBehaviors', 'adminBeforeBlogSettingsUpdate'));
-    $core->addBehavior('adminCommentsSpamForm', array('antispamBehaviors', 'adminCommentsSpamForm'));
-    $core->addBehavior('adminPageHelpBlock', array('antispamBehaviors', 'adminPageHelpBlock'));
+    $core->addBehavior('adminBlogPreferencesForm', ['antispamBehaviors', 'adminBlogPreferencesForm']);
+    $core->addBehavior('adminBeforeBlogSettingsUpdate', ['antispamBehaviors', 'adminBeforeBlogSettingsUpdate']);
+    $core->addBehavior('adminCommentsSpamForm', ['antispamBehaviors', 'adminCommentsSpamForm']);
+    $core->addBehavior('adminPageHelpBlock', ['antispamBehaviors', 'adminPageHelpBlock']);
 }
 
Index: plugins/antispam/_define.php
===================================================================
--- plugins/antispam/_define.php	(revision 3731)
+++ plugins/antispam/_define.php	(revision 3874)
@@ -17,11 +17,11 @@
     "Alain Vagner",                         // Author
     '1.4.1',                                // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'priority'    => 10,
-        'settings'    => array(
+        'settings'    => [
             'self' => '',
             'blog' => '#params.antispam_params'
-        )
-    )
+        ]
+    ]
 );
Index: plugins/antispam/_prepend.php
===================================================================
--- plugins/antispam/_prepend.php	(revision 3781)
+++ plugins/antispam/_prepend.php	(revision 3874)
@@ -22,8 +22,8 @@
 $__autoload['dcFilterWords']       = dirname(__FILE__) . '/filters/class.dc.filter.words.php';
 
-$core->spamfilters = array('dcFilterIP', 'dcFilterIpLookup', 'dcFilterWords', 'dcFilterLinksLookup');
+$core->spamfilters = ['dcFilterIP', 'dcFilterIpLookup', 'dcFilterWords', 'dcFilterLinksLookup'];
 
-$core->url->register('spamfeed', 'spamfeed', '^spamfeed/(.+)$', array('dcAntispamURL', 'spamFeed'));
-$core->url->register('hamfeed', 'hamfeed', '^hamfeed/(.+)$', array('dcAntispamURL', 'hamFeed'));
+$core->url->register('spamfeed', 'spamfeed', '^spamfeed/(.+)$', ['dcAntispamURL', 'spamFeed']);
+$core->url->register('hamfeed', 'hamfeed', '^hamfeed/(.+)$', ['dcAntispamURL', 'hamFeed']);
 
 if (!defined('DC_CONTEXT_ADMIN')) {return false;}
@@ -34,3 +34,3 @@
 
 // Register REST methods
-$core->rest->addFunction('getSpamsCount', array('dcAntispamRest', 'getSpamsCount'));
+$core->rest->addFunction('getSpamsCount', ['dcAntispamRest', 'getSpamsCount']);
Index: plugins/antispam/_public.php
===================================================================
--- plugins/antispam/_public.php	(revision 3731)
+++ plugins/antispam/_public.php	(revision 3874)
@@ -12,5 +12,5 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('publicBeforeCommentCreate', array('dcAntispam', 'isSpam'));
-$core->addBehavior('publicBeforeTrackbackCreate', array('dcAntispam', 'isSpam'));
-$core->addBehavior('publicBeforeDocument', array('dcAntispam', 'purgeOldSpam'));
+$core->addBehavior('publicBeforeCommentCreate', ['dcAntispam', 'isSpam']);
+$core->addBehavior('publicBeforeTrackbackCreate', ['dcAntispam', 'isSpam']);
+$core->addBehavior('publicBeforeDocument', ['dcAntispam', 'purgeOldSpam']);
Index: plugins/antispam/filters/class.dc.filter.ip.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.ip.php	(revision 3731)
+++ plugins/antispam/filters/class.dc.filter.ip.php	(revision 3874)
@@ -114,9 +114,9 @@
 
         '<p>' .
-        form::hidden(array('ip_type'), $type) .
+        form::hidden(['ip_type'], $type) .
         '<label class="classic" for="addip_' . $type . '">' . __('Add an IP address: ') . '</label> ' .
-        form::field(array('addip', 'addip_' . $type), 18, 255);
+        form::field(['addip', 'addip_' . $type], 18, 255);
         if ($core->auth->isSuperAdmin()) {
-            $res .= '<label class="classic" for="globalip_' . $type . '">' . form::checkbox(array('globalip', 'globalip_' . $type), 1) . ' ' .
+            $res .= '<label class="classic" for="globalip_' . $type . '">' . form::checkbox(['globalip', 'globalip_' . $type], 1) . ' ' .
             __('Global IP (used for all blogs)') . '</label> ';
         }
@@ -155,8 +155,8 @@
                 $item =
                 '<p class="' . $p_style . '"><label class="classic" for="' . $type . '-ip-' . $rs->rule_id . '">' .
-                form::checkbox(array('delip[]', $type . '-ip-' . $rs->rule_id), $rs->rule_id,
-                    array(
+                form::checkbox(['delip[]', $type . '-ip-' . $rs->rule_id], $rs->rule_id,
+                    [
                         'disabled' => $disabled_ip
-                    )
+                    ]
                 ) . ' ' .
                 html::escapeHTML($pattern) .
@@ -183,5 +183,5 @@
             '<p><input class="submit delete" type="submit" value="' . __('Delete') . '"/>' .
             $core->formNonce() .
-            form::hidden(array('ip_type'), $type) .
+            form::hidden(['ip_type'], $type) .
                 '</p>' .
                 '</form>';
Index: plugins/antispam/filters/class.dc.filter.words.php
===================================================================
--- plugins/antispam/filters/class.dc.filter.words.php	(revision 3731)
+++ plugins/antispam/filters/class.dc.filter.words.php	(revision 3874)
@@ -141,8 +141,8 @@
 
                 $item = '<p class="' . $p_style . '"><label class="classic" for="word-' . $rs->rule_id . '">' .
-                form::checkbox(array('swd[]', 'word-' . $rs->rule_id), $rs->rule_id,
-                    array(
+                form::checkbox(['swd[]', 'word-' . $rs->rule_id], $rs->rule_id,
+                    [
                         'disabled' => $disabled_word
-                    )
+                    ]
                 ) . ' ' .
                 html::escapeHTML($rs->rule_content) .
@@ -168,5 +168,5 @@
             $res .=
             '</div>' .
-            '<p>' . form::hidden(array('spamwords'), 1) .
+            '<p>' . form::hidden(['spamwords'], 1) .
             $core->formNonce() .
             '<input class="submit delete" type="submit" value="' . __('Delete selected words') . '"/></p>' .
@@ -178,6 +178,6 @@
             '<form action="' . html::escapeURL($url) . '" method="post">' .
             '<p><input type="submit" value="' . __('Create default wordlist') . '" />' .
-            form::hidden(array('spamwords'), 1) .
-            form::hidden(array('createlist'), 1) .
+            form::hidden(['spamwords'], 1) .
+            form::hidden(['createlist'], 1) .
             $core->formNonce() . '</p>' .
                 '</form>';
@@ -255,5 +255,5 @@
     public function defaultWordsList()
     {
-        $words = array(
+        $words = [
             '/-credit(\s+|$)/',
             '/-digest(\s+|$)/',
@@ -354,5 +354,5 @@
             'xanax',
             'zolus'
-        );
+        ];
 
         foreach ($words as $w) {
Index: plugins/antispam/inc/class.dc.spamfilter.php
===================================================================
--- plugins/antispam/inc/class.dc.spamfilter.php	(revision 3731)
+++ plugins/antispam/inc/class.dc.spamfilter.php	(revision 3874)
@@ -41,5 +41,5 @@
 
         if ($core && isset($core->adminurl)) {
-            $this->gui_url = $core->adminurl->get('admin.plugin.antispam', array('f' => get_class($this)), '&');
+            $this->gui_url = $core->adminurl->get('admin.plugin.antispam', ['f' => get_class($this)], '&');
         }
     }
Index: plugins/antispam/inc/class.dc.spamfilters.php
===================================================================
--- plugins/antispam/inc/class.dc.spamfilters.php	(revision 3731)
+++ plugins/antispam/inc/class.dc.spamfilters.php	(revision 3874)
@@ -14,6 +14,6 @@
 class dcSpamFilters
 {
-    private $filters     = array();
-    private $filters_opt = array();
+    private $filters     = [];
+    private $filters_opt = [];
     private $core;
 
@@ -42,5 +42,5 @@
         $this->setFilterOpts();
         if (!empty($this->filters_opt)) {
-            uasort($this->filters, array($this, 'orderCallBack'));
+            uasort($this->filters, [$this, 'orderCallBack']);
         }
     }
@@ -133,6 +133,6 @@
         # Create default options if needed
         if (!is_array($this->filters_opt)) {
-            $this->saveFilterOpts(array(), true);
-            $this->filters_opt = array();
+            $this->saveFilterOpts([], true);
+            $this->filters_opt = [];
         }
 
Index: plugins/antispam/inc/lib.dc.antispam.php
===================================================================
--- plugins/antispam/inc/lib.dc.antispam.php	(revision 3787)
+++ plugins/antispam/inc/lib.dc.antispam.php	(revision 3874)
@@ -73,5 +73,5 @@
         if (($count = self::countSpam($core)) > 0) {
             $str = ($count > 1) ? __('(including %d spam comments)') : __('(including %d spam comment)');
-            $icons['comments'][0] .= '</span></a> <a href="' . $core->adminurl->get('admin.comments', array('status' => '-2')) . '"><span class="db-icon-title-spam">' .
+            $icons['comments'][0] .= '</span></a> <a href="' . $core->adminurl->get('admin.comments', ['status' => '-2']) . '"><span class="db-icon-title-spam">' .
             sprintf($str, $count);
         }
@@ -82,5 +82,5 @@
         if (($count = self::countSpam($core)) > 0) {
             $str = ($count > 1) ? __('(including %d spam comments)') : __('(including %d spam comment)');
-            return '</span></a> <a href="' . $core->adminurl->get('admin.comments', array('status' => '-2')) . '"><span class="db-icon-title-spam">' .
+            return '</span></a> <a href="' . $core->adminurl->get('admin.comments', ['status' => '-2']) . '"><span class="db-icon-title-spam">' .
             sprintf($str, $count);
         } else {
@@ -96,10 +96,10 @@
     public static function countSpam($core)
     {
-        return $core->blog->getComments(array('comment_status' => -2), true)->f(0);
+        return $core->blog->getComments(['comment_status' => -2], true)->f(0);
     }
 
     public static function countPublishedComments($core)
     {
-        return $core->blog->getComments(array('comment_status' => 1), true)->f(0);
+        return $core->blog->getComments(['comment_status' => 1], true)->f(0);
     }
 
@@ -117,5 +117,5 @@
 
         $rs = $core->con->select($strReq);
-        $r  = array();
+        $r  = [];
         while ($rs->fetch()) {
             $r[] = (integer) $rs->comment_id;
Index: plugins/antispam/inc/lib.dc.antispam.url.php
===================================================================
--- plugins/antispam/inc/lib.dc.antispam.url.php	(revision 3731)
+++ plugins/antispam/inc/lib.dc.antispam.url.php	(revision 3874)
@@ -39,5 +39,5 @@
 
         $title   = $core->blog->name . ' - ' . __('Spam moderation') . ' - ';
-        $params  = array();
+        $params  = [];
         $end_url = '';
         if ($type == 'spam') {
Index: plugins/antispam/index.php
===================================================================
--- plugins/antispam/index.php	(revision 3731)
+++ plugins/antispam/index.php	(revision 3874)
@@ -48,8 +48,8 @@
     # Update filters
     if (isset($_POST['filters_upd'])) {
-        $filters_opt = array();
+        $filters_opt = [];
         $i           = 0;
         foreach ($filters as $fid => $f) {
-            $filters_opt[$fid] = array(false, $i);
+            $filters_opt[$fid] = [false, $i];
             $i++;
         }
@@ -118,9 +118,9 @@
 if ($filter_gui !== false) {
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins')                                         => '',
             $page_name                                            => $p_url,
             sprintf(__('%s filter configuration'), $filter->name) => ''
-        )) .
+        ]) .
     dcPage::notices();
 
@@ -134,8 +134,8 @@
 } else {
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins') => '',
             $page_name    => ''
-        )) .
+        ]) .
     dcPage::notices();
 
@@ -151,7 +151,7 @@
     echo
     '<ul class="spaminfo">' .
-    '<li class="spamcount"><a href="' . $core->adminurl->get('admin.comments', array('status' => '-2')) . '">' . __('Junk comments:') . '</a> ' .
+    '<li class="spamcount"><a href="' . $core->adminurl->get('admin.comments', ['status' => '-2']) . '">' . __('Junk comments:') . '</a> ' .
     '<strong>' . $spam_count . '</strong></li>' .
-    '<li class="hamcount"><a href="' . $core->adminurl->get('admin.comments', array('status' => '1')) . '">' . __('Published comments:') . '</a> ' .
+    '<li class="hamcount"><a href="' . $core->adminurl->get('admin.comments', ['status' => '1']) . '">' . __('Published comments:') . '</a> ' .
         $published_count . '</li>' .
         '</ul>';
@@ -204,22 +204,22 @@
         echo
         '<tr class="line' . ($f->active ? '' : ' offline') . '" id="f_' . $fid . '">' .
-        '<td class="handle">' . form::number(array('f_order[' . $fid . ']'), array(
+        '<td class="handle">' . form::number(['f_order[' . $fid . ']'], [
             'min'        => 0,
             'default'    => $i,
             'class'      => 'position',
             'extra_html' => 'title="' . __('position') . '"'
-        )) .
+        ]) .
         '</td>' .
-        '<td class="nowrap">' . form::checkbox(array('filters_active[]'), $fid,
-            array(
+        '<td class="nowrap">' . form::checkbox(['filters_active[]'], $fid,
+            [
                 'checked'    => $f->active,
                 'extra_html' => 'title="' . __('Active') . '"'
-            )
+            ]
         ) . '</td>' .
-        '<td class="nowrap">' . form::checkbox(array('filters_auto_del[]'), $fid,
-            array(
+        '<td class="nowrap">' . form::checkbox(['filters_auto_del[]'], $fid,
+            [
                 'checked'    => $f->auto_delete,
                 'extra_html' => 'title="' . __('Auto Del.') . '"'
-            )
+            ]
         ) . '</td>' .
         '<td class="nowrap" scope="row">' . $f->name . '</td>' .
Index: plugins/antispam/js/antispam.js
===================================================================
--- plugins/antispam/js/antispam.js	(revision 3730)
+++ plugins/antispam/js/antispam.js	(revision 3880)
@@ -3,23 +3,29 @@
 
 $(function() {
-	$('#filters-list').sortable({'cursor':'move'});
-	$('#filters-list tr').hover(function () {
-		$(this).css({'cursor':'move'});
-	}, function () {
-		$(this).css({'cursor':'auto'});
-	});
-	$('#filters-list-form').submit(function() {
-		var order=[];
-		$('#filters-list tr td input.position').each(function() {
-			order.push(this.name.replace(/^f_order\[([^\]]+)\]$/,'$1'));
-		});
-		$('input[name=filters_order]')[0].value = order.join(',');
-		return true;
-	});
-	$('#filters-list tr td input.position').hide();
-	$('#filters-list tr td.handle').addClass('handler');
+  $('#filters-list').sortable({
+    'cursor': 'move'
+  });
+  $('#filters-list tr').hover(function() {
+    $(this).css({
+      'cursor': 'move'
+    });
+  }, function() {
+    $(this).css({
+      'cursor': 'auto'
+    });
+  });
+  $('#filters-list-form').submit(function() {
+    let order = [];
+    $('#filters-list tr td input.position').each(function() {
+      order.push(this.name.replace(/^f_order\[([^\]]+)\]$/, '$1'));
+    });
+    $('input[name=filters_order]')[0].value = order.join(',');
+    return true;
+  });
+  $('#filters-list tr td input.position').hide();
+  $('#filters-list tr td.handle').addClass('handler');
 
-	$('form input[type=submit][name=delete_all]').click(function(){
-		return window.confirm(dotclear.msg.confirm_spam_delete);
-	});
+  $('form input[type=submit][name=delete_all]').click(function() {
+    return window.confirm(dotclear.msg.confirm_spam_delete);
+  });
 });
Index: plugins/antispam/js/dashboard.js
===================================================================
--- plugins/antispam/js/dashboard.js	(revision 3787)
+++ plugins/antispam/js/dashboard.js	(revision 3880)
@@ -3,5 +3,5 @@
 
 dotclear.dbSpamsCount = function() {
-  var params = {
+  const params = {
     f: 'getSpamsCount',
     xd_check: dotclear.nonce,
@@ -13,11 +13,11 @@
       window.console.log('Dotclear REST server error');
     } else {
-      var nb = $('rsp>count', data).attr('ret');
+      const nb = $('rsp>count', data).attr('ret');
       if (nb != dotclear.dbSpamsCount_Counter) {
         // First pass or counter changed
-        var icon = $('#dashboard-main #icons p a[href="comments.php?status=-2"]');
+        let icon = $('#dashboard-main #icons p a[href="comments.php?status=-2"]');
         if (icon.length) {
           // Update count if exists
-          var nb_label = icon.children('span.db-icon-title-spam');
+          const nb_label = icon.children('span.db-icon-title-spam');
           if (nb_label.length) {
             nb_label.text(nb);
@@ -26,7 +26,7 @@
           if (nb != '') {
             // Add full element (link + counter)
-            var icon = $('#dashboard-main #icons p a[href="comments.php"]');
+            icon = $('#dashboard-main #icons p a[href="comments.php"]');
             if (icon.length) {
-              var xml = ' <a href="comments.php?status=-2"><span class="db-icon-title-spam">' + nb + '</span></a>';
+              const xml = ` <a href="comments.php?status=-2"><span class="db-icon-title-spam">${nb}</span></a>`;
               icon.after(xml);
             }
@@ -43,5 +43,5 @@
   // run counters' update on some dashboard icons
   // Spam comments
-  var icon_spam = $('#dashboard-main #icons p a[href="comments.php"]');
+  const icon_spam = $('#dashboard-main #icons p a[href="comments.php"]');
   if (icon_spam.length) {
     // Icon exists on dashboard
Index: plugins/antispam/style.css
===================================================================
--- plugins/antispam/style.css	(revision 3730)
+++ plugins/antispam/style.css	(revision 3861)
@@ -32,5 +32,6 @@
   padding: 0.2em 0.5em;
 }
-.antispam p.global {
+.antispam .global {
+  color: #3c3c3c;
   background: #fec;
 }
Index: plugins/attachments/_admin.php
===================================================================
--- plugins/attachments/_admin.php	(revision 3731)
+++ plugins/attachments/_admin.php	(revision 3874)
@@ -12,11 +12,11 @@
 if (!defined('DC_CONTEXT_ADMIN')) {return;}
 
-$core->addBehavior('adminPostFormItems', array('attachmentAdmin', 'adminPostFormItems'));
-$core->addBehavior('adminPostAfterForm', array('attachmentAdmin', 'adminPostAfterForm'));
-$core->addBehavior('adminPostHeaders', array('attachmentAdmin', 'postHeaders'));
-$core->addBehavior('adminPageFormItems', array('attachmentAdmin', 'adminPostFormItems'));
-$core->addBehavior('adminPageAfterForm', array('attachmentAdmin', 'adminPostAfterForm'));
-$core->addBehavior('adminPageHeaders', array('attachmentAdmin', 'postHeaders'));
-$core->addBehavior('adminPageHelpBlock', array('attachmentAdmin', 'adminPageHelpBlock'));
+$core->addBehavior('adminPostFormItems', ['attachmentAdmin', 'adminPostFormItems']);
+$core->addBehavior('adminPostAfterForm', ['attachmentAdmin', 'adminPostAfterForm']);
+$core->addBehavior('adminPostHeaders', ['attachmentAdmin', 'postHeaders']);
+$core->addBehavior('adminPageFormItems', ['attachmentAdmin', 'adminPostFormItems']);
+$core->addBehavior('adminPageAfterForm', ['attachmentAdmin', 'adminPostAfterForm']);
+$core->addBehavior('adminPageHeaders', ['attachmentAdmin', 'postHeaders']);
+$core->addBehavior('adminPageHelpBlock', ['attachmentAdmin', 'adminPageHelpBlock']);
 
 class attachmentAdmin
@@ -56,8 +56,8 @@
                 $item .=
                 '<div class="media-item s-attachments">' .
-                '<a class="media-icon" href="' . $core->adminurl->get('admin.media.item', array('id' => $f->media_id)) . '">' .
+                '<a class="media-icon" href="' . $core->adminurl->get('admin.media.item', ['id' => $f->media_id]) . '">' .
                 '<img src="' . $f->media_icon . '" alt="" title="' . $f->basename . '" /></a>' .
                 '<ul>' .
-                '<li><a class="media-link" href="' . $core->adminurl->get('admin.media.item', array('id' => $f->media_id)) . '" ' .
+                '<li><a class="media-link" href="' . $core->adminurl->get('admin.media.item', ['id' => $f->media_id]) . '" ' .
                 'title="' . $f->basename . '">' . $ftitle . '</a></li>' .
                 '<li>' . $f->media_dtstr . '</li>' .
@@ -66,10 +66,10 @@
 
                 '<li class="media-action"><a class="attachment-remove" id="attachment-' . $f->media_id . '" ' .
-                'href="' . $core->adminurl->get('admin.post.media', array(
+                'href="' . $core->adminurl->get('admin.post.media', [
                     'post_id'   => $post->post_id,
                     'media_id'  => $f->media_id,
                     'link_type' => 'attachment',
                     'remove'    => '1'
-                )) . '">' .
+                ]) . '">' .
                 '<img src="images/trash.png" alt="' . __('remove') . '" /></a>' .
                     '</li>' .
@@ -84,5 +84,5 @@
             }
             $item .=
-            '<p class="s-attachments"><a class="button" href="' . $core->adminurl->get('admin.media', array('post_id' => $post->post_id, 'link_type' => 'attachment')) . '">' .
+            '<p class="s-attachments"><a class="button" href="' . $core->adminurl->get('admin.media', ['post_id' => $post->post_id, 'link_type' => 'attachment']) . '">' .
             __('Add files to this entry') . '</a></p>';
             $sidebar['metas-box']['items']['attachments'] = $item;
@@ -96,8 +96,8 @@
             echo
             '<form action="' . $core->adminurl->get('admin.post.media') . '" id="attachment-remove-hide" method="post">' .
-            '<div>' . form::hidden(array('post_id'), $post->post_id) .
-            form::hidden(array('media_id'), '') .
-            form::hidden(array('link_type'), 'attachment') .
-            form::hidden(array('remove'), 1) .
+            '<div>' . form::hidden(['post_id'], $post->post_id) .
+            form::hidden(['media_id'], '') .
+            form::hidden(['link_type'], 'attachment') .
+            form::hidden(['remove'], 1) .
             $core->formNonce() . '</div></form>';
         }
Index: plugins/attachments/_define.php
===================================================================
--- plugins/attachments/_define.php	(revision 3731)
+++ plugins/attachments/_define.php	(revision 3874)
@@ -17,8 +17,8 @@
     "Dotclear Team",           // Author
     '1.1',                     // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin,pages',
         'priority'    => 999,
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/attachments/_public.php
===================================================================
--- plugins/attachments/_public.php	(revision 3731)
+++ plugins/attachments/_public.php	(revision 3874)
@@ -13,20 +13,20 @@
 
 # Attachments
-$core->tpl->addBlock('Attachments', array('attachmentTpl', 'Attachments'));
-$core->tpl->addBlock('AttachmentsHeader', array('attachmentTpl', 'AttachmentsHeader'));
-$core->tpl->addBlock('AttachmentsFooter', array('attachmentTpl', 'AttachmentsFooter'));
-$core->tpl->addValue('AttachmentMimeType', array('attachmentTpl', 'AttachmentMimeType'));
-$core->tpl->addValue('AttachmentType', array('attachmentTpl', 'AttachmentType'));
-$core->tpl->addValue('AttachmentFileName', array('attachmentTpl', 'AttachmentFileName'));
-$core->tpl->addValue('AttachmentSize', array('attachmentTpl', 'AttachmentSize'));
-$core->tpl->addValue('AttachmentTitle', array('attachmentTpl', 'AttachmentTitle'));
-$core->tpl->addValue('AttachmentThumbnailURL', array('attachmentTpl', 'AttachmentThumbnailURL'));
-$core->tpl->addValue('AttachmentURL', array('attachmentTpl', 'AttachmentURL'));
-$core->tpl->addValue('MediaURL', array('attachmentTpl', 'MediaURL'));
-$core->tpl->addBlock('AttachmentIf', array('attachmentTpl', 'AttachmentIf'));
-
-$core->tpl->addValue('EntryAttachmentCount', array('attachmentTpl', 'EntryAttachmentCount'));
-
-$core->addBehavior('tplIfConditions', array('attachmentBehavior', 'tplIfConditions'));
+$core->tpl->addBlock('Attachments', ['attachmentTpl', 'Attachments']);
+$core->tpl->addBlock('AttachmentsHeader', ['attachmentTpl', 'AttachmentsHeader']);
+$core->tpl->addBlock('AttachmentsFooter', ['attachmentTpl', 'AttachmentsFooter']);
+$core->tpl->addValue('AttachmentMimeType', ['attachmentTpl', 'AttachmentMimeType']);
+$core->tpl->addValue('AttachmentType', ['attachmentTpl', 'AttachmentType']);
+$core->tpl->addValue('AttachmentFileName', ['attachmentTpl', 'AttachmentFileName']);
+$core->tpl->addValue('AttachmentSize', ['attachmentTpl', 'AttachmentSize']);
+$core->tpl->addValue('AttachmentTitle', ['attachmentTpl', 'AttachmentTitle']);
+$core->tpl->addValue('AttachmentThumbnailURL', ['attachmentTpl', 'AttachmentThumbnailURL']);
+$core->tpl->addValue('AttachmentURL', ['attachmentTpl', 'AttachmentURL']);
+$core->tpl->addValue('MediaURL', ['attachmentTpl', 'MediaURL']);
+$core->tpl->addBlock('AttachmentIf', ['attachmentTpl', 'AttachmentIf']);
+
+$core->tpl->addValue('EntryAttachmentCount', ['attachmentTpl', 'EntryAttachmentCount']);
+
+$core->addBehavior('tplIfConditions', ['attachmentBehavior', 'tplIfConditions']);
 
 class attachmentTpl
@@ -90,5 +90,5 @@
     public static function AttachmentIf($attr, $content)
     {
-        $if = array();
+        $if = [];
 
         $operator = isset($attr['operator']) ? dcTemplate::getOperator($attr['operator']) : '&&';
@@ -224,9 +224,9 @@
         return $core->tpl->displayCounter(
             '$_ctx->posts->countMedia(\'attachment\')',
-            array(
+            [
                 'none' => 'no attachments',
                 'one'  => 'one attachment',
                 'more' => '%d attachments'
-            ),
+            ],
             $attr,
             false
Index: plugins/blogroll/_admin.php
===================================================================
--- plugins/blogroll/_admin.php	(revision 3731)
+++ plugins/blogroll/_admin.php	(revision 3874)
@@ -18,13 +18,13 @@
 function blogroll_dashboard($core, $icons)
 {
-    $icons['blogroll'] = new ArrayObject(array(
+    $icons['blogroll'] = new ArrayObject([
         __('Blogroll'),
         $core->adminurl->get('admin.plugin.blogroll'),
         dcPage::getPF('blogroll/icon.png')
-    ));
+    ]);
 }
 function blogroll_dashboard_favorites($core, $favs)
 {
-    $favs->register('blogroll', array(
+    $favs->register('blogroll', [
         'title'       => __('Blogroll'),
         'url'         => $core->adminurl->get('admin.plugin.blogroll'),
@@ -32,5 +32,5 @@
         'large-icon'  => dcPage::getPF('blogroll/icon.png'),
         'permissions' => 'usage,contentadmin'
-    ));
+    ]);
 }
 function blogroll_users_actions_headers()
Index: plugins/blogroll/_define.php
===================================================================
--- plugins/blogroll/_define.php	(revision 3731)
+++ plugins/blogroll/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "Olivier Meunier",      // Author
     '1.4',                  // Version
-    array(
+    [
         'permissions' => 'blogroll',
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/blogroll/_public.php
===================================================================
--- plugins/blogroll/_public.php	(revision 3731)
+++ plugins/blogroll/_public.php	(revision 3874)
@@ -15,8 +15,8 @@
 
 # Blogroll template functions
-$core->tpl->addValue('Blogroll', array('tplBlogroll', 'blogroll'));
-$core->tpl->addValue('BlogrollXbelLink', array('tplBlogroll', 'blogrollXbelLink'));
-
-$core->url->register('xbel', 'xbel', '^xbel(?:/?)$', array('urlBlogroll', 'xbel'));
+$core->tpl->addValue('Blogroll', ['tplBlogroll', 'blogroll']);
+$core->tpl->addValue('BlogrollXbelLink', ['tplBlogroll', 'blogrollXbelLink']);
+
+$core->url->register('xbel', 'xbel', '^xbel(?:/?)$', ['urlBlogroll', 'xbel']);
 
 class tplBlogroll
@@ -75,5 +75,5 @@
                 return '';
             }
-            $hierarchy = array($hierarchy[$category]);
+            $hierarchy = [$hierarchy[$category]];
         }
 
Index: plugins/blogroll/_widgets.php
===================================================================
--- plugins/blogroll/_widgets.php	(revision 3731)
+++ plugins/blogroll/_widgets.php	(revision 3874)
@@ -12,6 +12,6 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('initWidgets', array('blogrollWidgets', 'initWidgets'));
-$core->addBehavior('initDefaultWidgets', array('blogrollWidgets', 'initDefaultWidgets'));
+$core->addBehavior('initWidgets', ['blogrollWidgets', 'initWidgets']);
+$core->addBehavior('initDefaultWidgets', ['blogrollWidgets', 'initDefaultWidgets']);
 
 class blogrollWidgets
@@ -19,5 +19,5 @@
     public static function initWidgets($w)
     {
-        $w->create('links', __('Blogroll'), array('tplBlogroll', 'linksWidget'), null, 'Blogroll list');
+        $w->create('links', __('Blogroll'), ['tplBlogroll', 'linksWidget'], null, 'Blogroll list');
         $w->links->setting('title', __('Title (optional)') . ' :', __('Links'));
 
@@ -25,5 +25,5 @@
         $h          = $br->getLinksHierarchy($br->getLinks());
         $h          = array_keys($h);
-        $categories = array(__('All categories') => '');
+        $categories = [__('All categories') => ''];
         foreach ($h as $v) {
             if ($v) {
@@ -35,9 +35,9 @@
 
         $w->links->setting('homeonly', __('Display on:'), 1, 'combo',
-            array(
+            [
                 __('All pages')           => 0,
                 __('Home page only')      => 1,
                 __('Except on home page') => 2
-            )
+            ]
         );
         $w->links->setting('content_only', __('Content only'), 0, 'check');
Index: plugins/blogroll/class.dc.blogroll.php
===================================================================
--- plugins/blogroll/class.dc.blogroll.php	(revision 3731)
+++ plugins/blogroll/class.dc.blogroll.php	(revision 3874)
@@ -25,5 +25,5 @@
     }
 
-    public function getLinks($params = array())
+    public function getLinks($params = [])
     {
         $strReq = 'SELECT link_id, link_title, link_desc, link_href, ' .
@@ -44,4 +44,28 @@
 
         return $rs;
+    }
+
+    public function getLangs($params = [])
+    {
+        // Use post_lang as an alias of link_lang to be able to use the dcAdminCombos::getLangsCombo() function
+        $strReq = 'SELECT COUNT(link_id) as nb_link, link_lang as post_lang ' .
+        'FROM ' . $this->table . ' ' .
+        "WHERE blog_id = '" . $this->con->escape($this->blog->id) . "' " .
+            "AND link_lang <> '' " .
+            "AND link_lang IS NOT NULL ";
+
+        if (isset($params['lang'])) {
+            $strReq .= "AND link_lang = '" . $this->con->escape($params['lang']) . "' ";
+        }
+
+        $strReq .= 'GROUP BY link_lang ';
+
+        $order = 'desc';
+        if (!empty($params['order']) && preg_match('/^(desc|asc)$/i', $params['order'])) {
+            $order = $params['order'];
+        }
+        $strReq .= 'ORDER BY link_lang ' . $order . ' ';
+
+        return $this->con->select($strReq);
     }
 
@@ -183,5 +207,5 @@
     public function getLinksHierarchy($rs)
     {
-        $res = array();
+        $res = [];
 
         foreach ($rs->rows() as $k => $v) {
Index: plugins/blogroll/class.dc.importblogroll.php
===================================================================
--- plugins/blogroll/class.dc.importblogroll.php	(revision 3731)
+++ plugins/blogroll/class.dc.importblogroll.php	(revision 3874)
@@ -36,5 +36,5 @@
         $outlines = $xml->xpath("//outline");
 
-        $this->entries = array();
+        $this->entries = [];
         foreach ($outlines as $outline) {
             if (isset($outline['htmlUrl'])) {
@@ -66,5 +66,5 @@
         $outlines = $xml->xpath("//bookmark");
 
-        $this->entries = array();
+        $this->entries = [];
         foreach ($outlines as $outline) {
             if (!isset($outline['href'])) {
Index: plugins/blogroll/edit.php
===================================================================
--- plugins/blogroll/edit.php	(revision 3731)
+++ plugins/blogroll/edit.php	(revision 3874)
@@ -84,4 +84,8 @@
 }
 
+# Languages combo
+$links      = $blogroll->getLangs(['order' => 'asc']);
+$lang_combo = dcAdminCombos::getLangsCombo($links, true);
+
 ?>
 <html>
@@ -93,8 +97,8 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Blogroll')                      => $p_url
-    )) .
+    ]) .
 dcPage::notices();
 ?>
@@ -109,8 +113,8 @@
 
     '<p><label for="link_desc" class="required classic"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label> ' .
-    form::field('link_desc', 30, 255, array(
+    form::field('link_desc', 30, 255, [
         'default'    => html::escapeHTML($link_desc),
         'extra_html' => 'required placeholder="' . __('Title') . '"'
-    )) .
+    ]) .
 
     form::hidden('edit', 1) .
@@ -129,16 +133,16 @@
 
     '<p><label for="link_title" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label> ' .
-    form::field('link_title', 30, 255, array(
+    form::field('link_title', 30, 255, [
         'default'    => html::escapeHTML($link_title),
         'extra_html' => 'required placeholder="' . __('Title') . '"'
-    )) .
+    ]) .
     '</p>' .
 
     '<p><label for="link_href" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('URL:') . '</label> ' .
-    form::url('link_href', array(
+    form::url('link_href', [
         'size'       => 30,
         'default'    => html::escapeHTML($link_href),
         'extra_html' => 'required placeholder="' . __('URL') . '"'
-    )) .
+    ]) .
     '</p>' .
 
@@ -147,5 +151,7 @@
 
     '<p><label for="link_lang">' . __('Language:') . '</label> ' .
-    form::field('link_lang', 5, 5, html::escapeHTML($link_lang)) . '</p>' .
+    form::combo('link_lang', $lang_combo, $link_lang) .
+    '</p>' .
+
     '</div>' .
 
@@ -153,4 +159,6 @@
     '<div class="col70 last-col">' .
     '<h3>' . __('XFN information') . '</h3>' .
+    '<p class="clear form-note">' . __('More information on <a href="https://en.wikipedia.org/wiki/XHTML_Friends_Network">Wikipedia</a> website') . '</p>' .
+
     '<div class="table-outer">' .
     '<table class="noborder">' .
@@ -159,5 +167,5 @@
     '<th>' . __('_xfn_Me') . '</th>' .
     '<td><p>' . '<label class="classic">' .
-    form::checkbox(array('identity'), 'me', ($link_xfn == 'me')) . ' ' .
+    form::checkbox(['identity'], 'me', ($link_xfn == 'me')) . ' ' .
     __('_xfn_Another link for myself') . '</label></p></td>' .
     '</tr>' .
@@ -166,11 +174,11 @@
     '<th>' . __('_xfn_Friendship') . '</th>' .
     '<td><p>' .
-    '<label class="classic">' . form::radio(array('friendship'), 'contact',
+    '<label class="classic">' . form::radio(['friendship'], 'contact',
         strpos($link_xfn, 'contact') !== false) . __('_xfn_Contact') . '</label> ' .
-    '<label class="classic">' . form::radio(array('friendship'), 'acquaintance',
+    '<label class="classic">' . form::radio(['friendship'], 'acquaintance',
         strpos($link_xfn, 'acquaintance') !== false) . __('_xfn_Acquaintance') . '</label> ' .
-    '<label class="classic">' . form::radio(array('friendship'), 'friend',
+    '<label class="classic">' . form::radio(['friendship'], 'friend',
         strpos($link_xfn, 'friend') !== false) . __('_xfn_Friend') . '</label> ' .
-    '<label class="classic">' . form::radio(array('friendship'), '') . __('None') . '</label>' .
+    '<label class="classic">' . form::radio(['friendship'], '') . __('None') . '</label>' .
     '</p></td>' .
     '</tr>' .
@@ -179,5 +187,5 @@
     '<th>' . __('_xfn_Physical') . '</th>' .
     '<td><p>' .
-    '<label class="classic">' . form::checkbox(array('physical'), 'met',
+    '<label class="classic">' . form::checkbox(['physical'], 'met',
         strpos($link_xfn, 'met') !== false) . __('_xfn_Met') . '</label>' .
     '</p></td>' .
@@ -187,7 +195,7 @@
     '<th>' . __('_xfn_Professional') . '</th>' .
     '<td><p>' .
-    '<label class="classic">' . form::checkbox(array('professional[]'), 'co-worker',
+    '<label class="classic">' . form::checkbox(['professional[]'], 'co-worker',
         strpos($link_xfn, 'co-worker') !== false) . __('_xfn_Co-worker') . '</label> ' .
-    '<label class="classic">' . form::checkbox(array('professional[]'), 'colleague',
+    '<label class="classic">' . form::checkbox(['professional[]'], 'colleague',
         strpos($link_xfn, 'colleague') !== false) . __('_xfn_Colleague') . '</label>' .
     '</p></td>' .
@@ -197,9 +205,9 @@
     '<th>' . __('_xfn_Geographical') . '</th>' .
     '<td><p>' .
-    '<label class="classic">' . form::radio(array('geographical'), 'co-resident',
+    '<label class="classic">' . form::radio(['geographical'], 'co-resident',
         strpos($link_xfn, 'co-resident') !== false) . __('_xfn_Co-resident') . '</label> ' .
-    '<label class="classic">' . form::radio(array('geographical'), 'neighbor',
+    '<label class="classic">' . form::radio(['geographical'], 'neighbor',
         strpos($link_xfn, 'neighbor') !== false) . __('_xfn_Neighbor') . '</label> ' .
-    '<label class="classic">' . form::radio(array('geographical'), '') . __('None') . '</label>' .
+    '<label class="classic">' . form::radio(['geographical'], '') . __('None') . '</label>' .
     '</p></td>' .
     '</tr>' .
@@ -208,15 +216,15 @@
     '<th>' . __('_xfn_Family') . '</th>' .
     '<td><p>' .
-    '<label class="classic">' . form::radio(array('family'), 'child',
+    '<label class="classic">' . form::radio(['family'], 'child',
         strpos($link_xfn, 'child') !== false) . __('_xfn_Child') . '</label> ' .
-    '<label class="classic">' . form::radio(array('family'), 'parent',
+    '<label class="classic">' . form::radio(['family'], 'parent',
         strpos($link_xfn, 'parent') !== false) . __('_xfn_Parent') . '</label> ' .
-    '<label class="classic">' . form::radio(array('family'), 'sibling',
+    '<label class="classic">' . form::radio(['family'], 'sibling',
         strpos($link_xfn, 'sibling') !== false) . __('_xfn_Sibling') . '</label> ' .
-    '<label class="classic">' . form::radio(array('family'), 'spouse',
+    '<label class="classic">' . form::radio(['family'], 'spouse',
         strpos($link_xfn, 'spouse') !== false) . __('_xfn_Spouse') . '</label> ' .
-    '<label class="classic">' . form::radio(array('family'), 'kin',
+    '<label class="classic">' . form::radio(['family'], 'kin',
         strpos($link_xfn, 'kin') !== false) . __('_xfn_Kin') . '</label> ' .
-    '<label class="classic">' . form::radio(array('family'), '') . __('None') . '</label>' .
+    '<label class="classic">' . form::radio(['family'], '') . __('None') . '</label>' .
     '</p></td>' .
     '</tr>' .
@@ -225,11 +233,11 @@
     '<th>' . __('_xfn_Romantic') . '</th>' .
     '<td><p>' .
-    '<label class="classic">' . form::checkbox(array('romantic[]'), 'muse',
+    '<label class="classic">' . form::checkbox(['romantic[]'], 'muse',
         strpos($link_xfn, 'muse') !== false) . __('_xfn_Muse') . '</label> ' .
-    '<label class="classic">' . form::checkbox(array('romantic[]'), 'crush',
+    '<label class="classic">' . form::checkbox(['romantic[]'], 'crush',
         strpos($link_xfn, 'crush') !== false) . __('_xfn_Crush') . '</label> ' .
-    '<label class="classic">' . form::checkbox(array('romantic[]'), 'date',
+    '<label class="classic">' . form::checkbox(['romantic[]'], 'date',
         strpos($link_xfn, 'date') !== false) . __('_xfn_Date') . '</label> ' .
-    '<label class="classic">' . form::checkbox(array('romantic[]'), 'sweetheart',
+    '<label class="classic">' . form::checkbox(['romantic[]'], 'sweetheart',
         strpos($link_xfn, 'sweetheart') !== false) . __('_xfn_Sweetheart') . '</label> ' .
     '</p></td>' .
Index: plugins/blogroll/index.php
===================================================================
--- plugins/blogroll/index.php	(revision 3731)
+++ plugins/blogroll/index.php	(revision 3874)
@@ -125,5 +125,5 @@
 
 # Order links
-$order = array();
+$order = [];
 if (empty($_POST['links_order']) && !empty($_POST['order'])) {
     $order = $_POST['order'];
@@ -178,8 +178,8 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Blogroll')                      => ''
-    )) .
+    ]) .
 dcPage::notices();
 ?>
@@ -208,14 +208,14 @@
         echo
         '<tr class="line" id="l_' . $rs->link_id . '">' .
-        '<td class="handle minimal">' . form::field(array('order[' . $rs->link_id . ']'), 2, 5, array(
+        '<td class="handle minimal">' . form::field(['order[' . $rs->link_id . ']'], 2, 5, [
             'default'    => $position,
             'class'      => 'position',
             'extra_html' => 'title="' . __('position') . '"'
-        )) .
+        ]) .
         '</td>' .
-        '<td class="minimal">' . form::checkbox(array('remove[]'), $rs->link_id,
-            array(
+        '<td class="minimal">' . form::checkbox(['remove[]'], $rs->link_id,
+            [
                 'extra_html' => 'title="' . __('select this link') . '"'
-            )
+            ]
         ) . '</td>';
 
@@ -244,5 +244,5 @@
 echo
     form::hidden('links_order', '') .
-    form::hidden(array('p'), 'blogroll') .
+    form::hidden(['p'], 'blogroll') .
     $core->formNonce();
     ?>
@@ -268,15 +268,15 @@
 '<h3>' . __('Add a new link') . '</h3>' .
 '<p class="col"><label for="link_title" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label> ' .
-form::field('link_title', 30, 255, array(
+form::field('link_title', 30, 255, [
     'default'    => $link_title,
     'extra_html' => 'required placeholder="' . __('Title') . '"'
-)) .
+]) .
 '</p>' .
 
 '<p class="col"><label for="link_href" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('URL:') . '</label> ' .
-form::field('link_href', 30, 255, array(
+form::field('link_href', 30, 255, [
     'default'    => $link_href,
     'extra_html' => 'required placeholder="' . __('URL') . '"'
-)) .
+]) .
 '</p>' .
 
@@ -288,5 +288,5 @@
 form::field('link_lang', 5, 5, $link_lang) .
 '</p>' .
-'<p>' . form::hidden(array('p'), 'blogroll') .
+'<p>' . form::hidden(['p'], 'blogroll') .
 $core->formNonce() .
 '<input type="submit" name="add_link" value="' . __('Save') . '" /></p>' .
@@ -299,10 +299,10 @@
 '<h3>' . __('Add a new category') . '</h3>' .
 '<p><label for="cat_title" class=" classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label> ' .
-form::field('cat_title', 30, 255, array(
+form::field('cat_title', 30, 255, [
     'default'    => $cat_title,
     'extra_html' => 'required placeholder="' . __('Title') . '"'
-)) .
+]) .
 ' ' .
-form::hidden(array('p'), 'blogroll') .
+form::hidden(['p'], 'blogroll') .
 $core->formNonce() .
 '<input type="submit" name="add_cat" value="' . __('Save') . '" /></p>' .
@@ -318,5 +318,5 @@
     '<p><label for="links_file" class=" classic required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('OPML or XBEL File:') . '</label> ' .
     '<input type="file" id="links_file" name="links_file" required /></p>' .
-    '<p>' . form::hidden(array('p'), 'blogroll') .
+    '<p>' . form::hidden(['p'], 'blogroll') .
     $core->formNonce() .
     '<input type="submit" name="import_links" value="' . __('Import') . '" /></p>' .
@@ -342,5 +342,5 @@
 
             echo
-            '<tr><td>' . form::checkbox(array('entries[]'), $i) . '</td>' .
+            '<tr><td>' . form::checkbox(['entries[]'], $i) . '</td>' .
                 '<td nowrap><a href="' . $url . '">' . $title . '</a>' .
                 '<input type="hidden" name="url[' . $i . ']" value="' . $url . '" />' .
@@ -358,5 +358,5 @@
 
         '<p class="col right">' .
-        form::hidden(array('p'), 'blogroll') .
+        form::hidden(['p'], 'blogroll') .
         $core->formNonce() .
         '<input type="submit" name="cancel_import" value="' . __('Cancel') . '" />&nbsp;' .
Index: plugins/blogroll/js/_users_actions.js
===================================================================
--- plugins/blogroll/js/_users_actions.js	(revision 3730)
+++ plugins/blogroll/js/_users_actions.js	(revision 3880)
@@ -5,10 +5,11 @@
   return this.each(function() {
 
-    var perms = {};
-    var re = /^perm\[(.+?)\]\[(.+?)\]$/;
-    var e, prop;
+    let perms = {};
+    const re = /^perm\[(.+?)\]\[(.+?)\]$/;
+    let e;
+    let prop;
 
     // Building a nice object of form elements
-    for (var i = 0; i < this.elements.length; i++) {
+    for (let i = 0; i < this.elements.length; i++) {
       e = this.elements[i];
 
@@ -16,5 +17,4 @@
         continue;
       }
-      var prop;
       prop = e.name.match(re);
       if (!prop) {
@@ -38,8 +38,8 @@
 
     function admin(E, perms, re) {
-      P = E.name.match(re);
+      const P = E.name.match(re);
 
-      perms[P[1]]['blogroll'].checked = E.checked;
-      perms[P[1]]['blogroll'].disabled = E.checked;
+      perms[P[1]].blogroll.checked = E.checked;
+      perms[P[1]].blogroll.disabled = E.checked;
     }
   });
Index: plugins/blogroll/js/blogroll.js
===================================================================
--- plugins/blogroll/js/blogroll.js	(revision 3709)
+++ plugins/blogroll/js/blogroll.js	(revision 3880)
@@ -3,20 +3,26 @@
 
 $(function() {
-	$('#links-list').sortable({'cursor':'move'});
-	$('#links-list tr').hover(function () {
-		$(this).css({'cursor':'move'});
-	}, function () {
-		$(this).css({'cursor':'auto'});
-	});
-	$('#links-form').submit(function() {
-		var order=[];
-		$('#links-list tr td input.position').each(function() {
-			order.push(this.name.replace(/^order\[([^\]]+)\]$/,'$1'));
-		});
-		$('input[name=links_order]')[0].value = order.join(',');
-		return true;
-	});
-	$('#links-list tr td input.position').hide();
-	$('#links-list tr td.handle').addClass('handler');
-	dotclear.condSubmit('#links-form td input[type="checkbox"]','#links-form #remove-action');
+  $('#links-list').sortable({
+    'cursor': 'move'
+  });
+  $('#links-list tr').hover(function() {
+    $(this).css({
+      'cursor': 'move'
+    });
+  }, function() {
+    $(this).css({
+      'cursor': 'auto'
+    });
+  });
+  $('#links-form').submit(function() {
+    let order = [];
+    $('#links-list tr td input.position').each(function() {
+      order.push(this.name.replace(/^order\[([^\]]+)\]$/, '$1'));
+    });
+    $('input[name=links_order]')[0].value = order.join(',');
+    return true;
+  });
+  $('#links-list tr td input.position').hide();
+  $('#links-list tr td.handle').addClass('handler');
+  dotclear.condSubmit('#links-form td input[type="checkbox"]', '#links-form #remove-action');
 });
Index: plugins/blowupConfig/_define.php
===================================================================
--- plugins/blowupConfig/_define.php	(revision 3731)
+++ plugins/blowupConfig/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "Olivier Meunier",             // Author
     '1.2',                         // Version
-    array(
+    [
         'permissions' => 'admin',
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/blowupConfig/_public.php
===================================================================
--- plugins/blowupConfig/_public.php	(revision 3731)
+++ plugins/blowupConfig/_public.php	(revision 3874)
@@ -17,5 +17,5 @@
 
 require dirname(__FILE__) . '/lib/class.blowup.config.php';
-$core->addBehavior('publicHeadContent', array('tplBlowupTheme', 'publicHeadContent'));
+$core->addBehavior('publicHeadContent', ['tplBlowupTheme', 'publicHeadContent']);
 
 class tplBlowUpTheme
Index: plugins/blowupConfig/index.php
===================================================================
--- plugins/blowupConfig/index.php	(revision 3731)
+++ plugins/blowupConfig/index.php	(revision 3874)
@@ -22,5 +22,5 @@
 }
 
-$blowup_base = array(
+$blowup_base = [
     'body_bg_c'           => null,
     'body_bg_g'           => 'light',
@@ -81,5 +81,5 @@
 
     'extra_css'           => null
-);
+];
 
 $blowup_user = $core->blog->settings->themes->blowup_style;
@@ -87,17 +87,17 @@
 $blowup_user = @unserialize($blowup_user);
 if (!is_array($blowup_user)) {
-    $blowup_user = array();
+    $blowup_user = [];
 }
 
 $blowup_user = array_merge($blowup_base, $blowup_user);
 
-$gradient_types = array(
+$gradient_types = [
     __('Light linear gradient')  => 'light',
     __('Medium linear gradient') => 'medium',
     __('Dark linear gradient')   => 'dark',
     __('Solid color')            => 'solid'
-);
-
-$top_images = array(__('Custom...') => 'custom');
+];
+
+$top_images = [__('Custom...') => 'custom'];
 $top_images = array_merge($top_images, array_flip(blowupConfig::$top_images));
 
@@ -205,10 +205,10 @@
   <?php
 echo dcPage::jsLoad(dcPage::getPF('blowupConfig/js/config.js'));
-echo dcPage::jsVars(array(
+echo dcPage::jsVars([
     'dotclear.blowup_public_url'          => blowupConfig::imagesURL(),
     'dotclear.msg.predefined_styles'      => __('Predefined styles'),
     'dotclear.msg.apply_code'             => __('Apply code'),
     'dotclear.msg.predefined_style_title' => __('Choose a predefined style')
-));
+]);
 ?>
 </head>
@@ -217,9 +217,9 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Blog appearance')               => $core->adminurl->get('admin.blog.theme'),
         __('Blowup configuration')          => ''
-    )) . dcPage::notices();
+    ]) . dcPage::notices();
 
 echo
@@ -239,5 +239,5 @@
     echo
     '<p class="field"><label for="body_bg_c">' . __('Background color:') . '</label> ' .
-    form::color('body_bg_c', array('default' => $blowup_user['body_bg_c'])) . '</p>' .
+    form::color('body_bg_c', ['default' => $blowup_user['body_bg_c']]) . '</p>' .
 
     '<p class="field"><label for="body_bg_g">' . __('Background color fill:') . '</label> ' .
@@ -253,5 +253,5 @@
 
 '<p class="field"><label for="body_txt_c">' . __('Main text color:') . '</label> ' .
-form::color('body_txt_c', array('default' => $blowup_user['body_txt_c'])) . '</p>' .
+form::color('body_txt_c', ['default' => $blowup_user['body_txt_c']]) . '</p>' .
 
 '<p class="field"><label for="body_line_height">' . __('Text line height:') . '</label> ' .
@@ -260,11 +260,11 @@
 '<h4 class="border-top">' . __('Links') . '</h4>' .
 '<p class="field"><label for="body_link_c">' . __('Links color:') . '</label> ' .
-form::color('body_link_c', array('default' => $blowup_user['body_link_c'])) . '</p>' .
+form::color('body_link_c', ['default' => $blowup_user['body_link_c']]) . '</p>' .
 
 '<p class="field"><label for="body_link_v_c">' . __('Visited links color:') . '</label> ' .
-form::color('body_link_v_c', array('default' => $blowup_user['body_link_v_c'])) . '</p>' .
+form::color('body_link_v_c', ['default' => $blowup_user['body_link_v_c']]) . '</p>' .
 
 '<p class="field"><label for="body_link_f_c">' . __('Focus links color:') . '</label> ' .
-form::color('body_link_f_c', array('default' => $blowup_user['body_link_f_c'])) . '</p>' .
+form::color('body_link_f_c', ['default' => $blowup_user['body_link_f_c']]) . '</p>' .
 
 '<h4 class="border-top">' . __('Page top') . '</h4>';
@@ -273,5 +273,5 @@
     echo
     '<p class="field"><label for="prelude_c">' . __('Prelude color:') . '</label> ' .
-    form::color('prelude_c', array('default' => $blowup_user['prelude_c'])) . '</p>';
+    form::color('prelude_c', ['default' => $blowup_user['prelude_c']]) . '</p>';
 }
 
@@ -287,8 +287,8 @@
 
 '<p class="field"><label for="blog_title_c">' . __('Main title color:') . '</label> ' .
-form::color('blog_title_c', array('default' => $blowup_user['blog_title_c'])) . '</p>' .
+form::color('blog_title_c', ['default' => $blowup_user['blog_title_c']]) . '</p>' .
 
 '<p class="field"><label for="blog_title_a">' . __('Main title alignment:') . '</label> ' .
-form::combo('blog_title_a', array(__('center') => 'center', __('left') => 'left', __('right') => 'right'), $blowup_user['blog_title_a']) . '</p>' .
+form::combo('blog_title_a', [__('center') => 'center', __('left') => 'left', __('right') => 'right'], $blowup_user['blog_title_a']) . '</p>' .
 
 '<p class="field"><label for="blog_title_p">' . __('Main title position (x:y)') . '</label> ' .
@@ -322,5 +322,5 @@
 '<h4 class="border-top">' . __('Sidebar') . '</h4>' .
 '<p class="field"><label for="sidebar_position">' . __('Sidebar position:') . '</label> ' .
-form::combo('sidebar_position', array(__('right') => 'right', __('left') => 'left'), $blowup_user['sidebar_position']) . '</p>' .
+form::combo('sidebar_position', [__('right') => 'right', __('left') => 'left'], $blowup_user['sidebar_position']) . '</p>' .
 
 '<p class="field"><label for="sidebar_text_f">' . __('Sidebar text font:') . '</label> ' .
@@ -331,5 +331,5 @@
 
 '<p class="field"><label for="sidebar_text_c">' . __('Sidebar text color:') . '</label> ' .
-form::color('sidebar_text_c', array('default' => $blowup_user['sidebar_text_c'])) . '</p>' .
+form::color('sidebar_text_c', ['default' => $blowup_user['sidebar_text_c']]) . '</p>' .
 
 '<p class="field"><label for="sidebar_title_f">' . __('Sidebar titles font:') . '</label> ' .
@@ -340,5 +340,5 @@
 
 '<p class="field"><label for="sidebar_title_c">' . __('Sidebar titles color:') . '</label> ' .
-form::color('sidebar_title_c', array('default' => $blowup_user['sidebar_title_c'])) . '</p>' .
+form::color('sidebar_title_c', ['default' => $blowup_user['sidebar_title_c']]) . '</p>' .
 
 '<p class="field"><label for="sidebar_title2_f">' . __('Sidebar 2nd level titles font:') . '</label> ' .
@@ -349,17 +349,17 @@
 
 '<p class="field"><label for="sidebar_title2_c">' . __('Sidebar 2nd level titles color:') . '</label> ' .
-form::color('sidebar_title2_c', array('default' => $blowup_user['sidebar_title2_c'])) . '</p>' .
+form::color('sidebar_title2_c', ['default' => $blowup_user['sidebar_title2_c']]) . '</p>' .
 
 '<p class="field"><label for="sidebar_line_c">' . __('Sidebar lines color:') . '</label> ' .
-form::color('sidebar_line_c', array('default' => $blowup_user['sidebar_line_c'])) . '</p>' .
+form::color('sidebar_line_c', ['default' => $blowup_user['sidebar_line_c']]) . '</p>' .
 
 '<p class="field"><label for="sidebar_link_c">' . __('Sidebar links color:') . '</label> ' .
-form::color('sidebar_link_c', array('default' => $blowup_user['sidebar_link_c'])) . '</p>' .
+form::color('sidebar_link_c', ['default' => $blowup_user['sidebar_link_c']]) . '</p>' .
 
 '<p class="field"><label for="sidebar_link_v_c">' . __('Sidebar visited links color:') . '</label> ' .
-form::color('sidebar_link_v_c', array('default' => $blowup_user['sidebar_link_v_c'])) . '</p>' .
+form::color('sidebar_link_v_c', ['default' => $blowup_user['sidebar_link_v_c']]) . '</p>' .
 
 '<p class="field"><label for="sidebar_link_f_c">' . __('Sidebar focus links color:') . '</label> ' .
-form::color('sidebar_link_f_c', array('default' => $blowup_user['sidebar_link_f_c'])) . '</p>' .
+form::color('sidebar_link_f_c', ['default' => $blowup_user['sidebar_link_f_c']]) . '</p>' .
 
 '<h4 class="border-top">' . __('Entries') . '</h4>' .
@@ -371,5 +371,5 @@
 
 '<p class="field"><label for="date_title_c">' . __('Date title color:') . '</label> ' .
-form::color('date_title_c', array('default' => $blowup_user['date_title_c'])) . '</p>' .
+form::color('date_title_c', ['default' => $blowup_user['date_title_c']]) . '</p>' .
 
 '<p class="field"><label for="post_title_f">' . __('Entry title font:') . '</label> ' .
@@ -380,25 +380,25 @@
 
 '<p class="field"><label for="post_title_c">' . __('Entry title color:') . '</label> ' .
-form::color('post_title_c', array('default' => $blowup_user['post_title_c'])) . '</p>';
+form::color('post_title_c', ['default' => $blowup_user['post_title_c']]) . '</p>';
 
 if ($can_write_images) {
     echo
     '<p class="field"><label for="post_comment_bg_c">' . __('Comment background color:') . '</label> ' .
-    form::color('post_comment_bg_c', array('default' => $blowup_user['post_comment_bg_c'])) . '</p>';
+    form::color('post_comment_bg_c', ['default' => $blowup_user['post_comment_bg_c']]) . '</p>';
 }
 
 echo
 '<p class="field"><label for="post_comment_c">' . __('Comment text color:') . '</label> ' .
-form::color('post_comment_c', array('default' => $blowup_user['post_comment_c'])) . '</p>';
+form::color('post_comment_c', ['default' => $blowup_user['post_comment_c']]) . '</p>';
 
 if ($can_write_images) {
     echo
     '<p class="field"><label for="post_commentmy_bg_c">' . __('My comment background color:') . '</label> ' .
-    form::color('post_commentmy_bg_c', array('default' => $blowup_user['post_commentmy_bg_c'])) . '</p>';
+    form::color('post_commentmy_bg_c', ['default' => $blowup_user['post_commentmy_bg_c']]) . '</p>';
 }
 
 echo
 '<p class="field"><label for="post_commentmy_c">' . __('My comment text color:') . '</label> ' .
-form::color('post_commentmy_c', array('default' => $blowup_user['post_commentmy_c'])) . '</p>' .
+form::color('post_commentmy_c', ['default' => $blowup_user['post_commentmy_c']]) . '</p>' .
 
 '<h4 class="border-top">' . __('Footer') . '</h4>' .
@@ -410,26 +410,26 @@
 
 '<p class="field"><label for="footer_c">' . __('Footer color:') . '</label> ' .
-form::color('footer_c', array('default' => $blowup_user['footer_c'])) . '</p>' .
+form::color('footer_c', ['default' => $blowup_user['footer_c']]) . '</p>' .
 
 '<p class="field"><label for="footer_l_c">' . __('Footer links color:') . '</label> ' .
-form::color('footer_l_c', array('default' => $blowup_user['footer_l_c'])) . '</p>' .
+form::color('footer_l_c', ['default' => $blowup_user['footer_l_c']]) . '</p>' .
 
 '<p class="field"><label for="footer_bg_c">' . __('Footer background color:') . '</label> ' .
-form::color('footer_bg_c', array('default' => $blowup_user['footer_bg_c'])) . '</p>';
+form::color('footer_bg_c', ['default' => $blowup_user['footer_bg_c']]) . '</p>';
 
 echo
 '<h4 class="border-top">' . __('Additional CSS') . '</h4>' .
 '<p><label for="extra_css">' . __('Any additional CSS styles (must be written using the CSS syntax):') . '</label> ' .
-form::textarea('extra_css', 72, 5, array(
+form::textarea('extra_css', 72, 5, [
     'default'    => html::escapeHTML($blowup_user['extra_css']),
     'class'      => 'maximal',
     'extra_html' => 'title="' . __('Additional CSS') . '"'
-)) .
+]) .
     '</p>' .
     '</div>';
 
 // Import / Export configuration
-$tmp_array   = array();
-$tmp_exclude = array('uploaded', 'top_height');
+$tmp_array   = [];
+$tmp_exclude = ['uploaded', 'top_height'];
 if ($blowup_user['top_image'] == 'custom') {
     $tmp_exclude[] = 'top_image';
@@ -445,9 +445,9 @@
 '<div id="bu_export_content">' .
 '<p>' . __('You can share your configuration using the following code. To apply a configuration, paste the code, click on "Apply code" and save.') . '</p>' .
-'<p>' . form::textarea('export_code', 72, 5, array(
+'<p>' . form::textarea('export_code', 72, 5, [
     'default'    => implode('; ', $tmp_array),
     'class'      => 'maximal',
     'extra_html' => 'title="' . __('Copy this code:') . '"'
-)) . '</p>' .
+]) . '</p>' .
     '</div>' .
     '</div>';
Index: plugins/blowupConfig/js/config.js
===================================================================
--- plugins/blowupConfig/js/config.js	(revision 3768)
+++ plugins/blowupConfig/js/config.js	(revision 3880)
@@ -39,11 +39,11 @@
 
   // Predefined styles
-  var styles_combo = document.createElement('select');
+  const styles_combo = document.createElement('select');
   $(styles_combo).append('<option value="">&nbsp;</option>');
   $(styles_combo).append('<option value="none">none</option>');
   $(styles_combo).attr('title', dotclear.msg.predefined_style_title);
 
-  for (var style in dotclear.blowup_styles) {
-    var styles_option = document.createElement('option');
+  for (let style in dotclear.blowup_styles) {
+    const styles_option = document.createElement('option');
     styles_option.value = dotclear.blowup_styles[style];
     $(styles_option).append(style);
@@ -68,11 +68,11 @@
 
   // Code import
-  var e = $('#bu_export_content');
+  const e = $('#bu_export_content');
 
-  $('#bu_export').toggleWithLegend($(e),{
-      legend_click: true
-  })
+  $('#bu_export').toggleWithLegend($(e), {
+    legend_click: true
+  });
 
-  var a = document.createElement('a');
+  const a = document.createElement('a');
   a.href = '#';
   $(a).text(dotclear.msg.apply_code);
@@ -81,5 +81,5 @@
 
   $(a).click(function() {
-    var code = e.find('#export_code');
+    const code = e.find('#export_code');
     if (code.size() == 0) {
       return false;
@@ -100,11 +100,13 @@
   function applyBlowupValues(code) {
     code = code.replace('\n', '');
-    var re = /(^| )([a-zA-Z0-9_]+):"([^"]*?)"(;|$)/g;
-    var reg = /^(.+):"([^"]*)"(;?)\s*$/;
-    var s = code.match(re);
+    const re = /(^| )([a-zA-Z0-9_]+):"([^"]*?)"(;|$)/g;
+    const reg = /^(.+):"([^"]*)"(;?)\s*$/;
+    const s = code.match(re);
 
     if (typeof(s) == 'object' && s.length > 0) {
-      var member, target, value;
-      for (var i = 0, s_length = s.length; i < s_length; i++) {
+      let member;
+      let target;
+      let value;
+      for (let i = 0, s_length = s.length; i < s_length; i++) {
         member = reg.exec(s[i]);
         target = member[1].replace(' ', '');
@@ -126,5 +128,5 @@
 
   function getColorLum(color) {
-    var rgb = [parseInt('0x' + color.substring(1, 3)) / 255,
+    const rgb = [parseInt('0x' + color.substring(1, 3)) / 255,
       parseInt('0x' + color.substring(3, 5)) / 255,
       parseInt('0x' + color.substring(5, 7)) / 255
Index: plugins/blowupConfig/lib/class.blowup.config.php
===================================================================
--- plugins/blowupConfig/lib/class.blowup.config.php	(revision 3731)
+++ plugins/blowupConfig/lib/class.blowup.config.php	(revision 3874)
@@ -17,6 +17,6 @@
     protected static $img_folder = 'blowup-images';
 
-    protected static $fonts = array(
-        'sans-serif' => array(
+    protected static $fonts = [
+        'sans-serif' => [
             'ss1' => 'Arial, Helvetica, sans-serif',
             'ss2' => 'Verdana,Geneva, Arial, Helvetica, sans-serif',
@@ -24,22 +24,22 @@
             'ss4' => '"Trebuchet MS", Helvetica, sans-serif',
             'ss5' => 'Impact, Charcoal, sans-serif'
-        ),
-
-        'serif'      => array(
+        ],
+
+        'serif'      => [
             's1' => 'Times, "Times New Roman", serif',
             's2' => 'Georgia, serif',
             's3' => 'Baskerville, "Palatino Linotype", serif'
-        ),
-
-        'monospace'  => array(
+        ],
+
+        'monospace'  => [
             'm1' => '"Andale Mono", "Courier New", monospace',
             'm2' => '"Courier New", Courier, mono, monospace'
-        )
-    );
-
-    protected static $fonts_combo = array();
-    protected static $fonts_list  = array();
-
-    public static $top_images = array(
+        ]
+    ];
+
+    protected static $fonts_combo = [];
+    protected static $fonts_list  = [];
+
+    public static $top_images = [
         'default'        => 'Default',
         'blank'          => 'Blank',
@@ -58,5 +58,5 @@
         'roadrunner-2'   => 'Road Runner 2',
         'typo'           => 'Typo'
-    );
+    ];
 
     public static function fontsList()
@@ -65,5 +65,5 @@
             self::$fonts_combo[__('default')] = '';
             foreach (self::$fonts as $family => $g) {
-                $fonts = array();
+                $fonts = [];
                 foreach ($g as $code => $font) {
                     $fonts[str_replace('"', '', $font)] = $code;
@@ -157,5 +157,5 @@
         }
 
-        $css = array();
+        $css = [];
 
         /* Sidebar position
@@ -199,9 +199,9 @@
             dcThemeConfig::prop($css, '#top h1 span', 'text-indent', '-5000px');
             dcThemeConfig::prop($css, '#top h1', 'top', '0px');
-            $css['#top h1 a'] = array(
+            $css['#top h1 a'] = [
                 'display' => 'block',
                 'height'  => $s['top_height'] ? ($s['top_height'] - 10) . 'px' : '120px',
                 'width'   => '800px'
-            );
+            ];
         }
         dcThemeConfig::prop($css, '#top', 'height', $s['top_height']);
@@ -325,9 +325,9 @@
         }
 
-        $body_fill = array(
+        $body_fill = [
             'light'  => dirname(__FILE__) . '/../alpha-img/gradient-l.png',
             'medium' => dirname(__FILE__) . '/../alpha-img/gradient-m.png',
             'dark'   => dirname(__FILE__) . '/../alpha-img/gradient-d.png'
-        );
+        ];
 
         $body_g = isset($body_fill[$gradient]) ? $body_fill[$gradient] : false;
Index: plugins/breadcrumb/_admin.php
===================================================================
--- plugins/breadcrumb/_admin.php	(revision 3731)
+++ plugins/breadcrumb/_admin.php	(revision 3874)
@@ -15,6 +15,6 @@
 __('Breadcrumb') . __('Breadcrumb for Dotclear');
 
-$core->addBehavior('adminBlogPreferencesForm', array('breadcrumbBehaviors', 'adminBlogPreferencesForm'));
-$core->addBehavior('adminBeforeBlogSettingsUpdate', array('breadcrumbBehaviors', 'adminBeforeBlogSettingsUpdate'));
+$core->addBehavior('adminBlogPreferencesForm', ['breadcrumbBehaviors', 'adminBlogPreferencesForm']);
+$core->addBehavior('adminBeforeBlogSettingsUpdate', ['breadcrumbBehaviors', 'adminBeforeBlogSettingsUpdate']);
 
 class breadcrumbBehaviors
Index: plugins/breadcrumb/_define.php
===================================================================
--- plugins/breadcrumb/_define.php	(revision 3731)
+++ plugins/breadcrumb/_define.php	(revision 3874)
@@ -17,10 +17,10 @@
     "Franck Paul",             // Author
     '0.7',                     // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin', // Permissions
         'type'        => 'plugin',             // Type
-        'settings'    => array(
+        'settings'    => [
             'blog' => '#params.breadcrumb_params'
-        )
-    )
+        ]
+    ]
 );
Index: plugins/breadcrumb/_public.php
===================================================================
--- plugins/breadcrumb/_public.php	(revision 3731)
+++ plugins/breadcrumb/_public.php	(revision 3874)
@@ -13,5 +13,5 @@
 
 # Breadcrumb template functions
-$core->tpl->addValue('Breadcrumb', array('tplBreadcrumb', 'breadcrumb'));
+$core->tpl->addValue('Breadcrumb', ['tplBreadcrumb', 'breadcrumb']);
 
 class tplBreadcrumb
Index: plugins/buildtools/_admin.php
===================================================================
--- plugins/buildtools/_admin.php	(revision 3731)
+++ plugins/buildtools/_admin.php	(revision 3874)
@@ -11,5 +11,5 @@
 
 if (!defined('DC_CONTEXT_ADMIN')) {return;}
-$core->addBehavior('dcMaintenanceInit', array('dcBuildTools', 'maintenanceAdmin'));
+$core->addBehavior('dcMaintenanceInit', ['dcBuildTools', 'maintenanceAdmin']);
 
 class dcBuildTools
Index: plugins/buildtools/_define.php
===================================================================
--- plugins/buildtools/_define.php	(revision 3731)
+++ plugins/buildtools/_define.php	(revision 3874)
@@ -17,6 +17,6 @@
     "dcTeam",                                 // Author
     '1.0',                                    // Version
-    array(
+    [
         'permissions' => 'admin'
-    )
+    ]
 );
Index: plugins/dcCKEditor/_admin.php
===================================================================
--- plugins/dcCKEditor/_admin.php	(revision 3731)
+++ plugins/dcCKEditor/_admin.php	(revision 3874)
@@ -24,9 +24,9 @@
     $core->addEditorFormater('dcCKEditor', 'xhtml', function ($s) {return $s;});
 
-    $core->addBehavior('adminPostEditor', array('dcCKEditorBehaviors', 'adminPostEditor'));
-    $core->addBehavior('adminPopupMedia', array('dcCKEditorBehaviors', 'adminPopupMedia'));
-    $core->addBehavior('adminPopupLink', array('dcCKEditorBehaviors', 'adminPopupLink'));
-    $core->addBehavior('adminPopupPosts', array('dcCKEditorBehaviors', 'adminPopupPosts'));
+    $core->addBehavior('adminPostEditor', ['dcCKEditorBehaviors', 'adminPostEditor']);
+    $core->addBehavior('adminPopupMedia', ['dcCKEditorBehaviors', 'adminPopupMedia']);
+    $core->addBehavior('adminPopupLink', ['dcCKEditorBehaviors', 'adminPopupLink']);
+    $core->addBehavior('adminPopupPosts', ['dcCKEditorBehaviors', 'adminPopupPosts']);
 
-    $core->addBehavior('adminMediaURL', array('dcCKEditorBehaviors', 'adminMediaURL'));
+    $core->addBehavior('adminMediaURL', ['dcCKEditorBehaviors', 'adminMediaURL']);
 }
Index: plugins/dcCKEditor/_define.php
===================================================================
--- plugins/dcCKEditor/_define.php	(revision 3731)
+++ plugins/dcCKEditor/_define.php	(revision 3874)
@@ -17,11 +17,11 @@
     "dotclear Team",                 // Author
     "1.1.0",                         // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'type'        => 'plugin',
-        'settings'    => array(
+        'settings'    => [
             'self' => '',
             'pref' => '#user-options.user_options_edition'
-        )
-    )
+        ]
+    ]
 );
Index: plugins/dcCKEditor/inc/_config.php
===================================================================
--- plugins/dcCKEditor/inc/_config.php	(revision 3731)
+++ plugins/dcCKEditor/inc/_config.php	(revision 3875)
@@ -40,5 +40,5 @@
 
             // default tags : p;h1;h2;h3;h4;h5;h6;pre;address
-            $allowed_tags = array('p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'address');
+            $allowed_tags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'pre', 'address'];
             if (!empty($_POST['dcckeditor_format_tags'])) {
                 $tags     = explode(';', $_POST['dcckeditor_format_tags']);
@@ -75,3 +75,3 @@
 }
 
-include dirname(__FILE__) . '/../tpl/index.tpl';
+include dirname(__FILE__) . '/../tpl/index.php';
Index: plugins/dcCKEditor/inc/dc.ckeditor.behaviors.php
===================================================================
--- plugins/dcCKEditor/inc/dc.ckeditor.behaviors.php	(revision 3731)
+++ plugins/dcCKEditor/inc/dc.ckeditor.behaviors.php	(revision 3874)
@@ -23,5 +23,5 @@
      * @param syntax   <b>string</b> wanted syntax (xhtml)
      */
-    public static function adminPostEditor($editor = '', $context = '', array $tags = array(), $syntax = 'xhtml')
+    public static function adminPostEditor($editor = '', $context = '', array $tags = [], $syntax = 'xhtml')
     {
         if (empty($editor) || $editor != 'dcCKEditor' || $syntax != 'xhtml') {return;}
Index: plugins/dcCKEditor/js/ckeditor-plugins/dclink/plugin.js
===================================================================
--- plugins/dcCKEditor/js/ckeditor-plugins/dclink/plugin.js	(revision 2962)
+++ plugins/dcCKEditor/js/ckeditor-plugins/dclink/plugin.js	(revision 3880)
@@ -1,47 +1,50 @@
+/*global CKEDITOR, dotclear, $ */
+'use strict';
+
 (function() {
-	CKEDITOR.plugins.add('dclink', {
-		icons: 'dclink',
-		init: function(editor) {
-			editor.addCommand('dcLinkCommand', {
-				exec: function(editor) {
-					if (editor.getSelection().getSelectedElement()!=null
-					    || editor.getSelection().getNative().toString().replace(/\s*/,'')!='') {
-						$.toolbarPopup('popup_link.php?plugin_id=dcCKEditor');
-					}
-				}
-			});
+  CKEDITOR.plugins.add('dclink', {
+    icons: 'dclink',
+    init: function(editor) {
+      editor.addCommand('dcLinkCommand', {
+        exec: function(editor) {
+          if (editor.getSelection().getSelectedElement() != null ||
+            editor.getSelection().getNative().toString().replace(/\s*/, '') != '') {
+            $.toolbarPopup('popup_link.php?plugin_id=dcCKEditor');
+          }
+        }
+      });
 
-			editor.ui.addButton('dcLink', {
-				label: dotclear.msg.link_title,
-				command: 'dcLinkCommand',
-				toolbar: 'insert'
-			});
+      editor.ui.addButton('dcLink', {
+        label: dotclear.msg.link_title,
+        command: 'dcLinkCommand',
+        toolbar: 'insert'
+      });
 
-			editor.on('doubleclick',function(e) {
-				var element = CKEDITOR.plugins.link.getSelectedLink(editor) || e.data.element;
-				if (!element.isReadOnly()) {
-					if (element.is('a')
-					    && !element.hasClass('media-link') // link to original media @see js/popup_media.js
-					    && !element.hasClass('ref-post')) {    // link to an entry @see js/popup_posts.js
+      editor.on('doubleclick', function(e) {
+        const element = CKEDITOR.plugins.link.getSelectedLink(editor) || e.data.element;
+        if (!element.isReadOnly()) {
+          if (element.is('a') &&
+            !element.hasClass('media-link') && // link to original media @see js/popup_media.js
+            !element.hasClass('ref-post')) { // link to an entry @see js/popup_posts.js
 
-						editor.getSelection().selectElement(element);
+            editor.getSelection().selectElement(element);
 
-						var popup_url = 'popup_link.php?plugin_id=dcCKEditor';
-						if (element.getAttribute('href')) {
-							popup_url += '&href='+element.getAttribute('href');
-						}
-						if (element.getAttribute('hreflang')) {
-							popup_url += '&hreflang='+element.getAttribute('hreflang');
-						}
-						if (element.getAttribute('title')) {
-							popup_url += '&title='+element.getAttribute('title');
-						}
+            let popup_url = 'popup_link.php?plugin_id=dcCKEditor';
+            if (element.getAttribute('href')) {
+              popup_url += '&href=' + element.getAttribute('href');
+            }
+            if (element.getAttribute('hreflang')) {
+              popup_url += '&hreflang=' + element.getAttribute('hreflang');
+            }
+            if (element.getAttribute('title')) {
+              popup_url += '&title=' + element.getAttribute('title');
+            }
 
-						$.toolbarPopup(popup_url);
-						return false;
-					}
-				}
-			});
-		}
-	});
+            $.toolbarPopup(popup_url);
+            return false;
+          }
+        }
+      });
+    }
+  });
 })();
Index: plugins/dcCKEditor/js/ckeditor-plugins/entrylink/plugin.js
===================================================================
--- plugins/dcCKEditor/js/ckeditor-plugins/entrylink/plugin.js	(revision 2901)
+++ plugins/dcCKEditor/js/ckeditor-plugins/entrylink/plugin.js	(revision 3880)
@@ -1,36 +1,41 @@
+/*global CKEDITOR, dotclear, $ */
+'use strict';
+
 (function() {
-	CKEDITOR.plugins.add('entrylink', {
-		icons: 'entrylink',
-		init: function(editor) {
-			popup_params = { 'width': 760, 'height': 500};
+  CKEDITOR.plugins.add('entrylink', {
+    icons: 'entrylink',
+    init: function(editor) {
+      const popup_params = {
+        'width': 760,
+        'height': 500
+      };
 
-			editor.addCommand('entryLinkCommand', {
-				exec: function(editor) {
-					if (editor.getSelection().getNative().toString().replace(/\s*/,'')!='') {
-						$.toolbarPopup('popup_posts.php?popup=1&plugin_id=dcCKEditor', popup_params);
-					}
-				}
-			});
+      editor.addCommand('entryLinkCommand', {
+        exec: function(editor) {
+          if (editor.getSelection().getNative().toString().replace(/\s*/, '') != '') {
+            $.toolbarPopup('popup_posts.php?popup=1&plugin_id=dcCKEditor', popup_params);
+          }
+        }
+      });
 
-			editor.ui.addButton('EntryLink', {
-				label: dotclear.msg.post_link_title,
-				command: 'entryLinkCommand',
-				toolbar: 'insert'
-			});
+      editor.ui.addButton('EntryLink', {
+        label: dotclear.msg.post_link_title,
+        command: 'entryLinkCommand',
+        toolbar: 'insert'
+      });
 
-			editor.on('doubleclick',function(e) {
-				var element = CKEDITOR.plugins.link.getSelectedLink(editor) || e.data.element;
-				if (!element.isReadOnly()) {
-					if (element.is('a')
-					    && !element.hasClass('media-link')
-					    && element.hasClass('ref-post')) { // link to original media @see js/popup_media.js
-						editor.getSelection().selectElement(element);
+      editor.on('doubleclick', function(e) {
+        const element = CKEDITOR.plugins.link.getSelectedLink(editor) || e.data.element;
+        if (!element.isReadOnly()) {
+          if (element.is('a') && !element.hasClass('media-link') && element.hasClass('ref-post')) {
+            // link to original media @see js/popup_media.js
+            editor.getSelection().selectElement(element);
 
-						$.toolbarPopup('popup_posts.php?popup=1&plugin_id=dcCKEditor', popup_params);
-						return false;
-					}
-				}
-			});
-		}
-	});
+            $.toolbarPopup('popup_posts.php?popup=1&plugin_id=dcCKEditor', popup_params);
+            return false;
+          }
+        }
+      });
+    }
+  });
 })();
Index: plugins/dcCKEditor/js/ckeditor-plugins/img/plugin.js
===================================================================
--- plugins/dcCKEditor/js/ckeditor-plugins/img/plugin.js	(revision 2869)
+++ plugins/dcCKEditor/js/ckeditor-plugins/img/plugin.js	(revision 3880)
@@ -1,16 +1,19 @@
+/*global CKEDITOR, dotclear */
+'use strict';
+
 (function() {
-	CKEDITOR.plugins.add('img', {
-		init: function(editor) {
-			editor.addCommand('dcImgCommand', new CKEDITOR.dialogCommand('imgDialog'));
+  CKEDITOR.plugins.add('img', {
+    init: function(editor) {
+      editor.addCommand('dcImgCommand', new CKEDITOR.dialogCommand('imgDialog'));
 
-			CKEDITOR.dialog.add('imgDialog', this.path+'dialogs/img.js');
+      CKEDITOR.dialog.add('imgDialog', this.path + 'dialogs/img.js');
 
-			editor.ui.addButton('img', {
-				label: dotclear.msg.img_title,
-				command: 'dcImgCommand',
-				toolbar: 'insert',
-				icon: this.path + 'icons/img.png'
-			});
-		}
-	});
+      editor.ui.addButton('img', {
+        label: dotclear.msg.img_title,
+        command: 'dcImgCommand',
+        toolbar: 'insert',
+        icon: this.path + 'icons/img.png'
+      });
+    }
+  });
 })();
Index: plugins/dcCKEditor/js/ckeditor-plugins/media/plugin.js
===================================================================
--- plugins/dcCKEditor/js/ckeditor-plugins/media/plugin.js	(revision 2835)
+++ plugins/dcCKEditor/js/ckeditor-plugins/media/plugin.js	(revision 3880)
@@ -1,30 +1,36 @@
+/*global CKEDITOR, dotclear, $ */
+'use strict';
+
 (function() {
-	CKEDITOR.plugins.add('media', {
-		icons: 'media',
-		init: function(editor) {
-			popup_params = { 'width': 760, 'height': 500};
+  CKEDITOR.plugins.add('media', {
+    icons: 'media',
+    init: function(editor) {
+      const popup_params = {
+        'width': 760,
+        'height': 500
+      };
 
-			editor.addCommand('mediaCommand', {
-				exec: function(editor) {
-					$.toolbarPopup('media.php?popup=1&plugin_id=dcCKEditor', popup_params);
-				}
-			});
+      editor.addCommand('mediaCommand', {
+        exec: function() {
+          $.toolbarPopup('media.php?popup=1&plugin_id=dcCKEditor', popup_params);
+        }
+      });
 
-			editor.ui.addButton('Media', {
-				label: dotclear.msg.img_select_title,
-				command: 'mediaCommand',
-				toolbar: 'insert'
-			});
+      editor.ui.addButton('Media', {
+        label: dotclear.msg.img_select_title,
+        command: 'mediaCommand',
+        toolbar: 'insert'
+      });
 
-			editor.on('doubleclick',function(e) {
-				var element = CKEDITOR.plugins.link.getSelectedLink(editor) || e.data.element;
-				if (!element.isReadOnly()) {
-					if (element.is('img') || (element.is('a') && element.hasClass('media-link'))) {
-						$.toolbarPopup('media.php?popup=1&plugin_id=dcCKEditor', popup_params);
-						return false;
-					}
-				}
-			});
-		}
-	});
+      editor.on('doubleclick', function(e) {
+        const element = CKEDITOR.plugins.link.getSelectedLink(editor) || e.data.element;
+        if (!element.isReadOnly()) {
+          if (element.is('img') || (element.is('a') && element.hasClass('media-link'))) {
+            $.toolbarPopup('media.php?popup=1&plugin_id=dcCKEditor', popup_params);
+            return false;
+          }
+        }
+      });
+    }
+  });
 })();
Index: plugins/dcCKEditor/js/ckeditor-skins/dotclear/skin.js
===================================================================
--- plugins/dcCKEditor/js/ckeditor-skins/dotclear/skin.js	(revision 2738)
+++ plugins/dcCKEditor/js/ckeditor-skins/dotclear/skin.js	(revision 3880)
@@ -1,2 +1,5 @@
+/*global CKEDITOR */
+'use strict';
+
 CKEDITOR.skin.name = 'dotclear';
 
Index: plugins/dcCKEditor/js/popup_link.js
===================================================================
--- plugins/dcCKEditor/js/popup_link.js	(revision 3709)
+++ plugins/dcCKEditor/js/popup_link.js	(revision 3880)
@@ -8,13 +8,13 @@
 
   $('#link-insert-ok').click(function() {
-    var insert_form = $('#link-insert-form').get(0);
+    const insert_form = $('#link-insert-form').get(0);
     if (insert_form == undefined) {
       return;
     }
 
-    var editor_name = window.opener.$.getEditorName(),
-      editor = window.opener.CKEDITOR.instances[editor_name],
-      link = '',
-      selected_element;
+    const editor_name = window.opener.$.getEditorName();
+    const editor = window.opener.CKEDITOR.instances[editor_name];
+    let link = '';
+    let selected_element;
     if (editor.getSelection().getSelectedElement() != null) {
       selected_element = editor.getSelection().getSelectedElement();
Index: plugins/dcCKEditor/js/popup_media.js
===================================================================
--- plugins/dcCKEditor/js/popup_media.js	(revision 3725)
+++ plugins/dcCKEditor/js/popup_media.js	(revision 3880)
@@ -8,35 +8,35 @@
 
   $('#media-insert-ok').click(function() {
-    var insert_form = $('#media-insert-form').get(0);
+    const insert_form = $('#media-insert-form').get(0);
     if (insert_form === undefined) {
       return;
     }
 
-    var editor_name = window.opener.$.getEditorName(),
-      editor = window.opener.CKEDITOR.instances[editor_name],
-      type = insert_form.elements.type.value,
-      media_align_grid = {
-        left: 'float: left; margin: 0 1em 1em 0;',
-        right: 'float: right; margin: 0 0 1em 1em;',
-        center: 'margin: 0 auto; display: table;'
-      };
+    const editor_name = window.opener.$.getEditorName();
+    const editor = window.opener.CKEDITOR.instances[editor_name];
+    const type = insert_form.elements.type.value;
+    const media_align_grid = {
+      left: 'float: left; margin: 0 1em 1em 0;',
+      right: 'float: right; margin: 0 0 1em 1em;',
+      center: 'margin: 0 auto; display: table;'
+    };
 
     if (type == 'image') {
       if (editor.mode == 'wysiwyg') {
 
-        var align = $('input[name="alignment"]:checked', insert_form).val();
-        var media_legend = $('input[name="legend"]:checked', insert_form).val();
-        var img_description = $('input[name="description"]', insert_form).val();
-        var style = '';
-        var template = '';
-        var template_figure = [
+        const align = $('input[name="alignment"]:checked', insert_form).val();
+        let media_legend = $('input[name="legend"]:checked', insert_form).val();
+        const img_description = $('input[name="description"]', insert_form).val();
+        let style = '';
+        let template = '';
+        let template_figure = [
           '',
           ''
         ];
-        var template_link = [
+        let template_link = [
           '',
           ''
         ];
-        var template_image = '';
+        let template_image = '';
 
         if (media_legend != '' && media_legend != 'title' && media_legend != 'none') {
@@ -58,5 +58,5 @@
           template_figure[1] = template_figure[1] + '</figure>';
         }
-        template_image = '<img class="media" src="{imgSrc}" alt="{imgAlt}"' + style + '/>';
+        template_image = `<img class="media" src="{imgSrc}" alt="{imgAlt}"${style}/>`;
         if ($('input[name="insertion"]:checked', insert_form).val() == 'link') {
           // With a link to original
@@ -66,6 +66,6 @@
         template = template_figure[0] + template_link[0] + template_image + template_link[1] + template_figure[1];
 
-        var block = new window.opener.CKEDITOR.template(template);
-        var params = {};
+        let block = new window.opener.CKEDITOR.template(template);
+        let params = {};
 
         // Set parameters for template
@@ -86,32 +86,34 @@
 
         // Insert element
-        var figure = window.opener.CKEDITOR.dom.element.createFromHtml(
+        const figure = window.opener.CKEDITOR.dom.element.createFromHtml(
           block.output(params), editor.document
         );
         editor.insertElement(figure);
       }
+
     } else if (type == 'mp3') {
       // Audio media
-      var player_audio = $('#public_player').val();
-      var align_audio = $('input[name="alignment"]:checked', insert_form).val();
+      let player_audio = $('#public_player').val();
+      const align_audio = $('input[name="alignment"]:checked', insert_form).val();
 
       if (align_audio != undefined && align_audio != 'none') {
-        player_audio = '<div style="' + media_align_grid[align_audio] + '">' + player_audio + '</div>';
+        player_audio = `<div style="${media_align_grid[align_audio]}">${player_audio}</div>`;
       }
       editor.insertElement(window.opener.CKEDITOR.dom.element.createFromHtml(player_audio));
+
     } else if (type == 'flv') {
       // Video media
-      var oplayer = $('<div>' + $('#public_player').val() + '</div>');
-      var flashvars = $('[name=FlashVars]', oplayer).val();
+      const oplayer = $(`<div>${$('#public_player').val()}</div>`);
+      let flashvars = $('[name=FlashVars]', oplayer).val();
 
-      var align_video = $('input[name="alignment"]:checked', insert_form).val();
+      const align_video = $('input[name="alignment"]:checked', insert_form).val();
 
-      var title = insert_form.elements.title.value;
+      const title = insert_form.elements.title.value;
       if (title) {
-        flashvars = 'title=' + encodeURI(title) + '&amp;' + flashvars;
+        flashvars = `title=${encodeURI(title)}&amp;${flashvars}`;
       }
 
-      var vw = $('#video_w').val();
-      var vh = $('#video_h').val();
+      const vw = $('#video_w').val();
+      const vh = $('#video_h').val();
 
       if (vw > 0) {
@@ -135,16 +137,16 @@
 
       $('[name=FlashVars]', oplayer).val(flashvars);
-      var player_video = oplayer.html();
+      let player_video = oplayer.html();
 
       if (align_video != undefined && align_video != 'none') {
-        player_video = '<div style="' + media_align_grid[align_video] + '">' + player_video + '</div>';
+        player_video = `<div style="${media_align_grid[align_video]}">${player_video}</div>`;
       }
       editor.insertElement(window.opener.CKEDITOR.dom.element.createFromHtml(player_video));
+
     } else {
       // Unknown media type
-      var link = '<a href="';
-      link += window.opener.$.stripBaseURL($('input[name="url"]', insert_form).val());
-      link += '">' + window.opener.CKEDITOR.tools.htmlEncodeAttr(insert_form.elements.title.value) + '</a>';
-      var element = window.opener.CKEDITOR.dom.element.createFromHtml(link);
+      const url = window.opener.$.stripBaseURL($('input[name="url"]', insert_form).val());
+      const text = window.opener.CKEDITOR.tools.htmlEncodeAttr(insert_form.elements.title.value);
+      const element = window.opener.CKEDITOR.dom.element.createFromHtml(`<a href="${url}">${text}</a>`);
 
       editor.insertElement(element);
Index: plugins/dcCKEditor/js/popup_posts.js
===================================================================
--- plugins/dcCKEditor/js/popup_posts.js	(revision 3709)
+++ plugins/dcCKEditor/js/popup_posts.js	(revision 3880)
@@ -9,12 +9,12 @@
   $('#form-entries tr>td.maximal>a').click(function(e) {
     e.preventDefault();
-    var editor_name = window.opener.$.getEditorName(),
-      editor = window.opener.CKEDITOR.instances[editor_name],
-      link = '',
-      selected_text = editor.getSelection().getNative().toString();
+    const editor_name = window.opener.$.getEditorName();
+    const editor = window.opener.CKEDITOR.instances[editor_name];
+    let link = '';
+    const selected_text = editor.getSelection().getNative().toString();
 
     if (editor.mode == 'wysiwyg') {
       link = '<a class="ref-post" href="' + window.opener.$.stripBaseURL($(this).attr('title')) + '">' + selected_text + '</a>';
-      var element = window.opener.CKEDITOR.dom.element.createFromHtml(link);
+      const element = window.opener.CKEDITOR.dom.element.createFromHtml(link);
       editor.insertElement(element);
     }
Index: plugins/dcCKEditor/tpl/index.php
===================================================================
--- plugins/dcCKEditor/tpl/index.php	(revision 3875)
+++ plugins/dcCKEditor/tpl/index.php	(revision 3875)
@@ -0,0 +1,109 @@
+<html>
+  <head>
+    <title>
+      dcCKEditor
+    </title>
+  </head>
+  <body>
+    <?php echo dcPage::breadcrumb([__('Plugins') =>
+    '', __('dcCKEditor') => '']) . dcPage::notices(); ?>
+    <?php if ($is_admin): ?>
+    <h3 class="hidden-if-js">
+      <?php echo __('Settings'); ?>
+    </h3>
+    <form action="<?php echo $p_url; ?>" enctype="multipart/form-data" method="post">
+      <div class="fieldset">
+        <h3>
+          <?php echo __('Plugin activation'); ?>
+        </h3>
+        <p>
+          <label class="classic" for="dcckeditor_active">
+            <?php echo form::checkbox('dcckeditor_active', 1, $dcckeditor_active); ?>
+            <?php echo __('Enable dcCKEditor plugin'); ?>
+          </label>
+        </p>
+      </div>
+      <?php if ($dcckeditor_active): ?>
+      <div class="fieldset">
+        <h3>
+          <?php echo __('Options'); ?>
+        </h3>
+        <p>
+          <?php echo form::checkbox('dcckeditor_alignment_buttons', 1, $dcckeditor_alignment_buttons); ?>
+          <label class="classic" for="dcckeditor_alignment_buttons">
+            <?php echo __('Add alignment buttons'); ?>
+          </label>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_list_buttons', 1, $dcckeditor_list_buttons); ?>
+          <label class="classic" for="dcckeditor_list_buttons">
+            <?php echo __('Add lists buttons'); ?>
+          </label>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_textcolor_button', 1, $dcckeditor_textcolor_button); ?>
+          <label class="classic" for="dcckeditor_textcolor_button">
+            <?php echo __('Add text color button'); ?>
+          </label>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_background_textcolor_button', 1, $dcckeditor_background_textcolor_button); ?>
+          <label class="classic" for="dcckeditor_background_textcolor_button">
+            <?php echo __('Add background text color button'); ?>
+          </label>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_cancollapse_button', 1, $dcckeditor_cancollapse_button); ?>
+          <label class="classic" for="dcckeditor_cancollapse_button">
+            <?php echo __('Add collapse button'); ?>
+          </label>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_format_select', 1, $dcckeditor_format_select); ?>
+          <label class="classic" for="dcckeditor_format_select">
+            <?php echo __('Add format selection'); ?>
+          </label>
+        </p>
+        <p>
+          <label class="classic" for="dcckeditor_format_tags">
+            <?php echo __('Custom formats'); ?>
+          </label>
+          <?php echo form::field('dcckeditor_format_tags', 100, 255, $dcckeditor_format_tags); ?>
+        </p>
+        <p class="clear form-note">
+          <?php echo __('Default formats are p;h1;h2;h3;h4;h5;h6;pre;address'); ?>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_table_button', 1, $dcckeditor_table_button); ?>
+          <label class="classic" for="dcckeditor_table_button">
+            <?php echo __('Add table button'); ?>
+          </label>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_clipboard_buttons', 1, $dcckeditor_clipboard_buttons); ?>
+          <label class="classic" for="dcckeditor_clipboard_buttons">
+            <?php echo __('Add clipboard buttons'); ?>
+          </label>
+        </p>
+        <p class="clear form-note">
+          <?php echo __('Copy, Paste, Paste Text, Paste from Word'); ?>
+        </p>
+        <p>
+          <?php echo form::checkbox('dcckeditor_disable_native_spellchecker', 1, $dcckeditor_disable_native_spellchecker); ?>
+          <label class="classic" for="dcckeditor_disable_native_spellchecker">
+            <?php echo __('Disables the built-in spell checker if the browser provides one'); ?>
+          </label>
+        </p>
+      </div>
+      <?php endif;?>
+      <p>
+        <input name="p" type="hidden" value="dcCKEditor"/>
+        <?php echo $core->
+    formNonce(); ?>
+        <input name="saveconfig" type="submit" value="<?php echo __('Save configuration'); ?>"/>
+      </p>
+    </form>
+    <?php endif;?>
+    <?php dcPage::helpBlock('dcCKEditor');?>
+  </body>
+</html>
Index: lugins/dcCKEditor/tpl/index.tpl
===================================================================
--- plugins/dcCKEditor/tpl/index.tpl	(revision 3730)
+++ 	(revision )
@@ -1,109 +1,0 @@
-<html>
-  <head>
-    <title>
-      dcCKEditor
-    </title>
-  </head>
-  <body>
-    <?php echo dcPage::breadcrumb(array(__('Plugins') =>
-    '', __('dcCKEditor') => '')) . dcPage::notices(); ?>
-    <?php if ($is_admin): ?>
-    <h3 class="hidden-if-js">
-      <?php echo __('Settings'); ?>
-    </h3>
-    <form action="<?php echo $p_url; ?>" enctype="multipart/form-data" method="post">
-      <div class="fieldset">
-        <h3>
-          <?php echo __('Plugin activation'); ?>
-        </h3>
-        <p>
-          <label class="classic" for="dcckeditor_active">
-            <?php echo form::checkbox('dcckeditor_active', 1, $dcckeditor_active); ?>
-            <?php echo __('Enable dcCKEditor plugin'); ?>
-          </label>
-        </p>
-      </div>
-      <?php if ($dcckeditor_active): ?>
-      <div class="fieldset">
-        <h3>
-          <?php echo __('Options'); ?>
-        </h3>
-        <p>
-          <?php echo form::checkbox('dcckeditor_alignment_buttons', 1, $dcckeditor_alignment_buttons); ?>
-          <label class="classic" for="dcckeditor_alignment_buttons">
-            <?php echo __('Add alignment buttons'); ?>
-          </label>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_list_buttons', 1, $dcckeditor_list_buttons); ?>
-          <label class="classic" for="dcckeditor_list_buttons">
-            <?php echo __('Add lists buttons'); ?>
-          </label>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_textcolor_button', 1, $dcckeditor_textcolor_button); ?>
-          <label class="classic" for="dcckeditor_textcolor_button">
-            <?php echo __('Add text color button'); ?>
-          </label>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_background_textcolor_button', 1, $dcckeditor_background_textcolor_button); ?>
-          <label class="classic" for="dcckeditor_background_textcolor_button">
-            <?php echo __('Add background text color button'); ?>
-          </label>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_cancollapse_button', 1, $dcckeditor_cancollapse_button); ?>
-          <label class="classic" for="dcckeditor_cancollapse_button">
-            <?php echo __('Add collapse button'); ?>
-          </label>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_format_select', 1, $dcckeditor_format_select); ?>
-          <label class="classic" for="dcckeditor_format_select">
-            <?php echo __('Add format selection'); ?>
-          </label>
-        </p>
-        <p>
-          <label class="classic" for="dcckeditor_format_tags">
-            <?php echo __('Custom formats'); ?>
-          </label>
-          <?php echo form::field('dcckeditor_format_tags', 100, 255, $dcckeditor_format_tags); ?>
-        </p>
-        <p class="clear form-note">
-          <?php echo __('Default formats are p;h1;h2;h3;h4;h5;h6;pre;address'); ?>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_table_button', 1, $dcckeditor_table_button); ?>
-          <label class="classic" for="dcckeditor_table_button">
-            <?php echo __('Add table button'); ?>
-          </label>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_clipboard_buttons', 1, $dcckeditor_clipboard_buttons); ?>
-          <label class="classic" for="dcckeditor_clipboard_buttons">
-            <?php echo __('Add clipboard buttons'); ?>
-          </label>
-        </p>
-        <p class="clear form-note">
-          <?php echo __('Copy, Paste, Paste Text, Paste from Word'); ?>
-        </p>
-        <p>
-          <?php echo form::checkbox('dcckeditor_disable_native_spellchecker', 1, $dcckeditor_disable_native_spellchecker); ?>
-          <label class="classic" for="dcckeditor_disable_native_spellchecker">
-            <?php echo __('Disables the built-in spell checker if the browser provides one'); ?>
-          </label>
-        </p>
-      </div>
-      <?php endif;?>
-      <p>
-        <input name="p" type="hidden" value="dcCKEditor"/>
-        <?php echo $core->
-    formNonce(); ?>
-        <input name="saveconfig" type="submit" value="<?php echo __('Save configuration'); ?>"/>
-      </p>
-    </form>
-    <?php endif;?>
-    <?php dcPage::helpBlock('dcCKEditor');?>
-  </body>
-</html>
Index: plugins/dcLegacyEditor/_admin.php
===================================================================
--- plugins/dcLegacyEditor/_admin.php	(revision 3731)
+++ plugins/dcLegacyEditor/_admin.php	(revision 3874)
@@ -27,9 +27,9 @@
 
     $core->addEditorFormater('dcLegacyEditor', 'xhtml', function ($s) {return $s;});
-    $core->addEditorFormater('dcLegacyEditor', 'wiki', array($core->wiki2xhtml, 'transform'));
+    $core->addEditorFormater('dcLegacyEditor', 'wiki', [$core->wiki2xhtml, 'transform']);
 
-    $core->addBehavior('adminPostEditor', array('dcLegacyEditorBehaviors', 'adminPostEditor'));
-    $core->addBehavior('adminPopupMedia', array('dcLegacyEditorBehaviors', 'adminPopupMedia'));
-    $core->addBehavior('adminPopupLink', array('dcLegacyEditorBehaviors', 'adminPopupLink'));
-    $core->addBehavior('adminPopupPosts', array('dcLegacyEditorBehaviors', 'adminPopupPosts'));
+    $core->addBehavior('adminPostEditor', ['dcLegacyEditorBehaviors', 'adminPostEditor']);
+    $core->addBehavior('adminPopupMedia', ['dcLegacyEditorBehaviors', 'adminPopupMedia']);
+    $core->addBehavior('adminPopupLink', ['dcLegacyEditorBehaviors', 'adminPopupLink']);
+    $core->addBehavior('adminPopupPosts', ['dcLegacyEditorBehaviors', 'adminPopupPosts']);
 }
Index: plugins/dcLegacyEditor/_define.php
===================================================================
--- plugins/dcLegacyEditor/_define.php	(revision 3731)
+++ plugins/dcLegacyEditor/_define.php	(revision 3874)
@@ -17,11 +17,11 @@
     "dotclear Team",          // Author
     '0.1.4',                  // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'type'        => 'plugin',
-        'settings'    => array(
+        'settings'    => [
             'self' => '',
             'pref' => '#user-options.user_options_edition'
-        )
-    )
+        ]
+    ]
 );
Index: plugins/dcLegacyEditor/inc/dc.legacy.editor.behaviors.php
===================================================================
--- plugins/dcLegacyEditor/inc/dc.legacy.editor.behaviors.php	(revision 3731)
+++ plugins/dcLegacyEditor/inc/dc.legacy.editor.behaviors.php	(revision 3874)
@@ -22,5 +22,5 @@
      * @param syntax   <b>string</b> wanted syntax (wiki,markdown,...)
      */
-    public static function adminPostEditor($editor = '', $context = '', array $tags = array(), $syntax = '')
+    public static function adminPostEditor($editor = '', $context = '', array $tags = [], $syntax = '')
     {
         if (empty($editor) || $editor != 'dcLegacyEditor') {return;}
Index: plugins/dcLegacyEditor/index.php
===================================================================
--- plugins/dcLegacyEditor/index.php	(revision 3731)
+++ plugins/dcLegacyEditor/index.php	(revision 3875)
@@ -29,3 +29,3 @@
 }
 
-include dirname(__FILE__) . '/tpl/index.tpl';
+include dirname(__FILE__) . '/tpl/index.php';
Index: plugins/dcLegacyEditor/js/_post_editor.js
===================================================================
--- plugins/dcLegacyEditor/js/_post_editor.js	(revision 3744)
+++ plugins/dcLegacyEditor/js/_post_editor.js	(revision 3880)
@@ -11,9 +11,14 @@
   }
 
+  // To be reviewed!
+  let formatField;
+  let excerptTb;
+  let contentTb;
+
   if ((dotclear.legacy_editor_tags_context[dotclear.legacy_editor_context].indexOf('#post_content') !== -1) &&
     (dotclear.legacy_editor_tags_context[dotclear.legacy_editor_context].indexOf('#post_excerpt') !== -1)) {
     // Get document format and prepare toolbars
-    var formatField = $('#post_format').get(0);
-    var last_post_format = $(formatField).val();
+    formatField = $('#post_format').get(0);
+    let last_post_format = $(formatField).val();
     $(formatField).change(function() {
       if (this.value != 'dcLegacyEditor') {
@@ -21,5 +26,5 @@
       }
 
-      var post_format = this.value;
+      const post_format = this.value;
 
       // Confirm post format change
@@ -37,6 +42,6 @@
     });
 
-    var excerptTb = new jsToolBar(document.getElementById('post_excerpt'));
-    var contentTb = new jsToolBar(document.getElementById('post_content'));
+    excerptTb = new jsToolBar(document.getElementById('post_excerpt'));
+    contentTb = new jsToolBar(document.getElementById('post_content'));
     excerptTb.context = contentTb.context = 'post';
 
@@ -47,5 +52,5 @@
   if (dotclear.legacy_editor_tags_context[dotclear.legacy_editor_context].indexOf('#comment_content') !== -1) {
     if ($('#comment_content').length > 0) {
-      var commentTb = new jsToolBar(document.getElementById('comment_content'));
+      let commentTb = new jsToolBar(document.getElementById('comment_content'));
       commentTb.draw('xhtml');
     }
@@ -75,6 +80,6 @@
 
     // Check unsaved changes before XHTML conversion
-    var excerpt = $('#post_excerpt').val();
-    var content = $('#post_content').val();
+    const excerpt = $('#post_excerpt').val();
+    const content = $('#post_content').val();
     $('#convert-xhtml').click(function() {
       if (excerpt != $('#post_excerpt').val() || content != $('#post_content').val()) {
Index: plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.dotclear.js
===================================================================
--- plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.dotclear.js	(revision 3735)
+++ plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.dotclear.js	(revision 3880)
@@ -13,5 +13,5 @@
 
   this.elements.link.data = {};
-  var url = this.elements.link.open_url + args;
+  const url = this.elements.link.open_url + args;
 
   window.open(url, 'dc_popup',
@@ -24,5 +24,5 @@
 };
 jsToolBar.prototype.elements.link.fncall.wiki = function() {
-  var data = this.elements.link.data;
+  const data = this.elements.link.data;
 
   if (data.href == '') {
@@ -30,5 +30,5 @@
   }
 
-  var etag = '|' + data.href;
+  let etag = '|' + data.href;
   if (data.hreflang) {
     etag += '|' + data.hreflang;
@@ -43,15 +43,15 @@
 
   if (data.content) {
-    this.encloseSelection('[' + data.content, etag + ']');
+    this.encloseSelection(`[${data.content}`, `${etag}]`);
   } else {
-    this.encloseSelection('[', etag + ']');
+    this.encloseSelection('[', `${etag}]`);
   }
 };
 
 jsToolBar.prototype.elements.link.fn.xhtml = function() {
-  this.elements.link.popup.call(this, '&hreflang=' + this.elements.link.default_hreflang);
+  this.elements.link.popup.call(this, `&hreflang=${this.elements.link.default_hreflang}`);
 };
 jsToolBar.prototype.elements.link.fncall.xhtml = function() {
-  var data = this.elements.link.data;
+  const data = this.elements.link.data;
 
   if (data.href == '') {
@@ -59,14 +59,14 @@
   }
 
-  var stag = '<a href="' + data.href + '"';
+  let stag = `<a href="${data.href}"`;
 
   if (data.hreflang) {
-    stag += ' hreflang="' + data.hreflang + '"';
+    stag += ` hreflang="${data.hreflang}"`;
   }
   if (data.title) {
-    stag += ' title="' + data.title + '"';
+    stag += ` title="${data.title}"`;
   }
   stag += '>';
-  var etag = '</a>';
+  const etag = '</a>';
 
   if (data.content) {
@@ -80,5 +80,7 @@
 
 jsToolBar.prototype.elements.link.fn.wysiwyg = function() {
-  var href, title, hreflang;
+  let href;
+  let title;
+  let hreflang;
   href = title = hreflang = '';
   hreflang = this.elements.link.default_hreflang;
@@ -92,10 +94,10 @@
   }
 
-  this.elements.link.popup.call(this, '&href=' + href + '&hreflang=' + hreflang + '&title=' + title);
+  this.elements.link.popup.call(this, `&href=${href}&hreflang=${hreflang}&title=${title}`);
 };
 jsToolBar.prototype.elements.link.fncall.wysiwyg = function() {
-  var data = this.elements.link.data;
-
-  var a = this.getAncestor();
+  const data = this.elements.link.data;
+
+  let a = this.getAncestor();
 
   if (a.tagName == 'a') {
@@ -123,5 +125,5 @@
 
   // Create link
-  var n;
+  let n;
   if (data.content) {
     n = document.createTextNode(data.content);
@@ -137,9 +139,10 @@
 };
 jsToolBar.prototype.getAncestor = function() {
-  var res = {};
-  var range, commonAncestorContainer;
+  let res = {};
+  let range;
+  let commonAncestorContainer;
 
   if (this.iwin.getSelection) { //gecko
-    var selection = this.iwin.getSelection();
+    const selection = this.iwin.getSelection();
     range = selection.getRangeAt(0);
     commonAncestorContainer = range.commonAncestorContainer;
@@ -152,5 +155,5 @@
   }
 
-  var ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+  let ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
   while (ancestorTagName != 'a' && ancestorTagName != 'body') {
     commonAncestorContainer = commonAncestorContainer.parentNode;
@@ -193,6 +196,6 @@
 
   this.encloseSelection('', '', function(str) {
-    var alt = (str) ? str : d.title;
-    var res = '((' + d.src + '|' + alt;
+    const alt = (str) ? str : d.title;
+    let res = `((${d.src}|${alt}`;
 
     if (d.alignment == 'left') {
@@ -207,5 +210,5 @@
 
     if (d.description) {
-      res += '|' + d.description;
+      res += `|${d.description}`;
     }
 
@@ -213,6 +216,5 @@
 
     if (d.link) {
-      var ltitle = (alt) ? '||' + alt : '';
-      res = '[' + res + '|' + d.url + ltitle + ']';
+      res = `[${res}|${d.url}${(alt) ? `||${alt}` : ''}]`;
     }
 
@@ -224,5 +226,5 @@
 };
 jsToolBar.prototype.elements.img_select.fncall.xhtml = function() {
-  var d = this.elements.img_select.data;
+  const d = this.elements.img_select.data;
   if (d.src == undefined) {
     return;
@@ -230,6 +232,6 @@
 
   this.encloseSelection('', '', function(str) {
-    var alt = (str) ? str : d.title;
-    var res = '<img src="' + d.src + '" alt="' + alt.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;').replace('"', '&quot;') + '"';
+    const alt = (str) ? str : d.title;
+    let res = `<img src="${d.src}" alt="${alt.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;').replace('"', '&quot;')}"`;
 
     if (d.alignment == 'left') {
@@ -242,5 +244,5 @@
 
     if (d.description) {
-      res += ' title="' + d.description.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;').replace('"', '&quot;') + '"';
+      res += ` title="${d.description.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;').replace('"', '&quot;')}"`;
     }
 
@@ -248,6 +250,6 @@
 
     if (d.link) {
-      var ltitle = (alt) ? ' title="' + alt.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;').replace('"', '&quot;') + '"' : '';
-      res = '<a href="' + d.url + '"' + ltitle + '>' + res + '</a>';
+      const ltitle = (alt) ? ` title="${alt.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;').replace('"', '&quot;')}"` : '';
+      res = `<a href="${d.url}"${ltitle}>${res}</a>`;
     }
 
@@ -257,10 +259,10 @@
 
 jsToolBar.prototype.elements.img.fn.wysiwyg = function() {
-  var src = this.elements.img.prompt.call(this);
+  const src = this.elements.img.prompt.call(this);
   if (!src) {
     return;
   }
 
-  var img = this.iwin.document.createElement('img');
+  const img = this.iwin.document.createElement('img');
   img.src = src;
   img.setAttribute('alt', this.getSelectedText());
@@ -273,11 +275,11 @@
 };
 jsToolBar.prototype.elements.img_select.fncall.wysiwyg = function() {
-  var d = this.elements.img_select.data;
-  var alt = (this.getSelectedText()) ? this.getSelectedText() : d.title;
+  const d = this.elements.img_select.data;
+  const alt = (this.getSelectedText()) ? this.getSelectedText() : d.title;
   if (d.src == undefined) {
     return;
   }
 
-  var img = this.iwin.document.createElement('img');
+  const img = this.iwin.document.createElement('img');
   img.src = d.src;
   img.setAttribute('alt', alt);
@@ -316,5 +318,5 @@
 
   if (d.link) {
-    var a = this.iwin.document.createElement('a');
+    const a = this.iwin.document.createElement('a');
     a.href = d.url;
     if (alt) {
@@ -334,5 +336,5 @@
 };
 jsToolBar.prototype.elements.mp3_insert.fncall.wiki = function() {
-  var d = this.elements.mp3_insert.data;
+  const d = this.elements.mp3_insert.data;
   if (d.player == undefined) {
     return;
@@ -344,5 +346,5 @@
 };
 jsToolBar.prototype.elements.mp3_insert.fncall.xhtml = function() {
-  var d = this.elements.mp3_insert.data;
+  const d = this.elements.mp3_insert.data;
   if (d.player == undefined) {
     return;
@@ -363,5 +365,5 @@
 };
 jsToolBar.prototype.elements.flv_insert.fncall.wiki = function() {
-  var d = this.elements.flv_insert.data;
+  const d = this.elements.flv_insert.data;
   if (d.player == undefined) {
     return;
@@ -373,5 +375,5 @@
 };
 jsToolBar.prototype.elements.flv_insert.fncall.xhtml = function() {
-  var d = this.elements.flv_insert.data;
+  const d = this.elements.flv_insert.data;
   if (d.player == undefined) {
     return;
Index: plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.js
===================================================================
--- plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.js	(revision 3735)
+++ plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.js	(revision 3880)
@@ -24,5 +24,5 @@
  */
 
-var jsToolBar = function(textarea) {
+const jsToolBar = function(textarea) {
   if (!document.createElement) {
     return;
@@ -59,6 +59,6 @@
       this.handle = document.createElement('div');
       this.handle.className = 'jstHandle';
-      var dragStart = this.resizeDragStart;
-      var This = this;
+      const dragStart = this.resizeDragStart;
+      const This = this;
       this.handle.addEventListener('mousedown', function(event) {
         dragStart.call(This, event);
@@ -73,5 +73,5 @@
 };
 
-var jsButton = function(title, fn, scope, className, accesskey) {
+const jsButton = function(title, fn, scope, className, accesskey) {
   this.title = title || null;
   this.fn = fn || function() {};
@@ -83,10 +83,10 @@
   if (!this.scope) return null;
 
-  var button = document.createElement('button');
+  const button = document.createElement('button');
   button.setAttribute('type', 'button');
   if (this.className) button.className = this.className;
   button.title = this.title;
   if (this.accesskey) button.accessKey = this.accesskey;
-  var span = document.createElement('span');
+  const span = document.createElement('span');
   span.appendChild(document.createTextNode(this.title));
   button.appendChild(span);
@@ -96,5 +96,5 @@
   }
   if (typeof(this.fn) == 'function') {
-    var This = this;
+    const This = this;
     button.onclick = function() {
       try {
@@ -107,10 +107,10 @@
 };
 
-var jsSpace = function(id) {
+const jsSpace = function(id) {
   this.id = id || null;
   this.width = null;
 };
 jsSpace.prototype.draw = function() {
-  var span = document.createElement('span');
+  const span = document.createElement('span');
   if (this.id) span.id = this.id;
   span.appendChild(document.createTextNode(String.fromCharCode(160)));
@@ -121,5 +121,5 @@
 };
 
-var jsCombo = function(title, options, scope, fn, className) {
+const jsCombo = function(title, options, scope, fn, className) {
   this.title = title || null;
   this.options = options || null;
@@ -131,11 +131,11 @@
   if (!this.scope || !this.options) return null;
 
-  var select = document.createElement('select');
+  const select = document.createElement('select');
   if (this.className) select.className = this.className;
   select.title = this.title;
 
-  for (var o in this.options) {
+  for (let o in this.options) {
     //var opt = this.options[o];
-    var option = document.createElement('option');
+    const option = document.createElement('option');
     option.value = o;
     option.appendChild(document.createTextNode(this.options[o]));
@@ -143,5 +143,5 @@
   }
 
-  var This = this;
+  const This = this;
   select.onchange = function() {
     try {
@@ -177,7 +177,7 @@
 
   button: function(toolName) {
-    var tool = this.elements[toolName];
+    const tool = this.elements[toolName];
     if (typeof tool.fn[this.mode] != 'function') return null;
-    var b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_' + toolName, tool.accesskey);
+    const b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_' + toolName, tool.accesskey);
     if (tool.icon != undefined) {
       b.icon = tool.icon;
@@ -186,5 +186,5 @@
   },
   space: function(toolName) {
-    var tool = new jsSpace(toolName);
+    const tool = new jsSpace(toolName);
     if (this.elements[toolName].format != undefined && !this.elements[toolName].format[this.mode]) return null;
     if (this.elements[toolName].width !== undefined) {
@@ -194,16 +194,16 @@
   },
   combo: function(toolName) {
-    var tool = this.elements[toolName];
+    const tool = this.elements[toolName];
 
     if (tool[this.mode] != undefined) {
 
-      var length = tool[this.mode].list.length;
+      const length = tool[this.mode].list.length;
 
       if (typeof tool[this.mode].fn != 'function' || length == 0) {
         return null;
       } else {
-        var options = {};
-        for (var i = 0; i < length; i++) {
-          var opt = tool[this.mode].list[i];
+        let options = {};
+        for (let i = 0; i < length; i++) {
+          const opt = tool[this.mode].list[i];
           options[opt] = tool.options[opt];
         }
@@ -224,10 +224,12 @@
 
     // Draw toolbar elements
-    var b, tool, newTool;
-
-    for (var i in this.elements) {
+    let b;
+    let tool;
+    let newTool;
+
+    for (let i in this.elements) {
       b = this.elements[i];
 
-      var disabled =
+      const disabled =
         b.type == undefined || b.type == '' ||
         (b.disabled != undefined && b.disabled) ||
@@ -262,5 +264,10 @@
     suffix = suffix || '';
 
-    var start, end, sel, scrollPos, subst, res;
+    let start;
+    let end;
+    let sel;
+    let scrollPos;
+    let subst;
+    let res;
 
     if (typeof(document.selection) != "undefined") {
@@ -305,5 +312,5 @@
   stripBaseURL: function(url) {
     if (this.base_url != '') {
-      var pos = url.indexOf(this.base_url);
+      const pos = url.indexOf(this.base_url);
       if (pos == 0) {
         url = url.substr(this.base_url.length);
@@ -321,5 +328,5 @@
 };
 jsToolBar.prototype.resizeDragStart = function(event) {
-  var This = this;
+  const This = this;
   this.dragStartY = event.clientY;
   this.resizeSetStartH();
@@ -364,5 +371,5 @@
       else
         try {
-          this.singleTag('<' + opt + '>', '</' + opt + '>');
+          this.singleTag(`<${opt}>`, `</${opt}>`);
         } catch (e) {}
       this.toolNodes.blocks.value = 'nonebis';
@@ -688,7 +695,7 @@
     this.encloseSelection('', '', function(str) {
       if (str) {
-        return '<img src="' + src + '" alt="' + str + '" />';
+        return `<img src="${src}" alt="${str}" />`;
       } else {
-        return '<img src="' + src + '" alt="" />';
+        return `<img src="${src}" alt="" />`;
       }
     });
@@ -700,7 +707,7 @@
     this.encloseSelection('', '', function(str) {
       if (str) {
-        return '((' + src + '|' + str + '))';
+        return `((${src}|${str}))`;
       } else {
-        return '((' + src + '))';
+        return `((${src}))`;
       }
     });
Index: plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.wysiwyg.js
===================================================================
--- plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.wysiwyg.js	(revision 3736)
+++ plugins/dcLegacyEditor/js/jsToolBar/jsToolBar.wysiwyg.js	(revision 3880)
@@ -64,10 +64,10 @@
 jsToolBar.prototype.syncContents = function(from) {
   from = from || 'textarea';
-  var This = this;
+  const This = this;
   if (from == 'textarea') {
     initContent();
   } else {
     this.validBlockquote();
-    var html = this.applyHtmlFilters(this.ibody.innerHTML);
+    let html = this.applyHtmlFilters(this.ibody.innerHTML);
     if (html == '<br />') {
       html = '<p></p>';
@@ -86,5 +86,5 @@
       This.ibody.innerHTML = This.applyWysiwygFilters(This.textarea.value);
       if (This.ibody.createTextRange) { //cursor at the begin for IE
-        var IErange = This.ibody.createTextRange();
+        const IErange = This.ibody.createTextRange();
         IErange.execCommand("SelectAll");
         IErange.collapse();
@@ -92,6 +92,6 @@
       }
     } else {
-      var idoc = This.iwin.document;
-      var para = idoc.createElement('p');
+      const idoc = This.iwin.document;
+      const para = idoc.createElement('p');
       para.appendChild(idoc.createElement('br'));
       while (idoc.body.hasChildNodes()) {
@@ -108,5 +108,5 @@
 };
 jsToolBar.prototype.applyHtmlFilters = function(str) {
-  for (var fn in this.htmlFilters) {
+  for (let fn in this.htmlFilters) {
     str = this.htmlFilters[fn].call(this, str);
   }
@@ -115,5 +115,5 @@
 jsToolBar.prototype.wysiwygFilters = {};
 jsToolBar.prototype.applyWysiwygFilters = function(str) {
-  for (var fn in this.wysiwygFilters) {
+  for (let fn in this.wysiwygFilters) {
     str = this.wysiwygFilters[fn].call(this, str);
   }
@@ -143,5 +143,5 @@
  */
 jsToolBar.prototype.initWindow = function() {
-  var This = this;
+  const This = this;
 
   this.iframe = document.createElement('iframe');
@@ -160,5 +160,5 @@
 
   function initIframe() {
-    var doc = This.iframe.contentWindow.document;
+    const doc = This.iframe.contentWindow.document;
     if (!doc) {
       setTimeout(initIframe, 1);
@@ -167,14 +167,13 @@
 
     doc.open();
-    var html =
-      '<html>\n' +
-      '<head>\n' +
-      '<link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />' +
-      '<style type="text/css">' + This.iframe_css + '</style>\n' +
-      (This.base_url != '' ? '<base href="' + This.base_url + '" />' : '') +
-      '</head>\n' +
-      '<body>\n' +
-      '</body>\n' +
-      '</html>';
+    const html =
+`<html>
+  <head>
+    <link rel="stylesheet" href="style/default.css" type="text/css" media="screen" />
+    <style type="text/css">${This.iframe_css}</style>
+    ${This.base_url != '' ? `<base href="${This.base_url}" />` : ''}
+  </head>
+  <body></body>
+</html>`;
 
     doc.write(html);
@@ -212,6 +211,6 @@
     }
 
-    for (var evt in This.iwinEvents) {
-      var event = This.iwinEvents[evt];
+    for (let evt in This.iwinEvents) {
+      const event = This.iwinEvents[evt];
       This.addIwinEvent(This.iframe.contentWindow.document, event.type, event.fn, This);
     }
@@ -227,5 +226,5 @@
 };
 jsToolBar.prototype.addIwinEvent = function(target, type, fn, scope) {
-  var myFn = function(e) {
+  const myFn = function(e) {
     fn.call(scope, e);
   };
@@ -260,9 +259,9 @@
   }
 
-  var This = this;
+  const This = this;
 
   function setLink(title, link) {
-    var li = document.createElement('li');
-    var a;
+    const li = document.createElement('li');
+    let a;
     if (link) {
       a = document.createElement('a');
@@ -307,5 +306,5 @@
       this.iwin.document.designMode = 'on';
     } catch (e) {} // Firefox needs this
-    var This = this;
+    const This = this;
     setTimeout(function() {
       This.iframe.contentWindow.focus();
@@ -326,5 +325,5 @@
 };
 jsToolBar.prototype.resizeDragMove = function(event) {
-  var new_height = (this.dragStartH + event.clientY - this.dragStartY) + 'px';
+  const new_height = `${this.dragStartH + event.clientY - this.dragStartY}px`;
   if (this.iframe != undefined) {
     this.iframe.style.height = new_height;
@@ -338,8 +337,8 @@
  */
 jsToolBar.prototype.insertNode = function(node) {
-  var range;
+  let range;
 
   if (this.iwin.getSelection) { // Gecko
-    var sel = this.iwin.getSelection();
+    const sel = this.iwin.getSelection();
     range = sel.getRangeAt(0);
 
@@ -366,5 +365,5 @@
   } else { // IE
     // lambda element
-    var p = this.iwin.document.createElement('div');
+    const p = this.iwin.document.createElement('div');
     p.appendChild(node);
     range = this.iwin.document.selection.createRange();
@@ -381,16 +380,16 @@
  */
 jsToolBar.prototype.getSelectedNode = function() {
-  var sel;
+  let sel;
   var content;
   if (this.iwin.getSelection) { // Gecko
     sel = this.iwin.getSelection();
-    var range = sel.getRangeAt(0);
+    const range = sel.getRangeAt(0);
     content = range.cloneContents();
   } else { // IE
     sel = this.iwin.document.selection;
-    var d = this.iwin.document.createElement('div');
+    const d = this.iwin.document.createElement('div');
     d.innerHTML = sel.createRange().htmlText;
     content = this.iwin.document.createDocumentFragment();
-    for (var i = 0; i < d.childNodes.length; i++) {
+    for (let i = 0; i < d.childNodes.length; i++) {
       content.appendChild(d.childNodes[i].cloneNode(true));
     }
@@ -405,5 +404,5 @@
     return this.iwin.getSelection().toString();
   } else { // IE
-    var range = this.iwin.document.selection.createRange();
+    const range = this.iwin.document.selection.createRange();
     return range.text;
   }
@@ -411,6 +410,6 @@
 
 jsToolBar.prototype.replaceNodeByContent = function(node) {
-  var content = this.iwin.document.createDocumentFragment();
-  for (var i = 0; i < node.childNodes.length; i++) {
+  const content = this.iwin.document.createDocumentFragment();
+  for (let i = 0; i < node.childNodes.length; i++) {
     content.appendChild(node.childNodes[i].cloneNode(true));
   }
@@ -419,9 +418,10 @@
 
 jsToolBar.prototype.getBlockLevel = function() {
-  var blockElts = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
-
-  var range, commonAncestorContainer;
+  const blockElts = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
+
+  let range;
+  let commonAncestorContainer;
   if (this.iwin.getSelection) { //gecko
-    var selection = this.iwin.getSelection();
+    const selection = this.iwin.getSelection();
     range = selection.getRangeAt(0);
     commonAncestorContainer = range.commonAncestorContainer;
@@ -434,5 +434,5 @@
   }
 
-  var ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+  let ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
   while (arrayIndexOf(blockElts, ancestorTagName) == -1 && ancestorTagName != 'body') {
     commonAncestorContainer = commonAncestorContainer.parentNode;
@@ -443,5 +443,5 @@
 };
 jsToolBar.prototype.adjustBlockLevelCombo = function() {
-  var blockLevel = this.getBlockLevel();
+  const blockLevel = this.getBlockLevel();
   if (blockLevel !== null)
     this.toolNodes.blocks.value = blockLevel.tagName.toLowerCase();
@@ -471,5 +471,5 @@
  */
 jsToolBar.prototype.tagsoup2xhtml = function(html) {
-  for (var reg in this.simpleCleanRegex) {
+  for (let reg in this.simpleCleanRegex) {
     html = html.replace(this.simpleCleanRegex[reg][0], this.simpleCleanRegex[reg][1]);
   }
@@ -488,7 +488,7 @@
 
   /* IE laisse souvent des attributs sans guillemets */
-  var myRegexp = /<[^>]+((\s+\w+\s*=\s*)([^"'][\w~@+$,%\/:.#?=&;!*()-]*))[^>]*?>/;
-  var myQuoteFn = function(str, val1, val2, val3) {
-    var tamponRegex = new RegExp(regexpEscape(val1));
+  const myRegexp = /<[^>]+((\s+\w+\s*=\s*)([^"'][\w~@+$,%\/:.#?=&;!*()-]*))[^>]*?>/;
+  const myQuoteFn = function(str, val1, val2, val3) {
+    const tamponRegex = new RegExp(regexpEscape(val1));
     return str.replace(tamponRegex, val2 + '"' + val3 + '"');
   };
@@ -508,5 +508,5 @@
 
   /* Trim only if there's no pre tag */
-  var pattern_pre = /<pre>[\s\S]*<\/pre>/gi;
+  const pattern_pre = /<pre>[\s\S]*<\/pre>/gi;
   if (!pattern_pre.test(html)) {
     html = html.replace(/^\s+/gm, '');
@@ -517,15 +517,15 @@
 };
 jsToolBar.prototype.validBlockquote = function() {
-  var blockElts = ['address', 'blockquote', 'dl', 'div', 'fieldset', 'form', 'h1',
+  const blockElts = ['address', 'blockquote', 'dl', 'div', 'fieldset', 'form', 'h1',
     'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'ol', 'p', 'pre', 'table', 'ul'
   ];
-  var BQs = this.iwin.document.getElementsByTagName('blockquote');
-  var bqChilds;
-  var p;
-
-  for (var bq = 0; bq < BQs.length; bq++) {
+  const BQs = this.iwin.document.getElementsByTagName('blockquote');
+  let bqChilds;
+  let p;
+
+  for (let bq = 0; bq < BQs.length; bq++) {
     bqChilds = BQs[bq].childNodes;
-    var frag = this.iwin.document.createDocumentFragment();
-    for (var i = (bqChilds.length - 1); i >= 0; i--) {
+    let frag = this.iwin.document.createDocumentFragment();
+    for (let i = (bqChilds.length - 1); i >= 0; i--) {
       if (bqChilds[i].nodeType == 1 && // Node.ELEMENT_NODE
         arrayIndexOf(blockElts, bqChilds[i].tagName.toLowerCase()) >= 0) {
@@ -561,5 +561,5 @@
 
 jsToolBar.prototype.removeTextFormating = function(html) {
-  for (var reg in this.removeFormatRegexp) {
+  for (let reg in this.removeFormatRegexp) {
     html = html.replace(this.removeFormatRegexp[reg][0], this.removeFormatRegexp[reg][1]);
   }
@@ -576,5 +576,5 @@
   fn: function(opt) {
     if (opt == 'none') {
-      var blockLevel = this.getBlockLevel();
+      const blockLevel = this.getBlockLevel();
       if (blockLevel !== null) {
         this.replaceNodeByContent(blockLevel);
@@ -611,6 +611,6 @@
 
 jsToolBar.prototype.elements.quote.fn.wysiwyg = function() {
-  var n = this.getSelectedNode();
-  var q = this.iwin.document.createElement('q');
+  const n = this.getSelectedNode();
+  const q = this.iwin.document.createElement('q');
   q.appendChild(n);
   this.insertNode(q);
@@ -618,6 +618,6 @@
 
 jsToolBar.prototype.elements.code.fn.wysiwyg = function() {
-  var n = this.getSelectedNode();
-  var code = this.iwin.document.createElement('code');
+  const n = this.getSelectedNode();
+  const code = this.iwin.document.createElement('code');
   code.appendChild(n);
   this.insertNode(code);
@@ -625,6 +625,6 @@
 
 jsToolBar.prototype.elements.mark.fn.wysiwyg = function() {
-  var n = this.getSelectedNode();
-  var mark = this.iwin.document.createElement('mark');
+  const n = this.getSelectedNode();
+  const mark = this.iwin.document.createElement('mark');
   mark.appendChild(n);
   this.insertNode(mark);
@@ -632,11 +632,11 @@
 
 jsToolBar.prototype.elements.br.fn.wysiwyg = function() {
-  var n = this.iwin.document.createElement('br');
+  const n = this.iwin.document.createElement('br');
   this.insertNode(n);
 };
 
 jsToolBar.prototype.elements.blockquote.fn.wysiwyg = function() {
-  var n = this.getSelectedNode();
-  var q = this.iwin.document.createElement('blockquote');
+  const n = this.getSelectedNode();
+  const q = this.iwin.document.createElement('blockquote');
   q.appendChild(n);
   this.insertNode(q);
@@ -659,8 +659,10 @@
 
 jsToolBar.prototype.elements.link.fn.wysiwyg = function() {
-  var href, hreflang;
-  var range, commonAncestorContainer;
+  let href;
+  let hreflang;
+  let range;
+  let commonAncestorContainer;
   if (this.iwin.getSelection) { //gecko
-    var selection = this.iwin.getSelection();
+    const selection = this.iwin.getSelection();
     range = selection.getRangeAt(0);
     commonAncestorContainer = range.commonAncestorContainer;
@@ -673,5 +675,5 @@
   }
 
-  var ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+  let ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
   while (ancestorTagName != 'a' && ancestorTagName != 'body') {
     commonAncestorContainer = commonAncestorContainer.parentNode;
@@ -707,6 +709,6 @@
 
   // Create link
-  var n = this.getSelectedNode();
-  var a = this.iwin.document.createElement('a');
+  const n = this.getSelectedNode();
+  const a = this.iwin.document.createElement('a');
   a.href = href;
   if (hreflang) a.setAttribute('hreflang', hreflang);
@@ -723,10 +725,10 @@
 jsToolBar.prototype.elements.removeFormat.disabled = !jsToolBar.prototype.can_wwg;
 jsToolBar.prototype.elements.removeFormat.fn.xhtml = function() {
-  var html = this.textarea.value;
+  let html = this.textarea.value;
   html = this.removeTextFormating(html);
   this.textarea.value = html;
 };
 jsToolBar.prototype.elements.removeFormat.fn.wysiwyg = function() {
-  var html = this.iwin.document.body.innerHTML;
+  let html = this.iwin.document.body.innerHTML;
   html = this.removeTextFormating(html);
   this.iwin.document.body.innerHTML = html;
@@ -738,7 +740,7 @@
     return aArray.indexOf(aValue);
   } else {
-    var index = -1;
-    var l = aArray.length;
-    for (var i = 0; i < l; i++) {
+    let index = -1;
+    const l = aArray.length;
+    for (let i = 0; i < l; i++) {
       if (aArray[i] === aValue) {
         index = i;
@@ -755,5 +757,5 @@
     return true;
   } else if (obj.attachEvent) {
-    var r = obj.attachEvent("on" + evType, fn);
+    const r = obj.attachEvent("on" + evType, fn);
     return r;
   } else {
@@ -767,5 +769,5 @@
     return true;
   } else if (obj.detachEvent) {
-    var r = obj.detachEvent("on" + evType, fn);
+    const r = obj.detachEvent("on" + evType, fn);
     return r;
   } else {
Index: plugins/dcLegacyEditor/js/jsToolBar/popup_link.js
===================================================================
--- plugins/dcLegacyEditor/js/jsToolBar/popup_link.js	(revision 3735)
+++ plugins/dcLegacyEditor/js/jsToolBar/popup_link.js	(revision 3880)
@@ -13,9 +13,9 @@
 
 	function sendClose() {
-		var insert_form = $('#link-insert-form').get(0);
+		const insert_form = $('#link-insert-form').get(0);
 		if (insert_form == undefined) { return; }
 
-		var tb = window.opener.the_toolbar;
-		var data = tb.elements.link.data;
+		const tb = window.opener.the_toolbar;
+		const data = tb.elements.link.data;
 
 		data.href = tb.stripBaseURL(insert_form.elements.href.value);
@@ -23,4 +23,4 @@
 		data.hreflang = insert_form.elements.hreflang.value;
 		tb.elements.link.fncall[tb.mode].call(tb);
-	};
+	}
 });
Index: plugins/dcLegacyEditor/js/jsToolBar/popup_media.js
===================================================================
--- plugins/dcLegacyEditor/js/jsToolBar/popup_media.js	(revision 3725)
+++ plugins/dcLegacyEditor/js/jsToolBar/popup_media.js	(revision 3880)
@@ -15,17 +15,18 @@
 
   function sendClose() {
-    var insert_form = $('#media-insert-form').get(0);
+    const insert_form = $('#media-insert-form').get(0);
     if (insert_form == undefined) {
       return;
     }
 
-    var tb = window.opener.the_toolbar;
-    var type = insert_form.elements.type.value;
-    var media_align_grid = {
+    const tb = window.opener.the_toolbar;
+    const type = insert_form.elements.type.value;
+    const media_align_grid = {
       left: 'float: left; margin: 0 1em 1em 0;',
       right: 'float: right; margin: 0 0 1em 1em;',
       center: 'text-align: center;'
     };
-    var align, player;
+    let align;
+    let player;
 
     if (type == 'image') {
@@ -38,5 +39,5 @@
       tb.elements.img_select.data.url = tb.stripBaseURL(insert_form.elements.url.value);
 
-      var media_legend = $('input[name="legend"]:checked', insert_form).val();
+      let media_legend = $('input[name="legend"]:checked', insert_form).val();
       if (media_legend != '' && media_legend != 'title' && media_legend != 'none') {
         media_legend = 'legend';
@@ -55,5 +56,5 @@
 
       if (align != undefined && align != 'none') {
-        player = '<div style="' + media_align_grid[align] + '">' + player + '</div>';
+        player = `<div style="${media_align_grid[align]}">${player}</div>`;
       }
 
@@ -62,5 +63,5 @@
     } else if (type == 'flv') // may be all video media, not only flv
     {
-      var oplayer = $('<div>' + $('#public_player').val() + '</div>');
+      var oplayer = $(`<div>${$('#public_player').val()}</div>`);
       var flashvars = $('[name=FlashVars]', oplayer).val();
 
@@ -98,5 +99,5 @@
 
       if (align != undefined && align != 'none') {
-        player = '<div style="' + media_align_grid[align] + '">' + player + '</div>';
+        player = `<div style="${media_align_grid[align]}">${player}</div>`;
       }
 
Index: plugins/dcLegacyEditor/js/jsToolBar/popup_posts.js
===================================================================
--- plugins/dcLegacyEditor/js/jsToolBar/popup_posts.js	(revision 3735)
+++ plugins/dcLegacyEditor/js/jsToolBar/popup_posts.js	(revision 3880)
@@ -9,6 +9,6 @@
 	$('#form-entries tr>td.maximal>a').click(function() {
 		// Get post_id
-		var tb = window.opener.the_toolbar;
-		var data = tb.elements.link.data;
+		const tb = window.opener.the_toolbar;
+		const data = tb.elements.link.data;
 
 		data.href = tb.stripBaseURL($(this).attr('title'));
Index: plugins/dcLegacyEditor/tpl/index.php
===================================================================
--- plugins/dcLegacyEditor/tpl/index.php	(revision 3875)
+++ plugins/dcLegacyEditor/tpl/index.php	(revision 3875)
@@ -0,0 +1,31 @@
+<html>
+  <head>
+    <title>dcLegacyEditor</title>
+  </head>
+  <body>
+    <?php echo dcPage::breadcrumb([__('Plugins') => '', __('dcLegacyEditor') => '']) . dcPage::notices(); ?>
+
+    <?php if ($is_admin): ?>
+      <h3 class="hidden-if-js"><?php echo __('Settings'); ?></h3>
+      <form action="<?php echo $p_url; ?>" method="post" enctype="multipart/form-data">
+        <div class="fieldset">
+          <h3><?php echo __('Plugin activation'); ?></h3>
+          <p>
+            <label class="classic" for="dclegacyeditor_active">
+              <?php echo form::checkbox('dclegacyeditor_active', 1, $dclegacyeditor_active); ?>
+              <?php echo __('Enable dcLegacyEditor plugin'); ?>
+            </label>
+          </p>
+        </div>
+
+        <p>
+        <input type="hidden" name="p" value="dcLegacyEditor"/>
+        <?php echo $core->formNonce(); ?>
+        <input type="submit" name="saveconfig" value="<?php echo __('Save configuration'); ?>" />
+        </p>
+      </form>
+    <?php endif;?>
+
+    <?php dcPage::helpBlock('dcLegacyEditor');?>
+  </body>
+</html>
Index: lugins/dcLegacyEditor/tpl/index.tpl
===================================================================
--- plugins/dcLegacyEditor/tpl/index.tpl	(revision 3730)
+++ 	(revision )
@@ -1,31 +1,0 @@
-<html>
-  <head>
-    <title>dcLegacyEditor</title>
-  </head>
-  <body>
-    <?php echo dcPage::breadcrumb(array(__('Plugins') => '', __('dcLegacyEditor') => '')) . dcPage::notices(); ?>
-
-    <?php if ($is_admin): ?>
-      <h3 class="hidden-if-js"><?php echo __('Settings'); ?></h3>
-      <form action="<?php echo $p_url; ?>" method="post" enctype="multipart/form-data">
-        <div class="fieldset">
-          <h3><?php echo __('Plugin activation'); ?></h3>
-          <p>
-            <label class="classic" for="dclegacyeditor_active">
-              <?php echo form::checkbox('dclegacyeditor_active', 1, $dclegacyeditor_active); ?>
-              <?php echo __('Enable dcLegacyEditor plugin'); ?>
-            </label>
-          </p>
-        </div>
-
-        <p>
-        <input type="hidden" name="p" value="dcLegacyEditor"/>
-        <?php echo $core->formNonce(); ?>
-        <input type="submit" name="saveconfig" value="<?php echo __('Save configuration'); ?>" />
-        </p>
-      </form>
-    <?php endif;?>
-
-    <?php dcPage::helpBlock('dcLegacyEditor');?>
-  </body>
-</html>
Index: plugins/dclegacy/_admin.php
===================================================================
--- plugins/dclegacy/_admin.php	(revision 3731)
+++ plugins/dclegacy/_admin.php	(revision 3874)
@@ -12,7 +12,7 @@
 if (!defined('DC_CONTEXT_ADMIN')) {return;}
 
-$GLOBALS['core']->addBehavior('adminPostsActionsPage', array('dcLegacyPosts', 'adminPostsActionsPage'));
-$GLOBALS['core']->addBehavior('adminPagesActionsPage', array('dcLegacyPages', 'adminPagesActionsPage'));
-$GLOBALS['core']->addBehavior('adminCommentsActionsPage', array('dcLegacyComments', 'adminCommentsActionsPage'));
+$GLOBALS['core']->addBehavior('adminPostsActionsPage', ['dcLegacyPosts', 'adminPostsActionsPage']);
+$GLOBALS['core']->addBehavior('adminPagesActionsPage', ['dcLegacyPages', 'adminPagesActionsPage']);
+$GLOBALS['core']->addBehavior('adminCommentsActionsPage', ['dcLegacyComments', 'adminCommentsActionsPage']);
 
 /* Handle deprecated behaviors :
@@ -26,7 +26,7 @@
     {
         $stub_actions = new ArrayObject();
-        $core->callBehavior('adminPostsActionsCombo', array($stub_actions));
+        $core->callBehavior('adminPostsActionsCombo', [$stub_actions]);
         if (!empty($stub_actions)) {
-            $as->addAction($stub_actions, array('dcLegacyPosts', 'onActionLegacy'));
+            $as->addAction($stub_actions, ['dcLegacyPosts', 'onActionLegacy']);
         }
     }
@@ -55,7 +55,7 @@
     {
         $stub_actions = new ArrayObject();
-        $core->callBehavior('adminCommentsActionsCombo', array($stub_actions));
+        $core->callBehavior('adminCommentsActionsCombo', [$stub_actions]);
         if (!empty($stub_actions)) {
-            $as->addAction($stub_actions, array('dcLegacyComments', 'onActionLegacy'));
+            $as->addAction($stub_actions, ['dcLegacyComments', 'onActionLegacy']);
         }
     }
@@ -88,7 +88,7 @@
     {
         $stub_actions = new ArrayObject();
-        $core->callBehavior('adminPagesActionsCombo', array($stub_actions));
+        $core->callBehavior('adminPagesActionsCombo', [$stub_actions]);
         if (!empty($stub_actions)) {
-            $as->addAction($stub_actions, array('dcLegacyPages', 'onActionLegacy'));
+            $as->addAction($stub_actions, ['dcLegacyPages', 'onActionLegacy']);
         }
     }
Index: plugins/dclegacy/_define.php
===================================================================
--- plugins/dclegacy/_define.php	(revision 3731)
+++ plugins/dclegacy/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "dc Team",                     // Author
     '1.0',                         // Version
-    array(
+    [
         'priority' => 500,
         'type'     => 'plugin'
-    )
+    ]
 );
Index: plugins/fairTrackbacks/_define.php
===================================================================
--- plugins/fairTrackbacks/_define.php	(revision 3731)
+++ plugins/fairTrackbacks/_define.php	(revision 3874)
@@ -17,8 +17,8 @@
     "Olivier Meunier",          // Author
     '1.1',                      // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'priority'    => 200,
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php
===================================================================
--- plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php	(revision 3731)
+++ plugins/fairTrackbacks/class.dc.filter.fairtrackbacks.php	(revision 3874)
@@ -37,5 +37,5 @@
         try
         {
-            $default_parse = array('scheme' => '', 'host' => '', 'path' => '', 'query' => '');
+            $default_parse = ['scheme' => '', 'host' => '', 'path' => '', 'query' => ''];
             $S             = array_merge($default_parse, parse_url($site));
 
@@ -45,5 +45,5 @@
 
             # Check incomink link page
-            $post     = $this->core->blog->getPosts(array('post_id' => $post_id));
+            $post     = $this->core->blog->getPosts(['post_id' => $post_id]);
             $post_url = $post->getURL();
             $P        = array_merge($default_parse, parse_url($post_url));
Index: plugins/importExport/_admin.php
===================================================================
--- plugins/importExport/_admin.php	(revision 3731)
+++ plugins/importExport/_admin.php	(revision 3874)
@@ -24,5 +24,5 @@
 function importExportDashboardFavorites($core, $favs)
 {
-    $favs->register('importExport', array(
+    $favs->register('importExport', [
         'title'       => __('Import/Export'),
         'url'         => $core->adminurl->get('admin.plugin.importExport'),
@@ -30,5 +30,5 @@
         'large-icon'  => dcPage::getPF('importExport/icon-big.png'),
         'permissions' => 'admin'
-    ));
+    ]);
 }
 
Index: plugins/importExport/_define.php
===================================================================
--- plugins/importExport/_define.php	(revision 3731)
+++ plugins/importExport/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "Olivier Meunier & Contributors", // Author
     '3.2',                            // Version
-    array(
+    [
         'permissions' => 'admin',
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/importExport/_prepend.php
===================================================================
--- plugins/importExport/_prepend.php	(revision 3731)
+++ plugins/importExport/_prepend.php	(revision 3874)
@@ -30,12 +30,12 @@
 function registerIeModules($modules, $core)
 {
-    $modules['import'] = array_merge($modules['import'], array('dcImportFlat'));
-    $modules['import'] = array_merge($modules['import'], array('dcImportFeed'));
+    $modules['import'] = array_merge($modules['import'], ['dcImportFlat']);
+    $modules['import'] = array_merge($modules['import'], ['dcImportFeed']);
 
-    $modules['export'] = array_merge($modules['export'], array('dcExportFlat'));
+    $modules['export'] = array_merge($modules['export'], ['dcExportFlat']);
 
     if ($core->auth->isSuperAdmin()) {
-        $modules['import'] = array_merge($modules['import'], array('dcImportDC1'));
-        $modules['import'] = array_merge($modules['import'], array('dcImportWP'));
+        $modules['import'] = array_merge($modules['import'], ['dcImportDC1']);
+        $modules['import'] = array_merge($modules['import'], ['dcImportWP']);
     }
 }
Index: plugins/importExport/inc/class.dc.export.flat.php
===================================================================
--- plugins/importExport/inc/class.dc.export.flat.php	(revision 3731)
+++ plugins/importExport/inc/class.dc.export.flat.php	(revision 3874)
@@ -191,13 +191,13 @@
 
         '<p><label for="file_zip" class="classic">' .
-        form::checkbox(array('file_zip', 'file_zip'), 1) . ' ' .
+        form::checkbox(['file_zip', 'file_zip'], 1) . ' ' .
         __('Compress file') . '</label>' .
         '</p>' .
 
-        '<p class="zip-dl"><a href="' . $this->core->decode('admin.media', array('d' => '', 'zipdl' => '1')) . '">' .
+        '<p class="zip-dl"><a href="' . $this->core->decode('admin.media', ['d' => '', 'zipdl' => '1']) . '">' .
         __('You may also want to download your media directory as a zip file') . '</a></p>' .
 
         '<p><input type="submit" value="' . __('Export') . '" />' .
-        form::hidden(array('do'), 'export_blog') .
+        form::hidden(['do'], 'export_blog') .
         $this->core->formNonce() . '</p>' .
 
@@ -211,14 +211,14 @@
 
             '<p><label for="file_name2">' . __('File name:') . '</label>' .
-            form::field(array('file_name', 'file_name2'), 50, 255, date('Y-m-d-H-i-') . 'dotclear-backup.txt') .
+            form::field(['file_name', 'file_name2'], 50, 255, date('Y-m-d-H-i-') . 'dotclear-backup.txt') .
             '</p>' .
 
             '<p><label for="file_zip2" class="classic">' .
-            form::checkbox(array('file_zip', 'file_zip2'), 1) . ' ' .
+            form::checkbox(['file_zip', 'file_zip2'], 1) . ' ' .
             __('Compress file') . '</label>' .
             '</p>' .
 
             '<p><input type="submit" value="' . __('Export') . '" />' .
-            form::hidden(array('do'), 'export_all') .
+            form::hidden(['do'], 'export_all') .
             $this->core->formNonce() . '</p>' .
 
Index: plugins/importExport/inc/class.dc.ieModule.php
===================================================================
--- plugins/importExport/inc/class.dc.ieModule.php	(revision 3731)
+++ plugins/importExport/inc/class.dc.ieModule.php	(revision 3874)
@@ -28,5 +28,5 @@
         $this->setInfo();
 
-        if (!in_array($this->type, array('import', 'export'))) {
+        if (!in_array($this->type, ['import', 'export'])) {
             throw new Exception(sprintf('Unknow type for module %s', get_class($this)));
         }
@@ -66,5 +66,5 @@
     protected function autoSubmit()
     {
-        return form::hidden(array('autosubmit'), 1);
+        return form::hidden(['autosubmit'], 1);
     }
 
Index: plugins/importExport/inc/class.dc.import.dc1.php
===================================================================
--- plugins/importExport/inc/class.dc.import.dc1.php	(revision 3731)
+++ plugins/importExport/inc/class.dc.import.dc1.php	(revision 3874)
@@ -25,8 +25,8 @@
     protected $post_count  = 0;
 
-    protected $has_table = array();
+    protected $has_table = [];
 
     protected $vars;
-    protected $base_vars = array(
+    protected $base_vars = [
         'db_driver'  => 'mysql',
         'db_host'    => '',
@@ -36,6 +36,6 @@
         'db_prefix'  => 'dc_',
         'post_limit' => 20,
-        'cat_ids'    => array()
-    );
+        'cat_ids'    => []
+    ];
 
     protected function setInfo()
@@ -141,8 +141,8 @@
 
         # db drivers
-        $db_drivers = array(
+        $db_drivers = [
             'mysql'  => 'mysql',
             'mysqli' => 'mysqli'
-        );
+        ];
 
         switch ($this->step) {
@@ -190,7 +190,7 @@
             case 5:
                 $t = sprintf(__('Importing entries from %d to %d / %d'), $this->post_offset,
-                    min(array($this->post_offset + $this->post_limit, $this->post_count)), $this->post_count);
+                    min([$this->post_offset + $this->post_limit, $this->post_count]), $this->post_count);
                 printf($this->imForm(5, $t),
-                    form::hidden(array('offset'), $this->post_offset) .
+                    form::hidden(['offset'], $this->post_offset) .
                     $this->autoSubmit()
                 );
@@ -226,5 +226,5 @@
         '<h3 class="vertical-separator">' . $legend . '</h3>' .
         '<div>' . $this->core->formNonce() .
-        form::hidden(array('do'), 'step' . $step) .
+        form::hidden(['do'], 'step' . $step) .
         '%s' . '</div>' .
         '<p class="vertical-separator"><input type="submit" value="' . $submit_value . '" /></p>' .
@@ -300,10 +300,10 @@
                     $cur->user_tz          = $this->core->blog->settings->system->blog_timezone;
                     $cur->user_post_status = $rs->user_post_pub ? 1 : -2;
-                    $cur->user_options     = new ArrayObject(array(
+                    $cur->user_options     = new ArrayObject([
                         'edit_size'   => (integer) $rs->user_edit_size,
                         'post_format' => $rs->user_post_format
-                    ));
-
-                    $permissions = array();
+                    ]);
+
+                    $permissions = [];
                     switch ($rs->user_level) {
                         case '0':
@@ -573,5 +573,5 @@
     protected function importPings($post_id, $new_post_id, $db)
     {
-        $urls = array();
+        $urls = [];
 
         $rs = $db->select(
Index: plugins/importExport/inc/class.dc.import.feed.php
===================================================================
--- plugins/importExport/inc/class.dc.import.feed.php	(revision 3731)
+++ plugins/importExport/inc/class.dc.import.feed.php	(revision 3874)
@@ -46,6 +46,6 @@
             $dns = $dns6;
         }
-        $ip6 = array();
-        $ip4 = array();
+        $ip6 = [];
+        $ip4 = [];
         foreach ($dns as $record) {
             if ($record["type"] == "A") {
@@ -178,5 +178,5 @@
         '<p>' .
         $this->core->formNonce() .
-        form::hidden(array('do'), 1) .
+        form::hidden(['do'], 1) .
         '<input type="submit" value="' . __('Import') . '" /></p>' .
 
Index: plugins/importExport/inc/class.dc.import.flat.php
===================================================================
--- plugins/importExport/inc/class.dc.import.flat.php	(revision 3731)
+++ plugins/importExport/inc/class.dc.import.flat.php	(revision 3874)
@@ -147,5 +147,5 @@
         }
 
-        $public_files = array_merge(array('-' => ''), $this->getPublicFiles());
+        $public_files = array_merge(['-' => ''], $this->getPublicFiles());
         $has_files    = (boolean) (count($public_files) - 1);
 
@@ -193,6 +193,6 @@
         '<p>' .
         $this->core->formNonce() .
-        form::hidden(array('do'), 1) .
-        form::hidden(array('MAX_FILE_SIZE'), DC_MAX_UPLOAD_SIZE) .
+        form::hidden(['do'], 1) .
+        form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) .
         '<input type="submit" value="' . __('Import') . '" /></p>' .
 
@@ -220,14 +220,14 @@
             '<p><label for="your_pwd" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Your password:') . '</label>' .
             form::password('your_pwd', 20, 255,
-                array(
+                [
                     'extra_html'   => 'required placeholder="' . __('Password') . '"',
                     'autocomplete' => 'current-password'
-                )
+                ]
             ) . '</p>' .
 
             '<p>' .
             $this->core->formNonce() .
-            form::hidden(array('do'), 1) .
-            form::hidden(array('MAX_FILE_SIZE'), DC_MAX_UPLOAD_SIZE) .
+            form::hidden(['do'], 1) .
+            form::hidden(['MAX_FILE_SIZE'], DC_MAX_UPLOAD_SIZE) .
             '<input type="submit" value="' . __('Import') . '" /></p>' .
 
@@ -238,5 +238,5 @@
     protected function getPublicFiles()
     {
-        $public_files = array();
+        $public_files = [];
         $dir          = @dir($this->core->blog->public_path);
         if ($dir) {
Index: plugins/importExport/inc/class.dc.import.wp.php
===================================================================
--- plugins/importExport/inc/class.dc.import.wp.php	(revision 3731)
+++ plugins/importExport/inc/class.dc.import.wp.php	(revision 3874)
@@ -25,8 +25,8 @@
     protected $post_count  = 0;
 
-    protected $has_table = array();
+    protected $has_table = [];
 
     protected $vars;
-    protected $base_vars = array(
+    protected $base_vars = [
         'db_host'            => '',
         'db_name'            => '',
@@ -41,8 +41,8 @@
         'post_formater'      => 'xhtml',
         'comment_formater'   => 'xhtml',
-        'user_ids'           => array(),
-        'cat_ids'            => array(),
+        'user_ids'           => [],
+        'cat_ids'            => [],
         'permalink_template' => 'p=%post_id%',
-        'permalink_tags'     => array(
+        'permalink_tags'     => [
             '%year%',
             '%monthnum%',
@@ -55,6 +55,6 @@
             '%category%',
             '%author%'
-        )
-    );
+        ]
+    ];
     protected $formaters;
 
@@ -244,7 +244,7 @@
             case 5:
                 $t = sprintf(__('Importing entries from %d to %d / %d'), $this->post_offset,
-                    min(array($this->post_offset + $this->post_limit, $this->post_count)), $this->post_count);
+                    min([$this->post_offset + $this->post_limit, $this->post_count]), $this->post_count);
                 printf($this->imForm(5, $t),
-                    form::hidden(array('offset'), $this->post_offset) .
+                    form::hidden(['offset'], $this->post_offset) .
                     $this->autoSubmit()
                 );
@@ -271,5 +271,5 @@
         '<h3 class="vertical-separator">' . $legend . '</h3>' .
         '<div>' . $this->core->formNonce() .
-        form::hidden(array('do'), 'step' . $step) .
+        form::hidden(['do'], 'step' . $step) .
         '%s' . '</div>' .
         '<p><input type="submit" value="' . $submit_value . '" /></p>' .
@@ -347,5 +347,5 @@
                     $cur->user_lang        = $this->core->blog->settings->system->lang;
                     $cur->user_tz          = $this->core->blog->settings->system->blog_timezone;
-                    $permissions           = array();
+                    $permissions           = [];
 
                     $rs_meta = $db->select('SELECT * FROM ' . $prefix . 'usermeta WHERE user_id = ' . $rs->ID);
@@ -362,7 +362,7 @@
                                 break;
                             case 'rich_editing':
-                                $cur->user_options = new ArrayObject(array(
+                                $cur->user_options = new ArrayObject([
                                     'enable_wysiwyg' => $rs_meta->meta_value == 'true' ? true : false
-                                ));
+                                ]);
                                 break;
                             case 'wp_user_level':
@@ -587,5 +587,5 @@
         }
 
-        $permalink_infos = array(
+        $permalink_infos = [
             date('Y', strtotime($cur->post_dt)),
             date('m', strtotime($cur->post_dt)),
@@ -598,5 +598,5 @@
             $cur->cat_id,
             $cur->user_id
-        );
+        ];
         $cur->post_url = str_replace(
             $this->vars['permalink_tags'],
@@ -727,6 +727,6 @@
     protected function importPings($post_id, $new_post_id, $db)
     {
-        $urls  = array();
-        $pings = array();
+        $urls  = [];
+        $pings = [];
 
         $rs = $db->select(
Index: plugins/importExport/inc/flat/class.flat.backup.php
===================================================================
--- plugins/importExport/inc/flat/class.flat.backup.php	(revision 3731)
+++ plugins/importExport/inc/flat/class.flat.backup.php	(revision 3874)
@@ -15,14 +15,14 @@
 {
     protected $fp;
-    private $line_cols = array();
+    private $line_cols = [];
     private $line_name;
     private $line_num;
 
-    private $replacement = array(
+    private $replacement = [
         '/(?<!\\\\)(?>(\\\\\\\\)*+)(\\\\n)/u' => "\$1\n",
         '/(?<!\\\\)(?>(\\\\\\\\)*+)(\\\\r)/u' => "\$1\r",
         '/(?<!\\\\)(?>(\\\\\\\\)*+)(\\\\")/u' => '$1"',
         '/(\\\\\\\\)/'                        => '\\'
-    );
+    ];
 
     public function __construct($file)
@@ -64,5 +64,5 @@
             }
 
-            $res = array();
+            $res = [];
 
             for ($i = 0; $i < count($line); $i++) {
@@ -95,5 +95,5 @@
     public $__name;
     public $__line;
-    private $__data = array();
+    private $__data = [];
 
     public function __construct($name, $data, $line)
@@ -124,7 +124,7 @@
     }
 
-    public function drop()
+    public function drop(...$args)
     {
-        foreach (func_get_args() as $n) {
+        foreach ($args as $n) {
             if (isset($this->__data[$n])) {
                 unset($this->__data[$n]);
Index: plugins/importExport/inc/flat/class.flat.export.php
===================================================================
--- plugins/importExport/inc/flat/class.flat.export.php	(revision 3731)
+++ plugins/importExport/inc/flat/class.flat.export.php	(revision 3874)
@@ -17,6 +17,6 @@
     private $prefix;
 
-    private $line_reg = array('/\\\\/u', '/\n/u', '/\r/u', '/"/u');
-    private $line_rep = array('\\\\\\\\', '\n', '\r', '\"');
+    private $line_reg = ['/\\\\/u', '/\n/u', '/\r/u', '/"/u'];
+    private $line_rep = ['\\\\\\\\', '\n', '\r', '\"'];
 
     public $fp;
@@ -74,5 +74,5 @@
         $db_tables = $schema->getTables();
 
-        $tables = array();
+        $tables = [];
         foreach ($db_tables as $t) {
             if ($this->prefix) {
@@ -90,5 +90,5 @@
     public function getLine($rs)
     {
-        $l    = array();
+        $l    = [];
         $cols = $rs->columns();
         foreach ($cols as $i => &$c) {
Index: plugins/importExport/inc/flat/class.flat.import.php
===================================================================
--- plugins/importExport/inc/flat/class.flat.import.php	(revision 3756)
+++ plugins/importExport/inc/flat/class.flat.import.php	(revision 3874)
@@ -26,16 +26,16 @@
     private $blog_desc;
 
-    private $users = array();
-
-    public $old_ids = array(
-        'category' => array(),
-        'post'     => array(),
-        'media'    => array()
-    );
-
-    public $stack = array(
+    private $users = [];
+
+    public $old_ids = [
+        'category' => [],
+        'post'     => [],
+        'media'    => []
+    ];
+
+    public $stack = [
         'categories' => null,
         'cat_id'     => 1,
-        'cat_lft'    => array(),
+        'cat_lft'    => [],
         'post_id'    => 1,
         'media_id'   => 1,
@@ -43,5 +43,5 @@
         'link_id'    => 1,
         'log_id'     => 1
-    );
+    ];
 
     public $has_categories = false;
@@ -157,5 +157,5 @@
         {
             $last_line_name = '';
-            $constrained    = array('post', 'meta', 'post_media', 'ping', 'comment');
+            $constrained    = ['post', 'meta', 'post_media', 'ping', 'comment'];
 
             while (($line = $this->getLine()) !== false) {
@@ -814,8 +814,8 @@
     private function prepareDC12line(&$line)
     {
-        $settings = array('dc_theme', 'dc_nb_post_per_page', 'dc_allow_comments',
+        $settings = ['dc_theme', 'dc_nb_post_per_page', 'dc_allow_comments',
             'dc_allow_trackbacks', 'dc_comment_pub', 'dc_comments_ttl',
             'dc_wiki_comments', 'dc_use_smilies', 'dc_date_format', 'dc_time_format',
-            'dc_url_scan');
+            'dc_url_scan'];
 
         switch ($line->__name) {
Index: plugins/importExport/index.php
===================================================================
--- plugins/importExport/index.php	(revision 3731)
+++ plugins/importExport/index.php	(revision 3874)
@@ -27,5 +27,5 @@
 }
 
-$modules = new ArrayObject(array('import' => array(), 'export' => array()));
+$modules = new ArrayObject(['import' => [], 'export' => []]);
 
 # --BEHAVIOR-- importExportModules
@@ -33,5 +33,5 @@
 
 $type = null;
-if (!empty($_REQUEST['type']) && in_array($_REQUEST['type'], array('export', 'import'))) {
+if (!empty($_REQUEST['type']) && in_array($_REQUEST['type'], ['export', 'import'])) {
     $type = $_REQUEST['type'];
 }
@@ -71,9 +71,9 @@
 if ($type && $module !== null) {
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins')                   => '',
             $title                          => $p_url,
             html::escapeHTML($module->name) => ''
-        )) .
+        ]) .
     dcPage::notices();
 
@@ -86,8 +86,8 @@
 } else {
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins') => '',
             $title        => ''
-        )) .
+        ]) .
     dcPage::notices();
 
@@ -98,5 +98,5 @@
     '<p class="info">' . sprintf(
         __('Export functions are in the page %s.'),
-        '<a href="' . $core->adminurl->get('admin.plugin.maintenance', array('tab' => 'backup')) . '#backup">' . __('Maintenance') . '</a>'
+        '<a href="' . $core->adminurl->get('admin.plugin.maintenance', ['tab' => 'backup']) . '#backup">' . __('Maintenance') . '</a>'
     ) . '</p>';
 }
Index: plugins/maintenance/_admin.php
===================================================================
--- plugins/maintenance/_admin.php	(revision 3731)
+++ plugins/maintenance/_admin.php	(revision 3874)
@@ -22,11 +22,11 @@
 
 // Admin behaviors
-$core->addBehavior('dcMaintenanceInit', array('dcMaintenanceAdmin', 'dcMaintenanceInit'));
-$core->addBehavior('adminDashboardFavorites', array('dcMaintenanceAdmin', 'adminDashboardFavorites'));
-$core->addBehavior('adminDashboardContents', array('dcMaintenanceAdmin', 'adminDashboardItems'));
-$core->addBehavior('adminDashboardOptionsForm', array('dcMaintenanceAdmin', 'adminDashboardOptionsForm'));
-$core->addBehavior('adminAfterDashboardOptionsUpdate', array('dcMaintenanceAdmin', 'adminAfterDashboardOptionsUpdate'));
-$core->addBehavior('adminPageHelpBlock', array('dcMaintenanceAdmin', 'adminPageHelpBlock'));
-$core->addBehavior('pluginsToolsHeaders', array('dcMaintenanceAdmin', 'pluginsToolsHeaders'));
+$core->addBehavior('dcMaintenanceInit', ['dcMaintenanceAdmin', 'dcMaintenanceInit']);
+$core->addBehavior('adminDashboardFavorites', ['dcMaintenanceAdmin', 'adminDashboardFavorites']);
+$core->addBehavior('adminDashboardContents', ['dcMaintenanceAdmin', 'adminDashboardItems']);
+$core->addBehavior('adminDashboardOptionsForm', ['dcMaintenanceAdmin', 'adminDashboardOptionsForm']);
+$core->addBehavior('adminAfterDashboardOptionsUpdate', ['dcMaintenanceAdmin', 'adminAfterDashboardOptionsUpdate']);
+$core->addBehavior('adminPageHelpBlock', ['dcMaintenanceAdmin', 'adminPageHelpBlock']);
+$core->addBehavior('pluginsToolsHeaders', ['dcMaintenanceAdmin', 'pluginsToolsHeaders']);
 
 /**
@@ -47,7 +47,7 @@
     {
         $maintenance
-            ->addTab('maintenance', __('Servicing'), array('summary' => __('Tools to maintain the performance of your blogs.')))
-            ->addTab('backup', __('Backup'), array('summary' => __('Tools to back up your content.')))
-            ->addTab('dev', __('Development'), array('summary' => __('Tools to assist in development of plugins, themes and core.')))
+            ->addTab('maintenance', __('Servicing'), ['summary' => __('Tools to maintain the performance of your blogs.')])
+            ->addTab('backup', __('Backup'), ['summary' => __('Tools to back up your content.')])
+            ->addTab('dev', __('Development'), ['summary' => __('Tools to assist in development of plugins, themes and core.')])
 
             ->addGroup('optimize', __('Optimize'))
@@ -58,5 +58,5 @@
             ->addGroup('zipfull', __('All blogs'))
 
-            ->addGroup('l10n', __('Translations'), array('summary' => __('Maintain translations')))
+            ->addGroup('l10n', __('Translations'), ['summary' => __('Maintain translations')])
 
             ->addTask('dcMaintenanceCache')
@@ -81,5 +81,5 @@
     public static function adminDashboardFavorites($core, $favs)
     {
-        $favs->register('maintenance', array(
+        $favs->register('maintenance', [
             'title'        => __('Maintenance'),
             'url'          => $core->adminurl->get('admin.plugin.maintenance'),
@@ -87,7 +87,7 @@
             'large-icon'   => dcPage::getPF('maintenance/icon-big.png'),
             'permissions'  => 'admin',
-            'active_cb'    => array('dcMaintenanceAdmin', 'adminDashboardFavoritesActive'),
-            'dashboard_cb' => array('dcMaintenanceAdmin', 'adminDashboardFavoritesCallback')
-        ));
+            'active_cb'    => ['dcMaintenanceAdmin', 'adminDashboardFavoritesActive'],
+            'dashboard_cb' => ['dcMaintenanceAdmin', 'adminDashboardFavoritesCallback']
+        ]);
     }
 
@@ -152,5 +152,5 @@
         $maintenance = new dcMaintenance($core);
 
-        $lines = array();
+        $lines = [];
         foreach ($maintenance->getTasks() as $t) {
             $ts = $t->expired();
@@ -174,5 +174,5 @@
         }
 
-        $items[] = new ArrayObject(array(
+        $items[] = new ArrayObject([
             '<div id="maintenance-expired" class="box small">' .
             '<h3><img src="' . dcPage::getPF('maintenance/icon-small.png') . '" alt="" /> ' . __('Maintenance') . '</h3>' .
@@ -181,5 +181,5 @@
             '<p><a href="' . $core->adminurl->get('admin.plugin.maintenance') . '">' . __('Manage tasks') . '</a></p>' .
             '</div>'
-        ));
+        ]);
     }
 
Index: plugins/maintenance/_define.php
===================================================================
--- plugins/maintenance/_define.php	(revision 3731)
+++ plugins/maintenance/_define.php	(revision 3874)
@@ -17,11 +17,11 @@
     "Olivier Meunier & Association Dotclear", // Author
     '1.3.1',                                  // Version
-    array(
+    [
         'permissions' => 'admin',
         'type'        => 'plugin',
-        'settings'    => array(
+        'settings'    => [
             'self' => '#settings'
-        )
-    )
+        ]
+    ]
 
 );
Index: plugins/maintenance/_prepend.php
===================================================================
--- plugins/maintenance/_prepend.php	(revision 3731)
+++ plugins/maintenance/_prepend.php	(revision 3874)
@@ -28,3 +28,3 @@
 $__autoload['dcMaintenanceZiptheme']       = dirname(__FILE__) . '/inc/tasks/class.dc.maintenance.ziptheme.php';
 
-$this->core->rest->addFunction('dcMaintenanceStep', array('dcMaintenanceRest', 'step'));
+$this->core->rest->addFunction('dcMaintenanceStep', ['dcMaintenanceRest', 'step']);
Index: plugins/maintenance/inc/class.dc.maintenance.descriptor.php
===================================================================
--- plugins/maintenance/inc/class.dc.maintenance.descriptor.php	(revision 3731)
+++ plugins/maintenance/inc/class.dc.maintenance.descriptor.php	(revision 3874)
@@ -31,5 +31,5 @@
      * @param    options    <b>string<b> Options
      */
-    public function __construct($id, $name, $options = array())
+    public function __construct($id, $name, $options = [])
     {
         $this->id      = (string) $id;
Index: plugins/maintenance/inc/class.dc.maintenance.php
===================================================================
--- plugins/maintenance/inc/class.dc.maintenance.php	(revision 3731)
+++ plugins/maintenance/inc/class.dc.maintenance.php	(revision 3874)
@@ -20,7 +20,7 @@
     public $p_url;
 
-    private $tasks  = array();
-    private $tabs   = array();
-    private $groups = array();
+    private $tasks  = [];
+    private $tabs   = [];
+    private $groups = [];
     private $logs   = null;
 
@@ -61,5 +61,5 @@
      * @return <b>dcMaintenance</b>    Self
      */
-    public function addTab($id, $name, $options = array())
+    public function addTab($id, $name, $options = [])
     {
         $this->tabs[$id] = new dcMaintenanceDescriptor($id, $name, $options);
@@ -100,5 +100,5 @@
      * @return <b>dcMaintenance</b>    Self
      */
-    public function addGroup($id, $name, $options = array())
+    public function addGroup($id, $name, $options = [])
     {
         $this->groups[$id] = new dcMaintenanceDescriptor($id, $name, $options);
@@ -205,5 +205,5 @@
         );
 
-        $logs = array();
+        $logs = [];
         while ($rs->fetch()) {
             $logs[] = $rs->log_id;
@@ -231,10 +231,10 @@
     {
         // Retrieve logs from this task
-        $rs = $this->core->log->getLogs(array(
+        $rs = $this->core->log->getLogs([
             'log_table' => 'maintenance',
             'blog_id'   => 'all'
-        ));
-
-        $logs = array();
+        ]);
+
+        $logs = [];
         while ($rs->fetch()) {
             $logs[] = $rs->log_id;
@@ -250,10 +250,10 @@
      * Get logs
      *
-     * Return array(
-     *        task id => array(
+     * Return [
+     *        task id => [
      *            timestamp of last execution,
      *            logged on current blog or not
-     *        )
-     * )
+     *        ]
+     * ]
      *
      * @return    <b>array</b> List of logged tasks
@@ -262,15 +262,15 @@
     {
         if ($this->logs === null) {
-            $rs = $this->core->log->getLogs(array(
+            $rs = $this->core->log->getLogs([
                 'log_table' => 'maintenance',
                 'blog_id'   => 'all'
-            ));
-
-            $this->logs = array();
+            ]);
+
+            $this->logs = [];
             while ($rs->fetch()) {
-                $this->logs[$rs->log_msg] = array(
+                $this->logs[$rs->log_msg] = [
                     'ts'   => strtotime($rs->log_dt),
                     'blog' => $rs->blog_id == $this->core->blog->id
-                );
+                ];
             }
         }
Index: plugins/maintenance/inc/class.dc.maintenance.task.php
===================================================================
--- plugins/maintenance/inc/class.dc.maintenance.task.php	(revision 3731)
+++ plugins/maintenance/inc/class.dc.maintenance.task.php	(revision 3874)
@@ -155,5 +155,5 @@
             } else {
                 $this->expired = null;
-                $logs          = array();
+                $logs          = [];
                 foreach ($this->maintenance->getLogs() as $id => $log) {
                     if ($id != $this->id() || $this->blog && !$log['blog']) {
Index: plugins/maintenance/index.php
===================================================================
--- plugins/maintenance/index.php	(revision 3731)
+++ plugins/maintenance/index.php	(revision 3874)
@@ -22,5 +22,5 @@
 $p_url   = $core->adminurl->get('admin.plugin.maintenance');
 $task    = null;
-$expired = array();
+$expired = [];
 
 $code = empty($_POST['code']) ? null : (integer) $_POST['code'];
@@ -101,5 +101,5 @@
 // Combos
 
-$combo_ts = array(
+$combo_ts = [
     __('Never')            => 0,
     __('Every week')       => 604800,
@@ -107,5 +107,5 @@
     __('Every month')      => 2592000,
     __('Every two months') => 5184000
-);
+];
 
 // Display page
@@ -132,8 +132,8 @@
 if (empty($tasks)) {
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins')     => '',
             __('Maintenance') => ''
-        )
+        ]
     ) .
     '<p class="warn">' . __('You have not sufficient permissions to view this page.') . '</p>' .
@@ -148,9 +148,9 @@
 
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins')                                            => '',
             '<a href="' . $p_url . '">' . __('Maintenance') . '</a>' => '',
             html::escapeHTML($task->name())                          => ''
-        )
+        ]
     ) . dcPage::notices();
 
@@ -172,6 +172,6 @@
     '<p class="step-submit">' .
     '<input type="submit" value="' . $task->task() . '" /> ' .
-    form::hidden(array('task'), $task->id()) .
-    form::hidden(array('code'), (integer) $code) .
+    form::hidden(['task'], $task->id()) .
+    form::hidden(['code'], (integer) $code) .
     $core->formNonce() .
         '</p>' .
@@ -183,8 +183,8 @@
 
     echo dcPage::breadcrumb(
-        array(
+        [
             __('Plugins')     => '',
             __('Maintenance') => ''
-        )
+        ]
     ) . dcPage::notices();
 
@@ -203,5 +203,5 @@
 
                 $res_task .=
-                '<p>' . form::radio(array('task', $t->id()), $t->id()) . ' ' .
+                '<p>' . form::radio(['task', $t->id()], $t->id()) . ' ' .
                 '<label class="classic" for="' . $t->id() . '">' .
                 html::escapeHTML($t->task()) . '</label>';
@@ -246,5 +246,5 @@
             $res_group .
             '<p><input type="submit" value="' . __('Execute task') . '" /> ' .
-            form::hidden(array('tab'), $tab_obj->id()) .
+            form::hidden(['tab'], $tab_obj->id()) .
             $core->formNonce() . '</p>' .
             '<p class="form-note info">' . __('This may take a very long time.') . '</p>' .
@@ -267,6 +267,6 @@
         $t->content() .
         '<p><input type="submit" value="' . __('Execute task') . '" /> ' .
-        form::hidden(array('task'), $t->id()) .
-        form::hidden(array('tab'), $t->id()) .
+        form::hidden(['task'], $t->id()) .
+        form::hidden(['tab'], $t->id()) .
         $core->formNonce() . '</p>' .
             '</form>' .
@@ -293,5 +293,5 @@
     '<h4 class="pretty-title vertical-separator">' . __('Frequency') . '</h4>' .
 
-    '<p class="vertical-separator">' . form::radio(array('settings_recall_type', 'settings_recall_all'), 'all') . ' ' .
+    '<p class="vertical-separator">' . form::radio(['settings_recall_type', 'settings_recall_all'], 'all') . ' ' .
     '<label class="classic" for="settings_recall_all">' .
     '<strong>' . __('Use one recall time for all tasks') . '</strong></label></p>' .
@@ -301,5 +301,5 @@
     '</p>' .
 
-    '<p class="vertical-separator">' . form::radio(array('settings_recall_type', 'settings_recall_separate'), 'separate', 1) . ' ' .
+    '<p class="vertical-separator">' . form::radio(['settings_recall_type', 'settings_recall_separate'], 'separate', 1) . ' ' .
     '<label class="classic" for="settings_recall_separate">' .
     '<strong>' . __('Use one recall time per task') . '</strong></label></p>';
@@ -321,6 +321,6 @@
     echo
     '<p class="field wide"><input type="submit" value="' . __('Save') . '" /> ' .
-    form::hidden(array('tab'), 'settings') .
-    form::hidden(array('save_settings'), 1) .
+    form::hidden(['tab'], 'settings') .
+    form::hidden(['save_settings'], 1) .
     $core->formNonce() . '</p>' .
         '</form>' .
Index: plugins/maintenance/js/dc.maintenance.js
===================================================================
--- plugins/maintenance/js/dc.maintenance.js	(revision 3709)
+++ plugins/maintenance/js/dc.maintenance.js	(revision 3880)
@@ -4,5 +4,5 @@
 $(function() {
   $('.step-box').each(function() {
-    var code = $('input[name=code]', this).val();
+    const code = $('input[name=code]', this).val();
 
     $('.step-submit', this).remove();
@@ -17,5 +17,5 @@
 
     function dcMaintenanceStep(box, code) {
-      var params = {
+      const params = {
         f: 'dcMaintenanceStep',
         xd_check: dotclear.nonce,
@@ -34,5 +34,5 @@
             $('rsp>step', data).attr('title')
           );
-          var code = $('rsp>step', data).attr('code');
+          const code = $('rsp>step', data).attr('code');
           if (code > 0) {
             dcMaintenanceStep(box, code);
Index: plugins/pages/_admin.php
===================================================================
--- plugins/pages/_admin.php	(revision 3731)
+++ plugins/pages/_admin.php	(revision 3874)
@@ -12,6 +12,6 @@
 if (!defined('DC_CONTEXT_ADMIN')) {return;}
 
-$core->addBehavior('adminColumnsLists', array('pagesColumnsLists', 'adminColumnsLists'));
-$core->addBehavior('adminDashboardFavorites', array('pagesDashboard', 'pagesDashboardFavs'));
+$core->addBehavior('adminColumnsLists', ['pagesColumnsLists', 'adminColumnsLists']);
+$core->addBehavior('adminDashboardFavorites', ['pagesDashboard', 'pagesDashboardFavs']);
 $core->addBehavior('adminUsersActionsHeaders', 'pages_users_actions_headers');
 
@@ -21,10 +21,10 @@
     {
         // Set optional columns in pages lists
-        $cols['pages'] = array(__('Pages'), array(
-            'date'       => array(true, __('Date')),
-            'author'     => array(true, __('Author')),
-            'comments'   => array(true, __('Comments')),
-            'trackbacks' => array(true, __('Trackbacks'))
-        ));
+        $cols['pages'] = [__('Pages'), [
+            'date'       => [true, __('Date')],
+            'author'     => [true, __('Author')],
+            'comments'   => [true, __('Comments')],
+            'trackbacks' => [true, __('Trackbacks')]
+        ]];
     }
 }
@@ -34,5 +34,5 @@
     public static function pagesDashboardFavs($core, $favs)
     {
-        $favs->register('pages', array(
+        $favs->register('pages', [
             'title'        => __('Pages'),
             'url'          => $core->adminurl->get('admin.plugin.pages'),
@@ -40,15 +40,15 @@
             'large-icon'   => dcPage::getPF('pages/icon-big.png'),
             'permissions'  => 'contentadmin,pages',
-            'dashboard_cb' => array('pagesDashboard', 'pagesDashboardCB'),
-            'active_cb'    => array('pagesDashboard', 'pagesActiveCB')
-        ));
-        $favs->register('newpage', array(
+            'dashboard_cb' => ['pagesDashboard', 'pagesDashboardCB'],
+            'active_cb'    => ['pagesDashboard', 'pagesActiveCB']
+        ]);
+        $favs->register('newpage', [
             'title'       => __('New page'),
-            'url'         => $core->adminurl->get('admin.plugin.pages', array('act' => 'page')),
+            'url'         => $core->adminurl->get('admin.plugin.pages', ['act' => 'page']),
             'small-icon'  => dcPage::getPF('pages/icon-np.png'),
             'large-icon'  => dcPage::getPF('pages/icon-np-big.png'),
             'permissions' => 'contentadmin,pages',
-            'active_cb'   => array('pagesDashboard', 'newPageActiveCB')
-        ));
+            'active_cb'   => ['pagesDashboard', 'newPageActiveCB']
+        ]);
     }
 
Index: plugins/pages/_define.php
===================================================================
--- plugins/pages/_define.php	(revision 3731)
+++ plugins/pages/_define.php	(revision 3874)
@@ -17,8 +17,8 @@
     "Olivier Meunier",                   // Author
     '1.4',                               // Version
-    array(
+    [
         'permissions' => 'contentadmin,pages',
         'priority'    => 999,
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/pages/_install.php
===================================================================
--- plugins/pages/_install.php	(revision 3731)
+++ plugins/pages/_install.php	(revision 3874)
@@ -22,8 +22,8 @@
 
     // Create a first pending page, only on a new installation of this plugin
-    $params = array(
+    $params = [
         'post_type'  => 'page',
         'no_content' => true
-    );
+    ];
     $counter = $core->blog->getPosts($params, true);
 
Index: plugins/pages/_prepend.php
===================================================================
--- plugins/pages/_prepend.php	(revision 3731)
+++ plugins/pages/_prepend.php	(revision 3874)
@@ -15,6 +15,6 @@
 $__autoload['adminPagesList']     = dirname(__FILE__) . '/class.listpage.php';
 
-$core->url->register('pages', 'pages', '^pages/(.+)$', array('urlPages', 'pages'));
-$core->url->register('pagespreview', 'pagespreview', '^pagespreview/(.+)$', array('urlPages', 'pagespreview'));
+$core->url->register('pages', 'pages', '^pages/(.+)$', ['urlPages', 'pages']);
+$core->url->register('pagespreview', 'pagespreview', '^pagespreview/(.+)$', ['urlPages', 'pagespreview']);
 
 $core->setPostType('page', 'plugin.php?p=pages&act=page&id=%d', $core->url->getURLFor('pages', '%s'), 'Pages');
Index: plugins/pages/_public.php
===================================================================
--- plugins/pages/_public.php	(revision 3731)
+++ plugins/pages/_public.php	(revision 3874)
@@ -12,5 +12,5 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('coreBlogBeforeGetPosts', array('publicPages', 'coreBlogBeforeGetPosts'));
+$core->addBehavior('coreBlogBeforeGetPosts', ['publicPages', 'coreBlogBeforeGetPosts']);
 
 # Localized string we find in template
@@ -31,5 +31,5 @@
                 if (!is_array($params['post_type'])) {
                     // Convert it in array
-                    $params['post_type'] = array($params['post_type']);
+                    $params['post_type'] = [$params['post_type']];
                 }
                 if (!in_array('page', $params['post_type'])) {
@@ -39,5 +39,5 @@
             } else {
                 // Dont miss default post type (aka post)
-                $params['post_type'] = array('post', 'page');
+                $params['post_type'] = ['post', 'page'];
             }
         }
@@ -58,7 +58,7 @@
             $core->blog->withoutPassword(false);
 
-            $params = new ArrayObject(array(
+            $params = new ArrayObject([
                 'post_type' => 'page',
-                'post_url'  => $args));
+                'post_url'  => $args]);
 
             $core->callBehavior('publicPagesBeforeGetPosts', $params, $args);
@@ -90,10 +90,10 @@
                         $pwd_cookie = json_decode($_COOKIE['dc_passwd']);
                         if ($pwd_cookie === null) {
-                            $pwd_cookie = array();
+                            $pwd_cookie = [];
                         } else {
                             $pwd_cookie = (array) $pwd_cookie;
                         }
                     } else {
-                        $pwd_cookie = array();
+                        $pwd_cookie = [];
                     }
 
@@ -268,5 +268,5 @@
 
         $sort = $w->sortby;
-        if (!in_array($sort, array('post_title', 'post_position', 'post_dt'))) {
+        if (!in_array($sort, ['post_title', 'post_position', 'post_dt'])) {
             $sort = 'post_title';
         }
Index: plugins/pages/_widgets.php
===================================================================
--- plugins/pages/_widgets.php	(revision 3731)
+++ plugins/pages/_widgets.php	(revision 3874)
@@ -12,6 +12,6 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('initWidgets', array('pagesWidgets', 'initWidgets'));
-$core->addBehavior('initDefaultWidgets', array('pagesWidgets', 'initDefaultWidgets'));
+$core->addBehavior('initWidgets', ['pagesWidgets', 'initWidgets']);
+$core->addBehavior('initDefaultWidgets', ['pagesWidgets', 'initDefaultWidgets']);
 
 class pagesWidgets
@@ -19,22 +19,22 @@
     public static function initWidgets($w)
     {
-        $w->create('pages', __('Pages'), array('tplPages', 'pagesWidget'), null, 'List of published pages');
+        $w->create('pages', __('Pages'), ['tplPages', 'pagesWidget'], null, 'List of published pages');
         $w->pages->setting('title', __('Title (optional)') . ' :', __('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('sortby', __('Order by:'), 'post_title', 'combo',
-            array(
+            [
                 __('Page title')       => 'post_title',
                 __('Page position')    => 'post_position',
                 __('Publication date') => 'post_dt'
-            )
+            ]
         );
         $w->pages->setting('orderby', __('Sort:'), 'asc', 'combo',
-            array(__('Ascending') => 'asc', __('Descending') => 'desc')
+            [__('Ascending') => 'asc', __('Descending') => 'desc']
         );
         $w->pages->setting('content_only', __('Content only'), 0, 'check');
Index: plugins/pages/class.actionpage.php
===================================================================
--- plugins/pages/class.actionpage.php	(revision 3731)
+++ plugins/pages/class.actionpage.php	(revision 3874)
@@ -12,8 +12,8 @@
 class dcPagesActionsPage extends dcPostsActionsPage
 {
-    public function __construct($core, $uri, $redirect_args = array())
+    public function __construct($core, $uri, $redirect_args = [])
     {
         parent::__construct($core, $uri, $redirect_args);
-        $this->redirect_fields = array();
+        $this->redirect_fields = [];
         $this->caller_title    = __('Pages');
 
@@ -24,9 +24,9 @@
         $this->core->error->add($e->getMessage());
         $this->beginPage(dcPage::breadcrumb(
-            array(
+            [
                 html::escapeHTML($this->core->blog->name) => '',
                 __('Pages')                               => $this->getRedirection(true),
                 __('Pages actions')                       => ''
-            ))
+            ])
         );
         $this->endPage();
@@ -52,5 +52,5 @@
     {
         DefaultPagesActions::adminPagesActionsPage($this->core, $this);
-        $this->actions['reorder'] = array('dcPagesActionsPage', 'doReorderPages');
+        $this->actions['reorder'] = ['dcPagesActionsPage', 'doReorderPages'];
         $this->core->callBehavior('adminPagesActionsPage', $this->core, $this);
 
@@ -102,25 +102,25 @@
         if ($core->auth->check('publish,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Status') => array(
+                [__('Status') => [
                     __('Publish')         => 'publish',
                     __('Unpublish')       => 'unpublish',
                     __('Schedule')        => 'schedule',
                     __('Mark as pending') => 'pending'
-                )),
-                array('dcDefaultPostActions', 'doChangePostStatus')
+                ]],
+                ['dcDefaultPostActions', 'doChangePostStatus']
             );
         }
         if ($core->auth->check('admin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Change') => array(
-                    __('Change author') => 'author')),
-                array('dcDefaultPostActions', 'doChangePostAuthor')
+                [__('Change') => [
+                    __('Change author') => 'author']],
+                ['dcDefaultPostActions', 'doChangePostAuthor']
             );
         }
         if ($core->auth->check('delete,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Delete') => array(
-                    __('Delete') => 'delete')),
-                array('dcDefaultPostActions', 'doDeletePost')
+                [__('Delete') => [
+                    __('Delete') => 'delete']],
+                ['dcDefaultPostActions', 'doDeletePost']
             );
         }
Index: plugins/pages/class.listpage.php
===================================================================
--- plugins/pages/class.listpage.php	(revision 3774)
+++ plugins/pages/class.listpage.php	(revision 3874)
@@ -20,5 +20,5 @@
         } else {
             $pager   = new dcPager($page, $this->rs_count, $nb_per_page, 10);
-            $entries = array();
+            $entries = [];
             if (isset($_REQUEST['entries'])) {
                 foreach ($_REQUEST['entries'] as $v) {
@@ -30,5 +30,5 @@
                 '<table class="maximal dragable"><thead><tr>';
 
-            $cols = array(
+            $cols = [
                 'title'      => '<th colspan="3" scope="col" class="first">' . __('Title') . '</th>',
                 'date'       => '<th scope="col">' . __('Date') . '</th>',
@@ -39,5 +39,5 @@
                 '" /><span class="hidden">' . __('Trackbacks') . '</span></th>',
                 'status'     => '<th scope="col">' . __('Status') . '</th>'
-            );
+            ];
 
             $cols = new ArrayObject($cols);
@@ -115,20 +115,20 @@
         ' id="p' . $this->rs->post_id . '">';
 
-        $cols = array(
+        $cols = [
             'position'   => '<td class="nowrap handle minimal">' .
-            form::number(array('order[' . $this->rs->post_id . ']'), array(
+            form::number(['order[' . $this->rs->post_id . ']'], [
                 'min'        => 1,
                 'default'    => $count + 1,
                 'class'      => 'position',
                 'extra_html' => 'title="' . sprintf(__('position of %s'), html::escapeHTML($this->rs->post_title)) . '"'
-            )) .
+            ]) .
             '</td>',
             'check'      => '<td class="nowrap">' .
-            form::checkbox(array('entries[]'), $this->rs->post_id,
-                array(
+            form::checkbox(['entries[]'], $this->rs->post_id,
+                [
                     'checked'    => $checked,
                     'disabled'   => !$this->rs->isEditable(),
                     'extra_html' => 'title="' . __('Select this page') . '"'
-                )
+                ]
             ) . '</td>',
             'title'      => '<td class="maximal" scope="row"><a href="' .
@@ -140,5 +140,5 @@
             'trackbacks' => '<td class="nowrap count">' . $this->rs->nb_trackback . '</td>',
             'status'     => '<td class="nowrap status">' . $img_status . ' ' . $selected . ' ' . $protected . ' ' . $attach . '</td>'
-        );
+        ];
 
         $cols = new ArrayObject($cols);
Index: plugins/pages/js/_users_actions.js
===================================================================
--- plugins/pages/js/_users_actions.js	(revision 3709)
+++ plugins/pages/js/_users_actions.js	(revision 3880)
@@ -5,16 +5,15 @@
   return this.each(function() {
 
-    var perms = {};
-    var re = /^perm\[(.+?)\]\[(.+?)\]$/;
-    var e, prop;
+    let perms = {};
+    const re = /^perm\[(.+?)\]\[(.+?)\]$/;
 
     // Building a nice object of form elements
-    for (var i = 0; i < this.elements.length; i++) {
-      e = this.elements[i];
+    for (let i = 0; i < this.elements.length; i++) {
+      const e = this.elements[i];
 
       if (e.name == undefined) {
         continue;
       }
-      prop = e.name.match(re);
+      const prop = e.name.match(re);
       if (!prop) {
         continue;
@@ -37,5 +36,5 @@
 
     function admin(E, perms, re) {
-      var P = E.name.match(re);
+      const P = E.name.match(re);
 
       perms[P[1]].pages.checked = E.checked;
Index: plugins/pages/js/list.js
===================================================================
--- plugins/pages/js/list.js	(revision 3709)
+++ plugins/pages/js/list.js	(revision 3880)
@@ -2,5 +2,5 @@
 'use strict';
 
-dotclear.viewPostContent = function(line, action) {
+dotclear.viewPostContent = function(line, action, e) {
   action = action || 'toggle';
   if ($(line).attr('id') == undefined) {
@@ -8,48 +8,32 @@
   }
 
-  var postId = $(line).attr('id').substr(1);
-  var tr = document.getElementById('pe' + postId);
+  const postId = $(line).attr('id').substr(1);
+  const lineId = `pe${postId}`;
+  let tr = document.getElementById(lineId);
 
-  if (!tr && (action == 'toggle' || action == 'open')) {
-    tr = document.createElement('tr');
-    tr.id = 'pe' + postId;
-    var td = document.createElement('td');
-    td.colSpan = 8;
-    td.className = 'expand';
-    tr.appendChild(td);
-
-    // Get post content
-    $.get('services.php', {
-      f: 'getPostById',
-      id: postId,
-      post_type: ''
-    }, function(data) {
-      var rsp = $(data).children('rsp')[0];
-
-      if (rsp.attributes[0].value == 'ok') {
-        var post = $(rsp).find('post_display_content').text();
-        var post_excerpt = $(rsp).find('post_display_excerpt').text();
-        var res = '';
-
-        if (post) {
-          if (post_excerpt) {
-            res += post_excerpt + '<hr />';
-          }
-          res += post;
-          $(td).append(res);
-        }
+  if (!tr) {
+    // Get post content if possible
+    dotclear.getEntryContent(postId, function(content) {
+      if (content) {
+        // Content found
+        tr = document.createElement('tr');
+        tr.id = lineId;
+        const td = document.createElement('td');
+        td.colSpan = $(line).children('td').length;
+        td.className = 'expand';
+        tr.appendChild(td);
+        $(td).append(content);
+        $(line).addClass('expand');
+        line.parentNode.insertBefore(tr, line.nextSibling);
       } else {
-        window.alert($(rsp).find('message').text());
+        $(line).toggleClass('expand');
       }
+    }, {
+      type: 'page',
+      clean: (e.metaKey)
     });
-
-    $(line).addClass('expand');
-    line.parentNode.insertBefore(tr, line.nextSibling);
-  } else if (tr && tr.style.display == 'none' && (action == 'toggle' || action == 'open')) {
-    $(tr).css('display', 'table-row');
-    $(line).addClass('expand');
-  } else if (tr && tr.style.display != 'none' && (action == 'toggle' || action == 'close')) {
-    $(tr).css('display', 'none');
-    $(line).removeClass('expand');
+  } else {
+    $(tr).toggle();
+    $(line).toggleClass('expand');
   }
 };
@@ -64,5 +48,5 @@
   });
   $('.checkboxes-helpers').each(function() {
-    var p = $('<p></p>');
+    const p = $('<p></p>');
     $(this).prepend(p);
     dotclear.checkboxesHelpers(p, undefined, '#pageslist td input[type=checkbox]', '#form-entries #do-action');
@@ -73,5 +57,5 @@
   $('#pageslist tr.line td:not(.expander)').mousedown(function() {
     $('#pageslist tr.line').each(function() {
-      var td = this.firstChild;
+      const td = this.firstChild;
       dotclear.viewPostContent(td.firstChild, td.firstChild.line, 'close');
     });
@@ -105,6 +89,6 @@
 
   $('#form-entries').submit(function() {
-    var action = $(this).find('select[name="action"]').val();
-    var checked = false;
+    const action = $(this).find('select[name="action"]').val();
+    let checked = false;
     if ($('input[name="reorder"][clicked=true]').val()) {
       return true;
Index: plugins/pages/js/page.js
===================================================================
--- plugins/pages/js/page.js	(revision 3878)
+++ plugins/pages/js/page.js	(revision 3878)
@@ -0,0 +1,12 @@
+/*global $, dotclear, datePicker, commentTb */
+'use strict';
+
+$(function() {
+  $('#comments').onetabload(function() {
+    $.expandContent({
+      line: $('#part-comments .comments-list tr:not(.line)'),
+      lines: $('#part-comments .comments-list tr.line'),
+      callback: dotclear.viewCommentContent
+    });
+  });
+});
Index: plugins/pages/list.php
===================================================================
--- plugins/pages/list.php	(revision 3731)
+++ plugins/pages/list.php	(revision 3874)
@@ -15,7 +15,7 @@
 /* Getting pages
 -------------------------------------------------------- */
-$params = array(
+$params = [
     'post_type' => 'page'
-);
+];
 
 $page        = !empty($_GET['page']) ? max(1, (integer) $_GET['page']) : 1;
@@ -26,5 +26,5 @@
 }
 
-$params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
 $params['no_content'] = true;
 $params['order']      = 'post_position ASC, post_title ASC';
@@ -40,10 +40,10 @@
 # Actions combo box
 
-$pages_actions_page = new dcPagesActionsPage($core, 'plugin.php', array('p' => 'pages'));
+$pages_actions_page = new dcPagesActionsPage($core, 'plugin.php', ['p' => 'pages']);
 
 if (!$pages_actions_page->process()) {
 
 # --BEHAVIOR-- adminPagesActionsCombo
-    $core->callBehavior('adminPagesActionsCombo', array(&$combo_action));
+    $core->callBehavior('adminPagesActionsCombo', [&$combo_action]);
 
 /* Display
@@ -68,8 +68,8 @@
 <?php
 echo dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             __('Pages')                         => ''
-        )) . dcPage::notices();
+        ]) . dcPage::notices();
 
     if (!empty($_GET['upd'])) {
@@ -96,7 +96,7 @@
             form::combo('action', $pages_actions_page->getCombo()) .
             '<input id="do-action" type="submit" value="' . __('ok') . '" />' .
-            form::hidden(array('post_type'), 'page') .
-            form::hidden(array('p'), 'pages') .
-            form::hidden(array('act'), 'list') .
+            form::hidden(['post_type'], 'page') .
+            form::hidden(['p'], 'pages') .
+            form::hidden(['act'], 'list') .
             $core->formNonce() .
             '</p></div>' .
Index: plugins/pages/page.php
===================================================================
--- plugins/pages/page.php	(revision 3771)
+++ plugins/pages/page.php	(revision 3878)
@@ -34,5 +34,5 @@
 $post_selected      = false;
 
-$post_media = array();
+$post_media = [];
 
 $page_title = __('New page');
@@ -60,5 +60,5 @@
 # Formaters combo
 $core_formaters    = $core->getFormaters();
-$available_formats = array('' => '');
+$available_formats = ['' => ''];
 foreach ($core_formaters as $editor => $formats) {
     foreach ($formats as $format) {
@@ -68,5 +68,5 @@
 
 # Languages combo
-$rs         = $core->blog->getLangs(array('order' => 'asc'));
+$rs         = $core->blog->getLangs(['order' => 'asc']);
 $lang_combo = dcAdminCombos::getLangsCombo($rs, true);
 
@@ -279,10 +279,10 @@
     if ($p_edit == $c_edit) {
         $admin_post_behavior .= $core->callBehavior('adminPostEditor',
-            $p_edit, 'page', array('#post_excerpt', '#post_content', '#comment_content'), $post_format);
+            $p_edit, 'page', ['#post_excerpt', '#post_content', '#comment_content'], $post_format);
     } else {
         $admin_post_behavior .= $core->callBehavior('adminPostEditor',
-            $p_edit, 'page', array('#post_excerpt', '#post_content'), $post_format);
+            $p_edit, 'page', ['#post_excerpt', '#post_content'], $post_format);
         $admin_post_behavior .= $core->callBehavior('adminPostEditor',
-            $c_edit, 'comment', array('#comment_content'), 'xhtml');
+            $c_edit, 'comment', ['#comment_content'], 'xhtml');
     }
 }
@@ -299,4 +299,5 @@
 dcPage::jsModal() .
 dcPage::jsLoad('js/_post.js') .
+dcPage::jsLoad(dcPage::getPF('pages/js/page.js')) .
 $admin_post_behavior .
 dcPage::jsConfirmClose('entry-form', 'comment-form') .
@@ -334,9 +335,9 @@
 }
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Pages')                         => $p_url,
         $edit_entry_title                   => ''
-    ));
+    ]);
 
 if (!empty($_GET['upd'])) {
@@ -386,12 +387,12 @@
 -------------------------------------------------------- */
 if ($can_edit_page) {
-    $sidebar_items = new ArrayObject(array(
-        'status-box'  => array(
+    $sidebar_items = new ArrayObject([
+        'status-box'  => [
             'title' => __('Status'),
-            'items' => array(
+            'items' => [
                 'post_status' =>
                 '<p><label for="post_status">' . __('Page status') . '</label> ' .
                 form::combo('post_status', $status_combo,
-                    array('default' => $post_status, 'disabled' => !$can_publish)) .
+                    ['default' => $post_status, 'disabled' => !$can_publish]) .
                 '</p>',
                 'post_dt'     =>
@@ -402,8 +403,8 @@
                 Dont forget to remove call to datepicker in post.js
 
-                form::datetime('post_dt', array(
+                form::datetime('post_dt', [
                 'default' => html::escapeHTML(dt::str('%Y-%m-%dT%H:%M', strtotime($post_dt))),
                 'class' => ($bad_dt ? 'invalid' : '')
-                )) .
+                ]) .
                  */
                 '</p>',
@@ -419,17 +420,17 @@
                 '<a id="convert-xhtml" class="button' . ($post_id && $post_format != 'wiki' ? ' hide' : '') .
                 '" href="' . html::escapeURL($redir_url) . '&amp;id=' . $post_id . '&amp;xconv=1">' .
-                __('Convert to XHTML') . '</a></p></div>')),
-        'metas-box'   => array(
+                __('Convert to XHTML') . '</a></p></div>']],
+        'metas-box'   => [
             'title' => __('Filing'),
-            'items' => array(
+            'items' => [
                 'post_position' =>
                 '<p><label for="post_position" class="classic">' . __('Page position') . '</label> ' .
-                form::number('post_position', array(
+                form::number('post_position', [
                     'default' => $post_position
-                )) .
-                '</p>')),
-        'options-box' => array(
+                ]) .
+                '</p>']],
+        'options-box' => [
             'title' => __('Options'),
-            'items' => array(
+            'items' => [
                 'post_open_comment_tb' =>
                 '<div>' .
@@ -471,14 +472,14 @@
                 __('Warning: If you set the URL manually, it may conflict with another page.') .
                 '</p></div>'
-            ))));
-    $main_items = new ArrayObject(array(
+            ]]]);
+    $main_items = new ArrayObject([
         "post_title"   =>
         '<p class="col">' .
         '<label class="required no-margin bold" for="post_title"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Title:') . '</label>' .
-        form::field('post_title', 20, 255, array(
+        form::field('post_title', 20, 255, [
             'default'    => html::escapeHTML($post_title),
             'class'      => 'maximal',
             'extra_html' => 'required placeholder="' . __('Title') . '"'
-        )) .
+        ]) .
         '</p>',
 
@@ -493,8 +494,8 @@
         'for="post_content"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Content:') . '</label> ' .
         form::textarea('post_content', 50, $core->auth->getOption('edit_size'),
-            array(
+            [
                 'default'    => html::escapeHTML($post_content),
                 'extra_html' => 'required placeholder="' . __('Content') . '"'
-            )) .
+            ]) .
         '</p>',
 
@@ -504,5 +505,5 @@
         form::textarea('post_notes', 50, 5, html::escapeHTML($post_notes)) .
         '</p>'
-    )
+    ]
     );
 
@@ -577,7 +578,7 @@
         echo
         '<form action="' . $core->adminurl->get('admin.post.media') . '" id="attachment-remove-hide" method="post">' .
-        '<div>' . form::hidden(array('post_id'), $post_id) .
-        form::hidden(array('media_id'), '') .
-        form::hidden(array('remove'), 1) .
+        '<div>' . form::hidden(['post_id'], $post_id) .
+        form::hidden(['media_id'], '') .
+        form::hidden(['remove'], 1) .
         $core->formNonce() . '</div></form>';
     }
@@ -587,11 +588,11 @@
 -------------------------------------------------------- */
 if ($post_id) {
-    $params = array('post_id' => $post_id, 'order' => 'comment_dt ASC');
-
-    $comments   = $core->blog->getComments(array_merge($params, array('comment_trackback' => 0)));
-    $trackbacks = $core->blog->getComments(array_merge($params, array('comment_trackback' => 1)));
+    $params = ['post_id' => $post_id, 'order' => 'comment_dt ASC'];
+
+    $comments   = $core->blog->getComments(array_merge($params, ['comment_trackback' => 0]));
+    $trackbacks = $core->blog->getComments(array_merge($params, ['comment_trackback' => 1]));
 
     # Actions combo box
-    $combo_action = array();
+    $combo_action = [];
     if ($can_edit_page && $core->auth->check('publish,contentadmin', $core->blog->id)) {
         $combo_action[__('Publish')]         = 'publish';
@@ -655,29 +656,29 @@
     '<div class="constrained">' .
     '<p><label for="comment_author" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Name:') . '</label>' .
-    form::field('comment_author', 30, 255, array(
+    form::field('comment_author', 30, 255, [
         'default'    => html::escapeHTML($core->auth->getInfo('user_cn')),
         'extra_html' => 'required placeholder="' . __('Author') . '"'
-    )) .
+    ]) .
     '</p>' .
 
     '<p><label for="comment_email">' . __('Email:') . '</label>' .
-    form::email('comment_email', array(
+    form::email('comment_email', [
         'size'         => 30,
         'default'      => html::escapeHTML($core->auth->getInfo('user_email')),
         'autocomplete' => 'email'
-    )) .
+    ]) .
     '</p>' .
 
     '<p><label for="comment_site">' . __('Web site:') . '</label>' .
-    form::url('comment_site', array(
+    form::url('comment_site', [
         'size'         => 30,
         'default'      => html::escapeHTML($core->auth->getInfo('user_url')),
         'autocomplete' => 'url'
-    )) .
+    ]) .
     '</p>' .
 
     '<p class="area"><label for="comment_content" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' .
     __('Comment:') . '</label> ' .
-    form::textarea('comment_content', 50, 8, array('extra_html' => 'required placeholder="' . __('Comment') . '"')) .
+    form::textarea('comment_content', 50, 8, ['extra_html' => 'required placeholder="' . __('Comment') . '"']) .
     '</p>' .
 
@@ -729,35 +730,40 @@
 
     while ($rs->fetch()) {
-        $comment_url = $core->adminurl->get('admin.comment', array('id' => $rs->comment_id));
-
-        $img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
+        $comment_url = $core->adminurl->get('admin.comment', ['id' => $rs->comment_id]);
+
+        $img       = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
+        $sts_class = '';
         switch ($rs->comment_status) {
             case 1:
                 $img_status = sprintf($img, __('Published'), 'check-on.png');
+                $sts_class  = 'sts-online';
                 break;
             case 0:
                 $img_status = sprintf($img, __('Unpublished'), 'check-off.png');
+                $sts_class  = 'sts-offline';
                 break;
             case -1:
                 $img_status = sprintf($img, __('Pending'), 'check-wrn.png');
+                $sts_class  = 'sts-pending';
                 break;
             case -2:
                 $img_status = sprintf($img, __('Junk'), 'junk.png');
+                $sts_class  = 'sts-junk';
                 break;
         }
 
         echo
-        '<tr class="line' . ($rs->comment_status != 1 ? ' offline' : '') . '"' .
+        '<tr class="line ' . ($rs->comment_status != 1 ? ' offline ' : '') . $sts_class . '"' .
         ' id="c' . $rs->comment_id . '">' .
 
         '<td class="nowrap">' .
-        ($has_action ? form::checkbox(array('comments[]'), $rs->comment_id,
-            array(
+        ($has_action ? form::checkbox(['comments[]'], $rs->comment_id,
+            [
                 'extra_html' => 'title="' . __('Select this comment') . '"'
-            )
+            ]
         ) : '') . '</td>' .
         '<td class="maximal">' . $rs->comment_author . '</td>' .
         '<td class="nowrap">' . dt::dt2str(__('%Y-%m-%d %H:%M'), $rs->comment_dt) . '</td>' .
-        '<td class="nowrap"><a href="' . $core->adminurl->get('admin.comment', array('ip' => $rs->comment_ip)) . '">' . $rs->comment_ip . '</a></td>' .
+        '<td class="nowrap"><a href="' . $core->adminurl->get('admin.comment', ['ip' => $rs->comment_ip]) . '">' . $rs->comment_ip . '</a></td>' .
         '<td class="nowrap status">' . $img_status . '</td>' .
         '<td class="nowrap status"><a href="' . $comment_url . '">' .
Index: plugins/pings/_admin.php
===================================================================
--- plugins/pings/_admin.php	(revision 3731)
+++ plugins/pings/_admin.php	(revision 3874)
@@ -20,8 +20,8 @@
 $__autoload['pingsAdminBehaviors'] = dirname(__FILE__) . '/lib.pings.php';
 
-$core->addBehavior('adminPostHeaders', array('pingsAdminBehaviors', 'pingJS'));
-$core->addBehavior('adminPostFormItems', array('pingsAdminBehaviors', 'pingsFormItems'));
-$core->addBehavior('adminAfterPostCreate', array('pingsAdminBehaviors', 'doPings'));
-$core->addBehavior('adminAfterPostUpdate', array('pingsAdminBehaviors', 'doPings'));
+$core->addBehavior('adminPostHeaders', ['pingsAdminBehaviors', 'pingJS']);
+$core->addBehavior('adminPostFormItems', ['pingsAdminBehaviors', 'pingsFormItems']);
+$core->addBehavior('adminAfterPostCreate', ['pingsAdminBehaviors', 'doPings']);
+$core->addBehavior('adminAfterPostUpdate', ['pingsAdminBehaviors', 'doPings']);
 
 $core->addBehavior('adminDashboardFavorites', 'pingDashboardFavorites');
@@ -29,10 +29,10 @@
 function pingDashboardFavorites($core, $favs)
 {
-    $favs->register('pings', array(
+    $favs->register('pings', [
         'title'      => __('Pings'),
         'url'        => $core->adminurl->get('admin.plugin.pings'),
         'small-icon' => dcPage::getPF('pings/icon.png'),
         'large-icon' => dcPage::getPF('pings/icon-big.png')
-    ));
+    ]);
 }
 
Index: plugins/pings/_define.php
===================================================================
--- plugins/pings/_define.php	(revision 3731)
+++ plugins/pings/_define.php	(revision 3874)
@@ -17,10 +17,10 @@
     "Olivier Meunier", // Author
     '1.3',             // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'type'        => 'plugin',
-        'settings'    => array(
+        'settings'    => [
             'self' => ''
-        )
-    )
+        ]
+    ]
 );
Index: plugins/pings/_install.php
===================================================================
--- plugins/pings/_install.php	(revision 3731)
+++ plugins/pings/_install.php	(revision 3874)
@@ -18,8 +18,8 @@
 
 // Default pings services
-$default_pings_uris = array(
+$default_pings_uris = [
     'Ping-o-Matic!'      => 'http://rpc.pingomatic.com/',
     'Google Blog Search' => 'http://blogsearch.google.com/ping/RPC2'
-);
+];
 
 $core->blog->settings->addNamespace('pings');
Index: plugins/pings/_prepend.php
===================================================================
--- plugins/pings/_prepend.php	(revision 3731)
+++ plugins/pings/_prepend.php	(revision 3874)
@@ -15,3 +15,3 @@
 $__autoload['pingsCoreBehaviour'] = dirname(__FILE__) . '/lib.pings.php';
 
-$core->addBehavior('coreFirstPublicationEntries', array('pingsCoreBehaviour', 'doPings'));
+$core->addBehavior('coreFirstPublicationEntries', ['pingsCoreBehaviour', 'doPings']);
Index: plugins/pings/index.php
===================================================================
--- plugins/pings/index.php	(revision 3731)
+++ plugins/pings/index.php	(revision 3874)
@@ -18,11 +18,11 @@
     $pings_uris = $core->blog->settings->pings->pings_uris;
     if (!$pings_uris) {
-        $pings_uris = array();
+        $pings_uris = [];
     }
 
     if (isset($_POST['pings_srv_name'])) {
-        $pings_srv_name = is_array($_POST['pings_srv_name']) ? $_POST['pings_srv_name'] : array();
-        $pings_srv_uri  = is_array($_POST['pings_srv_uri']) ? $_POST['pings_srv_uri'] : array();
-        $pings_uris     = array();
+        $pings_srv_name = is_array($_POST['pings_srv_name']) ? $_POST['pings_srv_name'] : [];
+        $pings_srv_uri  = is_array($_POST['pings_srv_uri']) ? $_POST['pings_srv_uri'] : [];
+        $pings_uris     = [];
 
         foreach ($pings_srv_name as $k => $v) {
@@ -55,8 +55,8 @@
 
 echo dcPage::breadcrumb(
-    array(
+    [
         __('Plugins')             => '',
         __('Pings configuration') => ''
-    ));
+    ]);
 
 echo
@@ -69,10 +69,10 @@
     echo
     '<p><label for="pings_srv_name-' . $i . '" class="classic">' . __('Service name:') . '</label> ' .
-    form::field(array('pings_srv_name[]', 'pings_srv_name-' . $i), 20, 128, html::escapeHTML($n)) . ' ' .
+    form::field(['pings_srv_name[]', 'pings_srv_name-' . $i], 20, 128, html::escapeHTML($n)) . ' ' .
     '<label for="pings_srv_uri-' . $i . '" class="classic">' . __('Service URI:') . '</label> ' .
-    form::url(array('pings_srv_uri[]', 'pings_srv_uri-' . $i), array(
+    form::url(['pings_srv_uri[]', 'pings_srv_uri-' . $i], [
         'size'    => 40,
         'default' => html::escapeHTML($u)
-    ));
+    ]);
 
     if (!empty($_GET['test'])) {
@@ -91,7 +91,7 @@
 echo
 '<p><label for="pings_srv_name2" class="classic">' . __('Service name:') . '</label> ' .
-form::field(array('pings_srv_name[]', 'pings_srv_name2'), 20, 128) . ' ' .
+form::field(['pings_srv_name[]', 'pings_srv_name2'], 20, 128) . ' ' .
 '<label for="pings_srv_uri2" class="classic">' . __('Service URI:') . '</label> ' .
-form::url(array('pings_srv_uri[]', 'pings_srv_uri2'), 40) .
+form::url(['pings_srv_uri[]', 'pings_srv_uri2'], 40) .
 '</p>' .
 
Index: plugins/pings/js/post.js
===================================================================
--- plugins/pings/js/post.js	(revision 3709)
+++ plugins/pings/js/post.js	(revision 3880)
@@ -3,15 +3,15 @@
 
 $(function() {
-	$('#edit-entry').onetabload(function() {
-		if ($('p.ping-services').length > 0) {
-			var p = $('<p></p>');
-			p.addClass('ping-services');
-			$('p.ping-services:last').after(p);
-			dotclear.checkboxesHelpers($('p.ping-services:last').get(0), $('.check-ping-services'));
-		}
-		$('h5.ping-services').toggleWithLegend($('p.ping-services'),{
-			user_pref: 'dcx_ping_services',
-			legend_click: true
-		});
-	});
+  $('#edit-entry').onetabload(function() {
+    if ($('p.ping-services').length > 0) {
+      const p = $('<p></p>');
+      p.addClass('ping-services');
+      $('p.ping-services:last').after(p);
+      dotclear.checkboxesHelpers($('p.ping-services:last').get(0), $('.check-ping-services'));
+    }
+    $('h5.ping-services').toggleWithLegend($('p.ping-services'), {
+      user_pref: 'dcx_ping_services',
+      legend_click: true
+    });
+  });
 });
Index: plugins/pings/lib.pings.php
===================================================================
--- plugins/pings/lib.pings.php	(revision 3731)
+++ plugins/pings/lib.pings.php	(revision 3874)
@@ -59,5 +59,5 @@
             $pings_do = $_POST['pings_do'];
         } else {
-            $pings_do = array();
+            $pings_do = [];
         }
 
@@ -67,5 +67,5 @@
             $item .=
             '<p class="ping-services"><label for="pings_do-' . $i . '" class="classic">' .
-            form::checkbox(array('pings_do[]', 'pings_do-' . $i), html::escapeHTML($v), in_array($v, $pings_do), 'check-ping-services') . ' ' .
+            form::checkbox(['pings_do[]', 'pings_do-' . $i], html::escapeHTML($v), in_array($v, $pings_do), 'check-ping-services') . ' ' .
             html::escapeHTML($k) . '</label></p>';
             $i++;
Index: plugins/simpleMenu/_admin.php
===================================================================
--- plugins/simpleMenu/_admin.php	(revision 3731)
+++ plugins/simpleMenu/_admin.php	(revision 3874)
@@ -16,11 +16,11 @@
 function simpleMenu_dashboard($core, $icons)
 {
-    $icons['simpleMenu'] = new ArrayObject(array(__('Simple menu'),
+    $icons['simpleMenu'] = new ArrayObject([__('Simple menu'),
         $core->adminurl->get('admin.plugin.simpleMenu'),
-        dcPage::getPF('simpleMenu/icon.png')));
+        dcPage::getPF('simpleMenu/icon.png')]);
 }
 function simpleMenu_dashboard_favs($core, $favs)
 {
-    $favs->register('simpleMenu', array(
+    $favs->register('simpleMenu', [
         'title'       => __('Simple menu'),
         'url'         => $core->adminurl->get('admin.plugin.simpleMenu'),
@@ -28,5 +28,5 @@
         'large-icon'  => dcPage::getPF('simpleMenu/icon.png'),
         'permissions' => 'usage,contentadmin'
-    ));
+    ]);
 }
 
Index: plugins/simpleMenu/_define.php
===================================================================
--- plugins/simpleMenu/_define.php	(revision 3731)
+++ plugins/simpleMenu/_define.php	(revision 3874)
@@ -17,10 +17,10 @@
     "Franck Paul",              // Author
     '1.5',                      // Version
-    array(
+    [
         'permissions' => 'admin',
         'type'        => 'plugin',
-        'settings'    => array(
+        'settings'    => [
             'self' => ''
-        )
-    )
+        ]
+    ]
 );
Index: plugins/simpleMenu/_install.php
===================================================================
--- plugins/simpleMenu/_install.php	(revision 3731)
+++ plugins/simpleMenu/_install.php	(revision 3874)
@@ -19,8 +19,8 @@
 # Menu par défaut
 $blog_url     = html::stripHostURL($core->blog->url);
-$menu_default = array(
-    array('label' => 'Home', 'descr' => 'Recent posts', 'url' => $blog_url, 'targetBlank' => false),
-    array('label' => 'Archives', 'descr' => '', 'url' => $blog_url . $core->url->getURLFor('archive'), 'targetBlank' => false)
-);
+$menu_default = [
+    ['label' => 'Home', 'descr' => 'Recent posts', 'url' => $blog_url, 'targetBlank' => false],
+    ['label' => 'Archives', 'descr' => '', 'url' => $blog_url . $core->url->getURLFor('archive'), 'targetBlank' => false]
+];
 $core->blog->settings->system->put('simpleMenu', $menu_default, 'array', 'simpleMenu default menu', false, true);
 $core->blog->settings->system->put('simpleMenu_active', true, 'boolean', 'Active', false, true);
Index: plugins/simpleMenu/_public.php
===================================================================
--- plugins/simpleMenu/_public.php	(revision 3731)
+++ plugins/simpleMenu/_public.php	(revision 3874)
@@ -15,5 +15,5 @@
 
 # Simple menu template functions
-$core->tpl->addValue('SimpleMenu', array('tplSimpleMenu', 'simpleMenu'));
+$core->tpl->addValue('SimpleMenu', ['tplSimpleMenu', 'simpleMenu']);
 
 class tplSimpleMenu
@@ -48,5 +48,5 @@
         global $core, $_ctx;
 
-        $descr_type = array(0 => 'span', 1 => 'title', 2 => 'both', 3 => 'none');
+        $descr_type = [0 => 'span', 1 => 'title', 2 => 'both', 3 => 'none'];
 
         if (!(boolean) $core->blog->settings->system->simpleMenu_active) {
@@ -145,5 +145,5 @@
                 $label = html::escapeHTML(__($m['label']));
 
-                $item = new ArrayObject(array(
+                $item = new ArrayObject([
                     'url'    => $href,   // URL
                     'label'  => $label,  // <a> link label
@@ -152,5 +152,5 @@
                     'active' => $active, // status (true/false)
                     'class'  => ''      // additional <li> class (optional)
-                ));
+                ]);
 
                 # --BEHAVIOR-- publicSimpleMenuItem
Index: plugins/simpleMenu/_widgets.php
===================================================================
--- plugins/simpleMenu/_widgets.php	(revision 3731)
+++ plugins/simpleMenu/_widgets.php	(revision 3874)
@@ -12,5 +12,5 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('initWidgets', array('simpleMenuWidgets', 'initWidgets'));
+$core->addBehavior('initWidgets', ['simpleMenuWidgets', 'initWidgets']);
 
 class simpleMenuWidgets
@@ -18,20 +18,20 @@
     public static function initWidgets($w)
     {
-        $w->create('simplemenu', __('Simple menu'), array('tplSimpleMenu', 'simpleMenuWidget'), null, 'List of simple menu items');
+        $w->create('simplemenu', __('Simple menu'), ['tplSimpleMenu', 'simpleMenuWidget'], null, 'List of simple menu items');
         $w->simplemenu->setting('title', __('Title (optional)') . ' :', __('Menu'));
         $w->simplemenu->setting('description', __('Item description'), 0, 'combo',
-            array(
+            [
                 __('Displayed in link')                   => 0, // span
                 __('Used as link title')                  => 1, // title
                 __('Displayed in link and used as title') => 2, // both
                 __('Not displayed nor used')              => 3 // none
-            )
+            ]
         );
         $w->simplemenu->setting('homeonly', __('Display on:'), 0, 'combo',
-            array(
+            [
                 __('All pages')           => 0,
                 __('Home page only')      => 1,
                 __('Except on home page') => 2
-            )
+            ]
         );
         $w->simplemenu->setting('content_only', __('Content only'), 0, 'check');
Index: plugins/simpleMenu/index.php
===================================================================
--- plugins/simpleMenu/index.php	(revision 3731)
+++ plugins/simpleMenu/index.php	(revision 3874)
@@ -23,6 +23,6 @@
 
 # Liste des catégories
-$categories_label = array();
-$rs               = $core->blog->getCategories(array('post_type' => 'post'));
+$categories_label = [];
+$rs               = $core->blog->getCategories(['post_type' => 'post']);
 $categories_combo = dcAdminCombos::getCategoriesCombo($rs, false, true);
 $rs->moveStart();
@@ -33,11 +33,11 @@
 # Liste des langues utilisées
 $langs_combo = dcAdminCombos::getLangscombo(
-    $core->blog->getLangs(array('order' => 'asc'))
+    $core->blog->getLangs(['order' => 'asc'])
 );
 
 # Liste des mois d'archive
-$rs           = $core->blog->getDates(array('type' => 'month'));
+$rs           = $core->blog->getDates(['type' => 'month']);
 $months_combo = array_merge(
-    array(__('All months') => '-'),
+    [__('All months') => '-'],
     dcAdmincombos::getDatesCombo($rs)
 );
@@ -57,7 +57,7 @@
 
 # Liste des pages -- Doit être pris en charge plus tard par le plugin ?
-$pages_combo = array();
+$pages_combo = [];
 try {
-    $rs = $core->blog->getPosts(array('post_type' => 'page'));
+    $rs = $core->blog->getPosts(['post_type' => 'page']);
     while ($rs->fetch()) {
         $pages_combo[$rs->post_title] = $rs->getURL();
@@ -67,7 +67,7 @@
 
 # Liste des tags -- Doit être pris en charge plus tard par le plugin ?
-$tags_combo = array();
+$tags_combo = [];
 try {
-    $rs                         = $core->meta->getMetadata(array('meta_type' => 'tag'));
+    $rs                         = $core->meta->getMetadata(['meta_type' => 'tag']);
     $tags_combo[__('All tags')] = '-';
     while ($rs->fetch()) {
@@ -79,18 +79,18 @@
 # Liste des types d'item de menu
 $items         = new ArrayObject();
-$items['home'] = new ArrayObject(array(__('Home'), false));
+$items['home'] = new ArrayObject([__('Home'), false]);
 
 if (count($langs_combo) > 1) {
-    $items['lang'] = new ArrayObject(array(__('Language'), true));
+    $items['lang'] = new ArrayObject([__('Language'), true]);
 }
 if (count($categories_combo)) {
-    $items['category'] = new ArrayObject(array(__('Category'), true));
+    $items['category'] = new ArrayObject([__('Category'), true]);
 }
 if (count($months_combo) > 1) {
-    $items['archive'] = new ArrayObject(array(__('Archive'), true));
+    $items['archive'] = new ArrayObject([__('Archive'), true]);
 }
 if ($core->plugins->moduleExists('pages')) {
     if (count($pages_combo)) {
-        $items['pages'] = new ArrayObject(array(__('Page'), true));
+        $items['pages'] = new ArrayObject([__('Page'), true]);
     }
 
@@ -98,5 +98,5 @@
 if ($core->plugins->moduleExists('tags')) {
     if (count($tags_combo) > 1) {
-        $items['tags'] = new ArrayObject(array(__('Tags'), true));
+        $items['tags'] = new ArrayObject([__('Tags'), true]);
     }
 
@@ -104,10 +104,10 @@
 
 # --BEHAVIOR-- adminSimpleMenuAddType
-# Should add an item to $items[<id>] as an array(<label>,<optional step (true or false)>)
+# Should add an item to $items[<id>] as an [<label>,<optional step (true or false)>]
 $core->callBehavior('adminSimpleMenuAddType', $items);
 
-$items['special'] = new ArrayObject(array(__('User defined'), false));
-
-$items_combo = array();
+$items['special'] = new ArrayObject([__('User defined'), false]);
+
+$items_combo = [];
 foreach ($items as $k => $v) {
     $items_combo[$v[0]] = $k;
@@ -117,5 +117,5 @@
 $menu = $core->blog->settings->system->get('simpleMenu');
 if (!is_array($menu)) {
-    $menu = array();
+    $menu = [];
 }
 
@@ -227,5 +227,5 @@
                         # Should set if necessary $item_select_label (displayed on further admin step only)
                         $core->callBehavior('adminSimpleMenuBeforeEdit', $item_type, $item_select,
-                            array(&$item_label, &$item_descr, &$item_url, &$item_select_label));
+                            [&$item_label, &$item_descr, &$item_url, &$item_select_label]);
                         break;
                 }
@@ -236,10 +236,10 @@
                     if (($item_label != '') && ($item_url != '')) {
                         // Add new item menu in menu array
-                        $menu[] = array(
+                        $menu[] = [
                             'label'       => $item_label,
                             'descr'       => $item_descr,
                             'url'         => $item_url,
                             'targetBlank' => $item_targetBlank
-                        );
+                        ];
 
                         // Save menu in blog settings
@@ -269,13 +269,13 @@
                         $menu[$v]['label'] = '';
                     }
-                    $newmenu = array();
+                    $newmenu = [];
                     foreach ($menu as $k => $v) {
                         if ($v['label']) {
-                            $newmenu[] = array(
+                            $newmenu[] = [
                                 'label'       => $v['label'],
                                 'descr'       => $v['descr'],
                                 'url'         => $v['url'],
                                 'targetBlank' => $v['targetBlank']
-                            );
+                            ];
                         }
                     }
@@ -311,12 +311,12 @@
 
                 }
-                $newmenu = array();
+                $newmenu = [];
                 for ($i = 0; $i < count($_POST['items_label']); $i++) {
-                    $newmenu[] = array(
+                    $newmenu[] = [
                         'label'       => $_POST['items_label'][$i],
                         'descr'       => $_POST['items_descr'][$i],
                         'url'         => $_POST['items_url'][$i],
                         'targetBlank' => (empty($_POST['items_targetBlank' . $i])) ? false : true
-                    );
+                    ];
                 }
                 $menu = $newmenu;
@@ -334,5 +334,5 @@
 
         # Order menu items
-        $order = array();
+        $order = [];
         if (empty($_POST['im_order']) && !empty($_POST['order'])) {
             $order = $_POST['order'];
@@ -349,10 +349,10 @@
         if (!empty($_POST['updateaction']) && !empty($order)) {
             try {
-                $newmenu = array();
+                $newmenu = [];
                 foreach ($order as $i => $k) {
-                    $newmenu[] = array(
+                    $newmenu[] = [
                         'label' => $menu[$k]['label'],
                         'descr' => $menu[$k]['descr'],
-                        'url'   => $menu[$k]['url']);
+                        'url'   => $menu[$k]['url']];
                 }
                 $menu = $newmenu;
@@ -413,20 +413,20 @@
     }
     echo dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             $page_title                         => $p_url,
             __('Add item')                      => '',
             $step_label                         => ''
-        ),
-        array(
-            'hl_pos' => -2)
+        ],
+        [
+            'hl_pos' => -2]
     ) .
     dcPage::notices();
 } else {
     echo dcPage::breadcrumb(
-        array(
+        [
             html::escapeHTML($core->blog->name) => '',
             $page_title                         => ''
-        )) .
+        ]) .
     dcPage::notices();
 }
@@ -488,8 +488,8 @@
             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, array(
+            form::field('item_label', 20, 255, [
                 'default'    => $item_label,
                 'extra_html' => 'required placeholder="' . __('Label') . '"'
-            )) .
+            ]) .
                 '</p>';
             echo '<p class="field"><label for="item_descr" class="classic">' .
@@ -497,8 +497,8 @@
             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, array(
+            form::field('item_url', 40, 255, [
                 'default'    => $item_url,
                 'extra_html' => 'required placeholder="' . __('URL') . '"'
-            )) .
+            ]) .
                 '</p>';
             echo form::hidden('item_type', $item_type) . form::hidden('item_select', $item_select);
@@ -567,15 +567,15 @@
             $count++;
             echo '<td class="handle minimal">' .
-            form::number(array('order[' . $i . ']'), array(
+            form::number(['order[' . $i . ']'], [
                 'min'        => 1,
                 'default'    => $count,
                 'class'      => 'position',
                 'extra_html' => 'title="' . sprintf(__('position of %s'), html::escapeHTML(__($m['label']))) . '"'
-            )) .
-            form::hidden(array('dynorder[]', 'dynorder-' . $i), $i) . '</td>';
-            echo '<td class="minimal">' . form::checkbox(array('items_selected[]', 'ims-' . $i), $i) . '</td>';
-            echo '<td class="nowrap" scope="row">' . form::field(array('items_label[]', 'iml-' . $i), '', 255, html::escapeHTML(__($m['label']))) . '</td>';
-            echo '<td class="nowrap">' . form::field(array('items_descr[]', 'imd-' . $i), '30', 255, html::escapeHTML(__($m['descr']))) . '</td>';
-            echo '<td class="nowrap">' . form::field(array('items_url[]', 'imu-' . $i), '30', 255, html::escapeHTML($m['url'])) . '</td>';
+            ]) .
+            form::hidden(['dynorder[]', 'dynorder-' . $i], $i) . '</td>';
+            echo '<td class="minimal">' . form::checkbox(['items_selected[]', 'ims-' . $i], $i) . '</td>';
+            echo '<td class="nowrap" scope="row">' . form::field(['items_label[]', 'iml-' . $i], '', 255, html::escapeHTML(__($m['label']))) . '</td>';
+            echo '<td class="nowrap">' . form::field(['items_descr[]', 'imd-' . $i], '30', 255, html::escapeHTML(__($m['descr']))) . '</td>';
+            echo '<td class="nowrap">' . form::field(['items_url[]', 'imu-' . $i], '30', 255, html::escapeHTML($m['url'])) . '</td>';
             echo '<td class="nowrap">' . form::checkbox('items_targetBlank' . $i, 'blank', $targetBlank) . '</td>';
         } else {
Index: plugins/simpleMenu/js/simplemenu.js
===================================================================
--- plugins/simpleMenu/js/simplemenu.js	(revision 3709)
+++ plugins/simpleMenu/js/simplemenu.js	(revision 3880)
@@ -16,5 +16,5 @@
   });
   $('#menuitems').submit(function() {
-    var order = [];
+    let order = [];
     $('#menuitemslist tr td input.position').each(function() {
       order.push(this.name.replace(/^order\[([^\]]+)\]$/, '$1'));
Index: plugins/tags/_admin.php
===================================================================
--- plugins/tags/_admin.php	(revision 3731)
+++ plugins/tags/_admin.php	(revision 3874)
@@ -13,5 +13,5 @@
 
 $_menu['Blog']->addItem(__('Tags'),
-    $core->adminurl->get('admin.plugin.tags', array('m' => 'tags')),
+    $core->adminurl->get('admin.plugin.tags', ['m' => 'tags']),
     dcPage::getPF('tags/icon.png'),
     preg_match('/' . preg_quote($core->adminurl->get('admin.plugin.tags')) . '&m=tag(s|_posts)?(&.*)?$/', $_SERVER['REQUEST_URI']),
@@ -20,24 +20,24 @@
 require dirname(__FILE__) . '/_widgets.php';
 
-$core->addBehavior('adminPostFormItems', array('tagsBehaviors', 'tagsField'));
+$core->addBehavior('adminPostFormItems', ['tagsBehaviors', 'tagsField']);
 
-$core->addBehavior('adminAfterPostCreate', array('tagsBehaviors', 'setTags'));
-$core->addBehavior('adminAfterPostUpdate', array('tagsBehaviors', 'setTags'));
+$core->addBehavior('adminAfterPostCreate', ['tagsBehaviors', 'setTags']);
+$core->addBehavior('adminAfterPostUpdate', ['tagsBehaviors', 'setTags']);
 
-$core->addBehavior('adminPostHeaders', array('tagsBehaviors', 'postHeaders'));
+$core->addBehavior('adminPostHeaders', ['tagsBehaviors', 'postHeaders']);
 
-$core->addBehavior('adminPostsActionsPage', array('tagsBehaviors', 'adminPostsActionsPage'));
+$core->addBehavior('adminPostsActionsPage', ['tagsBehaviors', 'adminPostsActionsPage']);
 
-$core->addBehavior('adminPreferencesForm', array('tagsBehaviors', 'adminUserForm'));
-$core->addBehavior('adminBeforeUserOptionsUpdate', array('tagsBehaviors', 'setTagListFormat'));
+$core->addBehavior('adminPreferencesForm', ['tagsBehaviors', 'adminUserForm']);
+$core->addBehavior('adminBeforeUserOptionsUpdate', ['tagsBehaviors', 'setTagListFormat']);
 
-$core->addBehavior('adminUserForm', array('tagsBehaviors', 'adminUserForm'));
-$core->addBehavior('adminBeforeUserCreate', array('tagsBehaviors', 'setTagListFormat'));
-$core->addBehavior('adminBeforeUserUpdate', array('tagsBehaviors', 'setTagListFormat'));
+$core->addBehavior('adminUserForm', ['tagsBehaviors', 'adminUserForm']);
+$core->addBehavior('adminBeforeUserCreate', ['tagsBehaviors', 'setTagListFormat']);
+$core->addBehavior('adminBeforeUserUpdate', ['tagsBehaviors', 'setTagListFormat']);
 
-$core->addBehavior('adminDashboardFavorites', array('tagsBehaviors', 'dashboardFavorites'));
+$core->addBehavior('adminDashboardFavorites', ['tagsBehaviors', 'dashboardFavorites']);
 
-$core->addBehavior('adminPageHelpBlock', array('tagsBehaviors', 'adminPageHelpBlock'));
+$core->addBehavior('adminPageHelpBlock', ['tagsBehaviors', 'adminPageHelpBlock']);
 
-$core->addBehavior('adminPostEditor', array('tagsBehaviors', 'adminPostEditor'));
-$core->addBehavior('ckeditorExtraPlugins', array('tagsBehaviors', 'ckeditorExtraPlugins'));
+$core->addBehavior('adminPostEditor', ['tagsBehaviors', 'adminPostEditor']);
+$core->addBehavior('ckeditorExtraPlugins', ['tagsBehaviors', 'ckeditorExtraPlugins']);
Index: plugins/tags/_define.php
===================================================================
--- plugins/tags/_define.php	(revision 3733)
+++ plugins/tags/_define.php	(revision 3874)
@@ -17,11 +17,11 @@
     "Olivier Meunier", // Author
     '1.5',             // Version
-    array(
+    [
         'permissions' => 'usage,contentadmin',
         'priority'    => 1001, // Must be higher than dcLegacyEditor/dcCKEditor priority (ie 1000)
         'type'        => 'plugin',
-        'settings'    => array(
+        'settings'    => [
             'pref' => '#user-options.tags_prefs'
-        )
-    )
+        ]
+    ]
 );
Index: plugins/tags/_prepend.php
===================================================================
--- plugins/tags/_prepend.php	(revision 3731)
+++ plugins/tags/_prepend.php	(revision 3874)
@@ -12,9 +12,9 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->url->register('tag', 'tag', '^tag/(.+)$', array('urlTags', 'tag'));
-$core->url->register('tags', 'tags', '^tags$', array('urlTags', 'tags'));
-$core->url->register('tag_feed', 'feed/tag', '^feed/tag/(.+)$', array('urlTags', 'tagFeed'));
+$core->url->register('tag', 'tag', '^tag/(.+)$', ['urlTags', 'tag']);
+$core->url->register('tags', 'tags', '^tags$', ['urlTags', 'tags']);
+$core->url->register('tag_feed', 'feed/tag', '^feed/tag/(.+)$', ['urlTags', 'tagFeed']);
 
 $__autoload['tagsBehaviors'] = dirname(__FILE__) . '/inc/tags.behaviors.php';
 
-$core->addBehavior('coreInitWikiPost', array('tagsBehaviors', 'coreInitWikiPost'));
+$core->addBehavior('coreInitWikiPost', ['tagsBehaviors', 'coreInitWikiPost']);
Index: plugins/tags/_public.php
===================================================================
--- plugins/tags/_public.php	(revision 3734)
+++ plugins/tags/_public.php	(revision 3874)
@@ -18,30 +18,30 @@
 require dirname(__FILE__) . '/_widgets.php';
 
-$core->tpl->addBlock('Tags', array('tplTags', 'Tags'));
-$core->tpl->addBlock('TagsHeader', array('tplTags', 'TagsHeader'));
-$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'));
-$core->tpl->addValue('TagURL', array('tplTags', 'TagURL'));
-$core->tpl->addValue('TagCloudURL', array('tplTags', 'TagCloudURL'));
-$core->tpl->addValue('TagFeedURL', array('tplTags', 'TagFeedURL'));
+$core->tpl->addBlock('Tags', ['tplTags', 'Tags']);
+$core->tpl->addBlock('TagsHeader', ['tplTags', 'TagsHeader']);
+$core->tpl->addBlock('TagsFooter', ['tplTags', 'TagsFooter']);
+$core->tpl->addBlock('EntryTags', ['tplTags', 'EntryTags']);
+$core->tpl->addBlock('TagIf', ['tplTags', 'TagIf']);
+$core->tpl->addValue('TagID', ['tplTags', 'TagID']);
+$core->tpl->addValue('TagCount', ['tplTags', 'TagCount']);
+$core->tpl->addValue('TagPercent', ['tplTags', 'TagPercent']);
+$core->tpl->addValue('TagRoundPercent', ['tplTags', 'TagRoundPercent']);
+$core->tpl->addValue('TagURL', ['tplTags', 'TagURL']);
+$core->tpl->addValue('TagCloudURL', ['tplTags', 'TagCloudURL']);
+$core->tpl->addValue('TagFeedURL', ['tplTags', 'TagFeedURL']);
 
 # Kept for backward compatibility (for now)
-$core->tpl->addBlock('MetaData', array('tplTags', 'Tags'));
-$core->tpl->addBlock('MetaDataHeader', array('tplTags', 'TagsHeader'));
-$core->tpl->addBlock('MetaDataFooter', array('tplTags', 'TagsFooter'));
-$core->tpl->addValue('MetaID', array('tplTags', 'TagID'));
-$core->tpl->addValue('MetaPercent', array('tplTags', 'TagPercent'));
-$core->tpl->addValue('MetaRoundPercent', array('tplTags', 'TagRoundPercent'));
-$core->tpl->addValue('MetaURL', array('tplTags', 'TagURL'));
-$core->tpl->addValue('MetaAllURL', array('tplTags', 'TagCloudURL'));
-$core->tpl->addBlock('EntryMetaData', array('tplTags', 'EntryTags'));
-
-$core->addBehavior('templateBeforeBlock', array('behaviorsTags', 'templateBeforeBlock'));
-$core->addBehavior('publicBeforeDocument', array('behaviorsTags', 'addTplPath'));
+$core->tpl->addBlock('MetaData', ['tplTags', 'Tags']);
+$core->tpl->addBlock('MetaDataHeader', ['tplTags', 'TagsHeader']);
+$core->tpl->addBlock('MetaDataFooter', ['tplTags', 'TagsFooter']);
+$core->tpl->addValue('MetaID', ['tplTags', 'TagID']);
+$core->tpl->addValue('MetaPercent', ['tplTags', 'TagPercent']);
+$core->tpl->addValue('MetaRoundPercent', ['tplTags', 'TagRoundPercent']);
+$core->tpl->addValue('MetaURL', ['tplTags', 'TagURL']);
+$core->tpl->addValue('MetaAllURL', ['tplTags', 'TagCloudURL']);
+$core->tpl->addBlock('EntryMetaData', ['tplTags', 'EntryTags']);
+
+$core->addBehavior('templateBeforeBlock', ['behaviorsTags', 'templateBeforeBlock']);
+$core->addBehavior('publicBeforeDocument', ['behaviorsTags', 'addTplPath']);
 
 class behaviorsTags
@@ -52,5 +52,5 @@
             return
             "<?php\n" .
-            "if (!isset(\$params)) { \$params = array(); }\n" .
+            "if (!isset(\$params)) { \$params = []; }\n" .
             "if (!isset(\$params['from'])) { \$params['from'] = ''; }\n" .
             "if (!isset(\$params['sql'])) { \$params['sql'] = ''; }\n" .
@@ -63,5 +63,5 @@
             return
                 '<?php if ($_ctx->exists("meta") && ($_ctx->meta->meta_type == "tag")) { ' .
-                "if (!isset(\$params)) { \$params = array(); }\n" .
+                "if (!isset(\$params)) { \$params = []; }\n" .
                 "if (!isset(\$params['from'])) { \$params['from'] = ''; }\n" .
                 "if (!isset(\$params['sql'])) { \$params['sql'] = ''; }\n" .
@@ -94,5 +94,5 @@
         $limit = isset($attr['limit']) ? (integer) $attr['limit'] : 'null';
 
-        $combo = array('meta_id_lower', 'count', 'latest', 'oldest');
+        $combo = ['meta_id_lower', 'count', 'latest', 'oldest'];
 
         $sortby = 'meta_id_lower';
@@ -108,8 +108,8 @@
         $res =
             "<?php\n" .
-            "\$_ctx->meta = \$core->meta->computeMetaStats(\$core->meta->getMetadata(array('meta_type'=>'"
+            "\$_ctx->meta = \$core->meta->computeMetaStats(\$core->meta->getMetadata(['meta_type'=>'"
             . $type . "','limit'=>" . $limit .
             ($sortby != 'meta_id_lower' ? ",'order'=>'" . $sortby . ' ' . ($order == 'asc' ? 'ASC' : 'DESC' ) . "'" : '')  .
-            "))); " .
+            "])); " .
             "\$_ctx->meta->sort('" . $sortby . "','" . $order . "'); " .
             '?>';
@@ -142,5 +142,5 @@
         $type = isset($attr['type']) ? addslashes($attr['type']) : 'tag';
 
-        $combo = array('meta_id_lower', 'count', 'latest', 'oldest');
+        $combo = ['meta_id_lower', 'count', 'latest', 'oldest'];
 
         $sortby = 'meta_id_lower';
@@ -169,5 +169,5 @@
     public static function TagIf($attr, $content)
     {
-        $if        = array();
+        $if        = [];
         $operateur = isset($attr['operator']) ? dcTemplate::getOperator($attr['operator']) : '&&';
 
@@ -245,5 +245,5 @@
         }
 
-        $combo = array('meta_id_lower', 'count', 'latest', 'oldest');
+        $combo = ['meta_id_lower', 'count', 'latest', 'oldest'];
 
         $sort = $w->sortby;
@@ -257,5 +257,5 @@
         }
 
-        $params = array('meta_type' => 'tag');
+        $params = ['meta_type' => 'tag'];
 
         if ($sort != 'meta_id_lower') {
@@ -329,7 +329,7 @@
 
             $GLOBALS['_ctx']->meta = $GLOBALS['core']->meta->computeMetaStats(
-                $GLOBALS['core']->meta->getMetadata(array(
+                $GLOBALS['core']->meta->getMetadata([
                     'meta_type' => 'tag',
-                    'meta_id'   => $m[1])));
+                    'meta_id'   => $m[1]]));
 
             if ($GLOBALS['_ctx']->meta->isEmpty()) {
@@ -350,7 +350,7 @@
 
             $GLOBALS['_ctx']->meta = $GLOBALS['core']->meta->computeMetaStats(
-                $GLOBALS['core']->meta->getMetadata(array(
+                $GLOBALS['core']->meta->getMetadata([
                     'meta_type' => 'tag',
-                    'meta_id'   => $args)));
+                    'meta_id'   => $args]));
 
             if ($GLOBALS['_ctx']->meta->isEmpty()) {
@@ -377,7 +377,7 @@
 
             $GLOBALS['_ctx']->meta = $GLOBALS['core']->meta->computeMetaStats(
-                $GLOBALS['core']->meta->getMetadata(array(
+                $GLOBALS['core']->meta->getMetadata([
                     'meta_type' => 'tag',
-                    'meta_id'   => $tag)));
+                    'meta_id'   => $tag]));
 
             if ($GLOBALS['_ctx']->meta->isEmpty()) {
Index: plugins/tags/_widgets.php
===================================================================
--- plugins/tags/_widgets.php	(revision 3733)
+++ plugins/tags/_widgets.php	(revision 3874)
@@ -12,6 +12,6 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('initWidgets', array('tagsWidgets', 'initWidgets'));
-$core->addBehavior('initDefaultWidgets', array('tagsWidgets', 'initDefaultWidgets'));
+$core->addBehavior('initWidgets', ['tagsWidgets', 'initWidgets']);
+$core->addBehavior('initDefaultWidgets', ['tagsWidgets', 'initDefaultWidgets']);
 
 class tagsWidgets
@@ -19,25 +19,25 @@
     public static function initWidgets($w)
     {
-        $combo = array(
+        $combo = [
             __('Tag name')       => 'meta_id_lower',
             __('Entries count')  => 'count',
             __('Newest entry')   => 'latest',
             __('Oldest entry')   => 'oldest'
-        );
+        ];
 
-        $w->create('tags', __('Tags'), array('tplTags', 'tagsWidget'), null, 'Tags cloud');
+        $w->create('tags', __('Tags'), ['tplTags', 'tagsWidget'], null, 'Tags cloud');
         $w->tags->setting('title', __('Title (optional)') . ' :', __('Tags'));
         $w->tags->setting('limit', __('Limit (empty means no limit):'), '20');
         $w->tags->setting('sortby', __('Order by:'), 'meta_id_lower', 'combo', $combo);
         $w->tags->setting('orderby', __('Sort:'), 'asc', 'combo',
-            array(__('Ascending') => 'asc', __('Descending') => 'desc')
+            [__('Ascending') => 'asc', __('Descending') => 'desc']
         );
         $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('content_only', __('Content only'), 0, 'check');
Index: plugins/tags/_xmlrpc.php
===================================================================
--- plugins/tags/_xmlrpc.php	(revision 3731)
+++ plugins/tags/_xmlrpc.php	(revision 3874)
@@ -12,7 +12,7 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('xmlrpcGetPostInfo', array('tagsXMLRPCbehaviors', 'getPostInfo'));
-$core->addBehavior('xmlrpcAfterNewPost', array('tagsXMLRPCbehaviors', 'editPost'));
-$core->addBehavior('xmlrpcAfterEditPost', array('tagsXMLRPCbehaviors', 'editPost'));
+$core->addBehavior('xmlrpcGetPostInfo', ['tagsXMLRPCbehaviors', 'getPostInfo']);
+$core->addBehavior('xmlrpcAfterNewPost', ['tagsXMLRPCbehaviors', 'editPost']);
+$core->addBehavior('xmlrpcAfterEditPost', ['tagsXMLRPCbehaviors', 'editPost']);
 
 class tagsXMLRPCbehaviors
@@ -22,9 +22,9 @@
         $res = &$res[0];
 
-        $rs = $x->core->meta->getMetadata(array(
+        $rs = $x->core->meta->getMetadata([
             'meta_type' => 'tag',
-            'post_id'   => $res['postid']));
+            'post_id'   => $res['postid']]);
 
-        $m = array();
+        $m = [];
         while ($rs->fetch()) {
             $m[] = $rs->meta_id;
Index: plugins/tags/inc/tags.behaviors.php
===================================================================
--- plugins/tags/inc/tags.behaviors.php	(revision 3731)
+++ plugins/tags/inc/tags.behaviors.php	(revision 3874)
@@ -13,5 +13,5 @@
 class tagsBehaviors
 {
-    public static function adminPostEditor($editor = '', $context = '', array $tags = array(), $syntax = '')
+    public static function adminPostEditor($editor = '', $context = '', array $tags = [], $syntax = '')
     {
         if (($editor != 'dcLegacyEditor' && $editor != 'dcCKEditor') || $context != 'post') {
@@ -45,9 +45,9 @@
             return;
         }
-        $extraPlugins[] = array(
+        $extraPlugins[] = [
             'name'   => 'dctags',
             'button' => 'dcTags',
             'url'    => DC_ADMIN_URL . 'index.php?pf=tags/js/ckeditor-tags-plugin.js'
-        );
+        ];
     }
 
@@ -69,16 +69,16 @@
     public static function dashboardFavorites($core, $favs)
     {
-        $favs->register('tags', array(
+        $favs->register('tags', [
             'title'       => __('Tags'),
-            'url'         => $core->adminurl->get('admin.plugin.tags', array('m' => 'tags')),
+            'url'         => $core->adminurl->get('admin.plugin.tags', ['m' => 'tags']),
             'small-icon'  => dcPage::getPF('tags/icon.png'),
             'large-icon'  => dcPage::getPF('tags/icon-big.png'),
             'permissions' => 'usage,contentadmin'
-        ));
+        ]);
     }
 
     public static function coreInitWikiPost($wiki2xhtml)
     {
-        $wiki2xhtml->registerFunction('url:tag', array('tagsBehaviors', 'wiki2xhtmlTag'));
+        $wiki2xhtml->registerFunction('url:tag', ['tagsBehaviors', 'wiki2xhtmlTag']);
     }
 
@@ -129,12 +129,12 @@
     {
         $ap->addAction(
-            array(__('Tags') => array(__('Add tags') => 'tags')),
-            array('tagsBehaviors', 'adminAddTags')
+            [__('Tags') => [__('Add tags') => 'tags']],
+            ['tagsBehaviors', 'adminAddTags']
         );
 
         if ($core->auth->check('delete,contentadmin', $core->blog->id)) {
             $ap->addAction(
-                array(__('Tags') => array(__('Remove tags') => 'tags_remove')),
-                array('tagsBehaviors', 'adminRemoveTags')
+                [__('Tags') => [__('Remove tags') => 'tags_remove']],
+                ['tagsBehaviors', 'adminRemoveTags']
             );
         }
@@ -149,8 +149,8 @@
             while ($posts->fetch()) {
                 # Get tags for post
-                $post_meta = $meta->getMetadata(array(
+                $post_meta = $meta->getMetadata([
                     'meta_type' => 'tag',
-                    'post_id'   => $posts->post_id));
-                $pm = array();
+                    'post_id'   => $posts->post_id]);
+                $pm = [];
                 while ($post_meta->fetch()) {
                     $pm[] = $post_meta->meta_id;
@@ -178,9 +178,9 @@
             $ap->beginPage(
                 dcPage::breadcrumb(
-                    array(
+                    [
                         html::escapeHTML($core->blog->name) => '',
                         __('Entries')                       => $ap->getRedirection(true),
                         __('Add tags to this selection')    => ''
-                    )),
+                    ]),
                 dcPage::jsMetaEditor() .
                 '<script type="text/javascript">' . "\n" .
@@ -211,5 +211,5 @@
             '</div>' .
             $core->formNonce() . $ap->getHiddenFields() .
-            form::hidden(array('action'), 'tags') .
+            form::hidden(['action'], 'tags') .
             '<p><input type="submit" value="' . __('Save') . '" ' .
                 'name="save_tags" /></p>' .
@@ -239,10 +239,10 @@
         } else {
             $meta = &$core->meta;
-            $tags = array();
+            $tags = [];
 
             foreach ($ap->getIDS() as $id) {
-                $post_tags = $meta->getMetadata(array(
+                $post_tags = $meta->getMetadata([
                     'meta_type' => 'tag',
-                    'post_id'   => (integer) $id))->toStatic()->rows();
+                    'post_id'   => (integer) $id])->toStatic()->rows();
                 foreach ($post_tags as $v) {
                     if (isset($tags[$v['meta_id']])) {
@@ -258,9 +258,9 @@
             $ap->beginPage(
                 dcPage::breadcrumb(
-                    array(
+                    [
                         html::escapeHTML($core->blog->name)            => '',
                         __('Entries')                                  => 'posts.php',
                         __('Remove selected tags from this selection') => ''
-                    )));
+                    ]));
             $posts_count = count($_POST['entries']);
 
@@ -276,5 +276,5 @@
                 }
                 echo '<p>' . sprintf($label,
-                    form::checkbox(array('meta_id[]'), html::escapeHTML($k)),
+                    form::checkbox(['meta_id[]'], html::escapeHTML($k)),
                     html::escapeHTML($k)) .
                     '</p>';
@@ -285,5 +285,5 @@
 
             $core->formNonce() . $ap->getHiddenFields() .
-            form::hidden(array('action'), 'tags_remove') .
+            form::hidden(['action'], 'tags_remove') .
                 '</p></div></form>';
             $ap->endPage();
@@ -328,8 +328,8 @@
             $opts = $args->options();
         } else {
-            $opts = array();
-        }
-
-        $combo                 = array();
+            $opts = [];
+        }
+
+        $combo                 = [];
         $combo[__('Short')]    = 'more';
         $combo[__('Extended')] = 'all';
Index: plugins/tags/js/ckeditor-tags-plugin.js
===================================================================
--- plugins/tags/js/ckeditor-tags-plugin.js	(revision 3709)
+++ plugins/tags/js/ckeditor-tags-plugin.js	(revision 3880)
@@ -8,9 +8,9 @@
         exec: function(editor) {
           if (editor.getSelection().getNative().toString().replace(/\s*/, '') != '') {
-            var str = editor.getSelection().getNative().toString().replace(/\s*/, '');
-            var url = dotclear.msg.tag_url;
+            const str = editor.getSelection().getNative().toString().replace(/\s*/, '');
+            const url = dotclear.msg.tag_url;
             window.dc_tag_editor.addMeta(str);
-            var link = '<a href="' + $.stripBaseURL(url + '/' + str) + '">' + str + '</a>';
-            var element = CKEDITOR.dom.element.createFromHtml(link);
+            const link = `<a href="${$.stripBaseURL(url + '/' + str)}">${str}</a>`;
+            const element = CKEDITOR.dom.element.createFromHtml(link);
             editor.insertElement(element);
           }
Index: plugins/tags/js/legacy-post.js
===================================================================
--- plugins/tags/js/legacy-post.js	(revision 3709)
+++ plugins/tags/js/legacy-post.js	(revision 3880)
@@ -35,5 +35,5 @@
 };
 jsToolBar.prototype.elements.tag.fn.markdown = function() {
-  var url = this.elements.tag.url;
+  const url = this.elements.tag.url;
   this.encloseSelection('', '', function(str) {
     if (str == '') {
@@ -50,5 +50,5 @@
 };
 jsToolBar.prototype.elements.tag.fn.xhtml = function() {
-  var url = this.elements.tag.url;
+  const url = this.elements.tag.url;
   this.encloseSelection('', '', function(str) {
     if (str == '') {
@@ -65,5 +65,5 @@
 };
 jsToolBar.prototype.elements.tag.fn.wysiwyg = function() {
-  var t = this.getSelectedText();
+  const t = this.getSelectedText();
 
   if (t == '') {
@@ -75,6 +75,6 @@
   }
 
-  var n = this.getSelectedNode();
-  var a = document.createElement('a');
+  const n = this.getSelectedNode();
+  const a = document.createElement('a');
   a.href = this.stripBaseURL(this.elements.tag.url + '/' + t);
   a.appendChild(n);
Index: plugins/tags/js/post.js
===================================================================
--- plugins/tags/js/post.js	(revision 3709)
+++ plugins/tags/js/post.js	(revision 3880)
@@ -4,8 +4,8 @@
 $(function() {
   $('#edit-entry').onetabload(function() {
-    var tags_edit = $('#tags-edit');
-    var post_id = $('#id');
-    var meta_field = null;
-    var mEdit = null;
+    const tags_edit = $('#tags-edit');
+    let post_id = $('#id');
+    let meta_field = null;
+    let mEdit = null;
 
     if (tags_edit.length > 0) {
@@ -34,5 +34,5 @@
       matchContains: true,
       parse: function(xml) {
-        var results = [];
+        let results = [];
         $(xml).find('meta').each(function() {
           results[results.length] = {
Index: plugins/tags/js/posts_actions.js
===================================================================
--- plugins/tags/js/posts_actions.js	(revision 3709)
+++ plugins/tags/js/posts_actions.js	(revision 3880)
@@ -3,61 +3,61 @@
 
 $(function() {
-	var tag_field = $('#new_tags');
+  const tag_field = $('#new_tags');
 
-	tag_field.after('<div id="tags_list"></div>');
-	tag_field.hide();
+  tag_field.after('<div id="tags_list"></div>');
+  tag_field.hide();
 
-	var target = $('#tags_list');
-	var mEdit = new metaEditor(target,tag_field,'tag',editor_tags_options);
-	mEdit.meta_url = 'plugin.php?p=tags&m=tag_posts&amp;tag=';
+  const target = $('#tags_list');
+  let mEdit = new metaEditor(target, tag_field, 'tag', editor_tags_options);
+  mEdit.meta_url = 'plugin.php?p=tags&m=tag_posts&amp;tag=';
 
-	mEdit.meta_dialog = $('<input type="text" />');
-	mEdit.meta_dialog.attr('title',mEdit.text_add_meta.replace(/%s/,mEdit.meta_type));
-	mEdit.meta_dialog.attr('id','post_meta_input');
-	mEdit.meta_dialog.css('width','90%');
+  mEdit.meta_dialog = $('<input type="text" />');
+  mEdit.meta_dialog.attr('title', mEdit.text_add_meta.replace(/%s/, mEdit.meta_type));
+  mEdit.meta_dialog.attr('id', 'post_meta_input');
+  mEdit.meta_dialog.css('width', '90%');
 
-	mEdit.addMetaDialog();
+  mEdit.addMetaDialog();
 
-	$('input[name="save_tags"]').click(function() {
-		tag_field.val($('#post_meta_input').val());
-	});
+  $('input[name="save_tags"]').click(function() {
+    tag_field.val($('#post_meta_input').val());
+  });
 
-	$('#post_meta_input').autocomplete(mEdit.service_uri, {
-		extraParams: {
-			'f':        'searchMeta',
-			'metaType': 'tag'
-		},
-		delay: 1000,
-		multiple: true,
-		matchSubset: false,
-		matchContains: true,
-		parse: function(xml) {
-			var results = [];
-			$(xml).find('meta').each(function(){
-				results[results.length] = {
-					data: {
-						'id':      $(this).text(),
-						'count':   $(this).attr('count'),
-						'percent': $(this).attr('roundpercent')
-					},
-					result: $(this).text()
-				};
-			});
-			return results;
-		},
-		formatItem: function(tag) {
-			return tag.id + ' <em>(' +
-			dotclear.msg.tags_autocomplete.
-				replace('%p',tag.percent).
-				replace('%e',tag.count + ' ' +
-					(tag.count > 1 ?
-					dotclear.msg.entries :
-					dotclear.msg.entry)
-				) +
-			')</em>';
-		},
-		formatResult: function(tag) {
-			return tag.result;
-		}
-	});
+  $('#post_meta_input').autocomplete(mEdit.service_uri, {
+    extraParams: {
+      'f': 'searchMeta',
+      'metaType': 'tag'
+    },
+    delay: 1000,
+    multiple: true,
+    matchSubset: false,
+    matchContains: true,
+    parse: function(xml) {
+      let results = [];
+      $(xml).find('meta').each(function() {
+        results[results.length] = {
+          data: {
+            'id': $(this).text(),
+            'count': $(this).attr('count'),
+            'percent': $(this).attr('roundpercent')
+          },
+          result: $(this).text()
+        };
+      });
+      return results;
+    },
+    formatItem: function(tag) {
+      return tag.id + ' <em>(' +
+        dotclear.msg.tags_autocomplete.
+      replace('%p', tag.percent).
+      replace('%e', tag.count + ' ' +
+          (tag.count > 1 ?
+            dotclear.msg.entries :
+            dotclear.msg.entry)
+        ) +
+        ')</em>';
+    },
+    formatResult: function(tag) {
+      return tag.result;
+    }
+  });
 });
Index: plugins/tags/tag_posts.php
===================================================================
--- plugins/tags/tag_posts.php	(revision 3731)
+++ plugins/tags/tag_posts.php	(revision 3874)
@@ -43,6 +43,6 @@
 }
 
-$params               = array();
-$params['limit']      = array((($page - 1) * $nb_per_page), $nb_per_page);
+$params               = [];
+$params['limit']      = [(($page - 1) * $nb_per_page), $nb_per_page];
 $params['no_content'] = true;
 
@@ -60,5 +60,5 @@
 }
 
-$posts_actions_page = new dcPostsActionsPage($core, 'plugin.php', array('p' => 'tags', 'm' => 'tag_posts', 'tag' => $tag));
+$posts_actions_page = new dcPostsActionsPage($core, 'plugin.php', ['p' => 'tags', 'm' => 'tag_posts', 'tag' => $tag]);
 
 if ($posts_actions_page->process()) {
@@ -86,9 +86,9 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name)                         => '',
         __('Tags')                                                  => $p_url . '&amp;m=tags',
         __('Tag') . ' &ldquo;' . html::escapeHTML($tag) . '&rdquo;' => ''
-    )) .
+    ]) .
 dcPage::notices();
 ?>
Index: plugins/tags/tags.php
===================================================================
--- plugins/tags/tags.php	(revision 3731)
+++ plugins/tags/tags.php	(revision 3874)
@@ -22,8 +22,8 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Tags')                          => ''
-    )) .
+    ]) .
 dcPage::notices();
 ?>
@@ -31,10 +31,10 @@
 <?php
 
-$tags = $core->meta->getMetadata(array('meta_type' => 'tag'));
+$tags = $core->meta->getMetadata(['meta_type' => 'tag']);
 $tags = $core->meta->computeMetaStats($tags);
 $tags->sort('meta_id_lower', 'asc');
 
 $last_letter = null;
-$cols        = array('', '');
+$cols        = ['', ''];
 $col         = 0;
 while ($tags->fetch()) {
Index: plugins/themeEditor/_admin.php
===================================================================
--- plugins/themeEditor/_admin.php	(revision 3731)
+++ plugins/themeEditor/_admin.php	(revision 3874)
@@ -16,8 +16,8 @@
 }
 
-$core->addBehavior('adminCurrentThemeDetails', array('themeEditorBehaviors', 'theme_editor_details'));
+$core->addBehavior('adminCurrentThemeDetails', ['themeEditorBehaviors', 'theme_editor_details']);
 
-$core->addBehavior('adminBeforeUserOptionsUpdate', array('themeEditorBehaviors', 'adminBeforeUserUpdate'));
-$core->addBehavior('adminPreferencesForm', array('themeEditorBehaviors', 'adminPreferencesForm'));
+$core->addBehavior('adminBeforeUserOptionsUpdate', ['themeEditorBehaviors', 'adminBeforeUserUpdate']);
+$core->addBehavior('adminPreferencesForm', ['themeEditorBehaviors', 'adminPreferencesForm']);
 
 class themeEditorBehaviors
@@ -51,5 +51,5 @@
 
         $themes_list  = dcPage::getCodeMirrorThemes();
-        $themes_combo = array(__('Default') => '');
+        $themes_combo = [__('Default') => ''];
         foreach ($themes_list as $theme) {
             $themes_combo[$theme] = $theme;
@@ -69,7 +69,7 @@
             '<p><label for="colorsyntax_theme" class="classic">' . __('Theme:') . '</label> ' .
             form::combo('colorsyntax_theme', $themes_combo,
-                array(
+                [
                     'default'    => $core->auth->user_prefs->interface->colorsyntax_theme,
-                    'extra_html' => 'onchange="selectTheme()"')) .
+                    'extra_html' => 'onchange="selectTheme()"']) .
                 '</p>';
         } else {
@@ -78,5 +78,5 @@
         echo '</div>';
         echo '<div class="col">';
-        echo dcPage::jsLoadCodeMirror('', false, array('javascript'));
+        echo dcPage::jsLoadCodeMirror('', false, ['javascript']);
         foreach ($themes_list as $theme) {
             echo dcPage::cssLoad('js/codemirror/theme/' . $theme . '.css');
Index: plugins/themeEditor/_define.php
===================================================================
--- plugins/themeEditor/_define.php	(revision 3731)
+++ plugins/themeEditor/_define.php	(revision 3874)
@@ -17,9 +17,9 @@
     "Olivier Meunier", // Author
     '1.3',             // Version
-    array(
+    [
         'type'     => 'plugin',
-        'settings' => array(
+        'settings' => [
             'pref' => '#user-options.themeEditor_prefs'
-        )
-    )
+        ]
+    ]
 );
Index: plugins/themeEditor/class.themeEditor.php
===================================================================
--- plugins/themeEditor/class.themeEditor.php	(revision 3731)
+++ plugins/themeEditor/class.themeEditor.php	(revision 3874)
@@ -23,8 +23,8 @@
     protected $tplset_name;
 
-    public $tpl = array();
-    public $css = array();
-    public $js  = array();
-    public $po  = array();
+    public $tpl = [];
+    public $css = [];
+    public $js  = [];
+    public $po  = [];
 
     public function __construct($core)
@@ -112,10 +112,10 @@
         }
 
-        return array(
+        return [
             'c'    => file_get_contents($F),
             'w'    => $this->getDestinationFile($type, $f) !== false,
             'type' => $type,
             'f'    => $f
-        );
+        ];
     }
 
@@ -256,5 +256,5 @@
                 return $this->po;
             default:
-                return array();
+                return [];
         }
     }
@@ -303,5 +303,5 @@
         }
 
-        uksort($this->tpl, array($this, 'sortFilesHelper'));
+        uksort($this->tpl, [$this, 'sortFilesHelper']);
     }
 
@@ -334,9 +334,9 @@
         $dir = path::real($dir);
         if (!$dir || !is_dir($dir) || !is_readable($dir)) {
-            return array();
+            return [];
         }
 
         $d   = dir($dir);
-        $res = array();
+        $res = [];
         while (($f = $d->read()) !== false) {
             if (is_file($dir . '/' . $f) && !preg_match('/^\./', $f) && (!$ext || preg_match('/\.' . preg_quote($ext) . '$/i', $f))) {
Index: plugins/themeEditor/index.php
===================================================================
--- plugins/themeEditor/index.php	(revision 3834)
+++ plugins/themeEditor/index.php	(revision 3874)
@@ -14,5 +14,5 @@
 require dirname(__FILE__) . '/class.themeEditor.php';
 
-$file_default = $file = array('c' => null, 'w' => false, 'type' => null, 'f' => null, 'default_file' => false);
+$file_default = $file = ['c' => null, 'w' => false, 'type' => null, 'f' => null, 'default_file' => false];
 
 # Get interface setting
@@ -66,14 +66,14 @@
     <title><?php echo __('Edit theme files'); ?></title>
     <?php
-echo dcPage::jsVars(array(
+echo dcPage::jsVars([
     'dotclear.msg.saving_document'    => __("Saving document..."),
     'dotclear.msg.document_saved'     => __("Document saved"),
     'dotclear.msg.error_occurred'     => __("An error occurred:"),
     'dotclear.msg.confirm_reset_file' => __("Are you sure you want to reset this file?")
-)) .
+]) .
 dcPage::jsConfirmClose('file-form') .
 dcPage::jsLoad(dcPage::getPF('themeEditor/js/script.js'));
 if ($user_ui_colorsyntax) {
-    echo dcPage::jsVars(array('dotclear.colorsyntax' => $user_ui_colorsyntax));
+    echo dcPage::jsVars(['dotclear.colorsyntax' => $user_ui_colorsyntax]);
     echo dcPage::jsLoadCodeMirror($user_ui_colorsyntax_theme);
 }
@@ -85,9 +85,9 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Blog appearance')               => $core->adminurl->get('admin.blog.theme'),
         __('Edit theme files')              => ''
-    )) .
+    ]) .
 dcPage::notices();
 ?>
@@ -110,9 +110,9 @@
     '<div class="fieldset"><h3>' . __('File editor') . '</h3>' .
     '<p><label for="file_content">' . sprintf(__('Editing file %s'), '<strong>' . $file['f']) . '</strong></label></p>' .
-    '<p>' . form::textarea('file_content', 72, 25, array(
+    '<p>' . form::textarea('file_content', 72, 25, [
         'default'  => html::escapeHTML($file['c']),
         'class'    => 'maximal',
         'disabled' => !$file['w']
-    )) . '</p>';
+    ]) . '</p>';
 
     if ($file['w']) {
@@ -121,5 +121,5 @@
         ($o->deletableFile($file['type'], $file['f']) ? '<input type="submit" name="delete" class="delete" value="' . __('Reset') . '" />' : '') .
         $core->formNonce() .
-            ($file['type'] ? form::hidden(array($file['type']), $file['f']) : '') .
+            ($file['type'] ? form::hidden([$file['type']], $file['f']) : '') .
             '</p>';
     } else {
Index: plugins/themeEditor/js/script.js
===================================================================
--- plugins/themeEditor/js/script.js	(revision 3709)
+++ plugins/themeEditor/js/script.js	(revision 3880)
@@ -4,9 +4,9 @@
 $(function() {
   // Cope with saving
-  var msg = false;
+  let msg = false;
   $('#file-form input[name="write"]').click(function(e) {
-    var f = this.form;
+    const f = this.form;
 
-    var data = {
+    const data = {
       file_content: (!dotclear.colorsyntax ? $(f).find('#file_content').get(0).value : editor.getValue()),
       xd_check: $(f).find('input[name="xd_check"]').get(0).value,
@@ -22,5 +22,5 @@
 
     $.post(document.location.href, data, function(res) {
-      var err = $(res).find('div.error li:first');
+      const err = $(res).find('div.error li:first');
       if (err.length > 0) {
         msg.text(dotclear.msg.error_occurred + ' ' + err.text());
Index: plugins/userPref/_define.php
===================================================================
--- plugins/userPref/_define.php	(revision 3731)
+++ plugins/userPref/_define.php	(revision 3874)
@@ -17,6 +17,6 @@
     "Franck Paul",                            // Author
     '0.3',                                    // Version
-    array(
+    [
         'type' => 'plugin'
-    )
+    ]
 );
Index: plugins/userPref/index.php
===================================================================
--- plugins/userPref/index.php	(revision 3731)
+++ plugins/userPref/index.php	(revision 3874)
@@ -69,16 +69,16 @@
 {
     if ($s['type'] == 'boolean') {
-        $field = form::combo(array($field_name . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id),
-            array(__('yes') => 1, __('no') => 0), $s['value'] ? 1 : 0);
+        $field = form::combo([$field_name . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id],
+            [__('yes') => 1, __('no') => 0], $s['value'] ? 1 : 0);
     } else {
         if ($s['type'] == 'array') {
-            $field = form::field(array($field_name . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id), 40, null,
+            $field = form::field([$field_name . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id], 40, null,
                 html::escapeHTML(json_encode($s['value'])));
         } else {
-            $field = form::field(array($field_name . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id), 40, null,
+            $field = form::field([$field_name . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id], 40, null,
                 html::escapeHTML($s['value']));
         }
     }
-    $type = form::hidden(array($field_name . '_type' . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id . '_type'),
+    $type = form::hidden([$field_name . '_type' . '[' . $ws . '][' . $id . ']', $field_name . '_' . $ws . '_' . $id . '_type'],
         html::escapeHTML($s['type']));
 
@@ -103,9 +103,9 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         __('System')                            => '',
         html::escapeHTML($core->auth->userID()) => '',
         __('user:preferences')                  => ''
-    )) .
+    ]) .
 dcPage::notices();
 
@@ -122,5 +122,5 @@
 '  <th>' . __('Value') . '</th>' . "\n" .
 '  <th>' . __('Type') . '</th>' . "\n" .
-'  <th class="maximalx">' . __('Description') . '</th>' . "\n" .
+'  <th>' . __('Description') . '</th>' . "\n" .
     '</tr>' . "\n" .
     '</thead>' . "\n" .
@@ -128,5 +128,5 @@
 $table_footer = '</tbody></table></div>';
 
-$prefs = array();
+$prefs = [];
 foreach ($core->auth->user_prefs->dumpWorkspaces() as $ws => $workspace) {
     foreach ($workspace->dumpPrefs() as $k => $v) {
@@ -136,5 +136,5 @@
 ksort($prefs);
 if (count($prefs) > 0) {
-    $ws_combo = array();
+    $ws_combo = [];
     foreach ($prefs as $ws => $s) {
         $ws_combo[$ws] = '#l_' . $ws;
@@ -144,5 +144,5 @@
     '<p class="anchor-nav">' .
     '<label for="lp_nav" class="classic">' . __('Goto:') . '</label> ' .
-    form::combo('lp_nav', $ws_combo, array('class' => 'navigation')) .
+    form::combo('lp_nav', $ws_combo, ['class' => 'navigation']) .
     ' <input type="submit" value="' . __('Ok') . '" id="lp_submit" />' .
     '<input type="hidden" name="p" value="userPref" />' .
@@ -174,5 +174,5 @@
 
 <?php
-$prefs = array();
+$prefs = [];
 
 foreach ($core->auth->user_prefs->dumpWorkspaces() as $ws => $workspace) {
@@ -185,5 +185,5 @@
 
 if (count($prefs) > 0) {
-    $ws_combo = array();
+    $ws_combo = [];
     foreach ($prefs as $ws => $s) {
         $ws_combo[$ws] = '#g_' . $ws;
@@ -193,5 +193,5 @@
     '<p class="anchor-nav">' .
     '<label for="gp_nav" class="classic">' . __('Goto:') . '</label> ' .
-    form::combo('gp_nav', $ws_combo, array('class' => 'navigation')) .
+    form::combo('gp_nav', $ws_combo, ['class' => 'navigation']) .
     ' <input type="submit" value="' . __('Ok') . '" id="gp_submit" />' .
     '<input type="hidden" name="p" value="userPref" />' .
Index: plugins/widgets/_admin.php
===================================================================
--- plugins/widgets/_admin.php	(revision 3731)
+++ plugins/widgets/_admin.php	(revision 3874)
@@ -12,6 +12,6 @@
 if (!defined('DC_CONTEXT_ADMIN')) {return;}
 
-$core->addBehavior('adminDashboardFavorites', array('widgetsBehaviors', 'widgets_dashboard_favorites'));
-$core->addBehavior('adminRteFlags', array('widgetsBehaviors', 'adminRteFlags'));
+$core->addBehavior('adminDashboardFavorites', ['widgetsBehaviors', 'widgets_dashboard_favorites']);
+$core->addBehavior('adminRteFlags', ['widgetsBehaviors', 'adminRteFlags']);
 
 $_menu['Blog']->addItem(__('Presentation widgets'),
@@ -25,15 +25,15 @@
     public static function widgets_dashboard_favorites($core, $favs)
     {
-        $favs->register('widgets', array(
+        $favs->register('widgets', [
             'title'      => __('Presentation widgets'),
             'url'        => $core->adminurl->get('admin.plugin.widgets'),
             'small-icon' => dcPage::getPF('widgets/icon.png'),
             'large-icon' => dcPage::getPF('widgets/icon-big.png')
-        ));
+        ]);
     }
 
     public static function adminRteFlags($core, $rte)
     {
-        $rte['widgets_text'] = array(true, __('Widget\'s textareas'));
+        $rte['widgets_text'] = [true, __('Widget\'s textareas')];
     }
 }
Index: plugins/widgets/_default_widgets.php
===================================================================
--- plugins/widgets/_default_widgets.php	(revision 3731)
+++ plugins/widgets/_default_widgets.php	(revision 3874)
@@ -18,39 +18,39 @@
 $__widgets = new dcWidgets;
 
-$__widgets->create('search', __('Search engine'), array('defaultWidgets', 'search'), null, 'Search engine form');
+$__widgets->create('search', __('Search engine'), ['defaultWidgets', 'search'], null, 'Search engine form');
 $__widgets->search->setting('title', __('Title (optional)') . ' :', __('Search'));
 $__widgets->search->setting('placeholder', __('Placeholder (HTML5 only, optional):'), '');
 $__widgets->search->setting('homeonly', __('Display on:'), 0, 'combo',
-    array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->search->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->search->setting('class', __('CSS class:'), '');
 $__widgets->search->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('navigation', __('Navigation links'), array('defaultWidgets', 'navigation'), null, 'List of navigation links');
+$__widgets->create('navigation', __('Navigation links'), ['defaultWidgets', 'navigation'], null, 'List of navigation links');
 $__widgets->navigation->setting('title', __('Title (optional)') . ' :', '');
 $__widgets->navigation->setting('homeonly', __('Display on:'), 0, 'combo',
-    array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->navigation->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->navigation->setting('class', __('CSS class:'), '');
 $__widgets->navigation->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('bestof', __('Selected entries'), array('defaultWidgets', 'bestof'), null, 'List of selected entries');
+$__widgets->create('bestof', __('Selected entries'), ['defaultWidgets', 'bestof'], null, 'List of selected entries');
 $__widgets->bestof->setting('title', __('Title (optional)') . ' :', __('Best of me'));
-$__widgets->bestof->setting('orderby', __('Sort:'), 'asc', 'combo', array(__('Ascending') => 'asc', __('Descending') => 'desc'));
+$__widgets->bestof->setting('orderby', __('Sort:'), 'asc', 'combo', [__('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));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->bestof->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->bestof->setting('class', __('CSS class:'), '');
 $__widgets->bestof->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('langs', __('Blog languages'), array('defaultWidgets', 'langs'), null, 'List of available languages');
+$__widgets->create('langs', __('Blog languages'), ['defaultWidgets', 'langs'], null, 'List of available languages');
 $__widgets->langs->setting('title', __('Title (optional)') . ' :', __('Languages'));
 $__widgets->langs->setting('homeonly', __('Display on:'), 1, 'combo',
-    array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->langs->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->langs->setting('class', __('CSS class:'), '');
 $__widgets->langs->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('categories', __('List of categories'), array('defaultWidgets', 'categories'), null, 'List of categories');
+$__widgets->create('categories', __('List of categories'), ['defaultWidgets', 'categories'], null, 'List of categories');
 $__widgets->categories->setting('title', __('Title (optional)') . ' :', __('Categories'));
 $__widgets->categories->setting('postcount', __('With entries counts'), 0, 'check');
@@ -58,41 +58,41 @@
 $__widgets->categories->setting('with_empty', __('Include empty categories'), 0, 'check');
 $__widgets->categories->setting('homeonly', __('Display on:'), 0, 'combo',
-    array(__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->categories->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->categories->setting('class', __('CSS class:'), '');
 $__widgets->categories->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('subscribe', __('Subscribe links'), array('defaultWidgets', 'subscribe'), null, 'Feed subscription links (RSS or Atom)');
+$__widgets->create('subscribe', __('Subscribe links'), ['defaultWidgets', 'subscribe'], null, 'Feed subscription links (RSS or Atom)');
 $__widgets->subscribe->setting('title', __('Title (optional)') . ' :', __('Subscribe'));
-$__widgets->subscribe->setting('type', __('Feeds type:'), 'atom', 'combo', array('Atom' => 'atom', 'RSS' => 'rss2'));
+$__widgets->subscribe->setting('type', __('Feeds type:'), 'atom', 'combo', ['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));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->subscribe->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->subscribe->setting('class', __('CSS class:'), '');
 $__widgets->subscribe->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('feed', __('Feed reader'), array('defaultWidgets', 'feed'), null, 'List of last entries from feed (RSS or Atom)');
+$__widgets->create('feed', __('Feed reader'), ['defaultWidgets', 'feed'], null, 'List of last entries from feed (RSS or Atom)');
 $__widgets->feed->setting('title', __('Title (optional)') . ' :', __('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));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->feed->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->feed->setting('class', __('CSS class:'), '');
 $__widgets->feed->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('text', __('Text'), array('defaultWidgets', 'text'), null, 'Simple text');
+$__widgets->create('text', __('Text'), ['defaultWidgets', 'text'], null, 'Simple text');
 $__widgets->text->setting('title', __('Title (optional)') . ' :', '');
 $__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));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->text->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->text->setting('class', __('CSS class:'), '');
 $__widgets->text->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('lastposts', __('Last entries'), array('defaultWidgets', 'lastposts'), null, 'List of last entries published');
+$__widgets->create('lastposts', __('Last entries'), ['defaultWidgets', 'lastposts'], null, 'List of last entries published');
 $__widgets->lastposts->setting('title', __('Title (optional)') . ' :', __('Last entries'));
-$rs         = $core->blog->getCategories(array('post_type' => 'post'));
-$categories = array('' => '', __('Uncategorized') => 'null');
+$rs         = $core->blog->getCategories(['post_type' => 'post']);
+$categories = ['' => '', __('Uncategorized') => 'null'];
 while ($rs->fetch()) {
     $categories[str_repeat('&nbsp;&nbsp;', $rs->level - 1) . ($rs->level - 1 == 0 ? '' : '&bull; ') . html::escapeHTML($rs->cat_title)] = $rs->cat_id;
@@ -105,14 +105,14 @@
 $__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));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->lastposts->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->lastposts->setting('class', __('CSS class:'), '');
 $__widgets->lastposts->setting('offline', __('Offline'), 0, 'check');
 
-$__widgets->create('lastcomments', __('Last comments'), array('defaultWidgets', 'lastcomments'), null, 'List of last comments published');
+$__widgets->create('lastcomments', __('Last comments'), ['defaultWidgets', 'lastcomments'], null, 'List of last comments published');
 $__widgets->lastcomments->setting('title', __('Title (optional)') . ' :', __('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));
+    [__('All pages') => 0, __('Home page only') => 1, __('Except on home page') => 2]);
 $__widgets->lastcomments->setting('content_only', __('Content only'), 0, 'check');
 $__widgets->lastcomments->setting('class', __('CSS class:'), '');
@@ -124,5 +124,5 @@
 # Default widgets
 global $__default_widgets;
-$__default_widgets = array('nav' => new dcWidgets(), 'extra' => new dcWidgets(), 'custom' => new dcWidgets());
+$__default_widgets = ['nav' => new dcWidgets(), 'extra' => new dcWidgets(), 'custom' => new dcWidgets()];
 
 $__default_widgets['nav']->append($__widgets->search);
Index: plugins/widgets/_define.php
===================================================================
--- plugins/widgets/_define.php	(revision 3731)
+++ plugins/widgets/_define.php	(revision 3874)
@@ -17,8 +17,8 @@
     "Olivier Meunier & Dotclear Team", // Author
     '3.4',                             // Version
-    array(
+    [
         'permissions' => 'admin',
         'priority'    => 1000000000,
         'type'        => 'plugin'
-    )
+    ]
 );
Index: plugins/widgets/_public.php
===================================================================
--- plugins/widgets/_public.php	(revision 3731)
+++ plugins/widgets/_public.php	(revision 3874)
@@ -15,7 +15,7 @@
 require_once dirname(__FILE__) . '/_widgets_functions.php';
 
-$core->tpl->addValue('Widgets', array('publicWidgets', 'tplWidgets'));
-$core->tpl->addBlock('Widget', array('publicWidgets', 'tplWidget'));
-$core->tpl->addBlock('IfWidgets', array('publicWidgets', 'tplIfWidgets'));
+$core->tpl->addValue('Widgets', ['publicWidgets', 'tplWidgets']);
+$core->tpl->addBlock('Widget', ['publicWidgets', 'tplWidget']);
+$core->tpl->addBlock('IfWidgets', ['publicWidgets', 'tplIfWidgets']);
 
 class publicWidgets
@@ -33,5 +33,5 @@
             "   publicWidgets::widgetsHandler('custom','" . addslashes($disable) . "');" . "\n";
         } else {
-            if (!in_array($type, array('nav', 'extra', 'custom'))) {
+            if (!in_array($type, ['nav', 'extra', 'custom'])) {
                 $type = 'nav';
             }
@@ -83,5 +83,5 @@
             "   publicWidgets::ifWidgetsHandler('custom','" . addslashes($disable) . "')" . "\n";
         } else {
-            if (!in_array($type, array('nav', 'extra', 'custom'))) {
+            if (!in_array($type, ['nav', 'extra', 'custom'])) {
                 $type = 'nav';
             }
@@ -164,5 +164,5 @@
                 $text = $e;
             }
-            $w->{$setting} = preg_replace_callback('/\{tpl:lang (.*?)\}/msu', array('self', 'widgetL10nHandler'), $text);
+            $w->{$setting} = preg_replace_callback('/\{tpl:lang (.*?)\}/msu', ['self', 'widgetL10nHandler'], $text);
         }
 
Index: plugins/widgets/_widgets_functions.php
===================================================================
--- plugins/widgets/_widgets_functions.php	(revision 3751)
+++ plugins/widgets/_widgets_functions.php	(revision 3874)
@@ -91,5 +91,5 @@
         }
 
-        $rs = $core->blog->getCategories(array('post_type' => 'post', 'without_empty' => !$w->with_empty));
+        $rs = $core->blog->getCategories(['post_type' => 'post', 'without_empty' => !$w->with_empty]);
         if ($rs->isEmpty()) {
             return;
@@ -145,9 +145,9 @@
         }
 
-        $params = array(
+        $params = [
             'post_selected' => true,
             'no_content'    => true,
             'order'         => 'post_dt ' . strtoupper($w->orderby)
-        );
+        ];
 
         $rs = $core->blog->getPosts($params);
Index: plugins/widgets/class.widgets.php
===================================================================
--- plugins/widgets/class.widgets.php	(revision 3731)
+++ plugins/widgets/class.widgets.php	(revision 3874)
@@ -14,5 +14,5 @@
 class dcWidgets
 {
-    private $__widgets = array();
+    private $__widgets = [];
 
     public static function load($s)
@@ -29,5 +29,5 @@
     public function store()
     {
-        $serialized = array();
+        $serialized = [];
         foreach ($this->__widgets as $pos => $w) {
             $serialized[] = ($w->serialize($pos));
@@ -60,5 +60,5 @@
     {
         if ($sorted) {
-            uasort($this->__widgets, array('self', 'sort'));
+            uasort($this->__widgets, ['self', 'sort']);
         }
         return $this->__widgets;
@@ -88,5 +88,5 @@
         }
 
-        uasort($A, array('self', 'arraySort'));
+        uasort($A, ['self', 'arraySort']);
 
         $result = new self;
@@ -135,9 +135,9 @@
     private $public_callback = null;
     public $append_callback  = null;
-    private $settings        = array();
+    private $settings        = [];
 
     public function serialize($order)
     {
-        $values = array();
+        $values = [];
         foreach ($this->settings as $k => $v) {
             $values[$k] = $v['value'];
@@ -274,14 +274,22 @@
                 return false;
             }
-        }
-
-        $this->settings[$name] = array(
+            // If any, the 5th argument should be an array (key → value) of opts
+            $opts = @func_get_arg(5);
+        } else {
+            // If any, the 4th argument should be an array (key → value) of opts
+            $opts = @func_get_arg(4);
+        }
+
+        $this->settings[$name] = [
             'title' => $title,
             'type'  => $type,
             'value' => $value
-        );
+        ];
 
         if (isset($options)) {
             $this->settings[$name]['options'] = $options;
+        }
+        if (isset($opt)) {
+            $this->settings[$name]['opts'] = $opts;
         }
     }
@@ -308,9 +316,10 @@
         $wfid  = "wf-" . $i;
         $iname = $pr ? $pr . '[' . $id . ']' : $id;
+        $class = (isset($s['opts']) && isset($s['opts']['class']) ? ' ' . $s['opts']['class'] : '');
         switch ($s['type']) {
             case 'text':
                 $res .=
                 '<p><label for="' . $wfid . '">' . $s['title'] . '</label> ' .
-                form::field(array($iname, $wfid), 20, 255, html::escapeHTML($s['value']), 'maximal') .
+                form::field([$iname, $wfid], 20, 255, html::escapeHTML($s['value']), 'maximal' . $class) .
                     '</p>';
                 break;
@@ -318,12 +327,12 @@
                 $res .=
                 '<p><label for="' . $wfid . '">' . $s['title'] . '</label> ' .
-                form::textarea(array($iname, $wfid), 30, 8, html::escapeHTML($s['value']), 'maximal') .
+                form::textarea([$iname, $wfid], 30, 8, html::escapeHTML($s['value']), 'maximal' . $class) .
                     '</p>';
                 break;
             case 'check':
                 $res .=
-                '<p>' . form::hidden(array($iname), '0') .
+                '<p>' . form::hidden([$iname], '0') .
                 '<label class="classic" for="' . $wfid . '">' .
-                form::checkbox(array($iname, $wfid), '1', $s['value']) . ' ' . $s['title'] .
+                form::checkbox([$iname, $wfid], '1', $s['value'], $class) . ' ' . $s['title'] .
                     '</label></p>';
                 break;
@@ -335,5 +344,5 @@
                         $res .=
                         '<label class="classic" for="' . $wfid . '-' . $k . '">' .
-                        form::radio(array($iname, $wfid . '-' . $k), $v[1], $s['value'] == $v[1]) . ' ' . $v[0] .
+                        form::radio([$iname, $wfid . '-' . $k], $v[1], $s['value'] == $v[1], $class) . ' ' . $v[0] .
                             '</label>';
                     }
@@ -344,5 +353,5 @@
                 $res .=
                 '<p><label for="' . $wfid . '">' . $s['title'] . '</label> ' .
-                form::combo(array($iname, $wfid), $s['options'], $s['value']) .
+                form::combo([$iname, $wfid], $s['options'], $s['value'], $class) .
                     '</p>';
                 break;
Index: plugins/widgets/index.php
===================================================================
--- plugins/widgets/index.php	(revision 3731)
+++ plugins/widgets/index.php	(revision 3874)
@@ -28,10 +28,10 @@
 }
 
-$append_combo = array(
+$append_combo = [
     '-'              => 0,
     __('navigation') => 'nav',
     __('extra')      => 'extra',
     __('custom')     => 'custom'
-);
+];
 
 function literalNullString($v)
@@ -46,5 +46,5 @@
 if (!empty($_POST['append']) && is_array($_POST['addw'])) {
     # Filter selection
-    $addw = array();
+    $addw = [];
     foreach ($_POST['addw'] as $k => $v) {
         if (($v == 'extra' || $v == 'nav' || $v == 'custom') && $__widgets->{$k} !== null) {
@@ -144,5 +144,5 @@
 if (!empty($_POST['wup']) || $removing || $move) {
     if (!isset($_POST['w']) || !is_array($_POST['w'])) {
-        $_POST['w'] = array();
+        $_POST['w'] = [];
     }
 
@@ -160,11 +160,11 @@
 
         if (!isset($_POST['w']['nav'])) {
-            $_POST['w']['nav'] = array();
+            $_POST['w']['nav'] = [];
         }
         if (!isset($_POST['w']['extra'])) {
-            $_POST['w']['extra'] = array();
+            $_POST['w']['extra'] = [];
         }
         if (!isset($_POST['w']['custom'])) {
-            $_POST['w']['custom'] = array();
+            $_POST['w']['custom'] = [];
         }
 
@@ -214,5 +214,5 @@
     echo dcPage::jsLoad(dcPage::getPF('widgets/js/dragdrop.js'));
 }
-echo dcPage::jsVars(array('dotclear.msg.confirm_widgets_reset' => __('Are you sure you want to reset sidebars?')));
+echo dcPage::jsVars(['dotclear.msg.confirm_widgets_reset' => __('Are you sure you want to reset sidebars?')]);
 
 $widget_editor = $core->auth->getOption('editor');
@@ -223,5 +223,9 @@
 }
 if ($rte_flag) {
-    echo $core->callBehavior('adminPostEditor', $widget_editor['xhtml'], 'widget', array('#sidebarsWidgets textarea'), 'xhtml');
+    echo dcPage::jsVars(['dotclear.widget_noeditor' => 0]);
+    echo $core->callBehavior('adminPostEditor', $widget_editor['xhtml'], 'widget',
+        ['#sidebarsWidgets textarea:not(.noeditor)'], 'xhtml');
+} else {
+    echo dcPage::jsVars(['dotclear.widget_noeditor' => 1]);
 }
 echo (dcPage::jsConfirmClose('sidebarsWidgets'));
@@ -231,8 +235,8 @@
 <?php
 echo dcPage::breadcrumb(
-    array(
+    [
         html::escapeHTML($core->blog->name) => '',
         __('Widgets')                       => ''
-    )) .
+    ]) .
 dcPage::notices();
 
@@ -247,14 +251,14 @@
 foreach ($__widgets->elements(true) as $w) {
     echo
-    '<li>' . form::hidden(array('w[void][0][id]'), html::escapeHTML($w->id())) .
-    '<p class="widget-name">' . form::number(array('w[void][0][order]'), array(
+    '<li>' . form::hidden(['w[void][0][id]'], html::escapeHTML($w->id())) .
+    '<p class="widget-name">' . form::number(['w[void][0][order]'], [
         'default'    => 0,
         'class'      => 'hide',
         'extra_html' => 'title="' . __('order') . '"'
-    )) .
+    ]) .
     ' ' . $w->name() .
     ($w->desc() != '' ? ' <span class="form-note">' . __($w->desc()) . '</span>' : '') . '</p>' .
     '<p class="manual-move remove-if-drag"><label class="classic">' . __('Append to:') . '</label> ' .
-    form::combo(array('addw[' . $w->id() . ']'), $append_combo) .
+    form::combo(['addw[' . $w->id() . ']'], $append_combo) .
     '<input type="submit" name="append[' . $w->id() . ']" value="' . __('Add') . '" /></p>' .
     '<div class="widgetSettings hidden-if-drag">' . $w->formSettings('w[void][0]', $j) . '</div>' .
@@ -361,10 +365,10 @@
 
         $res .=
-        '<li>' . form::hidden(array($iname . '[id]'), html::escapeHTML($w->id())) .
-        '<p class="widget-name">' . form::number(array($iname . '[order]'), array(
+        '<li>' . form::hidden([$iname . '[id]'], html::escapeHTML($w->id())) .
+        '<p class="widget-name">' . form::number([$iname . '[order]'], [
             'default'    => $i,
             'class'      => 'hidden',
             'extra_html' => 'title="' . __('order') . '"'
-        )) .
+        ]) .
         ' ' . $w->name() .
         ($w->desc() != '' ? ' <span class="form-note">' . __($w->desc()) . '</span>' : '') .
Index: plugins/widgets/js/dragdrop.js
===================================================================
--- plugins/widgets/js/dragdrop.js	(revision 3709)
+++ plugins/widgets/js/dragdrop.js	(revision 3880)
@@ -1,3 +1,3 @@
-/*global $, reorder, dotclear */
+/*global $, reorder, dotclear, jsToolBar */
 'use strict';
 
@@ -23,7 +23,7 @@
     },
     update: function(event, ui) {
-      var ul = $(this);
-      var widget = ui.item;
-      var field = ul.parents('.widgets');
+      const ul = $(this);
+      const widget = ui.item;
+      const field = ul.parents('.widgets');
 
       // met a zéro le décalage
@@ -71,4 +71,14 @@
         'width': $('#widgets-ref > li').css('width')
       });
+    },
+    stop: function(event, ui) {
+      if (!dotclear.widget_noeditor) {
+        ui.helper.find('textarea:not(.noeditor)').each(function() {
+          if ($.isFunction(jsToolBar)) {
+            const tbWidgetText = new jsToolBar(this);
+            tbWidgetText.draw('xhtml');
+          }
+        });
+      }
     }
   });
Index: plugins/widgets/js/widgets.js
===================================================================
--- plugins/widgets/js/widgets.js	(revision 3845)
+++ plugins/widgets/js/widgets.js	(revision 3880)
@@ -4,19 +4,19 @@
 dotclear.postExpander = function(line) {
 
-  var title = $(line).find('.widget-name');
+  const title = $(line).find('.widget-name');
   title.find('.form-note').remove();
 
-  var order = title.find('input[name*=order]');
-  var link = $('<a href="#" alt="expand" class="aexpand"/>').append(title.text());
-  var tools = title.find('.toolsWidget');
-  var br = title.find('br');
+  const order = title.find('input[name*=order]');
+  const link = $('<a href="#" alt="expand" class="aexpand"/>').append(title.text());
+  const tools = title.find('.toolsWidget');
+  const br = title.find('br');
   title.empty().append(order).append(link).append(tools).append(br);
 
-  var b = document.createElement('button');
+  const b = document.createElement('button');
   b.setAttribute('type', 'button');
   b.className = 'details-cmd';
   b.value = dotclear.img_plus_txt;
   b.setAttribute('aria-label', dotclear.img_plus_alt);
-  var t = document.createTextNode(dotclear.img_plus_txt);
+  const t = document.createTextNode(dotclear.img_plus_txt);
   b.appendChild(t);
   b.onclick = function(e) {
@@ -33,6 +33,6 @@
 dotclear.viewPostContent = function(line, action) {
   action = action || 'toogle';
-  var img = line.find('.details-cmd');
-  var isopen = img.attr('aria-label') == dotclear.img_plus_alt;
+  const img = line.find('.details-cmd');
+  const isopen = img.attr('aria-label') == dotclear.img_plus_alt;
 
   if (action == 'close' || (action == 'toogle' && !isopen)) {
@@ -53,10 +53,10 @@
   // réordonne
   if (ul.attr('id')) {
-    var $list = ul.find('li').not('.empty-widgets');
+    const $list = ul.find('li').not('.empty-widgets');
     $list.each(function(i) {
-      var $this = $(this);
+      const $this = $(this);
 
       // trouve la zone de réception
-      var name = ul.attr('id').split('dnd').join('');
+      const name = ul.attr('id').split('dnd').join('');
 
       // modifie le name en conséquence
@@ -112,21 +112,19 @@
   $('input[name*=_down]').click(function(e) {
     e.preventDefault();
-    var $this = $(this);
-    var $li = $this.parents('li');
+    const $li = $(this).parents('li');
     $li.next().after($li);
-    reorder($this.parents('ul.connected'));
+    reorder($(this).parents('ul.connected'));
   });
   $('input[name*=_up]').click(function(e) {
     e.preventDefault();
-    var $this = $(this);
-    var $li = $this.parents('li');
+    const $li = $(this).parents('li');
     $li.prev().before($li);
-    reorder($this.parents('ul.connected'));
+    reorder($(this).parents('ul.connected'));
   });
 
   // HTML text editor
   if ($.isFunction(jsToolBar)) {
-    $('#sidebarsWidgets textarea').each(function() {
-      var tbWidgetText = new jsToolBar(this);
+    $('#sidebarsWidgets textarea:not(.noeditor)').each(function() {
+      let tbWidgetText = new jsToolBar(this);
       tbWidgetText.draw('xhtml');
     });
Index: tests/unit/bootstrap.php
===================================================================
--- tests/unit/bootstrap.php	(revision 3064)
+++ tests/unit/bootstrap.php	(revision 3874)
@@ -11,21 +11,21 @@
 # -- END LICENSE BLOCK -----------------------------------------
 
-require_once __DIR__.'/../../vendor/autoload.php';
+require_once __DIR__ . '/../../vendor/autoload.php';
 
-define('CLEARBRICKS_PATH',__DIR__.'/../../inc/libs/clearbricks');
+define('CLEARBRICKS_PATH', __DIR__ . '/../../inc/libs/clearbricks');
 
-$__autoload = array();
-$__autoload['dbLayer'] = CLEARBRICKS_PATH.'/dblayer/dblayer.php';
-$__autoload['staticRecord'] = CLEARBRICKS_PATH.'/dblayer/dblayer.php';
-$__autoload['sqliteConnection'] = CLEARBRICKS_PATH.'/dblayer/class.sqlite.php';
-$__autoload['mysqlConnection'] = CLEARBRICKS_PATH.'/dblayer/class.mysql.php';
-$__autoload['mysqliConnection'] = CLEARBRICKS_PATH.'/dblayer/class.mysqli.php';
-$__autoload['pgsqlConnection'] = CLEARBRICKS_PATH.'/dblayer/class.pgsql.php';
-$__autoload['record'] = CLEARBRICKS_PATH.'/dblayer/dblayer.php';
-$__autoload['template'] = CLEARBRICKS_PATH.'/template/class.template.php';
-$__autoload['path'] = CLEARBRICKS_PATH.'/common/lib.files.php';
+$__autoload                     = [];
+$__autoload['dbLayer']          = CLEARBRICKS_PATH . '/dblayer/dblayer.php';
+$__autoload['staticRecord']     = CLEARBRICKS_PATH . '/dblayer/dblayer.php';
+$__autoload['sqliteConnection'] = CLEARBRICKS_PATH . '/dblayer/class.sqlite.php';
+$__autoload['mysqlConnection']  = CLEARBRICKS_PATH . '/dblayer/class.mysql.php';
+$__autoload['mysqliConnection'] = CLEARBRICKS_PATH . '/dblayer/class.mysqli.php';
+$__autoload['pgsqlConnection']  = CLEARBRICKS_PATH . '/dblayer/class.pgsql.php';
+$__autoload['record']           = CLEARBRICKS_PATH . '/dblayer/dblayer.php';
+$__autoload['template']         = CLEARBRICKS_PATH . '/template/class.template.php';
+$__autoload['path']             = CLEARBRICKS_PATH . '/common/lib.files.php';
 
-$__autoload['dcCore'] = __DIR__.'/../../inc/core/class.dc.core.php';
-$__autoload['dcNamespace'] = __DIR__.'/../../inc/core/class.dc.namespace.php';
+$__autoload['dcCore']      = __DIR__ . '/../../inc/core/class.dc.core.php';
+$__autoload['dcNamespace'] = __DIR__ . '/../../inc/core/class.dc.namespace.php';
 
 $loader = new \Composer\Autoload\ClassLoader();
@@ -33,5 +33,6 @@
 $loader->register();
 
-function __($s) {
+function __($s)
+{
     return $s;
 }
Index: tests/unit/inc/core/class.dc.core.php
===================================================================
--- tests/unit/inc/core/class.dc.core.php	(revision 2999)
+++ tests/unit/inc/core/class.dc.core.php	(revision 3874)
@@ -15,7 +15,7 @@
 use atoum;
 
-require_once __DIR__.'/../../bootstrap.php';
-$f = str_replace('\\','/',__FILE__);
-require_once(str_replace('tests/unit/','',$f));
+require_once __DIR__ . '/../../bootstrap.php';
+$f = str_replace('\\', '/', __FILE__);
+require_once str_replace('tests/unit/', '', $f);
 
 class dcCore extends atoum
@@ -23,92 +23,98 @@
     private $prefix = 'dc_';
 
-	private function getConnection($driver) {
-		$controller = new \atoum\mock\controller();
-		$controller->__construct = function() {};
+    private function getConnection($driver)
+    {
+        $controller              = new \atoum\mock\controller();
+        $controller->__construct = function () {};
 
-		$class_name = sprintf('\mock\%sConnection',$driver);
-		$con = new $class_name($driver,$controller);
-		$this->calling($con)->driver = $driver;
-		$this->calling($con)->escape = function($s) { // just for order, so don't care
+        $class_name                  = sprintf('\mock\%sConnection', $driver);
+        $con                         = new $class_name($driver, $controller);
+        $this->calling($con)->driver = $driver;
+        $this->calling($con)->escape = function ($s) {
+            // just for order, so don't care
             return $s;
         };
-		$this->calling($con)->select = function($sql) {
-            return new \staticRecord(array(),array());
+        $this->calling($con)->select = function ($sql) {
+            return new \staticRecord([], []);
         };
 
-		return $con;
-	}
+        return $con;
+    }
 
-    public function testGetUsers($driver) {
+    public function testGetUsers($driver)
+    {
         $con = $this->getConnection($driver);
 
-        $controller = new \atoum\mock\controller();
-        $controller->__construct = function() {};
+        $controller              = new \atoum\mock\controller();
+        $controller->__construct = function () {};
 
         $query = 'SELECT U.user_id,user_super,user_status,user_pwd,user_change_pwd,user_name,user_firstname,user_displayname,user_email,user_url,user_desc, user_lang,user_tz, user_post_status,user_options, count(P.post_id) AS nb_post FROM user U LEFT JOIN post P ON U.user_id = P.user_id WHERE NULL IS NULL GROUP BY U.user_id,user_super,user_status,user_pwd,user_change_pwd,user_name,user_firstname,user_displayname,user_email,user_url,user_desc, user_lang,user_tz,user_post_status,user_options ORDER BY U.user_id ASC ';
 
-        $core = new \mock\dcCore(null,null,null,null,null,null,null,$controller);
+        $core      = new \mock\dcCore(null, null, null, null, null, null, null, $controller);
         $core->con = $con;
         $this
-			->if($core->getUsers())
+            ->if($core->getUsers())
             ->then()
-				  ->mock($con)->call('select')
-				  ->withIdenticalArguments($query)
-				  ->once();
+            ->mock($con)->call('select')
+            ->withIdenticalArguments($query)
+            ->once();
     }
 
-    public function testGetUsersWithParams($driver,$params,$query) {
+    public function testGetUsersWithParams($driver, $params, $query)
+    {
         $con = $this->getConnection($driver);
 
-        $controller = new \atoum\mock\controller();
-        $controller->__construct = function() {};
+        $controller              = new \atoum\mock\controller();
+        $controller->__construct = function () {};
 
-        $core = new \mock\dcCore(null,null,null,null,null,null,null,$controller);
+        $core      = new \mock\dcCore(null, null, null, null, null, null, null, $controller);
         $core->con = $con;
 
         $this
-			->if($core->getUsers($params))
+            ->if($core->getUsers($params))
             ->then()
-				  ->mock($con)->call('select')
-				  ->withIdenticalArguments($query)
-				  ->once();
+            ->mock($con)->call('select')
+            ->withIdenticalArguments($query)
+            ->once();
     }
 
     /*
      * DataProviders
-    **/
-    protected function testGetUsersDataProvider() {
-        $query = array();
+     **/
+    protected function testGetUsersDataProvider()
+    {
+        $query = [];
 
-        return array(
-			array('pgsql'),
-			array('sqlite'),
-			array('mysql'),
-			array('mysqli'),
-		);
+        return [
+            ['pgsql'],
+            ['sqlite'],
+            ['mysql'],
+            ['mysqli']
+        ];
     }
 
-    protected function testGetUsersWithParamsDataProvider() {
+    protected function testGetUsersWithParamsDataProvider()
+    {
         $base_query = 'SELECT U.user_id,user_super,user_status,user_pwd,user_change_pwd,user_name,user_firstname,user_displayname,user_email,user_url,user_desc, user_lang,user_tz, user_post_status,user_options, count(P.post_id) AS nb_post FROM user U LEFT JOIN post P ON U.user_id = P.user_id WHERE NULL IS NULL GROUP BY U.user_id,user_super,user_status,user_pwd,user_change_pwd,user_name,user_firstname,user_displayname,user_email,user_url,user_desc, user_lang,user_tz,user_post_status,user_options ORDER BY ';
 
-        return array(
-			array('pgsql',array('order' => 'user_id asc'),$base_query.'U.user_id asc '),
-			array('pgsql',array('order' => 'U.user_id asc'),$base_query.'U.user_id asc '),
-			array('mysql',array('order' => 'user_id asc'),$base_query.'U.user_id asc '),
-			array('mysql',array('order' => 'U.user_id asc'),$base_query.'U.user_id asc '),
-			array('mysqli',array('order' => 'user_id asc'),$base_query.'U.user_id asc '),
-			array('mysqli',array('order' => 'U.user_id asc'),$base_query.'U.user_id asc '),
-			array('sqlite',array('order' => 'user_id asc'),$base_query.'U.user_id asc '),
-			array('sqlite',array('order' => 'U.user_id asc'),$base_query.'U.user_id asc '),
+        return [
+            ['pgsql', ['order' => 'user_id asc'], $base_query . 'U.user_id asc '],
+            ['pgsql', ['order' => 'U.user_id asc'], $base_query . 'U.user_id asc '],
+            ['mysql', ['order' => 'user_id asc'], $base_query . 'U.user_id asc '],
+            ['mysql', ['order' => 'U.user_id asc'], $base_query . 'U.user_id asc '],
+            ['mysqli', ['order' => 'user_id asc'], $base_query . 'U.user_id asc '],
+            ['mysqli', ['order' => 'U.user_id asc'], $base_query . 'U.user_id asc '],
+            ['sqlite', ['order' => 'user_id asc'], $base_query . 'U.user_id asc '],
+            ['sqlite', ['order' => 'U.user_id asc'], $base_query . 'U.user_id asc '],
 
-            array('pgsql',array('order' => 'nb_post desc'),$base_query.'P.nb_post desc '),
-			array('pgsql',array('order' => 'P.nb_post desc'),$base_query.'P.nb_post desc '),
-			array('mysql',array('order' => 'nb_post desc'),$base_query.'P.nb_post desc '),
-			array('mysql',array('order' => 'P.nb_post desc'),$base_query.'P.nb_post desc '),
-			array('mysqli',array('order' => 'nb_post desc'),$base_query.'P.nb_post desc '),
-			array('mysqli',array('order' => 'P.nb_post desc'),$base_query.'P.nb_post desc '),
-			array('sqlite',array('order' => 'nb_post desc'),$base_query.'P.nb_post desc '),
-			array('sqlite',array('order' => 'P.nb_post desc'),$base_query.'P.nb_post desc '),
-		);
+            ['pgsql', ['order' => 'nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['pgsql', ['order' => 'P.nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['mysql', ['order' => 'nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['mysql', ['order' => 'P.nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['mysqli', ['order' => 'nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['mysqli', ['order' => 'P.nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['sqlite', ['order' => 'nb_post desc'], $base_query . 'P.nb_post desc '],
+            ['sqlite', ['order' => 'P.nb_post desc'], $base_query . 'P.nb_post desc ']
+        ];
     }
 }
Index: tests/unit/inc/public/class.dc.template.php
===================================================================
--- tests/unit/inc/public/class.dc.template.php	(revision 3064)
+++ tests/unit/inc/public/class.dc.template.php	(revision 3874)
@@ -15,115 +15,120 @@
 use atoum;
 
-require_once __DIR__.'/../../bootstrap.php';
-$f = str_replace('\\','/',__FILE__);
-require_once(str_replace('tests/unit/','',$f));
+require_once __DIR__ . '/../../bootstrap.php';
+$f = str_replace('\\', '/', __FILE__);
+require_once str_replace('tests/unit/', '', $f);
 
 class dcTemplate extends atoum
 {
-	private function getCore() {
-		$controller = new \atoum\mock\controller();
-		$controller->__construct = function() {};
+    private function getCore()
+    {
+        $controller              = new \atoum\mock\controller();
+        $controller->__construct = function () {};
 
-		$core = new \mock\dcCore(null,null,null,null,null,null,$controller);
-		$core->blog = json_decode('{"settings": {"system": {"tpl_allow_php":false,"tpl_use_cache":true}}}',false);
-		return $core;
-	}
+        $core       = new \mock\dcCore(null, null, null, null, null, null, $controller);
+        $core->blog = json_decode('{"settings": {"system": {"tpl_allow_php":false,"tpl_use_cache":true}}}', false);
+        return $core;
+    }
 
-	public function testGetSortByStrWithDefaultValues() {
-		// copy from ../../../../inc/public/class.dc.template.php:getSortByStr()
-		$default_alias = array(
-			'post' => array(
-				'title' => 'post_title',
-				'selected' => 'post_selected',
-				'author' => 'user_id',
-				'date' => 'post_dt',
-				'id' => 'post_id',
-				'comment' => 'nb_comment',
-				'trackback' => 'nb_trackback'
-			),
-			'comment' => array(
-				'author' => 'comment_author',
-				'date' => 'comment_dt',
-				'id' => 'comment_id'
-			)
-		);
+    public function testGetSortByStrWithDefaultValues()
+    {
+        // copy from ../../../../inc/public/class.dc.template.php:getSortByStr()
+        $default_alias = [
+            'post'    => [
+                'title'     => 'post_title',
+                'selected'  => 'post_selected',
+                'author'    => 'user_id',
+                'date'      => 'post_dt',
+                'id'        => 'post_id',
+                'comment'   => 'nb_comment',
+                'trackback' => 'nb_trackback'
+            ],
+            'comment' => [
+                'author' => 'comment_author',
+                'date'   => 'comment_dt',
+                'id'     => 'comment_id'
+            ]
+        ];
 
-		$tpl = new \dcTemplate(sys_get_temp_dir(),'$tpl',$this->getCore());
+        $tpl = new \dcTemplate(sys_get_temp_dir(), '$tpl', $this->getCore());
 
-		foreach ($default_alias as $table => $fields) {
-			$this
-				->string($tpl->getSortByStr(array(),$table))
-				->isEqualTo($default_alias[$table]['date'].' desc');
-			foreach ($fields as $field => $value) {
-				$this
-					->string($tpl->getSortByStr(array('sortby' => $field),$table))
-					->isEqualTo($value.' desc');
-				$this
-					->string($tpl->getSortByStr(array('sortby' => $field,'order' => 'asc'),$table))
-					->isEqualTo($value.' asc');
-			}
-		}
-	}
+        foreach ($default_alias as $table => $fields) {
+            $this
+                ->string($tpl->getSortByStr([], $table))
+                ->isEqualTo($default_alias[$table]['date'] . ' desc');
+            foreach ($fields as $field => $value) {
+                $this
+                    ->string($tpl->getSortByStr(['sortby' => $field], $table))
+                    ->isEqualTo($value . ' desc');
+                $this
+                    ->string($tpl->getSortByStr(['sortby' => $field, 'order' => 'asc'], $table))
+                    ->isEqualTo($value . ' asc');
+            }
+        }
+    }
 
-	public function testGetSortByStrWithNonExistingKeyAndExistingTable() {
-		$tpl = new \dcTemplate(sys_get_temp_dir(),'$tpl',$this->getCore());
-		$this
-			->string($tpl->getSortByStr(array('sortby' => 'dummy_field'),'post'))
-			->isEqualTo('post_dt desc')
-			->string($tpl->getSortByStr(array('sortby' => 'dummy_field'),'comment'))
-			->isEqualTo('comment_dt desc');
-	}
+    public function testGetSortByStrWithNonExistingKeyAndExistingTable()
+    {
+        $tpl = new \dcTemplate(sys_get_temp_dir(), '$tpl', $this->getCore());
+        $this
+            ->string($tpl->getSortByStr(['sortby' => 'dummy_field'], 'post'))
+            ->isEqualTo('post_dt desc')
+            ->string($tpl->getSortByStr(['sortby' => 'dummy_field'], 'comment'))
+            ->isEqualTo('comment_dt desc');
+    }
 
-	public function testGetSortByStrWithNewKeyAndExistingTable() {
-		$new_alias = array();
-		$new_alias['post']['category'] = 'cat_id';
-		$new_alias['post']['format'] = 'post_format';
-		$new_alias['comment']['filter'] = 'spam_filter';
+    public function testGetSortByStrWithNewKeyAndExistingTable()
+    {
+        $new_alias                      = [];
+        $new_alias['post']['category']  = 'cat_id';
+        $new_alias['post']['format']    = 'post_format';
+        $new_alias['comment']['filter'] = 'spam_filter';
 
-		$core = $this->getCore();
-		$core->addBehavior('templateCustomSortByAlias',
-						   function($alias) use ($new_alias) {
-							   foreach ($new_alias as $table => $fields) {
-								   foreach ($fields as $field => $value) {
-									   $alias[$table][$field] = $value;
-								   }
-							   }
-						   }
-		);
+        $core = $this->getCore();
+        $core->addBehavior('templateCustomSortByAlias',
+            function ($alias) use ($new_alias) {
+                foreach ($new_alias as $table => $fields) {
+                    foreach ($fields as $field => $value) {
+                        $alias[$table][$field] = $value;
+                    }
+                }
+            }
+        );
 
-		$tpl = new \dcTemplate(sys_get_temp_dir(),'$tpl',$core);
-		foreach ($new_alias as $table => $fields) {
-			foreach ($fields as $field => $value) {
-				$this
-					->string($tpl->getSortByStr(array('sortby' => $field),$table))
-					->isEqualTo($value.' desc');
-			}
-		}
-	}
+        $tpl = new \dcTemplate(sys_get_temp_dir(), '$tpl', $core);
+        foreach ($new_alias as $table => $fields) {
+            foreach ($fields as $field => $value) {
+                $this
+                    ->string($tpl->getSortByStr(['sortby' => $field], $table))
+                    ->isEqualTo($value . ' desc');
+            }
+        }
+    }
 
-	public function testGetSortByStrWithNewTable() {
-		$new_alias = array();
-		$new_alias['dummy_table']['field1'] = 'field1_id';
-		$new_alias['dummy_table']['field2'] = 'field2_format';
+    public function testGetSortByStrWithNewTable()
+    {
+        $new_alias                          = [];
+        $new_alias['dummy_table']['field1'] = 'field1_id';
+        $new_alias['dummy_table']['field2'] = 'field2_format';
 
-		$core = $this->getCore();
-		$core->addBehavior('templateCustomSortByAlias',
-						   function($alias) use ($new_alias) {
-							   foreach ($new_alias as $table => $fields) {
-								   foreach ($fields as $field => $value) {
-									   $alias[$table][$field] = $value;
-								   }
-							   }
-						   }
-		);
+        $core = $this->getCore();
+        $core->addBehavior('templateCustomSortByAlias',
+            function ($alias) use ($new_alias) {
+                foreach ($new_alias as $table => $fields) {
+                    foreach ($fields as $field => $value) {
+                        $alias[$table][$field] = $value;
+                    }
+                }
+            }
+        );
 
-		$tpl = new \dcTemplate(sys_get_temp_dir(),'$tpl',$core);
-		foreach ($new_alias as $table => $fields) {
-			foreach ($fields as $field => $value) {
-				$this
-					->string($tpl->getSortByStr(array('sortby' => $field),$table))
-					->isEqualTo($value.' desc');
-			}
-		}
-	}
+        $tpl = new \dcTemplate(sys_get_temp_dir(), '$tpl', $core);
+        foreach ($new_alias as $table => $fields) {
+            foreach ($fields as $field => $value) {
+                $this
+                    ->string($tpl->getSortByStr(['sortby' => $field], $table))
+                    ->isEqualTo($value . ' desc');
+            }
+        }
+    }
 }
Index: themes/berlin/_define.php
===================================================================
--- themes/berlin/_define.php	(revision 3731)
+++ themes/berlin/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "Dotclear Team",               // Author
     '1.2',                         // Version
-    array(                         // Properties
+    [                              // Properties
         'type'   => 'theme',
         'tplset' => 'dotty'
-    )
+    ]
 );
Index: themes/berlin/_public.php
===================================================================
--- themes/berlin/_public.php	(revision 3731)
+++ themes/berlin/_public.php	(revision 3874)
@@ -17,5 +17,5 @@
 //__('Show menu').__('Hide menu').__('Navigation');
 
-$core->addBehavior('publicHeadContent', array(__NAMESPACE__ . '\behaviorBerlinTheme', 'publicHeadContent'));
+$core->addBehavior('publicHeadContent', [__NAMESPACE__ . '\behaviorBerlinTheme', 'publicHeadContent']);
 
 class behaviorBerlinTheme
@@ -23,9 +23,9 @@
     public static function publicHeadContent()
     {
-        echo \dcUtils::jsVars(array(
+        echo \dcUtils::jsVars([
             'dotclear_berlin_show_menu'  => __('Show menu'),
             'dotclear_berlin_hide_menu'  => __('Hide menu'),
             'dotclear_berlin_navigation' => __('Navigation')
-        ));
+        ]);
     }
 }
Index: themes/berlin/js/berlin.js
===================================================================
--- themes/berlin/js/berlin.js	(revision 3709)
+++ themes/berlin/js/berlin.js	(revision 3880)
@@ -5,5 +5,5 @@
 // Show/Hide main menu
 $('.header__nav').
-before('<button id="hamburger" type="button"><span class="visually-hidden">' + dotclear_berlin_navigation + '</span></button>').
+before(`<button id="hamburger" type="button"><span class="visually-hidden">${dotclear_berlin_navigation}</span></button>`).
 toggle();
 $('#hamburger').click(function() {
@@ -12,7 +12,7 @@
 });
 // Show/Hide sidebar on small screens
-$('#main').prepend('<button id="offcanvas-on" type="button"><span class="visually-hidden">' + dotclear_berlin_show_menu + '</span></button>');
+$('#main').prepend(`<button id="offcanvas-on" type="button"><span class="visually-hidden">${dotclear_berlin_show_menu}</span></button>`);
 $('#offcanvas-on').click(function() {
-  var btn = $('<button id="offcanvas-off" type="button"><span class="visually-hidden">' + dotclear_berlin_hide_menu + '</span></button>');
+  const btn = $(`<button id="offcanvas-off" type="button"><span class="visually-hidden">${dotclear_berlin_hide_menu}</span></button>`);
   $('#wrapper').addClass('off-canvas');
   $('#footer').addClass('off-canvas');
Index: themes/berlin/scss/partials/_common.scss
===================================================================
--- themes/berlin/scss/partials/_common.scss	(revision 2640)
+++ themes/berlin/scss/partials/_common.scss	(revision 3876)
@@ -64,4 +64,7 @@
     @include background-image(linear-gradient(left, $gray-medium, $gray-dark, $gray-medium));
 }
+abbr[title] {
+  text-decoration: none;
+}
 blockquote, q {
     font-family: $serif;
@@ -117,2 +120,13 @@
 }
 ul ul, ul ol, ol ol, ol ul { margin-top: .5em; }
+/* a11y */
+.sr {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px;
+}
Index: themes/berlin/style.css
===================================================================
--- themes/berlin/style.css	(revision 3760)
+++ themes/berlin/style.css	(revision 3876)
@@ -267,4 +267,7 @@
   background-image: linear-gradient(to right, #dcdcdc, #636363, #dcdcdc); }
 
+abbr[title] {
+  text-decoration: none; }
+
 blockquote, q {
   font-family: "New Century Schoolbook", "Century Schoolbook", "Century Schoolbook L", Georgia, serif;
@@ -321,4 +324,15 @@
 ul ul, ul ol, ol ol, ol ul {
   margin-top: .5em; }
+
+/* a11y */
+.sr {
+  border: 0;
+  clip: rect(0 0 0 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px; }
 
 .post-date,
Index: themes/blueSilence/_define.php
===================================================================
--- themes/blueSilence/_define.php	(revision 3731)
+++ themes/blueSilence/_define.php	(revision 3874)
@@ -17,6 +17,6 @@
     "Marco / marcarea.com", // Author
     '1.0',                  // Version
-    array(
+    [
         'type' => 'theme'
-    )
+    ]
 );
Index: themes/customCSS/_define.php
===================================================================
--- themes/customCSS/_define.php	(revision 3731)
+++ themes/customCSS/_define.php	(revision 3874)
@@ -17,6 +17,6 @@
     "Olivier",                  // Author
     '1.2',                      // Version
-    array(
+    [
         'type' => 'theme'
-    )
+    ]
 );
Index: themes/customCSS/_public.php
===================================================================
--- themes/customCSS/_public.php	(revision 3731)
+++ themes/customCSS/_public.php	(revision 3874)
@@ -14,5 +14,5 @@
 if (!defined('DC_RC_PATH')) {return;}
 
-$core->addBehavior('publicHeadContent', array(__NAMESPACE__ . '\tplCustomTheme', 'publicHeadContent'));
+$core->addBehavior('publicHeadContent', [__NAMESPACE__ . '\tplCustomTheme', 'publicHeadContent']);
 
 class tplCustomTheme
Index: themes/default/_define.php
===================================================================
--- themes/default/_define.php	(revision 3731)
+++ themes/default/_define.php	(revision 3874)
@@ -17,6 +17,6 @@
     "Marco & Olivier",                            // Author
     '1.0',                                        // Version
-    array(
+    [
         'type' => 'theme'
-    )
+    ]
 );
Index: themes/default/js/post.js
===================================================================
--- themes/default/js/post.js	(revision 3706)
+++ themes/default/js/post.js	(revision 3880)
@@ -5,7 +5,7 @@
   $('#comment-form p:has(input[type=submit][name=preview],button[type=submit][name=preview])').
   before(
-    '<p class="remember"><input type="checkbox" id="c_remember" name="c_remember" /> ' +
-    '<label for="c_remember">' + post_remember_str + '</label>' +
-    '</p>'
+`<p class="remember"><input type="checkbox" id="c_remember" name="c_remember" />
+<label for="c_remember">${post_remember_str}</label>
+</p>`
   );
 
@@ -46,8 +46,8 @@
 
   function setCookie() {
-    var name = $('#c_name').val();
-    var mail = $('#c_mail').val();
-    var site = $('#c_site').val();
-    var cpath = $('link[rel=top]').attr('href');
+    const name = $('#c_name').val();
+    const mail = $('#c_mail').val();
+    const site = $('#c_site').val();
+    let cpath = $('link[rel=top]').attr('href');
     if (!cpath) {
       cpath = '/';
@@ -73,12 +73,9 @@
       return false;
     }
-
-    var s = c.split('\n');
-
+    const s = c.split('\n');
     if (s.length != 3) {
       dropCookie();
       return false;
     }
-
     return s;
   }
Index: themes/ductile/_config.php
===================================================================
--- themes/ductile/_config.php	(revision 3731)
+++ themes/ductile/_config.php	(revision 3874)
@@ -30,9 +30,9 @@
 }
 
-$list_types = array(
+$list_types = [
     __('Title') => 'title',
     __('Short') => 'short',
     __('Full')  => 'full'
-);
+];
 // Get all _entry-*.html in tpl folder of theme
 $list_types_templates = files::scandir($tpl_path);
@@ -50,5 +50,5 @@
 }
 
-$contexts = array(
+$contexts = [
     'default'      => __('Home (first page)'),
     'default-page' => __('Home (other pages)'),
@@ -57,7 +57,7 @@
     'search'       => __('Search result entries'),
     'archive'      => __('Month archive entries')
-);
-
-$fonts = array(
+];
+
+$fonts = [
     __('Default')           => '',
     __('Ductile primary')   => 'Ductile body',
@@ -71,13 +71,13 @@
     __('Impact')            => 'Impact',
     __('Monospace')         => 'Monospace'
-);
-
-$webfont_apis = array(
+];
+
+$webfont_apis = [
     __('none')                => '',
     __('javascript (Adobe)')  => 'js',
     __('stylesheet (Google)') => 'css'
-);
-
-$font_families = array(
+];
+
+$font_families = [
     // Theme standard
     'Ductile body'      => '"Century Schoolbook", "Century Schoolbook L", Georgia, serif',
@@ -99,5 +99,5 @@
     // Monospace families
     'Monospace'         => 'Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace'
-);
+];
 
 function fontDef($c)
@@ -108,5 +108,5 @@
 }
 
-$ductile_base = array(
+$ductile_base = [
     // HTML
     'subtitle_hidden'          => null,
@@ -138,7 +138,7 @@
     'post_title_c_m'           => null,
     'post_simple_title_c'      => null
-);
-
-$ductile_lists_base = array(
+];
+
+$ductile_lists_base = [
     'default'      => 'short',
     'default-page' => 'short',
@@ -147,7 +147,7 @@
     'search'       => 'short',
     'archive'      => 'short'
-);
-
-$ductile_counts_base = array(
+];
+
+$ductile_counts_base = [
     'default'      => null,
     'default-page' => null,
@@ -155,10 +155,10 @@
     'tag'          => null,
     'search'       => null
-);
+];
 
 $ductile_user = $core->blog->settings->themes->get($core->blog->settings->system->theme . '_style');
 $ductile_user = @unserialize($ductile_user);
 if (!is_array($ductile_user)) {
-    $ductile_user = array();
+    $ductile_user = [];
 }
 $ductile_user = array_merge($ductile_base, $ductile_user);
@@ -183,13 +183,13 @@
 // If no stickers defined, add feed Atom one
 if (!is_array($ductile_stickers)) {
-    $ductile_stickers = array(array(
+    $ductile_stickers = [[
         'label' => __('Subscribe'),
         'url'   => $core->blog->url .
         $core->url->getURLFor('feed', 'atom'),
         'image' => 'sticker-feed.png'
-    ));
-}
-
-$ductile_stickers_full = array();
+    ]];
+}
+
+$ductile_stickers_full = [];
 // Get all sticker images already used
 if (is_array($ductile_stickers)) {
@@ -205,8 +205,8 @@
             if (!in_array($v, $ductile_stickers_full)) {
                 // image not already used
-                $ductile_stickers[] = array(
+                $ductile_stickers[] = [
                     'label' => null,
                     'url'   => null,
-                    'image' => $v);
+                    'image' => $v];
             }
         }
@@ -225,14 +225,14 @@
             $ductile_user['preview_not_mandatory'] = (integer) !empty($_POST['preview_not_mandatory']);
 
-            $ductile_stickers = array();
+            $ductile_stickers = [];
             for ($i = 0; $i < count($_POST['sticker_image']); $i++) {
-                $ductile_stickers[] = array(
+                $ductile_stickers[] = [
                     'label' => $_POST['sticker_label'][$i],
                     'url'   => $_POST['sticker_url'][$i],
                     'image' => $_POST['sticker_image'][$i]
-                );
-            }
-
-            $order = array();
+                ];
+            }
+
+            $order = [];
             if (empty($_POST['ds_order']) && !empty($_POST['order'])) {
                 $order = $_POST['order'];
@@ -241,11 +241,11 @@
             }
             if (!empty($order)) {
-                $new_ductile_stickers = array();
+                $new_ductile_stickers = [];
                 foreach ($order as $i => $k) {
-                    $new_ductile_stickers[] = array(
+                    $new_ductile_stickers[] = [
                         'label' => $ductile_stickers[$k]['label'],
                         'url'   => $ductile_stickers[$k]['url'],
                         'image' => $ductile_stickers[$k]['image']
-                    );
+                    ];
                 }
                 $ductile_stickers = $new_ductile_stickers;
@@ -325,5 +325,5 @@
 '<h3>' . __('Content') . '</h3>';
 
-echo '<form id="theme_config" action="' . $core->adminurl->get('admin.blog.theme', array('conf' => '1')) .
+echo '<form id="theme_config" action="' . $core->adminurl->get('admin.blog.theme', ['conf' => '1']) .
     '" method="post" enctype="multipart/form-data">';
 
@@ -357,13 +357,13 @@
     echo
     '<tr class="line" id="l_' . $i . '">' .
-    '<td class="handle minimal">' . form::number(array('order[' . $i . ']'), array(
+    '<td class="handle minimal">' . form::number(['order[' . $i . ']'], [
         'min'     => 0,
         'default' => $count,
         'class'   => 'position'
-    )) .
-    form::hidden(array('dynorder[]', 'dynorder-' . $i), $i) . '</td>' .
-    '<td>' . form::hidden(array('sticker_image[]'), $v['image']) . '<img src="' . $img_url . $v['image'] . '" alt="' . $v['image'] . '" /> ' . '</td>' .
-    '<td scope="row">' . form::field(array('sticker_label[]', 'dsl-' . $i), 20, 255, $v['label']) . '</td>' .
-    '<td>' . form::field(array('sticker_url[]', 'dsu-' . $i), 40, 255, $v['url']) . '</td>' .
+    ]) .
+    form::hidden(['dynorder[]', 'dynorder-' . $i], $i) . '</td>' .
+    '<td>' . form::hidden(['sticker_image[]'], $v['image']) . '<img src="' . $img_url . $v['image'] . '" alt="' . $v['image'] . '" /> ' . '</td>' .
+    '<td scope="row">' . form::field(['sticker_label[]', 'dsl-' . $i], 20, 255, $v['label']) . '</td>' .
+    '<td>' . form::field(['sticker_url[]', 'dsu-' . $i], 40, 255, $v['url']) . '</td>' .
         '</tr>';
 }
@@ -387,11 +387,11 @@
     '<tr>' .
     '<td scope="row">' . $contexts[$k] . '</td>' .
-    '<td>' . form::hidden(array('list_ctx[]'), $k) . form::combo(array('list_type[]'), $list_types, $v) . '</td>';
+    '<td>' . form::hidden(['list_ctx[]'], $k) . form::combo(['list_type[]'], $list_types, $v) . '</td>';
     if (array_key_exists($k, $ductile_counts)) {
-        echo '<td>' . form::hidden(array('count_ctx[]'), $k) . form::number(array('count_nb[]'), array(
+        echo '<td>' . form::hidden(['count_ctx[]'], $k) . form::number(['count_nb[]'], [
             'min'     => 0,
             'max'     => 999,
             'default' => $ductile_counts[$k]
-        )) . '</td>';
+        ]) . '</td>';
     } else {
         echo '<td></td>';
@@ -418,5 +418,5 @@
 echo '<div class="multi-part" id="themes-list' . ($conf_tab == 'css' ? '' : '-css') . '" title="' . __('Presentation') . '">';
 
-echo '<form id="theme_config" action="' . $core->adminurl->get('admin.blog.theme', array('conf' => '1')) .
+echo '<form id="theme_config" action="' . $core->adminurl->get('admin.blog.theme', ['conf' => '1']) .
     '" method="post" enctype="multipart/form-data">';
 
@@ -469,5 +469,5 @@
 
 '<p class="field picker"><label for="blog_title_c">' . __('Color:') . '</label> ' .
-form::color('blog_title_c', array('default' => $ductile_user['blog_title_c'])) .
+form::color('blog_title_c', ['default' => $ductile_user['blog_title_c']]) .
 dcThemeConfig::contrastRatio($ductile_user['blog_title_c'], '#ffffff',
     (!empty($ductile_user['blog_title_s']) ? $ductile_user['blog_title_s'] : '2em'),
@@ -486,5 +486,5 @@
 
 '<p class="field picker"><label for="post_title_c">' . __('Color:') . '</label> ' .
-form::color('post_title_c', array('default' => $ductile_user['post_title_c'])) .
+form::color('post_title_c', ['default' => $ductile_user['post_title_c']]) .
 dcThemeConfig::contrastRatio($ductile_user['post_title_c'], '#ffffff',
     (!empty($ductile_user['post_title_s']) ? $ductile_user['post_title_s'] : '2.5em'),
@@ -498,5 +498,5 @@
 
 '<p class="field picker"><label for="post_simple_title_c">' . __('Color:') . '</label> ' .
-form::color('post_simple_title_c', array('default' => $ductile_user['post_simple_title_c'])) .
+form::color('post_simple_title_c', ['default' => $ductile_user['post_simple_title_c']]) .
 dcThemeConfig::contrastRatio($ductile_user['post_simple_title_c'], '#ffffff',
     '1.1em', // H5 minimum size
@@ -509,5 +509,5 @@
 
 '<p class="field picker"><label for="post_link_v_c">' . __('Normal and visited links color:') . '</label> ' .
-form::color('post_link_v_c', array('default' => $ductile_user['post_link_v_c'])) .
+form::color('post_link_v_c', ['default' => $ductile_user['post_link_v_c']]) .
 dcThemeConfig::contrastRatio($ductile_user['post_link_v_c'], '#ffffff',
     '1em',
@@ -516,5 +516,5 @@
 
 '<p class="field picker"><label for="post_link_f_c">' . __('Active, hover and focus links color:') . '</label> ' .
-form::color('post_link_f_c', array('default' => $ductile_user['post_link_f_c'])) .
+form::color('post_link_f_c', ['default' => $ductile_user['post_link_f_c']]) .
 dcThemeConfig::contrastRatio($ductile_user['post_link_f_c'], '#ebebee',
     '1em',
@@ -535,5 +535,5 @@
 
 '<p class="field picker"><label for="blog_title_c_m">' . __('Color:') . '</label> ' .
-form::color('blog_title_c_m', array('default' => $ductile_user['blog_title_c_m'])) .
+form::color('blog_title_c_m', ['default' => $ductile_user['blog_title_c_m']]) .
 dcThemeConfig::contrastRatio($ductile_user['blog_title_c_m'], '#d7d7dc',
     (!empty($ductile_user['blog_title_s_m']) ? $ductile_user['blog_title_s_m'] : '1.8em'),
@@ -552,5 +552,5 @@
 
 '<p class="field picker"><label for="post_title_c_m">' . __('Color:') . '</label> ' .
-form::color('post_title_c_m', array('default' => $ductile_user['post_title_c_m'])) .
+form::color('post_title_c_m', ['default' => $ductile_user['post_title_c_m']]) .
 dcThemeConfig::contrastRatio($ductile_user['post_title_c_m'], '#ffffff',
     (!empty($ductile_user['post_title_s_m']) ? $ductile_user['post_title_s_m'] : '1.5em'),
Index: themes/ductile/_define.php
===================================================================
--- themes/ductile/_define.php	(revision 3731)
+++ themes/ductile/_define.php	(revision 3874)
@@ -17,7 +17,7 @@
     "Dotclear Team",                        // Author
     '1.5',                                  // Version
-    array(                                  // Properties
+    [                                  // Properties
         'standalone_config' => true,
         'type'              => 'theme'
-    )
+    ]
 );
Index: themes/ductile/_prepend.php
===================================================================
--- themes/ductile/_prepend.php	(revision 3731)
+++ themes/ductile/_prepend.php	(revision 3874)
@@ -19,5 +19,5 @@
 
 # Behaviors
-$GLOBALS['core']->addBehavior('adminPageHTMLHead', array(__NAMESPACE__ . '\tplDuctileThemeAdmin', 'adminPageHTMLHead'));
+$GLOBALS['core']->addBehavior('adminPageHTMLHead', [__NAMESPACE__ . '\tplDuctileThemeAdmin', 'adminPageHTMLHead']);
 
 class tplDuctileThemeAdmin
Index: themes/ductile/_public.php
===================================================================
--- themes/ductile/_public.php	(revision 3731)
+++ themes/ductile/_public.php	(revision 3874)
@@ -17,13 +17,13 @@
 
 # Behaviors
-$core->addBehavior('publicHeadContent', array(__NAMESPACE__ . '\tplDuctileTheme', 'publicHeadContent'));
-$core->addBehavior('publicInsideFooter', array(__NAMESPACE__ . '\tplDuctileTheme', 'publicInsideFooter'));
+$core->addBehavior('publicHeadContent', [__NAMESPACE__ . '\tplDuctileTheme', 'publicHeadContent']);
+$core->addBehavior('publicInsideFooter', [__NAMESPACE__ . '\tplDuctileTheme', 'publicInsideFooter']);
 
 # Templates
-$core->tpl->addValue('ductileEntriesList', array(__NAMESPACE__ . '\tplDuctileTheme', 'ductileEntriesList'));
-$core->tpl->addBlock('EntryIfContentIsCut', array(__NAMESPACE__ . '\tplDuctileTheme', 'EntryIfContentIsCut'));
-$core->tpl->addValue('ductileNbEntryPerPage', array(__NAMESPACE__ . '\tplDuctileTheme', 'ductileNbEntryPerPage'));
-$core->tpl->addValue('ductileLogoSrc', array(__NAMESPACE__ . '\tplDuctileTheme', 'ductileLogoSrc'));
-$core->tpl->addBlock('IfPreviewIsNotMandatory', array(__NAMESPACE__ . '\tplDuctileTheme', 'IfPreviewIsNotMandatory'));
+$core->tpl->addValue('ductileEntriesList', [__NAMESPACE__ . '\tplDuctileTheme', 'ductileEntriesList']);
+$core->tpl->addBlock('EntryIfContentIsCut', [__NAMESPACE__ . '\tplDuctileTheme', 'EntryIfContentIsCut']);
+$core->tpl->addValue('ductileNbEntryPerPage', [__NAMESPACE__ . '\tplDuctileTheme', 'ductileNbEntryPerPage']);
+$core->tpl->addValue('ductileLogoSrc', [__NAMESPACE__ . '\tplDuctileTheme', 'ductileLogoSrc']);
+$core->tpl->addBlock('IfPreviewIsNotMandatory', [__NAMESPACE__ . '\tplDuctileTheme', 'IfPreviewIsNotMandatory']);
 
 class tplDuctileTheme
@@ -109,5 +109,5 @@
 
         $tpl_path   = dirname(__FILE__) . '/tpl/';
-        $list_types = array('title', 'short', 'full');
+        $list_types = ['title', 'short', 'full'];
 
         // Get all _entry-*.html in tpl folder of theme
@@ -133,5 +133,5 @@
             $ret .= '   case \'' . $v . '\':' . "\n" .
             '?>' . "\n" .
-            $core->tpl->includeFile(array('src' => '_entry-' . $v . '.html')) . "\n" .
+            $core->tpl->includeFile(['src' => '_entry-' . $v . '.html']) . "\n" .
                 '<?php ' . "\n" .
                 '       break;' . "\n";
@@ -303,6 +303,6 @@
 
         $ret = '';
-        $css = array();
-        $uri = array();
+        $css = [];
+        $uri = [];
         if (!isset($s['body_font']) || ($s['body_font'] == '')) {
             // See if webfont defined for main font
@@ -369,5 +369,5 @@
         }
 
-        $css = array();
+        $css = [];
 
         # Properties
@@ -420,5 +420,5 @@
 
         # Large screens
-        $css_large = array();
+        $css_large = [];
 
         # Blog title font weight
@@ -478,5 +478,5 @@
 
         # Small screens
-        $css_small = array();
+        $css_small = [];
 
         # Blog title font weight
@@ -532,5 +532,5 @@
     }
 
-    protected static $fonts = array(
+    protected static $fonts = [
         // Theme standard
         'Ductile body'      => '"Century Schoolbook", "Century Schoolbook L", Georgia, serif',
@@ -552,5 +552,5 @@
         // Monospace families
         'Monospace'         => 'Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace'
-    );
+    ];
 
     protected static function fontDef($c)
Index: themes/ductile/ductile.js
===================================================================
--- themes/ductile/ductile.js	(revision 3706)
+++ themes/ductile/ductile.js	(revision 3880)
@@ -2,79 +2,69 @@
 'use strict';
 
-$(function() {
-  var create_name = function(text) {
+$(document).ready(function() {
+  if ($(window).width() < 1024) {
 
-    // Convert text to lower case.
-    var name = text.toLowerCase();
+    const create_name = function(text) {
 
-    // Remove leading and trailing spaces, and any non-alphanumeric
-    // characters except for ampersands, spaces and dashes.
-    name = name.replace(/^\s+|\s+$|[^a-z0-9&\s-]/g, '');
+      // Convert text to lower case.
+      let name = text.toLowerCase();
 
-    // Replace '&' with 'and'.
-    name = name.replace(/&/g, 'and');
+      // Remove leading and trailing spaces, and any non-alphanumeric
+      // characters except for ampersands, spaces and dashes.
+      name = name.replace(/^\s+|\s+$|[^a-z0-9&\s-]/g, '');
 
-    // Replaces spaces with dashes.
-    name = name.replace(/\s/g, '-');
+      // Replace '&' with 'and'.
+      name = name.replace(/&/g, 'and');
 
-    // Squash any duplicate dashes.
-    name = name.replace(/(-)+\1/g, '$1');
+      // Replaces spaces with dashes.
+      name = name.replace(/\s/g, '-');
 
-    return name;
-  };
+      // Squash any duplicate dashes.
+      name = name.replace(/(-)+\1/g, '$1');
 
-  var add_link = function() {
+      return name;
+    };
 
-    // Convert the h2 element text into a value that
-    // is safe to use in a name attribute.
-    var name = create_name($(this).text());
+    // Set toggle class to each #sidebar h2
+    $('#sidebar div div h2').addClass('toggle');
 
-    // Create a name attribute in the following sibling
-    // to act as a fragment anchor.
-    $(this).next().attr('name', name);
+    // Hide all h2.toggle siblings
+    $('#sidebar div div h2').nextAll().hide();
 
-    // Replace the h2.toggle element with a link to the
-    // fragment anchor.  Use the h2 text to create the
-    // link title attribute.
-    $(this).html(
-      '<a href="#' + name + '" title="Reveal ' +
-      $(this).text() + ' content">' +
-      $(this).html() + '</a>');
-  };
+    // Add a link to each h2.toggle element.
+    $('h2.toggle').each(function() {
 
-  var toggle = function(event) {
-    event.preventDefault();
+      // Convert the h2 element text into a value that
+      // is safe to use in a name attribute.
+      const name = create_name($(this).text());
 
-    // Toggle the 'expanded' class of the h2.toggle
-    // element, then apply the slideToggle effect
-    // to all siblings.
-    $(this).toggleClass('expanded').
-    nextAll().slideToggle('fast');
-  };
+      // Create a name attribute in the following sibling
+      // to act as a fragment anchor.
+      $(this).next().attr('name', name);
 
-  var remove_focus = function() {
-    // Use the blur() method to remove focus.
-    $(this).blur();
-  };
+      // Replace the h2.toggle element with a link to the
+      // fragment anchor.  Use the h2 text to create the
+      // link title attribute.
+      $(this).html(
+        '<a href="#' + name + '" title="Reveal ' +
+        $(this).text() + ' content">' +
+        $(this).html() + '</a>');
+    });
 
-  $(document).ready(function() {
-    if ($(window).width() < 1024) {
+    // Add a click event handler to all h2.toggle elements.
+    $('h2.toggle').click(function(event) {
+      event.preventDefault();
+      // Toggle the 'expanded' class of the h2.toggle
+      // element, then apply the slideToggle effect
+      // to all siblings.
+      $(this).toggleClass('expanded').
+      nextAll().slideToggle('fast');
+    });
 
-      // Set toggle class to each #sidebar h2
-      $('#sidebar div div h2').addClass('toggle');
-
-      // Hide all h2.toggle siblings
-      $('#sidebar div div h2').nextAll().hide();
-
-      // Add a link to each h2.toggle element.
-      $('h2.toggle').each(add_link);
-
-      // Add a click event handler to all h2.toggle elements.
-      $('h2.toggle').click(toggle);
-
-      // Remove the focus from the link tag when accessed with a mouse.
-      $('h2.toggle a').mouseup(remove_focus);
-    }
-  });
-
+    // Remove the focus from the link tag when accessed with a mouse.
+    $('h2.toggle a').mouseup(function() {
+      // Use the blur() method to remove focus.
+      $(this).blur();
+    });
+  }
 });
Index: travis/install.php
===================================================================
--- travis/install.php	(revision 2931)
+++ travis/install.php	(revision 3874)
@@ -16,9 +16,9 @@
 
 $tmp_pwd = md5(uniqid());  // don't care, user will be deleted
-$_POST = array(
+$_POST = [
     'u_login' => 'admin',
     'u_pwd' =>  $tmp_pwd,
     'u_pwd2' => $tmp_pwd
-);
+];
 
 ob_start();
